// Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin Core developers // Copyright (c) 2016-2023 The Zcash developers // Distributed under the MIT software license, see the accompanying // file COPYING or https://www.opensource.org/licenses/mit-license.php . #ifndef BITCOIN_VALIDATIONINTERFACE_H #define BITCOIN_VALIDATIONINTERFACE_H #include #include #include #include "miner.h" #include "zcash/IncrementalMerkleTree.hpp" /** * Limit on the maximum number of blocks that will be staged for * scanning before an interrupt will be handled. */ static const size_t WALLET_NOTIFY_MAX_BLOCKS = 1000; class CBlock; class CBlockIndex; struct CBlockLocator; class CReserveScript; class CTransaction; class CValidationInterface; class CValidationState; class uint256; class BatchScanner { public: /** * Adds a transaction to the batch scanner. * * `block_tag` is the hash of the block that triggered this txid being added * to the batch, or the all-zeros hash to indicate that no block triggered * it (i.e. it was a mempool change). */ virtual void AddTransaction( const CTransaction &tx, const std::vector &txBytes, const uint256 &blockTag, const int nHeight) = 0; /** * Flushes any pending batches. * * After calling this, every transaction passed to `AddTransaction` should * have its result available when the matching call to `SyncTransaction` is * made. */ virtual void Flush() = 0; /** * Notifies the batch scanner of updated transaction data (transaction, and * optionally the block it is found in). * * This will be called with transactions in the same order as they were * `AddTransaction`. */ virtual void SyncTransaction( const CTransaction &tx, const CBlock *pblock, const int nHeight) = 0; }; struct MerkleFrontiers { SproutMerkleTree sprout; SaplingMerkleTree sapling; OrchardMerkleFrontier orchard; }; // These functions dispatch to one or all registered wallets /** Register a wallet to receive updates from core */ void RegisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister a wallet from core */ void UnregisterValidationInterface(CValidationInterface* pwalletIn); /** Unregister all wallets from core */ void UnregisterAllValidationInterfaces(); class CValidationInterface { protected: virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual BatchScanner* GetBatchScanner() { return nullptr; } virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock, const int nHeight) {} virtual void EraseFromWallet(const uint256 &hash) {} virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, std::optional added) {} virtual void UpdatedTransaction(const uint256 &hash) {} virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} virtual void GetAddressForMining(std::optional&) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); friend void ::UnregisterAllValidationInterfaces(); }; // aggregate_non_null_values is a combiner which places any non-nullptr values // returned from slots into a container. template struct aggregate_non_null_values { typedef Container result_type; template Container operator()(InputIterator first, InputIterator last) const { Container values; while (first != last) { auto ptr = *first; if (ptr != nullptr) { values.push_back(ptr); } ++first; } return values; } }; struct CMainSignals { /** Notifies listeners of updated block chain tip */ boost::signals2::signal UpdatedBlockTip; /** * Requests a pointer to the listener's batch scanner for shielded outputs, * if it has one. * * The listener is responsible for managing the memory of the batch scanner. * In practice each listener will have a single persistent batch scanner. * * This signal is called at the start of each notification loop, which runs * on integer second boundaries. This is an opportunity for the listener to * perform any updating of the batch scanner's internal state (such as * updating its set of incoming viewing keys). * * Listeners of this signal should not listen to `SyncTransaction` or they * will be notified about transactions twice. */ boost::signals2::signal< BatchScanner* (), aggregate_non_null_values>> GetBatchScanner; /** * Notifies listeners of updated transaction data (the transaction, and * optionally the block it is found in). * * Listeners of this signal should not listen to `GetBatchScanner` or they * will be notified about transactions twice. */ boost::signals2::signal SyncTransaction; /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */ boost::signals2::signal EraseTransaction; /** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */ boost::signals2::signal UpdatedTransaction; /** Notifies listeners of a change to the tip of the active block chain. */ boost::signals2::signal)> ChainTip; /** Tells listeners to broadcast their data. */ boost::signals2::signal Broadcast; /** Notifies listeners of a block validation result */ boost::signals2::signal BlockChecked; /** Notifies listeners that an address for mining is required (coinbase) */ boost::signals2::signal&)> AddressForMining; }; CMainSignals& GetMainSignals(); void ThreadNotifyWallets(CBlockIndex *pindexLastTip); #endif // BITCOIN_VALIDATIONINTERFACE_H