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:
parent
7859b72ab4
commit
06a9919b48
15 changed files with 504 additions and 237 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
144
src/main.cpp
144
src/main.cpp
|
@ -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);
|
||||
|
|
|
@ -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__);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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"],
|
||||
|
|
12
src/undo.h
12
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<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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue