Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
751CFeeRate mempoolMinFee() override752{753if (!m_node.mempool) return {};754return m_node.mempool->GetMinFee();755}756CFeeRate relayMinFee() override757{758if (!m_node.mempool) return CFeeRate{DEFAULT_MIN_RELAY_TX_FEE};759return m_node.mempool->m_opts.min_relay_feerate;760}761CFeeRate relayIncrementalFee() override762{763if (!m_node.mempool) return CFeeRate{DEFAULT_INCREMENTAL_RELAY_FEE};764return m_node.mempool->m_opts.incremental_relay_feerate;765}766CFeeRate relayDustFee() override767{768if (!m_node.mempool) return CFeeRate{DUST_RELAY_TX_FEE};769return m_node.mempool->m_opts.dust_relay_feerate;770}771bool havePruned() override772{773LOCK(::cs_main);774return chainman().m_blockman.m_have_pruned;775}776std::optional<int> getPruneHeight() override777{778LOCK(chainman().GetMutex());779return GetPruneHeight(chainman().m_blockman, chainman().ActiveChain());780}781bool isReadyToBroadcast() override { return !chainman().m_blockman.LoadingBlocks() && !isInitialBlockDownload(); }782bool isInitialBlockDownload() override783{784return chainman().IsInitialBlockDownload();785}786bool shutdownRequested() override { return ShutdownRequested(m_node); }787void initMessage(const std::string& message) override { ::uiInterface.InitMessage(message); }788void initWarning(const bilingual_str& message) override { InitWarning(message); }789void initError(const bilingual_str& message) override { InitError(message); }790void showProgress(const std::string& title, int progress, bool resume_possible) override791{792::uiInterface.ShowProgress(title, progress, resume_possible);793}794std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override795{796return std::make_unique<NotificationsHandlerImpl>(validation_signals(), std::move(notifications));797}798void waitForNotificationsIfTipChanged(const uint256& old_tip) override799{800if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;801validation_signals().SyncWithValidationInterfaceQueue();802}803void waitForNotifications() override804{805validation_signals().SyncWithValidationInterfaceQueue();806}807std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override808{809return std::make_unique<RpcHandlerImpl>(command);810}811bool rpcEnableDeprecated(const std::string& method) override { return IsDeprecatedRPCEnabled(method); }812common::SettingsValue getSetting(const std::string& name) override813{814return args().GetSetting(name);815}816std::vector<common::SettingsValue> getSettingsList(const std::string& name) override817{818return args().GetSettingsList(name);819}820common::SettingsValue getRwSetting(const std::string& name) override821{822common::SettingsValue result;823args().LockSettings([&](const common::Settings& settings) {824if (const common::SettingsValue* value = common::FindKey(settings.rw_settings, name)) {825result = *value;826}827});828return result;829}830bool updateRwSetting(const std::string& name,831const interfaces::SettingsUpdate& update_settings_func) override832{833std::optional<interfaces::SettingsAction> action;834args().LockSettings([&](common::Settings& settings) {835if (auto* value = common::FindKey(settings.rw_settings, name)) {836action = update_settings_func(*value);837if (value->isNull()) settings.rw_settings.erase(name);838} else {839UniValue new_value;840action = update_settings_func(new_value);841if (!new_value.isNull()) settings.rw_settings[name] = std::move(new_value);842}843});844if (!action) return false;845// Now dump value to disk if requested846return *action != interfaces::SettingsAction::WRITE || (args().GetSettingsPath() && args().WriteSettingsFile());847}848bool overwriteRwSetting(const std::string& name, common::SettingsValue value, interfaces::SettingsAction action) override849{850return updateRwSetting(name, [&](common::SettingsValue& settings) {851settings = std::move(value);852return action;853});854}855bool deleteRwSettings(const std::string& name, interfaces::SettingsAction action) override856{857return overwriteRwSetting(name, {}, action);858}859void requestMempoolTransactions(Notifications& notifications) override860{861if (!m_node.mempool) return;862LOCK2(::cs_main, m_node.mempool->cs);863for (const CTxMemPoolEntry& entry : m_node.mempool->entryAll()) {864notifications.transactionAddedToMempool(entry.GetSharedTx());865}866}867bool hasAssumedValidChain() override868{869LOCK(::cs_main);870return bool{chainman().CurrentChainstate().m_from_snapshot_blockhash};871}873NodeContext* context() override { return &m_node; }874ArgsManager& args() { return *Assert(m_node.args); }875ChainstateManager& chainman() { return *Assert(m_node.chainman); }876ValidationSignals& validation_signals() { return *Assert(m_node.validation_signals); }877NodeContext& m_node;878};880class BlockTemplateImpl : public BlockTemplate881{882public:883explicit BlockTemplateImpl(BlockCreateOptions create_options,884std::unique_ptr<CBlockTemplate> block_template,885const NodeContext& node) : m_create_options(std::move(create_options)),886m_block_template(std::move(block_template)),887m_node(node)888{889assert(m_block_template);890}892CBlockHeader getBlockHeader() override893{894return m_block_template->block;895}897CBlock getBlock() override898{899return m_block_template->block;900}902std::vector<CAmount> getTxFees() override903{904return m_block_template->vTxFees;905}907std::vector<int64_t> getTxSigops() override908{909return m_block_template->vTxSigOpsCost;910}912CoinbaseTx getCoinbaseTx() override913{914return m_block_template->m_coinbase_tx;915}917std::vector<uint256> getCoinbaseMerklePath() override918{919return TransactionMerklePath(m_block_template->block, 0);920}922bool submitSolution(uint32_t version, uint32_t timestamp, uint32_t nonce, CTransactionRef coinbase, std::string& reason, std::string& debug) override923{924if (!coinbase) return false;925AddMerkleRootAndCoinbase(m_block_template->block, std::move(coinbase), version, timestamp, nonce);926return SubmitBlock(chainman(), std::make_shared<const CBlock>(m_block_template->block), reason, debug);927}929std::unique_ptr<BlockTemplate> waitNext(BlockWaitOptions options) override930{931auto new_template = WaitAndCreateNewBlock(chainman(),932notifications(),933m_node.mempool.get(),934m_block_template,935/*wait_options=*/options,936/*create_options=*/m_create_options,937/*interrupt_wait=*/m_interrupt_wait);938if (new_template) return std::make_unique<BlockTemplateImpl>(m_create_options, std::move(new_template), m_node);939return nullptr;940}942void interruptWait() override943{944InterruptWait(notifications(), m_interrupt_wait);945}947const BlockCreateOptions m_create_options;949const std::unique_ptr<CBlockTemplate> m_block_template;951bool m_interrupt_wait{false};952ChainstateManager& chainman() { return *Assert(m_node.chainman); }953KernelNotifications& notifications() { return *Assert(m_node.notifications); }954const NodeContext& m_node;955};957class MinerImpl : public Mining958{959public:960explicit MinerImpl(const NodeContext& node) : m_node(node) {}962bool isTestChain() override963{964return chainman().GetParams().IsTestChain();965}967bool isInitialBlockDownload() override968{969return chainman().IsInitialBlockDownload();970}972std::optional<BlockRef> getTip() override973{974return GetTip(chainman());975}977std::optional<BlockRef> waitTipChanged(uint256 current_tip, MillisecondsDouble timeout) override978{979return WaitTipChanged(chainman(), notifications(), current_tip, timeout, m_interrupt_mining);980}982std::unique_ptr<BlockTemplate> createNewBlock(const BlockCreateOptions& options, bool cooldown) override983{984// Ensure m_tip_block is set so consumers of BlockTemplate can rely on that.985std::optional<BlockRef> maybe_tip{waitTipChanged(uint256::ZERO, MillisecondsDouble::max())};987if (!maybe_tip) return {};989if (cooldown) {990// Do not return a template during IBD, because it can have long991// pauses and sometimes takes a while to get started. Although this992// is useful in general, it's gated behind the cooldown argument,993// because on regtest and single miner signets this would wait994// forever if no block was mined in the past day.995while (chainman().IsInitialBlockDownload()) {996maybe_tip = waitTipChanged(maybe_tip->hash, MillisecondsDouble{1000});997if (!maybe_tip || chainman().m_interrupt || WITH_LOCK(notifications().m_tip_block_mutex, return m_interrupt_mining)) return {};998}1000// Also wait during the final catch-up moments after IBD.
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.