Skip to content
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL
node/eviction.cpp
node/interface_ui.cpp
node/interfaces.cpp
node/kernel_mempool.cpp
node/kernel_notifications.cpp
node/mempool_args.cpp
node/mempool_persist.cpp
Expand Down
7 changes: 4 additions & 3 deletions src/bench/block_assemble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

#include <bench/bench.h>
#include <consensus/consensus.h>
#include <node/mining_types.h>
#include <node/miner.h>
#include <node/transaction.h>
#include <primitives/transaction.h>
#include <random.h>
#include <script/script.h>
Expand All @@ -25,7 +26,7 @@ using node::BlockCreateOptions;

static void AssembleBlock(benchmark::Bench& bench)
{
const auto test_setup = MakeNoLogFileContext<const TestingSetup>();
auto test_setup = MakeNoLogFileContext<const TestingSetup>();

CScriptWitness witness;
witness.stack.push_back(WITNESS_STACK_ELEM_OP_TRUE);
Expand All @@ -48,7 +49,7 @@ static void AssembleBlock(benchmark::Bench& bench)
LOCK(::cs_main);

for (const auto& txr : txs) {
const MempoolAcceptResult res = test_setup->m_node.chainman->ProcessTransaction(txr);
const MempoolAcceptResult res = node::ProcessTransaction(txr, test_setup->m_node);
assert(res.m_result_type == MempoolAcceptResult::ResultType::VALID);
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/bench/connectblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,12 @@
#include <coins.h>
#include <consensus/amount.h>
#include <consensus/validation.h>
#include <interfaces/chain.h>
#include <kernel/cs_main.h>
#include <key.h>
#include <node/blockstorage.h>
#include <policy/feerate.h>
#include <script/interpreter.h>
#include <primitives/block.h>
#include <primitives/transaction.h>
#include <pubkey.h>
Expand Down
12 changes: 8 additions & 4 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <node/chainstatemanager_args.h>
#include <node/context.h>
#include <node/interface_ui.h>
#include <node/kernel_mempool.h>
#include <node/kernel_notifications.h>
#include <node/mempool_args.h>
#include <node/mempool_persist.h>
Expand Down Expand Up @@ -156,6 +157,7 @@ using node::DEFAULT_PRINT_MODIFIED_FEE;
using node::DEFAULT_STOPATHEIGHT;
using node::DumpMempool;
using node::ImportBlocks;
using node::KernelMempool;
using node::KernelNotifications;
using node::LoadChainstate;
using node::LoadMempool;
Expand Down Expand Up @@ -1138,9 +1140,11 @@ bool AppInitParameterInteraction(const ArgsManager& args)
// Also report errors from parsing before daemonization
{
kernel::Notifications notifications{};
kernel::Mempool mempool_interface{};
ChainstateManager::Options chainman_opts_dummy{
.chainparams = chainparams,
.datadir = args.GetDataDirNet(),
.mempool_interface = mempool_interface,
.notifications = notifications,
};
auto chainman_result{ApplyArgsManOptions(args, chainman_opts_dummy)};
Expand Down Expand Up @@ -1341,12 +1345,14 @@ static ChainstateLoadResult InitAndLoadChainstate(
auto mining_args{node::ReadMiningArgs(args)};
Assert(mining_args); // no error can happen, already checked in AppInitParameterInteraction
node.mining_args = std::move(*mining_args);
node.mempool_interface = std::make_unique<KernelMempool>(*node.mempool);
LogInfo("* Using %.1f MiB for in-memory UTXO set (plus up to %.1f MiB of unused mempool space)",
cache_sizes.coins / double(1_MiB),
mempool_opts.max_size_bytes / double(1_MiB));
ChainstateManager::Options chainman_opts{
.chainparams = chainparams,
.datadir = args.GetDataDirNet(),
.mempool_interface = *node.mempool_interface,
.notifications = *node.notifications,
.signals = node.validation_signals.get(),
};
Expand Down Expand Up @@ -2062,10 +2068,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
return;
}
// Load mempool from disk
if (auto* pool{chainman.ActiveChainstate().GetMempool()}) {
LoadMempool(*pool, ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{}, chainman.ActiveChainstate(), {});
pool->SetLoadTried(!chainman.m_interrupt);
}
LoadMempool(*node.mempool.get(), ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{}, chainman.ActiveChainstate(), {});
node.mempool->SetLoadTried(!chainman.m_interrupt);
});

/*
Expand Down
12 changes: 1 addition & 11 deletions src/kernel/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ add_library(bitcoinkernel
../node/blockstorage.cpp
../node/chainstate.cpp
../node/utxo_snapshot.cpp
../policy/ephemeral_policy.cpp
../policy/feerate.cpp
../policy/packages.cpp
../policy/policy.cpp
../policy/rbf.cpp
../policy/settings.cpp
../policy/truc_policy.cpp
../pow.cpp
../primitives/block.cpp
../primitives/transaction.cpp
Expand All @@ -56,8 +49,6 @@ add_library(bitcoinkernel
../streams.cpp
../sync.cpp
../txdb.cpp
../txgraph.cpp
../txmempool.cpp
../uint256.cpp
../util/chaintype.cpp
../util/check.cpp
Expand All @@ -67,7 +58,7 @@ add_library(bitcoinkernel
../util/fs_helpers.cpp
../util/hasher.cpp
../util/moneystr.cpp
../util/rbf.cpp
../util/serfloat.cpp
../util/signalinterrupt.cpp
../util/syserror.cpp
../util/threadnames.cpp
Expand Down Expand Up @@ -103,7 +94,6 @@ target_link_libraries(bitcoinkernel
secp256k1_objs
$<$<PLATFORM_ID:Windows>:bcrypt>
$<TARGET_NAME_IF_EXISTS:USDT::headers>
Boost::headers
)

target_include_directories(bitcoinkernel PRIVATE $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/leveldb/include>)
Expand Down
6 changes: 6 additions & 0 deletions src/kernel/bitcoinkernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <kernel/chainparams.h>
#include <kernel/checks.h>
#include <kernel/context.h>
#include <kernel/cs_main.h>
#include <kernel/mempool_interface.h>
#include <kernel/notifications_interface.h>
#include <kernel/warning.h>
#include <logging.h>
Expand Down Expand Up @@ -397,6 +399,8 @@ class Context
public:
std::unique_ptr<kernel::Context> m_context;

std::shared_ptr<kernel::Mempool> m_mempool;

std::shared_ptr<KernelNotifications> m_notifications;

std::unique_ptr<util::SignalInterrupt> m_interrupt;
Expand All @@ -409,6 +413,7 @@ class Context

Context(const ContextOptions* options, bool& sane)
: m_context{std::make_unique<kernel::Context>()},
m_mempool{std::make_unique<kernel::Mempool>()},
m_interrupt{std::make_unique<util::SignalInterrupt>()}
{
if (options) {
Expand Down Expand Up @@ -459,6 +464,7 @@ struct ChainstateManagerOptions {
: m_chainman_options{ChainstateManager::Options{
.chainparams = *context->m_chainparams,
.datadir = data_dir,
.mempool_interface = *context->m_mempool,
.notifications = *context->m_notifications,
.signals = context->m_signals.get()}},
m_blockman_options{node::BlockManager::Options{
Expand Down
2 changes: 2 additions & 0 deletions src/kernel/chainstatemanager_opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H
#define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H

#include <kernel/mempool_interface.h>
#include <kernel/notifications_interface.h>

#include <arith_uint256.h>
Expand Down Expand Up @@ -42,6 +43,7 @@ struct ChainstateManagerOpts {
std::chrono::seconds max_tip_age{DEFAULT_MAX_TIP_AGE};
DBOptions coins_db{};
CoinsViewOptions coins_view{};
Mempool& mempool_interface;
Notifications& notifications;
ValidationSignals* signals{nullptr};
//! Number of script check worker threads. Zero means no parallel verification.
Expand Down
41 changes: 41 additions & 0 deletions src/kernel/mempool_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) 2025 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_KERNEL_MEMPOOL_INTERFACE_H
#define BITCOIN_KERNEL_MEMPOOL_INTERFACE_H

#include <cstddef>
#include <cstdint>

class CBlock;
class Chainstate;
class CCoinsViewCache;
class CTransaction;
class DisconnectedBlockTransactions;

namespace kernel {

/**
* A base class defining functions for notifying about certain kernel
* events.
*/
class Mempool
{
public:
virtual ~Mempool() = default;

virtual void removeRecursive(const CTransaction& tx) {}
virtual void removeForBlock(const CBlock& block, unsigned int block_height) {}
virtual bool empty() { return true; }
virtual size_t measureExternalDynamicMemoryUsage() { return 0; }
virtual void addTransactionsUpdated(uint32_t n) {}
virtual void check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) {}
virtual void MaybeUpdateMempoolForReorg(Chainstate& active_chainstate, DisconnectedBlockTransactions& disconnectpool, bool fAddToMempool) {}
virtual void BeginChainstateUpdate() {}
virtual void EndChainstateUpdate() {}
};

} // namespace kernel

#endif // BITCOIN_KERNEL_MEMPOOL_INTERFACE_H
7 changes: 4 additions & 3 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <node/protocol_version.h>
#include <node/timeoffsets.h>
#include <node/txdownloadman.h>
#include <node/transaction.h>
#include <node/txorphanage.h>
#include <node/txreconciliation.h>
#include <node/warnings.h>
Expand Down Expand Up @@ -1650,7 +1651,7 @@ void PeerManagerImpl::ReattemptPrivateBroadcast(CScheduler& scheduler)
if (!stale_txs.empty()) {
LOCK(cs_main);
for (const auto& stale_tx : stale_txs) {
auto mempool_acceptable = m_chainman.ProcessTransaction(stale_tx, /*test_accept=*/true);
auto mempool_acceptable = node::ProcessTransaction(stale_tx, m_chainman.ActiveChainstate(), m_mempool, /*test_accept=*/true);
if (mempool_acceptable.m_result_type == MempoolAcceptResult::ResultType::VALID) {
LogDebug(BCLog::PRIVBROADCAST,
"Reattempting broadcast of stale txid=%s wtxid=%s",
Expand Down Expand Up @@ -3232,7 +3233,7 @@ bool PeerManagerImpl::ProcessOrphanTx(Peer& peer)
CTransactionRef porphanTx = nullptr;

while (CTransactionRef porphanTx = m_txdownloadman.GetTxToReconsider(peer.m_id)) {
const MempoolAcceptResult result = m_chainman.ProcessTransaction(porphanTx);
const MempoolAcceptResult result = node::ProcessTransaction(porphanTx, m_chainman.ActiveChainstate(), m_mempool);
const TxValidationState& state = result.m_state;
const Txid& orphanHash = porphanTx->GetHash();
const Wtxid& orphan_wtxid = porphanTx->GetWitnessHash();
Expand Down Expand Up @@ -4446,7 +4447,7 @@ void PeerManagerImpl::ProcessMessage(Peer& peer, CNode& pfrom, const std::string
// ReceivedTx should not be telling us to validate the tx and a package.
Assume(!package_to_validate.has_value());

const MempoolAcceptResult result = m_chainman.ProcessTransaction(ptx);
const MempoolAcceptResult result = node::ProcessTransaction(ptx, m_chainman.ActiveChainstate(), m_mempool);
const TxValidationState& state = result.m_state;

if (result.m_result_type == MempoolAcceptResult::ResultType::VALID) {
Expand Down
4 changes: 2 additions & 2 deletions src/node/chainstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
chainman.m_total_coinsdb_cache = cache_sizes.coins_db;

// Load the fully validated chainstate.
Chainstate& validated_cs{chainman.InitializeChainstate(options.mempool)};
Chainstate& validated_cs{chainman.InitializeChainstate()};

// Load a chain created from a UTXO snapshot, if any exist.
Chainstate* assumeutxo_cs{chainman.LoadAssumeutxoChainstate()};
Expand Down Expand Up @@ -218,7 +218,7 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize
// duplicating the blockindex work above.
assert(chainman.m_chainstates.empty());

chainman.InitializeChainstate(options.mempool);
chainman.InitializeChainstate();

// A reload of the block index is required to recompute setBlockIndexCandidates
// for the fully validated chainstate.
Expand Down
1 change: 1 addition & 0 deletions src/node/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <net.h>
#include <net_processing.h>
#include <netgroup.h>
#include <node/kernel_mempool.h>
#include <node/kernel_notifications.h>
#include <node/warnings.h>
#include <policy/fees/block_policy_estimator.h>
Expand Down
2 changes: 2 additions & 0 deletions src/node/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class SignalInterrupt;

namespace node {
class KernelNotifications;
class KernelMempool;
class Warnings;

//! NodeContext struct containing references to chain state and connection
Expand Down Expand Up @@ -93,6 +94,7 @@ struct NodeContext {
std::function<void()> rpc_interruption_point = [] {};
//! Issues blocking calls about sync status, errors and warnings
std::unique_ptr<KernelNotifications> notifications;
std::unique_ptr<KernelMempool> mempool_interface;
//! Issues calls about blocks and transactions
std::unique_ptr<ValidationSignals> validation_signals;
std::atomic<int> exit_status{EXIT_SUCCESS};
Expand Down
67 changes: 67 additions & 0 deletions src/node/kernel_mempool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright (c) 2025 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <node/kernel_mempool.h>

#include <primitives/transaction.h>
#include <txmempool.h>

#include <cstddef>
#include <cstdint>

class CCoinsViewCache;

namespace node {

void KernelMempool::removeRecursive(const CTransaction& tx)
{
LOCK(m_mempool.cs);
m_mempool.removeRecursive(tx, MemPoolRemovalReason::REORG);
}

void KernelMempool::removeForBlock(const CBlock& block, unsigned int block_height)
{
LOCK(m_mempool.cs);
m_mempool.removeForBlock(block.vtx, block_height);
}

bool KernelMempool::empty()
{
return m_mempool.size() == 0;
}

size_t KernelMempool::measureExternalDynamicMemoryUsage()
{
return m_mempool.DynamicMemoryUsage();
}

void KernelMempool::addTransactionsUpdated(uint32_t n)
{
m_mempool.AddTransactionsUpdated(n);
}

void KernelMempool::check(const CCoinsViewCache& active_coins_tip, int64_t spendheight)
{
LOCK(::cs_main);
m_mempool.check(active_coins_tip, spendheight);
}

void KernelMempool::MaybeUpdateMempoolForReorg(Chainstate& active_chainstate, DisconnectedBlockTransactions& disconnectpool, bool fAddToMempool)
{
LOCK(::cs_main);
LOCK(m_mempool.cs);
m_mempool.MaybeUpdateMempoolForReorg(active_chainstate, disconnectpool, fAddToMempool);
}

void KernelMempool::BeginChainstateUpdate()
{
m_mempool.Lock();
}

void KernelMempool::EndChainstateUpdate()
{
m_mempool.Unlock();
}

} // namespace node
Loading
Loading