runs to norm fork
This commit is contained in:
parent
ef244ca801
commit
217c102f8f
4 changed files with 106 additions and 45 deletions
|
@ -96,7 +96,7 @@ bool CClaimScriptSpendOp::claimName(CClaimTrieCache& trieCache, const std::strin
|
||||||
{
|
{
|
||||||
auto claimId = ClaimIdHash(point.hash, point.n);
|
auto claimId = ClaimIdHash(point.hash, point.n);
|
||||||
auto ret = spendClaim(trieCache, name, claimId);
|
auto ret = spendClaim(trieCache, name, claimId);
|
||||||
LogPrint(BCLog::CLAIMS, "--- Spending original claim: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
LogPrint(BCLog::CLAIMS, "--- Spent original claim: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
||||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -105,7 +105,7 @@ bool CClaimScriptSpendOp::updateClaim(CClaimTrieCache& trieCache, const std::str
|
||||||
const std::vector<unsigned char>& metadata)
|
const std::vector<unsigned char>& metadata)
|
||||||
{
|
{
|
||||||
auto ret = spendClaim(trieCache, name, claimId);
|
auto ret = spendClaim(trieCache, name, claimId);
|
||||||
LogPrint(BCLog::CLAIMS, "--- Spending updated claim: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
LogPrint(BCLog::CLAIMS, "--- Spent updated claim: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
||||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ bool CClaimScriptSpendOp::supportClaim(CClaimTrieCache& trieCache, const std::st
|
||||||
{
|
{
|
||||||
std::string nodeName;
|
std::string nodeName;
|
||||||
bool res = trieCache.removeSupport(point, nodeName, nValidHeight);
|
bool res = trieCache.removeSupport(point, nodeName, nValidHeight);
|
||||||
LogPrint(BCLog::CLAIMS, "--- Spending support: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
LogPrint(BCLog::CLAIMS, "--- Spent support: %s, c: %.6s, t: %.6s:%d, h: %.6d, vh: %d\n",
|
||||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValidHeight);
|
||||||
if (!res)
|
if (!res)
|
||||||
LogPrint(BCLog::CLAIMS, "Remove support failed for %s with claimid %s\n", name, claimId.GetHex().substr(0, 6));
|
LogPrint(BCLog::CLAIMS, "Remove support failed for %s with claimid %s\n", name, claimId.GetHex().substr(0, 6));
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
#include <utilstrencodings.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -80,7 +81,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor)
|
||||||
db << "CREATE INDEX IF NOT EXISTS supports_nodeName ON supports (nodeName)";
|
db << "CREATE INDEX IF NOT EXISTS supports_nodeName ON supports (nodeName)";
|
||||||
|
|
||||||
db << "PRAGMA cache_size=-" + std::to_string(5 * 1024); // in -KB
|
db << "PRAGMA cache_size=-" + std::to_string(5 * 1024); // in -KB
|
||||||
db << "PRAGMA synchronous=NORMAL"; // don't disk sync after transaction commit
|
db << "PRAGMA synchronous=OFF"; // don't disk sync after transaction commit
|
||||||
db << "PRAGMA journal_mode=MEMORY";
|
db << "PRAGMA journal_mode=MEMORY";
|
||||||
db << "PRAGMA temp_store=MEMORY";
|
db << "PRAGMA temp_store=MEMORY";
|
||||||
db << "PRAGMA case_sensitive_like=true";
|
db << "PRAGMA case_sensitive_like=true";
|
||||||
|
@ -171,15 +172,12 @@ bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const COut
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims) {
|
bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::string& parent, int64_t& claims) {
|
||||||
if (name.empty()) return false;
|
if (name.empty()) return false;
|
||||||
// to remove a node it must have one or less children and no claims
|
// to remove a node it must have one or less children and no claims
|
||||||
claims.clear();
|
db << "SELECT COUNT(*) FROM claims WHERE nodeName = ?1 AND validHeight < ?2 AND expirationHeight >= ?2 "
|
||||||
db << "SELECT name FROM claims WHERE nodeName = ?1 AND validHeight < ?2 AND expirationHeight >= ?2 "
|
<< name << nNextHeight >> claims;
|
||||||
<< name << nNextHeight >> [&claims](std::string name) {
|
if (claims > 0) return false; // still has claims
|
||||||
claims.push_back(std::move(name));
|
|
||||||
};
|
|
||||||
if (!claims.empty()) return false; // still has claims
|
|
||||||
// we now know it has no claims, but we need to check its children
|
// we now know it has no claims, but we need to check its children
|
||||||
int64_t count;
|
int64_t count;
|
||||||
std::string childName;
|
std::string childName;
|
||||||
|
@ -204,19 +202,6 @@ bool CClaimTrieCacheBase::deleteNodeIfPossible(const std::string& name, std::str
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
std::string bin2hex(const std::string& bin)
|
|
||||||
{
|
|
||||||
std::stringstream s;
|
|
||||||
s << std::hex;
|
|
||||||
for (uint8_t i : bin) {
|
|
||||||
if (i < 16) s << '0';
|
|
||||||
s << uint32_t(i);
|
|
||||||
}
|
|
||||||
return s.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
if (!transacting) return;
|
if (!transacting) return;
|
||||||
|
|
||||||
|
@ -251,11 +236,11 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
|
|
||||||
|
|
||||||
for (auto& name: names) {
|
for (auto& name: names) {
|
||||||
std::vector<std::string> claims;
|
int64_t claims;
|
||||||
std::string parent, node;
|
std::string parent, node;
|
||||||
for (node = name; deleteNodeIfPossible(node, parent, claims);)
|
for (node = name; deleteNodeIfPossible(node, parent, claims);)
|
||||||
node = parent;
|
node = parent;
|
||||||
if (node != name || name.empty() || claims.empty())
|
if (node != name || name.empty() || claims <= 0)
|
||||||
continue; // if you have no claims but we couldn't delete you, you must have legitimate children
|
continue; // if you have no claims but we couldn't delete you, you must have legitimate children
|
||||||
|
|
||||||
parentQuery << name.substr(0, name.size() - 1);
|
parentQuery << name.substr(0, name.size() - 1);
|
||||||
|
@ -275,6 +260,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
};
|
};
|
||||||
std::size_t splitPos = 0;
|
std::size_t splitPos = 0;
|
||||||
auto psize = parent.size() + 1;
|
auto psize = parent.size() + 1;
|
||||||
|
const static std::string charsThatBreakLikeOp("_%\0", 3);
|
||||||
for (auto& sibling: siblings) {
|
for (auto& sibling: siblings) {
|
||||||
if (sibling.compare(0, psize, name, 0, psize) == 0) {
|
if (sibling.compare(0, psize, name, 0, psize) == 0) {
|
||||||
splitPos = psize;
|
splitPos = psize;
|
||||||
|
@ -294,7 +280,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
insertQuery << newNodeName << parent;
|
insertQuery << newNodeName << parent;
|
||||||
insertQuery++;
|
insertQuery++;
|
||||||
|
|
||||||
if (newNodeName.find('_') == std::string::npos && newNodeName.find('%') == std::string::npos) {
|
if (newNodeName.find_first_of(charsThatBreakLikeOp) == std::string::npos) {
|
||||||
updateUnaffectedsQuery << newNodeName << newNodeName + "_%" << newNodeName.size();
|
updateUnaffectedsQuery << newNodeName << newNodeName + "_%" << newNodeName.size();
|
||||||
updateUnaffectedsQuery++;
|
updateUnaffectedsQuery++;
|
||||||
}
|
}
|
||||||
|
@ -308,22 +294,19 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s(%s), parent %s\n", name, bin2hex(name), parent);
|
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s (%s), parent %s\n", name, HexStr(name), parent);
|
||||||
insertQuery << name << parent;
|
insertQuery << name << parent;
|
||||||
insertQuery++;
|
insertQuery++;
|
||||||
if (splitPos == 0)
|
if (splitPos == 0)
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << parent;
|
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << parent;
|
||||||
|
|
||||||
if (name.find('_') == std::string::npos && name.find('%') == std::string::npos) {
|
if (name.find_first_of(charsThatBreakLikeOp) == std::string::npos) {
|
||||||
updateUnaffectedsQuery << name << name + "_%" << name.size();
|
updateUnaffectedsQuery << name << name + "_%" << name.size();
|
||||||
updateUnaffectedsQuery++;
|
updateUnaffectedsQuery++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
||||||
<< name << name.size();
|
<< name << name.size();
|
||||||
|
|
||||||
if (name.size() == 1 && name[0] == 0)
|
|
||||||
db << "UPDATE nodes SET parent = '' WHERE name = ?" << name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parentQuery.used(true);
|
parentQuery.used(true);
|
||||||
|
@ -334,7 +317,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
// parents should all be set right
|
// parents should all be set right
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name IN (WITH RECURSIVE prefix(p) AS "
|
db << "UPDATE nodes SET hash = NULL WHERE name IN (WITH RECURSIVE prefix(p) AS "
|
||||||
"(SELECT parent FROM nodes WHERE hash IS NULL UNION SELECT parent FROM prefix, nodes "
|
"(SELECT parent FROM nodes WHERE hash IS NULL UNION SELECT parent FROM prefix, nodes "
|
||||||
"WHERE name = prefix.p AND prefix.p IS NOT NULL ORDER BY parent DESC) SELECT p FROM prefix)";
|
"WHERE name = prefix.p AND prefix.p != '') SELECT p FROM prefix)";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t CClaimTrieCacheBase::getTotalNamesInTrie() const
|
std::size_t CClaimTrieCacheBase::getTotalNamesInTrie() const
|
||||||
|
@ -357,7 +340,7 @@ std::size_t CClaimTrieCacheBase::getTotalClaimsInTrie() const
|
||||||
CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
|
||||||
{
|
{
|
||||||
CAmount ret = 0;
|
CAmount ret = 0;
|
||||||
std::string query("SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s "
|
std::string query("SELECT SUM(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM supports s "
|
||||||
"WHERE s.supportedClaimID = c.claimID AND s.validHeight < ?1 AND s.expirationHeight >= ?1) "
|
"WHERE s.supportedClaimID = c.claimID AND s.validHeight < ?1 AND s.expirationHeight >= ?1) "
|
||||||
"FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1");
|
"FROM claims c WHERE c.validHeight < ?1 AND s.expirationHeight >= ?1");
|
||||||
if (fControllingOnly)
|
if (fControllingOnly)
|
||||||
|
@ -454,7 +437,7 @@ uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name,
|
||||||
if (child.hash->IsNull()) {
|
if (child.hash->IsNull()) {
|
||||||
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
*child.hash = recursiveComputeMerkleHash(child.name, child.takeoverHeight, checkOnly);
|
||||||
}
|
}
|
||||||
LogPrint(BCLog::CLAIMS, "Hash of %s(%s): %s, takeover: %d\n", child.name, bin2hex(child.name), (*child.hash).GetHex(), child.takeoverHeight);
|
LogPrint(BCLog::CLAIMS, "Using hash of %s (%s): %s, takeover: %d\n", child.name, HexStr(child.name), (*child.hash).GetHex(), child.takeoverHeight);
|
||||||
completeHash(*child.hash, child.name, pos);
|
completeHash(*child.hash, child.name, pos);
|
||||||
vchToHash.push_back(child.name[pos]);
|
vchToHash.push_back(child.name[pos]);
|
||||||
vchToHash.insert(vchToHash.end(), child.hash->begin(), child.hash->end());
|
vchToHash.insert(vchToHash.end(), child.hash->begin(), child.hash->end());
|
||||||
|
@ -547,7 +530,7 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
||||||
nNextHeight = base->nNextHeight;
|
nNextHeight = base->nNextHeight;
|
||||||
|
|
||||||
db << "PRAGMA cache_size=-" + std::to_string(200 * 1024); // in -KB
|
db << "PRAGMA cache_size=-" + std::to_string(200 * 1024); // in -KB
|
||||||
db << "PRAGMA synchronous=NORMAL"; // don't disk sync after transaction commit
|
db << "PRAGMA synchronous=OFF"; // don't disk sync after transaction commit
|
||||||
db << "PRAGMA journal_mode=MEMORY";
|
db << "PRAGMA journal_mode=MEMORY";
|
||||||
db << "PRAGMA temp_store=MEMORY";
|
db << "PRAGMA temp_store=MEMORY";
|
||||||
db << "PRAGMA case_sensitive_like=true";
|
db << "PRAGMA case_sensitive_like=true";
|
||||||
|
@ -606,7 +589,10 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out
|
||||||
db << "INSERT INTO claims(claimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) "
|
db << "INSERT INTO claims(claimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) "
|
||||||
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << claimId << name << nodeName
|
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << claimId << name << nodeName
|
||||||
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
||||||
|
|
||||||
|
if (nValidHeight < nNextHeight)
|
||||||
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -623,7 +609,9 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& o
|
||||||
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << supportedClaimId << name << nodeName
|
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)" << supportedClaimId << name << nodeName
|
||||||
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
<< outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << expires << metadata;
|
||||||
|
|
||||||
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
if (nValidHeight < nNextHeight)
|
||||||
|
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << nodeName;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -961,10 +949,11 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
||||||
// for all dirty nodes look for new takeovers
|
// for all dirty nodes look for new takeovers
|
||||||
if (!transacting) { transacting = true; db << "begin"; }
|
if (!transacting) { transacting = true; db << "begin"; }
|
||||||
|
|
||||||
|
db << "INSERT INTO nodes(name) SELECT nodeName FROM claims "
|
||||||
|
"WHERE validHeight = ?1 AND expirationHeight > ?1 "
|
||||||
|
"ON CONFLICT(name) DO UPDATE SET hash = NULL" << nNextHeight;
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||||
"(SELECT nodeName FROM claims WHERE validHeight = ?)" << nNextHeight;
|
"(SELECT nodeName FROM supports WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
|
||||||
"(SELECT nodeName FROM supports WHERE validHeight = ?)" << nNextHeight;
|
|
||||||
|
|
||||||
assert(expireUndo.empty());
|
assert(expireUndo.empty());
|
||||||
{
|
{
|
||||||
|
@ -1027,7 +1016,7 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
||||||
if (takeoverHappening && activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover))
|
if (takeoverHappening && activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover))
|
||||||
hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1);
|
hasCandidate = getInfoForName(nameWithTakeover, candidateValue, 1);
|
||||||
|
|
||||||
LogPrint(BCLog::CLAIMS, "Takeover on %s(%s) at %d, happening: %d, set before: %d\n", nameWithTakeover, bin2hex(nameWithTakeover), nNextHeight, takeoverHappening, hasBeenSetBefore);
|
LogPrint(BCLog::CLAIMS, "Takeover on %s (%s) at %d, happening: %d, set before: %d\n", nameWithTakeover, HexStr(nameWithTakeover), nNextHeight, takeoverHappening, hasBeenSetBefore);
|
||||||
|
|
||||||
if (takeoverHappening || !hasBeenSetBefore) {
|
if (takeoverHappening || !hasBeenSetBefore) {
|
||||||
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : uint160()));
|
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, hasBeenSetBefore ? *existingID : uint160()));
|
||||||
|
@ -1129,9 +1118,9 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoTy
|
||||||
bool CClaimTrieCacheBase::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
bool CClaimTrieCacheBase::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||||
{
|
{
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||||
"(SELECT nodeName FROM claims WHERE validHeight = ?)" << nNextHeight;
|
"(SELECT nodeName FROM claims WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
db << "UPDATE nodes SET hash = NULL WHERE name IN "
|
||||||
"(SELECT nodeName FROM supports WHERE validHeight = ?)" << nNextHeight;
|
"(SELECT nodeName FROM supports WHERE validHeight = ?1 AND expirationHeight > ?1)" << nNextHeight;
|
||||||
|
|
||||||
for (auto it = takeoverUndo.crbegin(); it != takeoverUndo.crend(); ++it) {
|
for (auto it = takeoverUndo.crbegin(); it != takeoverUndo.crend(); ++it) {
|
||||||
if (it->second.second.IsNull())
|
if (it->second.second.IsNull())
|
||||||
|
|
|
@ -392,7 +392,7 @@ protected:
|
||||||
|
|
||||||
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
||||||
|
|
||||||
bool deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims);
|
bool deleteNodeIfPossible(const std::string& name, std::string& parent, int64_t& claims);
|
||||||
void ensureTreeStructureIsUpToDate();
|
void ensureTreeStructureIsUpToDate();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -401,4 +401,76 @@ BOOST_AUTO_TEST_CASE(bogus_claimtrie_hash_test)
|
||||||
BOOST_CHECK_EQUAL(orig_chain_height, chainActive.Height());
|
BOOST_CHECK_EQUAL(orig_chain_height, chainActive.Height());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MAC_OSX // can't find a random number generator that produces the same sequence on OSX
|
||||||
|
BOOST_AUTO_TEST_CASE(triehash_fuzzer_test)
|
||||||
|
{
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
|
||||||
|
auto envClaims = std::getenv("TRIEHASH_FUZZER_CLAIMS");
|
||||||
|
auto envBlocks = std::getenv("TRIEHASH_FUZZER_BLOCKS");
|
||||||
|
|
||||||
|
const int claimsPerBlock = envClaims ? std::atoi(envClaims) : 100;
|
||||||
|
const int blocks = envBlocks ? std::atoi(envBlocks) : 13;
|
||||||
|
|
||||||
|
auto names = random_strings(blocks * claimsPerBlock);
|
||||||
|
|
||||||
|
FastRandomContext frc(true);
|
||||||
|
std::unordered_map<std::string, std::vector<CMutableTransaction>> existingClaims;
|
||||||
|
std::vector<CMutableTransaction> existingSupports;
|
||||||
|
std::string value(1024, 'c');
|
||||||
|
|
||||||
|
std::vector<CTransaction> cb {fixture.GetCoinbase()};
|
||||||
|
for (int i = 0; i < blocks; ++i) {
|
||||||
|
for (int j = 0; j < claimsPerBlock; ++j) {
|
||||||
|
auto name = names[i * claimsPerBlock + j];
|
||||||
|
auto supportFront = frc.randrange(4) == 0;
|
||||||
|
auto supportBack = frc.randrange(4) == 0;
|
||||||
|
auto removeClaim = frc.randrange(4) == 0;
|
||||||
|
auto removeSupport = frc.randrange(4) == 0;
|
||||||
|
auto hit = existingClaims.find(name);
|
||||||
|
if (supportFront && hit != existingClaims.end() && hit->second.size()) {
|
||||||
|
auto tx = fixture.MakeSupport(cb.back(), hit->second[frc.rand64() % hit->second.size()], name, 2);
|
||||||
|
existingSupports.push_back(tx);
|
||||||
|
cb.emplace_back(std::move(tx));
|
||||||
|
}
|
||||||
|
if (removeClaim && hit != existingClaims.end() && hit->second.size()) {
|
||||||
|
auto idx = frc.rand64() % hit->second.size();
|
||||||
|
fixture.Spend(hit->second[idx]);
|
||||||
|
hit->second.erase(hit->second.begin() + idx);
|
||||||
|
} else {
|
||||||
|
auto tx = fixture.MakeClaim(cb.back(), name, value, 2);
|
||||||
|
existingClaims[name].push_back(tx);
|
||||||
|
hit = existingClaims.find(name);
|
||||||
|
cb.emplace_back(std::move(tx));
|
||||||
|
}
|
||||||
|
if (supportBack && hit != existingClaims.end() && hit->second.size()) {
|
||||||
|
auto tx = fixture.MakeSupport(cb.back(), hit->second[frc.rand64() % hit->second.size()], name, 2);
|
||||||
|
existingSupports.push_back(tx);
|
||||||
|
cb.emplace_back(std::move(tx));
|
||||||
|
}
|
||||||
|
if (removeSupport && (i & 7) == 7 && !existingSupports.empty()) {
|
||||||
|
const auto tidx = frc.rand64() % existingSupports.size();
|
||||||
|
const auto tx = existingSupports[tidx];
|
||||||
|
fixture.Spend(tx);
|
||||||
|
existingSupports.erase(existingSupports.begin() + tidx);
|
||||||
|
}
|
||||||
|
if (cb.back().GetValueOut() < 10 || cb.size() > 40000) {
|
||||||
|
cb.clear();
|
||||||
|
cb.push_back(fixture.GetCoinbase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
if (blocks > 13 && i % 50 == 0) // travisCI needs some periodic output
|
||||||
|
std::cerr << "In triehash_fuzzer_test with " << fixture.getTotalNamesInTrie() << " names at block " << i << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocks == 1000 && claimsPerBlock == 100)
|
||||||
|
BOOST_CHECK_EQUAL(fixture.getMerkleHash().GetHex(), "28825257a129eef69cab87d6255c8359fc6dc083ca7f09222526e3a7971f382d");
|
||||||
|
else if (blocks == 13 && claimsPerBlock == 100)
|
||||||
|
BOOST_CHECK_EQUAL(fixture.getMerkleHash().GetHex(), "4e5984d6984f5f05d50e821e6228d56bcfbd16ca2093cd0308f6ff1c2bc8689a");
|
||||||
|
else
|
||||||
|
std::cerr << "Hash: " << fixture.getMerkleHash().GetHex() << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
Loading…
Reference in a new issue