Inside Bitcoin
Opening the selected file…
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.
1// Copyright (c) 2018-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#ifndef BITCOIN_INTERFACES_CHAIN_H6#define BITCOIN_INTERFACES_CHAIN_H8#include <blockfilter.h>9#include <common/settings.h>10#include <consensus/amount.h>11#include <kernel/chain.h> // IWYU pragma: export12#include <primitives/transaction.h>13#include <util/expected.h>14#include <util/fees.h>15#include <util/result.h>16#include <util/time.h>18#include <cstddef>19#include <cstdint>20#include <functional>21#include <map>22#include <memory>23#include <optional>24#include <string>25#include <vector>27class CBlock;28class CFeeRate;29class CRPCCommand;30class CScheduler;31class Coin;32class uint256;33enum class MemPoolRemovalReason;34enum class RBFTransactionState;35struct bilingual_str;36struct CBlockLocator;37namespace kernel {38struct ChainstateRole;39} // namespace kernel40namespace node {41struct NodeContext;42enum class TxBroadcast : uint8_t;43} // namespace node45namespace interfaces {46class Handler;48//! Helper for findBlock to selectively return pieces of block data. If block is49//! found, data will be returned by setting specified output variables. If block50//! is not found, output variables will keep their previous values.51class FoundBlock52{53public:54FoundBlock& hash(uint256& hash) { m_hash = &hash; return *this; }55FoundBlock& height(int& height) { m_height = &height; return *this; }56FoundBlock& time(int64_t& time) { m_time = &time; return *this; }57FoundBlock& maxTime(int64_t& max_time) { m_max_time = &max_time; return *this; }58FoundBlock& mtpTime(int64_t& mtp_time) { m_mtp_time = &mtp_time; return *this; }59//! Return whether block is in the active (most-work) chain.60FoundBlock& inActiveChain(bool& in_active_chain) { m_in_active_chain = &in_active_chain; return *this; }61//! Return locator if block is in the active chain.62FoundBlock& locator(CBlockLocator& locator) { m_locator = &locator; return *this; }63//! Return next block in the active chain if current block is in the active chain.64FoundBlock& nextBlock(const FoundBlock& next_block) { m_next_block = &next_block; return *this; }65//! Read block data from disk. If the block exists but doesn't have data66//! (for example due to pruning), the CBlock variable will be set to null.67FoundBlock& data(CBlock& data) { m_data = &data; return *this; }69uint256* m_hash = nullptr;70int* m_height = nullptr;71int64_t* m_time = nullptr;72int64_t* m_max_time = nullptr;73int64_t* m_mtp_time = nullptr;74bool* m_in_active_chain = nullptr;75CBlockLocator* m_locator = nullptr;76const FoundBlock* m_next_block = nullptr;77CBlock* m_data = nullptr;78mutable bool found = false;79};81//! The action to be taken after updating a settings value.82//! WRITE indicates that the updated value must be written to disk,83//! while SKIP_WRITE indicates that the change will be kept in memory-only84//! without persisting it.85enum class SettingsAction {86WRITE,87SKIP_WRITE88};90using SettingsUpdate = std::function<std::optional<interfaces::SettingsAction>(common::SettingsValue&)>;92//! Interface giving clients (wallet processes, maybe other analysis tools in93//! the future) ability to access to the chain state, receive notifications,94//! estimate fees, and submit transactions.95//!96//! TODO: Current chain methods are too low level, exposing too much of the97//! internal workings of the bitcoin node, and not being very convenient to use.98//! Chain methods should be cleaned up and simplified over time. Examples:99//!100//! * The initMessages() and showProgress() methods which the wallet uses to send101//! notifications to the GUI should go away when GUI and wallet can directly102//! communicate with each other without going through the node103//! (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096).104//!105//! * The handleRpc, registerRpcs, rpcEnableDeprecated methods and other RPC106//! methods can go away if wallets listen for HTTP requests on their own107//! ports instead of registering to handle requests on the node HTTP port.108//!109//! * Move fee estimation queries to an asynchronous interface and let the110//! wallet cache it, fee estimation being driven by node mempool, wallet111//! should be the consumer.112//!113//! * `guessVerificationProgress` and similar methods can go away if rescan114//! logic moves out of the wallet, and the wallet just requests scans from the115//! node (https://github.com/bitcoin/bitcoin/issues/11756)116class Chain117{118public:119virtual ~Chain() = default;121//! Get current chain height, not including genesis block (returns 0 if122//! chain only contains genesis block, nullopt if chain does not contain123//! any blocks)124virtual std::optional<int> getHeight() = 0;126//! Get block hash. Height must be valid or this function will abort.127virtual uint256 getBlockHash(int height) = 0;129//! Check that the block is available on disk (i.e. has not been130//! pruned), and contains transactions.131virtual bool haveBlockOnDisk(int height) = 0;133//! Return height of the highest block on chain in common with the locator,134//! which will either be the original block used to create the locator,135//! or one of its ancestors.136virtual std::optional<int> findLocatorFork(const CBlockLocator& locator) = 0;138//! Returns whether a block filter index is available.139virtual bool hasBlockFilterIndex(BlockFilterType filter_type) = 0;141//! Returns whether any of the elements match the block via a BIP 157 block filter142//! or std::nullopt if the block filter for this block couldn't be found.143virtual std::optional<bool> blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) = 0;145//! Return whether node has the block and optionally return block metadata146//! or contents.147virtual bool findBlock(const uint256& hash, const FoundBlock& block={}) = 0;149//! Find first block in the chain with timestamp >= the given time150//! and height >= than the given height, return false if there is no block151//! with a high enough timestamp and height. Optionally return block152//! information.153virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block={}) = 0;155//! Find ancestor of block at specified height and optionally return156//! ancestor information.157virtual bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out={}) = 0;159//! Return whether block descends from a specified ancestor, and160//! optionally return ancestor information.161virtual bool findAncestorByHash(const uint256& block_hash,162const uint256& ancestor_hash,163const FoundBlock& ancestor_out={}) = 0;165//! Find most recent common ancestor between two blocks and optionally166//! return block information.167virtual bool findCommonAncestor(const uint256& block_hash1,168const uint256& block_hash2,169const FoundBlock& ancestor_out={},170const FoundBlock& block1_out={},171const FoundBlock& block2_out={}) = 0;173//! Look up unspent output information. Returns coins in the mempool and in174//! the current chain UTXO set. Iterates through all the keys in the map and175//! populates the values.176virtual void findCoins(std::map<COutPoint, Coin>& coins) = 0;178//! Estimate fraction of total transactions verified if blocks up to179//! the specified block hash are verified.180virtual double guessVerificationProgress(const uint256& block_hash) = 0;182//! Return true if data is available for all blocks in the specified range183//! of blocks. This checks all blocks that are ancestors of block_hash in184//! the height range from min_height to max_height, inclusive.185virtual bool hasBlocks(const uint256& block_hash, int min_height = 0, std::optional<int> max_height = {}) = 0;187//! Check if transaction is RBF opt in.188virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0;190//! Check if transaction is in mempool.191virtual bool isInMempool(const Txid& txid) = 0;193//! Check if transaction has descendants in mempool.194virtual bool hasDescendantsInMempool(const Txid& txid) = 0;196//! Process a local transaction, optionally adding it to the mempool and197//! optionally broadcasting it to the network.198//! @param[in] tx Transaction to process.199//! @param[in] max_tx_fee Don't add the transaction to the mempool or200//! broadcast it if its fee is higher than this.201//! @param[in] broadcast_method Whether to add the transaction to the202//! mempool and how/whether to broadcast it.203//! @param[out] err_string Set if an error occurs.204//! @return False if the transaction could not be added due to the fee or for another reason.205virtual bool broadcastTransaction(const CTransactionRef& tx,206const CAmount& max_tx_fee,207node::TxBroadcast broadcast_method,208std::string& err_string) = 0;210//! Calculate mempool ancestor and cluster counts for the given transaction.211virtual void getTransactionAncestry(const Txid& txid, size_t& ancestors, size_t& cluster_count, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0;213//! For each outpoint, calculate the fee-bumping cost to spend this outpoint at the specified214// feerate, including bumping its ancestors. For example, if the target feerate is 10sat/vbyte215// and this outpoint refers to a mempool transaction at 3sat/vbyte, the bump fee includes the216// cost to bump the mempool transaction to 10sat/vbyte (i.e. 7 * mempooltx.vsize). If that217// transaction also has, say, an unconfirmed parent with a feerate of 1sat/vbyte, the bump fee218// includes the cost to bump the parent (i.e. 9 * parentmempooltx.vsize).219//220// If the outpoint comes from an unconfirmed transaction that is already above the target221// feerate or bumped by its descendant(s) already, it does not need to be bumped. Its bump fee222// is 0. Likewise, if any of the transaction's ancestors are already bumped by a transaction223// in our mempool, they are not included in the transaction's bump fee.224//225// Also supported is bump-fee calculation in the case of replacements. If an outpoint226// conflicts with another transaction in the mempool, it is assumed that the goal is to replace227// that transaction. As such, the calculation will exclude the to-be-replaced transaction, but228// will include the fee-bumping cost. If bump fees of descendants of the to-be-replaced229// transaction are requested, the value will be 0. Fee-related RBF rules are not included as230// they are logically distinct.231//232// Any outpoints that are otherwise unavailable from the mempool (e.g. UTXOs from confirmed233// transactions or transactions not yet broadcast by the wallet) are given a bump fee of 0.234//235// If multiple outpoints come from the same transaction (which would be very rare because236// it means that one transaction has multiple change outputs or paid the same wallet using multiple237// outputs in the same transaction) or have shared ancestry, the bump fees are calculated238// independently, i.e. as if only one of them is spent. This may result in double-fee-bumping. This239// caveat can be rectified per use of the sister-function CalculateCombinedBumpFee(…).240virtual std::map<COutPoint, CAmount> calculateIndividualBumpFees(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) = 0;242//! Calculate the combined bump fee for an input set per the same strategy243// as in CalculateIndividualBumpFees(…).244// Unlike CalculateIndividualBumpFees(…), this does not return individual245// bump fees per outpoint, but a single bump fee for the shared ancestry.246// The combined bump fee may be used to correct overestimation due to247// shared ancestry by multiple UTXOs after coin selection.248virtual std::optional<CAmount> calculateCombinedBumpFee(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) = 0;250//! Get the node's package limits.
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.