@@ -1713,6 +1713,64 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
1713
1713
return true ;
1714
1714
}
1715
1715
1716
+ void static ProcessOrphanTx (CConnman* connman, std::set<uint256>& orphan_work_set, std::list<CTransactionRef>& removed_txn) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
1717
+ {
1718
+ AssertLockHeld (cs_main);
1719
+ AssertLockHeld (g_cs_orphans);
1720
+ std::set<NodeId> setMisbehaving;
1721
+ while (!orphan_work_set.empty ()) {
1722
+ const uint256 orphanHash = *orphan_work_set.begin ();
1723
+ orphan_work_set.erase (orphan_work_set.begin ());
1724
+
1725
+ auto orphan_it = mapOrphanTransactions.find (orphanHash);
1726
+ if (orphan_it == mapOrphanTransactions.end ()) continue ;
1727
+
1728
+ const CTransactionRef porphanTx = orphan_it->second .tx ;
1729
+ const CTransaction& orphanTx = *porphanTx;
1730
+ NodeId fromPeer = orphan_it->second .fromPeer ;
1731
+ bool fMissingInputs2 = false ;
1732
+ // Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
1733
+ // resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
1734
+ // anyone relaying LegitTxX banned)
1735
+ CValidationState stateDummy;
1736
+
1737
+ if (setMisbehaving.count (fromPeer)) continue ;
1738
+ if (AcceptToMemoryPool (mempool, stateDummy, porphanTx, &fMissingInputs2 , &removed_txn, false /* bypass_limits */ , 0 /* nAbsurdFee */ )) {
1739
+ LogPrint (BCLog::MEMPOOL, " accepted orphan tx %s\n " , orphanHash.ToString ());
1740
+ RelayTransaction (orphanTx, connman);
1741
+ for (unsigned int i = 0 ; i < orphanTx.vout .size (); i++) {
1742
+ auto it_by_prev = mapOrphanTransactionsByPrev.find (COutPoint (orphanHash, i));
1743
+ if (it_by_prev != mapOrphanTransactionsByPrev.end ()) {
1744
+ for (const auto & elem : it_by_prev->second ) {
1745
+ orphan_work_set.insert (elem->first );
1746
+ }
1747
+ }
1748
+ }
1749
+ EraseOrphanTx (orphanHash);
1750
+ } else if (!fMissingInputs2 ) {
1751
+ int nDos = 0 ;
1752
+ if (stateDummy.IsInvalid (nDos) && nDos > 0 ) {
1753
+ // Punish peer that gave us an invalid orphan tx
1754
+ Misbehaving (fromPeer, nDos);
1755
+ setMisbehaving.insert (fromPeer);
1756
+ LogPrint (BCLog::MEMPOOL, " invalid orphan tx %s\n " , orphanHash.ToString ());
1757
+ }
1758
+ // Has inputs but not accepted to mempool
1759
+ // Probably non-standard or insufficient fee
1760
+ LogPrint (BCLog::MEMPOOL, " removed orphan tx %s\n " , orphanHash.ToString ());
1761
+ if (!orphanTx.HasWitness () && !stateDummy.CorruptionPossible ()) {
1762
+ // Do not use rejection cache for witness transactions or
1763
+ // witness-stripped transactions, as they can have been malleated.
1764
+ // See https://github.com/bitcoin/bitcoin/issues/8279 for details.
1765
+ assert (recentRejects);
1766
+ recentRejects->insert (orphanHash);
1767
+ }
1768
+ EraseOrphanTx (orphanHash);
1769
+ }
1770
+ mempool.check (pcoinsTip.get ());
1771
+ }
1772
+ }
1773
+
1716
1774
bool static ProcessMessage (CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman* connman, const std::atomic<bool >& interruptMsgProc, bool enable_bip61)
1717
1775
{
1718
1776
LogPrint (BCLog::NET, " received: %s (%u bytes) peer=%d\n " , SanitizeString (strCommand), vRecv.size (), pfrom->GetId ());
@@ -2384,58 +2442,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
2384
2442
mempool.size (), mempool.DynamicMemoryUsage () / 1000 );
2385
2443
2386
2444
// Recursively process any orphan transactions that depended on this one
2387
- std::set<NodeId> setMisbehaving;
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
- }
2414
- }
2415
- }
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
- }
2435
- EraseOrphanTx (orphanHash);
2436
- }
2437
- mempool.check (pcoinsTip.get ());
2438
- }
2445
+ ProcessOrphanTx (connman, orphan_work_set, lRemovedTxn);
2439
2446
}
2440
2447
else if (fMissingInputs )
2441
2448
{
0 commit comments