make supports expire

This commit is contained in:
Jimmy Kiselak 2015-12-29 13:50:11 -05:00
parent 78871a7091
commit 97f2067c66
6 changed files with 328 additions and 27 deletions

View file

@ -605,6 +605,20 @@ void CClaimTrie::updateSupportNameQueue(const std::string& name, std::vector<CSu
itQueueRow->second.swap(row); itQueueRow->second.swap(row);
} }
void CClaimTrie::updateSupportExpirationQueue(int nHeight, supportQueueRowType& row)
{
supportQueueType::iterator itQueueRow = dirtySupportExpirationQueueRows.find(nHeight);
if (itQueueRow == dirtySupportExpirationQueueRows.end())
{
supportQueueRowType newRow;
std::pair<supportQueueType::iterator, bool> ret;
ret = dirtySupportExpirationQueueRows.insert(std::pair<int, supportQueueRowType >(nHeight, newRow));
assert(ret.second);
itQueueRow = ret.first;
}
itQueueRow->second.swap(row);
}
bool CClaimTrie::getSupportNode(std::string name, supportMapEntryType& node) const bool CClaimTrie::getSupportNode(std::string name, supportMapEntryType& node) const
{ {
supportMapType::const_iterator itNode = dirtySupportNodes.find(name); supportMapType::const_iterator itNode = dirtySupportNodes.find(name);
@ -638,7 +652,18 @@ bool CClaimTrie::getSupportQueueNameRow(const std::string& name, std::vector<CSu
return db.Read(std::make_pair(SUPPORT_QUEUE_NAME_ROW, name), row); return db.Read(std::make_pair(SUPPORT_QUEUE_NAME_ROW, name), row);
} }
bool CClaimTrie::update(nodeCacheType& cache, hashMapType& hashes, std::map<std::string, int>& takeoverHeights, const uint256& hashBlockIn, claimQueueType& queueCache, claimQueueNamesType& queueNameCache, claimQueueType& expirationQueueCache, int nNewHeight, supportMapType& supportCache, supportQueueType& supportQueueCache, supportQueueNamesType& supportQueueNameCache) bool CClaimTrie::getSupportExpirationQueueRow(int nHeight, supportQueueRowType& row) const
{
supportQueueType::const_iterator itQueueRow = dirtySupportExpirationQueueRows.find(nHeight);
if (itQueueRow != dirtySupportExpirationQueueRows.end())
{
row = itQueueRow->second;
return true;
}
return db.Read(std::make_pair(SUPPORT_EXP_QUEUE_ROW, nHeight), row);
}
bool CClaimTrie::update(nodeCacheType& cache, hashMapType& hashes, std::map<std::string, int>& takeoverHeights, const uint256& hashBlockIn, claimQueueType& queueCache, claimQueueNamesType& queueNameCache, claimQueueType& expirationQueueCache, int nNewHeight, supportMapType& supportCache, supportQueueType& supportQueueCache, supportQueueNamesType& supportQueueNameCache, supportQueueType& supportExpirationQueueCache)
{ {
for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache) for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache)
{ {
@ -679,6 +704,10 @@ bool CClaimTrie::update(nodeCacheType& cache, hashMapType& hashes, std::map<std:
{ {
updateSupportNameQueue(itSupportNameQueue->first, itSupportNameQueue->second); updateSupportNameQueue(itSupportNameQueue->first, itSupportNameQueue->second);
} }
for (supportQueueType::iterator itSupportExpirationQueue = supportExpirationQueueCache.begin(); itSupportExpirationQueue != supportExpirationQueueCache.end(); ++itSupportExpirationQueue)
{
updateSupportExpirationQueue(itSupportExpirationQueue->first, itSupportExpirationQueue->second);
}
hashBlock = hashBlockIn; hashBlock = hashBlockIn;
nCurrentHeight = nNewHeight; nCurrentHeight = nNewHeight;
return true; return true;
@ -888,6 +917,21 @@ void CClaimTrie::BatchWriteSupportQueueNameRows(CLevelDBBatch& batch)
} }
} }
void CClaimTrie::BatchWriteSupportExpirationQueueRows(CLevelDBBatch& batch)
{
for (supportQueueType::iterator itQueue = dirtySupportExpirationQueueRows.begin(); itQueue != dirtySupportExpirationQueueRows.end(); ++itQueue)
{
if (itQueue->second.empty())
{
batch.Erase(std::make_pair(SUPPORT_EXP_QUEUE_ROW, itQueue->first));
}
else
{
batch.Write(std::make_pair(SUPPORT_EXP_QUEUE_ROW, itQueue->first), itQueue->second);
}
}
}
bool CClaimTrie::WriteToDisk() bool CClaimTrie::WriteToDisk()
{ {
CLevelDBBatch batch(&db.GetObfuscateKey()); CLevelDBBatch batch(&db.GetObfuscateKey());
@ -1711,7 +1755,7 @@ bool CClaimTrieCache::addSupportToQueues(const std::string& name, CSupportValue&
supportQueueNamesType::iterator itQueueNameRow = getSupportQueueCacheNameRow(name, true); supportQueueNamesType::iterator itQueueNameRow = getSupportQueueCacheNameRow(name, true);
itQueueRow->second.push_back(entry); itQueueRow->second.push_back(entry);
itQueueNameRow->second.push_back(support); itQueueNameRow->second.push_back(support);
//addSupportToExpirationQueue(entry); addSupportToExpirationQueue(entry);
return true; return true;
} }
@ -1784,7 +1828,7 @@ bool CClaimTrieCache::undoSpendSupport(const std::string& name, const COutPoint&
if (nValidAtHeight < nCurrentHeight) if (nValidAtHeight < nCurrentHeight)
{ {
supportQueueEntryType entry(name, support); supportQueueEntryType entry(name, support);
//addSupportToExpirationQueue(entry); addSupportToExpirationQueue(entry);
return insertSupportIntoMap(name, support, false); return insertSupportIntoMap(name, support, false);
} }
else else
@ -1802,18 +1846,21 @@ bool CClaimTrieCache::removeSupport(const std::string& name, const COutPoint& ou
if (removed == false && removeSupportFromMap(name, outPoint, support, fCheckTakeover)) if (removed == false && removeSupportFromMap(name, outPoint, support, fCheckTakeover))
removed = true; removed = true;
if (removed) if (removed)
{
removeSupportFromExpirationQueue(name, outPoint, nHeight);
nValidAtHeight = support.nValidAtHeight; nValidAtHeight = support.nValidAtHeight;
}
return removed; return removed;
} }
/*void CClaimTrieCache::addSupportToExpirationQueue(supportQueueEntryType& entry) const void CClaimTrieCache::addSupportToExpirationQueue(supportQueueEntryType& entry) const
{ {
int expirationHeight = entry.second.nHeight + base->nExpirationTime; int expirationHeight = entry.second.nHeight + base->nExpirationTime;
supportQueueType::iterator itQueueRow = getSupportExpirationQueueCacheRow(expirationHeight, true); supportQueueType::iterator itQueueRow = getSupportExpirationQueueCacheRow(expirationHeight, true);
itQueueRow->second.push_back(entry); itQueueRow->second.push_back(entry);
}*/ }
/*void CClaimTrieCache::removeSupportFromExpirationQueue(const std::string& name, const COutPoint& outPoint, int nHeight) const void CClaimTrieCache::removeSupportFromExpirationQueue(const std::string& name, const COutPoint& outPoint, int nHeight) const
{ {
int expirationHeight = nHeight + base->nExpirationTime; int expirationHeight = nHeight + base->nExpirationTime;
supportQueueType::iterator itQueueRow = getSupportExpirationQueueCacheRow(expirationHeight, false); supportQueueType::iterator itQueueRow = getSupportExpirationQueueCacheRow(expirationHeight, false);
@ -1831,9 +1878,9 @@ bool CClaimTrieCache::removeSupport(const std::string& name, const COutPoint& ou
{ {
itQueueRow->second.erase(itQueue); itQueueRow->second.erase(itQueue);
} }
}*/ }
/*supportQueueType::iterator CClaimTrieCache::getSupportExpirationQueueCacheRow(int nHeight, bool createIfNotExists) const supportQueueType::iterator CClaimTrieCache::getSupportExpirationQueueCacheRow(int nHeight, bool createIfNotExists) const
{ {
supportQueueType::iterator itQueueRow = supportExpirationQueueCache.find(nHeight); supportQueueType::iterator itQueueRow = supportExpirationQueueCache.find(nHeight);
if (itQueueRow == supportExpirationQueueCache.end()) if (itQueueRow == supportExpirationQueueCache.end())
@ -1852,7 +1899,7 @@ bool CClaimTrieCache::removeSupport(const std::string& name, const COutPoint& ou
itQueueRow = ret.first; itQueueRow = ret.first;
} }
return itQueueRow; return itQueueRow;
}*/ }
bool CClaimTrieCache::undoAddSupport(const std::string& name, const COutPoint& outPoint, int nHeight) const bool CClaimTrieCache::undoAddSupport(const std::string& name, const COutPoint& outPoint, int nHeight) const
{ {
@ -1867,7 +1914,7 @@ bool CClaimTrieCache::spendSupport(const std::string& name, const COutPoint& out
return removeSupport(name, outPoint, nHeight, nValidAtHeight, true); return removeSupport(name, outPoint, nHeight, nValidAtHeight, true);
} }
bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo,/* supportQueueRowType& expireSupportUndo,*/ std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo, supportQueueRowType& expireSupportUndo, std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const
{ {
LogPrintf("%s: nCurrentHeight (before increment): %d\n", __func__, nCurrentHeight); LogPrintf("%s: nCurrentHeight (before increment): %d\n", __func__, nCurrentHeight);
claimQueueType::iterator itQueueRow = getQueueCacheRow(nCurrentHeight, false); claimQueueType::iterator itQueueRow = getQueueCacheRow(nCurrentHeight, false);
@ -1961,16 +2008,17 @@ bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRo
} }
itSupportRow->second.clear(); itSupportRow->second.clear();
} }
/*supportQueueType::iterator itSupportExpirationRow = getSupportExpirationQueueCacheRow(nCurrentHeight, false); supportQueueType::iterator itSupportExpirationRow = getSupportExpirationQueueCacheRow(nCurrentHeight, false);
if (itSupportExpirationRow != supportExpirationQueueCache.end()) if (itSupportExpirationRow != supportExpirationQueueCache.end())
{ {
for (supportQueueRowType::iterator itEntry = itSupportExpirationRow->second.begin(); itEntry != itSupportExpirationRow->second.end(); ++itEntry) for (supportQueueRowType::iterator itEntry = itSupportExpirationRow->second.begin(); itEntry != itSupportExpirationRow->second.end(); ++itEntry)
{ {
int nValidAtHeight; CSupportValue support;
assert(removeSupportFromMap(itEntry->first, itEntry->second.outPoint, nValidAtHeight, true)); assert(removeSupportFromMap(itEntry->first, itEntry->second.outPoint, support, true));
supportExpireUndo.push_back(*itEntry); expireSupportUndo.push_back(std::make_pair(itEntry->first, support));
} }
}*/ itSupportExpirationRow->second.clear();
}
// check each potentially taken over name to see if a takeover occurred. // check each potentially taken over name to see if a takeover occurred.
// if it did, then check the claim and support insertion queues for // if it did, then check the claim and support insertion queues for
// the names that have been taken over, immediately insert all claim and // the names that have been taken over, immediately insert all claim and
@ -2126,7 +2174,7 @@ bool CClaimTrieCache::incrementBlock(claimQueueRowType& insertUndo, claimQueueRo
return true; return true;
} }
bool CClaimTrieCache::decrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo, std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const bool CClaimTrieCache::decrementBlock(claimQueueRowType& insertUndo, claimQueueRowType& expireUndo, supportQueueRowType& insertSupportUndo, supportQueueRowType& expireSupportUndo, std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const
{ {
LogPrintf("%s: nCurrentHeight (before decrement): %d\n", __func__, nCurrentHeight); LogPrintf("%s: nCurrentHeight (before decrement): %d\n", __func__, nCurrentHeight);
nCurrentHeight--; nCurrentHeight--;
@ -2157,6 +2205,15 @@ bool CClaimTrieCache::decrementBlock(claimQueueRowType& insertUndo, claimQueueRo
itSupportRow->second.push_back(*itSupportUndo); itSupportRow->second.push_back(*itSupportUndo);
itSupportNameRow->second.push_back(itSupportUndo->second); itSupportNameRow->second.push_back(itSupportUndo->second);
} }
if (expireSupportUndo.begin() != expireSupportUndo.end())
{
supportQueueType::iterator itSupportExpireRow = getSupportExpirationQueueCacheRow(nCurrentHeight, true);
for (supportQueueRowType::iterator itSupportExpireUndo = expireSupportUndo.begin(); itSupportExpireUndo != expireSupportUndo.end(); ++itSupportExpireUndo)
{
insertSupportIntoMap(itSupportExpireUndo->first, itSupportExpireUndo->second, false);
itSupportExpireRow->second.push_back(*itSupportExpireUndo);
}
}
for (std::vector<std::pair<std::string, int> >::iterator itTakeoverHeightUndo = takeoverHeightUndo.begin(); itTakeoverHeightUndo != takeoverHeightUndo.end(); ++itTakeoverHeightUndo) for (std::vector<std::pair<std::string, int> >::iterator itTakeoverHeightUndo = takeoverHeightUndo.begin(); itTakeoverHeightUndo != takeoverHeightUndo.end(); ++itTakeoverHeightUndo)
{ {
@ -2241,7 +2298,7 @@ bool CClaimTrieCache::flush()
{ {
if (dirty()) if (dirty())
getMerkleHash(); getMerkleHash();
bool success = base->update(cache, cacheHashes, cacheTakeoverHeights, getBestBlock(), claimQueueCache, claimQueueNameCache, expirationQueueCache, nCurrentHeight, supportCache, supportQueueCache, supportQueueNameCache); bool success = base->update(cache, cacheHashes, cacheTakeoverHeights, getBestBlock(), claimQueueCache, claimQueueNameCache, expirationQueueCache, nCurrentHeight, supportCache, supportQueueCache, supportQueueNameCache, supportExpirationQueueCache);
if (success) if (success)
{ {
success = clear(); success = clear();

View file

@ -21,6 +21,7 @@
#define SUPPORT 's' #define SUPPORT 's'
#define SUPPORT_QUEUE_ROW 'u' #define SUPPORT_QUEUE_ROW 'u'
#define SUPPORT_QUEUE_NAME_ROW 'p' #define SUPPORT_QUEUE_NAME_ROW 'p'
#define SUPPORT_EXP_QUEUE_ROW 'x'
class CClaimValue class CClaimValue
{ {
@ -267,8 +268,8 @@ private:
claimQueueType& expirationQueueCache, int nNewHeight, claimQueueType& expirationQueueCache, int nNewHeight,
supportMapType& supportCache, supportMapType& supportCache,
supportQueueType& supportQueueCache, supportQueueType& supportQueueCache,
supportQueueNamesType& supportQueueNameCache);//, supportQueueNamesType& supportQueueNameCache,
//supportQueueType& supportExpirationQueueCache); supportQueueType& supportExpirationQueueCache);
bool updateName(const std::string& name, CClaimTrieNode* updatedNode); bool updateName(const std::string& name, CClaimTrieNode* updatedNode);
bool updateHash(const std::string& name, uint256& hash); bool updateHash(const std::string& name, uint256& hash);
bool updateTakeoverHeight(const std::string& name, int nTakeoverHeight); bool updateTakeoverHeight(const std::string& name, int nTakeoverHeight);
@ -295,7 +296,7 @@ private:
void updateSupportQueue(int nHeight, supportQueueRowType& row); void updateSupportQueue(int nHeight, supportQueueRowType& row);
void updateSupportNameQueue(const std::string& name, void updateSupportNameQueue(const std::string& name,
std::vector<CSupportValue>& row); std::vector<CSupportValue>& row);
void updateSupportExpirationRow(int nHeight, supportQueueRowType& row); void updateSupportExpirationQueue(int nHeight, supportQueueRowType& row);
void BatchWriteNode(CLevelDBBatch& batch, const std::string& name, void BatchWriteNode(CLevelDBBatch& batch, const std::string& name,
const CClaimTrieNode* pNode) const; const CClaimTrieNode* pNode) const;
@ -368,12 +369,12 @@ public:
bool incrementBlock(claimQueueRowType& insertUndo, bool incrementBlock(claimQueueRowType& insertUndo,
claimQueueRowType& expireUndo, claimQueueRowType& expireUndo,
supportQueueRowType& insertSupportUndo, supportQueueRowType& insertSupportUndo,
// supportQueueRowType& expireSupportUndo, supportQueueRowType& expireSupportUndo,
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const; std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const;
bool decrementBlock(claimQueueRowType& insertUndo, bool decrementBlock(claimQueueRowType& insertUndo,
claimQueueRowType& expireUndo, claimQueueRowType& expireUndo,
supportQueueRowType& insertSupportUndo, supportQueueRowType& insertSupportUndo,
// supportQueueRowType& expireSupportUndo, supportQueueRowType& expireSupportUndo,
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const; std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const;
~CClaimTrieCache() { clear(); } ~CClaimTrieCache() { clear(); }

View file

@ -1611,7 +1611,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
if (blockUndo.vtxundo.size() + 1 != block.vtx.size()) if (blockUndo.vtxundo.size() + 1 != block.vtx.size())
return error("DisconnectBlock(): block and undo data inconsistent"); return error("DisconnectBlock(): block and undo data inconsistent");
assert(trieCache.decrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo, blockUndo.takeoverHeightUndo)); assert(trieCache.decrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo, blockUndo.expireSupportUndo, blockUndo.takeoverHeightUndo));
// undo transactions in reverse order // undo transactions in reverse order
for (int i = block.vtx.size() - 1; i >= 0; i--) { for (int i = block.vtx.size() - 1; i >= 0; i--) {
@ -2067,7 +2067,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION); pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
} }
assert(trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, blockundo.insertSupportUndo, blockundo.takeoverHeightUndo)); assert(trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, blockundo.insertSupportUndo, blockundo.expireSupportUndo, blockundo.takeoverHeightUndo));
if (trieCache.getMerkleHash() != block.hashClaimTrie) if (trieCache.getMerkleHash() != block.hashClaimTrie)
return state.DoS(100, return state.DoS(100,

View file

@ -467,8 +467,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
claimQueueRowType dummyInsertUndo; claimQueueRowType dummyInsertUndo;
claimQueueRowType dummyExpireUndo; claimQueueRowType dummyExpireUndo;
supportQueueRowType dummyInsertSupportUndo; supportQueueRowType dummyInsertSupportUndo;
supportQueueRowType dummyExpireSupportUndo;
std::vector<std::pair<std::string, int> > dummyTakeoverHeightUndo; std::vector<std::pair<std::string, int> > dummyTakeoverHeightUndo;
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyTakeoverHeightUndo); trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverHeightUndo);
pblock->hashClaimTrie = trieCache.getMerkleHash(); pblock->hashClaimTrie = trieCache.getMerkleHash();
CValidationState state; CValidationState state;

View file

@ -2029,6 +2029,246 @@ BOOST_AUTO_TEST_CASE(claimtrie_supporting_claims2)
BOOST_CHECK(pclaimTrie->supportQueueEmpty()); BOOST_CHECK(pclaimTrie->supportQueueEmpty());
} }
BOOST_AUTO_TEST_CASE(claimtrie_expiring_supports)
{
BOOST_CHECK(pclaimTrie->nCurrentHeight = chainActive.Height() + 1);
LOCK(cs_main);
std::string sName("atest");
std::string sValue1("testa");
std::string sValue2("testb");
std::vector<unsigned char> vchName(sName.begin(), sName.end());
std::vector<unsigned char> vchValue1(sValue1.begin(), sValue1.end());
std::vector<unsigned char> vchValue2(sValue2.begin(), sValue2.end());
std::vector<CTransaction> coinbases;
BOOST_CHECK(CreateCoinbases(3, coinbases));
CMutableTransaction tx1 = BuildTransaction(coinbases[0]);
tx1.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName << vchValue1 << OP_2DROP << OP_DROP << OP_TRUE;
tx1.vout[0].nValue = 100000000;
COutPoint tx1OutPoint(tx1.GetHash(), 0);
CMutableTransaction tx2 = BuildTransaction(coinbases[1]);
tx2.vout[0].scriptPubKey = CScript() << OP_CLAIM_NAME << vchName << vchValue2 << OP_2DROP << OP_DROP << OP_TRUE;
tx2.vout[0].nValue = 500000000;
COutPoint tx2OutPoint(tx2.GetHash(), 0);
CMutableTransaction tx3 = BuildTransaction(coinbases[2]);
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;
COutPoint tx3OutPoint(tx3.GetHash(), 0);
CMutableTransaction tx4 = BuildTransaction(tx1);
tx4.vout[0].scriptPubKey = CScript() << OP_UPDATE_CLAIM << vchName << vchTx1ClaimId << vchValue1 << OP_2DROP << OP_2DROP << OP_TRUE;
COutPoint tx4OutPoint(tx4.GetHash(), 0);
CMutableTransaction tx5 = BuildTransaction(tx3);
tx5.vout[0].scriptPubKey = CScript() << OP_TRUE;
COutPoint tx5OutPoint(tx5.GetHash(), 0);
CClaimValue val;
std::vector<uint256> blocks_to_invalidate;
pclaimTrie->setExpirationTime(200);
// Verify that supports expire
// Create a 1 LBC claim (tx1)
AddToMempool(tx1);
BOOST_CHECK(CreateBlocks(1, 2));
blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash());
BOOST_CHECK(pcoinsTip->HaveCoins(tx1.GetHash()));
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK(pclaimTrie->queueEmpty());
BOOST_CHECK(pclaimTrie->supportEmpty());
BOOST_CHECK(pclaimTrie->supportQueueEmpty());
// Create a 5 LBC support (tx3)
AddToMempool(tx3);
BOOST_CHECK(CreateBlocks(1, 2));
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK(pclaimTrie->queueEmpty());
BOOST_CHECK(!pclaimTrie->supportEmpty());
BOOST_CHECK(pclaimTrie->supportQueueEmpty());
// Advance some, then insert 5 LBC claim (tx2)
BOOST_CHECK(CreateBlocks(49, 1));
AddToMempool(tx2);
BOOST_CHECK(CreateBlocks(1, 2));
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK(!pclaimTrie->queueEmpty());
BOOST_CHECK(!pclaimTrie->supportEmpty());
BOOST_CHECK(pclaimTrie->supportQueueEmpty());
// Advance until tx2 is valid
BOOST_CHECK(CreateBlocks(50, 1));
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK(!pclaimTrie->queueEmpty());
BOOST_CHECK(!pclaimTrie->supportEmpty());
BOOST_CHECK(pclaimTrie->supportQueueEmpty());
BOOST_CHECK(CreateBlocks(1, 1));
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.outPoint == tx1OutPoint);
// Update tx1 so that it expires after tx3 expires
AddToMempool(tx4);
BOOST_CHECK(CreateBlocks(1, 2));
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.outPoint == tx4OutPoint);
// Advance until the support expires
BOOST_CHECK(CreateBlocks(50, 1));
blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash());
BOOST_CHECK(CreateBlocks(47, 1));
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK(pclaimTrie->queueEmpty());
BOOST_CHECK(!pclaimTrie->supportEmpty());
BOOST_CHECK(pclaimTrie->supportQueueEmpty());
BOOST_CHECK(CreateBlocks(1, 1));
blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash());
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.outPoint == tx2OutPoint);
// undo the block, make sure control goes back
BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back()));
blocks_to_invalidate.pop_back();
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.outPoint == tx4OutPoint);
// redo the block, make sure it expires again
BOOST_CHECK(CreateBlocks(1, 1));
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.outPoint == tx2OutPoint);
// roll back some, spend the support, and make sure nothing unexpected
// happens at the time the support should have expired
BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back()));
blocks_to_invalidate.pop_back();
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.outPoint == tx4OutPoint);
AddToMempool(tx5);
BOOST_CHECK(CreateBlocks(1, 2));
blocks_to_invalidate.push_back(chainActive.Tip()->GetBlockHash());
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.outPoint == tx2OutPoint);
BOOST_CHECK(CreateBlocks(50, 1));
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.outPoint == tx2OutPoint);
//undo the spend, and make sure it still expires on time
BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back()));
blocks_to_invalidate.pop_back();
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.outPoint == tx4OutPoint);
BOOST_CHECK(CreateBlocks(48, 1));
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.outPoint == tx4OutPoint);
BOOST_CHECK(CreateBlocks(1, 1));
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.outPoint == tx2OutPoint);
// roll all the way back
BOOST_CHECK(RemoveBlock(blocks_to_invalidate.back()));
blocks_to_invalidate.pop_back();
BOOST_CHECK(pclaimTrie->empty());
BOOST_CHECK(pclaimTrie->queueEmpty());
BOOST_CHECK(pclaimTrie->supportEmpty());
BOOST_CHECK(pclaimTrie->supportQueueEmpty());
}
BOOST_AUTO_TEST_CASE(claimtrienode_serialize_unserialize) BOOST_AUTO_TEST_CASE(claimtrienode_serialize_unserialize)
{ {
CDataStream ss(SER_DISK, 0); CDataStream ss(SER_DISK, 0);

View file

@ -86,7 +86,8 @@ public:
std::vector<CTxUndo> vtxundo; // for all but the coinbase std::vector<CTxUndo> vtxundo; // for all but the coinbase
claimQueueRowType insertUndo; // any claims that went from the queue to the trie claimQueueRowType insertUndo; // any claims that went from the queue to the trie
claimQueueRowType expireUndo; // any claims that expired claimQueueRowType expireUndo; // any claims that expired
supportQueueRowType insertSupportUndo; // any claims that went from the support queue to the support map supportQueueRowType insertSupportUndo; // any supports that went from the support queue to the support map
supportQueueRowType expireSupportUndo; // any supports that expired
std::vector<std::pair<std::string, int> > takeoverHeightUndo; // for any name that was taken over, the previous time that name was taken over std::vector<std::pair<std::string, int> > takeoverHeightUndo; // for any name that was taken over, the previous time that name was taken over
ADD_SERIALIZE_METHODS; ADD_SERIALIZE_METHODS;
@ -97,6 +98,7 @@ public:
READWRITE(insertUndo); READWRITE(insertUndo);
READWRITE(expireUndo); READWRITE(expireUndo);
READWRITE(insertSupportUndo); READWRITE(insertSupportUndo);
READWRITE(expireSupportUndo);
READWRITE(takeoverHeightUndo); READWRITE(takeoverHeightUndo);
} }
}; };