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 ¤tTx, 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