Skip to content

Commit 67b9416

Browse files
author
MarcoFalke
committed
Merge bitcoin/bitcoin#21562: [net processing] Various tidying up of PeerManagerImpl ctor
fde1bf4 [net processing] Default initialize m_recent_confirmed_transactions (John Newbery) 37dcd12 scripted-diff: Rename recentRejects (John Newbery) cd9902a [net processing] Default initialize recentRejects (John Newbery) a28bfd1 [net processing] Default initialize m_stale_tip_check_time (John Newbery) 9190b01 [net processing] Add Orphanage empty consistency check (John Newbery) Pull request description: - Use default initialization of PeerManagerImpl members where possible - Remove unique_ptr indirection where it's not needed ACKs for top commit: MarcoFalke: ACK fde1bf4 👞 theStack: re-ACK fde1bf4 Tree-SHA512: 7ddedcc972df8e933e1fbe5c88b8ea17df89e1e58fc769518512c5540e49dc8eddb3f47e78d1329a6fc5644d2c1d11c981f681fd633f5218bfa4b3e6a86f3d7b
2 parents 31fef69 + fde1bf4 commit 67b9416

File tree

4 files changed

+41
-40
lines changed

4 files changed

+41
-40
lines changed

src/net_processing.cpp

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -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

16081605
bool 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

16321628
bool 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()) {

src/txorphanage.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ class TxOrphanage {
4747
* (ie orphans that may have found their final missing parent, and so should be reconsidered for the mempool) */
4848
void AddChildrenToWorkSet(const CTransaction& tx, std::set<uint256>& orphan_work_set) const EXCLUSIVE_LOCKS_REQUIRED(g_cs_orphans);
4949

50+
/** Return how many entries exist in the orphange */
51+
size_t Size() LOCKS_EXCLUDED(::g_cs_orphans)
52+
{
53+
LOCK(::g_cs_orphans);
54+
return m_orphans.size();
55+
}
56+
5057
protected:
5158
struct OrphanTx {
5259
CTransactionRef tx;

test/functional/mempool_reorg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def run_test(self):
8080
self.log.info("Generate a block")
8181
last_block = self.nodes[0].generate(1)
8282
# Sync blocks, so that peer 1 gets the block before timelock_tx
83-
# Otherwise, peer 1 would put the timelock_tx in recentRejects
83+
# Otherwise, peer 1 would put the timelock_tx in m_recent_rejects
8484
self.sync_all()
8585

8686
self.log.info("The time-locked transaction can now be spent")

test/functional/p2p_permissions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ def check_tx_relay(self):
130130
tx.vout[0].nValue += 1
131131
txid = tx.rehash()
132132
# Send the transaction twice. The first time, it'll be rejected by ATMP because it conflicts
133-
# with a mempool transaction. The second time, it'll be in the recentRejects filter.
133+
# with a mempool transaction. The second time, it'll be in the m_recent_rejects filter.
134134
p2p_rebroadcast_wallet.send_txs_and_test(
135135
[tx],
136136
self.nodes[1],

0 commit comments

Comments
 (0)