track original height (not working)
This commit is contained in:
parent
4b5f9e650b
commit
21774aa1d4
14 changed files with 113 additions and 79 deletions
|
@ -16,20 +16,20 @@ bool CClaimScriptAddOp::claimName(CClaimTrieCache& trieCache, const std::string&
|
|||
auto claimId = ClaimIdHash(point.hash, point.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);
|
||||
return addClaim(trieCache, name, claimId, -1);
|
||||
return addClaim(trieCache, name, claimId, -1, -1);
|
||||
}
|
||||
|
||||
bool CClaimScriptAddOp::updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
|
||||
{
|
||||
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);
|
||||
return addClaim(trieCache, name, claimId, -1);
|
||||
return addClaim(trieCache, name, claimId, -1, -1);
|
||||
}
|
||||
|
||||
bool CClaimScriptAddOp::addClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
||||
int takeoverHeight)
|
||||
int takeoverHeight, int originalHeight)
|
||||
{
|
||||
return trieCache.addClaim(name, point, claimId, nValue, nHeight, takeoverHeight);
|
||||
return trieCache.addClaim(name, point, claimId, nValue, nHeight, takeoverHeight, originalHeight);
|
||||
}
|
||||
|
||||
bool CClaimScriptAddOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
|
||||
|
@ -61,8 +61,8 @@ bool CClaimScriptUndoAddOp::updateClaim(CClaimTrieCache& trieCache, const std::s
|
|||
bool CClaimScriptUndoAddOp::undoAddClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
|
||||
{
|
||||
std::string nodeName;
|
||||
int validHeight;
|
||||
bool res = trieCache.removeClaim(claimId, point, nodeName, validHeight);
|
||||
int validHeight, originalHeight;
|
||||
bool res = trieCache.removeClaim(claimId, point, nodeName, validHeight, originalHeight);
|
||||
if (!res)
|
||||
LogPrint(BCLog::CLAIMS, "Remove claim failed for %s with claimid %s\n", name, claimId.GetHex().substr(0, 6));
|
||||
return res;
|
||||
|
@ -105,7 +105,7 @@ bool CClaimScriptSpendOp::updateClaim(CClaimTrieCache& trieCache, const std::str
|
|||
bool CClaimScriptSpendOp::spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
|
||||
{
|
||||
std::string nodeName;
|
||||
bool res = trieCache.removeClaim(claimId, point, nodeName, nValidHeight);
|
||||
bool res = trieCache.removeClaim(claimId, point, nodeName, nValidHeight, nOriginalHeight);
|
||||
if (!res)
|
||||
LogPrint(BCLog::CLAIMS, "Remove claim failed for %s with claimid %s\n", name, claimId.GetHex().substr(0, 6));
|
||||
return res;
|
||||
|
@ -122,8 +122,8 @@ bool CClaimScriptSpendOp::supportClaim(CClaimTrieCache& trieCache, const std::st
|
|||
return res;
|
||||
}
|
||||
|
||||
CClaimScriptUndoSpendOp::CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight)
|
||||
: point(point), nValue(nValue), nHeight(nHeight), nValidHeight(nValidHeight)
|
||||
CClaimScriptUndoSpendOp::CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight, int nOriginalHeight)
|
||||
: point(point), nValue(nValue), nHeight(nHeight), nValidHeight(nValidHeight), nOriginalHeight(nOriginalHeight)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,8 @@ bool CClaimScriptUndoSpendOp::updateClaim(CClaimTrieCache& trieCache, const std:
|
|||
|
||||
bool CClaimScriptUndoSpendOp::undoSpendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
|
||||
{
|
||||
return trieCache.addClaim(name, point, claimId, nValue, nHeight, nValidHeight);
|
||||
return trieCache.addClaim(name, point, claimId, nValue, nHeight,
|
||||
nValidHeight, nOriginalHeight);
|
||||
}
|
||||
|
||||
bool CClaimScriptUndoSpendOp::supportClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId)
|
||||
|
@ -188,17 +189,17 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
||||
{
|
||||
if (CClaimScriptSpendOp::spendClaim(trieCache, name, claimId)) {
|
||||
callback(name, claimId);
|
||||
callback(name, claimId, nOriginalHeight);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::function<void(const std::string& name, const uint160& claimId)> callback;
|
||||
std::function<void(const std::string& name, const uint160& claimId, int originalHeight)> callback;
|
||||
};
|
||||
|
||||
spentClaimsType spentClaims;
|
||||
|
||||
for (std::size_t j = 0; j < tx.vin.size(); j++) {
|
||||
for (uint32_t j = 0; j < tx.vin.size(); j++) {
|
||||
const CTxIn& txin = tx.vin[j];
|
||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
||||
|
||||
|
@ -214,13 +215,16 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
if (scriptPubKey.empty())
|
||||
continue;
|
||||
|
||||
int nValidAtHeight;
|
||||
int nValidAtHeight, nOriginalHeight = 0;
|
||||
CSpendClaimHistory spendClaim(COutPoint(txin.prevout.hash, txin.prevout.n), scriptHeight, nValidAtHeight);
|
||||
spendClaim.callback = [&spentClaims](const std::string& name, const uint160& claimId) {
|
||||
spentClaims.emplace_back(name, claimId);
|
||||
spendClaim.callback = [&spentClaims, &nOriginalHeight](const std::string& name, const uint160& claimId, int originalHeight) {
|
||||
spentClaims.push_back({name, claimId, originalHeight});
|
||||
nOriginalHeight = originalHeight;
|
||||
};
|
||||
if (ProcessClaim(spendClaim, trieCache, scriptPubKey) && callbacks.claimUndoHeights)
|
||||
callbacks.claimUndoHeights(j, nValidAtHeight);
|
||||
if (ProcessClaim(spendClaim, trieCache, scriptPubKey) && callbacks.claimUndoHeights) {
|
||||
// assert(nValidAtHeight > 0 && nOriginalHeight > 0); // fails on tests
|
||||
callbacks.claimUndoHeights(j, uint32_t(nValidAtHeight), uint32_t(nOriginalHeight));
|
||||
}
|
||||
}
|
||||
|
||||
class CAddSpendClaim : public CClaimScriptAddOp
|
||||
|
@ -230,11 +234,15 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
|
||||
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
||||
{
|
||||
if (callback(name, claimId))
|
||||
return CClaimScriptAddOp::updateClaim(trieCache, name, claimId);
|
||||
auto originalHeight = callback(name, claimId);
|
||||
if (originalHeight >= 0) {
|
||||
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);
|
||||
return CClaimScriptAddOp::addClaim(trieCache, name, claimId, -1, originalHeight);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
std::function<bool(const std::string& name, const uint160& claimId)> callback;
|
||||
std::function<int(const std::string& name, const uint160& claimId)> callback;
|
||||
};
|
||||
|
||||
for (std::size_t j = 0; j < tx.vout.size(); j++) {
|
||||
|
@ -244,14 +252,14 @@ void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoin
|
|||
continue;
|
||||
|
||||
CAddSpendClaim addClaim(COutPoint(tx.GetHash(), j), txout.nValue, nHeight);
|
||||
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId) -> bool {
|
||||
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId) -> int {
|
||||
for (auto itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) {
|
||||
if (itSpent->second == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first)) {
|
||||
if (itSpent->id == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->name)) {
|
||||
spentClaims.erase(itSpent);
|
||||
return true;
|
||||
return itSpent->originalHeight;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return -1;
|
||||
};
|
||||
ProcessClaim(addClaim, trieCache, txout.scriptPubKey);
|
||||
}
|
||||
|
|
|
@ -81,7 +81,8 @@ protected:
|
|||
* @param[in] name name of the claim
|
||||
* @param[in] claimId id of the claim
|
||||
*/
|
||||
virtual bool addClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId, int takeoverHeight);
|
||||
virtual bool addClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId,
|
||||
int takeoverHeight, int originalHeight);
|
||||
const COutPoint point;
|
||||
const CAmount nValue;
|
||||
const int nHeight;
|
||||
|
@ -167,6 +168,7 @@ protected:
|
|||
const COutPoint point;
|
||||
const int nHeight;
|
||||
int& nValidHeight;
|
||||
int nOriginalHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -182,7 +184,7 @@ public:
|
|||
* @param[in] nHeight entry height of the claim
|
||||
* @param[in] nValidHeight valid height of the claim
|
||||
*/
|
||||
CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight);
|
||||
CClaimScriptUndoSpendOp(const COutPoint& point, CAmount nValue, int nHeight, int nValidHeight, int nOriginalHeight);
|
||||
/**
|
||||
* Implementation of OP_CLAIM_NAME handler
|
||||
* @see CClaimScriptOp::claimName
|
||||
|
@ -211,6 +213,7 @@ protected:
|
|||
const CAmount nValue;
|
||||
const int nHeight;
|
||||
const int nValidHeight;
|
||||
const int nOriginalHeight;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -221,13 +224,13 @@ protected:
|
|||
*/
|
||||
bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CScript& scriptPubKey);
|
||||
|
||||
typedef std::pair<std::string, uint160> spentClaimType;
|
||||
struct spentClaimType { std::string name; uint160 id; int originalHeight; };
|
||||
typedef std::vector<spentClaimType> spentClaimsType;
|
||||
|
||||
struct CUpdateCacheCallbacks
|
||||
{
|
||||
std::function<CScript(const COutPoint& point)> findScriptKey;
|
||||
std::function<void(int, int)> claimUndoHeights;
|
||||
std::function<void(uint32_t, uint32_t, uint32_t)> claimUndoHeights;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -75,8 +75,8 @@ CNameOutPointHeightType::CNameOutPointHeightType(std::string name, COutPoint out
|
|||
{
|
||||
}
|
||||
|
||||
CClaimNsupports::CClaimNsupports(CClaimValue claim, int64_t effectiveAmount, std::vector<CSupportValue> supports)
|
||||
: claim(std::move(claim)), effectiveAmount(effectiveAmount), supports(std::move(supports))
|
||||
CClaimNsupports::CClaimNsupports(CClaimValue claim, int64_t effectiveAmount, int originalHeight, std::vector<CSupportValue> supports)
|
||||
: claim(std::move(claim)), effectiveAmount(effectiveAmount), originalHeight(originalHeight), supports(std::move(supports))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -78,12 +78,14 @@ struct CClaimNsupports
|
|||
CClaimNsupports& operator=(CClaimNsupports&&) = default;
|
||||
CClaimNsupports& operator=(const CClaimNsupports&) = default;
|
||||
|
||||
CClaimNsupports(CClaimValue claim, int64_t effectiveAmount, std::vector<CSupportValue> supports = {});
|
||||
CClaimNsupports(CClaimValue claim, int64_t effectiveAmount, int originalHeight,
|
||||
std::vector<CSupportValue> supports = {});
|
||||
|
||||
bool IsNull() const;
|
||||
|
||||
CClaimValue claim;
|
||||
int64_t effectiveAmount = 0;
|
||||
int originalHeight = -1;
|
||||
std::vector<CSupportValue> supports;
|
||||
};
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary()
|
|||
|
||||
// work around a bug in the old implementation:
|
||||
db << "UPDATE claim SET activationHeight = ?1 " // force a takeover on these
|
||||
"WHERE blockHeight < ?1 AND activationHeight > ?1 AND nodeName != name" << nNextHeight;
|
||||
"WHERE updateHeight < ?1 AND activationHeight > ?1 AND nodeName != name" << nNextHeight;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ namespace sqlite
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline int commit(database& db, std::size_t attempts = 60)
|
||||
inline int commit(database& db, std::size_t attempts = 200)
|
||||
{
|
||||
int code = SQLITE_OK;
|
||||
for (auto i = 0u; i < attempts; ++i) {
|
||||
|
@ -67,7 +67,7 @@ namespace sqlite
|
|||
code = e.get_code();
|
||||
if (code == SQLITE_LOCKED || code == SQLITE_BUSY) {
|
||||
using namespace std::chrono_literals;
|
||||
std::this_thread::sleep_for(1s);
|
||||
std::this_thread::sleep_for(100ms);
|
||||
continue;
|
||||
}
|
||||
return code;
|
||||
|
|
|
@ -88,7 +88,7 @@ CClaimTrie::CClaimTrie(std::size_t cacheBytes, bool fWipe, int height,
|
|||
|
||||
db << "CREATE TABLE IF NOT EXISTS claim (claimID BLOB NOT NULL PRIMARY KEY, name BLOB NOT NULL, "
|
||||
"nodeName BLOB NOT NULL REFERENCES node(name) DEFERRABLE INITIALLY DEFERRED, "
|
||||
"txID BLOB NOT NULL, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, "
|
||||
"txID BLOB NOT NULL, txN INTEGER NOT NULL, originalHeight INTEGER NOT NULL, updateHeight INTEGER NOT NULL, "
|
||||
"validHeight INTEGER NOT NULL, activationHeight INTEGER NOT NULL, "
|
||||
"expirationHeight INTEGER NOT NULL, amount INTEGER NOT NULL);";
|
||||
|
||||
|
@ -383,7 +383,7 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
|
|||
return it != supports.end();
|
||||
};
|
||||
|
||||
auto query = db << "SELECT claimID, txID, txN, blockHeight, activationHeight, amount "
|
||||
auto query = db << "SELECT claimID, txID, txN, originalHeight, updateHeight, activationHeight, amount "
|
||||
"FROM claim WHERE nodeName = ? AND expirationHeight >= ?"
|
||||
<< name << nNextHeight;
|
||||
|
||||
|
@ -391,10 +391,11 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
|
|||
std::vector<CClaimNsupports> claimsNsupports;
|
||||
for (auto &&row: query) {
|
||||
CClaimValue claim;
|
||||
int originalHeight;
|
||||
row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n
|
||||
>> claim.nHeight >> claim.nValidAtHeight >> claim.nAmount;
|
||||
>> originalHeight >> claim.nHeight >> claim.nValidAtHeight >> claim.nAmount;
|
||||
int64_t nAmount = claim.nValidAtHeight < nNextHeight ? claim.nAmount : 0;
|
||||
auto ic = claimsNsupports.emplace(claimsNsupports.end(), claim, nAmount);
|
||||
auto ic = claimsNsupports.emplace(claimsNsupports.end(), claim, nAmount, originalHeight);
|
||||
for (auto it = supports.begin(); find(it, claim); it = supports.erase(it)) {
|
||||
if (it->nValidAtHeight < nNextHeight)
|
||||
ic->effectiveAmount += it->nAmount;
|
||||
|
@ -492,12 +493,12 @@ bool CClaimTrieCacheBase::flush()
|
|||
const std::string childHashQuery_s = "SELECT name, hash FROM node WHERE parent = ? ORDER BY name";
|
||||
|
||||
const std::string claimHashQuery_s =
|
||||
"SELECT c.txID, c.txN, c.claimID, c.blockHeight, c.activationHeight, c.amount, "
|
||||
"SELECT c.txID, c.txN, c.claimID, c.updateHeight, c.activationHeight, c.amount, "
|
||||
"(SELECT IFNULL(SUM(s.amount),0)+c.amount FROM support s "
|
||||
"WHERE s.supportedClaimID = c.claimID AND s.nodeName = c.nodeName "
|
||||
"AND s.activationHeight < ?1 AND s.expirationHeight >= ?1) as effectiveAmount "
|
||||
"FROM claim c WHERE c.nodeName = ?2 AND c.activationHeight < ?1 AND c.expirationHeight >= ?1 "
|
||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN";
|
||||
"ORDER BY effectiveAmount DESC, c.updateHeight, c.txID, c.txN";
|
||||
|
||||
const std::string claimHashQueryLimit_s = claimHashQuery_s + " LIMIT 1";
|
||||
|
||||
|
@ -574,7 +575,7 @@ bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint16
|
|||
}
|
||||
|
||||
bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId,
|
||||
int64_t nAmount, int nHeight, int nValidHeight)
|
||||
int64_t nAmount, int nHeight, int nValidHeight, int originalHeight)
|
||||
{
|
||||
ensureTransacting();
|
||||
|
||||
|
@ -589,15 +590,19 @@ bool CClaimTrieCacheBase::addClaim(const std::string& name, const COutPoint& out
|
|||
// 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)
|
||||
nValidHeight = nHeight + getDelayForName(name, claimId); // sets nValidHeight to the old value
|
||||
|
||||
if (originalHeight <= 0)
|
||||
originalHeight = nHeight;
|
||||
|
||||
auto nodeName = adjustNameForValidHeight(name, nValidHeight);
|
||||
auto expires = expirationTime() + nHeight;
|
||||
|
||||
db << "INSERT INTO claim(claimID, name, nodeName, txID, txN, amount, blockHeight, validHeight, activationHeight, expirationHeight) "
|
||||
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
<< claimId << name << nodeName << outPoint.hash << outPoint.n << nAmount << nHeight << nValidHeight << nValidHeight << expires;
|
||||
db << "INSERT INTO claim(claimID, name, nodeName, txID, txN, amount, originalHeight, updateHeight, "
|
||||
"validHeight, activationHeight, expirationHeight) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
|
||||
<< claimId << name << nodeName << outPoint.hash << outPoint.n << nAmount
|
||||
<< originalHeight << nHeight << nValidHeight << nValidHeight << expires;
|
||||
|
||||
if (nValidHeight < nNextHeight)
|
||||
db << "INSERT INTO node(name) VALUES(?) ON CONFLICT(name) DO UPDATE SET hash = NULL" << nodeName;
|
||||
|
@ -626,7 +631,8 @@ bool CClaimTrieCacheBase::addSupport(const std::string& name, const COutPoint& o
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName, int& validHeight)
|
||||
bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& outPoint, std::string& nodeName,
|
||||
int& validHeight, int& originalHeight)
|
||||
{
|
||||
ensureTransacting();
|
||||
|
||||
|
@ -634,16 +640,19 @@ bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& o
|
|||
// when going forward we spend a claim (aka, call removeClaim) before updating it (aka, call addClaim)
|
||||
// when going backwards we first remove the update by calling removeClaim
|
||||
// we then undo the spend of the previous one by calling addClaim with the original data
|
||||
// in order to maintain the proper takeover height the udpater will need to use our height returned here
|
||||
// in order to maintain the proper takeover height the updater will need to use our height returned here
|
||||
|
||||
auto query = db << "SELECT nodeName, activationHeight FROM claim WHERE claimID = ? AND txID = ? AND txN = ? AND expirationHeight >= ?"
|
||||
auto query = db << "SELECT nodeName, activationHeight, originalHeight FROM claim WHERE claimID = ? AND txID = ? AND txN = ? AND expirationHeight >= ?"
|
||||
<< claimId << outPoint.hash << outPoint.n << nNextHeight;
|
||||
auto it = query.begin();
|
||||
if (it == query.end()) return false;
|
||||
*it >> nodeName >> validHeight;
|
||||
if (it == query.end())
|
||||
return false;
|
||||
|
||||
*it >> nodeName >> validHeight >> originalHeight;
|
||||
db << "DELETE FROM claim WHERE claimID = ? AND txID = ? and txN = ?" << claimId << outPoint.hash << outPoint.n;
|
||||
if (!db.rows_modified())
|
||||
return false;
|
||||
|
||||
db << "UPDATE node SET hash = NULL WHERE name = ?" << nodeName;
|
||||
|
||||
// when node should be deleted from cache but instead it's kept
|
||||
|
@ -653,10 +662,10 @@ bool CClaimTrieCacheBase::removeClaim(const uint160& claimId, const COutPoint& o
|
|||
&& nNextHeight < base->nMaxRemovalWorkaroundHeight) { // TODO: hard fork this out (which we already tried once but failed)
|
||||
// neither LIKE nor SUBSTR will use an index on a blob, but BETWEEN is a good, fast alternative
|
||||
auto end = nodeName + std::string( 256, std::numeric_limits<char>::max()); // 256 == MAX_CLAIM_NAME_SIZE + 1
|
||||
auto query = db << "SELECT nodeName FROM claim WHERE nodeName BETWEEN ?1 AND ?2 "
|
||||
auto innerQuery = db << "SELECT nodeName FROM claim WHERE nodeName BETWEEN ?1 AND ?2 "
|
||||
"AND activationHeight < ?3 AND expirationHeight >= ?3 ORDER BY nodeName LIMIT 1"
|
||||
<< nodeName << end << nNextHeight;
|
||||
for (auto&& row: query) {
|
||||
for (auto&& row: innerQuery) {
|
||||
std::string shortestMatch;
|
||||
row >> shortestMatch;
|
||||
if (shortestMatch != nodeName)
|
||||
|
@ -878,7 +887,7 @@ bool CClaimTrieCacheBase::findNameForClaim(std::vector<unsigned char> claim, CCl
|
|||
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 "
|
||||
auto query = db << "SELECT nodeName, claimID, txID, txN, amount, activationHeight, updateHeight "
|
||||
"FROM claim WHERE REVERSE(claimID) BETWEEN ?1 AND ?2 "
|
||||
"AND activationHeight < ?3 AND expirationHeight >= ?3 LIMIT 2"
|
||||
<< claim << maximum << nNextHeight;
|
||||
|
@ -902,7 +911,7 @@ void CClaimTrieCacheBase::getNamesInTrie(std::function<void(const std::string&)>
|
|||
|
||||
std::vector<uint160> CClaimTrieCacheBase::getActivatedClaims(int height) {
|
||||
std::vector<uint160> ret;
|
||||
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE activationHeight = ?1 AND blockHeight < ?1" << height;
|
||||
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE activationHeight = ?1 AND updateHeight < ?1" << height;
|
||||
for (auto&& row: query) {
|
||||
ret.emplace_back();
|
||||
row >> ret.back();
|
||||
|
@ -911,7 +920,7 @@ std::vector<uint160> CClaimTrieCacheBase::getActivatedClaims(int height) {
|
|||
}
|
||||
std::vector<uint160> CClaimTrieCacheBase::getClaimsWithActivatedSupports(int height) {
|
||||
std::vector<uint160> ret;
|
||||
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE activationHeight = ?1 AND blockHeight < ?1" << height;
|
||||
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE activationHeight = ?1 AND updateHeight < ?1" << height;
|
||||
for (auto&& row: query) {
|
||||
ret.emplace_back();
|
||||
row >> ret.back();
|
||||
|
@ -920,7 +929,7 @@ std::vector<uint160> CClaimTrieCacheBase::getClaimsWithActivatedSupports(int hei
|
|||
}
|
||||
std::vector<uint160> CClaimTrieCacheBase::getExpiredClaims(int height) {
|
||||
std::vector<uint160> ret;
|
||||
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE expirationHeight = ?1 AND blockHeight < ?1" << height;
|
||||
auto query = db << "SELECT DISTINCT claimID FROM claim WHERE expirationHeight = ?1 AND updateHeight < ?1" << height;
|
||||
for (auto&& row: query) {
|
||||
ret.emplace_back();
|
||||
row >> ret.back();
|
||||
|
@ -929,7 +938,7 @@ std::vector<uint160> CClaimTrieCacheBase::getExpiredClaims(int height) {
|
|||
}
|
||||
std::vector<uint160> CClaimTrieCacheBase::getClaimsWithExpiredSupports(int height) {
|
||||
std::vector<uint160> ret;
|
||||
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE expirationHeight = ?1 AND blockHeight < ?1" << height;
|
||||
auto query = db << "SELECT DISTINCT supportedClaimID FROM support WHERE expirationHeight = ?1 AND updateHeight < ?1" << height;
|
||||
for (auto&& row: query) {
|
||||
ret.emplace_back();
|
||||
row >> ret.back();
|
||||
|
|
|
@ -81,12 +81,13 @@ public:
|
|||
bool haveSupportInQueue(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
||||
|
||||
bool addClaim(const std::string& name, const COutPoint& outPoint, const uint160& claimId, int64_t nAmount,
|
||||
int nHeight, int nValidHeight = -1);
|
||||
int nHeight, int nValidHeight = -1, int originalHeight = -1);
|
||||
|
||||
bool addSupport(const std::string& name, const COutPoint& outPoint, const uint160& supportedClaimId, int64_t nAmount,
|
||||
int nHeight, int nValidHeight = -1);
|
||||
|
||||
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, int& originalHeight);
|
||||
bool removeSupport(const COutPoint& outPoint, std::string& nodeName, int& validHeight);
|
||||
|
||||
virtual bool incrementBlock();
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define T_NAMES "names"
|
||||
#define T_EFFECTIVEAMOUNT "effectiveAmount"
|
||||
#define T_LASTTAKEOVERHEIGHT "lastTakeoverHeight"
|
||||
#define T_ORIGINALHEIGHT "originalHeight"
|
||||
#define T_SUPPORTS "supports"
|
||||
#define T_SUPPORTSWITHOUTCLAIM "supportsWithoutClaim"
|
||||
#define T_TOTALNAMES "totalNames"
|
||||
|
@ -83,12 +84,13 @@ S3(" ", T_NAME, " (string) the original name of this claim
|
|||
S3(" ", T_VALUE, " (string) the value of this claim") \
|
||||
S3(" ", T_ADDRESS, " (string) the destination address of this claim") \
|
||||
S3(" ", T_CLAIMID, " (string) the claimId of the claim") \
|
||||
S3(" ", T_TXID, " (string) the txid of the claim") \
|
||||
S3(" ", T_TXID, " (string) the txid of the claim or its most recent update") \
|
||||
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs") \
|
||||
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located") \
|
||||
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the support became/becomes valid") \
|
||||
S3(" ", T_AMOUNT, " (numeric) the amount of the claim") \
|
||||
S3(" ", T_AMOUNT, " (numeric) the amount of the claim or its most recent update") \
|
||||
S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim") \
|
||||
S3(" ", T_ORIGINALHEIGHT, " (numeric) the block height where the claim was first created") \
|
||||
S3(" ", T_PENDINGAMOUNT, " (numeric) expected amount when claim and its supports are all valid") \
|
||||
S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim") \
|
||||
S3(" ", T_VALUE, " (string) the metadata of the support if any") \
|
||||
|
@ -159,12 +161,13 @@ S3(" ", T_NAME, " (string) the original name of this claim
|
|||
S3(" ", T_VALUE, " (string) the value of this claim")
|
||||
S3(" ", T_ADDRESS, " (string) the destination address of this claim")
|
||||
S3(" ", T_CLAIMID, " (string) the claimId of the claim")
|
||||
S3(" ", T_TXID, " (string) the txid of the claim")
|
||||
S3(" ", T_TXID, " (string) the txid of the claim or its most recent update")
|
||||
S3(" ", T_N, " (numeric) the index of the claim in the transaction's list of outputs")
|
||||
S3(" ", T_HEIGHT, " (numeric) the height of the block in which this transaction is located")
|
||||
S3(" ", T_VALIDATHEIGHT, " (numeric) the height at which the claim became/becomes valid")
|
||||
S3(" ", T_AMOUNT, " (numeric) the amount of the claim")
|
||||
S3(" ", T_AMOUNT, " (numeric) the amount of the claim or its most recent update")
|
||||
S3(" ", T_EFFECTIVEAMOUNT, " (numeric) the amount plus amount from all supports associated with the claim")
|
||||
S3(" ", T_ORIGINALHEIGHT, " (numeric) the block height where the claim was first created") \
|
||||
S3(" ", T_PENDINGAMOUNT, " (numeric) expected amount when claim and its support got valid")
|
||||
S3(" ", T_SUPPORTS, ": [ (array of object) supports for this claim")
|
||||
S3(" ", T_VALUE, " (string) the metadata of the support if any")
|
||||
|
|
|
@ -209,6 +209,8 @@ UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, const CClaimN
|
|||
|
||||
auto result = claimToJSON(coinsCache, claim);
|
||||
result.pushKV(T_EFFECTIVEAMOUNT, claimNsupports.effectiveAmount);
|
||||
if (claimNsupports.originalHeight > 0)
|
||||
result.pushKV(T_ORIGINALHEIGHT, claimNsupports.originalHeight);
|
||||
|
||||
auto fullAmount = amountToClaim(claimNsupports);
|
||||
if (fullAmount > claimNsupports.effectiveAmount)
|
||||
|
|
|
@ -31,14 +31,14 @@ public:
|
|||
}
|
||||
|
||||
bool removeClaimFromTrie(const std::string& key, const COutPoint& outPoint) {
|
||||
int validHeight;
|
||||
int validHeight, originalHeight;
|
||||
std::string nodeName;
|
||||
|
||||
auto p = outPoint;
|
||||
if (p.hash.IsNull())
|
||||
p.hash = Hash(key.begin(), key.end());
|
||||
|
||||
auto ret = removeClaim(ClaimIdHash(uint256(p.hash), p.n), p, nodeName, validHeight);
|
||||
auto ret = removeClaim(ClaimIdHash(uint256(p.hash), p.n), p, nodeName, validHeight, originalHeight);
|
||||
assert(!ret || nodeName == key);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -215,13 +215,13 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
|
|||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
CBlockIndex* pindex = chainActive.Tip();
|
||||
CBlock block;
|
||||
int amelieValidHeight;
|
||||
int amelieValidHeight, ameliaOriginalHeight;
|
||||
std::string removed;
|
||||
BOOST_CHECK(trieCache.shouldNormalize());
|
||||
BOOST_CHECK(ReadBlockFromDisk(block, pindex, Params().GetConsensus()));
|
||||
BOOST_CHECK(g_chainstate.DisconnectBlock(block, pindex, coins, trieCache) == DisconnectResult::DISCONNECT_OK);
|
||||
BOOST_CHECK(!trieCache.shouldNormalize());
|
||||
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), removed, amelieValidHeight));
|
||||
BOOST_CHECK(trieCache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), removed, amelieValidHeight, ameliaOriginalHeight));
|
||||
|
||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||
BOOST_CHECK_EQUAL(nval1.claimId, ClaimIdHash(tx1.GetHash(), 0));
|
||||
|
@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
|||
CMutableTransaction sx2 = fixture.MakeSupport(fixture.GetCoinbase(), tx2, "Ab", 1);
|
||||
|
||||
CClaimTrieCache cache(pclaimTrie);
|
||||
int height = chainActive.Height() + 1;
|
||||
int height = chainActive.Height() + 1, originalHeight;
|
||||
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);
|
||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, height);
|
||||
|
@ -317,9 +317,9 @@ BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
|||
std::string unused;
|
||||
BOOST_CHECK(cache.removeSupport(COutPoint(sx1.GetHash(), 0), unused, height));
|
||||
BOOST_CHECK(cache.removeSupport(COutPoint(sx2.GetHash(), 0), unused, height));
|
||||
BOOST_CHECK(cache.removeClaim(ClaimIdHash(tx1.GetHash(), 0), COutPoint(tx1.GetHash(), 0), unused, height));
|
||||
BOOST_CHECK(cache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), unused, height));
|
||||
BOOST_CHECK(cache.removeClaim(ClaimIdHash(tx3.GetHash(), 0), COutPoint(tx3.GetHash(), 0), unused, height));
|
||||
BOOST_CHECK(cache.removeClaim(ClaimIdHash(tx1.GetHash(), 0), COutPoint(tx1.GetHash(), 0), unused, height, originalHeight));
|
||||
BOOST_CHECK(cache.removeClaim(ClaimIdHash(tx2.GetHash(), 0), COutPoint(tx2.GetHash(), 0), unused, height, originalHeight));
|
||||
BOOST_CHECK(cache.removeClaim(ClaimIdHash(tx3.GetHash(), 0), COutPoint(tx3.GetHash(), 0), unused, height, originalHeight));
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claimsNsupports.size() == 0U);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,10 +26,11 @@ public:
|
|||
uint32_t nHeight; // if the outpoint was the last unspent: its height
|
||||
uint32_t nClaimValidHeight; // If the outpoint was a claim or support, the height at which the claim or support should be inserted into the trie
|
||||
bool fIsClaim; // if the outpoint was a claim or support
|
||||
uint32_t nClaimOriginalHeight; // If we are a claim, we need to track the original insertion height for that claim
|
||||
|
||||
CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nClaimValidHeight(0), fIsClaim(false) {}
|
||||
CTxInUndo() : txout(), fCoinBase(false), nHeight(0), nClaimValidHeight(0), fIsClaim(false), nClaimOriginalHeight(0) {}
|
||||
CTxInUndo(const CTxOut &txoutIn, bool fCoinBaseIn = false, uint32_t nHeightIn = 0) :
|
||||
txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nClaimValidHeight(0), fIsClaim(false) {}
|
||||
txout(txoutIn), fCoinBase(fCoinBaseIn), nHeight(nHeightIn), nClaimValidHeight(0), fIsClaim(false), nClaimOriginalHeight(0) {}
|
||||
|
||||
ADD_SERIALIZE_METHODS;
|
||||
|
||||
|
@ -50,6 +51,7 @@ public:
|
|||
READWRITE(REF(CTxOutCompressor(REF(txout))));
|
||||
READWRITE(VARINT(nClaimValidHeight));
|
||||
READWRITE(fIsClaim);
|
||||
READWRITE(VARINT(nClaimOriginalHeight));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1489,7 +1489,10 @@ int ApplyTxInUndo(unsigned int index, CTxUndo& txUndo, CCoinsViewCache& view, CC
|
|||
// restore claim if applicable
|
||||
if (undo.fIsClaim && !undo.txout.scriptPubKey.empty()) {
|
||||
auto nValidHeight = undo.nClaimValidHeight;
|
||||
CClaimScriptUndoSpendOp undoSpend(COutPoint(out.hash, out.n), undo.txout.nValue, undo.nHeight, nValidHeight);
|
||||
auto nOriginalHeight = undo.nClaimOriginalHeight;
|
||||
// assert(nValidHeight > 0 && nOriginalHeight > 0); // fails unit tests
|
||||
CClaimScriptUndoSpendOp undoSpend(COutPoint(out.hash, out.n), undo.txout.nValue, undo.nHeight,
|
||||
nValidHeight, nOriginalHeight);
|
||||
ProcessClaim(undoSpend, trieCache, undo.txout.scriptPubKey);
|
||||
}
|
||||
|
||||
|
@ -1966,7 +1969,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
for (unsigned int i = 0; i < block.vtx.size(); i++)
|
||||
{
|
||||
const CTransaction &tx = *(block.vtx[i]);
|
||||
std::map<unsigned int, unsigned int> mClaimUndoHeights;
|
||||
std::map<uint32_t, std::pair<uint32_t, uint32_t>> mClaimUndoHeights;
|
||||
|
||||
nInputs += tx.vin.size();
|
||||
|
||||
|
@ -2016,8 +2019,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
control.Add(vChecks);
|
||||
CUpdateCacheCallbacks callbacks = {
|
||||
.findScriptKey = {},
|
||||
.claimUndoHeights = [&mClaimUndoHeights](int index, int nValidAtHeight) {
|
||||
mClaimUndoHeights.emplace(index, nValidAtHeight);
|
||||
.claimUndoHeights = [&mClaimUndoHeights](uint32_t index, uint32_t nValidAtHeight, uint32_t nOriginalHeight) {
|
||||
mClaimUndoHeights.emplace(index, std::make_pair(nValidAtHeight, nOriginalHeight));
|
||||
}
|
||||
};
|
||||
UpdateCache(tx, trieCache, view, pindex->nHeight, callbacks);
|
||||
|
@ -2033,7 +2036,8 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
auto& txinUndos = blockundo.vtxundo.back().vprevout;
|
||||
for (auto itHeight = mClaimUndoHeights.begin(); itHeight != mClaimUndoHeights.end(); ++itHeight)
|
||||
{
|
||||
txinUndos[itHeight->first].nClaimValidHeight = itHeight->second;
|
||||
txinUndos[itHeight->first].nClaimValidHeight = itHeight->second.first;
|
||||
txinUndos[itHeight->first].nClaimOriginalHeight = itHeight->second.second;
|
||||
txinUndos[itHeight->first].fIsClaim = true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue