0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-02 09:46:52 -05:00

Merge bitcoin/bitcoin#21789: refactor: Remove ::Params() global from CChainState

fa0d9211ef refactor: Remove chainparams arg from CChainState member functions (MarcoFalke)
fa38947125 refactor: Remove ::Params() global from inside CChainState member functions (MarcoFalke)

Pull request description:

  The `::Params()` global is verbose and confusing. Also it makes tests a bit harder to write because they'd have to mock a global.

  Fix all issues by simply using a member variable that points to the right params.

  (Can be reviewed with `--word-diff-regex=.`)

ACKs for top commit:
  jnewbery:
    ACK fa0d9211ef
  kiminuo:
    utACK fa0d9211
  theStack:
    ACK fa0d9211ef 🍉

Tree-SHA512: 44676b19c9ed471ccb536331d3029bad192d7d50f394fd7b8527ec431452aeec8c4494164b9cf8e16e0123c4463b16be864366c6b599370032c17262625a0356
This commit is contained in:
fanquake 2021-06-29 09:50:14 +08:00
commit 8071ec179d
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
10 changed files with 149 additions and 147 deletions

View file

@ -1372,7 +1372,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
// block file from disk.
// Note that it also sets fReindex based on the disk flag!
// From here on out fReindex and fReset mean something different!
if (!chainman.LoadBlockIndex(chainparams)) {
if (!chainman.LoadBlockIndex()) {
if (ShutdownRequested()) break;
strLoadError = _("Error loading block database");
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
// (otherwise we use the one already on disk).
// 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");
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
if (!chainstate->ReplayBlocks(chainparams)) {
if (!chainstate->ReplayBlocks()) {
strLoadError = _("Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.");
failed_chainstate_init = true;
break;
@ -1439,7 +1439,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
if (!is_coinsview_empty(chainstate)) {
// LoadChainTip initializes the chain based on CoinsTip()'s best block
if (!chainstate->LoadChainTip(chainparams)) {
if (!chainstate->LoadChainTip()) {
strLoadError = _("Error initializing block database");
failed_chainstate_init = true;
break; // out of the per-chainstate loop
@ -1461,7 +1461,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
LOCK(cs_main);
auto chainstates{chainman.GetAll()};
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."),
chainparams.GetConsensus().SegwitHeight);
break;

View file

@ -1709,7 +1709,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
} // release cs_main before calling ActivateBestChain
if (need_activate_chain) {
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());
}
}
@ -2935,7 +2935,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
a_recent_block = most_recent_block;
}
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());
}
}

View file

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

View file

@ -1706,7 +1706,7 @@ static RPCHelpMan preciousblock()
}
BlockValidationState state;
chainman.ActiveChainstate().PreciousBlock(state, Params(), pblockindex);
chainman.ActiveChainstate().PreciousBlock(state, pblockindex);
if (!state.IsValid()) {
throw JSONRPCError(RPC_DATABASE_ERROR, state.ToString());
@ -1743,10 +1743,10 @@ static RPCHelpMan invalidateblock()
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
}
}
chainman.ActiveChainstate().InvalidateBlock(state, Params(), pblockindex);
chainman.ActiveChainstate().InvalidateBlock(state, pblockindex);
if (state.IsValid()) {
chainman.ActiveChainstate().ActivateBestChain(state, Params());
chainman.ActiveChainstate().ActivateBestChain(state);
}
if (!state.IsValid()) {
@ -1787,7 +1787,7 @@ static RPCHelpMan reconsiderblock()
}
BlockValidationState state;
chainman.ActiveChainstate().ActivateBestChain(state, Params());
chainman.ActiveChainstate().ActivateBestChain(state);
if (!state.IsValid()) {
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;
}
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();
for (int i = 0; i < 10; ++i) {
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);
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());
m_node.chainman->ActiveChainstate().InitCoinsCache(1 << 23);
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.");
}
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()));
}

View file

@ -31,7 +31,6 @@ BOOST_AUTO_TEST_CASE(chainstatemanager)
CTxMemPool& mempool = *m_node.mempool;
std::vector<CChainState*> chainstates;
const CChainParams& chainparams = Params();
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);
WITH_LOCK(::cs_main, c2.InitCoinsCache(1 << 23));
// Unlike c1, which doesn't have any blocks. Gets us different tip, height.
c2.LoadGenesisBlock(chainparams);
c2.LoadGenesisBlock();
BlockValidationState _;
BOOST_CHECK(c2.ActivateBestChain(_, chainparams, nullptr));
BOOST_CHECK(c2.ActivateBestChain(_, nullptr));
BOOST_CHECK(manager.IsSnapshotActive());
BOOST_CHECK(!manager.IsSnapshotValidated());
@ -138,7 +137,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
{
LOCK(::cs_main);
c1.InitCoinsCache(1 << 23);
BOOST_REQUIRE(c1.LoadGenesisBlock(Params()));
BOOST_REQUIRE(c1.LoadGenesisBlock());
c1.CoinsTip().SetBestBlock(InsecureRand256());
manager.MaybeRebalanceCaches();
}
@ -156,7 +155,7 @@ BOOST_AUTO_TEST_CASE(chainstatemanager_rebalance_caches)
{
LOCK(::cs_main);
c2.InitCoinsCache(1 << 23);
BOOST_REQUIRE(c2.LoadGenesisBlock(Params()));
BOOST_REQUIRE(c2.LoadGenesisBlock());
c2.CoinsTip().SetBestBlock(InsecureRand256());
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
BlockValidationState state_dummy;
active_chainstate.FlushStateToDisk(chainparams, state_dummy, FlushStateMode::PERIODIC);
active_chainstate.FlushStateToDisk(state_dummy, FlushStateMode::PERIODIC);
return result;
}
@ -1210,6 +1210,7 @@ void CoinsViews::InitCache()
CChainState::CChainState(CTxMemPool& mempool, BlockManager& blockman, std::optional<uint256> from_snapshot_blockhash)
: m_mempool(mempool),
m_params(::Params()),
m_blockman(blockman),
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
@ -1724,7 +1725,7 @@ static int64_t nBlocksTotal = 0;
* Validity checks that depend on the UTXO set are also done; ConnectBlock()
* can fail if those validity checks fail (among other reasons). */
bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CBlockIndex* pindex,
CCoinsViewCache& view, const CChainParams& chainparams, bool fJustCheck)
CCoinsViewCache& view, bool fJustCheck)
{
AssertLockHeld(cs_main);
assert(pindex);
@ -1744,7 +1745,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// is enforced in ContextualCheckBlockHeader(); we wouldn't want to
// re-enforce that rule here (at least until we make it impossible for
// 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) {
// We don't write down blocks to disk if they may have been
// corrupted, so this should be impossible unless we're having hardware
@ -1762,7 +1763,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Special case for the genesis block, skipping connection of its transactions
// (its coinbase is unspendable)
if (block.GetHash() == chainparams.GetConsensus().hashGenesisBlock) {
if (block.GetHash() == m_params.GetConsensus().hashGenesisBlock) {
if (!fJustCheck)
view.SetBestBlock(pindex->GetBlockHash());
return true;
@ -1794,7 +1795,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// artificially set the default assumed verified block further back.
// The test against nMinimumChainWork prevents the skipping when denied access to any chain at
// 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);
}
}
}
@ -1874,9 +1875,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// be reset before it reaches block 1,983,702 and starts doing unnecessary
// BIP30 checking again.
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.
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
// consensus change that ensures coinbases at those heights can not
@ -1894,12 +1895,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
// Start enforcing BIP68 (sequence locks)
int nLockTimeFlags = 0;
if (pindex->nHeight >= chainparams.GetConsensus().CSVHeight) {
if (pindex->nHeight >= m_params.GetConsensus().CSVHeight) {
nLockTimeFlags |= LOCKTIME_VERIFY_SEQUENCE;
}
// 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;
LogPrint(BCLog::BENCH, " - Fork checks: %.2fms [%.2fs (%.2fms/blk)]\n", MILLI * (nTime2 - nTime1), nTimeForks * MICRO, nTimeForks * MILLI / nBlocksTotal);
@ -1989,7 +1990,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
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);
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, chainparams.GetConsensus());
CAmount blockReward = nFees + GetBlockSubsidy(pindex->nHeight, m_params.GetConsensus());
if (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");
@ -2005,8 +2006,9 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
if (fJustCheck)
return true;
if (!WriteUndoDataForBlock(blockundo, state, pindex, chainparams))
if (!WriteUndoDataForBlock(blockundo, state, pindex, m_params)) {
return false;
}
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
@ -2059,7 +2061,6 @@ CoinsCacheSizeState CChainState::GetCoinsCacheSizeState(
}
bool CChainState::FlushStateToDisk(
const CChainParams& chainparams,
BlockValidationState &state,
FlushStateMode mode,
int nManualPruneHeight)
@ -2096,7 +2097,7 @@ bool CChainState::FlushStateToDisk(
} else {
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;
}
if (!setFilesToPrune.empty()) {
@ -2196,20 +2197,19 @@ bool CChainState::FlushStateToDisk(
return true;
}
void CChainState::ForceFlushStateToDisk() {
void CChainState::ForceFlushStateToDisk()
{
BlockValidationState state;
const CChainParams& chainparams = Params();
if (!this->FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS)) {
if (!this->FlushStateToDisk(state, FlushStateMode::ALWAYS)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
}
}
void CChainState::PruneAndFlush() {
void CChainState::PruneAndFlush()
{
BlockValidationState state;
fCheckForPruning = true;
const CChainParams& chainparams = Params();
if (!this->FlushStateToDisk(chainparams, state, FlushStateMode::NONE)) {
if (!this->FlushStateToDisk(state, FlushStateMode::NONE)) {
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
* in any case).
*/
bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams& chainparams, DisconnectedBlockTransactions* disconnectpool)
bool CChainState::DisconnectTip(BlockValidationState& state, DisconnectedBlockTransactions* disconnectpool)
{
AssertLockHeld(cs_main);
AssertLockHeld(m_mempool.cs);
@ -2288,8 +2288,9 @@ bool CChainState::DisconnectTip(BlockValidationState& state, const CChainParams&
// Read block from disk.
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock& block = *pblock;
if (!ReadBlockFromDisk(block, pindexDelete, chainparams.GetConsensus()))
if (!ReadBlockFromDisk(block, pindexDelete, m_params.GetConsensus())) {
return error("DisconnectTip(): Failed to read block");
}
// Apply the block atomically to the chain state.
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);
// Write the chain state to disk, if necessary.
if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
return false;
}
if (disconnectpool) {
// 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);
UpdateTip(m_mempool, pindexDelete->pprev, chainparams, *this);
UpdateTip(m_mempool, pindexDelete->pprev, m_params, *this);
// Let wallets know transactions went from 1-confirmed to
// 0-confirmed or conflicted:
GetMainSignals().BlockDisconnected(pblock, pindexDelete);
@ -2379,7 +2381,7 @@ public:
*
* 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(m_mempool.cs);
@ -2390,8 +2392,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
std::shared_ptr<const CBlock> pthisBlock;
if (!pblock) {
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");
}
pthisBlock = pblockNew;
} else {
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);
{
CCoinsViewCache view(&CoinsTip());
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view, chainparams);
bool rv = ConnectBlock(blockConnecting, state, pindexNew, view);
GetMainSignals().BlockChecked(blockConnecting, state);
if (!rv) {
if (state.IsInvalid())
@ -2419,8 +2422,9 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
int64_t nTime4 = GetTimeMicros(); nTimeFlush += nTime4 - nTime3;
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.
if (!FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED))
if (!FlushStateToDisk(state, FlushStateMode::IF_NEEDED)) {
return false;
}
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);
// Remove conflicting transactions from the mempool.;
@ -2428,7 +2432,7 @@ bool CChainState::ConnectTip(BlockValidationState& state, const CChainParams& ch
disconnectpool.removeForBlock(blockConnecting.vtx);
// Update m_chain & related variables.
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;
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
*/
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(m_mempool.cs);
@ -2527,7 +2531,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
bool fBlocksDisconnected = false;
DisconnectedBlockTransactions disconnectpool;
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,
// just in case. Only remove from the mempool in this case.
UpdateMempoolForReorg(*this, m_mempool, disconnectpool, false);
@ -2560,7 +2564,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, const CChai
// Connect new blocks.
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()) {
// The block violates a consensus rule.
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
// 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
@ -2683,7 +2688,7 @@ bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainPar
bool fInvalidFound = false;
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
return false;
}
@ -2725,17 +2730,17 @@ bool CChainState::ActivateBestChain(BlockValidationState &state, const CChainPar
// that the best block hash is non-null.
if (ShutdownRequested()) break;
} while (pindexNewTip != pindexMostWork);
CheckBlockIndex(chainparams.GetConsensus());
CheckBlockIndex();
// Write changes periodically to disk, after relay.
if (!FlushStateToDisk(chainparams, state, FlushStateMode::PERIODIC)) {
if (!FlushStateToDisk(state, FlushStateMode::PERIODIC)) {
return false;
}
return true;
}
bool CChainState::PreciousBlock(BlockValidationState& state, const CChainParams& params, CBlockIndex *pindex)
bool CChainState::PreciousBlock(BlockValidationState& state, CBlockIndex* pindex)
{
{
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
assert(pindex);
@ -2822,7 +2827,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, const CChainParam
// ActivateBestChain considers blocks already in m_chain
// unconditionally valid already, so force disconnect away from it.
DisconnectedBlockTransactions disconnectpool;
bool ret = DisconnectTip(state, chainparams, &disconnectpool);
bool ret = DisconnectTip(state, &disconnectpool);
// DisconnectTip will add transactions to disconnectpool.
// Adjust the mempool to be consistent with the new tip, adding
// 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;
}
CheckBlockIndex(chainparams.GetConsensus());
CheckBlockIndex();
{
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). */
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->nChainTx = 0;
@ -2983,7 +2988,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
pindexNew->nDataPos = pos.nPos;
pindexNew->nUndoPos = 0;
pindexNew->nStatus |= BLOCK_HAVE_DATA;
if (IsWitnessEnabled(pindexNew->pprev, consensusParams)) {
if (IsWitnessEnabled(pindexNew->pprev, m_params.GetConsensus())) {
pindexNew->nStatus |= BLOCK_OPT_WITNESS;
}
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
bool accepted = m_blockman.AcceptBlockHeader(
header, state, chainparams, &pindex);
ActiveChainstate().CheckBlockIndex(chainparams.GetConsensus());
ActiveChainstate().CheckBlockIndex();
if (!accepted) {
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 */
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;
@ -3429,8 +3434,8 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
CBlockIndex *pindexDummy = nullptr;
CBlockIndex *&pindex = ppindex ? *ppindex : pindexDummy;
bool accepted_header = m_blockman.AcceptBlockHeader(block, state, chainparams, &pindex);
CheckBlockIndex(chainparams.GetConsensus());
bool accepted_header = m_blockman.AcceptBlockHeader(block, state, m_params, &pindex);
CheckBlockIndex();
if (!accepted_header)
return false;
@ -3467,8 +3472,8 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
if (pindex->nChainWork < nMinimumChainWork) return true;
}
if (!CheckBlock(block, state, chainparams.GetConsensus()) ||
!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindex->pprev)) {
if (!CheckBlock(block, state, m_params.GetConsensus()) ||
!ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) {
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindex);
@ -3484,19 +3489,19 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file
if (fNewBlock) *fNewBlock = true;
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()) {
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
return false;
}
ReceivedBlockTransactions(block, pindex, blockPos, chainparams.GetConsensus());
ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) {
return AbortNode(state, std::string("System error: ") + e.what());
}
FlushStateToDisk(chainparams, state, FlushStateMode::NONE);
FlushStateToDisk(state, FlushStateMode::NONE);
CheckBlockIndex(chainparams.GetConsensus());
CheckBlockIndex();
return true;
}
@ -3522,7 +3527,7 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
bool ret = CheckBlock(*block, state, chainparams.GetConsensus());
if (ret) {
// 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) {
GetMainSignals().BlockChecked(*block, state);
@ -3533,8 +3538,9 @@ bool ChainstateManager::ProcessNewBlock(const CChainParams& chainparams, const s
NotifyHeaderTip(ActiveChainstate());
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 true;
}
@ -3563,8 +3569,9 @@ bool TestBlockValidity(BlockValidationState& state,
return error("%s: Consensus::CheckBlock: %s", __func__, state.ToString());
if (!ContextualCheckBlock(block, state, chainparams.GetConsensus(), pindexPrev))
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;
}
assert(state.IsValid());
return true;
@ -3635,9 +3642,8 @@ void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nM
void PruneBlockFilesManual(CChainState& active_chainstate, int nManualPruneHeight)
{
BlockValidationState state;
const CChainParams& chainparams = Params();
if (!active_chainstate.FlushStateToDisk(
chainparams, state, FlushStateMode::NONE, nManualPruneHeight)) {
state, FlushStateMode::NONE, nManualPruneHeight)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
}
}
@ -3787,10 +3793,10 @@ void BlockManager::Unload() {
m_block_index.clear();
}
bool CChainState::LoadBlockIndexDB(const CChainParams& chainparams)
bool CChainState::LoadBlockIndexDB()
{
if (!m_blockman.LoadBlockIndex(
chainparams.GetConsensus(), *pblocktree,
m_params.GetConsensus(), *pblocktree,
setBlockIndexCandidates)) {
return false;
}
@ -3850,7 +3856,7 @@ void CChainState::LoadMempool(const ArgsManager& args)
m_mempool.SetIsLoaded(!ShutdownRequested());
}
bool CChainState::LoadChainTip(const CChainParams& chainparams)
bool CChainState::LoadChainTip()
{
AssertLockHeld(cs_main);
const CCoinsViewCache& coins_cache = CoinsTip();
@ -3871,10 +3877,10 @@ bool CChainState::LoadChainTip(const CChainParams& chainparams)
tip = m_chain.Tip();
LogPrintf("Loaded best chain: hashBestChain=%s height=%d date=%s progress=%f\n",
tip->GetBlockHash().ToString(),
m_chain.Height(),
FormatISO8601DateTime(tip->GetBlockTime()),
GuessVerificationProgress(chainparams.TxData(), tip));
tip->GetBlockHash().ToString(),
m_chain.Height(),
FormatISO8601DateTime(tip->GetBlockTime()),
GuessVerificationProgress(m_params.TxData(), tip));
return true;
}
@ -3985,8 +3991,9 @@ bool CVerifyDB::VerifyDB(
CBlock block;
if (!ReadBlockFromDisk(block, pindex, chainparams.GetConsensus()))
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());
}
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. */
bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs, const CChainParams& params)
bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& inputs)
{
// TODO: merge with ConnectBlock
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());
}
@ -4018,7 +4025,7 @@ bool CChainState::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& i
return true;
}
bool CChainState::ReplayBlocks(const CChainParams& params)
bool CChainState::ReplayBlocks()
{
LOCK(cs_main);
@ -4054,7 +4061,7 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
while (pindexOld != pindexFork) {
if (pindexOld->nHeight > 0) { // Never disconnect the genesis 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());
}
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);
LogPrintf("Rolling forward %s (%i)\n", pindex->GetBlockHash().ToString(), nHeight);
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());
@ -4085,13 +4092,13 @@ bool CChainState::ReplayBlocks(const CChainParams& params)
return true;
}
bool CChainState::NeedsRedownload(const CChainParams& params) const
bool CChainState::NeedsRedownload() const
{
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()};
const int segwit_height{params.GetConsensus().SegwitHeight};
const int segwit_height{m_params.GetConsensus().SegwitHeight};
while (block != nullptr && block->nHeight >= segwit_height) {
if (!(block->nStatus & BLOCK_OPT_WITNESS)) {
@ -4130,13 +4137,13 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
fHavePruned = false;
}
bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams)
bool ChainstateManager::LoadBlockIndex()
{
AssertLockHeld(cs_main);
// Load block index from databases
bool needs_init = fReindex;
if (!fReindex) {
bool ret = ActiveChainstate().LoadBlockIndexDB(chainparams);
bool ret = ActiveChainstate().LoadBlockIndexDB();
if (!ret) return false;
needs_init = m_blockman.m_block_index.empty();
}
@ -4153,7 +4160,7 @@ bool ChainstateManager::LoadBlockIndex(const CChainParams& chainparams)
return true;
}
bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
bool CChainState::LoadGenesisBlock()
{
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
// set based on the coins db, not the block index db, which is the only
// 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;
try {
const CBlock& block = chainparams.GenesisBlock();
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, chainparams, nullptr);
const CBlock& block = m_params.GenesisBlock();
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr);
if (blockPos.IsNull())
return error("%s: writing genesis block to disk failed", __func__);
CBlockIndex *pindex = m_blockman.AddToBlockIndex(block);
ReceivedBlockTransactions(block, pindex, blockPos, chainparams.GetConsensus());
ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) {
return error("%s: failed to write genesis block: %s", __func__, e.what());
}
@ -4178,7 +4185,7 @@ bool CChainState::LoadGenesisBlock(const CChainParams& chainparams)
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)
static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
@ -4199,11 +4206,12 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
try {
// locate a header
unsigned char buf[CMessageHeader::MESSAGE_START_SIZE];
blkdat.FindByte(chainparams.MessageStart()[0]);
blkdat.FindByte(m_params.MessageStart()[0]);
nRewind = blkdat.GetPos()+1;
blkdat >> buf;
if (memcmp(buf, chainparams.MessageStart(), CMessageHeader::MESSAGE_START_SIZE))
if (memcmp(buf, m_params.MessageStart(), CMessageHeader::MESSAGE_START_SIZE)) {
continue;
}
// read size
blkdat >> nSize;
if (nSize < 80 || nSize > MAX_BLOCK_SERIALIZED_SIZE)
@ -4227,7 +4235,7 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
{
LOCK(cs_main);
// 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(),
block.hashPrevBlock.ToString());
if (dbp)
@ -4239,21 +4247,21 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
CBlockIndex* pindex = m_blockman.LookupBlockIndex(hash);
if (!pindex || (pindex->nStatus & BLOCK_HAVE_DATA) == 0) {
BlockValidationState state;
if (AcceptBlock(pblock, state, chainparams, nullptr, true, dbp, nullptr)) {
if (AcceptBlock(pblock, state, nullptr, true, dbp, nullptr)) {
nLoaded++;
}
if (state.IsError()) {
break;
}
} else if (hash != chainparams.GetConsensus().hashGenesisBlock && pindex->nHeight % 1000 == 0) {
LogPrint(BCLog::REINDEX, "Block Import: already had block %s at height %d\n", hash.ToString(), pindex->nHeight);
} 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);
}
}
// Activate the genesis block so normal node progress can continue
if (hash == chainparams.GetConsensus().hashGenesisBlock) {
if (hash == m_params.GetConsensus().hashGenesisBlock) {
BlockValidationState state;
if (!ActivateBestChain(state, chainparams, nullptr)) {
if (!ActivateBestChain(state, nullptr)) {
break;
}
}
@ -4270,14 +4278,12 @@ void CChainState::LoadExternalBlockFile(const CChainParams& chainparams, FILE* f
while (range.first != range.second) {
std::multimap<uint256, FlatFilePos>::iterator it = range.first;
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(),
head.ToString());
LOCK(cs_main);
BlockValidationState dummy;
if (AcceptBlock(pblockrecursive, dummy, chainparams, nullptr, true, &it->second, nullptr))
{
if (AcceptBlock(pblockrecursive, dummy, nullptr, true, &it->second, nullptr)) {
nLoaded++;
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);
}
void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
void CChainState::CheckBlockIndex()
{
if (!fCheckBlockIndex) {
return;
@ -4351,7 +4357,7 @@ void CChainState::CheckBlockIndex(const Consensus::Params& consensusParams)
// Begin: actual consistency checks.
if (pindex->pprev == nullptr) {
// 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.
}
if (!pindex->HaveTxsDownloaded()) assert(pindex->nSequenceId <= 0); // nSequenceId can't be set positive for blocks that aren't linked (negative is used for preciousblock)
@ -4507,16 +4513,14 @@ bool CChainState::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
this->ToString(), coinstip_size * (1.0 / 1024 / 1024));
BlockValidationState state;
const CChainParams& chainparams = Params();
bool ret;
if (coinstip_size > old_coinstip_size) {
// Likely no need to flush if cache sizes have grown.
ret = FlushStateToDisk(chainparams, state, FlushStateMode::IF_NEEDED);
ret = FlushStateToDisk(state, FlushStateMode::IF_NEEDED);
} else {
// Otherwise, flush state to disk and deallocate the in-memory coins map.
ret = FlushStateToDisk(chainparams, state, FlushStateMode::ALWAYS);
ret = FlushStateToDisk(state, FlushStateMode::ALWAYS);
CoinsTip().ReallocateCache();
}
return ret;
@ -4816,7 +4820,7 @@ bool ChainstateManager::ActivateSnapshot(
LOCK(::cs_main);
assert(!m_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);
m_active_chainstate = m_snapshot_chainstate.get();

View file

@ -595,6 +595,8 @@ protected:
//! mempool that is kept in sync with the chain
CTxMemPool& m_mempool;
const CChainParams& m_params;
//! Manages the UTXO set, which is a reflection of the contents of `m_chain`.
std::unique_ptr<CoinsViews> m_coins_views;
@ -680,7 +682,7 @@ public:
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** 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.
@ -694,8 +696,7 @@ public:
* @returns true unless a system error occurred
*/
bool FlushStateToDisk(
const CChainParams& chainparams,
BlockValidationState &state,
BlockValidationState& state,
FlushStateMode mode,
int nManualPruneHeight = 0);
@ -723,37 +724,36 @@ public:
*/
bool ActivateBestChain(
BlockValidationState& state,
const CChainParams& chainparams,
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:
DisconnectResult DisconnectBlock(const CBlock& block, const CBlockIndex* pindex, CCoinsViewCache& view);
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.
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:
/** Mark a block as precious and reorganize.
*
* 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. */
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. */
void ResetBlockFailureFlags(CBlockIndex* pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** 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 */
[[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. */
bool LoadGenesisBlock(const CChainParams& chainparams);
bool LoadGenesisBlock();
void PruneBlockIndexCandidates();
@ -767,13 +767,13 @@ public:
*
* 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 */
void LoadMempool(const ArgsManager& args);
/** 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.
//!
@ -789,19 +789,19 @@ public:
std::string ToString() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
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 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 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, 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);
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 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;
};
@ -1002,7 +1002,7 @@ public:
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
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.
void Unload() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);