LCOV - code coverage report
Current view: top level - src/interfaces - chain.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 19 25 76.0 %
Date: 2020-09-26 01:30:44 Functions: 14 26 53.8 %

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

Generated by: LCOV version 1.15