diff --git a/src/net.h b/src/net.h --- a/src/net.h +++ b/src/net.h @@ -780,6 +780,8 @@ Amount lastSentFeeFilter{Amount::zero()}; int64_t nextSendTimeFeeFilter{0}; + std::set orphan_work_set; + CNode(NodeId id, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn, SOCKET hSocketIn, const CAddress &addrIn, uint64_t nKeyedNetGroupIn, uint64_t nLocalHostNonceIn, const CAddress &addrBindIn, diff --git a/src/net_processing.cpp b/src/net_processing.cpp --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2058,7 +2058,8 @@ AssertLockHeld(cs_main); AssertLockHeld(g_cs_orphans); std::unordered_map rejectCountPerNode; - while (!orphan_work_set.empty()) { + bool done = false; + while (!done && !orphan_work_set.empty()) { const TxId orphanTxId = *orphan_work_set.begin(); orphan_work_set.erase(orphan_work_set.begin()); @@ -2099,6 +2100,7 @@ } } EraseOrphanTx(orphanTxId); + done = true; } else if (!fMissingInputs2) { int nDos = 0; if (stateDummy.IsInvalid(nDos)) { @@ -2125,6 +2127,7 @@ recentRejects->insert(orphanTxId); } EraseOrphanTx(orphanTxId); + done = true; } g_mempool.check(pcoinsTip.get()); } @@ -2856,8 +2859,6 @@ return true; } - std::set orphan_work_set; - CTransactionRef ptx; vRecv >> ptx; const CTransaction &tx = *ptx; @@ -2887,7 +2888,7 @@ mapOrphanTransactionsByPrev.find(COutPoint(txid, i)); if (it_by_prev != mapOrphanTransactionsByPrev.end()) { for (const auto &elem : it_by_prev->second) { - orphan_work_set.insert(elem->first); + pfrom->orphan_work_set.insert(elem->first); } } } @@ -2902,7 +2903,7 @@ // Recursively process any orphan transactions that depended on this // one - ProcessOrphanTx(config, connman, orphan_work_set); + ProcessOrphanTx(config, connman, pfrom->orphan_work_set); } else if (fMissingInputs) { // It may be the case that the orphans parents have all been // rejected. @@ -3842,6 +3843,11 @@ ProcessGetData(config, pfrom, connman, interruptMsgProc); } + if (!pfrom->orphan_work_set.empty()) { + LOCK2(cs_main, g_cs_orphans); + ProcessOrphanTx(config, connman, pfrom->orphan_work_set); + } + if (pfrom->fDisconnect) { return false; } @@ -3850,6 +3856,9 @@ if (!pfrom->vRecvGetData.empty()) { return true; } + if (!pfrom->orphan_work_set.empty()) { + return true; + } // Don't bother if send buffer is too full to respond anyway if (pfrom->fPauseSend) {