Implement a hard fork for extended/infinite claim expiration times #112
5 changed files with 69 additions and 43 deletions
|
@ -1641,6 +1641,7 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CNCCTrie
|
||||||
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, CNCCTrieCache& trieCache, bool* pfClean)
|
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, CNCCTrieCache& trieCache, bool* pfClean)
|
||||||
{
|
{
|
||||||
assert(pindex->GetBlockHash() == view.GetBestBlock());
|
assert(pindex->GetBlockHash() == view.GetBestBlock());
|
||||||
|
assert(pindex->GetBlockHash() == trieCache.getBestBlock());
|
||||||
|
|
||||||
if (pfClean)
|
if (pfClean)
|
||||||
*pfClean = false;
|
*pfClean = false;
|
||||||
|
@ -1714,6 +1715,7 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
|
||||||
|
|
||||||
// move best block pointer to prevout block
|
// move best block pointer to prevout block
|
||||||
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
||||||
|
trieCache.setBestBlock(pindex->pprev->GetBlockHash());
|
||||||
assert(trieCache.getMerkleHash() == pindex->pprev->hashNCCTrie);
|
assert(trieCache.getMerkleHash() == pindex->pprev->hashNCCTrie);
|
||||||
|
|
||||||
if (pfClean) {
|
if (pfClean) {
|
||||||
|
@ -1773,11 +1775,17 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
|
uint256 hashPrevBlock = pindex->pprev == NULL ? uint256() : pindex->pprev->GetBlockHash();
|
||||||
assert(hashPrevBlock == view.GetBestBlock());
|
assert(hashPrevBlock == view.GetBestBlock());
|
||||||
|
|
||||||
|
// also verify that the trie cache's current state corresponds to the previous block
|
||||||
|
assert(hashPrevBlock == trieCache.getBestBlock());
|
||||||
|
|
||||||
// Special case for the genesis block, skipping connection of its transactions
|
// Special case for the genesis block, skipping connection of its transactions
|
||||||
// (its coinbase is unspendable)
|
// (its coinbase is unspendable)
|
||||||
if (block.GetHash() == Params().HashGenesisBlock()) {
|
if (block.GetHash() == Params().HashGenesisBlock()) {
|
||||||
if (!fJustCheck)
|
if (!fJustCheck)
|
||||||
|
{
|
||||||
view.SetBestBlock(pindex->GetBlockHash());
|
view.SetBestBlock(pindex->GetBlockHash());
|
||||||
|
trieCache.setBestBlock(pindex->GetBlockHash());
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1960,6 +1968,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
||||||
|
|
||||||
// add this block to the view's block chain
|
// add this block to the view's block chain
|
||||||
view.SetBestBlock(pindex->GetBlockHash());
|
view.SetBestBlock(pindex->GetBlockHash());
|
||||||
|
trieCache.setBestBlock(pindex->GetBlockHash());
|
||||||
|
|
||||||
int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
|
int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2;
|
||||||
LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
|
LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001);
|
||||||
|
|
|
@ -175,7 +175,7 @@ bool CNCCTrie::recursiveCheckConsistency(CNCCTrieNode* node)
|
||||||
return calculatedHash == node->hash;
|
return calculatedHash == node->hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNCCTrie::update(nodeCacheType& cache, hashMapType& hashes)
|
bool CNCCTrie::update(nodeCacheType& cache, hashMapType& hashes, const uint256& hashBlockIn)
|
||||||
{
|
{
|
||||||
// General strategy: the cache is ordered by length, ensuring child
|
// General strategy: the cache is ordered by length, ensuring child
|
||||||
// nodes are always inserted after their parents. Insert each node
|
// nodes are always inserted after their parents. Insert each node
|
||||||
|
@ -196,10 +196,6 @@ bool CNCCTrie::update(nodeCacheType& cache, hashMapType& hashes)
|
||||||
// appending extra data to the normal txundo, which will call the
|
// appending extra data to the normal txundo, which will call the
|
||||||
// normal insert/remove names, but obviously the opposite and in
|
// normal insert/remove names, but obviously the opposite and in
|
||||||
// reverse order (though the order shouldn't ever matter).
|
// reverse order (though the order shouldn't ever matter).
|
||||||
if (cache.empty())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool success = true;
|
bool success = true;
|
||||||
std::vector<std::string> deletedNames;
|
std::vector<std::string> deletedNames;
|
||||||
for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache)
|
for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache)
|
||||||
|
@ -217,7 +213,8 @@ bool CNCCTrie::update(nodeCacheType& cache, hashMapType& hashes)
|
||||||
return false;
|
return false;
|
||||||
changedNodes[ithash->first] = pNode;
|
changedNodes[ithash->first] = pNode;
|
||||||
}
|
}
|
||||||
BatchWrite(changedNodes, deletedNames);
|
BatchWrite(changedNodes, deletedNames, hashBlockIn);
|
||||||
|
hashBlock = hashBlockIn;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,13 +305,14 @@ void BatchEraseNode(CLevelDBBatch& batch, const std::string& name)
|
||||||
batch.Erase(std::make_pair('n', name));
|
batch.Erase(std::make_pair('n', name));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNCCTrie::BatchWrite(nodeCacheType& changedNodes, std::vector<std::string>& deletedNames)
|
bool CNCCTrie::BatchWrite(nodeCacheType& changedNodes, std::vector<std::string>& deletedNames, const uint256& hashBlockIn)
|
||||||
{
|
{
|
||||||
CLevelDBBatch batch;
|
CLevelDBBatch batch;
|
||||||
for (nodeCacheType::iterator itcache = changedNodes.begin(); itcache != changedNodes.end(); ++itcache)
|
for (nodeCacheType::iterator itcache = changedNodes.begin(); itcache != changedNodes.end(); ++itcache)
|
||||||
BatchWriteNode(batch, itcache->first, itcache->second);
|
BatchWriteNode(batch, itcache->first, itcache->second);
|
||||||
for (std::vector<std::string>::iterator itname = deletedNames.begin(); itname != deletedNames.end(); ++itname)
|
for (std::vector<std::string>::iterator itname = deletedNames.begin(); itname != deletedNames.end(); ++itname)
|
||||||
BatchEraseNode(batch, *itname);
|
BatchEraseNode(batch, *itname);
|
||||||
|
batch.Write('h', hashBlockIn);
|
||||||
return db.WriteBatch(batch);
|
return db.WriteBatch(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,6 +337,9 @@ bool CNCCTrie::InsertFromDisk(const std::string& name, CNCCTrieNode* node)
|
||||||
|
|
||||||
bool CNCCTrie::ReadFromDisk(bool check)
|
bool CNCCTrie::ReadFromDisk(bool check)
|
||||||
{
|
{
|
||||||
|
if (!db.Read('h', hashBlock))
|
||||||
|
LogPrintf("%s: Couldn't read the best block's hash\n", __func__);
|
||||||
|
|
||||||
boost::scoped_ptr<leveldb::Iterator> pcursor(const_cast<CLevelDBWrapper*>(&db)->NewIterator());
|
boost::scoped_ptr<leveldb::Iterator> pcursor(const_cast<CLevelDBWrapper*>(&db)->NewIterator());
|
||||||
pcursor->SeekToFirst();
|
pcursor->SeekToFirst();
|
||||||
|
|
||||||
|
@ -459,7 +460,7 @@ uint256 CNCCTrieCache::getMerkleHash() const
|
||||||
|
|
||||||
bool CNCCTrieCache::empty() const
|
bool CNCCTrieCache::empty() const
|
||||||
{
|
{
|
||||||
return !base || (base->empty() && cache.empty());
|
return base->empty() && cache.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CNCCTrieCache::insertName(const std::string name, uint256 txhash, int nOut, CAmount nAmount, int nHeight) const
|
bool CNCCTrieCache::insertName(const std::string name, uint256 txhash, int nOut, CAmount nAmount, int nHeight) const
|
||||||
|
@ -673,6 +674,19 @@ bool CNCCTrieCache::recursivePruneName(CNCCTrieNode* tnCurrent, unsigned int nPo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint256 CNCCTrieCache::getBestBlock()
|
||||||
|
{
|
||||||
|
if (hashBlock.IsNull())
|
||||||
|
if (base != NULL)
|
||||||
|
hashBlock = base->hashBlock;
|
||||||
|
return hashBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CNCCTrieCache::setBestBlock(const uint256& hashBlockIn)
|
||||||
|
{
|
||||||
|
hashBlock = hashBlockIn;
|
||||||
|
}
|
||||||
|
|
||||||
bool CNCCTrieCache::clear() const
|
bool CNCCTrieCache::clear() const
|
||||||
{
|
{
|
||||||
for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache)
|
for (nodeCacheType::iterator itcache = cache.begin(); itcache != cache.end(); ++itcache)
|
||||||
|
@ -689,9 +703,7 @@ bool CNCCTrieCache::flush()
|
||||||
{
|
{
|
||||||
if (dirty())
|
if (dirty())
|
||||||
getMerkleHash();
|
getMerkleHash();
|
||||||
if (!base)
|
bool success = base->update(cache, cacheHashes, hashBlock);
|
||||||
return true;
|
|
||||||
bool success = base->update(cache, cacheHashes);
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
success = clear();
|
success = clear();
|
||||||
|
|
|
@ -133,27 +133,30 @@ public:
|
||||||
json_spirit::Object getInfoForName(const std::string& name) const;
|
json_spirit::Object getInfoForName(const std::string& name) const;
|
||||||
friend class CNCCTrieCache;
|
friend class CNCCTrieCache;
|
||||||
private:
|
private:
|
||||||
bool update(nodeCacheType& cache, hashMapType& hashes);
|
bool update(nodeCacheType& cache, hashMapType& hashes, const uint256& hashBlock);
|
||||||
bool updateName(const std::string& name, CNCCTrieNode* updatedNode, std::vector<std::string>& deletedNames);
|
bool updateName(const std::string& name, CNCCTrieNode* updatedNode, std::vector<std::string>& deletedNames);
|
||||||
bool updateHash(const std::string& name, uint256& hash, CNCCTrieNode** pNodeRet);
|
bool updateHash(const std::string& name, uint256& hash, CNCCTrieNode** pNodeRet);
|
||||||
bool recursiveNullify(CNCCTrieNode* node, std::string& name, std::vector<std::string>& deletedNames);
|
bool recursiveNullify(CNCCTrieNode* node, std::string& name, std::vector<std::string>& deletedNames);
|
||||||
bool recursiveCheckConsistency(CNCCTrieNode* node);
|
bool recursiveCheckConsistency(CNCCTrieNode* node);
|
||||||
bool BatchWrite(nodeCacheType& changedNodes, std::vector<std::string>& deletedNames);
|
bool BatchWrite(nodeCacheType& changedNodes, std::vector<std::string>& deletedNames, const uint256& hashBlock);
|
||||||
bool InsertFromDisk(const std::string& name, CNCCTrieNode* node);
|
bool InsertFromDisk(const std::string& name, CNCCTrieNode* node);
|
||||||
bool recursiveDumpToJSON(const std::string& name, const CNCCTrieNode* current, json_spirit::Array& ret) const;
|
bool recursiveDumpToJSON(const std::string& name, const CNCCTrieNode* current, json_spirit::Array& ret) const;
|
||||||
CNCCTrieNode root;
|
CNCCTrieNode root;
|
||||||
|
uint256 hashBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CNCCTrieCache
|
class CNCCTrieCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CNCCTrieCache(CNCCTrie* base): base(base) {}
|
CNCCTrieCache(CNCCTrie* base): base(base) {assert(base);}
|
||||||
uint256 getMerkleHash() const;
|
uint256 getMerkleHash() const;
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
bool flush();
|
bool flush();
|
||||||
bool dirty() const { return !dirtyHashes.empty(); }
|
bool dirty() const { return !dirtyHashes.empty(); }
|
||||||
bool insertName (const std::string name, uint256 txhash, int nOut, CAmount nAmount, int nDepth) const;
|
bool insertName (const std::string name, uint256 txhash, int nOut, CAmount nAmount, int nDepth) const;
|
||||||
bool removeName (const std::string name, uint256 txhash, int nOut) const;
|
bool removeName (const std::string name, uint256 txhash, int nOut) const;
|
||||||
|
uint256 getBestBlock();
|
||||||
|
void setBestBlock(const uint256& hashBlock);
|
||||||
~CNCCTrieCache() { clear(); }
|
~CNCCTrieCache() { clear(); }
|
||||||
private:
|
private:
|
||||||
CNCCTrie* base;
|
CNCCTrie* base;
|
||||||
|
@ -164,6 +167,7 @@ private:
|
||||||
bool recursiveComputeMerkleHash(CNCCTrieNode* tnCurrent, std::string sPos) const;
|
bool recursiveComputeMerkleHash(CNCCTrieNode* tnCurrent, std::string sPos) const;
|
||||||
bool recursivePruneName(CNCCTrieNode* tnCurrent, unsigned int nPos, std::string sName, bool* pfNullified = NULL) const;
|
bool recursivePruneName(CNCCTrieNode* tnCurrent, unsigned int nPos, std::string sName, bool* pfNullified = NULL) const;
|
||||||
bool clear() const;
|
bool clear() const;
|
||||||
|
uint256 hashBlock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_NCCTRIE_H
|
#endif // BITCOIN_NCCTRIE_H
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Distributed under the MIT software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://opensource.org/licenses/mit-license.php
|
// file COPYING or http://opensource.org/licenses/mit-license.php
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
#include "primitives/transaction.h"
|
#include "primitives/transaction.h"
|
||||||
#include "ncctrie.h"
|
#include "ncctrie.h"
|
||||||
#include "coins.h"
|
#include "coins.h"
|
||||||
|
@ -52,15 +53,13 @@ BOOST_AUTO_TEST_CASE(ncctrie_create_insert_remove)
|
||||||
uint256 hash4;
|
uint256 hash4;
|
||||||
hash4.SetHex("a79e8a5b28f7fa5e8836a4b48da9988bdf56ce749f81f413cb754f963a516200");
|
hash4.SetHex("a79e8a5b28f7fa5e8836a4b48da9988bdf56ce749f81f413cb754f963a516200");
|
||||||
|
|
||||||
CNCCTrie trie;
|
BOOST_CHECK(pnccTrie->empty());
|
||||||
|
|
||||||
BOOST_CHECK(trie.empty());
|
CNCCTrieCache ntState(pnccTrie);
|
||||||
|
|
||||||
CNCCTrieCache ntState(&trie);
|
|
||||||
ntState.insertName(std::string("test"), tx1.GetHash(), 0, 50, 100);
|
ntState.insertName(std::string("test"), tx1.GetHash(), 0, 50, 100);
|
||||||
ntState.insertName(std::string("test2"), tx2.GetHash(), 0, 50, 100);
|
ntState.insertName(std::string("test2"), tx2.GetHash(), 0, 50, 100);
|
||||||
|
|
||||||
BOOST_CHECK(trie.empty());
|
BOOST_CHECK(pnccTrie->empty());
|
||||||
BOOST_CHECK(!ntState.empty());
|
BOOST_CHECK(!ntState.empty());
|
||||||
BOOST_CHECK(ntState.getMerkleHash() == hash1);
|
BOOST_CHECK(ntState.getMerkleHash() == hash1);
|
||||||
|
|
||||||
|
@ -73,11 +72,11 @@ BOOST_AUTO_TEST_CASE(ncctrie_create_insert_remove)
|
||||||
BOOST_CHECK(ntState.getMerkleHash() == hash2);
|
BOOST_CHECK(ntState.getMerkleHash() == hash2);
|
||||||
ntState.flush();
|
ntState.flush();
|
||||||
|
|
||||||
BOOST_CHECK(!trie.empty());
|
BOOST_CHECK(!pnccTrie->empty());
|
||||||
BOOST_CHECK(trie.getMerkleHash() == hash2);
|
BOOST_CHECK(pnccTrie->getMerkleHash() == hash2);
|
||||||
BOOST_CHECK(trie.checkConsistency());
|
BOOST_CHECK(pnccTrie->checkConsistency());
|
||||||
|
|
||||||
CNCCTrieCache ntState1(&trie);
|
CNCCTrieCache ntState1(pnccTrie);
|
||||||
ntState1.removeName(std::string("test"), tx1.GetHash(), 0);
|
ntState1.removeName(std::string("test"), tx1.GetHash(), 0);
|
||||||
ntState1.removeName(std::string("test2"), tx2.GetHash(), 0);
|
ntState1.removeName(std::string("test2"), tx2.GetHash(), 0);
|
||||||
ntState1.removeName(std::string("test"), tx3.GetHash(), 0);
|
ntState1.removeName(std::string("test"), tx3.GetHash(), 0);
|
||||||
|
@ -85,7 +84,7 @@ BOOST_AUTO_TEST_CASE(ncctrie_create_insert_remove)
|
||||||
|
|
||||||
BOOST_CHECK(ntState1.getMerkleHash() == hash0);
|
BOOST_CHECK(ntState1.getMerkleHash() == hash0);
|
||||||
|
|
||||||
CNCCTrieCache ntState2(&trie);
|
CNCCTrieCache ntState2(pnccTrie);
|
||||||
ntState2.insertName(std::string("abab"), tx6.GetHash(), 0, 50, 100);
|
ntState2.insertName(std::string("abab"), tx6.GetHash(), 0, 50, 100);
|
||||||
ntState2.removeName(std::string("test"), tx1.GetHash(), 0);
|
ntState2.removeName(std::string("test"), tx1.GetHash(), 0);
|
||||||
|
|
||||||
|
@ -93,43 +92,43 @@ BOOST_AUTO_TEST_CASE(ncctrie_create_insert_remove)
|
||||||
|
|
||||||
ntState2.flush();
|
ntState2.flush();
|
||||||
|
|
||||||
BOOST_CHECK(!trie.empty());
|
BOOST_CHECK(!pnccTrie->empty());
|
||||||
BOOST_CHECK(trie.getMerkleHash() == hash3);
|
BOOST_CHECK(pnccTrie->getMerkleHash() == hash3);
|
||||||
BOOST_CHECK(trie.checkConsistency());
|
BOOST_CHECK(pnccTrie->checkConsistency());
|
||||||
|
|
||||||
CNCCTrieCache ntState3(&trie);
|
CNCCTrieCache ntState3(pnccTrie);
|
||||||
ntState3.insertName(std::string("test"), tx1.GetHash(), 0, 50, 100);
|
ntState3.insertName(std::string("test"), tx1.GetHash(), 0, 50, 100);
|
||||||
BOOST_CHECK(ntState3.getMerkleHash() == hash4);
|
BOOST_CHECK(ntState3.getMerkleHash() == hash4);
|
||||||
ntState3.flush();
|
ntState3.flush();
|
||||||
BOOST_CHECK(!trie.empty());
|
BOOST_CHECK(!pnccTrie->empty());
|
||||||
BOOST_CHECK(trie.getMerkleHash() == hash4);
|
BOOST_CHECK(pnccTrie->getMerkleHash() == hash4);
|
||||||
BOOST_CHECK(trie.checkConsistency());
|
BOOST_CHECK(pnccTrie->checkConsistency());
|
||||||
|
|
||||||
CNCCTrieCache ntState4(&trie);
|
CNCCTrieCache ntState4(pnccTrie);
|
||||||
ntState4.removeName(std::string("abab"), tx6.GetHash(), 0);
|
ntState4.removeName(std::string("abab"), tx6.GetHash(), 0);
|
||||||
BOOST_CHECK(ntState4.getMerkleHash() == hash2);
|
BOOST_CHECK(ntState4.getMerkleHash() == hash2);
|
||||||
ntState4.flush();
|
ntState4.flush();
|
||||||
BOOST_CHECK(!trie.empty());
|
BOOST_CHECK(!pnccTrie->empty());
|
||||||
BOOST_CHECK(trie.getMerkleHash() == hash2);
|
BOOST_CHECK(pnccTrie->getMerkleHash() == hash2);
|
||||||
BOOST_CHECK(trie.checkConsistency());
|
BOOST_CHECK(pnccTrie->checkConsistency());
|
||||||
|
|
||||||
CNCCTrieCache ntState5(&trie);
|
CNCCTrieCache ntState5(pnccTrie);
|
||||||
ntState5.removeName(std::string("test"), tx3.GetHash(), 0);
|
ntState5.removeName(std::string("test"), tx3.GetHash(), 0);
|
||||||
|
|
||||||
BOOST_CHECK(ntState5.getMerkleHash() == hash2);
|
BOOST_CHECK(ntState5.getMerkleHash() == hash2);
|
||||||
ntState5.flush();
|
ntState5.flush();
|
||||||
BOOST_CHECK(!trie.empty());
|
BOOST_CHECK(!pnccTrie->empty());
|
||||||
BOOST_CHECK(trie.getMerkleHash() == hash2);
|
BOOST_CHECK(pnccTrie->getMerkleHash() == hash2);
|
||||||
BOOST_CHECK(trie.checkConsistency());
|
BOOST_CHECK(pnccTrie->checkConsistency());
|
||||||
|
|
||||||
CNCCTrieCache ntState6(&trie);
|
CNCCTrieCache ntState6(pnccTrie);
|
||||||
ntState6.insertName(std::string("test"), tx3.GetHash(), 0, 50, 101);
|
ntState6.insertName(std::string("test"), tx3.GetHash(), 0, 50, 101);
|
||||||
|
|
||||||
BOOST_CHECK(ntState6.getMerkleHash() == hash2);
|
BOOST_CHECK(ntState6.getMerkleHash() == hash2);
|
||||||
ntState6.flush();
|
ntState6.flush();
|
||||||
BOOST_CHECK(!trie.empty());
|
BOOST_CHECK(!pnccTrie->empty());
|
||||||
BOOST_CHECK(trie.getMerkleHash() == hash2);
|
BOOST_CHECK(pnccTrie->getMerkleHash() == hash2);
|
||||||
BOOST_CHECK(trie.checkConsistency());
|
BOOST_CHECK(pnccTrie->checkConsistency());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(ncctrienode_serialize_unserialize)
|
BOOST_AUTO_TEST_CASE(ncctrienode_serialize_unserialize)
|
||||||
|
|
|
@ -42,6 +42,7 @@ struct TestingSetup {
|
||||||
pblocktree = new CBlockTreeDB(1 << 20, true);
|
pblocktree = new CBlockTreeDB(1 << 20, true);
|
||||||
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
||||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
||||||
|
pnccTrie = new CNCCTrie();
|
||||||
InitBlockIndex();
|
InitBlockIndex();
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
bool fFirstRun;
|
bool fFirstRun;
|
||||||
|
@ -63,6 +64,7 @@ struct TestingSetup {
|
||||||
delete pwalletMain;
|
delete pwalletMain;
|
||||||
pwalletMain = NULL;
|
pwalletMain = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
delete pnccTrie;
|
||||||
delete pcoinsTip;
|
delete pcoinsTip;
|
||||||
delete pcoinsdbview;
|
delete pcoinsdbview;
|
||||||
delete pblocktree;
|
delete pblocktree;
|
||||||
|
|
Loading…
Reference in a new issue