LCOV - code coverage report
Current view: top level - src/interfaces - chain.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 21 29 72.4 %
Date: 2026-06-25 07:23:43 Functions: 16 30 53.3 %

          Line data    Source code
       1             : // Copyright (c) 2018-2021 The Bitcoin Core developers
       2             : // Distributed under the MIT software license, see the accompanying
       3             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4             : 
       5             : #ifndef BITCOIN_INTERFACES_CHAIN_H
       6             : #define BITCOIN_INTERFACES_CHAIN_H
       7             : 
       8             : #include <blockfilter.h>
       9             : #include <primitives/transaction.h> // For CTransactionRef
      10             : #include <util/settings.h>          // For util::SettingsValue
      11             : 
      12             : #include <functional>
      13             : #include <memory>
      14             : #include <optional>
      15             : #include <stddef.h>
      16             : #include <stdint.h>
      17             : #include <string>
      18             : #include <vector>
      19             : 
      20             : class ArgsManager;
      21             : class CBlock;
      22             : class CConnman;
      23             : class CFeeRate;
      24             : class CRPCCommand;
      25             : class CScheduler;
      26             : class CTxMemPool;
      27             : class CFeeRate;
      28             : class CBlockIndex;
      29             : class Coin;
      30             : class uint256;
      31             : enum class MemPoolRemovalReason;
      32             : struct bilingual_str;
      33             : struct CBlockLocator;
      34             : struct FeeCalculation;
      35             : namespace chainlock {
      36             : struct ChainLockSig;
      37             : } // namespace chainlock
      38             : namespace instantsend {
      39             : struct InstantSendLock;
      40             : } // namespace instantsend
      41             : namespace node {
      42             : struct NodeContext;
      43             : } // namespace node
      44             : 
      45             : typedef std::shared_ptr<const CTransaction> CTransactionRef;
      46             : 
      47             : namespace interfaces {
      48             : 
      49             : class Wallet;
      50             : class Handler;
      51             : 
      52             : //! Helper for findBlock to selectively return pieces of block data. If block is
      53             : //! found, data will be returned by setting specified output variables. If block
      54             : //! is not found, output variables will keep their previous values.
      55      639423 : class FoundBlock
      56             : {
      57             : public:
      58      140609 :     FoundBlock& hash(uint256& hash) { m_hash = &hash; return *this; }
      59       50975 :     FoundBlock& height(int& height) { m_height = &height; return *this; }
      60       77855 :     FoundBlock& time(int64_t& time) { m_time = &time; return *this; }
      61      152570 :     FoundBlock& maxTime(int64_t& max_time) { m_max_time = &max_time; return *this; }
      62         659 :     FoundBlock& mtpTime(int64_t& mtp_time) { m_mtp_time = &mtp_time; return *this; }
      63             :     //! Return whether block is in the active (most-work) chain.
      64      328118 :     FoundBlock& inActiveChain(bool& in_active_chain) { m_in_active_chain = &in_active_chain; return *this; }
      65             :     //! Return next block in the active chain if current block is in the active chain.
      66      139335 :     FoundBlock& nextBlock(const FoundBlock& next_block) { m_next_block = &next_block; return *this; }
      67             :     //! Read block data from disk. If the block exists but doesn't have data
      68             :     //! (for example due to pruning), the CBlock variable will be set to null.
      69      138678 :     FoundBlock& data(CBlock& data) { m_data = &data; return *this; }
      70             : 
      71      639423 :     uint256* m_hash = nullptr;
      72      639423 :     int* m_height = nullptr;
      73      639423 :     int64_t* m_time = nullptr;
      74      639423 :     int64_t* m_max_time = nullptr;
      75      639423 :     int64_t* m_mtp_time = nullptr;
      76      639423 :     bool* m_in_active_chain = nullptr;
      77      639423 :     const FoundBlock* m_next_block = nullptr;
      78      639423 :     CBlock* m_data = nullptr;
      79      639423 :     mutable bool found = false;
      80             : };
      81             : 
      82             : //! Interface giving clients (wallet processes, maybe other analysis tools in
      83             : //! the future) ability to access to the chain state, receive notifications,
      84             : //! estimate fees, and submit transactions.
      85             : //!
      86             : //! TODO: Current chain methods are too low level, exposing too much of the
      87             : //! internal workings of the bitcoin node, and not being very convenient to use.
      88             : //! Chain methods should be cleaned up and simplified over time. Examples:
      89             : //!
      90             : //! * The initMessages() and showProgress() methods which the wallet uses to send
      91             : //!   notifications to the GUI should go away when GUI and wallet can directly
      92             : //!   communicate with each other without going through the node
      93             : //!   (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096).
      94             : //!
      95             : //! * The handleRpc, registerRpcs, rpcEnableDeprecated methods and other RPC
      96             : //!   methods can go away if wallets listen for HTTP requests on their own
      97             : //!   ports instead of registering to handle requests on the node HTTP port.
      98             : //!
      99             : //! * Move fee estimation queries to an asynchronous interface and let the
     100             : //!   wallet cache it, fee estimation being driven by node mempool, wallet
     101             : //!   should be the consumer.
     102             : //!
     103             : //! * `guessVerificationProgress` and similar methods can go away if rescan
     104             : //!   logic moves out of the wallet, and the wallet just requests scans from the
     105             : //!   node (https://github.com/bitcoin/bitcoin/issues/11756)
     106             : class Chain
     107             : {
     108             : public:
     109        3657 :     virtual ~Chain() {}
     110             : 
     111             :     //! Get current chain height, not including genesis block (returns 0 if
     112             :     //! chain only contains genesis block, nullopt if chain does not contain
     113             :     //! any blocks)
     114             :     virtual std::optional<int> getHeight() = 0;
     115             : 
     116             :     //! Get block hash. Height must be valid or this function will abort.
     117             :     virtual uint256 getBlockHash(int height) = 0;
     118             : 
     119             :     //! Check that the block is available on disk (i.e. has not been
     120             :     //! pruned), and contains transactions.
     121             :     virtual bool haveBlockOnDisk(int height) = 0;
     122             : 
     123             :     //! Return height of the specified block if it is on the chain, otherwise
     124             :     //! return the height of the highest block on chain that's an ancestor
     125             :     //! of the specified block, or nullopt if there is no common ancestor.
     126             :     //! Also return the height of the specified block as an optional output
     127             :     //! parameter (to avoid the cost of a second hash lookup in case this
     128             :     //! information is desired).
     129             :     virtual std::optional<int> findFork(const uint256& hash, std::optional<int>* height) = 0;
     130             : 
     131             :     //! Get locator for the current chain tip.
     132             :     virtual CBlockLocator getTipLocator() = 0;
     133             : 
     134             :     //! Return a locator that refers to a block in the active chain.
     135             :     //! If specified block is not in the active chain, return locator for the latest ancestor that is in the chain.
     136             :     virtual CBlockLocator getActiveChainLocator(const uint256& block_hash) = 0;
     137             : 
     138             :     //! Return height of the highest block on chain in common with the locator,
     139             :     //! which will either be the original block used to create the locator,
     140             :     //! or one of its ancestors.
     141             :     virtual std::optional<int> findLocatorFork(const CBlockLocator& locator) = 0;
     142             : 
     143             :     //! Returns whether a block filter index is available.
     144             :     virtual bool hasBlockFilterIndex(BlockFilterType filter_type) = 0;
     145             : 
     146             :     //! Returns whether any of the elements match the block via a BIP 157 block filter
     147             :     //! or std::nullopt if the block filter for this block couldn't be found.
     148             :     virtual std::optional<bool> blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) = 0;
     149             : 
     150             :     //! Check if transaction is locked by InstantSendManager
     151             :     virtual bool isInstantSendLockedTx(const uint256& hash) = 0;
     152             : 
     153             :     //! Check if block is chainlocked.
     154             :     virtual bool hasChainLock(int height, const uint256& hash) = 0;
     155             : 
     156             :     //! Return list of MN Collateral from outputs
     157             :     virtual std::vector<COutPoint> listMNCollaterials(const std::vector<std::pair<const CTransactionRef&, uint32_t>>& outputs) = 0;
     158             : 
     159             :     //! Return whether node has the block and optionally return block metadata
     160             :     //! or contents.
     161             :     virtual bool findBlock(const uint256& hash, const FoundBlock& block={}) = 0;
     162             : 
     163             :     //! Find first block in the chain with timestamp >= the given time
     164             :     //! and height >= than the given height, return false if there is no block
     165             :     //! with a high enough timestamp and height. Optionally return block
     166             :     //! information.
     167             :     virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block={}) = 0;
     168             : 
     169             :     //! Find ancestor of block at specified height and optionally return
     170             :     //! ancestor information.
     171             :     virtual bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out={}) = 0;
     172             : 
     173             :     //! Return whether block descends from a specified ancestor, and
     174             :     //! optionally return ancestor information.
     175             :     virtual bool findAncestorByHash(const uint256& block_hash,
     176             :         const uint256& ancestor_hash,
     177             :         const FoundBlock& ancestor_out={}) = 0;
     178             : 
     179             :     //! Find most recent common ancestor between two blocks and optionally
     180             :     //! return block information.
     181             :     virtual bool findCommonAncestor(const uint256& block_hash1,
     182             :         const uint256& block_hash2,
     183             :         const FoundBlock& ancestor_out={},
     184             :         const FoundBlock& block1_out={},
     185             :         const FoundBlock& block2_out={}) = 0;
     186             : 
     187             :     //! Look up unspent output information. Returns coins in the mempool and in
     188             :     //! the current chain UTXO set. Iterates through all the keys in the map and
     189             :     //! populates the values.
     190             :     virtual void findCoins(std::map<COutPoint, Coin>& coins) = 0;
     191             : 
     192             :     //! Estimate fraction of total transactions verified if blocks up to
     193             :     //! the specified block hash are verified.
     194             :     virtual double guessVerificationProgress(const uint256& block_hash) = 0;
     195             : 
     196             :     //! Return true if data is available for all blocks in the specified range
     197             :     //! of blocks. This checks all blocks that are ancestors of block_hash in
     198             :     //! the height range from min_height to max_height, inclusive.
     199             :     virtual bool hasBlocks(const uint256& block_hash, int min_height = 0, std::optional<int> max_height = {}) = 0;
     200             : 
     201             :     //! Check if transaction is in mempool.
     202             :     virtual bool isInMempool(const uint256& txid) = 0;
     203             : 
     204             :     //! Check if transaction has descendants in mempool.
     205             :     virtual bool hasDescendantsInMempool(const uint256& txid) = 0;
     206             : 
     207             :     //! Transaction is added to memory pool, if the transaction fee is below the
     208             :     //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true.
     209             :     //! Return false if the transaction could not be added due to the fee or for another reason.
     210             :     virtual bool broadcastTransaction(const CTransactionRef& tx,
     211             :         const CAmount& max_tx_fee,
     212             :         bool relay,
     213             :         bilingual_str& err_string) = 0;
     214             : 
     215             :     //! Calculate mempool ancestor and descendant counts for the given transaction.
     216             :     virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0;
     217             : 
     218             :     //! Get the node's package limits.
     219             :     //! Currently only returns the ancestor and descendant count limits, but could be enhanced to
     220             :     //! return more policy settings.
     221             :     virtual void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) = 0;
     222             : 
     223             :     //! Check if transaction will pass the mempool's chain limits.
     224             :     virtual bool checkChainLimits(const CTransactionRef& tx) = 0;
     225             : 
     226             :     //! Estimate smart fee.
     227             :     virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0;
     228             : 
     229             :     //! Fee estimator max target.
     230             :     virtual unsigned int estimateMaxBlocks() = 0;
     231             : 
     232             :     //! Mempool minimum fee.
     233             :     virtual CFeeRate mempoolMinFee() = 0;
     234             : 
     235             :     //! Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
     236             :     virtual CFeeRate relayMinFee() = 0;
     237             : 
     238             :     //! Relay incremental fee setting (-incrementalrelayfee), reflecting cost of relay.
     239             :     virtual CFeeRate relayIncrementalFee() = 0;
     240             : 
     241             :     //! Relay dust fee setting (-dustrelayfee), reflecting lowest rate it's economical to spend.
     242             :     virtual CFeeRate relayDustFee() = 0;
     243             : 
     244             :     //! Check if any block has been pruned.
     245             :     virtual bool havePruned() = 0;
     246             : 
     247             :     //! Check if the node is ready to broadcast transactions.
     248             :     virtual bool isReadyToBroadcast() = 0;
     249             : 
     250             :     //! Check if in IBD.
     251             :     virtual bool isInitialBlockDownload() = 0;
     252             : 
     253             :     //! Check if shutdown requested.
     254             :     virtual bool shutdownRequested() = 0;
     255             : 
     256             :     //! Send init message.
     257             :     virtual void initMessage(const std::string& message) = 0;
     258             : 
     259             :     //! Send init warning.
     260             :     virtual void initWarning(const bilingual_str& message) = 0;
     261             : 
     262             :     //! Send init error.
     263             :     virtual void initError(const bilingual_str& message) = 0;
     264             : 
     265             :     //! Send progress indicator.
     266             :     virtual void showProgress(const std::string& title, int progress, bool resume_possible) = 0;
     267             : 
     268             :     //! Chain notifications.
     269             :     class Notifications
     270             :     {
     271             :     public:
     272        2371 :         virtual ~Notifications() {}
     273           0 :         virtual void transactionAddedToMempool(const CTransactionRef& tx, int64_t nAcceptTime) {}
     274           0 :         virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) {}
     275           0 :         virtual void blockConnected(const CBlock& block, int height) {}
     276           0 :         virtual void blockDisconnected(const CBlock& block, int height) {}
     277           0 :         virtual void updatedBlockTip() {}
     278           0 :         virtual void chainStateFlushed(const CBlockLocator& locator) {}
     279           0 :         virtual void notifyChainLock(const CBlockIndex* pindexChainLock, const std::shared_ptr<const chainlock::ChainLockSig>& clsig) {}
     280           0 :         virtual void notifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const instantsend::InstantSendLock>& islock) {}
     281             :     };
     282             : 
     283             :     //! Register handler for notifications.
     284             :     virtual std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) = 0;
     285             : 
     286             :     //! Wait for pending notifications to be processed unless block hash points to the current
     287             :     //! chain tip.
     288             :     virtual void waitForNotificationsIfTipChanged(const uint256& old_tip) = 0;
     289             : 
     290             :     //! Register handler for RPC. Command is not copied, so reference
     291             :     //! needs to remain valid until Handler is disconnected.
     292             :     virtual std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) = 0;
     293             : 
     294             :     //! Check if deprecated RPC is enabled.
     295             :     virtual bool rpcEnableDeprecated(const std::string& method) = 0;
     296             : 
     297             :     //! Run function after given number of seconds. Cancel any previous calls with same name.
     298             :     virtual void rpcRunLater(const std::string& name, std::function<void()> fn, int64_t seconds) = 0;
     299             : 
     300             :     //! Get settings value.
     301             :     virtual util::SettingsValue getSetting(const std::string& arg) = 0;
     302             : 
     303             :     //! Get list of settings values.
     304             :     virtual std::vector<util::SettingsValue> getSettingsList(const std::string& arg) = 0;
     305             : 
     306             :     //! Return <datadir>/settings.json setting value.
     307             :     virtual util::SettingsValue getRwSetting(const std::string& name) = 0;
     308             : 
     309             :     //! Write a setting to <datadir>/settings.json. Optionally just update the
     310             :     //! setting in memory and do not write the file.
     311             :     virtual bool updateRwSetting(const std::string& name, const util::SettingsValue& value, bool write=true) = 0;
     312             : 
     313             :     //! Synchronously send transactionAddedToMempool notifications about all
     314             :     //! current mempool transactions to the specified handler and return after
     315             :     //! the last one is sent. These notifications aren't coordinated with async
     316             :     //! notifications sent by handleNotifications, so out of date async
     317             :     //! notifications from handleNotifications can arrive during and after
     318             :     //! synchronous notifications from requestMempoolTransactions. Clients need
     319             :     //! to be prepared to handle this by ignoring notifications about unknown
     320             :     //! removed transactions and already added new transactions.
     321             :     virtual void requestMempoolTransactions(Notifications& notifications) = 0;
     322             : 
     323             :     //! Return true if an assumed-valid chain is in use.
     324             :     virtual bool hasAssumedValidChain() = 0;
     325             : };
     326             : 
     327             : //! Interface to let node manage chain clients (wallets, or maybe tools for
     328             : //! monitoring and analysis in the future).
     329             : class ChainClient
     330             : {
     331             : public:
     332        1635 :     virtual ~ChainClient() {}
     333             : 
     334             :     //! Register rpcs.
     335             :     virtual void registerRpcs() = 0;
     336             : 
     337             :     //! Check for errors before loading.
     338             :     virtual bool verify() = 0;
     339             : 
     340             :     //! Load saved state.
     341             :     virtual bool load() = 0;
     342             : 
     343             :     //! Start client execution and provide a scheduler.
     344             :     virtual void start(CScheduler& scheduler) = 0;
     345             : 
     346             :     //! Save state to disk.
     347             :     virtual void flush() = 0;
     348             : 
     349             :     //! Shut down client.
     350             :     virtual void stop() = 0;
     351             : 
     352             :     //! Set mock time.
     353             :     virtual void setMockTime(int64_t time) = 0;
     354             : };
     355             : 
     356             : //! Return implementation of Chain interface.
     357             : std::unique_ptr<Chain> MakeChain(node::NodeContext& node);
     358             : 
     359             : } // namespace interfaces
     360             : 
     361             : #endif // BITCOIN_INTERFACES_CHAIN_H

Generated by: LCOV version 1.16