diff --git a/src/claimtrie.cpp b/src/claimtrie.cpp index 0b108f5a0..a2b0109be 100644 --- a/src/claimtrie.cpp +++ b/src/claimtrie.cpp @@ -113,7 +113,7 @@ void CClaimTrieNode::reorderClaims(supportMapEntryType& supports) { for (itclaim = claims.begin(); itclaim != claims.end(); ++itclaim) { - if (itsupport->supportTxhash == itclaim->txhash && itsupport->supportnOut == itclaim->nOut) + if (itsupport->supportedClaimId == itclaim->claimId) { itclaim->nEffectiveAmount += itsupport->nAmount; break; @@ -1360,35 +1360,29 @@ claimQueueNamesType::iterator CClaimTrieCache::getQueueCacheNameRow(const std::s return itQueueNameRow; } -bool CClaimTrieCache::addClaim(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight) const +bool CClaimTrieCache::addClaim(const std::string name, uint256 txhash, uint32_t nOut, uint160 claimId, CAmount nAmount, int nHeight) 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(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); + LogPrintf("%s: name: %s, txhash: %s, nOut: %d, claimId: %s, nAmount: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, claimId.GetHex(), nAmount, nHeight, nCurrentHeight); assert(nHeight == nCurrentHeight); CClaimValue currentClaim; - if (base->getInfoForName(name, currentClaim)) + int delayForClaim; + if (base->getInfoForName(name, currentClaim) && currentClaim.claimId == claimId) { - 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); - CClaimValue newClaim(txhash, nOut, nAmount, nHeight, nHeight, prevTxhash, nPrevOut); - return addClaimToQueues(name, newClaim); - } + LogPrintf("%s: This is an update to a best claim.\n", __func__); + delayForClaim = 0; } - return addClaim(name, txhash, nOut, nAmount, nHeight); + else + { + delayForClaim = getDelayForName(name); + } + CClaimValue newClaim(txhash, nOut, claimId, nAmount, nHeight, nHeight + delayForClaim); + return addClaimToQueues(name, newClaim); } -bool CClaimTrieCache::undoSpendClaim(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, int nValidAtHeight) const +bool CClaimTrieCache::undoSpendClaim(const std::string name, uint256 txhash, uint32_t nOut, uint160 claimId, 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); + LogPrintf("%s: name: %s, txhash: %s, nOut: %d, claimId: %s, nAmount: %d, nHeight: %d, nValidAtHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, claimId.GetHex(), nAmount, nHeight, nValidAtHeight, nCurrentHeight); + CClaimValue claim(txhash, nOut, claimId, nAmount, nHeight, nValidAtHeight); if (nValidAtHeight < nCurrentHeight) { claimQueueEntryType entry(name, claim); @@ -1625,7 +1619,7 @@ bool CClaimTrieCache::insertSupportIntoMap(const std::string name, CSupportValue 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, bool fCheckTakeover) const +bool CClaimTrieCache::removeSupportFromMap(const std::string name, uint256 txhash, uint32_t nOut, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const { supportMapType::iterator cachedNode; cachedNode = supportCache.find(name); @@ -1645,7 +1639,7 @@ bool CClaimTrieCache::removeSupportFromMap(const std::string name, uint256 txhas supportMapEntryType::iterator itSupport; for (itSupport = cachedNode->second.begin(); itSupport != cachedNode->second.end(); ++itSupport) { - if (itSupport->txhash == txhash && itSupport->nOut == nOut && itSupport->supportTxhash == supportedTxhash && itSupport->supportnOut == supportednOut && itSupport->nHeight == nHeight) + if (itSupport->txhash == txhash && itSupport->nOut == nOut && itSupport->nHeight == nHeight) { nValidAtHeight = itSupport->nValidAtHeight; break; @@ -1701,10 +1695,10 @@ supportQueueNamesType::iterator CClaimTrieCache::getSupportQueueCacheNameRow(con return itQueueNameRow; } -bool CClaimTrieCache::addSupportToQueue(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int nValidAtHeight) const +bool CClaimTrieCache::addSupportToQueue(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, uint160 supportedClaimId, int nHeight, int nValidAtHeight) const { LogPrintf("%s: nValidAtHeight: %d\n", __func__, nValidAtHeight); - CSupportValue support(txhash, nOut, supportedTxhash, supportednOut, nAmount, nHeight, nValidAtHeight); + CSupportValue support(txhash, nOut, supportedClaimId, nAmount, nHeight, nValidAtHeight); supportQueueEntryType entry(name, support); supportQueueType::iterator itQueueRow = getSupportQueueCacheRow(nValidAtHeight, true); supportQueueNamesType::iterator itQueueNameRow = getSupportQueueCacheNameRow(name, true); @@ -1713,7 +1707,7 @@ bool CClaimTrieCache::addSupportToQueue(const std::string name, uint256 txhash, return true; } -bool CClaimTrieCache::removeSupportFromQueue(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int& nValidAtHeight) const +bool CClaimTrieCache::removeSupportFromQueue(const std::string name, uint256 txhash, uint32_t nOut, int& nValidAtHeight) const { supportQueueNamesType::iterator itQueueNameRow = getSupportQueueCacheNameRow(name, false); if (itQueueNameRow == supportQueueNameCache.end()) @@ -1723,7 +1717,7 @@ bool CClaimTrieCache::removeSupportFromQueue(const std::string name, uint256 txh std::vector::iterator itQueueName; for (itQueueName = itQueueNameRow->second.begin(); itQueueName != itQueueNameRow->second.end(); ++itQueueName) { - if (itQueueName->txhash == txhash && itQueueName->nOut == nOut && itQueueName->supportTxhash == supportedTxhash && itQueueName->supportnOut == supportednOut) + if (itQueueName->txhash == txhash && itQueueName->nOut == nOut) { nValidAtHeight = itQueueName->nValidAtHeight; break; @@ -1740,7 +1734,7 @@ bool CClaimTrieCache::removeSupportFromQueue(const std::string name, uint256 txh for (itQueue = itQueueRow->second.begin(); itQueue != itQueueRow->second.end(); ++itQueue) { CSupportValue& support = itQueue->second; - if (name == itQueue->first && support.txhash == txhash && support.nOut == nOut && support.supportTxhash == supportedTxhash && support.supportnOut == supportednOut) + if (name == itQueue->first && support.txhash == txhash && support.nOut == nOut) { nValidAtHeight = support.nValidAtHeight; break; @@ -1757,58 +1751,58 @@ bool CClaimTrieCache::removeSupportFromQueue(const std::string name, uint256 txh return false; } -bool CClaimTrieCache::addSupport(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, uint256 supportedTxhash, uint32_t supportednOut, int nHeight) const +bool CClaimTrieCache::addSupport(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, uint160 supportedClaimId, int nHeight) const { - LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, supportedTxhash: %s, supportednOut: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, supportedTxhash.GetHex(), supportednOut, nHeight, nCurrentHeight); + LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, supportedClaimId: %s, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, supportedClaimId.GetHex(), nHeight, nCurrentHeight); assert(nHeight == nCurrentHeight); CClaimValue claim; if (base->getInfoForName(name, claim)) { - if (claim.txhash == supportedTxhash && claim.nOut == supportednOut) + if (claim.claimId == supportedClaimId) { LogPrintf("%s: This is a support to a best claim.\n", __func__); - return addSupportToQueue(name, txhash, nOut, nAmount, supportedTxhash, supportednOut, nHeight, nHeight); + return addSupportToQueue(name, txhash, nOut, nAmount, supportedClaimId, nHeight, nHeight); } } - return addSupportToQueue(name, txhash, nOut, nAmount, supportedTxhash, supportednOut, nHeight, nHeight + getDelayForName(name)); + return addSupportToQueue(name, txhash, nOut, nAmount, supportedClaimId, nHeight, nHeight + getDelayForName(name)); } -bool CClaimTrieCache::undoSpendSupport(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int nValidAtHeight) const +bool CClaimTrieCache::undoSpendSupport(const std::string name, uint256 txhash, uint32_t nOut, uint160 supportedClaimId, CAmount nAmount, int nHeight, int nValidAtHeight) const { - LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, supportedTxhash: %s, supportednOut: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, supportedTxhash.GetHex(), supportednOut, nHeight, nCurrentHeight); + LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nAmount: %d, supportedClaimId: %s, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nAmount, supportedClaimId.GetHex(), nHeight, nCurrentHeight); if (nValidAtHeight < nCurrentHeight) { - CSupportValue support(txhash, nOut, supportedTxhash, supportednOut, nAmount, nHeight, nValidAtHeight); + CSupportValue support(txhash, nOut, supportedClaimId, nAmount, nHeight, nValidAtHeight); supportQueueEntryType entry(name, support); return insertSupportIntoMap(name, support, false); } else { - return addSupportToQueue(name, txhash, nOut, nAmount, supportedTxhash, supportednOut, nHeight, nValidAtHeight); + return addSupportToQueue(name, txhash, nOut, nAmount, supportedClaimId, nHeight, nValidAtHeight); } } -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 CClaimTrieCache::removeSupport(const std::string name, uint256 txhash, uint32_t nOut, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const { bool removed = false; - if (removeSupportFromQueue(name, txhash, nOut, supportedTxhash, supportednOut, nValidAtHeight)) + if (removeSupportFromQueue(name, txhash, nOut, nValidAtHeight)) removed = true; - if (removed == false && removeSupportFromMap(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, nValidAtHeight, fCheckTakeover)) + if (removed == false && removeSupportFromMap(name, txhash, nOut, nHeight, nValidAtHeight, fCheckTakeover)) removed = true; return removed; } -bool CClaimTrieCache::undoAddSupport(const std::string name, uint256 txhash, uint32_t nOut, uint256 supportedTxhash, uint32_t supportednOut, int nHeight) const +bool CClaimTrieCache::undoAddSupport(const std::string name, uint256 txhash, uint32_t nOut, int nHeight) 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); + LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nHeight, nCurrentHeight); int throwaway; - return removeSupport(name, txhash, nOut, supportedTxhash, supportednOut, nHeight, throwaway, false); + return removeSupport(name, txhash, nOut, 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 +bool CClaimTrieCache::spendSupport(const std::string name, uint256 txhash, uint32_t nOut, 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, true); + LogPrintf("%s: name: %s, txhash: %s, nOut: %d, nHeight: %d, nCurrentHeight: %d\n", __func__, name, txhash.GetHex(), nOut, nHeight, nCurrentHeight); + return removeSupport(name, txhash, nOut, nHeight, nValidAtHeight, true); } bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo, std::vector >& takeoverHeightUndo) const @@ -1950,7 +1944,7 @@ bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRo } else if (claimInCache != claimInTrie) { - if (!claimInCache.fIsUpdate || claimInCache.updateToTxhash != claimInTrie.txhash || claimInCache.updateToNOut != claimInTrie.nOut) + if (claimInCache.claimId != claimInTrie.claimId) { takeoverHappened = true; } @@ -2086,7 +2080,7 @@ bool CClaimTrieCache::decrementBlock(claimQueueRowType& insertUndo, claimQueueRo { 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)); + assert(removeSupportFromMap(itSupportUndo->first, itSupportUndo->second.txhash, itSupportUndo->second.nOut, itSupportUndo->second.nHeight, nValidHeightInMap, false)); supportQueueNamesType::iterator itSupportNameRow = getSupportQueueCacheNameRow(itSupportUndo->first, true); itSupportRow->second.push_back(*itSupportUndo); itSupportNameRow->second.push_back(itSupportUndo->second); diff --git a/src/claimtrie.h b/src/claimtrie.h index e61bff834..79fbd6096 100644 --- a/src/claimtrie.h +++ b/src/claimtrie.h @@ -26,33 +26,19 @@ class CClaimValue public: uint256 txhash; uint32_t nOut; + uint160 claimId; CAmount nAmount; CAmount nEffectiveAmount; int nHeight; int nValidAtHeight; - bool fIsUpdate; - uint256 updateToTxhash; - uint32_t updateToNOut; - CClaimValue() {}; - CClaimValue(uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, + CClaimValue(uint256 txhash, uint32_t nOut, uint160 claimId, CAmount nAmount, int nHeight, int nValidAtHeight) - : txhash(txhash), nOut(nOut) + : txhash(txhash), nOut(nOut), claimId(claimId) , nAmount(nAmount), nEffectiveAmount(nAmount) , nHeight(nHeight), nValidAtHeight(nValidAtHeight) - , fIsUpdate(false) - {} - - CClaimValue(uint256 txhash, uint32_t nOut, CAmount nAmount, int nHeight, - int nValidAtHeight, uint256 updateToTxhash, - uint32_t updateToNOut) - : txhash(txhash), nOut(nOut) - , nAmount(nAmount), nEffectiveAmount(nAmount) - , nHeight(nHeight), nValidAtHeight(nValidAtHeight) - , fIsUpdate(true), updateToTxhash(updateToTxhash) - , updateToNOut(updateToNOut) {} uint256 GetHash() const; @@ -63,6 +49,7 @@ public: inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(txhash); READWRITE(nOut); + READWRITE(claimId); READWRITE(nAmount); READWRITE(nHeight); READWRITE(nValidAtHeight); @@ -90,7 +77,7 @@ public: bool operator==(const CClaimValue& other) const { - return txhash == other.txhash && nOut == other.nOut && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight; + return txhash == other.txhash && nOut == other.nOut && claimId == other.claimId && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight; } bool operator!=(const CClaimValue& other) const @@ -104,19 +91,16 @@ class CSupportValue public: uint256 txhash; uint32_t nOut; - uint256 supportTxhash; - uint32_t supportnOut; + uint160 supportedClaimId; CAmount nAmount; int nHeight; int nValidAtHeight; CSupportValue() {}; - CSupportValue(uint256 txhash, uint32_t nOut, uint256 supportTxhash, - uint32_t supportnOut, CAmount nAmount, int nHeight, - int nValidAtHeight) + CSupportValue(uint256 txhash, uint32_t nOut, uint160 supportedClaimId, + CAmount nAmount, int nHeight, int nValidAtHeight) : txhash(txhash), nOut(nOut) - , supportTxhash(supportTxhash) - , supportnOut(supportnOut), nAmount(nAmount) + , supportedClaimId(supportedClaimId), nAmount(nAmount) , nHeight(nHeight), nValidAtHeight(nValidAtHeight) {} @@ -126,8 +110,7 @@ public: inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { READWRITE(txhash); READWRITE(nOut); - READWRITE(supportTxhash); - READWRITE(supportnOut); + READWRITE(supportedClaimId); READWRITE(nAmount); READWRITE(nHeight); READWRITE(nValidAtHeight); @@ -135,7 +118,7 @@ public: bool operator==(const CSupportValue& other) const { - return txhash == other.txhash && nOut == other.nOut && supportTxhash == other.supportTxhash && supportnOut == other.supportnOut && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight; + return txhash == other.txhash && nOut == other.nOut && supportedClaimId == other.supportedClaimId && nAmount == other.nAmount && nHeight == other.nHeight && nValidAtHeight == other.nValidAtHeight; } bool operator!=(const CSupportValue& other) const { @@ -360,31 +343,25 @@ public: bool dirty() const { return !dirtyHashes.empty(); } bool addClaim(const std::string name, uint256 txhash, uint32_t nOut, - CAmount nAmount, int nHeight) const; - bool addClaim(const std::string name, uint256 txhash, uint32_t nOut, - CAmount nAmount, int nHeight, uint256 prevTxhash, - uint32_t nPrevOut) const; + uint160 claimId, CAmount nAmount, int nHeight) const; bool undoAddClaim(const std::string name, uint256 txhash, uint32_t nOut, int nHeight) const; bool spendClaim(const std::string name, uint256 txhash, uint32_t nOut, int nHeight, int& nValidAtHeight) const; bool undoSpendClaim(const std::string name, uint256 txhash, uint32_t nOut, - CAmount nAmount, int nHeight, + uint160 claimId, CAmount nAmount, int nHeight, int nValidAtHeight) const; bool addSupport(const std::string name, uint256 txhash, uint32_t nOut, - CAmount nAmount, uint256 supportedTxhash, - uint32_t supportednOut, int nHeight) const; + CAmount nAmount, uint160 supportedClaimId, + int nHeight) const; bool undoAddSupport(const std::string name, uint256 txhash, uint32_t nOut, - uint256 supportedTxhash, uint32_t supportednOut, int nHeight) const; bool spendSupport(const std::string name, uint256 txhash, uint32_t nOut, - uint256 supportedTxhash, uint32_t supportednOut, int nHeight, int& nValidAtHeight) const; bool undoSpendSupport(const std::string name, uint256 txhash, - uint32_t nOut, CAmount nAmount, - uint256 supportedTxhash, uint32_t supportednOut, - int nHeight, int nValidAtHeight) const; + uint32_t nOut, uint160 supportedClaimId, + CAmount nAmount, int nHeight, int nValidAtHeight) const; uint256 getBestBlock(); void setBestBlock(const uint256& hashBlock); @@ -455,13 +432,11 @@ private: bool createIfNotExists) const; bool removeSupport(const std::string name, uint256 txhash, uint32_t nOut, - uint256 supportedTxhash, uint32_t supportednOut, 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, bool fCheckTakeover) const; + uint32_t nOut, int nHeight, int& nValidAtHeight, + bool fCheckTakeover) const; bool insertSupportIntoMap(const std::string name, CSupportValue support, @@ -474,12 +449,10 @@ private: bool addSupportToQueue(const std::string name, uint256 txhash, uint32_t nOut, CAmount nAmount, - uint256 supportedTxhash, uint32_t supportednOut, + uint160 supportedClaimId, int nHeight, int nValidAtHeight) const; bool removeSupportFromQueue(const std::string name, uint256 txhash, - uint32_t nOut, uint256 supportedTxhash, - uint32_t supportednOut, - int& nValidAtHeight) const; + uint32_t nOut, int& nValidAtHeight) const; bool getSupportsForName(const std::string name, supportMapEntryType& node) const; diff --git a/src/main.cpp b/src/main.cpp index fa06a87ab..353ca3466 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1539,17 +1539,27 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CClaimTr // restore claim if applicable int op; std::vector > vvchParams; - if (DecodeClaimScript(undo.txout.scriptPubKey, op, vvchParams)) + if (undo.fIsClaim && DecodeClaimScript(undo.txout.scriptPubKey, op, vvchParams)) { - if (op == OP_CLAIM_NAME) + if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) { - assert(vvchParams.size() == 2); + uint160 claimId; + if (op == OP_CLAIM_NAME) + { + assert(vvchParams.size() == 2); + claimId = ClaimIdHash(out.hash, out.n); + } + else if (op == OP_UPDATE_CLAIM) + { + assert(vvchParams.size() == 3); + claimId = uint160(vvchParams[1]); + } std::string name(vvchParams[0].begin(), vvchParams[0].end()); int nValidHeight = undo.nClaimValidHeight; if (nValidHeight > 0 && nValidHeight >= coins->nHeight) { LogPrintf("%s: (txid: %s, nOut: %d) Restoring %s to the claim trie due to a block being disconnected\n", __func__, out.hash.ToString(), out.n, name.c_str()); - if (!trieCache.undoSpendClaim(name, out.hash, out.n, undo.txout.nValue, coins->nHeight, nValidHeight)) + if (!trieCache.undoSpendClaim(name, out.hash, out.n, claimId, undo.txout.nValue, coins->nHeight, nValidHeight)) LogPrintf("%s: Something went wrong inserting the claim\n", __func__); } else @@ -1559,20 +1569,19 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CClaimTr } else if (op == OP_SUPPORT_CLAIM) { - assert(vvchParams.size() == 3); + assert(vvchParams.size() == 2); std::string name(vvchParams[0].begin(), vvchParams[0].end()); - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]); + uint160 supportedClaimId(vvchParams[1]); int nValidHeight = undo.nClaimValidHeight; if (nValidHeight > 0 && nValidHeight >= coins->nHeight) { - LogPrintf("%s: (txid: %s, nOut: %d) Restoring support for %s in txid %s nOut %d due to a block being disconnected\n", __func__, out.hash.ToString(), out.n, name, supportedTxid.ToString(), supportednOut); - if (!trieCache.undoSpendSupport(name, out.hash, out.n, undo.txout.nValue, supportedTxid, supportednOut, coins->nHeight, nValidHeight)) + LogPrintf("%s: (txid: %s, nOut: %d) Restoring support for %s in claimid %s due to a block being disconnected\n", __func__, out.hash.ToString(), out.n, name, supportedClaimId.ToString()); + if (!trieCache.undoSpendSupport(name, out.hash, out.n, supportedClaimId, undo.txout.nValue, coins->nHeight, nValidHeight)) LogPrintf("%s: Something went wrong inserting support for the claim\n", __func__); } else { - LogPrintf("%s: (txid: %s, nOut: %d) Not restoring support for %s in txid %s nOut %d because the support expired before it was spent\n", __func__, out.hash.ToString(), out.n, name, supportedTxid.ToString(), supportednOut); + LogPrintf("%s: (txid: %s, nOut: %d) Not restoring support for %s in claimid %s because the support expired before it was spent\n", __func__, out.hash.ToString(), out.n, name, supportedClaimId.ToString()); } } } @@ -1633,22 +1642,33 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI std::vector > vvchParams; if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams)) { - if (op == OP_CLAIM_NAME) + if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) { - assert(vvchParams.size() == 2); + uint160 claimId; + if (op == OP_CLAIM_NAME) + { + assert(vvchParams.size() == 2); + claimId = ClaimIdHash(hash, i); + } + else if (op == OP_UPDATE_CLAIM) + { + assert(vvchParams.size() == 3); + claimId = uint160(vvchParams[1]); + } std::string name(vvchParams[0].begin(), vvchParams[0].end()); - LogPrintf("%s: (txid: %s, nOut: %d) Removing %s from the claim trie due to its block being disconnected\n", __func__, hash.ToString(), i, name.c_str()); + 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, hash, i, pindex->nHeight)) - LogPrintf("%s: Something went wrong removing the name %s in hash %s\n", __func__, name.c_str(), hash.GetHex()); + { + LogPrintf("%s: Could not find the claim in the trie or the cache\n", __func__); + } } else if (op == OP_SUPPORT_CLAIM) { - assert(vvchParams.size() == 3); + assert(vvchParams.size() == 2); std::string name(vvchParams[0].begin(), vvchParams[0].end()); - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]);; - LogPrintf("%s: (txid: %s, nOut: %d) Removing support for %s from txid %s nOut %d due to its block being disconnected\n", __func__, hash.ToString(), i, supportedTxid.ToString(), supportednOut, name.c_str()); - if (!trieCache.undoAddSupport(name, hash, i, supportedTxid, supportednOut, pindex->nHeight)) + uint160 supportedClaimId(vvchParams[1]); + LogPrintf("%s: (txid: %s, nOut: %d) Removing support for claim id %s on %s due to its block being disconnected\n", __func__, hash.ToString(), i, supportedClaimId.ToString(), name.c_str()); + if (!trieCache.undoAddSupport(name, hash, i, pindex->nHeight)) LogPrintf("%s: Something went wrong removing support for name %s in hash %s\n", __func__, name.c_str(), hash.ToString()); } } @@ -1910,14 +1930,8 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // and then remove the name: (txhash, nOut) mapping from the map. // If there are two or more claims in the inputs with the same name, only // use the first. - // TODO: before releasing, see if it's a better idea to make an explicit - // operation for updating, like OP_UPDATE_NAME, which directly references - // the claim to be updated. It would only be necessary to add a single extra - // parameter to the operation, the input number, to exactly specify which - // claim is being updated. Then here it would just need to be checked if that - // input number was already used by an earlier tx.vout in the transaction. - typedef std::map > spentClaimsType; + typedef std::vector > spentClaimsType; spentClaimsType spentClaims; for (unsigned int i = 0; i < tx.vin.size(); ++i) @@ -1930,29 +1944,37 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin std::vector > vvchParams; if (DecodeClaimScript(coins->vout[txin.prevout.n].scriptPubKey, op, vvchParams)) { - if (op == OP_CLAIM_NAME) + if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) { - assert(vvchParams.size() == 2); + uint160 claimId; + if (op == OP_CLAIM_NAME) + { + assert(vvchParams.size() == 2); + claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n); + } + else if (op == OP_UPDATE_CLAIM) + { + assert(vvchParams.size() == 3); + claimId = uint160(vvchParams[1]); + } 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, txin.prevout.hash, txin.prevout.n, coins->nHeight, nValidAtHeight)) { mClaimUndoHeights[i] = nValidAtHeight; - std::pair val(txin.prevout.hash, txin.prevout.n); - std::pair > entry(name, val); - spentClaims.insert(entry); + std::pair entry(name, claimId); + spentClaims.push_back(entry); } } else if (op == OP_SUPPORT_CLAIM) { - assert(vvchParams.size() == 3); + assert(vvchParams.size() == 2); std::string name(vvchParams[0].begin(), vvchParams[0].end()); - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]);; + uint160 supportedClaimId(vvchParams[1]); int nValidAtHeight; - LogPrintf("%s: Removing support for %s in txid %s nOut %d. Tx: %s, nOut: %d\n", __func__, name, supportedTxid.ToString(), supportednOut, txin.prevout.hash.ToString(), txin.prevout.n); - if (trieCache.spendSupport(name, txin.prevout.hash, txin.prevout.n, supportedTxid, supportednOut, coins->nHeight, nValidAtHeight)) + LogPrintf("%s: Removing support for %s in %s. Tx: %s, nOut: %d\n", __func__, supportedClaimId.ToString(), name, txin.prevout.hash.ToString(), txin.prevout.n); + if (trieCache.spendSupport(name, txin.prevout.hash, txin.prevout.n, coins->nHeight, nValidAtHeight)) { mClaimUndoHeights[0] = nValidAtHeight; } @@ -1973,27 +1995,43 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin assert(vvchParams.size() == 2); std::string name(vvchParams[0].begin(), vvchParams[0].end()); LogPrintf("%s: Inserting %s into the claim trie. Tx: %s, nOut: %d\n", __func__, name, tx.GetHash().GetHex(), i); - spentClaimsType::iterator itSpent = spentClaims.find(name); - bool success; - if (itSpent != spentClaims.end()) + if (!trieCache.addClaim(name, tx.GetHash(), i, ClaimIdHash(tx.GetHash(), i), txout.nValue, pindex->nHeight)) { - LogPrintf("%s: Updating a previous transaction. Old tx: %s, old nOut: %d\n", __func__, itSpent->second.first.GetHex(), itSpent->second.second); - success = trieCache.addClaim(name, tx.GetHash(), i, txout.nValue, pindex->nHeight, itSpent->second.first, itSpent->second.second); - spentClaims.erase(itSpent); + LogPrintf("%s: Something went wrong inserting the claim\n", __func__); } - else - success = trieCache.addClaim(name, tx.GetHash(), i, txout.nValue, pindex->nHeight); - if (!success) - LogPrintf("%s: Something went wrong inserting the name\n", __func__); } - else if (op == OP_SUPPORT_CLAIM) + else if (op == OP_UPDATE_CLAIM) { assert(vvchParams.size() == 3); std::string name(vvchParams[0].begin(), vvchParams[0].end()); - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]);; - if (!trieCache.addSupport(name, tx.GetHash(), i, txout.nValue, supportedTxid, supportednOut, pindex->nHeight)) + uint160 claimId(vvchParams[1]); + LogPrintf("%s: Got a claim update. Name: %s, claimId: %s, new txid: %s, nOut: %d\n", __func__, name, claimId.GetHex(), tx.GetHash().GetHex(), i); + spentClaimsType::iterator itSpent; + for (itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) + { + if (itSpent->first == name && itSpent->second == claimId) + { + break; + } + } + if (itSpent != spentClaims.end()) + { + spentClaims.erase(itSpent); + if (!trieCache.addClaim(name, tx.GetHash(), i, claimId, txout.nValue, pindex->nHeight)) + { + LogPrintf("%s: Something went wrong updating the claim\n", __func__); + } + } + } + else if (op == OP_SUPPORT_CLAIM) + { + assert(vvchParams.size() == 2); + std::string name(vvchParams[0].begin(), vvchParams[0].end()); + uint160 supportedClaimId(vvchParams[1]); + if (!trieCache.addSupport(name, tx.GetHash(), i, txout.nValue, supportedClaimId, pindex->nHeight)) + { LogPrintf("%s: Something went wrong inserting the support\n", __func__); + } } } } @@ -2011,6 +2049,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin for (std::map::iterator itHeight = mClaimUndoHeights.begin(); itHeight != mClaimUndoHeights.end(); ++itHeight) { txinUndos[itHeight->first].nClaimValidHeight = itHeight->second; + txinUndos[itHeight->first].fIsClaim = true; } } // The CTxUndo vector contains the heights at which claims should be put into the trie. @@ -2018,6 +2057,11 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin // others are inserted after a delay, depending on the state of the claim trie at the time // that the claim was originally inserted into the blockchain. That state will not be // available when and if this block is disconnected. + // It also contains whether or not any given txin represents a claim that should + // be put back into the trie. If we didn't find a claim or support in the trie + // or cache when trying to spend it, we shouldn't try to put a claim or support back + // in. Some OP_UPDATE_CLAIM's, for example, may be invalid, and so may never have been + // inserted into the trie in the first place. vPos.push_back(std::make_pair(tx.GetHash(), pos)); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); diff --git a/src/miner.cpp b/src/miner.cpp index f09734224..3d23d4c8f 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -299,7 +299,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true)) continue; - typedef std::map > spentClaimsType; + typedef std::vector > spentClaimsType; spentClaimsType spentClaims; BOOST_FOREACH(const CTxIn& txin, tx.vin) @@ -319,25 +319,40 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) if (DecodeClaimScript(coins->vout[txin.prevout.n].scriptPubKey, op, vvchParams)) { - if (op == OP_CLAIM_NAME) + if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) + { + uint160 claimId; + if (op == OP_CLAIM_NAME) + { + assert(vvchParams.size() == 2); + claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n); + } + else if (op == OP_UPDATE_CLAIM) + { + assert(vvchParams.size() == 3); + claimId = uint160(vvchParams[1]); + } + std::string name(vvchParams[0].begin(), vvchParams[0].end()); + int throwaway; + if (trieCache.spendClaim(name, txin.prevout.hash, txin.prevout.n, coins->nHeight, throwaway)) + { + std::pair entry(name, claimId); + spentClaims.push_back(entry); + } + else + { + LogPrintf("%s(): The claim was not found in the trie or queue and therefore can't be updated\n", __func__); + } + } + else if (op == OP_SUPPORT_CLAIM) { assert(vvchParams.size() == 2); std::string name(vvchParams[0].begin(), vvchParams[0].end()); int throwaway; - trieCache.spendClaim(name, txin.prevout.hash, txin.prevout.n, coins->nHeight, throwaway); - std::pair val(txin.prevout.hash, txin.prevout.n); - std::pair >entry(name, val); - spentClaims.insert(entry); - } - else if (op == OP_SUPPORT_CLAIM) - { - assert(vvchParams.size() == 3); - std::string name(vvchParams[0].begin(), vvchParams[0].end()); - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]); - int throwaway; - if (!trieCache.spendSupport(name, txin.prevout.hash, txin.prevout.n, supportedTxid, supportednOut, coins->nHeight, throwaway)) - LogPrintf("%s: Something went wrong removing the support\n", __func__); + if (!trieCache.spendSupport(name, txin.prevout.hash, txin.prevout.n, coins->nHeight, throwaway)) + { + LogPrintf("%s(): The support was not found in the trie or queue\n", __func__); + } } } } @@ -356,29 +371,45 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { assert(vvchParams.size() == 2); std::string name(vvchParams[0].begin(), vvchParams[0].end()); - spentClaimsType::iterator itSpent = spentClaims.find(name); - bool success; - if (itSpent != spentClaims.end()) + if (!trieCache.addClaim(name, tx.GetHash(), i, ClaimIdHash(tx.GetHash(), i), txout.nValue, nHeight)) { - success = trieCache.addClaim(name, tx.GetHash(), i, txout.nValue, nHeight, itSpent->second.first, itSpent->second.second); - spentClaims.erase(itSpent); - } - else - success = trieCache.addClaim(name, tx.GetHash(), i, txout.nValue, nHeight); - if (!success) LogPrintf("%s: Something went wrong inserting the name\n", __func__); + } } - else if (op == OP_SUPPORT_CLAIM) + else if (op == OP_UPDATE_CLAIM) { assert(vvchParams.size() == 3); std::string name(vvchParams[0].begin(), vvchParams[0].end()); - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]); - //CScriptNum snOut(vvchParams[2], true); - //int supportednOut = snOut.getint(); - if (!trieCache.addSupport(name, tx.GetHash(), i, txout.nValue, supportedTxid, supportednOut, nHeight)) + uint160 claimId(vvchParams[1]); + spentClaimsType::iterator itSpent; + for (itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) { - LogPrintf("%s: Something went wrong inserting the name\n", __func__); + if (itSpent->first == name && itSpent->second == claimId) + { + break; + } + } + if (itSpent != spentClaims.end()) + { + spentClaims.erase(itSpent); + if (!trieCache.addClaim(name, tx.GetHash(), i, claimId, txout.nValue, nHeight)) + { + LogPrintf("%s: Something went wrong updating a claim\n", __func__); + } + } + else + { + LogPrintf("%s(): This update refers to a claim that was not found in the trie or queue, and therefore cannot be updated. The claim may have expired or it may have never existed.\n", __func__); + } + } + else if (op == OP_SUPPORT_CLAIM) + { + assert(vvchParams.size() == 2); + std::string name(vvchParams[0].begin(), vvchParams[0].end()); + uint160 supportedClaimId(vvchParams[1]); + if (!trieCache.addSupport(name, tx.GetHash(), i, txout.nValue, supportedClaimId, nHeight)) + { + LogPrintf("%s: Something went wrong inserting the claim support\n", __func__); } } } diff --git a/src/nameclaim.cpp b/src/nameclaim.cpp index 006979ef0..5be6b64b2 100644 --- a/src/nameclaim.cpp +++ b/src/nameclaim.cpp @@ -1,4 +1,5 @@ #include "nameclaim.h" +#include "hash.h" #include "util.h" std::vector uint32_t_to_vch(uint32_t n) @@ -38,7 +39,7 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector vchParam3; // Valid formats: // OP_CLAIM_NAME vchName vchValue OP_2DROP OP_DROP pubkeyscript - // OP_SUPPORT_CLAIM vchName vchClaimHash vchClaimIndex OP_2DROP OP_2DROP pubkeyscript + // OP_UPDATE_CLAIM vchName vchClaimId vchValue OP_2DROP OP_2DROP pubkeyscript + // OP_SUPPORT_CLAIM vchName vchClaimId OP_2DROP OP_DROP pubkeyscript // All others are invalid. - if (!scriptIn.GetOp(pc, opcode, vchParam1) || opcode < 0 || opcode > OP_PUSHDATA4) { return false; @@ -62,13 +63,16 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector OP_PUSHDATA4) + if (vchParam2.size() != 160/8) { return false; } - if (vchParam3.size() != 4) + } + if (op == OP_UPDATE_CLAIM) + { + if (!scriptIn.GetOp(pc, opcode, vchParam3) || opcode < 0 || opcode > OP_PUSHDATA4) { return false; } @@ -77,23 +81,36 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector claimToHash(txhash.begin(), txhash.end()); + std::vector vchnOut = uint32_t_to_vch(nOut); + claimToHash.insert(claimToHash.end(), vchnOut.begin(), vchnOut.end()); + return Hash160(claimToHash); +} + CScript StripClaimScriptPrefix(const CScript& scriptIn) { int op; diff --git a/src/nameclaim.h b/src/nameclaim.h index 60b6254da..89dc1da16 100644 --- a/src/nameclaim.h +++ b/src/nameclaim.h @@ -2,6 +2,7 @@ #define BITCOIN_NAMECLAIM_H #include "script/script.h" +#include "uint256.h" #include @@ -9,6 +10,7 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector >& vvchParams, CScript::const_iterator& pc); CScript StripClaimScriptPrefix(const CScript& scriptIn); CScript StripClaimScriptPrefix(const CScript& scriptIn, int& op); +uint160 ClaimIdHash(const uint256& txhash, uint32_t nOut); std::vector uint32_t_to_vch(uint32_t n); uint32_t vch_to_uint32_t(std::vector& vchN); diff --git a/src/rpcclaimtrie.cpp b/src/rpcclaimtrie.cpp index b9b7c236d..186254cf0 100644 --- a/src/rpcclaimtrie.cpp +++ b/src/rpcclaimtrie.cpp @@ -235,19 +235,26 @@ UniValue getclaimsfortx(const UniValue& params, bool fHelp) if (op == OP_CLAIM_NAME) { std::string sValue(vvchParams[1].begin(), vvchParams[1].end()); + uint160 claimId = ClaimIdHash(hash, i); + o.push_back(Pair("claimId", claimId.GetHex())); + o.push_back(Pair("value", sValue)); + } + else if (op == OP_UPDATE_CLAIM) + { + uint160 claimId(vvchParams[1]); + std::string sValue(vvchParams[2].begin(), vvchParams[2].end()); + o.push_back(Pair("claimId", claimId.GetHex())); o.push_back(Pair("value", sValue)); } else if (op == OP_SUPPORT_CLAIM) { - uint256 supportedTxid(vvchParams[1]); - uint32_t supportednOut = vch_to_uint32_t(vvchParams[2]); - o.push_back(Pair("supported txid", supportedTxid.GetHex())); - o.push_back(Pair("supported nout", (int64_t)supportednOut)); + uint160 supportedClaimId(vvchParams[1]); + o.push_back(Pair("supported claimId", supportedClaimId.GetHex())); } if (nHeight > 0) { o.push_back(Pair("depth", chainActive.Height() - nHeight)); - if (op == OP_CLAIM_NAME) + if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) { bool inClaimTrie = pclaimTrie->haveClaim(sName, hash, i); o.push_back(Pair("in claim trie", inClaimTrie)); @@ -296,7 +303,7 @@ UniValue getclaimsfortx(const UniValue& params, bool fHelp) else { o.push_back(Pair("depth", 0)); - if (op == OP_CLAIM_NAME) + if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM) { o.push_back(Pair("in claim trie", false)); } diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index c373ca202..9d833124e 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -380,14 +380,14 @@ bool EvalScript(vector >& stack, const CScript& script, un break; } - case OP_CLAIM_NAME: case OP_SUPPORT_CLAIM: + case OP_CLAIM_NAME: case OP_SUPPORT_CLAIM: case OP_UPDATE_CLAIM: { CScriptNum n(OP_0); stack.push_back(vchZero); } break; - case OP_NOP4: case OP_NOP5: + case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: { if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) diff --git a/src/script/script.cpp b/src/script/script.cpp index ec96447c2..48a1a378d 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -133,7 +133,7 @@ const char* GetOpName(opcodetype opcode) case OP_CLAIM_NAME : return "OP_CLAIM_NAME"; case OP_SUPPORT_CLAIM : return "OP_SUPPORT_CLAIM"; case OP_NOP3 : return "OP_NOP3"; - case OP_NOP4 : return "OP_NOP4"; + case OP_UPDATE_CLAIM : return "OP_UPDATE_CLAIM"; case OP_NOP5 : return "OP_NOP5"; case OP_NOP6 : return "OP_NOP6"; case OP_NOP7 : return "OP_NOP7"; diff --git a/src/script/script.h b/src/script/script.h index c8be5adc0..6629084c1 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -160,6 +160,7 @@ enum opcodetype OP_NOP3 = 0xb2, OP_CHECKLOCKTIMEVERIFY = OP_NOP3, OP_NOP4 = 0xb3, + OP_UPDATE_CLAIM = OP_NOP4, OP_NOP5 = 0xb4, OP_NOP6 = 0xb5, OP_NOP7 = 0xb6, diff --git a/src/test/claimtrie_tests.cpp b/src/test/claimtrie_tests.cpp index 433656439..79263e47c 100644 --- a/src/test/claimtrie_tests.cpp +++ b/src/test/claimtrie_tests.cpp @@ -150,6 +150,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) { int unused; uint256 hash0(uint256S("0000000000000000000000000000000000000000000000000000000000000001")); + uint160 hash160; CMutableTransaction tx1 = BuildTransaction(hash0); CMutableTransaction tx2 = BuildTransaction(tx1.GetHash()); CMutableTransaction tx3 = BuildTransaction(tx2.GetHash()); @@ -172,18 +173,18 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->empty()); 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)); + ntState.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1.GetHash(), 0, hash160, 50, 100, 200)); + ntState.insertClaimIntoTrie(std::string("test2"), CClaimValue(tx2.GetHash(), 0, hash160, 50, 100, 200)); BOOST_CHECK(pclaimTrie->empty()); BOOST_CHECK(!ntState.empty()); BOOST_CHECK(ntState.getMerkleHash() == hash1); - ntState.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3.GetHash(), 0, 50, 101, 201)); + ntState.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3.GetHash(), 0, hash160, 50, 101, 201)); BOOST_CHECK(ntState.getMerkleHash() == hash1); - ntState.insertClaimIntoTrie(std::string("tes"), CClaimValue(tx4.GetHash(), 0, 50, 100, 200)); + ntState.insertClaimIntoTrie(std::string("tes"), CClaimValue(tx4.GetHash(), 0, hash160, 50, 100, 200)); BOOST_CHECK(ntState.getMerkleHash() == hash2); - ntState.insertClaimIntoTrie(std::string("testtesttesttest"), CClaimValue(tx5.GetHash(), 0, 50, 100, 200)); + ntState.insertClaimIntoTrie(std::string("testtesttesttest"), CClaimValue(tx5.GetHash(), 0, hash160, 50, 100, 200)); ntState.removeClaimFromTrie(std::string("testtesttesttest"), tx5.GetHash(), 0, unused); BOOST_CHECK(ntState.getMerkleHash() == hash2); ntState.flush(); @@ -201,7 +202,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(ntState1.getMerkleHash() == hash0); CClaimTrieCache ntState2(pclaimTrie, false); - ntState2.insertClaimIntoTrie(std::string("abab"), CClaimValue(tx6.GetHash(), 0, 50, 100, 200)); + ntState2.insertClaimIntoTrie(std::string("abab"), CClaimValue(tx6.GetHash(), 0, hash160, 50, 100, 200)); ntState2.removeClaimFromTrie(std::string("test"), tx1.GetHash(), 0, unused); BOOST_CHECK(ntState2.getMerkleHash() == hash3); @@ -213,7 +214,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->checkConsistency()); CClaimTrieCache ntState3(pclaimTrie, false); - ntState3.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1.GetHash(), 0, 50, 100, 200)); + ntState3.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1.GetHash(), 0, hash160, 50, 100, 200)); BOOST_CHECK(ntState3.getMerkleHash() == hash4); ntState3.flush(); BOOST_CHECK(!pclaimTrie->empty()); @@ -238,7 +239,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_merkle_hash) BOOST_CHECK(pclaimTrie->checkConsistency()); CClaimTrieCache ntState6(pclaimTrie, false); - ntState6.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3.GetHash(), 0, 50, 101, 201)); + ntState6.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3.GetHash(), 0, hash160, 50, 101, 201)); BOOST_CHECK(ntState6.getMerkleHash() == hash2); ntState6.flush(); @@ -284,26 +285,48 @@ BOOST_AUTO_TEST_CASE(claimtrie_insert_update_claim) CMutableTransaction tx1 = BuildTransaction(coinbases[0]); tx1.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName1 << vchValue1 << OP_2DROP << OP_DROP << OP_TRUE; + uint160 tx1ClaimId = ClaimIdHash(tx1.GetHash(), 0); + std::vector vchTx1ClaimId(tx1ClaimId.begin(), tx1ClaimId.end()); + CMutableTransaction tx2 = BuildTransaction(coinbases[1]); tx2.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName2 << vchValue2 << OP_2DROP << OP_DROP << OP_TRUE; tx2.vout[0].nValue = tx1.vout[0].nValue - 1; + CMutableTransaction tx3 = BuildTransaction(tx1); - tx3.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName1 << vchValue1 << OP_2DROP << OP_DROP << OP_TRUE; + tx3.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName1 << vchTx1ClaimId << vchValue1 << OP_2DROP << OP_2DROP << OP_TRUE; + CMutableTransaction tx4 = BuildTransaction(tx2); tx4.vout[0].scriptPubKey = CScript() << OP_TRUE; + CMutableTransaction tx5 = BuildTransaction(coinbases[2]); tx5.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName2 << vchValue2 << OP_2DROP << OP_DROP << OP_TRUE; + CMutableTransaction tx6 = BuildTransaction(tx3); tx6.vout[0].scriptPubKey = CScript() << OP_TRUE; + CMutableTransaction tx7 = BuildTransaction(coinbases[3]); tx7.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName1 << vchValue2 << OP_2DROP << OP_DROP << OP_TRUE; tx7.vout[0].nValue = tx1.vout[0].nValue - 1; + uint160 tx7ClaimId = ClaimIdHash(tx7.GetHash(), 0); + std::vector vchTx7ClaimId(tx7ClaimId.begin(), tx7ClaimId.end()); + CMutableTransaction tx8 = BuildTransaction(tx3, 0, 2); - tx8.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName1 << vchValue1 << OP_2DROP << OP_DROP << OP_TRUE; + tx8.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName1 << vchTx1ClaimId << vchValue1 << OP_2DROP << OP_2DROP << OP_TRUE; tx8.vout[0].nValue = tx8.vout[0].nValue - 1; tx8.vout[1].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName1 << vchValue2 << OP_2DROP << OP_DROP << OP_TRUE; + CMutableTransaction tx9 = BuildTransaction(tx7); - tx9.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName1 << vchValue2 << OP_2DROP << OP_DROP << OP_TRUE; + tx9.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName1 << vchTx7ClaimId << vchValue2 << OP_2DROP << OP_2DROP << OP_TRUE; + + CMutableTransaction tx10 = BuildTransaction(coinbases[4]); + tx10.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName1 << vchTx1ClaimId << vchValue1 << OP_2DROP << OP_2DROP << OP_TRUE; + + CMutableTransaction tx11 = BuildTransaction(tx10); + tx11.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName1 << vchTx1ClaimId << vchValue1 << OP_2DROP << OP_2DROP << OP_TRUE; + + CMutableTransaction tx12 = BuildTransaction(tx10); + tx12.vout[0].scriptPubKey = CScript() << OP_TRUE; + CClaimValue val; int nThrowaway; @@ -712,6 +735,154 @@ BOOST_AUTO_TEST_CASE(claimtrie_insert_update_claim) blocks_to_invalidate.pop_back(); BOOST_CHECK(pclaimTrie->empty()); BOOST_CHECK(pclaimTrie->queueEmpty()); + + // make sure invalid updates don't wreak any havoc + + // put tx1 into the trie + + AddToMempool(tx1); + + BOOST_CHECK(CreateBlocks(1, 2)); + blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash()); + + BOOST_CHECK(pclaimTrie->getInfoForName(sName1, val)); + BOOST_CHECK(val.txhash == tx1.GetHash()); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // advance a few blocks + + BOOST_CHECK(CreateBlocks(5, 1)); + + // put in bad tx10 + + AddToMempool(tx10); + + BOOST_CHECK(CreateBlocks(1, 2)); + + blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash()); + + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx10.GetHash(), 0, nThrowaway)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // roll back, make sure nothing bad happens + + BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back())); + blocks_to_invalidate.pop_back(); + + mempool.clear(); + + // put it back in + + AddToMempool(tx10); + + BOOST_CHECK(CreateBlocks(1, 2)); + + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx10.GetHash(), 0, nThrowaway)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // update it + + AddToMempool(tx11); + + BOOST_CHECK(CreateBlocks(1, 2)); + + blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash()); + + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx11.GetHash(), 0, nThrowaway)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + BOOST_CHECK(CreateBlocks(10, 1)); + + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx11.GetHash(), 0, nThrowaway)); + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx11.GetHash(), 0)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // roll back to before the update + + BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back())); + blocks_to_invalidate.pop_back(); + + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx11.GetHash(), 0)); + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx11.GetHash(), 0, nThrowaway)); + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx10.GetHash(), 0)); + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx10.GetHash(), 0, nThrowaway)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // make sure tx10 would have gotten into the trie, then run tests again + + BOOST_CHECK(CreateBlocks(10, 1)); + + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx10.GetHash(), 0)); + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx10.GetHash(), 0, nThrowaway)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // update it + + AddToMempool(tx11); + + BOOST_CHECK(CreateBlocks(1, 2)); + + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx11.GetHash(), 0, nThrowaway)); + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx11.GetHash(), 0)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // make sure tx11 would have gotten into the trie + + BOOST_CHECK(CreateBlocks(20, 1)); + + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx11.GetHash(), 0, nThrowaway)); + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx11.GetHash(), 0)); + BOOST_CHECK(!pclaimTrie->haveClaimInQueue(sName1, tx10.GetHash(), 0, nThrowaway)); + BOOST_CHECK(!pclaimTrie->haveClaim(sName1, tx10.GetHash(), 0)); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // roll all the way back + + BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back())); + blocks_to_invalidate.pop_back(); + + mempool.clear(); + + // Put tx10 and tx11 in without tx1 in + + AddToMempool(tx10); + + BOOST_CHECK(CreateBlocks(1, 2)); + blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash()); + + BOOST_CHECK(pclaimTrie->empty()); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // update with tx11 + + AddToMempool(tx11); + + BOOST_CHECK(CreateBlocks(1, 2)); + blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash()); + + BOOST_CHECK(pclaimTrie->empty()); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // roll back to before tx11 + + BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back())); + blocks_to_invalidate.pop_back(); + mempool.clear(); + + // spent tx10 with tx12 instead which is not a claim operation of any kind + + AddToMempool(tx12); + + BOOST_CHECK(CreateBlocks(1, 2)); + + BOOST_CHECK(pclaimTrie->empty()); + BOOST_CHECK(pclaimTrie->queueEmpty()); + + // roll all the way back + + BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back())); + blocks_to_invalidate.pop_back(); + mempool.clear(); } BOOST_AUTO_TEST_CASE(claimtrie_claim_expiration) @@ -1017,10 +1188,9 @@ BOOST_AUTO_TEST_CASE(claimtrie_supporting_claims) tx2.vout[0].nValue = 500000000; CMutableTransaction tx3 = BuildTransaction(coinbases[2]); - uint256 tx1Hash = tx1.GetHash(); - std::vector vchTx1Hash(tx1Hash.begin(), tx1Hash.end()); - std::vector vchSupportnOut = uint32_t_to_vch(0); - tx3.vout[0].scriptPubKey = CScript() << OP_SUPPORT_CLAIM << vchName << vchTx1Hash << vchSupportnOut << OP_2DROP << OP_2DROP << OP_TRUE; + uint160 tx1ClaimId = ClaimIdHash(tx1.GetHash(), 0); + std::vector vchTx1ClaimId(tx1ClaimId.begin(), tx1ClaimId.end()); + tx3.vout[0].scriptPubKey = CScript() << OP_SUPPORT_CLAIM << vchName << vchTx1ClaimId << OP_2DROP << OP_DROP << OP_TRUE; tx3.vout[0].nValue = 500000000; CMutableTransaction tx4 = BuildTransaction(tx1); @@ -1032,16 +1202,18 @@ BOOST_AUTO_TEST_CASE(claimtrie_supporting_claims) CMutableTransaction tx6 = BuildTransaction(tx3); tx6.vout[0].scriptPubKey = CScript() << OP_TRUE; + CMutableTransaction tx7 = BuildTransaction(tx1); + tx7.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName << vchTx1ClaimId << vchValue1 << OP_2DROP << OP_2DROP << OP_TRUE; + CClaimValue val; std::vector blocks_to_invalidate; // Test 1: create 1 LBC claim (tx1), create 5 LBC support (tx3), create 5 LBC claim (tx2) // Verify that tx1 retains control throughout // spend tx3, verify that tx2 gains control - // roll back to before tx3 is valid - // advance until tx3 and tx2 are valid, verify tx1 retains control - // spend tx3, verify tx2 gains control - // roll back to before tx3 is spent, verify tx1 gains control + // roll back to before tx3 is spent, verify tx1 regains control + // update tx1 with tx7, verify tx7 has control + // roll back to before tx7 is inserted, verify tx1 regains control // roll back to before tx2 is valid, spend tx3 // advance to tx2 valid, verify tx2 gains control // roll back to before tx3 is valid, spend tx3 @@ -1137,6 +1309,29 @@ BOOST_AUTO_TEST_CASE(claimtrie_supporting_claims) BOOST_CHECK(pclaimTrie->supportQueueEmpty()); BOOST_CHECK(pclaimTrie->getInfoForName(sName, val)); BOOST_CHECK(val.txhash == tx1.GetHash()); + + // update tx1 with tx7, verify tx7 has control + + AddToMempool(tx7); + BOOST_CHECK(CreateBlocks(1, 2)); + + blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash()); + + BOOST_CHECK(pcoinsTip->HaveCoins(tx7.GetHash())); + BOOST_CHECK(!pclaimTrie->empty()); + BOOST_CHECK(pclaimTrie->queueEmpty()); + BOOST_CHECK(!pclaimTrie->supportEmpty()); + BOOST_CHECK(pclaimTrie->supportQueueEmpty()); + BOOST_CHECK(pclaimTrie->getInfoForName(sName, val)); + BOOST_CHECK(val.txhash == tx7.GetHash()); + + // roll back to before tx7 is inserted, verify tx1 has control + + BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back())); + blocks_to_invalidate.pop_back(); + + BOOST_CHECK(pclaimTrie->getInfoForName(sName, val)); + BOOST_CHECK(val.txhash == tx1.GetHash()); // roll back to before tx2 is valid @@ -1340,10 +1535,9 @@ BOOST_AUTO_TEST_CASE(claimtrie_supporting_claims2) tx2.vout[0].nValue = 500000000; CMutableTransaction tx3 = BuildTransaction(coinbases[2]); - uint256 tx1Hash = tx1.GetHash(); - std::vector vchTx1Hash(tx1Hash.begin(), tx1Hash.end()); - std::vector vchSupportnOut = uint32_t_to_vch(0); - tx3.vout[0].scriptPubKey = CScript() << OP_SUPPORT_CLAIM << vchName << vchTx1Hash << vchSupportnOut << OP_2DROP << OP_2DROP << OP_TRUE; + uint160 tx1ClaimId = ClaimIdHash(tx1.GetHash(), 0); + std::vector vchTx1ClaimId(tx1ClaimId.begin(), tx1ClaimId.end()); + tx3.vout[0].scriptPubKey = CScript() << OP_SUPPORT_CLAIM << vchName << vchTx1ClaimId << OP_2DROP << OP_DROP << OP_TRUE; tx3.vout[0].nValue = 500000000; CMutableTransaction tx4 = BuildTransaction(tx1); @@ -1791,6 +1985,8 @@ BOOST_AUTO_TEST_CASE(claimtrienode_serialize_unserialize) { CDataStream ss(SER_DISK, 0); + uint160 hash160; + CClaimTrieNode n1; CClaimTrieNode n2; CClaimValue throwaway; @@ -1811,8 +2007,8 @@ BOOST_AUTO_TEST_CASE(claimtrienode_serialize_unserialize) ss >> n2; BOOST_CHECK(n1 == n2); - CClaimValue v1(uint256S("0000000000000000000000000000000000000000000000000000000000000001"), 0, 50, 0, 100); - CClaimValue v2(uint256S("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), 1, 100, 1, 101); + CClaimValue v1(uint256S("0000000000000000000000000000000000000000000000000000000000000001"), 0, hash160, 50, 0, 100); + CClaimValue v2(uint256S("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"), 1, hash160, 100, 1, 101); n1.insertClaim(v1); BOOST_CHECK(n1 != n2); diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index dbb8f286e..c43282dd8 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -160,11 +160,10 @@ ["2 2 LSHIFT", "8 EQUAL", "P2SH,STRICTENC", "disabled"], ["2 1 RSHIFT", "1 EQUAL", "P2SH,STRICTENC", "disabled"], -["1","NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["1","NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], ["Ensure 100% coverage of discouraged NOPS"], -["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], ["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], @@ -286,7 +285,7 @@ "P2SH,STRICTENC", "10,001-byte scriptPubKey"], -["NOP4", "NOP10", "P2SH,STRICTENC"], +["NOP5", "NOP10", "P2SH,STRICTENC"], ["1","VER", "P2SH,STRICTENC", "OP_VER is reserved"], ["1","VERIF", "P2SH,STRICTENC", "OP_VERIF is reserved"], @@ -401,7 +400,7 @@ ["NOP 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC", "Tests for Script.IsPushOnly()"], -["NOP4 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"], +["NOP5 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL", "P2SH,STRICTENC"], ["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "P2SH,STRICTENC", "OP_RESERVED in P2SH should fail"], ["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "P2SH,STRICTENC", "OP_VER in P2SH should fail"], diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 8db252f91..47d49db81 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -232,8 +232,8 @@ ["'abcdefghijklmnopqrstuvwxyz'", "HASH256 0x4c 0x20 0xca139bc10c2f660da42666f72e89a225936fc60f193c161124a672050c434671 EQUAL", "P2SH,STRICTENC"], -["1","NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], -["'NOP_1_to_10' NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1","NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], +["'NOP_1_to_10' NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], ["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], @@ -441,7 +441,6 @@ ["0", "HASH256", "P2SH,STRICTENC"], ["NOP", "CODESEPARATOR 1", "P2SH,STRICTENC"], -["NOP", "NOP4 1", "P2SH,STRICTENC"], ["NOP", "NOP5 1", "P2SH,STRICTENC"], ["NOP", "NOP6 1", "P2SH,STRICTENC"], ["NOP", "NOP7 1", "P2SH,STRICTENC"], diff --git a/src/undo.h b/src/undo.h index 6546284ce..313671d1c 100644 --- a/src/undo.h +++ b/src/undo.h @@ -25,16 +25,18 @@ public: bool fCoinBase; // if the outpoint was the last unspent: whether it belonged to a coinbase unsigned int nHeight; // if the outpoint was the last unspent: its height int nVersion; // if the outpoint was the last unspent: its version - unsigned int nClaimValidHeight; // If the outpoint was a name claim, the height at which the claim should be inserted into the trie + unsigned int nClaimValidHeight; // If the outpoint was a claim or support, the height at which the claim or support should be inserted into the trie + bool fIsClaim; // if the outpoint was a claim or support - CTxInUndo() : txout(), fLastUnspent(false), fCoinBase(false), nHeight(0), nVersion(0), nClaimValidHeight(0) {} - CTxInUndo(const CTxOut &txoutIn, bool fLastUnspent = false, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0, unsigned int nClaimValidHeight = 0) : txout(txoutIn), fLastUnspent(fLastUnspent), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn), nClaimValidHeight(nClaimValidHeight) { } + CTxInUndo() : txout(), fLastUnspent(false), fCoinBase(false), nHeight(0), nVersion(0), nClaimValidHeight(0), fIsClaim(false) {} + CTxInUndo(const CTxOut &txoutIn, bool fLastUnspent = false, bool fCoinBaseIn = false, unsigned int nHeightIn = 0, int nVersionIn = 0, unsigned int nClaimValidHeight = 0, bool fIsClaim = false) : txout(txoutIn), fLastUnspent(fLastUnspent), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nVersion(nVersionIn), nClaimValidHeight(nClaimValidHeight), fIsClaim(fIsClaim) { } unsigned int GetSerializeSize(int nType, int nVersion) const { return ::GetSerializeSize(VARINT(nHeight*4+(fCoinBase ? 2 : 0)+(fLastUnspent ? 1: 0)), nType, nVersion) + (fLastUnspent ? ::GetSerializeSize(VARINT(this->nVersion), nType, nVersion) : 0) + ::GetSerializeSize(CTxOutCompressor(REF(txout)), nType, nVersion) + - ::GetSerializeSize(VARINT(nClaimValidHeight), nType, nVersion); + ::GetSerializeSize(VARINT(nClaimValidHeight), nType, nVersion) + + ::GetSerializeSize(fIsClaim, nType, nVersion); } template @@ -44,6 +46,7 @@ public: ::Serialize(s, VARINT(this->nVersion), nType, nVersion); ::Serialize(s, CTxOutCompressor(REF(txout)), nType, nVersion); ::Serialize(s, VARINT(nClaimValidHeight), nType, nVersion); + ::Serialize(s, fIsClaim, nType, nVersion); } template @@ -57,6 +60,7 @@ public: ::Unserialize(s, VARINT(this->nVersion), nType, nVersion); ::Unserialize(s, REF(CTxOutCompressor(REF(txout))), nType, nVersion); ::Unserialize(s, VARINT(nClaimValidHeight), nType, nVersion); + ::Unserialize(s, fIsClaim, nType, nVersion); } }; diff --git a/src/wallet/wallet_ismine.cpp b/src/wallet/wallet_ismine.cpp index e9a7f6176..688cae6d4 100644 --- a/src/wallet/wallet_ismine.cpp +++ b/src/wallet/wallet_ismine.cpp @@ -47,7 +47,7 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) CScript strippedScriptPubKey = StripClaimScriptPrefix(scriptPubKey, opcode); if (strippedScriptPubKey != scriptPubKey) { - if (opcode == OP_CLAIM_NAME) + if (opcode == OP_CLAIM_NAME || opcode == OP_UPDATE_CLAIM) { spendable_type = ISMINE_CLAIM; }