track original height (not working)

This commit is contained in:
Brannon King 2020-01-02 17:48:47 -07:00
parent 4b5f9e650b
commit 21774aa1d4
14 changed files with 113 additions and 79 deletions

View file

@ -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);
}

View file

@ -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;
};
/**

View file

@ -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))
{
}

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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();

View file

@ -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")

View file

@ -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)

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));
}
};

View file

@ -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;
}
}