[MOVEONLY] Move processing of orphan queue to ProcessOrphanTx
This commit is contained in:
parent
9453018fdc
commit
6e051f3d32
1 changed files with 59 additions and 52 deletions
|
@ -1713,6 +1713,64 @@ bool static ProcessHeadersMessage(CNode *pfrom, CConnman *connman, const std::ve
|
|||
return true;
|
||||
}
|
||||
|
||||
void static ProcessOrphanTx(CConnman* connman, std::set<uint256>& orphan_work_set, std::list<CTransactionRef>& removed_txn) EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
AssertLockHeld(g_cs_orphans);
|
||||
std::set<NodeId> setMisbehaving;
|
||||
while (!orphan_work_set.empty()) {
|
||||
const uint256 orphanHash = *orphan_work_set.begin();
|
||||
orphan_work_set.erase(orphan_work_set.begin());
|
||||
|
||||
auto orphan_it = mapOrphanTransactions.find(orphanHash);
|
||||
if (orphan_it == mapOrphanTransactions.end()) continue;
|
||||
|
||||
const CTransactionRef porphanTx = orphan_it->second.tx;
|
||||
const CTransaction& orphanTx = *porphanTx;
|
||||
NodeId fromPeer = orphan_it->second.fromPeer;
|
||||
bool fMissingInputs2 = false;
|
||||
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
|
||||
// resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
|
||||
// anyone relaying LegitTxX banned)
|
||||
CValidationState stateDummy;
|
||||
|
||||
if (setMisbehaving.count(fromPeer)) continue;
|
||||
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, &fMissingInputs2, &removed_txn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
|
||||
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
|
||||
RelayTransaction(orphanTx, connman);
|
||||
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
|
||||
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(orphanHash, i));
|
||||
if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
|
||||
for (const auto& elem : it_by_prev->second) {
|
||||
orphan_work_set.insert(elem->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
EraseOrphanTx(orphanHash);
|
||||
} else if (!fMissingInputs2) {
|
||||
int nDos = 0;
|
||||
if (stateDummy.IsInvalid(nDos) && nDos > 0) {
|
||||
// Punish peer that gave us an invalid orphan tx
|
||||
Misbehaving(fromPeer, nDos);
|
||||
setMisbehaving.insert(fromPeer);
|
||||
LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", orphanHash.ToString());
|
||||
}
|
||||
// Has inputs but not accepted to mempool
|
||||
// Probably non-standard or insufficient fee
|
||||
LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString());
|
||||
if (!orphanTx.HasWitness() && !stateDummy.CorruptionPossible()) {
|
||||
// Do not use rejection cache for witness transactions or
|
||||
// witness-stripped transactions, as they can have been malleated.
|
||||
// See https://github.com/bitcoin/bitcoin/issues/8279 for details.
|
||||
assert(recentRejects);
|
||||
recentRejects->insert(orphanHash);
|
||||
}
|
||||
EraseOrphanTx(orphanHash);
|
||||
}
|
||||
mempool.check(pcoinsTip.get());
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
|||
mempool.size(), mempool.DynamicMemoryUsage() / 1000);
|
||||
|
||||
// Recursively process any orphan transactions that depended on this one
|
||||
std::set<NodeId> setMisbehaving;
|
||||
while (!orphan_work_set.empty()) {
|
||||
const uint256 orphanHash = *orphan_work_set.begin();
|
||||
orphan_work_set.erase(orphan_work_set.begin());
|
||||
|
||||
auto orphan_it = mapOrphanTransactions.find(orphanHash);
|
||||
if (orphan_it == mapOrphanTransactions.end()) continue;
|
||||
|
||||
const CTransactionRef porphanTx = orphan_it->second.tx;
|
||||
const CTransaction& orphanTx = *porphanTx;
|
||||
NodeId fromPeer = orphan_it->second.fromPeer;
|
||||
bool fMissingInputs2 = false;
|
||||
// Use a dummy CValidationState so someone can't setup nodes to counter-DoS based on orphan
|
||||
// resolution (that is, feeding people an invalid transaction based on LegitTxX in order to get
|
||||
// anyone relaying LegitTxX banned)
|
||||
CValidationState stateDummy;
|
||||
|
||||
if (setMisbehaving.count(fromPeer)) continue;
|
||||
if (AcceptToMemoryPool(mempool, stateDummy, porphanTx, &fMissingInputs2, &lRemovedTxn, false /* bypass_limits */, 0 /* nAbsurdFee */)) {
|
||||
LogPrint(BCLog::MEMPOOL, " accepted orphan tx %s\n", orphanHash.ToString());
|
||||
RelayTransaction(orphanTx, connman);
|
||||
for (unsigned int i = 0; i < orphanTx.vout.size(); i++) {
|
||||
auto it_by_prev = mapOrphanTransactionsByPrev.find(COutPoint(orphanHash, i));
|
||||
if (it_by_prev != mapOrphanTransactionsByPrev.end()) {
|
||||
for (const auto& elem : it_by_prev->second) {
|
||||
orphan_work_set.insert(elem->first);
|
||||
}
|
||||
}
|
||||
}
|
||||
EraseOrphanTx(orphanHash);
|
||||
} else if (!fMissingInputs2) {
|
||||
int nDos = 0;
|
||||
if (stateDummy.IsInvalid(nDos) && nDos > 0) {
|
||||
// Punish peer that gave us an invalid orphan tx
|
||||
Misbehaving(fromPeer, nDos);
|
||||
setMisbehaving.insert(fromPeer);
|
||||
LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", orphanHash.ToString());
|
||||
}
|
||||
// Has inputs but not accepted to mempool
|
||||
// Probably non-standard or insufficient fee
|
||||
LogPrint(BCLog::MEMPOOL, " removed orphan tx %s\n", orphanHash.ToString());
|
||||
if (!orphanTx.HasWitness() && !stateDummy.CorruptionPossible()) {
|
||||
// Do not use rejection cache for witness transactions or
|
||||
// witness-stripped transactions, as they can have been malleated.
|
||||
// See https://github.com/bitcoin/bitcoin/issues/8279 for details.
|
||||
assert(recentRejects);
|
||||
recentRejects->insert(orphanHash);
|
||||
}
|
||||
EraseOrphanTx(orphanHash);
|
||||
}
|
||||
mempool.check(pcoinsTip.get());
|
||||
}
|
||||
ProcessOrphanTx(connman, orphan_work_set, lRemovedTxn);
|
||||
}
|
||||
else if (fMissingInputs)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue