Fix expiration fork usage
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
This commit is contained in:
parent
55da76a515
commit
934908c79e
10 changed files with 196 additions and 191 deletions
|
@ -2,8 +2,9 @@
|
|||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "claimscriptop.h"
|
||||
#include "nameclaim.h"
|
||||
#include <coins.h>
|
||||
#include <claimscriptop.h>
|
||||
#include <nameclaim.h>
|
||||
|
||||
CClaimScriptAddOp::CClaimScriptAddOp(const COutPoint& point, CAmount nValue, int nHeight)
|
||||
: point(point), nValue(nValue), nHeight(nHeight)
|
||||
|
@ -153,59 +154,81 @@ bool ProcessClaim(CClaimScriptOp& claimOp, CClaimTrieCache& trieCache, const CSc
|
|||
throw std::runtime_error("Unimplemented OP handler.");
|
||||
}
|
||||
|
||||
bool SpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, int nHeight, int& nValidHeight, spentClaimsType& spentClaims)
|
||||
void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoinsViewCache& view, int nHeight, const CUpdateCacheCallbacks& callbacks)
|
||||
{
|
||||
class CSpendClaimHistory : public CClaimScriptSpendOp
|
||||
{
|
||||
public:
|
||||
CSpendClaimHistory(spentClaimsType& spentClaims, const COutPoint& point, int nHeight, int& nValidHeight)
|
||||
: CClaimScriptSpendOp(point, nHeight, nValidHeight), spentClaims(spentClaims)
|
||||
{
|
||||
}
|
||||
using CClaimScriptSpendOp::CClaimScriptSpendOp;
|
||||
|
||||
bool spendClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
||||
{
|
||||
if (CClaimScriptSpendOp::spendClaim(trieCache, name, claimId)) {
|
||||
spentClaims.emplace_back(name, claimId);
|
||||
callback(name, claimId);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
spentClaimsType& spentClaims;
|
||||
std::function<void(const std::string& name, const uint160& claimId)> callback;
|
||||
};
|
||||
|
||||
CSpendClaimHistory spendClaim(spentClaims, point, nHeight, nValidHeight);
|
||||
return ProcessClaim(spendClaim, trieCache, scriptPubKey);
|
||||
spentClaimsType spentClaims;
|
||||
|
||||
for (std::size_t j = 0; j < tx.vin.size(); j++) {
|
||||
const CTxIn& txin = tx.vin[j];
|
||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
||||
|
||||
CScript scriptPubKey;
|
||||
int scriptHeight = nHeight;
|
||||
if (coin.out.IsNull() && callbacks.findScriptKey) {
|
||||
scriptPubKey = callbacks.findScriptKey(txin.prevout);
|
||||
} else {
|
||||
scriptHeight = coin.nHeight;
|
||||
scriptPubKey = coin.out.scriptPubKey;
|
||||
}
|
||||
|
||||
if (scriptPubKey.empty())
|
||||
continue;
|
||||
|
||||
int nValidAtHeight;
|
||||
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);
|
||||
};
|
||||
if (ProcessClaim(spendClaim, trieCache, scriptPubKey) && callbacks.claimUndoHeights)
|
||||
callbacks.claimUndoHeights(j, nValidAtHeight);
|
||||
}
|
||||
|
||||
bool AddSpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, CAmount nValue, int nHeight, spentClaimsType& spentClaims)
|
||||
{
|
||||
class CAddSpendClaim : public CClaimScriptAddOp
|
||||
{
|
||||
public:
|
||||
CAddSpendClaim(spentClaimsType& spentClaims, const COutPoint& point, CAmount nValue, int nHeight)
|
||||
: CClaimScriptAddOp(point, nValue, nHeight), spentClaims(spentClaims)
|
||||
{
|
||||
}
|
||||
using CClaimScriptAddOp::CClaimScriptAddOp;
|
||||
|
||||
bool updateClaim(CClaimTrieCache& trieCache, const std::string& name, const uint160& claimId) override
|
||||
{
|
||||
spentClaimsType::iterator itSpent = spentClaims.begin();
|
||||
for (; itSpent != spentClaims.end(); ++itSpent) {
|
||||
if (callback(name, claimId))
|
||||
return CClaimScriptAddOp::updateClaim(trieCache, name, claimId);
|
||||
return false;
|
||||
}
|
||||
std::function<bool(const std::string& name, const uint160& claimId)> callback;
|
||||
};
|
||||
|
||||
for (std::size_t j = 0; j < tx.vout.size(); j++) {
|
||||
const CTxOut& txout = tx.vout[j];
|
||||
|
||||
if (txout.scriptPubKey.empty())
|
||||
continue;
|
||||
|
||||
CAddSpendClaim addClaim(COutPoint(tx.GetHash(), j), txout.nValue, nHeight);
|
||||
addClaim.callback = [&trieCache, &spentClaims](const std::string& name, const uint160& claimId) -> bool {
|
||||
for (auto itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent) {
|
||||
if (itSpent->second == claimId && trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first)) {
|
||||
spentClaims.erase(itSpent);
|
||||
return CClaimScriptAddOp::updateClaim(trieCache, name, claimId);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
spentClaimsType& spentClaims;
|
||||
};
|
||||
|
||||
CAddSpendClaim addClaim(spentClaims, point, nValue, nHeight);
|
||||
return ProcessClaim(addClaim, trieCache, scriptPubKey);
|
||||
ProcessClaim(addClaim, trieCache, txout.scriptPubKey);
|
||||
}
|
||||
}
|
|
@ -225,26 +225,21 @@ typedef std::pair<std::string, uint160> spentClaimType;
|
|||
|
||||
typedef std::vector<spentClaimType> spentClaimsType;
|
||||
|
||||
struct CUpdateCacheCallbacks
|
||||
{
|
||||
std::function<CScript(const COutPoint& point)> findScriptKey;
|
||||
std::function<void(int, int)> claimUndoHeights;
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to spend claim from tie, keeping the successful list on
|
||||
* @param[in] tx transaction inputs/outputs
|
||||
* @param[in] trieCache trie to operate on
|
||||
* @param[in] scriptPubKey claim script to be decoded
|
||||
* @param[in] view coins cache
|
||||
* @param[in] point pair of transaction hash and its index
|
||||
* @param[in] nHeight entry height of the claim
|
||||
* @param[out] nValidHeight valid height of the claim
|
||||
* @param[out] spentClaims inserts successfully spent claim
|
||||
* @param[out] fallback optional callbacks
|
||||
*/
|
||||
bool SpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, int nHeight, int& nValidHeight, spentClaimsType& spentClaims);
|
||||
|
||||
/**
|
||||
* Function to add / update (that present in spent list) claim in trie
|
||||
* @param[in] trieCache trie to operate on
|
||||
* @param[in] scriptPubKey claim script to be decoded
|
||||
* @param[in] point pair of transaction hash and its index
|
||||
* @param[in] nValue ` value of the claim
|
||||
* @param[in] nHeight entry height of the claim
|
||||
* @param[out] spentClaims erases successfully added claim
|
||||
*/
|
||||
bool AddSpendClaim(CClaimTrieCache& trieCache, const CScript& scriptPubKey, const COutPoint& point, CAmount nValue, int nHeight, spentClaimsType& spentClaims);
|
||||
void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoinsViewCache& view, int nHeight, const CUpdateCacheCallbacks& callbacks = {});
|
||||
|
||||
#endif // CLAIMSCRIPTOP_H
|
||||
|
|
|
@ -92,7 +92,6 @@ void CClaimTrieData::reorderClaims(const supportEntryType& supports)
|
|||
CClaimTrie::CClaimTrie(bool fMemory, bool fWipe, int proportionalDelayFactor)
|
||||
{
|
||||
nProportionalDelayFactor = proportionalDelayFactor;
|
||||
nExpirationTime = Params().GetConsensus().nOriginalClaimExpirationTime;
|
||||
db.reset(new CDBWrapper(GetDataDir() / "claimtrie", 100 * 1024 * 1024, fMemory, fWipe, false));
|
||||
}
|
||||
|
||||
|
@ -469,9 +468,7 @@ bool CClaimTrieCacheBase::ReadFromDisk(const CBlockIndex* tip)
|
|||
{
|
||||
LogPrintf("Loading the claim trie from disk...\n");
|
||||
|
||||
nNextHeight = tip ? tip->nHeight + 1 : 0;
|
||||
base->nNextHeight = nNextHeight;
|
||||
base->nExpirationTime = Params().GetConsensus().GetExpirationTime(nNextHeight - 1); // -1 okay
|
||||
base->nNextHeight = nNextHeight = tip ? tip->nHeight + 1 : 0;
|
||||
|
||||
clear();
|
||||
base->clear();
|
||||
|
@ -532,14 +529,9 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base, bool fRequireTakeover
|
|||
nNextHeight = base->nNextHeight;
|
||||
}
|
||||
|
||||
void CClaimTrieCacheBase::setExpirationTime(int time)
|
||||
int CClaimTrieCacheBase::expirationTime() const
|
||||
{
|
||||
base->nExpirationTime = time;
|
||||
}
|
||||
|
||||
int CClaimTrieCacheBase::expirationTime()
|
||||
{
|
||||
return base->nExpirationTime;
|
||||
return Params().GetConsensus().nOriginalClaimExpirationTime;
|
||||
}
|
||||
|
||||
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(CClaimTrie::iterator& it)
|
||||
|
@ -726,7 +718,7 @@ bool CClaimTrieCacheBase::undoSpendClaim(const std::string& name, const COutPoin
|
|||
CClaimValue claim(outPoint, claimId, nAmount, nHeight, nValidAtHeight);
|
||||
if (nValidAtHeight < nNextHeight) {
|
||||
CNameOutPointType entry(adjustNameForValidHeight(name, nValidAtHeight), claim.outPoint);
|
||||
addToExpirationQueue(claim.nHeight + base->nExpirationTime, entry);
|
||||
addToExpirationQueue(claim.nHeight + expirationTime(), entry);
|
||||
CClaimIndexElement element = {name, claim};
|
||||
claimsToAdd.push_back(element);
|
||||
return insertClaimIntoTrie(name, claim, false);
|
||||
|
@ -745,7 +737,7 @@ bool CClaimTrieCacheBase::addClaimToQueues(const std::string& name, const CClaim
|
|||
itQueueRow->second.push_back(entry);
|
||||
itQueueNameRow->second.emplace_back(claim.outPoint, claim.nValidAtHeight);
|
||||
CNameOutPointType expireEntry(name, claim.outPoint);
|
||||
addToExpirationQueue(claim.nHeight + base->nExpirationTime, expireEntry);
|
||||
addToExpirationQueue(claim.nHeight + expirationTime(), expireEntry);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -798,7 +790,7 @@ bool CClaimTrieCacheBase::removeClaim(const std::string& name, const COutPoint&
|
|||
std::string adjusted = adjustNameForValidHeight(name, nValidAtHeight);
|
||||
|
||||
if (removeClaimFromQueue(adjusted, outPoint, claim) || removeClaimFromTrie(name, outPoint, claim, fCheckTakeover)) {
|
||||
int expirationHeight = claim.nHeight + base->nExpirationTime;
|
||||
int expirationHeight = claim.nHeight + expirationTime();
|
||||
removeFromExpirationQueue(adjusted, outPoint, expirationHeight);
|
||||
claimsToDelete.insert(claim);
|
||||
nValidAtHeight = claim.nValidAtHeight;
|
||||
|
@ -880,7 +872,7 @@ bool CClaimTrieCacheBase::addSupportToQueues(const std::string& name, const CSup
|
|||
itQueueRow->second.push_back(entry);
|
||||
itQueueNameRow->second.emplace_back(support.outPoint, support.nValidAtHeight);
|
||||
CNameOutPointType expireEntry(name, support.outPoint);
|
||||
addSupportToExpirationQueue(support.nHeight + base->nExpirationTime, expireEntry);
|
||||
addSupportToExpirationQueue(support.nHeight + expirationTime(), expireEntry);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -929,7 +921,7 @@ bool CClaimTrieCacheBase::undoSpendSupport(const std::string& name, const COutPo
|
|||
CSupportValue support(outPoint, supportedClaimId, nAmount, nHeight, nValidAtHeight);
|
||||
if (nValidAtHeight < nNextHeight) {
|
||||
CNameOutPointType entry(adjustNameForValidHeight(name, nValidAtHeight), support.outPoint);
|
||||
addSupportToExpirationQueue(support.nHeight + base->nExpirationTime, entry);
|
||||
addSupportToExpirationQueue(support.nHeight + expirationTime(), entry);
|
||||
return insertSupportIntoMap(name, support, false);
|
||||
} else {
|
||||
return addSupportToQueues(name, support);
|
||||
|
@ -943,7 +935,7 @@ bool CClaimTrieCacheBase::removeSupport(const std::string& name, const COutPoint
|
|||
std::string adjusted = adjustNameForValidHeight(name, nValidAtHeight);
|
||||
|
||||
if (removeSupportFromQueue(adjusted, outPoint, support) || removeSupportFromMap(name, outPoint, support, fCheckTakeover)) {
|
||||
int expirationHeight = support.nHeight + base->nExpirationTime;
|
||||
int expirationHeight = support.nHeight + expirationTime();
|
||||
removeSupportFromExpirationQueue(adjusted, outPoint, expirationHeight);
|
||||
nValidAtHeight = support.nValidAtHeight;
|
||||
return true;
|
||||
|
@ -1244,7 +1236,7 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimQueueR
|
|||
if (!expireSupportUndo.empty()) {
|
||||
for (auto itSupportExpireUndo = expireSupportUndo.crbegin(); itSupportExpireUndo != expireSupportUndo.crend(); ++itSupportExpireUndo) {
|
||||
insertSupportIntoMap(itSupportExpireUndo->first, itSupportExpireUndo->second, false);
|
||||
if (nNextHeight == itSupportExpireUndo->second.nHeight + base->nExpirationTime) {
|
||||
if (nNextHeight == itSupportExpireUndo->second.nHeight + expirationTime()) {
|
||||
auto itSupportExpireRow = getSupportExpirationQueueCacheRow(nNextHeight, true);
|
||||
itSupportExpireRow->second.emplace_back(itSupportExpireUndo->first, itSupportExpireUndo->second.outPoint);
|
||||
}
|
||||
|
@ -1270,7 +1262,7 @@ bool CClaimTrieCacheBase::decrementBlock(insertUndoType& insertUndo, claimQueueR
|
|||
insertClaimIntoTrie(itExpireUndo->first, itExpireUndo->second, false);
|
||||
CClaimIndexElement element = {itExpireUndo->first, itExpireUndo->second};
|
||||
claimsToAdd.push_back(element);
|
||||
if (nNextHeight == itExpireUndo->second.nHeight + base->nExpirationTime) {
|
||||
if (nNextHeight == itExpireUndo->second.nHeight + expirationTime()) {
|
||||
auto itExpireRow = getExpirationQueueCacheRow(nNextHeight, true);
|
||||
itExpireRow->second.emplace_back(itExpireUndo->first, itExpireUndo->second.outPoint);
|
||||
}
|
||||
|
|
|
@ -302,7 +302,6 @@ struct CClaimsForNameType
|
|||
class CClaimTrie : public CPrefixTrie<std::string, CClaimTrieData>
|
||||
{
|
||||
int nNextHeight = 0;
|
||||
int nExpirationTime = 0;
|
||||
int nProportionalDelayFactor = 0;
|
||||
std::unique_ptr<CDBWrapper> db;
|
||||
|
||||
|
@ -434,6 +433,8 @@ public:
|
|||
virtual bool getProofForName(const std::string& name, CClaimTrieProof& proof);
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
|
||||
virtual int expirationTime() const;
|
||||
|
||||
bool finalizeDecrement(std::vector<std::pair<std::string, int>>& takeoverHeightUndo);
|
||||
|
||||
virtual CClaimsForNameType getClaimsForName(const std::string& name) const;
|
||||
|
@ -441,9 +442,6 @@ public:
|
|||
CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
|
||||
CAmount getEffectiveAmountForClaim(const CClaimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports = nullptr) const;
|
||||
|
||||
void setExpirationTime(int time);
|
||||
int expirationTime();
|
||||
|
||||
CClaimTrie::const_iterator begin() const;
|
||||
CClaimTrie::const_iterator end() const;
|
||||
CClaimTrie::const_iterator find(const std::string& name) const;
|
||||
|
@ -539,16 +537,27 @@ private:
|
|||
class CClaimTrieCacheExpirationFork : public CClaimTrieCacheBase
|
||||
{
|
||||
public:
|
||||
explicit CClaimTrieCacheExpirationFork(CClaimTrie* base, bool fRequireTakeoverHeights = true)
|
||||
: CClaimTrieCacheBase(base, fRequireTakeoverHeights)
|
||||
{
|
||||
}
|
||||
explicit CClaimTrieCacheExpirationFork(CClaimTrie* base, bool fRequireTakeoverHeights = true);
|
||||
|
||||
bool forkForExpirationChange(bool increment);
|
||||
void setExpirationTime(int time);
|
||||
int expirationTime() const override;
|
||||
|
||||
// TODO: move the expiration fork code from main.cpp to overrides of increment/decrement block
|
||||
void expirationForkActive(int height, bool increment);
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int>>& takeoverHeightUndo) override;
|
||||
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo) override;
|
||||
|
||||
private:
|
||||
int nExpirationTime;
|
||||
bool forkForExpirationChange(bool increment);
|
||||
void removeAndAddSupportToExpirationQueue(expirationQueueRowType& row, int height, bool increment);
|
||||
void removeAndAddToExpirationQueue(expirationQueueRowType& row, int height, bool increment);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#include "claimtrie.h"
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <claimtrie.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
@ -7,6 +9,46 @@
|
|||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/scope_exit.hpp>
|
||||
|
||||
CClaimTrieCacheExpirationFork::CClaimTrieCacheExpirationFork(CClaimTrie* base, bool fRequireTakeoverHeights)
|
||||
: CClaimTrieCacheBase(base, fRequireTakeoverHeights)
|
||||
{
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
}
|
||||
|
||||
void CClaimTrieCacheExpirationFork::setExpirationTime(int time)
|
||||
{
|
||||
nExpirationTime = time;
|
||||
}
|
||||
|
||||
int CClaimTrieCacheExpirationFork::expirationTime() const
|
||||
{
|
||||
return nExpirationTime;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::incrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo, std::vector<std::pair<std::string, int>>& takeoverHeightUndo)
|
||||
{
|
||||
if (CClaimTrieCacheBase::incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo)) {
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::decrementBlock(insertUndoType& insertUndo, claimQueueRowType& expireUndo, insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo)
|
||||
{
|
||||
if (CClaimTrieCacheBase::decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo)) {
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CClaimTrieCacheExpirationFork::expirationForkActive(int nHeight, bool increment)
|
||||
{
|
||||
if (nHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||
forkForExpirationChange(increment);
|
||||
}
|
||||
|
||||
void CClaimTrieCacheExpirationFork::removeAndAddToExpirationQueue(expirationQueueRowType& row, int height, bool increment)
|
||||
{
|
||||
for (auto e = row.begin(); e != row.end(); ++e) {
|
||||
|
@ -150,7 +192,7 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(insert
|
|||
auto supports = getSupportsForName(it.key());
|
||||
for (auto& support : supports) {
|
||||
// if it's already going to expire just skip it
|
||||
if (support.nHeight + base->nExpirationTime <= nNextHeight)
|
||||
if (support.nHeight + expirationTime() <= nNextHeight)
|
||||
continue;
|
||||
|
||||
CSupportValue removed;
|
||||
|
@ -167,7 +209,7 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(insert
|
|||
continue;
|
||||
|
||||
for (auto& claim : it->claims) {
|
||||
if (claim.nHeight + base->nExpirationTime <= nNextHeight)
|
||||
if (claim.nHeight + expirationTime() <= nNextHeight)
|
||||
continue;
|
||||
|
||||
CClaimValue removed;
|
||||
|
|
|
@ -1765,9 +1765,6 @@ bool AppInitMain(InitInterfaces& interfaces)
|
|||
}
|
||||
LogPrintf("nBestHeight = %d\n", chain_active_height);
|
||||
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
CClaimTrieCache(pclaimTrie).setExpirationTime(consensusParams.GetExpirationTime(chain_active_height));
|
||||
|
||||
if (gArgs.GetBoolArg("-listenonion", DEFAULT_LISTEN_ONION))
|
||||
StartTorControl();
|
||||
|
||||
|
|
|
@ -43,6 +43,35 @@ int64_t UpdateTime(CBlockHeader* pblock, const Consensus::Params& consensusParam
|
|||
return nNewTime - nOldTime;
|
||||
}
|
||||
|
||||
void blockToCache(const CBlock* pblock, CClaimTrieCache& trieCache, int nHeight)
|
||||
{
|
||||
insertUndoType dummyInsertUndo;
|
||||
claimQueueRowType dummyExpireUndo;
|
||||
insertUndoType dummyInsertSupportUndo;
|
||||
supportQueueRowType dummyExpireSupportUndo;
|
||||
std::vector<std::pair<std::string, int> > dummyTakeoverHeightUndo;
|
||||
|
||||
CUpdateCacheCallbacks callbacks = {
|
||||
.findScriptKey = [&pblock](const COutPoint& point) {
|
||||
for (auto& tx : pblock->vtx)
|
||||
if (tx->GetHash() == point.hash && point.n < tx->vout.size())
|
||||
return tx->vout[point.n].scriptPubKey;
|
||||
return CScript{};
|
||||
},
|
||||
.claimUndoHeights = {}
|
||||
};
|
||||
|
||||
trieCache.expirationForkActive(nHeight, true);
|
||||
|
||||
CCoinsViewCache view(pcoinsTip.get());
|
||||
|
||||
for (auto& tx : pblock->vtx)
|
||||
if (!tx->IsCoinBase())
|
||||
UpdateCache(*tx, trieCache, view, nHeight, callbacks);
|
||||
|
||||
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverHeightUndo);
|
||||
}
|
||||
|
||||
BlockAssembler::Options::Options() {
|
||||
blockMinFeeRate = CFeeRate(DEFAULT_BLOCK_MIN_TX_FEE);
|
||||
nBlockMaxWeight = DEFAULT_BLOCK_MAX_WEIGHT;
|
||||
|
@ -110,12 +139,6 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||
CBlockIndex* pindexPrev = ::ChainActive().Tip();
|
||||
assert(pindexPrev != nullptr);
|
||||
nHeight = pindexPrev->nHeight + 1;
|
||||
if (!pclaimTrie)
|
||||
{
|
||||
LogPrintf("CreateNewBlock(): pclaimTrie is invalid");
|
||||
return NULL;
|
||||
}
|
||||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
pblock->nVersion = ComputeBlockVersion(pindexPrev, chainparams.GetConsensus());
|
||||
// -regtest only: allow overriding block.nVersion with
|
||||
// -blockversion=N to test forking scenarios
|
||||
|
@ -142,7 +165,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||
|
||||
int nPackagesSelected = 0;
|
||||
int nDescendantsUpdated = 0;
|
||||
addPackageTxs(nPackagesSelected, nDescendantsUpdated, trieCache);
|
||||
addPackageTxs(nPackagesSelected, nDescendantsUpdated);
|
||||
|
||||
int64_t nTime1 = GetTimeMicros();
|
||||
|
||||
|
@ -170,20 +193,14 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
|
|||
pblock->nNonce = 0;
|
||||
pblocktemplate->vTxSigOpsCost[0] = WITNESS_SCALE_FACTOR * GetLegacySigOpCount(*pblock->vtx[0]);
|
||||
|
||||
insertUndoType dummyInsertUndo;
|
||||
claimQueueRowType dummyExpireUndo;
|
||||
insertUndoType dummyInsertSupportUndo;
|
||||
supportQueueRowType dummyExpireSupportUndo;
|
||||
std::vector<std::pair<std::string, int> > dummyTakeoverHeightUndo;
|
||||
|
||||
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverHeightUndo);
|
||||
|
||||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
blockToCache(pblock, trieCache, nHeight);
|
||||
pblock->hashClaimTrie = trieCache.getMerkleHash();
|
||||
|
||||
CValidationState state;
|
||||
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
|
||||
// if (trieCache.checkConsistency()) // TODO: bring back after prefixtrie merge
|
||||
// trieCache.dumpToLog(trieCache.begin());
|
||||
if (!trieCache.empty() && trieCache.checkConsistency())
|
||||
trieCache.dumpToLog(trieCache.begin());
|
||||
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
|
||||
}
|
||||
int64_t nTime2 = GetTimeMicros();
|
||||
|
@ -303,42 +320,6 @@ void BlockAssembler::SortForBlock(const CTxMemPool::setEntries& package, std::ve
|
|||
std::sort(sortedEntries.begin(), sortedEntries.end(), CompareTxIterByAncestorCount());
|
||||
}
|
||||
|
||||
void iterToTrieCache(CTxMemPool::txiter iter, CClaimTrieCache& trieCache, const CTxMemPool::setEntries& entries, int nHeight)
|
||||
{
|
||||
spentClaimsType spentClaims;
|
||||
auto& tx = iter->GetTx();
|
||||
|
||||
CCoinsViewCache view(pcoinsTip.get());
|
||||
for (const CTxIn& txin: tx.vin) {
|
||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
||||
CScript scriptPubKey;
|
||||
int scriptHeight = nHeight;
|
||||
if (coin.out.IsNull()) {
|
||||
for (auto entry : entries) {
|
||||
auto& e = entry->GetTx();
|
||||
if (e.GetHash() != txin.prevout.hash || txin.prevout.n >= e.vout.size())
|
||||
continue;
|
||||
scriptPubKey = e.vout[txin.prevout.n].scriptPubKey;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
scriptPubKey = coin.out.scriptPubKey;
|
||||
scriptHeight = coin.nHeight;
|
||||
}
|
||||
|
||||
if (!scriptPubKey.empty()) {
|
||||
int throwaway;
|
||||
SpendClaim(trieCache, scriptPubKey, COutPoint(txin.prevout.hash, txin.prevout.n), scriptHeight, throwaway, spentClaims);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < tx.vout.size(); ++i) {
|
||||
const CTxOut& txout = tx.vout[i];
|
||||
if (!txout.scriptPubKey.empty())
|
||||
AddSpendClaim(trieCache, txout.scriptPubKey, COutPoint(tx.GetHash(), i), txout.nValue, nHeight, spentClaims);
|
||||
}
|
||||
}
|
||||
|
||||
// This transaction selection algorithm orders the mempool based
|
||||
// on feerate of a transaction including all unconfirmed ancestors.
|
||||
// Since we don't remove transactions from the mempool as we select them
|
||||
|
@ -349,7 +330,7 @@ void iterToTrieCache(CTxMemPool::txiter iter, CClaimTrieCache& trieCache, const
|
|||
// Each time through the loop, we compare the best transaction in
|
||||
// mapModifiedTxs with the next transaction in the mempool to decide what
|
||||
// transaction package to work on next.
|
||||
void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, CClaimTrieCache& trieCache)
|
||||
void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated)
|
||||
{
|
||||
// mapModifiedTx will store sorted packages after they are modified
|
||||
// because some of their txs are already in the block
|
||||
|
@ -466,7 +447,6 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda
|
|||
SortForBlock(ancestors, sortedEntries);
|
||||
|
||||
for (size_t i=0; i<sortedEntries.size(); ++i) {
|
||||
iterToTrieCache(sortedEntries[i], trieCache, inBlock, nHeight);
|
||||
AddToBlock(sortedEntries[i]);
|
||||
// Erase from the modified set, if present
|
||||
mapModifiedTx.erase(sortedEntries[i]);
|
||||
|
|
|
@ -175,7 +175,7 @@ private:
|
|||
/** Add transactions based on feerate including unconfirmed ancestors
|
||||
* Increments nPackagesSelected / nDescendantsUpdated with corresponding
|
||||
* statistics from the package selection (for logging statistics). */
|
||||
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated, CClaimTrieCache& trieCache) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
|
||||
void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated) EXCLUSIVE_LOCKS_REQUIRED(mempool.cs);
|
||||
|
||||
// helper functions for addPackageTxs()
|
||||
/** Remove confirmed (inBlock) entries from given set */
|
||||
|
|
|
@ -72,7 +72,7 @@ static BlockAssembler AssemblerForTest()
|
|||
}
|
||||
|
||||
// Test Fixtures
|
||||
struct ClaimTrieChainFixture: public CClaimTrieCacheBase
|
||||
struct ClaimTrieChainFixture: public CClaimTrieCacheExpirationFork
|
||||
{
|
||||
std::vector<CTransaction> coinbase_txs;
|
||||
std::vector<int> marks;
|
||||
|
@ -86,9 +86,9 @@ struct ClaimTrieChainFixture: public CClaimTrieCacheBase
|
|||
int64_t originalExpiration;
|
||||
int64_t extendedExpiration;
|
||||
|
||||
using CClaimTrieCacheBase::getSupportsForName;
|
||||
using CClaimTrieCacheExpirationFork::getSupportsForName;
|
||||
|
||||
ClaimTrieChainFixture(): CClaimTrieCacheBase(pclaimTrie),
|
||||
ClaimTrieChainFixture(): CClaimTrieCacheExpirationFork(pclaimTrie),
|
||||
unique_block_counter(0), normalization_original(-1), expirationForkHeight(-1)
|
||||
{
|
||||
fRequireStandard = false;
|
||||
|
@ -114,14 +114,12 @@ struct ClaimTrieChainFixture: public CClaimTrieCacheBase
|
|||
DecrementBlocks(chainActive.Height());
|
||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
||||
if (normalization_original >= 0)
|
||||
{
|
||||
consensus.nNormalizedNameForkHeight = normalization_original;
|
||||
}
|
||||
|
||||
if (expirationForkHeight >= 0) {
|
||||
consensus.nExtendedClaimExpirationForkHeight = expirationForkHeight;
|
||||
consensus.nExtendedClaimExpirationTime = extendedExpiration;
|
||||
consensus.nOriginalClaimExpirationTime = originalExpiration;
|
||||
base->nExpirationTime = originalExpiration;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,7 +134,7 @@ struct ClaimTrieChainFixture: public CClaimTrieCacheBase
|
|||
consensus.nExtendedClaimExpirationForkHeight = target;
|
||||
consensus.nExtendedClaimExpirationTime = postForkExpirationTime;
|
||||
consensus.nOriginalClaimExpirationTime = preForkExpirationTime;
|
||||
base->nExpirationTime = targetMinusCurrent >= 0 ? preForkExpirationTime : postForkExpirationTime;
|
||||
setExpirationTime(targetMinusCurrent >= 0 ? preForkExpirationTime : postForkExpirationTime);
|
||||
}
|
||||
|
||||
void setNormalizationForkHeight(int targetMinusCurrent) {
|
||||
|
@ -292,6 +290,7 @@ struct ClaimTrieChainFixture: public CClaimTrieCacheBase
|
|||
num_txs_for_next_block = 0;
|
||||
nNextHeight = chainActive.Height() + 1;
|
||||
}
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight - 1));
|
||||
}
|
||||
|
||||
//disconnect i blocks from tip
|
||||
|
@ -306,9 +305,10 @@ struct ClaimTrieChainFixture: public CClaimTrieCacheBase
|
|||
}
|
||||
BOOST_CHECK_EQUAL(state.IsValid(), true);
|
||||
BOOST_CHECK_EQUAL(ActivateBestChain(state, Params()), true);
|
||||
nNextHeight = chainActive.Height() + 1;
|
||||
mempool.clear();
|
||||
num_txs_for_next_block = 0;
|
||||
nNextHeight = chainActive.Height() + 1;
|
||||
setExpirationTime(Params().GetConsensus().GetExpirationTime(nNextHeight - 1));
|
||||
}
|
||||
|
||||
// decrement back to last mark
|
||||
|
@ -1157,7 +1157,7 @@ BOOST_AUTO_TEST_CASE(hardfork_claim_test)
|
|||
// make sure decrementing to before the fork height will apppropriately set back the
|
||||
// expiration time to the original expiraiton time
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK_NE(fixture.expirationTime(), 6);
|
||||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK_EQUAL(fixture.expirationTime(), 6);
|
||||
|
||||
|
@ -1723,7 +1723,7 @@ BOOST_AUTO_TEST_CASE(normalization_does_not_kill_sort_order)
|
|||
BOOST_AUTO_TEST_CASE(normalization_does_not_kill_expirations)
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setExpirationTime(3);
|
||||
fixture.setExpirationForkHeight(800, 3, 800);
|
||||
fixture.setNormalizationForkHeight(4);
|
||||
// need to see that claims expiring on the frame when we normalize aren't kept
|
||||
// need to see that supports expiring on the frame when we normalize aren't kept
|
||||
|
|
|
@ -1840,12 +1840,7 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
|
|||
assert(merkleHash == pindex->pprev->hashClaimTrie);
|
||||
}
|
||||
|
||||
if (pindex->nHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||
{
|
||||
LogPrintf("Decremented past the extended claim expiration hard fork height\n");
|
||||
trieCache.setExpirationTime(Params().GetConsensus().GetExpirationTime(pindex->nHeight-1));
|
||||
trieCache.forkForExpirationChange(false);
|
||||
}
|
||||
trieCache.expirationForkActive(pindex->nHeight, false);
|
||||
|
||||
return fClean ? DISCONNECT_OK : DISCONNECT_UNCLEAN;
|
||||
}
|
||||
|
@ -2196,13 +2191,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
// Get the script flags for this block
|
||||
unsigned int flags = GetBlockScriptFlags(pindex, chainparams.GetConsensus());
|
||||
|
||||
// v 13 LBRYcrd hard fork to extend expiration time
|
||||
if (pindex->nHeight == Params().GetConsensus().nExtendedClaimExpirationForkHeight)
|
||||
{
|
||||
LogPrintf("Incremented past the extended claim expiration hard fork height\n");
|
||||
trieCache.setExpirationTime(chainparams.GetConsensus().GetExpirationTime(pindex->nHeight));
|
||||
trieCache.forkForExpirationChange(true);
|
||||
}
|
||||
trieCache.expirationForkActive(pindex->nHeight, true);
|
||||
|
||||
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1;
|
||||
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
|
||||
|
@ -2291,35 +2280,13 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
tx.GetHash().ToString(), FormatStateMessage(state));
|
||||
}
|
||||
control.Add(vChecks);
|
||||
|
||||
// To handle claim updates, stick all claims found in the inputs into a map of
|
||||
// name: (txhash, nOut). When running through the outputs, if any claim's
|
||||
// name is found in the map, send the name's txhash and nOut to the trie cache,
|
||||
// and then remove the name: (txhash, nOut) mapping from the map.
|
||||
// If there are two or more claims in the inputs with the same name, only
|
||||
// use the first.
|
||||
|
||||
spentClaimsType spentClaims;
|
||||
|
||||
for (unsigned int j = 0; j < tx.vin.size(); j++)
|
||||
{
|
||||
const CTxIn& txin = tx.vin[j];
|
||||
const Coin& coin = view.AccessCoin(txin.prevout);
|
||||
|
||||
if (coin.out.scriptPubKey.empty())
|
||||
continue;
|
||||
|
||||
int nValidAtHeight;
|
||||
if (SpendClaim(trieCache, coin.out.scriptPubKey, COutPoint(txin.prevout.hash, txin.prevout.n), coin.nHeight, nValidAtHeight, spentClaims))
|
||||
mClaimUndoHeights[j] = nValidAtHeight;
|
||||
}
|
||||
|
||||
for (unsigned int j = 0; j < tx.vout.size(); j++) {
|
||||
const CTxOut& txout = tx.vout[j];
|
||||
|
||||
if (!txout.scriptPubKey.empty())
|
||||
AddSpendClaim(trieCache, txout.scriptPubKey, COutPoint(tx.GetHash(), j), txout.nValue, pindex->nHeight, spentClaims);
|
||||
CUpdateCacheCallbacks callbacks = {
|
||||
.findScriptKey = {},
|
||||
.claimUndoHeights = [&mClaimUndoHeights](int index, int nValidAtHeight) {
|
||||
mClaimUndoHeights.emplace(index, nValidAtHeight);
|
||||
}
|
||||
};
|
||||
UpdateCache(tx, trieCache, view, pindex->nHeight, callbacks);
|
||||
}
|
||||
|
||||
CTxUndo undoDummy;
|
||||
|
@ -2358,7 +2325,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
|
|||
|
||||
if (trieCache.getMerkleHash() != block.hashClaimTrie)
|
||||
{
|
||||
if (trieCache.checkConsistency())
|
||||
if (!trieCache.empty() && trieCache.checkConsistency())
|
||||
trieCache.dumpToLog(trieCache.begin());
|
||||
return state.DoS(100, error("ConnectBlock() : the merkle root of the claim trie does not match "
|
||||
"(actual=%s vs block=%s on height=%d)", trieCache.getMerkleHash().GetHex(),
|
||||
|
|
Loading…
Reference in a new issue