fixed issue with untouched child nodes needing a parent update
This commit is contained in:
parent
dfc5ebf3f6
commit
75c4c7ab0d
5 changed files with 72 additions and 15 deletions
|
@ -15,7 +15,7 @@ bool CClaimScriptAddOp::claimName(CClaimTrieCache& trieCache, const std::string&
|
||||||
const std::vector<unsigned char>& metadata)
|
const std::vector<unsigned char>& metadata)
|
||||||
{
|
{
|
||||||
auto claimId = ClaimIdHash(point.hash, point.n);
|
auto claimId = ClaimIdHash(point.hash, point.n);
|
||||||
LogPrint(BCLog::CLAIMS, "+++ Claim added: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %du\n",
|
LogPrint(BCLog::CLAIMS, "+++ Claim added: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %d\n",
|
||||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
||||||
return addClaim(trieCache, name, claimId, -1, metadata);
|
return addClaim(trieCache, name, claimId, -1, metadata);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ bool CClaimScriptAddOp::claimName(CClaimTrieCache& trieCache, const std::string&
|
||||||
bool CClaimScriptAddOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
bool CClaimScriptAddOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
||||||
const std::vector<unsigned char>& metadata)
|
const std::vector<unsigned char>& metadata)
|
||||||
{
|
{
|
||||||
LogPrint(BCLog::CLAIMS, "+++ Claim updated: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %du\n",
|
LogPrint(BCLog::CLAIMS, "+++ Claim updated: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %d\n",
|
||||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
||||||
return addClaim(trieCache, name, claimId, -1, metadata);
|
return addClaim(trieCache, name, claimId, -1, metadata);
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ bool CClaimScriptAddOp::addClaim(CClaimTrieCache& trieCache, const std::string&
|
||||||
bool CClaimScriptAddOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
bool CClaimScriptAddOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
||||||
const std::vector<unsigned char>& metadata)
|
const std::vector<unsigned char>& metadata)
|
||||||
{
|
{
|
||||||
LogPrint(BCLog::CLAIMS, "+++ Support added: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %du\n",
|
LogPrint(BCLog::CLAIMS, "+++ Support added: %s, c: %.6s, t: %.6s:%d, h: %.6d, a: %d\n",
|
||||||
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
name, claimId.GetHex(), point.hash.GetHex(), point.n, nHeight, nValue);
|
||||||
return trieCache.addSupport(name, point, nValue, claimId, nHeight, -1, metadata);
|
return trieCache.addSupport(name, point, nValue, claimId, nHeight, -1, metadata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,8 @@ CClaimTrieCacheBase::~CClaimTrieCacheBase() {
|
||||||
db << "rollback";
|
db << "rollback";
|
||||||
transacting = false;
|
transacting = false;
|
||||||
}
|
}
|
||||||
|
claimHashQuery.used(true);
|
||||||
|
childHashQuery.used(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrie::SyncToDisk()
|
bool CClaimTrie::SyncToDisk()
|
||||||
|
@ -234,6 +236,12 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
||||||
"ORDER BY name DESC LIMIT 1";
|
"ORDER BY name DESC LIMIT 1";
|
||||||
|
|
||||||
|
auto insertQuery = db << "INSERT INTO nodes(name, parent, hash) VALUES(?, ?, NULL) "
|
||||||
|
"ON CONFLICT(name) DO UPDATE SET parent = excluded.parent, hash = NULL";
|
||||||
|
|
||||||
|
auto updateUnaffectedsQuery = db << "UPDATE nodes SET parent = ? WHERE name LIKE ? AND LENGTH(parent) < ?";
|
||||||
|
|
||||||
|
|
||||||
for (auto& name: names) {
|
for (auto& name: names) {
|
||||||
std::vector<std::string> claims;
|
std::vector<std::string> claims;
|
||||||
std::string parent;
|
std::string parent;
|
||||||
|
@ -273,26 +281,43 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// insert the split node:
|
// insert the split node:
|
||||||
LogPrint(BCLog::CLAIMS, "Inserting split node %s, parent %s\n", newNodeName, parent);
|
LogPrint(BCLog::CLAIMS, "Inserting split node %s near %s, parent %s\n", newNodeName, sibling, parent);
|
||||||
db << "INSERT INTO nodes(name, parent, hash) VALUES(?, ?, NULL) "
|
insertQuery << newNodeName << parent;
|
||||||
"ON CONFLICT(name) DO UPDATE SET parent = excluded.parent, hash = NULL"
|
insertQuery++;
|
||||||
<< newNodeName << parent;
|
|
||||||
|
if (newNodeName.find('_') == std::string::npos && newNodeName.find('%') == std::string::npos) {
|
||||||
|
updateUnaffectedsQuery << newNodeName << newNodeName + "_%" << newNodeName.size();
|
||||||
|
updateUnaffectedsQuery++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
||||||
|
<< newNodeName << newNodeName.size();
|
||||||
|
|
||||||
|
|
||||||
parent = std::move(newNodeName);
|
parent = std::move(newNodeName);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s, parent %s\n", name, parent);
|
LogPrint(BCLog::CLAIMS, "Inserting or updating node %s, parent %s\n", name, parent);
|
||||||
db << "INSERT INTO nodes(name, parent, hash) VALUES(?, ?, NULL) "
|
insertQuery << name << parent;
|
||||||
"ON CONFLICT(name) DO UPDATE SET parent = excluded.parent, hash = NULL"
|
insertQuery++;
|
||||||
<< name << parent;
|
|
||||||
if (splitPos == 0)
|
if (splitPos == 0)
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << parent;
|
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << parent;
|
||||||
|
|
||||||
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
if (name.find('_') == std::string::npos && name.find('%') == std::string::npos) {
|
||||||
<< name << name.size();
|
updateUnaffectedsQuery << name << name + "_%" << name.size();
|
||||||
|
updateUnaffectedsQuery++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
db << "UPDATE nodes SET parent = ?1 WHERE SUBSTR(name, 1, ?2) = ?1 AND LENGTH(parent) < ?2 AND name != ?1"
|
||||||
|
<< name << name.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parentQuery.used(true);
|
||||||
|
insertQuery.used(true);
|
||||||
|
updateUnaffectedsQuery.used(true);
|
||||||
|
|
||||||
// now we need to percolate the nulls up the tree
|
// now we need to percolate the nulls up the tree
|
||||||
// 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 "
|
||||||
|
@ -320,7 +345,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 (SELECT TOTAL(s.amount)+c.amount FROM supports s "
|
std::string query("SELECT TOTAL(SELECT TOTAL(s.amount)+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)
|
||||||
|
@ -417,6 +442,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, takeover: %d\n", 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());
|
||||||
|
@ -1003,6 +1029,10 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTakeoverQuery.used(true);
|
||||||
|
hasCandidateQuery.used(true);
|
||||||
|
noCandidateQuery.used(true);
|
||||||
|
|
||||||
nNextHeight++;
|
nNextHeight++;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1302,8 +1332,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160
|
||||||
|
|
||||||
const auto pos = key.size();
|
const auto pos = key.size();
|
||||||
std::vector<std::pair<unsigned char, uint256>> children;
|
std::vector<std::pair<unsigned char, uint256>> children;
|
||||||
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ?" << key;
|
for (auto&& child : childHashQuery << key) {
|
||||||
for (auto&& child : childQuery) {
|
|
||||||
std::string childKey;
|
std::string childKey;
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
child >> childKey >> hash;
|
child >> childKey >> hash;
|
||||||
|
@ -1321,6 +1350,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160
|
||||||
completeHash(hash, childKey, pos);
|
completeHash(hash, childKey, pos);
|
||||||
children.emplace_back(childKey[pos], hash);
|
children.emplace_back(childKey[pos], hash);
|
||||||
}
|
}
|
||||||
|
childHashQuery++;
|
||||||
if (key == name) {
|
if (key == name) {
|
||||||
proof.hasValue = fNodeHasValue && claim.claimId == finalClaim;
|
proof.hasValue = fNodeHasValue && claim.claimId == finalClaim;
|
||||||
if (proof.hasValue) {
|
if (proof.hasValue) {
|
||||||
|
|
|
@ -42,6 +42,22 @@ BOOST_AUTO_TEST_CASE(takeover_stability_test) {
|
||||||
BOOST_CHECK_EQUAL(takeover, height);
|
BOOST_CHECK_EQUAL(takeover, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(unaffected_children_get_new_parents_test) {
|
||||||
|
// this happens first on block 193976
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "longest123", "one", 1);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "longest", "two", 2);
|
||||||
|
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "longest1", "three", 3);
|
||||||
|
CMutableTransaction tx4 = fixture.MakeClaim(tx3, "longest1", "three1234", 2);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
auto n1 = fixture.getNodeChildren("longest");
|
||||||
|
auto n2 = fixture.getNodeChildren("longest1");
|
||||||
|
BOOST_CHECK_EQUAL(n1[0], "longest1");
|
||||||
|
BOOST_CHECK_EQUAL(n2[0], "longest123");
|
||||||
|
// TODO: this test at present fails to cover the split node case of the same thing (which occurs on block 202577)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
claims
|
claims
|
||||||
no competing bids
|
no competing bids
|
||||||
|
|
|
@ -403,3 +403,12 @@ bool ClaimTrieChainFixture::getClaimById(const uint160 &claimId, std::string &na
|
||||||
}
|
}
|
||||||
return hit;
|
return hit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> ClaimTrieChainFixture::getNodeChildren(const std::string &name) {
|
||||||
|
std::vector<std::string> ret;
|
||||||
|
for (auto&& row: db << "SELECT name FROM nodes WHERE parent = ?" << name) {
|
||||||
|
ret.emplace_back();
|
||||||
|
row >> ret.back();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -113,6 +113,8 @@ struct ClaimTrieChainFixture: public CClaimTrieCache
|
||||||
|
|
||||||
// check effective quantity of best claim
|
// check effective quantity of best claim
|
||||||
boost::test_tools::predicate_result best_claim_effective_amount_equals(const std::string& name, CAmount amount);
|
boost::test_tools::predicate_result best_claim_effective_amount_equals(const std::string& name, CAmount amount);
|
||||||
|
|
||||||
|
std::vector<std::string> getNodeChildren(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CLAIMTRIEFIXTURE_H_
|
#endif // _CLAIMTRIEFIXTURE_H_
|
||||||
|
|
Loading…
Reference in a new issue