some progress on making takeover height work
This commit is contained in:
parent
377432a459
commit
515446fe7b
12 changed files with 221 additions and 188 deletions
|
@ -174,9 +174,10 @@ bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CSc
|
|||
case OP_UPDATE_CLAIM:
|
||||
return claimOp.updateClaim(trieCache, vchToString(vvchParams[0]), uint160(vvchParams[1]),
|
||||
vvchParams[2]);
|
||||
}
|
||||
default:
|
||||
throw std::runtime_error("Unimplemented OP handler.");
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoinsViewCache& view, int nHeight, const CUpdateCacheCallbacks& callbacks)
|
||||
{
|
||||
|
@ -188,12 +189,12 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
||||
{
|
||||
if (CClaimScriptSpendOp::spendClaim(trieCache, name, claimId)) {
|
||||
callback(name, claimId, nValidHeight);
|
||||
callback(name, claimId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::function<void(const std::string& name, const uint160& claimId, const int takeoverHeight)> callback;
|
||||
std::function<void(const std::string& name, const uint160& claimId)> callback;
|
||||
};
|
||||
|
||||
spentClaimsType spentClaims;
|
||||
|
@ -216,8 +217,8 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
|
||||
int nValidAtHeight;
|
||||
CSpendClaimHistory spendClaim(COutPoint(txin.prevout.hash, txin.prevout.n), scriptHeight, nValidAtHeight);
|
||||
spendClaim.callback = [&spentClaims](const std::string& name, const uint160& claimId, const int takeoverHeight) {
|
||||
spentClaims.emplace_back(name, claimId, takeoverHeight);
|
||||
spendClaim.callback = [&spentClaims](const std::string& name, const uint160& claimId) {
|
||||
spentClaims.emplace_back(name, claimId);
|
||||
};
|
||||
if (ProcessClaim(spendClaim, trieCache, scriptPubKey) && callbacks.claimUndoHeights)
|
||||
callbacks.claimUndoHeights(j, nValidAtHeight);
|
||||
|
@ -231,12 +232,11 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
||||
const std::vector<unsigned char>& metadata) override
|
||||
{
|
||||
int takeoverHeight = -1;
|
||||
if (callback(name, claimId, takeoverHeight))
|
||||
return CClaimScriptAddOp::addClaim(trieCache, name, claimId, takeoverHeight, metadata);
|
||||
if (callback(name, claimId))
|
||||
return CClaimScriptAddOp::addClaim(trieCache, name, claimId, -1, metadata);
|
||||
return false;
|
||||
}
|
||||
std::function<bool(const std::string& name, const uint160& claimId, int& takeoverHeight)> callback;
|
||||
std::function<bool(const std::string& name, const uint160& claimId)> callback;
|
||||
};
|
||||
|
||||
for (std::size_t j = 0; j < tx.vout.size(); j++) {
|
||||
|
@ -246,10 +246,9 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
continue;
|
||||
|
||||
CAddSpendClaim addClaim(COutPoint(tx.GetHash(), j), txout.nValue, nHeight);
|
||||
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId, int& takeoverHeight) -> bool {
|
||||
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId) -> bool {
|
||||
for (auto itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) {
|
||||
if (std::get<1>(*itSpent) == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(std::get<0>(*itSpent))) {
|
||||
takeoverHeight = std::get<2>(*itSpent);
|
||||
if (itSpent->second == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first)) {
|
||||
spentClaims.erase(itSpent);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -238,8 +238,7 @@ protected:
|
|||
*/
|
||||
bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CScript& scriptPubKey);
|
||||
|
||||
typedef std::tuple<std::string, uint160, int> spentClaimType;
|
||||
|
||||
typedef std::pair<std::string, uint160> spentClaimType;
|
||||
typedef std::vector<spentClaimType> spentClaimsType;
|
||||
|
||||
struct CUpdateCacheCallbacks
|
||||
|
|
|
@ -56,7 +56,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor)
|
|||
db.define("MERKLE_PAIR", [](const std::vector<unsigned char>& blob1, const std::vector<unsigned char>& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); });
|
||||
db.define("MERKLE", [](const std::vector<unsigned char>& blob1) { return Hash(blob1.begin(), blob1.end()); });
|
||||
|
||||
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB)";
|
||||
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB, takeoverHeight INTEGER, takeoverID BLOB)";
|
||||
db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)";
|
||||
db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)";
|
||||
|
||||
|
@ -325,13 +325,14 @@ CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim) const
|
||||
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset) const
|
||||
{
|
||||
auto nextHeight = nNextHeight + heightOffset;
|
||||
auto query = db << "SELECT c.claimID, c.txID, c.txN, c.blockHeight, c.validHeight, c.amount, "
|
||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN LIMIT 1"
|
||||
<< nNextHeight << nNextHeight << name << nNextHeight << nNextHeight;
|
||||
<< nextHeight << nextHeight << name << nextHeight << nextHeight;
|
||||
for (auto&& row: query) {
|
||||
row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n
|
||||
>> claim.nHeight >> claim.nValidAtHeight >> claim.nAmount >> claim.nEffectiveAmount;
|
||||
|
@ -391,18 +392,19 @@ void completeHash(uint256& partialHash, const std::string& key, std::size_t to)
|
|||
.Finalize(partialHash.begin());
|
||||
}
|
||||
|
||||
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name, bool checkOnly)
|
||||
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||
{
|
||||
std::vector<uint8_t> vchToHash;
|
||||
const auto pos = name.size();
|
||||
auto query = db << "SELECT name, hash FROM nodes WHERE parent = ? ORDER BY name" << name;
|
||||
auto query = db << "SELECT name, hash, IFNULL(takeoverHeight,0) FROM nodes WHERE parent = ? ORDER BY name" << name;
|
||||
for (auto&& row : query) {
|
||||
std::string key;
|
||||
int childTakeoverHeight;
|
||||
std::unique_ptr<uint256> hash;
|
||||
row >> key >> hash;
|
||||
row >> key >> hash >> childTakeoverHeight;
|
||||
if (hash == nullptr) hash = std::make_unique<uint256>();
|
||||
if (hash->IsNull()) {
|
||||
*hash = recursiveComputeMerkleHash(key, checkOnly);
|
||||
*hash = recursiveComputeMerkleHash(key, childTakeoverHeight, checkOnly);
|
||||
}
|
||||
completeHash(*hash, key, pos);
|
||||
vchToHash.push_back(key[pos]);
|
||||
|
@ -411,7 +413,7 @@ uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name,
|
|||
|
||||
CClaimValue claim;
|
||||
if (getInfoForName(name, claim)) {
|
||||
uint256 valueHash = getValueHash(claim.outPoint, claim.nValidAtHeight);
|
||||
uint256 valueHash = getValueHash(claim.outPoint, takeoverHeight);
|
||||
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
|
||||
}
|
||||
|
||||
|
@ -425,12 +427,13 @@ bool CClaimTrieCacheBase::checkConsistency()
|
|||
{
|
||||
// verify that all claims hash to the values on the nodes
|
||||
|
||||
auto query = db << "SELECT name, hash FROM nodes";
|
||||
auto query = db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes";
|
||||
for (auto&& row: query) {
|
||||
std::string name;
|
||||
uint256 hash;
|
||||
row >> name >> hash;
|
||||
auto computedHash = recursiveComputeMerkleHash(name, true);
|
||||
int takeoverHeight;
|
||||
row >> name >> hash >> takeoverHeight;
|
||||
auto computedHash = recursiveComputeMerkleHash(name, takeoverHeight, true);
|
||||
if (computedHash != hash)
|
||||
return false;
|
||||
}
|
||||
|
@ -504,22 +507,23 @@ uint256 CClaimTrieCacheBase::getMerkleHash()
|
|||
{
|
||||
ensureTreeStructureIsUpToDate();
|
||||
std::unique_ptr<uint256> hash;
|
||||
db << "SELECT hash FROM nodes WHERE name = ''" >> hash;
|
||||
int takeoverHeight;
|
||||
db << "SELECT hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE name = ''" >> std::tie(hash, takeoverHeight);
|
||||
if (hash == nullptr || hash->IsNull()) {
|
||||
assert(transacting); // no data changed but we didn't have the root hash there already?
|
||||
return recursiveComputeMerkleHash("", false);
|
||||
return recursiveComputeMerkleHash("", takeoverHeight, false);
|
||||
}
|
||||
return *hash;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const
|
||||
{
|
||||
CClaimValue value;
|
||||
if (!getInfoForName(name, value))
|
||||
auto query = db << "SELECT takeoverHeight, takeoverID FROM nodes WHERE name = ? AND takeoverID IS NOT NULL" << name;
|
||||
auto it = query.begin();
|
||||
if (it == query.end())
|
||||
return false;
|
||||
takeoverHeight = value.nValidAtHeight;
|
||||
claimId = value.claimId;
|
||||
return true;
|
||||
*it >> takeoverHeight >> claimId;
|
||||
return !claimId.IsNull();
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId,
|
||||
|
@ -528,18 +532,26 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out
|
|||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
// in the update scenario the previous one should be removed already
|
||||
// in the downgrade scenario, the one ahead will be removed already and the old one's valid height is input
|
||||
// revisiting the update scenario we have two options:
|
||||
// 1. let them pull the old one first, in which case they will be responsible to pass in validHeight (since we can't determine it's a 0 delay)
|
||||
// 2. don't remove the old one; have this method do a kinder "update" situation.
|
||||
// Option 2 has the issue in that we don't actually update if we don't have an existing match,
|
||||
// and no way to know that here without an 'update' flag
|
||||
// In addition, as we currently do option 1 they use that to get the old valid height and store that for undo
|
||||
// We would have to make this method return that if we go without the removal
|
||||
// The other problem with 1 is that the outer shell would need to know if the one they removed was a winner or not
|
||||
|
||||
if (nValidHeight <= 0) {
|
||||
auto delay = getDelayForName(name, claimId);
|
||||
nValidHeight = nHeight + delay;
|
||||
}
|
||||
if (nValidHeight < 0)
|
||||
nValidHeight = nHeight + getDelayForName(name, claimId); // sets nValidHeight to the old value
|
||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||
auto expires = expirationTime() + nHeight;
|
||||
|
||||
db << "INSERT INTO claims(claimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) "
|
||||
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << claimId << name << nodeName
|
||||
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
||||
|
||||
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -548,10 +560,8 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& o
|
|||
{
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
if (nValidHeight <= 0) {
|
||||
auto delay = getDelayForName(name, supportedClaimId);
|
||||
nValidHeight = nHeight + delay;
|
||||
}
|
||||
if (nValidHeight < 0)
|
||||
nValidHeight = nHeight + getDelayForName(name, supportedClaimId);
|
||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||
auto expires = expirationTime() + nHeight;
|
||||
db << "INSERT INTO supports(supportedClaimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) "
|
||||
|
@ -884,7 +894,9 @@ static const boost::container::flat_map<std::pair<int, std::string>, int> takeov
|
|||
{{ 653524, "celtic-folk-music-full-live-concert-mps" }, 589762},
|
||||
};
|
||||
|
||||
bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
// the plan:
|
||||
// for every claim and support that becomes active this block set its node hash to null (aka, dirty)
|
||||
|
@ -932,18 +944,32 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimQueueR
|
|||
db << "SELECT name FROM nodes WHERE hash IS NULL" >> takeovers;
|
||||
|
||||
for (const auto& nameWithTakeover : takeovers) {
|
||||
auto needsActivate = false;
|
||||
if (nNextHeight >= 496856 && nNextHeight <= 653524) {
|
||||
auto wit = takeoverWorkarounds.find(std::make_pair(nNextHeight, nameWithTakeover));
|
||||
if (wit != takeoverWorkarounds.end()) {
|
||||
activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover);
|
||||
continue;
|
||||
}
|
||||
needsActivate = wit != takeoverWorkarounds.end();
|
||||
}
|
||||
|
||||
// if somebody activates on this block and they are the new best, then everybody activates on this block
|
||||
CClaimValue value;
|
||||
if (!getInfoForName(nameWithTakeover, value) || value.nValidAtHeight == nNextHeight)
|
||||
if (needsActivate || !getInfoForName(nameWithTakeover, value, 1) || value.nValidAtHeight == nNextHeight) {
|
||||
activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover);
|
||||
|
||||
// now that they're all in get the winner:
|
||||
if (getInfoForName(nameWithTakeover, value, 1)) {
|
||||
int existingHeight;
|
||||
std::unique_ptr<uint160> existingID;
|
||||
db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?"
|
||||
<< nameWithTakeover >> std::tie(existingHeight, existingID);
|
||||
if (existingID == nullptr || *existingID != value.claimId) {
|
||||
takeoverUndo.emplace_back(nameWithTakeover,
|
||||
std::make_pair(existingHeight, existingID == nullptr ? uint160() : *existingID));
|
||||
db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ? WHERE name = ?"
|
||||
<< nNextHeight << value.claimId << nameWithTakeover;
|
||||
assert(db.rows_modified());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nNextHeight++;
|
||||
|
@ -985,12 +1011,15 @@ void CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoT
|
|||
<< nNextHeight << name << nNextHeight << nNextHeight;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||
{
|
||||
if (!transacting) { transacting = true; db << "begin"; }
|
||||
|
||||
nNextHeight--;
|
||||
|
||||
// to actually delete the expired items and then restore them here I would have to look up the metadata in the block
|
||||
// that doesn't sound very fun so we modified the other queries to exclude expired items
|
||||
for (auto it = expireSupportUndo.crbegin(); it != expireSupportUndo.crend(); ++it) {
|
||||
db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?"
|
||||
<< it->second.nValidAtHeight << it->second.outPoint.hash << it->second.outPoint.n;
|
||||
|
@ -1017,16 +1046,20 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimQueueR
|
|||
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT nodeName FROM claims WHERE validHeight = ?)" << nNextHeight;
|
||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||
"(SELECT nodeName FROM supports WHERE validHeight = ?)" << nNextHeight;
|
||||
|
||||
return true;
|
||||
}
|
||||
for (auto it = takeoverUndo.crbegin(); it != takeoverUndo.crend(); ++it)
|
||||
db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ?, hash = NULL WHERE name = ?"
|
||||
<< it->second.first << it->second.second << it->first;
|
||||
|
||||
bool CClaimTrieCacheBase::finalizeDecrement()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1191,33 +1224,20 @@ static const boost::container::flat_set<std::pair<int, std::string>> ownershipWo
|
|||
{ 646584, "calling-tech-support-scammers-live-3" },
|
||||
};
|
||||
|
||||
int CClaimTrieCacheBase::getNumBlocksOfContinuousOwnership(const std::string& name) const
|
||||
{
|
||||
if (nNextHeight <= 646584 && ownershipWorkaround.find(std::make_pair(nNextHeight, name)) != ownershipWorkaround.end())
|
||||
return 0;
|
||||
|
||||
CClaimValue value;
|
||||
if (getInfoForName(name, value))
|
||||
return nNextHeight - value.nValidAtHeight;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CClaimTrieCacheBase::getDelayForName(const std::string& name) const
|
||||
{
|
||||
int nBlocksOfContinuousOwnership = getNumBlocksOfContinuousOwnership(name);
|
||||
return std::min(nBlocksOfContinuousOwnership / base->nProportionalDelayFactor, 4032);
|
||||
}
|
||||
|
||||
int CClaimTrieCacheBase::getDelayForName(const std::string& name, const uint160& claimId) const
|
||||
{
|
||||
uint160 winningClaimId;
|
||||
int winningTakeoverHeight;
|
||||
if (getLastTakeoverForName(name, winningClaimId, winningTakeoverHeight) && winningClaimId == claimId) {
|
||||
auto found = getLastTakeoverForName(name, winningClaimId, winningTakeoverHeight);
|
||||
if (found && winningClaimId == claimId) {
|
||||
assert(winningTakeoverHeight <= nNextHeight);
|
||||
return 0;
|
||||
}
|
||||
return getDelayForName(name);
|
||||
|
||||
if (nNextHeight <= 646584 && ownershipWorkaround.find(std::make_pair(nNextHeight, name)) != ownershipWorkaround.end())
|
||||
return 0;
|
||||
|
||||
return found ? std::min((nNextHeight - winningTakeoverHeight) / base->nProportionalDelayFactor, 4032) : 0;
|
||||
}
|
||||
|
||||
std::string CClaimTrieCacheBase::adjustNameForValidHeight(const std::string& name, int validHeight) const
|
||||
|
|
|
@ -199,33 +199,6 @@ struct CNameOutPointHeightType
|
|||
}
|
||||
};
|
||||
|
||||
struct CNameOutPointType
|
||||
{
|
||||
std::string name;
|
||||
COutPoint outPoint;
|
||||
|
||||
CNameOutPointType() = default;
|
||||
|
||||
CNameOutPointType(std::string name, const COutPoint& outPoint)
|
||||
: name(std::move(name)), outPoint(outPoint)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator==(const CNameOutPointType& other) const
|
||||
{
|
||||
return name == other.name && outPoint == other.outPoint;
|
||||
}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
||||
{
|
||||
READWRITE(name);
|
||||
READWRITE(outPoint);
|
||||
}
|
||||
};
|
||||
|
||||
struct CClaimNsupports
|
||||
{
|
||||
CClaimNsupports() = default;
|
||||
|
@ -347,9 +320,10 @@ struct CClaimTrieProof
|
|||
template <typename T>
|
||||
using queueEntryType = std::pair<std::string, T>;
|
||||
|
||||
typedef std::vector<queueEntryType<CClaimValue>> claimQueueRowType;
|
||||
typedef std::vector<queueEntryType<CSupportValue>> supportQueueRowType;
|
||||
typedef std::vector<queueEntryType<CClaimValue>> claimUndoType;
|
||||
typedef std::vector<queueEntryType<CSupportValue>> supportUndoType;
|
||||
typedef std::vector<CNameOutPointHeightType> insertUndoType;
|
||||
typedef std::vector<queueEntryType<std::pair<int, uint160>>> takeoverUndoType;
|
||||
|
||||
class CClaimTrieCacheBase
|
||||
{
|
||||
|
@ -370,29 +344,30 @@ public:
|
|||
bool haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
||||
|
||||
bool addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount,
|
||||
int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata);
|
||||
int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||
bool addSupport(const std::string& name, const COutPoint& outPoint, CAmount nAmount,
|
||||
const uint160& supportedClaimId, int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata);
|
||||
const uint160& supportedClaimId, int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||
|
||||
bool removeSupport(const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
bool removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
|
||||
virtual bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo);
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeovers);
|
||||
|
||||
virtual bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo);
|
||||
supportUndoType& expireSupportUndo);
|
||||
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const;
|
||||
virtual bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof);
|
||||
|
||||
virtual int expirationTime() const;
|
||||
|
||||
virtual bool finalizeDecrement();
|
||||
virtual bool finalizeDecrement(takeoverUndoType& takeovers);
|
||||
|
||||
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||
|
@ -412,14 +387,11 @@ protected:
|
|||
bool transacting;
|
||||
// one greater than the height of the chain's tip
|
||||
|
||||
virtual uint256 recursiveComputeMerkleHash(const std::string& name, bool checkOnly);
|
||||
virtual uint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly);
|
||||
supportEntryType getSupportsForName(const std::string& name) const;
|
||||
|
||||
int getDelayForName(const std::string& name) const;
|
||||
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
||||
|
||||
int getNumBlocksOfContinuousOwnership(const std::string& name) const;
|
||||
|
||||
bool deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims);
|
||||
void ensureTreeStructureIsUpToDate();
|
||||
|
||||
|
@ -441,17 +413,18 @@ public:
|
|||
int expirationTime() const override;
|
||||
|
||||
virtual void initializeIncrement();
|
||||
bool finalizeDecrement() override;
|
||||
bool finalizeDecrement(takeoverUndoType& takeovers) override;
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo) override;
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeovers) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo) override;
|
||||
supportUndoType& expireSupportUndo) override;
|
||||
|
||||
private:
|
||||
int nExpirationTime;
|
||||
|
@ -473,17 +446,18 @@ public:
|
|||
std::string normalizeClaimName(const std::string& name, bool force = false) const; // public only for validating name field on update op
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo) override;
|
||||
supportUndoType& expireSupportUndo,
|
||||
takeoverUndoType& takeovers) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo) override;
|
||||
supportUndoType& expireSupportUndo) override;
|
||||
|
||||
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
||||
bool getInfoForName(const std::string& name, CClaimValue& claim) const override;
|
||||
bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const override;
|
||||
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
||||
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
||||
|
||||
|
@ -501,12 +475,12 @@ public:
|
|||
|
||||
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
||||
void initializeIncrement() override;
|
||||
bool finalizeDecrement() override;
|
||||
bool finalizeDecrement(takeoverUndoType& takeovers) override;
|
||||
|
||||
bool allowSupportMetadata() const;
|
||||
|
||||
protected:
|
||||
uint256 recursiveComputeMerkleHash(const std::string& name, bool checkOnly) override;
|
||||
uint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly) override;
|
||||
};
|
||||
|
||||
typedef CClaimTrieCacheHashFork CClaimTrieCache;
|
||||
|
|
|
@ -25,16 +25,17 @@ int CClaimTrieCacheExpirationFork::expirationTime() const
|
|||
return nExpirationTime;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
||||
if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo)) {
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||
{
|
||||
if (CClaimTrieCacheBase::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
|
@ -52,9 +53,9 @@ void CClaimTrieCacheExpirationFork::initializeIncrement()
|
|||
forkForExpirationChange(true);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::finalizeDecrement()
|
||||
bool CClaimTrieCacheExpirationFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
auto ret = CClaimTrieCacheBase::finalizeDecrement();
|
||||
auto ret = CClaimTrieCacheBase::finalizeDecrement(takeoverUndo);
|
||||
if (ret && nNextHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||
forkForExpirationChange(false);
|
||||
return ret;
|
||||
|
@ -152,13 +153,14 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(bool f
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
normalizeAllNamesInTrieIfNecessary(true);
|
||||
return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo);
|
||||
return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||
{
|
||||
auto ret = CClaimTrieCacheExpirationFork::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo);
|
||||
if (ret)
|
||||
|
@ -171,9 +173,9 @@ bool CClaimTrieCacheNormalizationFork::getProofForName(const std::string& name,
|
|||
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), finalClaim, proof);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim) const
|
||||
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim, int offsetHeight) const
|
||||
{
|
||||
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim);
|
||||
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim, offsetHeight);
|
||||
}
|
||||
|
||||
CClaimSupportToName CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
|
||||
|
@ -198,26 +200,27 @@ CClaimTrieCacheHashFork::CClaimTrieCacheHashFork(CClaimTrie* base) : CClaimTrieC
|
|||
static const uint256 leafHash = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
|
||||
static const uint256 emptyHash = uint256S("0000000000000000000000000000000000000000000000000000000000000003");
|
||||
|
||||
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& name, bool checkOnly)
|
||||
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||
{
|
||||
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
|
||||
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(name, checkOnly);
|
||||
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(name, takeoverHeight, checkOnly);
|
||||
|
||||
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ? ORDER BY name" << name;
|
||||
auto childQuery = db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE parent = ? ORDER BY name" << name;
|
||||
|
||||
std::vector<uint256> childHashes;
|
||||
for (auto&& row: childQuery) {
|
||||
std::string key;
|
||||
std::unique_ptr<uint256> hash;
|
||||
row >> key >> hash;
|
||||
int childTakeoverHeight;
|
||||
row >> key >> hash >> childTakeoverHeight;
|
||||
if (hash == nullptr) hash = std::make_unique<uint256>();
|
||||
if (hash->IsNull()) {
|
||||
*hash = recursiveComputeMerkleHash(key, checkOnly);
|
||||
*hash = recursiveComputeMerkleHash(key, childTakeoverHeight, checkOnly);
|
||||
}
|
||||
childHashes.push_back(*hash);
|
||||
}
|
||||
|
||||
auto claimQuery = db << "SELECT c.txID, c.txN, c.validHeight, "
|
||||
auto claimQuery = db << "SELECT c.txID, c.txN, "
|
||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
||||
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount"
|
||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||
|
@ -226,9 +229,8 @@ uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& n
|
|||
std::vector<uint256> claimHashes;
|
||||
for (auto&& row: claimQuery) {
|
||||
COutPoint p;
|
||||
int validHeight;
|
||||
row >> p.hash >> p.n >> validHeight;
|
||||
auto claimHash = getValueHash(p, validHeight);
|
||||
row >> p.hash >> p.n;
|
||||
auto claimHash = getValueHash(p, takeoverHeight);
|
||||
claimHashes.push_back(claimHash);
|
||||
}
|
||||
|
||||
|
@ -310,13 +312,14 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
|||
// cache the parent nodes
|
||||
getMerkleHash();
|
||||
proof = CClaimTrieProof();
|
||||
auto nodeQuery = db << "SELECT name FROM nodes WHERE "
|
||||
auto nodeQuery = db << "SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE "
|
||||
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
||||
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
||||
"ORDER BY LENGTH(name)" << name;
|
||||
for (auto&& row: nodeQuery) {
|
||||
std::string key;;
|
||||
row >> key;
|
||||
int takeoverHeight;
|
||||
row >> key >> takeoverHeight;
|
||||
std::vector<uint256> childHashes;
|
||||
uint32_t nextCurrentIdx = 0;
|
||||
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ?" << key;
|
||||
|
@ -335,7 +338,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
|||
COutPoint finalOutPoint;
|
||||
for (uint32_t i = 0; i < cns.claimsNsupports.size(); ++i) {
|
||||
auto& child = cns.claimsNsupports[i].claim;
|
||||
claimHashes.push_back(getValueHash(child.outPoint, child.nValidAtHeight));
|
||||
claimHashes.push_back(getValueHash(child.outPoint, takeoverHeight));
|
||||
if (child.claimId == finalClaim) {
|
||||
finalClaimIdx = i;
|
||||
finalOutPoint = child.outPoint;
|
||||
|
@ -372,9 +375,9 @@ void CClaimTrieCacheHashFork::initializeIncrement()
|
|||
db << "UPDATE nodes SET hash = NULL";
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheHashFork::finalizeDecrement()
|
||||
bool CClaimTrieCacheHashFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||
{
|
||||
auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement();
|
||||
auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement(takeoverUndo);
|
||||
if (ret && nNextHeight == Params().GetConsensus().nAllClaimsInMerkleForkHeight - 1)
|
||||
db << "UPDATE nodes SET hash = NULL";
|
||||
return ret;
|
||||
|
|
|
@ -56,9 +56,10 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
|
|||
void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
||||
{
|
||||
insertUndoType dummyInsertUndo;
|
||||
claimQueueRowType dummyExpireUndo;
|
||||
claimUndoType dummyExpireUndo;
|
||||
insertUndoType dummyInsertSupportUndo;
|
||||
supportQueueRowType dummyExpireSupportUndo;
|
||||
supportUndoType dummyExpireSupportUndo;
|
||||
takeoverUndoType dummyTakeoverUndo;
|
||||
|
||||
CUpdateCacheCallbacks callbacks = {
|
||||
.findScriptKey = [&pblock](const COutPoint& point) {
|
||||
|
@ -78,7 +79,7 @@ void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
|||
if (!tx->IsCoinBase())
|
||||
UpdateCache(*tx, trieCache, view, nHeight, callbacks);
|
||||
|
||||
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo);
|
||||
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverUndo);
|
||||
}
|
||||
|
||||
BlockAssembler::Options::Options() {
|
||||
|
|
|
@ -384,6 +384,38 @@ BOOST_AUTO_TEST_CASE(support_spend_test)
|
|||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(fixture.is_best_claim("test",tx5));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(claimtrie_update_takeover_test)
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "one", 5);
|
||||
auto cid = ClaimIdHash(tx1.GetHash(), 0);
|
||||
fixture.IncrementBlocks(1);
|
||||
uint160 cid2;
|
||||
int takeover;
|
||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||
CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "a", cid, 4);
|
||||
fixture.IncrementBlocks(1);
|
||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||
CMutableTransaction u2 = fixture.MakeUpdate(u1, "test", "b", cid, 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||
CClaimValue value;
|
||||
BOOST_REQUIRE(fixture.getInfoForName("test", value) && value.nAmount == 3);
|
||||
BOOST_CHECK_EQUAL(cid, cid2);
|
||||
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||
fixture.DecrementBlocks(1);
|
||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||
BOOST_CHECK_EQUAL(cid, cid2);
|
||||
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||
fixture.DecrementBlocks(1);
|
||||
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||
BOOST_CHECK_EQUAL(cid, cid2);
|
||||
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||
}
|
||||
|
||||
/*
|
||||
update
|
||||
update preserves claim id
|
||||
|
@ -447,7 +479,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
|
|||
|
||||
CMutableTransaction tx;
|
||||
tx.nVersion = CTransaction::CURRENT_VERSION;
|
||||
tx.nLockTime = 1U << 31; // Disable BIP68
|
||||
tx.nLockTime = 1U << 31U; // Disable BIP68
|
||||
tx.vin.resize(2);
|
||||
tx.vout.resize(1);
|
||||
tx.vin[0].prevout.hash = tx8.GetHash();
|
||||
|
|
|
@ -26,7 +26,7 @@ public:
|
|||
if (c.IsNull())
|
||||
c = ClaimIdHash(p.hash, p.n);
|
||||
|
||||
return addClaim(key, p, c, value.nAmount, value.nHeight, -1, {});
|
||||
return addClaim(key, p, c, value.nAmount, value.nHeight);
|
||||
}
|
||||
|
||||
bool removeClaimFromTrie(const std::string& key, const COutPoint& outPoint) {
|
||||
|
@ -47,7 +47,7 @@ public:
|
|||
if (p.hash.IsNull())
|
||||
p.hash = Hash(key.begin(), key.end());
|
||||
|
||||
return addSupport(key, p, value.nAmount, value.supportedClaimId, value.nHeight, -1, {});
|
||||
return addSupport(key, p, value.nAmount, value.supportedClaimId, value.nHeight);
|
||||
}
|
||||
|
||||
bool removeSupportFromMap(const std::string& key, const COutPoint& outPoint) {
|
||||
|
@ -337,8 +337,8 @@ BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
|||
CClaimTrie trie(false, 0, 1);
|
||||
CClaimTrieCacheTest cache(&trie);
|
||||
|
||||
insertUndoType icu, isu; claimQueueRowType ecu; supportQueueRowType esu;
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
||||
insertUndoType icu, isu; claimUndoType ecu; supportUndoType esu; takeoverUndoType tut;
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||
|
||||
CClaimValue value;
|
||||
value.nHeight = 1;
|
||||
|
@ -351,9 +351,9 @@ BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
|||
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
||||
BOOST_CHECK(cache.insertSupportIntoMap("aa", CSupportValue()));
|
||||
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||
BOOST_CHECK(cache.flush());
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||
|
||||
CSupportValue temp;
|
||||
CClaimValue cv;
|
||||
|
@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
|||
BOOST_CHECK(cache.insertClaimIntoTrie("bb", value));
|
||||
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
||||
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||
|
||||
BOOST_CHECK(cache.getInfoForName("aa", cv));
|
||||
BOOST_CHECK_EQUAL(3, cv.nValidAtHeight);
|
||||
|
|
|
@ -189,7 +189,7 @@ void ClaimTrieChainFixture::CommitTx(const CMutableTransaction &tx, bool has_loc
|
|||
CValidationState state;
|
||||
CAmount txFeeRate = CAmount(0);
|
||||
LOCK(cs_main);
|
||||
BOOST_CHECK_EQUAL(AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr, nullptr, false, txFeeRate, false), true);
|
||||
BOOST_REQUIRE(AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr, nullptr, false, txFeeRate, false));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,10 +272,10 @@ void ClaimTrieChainFixture::IncrementBlocks(int num_blocks, bool mark)
|
|||
CScript coinbase_scriptpubkey;
|
||||
coinbase_scriptpubkey << CScriptNum(chainActive.Height());
|
||||
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest().CreateNewBlock(coinbase_scriptpubkey);
|
||||
BOOST_CHECK(pblocktemplate != nullptr);
|
||||
BOOST_REQUIRE(pblocktemplate != nullptr);
|
||||
if (!added_unchecked)
|
||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), num_txs_for_next_block + 1);
|
||||
BOOST_CHECK_EQUAL(CreateBlock(pblocktemplate), true);
|
||||
BOOST_REQUIRE(CreateBlock(pblocktemplate));
|
||||
num_txs_for_next_block = 0;
|
||||
nNextHeight = chainActive.Height() + 1;
|
||||
}
|
||||
|
|
|
@ -221,13 +221,14 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
|
|||
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), name_upper, amelieValidHeight));
|
||||
|
||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||
BOOST_CHECK(trieCache.addClaim(name, COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), CAmount(2), currentHeight + 1, -1, {}));
|
||||
BOOST_CHECK(trieCache.addClaim(name, COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), CAmount(2), currentHeight + 1));
|
||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||
insertUndoType insertUndo;
|
||||
claimQueueRowType expireUndo;
|
||||
claimUndoType expireUndo;
|
||||
insertUndoType insertSupportUndo;
|
||||
supportQueueRowType expireSupportUndo;
|
||||
BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
||||
supportUndoType expireSupportUndo;
|
||||
takeoverUndoType takeoverUndo;
|
||||
BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo));
|
||||
BOOST_CHECK(trieCache.shouldNormalize());
|
||||
}
|
||||
|
||||
|
@ -304,22 +305,23 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
|||
|
||||
CClaimTrieCache cache(pclaimTrie);
|
||||
int height = chainActive.Height() + 1;
|
||||
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height, -1, {});
|
||||
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height, -1, {});
|
||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height, -1, {});
|
||||
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), 1, ClaimIdHash(tx1.GetHash(), 0), height, -1, {});
|
||||
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), 1, ClaimIdHash(tx2.GetHash(), 0), height, -1, {});
|
||||
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height);
|
||||
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height);
|
||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height);
|
||||
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), 1, ClaimIdHash(tx1.GetHash(), 0), height);
|
||||
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), 1, ClaimIdHash(tx2.GetHash(), 0), height);
|
||||
insertUndoType insertUndo;
|
||||
claimQueueRowType expireUndo;
|
||||
claimUndoType expireUndo;
|
||||
insertUndoType insertSupportUndo;
|
||||
supportQueueRowType expireSupportUndo;
|
||||
BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
||||
supportUndoType expireSupportUndo;
|
||||
takeoverUndoType takeoverUndo;
|
||||
BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo));
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 3U);
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[0].supports.size() == 1U);
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[1].supports.size() == 0U);
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[2].supports.size() == 1U);
|
||||
BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
||||
BOOST_CHECK(cache.finalizeDecrement());
|
||||
BOOST_CHECK(cache.finalizeDecrement(takeoverUndo));
|
||||
std::string unused;
|
||||
BOOST_CHECK(cache.removeSupport(COutPoint(sx1.GetHash(), 0), unused, height));
|
||||
BOOST_CHECK(cache.removeSupport(COutPoint(sx2.GetHash(), 0), unused, height));
|
||||
|
|
|
@ -75,9 +75,10 @@ class CBlockUndo
|
|||
public:
|
||||
std::vector<CTxUndo> vtxundo; // for all but the coinbase
|
||||
insertUndoType insertUndo; // any claims that went from the queue to the trie
|
||||
claimQueueRowType expireUndo; // any claims that expired
|
||||
claimUndoType expireUndo; // any claims that expired
|
||||
insertUndoType insertSupportUndo; // any supports that went from the support queue to the support map
|
||||
supportQueueRowType expireSupportUndo; // any supports that expired
|
||||
supportUndoType expireSupportUndo; // any supports that expired
|
||||
takeoverUndoType takeoverUndo;
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
@ -88,6 +89,7 @@ public:
|
|||
READWRITE(expireUndo);
|
||||
READWRITE(insertSupportUndo);
|
||||
READWRITE(expireSupportUndo);
|
||||
READWRITE(takeoverUndo);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1554,7 +1554,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
|
|||
|
||||
// move best block pointer to prevout block
|
||||
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
||||
assert(trieCache.finalizeDecrement());
|
||||
assert(trieCache.finalizeDecrement(blockUndo.takeoverUndo));
|
||||
auto merkleHash = trieCache.getMerkleHash();
|
||||
if (merkleHash != pindex->pprev->hashClaimTrie) {
|
||||
LogPrintf("Hash comparison failure at block %d\n", pindex->nHeight);
|
||||
|
@ -2028,7 +2028,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
}
|
||||
|
||||
// TODO: if the "just check" flag is set, we should reduce the work done here. Incrementing blocks twice per mine is not efficient.
|
||||
const auto incremented = trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, blockundo.insertSupportUndo, blockundo.expireSupportUndo);
|
||||
const auto incremented = trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo,
|
||||
blockundo.insertSupportUndo, blockundo.expireSupportUndo, blockundo.takeoverUndo);
|
||||
assert(incremented);
|
||||
|
||||
if (trieCache.getMerkleHash() != block.hashClaimTrie)
|
||||
|
|
Loading…
Reference in a new issue