@@ -397,7 +397,8 @@ class PeerManagerImpl final : public PeerManager
397
397
/* * The height of the best chain */
398
398
std::atomic<int > m_best_height{-1 };
399
399
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 };
401
402
402
403
/* * Whether this node is running in blocks only mode */
403
404
const bool m_ignore_incoming_txs;
@@ -470,16 +471,26 @@ class PeerManagerImpl final : public PeerManager
470
471
*
471
472
* Memory used: 1.3 MB
472
473
*/
473
- std::unique_ptr< CRollingBloomFilter> recentRejects GUARDED_BY (cs_main);
474
+ CRollingBloomFilter m_recent_rejects GUARDED_BY (:: cs_main){ 120'000 , 0.000'001 } ;
474
475
uint256 hashRecentRejectsChainTip GUARDED_BY (cs_main);
475
476
476
477
/*
477
478
* Filter for transactions that have been recently confirmed.
478
479
* We use this to avoid requesting transactions that have already been
479
480
* 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).
480
491
*/
481
492
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 } ;
483
494
484
495
/* * Have we requested this block from a peer */
485
496
bool IsBlockRequested (const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@@ -1195,6 +1206,7 @@ void PeerManagerImpl::FinalizeNode(const CNode& node)
1195
1206
assert (m_outbound_peers_with_protect_from_disconnect == 0 );
1196
1207
assert (m_wtxid_relay_peers == 0 );
1197
1208
assert (m_txrequest.Size () == 0 );
1209
+ assert (m_orphanage.Size () == 0 );
1198
1210
}
1199
1211
} // cs_main
1200
1212
if (node.fSuccessfullyConnected && misbehavior == 0 &&
@@ -1399,23 +1411,8 @@ PeerManagerImpl::PeerManagerImpl(const CChainParams& chainparams, CConnman& conn
1399
1411
m_banman(banman),
1400
1412
m_chainman(chainman),
1401
1413
m_mempool(pool),
1402
- m_stale_tip_check_time(0 ),
1403
1414
m_ignore_incoming_txs(ignore_incoming_txs)
1404
1415
{
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
-
1419
1416
// Stale tip checking and peer eviction are on two different timers, but we
1420
1417
// don't want them to get out of sync due to drift in the scheduler, so we
1421
1418
// 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
1441
1438
{
1442
1439
LOCK (m_recent_confirmed_transactions_mutex);
1443
1440
for (const auto & ptx : pblock->vtx ) {
1444
- m_recent_confirmed_transactions-> insert (ptx->GetHash ());
1441
+ m_recent_confirmed_transactions. insert (ptx->GetHash ());
1445
1442
if (ptx->GetHash () != ptx->GetWitnessHash ()) {
1446
- m_recent_confirmed_transactions-> insert (ptx->GetWitnessHash ());
1443
+ m_recent_confirmed_transactions. insert (ptx->GetWitnessHash ());
1447
1444
}
1448
1445
}
1449
1446
}
@@ -1467,7 +1464,7 @@ void PeerManagerImpl::BlockDisconnected(const std::shared_ptr<const CBlock> &blo
1467
1464
// presumably the most common case of relaying a confirmed transaction
1468
1465
// should be just after a new block containing it is found.
1469
1466
LOCK (m_recent_confirmed_transactions_mutex);
1470
- m_recent_confirmed_transactions-> reset ();
1467
+ m_recent_confirmed_transactions. reset ();
1471
1468
}
1472
1469
1473
1470
// 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
1607
1604
1608
1605
bool PeerManagerImpl::AlreadyHaveTx (const GenTxid& gtxid)
1609
1606
{
1610
- assert (recentRejects);
1611
1607
if (m_chainman.ActiveChain ().Tip ()->GetBlockHash () != hashRecentRejectsChainTip) {
1612
1608
// If the chain tip has changed previously rejected transactions
1613
1609
// might be now valid, e.g. due to a nLockTime'd tx becoming valid,
1614
1610
// or a double-spend. Reset the rejects filter and give those
1615
1611
// txs a second chance.
1616
1612
hashRecentRejectsChainTip = m_chainman.ActiveChain ().Tip ()->GetBlockHash ();
1617
- recentRejects-> reset ();
1613
+ m_recent_rejects. reset ();
1618
1614
}
1619
1615
1620
1616
const uint256& hash = gtxid.GetHash ();
@@ -1623,10 +1619,10 @@ bool PeerManagerImpl::AlreadyHaveTx(const GenTxid& gtxid)
1623
1619
1624
1620
{
1625
1621
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 ;
1627
1623
}
1628
1624
1629
- return recentRejects-> contains (hash) || m_mempool.exists (gtxid);
1625
+ return m_recent_rejects. contains (hash) || m_mempool.exists (gtxid);
1630
1626
}
1631
1627
1632
1628
bool PeerManagerImpl::AlreadyHaveBlock (const uint256& block_hash)
@@ -2245,8 +2241,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
2245
2241
// See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
2246
2242
// for concerns around weakening security of unupgraded nodes
2247
2243
// if we start doing this too early.
2248
- assert (recentRejects);
2249
- recentRejects->insert (porphanTx->GetWitnessHash ());
2244
+ m_recent_rejects.insert (porphanTx->GetWitnessHash ());
2250
2245
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
2251
2246
// then we know that the witness was irrelevant to the policy
2252
2247
// failure, since this check depends only on the txid
@@ -2258,7 +2253,7 @@ void PeerManagerImpl::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
2258
2253
if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->GetWitnessHash () != porphanTx->GetHash ()) {
2259
2254
// We only add the txid if it differs from the wtxid, to
2260
2255
// avoid wasting entries in the rolling bloom filter.
2261
- recentRejects-> insert (porphanTx->GetHash ());
2256
+ m_recent_rejects. insert (porphanTx->GetHash ());
2262
2257
}
2263
2258
}
2264
2259
m_orphanage.EraseTx (orphanHash);
@@ -3259,7 +3254,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3259
3254
std::sort (unique_parents.begin (), unique_parents.end ());
3260
3255
unique_parents.erase (std::unique (unique_parents.begin (), unique_parents.end ()), unique_parents.end ());
3261
3256
for (const uint256& parent_txid : unique_parents) {
3262
- if (recentRejects-> contains (parent_txid)) {
3257
+ if (m_recent_rejects. contains (parent_txid)) {
3263
3258
fRejectedParents = true ;
3264
3259
break ;
3265
3260
}
@@ -3300,8 +3295,8 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3300
3295
// regardless of what witness is provided, we will not accept
3301
3296
// this, so we don't need to allow for redownload of this txid
3302
3297
// 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 ());
3305
3300
m_txrequest.ForgetTxHash (tx.GetHash ());
3306
3301
m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3307
3302
}
@@ -3320,8 +3315,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3320
3315
// See also comments in https://github.com/bitcoin/bitcoin/pull/18044#discussion_r443419034
3321
3316
// for concerns around weakening security of unupgraded nodes
3322
3317
// if we start doing this too early.
3323
- assert (recentRejects);
3324
- recentRejects->insert (tx.GetWitnessHash ());
3318
+ m_recent_rejects.insert (tx.GetWitnessHash ());
3325
3319
m_txrequest.ForgetTxHash (tx.GetWitnessHash ());
3326
3320
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
3327
3321
// 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,
3332
3326
// transactions are later received (resulting in
3333
3327
// parent-fetching by txid via the orphan-handling logic).
3334
3328
if (state.GetResult () == TxValidationResult::TX_INPUTS_NOT_STANDARD && tx.GetWitnessHash () != tx.GetHash ()) {
3335
- recentRejects-> insert (tx.GetHash ());
3329
+ m_recent_rejects. insert (tx.GetHash ());
3336
3330
m_txrequest.ForgetTxHash (tx.GetHash ());
3337
3331
}
3338
3332
if (RecursiveDynamicUsage (*ptx) < 100000 ) {
@@ -3341,21 +3335,21 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
3341
3335
}
3342
3336
}
3343
3337
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
3345
3339
// this point and the tx will have been ignored. Because we haven't run
3346
3340
// the tx through AcceptToMemoryPool, we won't have computed a DoS
3347
3341
// score for it or determined exactly why we consider it invalid.
3348
3342
//
3349
3343
// This means we won't penalize any peer subsequently relaying a DoSy
3350
3344
// 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
3352
3346
// other words, we shouldn't penalize a peer if we aren't *sure* they
3353
3347
// submitted a DoSy tx.
3354
3348
//
3355
- // Note that recentRejects doesn't just record DoSy or invalid
3349
+ // Note that m_recent_rejects doesn't just record DoSy or invalid
3356
3350
// transactions, but any tx not accepted by the mempool, which may be
3357
3351
// 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,
3359
3353
// regardless of false positives.
3360
3354
3361
3355
if (state.IsInvalid ()) {
0 commit comments