Create OP_UPDATE_CLAIM, make OP_SUPPORT_CLAIM refer to claimID

Updates to claims now refer to a unique ID assigned to OP_CLAIM_NAMEs.
The claimID is the Hash160 of the claim's hash and nOut. When an
update is updated, that same claimID is used, so all updates to a
claim will use the original claimID.

Supports now refer to the claimID rather than a specific hash and
nOut.
This commit is contained in:
Jimmy Kiselak 2015-12-22 19:11:50 -05:00
parent 7859b72ab4
commit 06a9919b48
15 changed files with 504 additions and 237 deletions

View file

@ -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<CSupportValue>::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<std::pair<std::string, int> >& 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);

View file

@ -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;

View file

@ -1539,17 +1539,27 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CClaimTr
// restore claim if applicable
int op;
std::vector<std::vector<unsigned char> > 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<std::vector<unsigned char> > 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<std::string, std::pair<uint256, unsigned int> > spentClaimsType;
typedef std::vector<std::pair<std::string, uint160> > 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<std::vector<unsigned char> > 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<uint256, unsigned int> val(txin.prevout.hash, txin.prevout.n);
std::pair<std::string, std::pair<uint256, unsigned int> > entry(name, val);
spentClaims.insert(entry);
std::pair<std::string, uint160> 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<unsigned int, unsigned int>::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);

View file

@ -299,7 +299,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
continue;
typedef std::map<std::string, std::pair<uint256, unsigned int> > spentClaimsType;
typedef std::vector<std::pair<std::string, uint160> > 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<std::string, uint160> 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<uint256, unsigned int> val(txin.prevout.hash, txin.prevout.n);
std::pair<std::string, std::pair<uint256, unsigned int> >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__);
}
}
}

View file

@ -1,4 +1,5 @@
#include "nameclaim.h"
#include "hash.h"
#include "util.h"
std::vector<unsigned char> uint32_t_to_vch(uint32_t n)
@ -38,7 +39,7 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector
return false;
}
if (opcode != OP_CLAIM_NAME && opcode != OP_SUPPORT_CLAIM)
if (opcode != OP_CLAIM_NAME && opcode != OP_SUPPORT_CLAIM && opcode != OP_UPDATE_CLAIM)
{
return false;
}
@ -50,10 +51,10 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector
std::vector<unsigned char> 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<std::vector
{
return false;
}
if (op == OP_SUPPORT_CLAIM)
if (op == OP_UPDATE_CLAIM || op == OP_SUPPORT_CLAIM)
{
if (!scriptIn.GetOp(pc, opcode, vchParam3) || opcode < 0 || opcode > 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<std::vector
{
return false;
}
if (!scriptIn.GetOp(pc, opcode) || (op == OP_CLAIM_NAME && opcode != OP_DROP) || (op == OP_SUPPORT_CLAIM && opcode != OP_2DROP))
if (!scriptIn.GetOp(pc, opcode))
{
return false;
}
if ((op == OP_CLAIM_NAME || op == OP_SUPPORT_CLAIM) && opcode != OP_DROP)
{
return false;
}
else if ((op == OP_UPDATE_CLAIM) && opcode != OP_2DROP)
{
return false;
}
vvchParams.push_back(vchParam1);
vvchParams.push_back(vchParam2);
if (op == OP_SUPPORT_CLAIM)
if (op == OP_UPDATE_CLAIM)
{
vvchParams.push_back(vchParam3);
if (vchParam2.size() != (256/8))
return false;
}
return true;
}
uint160 ClaimIdHash(const uint256& txhash, uint32_t nOut)
{
std::vector<unsigned char> claimToHash(txhash.begin(), txhash.end());
std::vector<unsigned char> vchnOut = uint32_t_to_vch(nOut);
claimToHash.insert(claimToHash.end(), vchnOut.begin(), vchnOut.end());
return Hash160(claimToHash);
}
CScript StripClaimScriptPrefix(const CScript& scriptIn)
{
int op;

View file

@ -2,6 +2,7 @@
#define BITCOIN_NAMECLAIM_H
#include "script/script.h"
#include "uint256.h"
#include <vector>
@ -9,6 +10,7 @@ bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector
bool DecodeClaimScript(const CScript& scriptIn, int& op, std::vector<std::vector<unsigned char> >& 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<unsigned char> uint32_t_to_vch(uint32_t n);
uint32_t vch_to_uint32_t(std::vector<unsigned char>& vchN);

View file

@ -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));
}

View file

@ -380,14 +380,14 @@ bool EvalScript(vector<vector<unsigned char> >& 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)

View file

@ -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";

View file

@ -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,

View file

@ -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<unsigned char> 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<unsigned char> 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<unsigned char> vchTx1Hash(tx1Hash.begin(), tx1Hash.end());
std::vector<unsigned char> 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<unsigned char> 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<uint256> 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<unsigned char> vchTx1Hash(tx1Hash.begin(), tx1Hash.end());
std::vector<unsigned char> 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<unsigned char> 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);

View file

@ -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"],

View file

@ -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"],

View file

@ -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<typename Stream>
@ -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<typename Stream>
@ -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);
}
};

View file

@ -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;
}