172 lines
6.3 KiB
C++
172 lines
6.3 KiB
C++
// 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 <optional>
|
|
|
|
#include <boost/signals2/signal.hpp>
|
|
#include <boost/shared_ptr.hpp>
|
|
|
|
#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<unsigned char> &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<MerkleFrontiers> 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<MinerAddress>&) {};
|
|
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<typename Container>
|
|
struct aggregate_non_null_values
|
|
{
|
|
typedef Container result_type;
|
|
|
|
template<typename InputIterator>
|
|
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<void (const CBlockIndex *)> 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<std::vector<BatchScanner*>>> 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<void (const CTransaction &, const CBlock *, const int nHeight)> SyncTransaction;
|
|
/** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
|
|
boost::signals2::signal<void (const uint256 &)> EraseTransaction;
|
|
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
|
|
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
|
|
/** Notifies listeners of a change to the tip of the active block chain. */
|
|
boost::signals2::signal<void (const CBlockIndex *, const CBlock *, std::optional<MerkleFrontiers>)> ChainTip;
|
|
/** Tells listeners to broadcast their data. */
|
|
boost::signals2::signal<void (int64_t nBestBlockTime)> Broadcast;
|
|
/** Notifies listeners of a block validation result */
|
|
boost::signals2::signal<void (const CBlock&, const CValidationState&)> BlockChecked;
|
|
/** Notifies listeners that an address for mining is required (coinbase) */
|
|
boost::signals2::signal<void (std::optional<MinerAddress>&)> AddressForMining;
|
|
};
|
|
|
|
CMainSignals& GetMainSignals();
|
|
|
|
void ThreadNotifyWallets(CBlockIndex *pindexLastTip);
|
|
|
|
#endif // BITCOIN_VALIDATIONINTERFACE_H
|