Skip to content

Commit 84f5c13

Browse files
committed
refactor: De-globalize g_signals
1 parent 473dd4b commit 84f5c13

30 files changed

+131
-154
lines changed

src/bench/wallet_balance.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ static void WalletBalance(benchmark::Bench& bench, const bool set_dirty, const b
3939
generatetoaddress(test_setup->m_node, address_mine.value_or(ADDRESS_WATCHONLY));
4040
generatetoaddress(test_setup->m_node, ADDRESS_WATCHONLY);
4141
}
42-
SyncWithValidationInterfaceQueue();
42+
// Calls SyncWithValidationInterfaceQueue
43+
wallet.chain().waitForNotificationsIfTipChanged(uint256::ZERO);
4344

4445
auto bal = GetBalance(wallet); // Cache
4546

src/bitcoin-chainstate.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,12 @@ int main(int argc, char* argv[])
7474
// Start the lightweight task scheduler thread
7575
scheduler.m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { scheduler.serviceQueue(); });
7676

77+
CMainSignals validation_signals{};
78+
7779
// Gather some entropy once per minute.
7880
scheduler.scheduleEvery(RandAddPeriodic, std::chrono::minutes{1});
7981

80-
GetMainSignals().RegisterBackgroundSignalScheduler(scheduler);
82+
validation_signals.RegisterBackgroundSignalScheduler(scheduler);
8183

8284
class KernelNotifications : public kernel::Notifications
8385
{
@@ -118,7 +120,7 @@ int main(int argc, char* argv[])
118120
.chainparams = *chainparams,
119121
.datadir = abs_datadir,
120122
.notifications = *notifications,
121-
.signals = &GetMainSignals(),
123+
.signals = &validation_signals,
122124
};
123125
const node::BlockManager::Options blockman_opts{
124126
.chainparams = chainman_opts.chainparams,
@@ -236,9 +238,9 @@ int main(int argc, char* argv[])
236238

237239
bool new_block;
238240
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
239-
RegisterSharedValidationInterface(sc);
241+
validation_signals.RegisterSharedValidationInterface(sc);
240242
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
241-
UnregisterSharedValidationInterface(sc);
243+
validation_signals.UnregisterSharedValidationInterface(sc);
242244
if (!new_block && accepted) {
243245
std::cerr << "duplicate" << std::endl;
244246
break;
@@ -291,7 +293,7 @@ int main(int argc, char* argv[])
291293
scheduler.stop();
292294
if (chainman.m_thread_load.joinable()) chainman.m_thread_load.join();
293295

294-
GetMainSignals().FlushBackgroundCallbacks();
296+
validation_signals.FlushBackgroundCallbacks();
295297
{
296298
LOCK(cs_main);
297299
for (Chainstate* chainstate : chainman.GetAll()) {
@@ -301,5 +303,5 @@ int main(int argc, char* argv[])
301303
}
302304
}
303305
}
304-
GetMainSignals().UnregisterBackgroundSignalScheduler();
306+
validation_signals.UnregisterBackgroundSignalScheduler();
305307
}

src/index/base.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ bool BaseIndex::Init()
8989
return &m_chain->context()->chainman->GetChainstateForIndexing());
9090
// Register to validation interface before setting the 'm_synced' flag, so that
9191
// callbacks are not missed once m_synced is true.
92-
RegisterValidationInterface(this);
92+
m_chain->context()->validation_signals->RegisterValidationInterface(this);
9393

9494
CBlockLocator locator;
9595
if (!GetDB().ReadBestBlock(locator)) {
@@ -380,7 +380,7 @@ bool BaseIndex::BlockUntilSyncedToCurrentChain() const
380380
}
381381

382382
LogPrintf("%s: %s is catching up on block notifications\n", __func__, GetName());
383-
SyncWithValidationInterfaceQueue();
383+
m_chain->context()->validation_signals->SyncWithValidationInterfaceQueue();
384384
return true;
385385
}
386386

@@ -399,7 +399,9 @@ bool BaseIndex::StartBackgroundSync()
399399

400400
void BaseIndex::Stop()
401401
{
402-
UnregisterValidationInterface(this);
402+
if (m_chain->context()->validation_signals) {
403+
m_chain->context()->validation_signals->UnregisterValidationInterface(this);
404+
}
403405

404406
if (m_thread_sync.joinable()) {
405407
m_thread_sync.join();

src/init.cpp

+21-13
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ void Shutdown(NodeContext& node)
291291

292292
// Because these depend on each-other, we make sure that neither can be
293293
// using the other before destroying them.
294-
if (node.peerman) UnregisterValidationInterface(node.peerman.get());
294+
if (node.peerman && node.validation_signals) node.validation_signals->UnregisterValidationInterface(node.peerman.get());
295295
if (node.connman) node.connman->Stop();
296296

297297
StopTorControl();
@@ -317,7 +317,9 @@ void Shutdown(NodeContext& node)
317317
// fee estimator from validation interface.
318318
if (node.fee_estimator) {
319319
node.fee_estimator->Flush();
320-
UnregisterValidationInterface(node.fee_estimator.get());
320+
if (node.validation_signals) {
321+
node.validation_signals->UnregisterValidationInterface(node.fee_estimator.get());
322+
}
321323
}
322324

323325
// FlushStateToDisk generates a ChainStateFlushed callback, which we should avoid missing
@@ -332,7 +334,7 @@ void Shutdown(NodeContext& node)
332334

333335
// After there are no more peers/RPC left to give us new data which may generate
334336
// CValidationInterface callbacks, flush them...
335-
GetMainSignals().FlushBackgroundCallbacks();
337+
if (node.validation_signals) node.validation_signals->FlushBackgroundCallbacks();
336338

337339
// Stop and delete all indexes only after flushing background callbacks.
338340
if (g_txindex) {
@@ -367,17 +369,20 @@ void Shutdown(NodeContext& node)
367369

368370
#if ENABLE_ZMQ
369371
if (g_zmq_notification_interface) {
370-
UnregisterValidationInterface(g_zmq_notification_interface.get());
372+
if (node.validation_signals) node.validation_signals->UnregisterValidationInterface(g_zmq_notification_interface.get());
371373
g_zmq_notification_interface.reset();
372374
}
373375
#endif
374376

375377
node.chain_clients.clear();
376-
UnregisterAllValidationInterfaces();
377-
GetMainSignals().UnregisterBackgroundSignalScheduler();
378+
if (node.validation_signals) {
379+
node.validation_signals->UnregisterAllValidationInterfaces();
380+
node.validation_signals->UnregisterBackgroundSignalScheduler();
381+
}
378382
node.mempool.reset();
379383
node.fee_estimator.reset();
380384
node.chainman.reset();
385+
node.validation_signals.reset();
381386
node.scheduler.reset();
382387
node.kernel.reset();
383388

@@ -1158,7 +1163,10 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
11581163
}
11591164
}, std::chrono::minutes{5});
11601165

1161-
GetMainSignals().RegisterBackgroundSignalScheduler(*node.scheduler);
1166+
assert(!node.validation_signals);
1167+
node.validation_signals = std::make_unique<CMainSignals>();
1168+
auto& validation_signals = *node.validation_signals;
1169+
validation_signals.RegisterBackgroundSignalScheduler(*node.scheduler);
11621170

11631171
// Create client interfaces for wallets that are supposed to be loaded
11641172
// according to -wallet and -disablewallet options. This only constructs
@@ -1264,7 +1272,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
12641272
// Flush estimates to disk periodically
12651273
CBlockPolicyEstimator* fee_estimator = node.fee_estimator.get();
12661274
node.scheduler->scheduleEvery([fee_estimator] { fee_estimator->FlushFeeEstimates(); }, FEE_FLUSH_INTERVAL);
1267-
RegisterValidationInterface(fee_estimator);
1275+
validation_signals.RegisterValidationInterface(fee_estimator);
12681276
}
12691277

12701278
// Check port numbers
@@ -1435,7 +1443,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14351443
});
14361444

14371445
if (g_zmq_notification_interface) {
1438-
RegisterValidationInterface(g_zmq_notification_interface.get());
1446+
validation_signals.RegisterValidationInterface(g_zmq_notification_interface.get());
14391447
}
14401448
#endif
14411449

@@ -1449,7 +1457,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14491457
.chainparams = chainparams,
14501458
.datadir = args.GetDataDirNet(),
14511459
.notifications = *node.notifications,
1452-
.signals = &GetMainSignals(),
1460+
.signals = &validation_signals,
14531461
};
14541462
Assert(ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
14551463

@@ -1479,7 +1487,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
14791487

14801488
CTxMemPool::Options mempool_opts{
14811489
.check_ratio = chainparams.DefaultConsistencyChecks() ? 1 : 0,
1482-
.signals = &GetMainSignals(),
1490+
.signals = &validation_signals,
14831491
};
14841492
auto result{ApplyArgsManOptions(args, chainparams, mempool_opts)};
14851493
if (!result) {
@@ -1507,7 +1515,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15071515

15081516
// Drain the validation interface queue to ensure that the old indexes
15091517
// don't have any pending work.
1510-
SyncWithValidationInterfaceQueue();
1518+
Assert(node.validation_signals)->SyncWithValidationInterfaceQueue();
15111519

15121520
for (auto* index : node.indexes) {
15131521
index->Interrupt();
@@ -1596,7 +1604,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
15961604
node.peerman = PeerManager::make(*node.connman, *node.addrman,
15971605
node.banman.get(), chainman,
15981606
*node.mempool, peerman_opts);
1599-
RegisterValidationInterface(node.peerman.get());
1607+
validation_signals.RegisterValidationInterface(node.peerman.get());
16001608

16011609
// ********************************************************* Step 8: start indexers
16021610

src/node/context.h

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class BanMan;
2020
class BaseIndex;
2121
class CBlockPolicyEstimator;
2222
class CConnman;
23+
class CMainSignals;
2324
class CScheduler;
2425
class CTxMemPool;
2526
class ChainstateManager;
@@ -70,7 +71,10 @@ struct NodeContext {
7071
interfaces::WalletLoader* wallet_loader{nullptr};
7172
std::unique_ptr<CScheduler> scheduler;
7273
std::function<void()> rpc_interruption_point = [] {};
74+
//! Issues blocking calls about sync status, errors and warnings
7375
std::unique_ptr<KernelNotifications> notifications;
76+
//! Issues calls about blocks and transactions
77+
std::unique_ptr<CMainSignals> validation_signals;
7478
std::atomic<int> exit_status{EXIT_SUCCESS};
7579

7680
//! Declare default constructor and destructor that are not inline, so code

src/node/interfaces.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -460,19 +460,20 @@ class NotificationsProxy : public CValidationInterface
460460
class NotificationsHandlerImpl : public Handler
461461
{
462462
public:
463-
explicit NotificationsHandlerImpl(std::shared_ptr<Chain::Notifications> notifications)
464-
: m_proxy(std::make_shared<NotificationsProxy>(std::move(notifications)))
463+
explicit NotificationsHandlerImpl(CMainSignals& signals, std::shared_ptr<Chain::Notifications> notifications)
464+
: m_signals{signals}, m_proxy{std::make_shared<NotificationsProxy>(std::move(notifications))}
465465
{
466-
RegisterSharedValidationInterface(m_proxy);
466+
m_signals.RegisterSharedValidationInterface(m_proxy);
467467
}
468468
~NotificationsHandlerImpl() override { disconnect(); }
469469
void disconnect() override
470470
{
471471
if (m_proxy) {
472-
UnregisterSharedValidationInterface(m_proxy);
472+
m_signals.UnregisterSharedValidationInterface(m_proxy);
473473
m_proxy.reset();
474474
}
475475
}
476+
CMainSignals& m_signals;
476477
std::shared_ptr<NotificationsProxy> m_proxy;
477478
};
478479

@@ -761,12 +762,12 @@ class ChainImpl : public Chain
761762
}
762763
std::unique_ptr<Handler> handleNotifications(std::shared_ptr<Notifications> notifications) override
763764
{
764-
return std::make_unique<NotificationsHandlerImpl>(std::move(notifications));
765+
return std::make_unique<NotificationsHandlerImpl>(validation_signals(), std::move(notifications));
765766
}
766767
void waitForNotificationsIfTipChanged(const uint256& old_tip) override
767768
{
768769
if (!old_tip.IsNull() && old_tip == WITH_LOCK(::cs_main, return chainman().ActiveChain().Tip()->GetBlockHash())) return;
769-
SyncWithValidationInterfaceQueue();
770+
validation_signals().SyncWithValidationInterfaceQueue();
770771
}
771772
std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
772773
{
@@ -822,6 +823,7 @@ class ChainImpl : public Chain
822823
NodeContext* context() override { return &m_node; }
823824
ArgsManager& args() { return *Assert(m_node.args); }
824825
ChainstateManager& chainman() { return *Assert(m_node.chainman); }
826+
CMainSignals& validation_signals() { return *Assert(m_node.validation_signals); }
825827
NodeContext& m_node;
826828
};
827829
} // namespace

src/node/transaction.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
9292
node.mempool->AddUnbroadcastTx(txid);
9393
}
9494

95-
if (wait_callback) {
95+
if (wait_callback && node.validation_signals) {
9696
// For transactions broadcast from outside the wallet, make sure
9797
// that the wallet has been notified of the transaction before
9898
// continuing.
@@ -101,7 +101,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
101101
// with a transaction to/from their wallet, immediately call some
102102
// wallet RPC, and get a stale result because callbacks have not
103103
// yet been processed.
104-
CallFunctionInValidationInterfaceQueue([&promise] {
104+
node.validation_signals->CallFunctionInValidationInterfaceQueue([&promise] {
105105
promise.set_value();
106106
});
107107
callback_set = true;

src/rpc/blockchain.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -395,7 +395,8 @@ static RPCHelpMan syncwithvalidationinterfacequeue()
395395
},
396396
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
397397
{
398-
SyncWithValidationInterfaceQueue();
398+
NodeContext& node = EnsureAnyNodeContext(request.context);
399+
CHECK_NONFATAL(node.validation_signals)->SyncWithValidationInterfaceQueue();
399400
return UniValue::VNULL;
400401
},
401402
};

src/rpc/fees.cpp

+4-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

66
#include <core_io.h>
7+
#include <node/context.h>
78
#include <policy/feerate.h>
89
#include <policy/fees.h>
910
#include <rpc/protocol.h>
@@ -21,10 +22,6 @@
2122
#include <cmath>
2223
#include <string>
2324

24-
namespace node {
25-
struct NodeContext;
26-
}
27-
2825
using node::NodeContext;
2926

3027
static RPCHelpMan estimatesmartfee()
@@ -68,7 +65,7 @@ static RPCHelpMan estimatesmartfee()
6865
const NodeContext& node = EnsureAnyNodeContext(request.context);
6966
const CTxMemPool& mempool = EnsureMemPool(node);
7067

71-
SyncWithValidationInterfaceQueue();
68+
CHECK_NONFATAL(mempool.m_signals)->SyncWithValidationInterfaceQueue();
7269
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
7370
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
7471
bool conservative = true;
@@ -156,8 +153,9 @@ static RPCHelpMan estimaterawfee()
156153
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
157154
{
158155
CBlockPolicyEstimator& fee_estimator = EnsureAnyFeeEstimator(request.context);
156+
const NodeContext& node = EnsureAnyNodeContext(request.context);
159157

160-
SyncWithValidationInterfaceQueue();
158+
CHECK_NONFATAL(node.validation_signals)->SyncWithValidationInterfaceQueue();
161159
unsigned int max_target = fee_estimator.HighestTargetTracked(FeeEstimateHorizon::LONG_HALFLIFE);
162160
unsigned int conf_target = ParseConfirmTarget(request.params[0], max_target);
163161
double threshold = 0.95;

src/rpc/mining.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1038,9 +1038,9 @@ static RPCHelpMan submitblock()
10381038

10391039
bool new_block;
10401040
auto sc = std::make_shared<submitblock_StateCatcher>(block.GetHash());
1041-
RegisterSharedValidationInterface(sc);
1041+
CHECK_NONFATAL(chainman.m_options.signals)->RegisterSharedValidationInterface(sc);
10421042
bool accepted = chainman.ProcessNewBlock(blockptr, /*force_processing=*/true, /*min_pow_checked=*/true, /*new_block=*/&new_block);
1043-
UnregisterSharedValidationInterface(sc);
1043+
CHECK_NONFATAL(chainman.m_options.signals)->UnregisterSharedValidationInterface(sc);
10441044
if (!new_block && accepted) {
10451045
return "duplicate";
10461046
}

src/rpc/node.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static RPCHelpMan mockscheduler()
9090

9191
const NodeContext& node_context{EnsureAnyNodeContext(request.context)};
9292
CHECK_NONFATAL(node_context.scheduler)->MockForward(std::chrono::seconds{delta_seconds});
93-
SyncWithValidationInterfaceQueue();
93+
CHECK_NONFATAL(node_context.validation_signals)->SyncWithValidationInterfaceQueue();
9494
for (const auto& chain_client : node_context.chain_clients) {
9595
chain_client->schedulerMockForward(std::chrono::seconds(delta_seconds));
9696
}

src/test/coinstatsindex_tests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ BOOST_FIXTURE_TEST_CASE(coinstatsindex_initial_sync, TestChain100Setup)
7070
// SyncWithValidationInterfaceQueue() call below is also needed to ensure
7171
// TSAN always sees the test thread waiting for the notification thread, and
7272
// avoid potential false positive reports.
73-
SyncWithValidationInterfaceQueue();
73+
m_node.validation_signals->SyncWithValidationInterfaceQueue();
7474

7575
// Shutdown sequence (c.f. Shutdown() in init.cpp)
7676
coin_stats_index.Stop();

0 commit comments

Comments
 (0)