refactor: pcoinsTip -> CChainState::CoinsTip()
This aliasing makes subsequent commits easier to review; eventually CoinsTip() will return the CCoinsViewCache managed by CChainState.
This commit is contained in:
parent
e5fdda68c6
commit
fae6ab6aed
13 changed files with 70 additions and 58 deletions
|
@ -232,7 +232,7 @@ public:
|
|||
bool getUnspentOutput(const COutPoint& output, Coin& coin) override
|
||||
{
|
||||
LOCK(::cs_main);
|
||||
return ::pcoinsTip->GetCoin(output, coin);
|
||||
return ::ChainstateActive().CoinsTip().GetCoin(output, coin);
|
||||
}
|
||||
std::string getWalletDir() override
|
||||
{
|
||||
|
|
|
@ -1291,11 +1291,12 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||
LOCK(g_cs_orphans);
|
||||
if (mapOrphanTransactions.count(inv.hash)) return true;
|
||||
}
|
||||
const CCoinsViewCache& coins_cache = ::ChainstateActive().CoinsTip();
|
||||
|
||||
return recentRejects->contains(inv.hash) ||
|
||||
mempool.exists(inv.hash) ||
|
||||
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
|
||||
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1));
|
||||
coins_cache.HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
|
||||
coins_cache.HaveCoinInCache(COutPoint(inv.hash, 1));
|
||||
}
|
||||
case MSG_BLOCK:
|
||||
case MSG_WITNESS_BLOCK:
|
||||
|
@ -1844,7 +1845,7 @@ void static ProcessOrphanTx(CConnman* connman, std::set<uint256>& orphan_work_se
|
|||
EraseOrphanTx(orphanHash);
|
||||
done = true;
|
||||
}
|
||||
mempool.check(pcoinsTip.get());
|
||||
mempool.check(&::ChainstateActive().CoinsTip());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2497,7 +2498,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
|
|||
|
||||
if (!AlreadyHave(inv) &&
|
||||
AcceptToMemoryPool(mempool, state, ptx, &fMissingInputs, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
|
||||
mempool.check(pcoinsTip.get());
|
||||
mempool.check(&::ChainstateActive().CoinsTip());
|
||||
RelayTransaction(tx.GetHash(), *connman);
|
||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(inv.hash, i));
|
||||
|
|
|
@ -10,8 +10,7 @@
|
|||
void FindCoins(std::map<COutPoint, Coin>& coins)
|
||||
{
|
||||
LOCK2(cs_main, ::mempool.cs);
|
||||
assert(pcoinsTip);
|
||||
CCoinsViewCache& chain_view = *::pcoinsTip;
|
||||
CCoinsViewCache& chain_view = ::ChainstateActive().CoinsTip();
|
||||
CCoinsViewMemPool mempool_view(&chain_view, ::mempool);
|
||||
for (auto& coin : coins) {
|
||||
if (!mempool_view.GetCoin(coin.first, coin.second)) {
|
||||
|
|
|
@ -25,7 +25,7 @@ TransactionError BroadcastTransaction(const CTransactionRef tx, std::string& err
|
|||
LOCK(cs_main);
|
||||
// If the transaction is already confirmed in the chain, don't do anything
|
||||
// and return early.
|
||||
CCoinsViewCache &view = *pcoinsTip;
|
||||
CCoinsViewCache &view = ::ChainstateActive().CoinsTip();
|
||||
for (size_t o = 0; o < tx->vout.size(); o++) {
|
||||
const Coin& existingCoin = view.AccessCoin(COutPoint(hashTx, o));
|
||||
// IsSpent doesnt mean the coin is spent, it means the output doesnt' exist.
|
||||
|
|
|
@ -503,12 +503,12 @@ static bool rest_getutxos(HTTPRequest* req, const std::string& strURIPart)
|
|||
if (fCheckMemPool) {
|
||||
// use db+mempool as cache backend in case user likes to query mempool
|
||||
LOCK2(cs_main, mempool.cs);
|
||||
CCoinsViewCache& viewChain = *pcoinsTip;
|
||||
CCoinsViewCache& viewChain = ::ChainstateActive().CoinsTip();
|
||||
CCoinsViewMemPool viewMempool(&viewChain, mempool);
|
||||
process_utxos(viewMempool, mempool);
|
||||
} else {
|
||||
LOCK(cs_main); // no need to lock mempool!
|
||||
process_utxos(*pcoinsTip, CTxMemPool());
|
||||
process_utxos(::ChainstateActive().CoinsTip(), CTxMemPool());
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < hits.size(); ++i) {
|
||||
|
|
|
@ -1126,19 +1126,21 @@ UniValue gettxout(const JSONRPCRequest& request)
|
|||
fMempool = request.params[2].get_bool();
|
||||
|
||||
Coin coin;
|
||||
CCoinsViewCache* coins_view = &::ChainstateActive().CoinsTip();
|
||||
|
||||
if (fMempool) {
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewMemPool view(pcoinsTip.get(), mempool);
|
||||
CCoinsViewMemPool view(coins_view, mempool);
|
||||
if (!view.GetCoin(out, coin) || mempool.isSpent(out)) {
|
||||
return NullUniValue;
|
||||
}
|
||||
} else {
|
||||
if (!pcoinsTip->GetCoin(out, coin)) {
|
||||
if (!coins_view->GetCoin(out, coin)) {
|
||||
return NullUniValue;
|
||||
}
|
||||
}
|
||||
|
||||
const CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock());
|
||||
const CBlockIndex* pindex = LookupBlockIndex(coins_view->GetBestBlock());
|
||||
ret.pushKV("bestblock", pindex->GetBlockHash().GetHex());
|
||||
if (coin.nHeight == MEMPOOL_HEIGHT) {
|
||||
ret.pushKV("confirmations", 0);
|
||||
|
@ -1180,7 +1182,8 @@ static UniValue verifychain(const JSONRPCRequest& request)
|
|||
if (!request.params[1].isNull())
|
||||
nCheckDepth = request.params[1].get_int();
|
||||
|
||||
return CVerifyDB().VerifyDB(Params(), pcoinsTip.get(), nCheckLevel, nCheckDepth);
|
||||
return CVerifyDB().VerifyDB(
|
||||
Params(), &::ChainstateActive().CoinsTip(), nCheckLevel, nCheckDepth);
|
||||
}
|
||||
|
||||
/** Implementation of IsSuperMajority with better feedback */
|
||||
|
|
|
@ -259,7 +259,7 @@ static UniValue gettxoutproof(const JSONRPCRequest& request)
|
|||
|
||||
// Loop through txids and try to find which block they're in. Exit loop once a block is found.
|
||||
for (const auto& tx : setTxids) {
|
||||
const Coin& coin = AccessByTxid(*pcoinsTip, tx);
|
||||
const Coin& coin = AccessByTxid(::ChainstateActive().CoinsTip(), tx);
|
||||
if (!coin.IsSpent()) {
|
||||
pblockindex = ::ChainActive()[coin.nHeight];
|
||||
break;
|
||||
|
@ -636,7 +636,7 @@ static UniValue combinerawtransaction(const JSONRPCRequest& request)
|
|||
{
|
||||
LOCK(cs_main);
|
||||
LOCK(mempool.cs);
|
||||
CCoinsViewCache &viewChain = *pcoinsTip;
|
||||
CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip();
|
||||
CCoinsViewMemPool viewMempool(&viewChain, mempool);
|
||||
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
|
||||
|
||||
|
@ -1505,7 +1505,7 @@ UniValue utxoupdatepsbt(const JSONRPCRequest& request)
|
|||
CCoinsViewCache view(&viewDummy);
|
||||
{
|
||||
LOCK2(cs_main, mempool.cs);
|
||||
CCoinsViewCache &viewChain = *pcoinsTip;
|
||||
CCoinsViewCache &viewChain = ::ChainstateActive().CoinsTip();
|
||||
CCoinsViewMemPool viewMempool(&viewChain, mempool);
|
||||
view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
|
||||
|
||||
|
|
|
@ -372,7 +372,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||
CBlockIndex* prev = ::ChainActive().Tip();
|
||||
CBlockIndex* next = new CBlockIndex();
|
||||
next->phashBlock = new uint256(InsecureRand256());
|
||||
pcoinsTip->SetBestBlock(next->GetBlockHash());
|
||||
::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash());
|
||||
next->pprev = prev;
|
||||
next->nHeight = prev->nHeight + 1;
|
||||
next->BuildSkip();
|
||||
|
@ -384,7 +384,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||
CBlockIndex* prev = ::ChainActive().Tip();
|
||||
CBlockIndex* next = new CBlockIndex();
|
||||
next->phashBlock = new uint256(InsecureRand256());
|
||||
pcoinsTip->SetBestBlock(next->GetBlockHash());
|
||||
::ChainstateActive().CoinsTip().SetBestBlock(next->GetBlockHash());
|
||||
next->pprev = prev;
|
||||
next->nHeight = prev->nHeight + 1;
|
||||
next->BuildSkip();
|
||||
|
@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity)
|
|||
while (::ChainActive().Tip()->nHeight > nHeight) {
|
||||
CBlockIndex* del = ::ChainActive().Tip();
|
||||
::ChainActive().SetTip(del->pprev);
|
||||
pcoinsTip->SetBestBlock(del->pprev->GetBlockHash());
|
||||
::ChainstateActive().CoinsTip().SetBestBlock(del->pprev->GetBlockHash());
|
||||
delete del->phashBlock;
|
||||
delete del;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ BOOST_FIXTURE_TEST_CASE(tx_mempool_block_doublespend, TestChain100Setup)
|
|||
BOOST_CHECK_EQUAL(mempool.size(), 0U);
|
||||
}
|
||||
|
||||
// Run CheckInputs (using pcoinsTip) on the given transaction, for all script
|
||||
// Run CheckInputs (using CoinsTip()) on the given transaction, for all script
|
||||
// flags. Test that CheckInputs passes for all flags that don't overlap with
|
||||
// the failing_flags argument, but otherwise fails.
|
||||
// CHECKLOCKTIMEVERIFY and CHECKSEQUENCEVERIFY (and future NOP codes that may
|
||||
|
@ -125,7 +125,7 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
|
|||
// WITNESS requires P2SH
|
||||
test_flags |= SCRIPT_VERIFY_P2SH;
|
||||
}
|
||||
bool ret = CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, nullptr);
|
||||
bool ret = CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, nullptr);
|
||||
// CheckInputs should succeed iff test_flags doesn't intersect with
|
||||
// failing_flags
|
||||
bool expected_return_value = !(test_flags & failing_flags);
|
||||
|
@ -135,13 +135,13 @@ static void ValidateCheckInputsForAllFlags(const CTransaction &tx, uint32_t fail
|
|||
if (ret && add_to_cache) {
|
||||
// Check that we get a cache hit if the tx was valid
|
||||
std::vector<CScriptCheck> scriptchecks;
|
||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
||||
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
||||
BOOST_CHECK(scriptchecks.empty());
|
||||
} else {
|
||||
// Check that we get script executions to check, if the transaction
|
||||
// was invalid, or we didn't add to cache.
|
||||
std::vector<CScriptCheck> scriptchecks;
|
||||
BOOST_CHECK(CheckInputs(tx, state, pcoinsTip.get(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
||||
BOOST_CHECK(CheckInputs(tx, state, &::ChainstateActive().CoinsTip(), true, test_flags, true, add_to_cache, txdata, &scriptchecks));
|
||||
BOOST_CHECK_EQUAL(scriptchecks.size(), tx.vin.size());
|
||||
}
|
||||
}
|
||||
|
@ -204,13 +204,13 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||
CValidationState state;
|
||||
PrecomputedTransactionData ptd_spend_tx(spend_tx);
|
||||
|
||||
BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
|
||||
BOOST_CHECK(!CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, nullptr));
|
||||
|
||||
// If we call again asking for scriptchecks (as happens in
|
||||
// ConnectBlock), we should add a script check object for this -- we're
|
||||
// not caching invalidity (if that changes, delete this test case).
|
||||
std::vector<CScriptCheck> scriptchecks;
|
||||
BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
|
||||
BOOST_CHECK(CheckInputs(CTransaction(spend_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_DERSIG, true, true, ptd_spend_tx, &scriptchecks));
|
||||
BOOST_CHECK_EQUAL(scriptchecks.size(), 1U);
|
||||
|
||||
// Test that CheckInputs returns true iff DERSIG-enforcing flags are
|
||||
|
@ -227,7 +227,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||
block = CreateAndProcessBlock({spend_tx}, p2pk_scriptPubKey);
|
||||
LOCK(cs_main);
|
||||
BOOST_CHECK(::ChainActive().Tip()->GetBlockHash() == block.GetHash());
|
||||
BOOST_CHECK(pcoinsTip->GetBestBlock() == block.GetHash());
|
||||
BOOST_CHECK(::ChainstateActive().CoinsTip().GetBestBlock() == block.GetHash());
|
||||
|
||||
// Test P2SH: construct a transaction that is valid without P2SH, and
|
||||
// then test validity with P2SH.
|
||||
|
@ -272,7 +272,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||
invalid_with_cltv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
|
||||
CValidationState state;
|
||||
PrecomputedTransactionData txdata(invalid_with_cltv_tx);
|
||||
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
|
||||
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_cltv_tx), state, ::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKLOCKTIMEVERIFY, true, true, txdata, nullptr));
|
||||
}
|
||||
|
||||
// TEST CHECKSEQUENCEVERIFY
|
||||
|
@ -300,7 +300,7 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||
invalid_with_csv_tx.vin[0].scriptSig = CScript() << vchSig << 100;
|
||||
CValidationState state;
|
||||
PrecomputedTransactionData txdata(invalid_with_csv_tx);
|
||||
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
|
||||
BOOST_CHECK(CheckInputs(CTransaction(invalid_with_csv_tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_CHECKSEQUENCEVERIFY, true, true, txdata, nullptr));
|
||||
}
|
||||
|
||||
// TODO: add tests for remaining script flags
|
||||
|
@ -362,12 +362,12 @@ BOOST_FIXTURE_TEST_CASE(checkinputs_test, TestChain100Setup)
|
|||
CValidationState state;
|
||||
PrecomputedTransactionData txdata(tx);
|
||||
// This transaction is now invalid under segwit, because of the second input.
|
||||
BOOST_CHECK(!CheckInputs(CTransaction(tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
|
||||
BOOST_CHECK(!CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, nullptr));
|
||||
|
||||
std::vector<CScriptCheck> scriptchecks;
|
||||
// Make sure this transaction was not cached (ie because the first
|
||||
// input was valid)
|
||||
BOOST_CHECK(CheckInputs(CTransaction(tx), state, pcoinsTip.get(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
|
||||
BOOST_CHECK(CheckInputs(CTransaction(tx), state, &::ChainstateActive().CoinsTip(), true, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS, true, true, txdata, &scriptchecks));
|
||||
// Should get 2 script checks back -- caching is on a whole-transaction basis.
|
||||
BOOST_CHECK_EQUAL(scriptchecks.size(), 2U);
|
||||
}
|
||||
|
|
|
@ -497,7 +497,7 @@ public:
|
|||
*
|
||||
* 1. Locking both `cs_main` and `mempool.cs` will give a view of mempool
|
||||
* that is consistent with current chain tip (`::ChainActive()` and
|
||||
* `pcoinsTip`) and is fully populated. Fully populated means that if the
|
||||
* `CoinsTip()`) and is fully populated. Fully populated means that if the
|
||||
* current active chain is missing transactions that were present in a
|
||||
* previously active chain, all the missing transactions will have been
|
||||
* re-added to the mempool and should be present if they meet size and
|
||||
|
|
|
@ -260,8 +260,8 @@ bool CheckSequenceLocks(const CTxMemPool& pool, const CTransaction& tx, int flag
|
|||
lockPair.second = lp->time;
|
||||
}
|
||||
else {
|
||||
// pcoinsTip contains the UTXO set for ::ChainActive().Tip()
|
||||
CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool);
|
||||
// CoinsTip() contains the UTXO set for ::ChainActive().Tip()
|
||||
CCoinsViewMemPool viewMemPool(&::ChainstateActive().CoinsTip(), pool);
|
||||
std::vector<int> prevheights;
|
||||
prevheights.resize(tx.vin.size());
|
||||
for (size_t txinIndex = 0; txinIndex < tx.vin.size(); txinIndex++) {
|
||||
|
@ -320,7 +320,7 @@ static void LimitMempoolSize(CTxMemPool& pool, size_t limit, unsigned long age)
|
|||
std::vector<COutPoint> vNoSpendsRemaining;
|
||||
pool.TrimToSize(limit, &vNoSpendsRemaining);
|
||||
for (const COutPoint& removed : vNoSpendsRemaining)
|
||||
pcoinsTip->Uncache(removed);
|
||||
::ChainstateActive().CoinsTip().Uncache(removed);
|
||||
}
|
||||
|
||||
static bool IsCurrentForFeeEstimation() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
||||
|
@ -382,7 +382,7 @@ static void UpdateMempoolForReorg(DisconnectedBlockTransactions& disconnectpool,
|
|||
mempool.UpdateTransactionsFromBlock(vHashUpdate);
|
||||
|
||||
// We also need to remove any now-immature transactions
|
||||
mempool.removeForReorg(pcoinsTip.get(), ::ChainActive().Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
|
||||
mempool.removeForReorg(&::ChainstateActive().CoinsTip(), ::ChainActive().Tip()->nHeight + 1, STANDARD_LOCKTIME_VERIFY_FLAGS);
|
||||
// Re-limit mempool size, in case we added any transactions
|
||||
LimitMempoolSize(mempool, gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY) * 60 * 60);
|
||||
}
|
||||
|
@ -414,7 +414,7 @@ static bool CheckInputsFromMempoolAndCache(const CTransaction& tx, CValidationSt
|
|||
assert(txFrom->vout.size() > txin.prevout.n);
|
||||
assert(txFrom->vout[txin.prevout.n] == coin.out);
|
||||
} else {
|
||||
const Coin& coinFromDisk = pcoinsTip->AccessCoin(txin.prevout);
|
||||
const Coin& coinFromDisk = ::ChainstateActive().CoinsTip().AccessCoin(txin.prevout);
|
||||
assert(!coinFromDisk.IsSpent());
|
||||
assert(coinFromDisk.out == coin.out);
|
||||
}
|
||||
|
@ -514,12 +514,13 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
|||
CCoinsViewCache view(&dummy);
|
||||
|
||||
LockPoints lp;
|
||||
CCoinsViewMemPool viewMemPool(pcoinsTip.get(), pool);
|
||||
CCoinsViewCache& coins_cache = ::ChainstateActive().CoinsTip();
|
||||
CCoinsViewMemPool viewMemPool(&coins_cache, pool);
|
||||
view.SetBackend(viewMemPool);
|
||||
|
||||
// do all inputs exist?
|
||||
for (const CTxIn& txin : tx.vin) {
|
||||
if (!pcoinsTip->HaveCoinInCache(txin.prevout)) {
|
||||
if (!coins_cache.HaveCoinInCache(txin.prevout)) {
|
||||
coins_to_uncache.push_back(txin.prevout);
|
||||
}
|
||||
|
||||
|
@ -530,7 +531,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool
|
|||
// Are inputs missing because we already have the tx?
|
||||
for (size_t out = 0; out < tx.vout.size(); out++) {
|
||||
// Optimistically just do efficient check of cache for outputs
|
||||
if (pcoinsTip->HaveCoinInCache(COutPoint(hash, out))) {
|
||||
if (coins_cache.HaveCoinInCache(COutPoint(hash, out))) {
|
||||
return state.Invalid(ValidationInvalidReason::TX_CONFLICT, false, REJECT_DUPLICATE, "txn-already-known");
|
||||
}
|
||||
}
|
||||
|
@ -860,7 +861,7 @@ static bool AcceptToMemoryPoolWithTime(const CChainParams& chainparams, CTxMemPo
|
|||
// (`CCoinsViewCache::cacheCoins`).
|
||||
|
||||
for (const COutPoint& hashTx : coins_to_uncache)
|
||||
pcoinsTip->Uncache(hashTx);
|
||||
::ChainstateActive().CoinsTip().Uncache(hashTx);
|
||||
}
|
||||
// After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
|
||||
CValidationState stateDummy;
|
||||
|
@ -2014,7 +2015,7 @@ bool CChainState::FlushStateToDisk(
|
|||
nLastFlush = nNow;
|
||||
}
|
||||
int64_t nMempoolSizeMax = gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000;
|
||||
int64_t cacheSize = pcoinsTip->DynamicMemoryUsage();
|
||||
int64_t cacheSize = CoinsTip().DynamicMemoryUsage();
|
||||
int64_t nTotalSpace = nCoinCacheUsage + std::max<int64_t>(nMempoolSizeMax - nMempoolUsage, 0);
|
||||
// The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing).
|
||||
bool fCacheLarge = mode == FlushStateMode::PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024);
|
||||
|
@ -2058,17 +2059,17 @@ bool CChainState::FlushStateToDisk(
|
|||
nLastWrite = nNow;
|
||||
}
|
||||
// Flush best chain related state. This can only be done if the blocks / block index write was also done.
|
||||
if (fDoFullFlush && !pcoinsTip->GetBestBlock().IsNull()) {
|
||||
if (fDoFullFlush && !CoinsTip().GetBestBlock().IsNull()) {
|
||||
// Typical Coin structures on disk are around 48 bytes in size.
|
||||
// Pushing a new one to the database can cause it to be written
|
||||
// twice (once in the log, and once in the tables). This is already
|
||||
// an overestimation, as most will delete an existing entry or
|
||||
// overwrite one. Still, use a conservative safety factor of 2.
|
||||
if (!CheckDiskSpace(GetDataDir(), 48 * 2 * 2 * pcoinsTip->GetCacheSize())) {
|
||||
if (!CheckDiskSpace(GetDataDir(), 48 * 2 * 2 * CoinsTip().GetCacheSize())) {
|
||||
return AbortNode(state, "Disk space is too low!", _("Error: Disk space is too low!").translated, CClientUIInterface::MSG_NOPREFIX);
|
||||
}
|
||||
// Flush the chainstate (which may refer to block index entries).
|
||||
if (!pcoinsTip->Flush())
|
||||
if (!CoinsTip().Flush())
|
||||
return AbortNode(state, "Failed to write to coin database");
|
||||
nLastFlush = nNow;
|
||||
full_flush_completed = true;
|
||||
|
@ -2162,7 +2163,7 @@ void static UpdateTip(const CBlockIndex *pindexNew, const CChainParams& chainPar
|
|||
pindexNew->GetBlockHash().ToString(), pindexNew->nHeight, pindexNew->nVersion,
|
||||
log(pindexNew->nChainWork.getdouble())/log(2.0), (unsigned long)pindexNew->nChainTx,
|
||||
FormatISO8601DateTime(pindexNew->GetBlockTime()),
|
||||
GuessVerificationProgress(chainParams.TxData(), pindexNew), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize());
|
||||
GuessVerificationProgress(chainParams.TxData(), pindexNew), ::ChainstateActive().CoinsTip().DynamicMemoryUsage() * (1.0 / (1<<20)), ::ChainstateActive().CoinsTip().GetCacheSize());
|
||||
if (!warningMessages.empty())
|
||||
LogPrintf(" warning='%s'", warningMessages); /* Continued */
|
||||
LogPrintf("\n");
|
||||
|
@ -2191,7 +2192,7 @@ bool CChainState::DisconnectTip(CValidationState& state, const CChainParams& cha
|
|||
// Apply the block atomically to the chain state.
|
||||
int64_t nStart = GetTimeMicros();
|
||||
{
|
||||
CCoinsViewCache view(pcoinsTip.get());
|
||||
CCoinsViewCache view(&CoinsTip());
|
||||
assert(view.GetBestBlock() == pindexDelete->GetBlockHash());
|
||||
if (DisconnectBlock(block, pindexDelete, view) != DISCONNECT_OK)
|
||||
return error("DisconnectTip(): DisconnectBlock %s failed", pindexDelete->GetBlockHash().ToString());
|
||||
|
@ -2319,7 +2320,7 @@ bool CChainState::ConnectTip(CValidationState& state, const CChainParams& chainp
|
|||
int64_t nTime3;
|
||||
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
|
||||
{
|
||||
CCoinsViewCache view(pcoinsTip.get());
|
||||
CCoinsViewCache view(&CoinsTip());
|
||||
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
|
||||
GetMainSignals().BlockChecked(blockConnecting, state);
|
||||
if (!rv) {
|
||||
|
@ -2506,7 +2507,7 @@ bool CChainState::ActivateBestChainStep(CValidationState& state, const CChainPar
|
|||
// any disconnected transactions back to the mempool.
|
||||
UpdateMempoolForReorg(disconnectpool, true);
|
||||
}
|
||||
mempool.check(pcoinsTip.get());
|
||||
mempool.check(&CoinsTip());
|
||||
|
||||
// Callbacks/notifications for a new best chain.
|
||||
if (fInvalidFound)
|
||||
|
@ -3508,7 +3509,7 @@ bool TestBlockValidity(CValidationState& state, const CChainParams& chainparams,
|
|||
{
|
||||
AssertLockHeld(cs_main);
|
||||
assert(pindexPrev && pindexPrev == ::ChainActive().Tip());
|
||||
CCoinsViewCache viewNew(pcoinsTip.get());
|
||||
CCoinsViewCache viewNew(&::ChainstateActive().CoinsTip());
|
||||
uint256 block_hash(block.GetHash());
|
||||
CBlockIndex indexDummy(block);
|
||||
indexDummy.pprev = pindexPrev;
|
||||
|
@ -3861,12 +3862,14 @@ bool static LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_RE
|
|||
bool LoadChainTip(const CChainParams& chainparams)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
assert(!pcoinsTip->GetBestBlock().IsNull()); // Never called when the coins view is empty
|
||||
const CCoinsViewCache& coins_cache = ::ChainstateActive().CoinsTip();
|
||||
assert(!coins_cache.GetBestBlock().IsNull()); // Never called when the coins view is empty
|
||||
|
||||
if (::ChainActive().Tip() && ::ChainActive().Tip()->GetBlockHash() == pcoinsTip->GetBestBlock()) return true;
|
||||
if (::ChainActive().Tip() &&
|
||||
::ChainActive().Tip()->GetBlockHash() == coins_cache.GetBestBlock()) return true;
|
||||
|
||||
// Load pointer to end of best chain
|
||||
CBlockIndex* pindex = LookupBlockIndex(pcoinsTip->GetBestBlock());
|
||||
CBlockIndex* pindex = LookupBlockIndex(coins_cache.GetBestBlock());
|
||||
if (!pindex) {
|
||||
return false;
|
||||
}
|
||||
|
@ -3943,7 +3946,7 @@ bool CVerifyDB::VerifyDB(const CChainParams& chainparams, CCoinsView *coinsview,
|
|||
}
|
||||
}
|
||||
// check level 3: check for inconsistencies during memory-only disconnect of tip blocks
|
||||
if (nCheckLevel >= 3 && (coins.DynamicMemoryUsage() + pcoinsTip->DynamicMemoryUsage()) <= nCoinCacheUsage) {
|
||||
if (nCheckLevel >= 3 && (coins.DynamicMemoryUsage() + ::ChainstateActive().CoinsTip().DynamicMemoryUsage()) <= nCoinCacheUsage) {
|
||||
assert(coins.GetBestBlock() == pindex->GetBlockHash());
|
||||
DisconnectResult res = ::ChainstateActive().DisconnectBlock(block, pindex, coins);
|
||||
if (res == DISCONNECT_FAILED) {
|
||||
|
|
|
@ -505,6 +505,9 @@ public:
|
|||
CBlockIndex** ppindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
|
||||
};
|
||||
|
||||
/** Global variable that points to the active CCoinsView (protected by cs_main) */
|
||||
extern std::unique_ptr<CCoinsViewCache> pcoinsTip;
|
||||
|
||||
/**
|
||||
* CChainState stores and provides an API to update our local knowledge of the
|
||||
* current best chain.
|
||||
|
@ -566,6 +569,12 @@ public:
|
|||
*/
|
||||
std::set<CBlockIndex*, CBlockIndexWorkComparator> setBlockIndexCandidates;
|
||||
|
||||
//! @returns A reference to the in-memory cache of the UTXO set.
|
||||
CCoinsViewCache& CoinsTip()
|
||||
{
|
||||
return *::pcoinsTip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the on-disk chain state.
|
||||
* The caches and indexes are flushed depending on the mode we're called with
|
||||
|
@ -662,9 +671,6 @@ BlockMap& BlockIndex();
|
|||
/** Global variable that points to the coins database (protected by cs_main) */
|
||||
extern std::unique_ptr<CCoinsViewDB> pcoinsdbview;
|
||||
|
||||
/** Global variable that points to the active CCoinsView (protected by cs_main) */
|
||||
extern std::unique_ptr<CCoinsViewCache> pcoinsTip;
|
||||
|
||||
/** Global variable that points to the active block tree (protected by cs_main) */
|
||||
extern std::unique_ptr<CBlockTreeDB> pblocktree;
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
|
|||
self.base_args = ["-limitdescendantsize=0", "-maxmempool=0", "-rpcservertimeout=900", "-dbbatchsize=200000"]
|
||||
|
||||
# Set different crash ratios and cache sizes. Note that not all of
|
||||
# -dbcache goes to pcoinsTip.
|
||||
# -dbcache goes to the in-memory coins cache.
|
||||
self.node0_args = ["-dbcrashratio=8", "-dbcache=4"] + self.base_args
|
||||
self.node1_args = ["-dbcrashratio=16", "-dbcache=8"] + self.base_args
|
||||
self.node2_args = ["-dbcrashratio=24", "-dbcache=16"] + self.base_args
|
||||
|
|
Loading…
Reference in a new issue