LCOV - code coverage report
Current view: top level - src/interfaces - chain.h (source / functions) Hit Total Coverage
Test: fuzz_coverage.info Lines: 2 38 5.3 %
Date: 2023-09-26 12:08:55 Functions: 4 27 14.8 %

          Line data    Source code
       1             : // Copyright (c) 2018-2022 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 <common/settings.h>
      10             : #include <primitives/transaction.h> // For CTransactionRef
      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 CBlockUndo;
      23             : class CFeeRate;
      24             : class CRPCCommand;
      25             : class CScheduler;
      26             : class Coin;
      27             : class uint256;
      28             : enum class MemPoolRemovalReason;
      29             : enum class RBFTransactionState;
      30             : struct bilingual_str;
      31             : struct CBlockLocator;
      32             : struct FeeCalculation;
      33             : namespace node {
      34             : struct NodeContext;
      35             : } // namespace node
      36             : 
      37             : namespace interfaces {
      38             : 
      39             : class Handler;
      40             : class Wallet;
      41             : 
      42             : //! Hash/height pair to help track and identify blocks.
      43             : struct BlockKey {
      44             :     uint256 hash;
      45             :     int height = -1;
      46             : };
      47             : 
      48             : //! Helper for findBlock to selectively return pieces of block data. If block is
      49             : //! found, data will be returned by setting specified output variables. If block
      50             : //! is not found, output variables will keep their previous values.
      51           0 : class FoundBlock
      52             : {
      53             : public:
      54           0 :     FoundBlock& hash(uint256& hash) { m_hash = &hash; return *this; }
      55           0 :     FoundBlock& height(int& height) { m_height = &height; return *this; }
      56           0 :     FoundBlock& time(int64_t& time) { m_time = &time; return *this; }
      57           0 :     FoundBlock& maxTime(int64_t& max_time) { m_max_time = &max_time; return *this; }
      58           0 :     FoundBlock& mtpTime(int64_t& mtp_time) { m_mtp_time = &mtp_time; return *this; }
      59             :     //! Return whether block is in the active (most-work) chain.
      60           0 :     FoundBlock& inActiveChain(bool& in_active_chain) { m_in_active_chain = &in_active_chain; return *this; }
      61             :     //! Return locator if block is in the active chain.
      62           0 :     FoundBlock& locator(CBlockLocator& locator) { m_locator = &locator; return *this; }
      63             :     //! Return next block in the active chain if current block is in the active chain.
      64           0 :     FoundBlock& 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 data
      66             :     //! (for example due to pruning), the CBlock variable will be set to null.
      67           0 :     FoundBlock& data(CBlock& data) { m_data = &data; return *this; }
      68             : 
      69           0 :     uint256* m_hash = nullptr;
      70           0 :     int* m_height = nullptr;
      71           0 :     int64_t* m_time = nullptr;
      72           0 :     int64_t* m_max_time = nullptr;
      73           0 :     int64_t* m_mtp_time = nullptr;
      74           0 :     bool* m_in_active_chain = nullptr;
      75           0 :     CBlockLocator* m_locator = nullptr;
      76           0 :     const FoundBlock* m_next_block = nullptr;
      77           0 :     CBlock* m_data = nullptr;
      78           0 :     mutable bool found = false;
      79             : };
      80             : 
      81             : //! Block data sent with blockConnected, blockDisconnected notifications.
      82             : struct BlockInfo {
      83             :     const uint256& hash;
      84           0 :     const uint256* prev_hash = nullptr;
      85           0 :     int height = -1;
      86           0 :     int file_number = -1;
      87           0 :     unsigned data_pos = 0;
      88           0 :     const CBlock* data = nullptr;
      89           0 :     const CBlockUndo* undo_data = nullptr;
      90             :     // The maximum time in the chain up to and including this block.
      91             :     // A timestamp that can only move forward.
      92           0 :     unsigned int chain_time_max{0};
      93             : 
      94           0 :     BlockInfo(const uint256& hash LIFETIMEBOUND) : hash(hash) {}
      95             : };
      96             : 
      97             : //! Interface giving clients (wallet processes, maybe other analysis tools in
      98             : //! the future) ability to access to the chain state, receive notifications,
      99             : //! estimate fees, and submit transactions.
     100             : //!
     101             : //! TODO: Current chain methods are too low level, exposing too much of the
     102             : //! internal workings of the bitcoin node, and not being very convenient to use.
     103             : //! Chain methods should be cleaned up and simplified over time. Examples:
     104             : //!
     105             : //! * The initMessages() and showProgress() methods which the wallet uses to send
     106             : //!   notifications to the GUI should go away when GUI and wallet can directly
     107             : //!   communicate with each other without going through the node
     108             : //!   (https://github.com/bitcoin/bitcoin/pull/15288#discussion_r253321096).
     109             : //!
     110             : //! * The handleRpc, registerRpcs, rpcEnableDeprecated methods and other RPC
     111             : //!   methods can go away if wallets listen for HTTP requests on their own
     112             : //!   ports instead of registering to handle requests on the node HTTP port.
     113             : //!
     114             : //! * Move fee estimation queries to an asynchronous interface and let the
     115             : //!   wallet cache it, fee estimation being driven by node mempool, wallet
     116             : //!   should be the consumer.
     117             : //!
     118             : //! * `guessVerificationProgress` and similar methods can go away if rescan
     119             : //!   logic moves out of the wallet, and the wallet just requests scans from the
     120             : //!   node (https://github.com/bitcoin/bitcoin/issues/11756)
     121             : class Chain
     122             : {
     123             : public:
     124           1 :     virtual ~Chain() {}
     125             : 
     126             :     //! Get current chain height, not including genesis block (returns 0 if
     127             :     //! chain only contains genesis block, nullopt if chain does not contain
     128             :     //! any blocks)
     129             :     virtual std::optional<int> getHeight() = 0;
     130             : 
     131             :     //! Get block hash. Height must be valid or this function will abort.
     132             :     virtual uint256 getBlockHash(int height) = 0;
     133             : 
     134             :     //! Check that the block is available on disk (i.e. has not been
     135             :     //! pruned), and contains transactions.
     136             :     virtual bool haveBlockOnDisk(int height) = 0;
     137             : 
     138             :     //! Get locator for the current chain tip.
     139             :     virtual CBlockLocator getTipLocator() = 0;
     140             : 
     141             :     //! Return a locator that refers to a block in the active chain.
     142             :     //! If specified block is not in the active chain, return locator for the latest ancestor that is in the chain.
     143             :     virtual CBlockLocator getActiveChainLocator(const uint256& block_hash) = 0;
     144             : 
     145             :     //! Return height of the highest block on chain in common with the locator,
     146             :     //! which will either be the original block used to create the locator,
     147             :     //! or one of its ancestors.
     148             :     virtual std::optional<int> findLocatorFork(const CBlockLocator& locator) = 0;
     149             : 
     150             :     //! Returns whether a block filter index is available.
     151             :     virtual bool hasBlockFilterIndex(BlockFilterType filter_type) = 0;
     152             : 
     153             :     //! Returns whether any of the elements match the block via a BIP 157 block filter
     154             :     //! or std::nullopt if the block filter for this block couldn't be found.
     155             :     virtual std::optional<bool> blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) = 0;
     156             : 
     157             :     //! Return whether node has the block and optionally return block metadata
     158             :     //! or contents.
     159             :     virtual bool findBlock(const uint256& hash, const FoundBlock& block={}) = 0;
     160             : 
     161             :     //! Find first block in the chain with timestamp >= the given time
     162             :     //! and height >= than the given height, return false if there is no block
     163             :     //! with a high enough timestamp and height. Optionally return block
     164             :     //! information.
     165             :     virtual bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block={}) = 0;
     166             : 
     167             :     //! Find ancestor of block at specified height and optionally return
     168             :     //! ancestor information.
     169             :     virtual bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out={}) = 0;
     170             : 
     171             :     //! Return whether block descends from a specified ancestor, and
     172             :     //! optionally return ancestor information.
     173             :     virtual bool findAncestorByHash(const uint256& block_hash,
     174             :         const uint256& ancestor_hash,
     175             :         const FoundBlock& ancestor_out={}) = 0;
     176             : 
     177             :     //! Find most recent common ancestor between two blocks and optionally
     178             :     //! return block information.
     179             :     virtual bool findCommonAncestor(const uint256& block_hash1,
     180             :         const uint256& block_hash2,
     181             :         const FoundBlock& ancestor_out={},
     182             :         const FoundBlock& block1_out={},
     183             :         const FoundBlock& block2_out={}) = 0;
     184             : 
     185             :     //! Look up unspent output information. Returns coins in the mempool and in
     186             :     //! the current chain UTXO set. Iterates through all the keys in the map and
     187             :     //! populates the values.
     188             :     virtual void findCoins(std::map<COutPoint, Coin>& coins) = 0;
     189             : 
     190             :     //! Estimate fraction of total transactions verified if blocks up to
     191             :     //! the specified block hash are verified.
     192             :     virtual double guessVerificationProgress(const uint256& block_hash) = 0;
     193             : 
     194             :     //! Return true if data is available for all blocks in the specified range
     195             :     //! of blocks. This checks all blocks that are ancestors of block_hash in
     196             :     //! the height range from min_height to max_height, inclusive.
     197             :     virtual bool hasBlocks(const uint256& block_hash, int min_height = 0, std::optional<int> max_height = {}) = 0;
     198             : 
     199             :     //! Check if transaction is RBF opt in.
     200             :     virtual RBFTransactionState isRBFOptIn(const CTransaction& tx) = 0;
     201             : 
     202             :     //! Check if transaction is in mempool.
     203             :     virtual bool isInMempool(const uint256& txid) = 0;
     204             : 
     205             :     //! Check if transaction has descendants in mempool.
     206             :     virtual bool hasDescendantsInMempool(const uint256& txid) = 0;
     207             : 
     208             :     //! Transaction is added to memory pool, if the transaction fee is below the
     209             :     //! amount specified by max_tx_fee, and broadcast to all peers if relay is set to true.
     210             :     //! Return false if the transaction could not be added due to the fee or for another reason.
     211             :     virtual bool broadcastTransaction(const CTransactionRef& tx,
     212             :         const CAmount& max_tx_fee,
     213             :         bool relay,
     214             :         std::string& err_string) = 0;
     215             : 
     216             :     //! Calculate mempool ancestor and descendant counts for the given transaction.
     217             :     virtual void getTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* ancestorsize = nullptr, CAmount* ancestorfees = nullptr) = 0;
     218             : 
     219             :     //! For each outpoint, calculate the fee-bumping cost to spend this outpoint at the specified
     220             :     //  feerate, including bumping its ancestors. For example, if the target feerate is 10sat/vbyte
     221             :     //  and this outpoint refers to a mempool transaction at 3sat/vbyte, the bump fee includes the
     222             :     //  cost to bump the mempool transaction to 10sat/vbyte (i.e. 7 * mempooltx.vsize). If that
     223             :     //  transaction also has, say, an unconfirmed parent with a feerate of 1sat/vbyte, the bump fee
     224             :     //  includes the cost to bump the parent (i.e. 9 * parentmempooltx.vsize).
     225             :     //
     226             :     //  If the outpoint comes from an unconfirmed transaction that is already above the target
     227             :     //  feerate or bumped by its descendant(s) already, it does not need to be bumped. Its bump fee
     228             :     //  is 0. Likewise, if any of the transaction's ancestors are already bumped by a transaction
     229             :     //  in our mempool, they are not included in the transaction's bump fee.
     230             :     //
     231             :     //  Also supported is bump-fee calculation in the case of replacements. If an outpoint
     232             :     //  conflicts with another transaction in the mempool, it is assumed that the goal is to replace
     233             :     //  that transaction. As such, the calculation will exclude the to-be-replaced transaction, but
     234             :     //  will include the fee-bumping cost. If bump fees of descendants of the to-be-replaced
     235             :     //  transaction are requested, the value will be 0. Fee-related RBF rules are not included as
     236             :     //  they are logically distinct.
     237             :     //
     238             :     //  Any outpoints that are otherwise unavailable from the mempool (e.g. UTXOs from confirmed
     239             :     //  transactions or transactions not yet broadcast by the wallet) are given a bump fee of 0.
     240             :     //
     241             :     //  If multiple outpoints come from the same transaction (which would be very rare because
     242             :     //  it means that one transaction has multiple change outputs or paid the same wallet using multiple
     243             :     //  outputs in the same transaction) or have shared ancestry, the bump fees are calculated
     244             :     //  independently, i.e. as if only one of them is spent. This may result in double-fee-bumping. This
     245             :     //  caveat can be rectified per use of the sister-function CalculateCombinedBumpFee(…).
     246             :     virtual std::map<COutPoint, CAmount> CalculateIndividualBumpFees(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) = 0;
     247             : 
     248             :     //! Calculate the combined bump fee for an input set per the same strategy
     249             :     //  as in CalculateIndividualBumpFees(…).
     250             :     //  Unlike CalculateIndividualBumpFees(…), this does not return individual
     251             :     //  bump fees per outpoint, but a single bump fee for the shared ancestry.
     252             :     //  The combined bump fee may be used to correct overestimation due to
     253             :     //  shared ancestry by multiple UTXOs after coin selection.
     254             :     virtual std::optional<CAmount> CalculateCombinedBumpFee(const std::vector<COutPoint>& outpoints, const CFeeRate& target_feerate) = 0;
     255             : 
     256             :     //! Get the node's package limits.
     257             :     //! Currently only returns the ancestor and descendant count limits, but could be enhanced to
     258             :     //! return more policy settings.
     259             :     virtual void getPackageLimits(unsigned int& limit_ancestor_count, unsigned int& limit_descendant_count) = 0;
     260             : 
     261             :     //! Check if transaction will pass the mempool's chain limits.
     262             :     virtual bool checkChainLimits(const CTransactionRef& tx) = 0;
     263             : 
     264             :     //! Estimate smart fee.
     265             :     virtual CFeeRate estimateSmartFee(int num_blocks, bool conservative, FeeCalculation* calc = nullptr) = 0;
     266             : 
     267             :     //! Fee estimator max target.
     268             :     virtual unsigned int estimateMaxBlocks() = 0;
     269             : 
     270             :     //! Mempool minimum fee.
     271             :     virtual CFeeRate mempoolMinFee() = 0;
     272             : 
     273             :     //! Relay current minimum fee (from -minrelaytxfee and -incrementalrelayfee settings).
     274             :     virtual CFeeRate relayMinFee() = 0;
     275             : 
     276             :     //! Relay incremental fee setting (-incrementalrelayfee), reflecting cost of relay.
     277             :     virtual CFeeRate relayIncrementalFee() = 0;
     278             : 
     279             :     //! Relay dust fee setting (-dustrelayfee), reflecting lowest rate it's economical to spend.
     280             :     virtual CFeeRate relayDustFee() = 0;
     281             : 
     282             :     //! Check if any block has been pruned.
     283             :     virtual bool havePruned() = 0;
     284             : 
     285             :     //! Check if the node is ready to broadcast transactions.
     286             :     virtual bool isReadyToBroadcast() = 0;
     287             : 
     288             :     //! Check if in IBD.
     289             :     virtual bool isInitialBlockDownload() = 0;
     290             : 
     291             :     //! Check if shutdown requested.
     292             :     virtual bool shutdownRequested() = 0;
     293             : 
     294             :     //! Send init message.
     295             :     virtual void initMessage(const std::string& message) = 0;
     296             : 
     297             :     //! Send init warning.
     298             :     virtual void initWarning(const bilingual_str& message) = 0;
     299             : 
     300             :     //! Send init error.
     301             :     virtual void initError(const bilingual_str& message) = 0;
     302             : 
     303             :     //! Send progress indicator.
     304             :     virtual void showProgress(const std::string& title, int progress, bool resume_possible) = 0;
     305             : 
     306             :     //! Chain notifications.
     307             :     class Notifications
     308             :     {
     309             :     public:
     310           1 :         virtual ~Notifications() {}
     311           0 :         virtual void transactionAddedToMempool(const CTransactionRef& tx) {}
     312           0 :         virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) {}
     313           0 :         virtual void blockConnected(const BlockInfo& block) {}
     314           0 :         virtual void blockDisconnected(const BlockInfo& block) {}
     315           0 :         virtual void updatedBlockTip() {}
     316           0 :         virtual void chainStateFlushed(const CBlockLocator& locator) {}
     317             :     };
     318             : 
     319             :     //! Register handler for notifications.
     320             :     virtual std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) = 0;
     321             : 
     322             :     //! Wait for pending notifications to be processed unless block hash points to the current
     323             :     //! chain tip.
     324             :     virtual void waitForNotificationsIfTipChanged(const uint256& old_tip) = 0;
     325             : 
     326             :     //! Register handler for RPC. Command is not copied, so reference
     327             :     //! needs to remain valid until Handler is disconnected.
     328             :     virtual std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) = 0;
     329             : 
     330             :     //! Check if deprecated RPC is enabled.
     331             :     virtual bool rpcEnableDeprecated(const std::string& method) = 0;
     332             : 
     333             :     //! Run function after given number of seconds. Cancel any previous calls with same name.
     334             :     virtual void rpcRunLater(const std::string& name, std::function<void()> fn, int64_t seconds) = 0;
     335             : 
     336             :     //! Current RPC serialization flags.
     337             :     virtual int rpcSerializationFlags() = 0;
     338             : 
     339             :     //! Get settings value.
     340             :     virtual common::SettingsValue getSetting(const std::string& arg) = 0;
     341             : 
     342             :     //! Get list of settings values.
     343             :     virtual std::vector<common::SettingsValue> getSettingsList(const std::string& arg) = 0;
     344             : 
     345             :     //! Return <datadir>/settings.json setting value.
     346             :     virtual common::SettingsValue getRwSetting(const std::string& name) = 0;
     347             : 
     348             :     //! Write a setting to <datadir>/settings.json. Optionally just update the
     349             :     //! setting in memory and do not write the file.
     350             :     virtual bool updateRwSetting(const std::string& name, const common::SettingsValue& value, bool write=true) = 0;
     351             : 
     352             :     //! Synchronously send transactionAddedToMempool notifications about all
     353             :     //! current mempool transactions to the specified handler and return after
     354             :     //! the last one is sent. These notifications aren't coordinated with async
     355             :     //! notifications sent by handleNotifications, so out of date async
     356             :     //! notifications from handleNotifications can arrive during and after
     357             :     //! synchronous notifications from requestMempoolTransactions. Clients need
     358             :     //! to be prepared to handle this by ignoring notifications about unknown
     359             :     //! removed transactions and already added new transactions.
     360             :     virtual void requestMempoolTransactions(Notifications& notifications) = 0;
     361             : 
     362             :     //! Return true if an assumed-valid chain is in use.
     363             :     virtual bool hasAssumedValidChain() = 0;
     364             : 
     365             :     //! Get internal node context. Useful for testing, but not
     366             :     //! accessible across processes.
     367           0 :     virtual node::NodeContext* context() { return nullptr; }
     368             : };
     369             : 
     370             : //! Interface to let node manage chain clients (wallets, or maybe tools for
     371             : //! monitoring and analysis in the future).
     372             : class ChainClient
     373             : {
     374             : public:
     375           0 :     virtual ~ChainClient() {}
     376             : 
     377             :     //! Register rpcs.
     378             :     virtual void registerRpcs() = 0;
     379             : 
     380             :     //! Check for errors before loading.
     381             :     virtual bool verify() = 0;
     382             : 
     383             :     //! Load saved state.
     384             :     virtual bool load() = 0;
     385             : 
     386             :     //! Start client execution and provide a scheduler.
     387             :     virtual void start(CScheduler& scheduler) = 0;
     388             : 
     389             :     //! Save state to disk.
     390             :     virtual void flush() = 0;
     391             : 
     392             :     //! Shut down client.
     393             :     virtual void stop() = 0;
     394             : 
     395             :     //! Set mock time.
     396             :     virtual void setMockTime(int64_t time) = 0;
     397             : };
     398             : 
     399             : //! Return implementation of Chain interface.
     400             : std::unique_ptr<Chain> MakeChain(node::NodeContext& node);
     401             : 
     402             : } // namespace interfaces
     403             : 
     404             : #endif // BITCOIN_INTERFACES_CHAIN_H

Generated by: LCOV version 1.14