@@ -2342,8 +2342,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2342
2342
return true ;
2343
2343
}
2344
2344
2345
- std::deque<COutPoint> vWorkQueue ;
2346
- std::vector<uint256> vEraseQueue;
2345
+ std::set<uint256> orphan_work_set ;
2346
+
2347
2347
CTransactionRef ptx;
2348
2348
vRecv >> ptx;
2349
2349
const CTransaction& tx = *ptx;
@@ -2368,7 +2368,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2368
2368
mempool.check (pcoinsTip.get ());
2369
2369
RelayTransaction (tx, connman);
2370
2370
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
+ }
2372
2377
}
2373
2378
2374
2379
pfrom->nLastTXTime = GetTime ();
@@ -2380,64 +2385,57 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2380
2385
2381
2386
// Recursively process any orphan transactions that depended on this one
2382
2387
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
+ }
2410
2414
}
2411
- vEraseQueue.push_back (orphanHash);
2412
2415
}
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);
2434
2434
}
2435
- mempool. check (pcoinsTip. get () );
2435
+ EraseOrphanTx (orphanHash );
2436
2436
}
2437
+ mempool.check (pcoinsTip.get ());
2437
2438
}
2438
-
2439
- for (const uint256& hash : vEraseQueue)
2440
- EraseOrphanTx (hash);
2441
2439
}
2442
2440
else if (fMissingInputs )
2443
2441
{
0 commit comments