some progress on making takeover height work
This commit is contained in:
parent
395e773ef5
commit
0be9249171
12 changed files with 221 additions and 188 deletions
|
@ -174,8 +174,9 @@ bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CSc
|
||||||
case OP_UPDATE_CLAIM:
|
case OP_UPDATE_CLAIM:
|
||||||
return claimOp.updateClaim(trieCache, vchToString(vvchParams[0]), uint160(vvchParams[1]),
|
return claimOp.updateClaim(trieCache, vchToString(vvchParams[0]), uint160(vvchParams[1]),
|
||||||
vvchParams[2]);
|
vvchParams[2]);
|
||||||
}
|
default:
|
||||||
throw std::runtime_error("Unimplemented OP handler.");
|
throw std::runtime_error("Unimplemented OP handler.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoinsViewCache& view, int nHeight, const CUpdateCacheCallbacks& callbacks)
|
void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoinsViewCache& view, int nHeight, const CUpdateCacheCallbacks& callbacks)
|
||||||
|
@ -188,12 +189,12 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
||||||
bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
||||||
{
|
{
|
||||||
if (CClaimScriptSpendOp::spendClaim(trieCache, name, claimId)) {
|
if (CClaimScriptSpendOp::spendClaim(trieCache, name, claimId)) {
|
||||||
callback(name, claimId, nValidHeight);
|
callback(name, claimId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::function<void(const std::string& name, const uint160& claimId, const int takeoverHeight)> callback;
|
std::function<void(const std::string& name, const uint160& claimId)> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
spentClaimsType spentClaims;
|
spentClaimsType spentClaims;
|
||||||
|
@ -216,8 +217,8 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
||||||
|
|
||||||
int nValidAtHeight;
|
int nValidAtHeight;
|
||||||
CSpendClaimHistory spendClaim(COutPoint(txin.prevout.hash, txin.prevout.n), scriptHeight, nValidAtHeight);
|
CSpendClaimHistory spendClaim(COutPoint(txin.prevout.hash, txin.prevout.n), scriptHeight, nValidAtHeight);
|
||||||
spendClaim.callback = [&spentClaims](const std::string& name, const uint160& claimId, const int takeoverHeight) {
|
spendClaim.callback = [&spentClaims](const std::string& name, const uint160& claimId) {
|
||||||
spentClaims.emplace_back(name, claimId, takeoverHeight);
|
spentClaims.emplace_back(name, claimId);
|
||||||
};
|
};
|
||||||
if (ProcessClaim(spendClaim, trieCache, scriptPubKey) && callbacks.claimUndoHeights)
|
if (ProcessClaim(spendClaim, trieCache, scriptPubKey) && callbacks.claimUndoHeights)
|
||||||
callbacks.claimUndoHeights(j, nValidAtHeight);
|
callbacks.claimUndoHeights(j, nValidAtHeight);
|
||||||
|
@ -231,12 +232,11 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
||||||
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
||||||
const std::vector<unsigned char>& metadata) override
|
const std::vector<unsigned char>& metadata) override
|
||||||
{
|
{
|
||||||
int takeoverHeight = -1;
|
if (callback(name, claimId))
|
||||||
if (callback(name, claimId, takeoverHeight))
|
return CClaimScriptAddOp::addClaim(trieCache, name, claimId, -1, metadata);
|
||||||
return CClaimScriptAddOp::addClaim(trieCache, name, claimId, takeoverHeight, metadata);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::function<bool(const std::string& name, const uint160& claimId, int& takeoverHeight)> callback;
|
std::function<bool(const std::string& name, const uint160& claimId)> callback;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (std::size_t j = 0; j < tx.vout.size(); j++) {
|
for (std::size_t j = 0; j < tx.vout.size(); j++) {
|
||||||
|
@ -246,10 +246,9 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CAddSpendClaim addClaim(COutPoint(tx.GetHash(), j), txout.nValue, nHeight);
|
CAddSpendClaim addClaim(COutPoint(tx.GetHash(), j), txout.nValue, nHeight);
|
||||||
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId, int& takeoverHeight) -> bool {
|
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId) -> bool {
|
||||||
for (auto itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) {
|
for (auto itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) {
|
||||||
if (std::get<1>(*itSpent) == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(std::get<0>(*itSpent))) {
|
if (itSpent->second == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first)) {
|
||||||
takeoverHeight = std::get<2>(*itSpent);
|
|
||||||
spentClaims.erase(itSpent);
|
spentClaims.erase(itSpent);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,8 +238,7 @@ protected:
|
||||||
*/
|
*/
|
||||||
bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CScript& scriptPubKey);
|
bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CScript& scriptPubKey);
|
||||||
|
|
||||||
typedef std::tuple<std::string, uint160, int> spentClaimType;
|
typedef std::pair<std::string, uint160> spentClaimType;
|
||||||
|
|
||||||
typedef std::vector<spentClaimType> spentClaimsType;
|
typedef std::vector<spentClaimType> spentClaimsType;
|
||||||
|
|
||||||
struct CUpdateCacheCallbacks
|
struct CUpdateCacheCallbacks
|
||||||
|
|
|
@ -56,7 +56,7 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor)
|
||||||
db.define("MERKLE_PAIR", [](const std::vector<unsigned char>& blob1, const std::vector<unsigned char>& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); });
|
db.define("MERKLE_PAIR", [](const std::vector<unsigned char>& blob1, const std::vector<unsigned char>& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); });
|
||||||
db.define("MERKLE", [](const std::vector<unsigned char>& blob1) { return Hash(blob1.begin(), blob1.end()); });
|
db.define("MERKLE", [](const std::vector<unsigned char>& blob1) { return Hash(blob1.begin(), blob1.end()); });
|
||||||
|
|
||||||
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB)";
|
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB, takeoverHeight INTEGER, takeoverID BLOB)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)";
|
db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)";
|
db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)";
|
||||||
|
|
||||||
|
@ -325,13 +325,14 @@ CAmount CClaimTrieCacheBase::getTotalValueOfClaimsInTrie(bool fControllingOnly)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim) const
|
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset) const
|
||||||
{
|
{
|
||||||
|
auto nextHeight = nNextHeight + heightOffset;
|
||||||
auto query = db << "SELECT c.claimID, c.txID, c.txN, c.blockHeight, c.validHeight, c.amount, "
|
auto query = db << "SELECT c.claimID, c.txID, c.txN, c.blockHeight, c.validHeight, c.amount, "
|
||||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
||||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN LIMIT 1"
|
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN LIMIT 1"
|
||||||
<< nNextHeight << nNextHeight << name << nNextHeight << nNextHeight;
|
<< nextHeight << nextHeight << name << nextHeight << nextHeight;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n
|
row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n
|
||||||
>> claim.nHeight >> claim.nValidAtHeight >> claim.nAmount >> claim.nEffectiveAmount;
|
>> claim.nHeight >> claim.nValidAtHeight >> claim.nAmount >> claim.nEffectiveAmount;
|
||||||
|
@ -391,18 +392,19 @@ void completeHash(uint256& partialHash, const std::string& key, std::size_t to)
|
||||||
.Finalize(partialHash.begin());
|
.Finalize(partialHash.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name, bool checkOnly)
|
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||||
{
|
{
|
||||||
std::vector<uint8_t> vchToHash;
|
std::vector<uint8_t> vchToHash;
|
||||||
const auto pos = name.size();
|
const auto pos = name.size();
|
||||||
auto query = db << "SELECT name, hash FROM nodes WHERE parent = ? ORDER BY name" << name;
|
auto query = db << "SELECT name, hash, IFNULL(takeoverHeight,0) FROM nodes WHERE parent = ? ORDER BY name" << name;
|
||||||
for (auto&& row : query) {
|
for (auto&& row : query) {
|
||||||
std::string key;
|
std::string key;
|
||||||
|
int childTakeoverHeight;
|
||||||
std::unique_ptr<uint256> hash;
|
std::unique_ptr<uint256> hash;
|
||||||
row >> key >> hash;
|
row >> key >> hash >> childTakeoverHeight;
|
||||||
if (hash == nullptr) hash = std::make_unique<uint256>();
|
if (hash == nullptr) hash = std::make_unique<uint256>();
|
||||||
if (hash->IsNull()) {
|
if (hash->IsNull()) {
|
||||||
*hash = recursiveComputeMerkleHash(key, checkOnly);
|
*hash = recursiveComputeMerkleHash(key, childTakeoverHeight, checkOnly);
|
||||||
}
|
}
|
||||||
completeHash(*hash, key, pos);
|
completeHash(*hash, key, pos);
|
||||||
vchToHash.push_back(key[pos]);
|
vchToHash.push_back(key[pos]);
|
||||||
|
@ -411,7 +413,7 @@ uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(const std::string& name,
|
||||||
|
|
||||||
CClaimValue claim;
|
CClaimValue claim;
|
||||||
if (getInfoForName(name, claim)) {
|
if (getInfoForName(name, claim)) {
|
||||||
uint256 valueHash = getValueHash(claim.outPoint, claim.nValidAtHeight);
|
uint256 valueHash = getValueHash(claim.outPoint, takeoverHeight);
|
||||||
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
|
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,12 +427,13 @@ bool CClaimTrieCacheBase::checkConsistency()
|
||||||
{
|
{
|
||||||
// verify that all claims hash to the values on the nodes
|
// verify that all claims hash to the values on the nodes
|
||||||
|
|
||||||
auto query = db << "SELECT name, hash FROM nodes";
|
auto query = db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes";
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
std::string name;
|
std::string name;
|
||||||
uint256 hash;
|
uint256 hash;
|
||||||
row >> name >> hash;
|
int takeoverHeight;
|
||||||
auto computedHash = recursiveComputeMerkleHash(name, true);
|
row >> name >> hash >> takeoverHeight;
|
||||||
|
auto computedHash = recursiveComputeMerkleHash(name, takeoverHeight, true);
|
||||||
if (computedHash != hash)
|
if (computedHash != hash)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -504,22 +507,23 @@ uint256 CClaimTrieCacheBase::getMerkleHash()
|
||||||
{
|
{
|
||||||
ensureTreeStructureIsUpToDate();
|
ensureTreeStructureIsUpToDate();
|
||||||
std::unique_ptr<uint256> hash;
|
std::unique_ptr<uint256> hash;
|
||||||
db << "SELECT hash FROM nodes WHERE name = ''" >> hash;
|
int takeoverHeight;
|
||||||
|
db << "SELECT hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE name = ''" >> std::tie(hash, takeoverHeight);
|
||||||
if (hash == nullptr || hash->IsNull()) {
|
if (hash == nullptr || hash->IsNull()) {
|
||||||
assert(transacting); // no data changed but we didn't have the root hash there already?
|
assert(transacting); // no data changed but we didn't have the root hash there already?
|
||||||
return recursiveComputeMerkleHash("", false);
|
return recursiveComputeMerkleHash("", takeoverHeight, false);
|
||||||
}
|
}
|
||||||
return *hash;
|
return *hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const
|
bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const
|
||||||
{
|
{
|
||||||
CClaimValue value;
|
auto query = db << "SELECT takeoverHeight, takeoverID FROM nodes WHERE name = ? AND takeoverID IS NOT NULL" << name;
|
||||||
if (!getInfoForName(name, value))
|
auto it = query.begin();
|
||||||
|
if (it == query.end())
|
||||||
return false;
|
return false;
|
||||||
takeoverHeight = value.nValidAtHeight;
|
*it >> takeoverHeight >> claimId;
|
||||||
claimId = value.claimId;
|
return !claimId.IsNull();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId,
|
bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId,
|
||||||
|
@ -528,18 +532,26 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out
|
||||||
if (!transacting) { transacting = true; db << "begin"; }
|
if (!transacting) { transacting = true; db << "begin"; }
|
||||||
|
|
||||||
// in the update scenario the previous one should be removed already
|
// in the update scenario the previous one should be removed already
|
||||||
|
// in the downgrade scenario, the one ahead will be removed already and the old one's valid height is input
|
||||||
|
// revisiting the update scenario we have two options:
|
||||||
|
// 1. let them pull the old one first, in which case they will be responsible to pass in validHeight (since we can't determine it's a 0 delay)
|
||||||
|
// 2. don't remove the old one; have this method do a kinder "update" situation.
|
||||||
|
// Option 2 has the issue in that we don't actually update if we don't have an existing match,
|
||||||
|
// and no way to know that here without an 'update' flag
|
||||||
|
// In addition, as we currently do option 1 they use that to get the old valid height and store that for undo
|
||||||
|
// We would have to make this method return that if we go without the removal
|
||||||
|
// The other problem with 1 is that the outer shell would need to know if the one they removed was a winner or not
|
||||||
|
|
||||||
if (nValidHeight <= 0) {
|
if (nValidHeight < 0)
|
||||||
auto delay = getDelayForName(name, claimId);
|
nValidHeight = nHeight + getDelayForName(name, claimId); // sets nValidHeight to the old value
|
||||||
nValidHeight = nHeight + delay;
|
|
||||||
}
|
|
||||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||||
auto expires = expirationTime() + nHeight;
|
auto expires = expirationTime() + nHeight;
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,10 +560,8 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& o
|
||||||
{
|
{
|
||||||
if (!transacting) { transacting = true; db << "begin"; }
|
if (!transacting) { transacting = true; db << "begin"; }
|
||||||
|
|
||||||
if (nValidHeight <= 0) {
|
if (nValidHeight < 0)
|
||||||
auto delay = getDelayForName(name, supportedClaimId);
|
nValidHeight = nHeight + getDelayForName(name, supportedClaimId);
|
||||||
nValidHeight = nHeight + delay;
|
|
||||||
}
|
|
||||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||||
auto expires = expirationTime() + nHeight;
|
auto expires = expirationTime() + nHeight;
|
||||||
db << "INSERT INTO supports(supportedClaimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) "
|
db << "INSERT INTO supports(supportedClaimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, expirationHeight, metadata) "
|
||||||
|
@ -884,7 +894,9 @@ static const boost::container::flat_map<std::pair<int, std::string>, int> takeov
|
||||||
{{ 653524, "celtic-folk-music-full-live-concert-mps" }, 589762},
|
{{ 653524, "celtic-folk-music-full-live-concert-mps" }, 589762},
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||||
|
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo,
|
||||||
|
takeoverUndoType& takeoverUndo)
|
||||||
{
|
{
|
||||||
// the plan:
|
// the plan:
|
||||||
// for every claim and support that becomes active this block set its node hash to null (aka, dirty)
|
// for every claim and support that becomes active this block set its node hash to null (aka, dirty)
|
||||||
|
@ -932,18 +944,32 @@ bool CClaimTrieCacheBase::incrementBlock(insertUndoType& insertUndo, claimQueueR
|
||||||
db << "SELECT name FROM nodes WHERE hash IS NULL" >> takeovers;
|
db << "SELECT name FROM nodes WHERE hash IS NULL" >> takeovers;
|
||||||
|
|
||||||
for (const auto& nameWithTakeover : takeovers) {
|
for (const auto& nameWithTakeover : takeovers) {
|
||||||
|
auto needsActivate = false;
|
||||||
if (nNextHeight >= 496856 && nNextHeight <= 653524) {
|
if (nNextHeight >= 496856 && nNextHeight <= 653524) {
|
||||||
auto wit = takeoverWorkarounds.find(std::make_pair(nNextHeight, nameWithTakeover));
|
auto wit = takeoverWorkarounds.find(std::make_pair(nNextHeight, nameWithTakeover));
|
||||||
if (wit != takeoverWorkarounds.end()) {
|
needsActivate = wit != takeoverWorkarounds.end();
|
||||||
activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// if somebody activates on this block and they are the new best, then everybody activates on this block
|
// if somebody activates on this block and they are the new best, then everybody activates on this block
|
||||||
CClaimValue value;
|
CClaimValue value;
|
||||||
if (!getInfoForName(nameWithTakeover, value) || value.nValidAtHeight == nNextHeight)
|
if (needsActivate || !getInfoForName(nameWithTakeover, value, 1) || value.nValidAtHeight == nNextHeight) {
|
||||||
activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover);
|
activateAllFor(insertUndo, insertSupportUndo, nameWithTakeover);
|
||||||
|
|
||||||
|
// 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nNextHeight++;
|
nNextHeight++;
|
||||||
|
@ -985,12 +1011,15 @@ void CClaimTrieCacheBase::activateAllFor(insertUndoType& insertUndo, insertUndoT
|
||||||
<< nNextHeight << name << nNextHeight << nNextHeight;
|
<< nNextHeight << name << nNextHeight << nNextHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||||
|
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||||
{
|
{
|
||||||
if (!transacting) { transacting = true; db << "begin"; }
|
if (!transacting) { transacting = true; db << "begin"; }
|
||||||
|
|
||||||
nNextHeight--;
|
nNextHeight--;
|
||||||
|
|
||||||
|
// 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) {
|
for (auto it = expireSupportUndo.crbegin(); it != expireSupportUndo.crend(); ++it) {
|
||||||
db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?"
|
db << "UPDATE supports SET validHeight = ? WHERE txID = ? AND txN = ?"
|
||||||
<< it->second.nValidAtHeight << it->second.outPoint.hash << it->second.outPoint.n;
|
<< it->second.nValidAtHeight << it->second.outPoint.hash << it->second.outPoint.n;
|
||||||
|
@ -1017,16 +1046,20 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimQueueR
|
||||||
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->name;
|
db << "UPDATE nodes SET hash = NULL WHERE name = ?" << it->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 = ?)" << 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 = ?)" << nNextHeight;
|
||||||
|
|
||||||
return true;
|
for (auto it = takeoverUndo.crbegin(); it != takeoverUndo.crend(); ++it)
|
||||||
}
|
db << "UPDATE nodes SET takeoverHeight = ?, takeoverID = ?, hash = NULL WHERE name = ?"
|
||||||
|
<< it->second.first << it->second.second << it->first;
|
||||||
|
|
||||||
bool CClaimTrieCacheBase::finalizeDecrement()
|
|
||||||
{
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1191,33 +1224,20 @@ static const boost::container::flat_set<std::pair<int, std::string>> ownershipWo
|
||||||
{ 646584, "calling-tech-support-scammers-live-3" },
|
{ 646584, "calling-tech-support-scammers-live-3" },
|
||||||
};
|
};
|
||||||
|
|
||||||
int CClaimTrieCacheBase::getNumBlocksOfContinuousOwnership(const std::string& name) const
|
|
||||||
{
|
|
||||||
if (nNextHeight <= 646584 && ownershipWorkaround.find(std::make_pair(nNextHeight, name)) != ownershipWorkaround.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
CClaimValue value;
|
|
||||||
if (getInfoForName(name, value))
|
|
||||||
return nNextHeight - value.nValidAtHeight;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CClaimTrieCacheBase::getDelayForName(const std::string& name) const
|
|
||||||
{
|
|
||||||
int nBlocksOfContinuousOwnership = getNumBlocksOfContinuousOwnership(name);
|
|
||||||
return std::min(nBlocksOfContinuousOwnership / base->nProportionalDelayFactor, 4032);
|
|
||||||
}
|
|
||||||
|
|
||||||
int CClaimTrieCacheBase::getDelayForName(const std::string& name, const uint160& claimId) const
|
int CClaimTrieCacheBase::getDelayForName(const std::string& name, const uint160& claimId) const
|
||||||
{
|
{
|
||||||
uint160 winningClaimId;
|
uint160 winningClaimId;
|
||||||
int winningTakeoverHeight;
|
int winningTakeoverHeight;
|
||||||
if (getLastTakeoverForName(name, winningClaimId, winningTakeoverHeight) && winningClaimId == claimId) {
|
auto found = getLastTakeoverForName(name, winningClaimId, winningTakeoverHeight);
|
||||||
|
if (found && winningClaimId == claimId) {
|
||||||
assert(winningTakeoverHeight <= nNextHeight);
|
assert(winningTakeoverHeight <= nNextHeight);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return getDelayForName(name);
|
|
||||||
|
if (nNextHeight <= 646584 && ownershipWorkaround.find(std::make_pair(nNextHeight, name)) != ownershipWorkaround.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return found ? std::min((nNextHeight - winningTakeoverHeight) / base->nProportionalDelayFactor, 4032) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CClaimTrieCacheBase::adjustNameForValidHeight(const std::string& name, int validHeight) const
|
std::string CClaimTrieCacheBase::adjustNameForValidHeight(const std::string& name, int validHeight) const
|
||||||
|
|
|
@ -199,33 +199,6 @@ struct CNameOutPointHeightType
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CNameOutPointType
|
|
||||||
{
|
|
||||||
std::string name;
|
|
||||||
COutPoint outPoint;
|
|
||||||
|
|
||||||
CNameOutPointType() = default;
|
|
||||||
|
|
||||||
CNameOutPointType(std::string name, const COutPoint& outPoint)
|
|
||||||
: name(std::move(name)), outPoint(outPoint)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const CNameOutPointType& other) const
|
|
||||||
{
|
|
||||||
return name == other.name && outPoint == other.outPoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
|
||||||
|
|
||||||
template <typename Stream, typename Operation>
|
|
||||||
inline void SerializationOp(Stream& s, Operation ser_action)
|
|
||||||
{
|
|
||||||
READWRITE(name);
|
|
||||||
READWRITE(outPoint);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CClaimNsupports
|
struct CClaimNsupports
|
||||||
{
|
{
|
||||||
CClaimNsupports() = default;
|
CClaimNsupports() = default;
|
||||||
|
@ -347,9 +320,10 @@ struct CClaimTrieProof
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using queueEntryType = std::pair<std::string, T>;
|
using queueEntryType = std::pair<std::string, T>;
|
||||||
|
|
||||||
typedef std::vector<queueEntryType<CClaimValue>> claimQueueRowType;
|
typedef std::vector<queueEntryType<CClaimValue>> claimUndoType;
|
||||||
typedef std::vector<queueEntryType<CSupportValue>> supportQueueRowType;
|
typedef std::vector<queueEntryType<CSupportValue>> supportUndoType;
|
||||||
typedef std::vector<CNameOutPointHeightType> insertUndoType;
|
typedef std::vector<CNameOutPointHeightType> insertUndoType;
|
||||||
|
typedef std::vector<queueEntryType<std::pair<int, uint160>>> takeoverUndoType;
|
||||||
|
|
||||||
class CClaimTrieCacheBase
|
class CClaimTrieCacheBase
|
||||||
{
|
{
|
||||||
|
@ -370,29 +344,30 @@ public:
|
||||||
bool haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
bool haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
||||||
|
|
||||||
bool addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount,
|
bool addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, CAmount nAmount,
|
||||||
int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata);
|
int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||||
bool addSupport(const std::string& name, const COutPoint& outPoint, CAmount nAmount,
|
bool addSupport(const std::string& name, const COutPoint& outPoint, CAmount nAmount,
|
||||||
const uint160& supportedClaimId, int nHeight, int nValidHeight, const std::vector<unsigned char>& metadata);
|
const uint160& supportedClaimId, int nHeight, int nValidHeight = -1, const std::vector<unsigned char>& metadata = {});
|
||||||
|
|
||||||
bool removeSupport(const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
bool removeSupport(const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||||
bool removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
bool removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||||
|
|
||||||
virtual bool incrementBlock(insertUndoType& insertUndo,
|
virtual bool incrementBlock(insertUndoType& insertUndo,
|
||||||
claimQueueRowType& expireUndo,
|
claimUndoType& expireUndo,
|
||||||
insertUndoType& insertSupportUndo,
|
insertUndoType& insertSupportUndo,
|
||||||
supportQueueRowType& expireSupportUndo);
|
supportUndoType& expireSupportUndo,
|
||||||
|
takeoverUndoType& takeovers);
|
||||||
|
|
||||||
virtual bool decrementBlock(insertUndoType& insertUndo,
|
virtual bool decrementBlock(insertUndoType& insertUndo,
|
||||||
claimQueueRowType& expireUndo,
|
claimUndoType& expireUndo,
|
||||||
insertUndoType& insertSupportUndo,
|
insertUndoType& insertSupportUndo,
|
||||||
supportQueueRowType& expireSupportUndo);
|
supportUndoType& expireSupportUndo);
|
||||||
|
|
||||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
virtual bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const;
|
||||||
virtual bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof);
|
virtual bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof);
|
||||||
|
|
||||||
virtual int expirationTime() const;
|
virtual int expirationTime() const;
|
||||||
|
|
||||||
virtual bool finalizeDecrement();
|
virtual bool finalizeDecrement(takeoverUndoType& takeovers);
|
||||||
|
|
||||||
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
|
||||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||||
|
@ -412,14 +387,11 @@ protected:
|
||||||
bool transacting;
|
bool transacting;
|
||||||
// one greater than the height of the chain's tip
|
// one greater than the height of the chain's tip
|
||||||
|
|
||||||
virtual uint256 recursiveComputeMerkleHash(const std::string& name, bool checkOnly);
|
virtual uint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly);
|
||||||
supportEntryType getSupportsForName(const std::string& name) const;
|
supportEntryType getSupportsForName(const std::string& name) const;
|
||||||
|
|
||||||
int getDelayForName(const std::string& name) const;
|
|
||||||
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
||||||
|
|
||||||
int getNumBlocksOfContinuousOwnership(const std::string& name) const;
|
|
||||||
|
|
||||||
bool deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims);
|
bool deleteNodeIfPossible(const std::string& name, std::string& parent, std::vector<std::string>& claims);
|
||||||
void ensureTreeStructureIsUpToDate();
|
void ensureTreeStructureIsUpToDate();
|
||||||
|
|
||||||
|
@ -441,17 +413,18 @@ public:
|
||||||
int expirationTime() const override;
|
int expirationTime() const override;
|
||||||
|
|
||||||
virtual void initializeIncrement();
|
virtual void initializeIncrement();
|
||||||
bool finalizeDecrement() override;
|
bool finalizeDecrement(takeoverUndoType& takeovers) override;
|
||||||
|
|
||||||
bool incrementBlock(insertUndoType& insertUndo,
|
bool incrementBlock(insertUndoType& insertUndo,
|
||||||
claimQueueRowType& expireUndo,
|
claimUndoType& expireUndo,
|
||||||
insertUndoType& insertSupportUndo,
|
insertUndoType& insertSupportUndo,
|
||||||
supportQueueRowType& expireSupportUndo) override;
|
supportUndoType& expireSupportUndo,
|
||||||
|
takeoverUndoType& takeovers) override;
|
||||||
|
|
||||||
bool decrementBlock(insertUndoType& insertUndo,
|
bool decrementBlock(insertUndoType& insertUndo,
|
||||||
claimQueueRowType& expireUndo,
|
claimUndoType& expireUndo,
|
||||||
insertUndoType& insertSupportUndo,
|
insertUndoType& insertSupportUndo,
|
||||||
supportQueueRowType& expireSupportUndo) override;
|
supportUndoType& expireSupportUndo) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int nExpirationTime;
|
int nExpirationTime;
|
||||||
|
@ -473,17 +446,18 @@ public:
|
||||||
std::string normalizeClaimName(const std::string& name, bool force = false) const; // public only for validating name field on update op
|
std::string normalizeClaimName(const std::string& name, bool force = false) const; // public only for validating name field on update op
|
||||||
|
|
||||||
bool incrementBlock(insertUndoType& insertUndo,
|
bool incrementBlock(insertUndoType& insertUndo,
|
||||||
claimQueueRowType& expireUndo,
|
claimUndoType& expireUndo,
|
||||||
insertUndoType& insertSupportUndo,
|
insertUndoType& insertSupportUndo,
|
||||||
supportQueueRowType& expireSupportUndo) override;
|
supportUndoType& expireSupportUndo,
|
||||||
|
takeoverUndoType& takeovers) override;
|
||||||
|
|
||||||
bool decrementBlock(insertUndoType& insertUndo,
|
bool decrementBlock(insertUndoType& insertUndo,
|
||||||
claimQueueRowType& expireUndo,
|
claimUndoType& expireUndo,
|
||||||
insertUndoType& insertSupportUndo,
|
insertUndoType& insertSupportUndo,
|
||||||
supportQueueRowType& expireSupportUndo) override;
|
supportUndoType& expireSupportUndo) override;
|
||||||
|
|
||||||
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
||||||
bool getInfoForName(const std::string& name, CClaimValue& claim) const override;
|
bool getInfoForName(const std::string& name, CClaimValue& claim, int heightOffset = 0) const override;
|
||||||
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
CClaimSupportToName getClaimsForName(const std::string& name) const override;
|
||||||
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
std::string adjustNameForValidHeight(const std::string& name, int validHeight) const override;
|
||||||
|
|
||||||
|
@ -501,12 +475,12 @@ public:
|
||||||
|
|
||||||
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
bool getProofForName(const std::string& name, const uint160& finalClaim, CClaimTrieProof& proof) override;
|
||||||
void initializeIncrement() override;
|
void initializeIncrement() override;
|
||||||
bool finalizeDecrement() override;
|
bool finalizeDecrement(takeoverUndoType& takeovers) override;
|
||||||
|
|
||||||
bool allowSupportMetadata() const;
|
bool allowSupportMetadata() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
uint256 recursiveComputeMerkleHash(const std::string& name, bool checkOnly) override;
|
uint256 recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef CClaimTrieCacheHashFork CClaimTrieCache;
|
typedef CClaimTrieCacheHashFork CClaimTrieCache;
|
||||||
|
|
|
@ -25,16 +25,17 @@ int CClaimTrieCacheExpirationFork::expirationTime() const
|
||||||
return nExpirationTime;
|
return nExpirationTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||||
|
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo)
|
||||||
{
|
{
|
||||||
if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo)) {
|
||||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||||
{
|
{
|
||||||
if (CClaimTrieCacheBase::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
if (CClaimTrieCacheBase::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
||||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||||
|
@ -52,9 +53,9 @@ void CClaimTrieCacheExpirationFork::initializeIncrement()
|
||||||
forkForExpirationChange(true);
|
forkForExpirationChange(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheExpirationFork::finalizeDecrement()
|
bool CClaimTrieCacheExpirationFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||||
{
|
{
|
||||||
auto ret = CClaimTrieCacheBase::finalizeDecrement();
|
auto ret = CClaimTrieCacheBase::finalizeDecrement(takeoverUndo);
|
||||||
if (ret && nNextHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
if (ret && nNextHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||||
forkForExpirationChange(false);
|
forkForExpirationChange(false);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -152,13 +153,14 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(bool f
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo,
|
||||||
|
insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo, takeoverUndoType& takeoverUndo)
|
||||||
{
|
{
|
||||||
normalizeAllNamesInTrieIfNecessary(true);
|
normalizeAllNamesInTrieIfNecessary(true);
|
||||||
return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo);
|
return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo, claimUndoType& expireUndo, insertUndoType& insertSupportUndo, supportUndoType& expireSupportUndo)
|
||||||
{
|
{
|
||||||
auto ret = CClaimTrieCacheExpirationFork::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo);
|
auto ret = CClaimTrieCacheExpirationFork::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -171,9 +173,9 @@ bool CClaimTrieCacheNormalizationFork::getProofForName(const std::string& name,
|
||||||
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), finalClaim, proof);
|
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), finalClaim, proof);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim) const
|
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim, int offsetHeight) const
|
||||||
{
|
{
|
||||||
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim);
|
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim, offsetHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
CClaimSupportToName CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
|
CClaimSupportToName CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const
|
||||||
|
@ -198,26 +200,27 @@ CClaimTrieCacheHashFork::CClaimTrieCacheHashFork(CClaimTrie* base) : CClaimTrieC
|
||||||
static const uint256 leafHash = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
|
static const uint256 leafHash = uint256S("0000000000000000000000000000000000000000000000000000000000000002");
|
||||||
static const uint256 emptyHash = uint256S("0000000000000000000000000000000000000000000000000000000000000003");
|
static const uint256 emptyHash = uint256S("0000000000000000000000000000000000000000000000000000000000000003");
|
||||||
|
|
||||||
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& name, bool checkOnly)
|
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& name, int takeoverHeight, bool checkOnly)
|
||||||
{
|
{
|
||||||
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
|
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
|
||||||
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(name, checkOnly);
|
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(name, takeoverHeight, checkOnly);
|
||||||
|
|
||||||
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ? ORDER BY name" << name;
|
auto childQuery = db << "SELECT name, hash, IFNULL(takeoverHeight, 0) FROM nodes WHERE parent = ? ORDER BY name" << name;
|
||||||
|
|
||||||
std::vector<uint256> childHashes;
|
std::vector<uint256> childHashes;
|
||||||
for (auto&& row: childQuery) {
|
for (auto&& row: childQuery) {
|
||||||
std::string key;
|
std::string key;
|
||||||
std::unique_ptr<uint256> hash;
|
std::unique_ptr<uint256> hash;
|
||||||
row >> key >> hash;
|
int childTakeoverHeight;
|
||||||
|
row >> key >> hash >> childTakeoverHeight;
|
||||||
if (hash == nullptr) hash = std::make_unique<uint256>();
|
if (hash == nullptr) hash = std::make_unique<uint256>();
|
||||||
if (hash->IsNull()) {
|
if (hash->IsNull()) {
|
||||||
*hash = recursiveComputeMerkleHash(key, checkOnly);
|
*hash = recursiveComputeMerkleHash(key, childTakeoverHeight, checkOnly);
|
||||||
}
|
}
|
||||||
childHashes.push_back(*hash);
|
childHashes.push_back(*hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto claimQuery = db << "SELECT c.txID, c.txN, c.validHeight, "
|
auto claimQuery = db << "SELECT c.txID, c.txN, "
|
||||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
||||||
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount"
|
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount"
|
||||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||||
|
@ -226,9 +229,8 @@ uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& n
|
||||||
std::vector<uint256> claimHashes;
|
std::vector<uint256> claimHashes;
|
||||||
for (auto&& row: claimQuery) {
|
for (auto&& row: claimQuery) {
|
||||||
COutPoint p;
|
COutPoint p;
|
||||||
int validHeight;
|
row >> p.hash >> p.n;
|
||||||
row >> p.hash >> p.n >> validHeight;
|
auto claimHash = getValueHash(p, takeoverHeight);
|
||||||
auto claimHash = getValueHash(p, validHeight);
|
|
||||||
claimHashes.push_back(claimHash);
|
claimHashes.push_back(claimHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -310,13 +312,14 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
||||||
// cache the parent nodes
|
// cache the parent nodes
|
||||||
getMerkleHash();
|
getMerkleHash();
|
||||||
proof = CClaimTrieProof();
|
proof = CClaimTrieProof();
|
||||||
auto nodeQuery = db << "SELECT name FROM nodes WHERE "
|
auto nodeQuery = db << "SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE "
|
||||||
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
||||||
"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 LENGTH(name)" << name;
|
"ORDER BY LENGTH(name)" << name;
|
||||||
for (auto&& row: nodeQuery) {
|
for (auto&& row: nodeQuery) {
|
||||||
std::string key;;
|
std::string key;;
|
||||||
row >> key;
|
int takeoverHeight;
|
||||||
|
row >> key >> takeoverHeight;
|
||||||
std::vector<uint256> childHashes;
|
std::vector<uint256> childHashes;
|
||||||
uint32_t nextCurrentIdx = 0;
|
uint32_t nextCurrentIdx = 0;
|
||||||
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ?" << key;
|
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ?" << key;
|
||||||
|
@ -335,7 +338,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
||||||
COutPoint finalOutPoint;
|
COutPoint finalOutPoint;
|
||||||
for (uint32_t i = 0; i < cns.claimsNsupports.size(); ++i) {
|
for (uint32_t i = 0; i < cns.claimsNsupports.size(); ++i) {
|
||||||
auto& child = cns.claimsNsupports[i].claim;
|
auto& child = cns.claimsNsupports[i].claim;
|
||||||
claimHashes.push_back(getValueHash(child.outPoint, child.nValidAtHeight));
|
claimHashes.push_back(getValueHash(child.outPoint, takeoverHeight));
|
||||||
if (child.claimId == finalClaim) {
|
if (child.claimId == finalClaim) {
|
||||||
finalClaimIdx = i;
|
finalClaimIdx = i;
|
||||||
finalOutPoint = child.outPoint;
|
finalOutPoint = child.outPoint;
|
||||||
|
@ -372,9 +375,9 @@ void CClaimTrieCacheHashFork::initializeIncrement()
|
||||||
db << "UPDATE nodes SET hash = NULL";
|
db << "UPDATE nodes SET hash = NULL";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CClaimTrieCacheHashFork::finalizeDecrement()
|
bool CClaimTrieCacheHashFork::finalizeDecrement(takeoverUndoType& takeoverUndo)
|
||||||
{
|
{
|
||||||
auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement();
|
auto ret = CClaimTrieCacheNormalizationFork::finalizeDecrement(takeoverUndo);
|
||||||
if (ret && nNextHeight == Params().GetConsensus().nAllClaimsInMerkleForkHeight - 1)
|
if (ret && nNextHeight == Params().GetConsensus().nAllClaimsInMerkleForkHeight - 1)
|
||||||
db << "UPDATE nodes SET hash = NULL";
|
db << "UPDATE nodes SET hash = NULL";
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -46,9 +46,10 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
|
||||||
void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
||||||
{
|
{
|
||||||
insertUndoType dummyInsertUndo;
|
insertUndoType dummyInsertUndo;
|
||||||
claimQueueRowType dummyExpireUndo;
|
claimUndoType dummyExpireUndo;
|
||||||
insertUndoType dummyInsertSupportUndo;
|
insertUndoType dummyInsertSupportUndo;
|
||||||
supportQueueRowType dummyExpireSupportUndo;
|
supportUndoType dummyExpireSupportUndo;
|
||||||
|
takeoverUndoType dummyTakeoverUndo;
|
||||||
|
|
||||||
CUpdateCacheCallbacks callbacks = {
|
CUpdateCacheCallbacks callbacks = {
|
||||||
.findScriptKey = [&pblock](const COutPoint& point) {
|
.findScriptKey = [&pblock](const COutPoint& point) {
|
||||||
|
@ -68,7 +69,7 @@ void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
||||||
if (!tx->IsCoinBase())
|
if (!tx->IsCoinBase())
|
||||||
UpdateCache(*tx, trieCache, view, nHeight, callbacks);
|
UpdateCache(*tx, trieCache, view, nHeight, callbacks);
|
||||||
|
|
||||||
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo);
|
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverUndo);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockAssembler::Options::Options() {
|
BlockAssembler::Options::Options() {
|
||||||
|
|
|
@ -384,6 +384,38 @@ BOOST_AUTO_TEST_CASE(support_spend_test)
|
||||||
fixture.DecrementBlocks(1);
|
fixture.DecrementBlocks(1);
|
||||||
BOOST_CHECK(fixture.is_best_claim("test",tx5));
|
BOOST_CHECK(fixture.is_best_claim("test",tx5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(claimtrie_update_takeover_test)
|
||||||
|
{
|
||||||
|
ClaimTrieChainFixture fixture;
|
||||||
|
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "one", 5);
|
||||||
|
auto cid = ClaimIdHash(tx1.GetHash(), 0);
|
||||||
|
fixture.IncrementBlocks(1);
|
||||||
|
uint160 cid2;
|
||||||
|
int takeover;
|
||||||
|
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, 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);
|
||||||
|
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);
|
||||||
|
fixture.DecrementBlocks(1);
|
||||||
|
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||||
|
BOOST_CHECK_EQUAL(cid, cid2);
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||||
|
fixture.DecrementBlocks(1);
|
||||||
|
fixture.getLastTakeoverForName("test", cid2, takeover);
|
||||||
|
BOOST_CHECK_EQUAL(cid, cid2);
|
||||||
|
BOOST_CHECK_EQUAL(chainActive.Tip()->nHeight, takeover);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
update
|
update
|
||||||
update preserves claim id
|
update preserves claim id
|
||||||
|
@ -447,7 +479,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
|
||||||
|
|
||||||
CMutableTransaction tx;
|
CMutableTransaction tx;
|
||||||
tx.nVersion = CTransaction::CURRENT_VERSION;
|
tx.nVersion = CTransaction::CURRENT_VERSION;
|
||||||
tx.nLockTime = 1U << 31; // Disable BIP68
|
tx.nLockTime = 1U << 31U; // Disable BIP68
|
||||||
tx.vin.resize(2);
|
tx.vin.resize(2);
|
||||||
tx.vout.resize(1);
|
tx.vout.resize(1);
|
||||||
tx.vin[0].prevout.hash = tx8.GetHash();
|
tx.vin[0].prevout.hash = tx8.GetHash();
|
||||||
|
|
|
@ -26,7 +26,7 @@ public:
|
||||||
if (c.IsNull())
|
if (c.IsNull())
|
||||||
c = ClaimIdHash(p.hash, p.n);
|
c = ClaimIdHash(p.hash, p.n);
|
||||||
|
|
||||||
return addClaim(key, p, c, value.nAmount, value.nHeight, -1, {});
|
return addClaim(key, p, c, value.nAmount, value.nHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool removeClaimFromTrie(const std::string& key, const COutPoint& outPoint) {
|
bool removeClaimFromTrie(const std::string& key, const COutPoint& outPoint) {
|
||||||
|
@ -47,7 +47,7 @@ public:
|
||||||
if (p.hash.IsNull())
|
if (p.hash.IsNull())
|
||||||
p.hash = Hash(key.begin(), key.end());
|
p.hash = Hash(key.begin(), key.end());
|
||||||
|
|
||||||
return addSupport(key, p, value.nAmount, value.supportedClaimId, value.nHeight, -1, {});
|
return addSupport(key, p, value.nAmount, value.supportedClaimId, value.nHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool removeSupportFromMap(const std::string& key, const COutPoint& outPoint) {
|
bool removeSupportFromMap(const std::string& key, const COutPoint& outPoint) {
|
||||||
|
@ -337,8 +337,8 @@ BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
||||||
CClaimTrie trie(false, 0, 1);
|
CClaimTrie trie(false, 0, 1);
|
||||||
CClaimTrieCacheTest cache(&trie);
|
CClaimTrieCacheTest cache(&trie);
|
||||||
|
|
||||||
insertUndoType icu, isu; claimQueueRowType ecu; supportQueueRowType esu;
|
insertUndoType icu, isu; claimUndoType ecu; supportUndoType esu; takeoverUndoType tut;
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||||
|
|
||||||
CClaimValue value;
|
CClaimValue value;
|
||||||
value.nHeight = 1;
|
value.nHeight = 1;
|
||||||
|
@ -351,9 +351,9 @@ BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
||||||
BOOST_CHECK(cache.insertSupportIntoMap("aa", CSupportValue()));
|
BOOST_CHECK(cache.insertSupportIntoMap("aa", CSupportValue()));
|
||||||
|
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||||
BOOST_CHECK(cache.flush());
|
BOOST_CHECK(cache.flush());
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||||
|
|
||||||
CSupportValue temp;
|
CSupportValue temp;
|
||||||
CClaimValue cv;
|
CClaimValue cv;
|
||||||
|
@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("bb", value));
|
BOOST_CHECK(cache.insertClaimIntoTrie("bb", value));
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
||||||
|
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu));
|
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
||||||
|
|
||||||
BOOST_CHECK(cache.getInfoForName("aa", cv));
|
BOOST_CHECK(cache.getInfoForName("aa", cv));
|
||||||
BOOST_CHECK_EQUAL(3, cv.nValidAtHeight);
|
BOOST_CHECK_EQUAL(3, cv.nValidAtHeight);
|
||||||
|
|
|
@ -189,7 +189,7 @@ void ClaimTrieChainFixture::CommitTx(const CMutableTransaction &tx, bool has_loc
|
||||||
CValidationState state;
|
CValidationState state;
|
||||||
CAmount txFeeRate = CAmount(0);
|
CAmount txFeeRate = CAmount(0);
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
BOOST_CHECK_EQUAL(AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr, nullptr, false, txFeeRate, false), true);
|
BOOST_REQUIRE(AcceptToMemoryPool(mempool, state, MakeTransactionRef(tx), nullptr, nullptr, false, txFeeRate, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,10 +272,10 @@ void ClaimTrieChainFixture::IncrementBlocks(int num_blocks, bool mark)
|
||||||
CScript coinbase_scriptpubkey;
|
CScript coinbase_scriptpubkey;
|
||||||
coinbase_scriptpubkey << CScriptNum(chainActive.Height());
|
coinbase_scriptpubkey << CScriptNum(chainActive.Height());
|
||||||
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest().CreateNewBlock(coinbase_scriptpubkey);
|
std::unique_ptr<CBlockTemplate> pblocktemplate = AssemblerForTest().CreateNewBlock(coinbase_scriptpubkey);
|
||||||
BOOST_CHECK(pblocktemplate != nullptr);
|
BOOST_REQUIRE(pblocktemplate != nullptr);
|
||||||
if (!added_unchecked)
|
if (!added_unchecked)
|
||||||
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), num_txs_for_next_block + 1);
|
BOOST_CHECK_EQUAL(pblocktemplate->block.vtx.size(), num_txs_for_next_block + 1);
|
||||||
BOOST_CHECK_EQUAL(CreateBlock(pblocktemplate), true);
|
BOOST_REQUIRE(CreateBlock(pblocktemplate));
|
||||||
num_txs_for_next_block = 0;
|
num_txs_for_next_block = 0;
|
||||||
nNextHeight = chainActive.Height() + 1;
|
nNextHeight = chainActive.Height() + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -221,13 +221,14 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
|
||||||
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), name_upper, amelieValidHeight));
|
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), name_upper, amelieValidHeight));
|
||||||
|
|
||||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||||
BOOST_CHECK(trieCache.addClaim(name, COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), CAmount(2), currentHeight + 1, -1, {}));
|
BOOST_CHECK(trieCache.addClaim(name, COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), CAmount(2), currentHeight + 1));
|
||||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||||
insertUndoType insertUndo;
|
insertUndoType insertUndo;
|
||||||
claimQueueRowType expireUndo;
|
claimUndoType expireUndo;
|
||||||
insertUndoType insertSupportUndo;
|
insertUndoType insertSupportUndo;
|
||||||
supportQueueRowType expireSupportUndo;
|
supportUndoType expireSupportUndo;
|
||||||
BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
takeoverUndoType takeoverUndo;
|
||||||
|
BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo));
|
||||||
BOOST_CHECK(trieCache.shouldNormalize());
|
BOOST_CHECK(trieCache.shouldNormalize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,22 +305,23 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
||||||
|
|
||||||
CClaimTrieCache cache(pclaimTrie);
|
CClaimTrieCache cache(pclaimTrie);
|
||||||
int height = chainActive.Height() + 1;
|
int height = chainActive.Height() + 1;
|
||||||
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height, -1, {});
|
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, height);
|
||||||
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height, -1, {});
|
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, height);
|
||||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height, -1, {});
|
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height);
|
||||||
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), 1, ClaimIdHash(tx1.GetHash(), 0), height, -1, {});
|
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), 1, ClaimIdHash(tx1.GetHash(), 0), height);
|
||||||
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), 1, ClaimIdHash(tx2.GetHash(), 0), height, -1, {});
|
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), 1, ClaimIdHash(tx2.GetHash(), 0), height);
|
||||||
insertUndoType insertUndo;
|
insertUndoType insertUndo;
|
||||||
claimQueueRowType expireUndo;
|
claimUndoType expireUndo;
|
||||||
insertUndoType insertSupportUndo;
|
insertUndoType insertSupportUndo;
|
||||||
supportQueueRowType expireSupportUndo;
|
supportUndoType expireSupportUndo;
|
||||||
BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
takeoverUndoType takeoverUndo;
|
||||||
|
BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverUndo));
|
||||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 3U);
|
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 3U);
|
||||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[0].supports.size() == 1U);
|
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[0].supports.size() == 1U);
|
||||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[1].supports.size() == 0U);
|
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[1].supports.size() == 0U);
|
||||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[2].supports.size() == 1U);
|
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports[2].supports.size() == 1U);
|
||||||
BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo));
|
||||||
BOOST_CHECK(cache.finalizeDecrement());
|
BOOST_CHECK(cache.finalizeDecrement(takeoverUndo));
|
||||||
std::string unused;
|
std::string unused;
|
||||||
BOOST_CHECK(cache.removeSupport(COutPoint(sx1.GetHash(), 0), unused, height));
|
BOOST_CHECK(cache.removeSupport(COutPoint(sx1.GetHash(), 0), unused, height));
|
||||||
BOOST_CHECK(cache.removeSupport(COutPoint(sx2.GetHash(), 0), unused, height));
|
BOOST_CHECK(cache.removeSupport(COutPoint(sx2.GetHash(), 0), unused, height));
|
||||||
|
|
|
@ -77,9 +77,10 @@ class CBlockUndo
|
||||||
public:
|
public:
|
||||||
std::vector<CTxUndo> vtxundo; // for all but the coinbase
|
std::vector<CTxUndo> vtxundo; // for all but the coinbase
|
||||||
insertUndoType insertUndo; // any claims that went from the queue to the trie
|
insertUndoType insertUndo; // any claims that went from the queue to the trie
|
||||||
claimQueueRowType expireUndo; // any claims that expired
|
claimUndoType expireUndo; // any claims that expired
|
||||||
insertUndoType insertSupportUndo; // any supports that went from the support queue to the support map
|
insertUndoType insertSupportUndo; // any supports that went from the support queue to the support map
|
||||||
supportQueueRowType expireSupportUndo; // any supports that expired
|
supportUndoType expireSupportUndo; // any supports that expired
|
||||||
|
takeoverUndoType takeoverUndo;
|
||||||
|
|
||||||
ADD_SERIALIZE_METHODS;
|
ADD_SERIALIZE_METHODS;
|
||||||
|
|
||||||
|
@ -90,6 +91,7 @@ public:
|
||||||
READWRITE(expireUndo);
|
READWRITE(expireUndo);
|
||||||
READWRITE(insertSupportUndo);
|
READWRITE(insertSupportUndo);
|
||||||
READWRITE(expireSupportUndo);
|
READWRITE(expireSupportUndo);
|
||||||
|
READWRITE(takeoverUndo);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1819,7 +1819,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
|
||||||
|
|
||||||
// move best block pointer to prevout block
|
// move best block pointer to prevout block
|
||||||
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
view.SetBestBlock(pindex->pprev->GetBlockHash());
|
||||||
assert(trieCache.finalizeDecrement());
|
assert(trieCache.finalizeDecrement(blockUndo.takeoverUndo));
|
||||||
auto merkleHash = trieCache.getMerkleHash();
|
auto merkleHash = trieCache.getMerkleHash();
|
||||||
if (merkleHash != pindex->pprev->hashClaimTrie) {
|
if (merkleHash != pindex->pprev->hashClaimTrie) {
|
||||||
LogPrintf("Hash comparison failure at block %d\n", pindex->nHeight);
|
LogPrintf("Hash comparison failure at block %d\n", pindex->nHeight);
|
||||||
|
@ -2304,7 +2304,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: if the "just check" flag is set, we should reduce the work done here. Incrementing blocks twice per mine is not efficient.
|
// TODO: if the "just check" flag is set, we should reduce the work done here. Incrementing blocks twice per mine is not efficient.
|
||||||
const auto incremented = trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo, blockundo.insertSupportUndo, blockundo.expireSupportUndo);
|
const auto incremented = trieCache.incrementBlock(blockundo.insertUndo, blockundo.expireUndo,
|
||||||
|
blockundo.insertSupportUndo, blockundo.expireSupportUndo, blockundo.takeoverUndo);
|
||||||
assert(incremented);
|
assert(incremented);
|
||||||
|
|
||||||
if (trieCache.getMerkleHash() != block.hashClaimTrie)
|
if (trieCache.getMerkleHash() != block.hashClaimTrie)
|
||||||
|
|
Loading…
Reference in a new issue