1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-2018 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 CCriticalSection cs_main; 16 class CBlock; 17 class CBlockIndex; 18 struct CBlockLocator; 19 class CBlockIndex; 20 class CConnman; 21 class CReserveScript; 22 class CValidationInterface; 23 class CValidationState; 24 class uint256; 25 class CScheduler; 26 class CTxMemPool; 27 enum class MemPoolRemovalReason; 28 29 // These functions dispatch to one or all registered wallets 30 31 /** Register a wallet to receive updates from core */ 32 void RegisterValidationInterface(CValidationInterface* pwalletIn); 33 /** Unregister a wallet from core */ 34 void UnregisterValidationInterface(CValidationInterface* pwalletIn); 35 /** Unregister all wallets from core */ 36 void UnregisterAllValidationInterfaces(); 37 /** 38 * Pushes a function to callback onto the notification queue, guaranteeing any 39 * callbacks generated prior to now are finished when the function is called. 40 * 41 * Be very careful blocking on func to be called if any locks are held - 42 * validation interface clients may not be able to make progress as they often 43 * wait for things like cs_main, so blocking until func is called with cs_main 44 * will result in a deadlock (that DEBUG_LOCKORDER will miss). 45 */ 46 void CallFunctionInValidationInterfaceQueue(std::function<void ()> func); 47 /** 48 * This is a synonym for the following, which asserts certain locks are not 49 * held: 50 * std::promise<void> promise; 51 * CallFunctionInValidationInterfaceQueue([&promise] { 52 * promise.set_value(); 53 * }); 54 * promise.get_future().wait(); 55 */ 56 void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main); 57 58 /** 59 * Implement this to subscribe to events generated in validation 60 * 61 * Each CValidationInterface() subscriber will receive event callbacks 62 * in the order in which the events were generated by validation. 63 * Furthermore, each ValidationInterface() subscriber may assume that 64 * callbacks effectively run in a single thread with single-threaded 65 * memory consistency. That is, for a given ValidationInterface() 66 * instantiation, each callback will complete before the next one is 67 * invoked. This means, for example when a block is connected that the 68 * UpdatedBlockTip() callback may depend on an operation performed in 69 * the BlockConnected() callback without worrying about explicit 70 * synchronization. No ordering should be assumed across 71 * ValidationInterface() subscribers. 72 */ 73 class CValidationInterface { 74 protected: 75 /** 76 * Protected destructor so that instances can only be deleted by derived classes. 77 * If that restriction is no longer desired, this should be made public and virtual. 78 */ 79 ~CValidationInterface() = default; 80 /** 81 * Notifies listeners when the block chain tip advances. 82 * 83 * When multiple blocks are connected at once, UpdatedBlockTip will be called on the final tip 84 * but may not be called on every intermediate tip. If the latter behavior is desired, 85 * subscribe to BlockConnected() instead. 86 * 87 * Called on a background thread. 88 */ UpdatedBlockTip(const CBlockIndex * pindexNew,const CBlockIndex * pindexFork,bool fInitialDownload)89 virtual void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) {} 90 /** 91 * Notifies listeners of a transaction having been added to mempool. 92 * 93 * Called on a background thread. 94 */ TransactionAddedToMempool(const CTransactionRef & ptxn)95 virtual void TransactionAddedToMempool(const CTransactionRef &ptxn) {} 96 /** 97 * Notifies listeners of a transaction leaving mempool. 98 * 99 * This only fires for transactions which leave mempool because of expiry, 100 * size limiting, reorg (changes in lock times/coinbase maturity), or 101 * replacement. This does not include any transactions which are included 102 * in BlockConnectedDisconnected either in block->vtx or in txnConflicted. 103 * 104 * Called on a background thread. 105 */ TransactionRemovedFromMempool(const CTransactionRef & ptx)106 virtual void TransactionRemovedFromMempool(const CTransactionRef &ptx) {} 107 /** 108 * Notifies listeners of a block being connected. 109 * Provides a vector of transactions evicted from the mempool as a result. 110 * 111 * Called on a background thread. 112 */ BlockConnected(const std::shared_ptr<const CBlock> & block,const CBlockIndex * pindex,const std::vector<CTransactionRef> & txnConflicted)113 virtual void BlockConnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex, const std::vector<CTransactionRef> &txnConflicted) {} 114 /** 115 * Notifies listeners of a block being disconnected 116 * 117 * Called on a background thread. 118 */ BlockDisconnected(const std::shared_ptr<const CBlock> & block)119 virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block) {} 120 /** 121 * Notifies listeners of the new active block chain on-disk. 122 * 123 * Prior to this callback, any updates are not guaranteed to persist on disk 124 * (ie clients need to handle shutdown/restart safety by being able to 125 * understand when some updates were lost due to unclean shutdown). 126 * 127 * When this callback is invoked, the validation changes done by any prior 128 * callback are guaranteed to exist on disk and survive a restart, including 129 * an unclean shutdown. 130 * 131 * Provides a locator describing the best chain, which is likely useful for 132 * storing current state on disk in client DBs. 133 * 134 * Called on a background thread. 135 */ ChainStateFlushed(const CBlockLocator & locator)136 virtual void ChainStateFlushed(const CBlockLocator &locator) {} 137 /** Tells listeners to broadcast their data. */ ResendWalletTransactions(int64_t nBestBlockTime,CConnman * connman)138 virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) {} 139 /** 140 * Notifies listeners of a block validation result. 141 * If the provided CValidationState IsValid, the provided block 142 * is guaranteed to be the current best block at the time the 143 * callback was generated (not necessarily now) 144 */ BlockChecked(const CBlock &,const CValidationState &)145 virtual void BlockChecked(const CBlock&, const CValidationState&) {} 146 /** 147 * Notifies listeners that a block which builds directly on our current tip 148 * has been received and connected to the headers tree, though not validated yet */ NewPoWValidBlock(const CBlockIndex * pindex,const std::shared_ptr<const CBlock> & block)149 virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& block) {}; 150 friend void ::RegisterValidationInterface(CValidationInterface*); 151 friend void ::UnregisterValidationInterface(CValidationInterface*); 152 friend void ::UnregisterAllValidationInterfaces(); 153 }; 154 155 struct MainSignalsInstance; 156 class CMainSignals { 157 private: 158 std::unique_ptr<MainSignalsInstance> m_internals; 159 160 friend void ::RegisterValidationInterface(CValidationInterface*); 161 friend void ::UnregisterValidationInterface(CValidationInterface*); 162 friend void ::UnregisterAllValidationInterfaces(); 163 friend void ::CallFunctionInValidationInterfaceQueue(std::function<void ()> func); 164 165 void MempoolEntryRemoved(CTransactionRef tx, MemPoolRemovalReason reason); 166 167 public: 168 /** Register a CScheduler to give callbacks which should run in the background (may only be called once) */ 169 void RegisterBackgroundSignalScheduler(CScheduler& scheduler); 170 /** Unregister a CScheduler to give callbacks which should run in the background - these callbacks will now be dropped! */ 171 void UnregisterBackgroundSignalScheduler(); 172 /** Call any remaining callbacks on the calling thread */ 173 void FlushBackgroundCallbacks(); 174 175 size_t CallbacksPending(); 176 177 /** Register with mempool to call TransactionRemovedFromMempool callbacks */ 178 void RegisterWithMempoolSignals(CTxMemPool& pool); 179 /** Unregister with mempool */ 180 void UnregisterWithMempoolSignals(CTxMemPool& pool); 181 182 void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload); 183 void TransactionAddedToMempool(const CTransactionRef &); 184 void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::shared_ptr<const std::vector<CTransactionRef>> &); 185 void BlockDisconnected(const std::shared_ptr<const CBlock> &); 186 void ChainStateFlushed(const CBlockLocator &); 187 void Broadcast(int64_t nBestBlockTime, CConnman* connman); 188 void BlockChecked(const CBlock&, const CValidationState&); 189 void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&); 190 }; 191 192 CMainSignals& GetMainSignals(); 193 194 #endif // BITCOIN_VALIDATIONINTERFACE_H 195