continued work on the takeover height

This commit is contained in:
Brannon King 2019-10-31 17:02:56 -06:00 committed by Anthony Fieroni
parent 0be9249171
commit 649efe8d51
5 changed files with 57 additions and 39 deletions

View file

@ -109,7 +109,7 @@ bool CClaimTrie::SyncToDisk()
bool CClaimTrie::empty() {
int64_t count;
db << "SELECT COUNT(*) FROM claims" >> count;
db << "SELECT COUNT(*) FROM claims WHERE validHeight < ? AND expirationHeight >= ?" << nNextHeight << nNextHeight >> count;
return count == 0;
}
@ -952,23 +952,24 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
// if somebody activates on this block and they are the new best, then everybody activates on this block
CClaimValue value;
if (needsActivate || !getInfoForName(nameWithTakeover, value, 1) || value.nValidAtHeight == nNextHeight) {
activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover);
auto hasCurrent = getInfoForName(nameWithTakeover, value, 1);
// now that they're all in get the winner:
int existingHeight;
std::unique_ptr<uint160> existingID;
db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?"
<< nameWithTakeover >> std::tie(existingHeight, existingID);
// now that they're all in get the winner:
if (getInfoForName(nameWithTakeover, value, 1)) {
int existingHeight;
std::unique_ptr<uint160> existingID;
db << "SELECT IFNULL(takeoverHeight, 0), takeoverID FROM nodes WHERE name = ?"
<< nameWithTakeover >> std::tie(existingHeight, existingID);
if (existingID == nullptr || *existingID != value.claimId) {
takeoverUndo.emplace_back(nameWithTakeover,
std::make_pair(existingHeight, existingID == nullptr ? uint160() : *existingID));
db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ? WHERE name = ?"
<< nNextHeight << value.claimId << nameWithTakeover;
assert(db.rows_modified());
}
}
auto newOwner = needsActivate || existingID == nullptr || !hasCurrent || *existingID != value.claimId;
if (newOwner && activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover))
getInfoForName(nameWithTakeover, value, 1);
if (existingID != nullptr)
takeoverUndo.emplace_back(nameWithTakeover, std::make_pair(existingHeight, *existingID));
if (newOwner) {
db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ? WHERE name = ?"
<< nNextHeight << value.claimId << nameWithTakeover;
assert(db.rows_modified());
}
}
@ -976,9 +977,10 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoTy
return true;
}
void CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
bool CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
const std::string& name) {
// now that we know a takeover is happening, we bring everybody in:
auto ret = false;
{
auto query = db << "SELECT txID, txN, validHeight FROM claims WHERE nodeName = ? AND validHeight > ? AND expirationHeight > ?"
<< name << nNextHeight << nNextHeight;
@ -993,6 +995,7 @@ void CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoT
// and then update them all to activate now:
db << "UPDATE claims SET validHeight = ? WHERE nodeName = ? AND validHeight > ? AND expirationHeight > ?"
<< nNextHeight << name << nNextHeight << nNextHeight;
ret |= db.rows_modified() > 0;
// then do the same for supports:
{
@ -1009,6 +1012,8 @@ void CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoT
// and then update them all to activate now:
db << "UPDATE supports SET validHeight = ? WHERE nodeName = ? AND validHeight > ? AND expirationHeight > ?"
<< nNextHeight << name << nNextHeight << nNextHeight;
ret |= db.rows_modified() > 0;
return ret;
}
bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
@ -1021,29 +1026,25 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoTy
// to actually delete the expired items and then restore them here I would have to look up the metadata in the block
// that doesn't sound very fun so we modified the other queries to exclude expired items
for (auto it = expireSupportUndo.crbegin(); it != expireSupportUndo.crend(); ++it) {
db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?"
<< it->second.nValidAtHeight << it->second.outPoint.hash << it->second.outPoint.n;
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->first;
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << it->first;
}
for (auto it = expireUndo.crbegin(); it != expireUndo.crend(); ++it) {
db << "UPDATE claims SET validHeight = ? WHERE claimID = ?"
<< it->second.nValidAtHeight << it->second.claimId;
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->first;
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << it->first;
}
for (auto it = insertSupportUndo.crbegin(); it != insertSupportUndo.crend(); ++it) {
LogPrint(BCLog::CLAIMS, "Resetting support valid height to %d for %s\n", it->nValidHeight, it->name);
db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?"
<< it->nValidHeight << it->outPoint.hash << it->outPoint.n;
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->name;
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << it->name;
}
for (auto it = insertUndo.crbegin(); it != insertUndo.crend(); ++it) {
LogPrint(BCLog::CLAIMS, "Resetting valid height to %d for %s\n", it->nValidHeight, it->name);
db << "UPDATE claims SET validHeight = ? WHERE nodeName = ? AND txID = ? AND txN = ?"
<< it->nValidHeight << it->name << it->outPoint.hash << it->outPoint.n;
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->name;
db << "INSERT INTO nodes(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << it->name;
}
return true;

View file

@ -400,7 +400,7 @@ private:
friend struct ClaimTrieChainFixture;
friend class CClaimTrieCacheTest;
void activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
bool activateAllFor(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
const std::string& takeover);
};

View file

@ -74,10 +74,18 @@ bool CClaimTrieCacheExpirationFork::forkForExpirationChange(bool increment)
*/
auto extension = Params().GetConsensus().nExtendedClaimExpirationTime - Params().GetConsensus().nOriginalClaimExpirationTime;
if (!increment) extension = -extension;
db << "UPDATE claims SET expirationHeight = expirationHeight + ? WHERE expirationHeight >= ?" << extension << nNextHeight;
db << "UPDATE supports SET expirationHeight = expirationHeight + ? WHERE expirationHeight >= ?" << extension << nNextHeight;
db << "UPDATE nodes SET hash = NULL"; // recompute all hashes (as there aren't that many at this point)
if (increment) {
db << "UPDATE claims SET expirationHeight = expirationHeight + ? WHERE expirationHeight >= ?"
<< extension << nNextHeight;
db << "UPDATE supports SET expirationHeight = expirationHeight + ? WHERE expirationHeight >= ?"
<< extension << nNextHeight;
}
else {
db << "UPDATE claims SET expirationHeight = expirationHeight - ? WHERE expirationHeight >= ?"
<< extension << nNextHeight + extension;
db << "UPDATE supports SET expirationHeight = expirationHeight - ? WHERE expirationHeight >= ?"
<< extension << nNextHeight + extension;
}
return true;
}

View file

@ -393,27 +393,28 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_takeover_test)
fixture.IncrementBlocks(1);
uint160 cid2;
int takeover;
int height = chainActive.Tip()->nHeight;
fixture.getLastTakeoverForName("test", cid2, takeover);
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
BOOST_CHECK_EQUAL(height, takeover);
CMutableTransaction u1 = fixture.MakeUpdate(tx1, "test", "a", cid, 4);
fixture.IncrementBlocks(1);
fixture.getLastTakeoverForName("test", cid2, takeover);
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
BOOST_CHECK_EQUAL(height, takeover);
CMutableTransaction u2 = fixture.MakeUpdate(u1, "test", "b", cid, 3);
fixture.IncrementBlocks(1);
fixture.getLastTakeoverForName("test", cid2, takeover);
CClaimValue value;
BOOST_REQUIRE(fixture.getInfoForName("test", value) && value.nAmount == 3);
BOOST_CHECK_EQUAL(cid, cid2);
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
BOOST_CHECK_EQUAL(height, takeover);
fixture.DecrementBlocks(1);
fixture.getLastTakeoverForName("test", cid2, takeover);
BOOST_CHECK_EQUAL(cid, cid2);
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
BOOST_CHECK_EQUAL(height, takeover);
fixture.DecrementBlocks(1);
fixture.getLastTakeoverForName("test", cid2, takeover);
BOOST_CHECK_EQUAL(cid, cid2);
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
BOOST_CHECK_EQUAL(height, takeover);
}
/*

View file

@ -324,7 +324,7 @@ bool ClaimTrieChainFixture::expirationQueueEmpty() const
bool ClaimTrieChainFixture::supportEmpty() const
{
int64_t count;
db << "SELECT COUNT(*) FROM supports" >> count;
db << "SELECT COUNT(*) FROM supports WHERE validHeight < ? AND expirationHeight >= ?" << nNextHeight << nNextHeight >> count;
return count == 0;
}
@ -392,6 +392,14 @@ boost::test_tools::predicate_result ClaimTrieChainFixture::best_claim_effective_
}
bool ClaimTrieChainFixture::getClaimById(const uint160 &claimId, std::string &name, CClaimValue &value) {
std::vector<unsigned char> claim(claimId.begin(), claimId.end());
return findNameForClaim(claim, value, name);
auto query = db << "SELECT nodeName, claimID, txID, txN, amount, validHeight, blockHeight "
"FROM claims WHERE claimID = ?" << claimId;
auto hit = false;
for (auto&& row: query) {
if (hit) return false;
row >> name >> value.claimId >> value.outPoint.hash >> value.outPoint.n
>> value.nAmount >> value.nValidAtHeight >> value.nHeight;
hit = true;
}
return hit;
}