mirror of
https://github.com/bitcoin/bitcoin.git
synced 2024-11-19 09:53:47 +01:00
validation: pass ChainstateRole for validationinterface calls
This allows consumers to decide how to handle events from background or assumedvalid chainstates.
This commit is contained in:
parent
1e59acdf17
commit
4d8f4dcb45
@ -70,7 +70,7 @@ void generateFakeBlock(const CChainParams& params,
|
||||
|
||||
// notify wallet
|
||||
const auto& pindex = WITH_LOCK(::cs_main, return context.chainman->ActiveChain().Tip());
|
||||
wallet.blockConnected(kernel::MakeBlockInfo(pindex, &block));
|
||||
wallet.blockConnected(ChainstateRole::NORMAL, kernel::MakeBlockInfo(pindex, &block));
|
||||
}
|
||||
|
||||
struct PreSelectInputs {
|
||||
|
@ -250,7 +250,7 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
|
||||
return true;
|
||||
}
|
||||
|
||||
void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex)
|
||||
void BaseIndex::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex)
|
||||
{
|
||||
if (!m_synced) {
|
||||
return;
|
||||
@ -296,7 +296,7 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
|
||||
}
|
||||
}
|
||||
|
||||
void BaseIndex::ChainStateFlushed(const CBlockLocator& locator)
|
||||
void BaseIndex::ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator)
|
||||
{
|
||||
if (!m_synced) {
|
||||
return;
|
||||
|
@ -102,9 +102,9 @@ protected:
|
||||
Chainstate* m_chainstate{nullptr};
|
||||
const std::string m_name;
|
||||
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
|
||||
void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
|
||||
|
||||
void ChainStateFlushed(const CBlockLocator& locator) override;
|
||||
void ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator) override;
|
||||
|
||||
/// Initialize internal state from the database and block index.
|
||||
[[nodiscard]] virtual bool CustomInit(const std::optional<interfaces::BlockKey>& block) { return true; }
|
||||
|
@ -27,6 +27,7 @@ class Coin;
|
||||
class uint256;
|
||||
enum class MemPoolRemovalReason;
|
||||
enum class RBFTransactionState;
|
||||
enum class ChainstateRole;
|
||||
struct bilingual_str;
|
||||
struct CBlockLocator;
|
||||
struct FeeCalculation;
|
||||
@ -310,10 +311,10 @@ public:
|
||||
virtual ~Notifications() {}
|
||||
virtual void transactionAddedToMempool(const CTransactionRef& tx) {}
|
||||
virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) {}
|
||||
virtual void blockConnected(const BlockInfo& block) {}
|
||||
virtual void blockConnected(ChainstateRole role, const BlockInfo& block) {}
|
||||
virtual void blockDisconnected(const BlockInfo& block) {}
|
||||
virtual void updatedBlockTip() {}
|
||||
virtual void chainStateFlushed(const CBlockLocator& locator) {}
|
||||
virtual void chainStateFlushed(ChainstateRole role, const CBlockLocator& locator) {}
|
||||
};
|
||||
|
||||
//! Register handler for notifications.
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <kernel/mempool_entry.h>
|
||||
#include <logging.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <merkleblock.h>
|
||||
#include <netbase.h>
|
||||
#include <netmessagemaker.h>
|
||||
@ -483,7 +484,7 @@ public:
|
||||
CTxMemPool& pool, Options opts);
|
||||
|
||||
/** Overridden from CValidationInterface. */
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
|
||||
void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override
|
||||
EXCLUSIVE_LOCKS_REQUIRED(!m_recent_confirmed_transactions_mutex);
|
||||
@ -1911,7 +1912,10 @@ void PeerManagerImpl::StartScheduledTasks(CScheduler& scheduler)
|
||||
* announcements for them. Also save the time of the last tip update and
|
||||
* possibly reduce dynamic block stalling timeout.
|
||||
*/
|
||||
void PeerManagerImpl::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindex)
|
||||
void PeerManagerImpl::BlockConnected(
|
||||
ChainstateRole role,
|
||||
const std::shared_ptr<const CBlock>& pblock,
|
||||
const CBlockIndex* pindex)
|
||||
{
|
||||
m_orphanage.EraseForBlock(*pblock);
|
||||
m_last_tip_update = GetTime<std::chrono::seconds>();
|
||||
|
@ -434,9 +434,9 @@ public:
|
||||
{
|
||||
m_notifications->transactionRemovedFromMempool(tx, reason);
|
||||
}
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
|
||||
void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
|
||||
{
|
||||
m_notifications->blockConnected(kernel::MakeBlockInfo(index, block.get()));
|
||||
m_notifications->blockConnected(role, kernel::MakeBlockInfo(index, block.get()));
|
||||
}
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
|
||||
{
|
||||
@ -446,7 +446,9 @@ public:
|
||||
{
|
||||
m_notifications->updatedBlockTip();
|
||||
}
|
||||
void ChainStateFlushed(const CBlockLocator& locator) override { m_notifications->chainStateFlushed(locator); }
|
||||
void ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator) override {
|
||||
m_notifications->chainStateFlushed(role, locator);
|
||||
}
|
||||
std::shared_ptr<Chain::Notifications> m_notifications;
|
||||
};
|
||||
|
||||
|
@ -105,7 +105,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_unclean_shutdown, TestChain100Setup)
|
||||
// Send block connected notification, then stop the index without
|
||||
// sending a chainstate flushed notification. Prior to #24138, this
|
||||
// would cause the index to be corrupted and fail to reload.
|
||||
ValidationInterfaceTest::BlockConnected(index, new_block, new_block_index);
|
||||
ValidationInterfaceTest::BlockConnected(ChainstateRole::NORMAL, index, new_block, new_block_index);
|
||||
index.Stop();
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,11 @@ void TestChainstateManager::JumpOutOfIbd()
|
||||
Assert(!IsInitialBlockDownload());
|
||||
}
|
||||
|
||||
void ValidationInterfaceTest::BlockConnected(CValidationInterface& obj, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex)
|
||||
void ValidationInterfaceTest::BlockConnected(
|
||||
ChainstateRole role,
|
||||
CValidationInterface& obj,
|
||||
const std::shared_ptr<const CBlock>& block,
|
||||
const CBlockIndex* pindex)
|
||||
{
|
||||
obj.BlockConnected(block, pindex);
|
||||
obj.BlockConnected(role, block, pindex);
|
||||
}
|
||||
|
@ -19,7 +19,11 @@ struct TestChainstateManager : public ChainstateManager {
|
||||
class ValidationInterfaceTest
|
||||
{
|
||||
public:
|
||||
static void BlockConnected(CValidationInterface& obj, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex);
|
||||
static void BlockConnected(
|
||||
ChainstateRole role,
|
||||
CValidationInterface& obj,
|
||||
const std::shared_ptr<const CBlock>& block,
|
||||
const CBlockIndex* pindex);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_TEST_UTIL_VALIDATION_H
|
||||
|
@ -43,7 +43,7 @@ struct TestSubscriber final : public CValidationInterface {
|
||||
BOOST_CHECK_EQUAL(m_expected_tip, pindexNew->GetBlockHash());
|
||||
}
|
||||
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override
|
||||
void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override
|
||||
{
|
||||
BOOST_CHECK_EQUAL(m_expected_tip, block->hashPrevBlock);
|
||||
BOOST_CHECK_EQUAL(m_expected_tip, pindex->pprev->GetBlockHash());
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <scheduler.h>
|
||||
#include <test/util/setup_common.h>
|
||||
#include <util/check.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <validationinterface.h>
|
||||
|
||||
#include <atomic>
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <validation.h>
|
||||
|
||||
#include <kernel/chain.h>
|
||||
#include <kernel/coinstats.h>
|
||||
#include <kernel/mempool_persist.h>
|
||||
|
||||
@ -2645,7 +2646,7 @@ bool Chainstate::FlushStateToDisk(
|
||||
}
|
||||
if (full_flush_completed) {
|
||||
// Update best block in wallet (so we can detect restored wallets).
|
||||
GetMainSignals().ChainStateFlushed(m_chain.GetLocator());
|
||||
GetMainSignals().ChainStateFlushed(this->GetRole(), m_chain.GetLocator());
|
||||
}
|
||||
} catch (const std::runtime_error& e) {
|
||||
return FatalError(m_chainman.GetNotifications(), state, std::string("System error while flushing: ") + e.what());
|
||||
@ -3239,7 +3240,7 @@ bool Chainstate::ActivateBestChain(BlockValidationState& state, std::shared_ptr<
|
||||
|
||||
for (const PerBlockConnectTrace& trace : connectTrace.GetBlocksConnected()) {
|
||||
assert(trace.pblock && trace.pindex);
|
||||
GetMainSignals().BlockConnected(trace.pblock, trace.pindex);
|
||||
GetMainSignals().BlockConnected(this->GetRole(), trace.pblock, trace.pindex);
|
||||
}
|
||||
|
||||
// This will have been toggled in
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <attributes.h>
|
||||
#include <chain.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <logging.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
@ -223,9 +224,9 @@ void CMainSignals::TransactionRemovedFromMempool(const CTransactionRef& tx, MemP
|
||||
RemovalReasonToString(reason));
|
||||
}
|
||||
|
||||
void CMainSignals::BlockConnected(const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex) {
|
||||
auto event = [pblock, pindex, this] {
|
||||
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.BlockConnected(pblock, pindex); });
|
||||
void CMainSignals::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex) {
|
||||
auto event = [role, pblock, pindex, this] {
|
||||
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.BlockConnected(role, pblock, pindex); });
|
||||
};
|
||||
ENQUEUE_AND_LOG_EVENT(event, "%s: block hash=%s block height=%d", __func__,
|
||||
pblock->GetHash().ToString(),
|
||||
@ -242,9 +243,9 @@ void CMainSignals::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock
|
||||
pindex->nHeight);
|
||||
}
|
||||
|
||||
void CMainSignals::ChainStateFlushed(const CBlockLocator &locator) {
|
||||
auto event = [locator, this] {
|
||||
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.ChainStateFlushed(locator); });
|
||||
void CMainSignals::ChainStateFlushed(ChainstateRole role, const CBlockLocator &locator) {
|
||||
auto event = [role, locator, this] {
|
||||
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.ChainStateFlushed(role, locator); });
|
||||
};
|
||||
ENQUEUE_AND_LOG_EVENT(event, "%s: block hash=%s", __func__,
|
||||
locator.IsNull() ? "null" : locator.vHave.front().ToString());
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define BITCOIN_VALIDATIONINTERFACE_H
|
||||
|
||||
#include <kernel/cs_main.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <primitives/transaction.h> // CTransaction(Ref)
|
||||
#include <sync.h>
|
||||
|
||||
@ -136,11 +137,12 @@ protected:
|
||||
*
|
||||
* Called on a background thread.
|
||||
*/
|
||||
virtual void BlockConnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
|
||||
virtual void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
|
||||
/**
|
||||
* Notifies listeners of a block being disconnected
|
||||
*
|
||||
* Called on a background thread.
|
||||
* Called on a background thread. Only called for the active chainstate, since
|
||||
* background chainstates should never disconnect blocks.
|
||||
*/
|
||||
virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) {}
|
||||
/**
|
||||
@ -159,17 +161,18 @@ protected:
|
||||
*
|
||||
* Called on a background thread.
|
||||
*/
|
||||
virtual void ChainStateFlushed(const CBlockLocator &locator) {}
|
||||
virtual void ChainStateFlushed(ChainstateRole role, const CBlockLocator &locator) {}
|
||||
/**
|
||||
* Notifies listeners of a block validation result.
|
||||
* If the provided BlockValidationState IsValid, the provided block
|
||||
* is guaranteed to be the current best block at the time the
|
||||
* callback was generated (not necessarily now)
|
||||
* callback was generated (not necessarily now).
|
||||
*/
|
||||
virtual void BlockChecked(const CBlock&, const BlockValidationState&) {}
|
||||
/**
|
||||
* Notifies listeners that a block which builds directly on our current tip
|
||||
* has been received and connected to the headers tree, though not validated yet */
|
||||
* has been received and connected to the headers tree, though not validated yet.
|
||||
*/
|
||||
virtual void NewPoWValidBlock(const CBlockIndex *pindex, const std::shared_ptr<const CBlock>& block) {};
|
||||
friend class CMainSignals;
|
||||
friend class ValidationInterfaceTest;
|
||||
@ -199,9 +202,9 @@ public:
|
||||
void UpdatedBlockTip(const CBlockIndex *, const CBlockIndex *, bool fInitialDownload);
|
||||
void TransactionAddedToMempool(const CTransactionRef&, uint64_t mempool_sequence);
|
||||
void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);
|
||||
void BlockConnected(const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
|
||||
void BlockConnected(ChainstateRole, const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindex);
|
||||
void ChainStateFlushed(const CBlockLocator &);
|
||||
void ChainStateFlushed(ChainstateRole, const CBlockLocator &);
|
||||
void BlockChecked(const CBlock&, const BlockValidationState&);
|
||||
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <kernel/chain.h>
|
||||
#include <test/fuzz/FuzzedDataProvider.h>
|
||||
#include <test/fuzz/fuzz.h>
|
||||
#include <test/fuzz/util.h>
|
||||
@ -145,8 +146,8 @@ FUZZ_TARGET(wallet_notifications, .init = initialize_setup)
|
||||
// time to the maximum value. This ensures that the wallet's birth time is always
|
||||
// earlier than this maximum time.
|
||||
info.chain_time_max = std::numeric_limits<unsigned int>::max();
|
||||
a.wallet->blockConnected(info);
|
||||
b.wallet->blockConnected(info);
|
||||
a.wallet->blockConnected(ChainstateRole::NORMAL, info);
|
||||
b.wallet->blockConnected(ChainstateRole::NORMAL, info);
|
||||
// Store the coins for the next block
|
||||
Coins coins_new;
|
||||
for (const auto& tx : block.vtx) {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <interfaces/chain.h>
|
||||
#include <interfaces/handler.h>
|
||||
#include <interfaces/wallet.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <kernel/mempool_removal_reason.h>
|
||||
#include <key.h>
|
||||
#include <key_io.h>
|
||||
@ -626,7 +627,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||
return false;
|
||||
}
|
||||
|
||||
void CWallet::chainStateFlushed(const CBlockLocator& loc)
|
||||
void CWallet::chainStateFlushed(ChainstateRole role, const CBlockLocator& loc)
|
||||
{
|
||||
// Don't update the best block until the chain is attached so that in case of a shutdown,
|
||||
// the rescan will be restarted at next startup.
|
||||
@ -1462,7 +1463,7 @@ void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRe
|
||||
}
|
||||
}
|
||||
|
||||
void CWallet::blockConnected(const interfaces::BlockInfo& block)
|
||||
void CWallet::blockConnected(ChainstateRole role, const interfaces::BlockInfo& block)
|
||||
{
|
||||
assert(block.data);
|
||||
LOCK(cs_wallet);
|
||||
@ -2941,7 +2942,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
||||
}
|
||||
|
||||
if (chain) {
|
||||
walletInstance->chainStateFlushed(chain->getTipLocator());
|
||||
walletInstance->chainStateFlushed(ChainstateRole::NORMAL, chain->getTipLocator());
|
||||
}
|
||||
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
||||
// Make it impossible to disable private keys after creation
|
||||
@ -3227,7 +3228,7 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
|
||||
}
|
||||
}
|
||||
walletInstance->m_attaching_chain = false;
|
||||
walletInstance->chainStateFlushed(chain.getTipLocator());
|
||||
walletInstance->chainStateFlushed(ChainstateRole::NORMAL, chain.getTipLocator());
|
||||
walletInstance->GetDatabase().IncrementUpdateCounter();
|
||||
}
|
||||
walletInstance->m_attaching_chain = false;
|
||||
|
@ -599,7 +599,7 @@ public:
|
||||
CWalletTx* AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx=nullptr, bool fFlushOnClose=true, bool rescanning_old_block = false);
|
||||
bool LoadToWallet(const uint256& hash, const UpdateWalletTxFn& fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
void transactionAddedToMempool(const CTransactionRef& tx) override;
|
||||
void blockConnected(const interfaces::BlockInfo& block) override;
|
||||
void blockConnected(ChainstateRole role, const interfaces::BlockInfo& block) override;
|
||||
void blockDisconnected(const interfaces::BlockInfo& block) override;
|
||||
void updatedBlockTip() override;
|
||||
int64_t RescanFromTime(int64_t startTime, const WalletRescanReserver& reserver, bool update);
|
||||
@ -777,7 +777,7 @@ public:
|
||||
/** should probably be renamed to IsRelevantToMe */
|
||||
bool IsFromMe(const CTransaction& tx) const;
|
||||
CAmount GetDebit(const CTransaction& tx, const isminefilter& filter) const;
|
||||
void chainStateFlushed(const CBlockLocator& loc) override;
|
||||
void chainStateFlushed(ChainstateRole role, const CBlockLocator& loc) override;
|
||||
|
||||
DBErrors LoadWallet();
|
||||
DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <zmq/zmqnotificationinterface.h>
|
||||
|
||||
#include <common/args.h>
|
||||
#include <kernel/chain.h>
|
||||
#include <logging.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
@ -170,7 +171,7 @@ void CZMQNotificationInterface::TransactionRemovedFromMempool(const CTransaction
|
||||
});
|
||||
}
|
||||
|
||||
void CZMQNotificationInterface::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected)
|
||||
void CZMQNotificationInterface::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected)
|
||||
{
|
||||
for (const CTransactionRef& ptx : pblock->vtx) {
|
||||
const CTransaction& tx = *ptx;
|
||||
|
@ -33,7 +33,7 @@ protected:
|
||||
// CValidationInterface
|
||||
void TransactionAddedToMempool(const CTransactionRef& tx, uint64_t mempool_sequence) override;
|
||||
void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override;
|
||||
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override;
|
||||
void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override;
|
||||
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexDisconnected) override;
|
||||
void UpdatedBlockTip(const CBlockIndex *pindexNew, const CBlockIndex *pindexFork, bool fInitialDownload) override;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user