Skip to content

Commit 9453018

Browse files
committed
Simplify orphan processing in preparation for interruptibility
1 parent 6852059 commit 9453018

File tree

1 file changed

+54
-56
lines changed

1 file changed

+54
-56
lines changed

src/net_processing.cpp

Lines changed: 54 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -2342,8 +2342,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
23422342
return true;
23432343
}
23442344

2345-
std::deque<COutPoint> vWorkQueue;
2346-
std::vector<uint256> vEraseQueue;
2345+
std::set<uint256> orphan_work_set;
2346+
23472347
CTransactionRef ptx;
23482348
vRecv >> ptx;
23492349
const CTransaction& tx = *ptx;
@@ -2368,7 +2368,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
23682368
mempool.check(pcoinsTip.get());
23692369
RelayTransaction(tx, connman);
23702370
for (unsigned int i = 0; i < tx.vout.size(); i++) {
2371-
vWorkQueue.emplace_back(inv.hash, i);
2371+
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(inv.hash, i));
2372+
if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
2373+
for (const auto& elem : it_by_prev->second) {
2374+
orphan_work_set.insert(elem->first);
2375+
}
2376+
}
23722377
}
23732378

23742379
pfrom->nLastTXTime = GetTime();
@@ -2380,64 +2385,57 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
23802385

23812386
// Recursively process any orphan transactions that depended on this one
23822387
std::set<NodeId> setMisbehaving;
2383-
while (!vWorkQueue.empty()) {
2384-
auto itByPrev = mapOrphanTransactionsByPrev.find(vWorkQueue.front());
2385-
vWorkQueue.pop_front();
2386-
if (itByPrev == mapOrphanTransactionsByPrev.end())
2387-
continue;
2388-
for (auto mi = itByPrev->second.begin();
2389-
mi != itByPrev->second.end();
2390-
++mi)
2391-
{
2392-
const CTransactionRef& porphanTx = (*mi)->second.tx;
2393-
const CTransaction& orphanTx = *porphanTx;
2394-
const uint256& orphanHash = orphanTx.GetHash();
2395-
NodeId fromPeer = (*mi)->second.fromPeer;
2396-
bool fMissingInputs2 = false;
2397-
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
2398-
// resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
2399-
// anyone relaying LegitTxX banned)
2400-
CValidationState stateDummy;
2401-
2402-
2403-
if (setMisbehaving.count(fromPeer))
2404-
continue;
2405-
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, &fMissingInputs2, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
2406-
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
2407-
RelayTransaction(orphanTx, connman);
2408-
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
2409-
vWorkQueue.emplace_back(orphanHash, i);
2388+
while (!orphan_work_set.empty()) {
2389+
const uint256 orphanHash = *orphan_work_set.begin();
2390+
orphan_work_set.erase(orphan_work_set.begin());
2391+
2392+
auto orphan_it = mapOrphanTransactions.find(orphanHash);
2393+
if (orphan_it == mapOrphanTransactions.end()) continue;
2394+
2395+
const CTransactionRef porphanTx = orphan_it->second.tx;
2396+
const CTransaction& orphanTx = *porphanTx;
2397+
NodeId fromPeer = orphan_it->second.fromPeer;
2398+
bool fMissingInputs2 = false;
2399+
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
2400+
// resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
2401+
// anyone relaying LegitTxX banned)
2402+
CValidationState stateDummy;
2403+
2404+
if (setMisbehaving.count(fromPeer)) continue;
2405+
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, &fMissingInputs2, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
2406+
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
2407+
RelayTransaction(orphanTx, connman);
2408+
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
2409+
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(orphanHash, i));
2410+
if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
2411+
for (const auto& elem : it_by_prev->second) {
2412+
orphan_work_set.insert(elem->first);
2413+
}
24102414
}
2411-
vEraseQueue.push_back(orphanHash);
24122415
}
2413-
else if (!fMissingInputs2)
2414-
{
2415-
int nDos = 0;
2416-
if (stateDummy.IsInvalid(nDos) && nDos > 0)
2417-
{
2418-
// Punish peer that gave us an invalid orphan tx
2419-
Misbehaving(fromPeer, nDos);
2420-
setMisbehaving.insert(fromPeer);
2421-
LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", orphanHash.ToString());
2422-
}
2423-
// Has inputs but not accepted to mempool
2424-
// Probably non-standard or insufficient fee
2425-
LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString());
2426-
vEraseQueue.push_back(orphanHash);
2427-
if (!orphanTx.HasWitness() && !stateDummy.CorruptionPossible()) {
2428-
// Do not use rejection cache for witness transactions or
2429-
// witness-stripped transactions, as they can have been malleated.
2430-
// See https://github.com/bitcoin/bitcoin/issues/8279 for details.
2431-
assert(recentRejects);
2432-
recentRejects->insert(orphanHash);
2433-
}
2416+
EraseOrphanTx(orphanHash);
2417+
} else if (!fMissingInputs2) {
2418+
int nDos = 0;
2419+
if (stateDummy.IsInvalid(nDos) && nDos > 0) {
2420+
// Punish peer that gave us an invalid orphan tx
2421+
Misbehaving(fromPeer, nDos);
2422+
setMisbehaving.insert(fromPeer);
2423+
LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", orphanHash.ToString());
2424+
}
2425+
// Has inputs but not accepted to mempool
2426+
// Probably non-standard or insufficient fee
2427+
LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString());
2428+
if (!orphanTx.HasWitness() && !stateDummy.CorruptionPossible()) {
2429+
// Do not use rejection cache for witness transactions or
2430+
// witness-stripped transactions, as they can have been malleated.
2431+
// See https://github.com/bitcoin/bitcoin/issues/8279 for details.
2432+
assert(recentRejects);
2433+
recentRejects->insert(orphanHash);
24342434
}
2435-
mempool.check(pcoinsTip.get());
2435+
EraseOrphanTx(orphanHash);
24362436
}
2437+
mempool.check(pcoinsTip.get());
24372438
}
2438-
2439-
for (const uint256& hash : vEraseQueue)
2440-
EraseOrphanTx(hash);
24412439
}
24422440
else if (fMissingInputs)
24432441
{

0 commit comments

Comments
 (0)