refactor: De-globalize g_signals
This commit is contained in:
30 files changed
+131
-154
No files matched your search
@@ -39,7 +39,8 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
|
|||||||
generatetoaddress(test_setup->m_node, address_mine.value_or(ADDRESS_WATCHONLY));
|
generatetoaddress(test_setup->m_node, address_mine.value_or(ADDRESS_WATCHONLY));
|
||||||
generatetoaddress(test_setup->m_node, ADDRESS_WATCHONLY);
|
generatetoaddress(test_setup->m_node, ADDRESS_WATCHONLY);
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
// Calls SyncWithValidationInterfaceQueue
|
||||||
|
wallet.chain().waitForNotificationsIfTipChanged(uint256::ZERO);
|
||||||
|
|
||||||
auto bal = GetBalance(wallet); // Cache
|
auto bal = GetBalance(wallet); // Cache
|
||||||
|
|
||||||
|
|||||||
@@ -74,10 +74,12 @@ int main(int argc, char* argv[])
|
|||||||
// Start the lightweight task scheduler thread
|
// Start the lightweight task scheduler thread
|
||||||
scheduler.m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { scheduler.serviceQueue(); });
|
scheduler.m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { scheduler.serviceQueue(); });
|
||||||
|
|
||||||
|
CMainSignals validation_signals{};
|
||||||
|
|
||||||
// Gather some entropy once per minute.
|
// Gather some entropy once per minute.
|
||||||
scheduler.scheduleEvery(RandAddPeriodic, std::chrono::minutes{1});
|
scheduler.scheduleEvery(RandAddPeriodic, std::chrono::minutes{1});
|
||||||
|
|
||||||
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
|
validation_signals.RegisterBackgroundSignalScheduler(scheduler);
|
||||||
|
|
||||||
class KernelNotifications : public kernel::Notifications
|
class KernelNotifications : public kernel::Notifications
|
||||||
{
|
{
|
||||||
@@ -118,7 +120,7 @@ int main(int argc, char* argv[])
|
|||||||
.chainparams = *chainparams,
|
.chainparams = *chainparams,
|
||||||
.datadir = abs_datadir,
|
.datadir = abs_datadir,
|
||||||
.notifications = *notifications,
|
.notifications = *notifications,
|
||||||
.signals = &GetMainSignals(),
|
.signals = &validation_signals,
|
||||||
};
|
};
|
||||||
const node::BlockManager::Options blockman_opts{
|
const node::BlockManager::Options blockman_opts{
|
||||||
.chainparams = chainman_opts.chainparams,
|
.chainparams = chainman_opts.chainparams,
|
||||||
@@ -236,9 +238,9 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
bool new_block;
|
bool new_block;
|
||||||
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
||||||
RegisterSharedValidationInterface(sc);
|
validation_signals.RegisterSharedValidationInterface(sc);
|
||||||
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
|
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
|
||||||
UnregisterSharedValidationInterface(sc);
|
validation_signals.UnregisterSharedValidationInterface(sc);
|
||||||
if (!new_block && accepted) {
|
if (!new_block && accepted) {
|
||||||
std::cerr << "duplicate" << std::endl;
|
std::cerr << "duplicate" << std::endl;
|
||||||
break;
|
break;
|
||||||
@@ -291,7 +293,7 @@ epilogue:
|
|||||||
scheduler.stop();
|
scheduler.stop();
|
||||||
if (chainman.m_thread_load.joinable()) chainman.m_thread_load.join();
|
if (chainman.m_thread_load.joinable()) chainman.m_thread_load.join();
|
||||||
|
|
||||||
GetMainSignals().FlushBackgroundCallbacks();
|
validation_signals.FlushBackgroundCallbacks();
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
for (Chainstate* chainstate : chainman.GetAll()) {
|
for (Chainstate* chainstate : chainman.GetAll()) {
|
||||||
@@ -301,5 +303,5 @@ epilogue:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
validation_signals.UnregisterBackgroundSignalScheduler();
|
||||||
}
|
}
|
||||||
+5
-3
@@ -89,7 +89,7 @@ bool BaseIndex::Init()
|
|||||||
return &m_chain->context()->chainman->GetChainstateForIndexing());
|
return &m_chain->context()->chainman->GetChainstateForIndexing());
|
||||||
// Register to validation interface before setting the 'm_synced' flag, so that
|
// Register to validation interface before setting the 'm_synced' flag, so that
|
||||||
// callbacks are not missed once m_synced is true.
|
// callbacks are not missed once m_synced is true.
|
||||||
RegisterValidationInterface(this);
|
m_chain->context()->validation_signals->RegisterValidationInterface(this);
|
||||||
|
|
||||||
CBlockLocator locator;
|
CBlockLocator locator;
|
||||||
if (!GetDB().ReadBestBlock(locator)) {
|
if (!GetDB().ReadBestBlock(locator)) {
|
||||||
@@ -380,7 +380,7 @@ bool BaseIndex::BlockUntilSyncedToCurrentChain() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogPrintf("%s: %s is catching up on block notifications\n", __func__, GetName());
|
LogPrintf("%s: %s is catching up on block notifications\n", __func__, GetName());
|
||||||
SyncWithValidationInterfaceQueue();
|
m_chain->context()->validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +399,9 @@ bool BaseIndex::StartBackgroundSync()
|
|||||||
|
|
||||||
void BaseIndex::Stop()
|
void BaseIndex::Stop()
|
||||||
{
|
{
|
||||||
UnregisterValidationInterface(this);
|
if (m_chain->context()->validation_signals) {
|
||||||
|
m_chain->context()->validation_signals->UnregisterValidationInterface(this);
|
||||||
|
}
|
||||||
|
|
||||||
if (m_thread_sync.joinable()) {
|
if (m_thread_sync.joinable()) {
|
||||||
m_thread_sync.join();
|
m_thread_sync.join();
|
||||||
|
|||||||
+21
-13
@@ -291,7 +291,7 @@ void Shutdown(NodeContext& node)
|
|||||||
|
|
||||||
// Because these depend on each-other, we make sure that neither can be
|
// Because these depend on each-other, we make sure that neither can be
|
||||||
// using the other before destroying them.
|
// using the other before destroying them.
|
||||||
if (node.peerman) UnregisterValidationInterface(node.peerman.get());
|
if (node.peerman && node.validation_signals) node.validation_signals->UnregisterValidationInterface(node.peerman.get());
|
||||||
if (node.connman) node.connman->Stop();
|
if (node.connman) node.connman->Stop();
|
||||||
|
|
||||||
StopTorControl();
|
StopTorControl();
|
||||||
@@ -317,7 +317,9 @@ void Shutdown(NodeContext& node)
|
|||||||
// fee estimator from validation interface.
|
// fee estimator from validation interface.
|
||||||
if (node.fee_estimator) {
|
if (node.fee_estimator) {
|
||||||
node.fee_estimator->Flush();
|
node.fee_estimator->Flush();
|
||||||
UnregisterValidationInterface(node.fee_estimator.get());
|
if (node.validation_signals) {
|
||||||
|
node.validation_signals->UnregisterValidationInterface(node.fee_estimator.get());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
|
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
|
||||||
@@ -332,7 +334,7 @@ void Shutdown(NodeContext& node)
|
|||||||
|
|
||||||
// After there are no more peers/RPC left to give us new data which may generate
|
// After there are no more peers/RPC left to give us new data which may generate
|
||||||
// CValidationInterface callbacks, flush them...
|
// CValidationInterface callbacks, flush them...
|
||||||
GetMainSignals().FlushBackgroundCallbacks();
|
if (node.validation_signals) node.validation_signals->FlushBackgroundCallbacks();
|
||||||
|
|
||||||
// Stop and delete all indexes only after flushing background callbacks.
|
// Stop and delete all indexes only after flushing background callbacks.
|
||||||
if (g_txindex) {
|
if (g_txindex) {
|
||||||
@@ -367,17 +369,20 @@ void Shutdown(NodeContext& node)
|
|||||||
|
|
||||||
#if ENABLE_ZMQ
|
#if ENABLE_ZMQ
|
||||||
if (g_zmq_notification_interface) {
|
if (g_zmq_notification_interface) {
|
||||||
UnregisterValidationInterface(g_zmq_notification_interface.get());
|
if (node.validation_signals) node.validation_signals->UnregisterValidationInterface(g_zmq_notification_interface.get());
|
||||||
g_zmq_notification_interface.reset();
|
g_zmq_notification_interface.reset();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
node.chain_clients.clear();
|
node.chain_clients.clear();
|
||||||
UnregisterAllValidationInterfaces();
|
if (node.validation_signals) {
|
||||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
node.validation_signals->UnregisterAllValidationInterfaces();
|
||||||
|
node.validation_signals->UnregisterBackgroundSignalScheduler();
|
||||||
|
}
|
||||||
node.mempool.reset();
|
node.mempool.reset();
|
||||||
node.fee_estimator.reset();
|
node.fee_estimator.reset();
|
||||||
node.chainman.reset();
|
node.chainman.reset();
|
||||||
|
node.validation_signals.reset();
|
||||||
node.scheduler.reset();
|
node.scheduler.reset();
|
||||||
node.kernel.reset();
|
node.kernel.reset();
|
||||||
|
|
||||||
@@ -1158,7 +1163,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
}
|
}
|
||||||
}, std::chrono::minutes{5});
|
}, std::chrono::minutes{5});
|
||||||
|
|
||||||
GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler);
|
assert(!node.validation_signals);
|
||||||
|
node.validation_signals = std::make_unique<CMainSignals>();
|
||||||
|
auto& validation_signals = *node.validation_signals;
|
||||||
|
validation_signals.RegisterBackgroundSignalScheduler(*node.scheduler);
|
||||||
|
|
||||||
// Create client interfaces for wallets that are supposed to be loaded
|
// Create client interfaces for wallets that are supposed to be loaded
|
||||||
// according to -wallet and -disablewallet options. This only constructs
|
// according to -wallet and -disablewallet options. This only constructs
|
||||||
@@ -1264,7 +1272,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
// Flush estimates to disk periodically
|
// Flush estimates to disk periodically
|
||||||
CBlockPolicyEstimator* fee_estimator = node.fee_estimator.get();
|
CBlockPolicyEstimator* fee_estimator = node.fee_estimator.get();
|
||||||
node.scheduler->scheduleEvery([fee_estimator] { fee_estimator->FlushFeeEstimates(); }, FEE_FLUSH_INTERVAL);
|
node.scheduler->scheduleEvery([fee_estimator] { fee_estimator->FlushFeeEstimates(); }, FEE_FLUSH_INTERVAL);
|
||||||
RegisterValidationInterface(fee_estimator);
|
validation_signals.RegisterValidationInterface(fee_estimator);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check port numbers
|
// Check port numbers
|
||||||
@@ -1435,7 +1443,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (g_zmq_notification_interface) {
|
if (g_zmq_notification_interface) {
|
||||||
RegisterValidationInterface(g_zmq_notification_interface.get());
|
validation_signals.RegisterValidationInterface(g_zmq_notification_interface.get());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1449,7 +1457,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
.chainparams = chainparams,
|
.chainparams = chainparams,
|
||||||
.datadir = args.GetDataDirNet(),
|
.datadir = args.GetDataDirNet(),
|
||||||
.notifications = *node.notifications,
|
.notifications = *node.notifications,
|
||||||
.signals = &GetMainSignals(),
|
.signals = &validation_signals,
|
||||||
};
|
};
|
||||||
Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
|
||||||
|
|
||||||
@@ -1479,7 +1487,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
|
|
||||||
CTxMemPool::Options mempool_opts{
|
CTxMemPool::Options mempool_opts{
|
||||||
.check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
|
.check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
|
||||||
.signals = &GetMainSignals(),
|
.signals = &validation_signals,
|
||||||
};
|
};
|
||||||
auto result{ApplyArgsManOptions(args, chainparams, mempool_opts)};
|
auto result{ApplyArgsManOptions(args, chainparams, mempool_opts)};
|
||||||
if (!result) {
|
if (!result) {
|
||||||
@@ -1507,7 +1515,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
|
|
||||||
// Drain the validation interface queue to ensure that the old indexes
|
// Drain the validation interface queue to ensure that the old indexes
|
||||||
// don't have any pending work.
|
// don't have any pending work.
|
||||||
SyncWithValidationInterfaceQueue();
|
Assert(node.validation_signals)->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
for (auto* index : node.indexes) {
|
for (auto* index : node.indexes) {
|
||||||
index->Interrupt();
|
index->Interrupt();
|
||||||
@@ -1596,7 +1604,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
|||||||
node.peerman = PeerManager::make(*node.connman, *node.addrman,
|
node.peerman = PeerManager::make(*node.connman, *node.addrman,
|
||||||
node.banman.get(), chainman,
|
node.banman.get(), chainman,
|
||||||
*node.mempool, peerman_opts);
|
*node.mempool, peerman_opts);
|
||||||
RegisterValidationInterface(node.peerman.get());
|
validation_signals.RegisterValidationInterface(node.peerman.get());
|
||||||
|
|
||||||
// ********************************************************* Step 8: start indexers
|
// ********************************************************* Step 8: start indexers
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ class BanMan;
|
|||||||
class BaseIndex;
|
class BaseIndex;
|
||||||
class CBlockPolicyEstimator;
|
class CBlockPolicyEstimator;
|
||||||
class CConnman;
|
class CConnman;
|
||||||
|
class CMainSignals;
|
||||||
class CScheduler;
|
class CScheduler;
|
||||||
class CTxMemPool;
|
class CTxMemPool;
|
||||||
class ChainstateManager;
|
class ChainstateManager;
|
||||||
@@ -70,7 +71,10 @@ struct NodeContext {
|
|||||||
interfaces::WalletLoader* wallet_loader{nullptr};
|
interfaces::WalletLoader* wallet_loader{nullptr};
|
||||||
std::unique_ptr<CScheduler> scheduler;
|
std::unique_ptr<CScheduler> scheduler;
|
||||||
std::function<void()> rpc_interruption_point = [] {};
|
std::function<void()> rpc_interruption_point = [] {};
|
||||||
|
//! Issues blocking calls about sync status, errors and warnings
|
||||||
std::unique_ptr<KernelNotifications> notifications;
|
std::unique_ptr<KernelNotifications> notifications;
|
||||||
|
//! Issues calls about blocks and transactions
|
||||||
|
std::unique_ptr<CMainSignals> validation_signals;
|
||||||
std::atomic<int> exit_status{EXIT_SUCCESS};
|
std::atomic<int> exit_status{EXIT_SUCCESS};
|
||||||
|
|
||||||
//! Declare default constructor and destructor that are not inline, so code
|
//! Declare default constructor and destructor that are not inline, so code
|
||||||
|
|||||||
@@ -460,19 +460,20 @@ public:
|
|||||||
class NotificationsHandlerImpl : public Handler
|
class NotificationsHandlerImpl : public Handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit NotificationsHandlerImpl(std::shared_ptr<Chain::Notifications> notifications)
|
explicit NotificationsHandlerImpl(CMainSignals& signals, std::shared_ptr<Chain::Notifications> notifications)
|
||||||
: m_proxy(std::make_shared<NotificationsProxy>(std::move(notifications)))
|
: m_signals{signals}, m_proxy{std::make_shared<NotificationsProxy>(std::move(notifications))}
|
||||||
{
|
{
|
||||||
RegisterSharedValidationInterface(m_proxy);
|
m_signals.RegisterSharedValidationInterface(m_proxy);
|
||||||
}
|
}
|
||||||
~NotificationsHandlerImpl() override { disconnect(); }
|
~NotificationsHandlerImpl() override { disconnect(); }
|
||||||
void disconnect() override
|
void disconnect() override
|
||||||
{
|
{
|
||||||
if (m_proxy) {
|
if (m_proxy) {
|
||||||
UnregisterSharedValidationInterface(m_proxy);
|
m_signals.UnregisterSharedValidationInterface(m_proxy);
|
||||||
m_proxy.reset();
|
m_proxy.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CMainSignals& m_signals;
|
||||||
std::shared_ptr<NotificationsProxy> m_proxy;
|
std::shared_ptr<NotificationsProxy> m_proxy;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -761,12 +762,12 @@ public:
|
|||||||
}
|
}
|
||||||
std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
|
std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
|
||||||
{
|
{
|
||||||
return std::make_unique<NotificationsHandlerImpl>(std::move(notifications));
|
return std::make_unique<NotificationsHandlerImpl>(validation_signals(), std::move(notifications));
|
||||||
}
|
}
|
||||||
void waitForNotificationsIfTipChanged(const uint256& old_tip) override
|
void waitForNotificationsIfTipChanged(const uint256& old_tip) override
|
||||||
{
|
{
|
||||||
if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;
|
if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;
|
||||||
SyncWithValidationInterfaceQueue();
|
validation_signals().SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
|
std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
|
||||||
{
|
{
|
||||||
@@ -822,6 +823,7 @@ public:
|
|||||||
NodeContext* context() override { return &m_node; }
|
NodeContext* context() override { return &m_node; }
|
||||||
ArgsManager& args() { return *Assert(m_node.args); }
|
ArgsManager& args() { return *Assert(m_node.args); }
|
||||||
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
|
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
|
||||||
|
CMainSignals& validation_signals() { return *Assert(m_node.validation_signals); }
|
||||||
NodeContext& m_node;
|
NodeContext& m_node;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
|||||||
node.mempool->AddUnbroadcastTx(txid);
|
node.mempool->AddUnbroadcastTx(txid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait_callback) {
|
if (wait_callback && node.validation_signals) {
|
||||||
// For transactions broadcast from outside the wallet, make sure
|
// For transactions broadcast from outside the wallet, make sure
|
||||||
// that the wallet has been notified of the transaction before
|
// that the wallet has been notified of the transaction before
|
||||||
// continuing.
|
// continuing.
|
||||||
@@ -101,7 +101,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
|
|||||||
// with a transaction to/from their wallet, immediately call some
|
// with a transaction to/from their wallet, immediately call some
|
||||||
// wallet RPC, and get a stale result because callbacks have not
|
// wallet RPC, and get a stale result because callbacks have not
|
||||||
// yet been processed.
|
// yet been processed.
|
||||||
CallFunctionInValidationInterfaceQueue([&promise] {
|
node.validation_signals->CallFunctionInValidationInterfaceQueue([&promise] {
|
||||||
promise.set_value();
|
promise.set_value();
|
||||||
});
|
});
|
||||||
callback_set = true;
|
callback_set = true;
|
||||||
|
|||||||
@@ -395,7 +395,8 @@ static RPCHelpMan syncwithvalidationinterfacequeue()
|
|||||||
},
|
},
|
||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
SyncWithValidationInterfaceQueue();
|
NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
|
CHECK_NONFATAL(node.validation_signals)->SyncWithValidationInterfaceQueue();
|
||||||
return UniValue::VNULL;
|
return UniValue::VNULL;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
+4
-6
@@ -4,6 +4,7 @@
|
|||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
|
#include <node/context.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
#include <policy/fees.h>
|
#include <policy/fees.h>
|
||||||
#include <rpc/protocol.h>
|
#include <rpc/protocol.h>
|
||||||
@@ -21,10 +22,6 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace node {
|
|
||||||
struct NodeContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
using node::NodeContext;
|
using node::NodeContext;
|
||||||
|
|
||||||
static RPCHelpMan estimatesmartfee()
|
static RPCHelpMan estimatesmartfee()
|
||||||
@@ -68,7 +65,7 @@ static RPCHelpMan estimatesmartfee()
|
|||||||
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
const CTxMemPool& mempool = EnsureMemPool(node);
|
const CTxMemPool& mempool = EnsureMemPool(node);
|
||||||
|
|
||||||
SyncWithValidationInterfaceQueue();
|
CHECK_NONFATAL(mempool.m_signals)->SyncWithValidationInterfaceQueue();
|
||||||
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||||
bool conservative = true;
|
bool conservative = true;
|
||||||
@@ -156,8 +153,9 @@ static RPCHelpMan estimaterawfee()
|
|||||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||||
{
|
{
|
||||||
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
|
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
|
||||||
|
const NodeContext& node = EnsureAnyNodeContext(request.context);
|
||||||
|
|
||||||
SyncWithValidationInterfaceQueue();
|
CHECK_NONFATAL(node.validation_signals)->SyncWithValidationInterfaceQueue();
|
||||||
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
|
||||||
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
|
||||||
double threshold = 0.95;
|
double threshold = 0.95;
|
||||||
|
|||||||
+2
-2
@@ -1038,9 +1038,9 @@ static RPCHelpMan submitblock()
|
|||||||
|
|
||||||
bool new_block;
|
bool new_block;
|
||||||
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
|
||||||
RegisterSharedValidationInterface(sc);
|
CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);
|
||||||
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
|
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
|
||||||
UnregisterSharedValidationInterface(sc);
|
CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);
|
||||||
if (!new_block && accepted) {
|
if (!new_block && accepted) {
|
||||||
return "duplicate";
|
return "duplicate";
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -90,7 +90,7 @@ static RPCHelpMan mockscheduler()
|
|||||||
|
|
||||||
const NodeContext& node_context{EnsureAnyNodeContext(request.context)};
|
const NodeContext& node_context{EnsureAnyNodeContext(request.context)};
|
||||||
CHECK_NONFATAL(node_context.scheduler)->MockForward(std::chrono::seconds{delta_seconds});
|
CHECK_NONFATAL(node_context.scheduler)->MockForward(std::chrono::seconds{delta_seconds});
|
||||||
SyncWithValidationInterfaceQueue();
|
CHECK_NONFATAL(node_context.validation_signals)->SyncWithValidationInterfaceQueue();
|
||||||
for (const auto& chain_client : node_context.chain_clients) {
|
for (const auto& chain_client : node_context.chain_clients) {
|
||||||
chain_client->schedulerMockForward(std::chrono::seconds(delta_seconds));
|
chain_client->schedulerMockForward(std::chrono::seconds(delta_seconds));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
|
|||||||
// SyncWithValidationInterfaceQueue() call below is also needed to ensure
|
// SyncWithValidationInterfaceQueue() call below is also needed to ensure
|
||||||
// TSAN always sees the test thread waiting for the notification thread, and
|
// TSAN always sees the test thread waiting for the notification thread, and
|
||||||
// avoid potential false positive reports.
|
// avoid potential false positive reports.
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
// Shutdown sequence (c.f. Shutdown() in init.cpp)
|
// Shutdown sequence (c.f. Shutdown() in init.cpp)
|
||||||
coin_stats_index.Stop();
|
coin_stats_index.Stop();
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void initialize_tx_pool()
|
|||||||
g_outpoints_coinbase_init_mature.push_back(prevout);
|
g_outpoints_coinbase_init_mature.push_back(prevout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OutpointsUpdater final : public CValidationInterface {
|
struct OutpointsUpdater final : public CValidationInterface {
|
||||||
@@ -147,7 +147,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto outpoints_updater = std::make_shared<OutpointsUpdater>(mempool_outpoints);
|
auto outpoints_updater = std::make_shared<OutpointsUpdater>(mempool_outpoints);
|
||||||
RegisterSharedValidationInterface(outpoints_updater);
|
node.validation_signals->RegisterSharedValidationInterface(outpoints_updater);
|
||||||
|
|
||||||
CTxMemPool tx_pool_{MakeMempool(fuzzed_data_provider, node)};
|
CTxMemPool tx_pool_{MakeMempool(fuzzed_data_provider, node)};
|
||||||
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_);
|
MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_);
|
||||||
@@ -269,7 +269,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
|||||||
// Remember all added transactions
|
// Remember all added transactions
|
||||||
std::set<CTransactionRef> added;
|
std::set<CTransactionRef> added;
|
||||||
auto txr = std::make_shared<TransactionsDelta>(added);
|
auto txr = std::make_shared<TransactionsDelta>(added);
|
||||||
RegisterSharedValidationInterface(txr);
|
node.validation_signals->RegisterSharedValidationInterface(txr);
|
||||||
|
|
||||||
// When there are multiple transactions in the package, we call ProcessNewPackage(txs, test_accept=false)
|
// When there are multiple transactions in the package, we call ProcessNewPackage(txs, test_accept=false)
|
||||||
// and AcceptToMemoryPool(txs.back(), test_accept=true). When there is only 1 transaction, we might flip it
|
// and AcceptToMemoryPool(txs.back(), test_accept=true). When there is only 1 transaction, we might flip it
|
||||||
@@ -285,8 +285,8 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
|||||||
/*bypass_limits=*/false, /*test_accept=*/!single_submit));
|
/*bypass_limits=*/false, /*test_accept=*/!single_submit));
|
||||||
const bool passed = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
const bool passed = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
||||||
|
|
||||||
SyncWithValidationInterfaceQueue();
|
node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
UnregisterSharedValidationInterface(txr);
|
node.validation_signals->UnregisterSharedValidationInterface(txr);
|
||||||
|
|
||||||
// There is only 1 transaction in the package. We did a test-package-accept and a ATMP
|
// There is only 1 transaction in the package. We did a test-package-accept and a ATMP
|
||||||
if (single_submit) {
|
if (single_submit) {
|
||||||
@@ -310,7 +310,7 @@ FUZZ_TARGET(tx_package_eval, .init = initialize_tx_pool)
|
|||||||
CheckMempoolV3Invariants(tx_pool);
|
CheckMempoolV3Invariants(tx_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
UnregisterSharedValidationInterface(outpoints_updater);
|
node.validation_signals->UnregisterSharedValidationInterface(outpoints_updater);
|
||||||
|
|
||||||
WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
|
WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ void initialize_process_message()
|
|||||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||||
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
|
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
FUZZ_TARGET(process_message, .init = initialize_process_message)
|
FUZZ_TARGET(process_message, .init = initialize_process_message)
|
||||||
@@ -89,6 +89,6 @@ FUZZ_TARGET(process_message, .init = initialize_process_message)
|
|||||||
}
|
}
|
||||||
g_setup->m_node.peerman->SendMessages(&p2p_node);
|
g_setup->m_node.peerman->SendMessages(&p2p_node);
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
g_setup->m_node.connman->StopNodes();
|
g_setup->m_node.connman->StopNodes();
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ void initialize_process_messages()
|
|||||||
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
for (int i = 0; i < 2 * COINBASE_MATURITY; i++) {
|
||||||
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
|
MineBlock(g_setup->m_node, CScript() << OP_TRUE);
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
||||||
@@ -89,6 +89,6 @@ FUZZ_TARGET(process_messages, .init = initialize_process_messages)
|
|||||||
g_setup->m_node.peerman->SendMessages(&random_node);
|
g_setup->m_node.peerman->SendMessages(&random_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
g_setup->m_node.connman->StopNodes();
|
g_setup->m_node.connman->StopNodes();
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,7 @@ void initialize_tx_pool()
|
|||||||
g_outpoints_coinbase_init_immature;
|
g_outpoints_coinbase_init_immature;
|
||||||
outpoints.push_back(prevout);
|
outpoints.push_back(prevout);
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TransactionsDelta final : public CValidationInterface {
|
struct TransactionsDelta final : public CValidationInterface {
|
||||||
@@ -105,7 +105,7 @@ void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, Cha
|
|||||||
assert(tx_pool.size() < info_all.size());
|
assert(tx_pool.size() < info_all.size());
|
||||||
WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
|
WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1));
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chainstate)
|
void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chainstate)
|
||||||
@@ -285,7 +285,7 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
|
|||||||
std::set<CTransactionRef> removed;
|
std::set<CTransactionRef> removed;
|
||||||
std::set<CTransactionRef> added;
|
std::set<CTransactionRef> added;
|
||||||
auto txr = std::make_shared<TransactionsDelta>(removed, added);
|
auto txr = std::make_shared<TransactionsDelta>(removed, added);
|
||||||
RegisterSharedValidationInterface(txr);
|
node.validation_signals->RegisterSharedValidationInterface(txr);
|
||||||
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
|
const bool bypass_limits = fuzzed_data_provider.ConsumeBool();
|
||||||
|
|
||||||
// Make sure ProcessNewPackage on one transaction works.
|
// Make sure ProcessNewPackage on one transaction works.
|
||||||
@@ -303,8 +303,8 @@ FUZZ_TARGET(tx_pool_standard, .init = initialize_tx_pool)
|
|||||||
|
|
||||||
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
|
const auto res = WITH_LOCK(::cs_main, return AcceptToMemoryPool(chainstate, tx, GetTime(), bypass_limits, /*test_accept=*/false));
|
||||||
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
const bool accepted = res.m_result_type == MempoolAcceptResult::ResultType::VALID;
|
||||||
SyncWithValidationInterfaceQueue();
|
node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
UnregisterSharedValidationInterface(txr);
|
node.validation_signals->UnregisterSharedValidationInterface(txr);
|
||||||
|
|
||||||
bool txid_in_mempool = tx_pool.exists(GenTxid::Txid(tx->GetHash()));
|
bool txid_in_mempool = tx_pool.exists(GenTxid::Txid(tx->GetHash()));
|
||||||
bool wtxid_in_mempool = tx_pool.exists(GenTxid::Wtxid(tx->GetWitnessHash()));
|
bool wtxid_in_mempool = tx_pool.exists(GenTxid::Wtxid(tx->GetWitnessHash()));
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ static void mineBlock(const node::NodeContext& node, std::chrono::seconds block_
|
|||||||
block.fChecked = true; // little speedup
|
block.fChecked = true; // little speedup
|
||||||
SetMockTime(curr_time); // process block at current time
|
SetMockTime(curr_time); // process block at current time
|
||||||
Assert(node.chainman->ProcessNewBlock(std::make_shared<const CBlock>(block), /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
|
Assert(node.chainman->ProcessNewBlock(std::make_shared<const CBlock>(block), /*force_processing=*/true, /*min_pow_checked=*/true, nullptr));
|
||||||
SyncWithValidationInterfaceQueue(); // drain events queue
|
node.validation_signals->SyncWithValidationInterfaceQueue(); // drain events queue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verifying when network-limited peer connections are desirable based on the node's proximity to the tip
|
// Verifying when network-limited peer connections are desirable based on the node's proximity to the tip
|
||||||
@@ -57,7 +57,7 @@ BOOST_AUTO_TEST_CASE(connections_desirable_service_flags)
|
|||||||
|
|
||||||
// By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip.
|
// By now, we tested that the connections desirable services flags change based on the node's time proximity to the tip.
|
||||||
// Now, perform the same tests for when the node receives a block.
|
// Now, perform the same tests for when the node receives a block.
|
||||||
RegisterValidationInterface(peerman.get());
|
m_node.validation_signals->RegisterValidationInterface(peerman.get());
|
||||||
|
|
||||||
// First, verify a block in the past doesn't enable limited peers connections
|
// First, verify a block in the past doesn't enable limited peers connections
|
||||||
// At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time.
|
// At this point, our time is (NODE_NETWORK_LIMITED_ALLOW_CONN_BLOCKS + 1) * 10 minutes ahead the tip's time.
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
{
|
{
|
||||||
CBlockPolicyEstimator& feeEst = *Assert(m_node.fee_estimator);
|
CBlockPolicyEstimator& feeEst = *Assert(m_node.fee_estimator);
|
||||||
CTxMemPool& mpool = *Assert(m_node.mempool);
|
CTxMemPool& mpool = *Assert(m_node.mempool);
|
||||||
RegisterValidationInterface(&feeEst);
|
m_node.validation_signals->RegisterValidationInterface(&feeEst);
|
||||||
TestMemPoolEntryHelper entry;
|
TestMemPoolEntryHelper entry;
|
||||||
CAmount basefee(2000);
|
CAmount basefee(2000);
|
||||||
CAmount deltaFee(100);
|
CAmount deltaFee(100);
|
||||||
@@ -74,7 +74,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
/*submitted_in_package=*/false,
|
/*submitted_in_package=*/false,
|
||||||
/*chainstate_is_current=*/true,
|
/*chainstate_is_current=*/true,
|
||||||
/*has_no_mempool_parents=*/true)};
|
/*has_no_mempool_parents=*/true)};
|
||||||
GetMainSignals().TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
|
m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
|
||||||
}
|
}
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
txHashes[j].push_back(hash);
|
txHashes[j].push_back(hash);
|
||||||
@@ -102,7 +102,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
// Check after just a few txs that combining buckets works as expected
|
// Check after just a few txs that combining buckets works as expected
|
||||||
if (blocknum == 3) {
|
if (blocknum == 3) {
|
||||||
// Wait for fee estimator to catch up
|
// Wait for fee estimator to catch up
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
// At this point we should need to combine 3 buckets to get enough data points
|
// At this point we should need to combine 3 buckets to get enough data points
|
||||||
// So estimateFee(1) should fail and estimateFee(2) should return somewhere around
|
// So estimateFee(1) should fail and estimateFee(2) should return somewhere around
|
||||||
// 9*baserate. estimateFee(2) %'s are 100,100,90 = average 97%
|
// 9*baserate. estimateFee(2) %'s are 100,100,90 = average 97%
|
||||||
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for fee estimator to catch up
|
// Wait for fee estimator to catch up
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
std::vector<CAmount> origFeeEst;
|
std::vector<CAmount> origFeeEst;
|
||||||
// Highest feerate is 10*baseRate and gets in all blocks,
|
// Highest feerate is 10*baseRate and gets in all blocks,
|
||||||
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for fee estimator to catch up
|
// Wait for fee estimator to catch up
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
|
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
|
||||||
for (int i = 2; i < 10;i++) {
|
for (int i = 2; i < 10;i++) {
|
||||||
@@ -175,7 +175,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
/*submitted_in_package=*/false,
|
/*submitted_in_package=*/false,
|
||||||
/*chainstate_is_current=*/true,
|
/*chainstate_is_current=*/true,
|
||||||
/*has_no_mempool_parents=*/true)};
|
/*has_no_mempool_parents=*/true)};
|
||||||
GetMainSignals().TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
|
m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
|
||||||
}
|
}
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
txHashes[j].push_back(hash);
|
txHashes[j].push_back(hash);
|
||||||
@@ -188,7 +188,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Wait for fee estimator to catch up
|
// Wait for fee estimator to catch up
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
for (int i = 1; i < 10;i++) {
|
for (int i = 1; i < 10;i++) {
|
||||||
BOOST_CHECK(feeEst.estimateFee(i) == CFeeRate(0) || feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
|
BOOST_CHECK(feeEst.estimateFee(i) == CFeeRate(0) || feeEst.estimateFee(i).GetFeePerK() > origFeeEst[i-1] - deltaFee);
|
||||||
@@ -212,7 +212,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
block.clear();
|
block.clear();
|
||||||
|
|
||||||
// Wait for fee estimator to catch up
|
// Wait for fee estimator to catch up
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
|
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
|
||||||
for (int i = 2; i < 10;i++) {
|
for (int i = 2; i < 10;i++) {
|
||||||
@@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
/*submitted_in_package=*/false,
|
/*submitted_in_package=*/false,
|
||||||
/*chainstate_is_current=*/true,
|
/*chainstate_is_current=*/true,
|
||||||
/*has_no_mempool_parents=*/true)};
|
/*has_no_mempool_parents=*/true)};
|
||||||
GetMainSignals().TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
|
m_node.validation_signals->TransactionAddedToMempool(tx_info, mpool.GetAndIncrementSequence());
|
||||||
}
|
}
|
||||||
uint256 hash = tx.GetHash();
|
uint256 hash = tx.GetHash();
|
||||||
CTransactionRef ptx = mpool.get(hash);
|
CTransactionRef ptx = mpool.get(hash);
|
||||||
@@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates)
|
|||||||
block.clear();
|
block.clear();
|
||||||
}
|
}
|
||||||
// Wait for fee estimator to catch up
|
// Wait for fee estimator to catch up
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
|
BOOST_CHECK(feeEst.estimateFee(1) == CFeeRate(0));
|
||||||
for (int i = 2; i < 9; i++) { // At 9, the original estimate was already at the bottom (b/c scale = 2)
|
for (int i = 2; i < 9; i++) { // At 9, the original estimate was already at the bottom (b/c scale = 2)
|
||||||
BOOST_CHECK(feeEst.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee);
|
BOOST_CHECK(feeEst.estimateFee(i).GetFeePerK() < origFeeEst[i-1] - deltaFee);
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ BOOST_FIXTURE_TEST_CASE(txindex_initial_sync, TestChain100Setup)
|
|||||||
// SyncWithValidationInterfaceQueue() call below is also needed to ensure
|
// SyncWithValidationInterfaceQueue() call below is also needed to ensure
|
||||||
// TSAN always sees the test thread waiting for the notification thread, and
|
// TSAN always sees the test thread waiting for the notification thread, and
|
||||||
// avoid potential false positive reports.
|
// avoid potential false positive reports.
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
// shutdown sequence (c.f. Shutdown() in init.cpp)
|
// shutdown sequence (c.f. Shutdown() in init.cpp)
|
||||||
txindex.Stop();
|
txindex.Stop();
|
||||||
|
|||||||
@@ -95,12 +95,12 @@ COutPoint MineBlock(const NodeContext& node, std::shared_ptr<CBlock>& block)
|
|||||||
const auto old_height = WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight());
|
const auto old_height = WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight());
|
||||||
bool new_block;
|
bool new_block;
|
||||||
BlockValidationStateCatcher bvsc{block->GetHash()};
|
BlockValidationStateCatcher bvsc{block->GetHash()};
|
||||||
RegisterValidationInterface(&bvsc);
|
node.validation_signals->RegisterValidationInterface(&bvsc);
|
||||||
const bool processed{chainman.ProcessNewBlock(block, true, true, &new_block)};
|
const bool processed{chainman.ProcessNewBlock(block, true, true, &new_block)};
|
||||||
const bool duplicate{!new_block && processed};
|
const bool duplicate{!new_block && processed};
|
||||||
assert(!duplicate);
|
assert(!duplicate);
|
||||||
UnregisterValidationInterface(&bvsc);
|
node.validation_signals->UnregisterValidationInterface(&bvsc);
|
||||||
SyncWithValidationInterfaceQueue();
|
node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
const bool was_valid{bvsc.m_state && bvsc.m_state->IsValid()};
|
const bool was_valid{bvsc.m_state && bvsc.m_state->IsValid()};
|
||||||
assert(old_height + was_valid == WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight()));
|
assert(old_height + was_valid == WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight()));
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,8 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto
|
|||||||
// from blocking due to queue overrun.
|
// from blocking due to queue overrun.
|
||||||
m_node.scheduler = std::make_unique<CScheduler>();
|
m_node.scheduler = std::make_unique<CScheduler>();
|
||||||
m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); });
|
m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); });
|
||||||
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
|
m_node.validation_signals = std::make_unique<CMainSignals>();
|
||||||
|
m_node.validation_signals->RegisterBackgroundSignalScheduler(*m_node.scheduler);
|
||||||
|
|
||||||
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(*m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES);
|
m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(*m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES);
|
||||||
m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node));
|
m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node));
|
||||||
@@ -185,7 +186,7 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto
|
|||||||
.datadir = m_args.GetDataDirNet(),
|
.datadir = m_args.GetDataDirNet(),
|
||||||
.check_block_index = true,
|
.check_block_index = true,
|
||||||
.notifications = *m_node.notifications,
|
.notifications = *m_node.notifications,
|
||||||
.signals = &GetMainSignals(),
|
.signals = m_node.validation_signals.get(),
|
||||||
.worker_threads_num = 2,
|
.worker_threads_num = 2,
|
||||||
};
|
};
|
||||||
const BlockManager::Options blockman_opts{
|
const BlockManager::Options blockman_opts{
|
||||||
@@ -203,8 +204,8 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto
|
|||||||
ChainTestingSetup::~ChainTestingSetup()
|
ChainTestingSetup::~ChainTestingSetup()
|
||||||
{
|
{
|
||||||
if (m_node.scheduler) m_node.scheduler->stop();
|
if (m_node.scheduler) m_node.scheduler->stop();
|
||||||
GetMainSignals().FlushBackgroundCallbacks();
|
m_node.validation_signals->FlushBackgroundCallbacks();
|
||||||
GetMainSignals().UnregisterBackgroundSignalScheduler();
|
m_node.validation_signals->UnregisterBackgroundSignalScheduler();
|
||||||
m_node.connman.reset();
|
m_node.connman.reset();
|
||||||
m_node.banman.reset();
|
m_node.banman.reset();
|
||||||
m_node.addrman.reset();
|
m_node.addrman.reset();
|
||||||
@@ -213,6 +214,7 @@ ChainTestingSetup::~ChainTestingSetup()
|
|||||||
m_node.mempool.reset();
|
m_node.mempool.reset();
|
||||||
m_node.fee_estimator.reset();
|
m_node.fee_estimator.reset();
|
||||||
m_node.chainman.reset();
|
m_node.chainman.reset();
|
||||||
|
m_node.validation_signals.reset();
|
||||||
m_node.scheduler.reset();
|
m_node.scheduler.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include <util/time.h>
|
#include <util/time.h>
|
||||||
#include <util/translation.h>
|
#include <util/translation.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
#include <validationinterface.h>
|
|
||||||
|
|
||||||
using node::NodeContext;
|
using node::NodeContext;
|
||||||
|
|
||||||
@@ -23,7 +22,7 @@ CTxMemPool::Options MemPoolOptionsForTest(const NodeContext& node)
|
|||||||
// Default to always checking mempool regardless of
|
// Default to always checking mempool regardless of
|
||||||
// chainparams.DefaultConsistencyChecks for tests
|
// chainparams.DefaultConsistencyChecks for tests
|
||||||
.check_ratio = 1,
|
.check_ratio = 1,
|
||||||
.signals = &GetMainSignals(),
|
.signals = node.validation_signals.get(),
|
||||||
};
|
};
|
||||||
const auto result{ApplyArgsManOptions(*node.args, ::Params(), mempool_opts)};
|
const auto result{ApplyArgsManOptions(*node.args, ::Params(), mempool_opts)};
|
||||||
Assert(result);
|
Assert(result);
|
||||||
|
|||||||
@@ -158,7 +158,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
|
|||||||
bool ignored;
|
bool ignored;
|
||||||
// Connect the genesis block and drain any outstanding events
|
// Connect the genesis block and drain any outstanding events
|
||||||
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(std::make_shared<CBlock>(Params().GenesisBlock()), true, true, &ignored));
|
BOOST_CHECK(Assert(m_node.chainman)->ProcessNewBlock(std::make_shared<CBlock>(Params().GenesisBlock()), true, true, &ignored));
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
// subscribe to events (this subscriber will validate event ordering)
|
// subscribe to events (this subscriber will validate event ordering)
|
||||||
const CBlockIndex* initial_tip = nullptr;
|
const CBlockIndex* initial_tip = nullptr;
|
||||||
@@ -167,7 +167,7 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
|
|||||||
initial_tip = m_node.chainman->ActiveChain().Tip();
|
initial_tip = m_node.chainman->ActiveChain().Tip();
|
||||||
}
|
}
|
||||||
auto sub = std::make_shared<TestSubscriber>(initial_tip->GetBlockHash());
|
auto sub = std::make_shared<TestSubscriber>(initial_tip->GetBlockHash());
|
||||||
RegisterSharedValidationInterface(sub);
|
m_node.validation_signals->RegisterSharedValidationInterface(sub);
|
||||||
|
|
||||||
// create a bunch of threads that repeatedly process a block generated above at random
|
// create a bunch of threads that repeatedly process a block generated above at random
|
||||||
// this will create parallelism and randomness inside validation - the ValidationInterface
|
// this will create parallelism and randomness inside validation - the ValidationInterface
|
||||||
@@ -196,9 +196,9 @@ BOOST_AUTO_TEST_CASE(processnewblock_signals_ordering)
|
|||||||
for (auto& t : threads) {
|
for (auto& t : threads) {
|
||||||
t.join();
|
t.join();
|
||||||
}
|
}
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
UnregisterSharedValidationInterface(sub);
|
m_node.validation_signals->UnregisterSharedValidationInterface(sub);
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
BOOST_CHECK_EQUAL(sub->m_expected_tip, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
|
BOOST_CHECK_EQUAL(sub->m_expected_tip, m_node.chainman->ActiveChain().Tip()->GetBlockHash());
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ BOOST_FIXTURE_TEST_CASE(chainstatemanager, TestChain100Setup)
|
|||||||
BOOST_CHECK_EQUAL(active_tip2, c2.m_chain.Tip());
|
BOOST_CHECK_EQUAL(active_tip2, c2.m_chain.Tip());
|
||||||
|
|
||||||
// Let scheduler events finish running to avoid accessing memory that is going to be unloaded
|
// Let scheduler events finish running to avoid accessing memory that is going to be unloaded
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Test rebalancing the caches associated with each chainstate.
|
//! Test rebalancing the caches associated with each chainstate.
|
||||||
@@ -374,7 +374,7 @@ struct SnapshotTestSetup : TestChain100Setup {
|
|||||||
cs->ForceFlushStateToDisk();
|
cs->ForceFlushStateToDisk();
|
||||||
}
|
}
|
||||||
// Process all callbacks referring to the old manager before wiping it.
|
// Process all callbacks referring to the old manager before wiping it.
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
LOCK(::cs_main);
|
LOCK(::cs_main);
|
||||||
chainman.ResetChainstates();
|
chainman.ResetChainstates();
|
||||||
BOOST_CHECK_EQUAL(chainman.GetAll().size(), 0);
|
BOOST_CHECK_EQUAL(chainman.GetAll().size(), 0);
|
||||||
@@ -383,7 +383,7 @@ struct SnapshotTestSetup : TestChain100Setup {
|
|||||||
.chainparams = ::Params(),
|
.chainparams = ::Params(),
|
||||||
.datadir = chainman.m_options.datadir,
|
.datadir = chainman.m_options.datadir,
|
||||||
.notifications = *m_node.notifications,
|
.notifications = *m_node.notifications,
|
||||||
.signals = &GetMainSignals(),
|
.signals = m_node.validation_signals.get(),
|
||||||
};
|
};
|
||||||
const BlockManager::Options blockman_opts{
|
const BlockManager::Options blockman_opts{
|
||||||
.chainparams = chainman_opts.chainparams,
|
.chainparams = chainman_opts.chainparams,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
|
|||||||
const CBlock block_dummy;
|
const CBlock block_dummy;
|
||||||
BlockValidationState state_dummy;
|
BlockValidationState state_dummy;
|
||||||
while (generate) {
|
while (generate) {
|
||||||
GetMainSignals().BlockChecked(block_dummy, state_dummy);
|
m_node.validation_signals->BlockChecked(block_dummy, state_dummy);
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -37,8 +37,8 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
|
|||||||
// keep going for about 1 sec, which is 250k iterations
|
// keep going for about 1 sec, which is 250k iterations
|
||||||
for (int i = 0; i < 250000; i++) {
|
for (int i = 0; i < 250000; i++) {
|
||||||
auto sub = std::make_shared<TestSubscriberNoop>();
|
auto sub = std::make_shared<TestSubscriberNoop>();
|
||||||
RegisterSharedValidationInterface(sub);
|
m_node.validation_signals->RegisterSharedValidationInterface(sub);
|
||||||
UnregisterSharedValidationInterface(sub);
|
m_node.validation_signals->UnregisterSharedValidationInterface(sub);
|
||||||
}
|
}
|
||||||
// tell the other thread we are done
|
// tell the other thread we are done
|
||||||
generate = false;
|
generate = false;
|
||||||
@@ -52,8 +52,8 @@ BOOST_AUTO_TEST_CASE(unregister_validation_interface_race)
|
|||||||
class TestInterface : public CValidationInterface
|
class TestInterface : public CValidationInterface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TestInterface(std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)
|
TestInterface(CMainSignals& signals, std::function<void()> on_call = nullptr, std::function<void()> on_destroy = nullptr)
|
||||||
: m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy))
|
: m_on_call(std::move(on_call)), m_on_destroy(std::move(on_destroy)), m_signals{signals}
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual ~TestInterface()
|
virtual ~TestInterface()
|
||||||
@@ -64,14 +64,15 @@ public:
|
|||||||
{
|
{
|
||||||
if (m_on_call) m_on_call();
|
if (m_on_call) m_on_call();
|
||||||
}
|
}
|
||||||
static void Call()
|
void Call()
|
||||||
{
|
{
|
||||||
CBlock block;
|
CBlock block;
|
||||||
BlockValidationState state;
|
BlockValidationState state;
|
||||||
GetMainSignals().BlockChecked(block, state);
|
m_signals.BlockChecked(block, state);
|
||||||
}
|
}
|
||||||
std::function<void()> m_on_call;
|
std::function<void()> m_on_call;
|
||||||
std::function<void()> m_on_destroy;
|
std::function<void()> m_on_destroy;
|
||||||
|
CMainSignals& m_signals;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Regression test to ensure UnregisterAllValidationInterfaces calls don't
|
// Regression test to ensure UnregisterAllValidationInterfaces calls don't
|
||||||
@@ -80,17 +81,23 @@ public:
|
|||||||
BOOST_AUTO_TEST_CASE(unregister_all_during_call)
|
BOOST_AUTO_TEST_CASE(unregister_all_during_call)
|
||||||
{
|
{
|
||||||
bool destroyed = false;
|
bool destroyed = false;
|
||||||
RegisterSharedValidationInterface(std::make_shared<TestInterface>(
|
auto shared{std::make_shared<TestInterface>(
|
||||||
|
*m_node.validation_signals,
|
||||||
[&] {
|
[&] {
|
||||||
// First call should decrements reference count 2 -> 1
|
// First call should decrements reference count 2 -> 1
|
||||||
UnregisterAllValidationInterfaces();
|
m_node.validation_signals->UnregisterAllValidationInterfaces();
|
||||||
BOOST_CHECK(!destroyed);
|
BOOST_CHECK(!destroyed);
|
||||||
// Second call should not decrement reference count 1 -> 0
|
// Second call should not decrement reference count 1 -> 0
|
||||||
UnregisterAllValidationInterfaces();
|
m_node.validation_signals->UnregisterAllValidationInterfaces();
|
||||||
BOOST_CHECK(!destroyed);
|
BOOST_CHECK(!destroyed);
|
||||||
},
|
},
|
||||||
[&] { destroyed = true; }));
|
[&] { destroyed = true; })};
|
||||||
TestInterface::Call();
|
m_node.validation_signals->RegisterSharedValidationInterface(shared);
|
||||||
|
BOOST_CHECK(shared.use_count() == 2);
|
||||||
|
shared->Call();
|
||||||
|
BOOST_CHECK(shared.use_count() == 1);
|
||||||
|
BOOST_CHECK(!destroyed);
|
||||||
|
shared.reset();
|
||||||
BOOST_CHECK(destroyed);
|
BOOST_CHECK(destroyed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -3217,7 +3217,7 @@ static void LimitValidationInterfaceQueue(CMainSignals& signals) LOCKS_EXCLUDED(
|
|||||||
AssertLockNotHeld(cs_main);
|
AssertLockNotHeld(cs_main);
|
||||||
|
|
||||||
if (signals.CallbacksPending() > 10) {
|
if (signals.CallbacksPending() > 10) {
|
||||||
SyncWithValidationInterfaceQueue();
|
signals.SyncWithValidationInterfaceQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static CMainSignals g_signals;
|
|
||||||
|
|
||||||
CMainSignals::CMainSignals() {}
|
CMainSignals::CMainSignals() {}
|
||||||
|
|
||||||
CMainSignals::~CMainSignals() {}
|
CMainSignals::~CMainSignals() {}
|
||||||
@@ -124,11 +122,6 @@ size_t CMainSignals::CallbacksPending()
|
|||||||
return m_internals->m_schedulerClient.CallbacksPending();
|
return m_internals->m_schedulerClient.CallbacksPending();
|
||||||
}
|
}
|
||||||
|
|
||||||
CMainSignals& GetMainSignals()
|
|
||||||
{
|
|
||||||
return g_signals;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CMainSignals::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
|
void CMainSignals::RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
|
||||||
{
|
{
|
||||||
// Each connection captures the shared_ptr to ensure that each callback is
|
// Each connection captures the shared_ptr to ensure that each callback is
|
||||||
@@ -277,33 +270,3 @@ void CMainSignals::NewPoWValidBlock(const CBlockIndex *pindex, const std::shared
|
|||||||
LOG_EVENT("%s: block hash=%s", __func__, block->GetHash().ToString());
|
LOG_EVENT("%s: block hash=%s", __func__, block->GetHash().ToString());
|
||||||
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NewPoWValidBlock(pindex, block); });
|
m_internals->Iterate([&](CValidationInterface& callbacks) { callbacks.NewPoWValidBlock(pindex, block); });
|
||||||
}
|
}
|
||||||
|
|
||||||
// These functions are temporary and will be removed in the following commit
|
|
||||||
void RegisterValidationInterface(CValidationInterface* callbacks)
|
|
||||||
{
|
|
||||||
GetMainSignals().RegisterValidationInterface(callbacks);
|
|
||||||
}
|
|
||||||
void UnregisterValidationInterface(CValidationInterface* callbacks)
|
|
||||||
{
|
|
||||||
GetMainSignals().UnregisterValidationInterface(callbacks);
|
|
||||||
}
|
|
||||||
void UnregisterAllValidationInterfaces()
|
|
||||||
{
|
|
||||||
GetMainSignals().UnregisterAllValidationInterfaces();
|
|
||||||
}
|
|
||||||
void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
|
|
||||||
{
|
|
||||||
GetMainSignals().RegisterSharedValidationInterface(callbacks);
|
|
||||||
}
|
|
||||||
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks)
|
|
||||||
{
|
|
||||||
GetMainSignals().UnregisterSharedValidationInterface(callbacks);
|
|
||||||
}
|
|
||||||
void CallFunctionInValidationInterfaceQueue(std::function<void ()> func)
|
|
||||||
{
|
|
||||||
GetMainSignals().CallFunctionInValidationInterfaceQueue(func);
|
|
||||||
}
|
|
||||||
void SyncWithValidationInterfaceQueue()
|
|
||||||
{
|
|
||||||
GetMainSignals().SyncWithValidationInterfaceQueue();
|
|
||||||
}
|
|
||||||
@@ -21,22 +21,11 @@ class BlockValidationState;
|
|||||||
class CBlock;
|
class CBlock;
|
||||||
class CBlockIndex;
|
class CBlockIndex;
|
||||||
struct CBlockLocator;
|
struct CBlockLocator;
|
||||||
class CValidationInterface;
|
|
||||||
class CScheduler;
|
class CScheduler;
|
||||||
enum class MemPoolRemovalReason;
|
enum class MemPoolRemovalReason;
|
||||||
struct RemovedMempoolTransactionInfo;
|
struct RemovedMempoolTransactionInfo;
|
||||||
struct NewMempoolTransactionInfo;
|
struct NewMempoolTransactionInfo;
|
||||||
|
|
||||||
void RegisterValidationInterface(CValidationInterface* callbacks);
|
|
||||||
void UnregisterValidationInterface(CValidationInterface* callbacks);
|
|
||||||
void UnregisterAllValidationInterfaces();
|
|
||||||
|
|
||||||
void RegisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);
|
|
||||||
void UnregisterSharedValidationInterface(std::shared_ptr<CValidationInterface> callbacks);
|
|
||||||
|
|
||||||
void CallFunctionInValidationInterfaceQueue(std::function<void ()> func);
|
|
||||||
void SyncWithValidationInterfaceQueue() LOCKS_EXCLUDED(cs_main);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement this to subscribe to events generated in validation and mempool
|
* Implement this to subscribe to events generated in validation and mempool
|
||||||
*
|
*
|
||||||
@@ -232,6 +221,4 @@ public:
|
|||||||
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
|
void NewPoWValidBlock(const CBlockIndex *, const std::shared_ptr<const CBlock>&);
|
||||||
};
|
};
|
||||||
|
|
||||||
CMainSignals& GetMainSignals();
|
|
||||||
|
|
||||||
#endif // BITCOIN_VALIDATIONINTERFACE_H
|
#endif // BITCOIN_VALIDATIONINTERFACE_H
|
||||||
@@ -71,7 +71,8 @@ std::shared_ptr<CWallet> TestLoadWallet(WalletContext& context)
|
|||||||
|
|
||||||
void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
void TestUnloadWallet(std::shared_ptr<CWallet>&& wallet)
|
||||||
{
|
{
|
||||||
SyncWithValidationInterfaceQueue();
|
// Calls SyncWithValidationInterfaceQueue
|
||||||
|
wallet->chain().waitForNotificationsIfTipChanged({});
|
||||||
wallet->m_chain_notifications_handler.reset();
|
wallet->m_chain_notifications_handler.reset();
|
||||||
UnloadWallet(std::move(wallet));
|
UnloadWallet(std::move(wallet));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -812,7 +812,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||||||
// transactionAddedToMempool notifications, and create block and mempool
|
// transactionAddedToMempool notifications, and create block and mempool
|
||||||
// transactions paying to the wallet
|
// transactions paying to the wallet
|
||||||
std::promise<void> promise;
|
std::promise<void> promise;
|
||||||
CallFunctionInValidationInterfaceQueue([&promise] {
|
m_node.validation_signals->CallFunctionInValidationInterfaceQueue([&promise] {
|
||||||
promise.get_future().wait();
|
promise.get_future().wait();
|
||||||
});
|
});
|
||||||
std::string error;
|
std::string error;
|
||||||
@@ -840,7 +840,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||||||
// Unblock notification queue and make sure stale blockConnected and
|
// Unblock notification queue and make sure stale blockConnected and
|
||||||
// transactionAddedToMempool events are processed
|
// transactionAddedToMempool events are processed
|
||||||
promise.set_value();
|
promise.set_value();
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
// AddToWallet events for block_tx and mempool_tx events are counted a
|
// AddToWallet events for block_tx and mempool_tx events are counted a
|
||||||
// second time as the notification queue is processed
|
// second time as the notification queue is processed
|
||||||
BOOST_CHECK_EQUAL(addtx_count, 5);
|
BOOST_CHECK_EQUAL(addtx_count, 5);
|
||||||
@@ -863,7 +863,7 @@ BOOST_FIXTURE_TEST_CASE(CreateWallet, TestChain100Setup)
|
|||||||
m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
|
m_coinbase_txns.push_back(CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())).vtx[0]);
|
||||||
mempool_tx = TestSimpleSpend(*m_coinbase_txns[3], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
mempool_tx = TestSimpleSpend(*m_coinbase_txns[3], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
||||||
BOOST_CHECK(m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error));
|
BOOST_CHECK(m_node.chain->broadcastTransaction(MakeTransactionRef(mempool_tx), DEFAULT_TRANSACTION_MAXFEE, false, error));
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
});
|
});
|
||||||
wallet = TestLoadWallet(context);
|
wallet = TestLoadWallet(context);
|
||||||
// Since mempool transactions are requested at the end of loading, there will
|
// Since mempool transactions are requested at the end of loading, there will
|
||||||
@@ -903,7 +903,7 @@ BOOST_FIXTURE_TEST_CASE(ZapSelectTx, TestChain100Setup)
|
|||||||
auto block_tx = TestSimpleSpend(*m_coinbase_txns[0], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
auto block_tx = TestSimpleSpend(*m_coinbase_txns[0], 0, coinbaseKey, GetScriptForRawPubKey(key.GetPubKey()));
|
||||||
CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
CreateAndProcessBlock({block_tx}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
|
||||||
|
|
||||||
SyncWithValidationInterfaceQueue();
|
m_node.validation_signals->SyncWithValidationInterfaceQueue();
|
||||||
|
|
||||||
{
|
{
|
||||||
auto block_hash = block_tx.GetHash();
|
auto block_hash = block_tx.GetHash();
|
||||||
|
|||||||
Reference in new issue
Block a user