LCOV - code coverage report
Current view: top level - src - validationinterface.h (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 19 19 100.0 %
Date: 2026-06-25 07:23:43 Functions: 20 22 90.9 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2020 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #ifndef BITCOIN_VALIDATIONINTERFACE_H
       7             : #define BITCOIN_VALIDATIONINTERFACE_H
       8             : 
       9             : #include <primitives/transaction.h> // CTransaction(Ref)
      10             : #include <sync.h>
      11             : 
      12             : #include <functional>
      13             : #include <memory>
      14             : 
      15             : extern RecursiveMutex cs_main; // NOLINT(readability-redundant-declaration)
      16             : class BlockValidationState;
      17             : class CBlock;
      18             : class CBlockIndex;
      19             : struct CBlockLocator;
      20             : class CValidationInterface;
      21             : class CGovernanceVote;
      22             : class CDeterministicMNList;
      23             : class CDeterministicMNListDiff;
      24             : class CScheduler;
      25             : enum class MemPoolRemovalReason;
      26             : namespace chainlock {
      27             : struct ChainLockSig;
      28             : } // namespace chainlock
      29             : namespace Governance {
      30             : class Object;
      31             : } // namespace Governance
      32             : namespace instantsend {
      33             : struct InstantSendLock;
      34             : } // namespace instantsend
      35             : namespace llmq {
      36             : class CRecoveredSig;
      37             : } // namespace llmq
      38             : 
      39             : /** Register subscriber */
      40             : void RegisterValidationInterface(CValidationInterface* callbacks);
      41             : /** Unregister subscriber. DEPRECATED. This is not safe to use when the RPC server or main message handler thread is running. */
      42             : void UnregisterValidationInterface(CValidationInterface* callbacks);
      43             : /** Unregister all subscribers */
      44             : void UnregisterAllValidationInterfaces();
      45             : 
      46             : // Alternate registration functions that release a shared_ptr after the last
      47             : // notification is sent. These are useful for race-free cleanup, since
      48             : // unregistration is nonblocking and can return before the last notification is
      49             : // processed.
      50             : /** Register subscriber */
      51             : void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);
      52             : /** Unregister subscriber */
      53             : void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);
      54             : 
      55             : /**
      56             :  * Pushes a function to callback onto the notification queue, guaranteeing any
      57             :  * callbacks generated prior to now are finished when the function is called.
      58             :  *
      59             :  * Be very careful blocking on func to be called if any locks are held -
      60             :  * validation interface clients may not be able to make progress as they often
      61             :  * wait for things like cs_main, so blocking until func is called with cs_main
      62             :  * will result in a deadlock (that DEBUG_LOCKORDER will miss).
      63             :  */
      64             : void CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
      65             : /**
      66             :  * This is a synonym for the following, which asserts certain locks are not
      67             :  * held:
      68             :  *     std::promise<void> promise;
      69             :  *     CallFunctionInValidationInterfaceQueue([&promise] {
      70             :  *         promise.set_value();
      71             :  *     });
      72             :  *     promise.get_future().wait();
      73             :  */
      74             : void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);
      75             : 
      76             : /**
      77             :  * Implement this to subscribe to events generated in validation
      78             :  *
      79             :  * Each CValidationInterface() subscriber will receive event callbacks
      80             :  * in the order in which the events were generated by validation.
      81             :  * Furthermore, each ValidationInterface() subscriber may assume that
      82             :  * callbacks effectively run in a single thread with single-threaded
      83             :  * memory consistency. That is, for a given ValidationInterface()
      84             :  * instantiation, each callback will complete before the next one is
      85             :  * invoked. This means, for example when a block is connected that the
      86             :  * UpdatedBlockTip() callback may depend on an operation performed in
      87             :  * the BlockConnected() callback without worrying about explicit
      88             :  * synchronization. No ordering should be assumed across
      89             :  * ValidationInterface() subscribers.
      90             :  */
      91             : class CValidationInterface {
      92             : protected:
      93     1766040 :     virtual void AcceptedBlockHeader(const CBlockIndex *pindexNew) {}
      94     1621302 :     virtual void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload) {}
      95             :     /**
      96             :      * Protected destructor so that instances can only be deleted by derived classes.
      97             :      * If that restriction is no longer desired, this should be made public and virtual.
      98             :      */
      99             :     ~CValidationInterface() = default;
     100             :     /**
     101             :      * Notifies listeners when the block chain tip advances.
     102             :      *
     103             :      * When multiple blocks are connected at once, UpdatedBlockTip will be called on the final tip
     104             :      * but may not be called on every intermediate tip. If the latter behavior is desired,
     105             :      * subscribe to BlockConnected() instead.
     106             :      *
     107             :      * Called on a background thread.
     108             :      */
     109      548622 :     virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
     110             :     /**
     111             :      * Force UpdatedBlockTip to initialize block-tip-dependent state at
     112             :      * startup (e.g. nCachedBlockHeight for DS/MN payments/budgets,
     113             :      * quorum connections).  Called synchronously from the loadblk
     114             :      * thread — once after ThreadImport for general subscribers and
     115             :      * again after nodeman->Init() so that masternode-specific state
     116             :      * (proTxHash) is available for quorum connection setup.
     117             :      *
     118             :      * Unlike GetMainSignals().UpdatedBlockTip(), this does not trigger
     119             :      * other listeners like ZMQ.
     120             :      */
     121       18196 :     virtual void InitializeCurrentBlockTip(const CBlockIndex* /*tip*/, bool /*ibd*/) {}
     122             :     /**
     123             :      * Same as UpdatedBlockTip, but called from the caller's thread
     124             :      */
     125     1622817 :     virtual void SynchronousUpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}
     126             :     /**
     127             :      * Notifies listeners of a transaction having been added to mempool.
     128             :      *
     129             :      * Called on a background thread.
     130             :      */
     131      188077 :     virtual void TransactionAddedToMempool(const CTransactionRef &xn, int64_t nAcceptTime, uint64_t mempool_sequence) {}
     132             : 
     133             :     /**
     134             :      * Notifies listeners of a transaction leaving mempool.
     135             :      *
     136             :      * This notification fires for transactions that are removed from the
     137             :      * mempool for the following reasons:
     138             :      *
     139             :      * - EXPIRY (expired from mempool after -mempoolexpiry hours)
     140             :      * - SIZELIMIT (removed in size limiting if the mempool exceeds -maxmempool megabytes)
     141             :      * - REORG (removed during a reorg)
     142             :      * - CONFLICT (removed because it conflicts with in-block transaction)
     143             :      *
     144             :      * This does not fire for transactions that are removed from the mempool
     145             :      * because they have been included in a block. Any client that is interested
     146             :      * in transactions removed from the mempool for inclusion in a block can learn
     147             :      * about those transactions from the BlockConnected notification.
     148             :      *
     149             :      * Transactions that are removed from the mempool because they conflict
     150             :      * with a transaction in the new block will have
     151             :      * TransactionRemovedFromMempool events fired *before* the BlockConnected
     152             :      * event is fired. If multiple blocks are connected in one step, then the
     153             :      * ordering could be:
     154             :      *
     155             :      * - TransactionRemovedFromMempool(tx1 from block A)
     156             :      * - TransactionRemovedFromMempool(tx2 from block A)
     157             :      * - TransactionRemovedFromMempool(tx1 from block B)
     158             :      * - TransactionRemovedFromMempool(tx2 from block B)
     159             :      * - BlockConnected(A)
     160             :      * - BlockConnected(B)
     161             :      *
     162             :      * Called on a background thread.
     163             :      */
     164        2408 :     virtual void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {}
     165             :     /**
     166             :      * Notifies listeners of a block being connected.
     167             :      * Provides a vector of transactions evicted from the mempool as a result.
     168             :      *
     169             :      * Called on a background thread.
     170             :      */
     171      684503 :     virtual void BlockConnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
     172             :     /**
     173             :      * Notifies listeners of a block being disconnected
     174             :      *
     175             :      * Called on a background thread.
     176             :      */
     177       56929 :     virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
     178        7712 :     virtual void NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const instantsend::InstantSendLock>& islock) {}
     179      104852 :     virtual void NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const chainlock::ChainLockSig>& clsig) {}
     180       14544 :     virtual void NotifyGovernanceVote(const std::shared_ptr<CDeterministicMNList>& tip_mn_list, const std::shared_ptr<const CGovernanceVote>& vote) {}
     181        2948 :     virtual void NotifyGovernanceObject(const std::shared_ptr<const Governance::Object>& object) {}
     182          18 :     virtual void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef& currentTx, const CTransactionRef& previousTx) {}
     183      244688 :     virtual void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig>& sig, bool proactive_relay) {}
     184      878420 :     virtual void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff) {}
     185             :     /**
     186             :      * Notifies listeners of the new active block chain on-disk.
     187             :      *
     188             :      * Prior to this callback, any updates are not guaranteed to persist on disk
     189             :      * (ie clients need to handle shutdown/restart safety by being able to
     190             :      * understand when some updates were lost due to unclean shutdown).
     191             :      *
     192             :      * When this callback is invoked, the validation changes done by any prior
     193             :      * callback are guaranteed to exist on disk and survive a restart, including
     194             :      * an unclean shutdown.
     195             :      *
     196             :      * Provides a locator describing the best chain, which is likely useful for
     197             :      * storing current state on disk in client DBs.
     198             :      *
     199             :      * Called on a background thread.
     200             :      */
     201       18005 :     virtual void ChainStateFlushed(const CBlockLocator &locator) {}
     202             :     /**
     203             :      * Notifies listeners of a block validation result.
     204             :      * If the provided BlockValidationState IsValid, the provided block
     205             :      * is guaranteed to be the current best block at the time the
     206             :      * callback was generated (not necessarily now)
     207             :      */
     208     1923964 :     virtual void BlockChecked(const CBlock&, const BlockValidationState&) {}
     209             :     /**
     210             :      * Notifies listeners that a block which builds directly on our current tip
     211             :      * has been received and connected to the headers tree, though not validated yet */
     212     1687772 :     virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& block) {};
     213             :     friend class CMainSignals;
     214             :     friend class ValidationInterfaceTest;
     215             : };
     216             : 
     217             : class MainSignalsImpl;
     218             : class CMainSignals {
     219             : private:
     220             :     std::unique_ptr<MainSignalsImpl> m_internals;
     221             : 
     222             :     friend void ::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface>);
     223             :     friend void ::UnregisterValidationInterface(CValidationInterface*);
     224             :     friend void ::UnregisterAllValidationInterfaces();
     225             :     friend void ::CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
     226             : 
     227             : public:
     228             :     /** Register a CScheduler to give callbacks which should run in the background (may only be called once) */
     229             :     void RegisterBackgroundSignalScheduler(CScheduler& scheduler);
     230             :     /** Unregister a CScheduler to give callbacks which should run in the background - these callbacks will now be dropped! */
     231             :     void UnregisterBackgroundSignalScheduler();
     232             :     /** Call any remaining callbacks on the calling thread */
     233             :     void FlushBackgroundCallbacks();
     234             : 
     235             :     size_t CallbacksPending();
     236             : 
     237             : 
     238             :     void AcceptedBlockHeader(const CBlockIndex *pindexNew);
     239             :     void NotifyHeaderTip(const CBlockIndex *pindexNew, bool fInitialDownload);
     240             :     void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
     241             :     void InitializeCurrentBlockTip(const CBlockIndex* tip, bool ibd);
     242             :     void SynchronousUpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
     243             :     void TransactionAddedToMempool(const CTransactionRef&, int64_t, uint64_t mempool_sequence);
     244             :     void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);
     245             :     void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
     246             :     void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindex);
     247             :     void NotifyTransactionLock(const CTransactionRef &tx, const std::shared_ptr<const instantsend::InstantSendLock>& islock);
     248             :     void NotifyChainLock(const CBlockIndex* pindex, const std::shared_ptr<const chainlock::ChainLockSig>& clsig, const std::string& id);
     249             :     void NotifyGovernanceVote(const std::shared_ptr<CDeterministicMNList>& tip_mn_list, const std::shared_ptr<const CGovernanceVote>& vote, const std::string& id);
     250             :     void NotifyGovernanceObject(const std::shared_ptr<const Governance::Object>& object, const std::string& id);
     251             :     void NotifyInstantSendDoubleSpendAttempt(const CTransactionRef &currentTx, const CTransactionRef &previousTx);
     252             :     void NotifyRecoveredSig(const std::shared_ptr<const llmq::CRecoveredSig> &sig, const std::string& id, bool proactive_relay);
     253             :     void NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& oldMNList, const CDeterministicMNListDiff& diff);
     254             :     void ChainStateFlushed(const CBlockLocator &);
     255             :     void BlockChecked(const CBlock&, const BlockValidationState&);
     256             :     void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
     257             : };
     258             : 
     259             : CMainSignals& GetMainSignals();
     260             : 
     261             : #endif // BITCOIN_VALIDATIONINTERFACE_H

Generated by: LCOV version 1.16