optimized findNameForClaim, added test for removalWorkaround

This commit is contained in:
Brannon King 2019-12-18 14:37:19 -07:00
parent 456ac2f562
commit 29c5176a22
2 changed files with 42 additions and 4 deletions

View file

@ -44,6 +44,9 @@ void applyPragmas(sqlite::database& db, std::size_t cache)
db << "PRAGMA journal_mode=MEMORY";
db << "PRAGMA temp_store=MEMORY";
db << "PRAGMA case_sensitive_like=true";
db.define("POPS", [](std::string s) -> std::string { if (!s.empty()) s.pop_back(); return s; });
db.define("REVERSE", [](std::vector<uint8_t> s) -> std::vector<uint8_t> { std::reverse(s.begin(), s.end()); return s; });
}
CClaimTrie::CClaimTrie(std::size_t cacheBytes, bool fWipe, int height,
@ -460,6 +463,10 @@ bool CClaimTrieCacheBase::validateDb(int height, const uint256& rootHash)
logPrint << "CClaimTrieCacheBase::" << __func__ << "(): the block's root claim hash doesn't match the persisted claim root hash." << Clog::endl;
return false;
}
if (nNextHeight > base->nAllClaimsInMerkleForkHeight) // index not used as part of sync:
db << "CREATE UNIQUE INDEX IF NOT EXISTS claim_reverseClaimID ON claim (REVERSE(claimID))";
return true;
}
logPrint << "inconsistent!" << Clog::endl;
@ -511,7 +518,6 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
nNextHeight = base->nNextHeight;
applyPragmas(db, base->dbCacheBytes >> 10U); // in KB
db.define("POPS", [](std::string s) -> std::string { if (!s.empty()) s.pop_back(); return s; });
}
void CClaimTrieCacheBase::ensureTransacting()
@ -868,10 +874,14 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160
bool CClaimTrieCacheBase::findNameForClaim(std::vector<unsigned char> claim, CClaimValue& value, std::string& name) const
{
std::reverse(claim.begin(), claim.end());
if (claim.size() > 20)
return false;
auto maximum = claim;
maximum.insert(maximum.end(), 20 - claim.size(), std::numeric_limits<unsigned char>::max());
auto query = db << "SELECT nodeName, claimID, txID, txN, amount, activationHeight, blockHeight "
"FROM claim WHERE SUBSTR(claimID, ?1) = ?2 AND activationHeight < ?3 AND expirationHeight >= ?3"
<< -int(claim.size()) << claim << nNextHeight;
"FROM claim WHERE REVERSE(claimID) BETWEEN ?1 AND ?2 "
"AND activationHeight < ?3 AND expirationHeight >= ?3 LIMIT 2"
<< claim << maximum << nNextHeight;
auto hit = false;
for (auto&& row: query) {
if (hit) return false;

View file

@ -802,4 +802,32 @@ BOOST_AUTO_TEST_CASE(get_claim_by_id_test_3)
BOOST_CHECK_EQUAL(claimValue.claimId, claimId2);
}
BOOST_AUTO_TEST_CASE(removal_workaround_functions)
{
// to hit the removalWorkaround, you must
// 1. have all claims of a name removed (but still have children of that claim not removed)
// 2.
ClaimTrieChainFixture fixture;
fixture.setRemovalWorkaroundHeight(7, 20);
CMutableTransaction tx1a = fixture.MakeClaim(fixture.GetCoinbase(), "a", "a", 3);
CMutableTransaction tx1b = fixture.MakeClaim(fixture.GetCoinbase(), "a", "a", 2);
CMutableTransaction tx1c = fixture.MakeClaim(fixture.GetCoinbase(), "ack", "ack", 3);
CMutableTransaction tx2a = fixture.MakeClaim(fixture.GetCoinbase(), "b", "b", 3);
CMutableTransaction tx2b = fixture.MakeClaim(fixture.GetCoinbase(), "b", "b", 2);
CMutableTransaction tx2c = fixture.MakeClaim(fixture.GetCoinbase(), "bob", "bob", 3);
fixture.IncrementBlocks(3);
CMutableTransaction tx3a = fixture.MakeUpdate(tx1a, "a", "a", ClaimIdHash(tx1a.GetHash(), 0), 4);
CMutableTransaction tx3b = fixture.MakeUpdate(tx1b, "a", "a", ClaimIdHash(tx1b.GetHash(), 0), 5); // trigger a takeover
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("a", tx3a));
fixture.IncrementBlocks(7);
CMutableTransaction tx4a = fixture.MakeUpdate(tx2a, "b", "b", ClaimIdHash(tx2a.GetHash(), 0), 4);
CMutableTransaction tx4b = fixture.MakeUpdate(tx2b, "b", "b", ClaimIdHash(tx2b.GetHash(), 0), 5); // trigger a takeover
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.is_best_claim("b", tx4b));
}
BOOST_AUTO_TEST_SUITE_END()