Skip to content

Commit 703b1e6

Browse files
committed
Close minor startup race between main and scheduler threads
Don't schedule class PeerManagerImpl's background tasks from its constructor, but instead do that from a separate method, StartScheduledTasks(), that can be called later at the end of startup, after other things, such as the active chain, are initialzed.
1 parent 4b1fb50 commit 703b1e6

File tree

5 files changed

+21
-11
lines changed

5 files changed

+21
-11
lines changed

src/init.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
11801180

11811181
assert(!node.peerman);
11821182
node.peerman = PeerManager::make(chainparams, *node.connman, *node.addrman, node.banman.get(),
1183-
*node.scheduler, chainman, *node.mempool, ignores_incoming_txs);
1183+
chainman, *node.mempool, ignores_incoming_txs);
11841184
RegisterValidationInterface(node.peerman.get());
11851185

11861186
// sanitize comments per BIP-0014, format user agent and check total size
@@ -1789,6 +1789,8 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17891789
banman->DumpBanlist();
17901790
}, DUMP_BANS_INTERVAL);
17911791

1792+
if (node.peerman) node.peerman->StartScheduledTasks(*node.scheduler);
1793+
17921794
#if HAVE_SYSTEM
17931795
StartupNotify(args);
17941796
#endif

src/net_processing.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ class PeerManagerImpl final : public PeerManager
271271
{
272272
public:
273273
PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman,
274-
BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman,
274+
BanMan* banman, ChainstateManager& chainman,
275275
CTxMemPool& pool, bool ignore_incoming_txs);
276276

277277
/** Overridden from CValidationInterface. */
@@ -288,6 +288,7 @@ class PeerManagerImpl final : public PeerManager
288288
bool SendMessages(CNode* pto) override EXCLUSIVE_LOCKS_REQUIRED(pto->cs_sendProcessing);
289289

290290
/** Implement PeerManager */
291+
void StartScheduledTasks(CScheduler& scheduler) override;
291292
void CheckForStaleTipAndEvictPeers() override;
292293
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const override;
293294
bool IgnoresIncomingTxs() override { return m_ignore_incoming_txs; }
@@ -1396,14 +1397,14 @@ bool PeerManagerImpl::BlockRequestAllowed(const CBlockIndex* pindex)
13961397
}
13971398

13981399
std::unique_ptr<PeerManager> PeerManager::make(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman,
1399-
BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman,
1400+
BanMan* banman, ChainstateManager& chainman,
14001401
CTxMemPool& pool, bool ignore_incoming_txs)
14011402
{
1402-
return std::make_unique<PeerManagerImpl>(chainparams, connman, addrman, banman, scheduler, chainman, pool, ignore_incoming_txs);
1403+
return std::make_unique<PeerManagerImpl>(chainparams, connman, addrman, banman, chainman, pool, ignore_incoming_txs);
14031404
}
14041405

14051406
PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman,
1406-
BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman,
1407+
BanMan* banman, ChainstateManager& chainman,
14071408
CTxMemPool& pool, bool ignore_incoming_txs)
14081409
: m_chainparams(chainparams),
14091410
m_connman(connman),
@@ -1412,6 +1413,10 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
14121413
m_chainman(chainman),
14131414
m_mempool(pool),
14141415
m_ignore_incoming_txs(ignore_incoming_txs)
1416+
{
1417+
}
1418+
1419+
void PeerManagerImpl::StartScheduledTasks(CScheduler& scheduler)
14151420
{
14161421
// Stale tip checking and peer eviction are on two different timers, but we
14171422
// don't want them to get out of sync due to drift in the scheduler, so we

src/net_processing.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,13 @@ class PeerManager : public CValidationInterface, public NetEventsInterface
3737
{
3838
public:
3939
static std::unique_ptr<PeerManager> make(const CChainParams& chainparams, CConnman& connman, CAddrMan& addrman,
40-
BanMan* banman, CScheduler& scheduler, ChainstateManager& chainman,
40+
BanMan* banman, ChainstateManager& chainman,
4141
CTxMemPool& pool, bool ignore_incoming_txs);
4242
virtual ~PeerManager() { }
4343

44+
/** Begin running background tasks, should only be called once */
45+
virtual void StartScheduledTasks(CScheduler& scheduler) = 0;
46+
4447
/** Get statistics from node state */
4548
virtual bool GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) const = 0;
4649

src/test/denialofservice_tests.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(outbound_slow_chain_eviction)
5353
const CChainParams& chainparams = Params();
5454
auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
5555
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr,
56-
*m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
56+
*m_node.chainman, *m_node.mempool, false);
5757

5858
// Mock an outbound peer
5959
CAddress addr1(ip(0xa0b0c001), NODE_NONE);
@@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(stale_tip_peer_management)
121121
const CChainParams& chainparams = Params();
122122
auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman);
123123
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, nullptr,
124-
*m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
124+
*m_node.chainman, *m_node.mempool, false);
125125

126126
constexpr int max_outbound_full_relay = MAX_OUTBOUND_FULL_RELAY_CONNECTIONS;
127127
CConnman::Options options;
@@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(peer_discouragement)
194194
auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
195195
auto connman = std::make_unique<ConnmanTestMsg>(0x1337, 0x1337, *m_node.addrman);
196196
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(),
197-
*m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
197+
*m_node.chainman, *m_node.mempool, false);
198198

199199
CNetAddr tor_netaddr;
200200
BOOST_REQUIRE(
@@ -288,7 +288,7 @@ BOOST_AUTO_TEST_CASE(DoS_bantime)
288288
auto banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
289289
auto connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman);
290290
auto peerLogic = PeerManager::make(chainparams, *connman, *m_node.addrman, banman.get(),
291-
*m_node.scheduler, *m_node.chainman, *m_node.mempool, false);
291+
*m_node.chainman, *m_node.mempool, false);
292292

293293
banman->ClearBanned();
294294
int64_t nStartTime = GetTime();

src/test/util/setup_common.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ TestingSetup::TestingSetup(const std::string& chainName, const std::vector<const
197197
m_node.banman = std::make_unique<BanMan>(m_args.GetDataDirBase() / "banlist", nullptr, DEFAULT_MISBEHAVING_BANTIME);
198198
m_node.connman = std::make_unique<CConnman>(0x1337, 0x1337, *m_node.addrman); // Deterministic randomness for tests.
199199
m_node.peerman = PeerManager::make(chainparams, *m_node.connman, *m_node.addrman,
200-
m_node.banman.get(), *m_node.scheduler, *m_node.chainman,
200+
m_node.banman.get(), *m_node.chainman,
201201
*m_node.mempool, false);
202202
{
203203
CConnman::Options options;

0 commit comments

Comments
 (0)