@@ -397,7 +397,8 @@ class PeerManagerImpl final : public PeerManager
397397 /* * The height of the best chain */
398398 std::atomic<int > m_best_height{-1 };
399399
400- int64_t m_stale_tip_check_time; // !< Next time to check for stale tip
400+ /* * Next time to check for stale tip */
401+ int64_t m_stale_tip_check_time{0 };
401402
402403 /* * Whether this node is running in blocks only mode */
403404 const bool m_ignore_incoming_txs;
@@ -470,16 +471,26 @@ class PeerManagerImpl final : public PeerManager
470471 *
471472 * Memory used: 1.3 MB
472473 */
473- std::unique_ptr< CRollingBloomFilter> recentRejects GUARDED_BY (cs_main);
474+ CRollingBloomFilter m_recent_rejects GUARDED_BY (:: cs_main){ 120'000 , 0.000'001 } ;
474475 uint256 hashRecentRejectsChainTip GUARDED_BY (cs_main);
475476
476477 /*
477478 * Filter for transactions that have been recently confirmed.
478479 * We use this to avoid requesting transactions that have already been
479480 * confirnmed.
481+ *
482+ * Blocks don't typically have more than 4000 transactions, so this should
483+ * be at least six blocks (~1 hr) worth of transactions that we can store,
484+ * inserting both a txid and wtxid for every observed transaction.
485+ * If the number of transactions appearing in a block goes up, or if we are
486+ * seeing getdata requests more than an hour after initial announcement, we
487+ * can increase this number.
488+ * The false positive rate of 1/1M should come out to less than 1
489+ * transaction per day that would be inadvertently ignored (which is the
490+ * same probability that we have in the reject filter).
480491 */
481492 Mutex m_recent_confirmed_transactions_mutex;
482- std::unique_ptr< CRollingBloomFilter> m_recent_confirmed_transactions GUARDED_BY (m_recent_confirmed_transactions_mutex);
493+ CRollingBloomFilter m_recent_confirmed_transactions GUARDED_BY (m_recent_confirmed_transactions_mutex){ 48'000 , 0.000'001 } ;
483494
484495 /* * Have we requested this block from a peer */
485496 bool IsBlockRequested (const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@@ -1195,6 +1206,7 @@ void PeerManagerImpl::FinalizeNode(const CNode& node)
11951206 assert (m_outbound_peers_with_protect_from_disconnect == 0 );
11961207 assert (m_wtxid_relay_peers == 0 );
11971208 assert (m_txrequest.Size () == 0 );
1209+ assert (m_orphanage.Size () == 0 );
11981210 }
11991211 } // cs_main
12001212 if (node.fSuccessfullyConnected && misbehavior == 0 &&
@@ -1399,23 +1411,8 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
13991411 m_banman(banman),
14001412 m_chainman(chainman),
14011413 m_mempool(pool),
1402- m_stale_tip_check_time(0 ),
14031414 m_ignore_incoming_txs(ignore_incoming_txs)
14041415{
1405- // Initialize global variables that cannot be constructed at startup.
1406- recentRejects.reset (new CRollingBloomFilter (120000 , 0.000001 ));
1407-
1408- // Blocks don't typically have more than 4000 transactions, so this should
1409- // be at least six blocks (~1 hr) worth of transactions that we can store,
1410- // inserting both a txid and wtxid for every observed transaction.
1411- // If the number of transactions appearing in a block goes up, or if we are
1412- // seeing getdata requests more than an hour after initial announcement, we
1413- // can increase this number.
1414- // The false positive rate of 1/1M should come out to less than 1
1415- // transaction per day that would be inadvertently ignored (which is the
1416- // same probability that we have in the reject filter).
1417- m_recent_confirmed_transactions.reset (new CRollingBloomFilter (48000 , 0.000001 ));
1418-
14191416 // Stale tip checking and peer eviction are on two different timers, but we
14201417 // don't want them to get out of sync due to drift in the scheduler, so we
14211418 // combine them in one function and schedule at the quicker (peer-eviction)
@@ -1441,9 +1438,9 @@ void PeerManagerImpl::BlockConnected(const std::shared_ptr<const CBlock>& pblock
14411438 {
14421439 LOCK (m_recent_confirmed_transactions_mutex);
14431440 for (const auto & ptx : pblock->vtx ) {
1444- m_recent_confirmed_transactions-> insert (ptx->GetHash ());
1441+ m_recent_confirmed_transactions. insert (ptx->GetHash ());
14451442 if (ptx->GetHash () != ptx->GetWitnessHash ()) {
1446- m_recent_confirmed_transactions-> insert (ptx->GetWitnessHash ());
1443+ m_recent_confirmed_transactions. insert (ptx->GetWitnessHash ());
14471444 }
14481445 }
14491446 }
@@ -1467,7 +1464,7 @@ void PeerManagerImpl::BlockDisconnected(const std::shared_ptr<const CBlock> &blo
14671464 // presumably the most common case of relaying a confirmed transaction
14681465 // should be just after a new block containing it is found.
14691466 LOCK (m_recent_confirmed_transactions_mutex);
1470- m_recent_confirmed_transactions-> reset ();
1467+ m_recent_confirmed_transactions. reset ();
14711468}
14721469
14731470// All of the following cache a recent block, and are protected by cs_most_recent_block
@@ -1607,14 +1604,13 @@ void PeerManagerImpl::BlockChecked(const CBlock& block, const BlockValidationSta
16071604
16081605bool PeerManagerImpl::AlreadyHaveTx (const GenTxid& gtxid)
16091606{
1610- assert (recentRejects);
16111607 if (m_chainman.ActiveChain ().Tip ()->GetBlockHash () != hashRecentRejectsChainTip) {
16121608 // If the chain tip has changed previously rejected transactions
16131609 // might be now valid, e.g. due to a nLockTime'd tx becoming valid,
16141610 // or a double-spend. Reset the rejects filter and give those
16151611 // txs a second chance.
16161612 hashRecentRejectsChainTip = m_chainman.ActiveChain ().Tip ()->GetBlockHash ();
1617- recentRejects-> reset ();
1613+ m_recent_rejects. reset ();
16181614 }
16191615
16201616 const uint256& hash = gtxid.GetHash ();
@@ -1623,10 +1619,10 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
16231619
16241620 {
16251621 LOCK (m_recent_confirmed_transactions_mutex);
1626- if (m_recent_confirmed_transactions-> contains (hash)) return true ;
1622+ if (m_recent_confirmed_transactions. contains (hash)) return true ;
16271623 }
16281624
1629- return recentRejects-> contains (hash) || m_mempool.exists (gtxid);
1625+ return m_recent_rejects. contains (hash) || m_mempool.exists (gtxid);
16301626}
16311627
16321628bool PeerManagerImpl::AlreadyHaveBlock (const uint256& block_hash)
@@ -2245,8 +2241,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
22452241 // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
22462242 // for concerns around weakening security of unupgraded nodes
22472243 // if we start doing this too early.
2248- assert (recentRejects);
2249- recentRejects->insert (porphanTx->GetWitnessHash ());
2244+ m_recent_rejects.insert (porphanTx->GetWitnessHash ());
22502245 // If the transaction failed for TX_INPUTS_NOT_STANDARD,
22512246 // then we know that the witness was irrelevant to the policy
22522247 // failure, since this check depends only on the txid
@@ -2258,7 +2253,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
22582253 if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->GetWitnessHash () != porphanTx->GetHash ()) {
22592254 // We only add the txid if it differs from the wtxid, to
22602255 // avoid wasting entries in the rolling bloom filter.
2261- recentRejects-> insert (porphanTx->GetHash ());
2256+ m_recent_rejects. insert (porphanTx->GetHash ());
22622257 }
22632258 }
22642259 m_orphanage.EraseTx (orphanHash);
@@ -3259,7 +3254,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
32593254 std::sort (unique_parents.begin (), unique_parents.end ());
32603255 unique_parents.erase (std::unique (unique_parents.begin (), unique_parents.end ()), unique_parents.end ());
32613256 for (const uint256& parent_txid : unique_parents) {
3262- if (recentRejects-> contains (parent_txid)) {
3257+ if (m_recent_rejects. contains (parent_txid)) {
32633258 fRejectedParents = true ;
32643259 break ;
32653260 }
@@ -3300,8 +3295,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
33003295 // regardless of what witness is provided, we will not accept
33013296 // this, so we don't need to allow for redownload of this txid
33023297 // from any of our non-wtxidrelay peers.
3303- recentRejects-> insert (tx.GetHash ());
3304- recentRejects-> insert (tx.GetWitnessHash ());
3298+ m_recent_rejects. insert (tx.GetHash ());
3299+ m_recent_rejects. insert (tx.GetWitnessHash ());
33053300 m_txrequest.ForgetTxHash (tx.GetHash ());
33063301 m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
33073302 }
@@ -3320,8 +3315,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
33203315 // See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
33213316 // for concerns around weakening security of unupgraded nodes
33223317 // if we start doing this too early.
3323- assert (recentRejects);
3324- recentRejects->insert (tx.GetWitnessHash ());
3318+ m_recent_rejects.insert (tx.GetWitnessHash ());
33253319 m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
33263320 // If the transaction failed for TX_INPUTS_NOT_STANDARD,
33273321 // then we know that the witness was irrelevant to the policy
@@ -3332,7 +3326,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
33323326 // transactions are later received (resulting in
33333327 // parent-fetching by txid via the orphan-handling logic).
33343328 if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash () != tx.GetHash ()) {
3335- recentRejects-> insert (tx.GetHash ());
3329+ m_recent_rejects. insert (tx.GetHash ());
33363330 m_txrequest.ForgetTxHash (tx.GetHash ());
33373331 }
33383332 if (RecursiveDynamicUsage (*ptx) < 100000 ) {
@@ -3341,21 +3335,21 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
33413335 }
33423336 }
33433337
3344- // If a tx has been detected by recentRejects , we will have reached
3338+ // If a tx has been detected by m_recent_rejects , we will have reached
33453339 // this point and the tx will have been ignored. Because we haven't run
33463340 // the tx through AcceptToMemoryPool, we won't have computed a DoS
33473341 // score for it or determined exactly why we consider it invalid.
33483342 //
33493343 // This means we won't penalize any peer subsequently relaying a DoSy
33503344 // tx (even if we penalized the first peer who gave it to us) because
3351- // we have to account for recentRejects showing false positives. In
3345+ // we have to account for m_recent_rejects showing false positives. In
33523346 // other words, we shouldn't penalize a peer if we aren't *sure* they
33533347 // submitted a DoSy tx.
33543348 //
3355- // Note that recentRejects doesn't just record DoSy or invalid
3349+ // Note that m_recent_rejects doesn't just record DoSy or invalid
33563350 // transactions, but any tx not accepted by the mempool, which may be
33573351 // due to node policy (vs. consensus). So we can't blanket penalize a
3358- // peer simply for relaying a tx that our recentRejects has caught,
3352+ // peer simply for relaying a tx that our m_recent_rejects has caught,
33593353 // regardless of false positives.
33603354
33613355 if (state.IsInvalid ()) {
0 commit comments