diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/init.cpp | 4 | ||||
-rw-r--r-- | src/interfaces/mining.h | 25 | ||||
-rw-r--r-- | src/ipc/capnp/mining.capnp | 3 | ||||
-rw-r--r-- | src/node/interfaces.cpp | 37 | ||||
-rw-r--r-- | src/node/kernel_notifications.cpp | 8 | ||||
-rw-r--r-- | src/node/kernel_notifications.h | 4 | ||||
-rw-r--r-- | src/node/types.h | 2 | ||||
-rw-r--r-- | src/rpc/blockchain.cpp | 4 | ||||
-rw-r--r-- | src/rpc/mining.cpp | 29 | ||||
-rw-r--r-- | src/test/fuzz/util/check_globals.cpp | 6 | ||||
-rw-r--r-- | src/test/fuzz/utxo_total_supply.cpp | 2 | ||||
-rw-r--r-- | src/test/util/mining.cpp | 2 | ||||
-rw-r--r-- | src/test/validation_chainstate_tests.cpp | 3 | ||||
-rw-r--r-- | src/validation.cpp | 21 | ||||
-rw-r--r-- | src/validation.h | 6 |
15 files changed, 59 insertions, 97 deletions
diff --git a/src/init.cpp b/src/init.cpp index 03af3dfb23..f4b842bebb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1807,7 +1807,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) { WAIT_LOCK(kernel_notifications.m_tip_block_mutex, lock); kernel_notifications.m_tip_block_cv.wait(lock, [&]() EXCLUSIVE_LOCKS_REQUIRED(kernel_notifications.m_tip_block_mutex) { - return !kernel_notifications.m_tip_block.IsNull() || ShutdownRequested(node); + return kernel_notifications.TipBlock() || ShutdownRequested(node); }); } @@ -1827,7 +1827,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) if (tip_info) { tip_info->block_height = chain_active_height; tip_info->block_time = best_block_time; - tip_info->verification_progress = GuessVerificationProgress(chainman.GetParams().TxData(), &tip); + tip_info->verification_progress = chainman.GuessVerificationProgress(&tip); } if (tip_info && chainman.m_best_header) { tip_info->header_height = chainman.m_best_header->nHeight; diff --git a/src/interfaces/mining.h b/src/interfaces/mining.h index dd5cfe5ccc..bc5955ded6 100644 --- a/src/interfaces/mining.h +++ b/src/interfaces/mining.h @@ -93,31 +93,6 @@ public: */ virtual std::unique_ptr<BlockTemplate> createNewBlock(const node::BlockCreateOptions& options = {}) = 0; - /** - * Processes new block. A valid new block is automatically relayed to peers. - * - * @param[in] block The block we want to process. - * @param[out] new_block A boolean which is set to indicate if the block was first received via this call - * @returns If the block was processed, independently of block validity - */ - virtual bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) = 0; - - //! Return the number of transaction updates in the mempool, - //! used to decide whether to make a new block template. - virtual unsigned int getTransactionsUpdated() = 0; - - /** - * Check a block is completely valid from start to finish. - * Only works on top of our current best block. - * Does not check proof-of-work. - * - * @param[in] block the block to validate - * @param[in] check_merkle_root call CheckMerkleRoot() - * @param[out] state details of why a block failed to validate - * @returns false if it does not build on the current tip, or any of the checks fail - */ - virtual bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) = 0; - //! Get internal node context. Useful for RPC and testing, //! but not accessible across processes. virtual node::NodeContext* context() { return nullptr; } diff --git a/src/ipc/capnp/mining.capnp b/src/ipc/capnp/mining.capnp index 5af37b725a..50b07bda70 100644 --- a/src/ipc/capnp/mining.capnp +++ b/src/ipc/capnp/mining.capnp @@ -18,9 +18,6 @@ interface Mining $Proxy.wrap("interfaces::Mining") { getTip @2 (context :Proxy.Context) -> (result: Common.BlockRef, hasResult: Bool); waitTipChanged @3 (context :Proxy.Context, currentTip: Data, timeout: Float64) -> (result: Common.BlockRef); createNewBlock @4 (options: BlockCreateOptions) -> (result: BlockTemplate); - processNewBlock @5 (context :Proxy.Context, block: Data) -> (newBlock: Bool, result: Bool); - getTransactionsUpdated @6 (context :Proxy.Context) -> (result: UInt32); - testBlockValidity @7 (context :Proxy.Context, block: Data, checkMerkleRoot: Bool) -> (state: BlockValidationState, result: Bool); } interface BlockTemplate $Proxy.wrap("interfaces::BlockTemplate") { diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 68fc17aa70..f3b8c6a072 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -324,7 +324,7 @@ public: } double getVerificationProgress() override { - return GuessVerificationProgress(chainman().GetParams().TxData(), WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip())); + return chainman().GuessVerificationProgress(WITH_LOCK(chainman().GetMutex(), return chainman().ActiveChain().Tip())); } bool isInitialBlockDownload() override { @@ -406,9 +406,9 @@ public: } std::unique_ptr<Handler> handleNotifyBlockTip(NotifyBlockTipFn fn) override { - return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn](SynchronizationState sync_state, const CBlockIndex* block) { + return MakeSignalHandler(::uiInterface.NotifyBlockTip_connect([fn, this](SynchronizationState sync_state, const CBlockIndex* block) { fn(sync_state, BlockTip{block->nHeight, block->GetBlockTime(), block->GetBlockHash()}, - GuessVerificationProgress(Params().TxData(), block)); + chainman().GuessVerificationProgress(block)); })); } std::unique_ptr<Handler> handleNotifyHeaderTip(NotifyHeaderTipFn fn) override @@ -639,8 +639,8 @@ public: void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); } double guessVerificationProgress(const uint256& block_hash) override { - LOCK(::cs_main); - return GuessVerificationProgress(chainman().GetParams().TxData(), chainman().m_blockman.LookupBlockIndex(block_hash)); + LOCK(chainman().GetMutex()); + return chainman().GuessVerificationProgress(chainman().m_blockman.LookupBlockIndex(block_hash)); } bool hasBlocks(const uint256& block_hash, int min_height, std::optional<int> max_height) override { @@ -971,7 +971,9 @@ public: { WAIT_LOCK(notifications().m_tip_block_mutex, lock); notifications().m_tip_block_cv.wait_for(lock, timeout, [&]() EXCLUSIVE_LOCKS_REQUIRED(notifications().m_tip_block_mutex) { - return (notifications().m_tip_block != current_tip && notifications().m_tip_block != uint256::ZERO) || chainman().m_interrupt; + // We need to wait for m_tip_block to be set AND for the value + // to differ from the current_tip value. + return (notifications().TipBlock() && notifications().TipBlock() != current_tip) || chainman().m_interrupt; }); } // Must release m_tip_block_mutex before locking cs_main, to avoid deadlocks. @@ -979,29 +981,6 @@ public: return BlockRef{chainman().ActiveChain().Tip()->GetBlockHash(), chainman().ActiveChain().Tip()->nHeight}; } - bool processNewBlock(const std::shared_ptr<const CBlock>& block, bool* new_block) override - { - return chainman().ProcessNewBlock(block, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/new_block); - } - - unsigned int getTransactionsUpdated() override - { - return context()->mempool->GetTransactionsUpdated(); - } - - bool testBlockValidity(const CBlock& block, bool check_merkle_root, BlockValidationState& state) override - { - LOCK(cs_main); - CBlockIndex* tip{chainman().ActiveChain().Tip()}; - // Fail if the tip updated before the lock was taken - if (block.hashPrevBlock != tip->GetBlockHash()) { - state.Error("Block does not connect to current chain tip."); - return false; - } - - return TestBlockValidity(state, chainman().GetParams(), chainman().ActiveChainstate(), block, tip, /*fCheckPOW=*/false, check_merkle_root); - } - std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options) override { BlockAssembler::Options assemble_options{options}; diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp index a09803165c..550ffe74c4 100644 --- a/src/node/kernel_notifications.cpp +++ b/src/node/kernel_notifications.cpp @@ -52,6 +52,7 @@ kernel::InterruptResult KernelNotifications::blockTip(SynchronizationState state { { LOCK(m_tip_block_mutex); + Assume(index.GetBlockHash() != uint256::ZERO); m_tip_block = index.GetBlockHash(); m_tip_block_cv.notify_all(); } @@ -99,6 +100,13 @@ void KernelNotifications::fatalError(const bilingual_str& message) m_exit_status, message, &m_warnings); } +std::optional<uint256> KernelNotifications::TipBlock() +{ + AssertLockHeld(m_tip_block_mutex); + return m_tip_block; +}; + + void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications) { if (auto value{args.GetIntArg("-stopatheight")}) notifications.m_stop_at_height = *value; diff --git a/src/node/kernel_notifications.h b/src/node/kernel_notifications.h index 35070b5285..f4174381da 100644 --- a/src/node/kernel_notifications.h +++ b/src/node/kernel_notifications.h @@ -59,12 +59,14 @@ public: //! The block for which the last blockTip notification was received. //! It's first set when the tip is connected during node initialization. //! Might be unset during an early shutdown. - uint256 m_tip_block GUARDED_BY(m_tip_block_mutex){uint256::ZERO}; + std::optional<uint256> TipBlock() EXCLUSIVE_LOCKS_REQUIRED(m_tip_block_mutex); private: const std::function<bool()>& m_shutdown_request; std::atomic<int>& m_exit_status; node::Warnings& m_warnings; + + std::optional<uint256> m_tip_block GUARDED_BY(m_tip_block_mutex); }; void ReadNotificationArgs(const ArgsManager& args, KernelNotifications& notifications); diff --git a/src/node/types.h b/src/node/types.h index 2fc66b892b..4b0de084ab 100644 --- a/src/node/types.h +++ b/src/node/types.h @@ -3,7 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. //! @file node/types.h is a home for public enum and struct type definitions -//! that are used by internally by node code, but also used externally by wallet, +//! that are used internally by node code, but also used externally by wallet, //! mining or GUI code. //! //! This file is intended to define only simple types that do not have external diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 41673ee21d..89e01bbf7f 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1336,7 +1336,7 @@ RPCHelpMan getblockchaininfo() obj.pushKV("difficulty", GetDifficulty(tip)); obj.pushKV("time", tip.GetBlockTime()); obj.pushKV("mediantime", tip.GetMedianTimePast()); - obj.pushKV("verificationprogress", GuessVerificationProgress(chainman.GetParams().TxData(), &tip)); + obj.pushKV("verificationprogress", chainman.GuessVerificationProgress(&tip)); obj.pushKV("initialblockdownload", chainman.IsInitialBlockDownload()); obj.pushKV("chainwork", tip.nChainWork.GetHex()); obj.pushKV("size_on_disk", chainman.m_blockman.CalculateCurrentUsage()); @@ -3338,7 +3338,7 @@ return RPCHelpMan{ data.pushKV("blocks", (int)chain.Height()); data.pushKV("bestblockhash", tip->GetBlockHash().GetHex()); data.pushKV("difficulty", GetDifficulty(*tip)); - data.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip)); + data.pushKV("verificationprogress", chainman.GuessVerificationProgress(tip)); data.pushKV("coins_db_cache_bytes", cs.m_coinsdb_cache_size_bytes); data.pushKV("coins_tip_cache_bytes", cs.m_coinstip_cache_size_bytes); if (cs.m_from_snapshot_blockhash) { diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 5516e1c0d9..3b05f84eee 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -131,7 +131,7 @@ static RPCHelpMan getnetworkhashps() }; } -static bool GenerateBlock(ChainstateManager& chainman, Mining& miner, CBlock&& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block) +static bool GenerateBlock(ChainstateManager& chainman, CBlock&& block, uint64_t& max_tries, std::shared_ptr<const CBlock>& block_out, bool process_new_block) { block_out.reset(); block.hashMerkleRoot = BlockMerkleRoot(block); @@ -151,7 +151,7 @@ static bool GenerateBlock(ChainstateManager& chainman, Mining& miner, CBlock&& b if (!process_new_block) return true; - if (!miner.processNewBlock(block_out, nullptr)) { + if (!chainman.ProcessNewBlock(block_out, /*force_processing=*/true, /*min_pow_checked=*/true, nullptr)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "ProcessNewBlock, block not accepted"); } @@ -166,7 +166,7 @@ static UniValue generateBlocks(ChainstateManager& chainman, Mining& miner, const CHECK_NONFATAL(block_template); std::shared_ptr<const CBlock> block_out; - if (!GenerateBlock(chainman, miner, block_template->getBlock(), nMaxTries, block_out, /*process_new_block=*/true)) { + if (!GenerateBlock(chainman, block_template->getBlock(), nMaxTries, block_out, /*process_new_block=*/true)) { break; } @@ -384,16 +384,17 @@ static RPCHelpMan generateblock() RegenerateCommitments(block, chainman); { + LOCK(::cs_main); BlockValidationState state; - if (!miner.testBlockValidity(block, /*check_merkle_root=*/false, state)) { - throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("testBlockValidity failed: %s", state.ToString())); + if (!TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/false)) { + throw JSONRPCError(RPC_VERIFY_ERROR, strprintf("TestBlockValidity failed: %s", state.ToString())); } } std::shared_ptr<const CBlock> block_out; uint64_t max_tries{DEFAULT_MAX_TRIES}; - if (!GenerateBlock(chainman, miner, std::move(block), max_tries, block_out, process_new_block) || !block_out) { + if (!GenerateBlock(chainman, std::move(block), max_tries, block_out, process_new_block) || !block_out) { throw JSONRPCError(RPC_MISC_ERROR, "Failed to make block."); } @@ -709,12 +710,12 @@ static RPCHelpMan getblocktemplate() return "duplicate-inconclusive"; } - // testBlockValidity only supports blocks built on the current Tip + // TestBlockValidity only supports blocks built on the current Tip if (block.hashPrevBlock != tip) { return "inconclusive-not-best-prevblk"; } BlockValidationState state; - miner.testBlockValidity(block, /*check_merkle_root=*/true, state); + TestBlockValidity(state, chainman.GetParams(), chainman.ActiveChainstate(), block, chainman.m_blockman.LookupBlockIndex(block.hashPrevBlock), /*fCheckPOW=*/false, /*fCheckMerkleRoot=*/true); return BIP22ValidationResult(state); } @@ -742,6 +743,7 @@ static RPCHelpMan getblocktemplate() } static unsigned int nTransactionsUpdatedLast; + const CTxMemPool& mempool = EnsureMemPool(node); if (!lpval.isNull()) { @@ -772,7 +774,7 @@ static RPCHelpMan getblocktemplate() tip = miner.waitTipChanged(hashWatchedChain, checktxtime).hash; // Timeout: Check transactions for update // without holding the mempool lock to avoid deadlocks - if (miner.getTransactionsUpdated() != nTransactionsUpdatedLastLP) + if (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLastLP) break; checktxtime = std::chrono::seconds(10); } @@ -803,13 +805,13 @@ static RPCHelpMan getblocktemplate() static int64_t time_start; static std::unique_ptr<BlockTemplate> block_template; if (!pindexPrev || pindexPrev->GetBlockHash() != tip || - (miner.getTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5)) + (mempool.GetTransactionsUpdated() != nTransactionsUpdatedLast && GetTime() - time_start > 5)) { // Clear pindexPrev so future calls make a new block, despite any failures from here on pindexPrev = nullptr; // Store the pindexBest used before createNewBlock, to avoid races - nTransactionsUpdatedLast = miner.getTransactionsUpdated(); + nTransactionsUpdatedLast = mempool.GetTransactionsUpdated(); CBlockIndex* pindexPrevNew = chainman.m_blockman.LookupBlockIndex(tip); time_start = GetTime(); @@ -1032,13 +1034,10 @@ static RPCHelpMan submitblock() } } - NodeContext& node = EnsureAnyNodeContext(request.context); - Mining& miner = EnsureMining(node); - bool new_block; auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash()); CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc); - bool accepted = miner.processNewBlock(blockptr, /*new_block=*/&new_block); + bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block); CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc); if (!new_block && accepted) { return "duplicate"; diff --git a/src/test/fuzz/util/check_globals.cpp b/src/test/fuzz/util/check_globals.cpp index 4b74ddedd6..fbc5a55598 100644 --- a/src/test/fuzz/util/check_globals.cpp +++ b/src/test/fuzz/util/check_globals.cpp @@ -24,12 +24,12 @@ struct CheckGlobalsImpl { "The current fuzz target used the global random state.\n\n" "This is acceptable, but requires the fuzz target to call \n" - "SeedRandomStateForTest(SeedRand::ZEROS) at the beginning \n" - "of processing the fuzz input.\n\n" + "SeedRandomStateForTest(SeedRand::ZEROS) in the first line \n" + "of the FUZZ_TARGET function.\n\n" "An alternative solution would be to avoid any use of globals.\n\n" - "Without a solution, fuzz stability and determinism can lead \n" + "Without a solution, fuzz instability and non-determinism can lead \n" "to non-reproducible bugs or inefficient fuzzing.\n\n" << std::endl; std::abort(); // Abort, because AFL may try to recover from a std::exit diff --git a/src/test/fuzz/utxo_total_supply.cpp b/src/test/fuzz/utxo_total_supply.cpp index 8dfc6c8e57..84d82f71e2 100644 --- a/src/test/fuzz/utxo_total_supply.cpp +++ b/src/test/fuzz/utxo_total_supply.cpp @@ -21,6 +21,7 @@ using node::BlockAssembler; FUZZ_TARGET(utxo_total_supply) { + SeedRandomStateForTest(SeedRand::ZEROS); /** The testing setup that creates a chainman only (no chainstate) */ ChainTestingSetup test_setup{ ChainType::REGTEST, @@ -28,7 +29,6 @@ FUZZ_TARGET(utxo_total_supply) .extra_args = {"-testactivationheight=bip34@2"}, }, }; - SeedRandomStateForTest(SeedRand::ZEROS); // Can not be done before test_setup // Create chainstate test_setup.LoadVerifyActivateChainstate(); auto& node{test_setup.m_node}; diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp index bde634ec1c..04925792dc 100644 --- a/src/test/util/mining.cpp +++ b/src/test/util/mining.cpp @@ -25,7 +25,7 @@ COutPoint generatetoaddress(const NodeContext& node, const std::string& address) const auto dest = DecodeDestination(address); assert(IsValidDestination(dest)); BlockAssembler::Options assembler_options; - assembler_options.coinbase_output_script = {GetScriptForDestination(dest)}; + assembler_options.coinbase_output_script = GetScriptForDestination(dest); return MineBlock(node, assembler_options); } diff --git a/src/test/validation_chainstate_tests.cpp b/src/test/validation_chainstate_tests.cpp index c9cca8af04..bf8cd819f2 100644 --- a/src/test/validation_chainstate_tests.cpp +++ b/src/test/validation_chainstate_tests.cpp @@ -72,7 +72,8 @@ BOOST_FIXTURE_TEST_CASE(chainstate_update_tip, TestChain100Setup) ChainstateManager& chainman = *Assert(m_node.chainman); const auto get_notify_tip{[&]() { LOCK(m_node.notifications->m_tip_block_mutex); - return m_node.notifications->m_tip_block; + BOOST_REQUIRE(m_node.notifications->TipBlock()); + return *m_node.notifications->TipBlock(); }}; uint256 curr_tip = get_notify_tip(); diff --git a/src/validation.cpp b/src/validation.cpp index aff8fe7024..3f774fd0a1 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2983,9 +2983,9 @@ void Chainstate::PruneAndFlush() } static void UpdateTipLog( + const ChainstateManager& chainman, const CCoinsViewCache& coins_tip, const CBlockIndex* tip, - const CChainParams& params, const std::string& func_name, const std::string& prefix, const std::string& warning_messages) EXCLUSIVE_LOCKS_REQUIRED(::cs_main) @@ -2997,7 +2997,7 @@ static void UpdateTipLog( tip->GetBlockHash().ToString(), tip->nHeight, tip->nVersion, log(tip->nChainWork.getdouble()) / log(2.0), tip->m_chain_tx_count, FormatISO8601DateTime(tip->GetBlockTime()), - GuessVerificationProgress(params.TxData(), tip), + chainman.GuessVerificationProgress(tip), coins_tip.DynamicMemoryUsage() * (1.0 / (1 << 20)), coins_tip.GetCacheSize(), !warning_messages.empty() ? strprintf(" warning='%s'", warning_messages) : ""); @@ -3008,15 +3008,13 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) AssertLockHeld(::cs_main); const auto& coins_tip = this->CoinsTip(); - const CChainParams& params{m_chainman.GetParams()}; - // The remainder of the function isn't relevant if we are not acting on // the active chainstate, so return if need be. if (this != &m_chainman.ActiveChainstate()) { // Only log every so often so that we don't bury log messages at the tip. constexpr int BACKGROUND_LOG_INTERVAL = 2000; if (pindexNew->nHeight % BACKGROUND_LOG_INTERVAL == 0) { - UpdateTipLog(coins_tip, pindexNew, params, __func__, "[background validation] ", ""); + UpdateTipLog(m_chainman, coins_tip, pindexNew, __func__, "[background validation] ", ""); } return; } @@ -3031,7 +3029,7 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) const CBlockIndex* pindex = pindexNew; for (int bit = 0; bit < VERSIONBITS_NUM_BITS; bit++) { WarningBitsConditionChecker checker(m_chainman, bit); - ThresholdState state = checker.GetStateFor(pindex, params.GetConsensus(), m_chainman.m_warningcache.at(bit)); + ThresholdState state = checker.GetStateFor(pindex, m_chainman.GetConsensus(), m_chainman.m_warningcache.at(bit)); if (state == ThresholdState::ACTIVE || state == ThresholdState::LOCKED_IN) { const bilingual_str warning = strprintf(_("Unknown new rules activated (versionbit %i)"), bit); if (state == ThresholdState::ACTIVE) { @@ -3042,7 +3040,7 @@ void Chainstate::UpdateTip(const CBlockIndex* pindexNew) } } } - UpdateTipLog(coins_tip, pindexNew, params, __func__, "", + UpdateTipLog(m_chainman, coins_tip, pindexNew, __func__, "", util::Join(warning_messages, Untranslated(", ")).original); } @@ -4720,7 +4718,7 @@ bool Chainstate::LoadChainTip() tip->GetBlockHash().ToString(), m_chain.Height(), FormatISO8601DateTime(tip->GetBlockTime()), - GuessVerificationProgress(m_chainman.GetParams().TxData(), tip)); + m_chainman.GuessVerificationProgress(tip)); // Ensure KernelNotifications m_tip_block is set even if no new block arrives. if (this->GetRole() != ChainstateRole::BACKGROUND) { @@ -5611,9 +5609,12 @@ bool Chainstate::ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size) //! Guess how far we are in the verification process at the given block index //! require cs_main if pindex has not been validated yet (because m_chain_tx_count might be unset) -double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pindex) { - if (pindex == nullptr) +double ChainstateManager::GuessVerificationProgress(const CBlockIndex* pindex) const +{ + const ChainTxData& data{GetParams().TxData()}; + if (pindex == nullptr) { return 0.0; + } if (!Assume(pindex->m_chain_tx_count > 0)) { LogWarning("Internal bug detected: block %d has unset m_chain_tx_count (%s %s). Please report this issue here: %s\n", diff --git a/src/validation.h b/src/validation.h index aea7a4621b..e2ff5925c5 100644 --- a/src/validation.h +++ b/src/validation.h @@ -95,9 +95,6 @@ CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams); bool FatalError(kernel::Notifications& notifications, BlockValidationState& state, const bilingual_str& message); -/** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ -double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex* pindex); - /** Prune block files up to a given height */ void PruneBlockFilesManual(Chainstate& active_chainstate, int nManualPruneHeight); @@ -1151,6 +1148,9 @@ public: /** Check whether we are doing an initial block download (synchronizing from disk or network) */ bool IsInitialBlockDownload() const; + /** Guess verification progress (as a fraction between 0.0=genesis and 1.0=current tip). */ + double GuessVerificationProgress(const CBlockIndex* pindex) const; + /** * Import blocks from an external file * |