From 50d78cfdba916b335118bf0778a2a3eb4073de27 Mon Sep 17 00:00:00 2001 From: Jimmy Kiselak Date: Sat, 5 Dec 2015 21:55:23 -0500 Subject: [PATCH] implement the proportional auction delay --- src/claimtrie.cpp | 390 +++++++++++++++++++++++++++++------ src/claimtrie.h | 113 ++++------ src/main.cpp | 4 +- src/miner.cpp | 3 +- src/test/claimtrie_tests.cpp | 24 +-- src/test/test_bitcoin.cpp | 2 +- src/undo.h | 2 + 7 files changed, 382 insertions(+), 156 deletions(-) diff --git a/src/claimtrie.cpp b/src/claimtrie.cpp index c3cb9aeeb..34b55798a 100644 --- a/src/claimtrie.cpp +++ b/src/claimtrie.cpp @@ -6,6 +6,21 @@ #include #include +std::vector heightToVch(int n) +{ + std::vector vchHeight; + vchHeight.resize(8); + vchHeight[0] = 0; + vchHeight[1] = 0; + vchHeight[2] = 0; + vchHeight[3] = 0; + vchHeight[4] = n >> 24; + vchHeight[5] = n >> 16; + vchHeight[6] = n >> 8; + vchHeight[7] = n; + return vchHeight; +} + uint256 CClaimValue::GetHash() const { CHash256 txHasher; @@ -396,31 +411,50 @@ std::vector CClaimTrie::flattenTrie() const return nodes; } -bool CClaimTrie::getInfoForName(const std::string& name, CClaimValue& claim) const +const CClaimTrieNode* CClaimTrie::getNodeForName(const std::string& name) const { const CClaimTrieNode* current = &root; for (std::string::const_iterator itname = name.begin(); itname != name.end(); ++itname) { nodeMapType::const_iterator itchildren = current->children.find(*itname); if (itchildren == current->children.end()) - return false; + return NULL; current = itchildren->second; } - return current->getBestClaim(claim); + return current; } -bool CClaimTrie::checkConsistency() +bool CClaimTrie::getInfoForName(const std::string& name, CClaimValue& claim) const +{ + const CClaimTrieNode* current = getNodeForName(name); + if (current) + return current->getBestClaim(claim); + return false; +} + +bool CClaimTrie::getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const +{ + const CClaimTrieNode* current = getNodeForName(name); + if (current) + { + lastTakeoverHeight = current->nHeightOfLastTakeover; + return true; + } + return false; +} + +bool CClaimTrie::checkConsistency() const { if (empty()) return true; return recursiveCheckConsistency(&root); } -bool CClaimTrie::recursiveCheckConsistency(CClaimTrieNode* node) +bool CClaimTrie::recursiveCheckConsistency(const CClaimTrieNode* node) const { std::vector vchToHash; - for (nodeMapType::iterator it = node->children.begin(); it != node->children.end(); ++it) + for (nodeMapType::const_iterator it = node->children.begin(); it != node->children.end(); ++it) { if (recursiveCheckConsistency(it->second)) { @@ -438,6 +472,8 @@ bool CClaimTrie::recursiveCheckConsistency(CClaimTrieNode* node) { uint256 claimHash = claim.GetHash(); vchToHash.insert(vchToHash.end(), claimHash.begin(), claimHash.end()); + std::vector heightToHash = heightToVch(node->nHeightOfLastTakeover); + vchToHash.insert(vchToHash.end(), heightToHash.begin(), heightToHash.end()); } CHash256 hasher; @@ -598,19 +634,21 @@ bool CClaimTrie::getSupportQueueNameRow(const std::string& name, std::vector& takeoverHeights, const uint256& hashBlockIn, claimQueueType& queueCache, claimQueueNamesType& queueNameCache, claimQueueType& expirationQueueCache, int nNewHeight, supportMapType& supportCache, supportQueueType& supportQueueCache, supportQueueNamesType& supportQueueNameCache) { - bool success = true; for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache) { - success = updateName(itcache->first, itcache->second); - if (!success) + if (!updateName(itcache->first, itcache->second)) return false; } for (hashMapType::iterator ithash = hashes.begin(); ithash != hashes.end(); ++ithash) { - success = updateHash(ithash->first, ithash->second); - if (!success) + if (!updateHash(ithash->first, ithash->second)) + return false; + } + for (std::map::iterator itheight = takeoverHeights.begin(); itheight != takeoverHeights.end(); ++itheight) + { + if (!updateTakeoverHeight(itheight->first, itheight->second)) return false; } for (claimQueueType::iterator itQueueCacheRow = queueCache.begin(); itQueueCacheRow != queueCache.end(); ++itQueueCacheRow) @@ -728,6 +766,22 @@ bool CClaimTrie::updateHash(const std::string& name, uint256& hash) return true; } +bool CClaimTrie::updateTakeoverHeight(const std::string& name, int nTakeoverHeight) +{ + CClaimTrieNode* current = &root; + for (std::string::const_iterator itname = name.begin(); itname != name.end(); ++itname) + { + nodeMapType::iterator itchild = current->children.find(*itname); + if (itchild == current->children.end()) + return false; + current = itchild->second; + } + assert(current != NULL); + current->nHeightOfLastTakeover = nTakeoverHeight; + markNodeDirty(name, current); + return true; +} + void CClaimTrie::BatchWriteNode(CLevelDBBatch& batch, const std::string& name, const CClaimTrieNode* pNode) const { uint32_t num_claims = 0; @@ -962,6 +1016,10 @@ bool CClaimTrieCache::recursiveComputeMerkleHash(CClaimTrieNode* tnCurrent, std: { uint256 claimHash = claim.GetHash(); vchToHash.insert(vchToHash.end(), claimHash.begin(), claimHash.end()); + int nHeightOfLastTakeover; + assert(getLastTakeoverForName(sPos, nHeightOfLastTakeover)); + std::vector heightToHash = heightToVch(nHeightOfLastTakeover); + vchToHash.insert(vchToHash.end(), heightToHash.begin(), heightToHash.end()); } CHash256 hasher; @@ -1002,7 +1060,7 @@ bool CClaimTrieCache::empty() const return base->empty() && cache.empty(); } -bool CClaimTrieCache::insertClaimIntoTrie(const std::string name, CClaimValue claim) const +bool CClaimTrieCache::insertClaimIntoTrie(const std::string name, CClaimValue claim, bool fCheckTakeover) const { assert(base); CClaimTrieNode* currentNode = &(base->root); @@ -1092,11 +1150,13 @@ bool CClaimTrieCache::insertClaimIntoTrie(const std::string name, CClaimValue cl dirtyHashes.insert(sub); } dirtyHashes.insert(name); + if (fCheckTakeover) + namesToCheckForTakeover.insert(name); } return true; } -bool CClaimTrieCache::removeClaimFromTrie(const std::string name, uint256 txhash, uint32_t nOut, int& nValidAtHeight) const +bool CClaimTrieCache::removeClaimFromTrie(const std::string name, uint256 txhash, uint32_t nOut, int& nValidAtHeight, bool fCheckTakeover) const { assert(base); CClaimTrieNode* currentNode = &(base->root); @@ -1176,6 +1236,8 @@ bool CClaimTrieCache::removeClaimFromTrie(const std::string name, uint256 txhash dirtyHashes.insert(sub); } dirtyHashes.insert(name); + if (fCheckTakeover) + namesToCheckForTakeover.insert(name); } CClaimTrieNode* rootNode = &(base->root); cachedNode = cache.find(""); @@ -1302,20 +1364,22 @@ bool CClaimTrieCache::addClaim(const std::string name, uint256 txhash, uint32_t { LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, nHeight, nCurrentHeight); assert(nHeight == nCurrentHeight); - return addClaimToQueues(name, txhash, nOut, nAmount, nHeight, nHeight + getDelayForName(name)); + CClaimValue claim(txhash, nOut, nAmount, nHeight, nHeight + getDelayForName(name)); + return addClaimToQueues(name, claim); } bool CClaimTrieCache::addClaim(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, uint256 prevTxhash, uint32_t nPrevOut) const { LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, nHeight, nCurrentHeight); assert(nHeight == nCurrentHeight); - CClaimValue claim; - if (base->getInfoForName(name, claim)) + CClaimValue currentClaim; + if (base->getInfoForName(name, currentClaim)) { - if (claim.txhash == prevTxhash && claim.nOut == nPrevOut) + if (currentClaim.txhash == prevTxhash && currentClaim.nOut == nPrevOut) { LogPrintf("%s: This is an update to a best claim. Previous claim txhash: %s, nOut: %d\n", __func__, prevTxhash.GetHex(), nPrevOut); - return addClaimToQueues(name, txhash, nOut, nAmount, nHeight, nHeight); + CClaimValue newClaim(txhash, nOut, nAmount, nHeight, nHeight, prevTxhash, nPrevOut); + return addClaimToQueues(name, newClaim); } } return addClaim(name, txhash, nOut, nAmount, nHeight); @@ -1324,25 +1388,24 @@ bool CClaimTrieCache::addClaim(const std::string name, uint256 txhash, uint32_t bool CClaimTrieCache::undoSpendClaim(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, int nValidAtHeight) const { LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, nHeight: %d, nValidAtHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, nHeight, nValidAtHeight, nCurrentHeight); + CClaimValue claim(txhash, nOut, nAmount, nHeight, nValidAtHeight); if (nValidAtHeight < nCurrentHeight) { - CClaimValue claim(txhash, nOut, nAmount, nHeight, nValidAtHeight); claimQueueEntryType entry(name, claim); addToExpirationQueue(entry); - return insertClaimIntoTrie(name, claim); + return insertClaimIntoTrie(name, claim, false); } else { - return addClaimToQueues(name, txhash, nOut, nAmount, nHeight, nValidAtHeight); + return addClaimToQueues(name, claim); } } -bool CClaimTrieCache::addClaimToQueues(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, int nValidAtHeight) const +bool CClaimTrieCache::addClaimToQueues(const std::string name, CClaimValue& claim) const { - LogPrintf("%s: nValidAtHeight: %d\n", __func__, nValidAtHeight); - CClaimValue claim(txhash, nOut, nAmount, nHeight, nValidAtHeight); + LogPrintf("%s: nValidAtHeight: %d\n", __func__, claim.nValidAtHeight); claimQueueEntryType entry(name, claim); - claimQueueType::iterator itQueueRow = getQueueCacheRow(nValidAtHeight, true); + claimQueueType::iterator itQueueRow = getQueueCacheRow(claim.nValidAtHeight, true); claimQueueNamesType::iterator itQueueNameRow = getQueueCacheNameRow(name, true); itQueueRow->second.push_back(entry); itQueueNameRow->second.push_back(claim); @@ -1395,21 +1458,21 @@ bool CClaimTrieCache::removeClaimFromQueue(const std::string name, uint256 txhas bool CClaimTrieCache::undoAddClaim(const std::string name, uint256 txhash, uint32_t nOut, int nHeight) const { int throwaway; - return removeClaim(name, txhash, nOut, nHeight, throwaway); + return removeClaim(name, txhash, nOut, nHeight, throwaway, false); } bool CClaimTrieCache::spendClaim(const std::string name, uint256 txhash, uint32_t nOut, int nHeight, int& nValidAtHeight) const { - return removeClaim(name, txhash, nOut, nHeight, nValidAtHeight); + return removeClaim(name, txhash, nOut, nHeight, nValidAtHeight, true); } -bool CClaimTrieCache::removeClaim(const std::string name, uint256 txhash, uint32_t nOut, int nHeight, int& nValidAtHeight) const +bool CClaimTrieCache::removeClaim(const std::string name, uint256 txhash, uint32_t nOut, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const { LogPrintf("%s: name: %s, txhash: %s, nOut: %s, nHeight: %s, nCurrentHeight: %s\n", __func__, name, txhash.GetHex(), nOut, nHeight, nCurrentHeight); bool removed = false; if (removeClaimFromQueue(name, txhash, nOut, nValidAtHeight)) removed = true; - if (removed == false && removeClaimFromTrie(name, txhash, nOut, nValidAtHeight)) + if (removed == false && removeClaimFromTrie(name, txhash, nOut, nValidAtHeight, fCheckTakeover)) removed = true; if (removed == true) removeFromExpirationQueue(name, txhash, nOut, nHeight); @@ -1464,7 +1527,7 @@ claimQueueType::iterator CClaimTrieCache::getExpirationQueueCacheRow(int nHeight return itQueueRow; } -bool CClaimTrieCache::reorderTrieNode(const std::string name) const +bool CClaimTrieCache::reorderTrieNode(const std::string name, bool fCheckTakeover) const { assert(base); nodeCacheType::iterator cachedNode; @@ -1521,6 +1584,8 @@ bool CClaimTrieCache::reorderTrieNode(const std::string name) const dirtyHashes.insert(sub); } dirtyHashes.insert(name); + if (fCheckTakeover) + namesToCheckForTakeover.insert(name); } return true; } @@ -1540,7 +1605,7 @@ bool CClaimTrieCache::getSupportsForName(const std::string name, supportMapEntry } } -bool CClaimTrieCache::insertSupportIntoMap(const std::string name, CSupportValue support) const +bool CClaimTrieCache::insertSupportIntoMap(const std::string name, CSupportValue support, bool fCheckTakeover) const { supportMapType::iterator cachedNode; // If this node is already in the cache, use that @@ -1557,10 +1622,10 @@ bool CClaimTrieCache::insertSupportIntoMap(const std::string name, CSupportValue } cachedNode->second.push_back(support); // See if this changed the biggest bid - return reorderTrieNode(name); + return reorderTrieNode(name, fCheckTakeover); } -bool CClaimTrieCache::removeSupportFromMap(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int& nValidAtHeight) const +bool CClaimTrieCache::removeSupportFromMap(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const { supportMapType::iterator cachedNode; cachedNode = supportCache.find(name); @@ -1589,7 +1654,7 @@ bool CClaimTrieCache::removeSupportFromMap(const std::string name, uint256 txhas if (itSupport != cachedNode->second.end()) { cachedNode->second.erase(itSupport); - return reorderTrieNode(name); + return reorderTrieNode(name, fCheckTakeover); } else { @@ -1715,7 +1780,7 @@ bool CClaimTrieCache::undoSpendSupport(const std::string name, uint256 txhash, u { CSupportValue support(txhash, nOut, supportedTxhash, supportednOut, nAmount, nHeight, nValidAtHeight); supportQueueEntryType entry(name, support); - return insertSupportIntoMap(name, support); + return insertSupportIntoMap(name, support, false); } else { @@ -1723,12 +1788,12 @@ bool CClaimTrieCache::undoSpendSupport(const std::string name, uint256 txhash, u } } -bool CClaimTrieCache::removeSupport(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int& nValidAtHeight) const +bool CClaimTrieCache::removeSupport(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const { bool removed = false; if (removeSupportFromQueue(name, txhash, nOut, supportedTxhash, supportednOut, nValidAtHeight)) removed = true; - if (removed == false && removeSupportFromMap(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, nValidAtHeight)) + if (removed == false && removeSupportFromMap(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, nValidAtHeight, fCheckTakeover)) removed = true; return removed; } @@ -1737,16 +1802,16 @@ bool CClaimTrieCache::undoAddSupport(const std::string name, uint256 txhash, uin { LogPrintf("%s: name: %s, txhash: %s, nOut: %d, supportedTxhash: %s, supportednOut: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, supportedTxhash.GetHex(), supportednOut, nHeight, nCurrentHeight); int throwaway; - return removeSupport(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, throwaway); + return removeSupport(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, throwaway, false); } bool CClaimTrieCache::spendSupport(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int& nValidAtHeight) const { LogPrintf("%s: name: %s, txhash: %s, nOut: %d, supportedTxhash: %s, supportednOut: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, supportedTxhash.GetHex(), supportednOut, nHeight, nCurrentHeight); - return removeSupport(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, nValidAtHeight); + return removeSupport(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, nValidAtHeight, true); } -bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo) const +bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo, std::vector >& takeoverHeightUndo) const { LogPrintf("%s: nCurrentHeight (before increment): %d\n", __func__, nCurrentHeight); claimQueueType::iterator itQueueRow = getQueueCacheRow(nCurrentHeight, false); @@ -1784,7 +1849,7 @@ bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRo LogPrintf("No claims found for that name\n"); } } - insertClaimIntoTrie(itEntry->first, itEntry->second); + insertClaimIntoTrie(itEntry->first, itEntry->second, true); insertUndo.push_back(*itEntry); } itQueueRow->second.clear(); @@ -1795,7 +1860,7 @@ bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRo for (claimQueueRowType::iterator itEntry = itExpirationRow->second.begin(); itEntry != itExpirationRow->second.end(); ++itEntry) { int nValidAtHeight; - assert(removeClaimFromTrie(itEntry->first, itEntry->second.txhash, itEntry->second.nOut, nValidAtHeight)); + assert(removeClaimFromTrie(itEntry->first, itEntry->second.txhash, itEntry->second.nOut, nValidAtHeight, true)); expireUndo.push_back(*itEntry); } itExpirationRow->second.clear(); @@ -1835,54 +1900,230 @@ bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRo LogPrintf("No support found for that name\n"); } } - insertSupportIntoMap(itSupport->first, itSupport->second); + insertSupportIntoMap(itSupport->first, itSupport->second, true); insertSupportUndo.push_back(*itSupport); } itSupportRow->second.clear(); } + // check each potentially taken over name to see if a takeover occurred. + // if it did, then check the claim and support insertion queues for + // the names that have been taken over, immediately insert all claim and + // supports for those names, and stick them in the insertUndo or + // insertSupportUndo vectors, with the nValidAtHeight they had prior to + // this block + // Run through all names that have been taken over + for (std::set::iterator itNamesToCheck = namesToCheckForTakeover.begin(); itNamesToCheck != namesToCheckForTakeover.end(); ++itNamesToCheck) + { + // Check if a takeover has occurred + nodeCacheType::iterator itCachedNode = cache.find(*itNamesToCheck); + // many possibilities + // if this node is new, don't put it into the undo -- there will be nothing to restore, after all + // if all of this node's claims were deleted, it should be put into the undo -- there could be + // claims in the queue for that name and the takeover height should be the current height + // if the node is not in the cache, or getbestclaim fails, that means all of its claims were + // deleted + // if base->getInfoForName returns false, that means it's new and shouldn't go into the undo + // if both exist, and the current best claim is not the same as or the parent to the new best + // claim, then ownership has changed and the current height of last takeover should go into + // the queue + CClaimValue claimInCache; + CClaimValue claimInTrie; + bool haveClaimInCache; + bool haveClaimInTrie; + if (itCachedNode == cache.end()) + { + haveClaimInCache = false; + } + else + { + haveClaimInCache = itCachedNode->second->getBestClaim(claimInCache); + } + haveClaimInTrie = base->getInfoForName(*itNamesToCheck, claimInTrie); + bool takeoverHappened = false; + if (!haveClaimInTrie) + { + takeoverHappened = true; + } + else if (!haveClaimInCache) + { + takeoverHappened = true; + } + else if (claimInCache != claimInTrie) + { + if (!claimInCache.fIsUpdate || claimInCache.updateToTxhash != claimInTrie.txhash || claimInCache.updateToNOut != claimInTrie.nOut) + { + takeoverHappened = true; + } + } + if (takeoverHappened && !base->fConstantDelay) + { + // Get all claims in the queue for that name + claimQueueNamesType::iterator itQueueNameRow = getQueueCacheNameRow(*itNamesToCheck, false); + if (itQueueNameRow != claimQueueNameCache.end()) + { + for (std::vector::iterator itQueueName = itQueueNameRow->second.begin(); itQueueName != itQueueNameRow->second.end(); ++itQueueName) + { + // Pull those claims out of the height-based queue + claimQueueType::iterator itQueueRow = getQueueCacheRow(itQueueName->nValidAtHeight, false); + if (itQueueRow != claimQueueCache.end()) + { + claimQueueRowType::iterator itQueue; + for (itQueue = itQueueRow->second.begin(); itQueue != itQueueRow->second.end(); ++itQueue) + { + if (*itNamesToCheck == itQueue->first && itQueue->second == *itQueueName) + { + break; + } + } + if (itQueue != itQueueRow->second.end()) + { + // Insert them into the queue undo with their previous nValidAtHeight + insertUndo.push_back(*itQueue); + // Insert them into the name trie with the new nValidAtHeight + itQueue->second.nValidAtHeight = nCurrentHeight; + insertClaimIntoTrie(itQueue->first, itQueue->second, false); + // Delete them from the height-based queue + itQueueRow->second.erase(itQueue); + } + else + { + // here be problems + } + } + else + { + // here be problems + } + } + // remove all claims from the queue for that name + itQueueNameRow->second.clear(); + } + // + // Then, get all supports in the queue for that name + supportQueueNamesType::iterator itSupportQueueNameRow = getSupportQueueCacheNameRow(*itNamesToCheck, false); + if (itSupportQueueNameRow != supportQueueNameCache.end()) + { + for (std::vector::iterator itSupportQueueName = itSupportQueueNameRow->second.begin(); itSupportQueueName != itSupportQueueNameRow->second.end(); ++itSupportQueueName) + { + // Pull those supports out of the height-based queue + supportQueueType::iterator itSupportQueueRow = getSupportQueueCacheRow(itSupportQueueName->nValidAtHeight, false); + if (itSupportQueueRow != supportQueueCache.end()) + { + supportQueueRowType::iterator itSupportQueue; + for (itSupportQueue = itSupportQueueRow->second.begin(); itSupportQueue != itSupportQueueRow->second.end(); ++itSupportQueue) + { + if (*itNamesToCheck == itSupportQueue->first && itSupportQueue->second == *itSupportQueueName) + { + break; + } + } + if (itSupportQueue != itSupportQueueRow->second.end()) + { + // Insert them into the support queue undo with the previous nValidAtHeight + insertSupportUndo.push_back(*itSupportQueue); + // Insert them into the support map with the new nValidAtHeight + itSupportQueue->second.nValidAtHeight = nCurrentHeight; + insertSupportIntoMap(itSupportQueue->first, itSupportQueue->second, false); + // Delete them from the height-based queue + itSupportQueueRow->second.erase(itSupportQueue); + } + else + { + // here be problems + } + } + else + { + // here be problems + } + } + // remove all supports from the queue for that name + itSupportQueueNameRow->second.clear(); + } + } + if (takeoverHappened) + { + // save the old last height so that it can be restored if the block is undone + if (haveClaimInTrie) + { + int nHeightOfLastTakeover; + assert(getLastTakeoverForName(*itNamesToCheck, nHeightOfLastTakeover)); + takeoverHeightUndo.push_back(std::make_pair(*itNamesToCheck, nHeightOfLastTakeover)); + } + itCachedNode = cache.find(*itNamesToCheck); + if (itCachedNode != cache.end()) + { + cacheTakeoverHeights[*itNamesToCheck] = nCurrentHeight; + } + } + } + namesToCheckForTakeover.clear(); nCurrentHeight++; return true; } -bool CClaimTrieCache::decrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo) const +bool CClaimTrieCache::decrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo, std::vector >& takeoverHeightUndo) const { LogPrintf("%s: nCurrentHeight (before decrement): %d\n", __func__, nCurrentHeight); nCurrentHeight--; - if (insertUndo.begin() != insertUndo.end()) + for (claimQueueRowType::iterator itInsertUndo = insertUndo.begin(); itInsertUndo != insertUndo.end(); ++itInsertUndo) { - claimQueueType::iterator itQueueRow = getQueueCacheRow(nCurrentHeight, true); - for (claimQueueRowType::iterator itInsertUndo = insertUndo.begin(); itInsertUndo != insertUndo.end(); ++itInsertUndo) - { - int nValidHeightInTrie; - assert(removeClaimFromTrie(itInsertUndo->first, itInsertUndo->second.txhash, itInsertUndo->second.nOut, nValidHeightInTrie)); - assert(nValidHeightInTrie == itInsertUndo->second.nValidAtHeight); - claimQueueNamesType::iterator itQueueNameRow = getQueueCacheNameRow(itInsertUndo->first, true); - itQueueRow->second.push_back(*itInsertUndo); - itQueueNameRow->second.push_back(itInsertUndo->second); - } + claimQueueType::iterator itQueueRow = getQueueCacheRow(itInsertUndo->second.nValidAtHeight, true); + int nValidHeightInTrie; + assert(removeClaimFromTrie(itInsertUndo->first, itInsertUndo->second.txhash, itInsertUndo->second.nOut, nValidHeightInTrie, false)); + claimQueueNamesType::iterator itQueueNameRow = getQueueCacheNameRow(itInsertUndo->first, true); + itQueueRow->second.push_back(*itInsertUndo); + itQueueNameRow->second.push_back(itInsertUndo->second); } if (expireUndo.begin() != expireUndo.end()) { claimQueueType::iterator itExpireRow = getExpirationQueueCacheRow(nCurrentHeight, true); for (claimQueueRowType::iterator itExpireUndo = expireUndo.begin(); itExpireUndo != expireUndo.end(); ++itExpireUndo) { - insertClaimIntoTrie(itExpireUndo->first, itExpireUndo->second); + insertClaimIntoTrie(itExpireUndo->first, itExpireUndo->second, false); itExpireRow->second.push_back(*itExpireUndo); } } - if (insertSupportUndo.begin() != insertSupportUndo.end()) + for (supportQueueRowType::iterator itSupportUndo = insertSupportUndo.begin(); itSupportUndo != insertSupportUndo.end(); ++itSupportUndo) { - supportQueueType::iterator itSupportRow = getSupportQueueCacheRow(nCurrentHeight, true); - for (supportQueueRowType::iterator itSupportUndo = insertSupportUndo.begin(); itSupportUndo != insertSupportUndo.end(); ++itSupportUndo) + supportQueueType::iterator itSupportRow = getSupportQueueCacheRow(itSupportUndo->second.nValidAtHeight, true); + int nValidHeightInMap; + assert(removeSupportFromMap(itSupportUndo->first, itSupportUndo->second.txhash, itSupportUndo->second.nOut, itSupportUndo->second.supportTxhash, itSupportUndo->second.supportnOut, itSupportUndo->second.nHeight, nValidHeightInMap, false)); + supportQueueNamesType::iterator itSupportNameRow = getSupportQueueCacheNameRow(itSupportUndo->first, true); + itSupportRow->second.push_back(*itSupportUndo); + itSupportNameRow->second.push_back(itSupportUndo->second); + } + + for (std::vector >::iterator itTakeoverHeightUndo = takeoverHeightUndo.begin(); itTakeoverHeightUndo != takeoverHeightUndo.end(); ++itTakeoverHeightUndo) + { + cacheTakeoverHeights[itTakeoverHeightUndo->first] = itTakeoverHeightUndo->second; + } + return true; +} + +bool CClaimTrieCache::getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const +{ + std::map::iterator itHeights = cacheTakeoverHeights.find(name); + if (itHeights == cacheTakeoverHeights.end()) + { + if (base->getLastTakeoverForName(name, lastTakeoverHeight)) { - int nValidHeightInMap; - assert(removeSupportFromMap(itSupportUndo->first, itSupportUndo->second.txhash, itSupportUndo->second.nOut, itSupportUndo->second.supportTxhash, itSupportUndo->second.supportnOut, itSupportUndo->second.nHeight, nValidHeightInMap)); - assert(nValidHeightInMap == itSupportUndo->second.nValidAtHeight); - supportQueueNamesType::iterator itSupportNameRow = getSupportQueueCacheNameRow(itSupportUndo->first, true); - itSupportRow->second.push_back(*itSupportUndo); - itSupportNameRow->second.push_back(itSupportUndo->second); + return true; + } + else + { + if (fRequireTakeoverHeights) + { + return false; + } + else + { + lastTakeoverHeight = 0; + return true; + } } } + lastTakeoverHeight = itHeights->second; return true; } @@ -1892,7 +2133,18 @@ int CClaimTrieCache::getDelayForName(const std::string name) const { return base->nConstantDelayHeight; } - return 0; + else + { + int nHeightOfLastTakeover; + if (getLastTakeoverForName(name, nHeightOfLastTakeover)) + { + return nHeightOfLastTakeover >> base->nProportionalDelayBits; + } + else + { + return 0; + } + } } uint256 CClaimTrieCache::getBestBlock() @@ -1923,6 +2175,8 @@ bool CClaimTrieCache::clear() const supportCache.clear(); supportQueueCache.clear(); supportQueueNameCache.clear(); + namesToCheckForTakeover.clear(); + cacheTakeoverHeights.clear(); return true; } @@ -1930,7 +2184,7 @@ bool CClaimTrieCache::flush() { if (dirty()) getMerkleHash(); - bool success = base->update(cache, cacheHashes, getBestBlock(), claimQueueCache, claimQueueNameCache, expirationQueueCache, nCurrentHeight, supportCache, supportQueueCache, supportQueueNameCache); + bool success = base->update(cache, cacheHashes, cacheTakeoverHeights, getBestBlock(), claimQueueCache, claimQueueNameCache, expirationQueueCache, nCurrentHeight, supportCache, supportQueueCache, supportQueueNameCache); if (success) { success = clear(); diff --git a/src/claimtrie.h b/src/claimtrie.h index b6355c729..ec89b264b 100644 --- a/src/claimtrie.h +++ b/src/claimtrie.h @@ -56,57 +56,8 @@ public: {} uint256 GetHash() const; - - unsigned int GetSerializeSize(int nType, int nVersion) const - { - unsigned int nSize = 0; - nSize += ::GetSerializeSize(txhash, nType, nVersion); - nSize += ::GetSerializeSize(nOut, nType, nVersion); - nSize += ::GetSerializeSize(nAmount, nType, nVersion); - nSize += ::GetSerializeSize(nHeight, nType, nVersion); - nSize += ::GetSerializeSize(nValidAtHeight, nType, nVersion); - nSize += ::GetSerializeSize(fIsUpdate, nType, nVersion); - if (fIsUpdate) - { - nSize += ::GetSerializeSize(updateToTxhash, nType, nVersion); - nSize += ::GetSerializeSize(updateToNOut, nType, nVersion); - } - return nSize; - } - template - void Serialize(Stream& s, int nType, int nVersion) const - { - ::Serialize(s, txhash, nType, nVersion); - ::Serialize(s, nOut, nType, nVersion); - ::Serialize(s, nAmount, nType, nVersion); - ::Serialize(s, nHeight, nType, nVersion); - ::Serialize(s, nValidAtHeight, nType, nVersion); - ::Serialize(s, fIsUpdate, nType, nVersion); - if (fIsUpdate) - { - ::Serialize(s, updateToTxhash, nType, nVersion); - ::Serialize(s, updateToNOut, nType, nVersion); - } - } - - template - void Unserialize(Stream& s, int nType, int nVersion) - { - ::Unserialize(s, txhash, nType, nVersion); - ::Unserialize(s, nOut, nType, nVersion); - ::Unserialize(s, nAmount, nType, nVersion); - ::Unserialize(s, nHeight, nType, nVersion); - ::Unserialize(s, nValidAtHeight, nType, nVersion); - ::Unserialize(s, fIsUpdate, nType, nVersion); - if (fIsUpdate) - { - ::Unserialize(s, updateToTxhash, nType, nVersion); - ::Unserialize(s, updateToNOut, nType, nVersion); - } - } - - /*ADD_SERIALIZE_METHODS; + ADD_SERIALIZE_METHODS; template inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { @@ -115,7 +66,7 @@ public: READWRITE(nAmount); READWRITE(nHeight); READWRITE(nValidAtHeight); - }*/ + } bool operator<(const CClaimValue& other) const { @@ -204,11 +155,11 @@ typedef std::pair namedNodeType; class CClaimTrieNode { public: - CClaimTrieNode() {} - CClaimTrieNode(uint256 hash) : hash(hash) {} + CClaimTrieNode() : nHeightOfLastTakeover(0) {} + CClaimTrieNode(uint256 hash) : hash(hash), nHeightOfLastTakeover(0) {} uint256 hash; nodeMapType children; - int nBlocksSinceTakeover; + int nHeightOfLastTakeover; std::vector claims; bool insertClaim(CClaimValue claim); @@ -224,6 +175,7 @@ public: inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(hash); READWRITE(claims); + READWRITE(nHeightOfLastTakeover); } bool operator==(const CClaimTrieNode& other) const @@ -270,10 +222,10 @@ class CClaimTrieCache; class CClaimTrie { public: - CClaimTrie(bool fMemory = false, bool fWipe = false) + CClaimTrie(bool fMemory = false, bool fWipe = false, bool fConstantDelay = false) : db(GetDataDir() / "claimtrie", 100, fMemory, fWipe, false) , nCurrentHeight(0), nExpirationTime(262974) - , fConstantDelay(false), nConstantDelayHeight(100) + , fConstantDelay(fConstantDelay), nConstantDelayHeight(100) , nProportionalDelayBits(5) , root(uint256S("0000000000000000000000000000000000000000000000000000000000000001")) {} @@ -283,13 +235,14 @@ public: bool empty() const; void clear(); - bool checkConsistency(); + bool checkConsistency() const; bool WriteToDisk(); bool ReadFromDisk(bool check = false); std::vector flattenTrie() const; bool getInfoForName(const std::string& name, CClaimValue& claim) const; + bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const; bool queueEmpty() const; bool supportEmpty() const; @@ -331,8 +284,11 @@ public: int nProportionalDelayBits; private: void clear(CClaimTrieNode* current); + + const CClaimTrieNode* getNodeForName(const std::string& name) const; bool update(nodeCacheType& cache, hashMapType& hashes, + std::map& takeoverHeights, const uint256& hashBlock, claimQueueType& queueCache, claimQueueNamesType& queueNameCache, claimQueueType& expirationQueueCache, int nNewHeight, @@ -341,9 +297,10 @@ private: supportQueueNamesType& supportQueueNameCache); bool updateName(const std::string& name, CClaimTrieNode* updatedNode); bool updateHash(const std::string& name, uint256& hash); + bool updateTakeoverHeight(const std::string& name, int nTakeoverHeight); bool recursiveNullify(CClaimTrieNode* node, std::string& name); - bool recursiveCheckConsistency(CClaimTrieNode* node); + bool recursiveCheckConsistency(const CClaimTrieNode* node) const; bool InsertFromDisk(const std::string& name, CClaimTrieNode* node); @@ -393,7 +350,9 @@ private: class CClaimTrieCache { public: - CClaimTrieCache(CClaimTrie* base): base(base) + CClaimTrieCache(CClaimTrie* base, bool fRequireTakeoverHeights = true) + : base(base), + fRequireTakeoverHeights(fRequireTakeoverHeights) { assert(base); nCurrentHeight = base->nCurrentHeight; @@ -437,19 +396,25 @@ public: bool incrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, - supportQueueRowType& insertSupportUndo) const; + supportQueueRowType& insertSupportUndo, + std::vector >& takeoverHeightUndo) const; bool decrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, - supportQueueRowType& insertSupportUndo) const; + supportQueueRowType& insertSupportUndo, + std::vector >& takeoverHeightUndo) const; ~CClaimTrieCache() { clear(); } - bool insertClaimIntoTrie(const std::string name, CClaimValue claim) const; + bool insertClaimIntoTrie(const std::string name, CClaimValue claim, + bool fCheckTakeover = false) const; bool removeClaimFromTrie(const std::string name, uint256 txhash, - uint32_t nOut, int& nValidAtHeight) const; + uint32_t nOut, int& nValidAtHeight, + bool fCheckTakeover = false) const; private: CClaimTrie* base; + bool fRequireTakeoverHeights; + mutable nodeCacheType cache; mutable std::set dirtyHashes; mutable hashMapType cacheHashes; @@ -458,7 +423,9 @@ private: mutable claimQueueType expirationQueueCache; mutable supportMapType supportCache; mutable supportQueueType supportQueueCache; - mutable supportQueueNamesType supportQueueNameCache; + mutable supportQueueNamesType supportQueueNameCache; + mutable std::set namesToCheckForTakeover; + mutable std::map cacheTakeoverHeights; mutable int nCurrentHeight; // Height of the block that is being worked on, which is // one greater than the height of the chain's tip @@ -466,7 +433,7 @@ private: uint256 computeHash() const; - bool reorderTrieNode(const std::string name) const; + bool reorderTrieNode(const std::string name, bool fCheckTakeover) const; bool recursiveComputeMerkleHash(CClaimTrieNode* tnCurrent, std::string sPos) const; bool recursivePruneName(CClaimTrieNode* tnCurrent, unsigned int nPos, @@ -476,11 +443,9 @@ private: bool clear() const; bool removeClaim(const std::string name, uint256 txhash, uint32_t nOut, - int nHeight, int& nValidAtHeight) const; + int nHeight, int& nValidAtHeight, bool fCheckTakeover) const; - bool addClaimToQueues(const std::string name, uint256 txhash, - uint32_t nOut, CAmount nAmount, int nHeight, - int nValidAtHeight) const; + bool addClaimToQueues(const std::string name, CClaimValue& claim) const; bool removeClaimFromQueue(const std::string name, uint256 txhash, uint32_t nOut, int& nValidAtHeight) const; void addToExpirationQueue(claimQueueEntryType& entry) const; @@ -496,14 +461,16 @@ private: bool removeSupport(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, - int nHeight, int& nValidAtHeight) const; + int nHeight, int& nValidAtHeight, + bool fCheckTakeover) const; bool removeSupportFromMap(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, - int& nValidAtHeight) const; + int& nValidAtHeight, bool fCheckTakeover) const; bool insertSupportIntoMap(const std::string name, - CSupportValue support) const; + CSupportValue support, + bool fCheckTakeover) const; supportQueueType::iterator getSupportQueueCacheRow(int nHeight, bool createIfNotExists) const; @@ -522,6 +489,8 @@ private: bool getSupportsForName(const std::string name, supportMapEntryType& node) const; + bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const; + int getDelayForName(const std::string name) const; }; diff --git a/src/main.cpp b/src/main.cpp index f05e435d5..fa06a87ab 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1602,7 +1602,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) return error("DisconnectBlock(): block and undo data inconsistent"); - assert(trieCache.decrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo)); + assert(trieCache.decrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo, blockUndo.takeoverHeightUndo)); // undo transactions in reverse order for (int i = block.vtx.size() - 1; i >= 0; i--) { @@ -2023,7 +2023,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); } - assert(trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, blockundo.insertSupportUndo)); + assert(trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, blockundo.insertSupportUndo, blockundo.takeoverHeightUndo)); if (trieCache.getMerkleHash() != block.hashClaimTrie) return state.DoS(100, diff --git a/src/miner.cpp b/src/miner.cpp index 8ff15c85d..380467523 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -437,7 +437,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) claimQueueRowType dummyInsertUndo; claimQueueRowType dummyExpireUndo; supportQueueRowType dummyInsertSupportUndo; - trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo); + std::vector > dummyTakeoverHeightUndo; + trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyTakeoverHeightUndo); pblock->hashClaimTrie = trieCache.getMerkleHash(); CValidationState state; diff --git a/src/test/claimtrie_tests.cpp b/src/test/claimtrie_tests.cpp index 34cbbf79d..097ad012c 100644 --- a/src/test/claimtrie_tests.cpp +++ b/src/test/claimtrie_tests.cpp @@ -158,20 +158,20 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) CMutableTransaction tx6 = BuildTransaction(tx5.GetHash()); uint256 hash1; - hash1.SetHex("09732c6efebb4065a27f184285a6b66280a978cf972b1f41a563f0d3644f3e5c"); + hash1.SetHex("4bbf61ec5669c721bf007c71c59f85e6658f1de7b4562078e22f69f8f7ebcafd"); uint256 hash2; - hash2.SetHex("8db92b76b6b0416d7abda4fd7404ba69e340853dfe9ffc04843c50142b857471"); + hash2.SetHex("33d00d8f4707eb0abef7297a7ff4975e7354fe1ed81455f28301dbceb939494d"); uint256 hash3; - hash3.SetHex("2e38561067f3e83d6ca0b627861689de72bba77cb5aca69d13b3685b5229525b"); + hash3.SetHex("eb19bbaeecfd6dee77a8cb69286ac01226caee3c3883f55b86d0ca5a2f4252d7"); uint256 hash4; - hash4.SetHex("6ec84089eb4ca1aeead6cf3538d4def78baebb44715c31be8790e627e0dcbc28"); + hash4.SetHex("a889778ba28603294c1e5c7cec469a9019332ec93838b2f1331ebba547c5fd22"); BOOST_CHECK(pclaimTrie->empty()); - CClaimTrieCache ntState(pclaimTrie); + CClaimTrieCache ntState(pclaimTrie, false); ntState.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1.GetHash(), 0, 50, 100, 200)); ntState.insertClaimIntoTrie(std::string("test2"), CClaimValue(tx2.GetHash(), 0, 50, 100, 200)); @@ -192,7 +192,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2); BOOST_CHECK(pclaimTrie->checkConsistency()); - CClaimTrieCache ntState1(pclaimTrie); + CClaimTrieCache ntState1(pclaimTrie, false); ntState1.removeClaimFromTrie(std::string("test"), tx1.GetHash(), 0, unused); ntState1.removeClaimFromTrie(std::string("test2"), tx2.GetHash(), 0, unused); ntState1.removeClaimFromTrie(std::string("test"), tx3.GetHash(), 0, unused); @@ -200,7 +200,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(ntState1.getMerkleHash() == hash0); - CClaimTrieCache ntState2(pclaimTrie); + CClaimTrieCache ntState2(pclaimTrie, false); ntState2.insertClaimIntoTrie(std::string("abab"), CClaimValue(tx6.GetHash(), 0, 50, 100, 200)); ntState2.removeClaimFromTrie(std::string("test"), tx1.GetHash(), 0, unused); @@ -212,7 +212,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->getMerkleHash() == hash3); BOOST_CHECK(pclaimTrie->checkConsistency()); - CClaimTrieCache ntState3(pclaimTrie); + CClaimTrieCache ntState3(pclaimTrie, false); ntState3.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1.GetHash(), 0, 50, 100, 200)); BOOST_CHECK(ntState3.getMerkleHash() == hash4); ntState3.flush(); @@ -220,7 +220,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->getMerkleHash() == hash4); BOOST_CHECK(pclaimTrie->checkConsistency()); - CClaimTrieCache ntState4(pclaimTrie); + CClaimTrieCache ntState4(pclaimTrie, false); ntState4.removeClaimFromTrie(std::string("abab"), tx6.GetHash(), 0, unused); BOOST_CHECK(ntState4.getMerkleHash() == hash2); ntState4.flush(); @@ -228,7 +228,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2); BOOST_CHECK(pclaimTrie->checkConsistency()); - CClaimTrieCache ntState5(pclaimTrie); + CClaimTrieCache ntState5(pclaimTrie, false); ntState5.removeClaimFromTrie(std::string("test"), tx3.GetHash(), 0, unused); BOOST_CHECK(ntState5.getMerkleHash() == hash2); @@ -237,7 +237,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2); BOOST_CHECK(pclaimTrie->checkConsistency()); - CClaimTrieCache ntState6(pclaimTrie); + CClaimTrieCache ntState6(pclaimTrie, false); ntState6.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3.GetHash(), 0, 50, 101, 201)); BOOST_CHECK(ntState6.getMerkleHash() == hash2); @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2); BOOST_CHECK(pclaimTrie->checkConsistency()); - CClaimTrieCache ntState7(pclaimTrie); + CClaimTrieCache ntState7(pclaimTrie, false); ntState7.removeClaimFromTrie(std::string("test"), tx3.GetHash(), 0, unused); ntState7.removeClaimFromTrie(std::string("test"), tx1.GetHash(), 0, unused); ntState7.removeClaimFromTrie(std::string("tes"), tx4.GetHash(), 0, unused); diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp index 9e68f18d3..60c42ca4c 100644 --- a/src/test/test_bitcoin.cpp +++ b/src/test/test_bitcoin.cpp @@ -59,7 +59,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pblocktree = new CBlockTreeDB(1 << 20, true); pcoinsdbview = new CCoinsViewDB(1 << 23, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - pclaimTrie = new CClaimTrie(true); + pclaimTrie = new CClaimTrie(true, false, true); InitBlockIndex(); #ifdef ENABLE_WALLET bool fFirstRun; diff --git a/src/undo.h b/src/undo.h index a79a6d9ab..6546284ce 100644 --- a/src/undo.h +++ b/src/undo.h @@ -83,6 +83,7 @@ public: claimQueueRowType insertUndo; // any claims that went from the queue to the trie claimQueueRowType expireUndo; // any claims that expired supportQueueRowType insertSupportUndo; // any claims that went from the support queue to the support map + std::vector > takeoverHeightUndo; // for any name that was taken over, the previous time that name was taken over ADD_SERIALIZE_METHODS; @@ -92,6 +93,7 @@ public: READWRITE(insertUndo); READWRITE(expireUndo); READWRITE(insertSupportUndo); + READWRITE(takeoverHeightUndo); } };