Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6#ifndef BITCOIN_VALIDATIONINTERFACE_H7#define BITCOIN_VALIDATIONINTERFACE_H9#include <kernel/cs_main.h>10#include <primitives/transaction.h>11#include <sync.h>12#include <uint256.h>14#include <cstddef>15#include <cstdint>16#include <functional>17#include <memory>18#include <vector>20namespace kernel {21struct ChainstateRole;22} // namespace kernel23namespace util {24class TaskRunnerInterface;25} // namespace util27class BlockValidationState;28class CBlock;29class CBlockIndex;30struct CBlockLocator;31enum class MemPoolRemovalReason;32struct RemovedMempoolTransactionInfo;33struct NewMempoolTransactionInfo;35/**36* Implement this to subscribe to events generated in validation and mempool37*38* Each CValidationInterface() subscriber will receive event callbacks39* in the order in which the events were generated by validation and mempool.40* Furthermore, each ValidationInterface() subscriber may assume that41* callbacks effectively run in a single thread with single-threaded42* memory consistency. That is, for a given ValidationInterface()43* instantiation, each callback will complete before the next one is44* invoked. This means, for example when a block is connected that the45* UpdatedBlockTip() callback may depend on an operation performed in46* the BlockConnected() callback without worrying about explicit47* synchronization. No ordering should be assumed across48* ValidationInterface() subscribers.49*/50class CValidationInterface {51protected:52/**53* Protected destructor so that instances can only be deleted by derived classes.54* If that restriction is no longer desired, this should be made public and virtual.55*/56~CValidationInterface() = default;57/**58* Notifies listeners when the block chain tip advances.59*60* When multiple blocks are connected at once, UpdatedBlockTip will be called on the final tip61* but may not be called on every intermediate tip. If the latter behavior is desired,62* subscribe to BlockConnected() instead.63*64* Called on a background thread. Only called for the active chainstate.65*/66virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {}67/**68* Notifies listeners any time the block chain tip changes, synchronously.69*/70virtual void ActiveTipChange(const CBlockIndex& new_tip, bool is_ibd) {};71/**72* Notifies listeners of a transaction having been added to mempool.73*74* Called on a background thread.75*/76virtual void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t mempool_sequence) {}78/**79* Notifies listeners of a transaction leaving mempool.80*81* This notification fires for transactions that are removed from the82* mempool for the following reasons:83*84* - EXPIRY (expired from mempool after -mempoolexpiry hours)85* - SIZELIMIT (removed in size limiting if the mempool exceeds -maxmempool megabytes)86* - REORG (removed during a reorg)87* - CONFLICT (removed because it conflicts with in-block transaction)88* - REPLACED (removed due to RBF replacement)89*90* This does not fire for transactions that are removed from the mempool91* because they have been included in a block. Any client that is interested92* in transactions removed from the mempool for inclusion in a block can learn93* about those transactions from the MempoolTransactionsRemovedForBlock notification.94*95* Transactions that are removed from the mempool because they conflict96* with a transaction in the new block will have97* TransactionRemovedFromMempool events fired *before* the BlockConnected98* event is fired. If multiple blocks are connected in one step, then the99* ordering could be:100*101* - TransactionRemovedFromMempool(tx1 from block A)102* - TransactionRemovedFromMempool(tx2 from block A)103* - TransactionRemovedFromMempool(tx1 from block B)104* - TransactionRemovedFromMempool(tx2 from block B)105* - BlockConnected(A)106* - BlockConnected(B)107*108* Called on a background thread.109*/110virtual void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) {}111/*112* Notifies listeners of transactions removed from the mempool as113* as a result of new block being connected.114* MempoolTransactionsRemovedForBlock will be fired before BlockConnected.115*116* Not fired while initial block download is active.117*118* Called on a background thread.119*/120virtual void MempoolTransactionsRemovedForBlock(const std::shared_ptr<const CBlock>& block, const std::vector<RemovedMempoolTransactionInfo>& txs_removed_for_block, unsigned int block_height) {}121/**122* Notifies listeners of a block being connected.123*124* Called on a background thread.125*/126virtual void BlockConnected(const kernel::ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) {}127/**128* Notifies listeners of a block being disconnected129* Provides the block that was disconnected.130*131* Called on a background thread. Only called for the active chainstate, since132* background chainstates should never disconnect blocks.133*/134virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) {}135/**136* Notifies listeners of the new active block chain on-disk.137*138* Prior to this callback, any updates are not guaranteed to persist on disk139* (ie clients need to handle shutdown/restart safety by being able to140* understand when some updates were lost due to unclean shutdown).141*142* When this callback is invoked, the validation changes done by any prior143* callback are guaranteed to exist on disk and survive a restart, including144* an unclean shutdown.145*146* Provides a locator describing the best chain, which is likely useful for147* storing current state on disk in client DBs.148*149* Called on a background thread.150*/151virtual void ChainStateFlushed(const kernel::ChainstateRole& role, const CBlockLocator& locator) {}152/**153* Notifies listeners of a block validation result.154* If the provided BlockValidationState IsValid, the provided block155* is guaranteed to be the current best block at the time the156* callback was generated (not necessarily now).157*/158virtual void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&) {}159/**160* Notifies listeners that a block which builds directly on our current tip161* has been received and connected to the headers tree, though not validated yet.162*/163virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& block) {};164friend class ValidationSignals;165friend class ValidationInterfaceTest;166};168class ValidationSignalsImpl;169class ValidationSignals {170private:171std::unique_ptr<ValidationSignalsImpl> m_internals;173public:174// The task runner will block validation if it calls its insert method's175// func argument synchronously. In this class func contains a loop that176// dispatches a single validation event to all subscribers sequentially.177explicit ValidationSignals(std::unique_ptr<util::TaskRunnerInterface> task_runner);179~ValidationSignals();181/** Call any remaining callbacks on the calling thread */182void FlushBackgroundCallbacks();184size_t CallbacksPending();186/** Register subscriber */187void RegisterValidationInterface(CValidationInterface* callbacks);188/** Unregister subscriber. DEPRECATED. This is not safe to use when the RPC server or main message handler thread is running. */189void UnregisterValidationInterface(CValidationInterface* callbacks);190/** Unregister all subscribers */191void UnregisterAllValidationInterfaces();193// Alternate registration functions that release a shared_ptr after the last194// notification is sent. These are useful for race-free cleanup, since195// unregistration is nonblocking and can return before the last notification is196// processed.197/** Register subscriber */198void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);199/** Unregister subscriber */200void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);202/**203* Pushes a function to callback onto the notification queue, guaranteeing any204* callbacks generated prior to now are finished when the function is called.205*206* Be very careful blocking on func to be called if any locks are held -207* validation interface clients may not be able to make progress as they often208* wait for things like cs_main, so blocking until func is called with cs_main209* will result in a deadlock (that DEBUG_LOCKORDER will miss).210*/211void CallFunctionInValidationInterfaceQueue(std::function<void ()> func);213/**214* This is a synonym for the following, which asserts certain locks are not215* held:216* std::promise<void> promise;217* CallFunctionInValidationInterfaceQueue([&promise] {218* promise.set_value();219* });220* promise.get_future().wait();221*/222void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);224void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);225void ActiveTipChange(const CBlockIndex&, bool);226void TransactionAddedToMempool(const NewMempoolTransactionInfo&, uint64_t mempool_sequence);227void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);228void MempoolTransactionsRemovedForBlock(std::shared_ptr<const CBlock>, std::vector<RemovedMempoolTransactionInfo>, unsigned int block_height);229void BlockConnected(const kernel::ChainstateRole&, std::shared_ptr<const CBlock>, const CBlockIndex* pindex);230void BlockDisconnected(std::shared_ptr<const CBlock>, const CBlockIndex* pindex);231void ChainStateFlushed(const kernel::ChainstateRole&, const CBlockLocator&);232void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&);233void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);234};236#endif // BITCOIN_VALIDATIONINTERFACE_H
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.