Skip to content

Commit 7b7cb70

Browse files
author
MarcoFalke
committed
Merge bitcoin#19498: Tidy up ProcessOrphanTx
001343f ProcessOrphanTx: Move AddToCompactExtraTransactions call into ProcessOrphanTx (John Newbery) 4fce726 ProcessOrphanTx: Remove aliases (John Newbery) e07c5d9 ProcessOrphanTx: Remove outdated commented (John Newbery) 4763b51 ProcessOrphanTx: remove useless setMisbehaving set (John Newbery) 55c79a9 ProcessOrphanTx: remove useless done variable (John Newbery) 6e8dd99 [net processing] Add doxygen comments for orphan data and function (John Newbery) Pull request description: Originally a follow-up to bitcoin#19364, this simplifies the logic in ProcessOrphanTx() and removes unused variables. ACKs for top commit: troygiorshev: ACK 001343f sipa: utACK 001343f MarcoFalke: ACK 001343f 🌮 Tree-SHA512: be558457f2e08ebb6bddcd49bdd75bd410c3650da44a76c688fc9f07822f94d5a1af93fa1342678052b2c8163cdb9745c352c7884325ab0a41fa593c3eb89116
2 parents 301959f + 001343f commit 7b7cb70

File tree

2 files changed

+55
-43
lines changed

2 files changed

+55
-43
lines changed

src/net_processing.cpp

+54-41
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,14 @@ struct COrphanTx {
153153
int64_t nTimeExpire;
154154
size_t list_pos;
155155
};
156+
157+
/** Guards orphan transactions and extra txs for compact blocks */
156158
RecursiveMutex g_cs_orphans;
159+
/** Map from txid to orphan transaction record. Limited by
160+
* -maxorphantx/DEFAULT_MAX_ORPHAN_TRANSACTIONS */
157161
std::map<uint256, COrphanTx> mapOrphanTransactions GUARDED_BY(g_cs_orphans);
162+
/** Index from wtxid into the mapOrphanTransactions to lookup orphan
163+
* transactions using their witness ids. */
158164
std::map<uint256, std::map<uint256, COrphanTx>::iterator> g_orphans_by_wtxid GUARDED_BY(g_cs_orphans);
159165

160166
void EraseOrphansFor(NodeId peer);
@@ -258,12 +264,19 @@ namespace {
258264
return &(*a) < &(*b);
259265
}
260266
};
261-
std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans);
262267

263-
std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list GUARDED_BY(g_cs_orphans); //! For random eviction
268+
/** Index from the parents' COutPoint into the mapOrphanTransactions. Used
269+
* to remove orphan transactions from the mapOrphanTransactions */
270+
std::map<COutPoint, std::set<std::map<uint256, COrphanTx>::iterator, IteratorComparator>> mapOrphanTransactionsByPrev GUARDED_BY(g_cs_orphans);
271+
/** Orphan transactions in vector for quick random eviction */
272+
std::vector<std::map<uint256, COrphanTx>::iterator> g_orphan_list GUARDED_BY(g_cs_orphans);
264273

265-
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
274+
/** Orphan/conflicted/etc transactions that are kept for compact block reconstruction.
275+
* The last -blockreconstructionextratxn/DEFAULT_BLOCK_RECONSTRUCTION_EXTRA_TXN of
276+
* these are kept in a ring buffer */
266277
static std::vector<std::pair<uint256, CTransactionRef>> vExtraTxnForCompact GUARDED_BY(g_cs_orphans);
278+
/** Offset into vExtraTxnForCompact to insert the next tx */
279+
static size_t vExtraTxnForCompactIt GUARDED_BY(g_cs_orphans) = 0;
267280
} // namespace
268281

269282
namespace {
@@ -2021,32 +2034,34 @@ void PeerManager::ProcessHeadersMessage(CNode& pfrom, const std::vector<CBlockHe
20212034
return;
20222035
}
20232036

2024-
void PeerManager::ProcessOrphanTx(std::set<uint256>& orphan_work_set, std::list<CTransactionRef>& removed_txn)
2037+
/**
2038+
* Reconsider orphan transactions after a parent has been accepted to the mempool.
2039+
*
2040+
* @param[in/out] orphan_work_set The set of orphan transactions to reconsider. Generally only one
2041+
* orphan will be reconsidered on each call of this function. This set
2042+
* may be added to if accepting an orphan causes its children to be
2043+
* reconsidered.
2044+
*/
2045+
void PeerManager::ProcessOrphanTx(std::set<uint256>& orphan_work_set)
20252046
{
20262047
AssertLockHeld(cs_main);
20272048
AssertLockHeld(g_cs_orphans);
2028-
std::set<NodeId> setMisbehaving;
2029-
bool done = false;
2030-
while (!done && !orphan_work_set.empty()) {
2049+
2050+
while (!orphan_work_set.empty()) {
20312051
const uint256 orphanHash = *orphan_work_set.begin();
20322052
orphan_work_set.erase(orphan_work_set.begin());
20332053

20342054
auto orphan_it = mapOrphanTransactions.find(orphanHash);
20352055
if (orphan_it == mapOrphanTransactions.end()) continue;
20362056

20372057
const CTransactionRef porphanTx = orphan_it->second.tx;
2038-
const CTransaction& orphanTx = *porphanTx;
2039-
NodeId fromPeer = orphan_it->second.fromPeer;
2040-
// Use a new TxValidationState because orphans come from different peers (and we call
2041-
// MaybePunishNodeForTx based on the source peer from the orphan map, not based on the peer
2042-
// that relayed the previous transaction).
2043-
TxValidationState orphan_state;
2044-
2045-
if (setMisbehaving.count(fromPeer)) continue;
2046-
if (AcceptToMemoryPool(m_mempool, orphan_state, porphanTx, &removed_txn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
2058+
TxValidationState state;
2059+
std::list<CTransactionRef> removed_txn;
2060+
2061+
if (AcceptToMemoryPool(m_mempool, state, porphanTx, &removed_txn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
20472062
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
20482063
RelayTransaction(orphanHash, porphanTx->GetWitnessHash(), m_connman);
2049-
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
2064+
for (unsigned int i = 0; i < porphanTx->vout.size(); i++) {
20502065
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(orphanHash, i));
20512066
if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
20522067
for (const auto& elem : it_by_prev->second) {
@@ -2055,22 +2070,23 @@ void PeerManager::ProcessOrphanTx(std::set<uint256>& orphan_work_set, std::list<
20552070
}
20562071
}
20572072
EraseOrphanTx(orphanHash);
2058-
done = true;
2059-
} else if (orphan_state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) {
2060-
if (orphan_state.IsInvalid()) {
2061-
// Punish peer that gave us an invalid orphan tx
2062-
if (MaybePunishNodeForTx(fromPeer, orphan_state)) {
2063-
setMisbehaving.insert(fromPeer);
2064-
}
2073+
for (const CTransactionRef& removedTx : removed_txn) {
2074+
AddToCompactExtraTransactions(removedTx);
2075+
}
2076+
break;
2077+
} else if (state.GetResult() != TxValidationResult::TX_MISSING_INPUTS) {
2078+
if (state.IsInvalid()) {
20652079
LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s from peer=%d. %s\n",
20662080
orphanHash.ToString(),
2067-
fromPeer,
2068-
orphan_state.ToString());
2081+
orphan_it->second.fromPeer,
2082+
state.ToString());
2083+
// Maybe punish peer that gave us an invalid orphan tx
2084+
MaybePunishNodeForTx(orphan_it->second.fromPeer, state);
20692085
}
20702086
// Has inputs but not accepted to mempool
20712087
// Probably non-standard or insufficient fee
20722088
LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString());
2073-
if (orphan_state.GetResult() != TxValidationResult::TX_WITNESS_STRIPPED) {
2089+
if (state.GetResult() != TxValidationResult::TX_WITNESS_STRIPPED) {
20742090
// We can add the wtxid of this transaction to our reject filter.
20752091
// Do not add txids of witness transactions or witness-stripped
20762092
// transactions to the filter, as they can have been malleated;
@@ -2085,7 +2101,7 @@ void PeerManager::ProcessOrphanTx(std::set<uint256>& orphan_work_set, std::list<
20852101
// for concerns around weakening security of unupgraded nodes
20862102
// if we start doing this too early.
20872103
assert(recentRejects);
2088-
recentRejects->insert(orphanTx.GetWitnessHash());
2104+
recentRejects->insert(porphanTx->GetWitnessHash());
20892105
// If the transaction failed for TX_INPUTS_NOT_STANDARD,
20902106
// then we know that the witness was irrelevant to the policy
20912107
// failure, since this check depends only on the txid
@@ -2094,17 +2110,17 @@ void PeerManager::ProcessOrphanTx(std::set<uint256>& orphan_work_set, std::list<
20942110
// processing of this transaction in the event that child
20952111
// transactions are later received (resulting in
20962112
// parent-fetching by txid via the orphan-handling logic).
2097-
if (orphan_state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && orphanTx.GetWitnessHash() != orphanTx.GetHash()) {
2113+
if (state.GetResult() == TxValidationResult::TX_INPUTS_NOT_STANDARD && porphanTx->GetWitnessHash() != porphanTx->GetHash()) {
20982114
// We only add the txid if it differs from the wtxid, to
20992115
// avoid wasting entries in the rolling bloom filter.
2100-
recentRejects->insert(orphanTx.GetHash());
2116+
recentRejects->insert(porphanTx->GetHash());
21012117
}
21022118
}
21032119
EraseOrphanTx(orphanHash);
2104-
done = true;
2120+
break;
21052121
}
2106-
m_mempool.check(&::ChainstateActive().CoinsTip());
21072122
}
2123+
m_mempool.check(&::ChainstateActive().CoinsTip());
21082124
}
21092125

21102126
/**
@@ -3017,8 +3033,12 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
30173033
tx.GetHash().ToString(),
30183034
m_mempool.size(), m_mempool.DynamicMemoryUsage() / 1000);
30193035

3036+
for (const CTransactionRef& removedTx : lRemovedTxn) {
3037+
AddToCompactExtraTransactions(removedTx);
3038+
}
3039+
30203040
// Recursively process any orphan transactions that depended on this one
3021-
ProcessOrphanTx(pfrom.orphan_work_set, lRemovedTxn);
3041+
ProcessOrphanTx(pfrom.orphan_work_set);
30223042
}
30233043
else if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS)
30243044
{
@@ -3119,9 +3139,6 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
31193139
}
31203140
}
31213141

3122-
for (const CTransactionRef& removedTx : lRemovedTxn)
3123-
AddToCompactExtraTransactions(removedTx);
3124-
31253142
// If a tx has been detected by recentRejects, we will have reached
31263143
// this point and the tx will have been ignored. Because we haven't run
31273144
// the tx through AcceptToMemoryPool, we won't have computed a DoS
@@ -3821,12 +3838,8 @@ bool PeerManager::ProcessMessages(CNode* pfrom, std::atomic<bool>& interruptMsgP
38213838
ProcessGetData(*pfrom, m_chainparams, m_connman, m_mempool, interruptMsgProc);
38223839

38233840
if (!pfrom->orphan_work_set.empty()) {
3824-
std::list<CTransactionRef> removed_txn;
38253841
LOCK2(cs_main, g_cs_orphans);
3826-
ProcessOrphanTx(pfrom->orphan_work_set, removed_txn);
3827-
for (const CTransactionRef& removedTx : removed_txn) {
3828-
AddToCompactExtraTransactions(removedTx);
3829-
}
3842+
ProcessOrphanTx(pfrom->orphan_work_set);
38303843
}
38313844

38323845
if (pfrom->fDisconnect)

src/net_processing.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,7 @@ class PeerManager final : public CValidationInterface, public NetEventsInterface
121121
*/
122122
bool MaybeDiscourageAndDisconnect(CNode& pnode);
123123

124-
void ProcessOrphanTx(std::set<uint256>& orphan_work_set, std::list<CTransactionRef>& removed_txn)
125-
EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
124+
void ProcessOrphanTx(std::set<uint256>& orphan_work_set) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans);
126125
/** Process a single headers message from a peer. */
127126
void ProcessHeadersMessage(CNode& pfrom, const std::vector<CBlockHeader>& headers, bool via_compact_block);
128127

0 commit comments

Comments
 (0)