0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-13 11:25:02 -05:00

refactor: Remove chainparams arg from CChainState member functions

Passing this is confusing and redundant with the m_params member.
This commit is contained in:
MarcoFalke 2021-04-27 22:54:53 +02:00
parent fa38947125
commit fa0d9211ef
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
10 changed files with 142 additions and 140 deletions

View file

@ -1372,7 +1372,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// block file from disk. // block file from disk.
// Note that it also sets fReindex based on the disk flag! // Note that it also sets fReindex based on the disk flag!
// From here on out fReindex and fReset mean something different! // From here on out fReindex and fReset mean something different!
if (!chainman.LoadBlockIndex(chainparams)) { if (!chainman.LoadBlockIndex()) {
if (ShutdownRequested()) break; if (ShutdownRequested()) break;
strLoadError = _("Error loading block database"); strLoadError = _("Error loading block database");
break; break;
@ -1396,7 +1396,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// If we're not mid-reindex (based on disk + args), add a genesis block on disk // If we're not mid-reindex (based on disk + args), add a genesis block on disk
// (otherwise we use the one already on disk). // (otherwise we use the one already on disk).
// This is called again in ThreadImport after the reindex completes. // This is called again in ThreadImport after the reindex completes.
if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock(chainparams)) { if (!fReindex && !chainman.ActiveChainstate().LoadGenesisBlock()) {
strLoadError = _("Error initializing block database"); strLoadError = _("Error initializing block database");
break; break;
} }
@ -1427,7 +1427,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} }
// ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate // ReplayBlocks is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate
if (!chainstate->ReplayBlocks(chainparams)) { if (!chainstate->ReplayBlocks()) {
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate."); strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
failed_chainstate_init = true; failed_chainstate_init = true;
break; break;
@ -1439,7 +1439,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (!is_coinsview_empty(chainstate)) { if (!is_coinsview_empty(chainstate)) {
// LoadChainTip initializes the chain based on CoinsTip()'s best block // LoadChainTip initializes the chain based on CoinsTip()'s best block
if (!chainstate->LoadChainTip(chainparams)) { if (!chainstate->LoadChainTip()) {
strLoadError = _("Error initializing block database"); strLoadError = _("Error initializing block database");
failed_chainstate_init = true; failed_chainstate_init = true;
break; // out of the per-chainstate loop break; // out of the per-chainstate loop
@ -1461,7 +1461,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
LOCK(cs_main); LOCK(cs_main);
auto chainstates{chainman.GetAll()}; auto chainstates{chainman.GetAll()};
if (std::any_of(chainstates.begin(), chainstates.end(), if (std::any_of(chainstates.begin(), chainstates.end(),
[&chainparams](const CChainState* cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(chainparams); })) { [](const CChainState* cs) EXCLUSIVE_LOCKS_REQUIRED(cs_main) { return cs->NeedsRedownload(); })) {
strLoadError = strprintf(_("Witness data for blocks after height %d requires validation. Please restart with -reindex."), strLoadError = strprintf(_("Witness data for blocks after height %d requires validation. Please restart with -reindex."),
chainparams.GetConsensus().SegwitHeight); chainparams.GetConsensus().SegwitHeight);
break; break;

View file

@ -1694,7 +1694,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
} // release cs_main before calling ActivateBestChain } // release cs_main before calling ActivateBestChain
if (need_activate_chain) { if (need_activate_chain) {
BlockValidationState state; BlockValidationState state;
if (!m_chainman.ActiveChainstate().ActivateBestChain(state, m_chainparams, a_recent_block)) { if (!m_chainman.ActiveChainstate().ActivateBestChain(state, a_recent_block)) {
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString()); LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
} }
} }
@ -2920,7 +2920,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
a_recent_block = most_recent_block; a_recent_block = most_recent_block;
} }
BlockValidationState state; BlockValidationState state;
if (!m_chainman.ActiveChainstate().ActivateBestChain(state, m_chainparams, a_recent_block)) { if (!m_chainman.ActiveChainstate().ActivateBestChain(state, a_recent_block)) {
LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString()); LogPrint(BCLog::NET, "failed to activate chain (%s)\n", state.ToString());
} }
} }

View file

@ -493,7 +493,6 @@ struct CImportingNow {
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args) void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
{ {
const CChainParams& chainparams = Params();
ScheduleBatchPriority(); ScheduleBatchPriority();
{ {
@ -512,7 +511,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
break; // This error is logged in OpenBlockFile break; // This error is logged in OpenBlockFile
} }
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile); LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file, &pos); chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos);
if (ShutdownRequested()) { if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exit %s\n", __func__); LogPrintf("Shutdown requested. Exit %s\n", __func__);
return; return;
@ -523,7 +522,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
fReindex = false; fReindex = false;
LogPrintf("Reindexing finished\n"); LogPrintf("Reindexing finished\n");
// To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked): // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
chainman.ActiveChainstate().LoadGenesisBlock(chainparams); chainman.ActiveChainstate().LoadGenesisBlock();
} }
// -loadblock= // -loadblock=
@ -531,7 +530,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
FILE* file = fsbridge::fopen(path, "rb"); FILE* file = fsbridge::fopen(path, "rb");
if (file) { if (file) {
LogPrintf("Importing blocks file %s...\n", path.string()); LogPrintf("Importing blocks file %s...\n", path.string());
chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file); chainman.ActiveChainstate().LoadExternalBlockFile(file);
if (ShutdownRequested()) { if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exit %s\n", __func__); LogPrintf("Shutdown requested. Exit %s\n", __func__);
return; return;
@ -548,7 +547,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
// the relevant pointers before the ABC call. // the relevant pointers before the ABC call.
for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) { for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
BlockValidationState state; BlockValidationState state;
if (!chainstate->ActivateBestChain(state, chainparams, nullptr)) { if (!chainstate->ActivateBestChain(state, nullptr)) {
LogPrintf("Failed to connect best block (%s)\n", state.ToString()); LogPrintf("Failed to connect best block (%s)\n", state.ToString());
StartShutdown(); StartShutdown();
return; return;

View file

@ -1706,7 +1706,7 @@ static RPCHelpMan preciousblock()
} }
BlockValidationState state; BlockValidationState state;
chainman.ActiveChainstate().PreciousBlock(state, Params(), pblockindex); chainman.ActiveChainstate().PreciousBlock(state, pblockindex);
if (!state.IsValid()) { if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString()); throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@ -1743,10 +1743,10 @@ static RPCHelpMan invalidateblock()
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
} }
} }
chainman.ActiveChainstate().InvalidateBlock(state, Params(), pblockindex); chainman.ActiveChainstate().InvalidateBlock(state, pblockindex);
if (state.IsValid()) { if (state.IsValid()) {
chainman.ActiveChainstate().ActivateBestChain(state, Params()); chainman.ActiveChainstate().ActivateBestChain(state);
} }
if (!state.IsValid()) { if (!state.IsValid()) {
@ -1787,7 +1787,7 @@ static RPCHelpMan reconsiderblock()
} }
BlockValidationState state; BlockValidationState state;
chainman.ActiveChainstate().ActivateBestChain(state, Params()); chainman.ActiveChainstate().ActivateBestChain(state);
if (!state.IsValid()) { if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString()); throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());

View file

@ -32,5 +32,5 @@ FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
return; return;
} }
FlatFilePos flat_file_pos; FlatFilePos flat_file_pos;
g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(Params(), fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr); g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
} }

View file

@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(findCommonAncestor)
auto* orig_tip = active.Tip(); auto* orig_tip = active.Tip();
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 10; ++i) {
BlockValidationState state; BlockValidationState state;
m_node.chainman->ActiveChainstate().InvalidateBlock(state, Params(), active.Tip()); m_node.chainman->ActiveChainstate().InvalidateBlock(state, active.Tip());
} }
BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10); BOOST_CHECK_EQUAL(active.Height(), orig_tip->nHeight - 10);
coinbaseKey.MakeNewKey(true); coinbaseKey.MakeNewKey(true);

View file

@ -186,12 +186,12 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk()); assert(!m_node.chainman->ActiveChainstate().CanFlushToDisk());
m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23); m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23);
assert(m_node.chainman->ActiveChainstate().CanFlushToDisk()); assert(m_node.chainman->ActiveChainstate().CanFlushToDisk());
if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock(chainparams)) { if (!m_node.chainman->ActiveChainstate().LoadGenesisBlock()) {
throw std::runtime_error("LoadGenesisBlock failed."); throw std::runtime_error("LoadGenesisBlock failed.");
} }
BlockValidationState state; BlockValidationState state;
if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state, chainparams)) { if (!m_node.chainman->ActiveChainstate().ActivateBestChain(state)) {
throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString())); throw std::runtime_error(strprintf("ActivateBestChain failed. (%s)", state.ToString()));
} }

View file

@ -31,7 +31,6 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
CTxMemPool& mempool = *m_node.mempool; CTxMemPool& mempool = *m_node.mempool;
std::vector<CChainState*> chainstates; std::vector<CChainState*> chainstates;
const CChainParams& chainparams = Params();
BOOST_CHECK(!manager.SnapshotBlockhash().has_value()); BOOST_CHECK(!manager.SnapshotBlockhash().has_value());
@ -76,9 +75,9 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
/* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false); /* cache_size_bytes */ 1 << 23, /* in_memory */ true, /* should_wipe */ false);
WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23)); WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23));
// Unlike c1, which doesn't have any blocks. Gets us different tip, height. // Unlike c1, which doesn't have any blocks. Gets us different tip, height.
c2.LoadGenesisBlock(chainparams); c2.LoadGenesisBlock();
BlockValidationState _; BlockValidationState _;
BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr)); BOOST_CHECK(c2.ActivateBestChain(_, nullptr));
BOOST_CHECK(manager.IsSnapshotActive()); BOOST_CHECK(manager.IsSnapshotActive());
BOOST_CHECK(!manager.IsSnapshotValidated()); BOOST_CHECK(!manager.IsSnapshotValidated());
@ -138,7 +137,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
{ {
LOCK(::cs_main); LOCK(::cs_main);
c1.InitCoinsCache(1 << 23); c1.InitCoinsCache(1 << 23);
BOOST_REQUIRE(c1.LoadGenesisBlock(Params())); BOOST_REQUIRE(c1.LoadGenesisBlock());
c1.CoinsTip().SetBestBlock(InsecureRand256()); c1.CoinsTip().SetBestBlock(InsecureRand256());
manager.MaybeRebalanceCaches(); manager.MaybeRebalanceCaches();
} }
@ -156,7 +155,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
{ {
LOCK(::cs_main); LOCK(::cs_main);
c2.InitCoinsCache(1 << 23); c2.InitCoinsCache(1 << 23);
BOOST_REQUIRE(c2.LoadGenesisBlock(Params())); BOOST_REQUIRE(c2.LoadGenesisBlock());
c2.CoinsTip().SetBestBlock(InsecureRand256()); c2.CoinsTip().SetBestBlock(InsecureRand256());
manager.MaybeRebalanceCaches(); manager.MaybeRebalanceCaches();
} }

View file

@ -1124,7 +1124,7 @@ static MempoolAcceptResult AcceptToMemoryPoolWithTime(const CChainParams& chainp
} }
// After we've (potentially) uncached entries, ensure our coins cache is still within its size limits // After we've (potentially) uncached entries, ensure our coins cache is still within its size limits
BlockValidationState state_dummy; BlockValidationState state_dummy;
active_chainstate.FlushStateToDisk(chainparams, state_dummy, FlushStateMode::PERIODIC); active_chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
return result; return result;
} }
@ -1725,7 +1725,7 @@ static int64_t nBlocksTotal = 0;
* Validity checks that depend on the UTXO set are also done; ConnectBlock() * Validity checks that depend on the UTXO set are also done; ConnectBlock()
* can fail if those validity checks fail (among other reasons). */ * can fail if those validity checks fail (among other reasons). */
bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex, bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck) CCoinsViewCache& view, bool fJustCheck)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
assert(pindex); assert(pindex);
@ -1745,7 +1745,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// is enforced in ContextualCheckBlockHeader(); we wouldn't want to // is enforced in ContextualCheckBlockHeader(); we wouldn't want to
// re-enforce that rule here (at least until we make it impossible for // re-enforce that rule here (at least until we make it impossible for
// GetAdjustedTime() to go backward). // GetAdjustedTime() to go backward).
if (!CheckBlock(block, state, chainparams.GetConsensus(), !fJustCheck, !fJustCheck)) { if (!CheckBlock(block, state, m_params.GetConsensus(), !fJustCheck, !fJustCheck)) {
if (state.GetResult() == BlockValidationResult::BLOCK_MUTATED) { if (state.GetResult() == BlockValidationResult::BLOCK_MUTATED) {
// We don't write down blocks to disk if they may have been // We don't write down blocks to disk if they may have been
// corrupted, so this should be impossible unless we're having hardware // corrupted, so this should be impossible unless we're having hardware
@ -1763,7 +1763,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Special case for the genesis block, skipping connection of its transactions // Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable) // (its coinbase is unspendable)
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) { if (block.GetHash() == m_params.GetConsensus().hashGenesisBlock) {
if (!fJustCheck) if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash()); view.SetBestBlock(pindex->GetBlockHash());
return true; return true;
@ -1795,7 +1795,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// artificially set the default assumed verified block further back. // artificially set the default assumed verified block further back.
// The test against nMinimumChainWork prevents the skipping when denied access to any chain at // The test against nMinimumChainWork prevents the skipping when denied access to any chain at
// least as good as the expected chain. // least as good as the expected chain.
fScriptChecks = (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, chainparams.GetConsensus()) <= 60 * 60 * 24 * 7 * 2); fScriptChecks = (GetBlockProofEquivalentTime(*pindexBestHeader, *pindex, *pindexBestHeader, m_params.GetConsensus()) <= 60 * 60 * 24 * 7 * 2);
} }
} }
} }
@ -1875,9 +1875,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// be reset before it reaches block 1,983,702 and starts doing unnecessary // be reset before it reaches block 1,983,702 and starts doing unnecessary
// BIP30 checking again. // BIP30 checking again.
assert(pindex->pprev); assert(pindex->pprev);
CBlockIndex *pindexBIP34height = pindex->pprev->GetAncestor(chainparams.GetConsensus().BIP34Height); CBlockIndex* pindexBIP34height = pindex->pprev->GetAncestor(m_params.GetConsensus().BIP34Height);
//Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond. //Only continue to enforce if we're below BIP34 activation height or the block hash at that height doesn't correspond.
fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == chainparams.GetConsensus().BIP34Hash)); fEnforceBIP30 = fEnforceBIP30 && (!pindexBIP34height || !(pindexBIP34height->GetBlockHash() == m_params.GetConsensus().BIP34Hash));
// TODO: Remove BIP30 checking from block height 1,983,702 on, once we have a // TODO: Remove BIP30 checking from block height 1,983,702 on, once we have a
// consensus change that ensures coinbases at those heights can not // consensus change that ensures coinbases at those heights can not
@ -1895,12 +1895,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Start enforcing BIP68 (sequence locks) // Start enforcing BIP68 (sequence locks)
int nLockTimeFlags = 0; int nLockTimeFlags = 0;
if (pindex->nHeight >= chainparams.GetConsensus().CSVHeight) { if (pindex->nHeight >= m_params.GetConsensus().CSVHeight) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE; nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
} }
// Get the script flags for this block // Get the script flags for this block
unsigned int flags = GetBlockScriptFlags(pindex, chainparams.GetConsensus()); unsigned int flags = GetBlockScriptFlags(pindex, m_params.GetConsensus());
int64_t nTime2 = GetTimeMicros(); nTimeForks += nTime2 - nTime1; 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); LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
@ -1990,7 +1990,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2; int64_t nTime3 = GetTimeMicros(); nTimeConnect += nTime3 - nTime2;
LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Connect %u transactions: %.2fms (%.3fms/tx, %.3fms/txin) [%.2fs (%.2fms/blk)]\n", (unsigned)block.vtx.size(), MILLI * (nTime3 - nTime2), MILLI * (nTime3 - nTime2) / block.vtx.size(), nInputs <= 1 ? 0 : MILLI * (nTime3 - nTime2) / (nInputs-1), nTimeConnect * MICRO, nTimeConnect * MILLI / nBlocksTotal);
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus()); CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, m_params.GetConsensus());
if (block.vtx[0]->GetValueOut() > blockReward) { if (block.vtx[0]->GetValueOut() > blockReward) {
LogPrintf("ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.vtx[0]->GetValueOut(), blockReward); LogPrintf("ERROR: ConnectBlock(): coinbase pays too much (actual=%d vs limit=%d)\n", block.vtx[0]->GetValueOut(), blockReward);
return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount"); return state.Invalid(BlockValidationResult::BLOCK_CONSENSUS, "bad-cb-amount");
@ -2006,8 +2006,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
if (fJustCheck) if (fJustCheck)
return true; return true;
if (!WriteUndoDataForBlock(blockundo, state, pindex, chainparams)) if (!WriteUndoDataForBlock(blockundo, state, pindex, m_params)) {
return false; return false;
}
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) { if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS); pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
@ -2060,7 +2061,6 @@ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(
} }
bool CChainState::FlushStateToDisk( bool CChainState::FlushStateToDisk(
const CChainParams& chainparams,
BlockValidationState &state, BlockValidationState &state,
FlushStateMode mode, FlushStateMode mode,
int nManualPruneHeight) int nManualPruneHeight)
@ -2097,7 +2097,7 @@ bool CChainState::FlushStateToDisk(
} else { } else {
LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH); LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH);
m_blockman.FindFilesToPrune(setFilesToPrune, chainparams.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload()); m_blockman.FindFilesToPrune(setFilesToPrune, m_params.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload());
fCheckForPruning = false; fCheckForPruning = false;
} }
if (!setFilesToPrune.empty()) { if (!setFilesToPrune.empty()) {
@ -2200,7 +2200,7 @@ bool CChainState::FlushStateToDisk(
void CChainState::ForceFlushStateToDisk() void CChainState::ForceFlushStateToDisk()
{ {
BlockValidationState state; BlockValidationState state;
if (!this->FlushStateToDisk(m_params, state, FlushStateMode::ALWAYS)) { if (!this->FlushStateToDisk(state, FlushStateMode::ALWAYS)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString()); LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
} }
} }
@ -2209,7 +2209,7 @@ void CChainState::PruneAndFlush()
{ {
BlockValidationState state; BlockValidationState state;
fCheckForPruning = true; fCheckForPruning = true;
if (!this->FlushStateToDisk(m_params, state, FlushStateMode::NONE)) { if (!this->FlushStateToDisk(state, FlushStateMode::NONE)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString()); LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
} }
} }
@ -2278,7 +2278,7 @@ static void UpdateTip(CTxMemPool& mempool, const CBlockIndex* pindexNew, const C
* disconnectpool (note that the caller is responsible for mempool consistency * disconnectpool (note that the caller is responsible for mempool consistency
* in any case). * in any case).
*/ */
bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) bool CChainState::DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs); AssertLockHeld(m_mempool.cs);
@ -2288,8 +2288,9 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
// Read block from disk. // Read block from disk.
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock& block = *pblock; CBlock& block = *pblock;
if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus())) if (!ReadBlockFromDisk(block, pindexDelete, m_params.GetConsensus())) {
return error("DisconnectTip(): Failed to read block"); return error("DisconnectTip(): Failed to read block");
}
// Apply the block atomically to the chain state. // Apply the block atomically to the chain state.
int64_t nStart = GetTimeMicros(); int64_t nStart = GetTimeMicros();
{ {
@ -2302,8 +2303,9 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
} }
LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * MILLI); LogPrint(BCLog::BENCH, "- Disconnect block: %.2fms\n", (GetTimeMicros() - nStart) * MILLI);
// Write the chain state to disk, if necessary. // Write the chain state to disk, if necessary.
if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED)) if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
return false; return false;
}
if (disconnectpool) { if (disconnectpool) {
// Save transactions to re-add to mempool at end of reorg // Save transactions to re-add to mempool at end of reorg
@ -2320,7 +2322,7 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
m_chain.SetTip(pindexDelete->pprev); m_chain.SetTip(pindexDelete->pprev);
UpdateTip(m_mempool, pindexDelete->pprev, chainparams, *this); UpdateTip(m_mempool, pindexDelete->pprev, m_params, *this);
// Let wallets know transactions went from 1-confirmed to // Let wallets know transactions went from 1-confirmed to
// 0-confirmed or conflicted: // 0-confirmed or conflicted:
GetMainSignals().BlockDisconnected(pblock, pindexDelete); GetMainSignals().BlockDisconnected(pblock, pindexDelete);
@ -2379,7 +2381,7 @@ public:
* *
* The block is added to connectTrace if connection succeeds. * The block is added to connectTrace if connection succeeds.
*/ */
bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions &disconnectpool) bool CChainState::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs); AssertLockHeld(m_mempool.cs);
@ -2390,8 +2392,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
std::shared_ptr<const CBlock> pthisBlock; std::shared_ptr<const CBlock> pthisBlock;
if (!pblock) { if (!pblock) {
std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
if (!ReadBlockFromDisk(*pblockNew, pindexNew, chainparams.GetConsensus())) if (!ReadBlockFromDisk(*pblockNew, pindexNew, m_params.GetConsensus())) {
return AbortNode(state, "Failed to read block"); return AbortNode(state, "Failed to read block");
}
pthisBlock = pblockNew; pthisBlock = pblockNew;
} else { } else {
pthisBlock = pblock; pthisBlock = pblock;
@ -2403,7 +2406,7 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO); LogPrint(BCLog::BENCH, " - Load block from disk: %.2fms [%.2fs]\n", (nTime2 - nTime1) * MILLI, nTimeReadFromDisk * MICRO);
{ {
CCoinsViewCache view(&CoinsTip()); CCoinsViewCache view(&CoinsTip());
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams); bool rv = ConnectBlock(blockConnecting, state, pindexNew, view);
GetMainSignals().BlockChecked(blockConnecting, state); GetMainSignals().BlockChecked(blockConnecting, state);
if (!rv) { if (!rv) {
if (state.IsInvalid()) if (state.IsInvalid())
@ -2419,8 +2422,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3; int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
LogPrint(BCLog::BENCH, " - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Flush: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime4 - nTime3) * MILLI, nTimeFlush * MICRO, nTimeFlush * MILLI / nBlocksTotal);
// Write the chain state to disk, if necessary. // Write the chain state to disk, if necessary.
if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED)) if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
return false; return false;
}
int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4; int64_t nTime5 = GetTimeMicros(); nTimeChainState += nTime5 - nTime4;
LogPrint(BCLog::BENCH, " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Writing chainstate: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime5 - nTime4) * MILLI, nTimeChainState * MICRO, nTimeChainState * MILLI / nBlocksTotal);
// Remove conflicting transactions from the mempool.; // Remove conflicting transactions from the mempool.;
@ -2428,7 +2432,7 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
disconnectpool.removeForBlock(blockConnecting.vtx); disconnectpool.removeForBlock(blockConnecting.vtx);
// Update m_chain & related variables. // Update m_chain & related variables.
m_chain.SetTip(pindexNew); m_chain.SetTip(pindexNew);
UpdateTip(m_mempool, pindexNew, chainparams, *this); UpdateTip(m_mempool, pindexNew, m_params, *this);
int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1; int64_t nTime6 = GetTimeMicros(); nTimePostConnect += nTime6 - nTime5; nTimeTotal += nTime6 - nTime1;
LogPrint(BCLog::BENCH, " - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal); LogPrint(BCLog::BENCH, " - Connect postprocess: %.2fms [%.2fs (%.2fms/blk)]\n", (nTime6 - nTime5) * MILLI, nTimePostConnect * MICRO, nTimePostConnect * MILLI / nBlocksTotal);
@ -2515,7 +2519,7 @@ void CChainState::PruneBlockIndexCandidates() {
* *
* @returns true unless a system error occurred * @returns true unless a system error occurred
*/ */
bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace)
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs); AssertLockHeld(m_mempool.cs);
@ -2527,7 +2531,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
bool fBlocksDisconnected = false; bool fBlocksDisconnected = false;
DisconnectedBlockTransactions disconnectpool; DisconnectedBlockTransactions disconnectpool;
while (m_chain.Tip() && m_chain.Tip() != pindexFork) { while (m_chain.Tip() && m_chain.Tip() != pindexFork) {
if (!DisconnectTip(state, chainparams, &disconnectpool)) { if (!DisconnectTip(state, &disconnectpool)) {
// This is likely a fatal error, but keep the mempool consistent, // This is likely a fatal error, but keep the mempool consistent,
// just in case. Only remove from the mempool in this case. // just in case. Only remove from the mempool in this case.
UpdateMempoolForReorg(*this, m_mempool, disconnectpool, false); UpdateMempoolForReorg(*this, m_mempool, disconnectpool, false);
@ -2560,7 +2564,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
// Connect new blocks. // Connect new blocks.
for (CBlockIndex* pindexConnect : reverse_iterate(vpindexToConnect)) { for (CBlockIndex* pindexConnect : reverse_iterate(vpindexToConnect)) {
if (!ConnectTip(state, chainparams, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) { if (!ConnectTip(state, pindexConnect, pindexConnect == pindexMostWork ? pblock : std::shared_ptr<const CBlock>(), connectTrace, disconnectpool)) {
if (state.IsInvalid()) { if (state.IsInvalid()) {
// The block violates a consensus rule. // The block violates a consensus rule.
if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
@ -2637,7 +2641,8 @@ static void LimitValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main) {
} }
} }
bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainParams& chainparams, std::shared_ptr<const CBlock> pblock) { bool CChainState::ActivateBestChain(BlockValidationState& state, std::shared_ptr<const CBlock> pblock)
{
// Note that while we're often called here from ProcessNewBlock, this is // Note that while we're often called here from ProcessNewBlock, this is
// far from a guarantee. Things in the P2P/RPC will often end up calling // far from a guarantee. Things in the P2P/RPC will often end up calling
// us in the middle of ProcessNewBlock - do not assume pblock is set // us in the middle of ProcessNewBlock - do not assume pblock is set
@ -2683,7 +2688,7 @@ bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainPar
bool fInvalidFound = false; bool fInvalidFound = false;
std::shared_ptr<const CBlock> nullBlockPtr; std::shared_ptr<const CBlock> nullBlockPtr;
if (!ActivateBestChainStep(state, chainparams, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) { if (!ActivateBestChainStep(state, pindexMostWork, pblock && pblock->GetHash() == pindexMostWork->GetBlockHash() ? pblock : nullBlockPtr, fInvalidFound, connectTrace)) {
// A system error occurred // A system error occurred
return false; return false;
} }
@ -2725,17 +2730,17 @@ bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainPar
// that the best block hash is non-null. // that the best block hash is non-null.
if (ShutdownRequested()) break; if (ShutdownRequested()) break;
} while (pindexNewTip != pindexMostWork); } while (pindexNewTip != pindexMostWork);
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex();
// Write changes periodically to disk, after relay. // Write changes periodically to disk, after relay.
if (!FlushStateToDisk(chainparams, state, FlushStateMode::PERIODIC)) { if (!FlushStateToDisk(state, FlushStateMode::PERIODIC)) {
return false; return false;
} }
return true; return true;
} }
bool CChainState::PreciousBlock(BlockValidationState& state, const CChainParams& params, CBlockIndex *pindex) bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex)
{ {
{ {
LOCK(cs_main); LOCK(cs_main);
@ -2761,10 +2766,10 @@ bool CChainState::PreciousBlock(BlockValidationState& state, const CChainParams&
} }
} }
return ActivateBestChain(state, params, std::shared_ptr<const CBlock>()); return ActivateBestChain(state, std::shared_ptr<const CBlock>());
} }
bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex *pindex) bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex)
{ {
// Genesis block can't be invalidated // Genesis block can't be invalidated
assert(pindex); assert(pindex);
@ -2822,7 +2827,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
// ActivateBestChain considers blocks already in m_chain // ActivateBestChain considers blocks already in m_chain
// unconditionally valid already, so force disconnect away from it. // unconditionally valid already, so force disconnect away from it.
DisconnectedBlockTransactions disconnectpool; DisconnectedBlockTransactions disconnectpool;
bool ret = DisconnectTip(state, chainparams, &disconnectpool); bool ret = DisconnectTip(state, &disconnectpool);
// DisconnectTip will add transactions to disconnectpool. // DisconnectTip will add transactions to disconnectpool.
// Adjust the mempool to be consistent with the new tip, adding // Adjust the mempool to be consistent with the new tip, adding
// transactions back to the mempool if disconnecting was successful, // transactions back to the mempool if disconnecting was successful,
@ -2864,7 +2869,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
to_mark_failed = invalid_walk_tip; to_mark_failed = invalid_walk_tip;
} }
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex();
{ {
LOCK(cs_main); LOCK(cs_main);
@ -2975,7 +2980,7 @@ CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block)
} }
/** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */ /** Mark a block as having its data received and checked (up to BLOCK_VALID_TRANSACTIONS). */
void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos, const Consensus::Params& consensusParams) void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos)
{ {
pindexNew->nTx = block.vtx.size(); pindexNew->nTx = block.vtx.size();
pindexNew->nChainTx = 0; pindexNew->nChainTx = 0;
@ -2983,7 +2988,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
pindexNew->nDataPos = pos.nPos; pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0; pindexNew->nUndoPos = 0;
pindexNew->nStatus |= BLOCK_HAVE_DATA; pindexNew->nStatus |= BLOCK_HAVE_DATA;
if (IsWitnessEnabled(pindexNew->pprev, consensusParams)) { if (IsWitnessEnabled(pindexNew->pprev, m_params.GetConsensus())) {
pindexNew->nStatus |= BLOCK_OPT_WITNESS; pindexNew->nStatus |= BLOCK_OPT_WITNESS;
} }
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
@ -3400,7 +3405,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast CBlockIndex *pindex = nullptr; // Use a temp pindex instead of ppindex to avoid a const_cast
bool accepted = m_blockman.AcceptBlockHeader( bool accepted = m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex); header, state, chainparams, &pindex);
ActiveChainstate().CheckBlockIndex(chainparams.GetConsensus()); ActiveChainstate().CheckBlockIndex();
if (!accepted) { if (!accepted) {
return false; return false;
@ -3419,7 +3424,7 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
} }
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ /** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
{ {
const CBlock& block = *pblock; const CBlock& block = *pblock;
@ -3429,8 +3434,8 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
CBlockIndex *pindexDummy = nullptr; CBlockIndex *pindexDummy = nullptr;
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy; CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
bool accepted_header = m_blockman.AcceptBlockHeader(block, state, chainparams, &pindex); bool accepted_header = m_blockman.AcceptBlockHeader(block, state, m_params, &pindex);
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex();
if (!accepted_header) if (!accepted_header)
return false; return false;
@ -3467,8 +3472,8 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
if (pindex->nChainWork < nMinimumChainWork) return true; if (pindex->nChainWork < nMinimumChainWork) return true;
} }
if (!CheckBlock(block, state, chainparams.GetConsensus()) || if (!CheckBlock(block, state, m_params.GetConsensus()) ||
!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) { !ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) {
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID; pindex->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindex); setDirtyBlockIndex.insert(pindex);
@ -3484,19 +3489,19 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file // Write block to history file
if (fNewBlock) *fNewBlock = true; if (fNewBlock) *fNewBlock = true;
try { try {
FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, chainparams, dbp); FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, m_params, dbp);
if (blockPos.IsNull()) { if (blockPos.IsNull()) {
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__)); state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
return false; return false;
} }
ReceivedBlockTransactions(block, pindex, blockPos, chainparams.GetConsensus()); ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
return AbortNode(state, std::string("System error: ") + e.what()); return AbortNode(state, std::string("System error: ") + e.what());
} }
FlushStateToDisk(chainparams, state, FlushStateMode::NONE); FlushStateToDisk(state, FlushStateMode::NONE);
CheckBlockIndex(chainparams.GetConsensus()); CheckBlockIndex();
return true; return true;
} }
@ -3522,7 +3527,7 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
bool ret = CheckBlock(*block, state, chainparams.GetConsensus()); bool ret = CheckBlock(*block, state, chainparams.GetConsensus());
if (ret) { if (ret) {
// Store to disk // Store to disk
ret = ActiveChainstate().AcceptBlock(block, state, chainparams, &pindex, force_processing, nullptr, new_block); ret = ActiveChainstate().AcceptBlock(block, state, &pindex, force_processing, nullptr, new_block);
} }
if (!ret) { if (!ret) {
GetMainSignals().BlockChecked(*block, state); GetMainSignals().BlockChecked(*block, state);
@ -3533,8 +3538,9 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
NotifyHeaderTip(ActiveChainstate()); NotifyHeaderTip(ActiveChainstate());
BlockValidationState state; // Only used to report errors, not invalidity - ignore it BlockValidationState state; // Only used to report errors, not invalidity - ignore it
if (!ActiveChainstate().ActivateBestChain(state, chainparams, block)) if (!ActiveChainstate().ActivateBestChain(state, block)) {
return error("%s: ActivateBestChain failed (%s)", __func__, state.ToString()); return error("%s: ActivateBestChain failed (%s)", __func__, state.ToString());
}
return true; return true;
} }
@ -3563,8 +3569,9 @@ bool TestBlockValidity(BlockValidationState& state,
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString()); return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev)) if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString()); return error("%s: Consensus::ContextualCheckBlock: %s", __func__, state.ToString());
if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, chainparams, true)) if (!chainstate.ConnectBlock(block, state, &indexDummy, viewNew, true)) {
return false; return false;
}
assert(state.IsValid()); assert(state.IsValid());
return true; return true;
@ -3635,9 +3642,8 @@ void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nM
void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight) void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight)
{ {
BlockValidationState state; BlockValidationState state;
const CChainParams& chainparams = Params();
if (!active_chainstate.FlushStateToDisk( if (!active_chainstate.FlushStateToDisk(
chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) { state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString()); LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
} }
} }
@ -3787,10 +3793,10 @@ void BlockManager::Unload() {
m_block_index.clear(); m_block_index.clear();
} }
bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams) bool CChainState::LoadBlockIndexDB()
{ {
if (!m_blockman.LoadBlockIndex( if (!m_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree, m_params.GetConsensus(), *pblocktree,
setBlockIndexCandidates)) { setBlockIndexCandidates)) {
return false; return false;
} }
@ -3850,7 +3856,7 @@ void CChainState::LoadMempool(const ArgsManager& args)
m_mempool.SetIsLoaded(!ShutdownRequested()); m_mempool.SetIsLoaded(!ShutdownRequested());
} }
bool CChainState::LoadChainTip(const CChainParams& chainparams) bool CChainState::LoadChainTip()
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
const CCoinsViewCache& coins_cache = CoinsTip(); const CCoinsViewCache& coins_cache = CoinsTip();
@ -3874,7 +3880,7 @@ bool CChainState::LoadChainTip(const CChainParams& chainparams)
tip->GetBlockHash().ToString(), tip->GetBlockHash().ToString(),
m_chain.Height(), m_chain.Height(),
FormatISO8601DateTime(tip->GetBlockTime()), FormatISO8601DateTime(tip->GetBlockTime()),
GuessVerificationProgress(chainparams.TxData(), tip)); GuessVerificationProgress(m_params.TxData(), tip));
return true; return true;
} }
@ -3985,8 +3991,9 @@ bool CVerifyDB::VerifyDB(
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus())) if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("VerifyDB(): *** ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
if (!chainstate.ConnectBlock(block, state, pindex, coins, chainparams)) if (!chainstate.ConnectBlock(block, state, pindex, coins)) {
return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString()); return error("VerifyDB(): *** found unconnectable block at %d, hash=%s (%s)", pindex->nHeight, pindex->GetBlockHash().ToString(), state.ToString());
}
if (ShutdownRequested()) return true; if (ShutdownRequested()) return true;
} }
} }
@ -3998,11 +4005,11 @@ bool CVerifyDB::VerifyDB(
} }
/** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */ /** Apply the effects of a block on the utxo cache, ignoring that it may already have been applied. */
bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs)
{ {
// TODO: merge with ConnectBlock // TODO: merge with ConnectBlock
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, params.GetConsensus())) { if (!ReadBlockFromDisk(block, pindex, m_params.GetConsensus())) {
return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
} }
@ -4018,7 +4025,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
return true; return true;
} }
bool CChainState::ReplayBlocks(const CChainParams& params) bool CChainState::ReplayBlocks()
{ {
LOCK(cs_main); LOCK(cs_main);
@ -4054,7 +4061,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
while (pindexOld != pindexFork) { while (pindexOld != pindexFork) {
if (pindexOld->nHeight > 0) { // Never disconnect the genesis block. if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindexOld, params.GetConsensus())) { if (!ReadBlockFromDisk(block, pindexOld, m_params.GetConsensus())) {
return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString()); return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
} }
LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight); LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
@ -4076,7 +4083,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight); const CBlockIndex* pindex = pindexNew->GetAncestor(nHeight);
LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight); LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight);
uiInterface.ShowProgress(_("Replaying blocks…").translated, (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false); uiInterface.ShowProgress(_("Replaying blocks…").translated, (int) ((nHeight - nForkHeight) * 100.0 / (pindexNew->nHeight - nForkHeight)) , false);
if (!RollforwardBlock(pindex, cache, params)) return false; if (!RollforwardBlock(pindex, cache)) return false;
} }
cache.SetBestBlock(pindexNew->GetBlockHash()); cache.SetBestBlock(pindexNew->GetBlockHash());
@ -4085,13 +4092,13 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
return true; return true;
} }
bool CChainState::NeedsRedownload(const CChainParams& params) const bool CChainState::NeedsRedownload() const
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
// At and above params.SegwitHeight, segwit consensus rules must be validated // At and above m_params.SegwitHeight, segwit consensus rules must be validated
CBlockIndex* block{m_chain.Tip()}; CBlockIndex* block{m_chain.Tip()};
const int segwit_height{params.GetConsensus().SegwitHeight}; const int segwit_height{m_params.GetConsensus().SegwitHeight};
while (block != nullptr && block->nHeight >= segwit_height) { while (block != nullptr && block->nHeight >= segwit_height) {
if (!(block->nStatus & BLOCK_OPT_WITNESS)) { if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
@ -4130,13 +4137,13 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
fHavePruned = false; fHavePruned = false;
} }
bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams) bool ChainstateManager::LoadBlockIndex()
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
// Load block index from databases // Load block index from databases
bool needs_init = fReindex; bool needs_init = fReindex;
if (!fReindex) { if (!fReindex) {
bool ret = ActiveChainstate().LoadBlockIndexDB(chainparams); bool ret = ActiveChainstate().LoadBlockIndexDB();
if (!ret) return false; if (!ret) return false;
needs_init = m_blockman.m_block_index.empty(); needs_init = m_blockman.m_block_index.empty();
} }
@ -4153,7 +4160,7 @@ bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams)
return true; return true;
} }
bool CChainState::LoadGenesisBlock(const CChainParams& chainparams) bool CChainState::LoadGenesisBlock()
{ {
LOCK(cs_main); LOCK(cs_main);
@ -4161,16 +4168,16 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
// m_blockman.m_block_index. Note that we can't use m_chain here, since it is // m_blockman.m_block_index. Note that we can't use m_chain here, since it is
// set based on the coins db, not the block index db, which is the only // set based on the coins db, not the block index db, which is the only
// thing loaded at this point. // thing loaded at this point.
if (m_blockman.m_block_index.count(chainparams.GenesisBlock().GetHash())) if (m_blockman.m_block_index.count(m_params.GenesisBlock().GetHash()))
return true; return true;
try { try {
const CBlock& block = chainparams.GenesisBlock(); const CBlock& block = m_params.GenesisBlock();
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, chainparams, nullptr); FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr);
if (blockPos.IsNull()) if (blockPos.IsNull())
return error("%s: writing genesis block to disk failed", __func__); return error("%s: writing genesis block to disk failed", __func__);
CBlockIndex *pindex = m_blockman.AddToBlockIndex(block); CBlockIndex *pindex = m_blockman.AddToBlockIndex(block);
ReceivedBlockTransactions(block, pindex, blockPos, chainparams.GetConsensus()); ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
return error("%s: failed to write genesis block: %s", __func__, e.what()); return error("%s: failed to write genesis block: %s", __func__, e.what());
} }
@ -4178,7 +4185,7 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
return true; return true;
} }
void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFilePos* dbp) void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
{ {
// Map of disk positions for blocks with unknown parent (only used for reindex) // Map of disk positions for blocks with unknown parent (only used for reindex)
static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent; static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
@ -4199,11 +4206,12 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
try { try {
// locate a header // locate a header
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE]; unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
blkdat.FindByte(chainparams.MessageStart()[0]); blkdat.FindByte(m_params.MessageStart()[0]);
nRewind = blkdat.GetPos()+1; nRewind = blkdat.GetPos()+1;
blkdat >> buf; blkdat >> buf;
if (memcmp(buf, chainparams.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
continue; continue;
}
// read size // read size
blkdat >> nSize; blkdat >> nSize;
if (nSize < 80 || nSize > MAX_BLOCK_SERIALIZED_SIZE) if (nSize < 80 || nSize > MAX_BLOCK_SERIALIZED_SIZE)
@ -4227,7 +4235,7 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
{ {
LOCK(cs_main); LOCK(cs_main);
// detect out of order blocks, and store them for later // detect out of order blocks, and store them for later
if (hash != chainparams.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) { if (hash != m_params.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(), LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString()); block.hashPrevBlock.ToString());
if (dbp) if (dbp)
@ -4239,21 +4247,21 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash); CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) { if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
BlockValidationState state; BlockValidationState state;
if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) { if (AcceptBlock(pblock, state, nullptr, true, dbp, nullptr)) {
nLoaded++; nLoaded++;
} }
if (state.IsError()) { if (state.IsError()) {
break; break;
} }
} else if (hash != chainparams.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) { } else if (hash != m_params.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight); LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
} }
} }
// Activate the genesis block so normal node progress can continue // Activate the genesis block so normal node progress can continue
if (hash == chainparams.GetConsensus().hashGenesisBlock) { if (hash == m_params.GetConsensus().hashGenesisBlock) {
BlockValidationState state; BlockValidationState state;
if (!ActivateBestChain(state, chainparams, nullptr)) { if (!ActivateBestChain(state, nullptr)) {
break; break;
} }
} }
@ -4270,14 +4278,12 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
while (range.first != range.second) { while (range.first != range.second) {
std::multimap<uint256, FlatFilePos>::iterator it = range.first; std::multimap<uint256, FlatFilePos>::iterator it = range.first;
std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
if (ReadBlockFromDisk(*pblockrecursive, it->second, chainparams.GetConsensus())) if (ReadBlockFromDisk(*pblockrecursive, it->second, m_params.GetConsensus())) {
{
LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(), LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
head.ToString()); head.ToString());
LOCK(cs_main); LOCK(cs_main);
BlockValidationState dummy; BlockValidationState dummy;
if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr)) if (AcceptBlock(pblockrecursive, dummy, nullptr, true, &it->second, nullptr)) {
{
nLoaded++; nLoaded++;
queue.push_back(pblockrecursive->GetHash()); queue.push_back(pblockrecursive->GetHash());
} }
@ -4297,7 +4303,7 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart); LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
} }
void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams) void CChainState::CheckBlockIndex()
{ {
if (!fCheckBlockIndex) { if (!fCheckBlockIndex) {
return; return;
@ -4351,7 +4357,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// Begin: actual consistency checks. // Begin: actual consistency checks.
if (pindex->pprev == nullptr) { if (pindex->pprev == nullptr) {
// Genesis block checks. // Genesis block checks.
assert(pindex->GetBlockHash() == consensusParams.hashGenesisBlock); // Genesis block's hash must match. assert(pindex->GetBlockHash() == m_params.GetConsensus().hashGenesisBlock); // Genesis block's hash must match.
assert(pindex == m_chain.Genesis()); // The current active chain's genesis block must be this block. assert(pindex == m_chain.Genesis()); // The current active chain's genesis block must be this block.
} }
if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock) if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock)
@ -4511,10 +4517,10 @@ bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
if (coinstip_size > old_coinstip_size) { if (coinstip_size > old_coinstip_size) {
// Likely no need to flush if cache sizes have grown. // Likely no need to flush if cache sizes have grown.
ret = FlushStateToDisk(m_params, state, FlushStateMode::IF_NEEDED); ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
} else { } else {
// Otherwise, flush state to disk and deallocate the in-memory coins map. // Otherwise, flush state to disk and deallocate the in-memory coins map.
ret = FlushStateToDisk(m_params, state, FlushStateMode::ALWAYS); ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
CoinsTip().ReallocateCache(); CoinsTip().ReallocateCache();
} }
return ret; return ret;
@ -4814,7 +4820,7 @@ bool ChainstateManager::ActivateSnapshot(
LOCK(::cs_main); LOCK(::cs_main);
assert(!m_snapshot_chainstate); assert(!m_snapshot_chainstate);
m_snapshot_chainstate.swap(snapshot_chainstate); m_snapshot_chainstate.swap(snapshot_chainstate);
const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip(::Params()); const bool chaintip_loaded = m_snapshot_chainstate->LoadChainTip();
assert(chaintip_loaded); assert(chaintip_loaded);
m_active_chainstate = m_snapshot_chainstate.get(); m_active_chainstate = m_snapshot_chainstate.get();

View file

@ -682,7 +682,7 @@ public:
EXCLUSIVE_LOCKS_REQUIRED(::cs_main); EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** Import blocks from an external file */ /** Import blocks from an external file */
void LoadExternalBlockFile(const CChainParams& chainparams, FILE* fileIn, FlatFilePos* dbp = nullptr); void LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp = nullptr);
/** /**
* Update the on-disk chain state. * Update the on-disk chain state.
@ -696,8 +696,7 @@ public:
* @returns true unless a system error occurred * @returns true unless a system error occurred
*/ */
bool FlushStateToDisk( bool FlushStateToDisk(
const CChainParams& chainparams, BlockValidationState& state,
BlockValidationState &state,
FlushStateMode mode, FlushStateMode mode,
int nManualPruneHeight = 0); int nManualPruneHeight = 0);
@ -725,37 +724,36 @@ public:
*/ */
bool ActivateBestChain( bool ActivateBestChain(
BlockValidationState& state, BlockValidationState& state,
const CChainParams& chainparams,
std::shared_ptr<const CBlock> pblock = nullptr) LOCKS_EXCLUDED(cs_main); std::shared_ptr<const CBlock> pblock = nullptr) LOCKS_EXCLUDED(cs_main);
bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Block (dis)connection on a given view: // Block (dis)connection on a given view:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view); DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view);
bool ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex, bool ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main); CCoinsViewCache& view, bool fJustCheck = false) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
// Apply the effects of a block disconnection on the UTXO set. // Apply the effects of a block disconnection on the UTXO set.
bool DisconnectTip(BlockValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs); bool DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
// Manual block validity manipulation: // Manual block validity manipulation:
/** Mark a block as precious and reorganize. /** Mark a block as precious and reorganize.
* *
* May not be called in a validationinterface callback. * May not be called in a validationinterface callback.
*/ */
bool PreciousBlock(BlockValidationState& state, const CChainParams& params, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); bool PreciousBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
/** Mark a block as invalid. */ /** Mark a block as invalid. */
bool InvalidateBlock(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main); bool InvalidateBlock(BlockValidationState& state, CBlockIndex* pindex) LOCKS_EXCLUDED(cs_main);
/** Remove invalidity status from a block and its descendants. */ /** Remove invalidity status from a block and its descendants. */
void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Replay blocks that aren't fully applied to the database. */ /** Replay blocks that aren't fully applied to the database. */
bool ReplayBlocks(const CChainParams& params); bool ReplayBlocks();
/** Whether the chain state needs to be redownloaded due to lack of witness data */ /** Whether the chain state needs to be redownloaded due to lack of witness data */
[[nodiscard]] bool NeedsRedownload(const CChainParams& params) const EXCLUSIVE_LOCKS_REQUIRED(cs_main); [[nodiscard]] bool NeedsRedownload() const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Ensures we have a genesis block in the block tree, possibly writing one to disk. */ /** Ensures we have a genesis block in the block tree, possibly writing one to disk. */
bool LoadGenesisBlock(const CChainParams& chainparams); bool LoadGenesisBlock();
void PruneBlockIndexCandidates(); void PruneBlockIndexCandidates();
@ -769,13 +767,13 @@ public:
* *
* By default this only executes fully when using the Regtest chain; see: fCheckBlockIndex. * By default this only executes fully when using the Regtest chain; see: fCheckBlockIndex.
*/ */
void CheckBlockIndex(const Consensus::Params& consensusParams); void CheckBlockIndex();
/** Load the persisted mempool from disk */ /** Load the persisted mempool from disk */
void LoadMempool(const ArgsManager& args); void LoadMempool(const ArgsManager& args);
/** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */ /** Update the chain tip based on database information, i.e. CoinsTip()'s best block. */
bool LoadChainTip(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool LoadChainTip() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
//! Dictates whether we need to flush the cache to disk or not. //! Dictates whether we need to flush the cache to disk or not.
//! //!
@ -791,19 +789,19 @@ public:
std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
private: private:
bool ActivateBestChainStep(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs); bool ActivateBestChainStep(BlockValidationState& state, CBlockIndex* pindexMostWork, const std::shared_ptr<const CBlock>& pblock, bool& fInvalidFound, ConnectTrace& connectTrace) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
bool ConnectTip(BlockValidationState& state, const CChainParams& chainparams, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs); bool ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew, const std::shared_ptr<const CBlock>& pblock, ConnectTrace& connectTrace, DisconnectedBlockTransactions& disconnectpool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool.cs);
void InvalidBlockFound(CBlockIndex *pindex, const BlockValidationState &state) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void InvalidBlockFound(CBlockIndex* pindex, const BlockValidationState& state) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main); CBlockIndex* FindMostWorkChain() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos, const Consensus::Params& consensusParams) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pindexNew, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main); void CheckForkWarningConditions() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
void InvalidChainFound(CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main); void InvalidChainFound(CBlockIndex* pindexNew) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
bool LoadBlockIndexDB(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
friend ChainstateManager; friend ChainstateManager;
}; };
@ -1004,7 +1002,7 @@ public:
bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main); bool ProcessNewBlockHeaders(const std::vector<CBlockHeader>& block, BlockValidationState& state, const CChainParams& chainparams, const CBlockIndex** ppindex = nullptr) LOCKS_EXCLUDED(cs_main);
//! Load the block tree and coins database from disk, initializing state if we're running with -reindex //! Load the block tree and coins database from disk, initializing state if we're running with -reindex
bool LoadBlockIndex(const CChainParams& chainparams) EXCLUSIVE_LOCKS_REQUIRED(cs_main); bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
//! Unload block index and chain data before shutdown. //! Unload block index and chain data before shutdown.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main); void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);