diff --git a/.travis.yml b/.travis.yml index f60e6a9a7..829422909 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,17 +2,17 @@ matrix: include: - os: linux sudo: required - dist: xenial + dist: trusty language: c env: TARGET=linux - os: linux sudo: required - dist: xenial + dist: trusty language: c env: TARGET=windows - os: osx language: c - osx_image: xcode8.3 + osx_image: xcode7.3 env: TARGET=osx cache: apt: true @@ -20,12 +20,11 @@ cache: directories: - build - depends/built -git: - depth: false before_install: - date +%s > "${TRAVIS_BUILD_DIR}/start_time" - ls -lh build - du -h -d 2 build +- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install ccache; fi - if [ "$TRAVIS_OS_NAME" == "osx" ]; then export PATH="/usr/local/opt/ccache/libexec:$PATH"; fi install: true diff --git a/configure.ac b/configure.ac index d19f0eb32..6be5a02b9 100644 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MINOR, 12) -define(_CLIENT_VERSION_REVISION, 3) -define(_CLIENT_VERSION_BUILD, 1) +define(_CLIENT_VERSION_REVISION, 2) +define(_CLIENT_VERSION_BUILD, 3) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2016) define(_COPYRIGHT_HOLDERS,[The %s developers]) diff --git a/contrib/devtools/clang-format-diff.py b/contrib/devtools/clang-format-diff.py index b0dd9f59a..13d2573b9 100755 --- a/contrib/devtools/clang-format-diff.py +++ b/contrib/devtools/clang-format-diff.py @@ -144,8 +144,7 @@ def main(): command.extend(lines) command.extend(['-style=file', '-fallback-style=none']) p = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=None, - stdin=subprocess.PIPE) + stderr=None, stdin=subprocess.PIPE) stdout, stderr = p.communicate() if p.returncode != 0: sys.exit(p.returncode); diff --git a/reproducible_build.sh b/reproducible_build.sh index 2a929902f..4bd67a034 100755 --- a/reproducible_build.sh +++ b/reproducible_build.sh @@ -237,7 +237,7 @@ function install_apt_packages() { if [ "${CHECK_CODE_FORMAT}" = true ]; then $SUDO apt-get ${QUIET} install -y --no-install-recommends \ - clang-format-3.9 + clang-format-3.4 fi } @@ -327,7 +327,6 @@ function build_libevent() { } function build_dependency() { - pushd . PREFIX=$1 LOG=$2 BUILD=$3 @@ -338,7 +337,6 @@ function build_dependency() { "${BUILD}" "${LOG}" trap - INT TERM EXIT fi - popd } function build_lbrycrd() { @@ -372,7 +370,11 @@ function build_lbrycrd() { function clang_format_diff(){ # run a code formatting check on any commits not in master # requires clang-format - git diff -U0 origin/master -- '*.h' '*.cpp' | ./contrib/devtools/clang-format-diff.py -p1 + if ! git config remote.origin2.url > /dev/null; then + git remote add origin2 https://github.com/lbryio/lbrycrd.git + fi + git fetch origin2 + git diff -U0 origin2/master -- '*.h' '*.cpp' | ./contrib/devtools/clang-format-diff.py -p1 } # these variables are needed in both functions diff --git a/src/claimtrie.cpp b/src/claimtrie.cpp index f4b1ccd98..f7cefab5c 100644 --- a/src/claimtrie.cpp +++ b/src/claimtrie.cpp @@ -151,7 +151,7 @@ template bool CClaimTrie::keyTypeEmpty(char keyType, K& dummy) const { boost::scoped_ptr pcursor(const_cast(&db)->NewIterator()); pcursor->SeekToFirst(); - + while (pcursor->Valid()) { std::pair key; @@ -403,6 +403,28 @@ CAmount CClaimTrie::getTotalValueOfClaimsRecursive(const CClaimTrieNode* current return value_in_subtrie; } +bool CClaimTrie::recursiveFlattenTrie(const std::string& name, const CClaimTrieNode* current, std::vector& nodes) const +{ + namedNodeType node(name, *current); + nodes.push_back(node); + for (nodeMapType::const_iterator it = current->children.begin(); it != current->children.end(); ++it) + { + std::stringstream ss; + ss << name << it->first; + if (!recursiveFlattenTrie(ss.str(), it->second, nodes)) + return false; + } + return true; +} + +std::vector CClaimTrie::flattenTrie() const +{ + std::vector nodes; + if (!recursiveFlattenTrie("", &root, nodes)) + LogPrintf("%s: Something went wrong flattening the trie", __func__); + return nodes; +} + const CClaimTrieNode* CClaimTrie::getNodeForName(const std::string& name) const { const CClaimTrieNode* current = &root; @@ -1175,7 +1197,7 @@ bool CClaimTrieCache::recursiveComputeMerkleHash(CClaimTrieNode* tnCurrent, std: vchToHash.insert(vchToHash.end(), it->second->hash.begin(), it->second->hash.end()); } } - + CClaimValue claim; bool hasClaim = tnCurrent->getBestClaim(claim); @@ -1279,7 +1301,7 @@ bool CClaimTrieCache::insertClaimIntoTrie(const std::string& name, CClaimValue c currentNode = childNode->second; continue; } - + // This next substring doesn't exist in the cache and the next // character doesn't exist in current node's children, so check // if the current node is in the cache, and if it's not, copy @@ -1380,7 +1402,7 @@ bool CClaimTrieCache::removeClaimFromTrie(const std::string& name, const COutPoi bool fChanged = false; assert(currentNode != NULL); bool success = false; - + if (currentNode->claims.empty()) { LogPrintf("%s: Asked to remove claim from node without claims\n", __func__); @@ -1456,7 +1478,7 @@ bool CClaimTrieCache::recursivePruneName(CClaimTrieNode* tnCurrent, unsigned int // tnCurrent isn't necessarily in the cache. If it's not, it // has to be added to the cache, so nothing is changed in the // trie. If the current node is added to the cache, however, - // that does not imply that the parent node must be altered to + // that does not imply that the parent node must be altered to // reflect that its child is now in the cache, since it // already has a character in its child map which will be used // when calculating the merkle root. @@ -1631,20 +1653,20 @@ bool CClaimTrieCache::removeClaimFromQueue(const std::string& name, const COutPo return false; } -bool CClaimTrieCache::undoAddClaim(const std::string& name, const COutPoint& outPoint) const +bool CClaimTrieCache::undoAddClaim(const std::string& name, const COutPoint& outPoint, int nHeight) const { int throwaway; - return removeClaim(name, outPoint, throwaway, false); + return removeClaim(name, outPoint, nHeight, throwaway, false); } -bool CClaimTrieCache::spendClaim(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const +bool CClaimTrieCache::spendClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight) const { - return removeClaim(name, outPoint, nValidAtHeight, true); + return removeClaim(name, outPoint, nHeight, nValidAtHeight, true); } -bool CClaimTrieCache::removeClaim(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight, bool fCheckTakeover) const +bool CClaimTrieCache::removeClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const { - LogPrintf("%s: name: %s, txhash: %s, nOut: %s, nCurrentHeight: %s\n", __func__, name, outPoint.hash.GetHex(), outPoint.n, nCurrentHeight); + LogPrintf("%s: name: %s, txhash: %s, nOut: %s, nHeight: %s, nCurrentHeight: %s\n", __func__, name, outPoint.hash.GetHex(), outPoint.n, nHeight, nCurrentHeight); bool removed = false; CClaimValue claim; if (removeClaimFromQueue(name, outPoint, claim)) @@ -1658,7 +1680,7 @@ bool CClaimTrieCache::removeClaim(const std::string& name, const COutPoint& outP if (removed == true) { nValidAtHeight = claim.nValidAtHeight; - int expirationHeight = claim.nHeight + base->nExpirationTime; + int expirationHeight = nHeight + base->nExpirationTime; removeFromExpirationQueue(name, outPoint, expirationHeight); claimsToDelete.insert(claim); } @@ -2162,7 +2184,7 @@ bool CClaimTrieCache::incrementBlock(insertUndoType& insertUndo, claimQueueRowTy itSupportExpirationRow->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 + // 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 @@ -2213,7 +2235,7 @@ bool CClaimTrieCache::incrementBlock(insertUndoType& insertUndo, claimQueueRowTy } if (takeoverHappened) { - // Get all pending claims for that name and activate them all in the case that our winner is defunct. + // Get all claims in the queue for that name queueNameType::iterator itQueueNameRow = getQueueCacheNameRow(*itNamesToCheck, false); if (itQueueNameRow != claimQueueNameCache.end()) { @@ -2253,7 +2275,7 @@ bool CClaimTrieCache::incrementBlock(insertUndoType& insertUndo, claimQueueRowTy // remove all claims from the queue for that name itQueueNameRow->second.clear(); } - // + // // Then, get all supports in the queue for that name queueNameType::iterator itSupportQueueNameRow = getSupportQueueCacheNameRow(*itNamesToCheck, false); if (itSupportQueueNameRow != supportQueueNameCache.end()) @@ -2344,9 +2366,6 @@ bool CClaimTrieCache::decrementBlock(insertUndoType& insertUndo, claimQueueRowTy supportQueueType::iterator itSupportRow = getSupportQueueCacheRow(itSupportUndo->nHeight, true); CSupportValue support; assert(removeSupportFromMap(itSupportUndo->name, itSupportUndo->outPoint, support, false)); - // support.nValidHeight may have been changed if this was inserted before activation height - // due to a triggered takeover, change it back to original nValidAtHeight - support.nValidAtHeight = itSupportUndo->nHeight; queueNameType::iterator itSupportNameRow = getSupportQueueCacheNameRow(itSupportUndo->name, true); itSupportRow->second.push_back(std::make_pair(itSupportUndo->name, support)); itSupportNameRow->second.push_back(outPointHeightType(support.outPoint, support.nValidAtHeight)); @@ -2367,15 +2386,11 @@ bool CClaimTrieCache::decrementBlock(insertUndoType& insertUndo, claimQueueRowTy for (insertUndoType::iterator itInsertUndo = insertUndo.begin(); itInsertUndo != insertUndo.end(); ++itInsertUndo) { claimQueueType::iterator itQueueRow = getQueueCacheRow(itInsertUndo->nHeight, true); - CClaimValue claim; assert(removeClaimFromTrie(itInsertUndo->name, itInsertUndo->outPoint, claim, false)); - // claim.nValidHeight may have been changed if this was inserted before activation height - // due to a triggered takeover, change it back to original nValidAtHeight - claim.nValidAtHeight = itInsertUndo->nHeight; queueNameType::iterator itQueueNameRow = getQueueCacheNameRow(itInsertUndo->name, true); itQueueRow->second.push_back(std::make_pair(itInsertUndo->name, claim)); - itQueueNameRow->second.push_back(outPointHeightType(itInsertUndo->outPoint, claim.nValidAtHeight)); + itQueueNameRow->second.push_back(outPointHeightType(itInsertUndo->outPoint, itInsertUndo->nHeight)); } for (std::vector >::iterator itTakeoverHeightUndo = takeoverHeightUndo.begin(); itTakeoverHeightUndo != takeoverHeightUndo.end(); ++itTakeoverHeightUndo) @@ -2526,32 +2541,25 @@ uint256 CClaimTrieCache::getLeafHashForProof(const std::string& currentPosition, } } -void CClaimTrieCache::recursiveIterateTrie(std::string& name, const CClaimTrieNode* current, CNodeCallback& callback) const +void CClaimTrieCache::recursiveFlattenTrie(const std::string& name, const CClaimTrieNode* current, std::vector& nodes) const { - callback.visit(name, current); - + nodes.push_back(std::make_pair(name, *current)); nodeCacheType::const_iterator cachedNode; for (nodeMapType::const_iterator it = current->children.begin(); it != current->children.end(); ++it) { - name.push_back(it->first); - cachedNode = cache.find(name); + const std::string str = name + char(it->first); + cachedNode = cache.find(str); if (cachedNode != cache.end()) - recursiveIterateTrie(name, cachedNode->second, callback); + recursiveFlattenTrie(str, cachedNode->second, nodes); else - recursiveIterateTrie(name, it->second, callback); - name.erase(name.end() - 1); + recursiveFlattenTrie(str, it->second, nodes); } } -bool CClaimTrieCache::iterateTrie(CNodeCallback& callback) const +std::vector CClaimTrieCache::flattenTrie() const { - try { - std::string name; - recursiveIterateTrie(name, getRoot(), callback); - assert(name.empty()); - } catch (const CNodeCallback::CRecursionInterruptionException& ex) { - return ex.success; - } - return true; + std::vector nodes; + recursiveFlattenTrie("", getRoot(), nodes); + return nodes; } claimsForNameType CClaimTrieCache::getClaimsForName(const std::string& name) const diff --git a/src/claimtrie.h b/src/claimtrie.h index d192cf6f6..ae3c88dac 100644 --- a/src/claimtrie.h +++ b/src/claimtrie.h @@ -132,6 +132,8 @@ typedef std::vector supportMapEntryType; typedef std::map nodeMapType; +typedef std::pair namedNodeType; + class CClaimTrieNode { public: @@ -210,6 +212,7 @@ struct nameOutPointHeightType nameOutPointHeightType(std::string name, COutPoint outPoint, int nHeight) : name(name), outPoint(outPoint), nHeight(nHeight) {} + ADD_SERIALIZE_METHODS; template @@ -315,11 +318,11 @@ public: 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; claimsForNameType getClaimsForName(const std::string& name) const; - CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector* supports = NULL) const; CAmount getEffectiveAmountForClaim(const claimsForNameType& claims, const uint160& claimId, std::vector* supports = NULL) const; @@ -389,6 +392,9 @@ private: unsigned int getTotalClaimsRecursive(const CClaimTrieNode* current) const; CAmount getTotalValueOfClaimsRecursive(const CClaimTrieNode* current, bool fControllingOnly) const; + bool recursiveFlattenTrie(const std::string& name, + const CClaimTrieNode* current, + std::vector& nodes) const; void markNodeDirty(const std::string& name, CClaimTrieNode* node); void updateQueueRow(int nHeight, claimQueueRowType& row); @@ -453,27 +459,6 @@ public: int nHeightOfLastTakeover; }; -struct CNodeCallback { - struct CRecursionInterruptionException : public std::exception { - const bool success; - explicit CRecursionInterruptionException(bool success) : success(success) {} - }; - - virtual ~CNodeCallback() - { - } - - /** - * Callback to be called on every trie node - * @param[in] name full name of the node - * @param[in] node pointer to node itself - * - * To breakout early throw an exception. - * Throwing CRecursionInterruptionException will allow you to set the return value of iterateTrie. - */ - virtual void visit(const std::string& name, const CClaimTrieNode* node) = 0; -}; - class CClaimTrieCache { public: @@ -499,8 +484,10 @@ public: bool addClaim(const std::string& name, const COutPoint& outPoint, uint160 claimId, CAmount nAmount, int nHeight) const; - bool undoAddClaim(const std::string& name, const COutPoint& outPoint) const; - bool spendClaim(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const; + bool undoAddClaim(const std::string& name, const COutPoint& outPoint, + int nHeight) const; + bool spendClaim(const std::string& name, const COutPoint& outPoint, + int nHeight, int& nValidAtHeight) const; bool undoSpendClaim(const std::string& name, const COutPoint& outPoint, uint160 claimId, CAmount nAmount, int nHeight, int nValidAtHeight) const; @@ -548,7 +535,7 @@ public: bool forkForExpirationChange(bool increment) const; - bool iterateTrie(CNodeCallback& callback) const; + std::vector flattenTrie() const; claimsForNameType getClaimsForName(const std::string& name) const; @@ -572,7 +559,7 @@ protected: mutable queueNameType supportQueueNameCache; mutable expirationQueueType supportExpirationQueueCache; mutable std::set namesToCheckForTakeover; - mutable std::map cacheTakeoverHeights; + 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 mutable claimIndexElementListType claimsToAdd; @@ -591,7 +578,9 @@ protected: bool clear() const; - bool removeClaim(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight, bool fCheckTakeover) const; + bool removeClaim(const std::string& name, const COutPoint& outPoint, + int nHeight, int& nValidAtHeight, bool fCheckTakeover) const; + bool addClaimToQueues(const std::string& name, CClaimValue& claim) const; bool removeClaimFromQueue(const std::string& name, const COutPoint& outPoint, CClaimValue& claim) const; @@ -650,7 +639,7 @@ protected: int getNumBlocksOfContinuousOwnership(const std::string& name) const; - void recursiveIterateTrie(std::string& name, const CClaimTrieNode* current, CNodeCallback& callback) const; + void recursiveFlattenTrie(const std::string& name, const CClaimTrieNode* current, std::vector& nodes) const; const CClaimTrieNode* getNodeForName(const std::string& name) const; }; diff --git a/src/clientversion.h b/src/clientversion.h index dbcf9c627..67a55a4a9 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -16,8 +16,8 @@ //! These need to be macros, as clientversion.cpp's and bitcoin*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MINOR 12 -#define CLIENT_VERSION_REVISION 3 -#define CLIENT_VERSION_BUILD 1 +#define CLIENT_VERSION_REVISION 2 +#define CLIENT_VERSION_BUILD 3 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/main.cpp b/src/main.cpp index 38f738834..bde0cd1ba 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -963,12 +963,13 @@ bool CheckTransaction(const CTransaction& tx, CValidationState &state) if (!MoneyRange(nValueOut)) return state.DoS(100, false, REJECT_INVALID, "bad-txns-txouttotal-toolarge"); - // check claimtrie transactions + // check claimtrie transactions if (ClaimScriptSize(txout.scriptPubKey) > MAX_CLAIM_SCRIPT_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-txns-claimscriptsize-toolarge"); - if (ClaimNameSize(txout.scriptPubKey) > MAX_CLAIM_NAME_SIZE) + if (ClaimNameSize(txout.scriptPubKey) > MAX_CLAIM_NAME_SIZE) return state.DoS(100, false, REJECT_INVALID, "bad-txns-claimscriptname-toolarge"); + } // Check for duplicate inputs @@ -2193,7 +2194,8 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI } std::string name(vvchParams[0].begin(), vvchParams[0].end()); LogPrintf("%s: (txid: %s, nOut: %d) Trying to remove %s from the claim trie due to its block being disconnected\n", __func__, hash.ToString(), i, name.c_str()); - if (!trieCache.undoAddClaim(name, COutPoint(hash, i))) { + if (!trieCache.undoAddClaim(name, COutPoint(hash, i), pindex->nHeight)) + { LogPrintf("%s: Could not find the claim in the trie or the cache\n", __func__); } } @@ -2501,7 +2503,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin flags |= SCRIPT_VERIFY_CHECKSEQUENCEVERIFY; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; } - + // v 13 LBRYcrd hard fork to extend expiration time if (pindex->nHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight) { @@ -2586,7 +2588,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin typedef std::vector > spentClaimsType; spentClaimsType spentClaims; - + for (unsigned int i = 0; i < tx.vin.size(); ++i) { const CTxIn& txin = tx.vin[i]; @@ -2623,7 +2625,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::string name(vvchParams[0].begin(), vvchParams[0].end()); int nValidAtHeight; LogPrintf("%s: Removing %s from the claim trie. Tx: %s, nOut: %d\n", __func__, name, txin.prevout.hash.GetHex(), txin.prevout.n); - if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), nValidAtHeight)) { + if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), coins->nHeight, nValidAtHeight)) + { mClaimUndoHeights[i] = nValidAtHeight; std::pair entry(name, claimId); spentClaims.push_back(entry); @@ -2646,7 +2649,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin } } } - + for (unsigned int i = 0; i < tx.vout.size(); ++i) { const CTxOut& txout = tx.vout[i]; @@ -4215,8 +4218,8 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); // check level 1: verify block validity if (nCheckLevel >= 1 && !CheckBlock(block, state)) - return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, - pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); + return error("%s: *** found bad block at %d, hash=%s (%s)\n", __func__, + pindex->nHeight, pindex->GetBlockHash().ToString(), FormatStateMessage(state)); // check level 2: verify undo validity if (nCheckLevel >= 2 && pindex) { CBlockUndo undo; @@ -4264,6 +4267,45 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview, return true; } +bool RollBackTo(const CBlockIndex* targetIndex, CCoinsViewCache& coinsCache, CClaimTrieCache& trieCache) +{ + AssertLockHeld(cs_main); + for (CBlockIndex* index = chainActive.Tip(); index && index != targetIndex; index = index->pprev) { + boost::this_thread::interruption_point(); + CBlock block; + + if (!ReadBlockFromDisk(block, index, Params().GetConsensus())) + return false; // return error() instead? + + if (coinsCache.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage() > nCoinCacheUsage) + return false; // don't allow a single query to chew up all our memory? + + if (ShutdownRequested()) + return false; + + CValidationState state; + if (!DisconnectBlock(block, state, index, coinsCache, trieCache)) + return false; + + if (state.IsError()) + return false; + } + return true; +} + +bool GetProofForName(const CBlockIndex* pindexProof, const std::string& name, CClaimTrieProof& proof) +{ + AssertLockHeld(cs_main); + if (!chainActive.Contains(pindexProof)) + return false; + + CCoinsViewCache coinsCache(pcoinsTip); + CClaimTrieCache trieCache(pclaimTrie); + if (RollBackTo(pindexProof, coinsCache, trieCache)) + return trieCache.getProofForName(name, proof); + return false; +} + void UnloadBlockIndex() { LOCK(cs_main); @@ -4306,7 +4348,7 @@ bool LoadBlockIndex() return true; } -bool InitBlockIndex(const CChainParams& chainparams) +bool InitBlockIndex(const CChainParams& chainparams) { LOCK(cs_main); diff --git a/src/main.h b/src/main.h index 00bfcb5dd..3c9f845ee 100644 --- a/src/main.h +++ b/src/main.h @@ -225,6 +225,10 @@ FILE* OpenBlockFile(const CDiskBlockPos &pos, bool fReadOnly = false); FILE* OpenUndoFile(const CDiskBlockPos &pos, bool fReadOnly = false); /** Translation to a filesystem path */ boost::filesystem::path GetBlockPosFilename(const CDiskBlockPos &pos, const char *prefix); +/** Utility method for going back to a previous state **/ +bool RollBackTo(const CBlockIndex* targetIndex, CCoinsViewCache& coinsCache, CClaimTrieCache& trieCache); +/** Get a cryptographic proof that a name maps to a value **/ +bool GetProofForName(const CBlockIndex* pindexProof, const std::string& name, CClaimTrieProof& proof); /** Import blocks from an external file */ bool LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, CDiskBlockPos *dbp = NULL); /** Initialize a new block tree database + block data on disk */ diff --git a/src/miner.cpp b/src/miner.cpp index bfa5613e1..8136d8e80 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -294,7 +294,8 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s } std::string name(vvchParams[0].begin(), vvchParams[0].end()); int throwaway; - if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), throwaway)) { + if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), nTxinHeight, throwaway)) + { std::pair entry(name, claimId); spentClaims.push_back(entry); } @@ -315,11 +316,11 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s } } } - + for (unsigned int i = 0; i < tx.vout.size(); ++i) { const CTxOut& txout = tx.vout[i]; - + std::vector > vvchParams; int op; if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams)) @@ -567,7 +568,7 @@ void static BitcoinMiner(const CChainParams& chainparams) while (true) { unsigned int nHashesDone = 0; - + // Check if something found while (true) { @@ -598,7 +599,7 @@ void static BitcoinMiner(const CChainParams& chainparams) } if (found) break; - + // Meter hashes/sec static int64_t nHashCounter; if (nHPSTimerStart == 0) diff --git a/src/rpc/claimtrie.cpp b/src/rpc/claimtrie.cpp index dc66cefa2..c8920ae01 100644 --- a/src/rpc/claimtrie.cpp +++ b/src/rpc/claimtrie.cpp @@ -1,15 +1,13 @@ #include "boost/scope_exit.hpp" #include "consensus/validation.h" -#include "init.h" #include "main.h" #include "nameclaim.h" #include "rpc/server.h" #include "txmempool.h" #include "univalue.h" -#include - -#include +// Maximum block decrement that is allowed from rpc calls +const int MAX_RPC_BLOCK_DECREMENTS = 50; uint160 ParseClaimtrieId(const UniValue& v, const std::string& strName) { @@ -37,39 +35,10 @@ static CBlockIndex* BlockHashIndex(const uint256& blockHash) if (!chainActive.Contains(pblockIndex)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not in main chain"); - return pblockIndex; -} - -#define MAX_RPC_BLOCK_DECREMENTS 500 - -void RollBackTo(const CBlockIndex* targetIndex, CCoinsViewCache& coinsCache, CClaimTrieCache& trieCache) -{ - AssertLockHeld(cs_main); - - const CBlockIndex* activeIndex = chainActive.Tip(); - - if (activeIndex->nHeight > (targetIndex->nHeight + MAX_RPC_BLOCK_DECREMENTS)) + if (chainActive.Tip()->nHeight > (pblockIndex->nHeight + MAX_RPC_BLOCK_DECREMENTS)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Block is too deep"); - const size_t currentMemoryUsage = pcoinsTip->DynamicMemoryUsage(); - - for (; activeIndex && activeIndex != targetIndex; activeIndex = activeIndex->pprev) { - boost::this_thread::interruption_point(); - - CBlock block; - if (!ReadBlockFromDisk(block, activeIndex, Params().GetConsensus())) - throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Failed to read %s", activeIndex->ToString())); - - if (coinsCache.DynamicMemoryUsage() + currentMemoryUsage > nCoinCacheUsage) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Out of memory, you may want to increase dbcache size"); - - if (ShutdownRequested()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested"); - - CValidationState state; - if (!DisconnectBlock(block, state, activeIndex, coinsCache, trieCache)) - throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Failed to disconnect %s", block.ToString())); - } + return pblockIndex; } UniValue getclaimsintrie(const UniValue& params, bool fHelp) @@ -109,68 +78,48 @@ UniValue getclaimsintrie(const UniValue& params, bool fHelp) if (!params.empty()) { CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(params[0], "blockhash (optional parameter 1)")); - RollBackTo(blockIndex, coinsCache, trieCache); + if (!RollBackTo(blockIndex, coinsCache, trieCache)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Rollback failure"); } - class CClaimsCallback : public CNodeCallback - { - public: - CClaimsCallback(UniValue& ret, const CCoinsViewCache& coinsCache) : nodes(ret), coinsCache(coinsCache) - { - } - - void visit(const std::string& name, const CClaimTrieNode* node) - { - if (ShutdownRequested()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested"); - - boost::this_thread::interruption_point(); - - if (node->claims.empty()) - return; - - UniValue claims(UniValue::VARR); - for (std::vector::const_iterator itClaims = node->claims.begin(); itClaims != node->claims.end(); ++itClaims) { - UniValue claim(UniValue::VOBJ); - claim.push_back(Pair("claimId", itClaims->claimId.GetHex())); - claim.push_back(Pair("txid", itClaims->outPoint.hash.GetHex())); - claim.push_back(Pair("n", (int)itClaims->outPoint.n)); - claim.push_back(Pair("amount", ::ValueFromAmount(itClaims->nAmount))); - claim.push_back(Pair("height", itClaims->nHeight)); - const CCoins* coin = coinsCache.AccessCoins(itClaims->outPoint.hash); - if (!coin) { - LogPrintf("%s: %s does not exist in the coins view, despite being associated with a name\n", - __func__, itClaims->outPoint.hash.GetHex()); - claim.push_back(Pair("error", "No value found for claim")); - } else if (!coin->IsAvailable(itClaims->outPoint.n)) { - LogPrintf("%s: the specified txout of %s appears to have been spent\n", __func__, itClaims->outPoint.hash.GetHex()); - claim.push_back(Pair("error", "Txout spent")); - } else { - int op; - std::vector > vvchParams; - if (!DecodeClaimScript(coin->vout[itClaims->outPoint.n].scriptPubKey, op, vvchParams)) { - LogPrintf("%s: the specified txout of %s does not have an claim command\n", __func__, itClaims->outPoint.hash.GetHex()); - } - std::string sValue(vvchParams[1].begin(), vvchParams[1].end()); - claim.push_back(Pair("value", sValue)); - } - claims.push_back(claim); - } - - UniValue nodeObj(UniValue::VOBJ); - nodeObj.push_back(Pair("name", name)); - nodeObj.push_back(Pair("claims", claims)); - nodes.push_back(nodeObj); - } - - private: - UniValue& nodes; - const CCoinsViewCache& coinsCache; - }; - UniValue ret(UniValue::VARR); - CClaimsCallback claimsCallback(ret, coinsCache); - trieCache.iterateTrie(claimsCallback); + std::vector nodes = trieCache.flattenTrie(); + for (std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it) { + if (it->second.claims.empty()) continue; + + UniValue claims(UniValue::VARR); + for (std::vector::iterator itClaims = it->second.claims.begin(); itClaims != it->second.claims.end(); ++itClaims) { + UniValue claim(UniValue::VOBJ); + claim.push_back(Pair("claimId", itClaims->claimId.GetHex())); + claim.push_back(Pair("txid", itClaims->outPoint.hash.GetHex())); + claim.push_back(Pair("n", (int)itClaims->outPoint.n)); + claim.push_back(Pair("amount", ValueFromAmount(itClaims->nAmount))); + claim.push_back(Pair("height", itClaims->nHeight)); + const CCoins* coin = coinsCache.AccessCoins(itClaims->outPoint.hash); + if (!coin) { + LogPrintf("%s: %s does not exist in the coins view, despite being associated with a name\n", + __func__, itClaims->outPoint.hash.GetHex()); + claim.push_back(Pair("error", "No value found for claim")); + } else if (!coin->IsAvailable(itClaims->outPoint.n)) { + LogPrintf("%s: the specified txout of %s appears to have been spent\n", __func__, itClaims->outPoint.hash.GetHex()); + claim.push_back(Pair("error", "Txout spent")); + } else { + int op; + std::vector > vvchParams; + if (!DecodeClaimScript(coin->vout[itClaims->outPoint.n].scriptPubKey, op, vvchParams)) { + LogPrintf("%s: the specified txout of %s does not have an claim command\n", __func__, itClaims->outPoint.hash.GetHex()); + } + std::string sValue(vvchParams[1].begin(), vvchParams[1].end()); + claim.push_back(Pair("value", sValue)); + } + claims.push_back(claim); + } + + UniValue node(UniValue::VOBJ); + node.push_back(Pair("name", it->first)); + node.push_back(Pair("claims", claims)); + ret.push_back(node); + } return ret; } @@ -179,7 +128,7 @@ UniValue getclaimtrie(const UniValue& params, bool fHelp) if (fHelp || params.size() > 1) throw std::runtime_error( "getclaimtrie\n" - "DEPRECATED. Return the entire name trie.\n" + "Return the entire name trie.\n" "Arguments:\n" "1. \"blockhash\" (string, optional) get claim in the trie\n" " at the block specified\n" @@ -206,43 +155,27 @@ UniValue getclaimtrie(const UniValue& params, bool fHelp) if (!params.empty()) { CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(params[0], "blockhash (optional parameter 1)")); - RollBackTo(blockIndex, coinsCache, trieCache); + if (!RollBackTo(blockIndex, coinsCache, trieCache)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Rollback failure"); } - class CClaimCallback : public CNodeCallback - { - public: - CClaimCallback(UniValue& ret) : nodes(ret) - { - } - - void visit(const std::string& name, const CClaimTrieNode* node) - { - if (ShutdownRequested()) - throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested"); - - boost::this_thread::interruption_point(); - - UniValue nodeObj(UniValue::VOBJ); - nodeObj.push_back(Pair("name", name)); - nodeObj.push_back(Pair("hash", node->hash.GetHex())); - CClaimValue claim; - if (node->getBestClaim(claim)) { - nodeObj.push_back(Pair("txid", claim.outPoint.hash.GetHex())); - nodeObj.push_back(Pair("n", (int)claim.outPoint.n)); - nodeObj.push_back(Pair("value", ::ValueFromAmount(claim.nAmount))); - nodeObj.push_back(Pair("height", claim.nHeight)); - } - nodes.push_back(nodeObj); - } - - private: - UniValue& nodes; - }; - UniValue ret(UniValue::VARR); - CClaimCallback claimCallback(ret); - trieCache.iterateTrie(claimCallback); + std::vector nodes = trieCache.flattenTrie(); + for (std::vector::iterator it = nodes.begin(); it != nodes.end(); ++it) + { + UniValue node(UniValue::VOBJ); + node.push_back(Pair("name", it->first)); + node.push_back(Pair("hash", it->second.hash.GetHex())); + CClaimValue claim; + if (it->second.getBestClaim(claim)) + { + node.push_back(Pair("txid", claim.outPoint.hash.GetHex())); + node.push_back(Pair("n", (int)claim.outPoint.n)); + node.push_back(Pair("value", ValueFromAmount(claim.nAmount))); + node.push_back(Pair("height", claim.nHeight)); + } + ret.push_back(node); + } return ret; } @@ -303,6 +236,7 @@ UniValue getvalueforname(const UniValue& params, bool fHelp) "\"n\" (numeric) vout value\n" "\"amount\" (numeric) txout amount\n" "\"effective amount\" (numeric) txout amount plus amount from all supports associated with the claim\n" + "\"pending effective amount\" (numeric) expected effective amount when claim and its support got valid\n" "\"height\" (numeric) the height of the block in which this transaction is located\n"); LOCK(cs_main); @@ -312,7 +246,8 @@ UniValue getvalueforname(const UniValue& params, bool fHelp) if (params.size() > 1) { CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(params[1], "blockhash (optional parameter 2)")); - RollBackTo(blockIndex, coinsCache, trieCache); + if (!RollBackTo(blockIndex, coinsCache, trieCache)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Rollback failure"); } CClaimValue claim; @@ -333,6 +268,10 @@ UniValue getvalueforname(const UniValue& params, bool fHelp) ret.push_back(Pair("n", (int)claim.outPoint.n)); ret.push_back(Pair("amount", claim.nAmount)); ret.push_back(Pair("effective amount", nEffectiveAmount)); + + if (nEffectiveAmount < claim.nEffectiveAmount) + ret.push_back(Pair("pending effective amount", claim.nEffectiveAmount)); + ret.push_back(Pair("height", claim.nHeight)); return ret; } @@ -351,7 +290,7 @@ UniValue supportToJSON(const CSupportValue& support) return ret; } -UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, CAmount nEffectiveAmount, claimSupportMapType::const_iterator itClaimsAndSupports) +UniValue claimAndSupportsToJSON(CAmount nEffectiveAmount, claimSupportMapType::const_iterator itClaimsAndSupports) { UniValue ret(UniValue::VOBJ); const CClaimValue& claim = itClaimsAndSupports->second.first; @@ -366,10 +305,11 @@ UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, CAmount nEffe ret.push_back(Pair("nHeight", claim.nHeight)); ret.push_back(Pair("nValidAtHeight", claim.nValidAtHeight)); ret.push_back(Pair("nAmount", claim.nAmount)); - std::string sValue; - if (getValueForClaim(coinsCache, claim.outPoint, sValue)) - ret.push_back(Pair("value", sValue)); ret.push_back(Pair("nEffectiveAmount", nEffectiveAmount)); + + if (nEffectiveAmount < claim.nEffectiveAmount) + ret.push_back(Pair("nPendingEffectiveAmount", claim.nEffectiveAmount)); + ret.push_back(Pair("supports", supportObjs)); return ret; } @@ -399,8 +339,8 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp) " \"nHeight\" (numeric) the height at which the claim was included in the blockchain\n" " \"nValidAtHeight\" (numeric) the height at which the claim became/becomes valid\n" " \"nAmount\" (numeric) the amount of the claim\n" - " \"value\" (string) the value of the name, if it exists\n" " \"nEffectiveAmount\" (numeric) the total effective amount of the claim, taking into effect whether the claim or support has reached its nValidAtHeight\n" + " \"nPendingEffectiveAmount\" (numeric) expected effective amount when claim and its support got valid\n" " \"supports\" : [ (array of object) supports for this claim\n" " \"txid\" (string) the txid of the support\n" " \"n\" (numeric) the index of the support in the transaction's list of outputs\n" @@ -410,7 +350,7 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp) " ]\n" " }\n" " ],\n" - " \"supports without claims\": [ (array of object) supports that did not match a claim for this name\n" + " \"unmatched supports\": [ (array of object) supports that did not match a claim for this name\n" " {\n" " \"txid\" (string) the txid of the support\n" " \"n\" (numeric) the index of the support in the transaction's list of outputs\n" @@ -428,7 +368,8 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp) if (params.size() > 1) { CBlockIndex* blockIndex = BlockHashIndex(ParseHashV(params[1], "blockhash (optional parameter 2)")); - RollBackTo(blockIndex, coinsCache, trieCache); + if (!RollBackTo(blockIndex, coinsCache, trieCache)) + throw JSONRPCError(RPC_INTERNAL_ERROR, "Rollback failure"); } std::string name = params[0].get_str(); @@ -457,12 +398,12 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp) for (claimSupportMapType::const_iterator itClaimsAndSupports = claimSupportMap.begin(); itClaimsAndSupports != claimSupportMap.end(); ++itClaimsAndSupports) { CAmount nEffectiveAmount = trieCache.getEffectiveAmountForClaim(claimsForName, itClaimsAndSupports->first); - UniValue claimObj = claimAndSupportsToJSON(coinsCache, nEffectiveAmount, itClaimsAndSupports); + UniValue claimObj = claimAndSupportsToJSON(nEffectiveAmount, itClaimsAndSupports); claimObjs.push_back(claimObj); } ret.push_back(Pair("claims", claimObjs)); - ret.push_back(Pair("supports without claims", unmatchedSupports)); + ret.push_back(Pair("unmatched supports", unmatchedSupports)); return ret; } @@ -483,6 +424,7 @@ UniValue getclaimbyid(const UniValue& params, bool fHelp) " \"n\" (numeric) vout value\n" " \"amount\" (numeric) txout value\n" " \"effective amount\" (numeric) txout amount plus amount from all supports associated with the claim\n" + " \"pending effective amount\" (numeric) expected effective amount when claim and its support got valid\n" " \"supports\" (array of object) supports for this claim\n" " [\n" " \"txid\" (string) the txid of the support\n" @@ -516,6 +458,10 @@ UniValue getclaimbyid(const UniValue& params, bool fHelp) claim.push_back(Pair("n", (int) claimValue.outPoint.n)); claim.push_back(Pair("amount", claimValue.nAmount)); claim.push_back(Pair("effective amount", effectiveAmount)); + + if (effectiveAmount < claimValue.nEffectiveAmount) + claim.push_back(Pair("pending effective amount", claimValue.nEffectiveAmount)); + UniValue supportList(UniValue::VARR); BOOST_FOREACH(const CSupportValue& support, supports) { UniValue supportEntry(UniValue::VOBJ); @@ -849,18 +795,16 @@ UniValue getnameproof(const UniValue& params, bool fHelp) "}\n"); LOCK(cs_main); - - CCoinsViewCache coinsCache(pcoinsTip); - CClaimTrieCache trieCache(pclaimTrie); - + std::string strName = params[0].get_str(); + CBlockIndex* pblockIndex; if (params.size() == 2) { - CBlockIndex* pblockIndex = BlockHashIndex(ParseHashV(params[1], "blockhash (optional parameter 2)")); - RollBackTo(pblockIndex, coinsCache, trieCache); + pblockIndex = BlockHashIndex(ParseHashV(params[1], "blockhash (optional parameter 2)")); + } else { + pblockIndex = mapBlockIndex[chainActive.Tip()->GetBlockHash()]; } CClaimTrieProof proof; - std::string name = params[0].get_str(); - if (!trieCache.getProofForName(name, proof)) + if (!GetProofForName(pblockIndex, strName, proof)) throw JSONRPCError(RPC_INTERNAL_ERROR, "Failed to generate proof"); return proofToJSON(proof); diff --git a/src/test/claimtriebranching_tests.cpp b/src/test/claimtriebranching_tests.cpp index bc5bb8e3f..6303e6264 100644 --- a/src/test/claimtriebranching_tests.cpp +++ b/src/test/claimtriebranching_tests.cpp @@ -24,37 +24,37 @@ using namespace std; BOOST_FIXTURE_TEST_SUITE(claimtriebranching_tests, RegTestingSetup) -//is a claim in queue +//is a claim in queue boost::test_tools::predicate_result is_claim_in_queue(std::string name, const CTransaction &tx) { COutPoint outPoint(tx.GetHash(), 0); - int validAtHeight; - bool have_claim = pclaimTrie->haveClaimInQueue(name, outPoint, validAtHeight); + int validAtHeight; + bool have_claim = pclaimTrie->haveClaimInQueue(name,outPoint,validAtHeight); if (have_claim){ return true; } else{ boost::test_tools::predicate_result res(false); - res.message() << "Is not a claim in queue."; + res.message()<<"Is not a claim in queue."; return res; } } -// check if tx is best claim based on outpoint +// check if tx is best claim based on outpoint boost::test_tools::predicate_result is_best_claim(std::string name, const CTransaction &tx) { CClaimValue val; COutPoint outPoint(tx.GetHash(), 0); - bool have_claim = pclaimTrie->haveClaim(name, outPoint); + bool have_claim = pclaimTrie->haveClaim(name,outPoint); bool have_info = pclaimTrie->getInfoForName(name, val); if (have_claim && have_info && val.outPoint == outPoint){ return true; } else{ boost::test_tools::predicate_result res(false); - res.message() << "Is not best claim"; + res.message()<<"Is not best claim"; return res; } } @@ -111,15 +111,56 @@ CMutableTransaction BuildTransaction(const CMutableTransaction& prev, uint32_t p return tx; } +bool CreateBlock(CBlockTemplate* pblocktemplate) +{ + static int unique_block_counter = 0; + CBlock* pblock = &pblocktemplate->block; + pblock->nVersion = 1; + pblock->nTime = chainActive.Tip()->GetBlockTime()+Params().GetConsensus().nPowTargetSpacing; + CMutableTransaction txCoinbase(pblock->vtx[0]); + txCoinbase.vin[0].scriptSig = CScript() << CScriptNum(unique_block_counter++) << CScriptNum(chainActive.Height()); + txCoinbase.vout[0].nValue = GetBlockSubsidy(chainActive.Height() + 1, Params().GetConsensus()); + pblock->vtx[0] = CTransaction(txCoinbase); + pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); + for (uint32_t i = 0;; ++i) { + pblock->nNonce = i; + if (CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus())) + { + break; + } + } + CValidationState state; + bool success = (ProcessNewBlock(state, Params(), NULL, pblock, true, NULL) && state.IsValid() && pblock->GetHash() == chainActive.Tip()->GetBlockHash()); + pblock->hashPrevBlock = pblock->GetHash(); + return success; -// Test Fixtures +} + +bool CreateCoinbases(unsigned int num_coinbases, std::vector& coinbases) +{ + CBlockTemplate *pblocktemplate; + coinbases.clear(); + BOOST_CHECK(pblocktemplate = CreateNewBlock(Params(), CScript()<block.vtx.size() == 1); + pblocktemplate->block.hashPrevBlock = chainActive.Tip()->GetBlockHash(); + for (unsigned int i = 0; i < 100 + num_coinbases; ++i) + { + BOOST_CHECK(CreateBlock(pblocktemplate)); + if (coinbases.size() < num_coinbases) + coinbases.push_back(CTransaction(pblocktemplate->block.vtx[0])); + } + delete pblocktemplate; + return true; +} + + +// Test Fixtures struct ClaimTrieChainFixture{ std::vector coinbase_txs; std::vector marks; - int coinbase_txs_used; - int unique_block_counter; - unsigned int num_txs; - unsigned int num_txs_for_next_block; + int coinbase_txs_used; + unsigned int num_txs; + unsigned int num_txs_for_next_block; // these will take on regtest parameters const int expirationForkHeight; @@ -135,11 +176,9 @@ struct ClaimTrieChainFixture{ fRequireStandard = false; ENTER_CRITICAL_SECTION(cs_main); BOOST_CHECK(pclaimTrie->nCurrentHeight == chainActive.Height() + 1); - pclaimTrie->setExpirationTime(originalExpiration); // in case it was changed during the test num_txs_for_next_block = 0; - num_txs = 0; + num_txs = 0; coinbase_txs_used = 0; - unique_block_counter = 0; // generate coinbases to spend CreateCoinbases(40, coinbase_txs); } @@ -150,43 +189,6 @@ struct ClaimTrieChainFixture{ LEAVE_CRITICAL_SECTION(cs_main); } - bool CreateBlock(CBlockTemplate* pblocktemplate) - { - CBlock* pblock = &pblocktemplate->block; - pblock->nVersion = 1; - pblock->nTime = chainActive.Tip()->GetBlockTime() + Params().GetConsensus().nPowTargetSpacing; - CMutableTransaction txCoinbase(pblock->vtx[0]); - txCoinbase.vin[0].scriptSig = CScript() << CScriptNum(unique_block_counter++) << CScriptNum(chainActive.Height()); - txCoinbase.vout[0].nValue = GetBlockSubsidy(chainActive.Height() + 1, Params().GetConsensus()); - pblock->vtx[0] = CTransaction(txCoinbase); - pblock->hashMerkleRoot = BlockMerkleRoot(*pblock); - for (uint32_t i = 0;; ++i) { - pblock->nNonce = i; - if (CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus())) { - break; - } - } - CValidationState state; - bool success = (ProcessNewBlock(state, Params(), NULL, pblock, true, NULL) && state.IsValid() && pblock->GetHash() == chainActive.Tip()->GetBlockHash()); - pblock->hashPrevBlock = pblock->GetHash(); - return success; - } - - bool CreateCoinbases(unsigned int num_coinbases, std::vector& coinbases) - { - CBlockTemplate* pblocktemplate; - coinbases.clear(); - BOOST_CHECK(pblocktemplate = CreateNewBlock(Params(), CScript() << OP_TRUE)); - BOOST_CHECK(pblocktemplate->block.vtx.size() == 1); - pblocktemplate->block.hashPrevBlock = chainActive.Tip()->GetBlockHash(); - for (unsigned int i = 0; i < 100 + num_coinbases; ++i) { - BOOST_CHECK(CreateBlock(pblocktemplate)); - if (coinbases.size() < num_coinbases) - coinbases.push_back(CTransaction(pblocktemplate->block.vtx[0])); - } - delete pblocktemplate; - return true; - } void CommitTx(CMutableTransaction &tx){ num_txs_for_next_block++; @@ -203,29 +205,30 @@ struct ClaimTrieChainFixture{ BOOST_CHECK(AcceptToMemoryPool(mempool, state, tx, false, &fMissingInputs, &txFeeRate)); } - //spend a bid into some non claimtrie related unspent + //spend a bid into some non claimtrie related unspent CMutableTransaction Spend(const CTransaction &prev){ uint32_t prevout = 0; - CMutableTransaction tx = BuildTransaction(prev, prevout); + CMutableTransaction tx = BuildTransaction(prev,prevout); tx.vout[0].scriptPubKey = CScript() << OP_TRUE; tx.vout[0].nValue = 1; - CommitTx(tx); - return tx; + CommitTx(tx); + return tx; } //make claim at the current block - CMutableTransaction MakeClaim(const CTransaction& prev, std::string name, std::string value, CAmount quantity) + CMutableTransaction MakeClaim(const CTransaction &prev, std::string name, std::string value, + CAmount quantity) { - uint32_t prevout = 0; + uint32_t prevout = 0; CMutableTransaction tx = BuildTransaction(prev,prevout); - tx.vout[0].scriptPubKey = ClaimNameScript(name, value); + tx.vout[0].scriptPubKey = ClaimNameScript(name,value); tx.vout[0].nValue = quantity; - CommitTx(tx); - return tx; + CommitTx(tx); + return tx; } CMutableTransaction MakeClaim(const CTransaction& prev, std::string name, std::string value) @@ -240,10 +243,10 @@ struct ClaimTrieChainFixture{ uint32_t prevout = 0; CMutableTransaction tx = BuildTransaction(prev,prevout); - tx.vout[0].scriptPubKey = SupportClaimScript(name, claimId); + tx.vout[0].scriptPubKey = SupportClaimScript(name,claimId); tx.vout[0].nValue = quantity; - CommitTx(tx); + CommitTx(tx); return tx; } @@ -254,10 +257,10 @@ struct ClaimTrieChainFixture{ uint32_t prevout = 0; CMutableTransaction tx = BuildTransaction(prev,prevout); - tx.vout[0].scriptPubKey = UpdateClaimScript(name, claimId, value); + tx.vout[0].scriptPubKey = UpdateClaimScript(name,claimId,value); tx.vout[0].nValue = quantity; - CommitTx(tx); + CommitTx(tx); return tx; } @@ -277,7 +280,7 @@ struct ClaimTrieChainFixture{ for (int i = 0; i < num_blocks; ++i) { CBlockTemplate *pblocktemplate; - CScript coinbase_scriptpubkey; + CScript coinbase_scriptpubkey; coinbase_scriptpubkey << CScriptNum(chainActive.Height()); BOOST_CHECK(pblocktemplate = CreateNewBlock(Params(), coinbase_scriptpubkey)); BOOST_CHECK(pblocktemplate->block.vtx.size() == num_txs_for_next_block+1); @@ -335,8 +338,8 @@ struct ClaimTrieChainFixture{ there is a competing bid inserted same height check the greater one wins - quantity is same, check outpoint greater wins - there is an existing competing bid - check that rules for delays are observed + there is an existing competing bid + check that rules for delays are observed check that a greater amount wins check that a smaller amount does not win @@ -351,7 +354,7 @@ BOOST_AUTO_TEST_CASE(claim_test) fixture.DecrementBlocks(1); BOOST_CHECK(!is_best_claim("test",tx1)); - + // there is a competing bid inserted same height CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); @@ -359,34 +362,34 @@ BOOST_AUTO_TEST_CASE(claim_test) BOOST_CHECK(is_best_claim("test",tx3)); BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size()); - fixture.DecrementBlocks(1); + fixture.DecrementBlocks(1); BOOST_CHECK(!is_best_claim("test",tx2)); BOOST_CHECK(!is_best_claim("test",tx3)); BOOST_CHECK_EQUAL(0U, pclaimTrie->getClaimsForName("test").claims.size()); - // make two claims , one older + // make two claims , one older CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); - fixture.IncrementBlocks(1); + fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx4)); CMutableTransaction tx5 = fixture.MakeClaim(fixture.GetCoinbase(),"test","two",1); fixture.IncrementBlocks(1); BOOST_CHECK(is_claim_in_queue("test",tx5)); - BOOST_CHECK(is_best_claim("test", tx4)); + BOOST_CHECK(is_best_claim("test",tx4)); fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx4)); BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size()); - fixture.DecrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx4)); + fixture.DecrementBlocks(1); + BOOST_CHECK(is_best_claim("test",tx4)); BOOST_CHECK(is_claim_in_queue("test",tx5)); - fixture.DecrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx4)); + fixture.DecrementBlocks(1); + BOOST_CHECK(is_best_claim("test",tx4)); fixture.DecrementBlocks(1); // check claim takeover, note that CClaimTrie.nProportionalDelayFactor is set to 1 // instead of 32 in test_bitcoin.cpp CMutableTransaction tx6 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); - fixture.IncrementBlocks(10); + fixture.IncrementBlocks(10); BOOST_CHECK(is_best_claim("test",tx6)); CMutableTransaction tx7 = fixture.MakeClaim(fixture.GetCoinbase(),"test","two",2); fixture.IncrementBlocks(1); @@ -398,7 +401,7 @@ BOOST_AUTO_TEST_CASE(claim_test) fixture.DecrementBlocks(10); BOOST_CHECK(is_claim_in_queue("test",tx7)); - BOOST_CHECK(is_best_claim("test", tx6)); + BOOST_CHECK(is_best_claim("test",tx6)); fixture.DecrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx6)); fixture.DecrementBlocks(10); @@ -406,26 +409,26 @@ BOOST_AUTO_TEST_CASE(claim_test) /* spent claims - spending winning claim will make losing active claim winner + spending winning claim will make losing active claim winner spending winning claim will make inactive claim winner - spending winning claim will empty out claim trie + spending winning claim will empty out claim trie */ BOOST_AUTO_TEST_CASE(spend_claim_test) { ClaimTrieChainFixture fixture; - // spending winning claim will make losing active claim winner + // spending winning claim will make losing active claim winner CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx1)); + BOOST_CHECK(is_best_claim("test",tx1)); fixture.Spend(tx1); fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx2)); - - fixture.DecrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx1)); + BOOST_CHECK(is_best_claim("test",tx2)); + fixture.DecrementBlocks(1); + BOOST_CHECK(is_best_claim("test",tx1)); + fixture.DecrementBlocks(1); // spending winning claim will make inactive claim winner @@ -433,7 +436,7 @@ BOOST_AUTO_TEST_CASE(spend_claim_test) fixture.IncrementBlocks(10); BOOST_CHECK(is_best_claim("test",tx3)); CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); - fixture.IncrementBlocks(1); + fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx3)); fixture.Spend(tx3); fixture.IncrementBlocks(1); @@ -446,7 +449,7 @@ BOOST_AUTO_TEST_CASE(spend_claim_test) fixture.DecrementBlocks(10); - //spending winning claim will empty out claim trie + //spending winning claim will empty out claim trie CMutableTransaction tx5 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx5)); @@ -463,14 +466,14 @@ BOOST_AUTO_TEST_CASE(spend_claim_test) /* supports - check support with wrong name does not work + check support with wrong name does not work check claim with more support wins - check support delay + check support delay */ BOOST_AUTO_TEST_CASE(support_test) { ClaimTrieChainFixture fixture; - // check claim with more support wins + // check claim with more support wins CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),tx1,"test",1); @@ -480,13 +483,13 @@ BOOST_AUTO_TEST_CASE(support_test) BOOST_CHECK(best_claim_effective_amount_equals("test",11)); fixture.DecrementBlocks(1); - // check support delay + // check support delay CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","two",2); fixture.IncrementBlocks(10); BOOST_CHECK(is_best_claim("test",tx4)); BOOST_CHECK(best_claim_effective_amount_equals("test",2)); - CMutableTransaction s4 = fixture.MakeSupport(fixture.GetCoinbase(), tx3, "test", 10); //10 delay + CMutableTransaction s4 = fixture.MakeSupport(fixture.GetCoinbase(),tx3,"test",10); //10 delay fixture.IncrementBlocks(10); BOOST_CHECK(is_best_claim("test",tx4)); BOOST_CHECK(best_claim_effective_amount_equals("test",2)); @@ -498,7 +501,7 @@ BOOST_AUTO_TEST_CASE(support_test) BOOST_CHECK(is_best_claim("test",tx4)); BOOST_CHECK(best_claim_effective_amount_equals("test",2)); fixture.DecrementBlocks(10); - BOOST_CHECK(is_best_claim("test", tx4)); + BOOST_CHECK(is_best_claim("test",tx4)); BOOST_CHECK(best_claim_effective_amount_equals("test",2)); fixture.DecrementBlocks(10); } @@ -569,7 +572,7 @@ BOOST_AUTO_TEST_CASE(update_on_support_test) support spend spending suport on winning claim will cause it to lose - spending a support on txin[i] where i is not 0 + spending a support on txin[i] where i is not 0 */ BOOST_AUTO_TEST_CASE(support_spend_test) { @@ -579,7 +582,7 @@ BOOST_AUTO_TEST_CASE(support_spend_test) CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),tx1,"test",2); fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx1)); + BOOST_CHECK(is_best_claim("test",tx1)); CMutableTransaction sp1 = fixture.Spend(s1); fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx2)); @@ -588,8 +591,8 @@ BOOST_AUTO_TEST_CASE(support_spend_test) BOOST_CHECK(is_best_claim("test",tx1)); fixture.DecrementBlocks(1); - // spend a support on txin[i] where i is not 0 - + // spend a support on txin[i] where i is not 0 + CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"x","one",3); CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","two",2); CMutableTransaction tx5 = fixture.MakeClaim(fixture.GetCoinbase(),"test","three",1); @@ -598,7 +601,7 @@ BOOST_AUTO_TEST_CASE(support_spend_test) BOOST_CHECK(is_best_claim("test",tx5)); BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size()); - // build the spend where s2 is sppent on txin[1] and tx3 is spent on txin[0] + // build the spend where s2 is sppent on txin[1] and tx3 is spent on txin[0] uint32_t prevout = 0; CMutableTransaction tx; tx.nVersion = 1; @@ -616,40 +619,40 @@ BOOST_AUTO_TEST_CASE(support_spend_test) tx.vout[0].scriptPubKey = CScript() << OP_TRUE; tx.vout[0].nValue = 1; - fixture.CommitTx(tx); + fixture.CommitTx(tx); fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx4)); + BOOST_CHECK(is_best_claim("test",tx4)); fixture.DecrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx5)); } /* update update preserves claim id - update preserves supports + update preserves supports winning update on winning claim happens without delay losing update on winning claim happens without delay update on losing claim happens with delay , and wins - - + + */ BOOST_AUTO_TEST_CASE(claimtrie_update_test) { - //update preserves claim id + //update preserves claim id ClaimTrieChainFixture fixture; CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); - CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "one", ClaimIdHash(tx1.GetHash(), 0), 2); + CMutableTransaction u1 = fixture.MakeUpdate(tx1,"test","one",ClaimIdHash(tx1.GetHash(),0),2); fixture.IncrementBlocks(1); - CClaimValue val; + CClaimValue val; pclaimTrie->getInfoForName("test",val); BOOST_CHECK(val.claimId == ClaimIdHash(tx1.GetHash(),0)); BOOST_CHECK(is_best_claim("test",u1)); - fixture.DecrementBlocks(1); - + fixture.DecrementBlocks(1); + // update preserves supports CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); - CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(), tx2, "test", 1); - CMutableTransaction u2 = fixture.MakeUpdate(tx2, "test", "one", ClaimIdHash(tx2.GetHash(), 0), 1); + CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),tx2,"test",1); + CMutableTransaction u2 = fixture.MakeUpdate(tx2,"test","one",ClaimIdHash(tx2.GetHash(),0),1); fixture.IncrementBlocks(1); BOOST_CHECK(best_claim_effective_amount_equals("test",2)); fixture.DecrementBlocks(1); @@ -658,7 +661,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test) CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); fixture.IncrementBlocks(10); - CMutableTransaction u3 = fixture.MakeUpdate(tx3, "test", "one", ClaimIdHash(tx3.GetHash(), 0), 2); + CMutableTransaction u3 = fixture.MakeUpdate(tx3,"test","one",ClaimIdHash(tx3.GetHash(),0),2); fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",u3)); BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size()); @@ -675,14 +678,14 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test) BOOST_CHECK(is_best_claim("test",tx6)); fixture.DecrementBlocks(1); - BOOST_CHECK(is_best_claim("test", tx5)); + BOOST_CHECK(is_best_claim("test",tx5)); fixture.DecrementBlocks(10); // update on losing claim happens with delay , and wins CMutableTransaction tx7 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",3); CMutableTransaction tx8 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2); fixture.IncrementBlocks(10); - BOOST_CHECK(is_best_claim("test", tx7)); + BOOST_CHECK(is_best_claim("test",tx7)); CMutableTransaction tx; tx.nVersion = 1; @@ -699,7 +702,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test) tx.vin[1].nSequence = std::numeric_limits::max(); tx.vout[0].scriptPubKey = UpdateClaimScript("test",ClaimIdHash(tx8.GetHash(),0),"one"); tx.vout[0].nValue = 4; - fixture.CommitTx(tx); + fixture.CommitTx(tx); fixture.IncrementBlocks(1); BOOST_CHECK(is_best_claim("test",tx7)); @@ -715,7 +718,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test) expiration check claims expire and loses claim check claims expire and is not updateable (may be changed in future soft fork) - check supports expire and can cause supported bid to lose claim + check supports expire and can cause supported bid to lose claim */ BOOST_AUTO_TEST_CASE(claimtrie_expire_test) { @@ -974,7 +977,7 @@ BOOST_AUTO_TEST_CASE(hardfork_support_test) ClaimTrieChainFixture fixture; int blocks_before_fork = 10; - fixture.IncrementBlocks(fixture.expirationForkHeight - chainActive.Height() - blocks_before_fork - 1); + fixture.IncrementBlocks(fixture.expirationForkHeight - chainActive.Height() - blocks_before_fork-1); // Create claim and support it before the fork height CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1); CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(),tx1,"test",2); @@ -1018,65 +1021,6 @@ BOOST_AUTO_TEST_CASE(hardfork_support_test) } -/* - activation_fall_through and supports_fall_through - Tests for where claims/supports in queues would be undone properly in a decrement. - See https://github.com/lbryio/lbrycrd/issues/243 for more details -*/ - -BOOST_AUTO_TEST_CASE(activations_fall_through) -{ - ClaimTrieChainFixture fixture; - - CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "1", 1); - fixture.IncrementBlocks(3); - BOOST_CHECK(pclaimTrie->nProportionalDelayFactor == 1); - CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "2", 3); - fixture.IncrementBlocks(1); - - BOOST_CHECK(is_best_claim("A", tx1)); - fixture.IncrementBlocks(3); - BOOST_CHECK(is_best_claim("A", tx2)); - fixture.DecrementBlocks(3); - fixture.Spend(tx1); // this will trigger early activation on tx2 claim - fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("A", tx2)); - fixture.DecrementBlocks(1); //reorg the early activation - BOOST_CHECK(is_best_claim("A", tx1)); - fixture.Spend(tx1); - fixture.IncrementBlocks(1); // this should not cause tx2 to activate again and crash - BOOST_CHECK(is_best_claim("A", tx2)); -} - -BOOST_AUTO_TEST_CASE(supports_fall_through) -{ - ClaimTrieChainFixture fixture; - - CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "1", 3); - CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "2", 1); - CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "3", 2); - fixture.IncrementBlocks(3); - BOOST_CHECK(pclaimTrie->nProportionalDelayFactor == 1); - CMutableTransaction sx2 = fixture.MakeSupport(fixture.GetCoinbase(), tx2, "A", 3); - fixture.IncrementBlocks(1); - - BOOST_CHECK(is_best_claim("A", tx1)); - fixture.IncrementBlocks(3); - BOOST_CHECK(is_best_claim("A", tx2)); - fixture.DecrementBlocks(3); - fixture.Spend(tx1); // this will trigger early activation - fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("A", tx2)); - fixture.DecrementBlocks(1); // reorg the early activation - BOOST_CHECK(is_best_claim("A", tx1)); - fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("A", tx1)); //tx2 support should not be active - fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("A", tx1)); //tx2 support should not be active - fixture.IncrementBlocks(1); - BOOST_CHECK(is_best_claim("A", tx2)); //tx2 support should be active now -} - /* claim/support expiration for hard fork, but with checks for disk procedures */ @@ -1956,29 +1900,6 @@ BOOST_AUTO_TEST_CASE(claimtrienode_serialize_unserialize) BOOST_CHECK(n1 == n2); } -BOOST_AUTO_TEST_CASE(claimtrienode_remove_invalid_claim) -{ - uint160 hash160; - - CClaimTrieNode n1; - CClaimTrieNode n2; - CClaimValue throwaway; - - CClaimValue v1(COutPoint(uint256S("0000000000000000000000000000000000000000000000000000000000000001"), 0), hash160, 50, 0, 100); - CClaimValue v2(COutPoint(uint256S("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), 1), hash160, 100, 1, 101); - - n1.insertClaim(v1); - - n2.insertClaim(v2); - - bool invalidClaim = n2.removeClaim(v1.outPoint, throwaway); - BOOST_CHECK(invalidClaim == false); - - invalidClaim = n1.removeClaim(v2.outPoint, throwaway); - BOOST_CHECK(invalidClaim == false); -} - - BOOST_AUTO_TEST_CASE(invalid_claimid_test) { ClaimTrieChainFixture fixture; @@ -3457,4 +3378,37 @@ BOOST_AUTO_TEST_CASE(claim_rpcs_rollback3_test) BOOST_CHECK(valueResults["amount"].get_int() == 3); } +BOOST_AUTO_TEST_CASE(claim_rpcs_pending_effective_amount_test) +{ + ClaimTrieChainFixture fixture; + std::string sName1("test"); + std::string sValue1("test1"); + std::string sValue2("test2"); + + rpcfn_type getclaimsforname = tableRPC["getclaimsforname"]->actor; + + UniValue claims; + UniValue params(UniValue::VARR); + params.push_back(UniValue(sName1)); + + CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue1, 1); + fixture.IncrementBlocks(1); + + CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, sValue2, 2); + fixture.IncrementBlocks(1); + + claims = getclaimsforname(params, false)["claims"]; + BOOST_CHECK(claims.size() == 2U); + BOOST_CHECK(claims[0]["nEffectiveAmount"].get_int() == 0); + BOOST_CHECK(claims[0].exists("nPendingEffectiveAmount")); + BOOST_CHECK(claims[0]["nPendingEffectiveAmount"].get_int() == 2); + + fixture.IncrementBlocks(1); + + claims = getclaimsforname(params, false)["claims"]; + BOOST_CHECK(claims.size() == 2U); + BOOST_CHECK(claims[0]["nEffectiveAmount"].get_int() == 2); + BOOST_CHECK(!claims[0].exists("nPendingEffectiveAmount")); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/claimtriecache_tests.cpp b/src/test/claimtriecache_tests.cpp index aa06fd19e..52d0e8fc6 100644 --- a/src/test/claimtriecache_tests.cpp +++ b/src/test/claimtriecache_tests.cpp @@ -274,58 +274,5 @@ BOOST_AUTO_TEST_CASE(recursive_prune_test) BOOST_CHECK_EQUAL(0, it->second->children.size()); } -BOOST_AUTO_TEST_CASE(iteratetrie_test) -{ - BOOST_CHECK(pclaimTrie->empty()); - CClaimTrieCacheTest ctc(pclaimTrie); - - uint256 hash0(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); - CMutableTransaction tx1 = BuildTransaction(hash0); - - const uint256 txhash = tx1.GetHash(); - CClaimValue claimVal(COutPoint(txhash, 0), ClaimIdHash(txhash, 0), CAmount(10), 0, 0); - ctc.insertClaimIntoTrie("test", claimVal); - - - int count = 0; - - struct TestCallBack : public CNodeCallback { - TestCallBack(int& count) : count(count) - { - } - - void visit(const std::string& name, const CClaimTrieNode* node) - { - count++; - if (name == "test") { - BOOST_CHECK(node->claims.size() == 1); - } - } - - int& count; - } testCallback(count); - - BOOST_CHECK(ctc.iterateTrie(testCallback)); - BOOST_CHECK(count == 5); - - count = 3; - - struct TestCallBack2 : public CNodeCallback { - TestCallBack2(int& count) : count(count) - { - } - - void visit(const std::string& name, const CClaimTrieNode* node) - { - if (--count <= 0) - throw CRecursionInterruptionException(false); - } - - int& count; - } testCallback2(count); - - BOOST_CHECK(!ctc.iterateTrie(testCallback2)); - BOOST_CHECK(count == 0); -} BOOST_AUTO_TEST_SUITE_END() diff --git a/src/txdb.h b/src/txdb.h index 9186aab61..749802f0e 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -20,7 +20,7 @@ struct CDiskTxPos; class uint256; //! -dbcache default (MiB) -static const int64_t nDefaultDbCache = sizeof(void*) > 4 ? 700 : 500; +static const int64_t nDefaultDbCache = 100; //! max. -dbcache in (MiB) static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024; //! min. -dbcache in (MiB)