refactor: Convert ChainstateRole enum to struct
What changed, and why it matters
This is a code cleanup (refactor) change in Bitcoin Core. It replaces a three-value enum called ChainstateRole with a small struct carrying two yes/no flags: whether a chainstate is fully validated and whether it is historical (used for assumeutxo background validation). The logic that decides how wallets, indexes, and network processing react to block notifications is preserved; only the internal data type and comparisons are changed. There is no security fix or behavior change intended here.
No security action required. Treat as ordinary code maintenance. If reviewing for correctness, verify that every former ChainstateRole::BACKGROUND check maps to role.historical, every ASSUMEDVALID check maps to !role.validated, and that GetRole() returns the expected flag combinations for all three chainstate kinds.
Security signals we found
No security-relevant signal: refactor only
Behavior-preserving mapping of enum values to struct flags
No new input parsing, network handling, or cryptographic operations
No change to consensus, mempool, or script validation rules
Evidence from the diff
The commit converts ChainstateRole from an enum {NORMAL, ASSUMEDVALID, BACKGROUND} into a kernel::ChainstateRole struct with bool validated and bool historical. Callers now check role.validated and role.historical instead of enum equality. GetRole() in validation.cpp maps the old states: NORMAL -> {validated=true, historical=false}; ASSUMEDVALID -> {validated=false, historical=false}; BACKGROUND -> {validated=true, historical=true}. All notification paths (BaseIndex, CWallet, PeerManager, ZMQ, validation tests, kernel interface) are updated consistently. The change is purely structural and does not alter the underlying assumeutxo/index/wallet behavior.
Changed components
src/kernel/types.h (new)src/kernel/chain.hsrc/kernel/chain.cppsrc/validation.cppsrc/validation.hsrc/validationinterface.cppsrc/validationinterface.hsrc/index/base.cppsrc/index/base.hsrc/wallet/wallet.cppsrc/wallet/wallet.hsrc/net_processing.cppsrc/zmq/zmqnotificationinterface.cppsrc/zmq/zmqnotificationinterface.hsrc/interfaces/chain.hsrc/kernel/bitcoinkernel.cppsrc/node/interfaces.cppsrc/node/blockstorage.cpptest filesInspect captured patch +130 / −79
diff --git a/src/bench/wallet_create_tx.cpp b/src/bench/wallet_create_tx.cpp
index 7fb535f4..73ad0e7e 100644
--- a/src/bench/wallet_create_tx.cpp
+++ b/src/bench/wallet_create_tx.cpp
@@ -11,6 +11,7 @@
#include <consensus/merkle.h>
#include <interfaces/chain.h>
#include <kernel/chain.h>
+#include <kernel/types.h>
#include <node/blockstorage.h>
#include <outputtype.h>
#include <policy/feerate.h>
@@ -39,6 +40,7 @@
#include <utility>
#include <vector>
+using kernel::ChainstateRole;
using wallet::CWallet;
using wallet::CreateMockableWalletDatabase;
using wallet::WALLET_FLAG_DESCRIPTORS;
@@ -101,7 +103,7 @@ void generateFakeBlock(const CChainParams& params,
// notify wallet
const auto& pindex = WITH_LOCK(::cs_main, return context.chainman->ActiveChain().Tip());
- wallet.blockConnected(ChainstateRole::NORMAL, kernel::MakeBlockInfo(pindex, &block));
+ wallet.blockConnected(ChainstateRole{}, kernel::MakeBlockInfo(pindex, &block));
}
struct PreSelectInputs {
diff --git a/src/bench/wallet_migration.cpp b/src/bench/wallet_migration.cpp
index 0ce23a49..9d61b984 100644
--- a/src/bench/wallet_migration.cpp
+++ b/src/bench/wallet_migration.cpp
@@ -6,6 +6,7 @@
#include <interfaces/chain.h>
#include <interfaces/wallet.h>
#include <kernel/chain.h>
+#include <kernel/types.h>
#include <node/context.h>
#include <test/util/mining.h>
#include <test/util/setup_common.h>
diff --git a/src/index/base.cpp b/src/index/base.cpp
index a94b4ca7..425f9f7e 100644
--- a/src/index/base.cpp
+++ b/src/index/base.cpp
@@ -10,6 +10,7 @@
#include <interfaces/chain.h>
#include <interfaces/types.h>
#include <kernel/chain.h>
+#include <kernel/types.h>
#include <logging.h>
#include <node/abort.h>
#include <node/blockstorage.h>
@@ -42,6 +43,8 @@
#include <utility>
#include <vector>
+using kernel::ChainstateRole;
+
constexpr uint8_t DB_BEST_BLOCK{'B'};
constexpr auto SYNC_LOG_INTERVAL{30s};
@@ -323,15 +326,13 @@ bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_ti
return true;
}
-void BaseIndex::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex)
+void BaseIndex::BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex)
{
- // Ignore events from the assumed-valid chain; we will process its blocks
- // (sequentially) after it is fully verified by the background chainstate. This
- // is to avoid any out-of-order indexing.
+ // Ignore events from not fully validated chains to avoid out-of-order indexing.
//
// TODO at some point we could parameterize whether a particular index can be
// built out of order, but for now just do the conservative simple thing.
- if (role == ChainstateRole::ASSUMEDVALID) {
+ if (!role.validated) {
return;
}
@@ -377,11 +378,10 @@ void BaseIndex::BlockConnected(ChainstateRole role, const std::shared_ptr<const
}
}
-void BaseIndex::ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator)
+void BaseIndex::ChainStateFlushed(const ChainstateRole& role, const CBlockLocator& locator)
{
- // Ignore events from the assumed-valid chain; we will process its blocks
- // (sequentially) after it is fully verified by the background chainstate.
- if (role == ChainstateRole::ASSUMEDVALID) {
+ // Ignore events from not fully validated chains to avoid out-of-order indexing.
+ if (!role.validated) {
return;
}
diff --git a/src/index/base.h b/src/index/base.h
index cbd0211a..8cb8ad8e 100644
--- a/src/index/base.h
+++ b/src/index/base.h
@@ -118,9 +118,9 @@ protected:
Chainstate* m_chainstate{nullptr};
const std::string m_name;
- void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
+ void BlockConnected(const kernel::ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override;
- void ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator) override;
+ void ChainStateFlushed(const kernel::ChainstateRole& role, const CBlockLocator& locator) override;
/// Return custom notification options for index.
[[nodiscard]] virtual interfaces::Chain::NotifyOptions CustomOptions() { return {}; }
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index 40291d20..17417218 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -30,10 +30,12 @@ class Coin;
class uint256;
enum class MemPoolRemovalReason;
enum class RBFTransactionState;
-enum class ChainstateRole;
struct bilingual_str;
struct CBlockLocator;
struct FeeCalculation;
+namespace kernel {
+struct ChainstateRole;
+} // namespace kernel
namespace node {
struct NodeContext;
} // namespace node
@@ -321,10 +323,10 @@ public:
virtual ~Notifications() = default;
virtual void transactionAddedToMempool(const CTransactionRef& tx) {}
virtual void transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason) {}
- virtual void blockConnected(ChainstateRole role, const BlockInfo& block) {}
+ virtual void blockConnected(const kernel::ChainstateRole& role, const BlockInfo& block) {}
virtual void blockDisconnected(const BlockInfo& block) {}
virtual void updatedBlockTip() {}
- virtual void chainStateFlushed(ChainstateRole role, const CBlockLocator& locator) {}
+ virtual void chainStateFlushed(const kernel::ChainstateRole& role, const CBlockLocator& locator) {}
};
//! Options specifying which chain notifications are required.
diff --git a/src/kernel/bitcoinkernel.cpp b/src/kernel/bitcoinkernel.cpp
index be7c22de..3a36e2c8 100644
--- a/src/kernel/bitcoinkernel.cpp
+++ b/src/kernel/bitcoinkernel.cpp
@@ -51,6 +51,7 @@
#include <utility>
#include <vector>
+using kernel::ChainstateRole;
using util::ImmediateTaskRunner;
// Define G_TRANSLATION_FUN symbol in libbitcoinkernel library so users of the
@@ -359,7 +360,7 @@ protected:
}
}
- void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override
+ void BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override
{
if (m_cbs.block_connected) {
m_cbs.block_connected(m_cbs.user_data,
diff --git a/src/kernel/chain.cpp b/src/kernel/chain.cpp
index 318c956b..52da2e3c 100644
--- a/src/kernel/chain.cpp
+++ b/src/kernel/chain.cpp
@@ -5,11 +5,14 @@
#include <chain.h>
#include <interfaces/chain.h>
#include <kernel/chain.h>
+#include <kernel/types.h>
#include <sync.h>
#include <uint256.h>
class CBlock;
+using kernel::ChainstateRole;
+
namespace kernel {
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* index, const CBlock* data)
{
@@ -25,14 +28,15 @@ interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* index, const CBlock* data
info.data = data;
return info;
}
-} // namespace kernel
std::ostream& operator<<(std::ostream& os, const ChainstateRole& role) {
- switch(role) {
- case ChainstateRole::NORMAL: os << "normal"; break;
- case ChainstateRole::ASSUMEDVALID: os << "assumedvalid"; break;
- case ChainstateRole::BACKGROUND: os << "background"; break;
- default: os.setstate(std::ios_base::failbit);
+ if (!role.validated) {
+ os << "assumedvalid";
+ } else if (role.historical) {
+ os << "background";
+ } else {
+ os << "normal";
}
return os;
}
+} // namespace kernel
diff --git a/src/kernel/chain.h b/src/kernel/chain.h
index feba24a5..7dbd0eb6 100644
--- a/src/kernel/chain.h
+++ b/src/kernel/chain.h
@@ -14,26 +14,10 @@ struct BlockInfo;
} // namespace interfaces
namespace kernel {
+struct ChainstateRole;
//! Return data from block index.
interfaces::BlockInfo MakeBlockInfo(const CBlockIndex* block_index, const CBlock* data = nullptr);
-
-} // namespace kernel
-
-//! This enum describes the various roles a specific Chainstate instance can take.
-//! Other parts of the system sometimes need to vary in behavior depending on the
-//! existence of a background validation chainstate, e.g. when building indexes.
-enum class ChainstateRole {
- // Single chainstate in use, "normal" IBD mode.
- NORMAL,
-
- // Doing IBD-style validation in the background. Implies use of an assumed-valid
- // chainstate.
- BACKGROUND,
-
- // Active assumed-valid chainstate. Implies use of a background IBD chainstate.
- ASSUMEDVALID,
-};
-
std::ostream& operator<<(std::ostream& os, const ChainstateRole& role);
+} // namespace kernel
#endif // BITCOIN_KERNEL_CHAIN_H
diff --git a/src/kernel/types.h b/src/kernel/types.h
new file mode 100644
index 00000000..164d4cfd
--- /dev/null
+++ b/src/kernel/types.h
@@ -0,0 +1,30 @@
+// Copyright (c) The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+//! @file kernel/types.h is a home for simple enum and struct type definitions
+//! that can be used internally by functions in the libbitcoin_kernel library,
+//! but also used externally by node, wallet, and GUI code.
+//!
+//! This file is intended to define only simple types that do not have external
+//! dependencies. More complicated types should be defined in dedicated header
+//! files.
+
+#ifndef BITCOIN_KERNEL_TYPES_H
+#define BITCOIN_KERNEL_TYPES_H
+
+namespace kernel {
+//! Information about chainstate that notifications are sent from.
+struct ChainstateRole {
+ //! Whether this is a notification from a chainstate that's been fully
+ //! validated starting from the genesis block. False if it is from an
+ //! assumeutxo snapshot chainstate that has not been validated yet.
+ bool validated{true};
+
+ //! Whether this is a historical chainstate downloading old blocks to
+ //! validate an assumeutxo snapshot, not syncing to the network tip.
+ bool historical{false};
+};
+} // namespace kernel
+
+#endif // BITCOIN_KERNEL_TYPES_H
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index 09b2f221..d7fd2879 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -22,7 +22,7 @@
#include <flatfile.h>
#include <headerssync.h>
#include <index/blockfilterindex.h>
-#include <kernel/chain.h>
+#include <kernel/types.h>
#include <logging.h>
#include <merkleblock.h>
#include <net.h>
@@ -85,6 +85,7 @@
#include <typeinfo>
#include <utility>
+using kernel::ChainstateRole;
using namespace util::hex_literals;
TRACEPOINT_SEMAPHORE(net, inbound_message);
@@ -507,7 +508,7 @@ public:
/** Overridden from CValidationInterface. */
void ActiveTipChange(const CBlockIndex& new_tip, bool) override
EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
- void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
+ void BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override
EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
void BlockDisconnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex* pindex) override
EXCLUSIVE_LOCKS_REQUIRED(!m_tx_download_mutex);
@@ -1946,7 +1947,7 @@ void PeerManagerImpl::ActiveTipChange(const CBlockIndex& new_tip, bool is_ibd)
* possibly reduce dynamic block stalling timeout.
*/
void PeerManagerImpl::BlockConnected(
- ChainstateRole role,
+ const ChainstateRole& role,
const std::shared_ptr<const CBlock>& pblock,
const CBlockIndex* pindex)
{
@@ -1965,8 +1966,8 @@ void PeerManagerImpl::BlockConnected(
}
// The following task can be skipped since we don't maintain a mempool for
- // the ibd/background chainstate.
- if (role == ChainstateRole::BACKGROUND) {
+ // the historical chainstate.
+ if (role.historical) {
return;
}
LOCK(m_tx_download_mutex);
diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp
index a5984df6..c5d26e5c 100644
--- a/src/node/blockstorage.cpp
+++ b/src/node/blockstorage.cpp
@@ -12,9 +12,11 @@
#include <flatfile.h>
#include <hash.h>
#include <kernel/blockmanager_opts.h>
+#include <kernel/chain.h>
#include <kernel/chainparams.h>
#include <kernel/messagestartchars.h>
#include <kernel/notifications_interface.h>
+#include <kernel/types.h>
#include <logging.h>
#include <pow.h>
#include <primitives/block.h>
diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp
index ac817e01..dfcf6629 100644
--- a/src/node/interfaces.cpp
+++ b/src/node/interfaces.cpp
@@ -81,6 +81,7 @@ using interfaces::MakeSignalHandler;
using interfaces::Mining;
using interfaces::Node;
using interfaces::WalletLoader;
+using kernel::ChainstateRole;
using node::BlockAssembler;
using node::BlockWaitOptions;
using util::Join;
@@ -461,7 +462,7 @@ public:
{
m_notifications->transactionRemovedFromMempool(tx, reason);
}
- void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
+ void BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* index) override
{
m_notifications->blockConnected(role, kernel::MakeBlockInfo(index, block.get()));
}
@@ -473,7 +474,8 @@ public:
{
m_notifications->updatedBlockTip();
}
- void ChainStateFlushed(ChainstateRole role, const CBlockLocator& locator) override {
+ void ChainStateFlushed(const ChainstateRole& role, const CBlockLocator& locator) override
+ {
m_notifications->chainStateFlushed(role, locator);
}
std::shared_ptr<Chain::Notifications> m_notifications;
diff --git a/src/test/chainstate_write_tests.cpp b/src/test/chainstate_write_tests.cpp
index e1b82ebc..5c459227 100644
--- a/src/test/chainstate_write_tests.cpp
+++ b/src/test/chainstate_write_tests.cpp
@@ -8,6 +8,8 @@
#include <boost/test/unit_test.hpp>
+using kernel::ChainstateRole;
+
// Taken from validation.cpp
static constexpr auto DATABASE_WRITE_INTERVAL_MIN{50min};
static constexpr auto DATABASE_WRITE_INTERVAL_MAX{70min};
@@ -18,7 +20,7 @@ BOOST_FIXTURE_TEST_CASE(chainstate_write_interval, TestingSetup)
{
struct TestSubscriber final : CValidationInterface {
bool m_did_flush{false};
- void ChainStateFlushed(ChainstateRole, const CBlockLocator&) override
+ void ChainStateFlushed(const ChainstateRole&, const CBlockLocator&) override
{
m_did_flush = true;
}
@@ -55,7 +57,7 @@ BOOST_FIXTURE_TEST_CASE(write_during_multiblock_activation, TestChain100Setup)
{
const CBlockIndex* m_tip{nullptr};
const CBlockIndex* m_flushed_at_block{nullptr};
- void ChainStateFlushed(ChainstateRole, const CBlockLocator&) override
+ void ChainStateFlushed(const ChainstateRole&, const CBlockLocator&) override
{
m_flushed_at_block = m_tip;
}
diff --git a/src/test/coinstatsindex_tests.cpp b/src/test/coinstatsindex_tests.cpp
index 7d54f0fd..d55fb1b0 100644
--- a/src/test/coinstatsindex_tests.cpp
+++ b/src/test/coinstatsindex_tests.cpp
@@ -6,12 +6,15 @@
#include <index/coinstatsindex.h>
#include <interfaces/chain.h>
#include <kernel/coinstats.h>
+#include <kernel/types.h>
#include <test/util/setup_common.h>
#include <test/util/validation.h>
#include <validation.h>
#include <boost/test/unit_test.hpp>
+using kernel::ChainstateRole;
+
BOOST_AUTO_TEST_SUITE(coinstatsindex_tests)
BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
@@ -101,7 +104,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(ChainstateRole::NORMAL, index, new_block, new_block_index);
+ ValidationInterfaceTest::BlockConnected(ChainstateRole{}, index, new_block, new_block_index);
index.Stop();
}
diff --git a/src/test/util/validation.cpp b/src/test/util/validation.cpp
index ce558078..ae8642f9 100644
--- a/src/test/util/validation.cpp
+++ b/src/test/util/validation.cpp
@@ -9,6 +9,8 @@
#include <validation.h>
#include <validationinterface.h>
+using kernel::ChainstateRole;
+
void TestChainstateManager::DisableNextWrite()
{
struct TestChainstate : public Chainstate {
@@ -18,6 +20,7 @@ void TestChainstateManager::DisableNextWrite()
static_cast<TestChainstate*>(cs)->ResetNextWrite();
}
}
+
void TestChainstateManager::ResetIbd()
{
m_cached_finished_ibd = false;
@@ -32,10 +35,10 @@ void TestChainstateManager::JumpOutOfIbd()
}
void ValidationInterfaceTest::BlockConnected(
- ChainstateRole role,
- CValidationInterface& obj,
- const std::shared_ptr<const CBlock>& block,
- const CBlockIndex* pindex)
+ const ChainstateRole& role,
+ CValidationInterface& obj,
+ const std::shared_ptr<const CBlock>& block,
+ const CBlockIndex* pindex)
{
obj.BlockConnected(role, block, pindex);
}
diff --git a/src/test/util/validation.h b/src/test/util/validation.h
index f9c6a8ac..4a24c97e 100644
--- a/src/test/util/validation.h
+++ b/src/test/util/validation.h
@@ -22,7 +22,7 @@ class ValidationInterfaceTest
{
public:
static void BlockConnected(
- ChainstateRole role,
+ const kernel::ChainstateRole& role,
CValidationInterface& obj,
const std::shared_ptr<const CBlock>& block,
const CBlockIndex* pindex);
diff --git a/src/test/validation_block_tests.cpp b/src/test/validation_block_tests.cpp
index a0b23f5d..9f574be8 100644
--- a/src/test/validation_block_tests.cpp
+++ b/src/test/validation_block_tests.cpp
@@ -19,6 +19,7 @@
#include <thread>
+using kernel::ChainstateRole;
using node::BlockAssembler;
namespace validation_block_tests {
@@ -43,7 +44,7 @@ struct TestSubscriber final : public CValidationInterface {
BOOST_CHECK_EQUAL(m_expected_tip, pindexNew->GetBlockHash());
}
- void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) override
+ void BlockConnected(const 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());
diff --git a/src/test/validationinterface_tests.cpp b/src/test/validationinterface_tests.cpp
index 8a24b282..0b0bae80 100644
--- a/src/test/validationinterface_tests.cpp
+++ b/src/test/validationinterface_tests.cpp
@@ -8,7 +8,6 @@
#include <scheduler.h>
#include <test/util/setup_common.h>
#include <util/check.h>
-#include <kernel/chain.h>
#include <validationinterface.h>
#include <atomic>
diff --git a/src/validation.cpp b/src/validation.cpp
index da60efbc..c229851e 100644
--- a/src/validation.cpp
+++ b/src/validation.cpp
@@ -20,13 +20,13 @@
#include <cuckoocache.h>
#include <flatfile.h>
#include <hash.h>
-#include <kernel/chain.h>
#include <kernel/chainparams.h>
#include <kernel/coinstats.h>
#include <kernel/disconnected_transactions.h>
#include <kernel/mempool_entry.h>
#include <kernel/messagestartchars.h>
#include <kernel/notifications_interface.h>
+#include <kernel/types.h>
#include <kernel/warning.h>
#include <logging.h>
#include <logging/timer.h>
@@ -77,6 +77,7 @@
#include <utility>
using kernel::CCoinsStats;
+using kernel::ChainstateRole;
using kernel::CoinStatsHashType;
using kernel::ComputeUTXOStats;
using kernel::Notifications;
@@ -1986,7 +1987,7 @@ void Chainstate::CheckForkWarningConditions()
{
AssertLockHeld(cs_main);
- if (this->GetRole() == ChainstateRole::BACKGROUND) {
+ if (this->GetRole().historical) {
return;
}
@@ -2532,7 +2533,8 @@ bool Chainstate::ConnectBlock(const CBlock& block, BlockValidationState& state,
Ticks<MillisecondsDouble>(m_chainman.time_forks) / m_chainman.num_blocks_total);
const bool fScriptChecks{!!script_check_reason};
- if (script_check_reason != m_last_script_check_reason_logged && GetRole() == ChainstateRole::NORMAL) {
+ const kernel::ChainstateRole role{GetRole()};
+ if (script_check_reason != m_last_script_check_reason_logged && role.validated && !role.historical) {
if (fScriptChecks) {
LogInfo("Enabling script verification at block #%d (%s): %s.",
pindex->nHeight, block_hash.ToString(), script_check_reason);
@@ -4656,7 +4658,7 @@ bool Chainstate::LoadChainTip()
m_chainman.GuessVerificationProgress(tip));
// Ensure KernelNotifications m_tip_block is set even if no new block arrives.
- if (this->GetRole() != ChainstateRole::BACKGROUND) {
+ if (!this->GetRole().historical) {
// Ignoring return value for now.
(void)m_chainman.GetNotifications().blockTip(
/*state=*/GetSynchronizationState(/*init=*/true, m_chainman.m_blockman.m_blockfiles_indexed),
@@ -6354,7 +6356,7 @@ bool ChainstateManager::DeleteSnapshotChainstate()
ChainstateRole Chainstate::GetRole() const
{
- return m_target_blockhash ? ChainstateRole::BACKGROUND : m_assumeutxo == Assumeutxo::UNVALIDATED ? ChainstateRole::ASSUMEDVALID : ChainstateRole::NORMAL;
+ return ChainstateRole{.validated = m_assumeutxo == Assumeutxo::VALIDATED, .historical = bool{m_target_blockhash}};
}
void ChainstateManager::RecalculateBestHeader()
diff --git a/src/validation.h b/src/validation.h
index 464dcbd0..0f7fa2cb 100644
--- a/src/validation.h
+++ b/src/validation.h
@@ -58,6 +58,9 @@ class DisconnectedBlockTransactions;
struct PrecomputedTransactionData;
struct LockPoints;
struct AssumeutxoData;
+namespace kernel {
+struct ChainstateRole;
+} // namespace kernel
namespace node {
class SnapshotMetadata;
} // namespace node
@@ -586,7 +589,7 @@ public:
//! documentation for a description of the different types of chainstates.
//!
//! @sa ChainstateRole
- ChainstateRole GetRole() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
+ kernel::ChainstateRole GetRole() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/**
* Initialize the CoinsViews UTXO set database management data structures. The in-memory
diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp
index 313f730e..c4cd1010 100644
--- a/src/validationinterface.cpp
+++ b/src/validationinterface.cpp
@@ -7,9 +7,9 @@
#include <chain.h>
#include <consensus/validation.h>
-#include <kernel/chain.h>
#include <kernel/mempool_entry.h>
#include <kernel/mempool_removal_reason.h>
+#include <kernel/types.h>
#include <logging.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
@@ -21,6 +21,8 @@
#include <unordered_map>
#include <utility>
+using kernel::ChainstateRole;
+
/**
* ValidationSignalsImpl manages a list of shared_ptr<CValidationInterface> callbacks.
*
@@ -209,7 +211,8 @@ void ValidationSignals::TransactionRemovedFromMempool(const CTransactionRef& tx,
RemovalReasonToString(reason));
}
-void ValidationSignals::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock> &pblock, const CBlockIndex *pindex) {
+void ValidationSignals::BlockConnected(const 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); });
};
@@ -238,7 +241,8 @@ void ValidationSignals::BlockDisconnected(const std::shared_ptr<const CBlock>& p
pindex->nHeight);
}
-void ValidationSignals::ChainStateFlushed(ChainstateRole role, const CBlockLocator &locator) {
+void ValidationSignals::ChainStateFlushed(const ChainstateRole& role, const CBlockLocator& locator)
+{
auto event = [role, locator, this] {
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.ChainStateFlushed(role, locator); });
};
diff --git a/src/validationinterface.h b/src/validationinterface.h
index e0a88ad0..4777e8dc 100644
--- a/src/validationinterface.h
+++ b/src/validationinterface.h
@@ -6,7 +6,6 @@
#ifndef BITCOIN_VALIDATIONINTERFACE_H
#define BITCOIN_VALIDATIONINTERFACE_H
-#include <kernel/chain.h>
#include <kernel/cs_main.h>
#include <primitives/transaction.h>
#include <sync.h>
@@ -17,6 +16,9 @@
#include <memory>
#include <vector>
+namespace kernel {
+struct ChainstateRole;
+} // namespace kernel
namespace util {
class TaskRunnerInterface;
} // namespace util
@@ -118,7 +120,7 @@ protected:
*
* Called on a background thread.
*/
- virtual void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex) {}
+ virtual void BlockConnected(const kernel::ChainstateRole& role, const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex) {}
/**
* Notifies listeners of a block being disconnected
* Provides the block that was disconnected.
@@ -143,7 +145,7 @@ protected:
*
* Called on a background thread.
*/
- virtual void ChainStateFlushed(ChainstateRole role, const CBlockLocator &locator) {}
+ virtual void ChainStateFlushed(const kernel::ChainstateRole& role, const CBlockLocator& locator) {}
/**
* Notifies listeners of a block validation result.
* If the provided BlockValidationState IsValid, the provided block
@@ -221,9 +223,9 @@ public:
void TransactionAddedToMempool(const NewMempoolTransactionInfo&, uint64_t mempool_sequence);
void TransactionRemovedFromMempool(const CTransactionRef&, MemPoolRemovalReason, uint64_t mempool_sequence);
void MempoolTransactionsRemovedForBlock(const std::vector<RemovedMempoolTransactionInfo>&, unsigned int nBlockHeight);
- void BlockConnected(ChainstateRole, const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex);
+ void BlockConnected(const kernel::ChainstateRole&, const std::shared_ptr<const CBlock>&, const CBlockIndex* pindex);
void BlockDisconnected(const std::shared_ptr<const CBlock> &, const CBlockIndex* pindex);
- void ChainStateFlushed(ChainstateRole, const CBlockLocator &);
+ void ChainStateFlushed(const kernel::ChainstateRole&, const CBlockLocator&);
void BlockChecked(const std::shared_ptr<const CBlock>&, const BlockValidationState&);
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
};
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 86474a45..d7b749bc 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -22,8 +22,8 @@
#include <interfaces/chain.h>
#include <interfaces/handler.h>
#include <interfaces/wallet.h>
-#include <kernel/chain.h>
#include <kernel/mempool_removal_reason.h>
+#include <kernel/types.h>
#include <key.h>
#include <key_io.h>
#include <logging.h>
@@ -87,6 +87,7 @@ using common::AmountErrMsg;
using common::AmountHighWarn;
using common::PSBTError;
using interfaces::FoundBlock;
+using kernel::ChainstateRole;
using util::ReplaceAll;
using util::ToString;
@@ -1477,9 +1478,9 @@ void CWallet::transactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRe
}
}
-void CWallet::blockConnected(ChainstateRole role, const interfaces::BlockInfo& block)
+void CWallet::blockConnected(const ChainstateRole& role, const interfaces::BlockInfo& block)
{
- if (role == ChainstateRole::BACKGROUND) {
+ if (role.historical) {
return;
}
assert(block.data);
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index 275d4ead..1d463564 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -629,7 +629,7 @@ public:
CWalletTx* AddToWallet(CTransactionRef tx, const TxState& state, const UpdateWalletTxFn& update_wtx=nullptr, bool rescanning_old_block = false);
bool LoadToWallet(const Txid& hash, const UpdateWalletTxFn& fill_wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
void transactionAddedToMempool(const CTransactionRef& tx) override;
- void blockConnected(ChainstateRole role, const interfaces::BlockInfo& block) override;
+ void blockConnected(const kernel::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);
diff --git a/src/zmq/zmqnotificationinterface.cpp b/src/zmq/zmqnotificationinterface.cpp
index e5b5f9d8..316c7a19 100644
--- a/src/zmq/zmqnotificationinterface.cpp
+++ b/src/zmq/zmqnotificationinterface.cpp
@@ -5,8 +5,8 @@
#include <zmq/zmqnotificationinterface.h>
#include <common/args.h>
-#include <kernel/chain.h>
#include <kernel/mempool_entry.h>
+#include <kernel/types.h>
#include <logging.h>
#include <netbase.h>
#include <primitives/block.h>
@@ -24,6 +24,8 @@
#include <utility>
#include <vector>
+using kernel::ChainstateRole;
+
CZMQNotificationInterface::CZMQNotificationInterface() = default;
CZMQNotificationInterface::~CZMQNotificationInterface()
@@ -176,9 +178,9 @@ void CZMQNotificationInterface::TransactionRemovedFromMempool(const CTransaction
});
}
-void CZMQNotificationInterface::BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected)
+void CZMQNotificationInterface::BlockConnected(const ChainstateRole& role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected)
{
- if (role == ChainstateRole::BACKGROUND) {
+ if (role.historical) {
return;
}
for (const CTransactionRef& ptx : pblock->vtx) {
diff --git a/src/zmq/zmqnotificationinterface.h b/src/zmq/zmqnotificationinterface.h
index 5dacf3b3..12d805c1 100644
--- a/src/zmq/zmqnotificationinterface.h
+++ b/src/zmq/zmqnotificationinterface.h
@@ -35,7 +35,7 @@ protected:
// CValidationInterface
void TransactionAddedToMempool(const NewMempoolTransactionInfo& tx, uint64_t mempool_sequence) override;
void TransactionRemovedFromMempool(const CTransactionRef& tx, MemPoolRemovalReason reason, uint64_t mempool_sequence) override;
- void BlockConnected(ChainstateRole role, const std::shared_ptr<const CBlock>& pblock, const CBlockIndex* pindexConnected) override;
+ void BlockConnected(const kernel::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;
Why this scored 18/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.