Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 3,637 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::TX) { | ||||
// Recursively process any orphan transactions that depended on this | // Recursively process any orphan transactions that depended on this | ||||
// one | // one | ||||
ProcessOrphanTx(config, pfrom.orphan_work_set); | ProcessOrphanTx(config, pfrom.orphan_work_set); | ||||
} else if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) { | } else if (state.GetResult() == TxValidationResult::TX_MISSING_INPUTS) { | ||||
// It may be the case that the orphans parents have all been | // It may be the case that the orphans parents have all been | ||||
// rejected. | // rejected. | ||||
bool fRejectedParents = false; | bool fRejectedParents = false; | ||||
// Deduplicate parent txids, so that we don't have to loop over | |||||
// the same parent txid more than once down below. | |||||
std::vector<TxId> unique_parents; | |||||
unique_parents.reserve(tx.vin.size()); | |||||
for (const CTxIn &txin : tx.vin) { | for (const CTxIn &txin : tx.vin) { | ||||
if (recentRejects->contains(txin.prevout.GetTxId())) { | // We start with all parents, and then remove duplicates below. | ||||
unique_parents.push_back(txin.prevout.GetTxId()); | |||||
} | |||||
std::sort(unique_parents.begin(), unique_parents.end()); | |||||
unique_parents.erase( | |||||
std::unique(unique_parents.begin(), unique_parents.end()), | |||||
unique_parents.end()); | |||||
for (const TxId &parent_txid : unique_parents) { | |||||
if (recentRejects->contains(parent_txid)) { | |||||
fRejectedParents = true; | fRejectedParents = true; | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
if (!fRejectedParents) { | if (!fRejectedParents) { | ||||
const auto current_time = GetTime<std::chrono::microseconds>(); | const auto current_time = GetTime<std::chrono::microseconds>(); | ||||
for (const CTxIn &txin : tx.vin) { | for (const TxId &parent_txid : unique_parents) { | ||||
// FIXME: MSG_TX should use a TxHash, not a TxId. | // FIXME: MSG_TX should use a TxHash, not a TxId. | ||||
const TxId _txid = txin.prevout.GetTxId(); | pfrom.AddKnownTx(parent_txid); | ||||
pfrom.AddKnownTx(_txid); | if (!AlreadyHaveTx(parent_txid, m_mempool)) { | ||||
if (!AlreadyHaveTx(_txid, m_mempool)) { | AddTxAnnouncement(pfrom, parent_txid, current_time); | ||||
AddTxAnnouncement(pfrom, _txid, current_time); | |||||
} | } | ||||
} | } | ||||
AddOrphanTx(ptx, pfrom.GetId()); | AddOrphanTx(ptx, pfrom.GetId()); | ||||
// Once added to the orphan pool, a tx is considered | // Once added to the orphan pool, a tx is considered | ||||
// AlreadyHave, and we shouldn't request it anymore. | // AlreadyHave, and we shouldn't request it anymore. | ||||
m_txrequest.ForgetInvId(tx.GetId()); | m_txrequest.ForgetInvId(tx.GetId()); | ||||
▲ Show 20 Lines • Show All 2,266 Lines • Show Last 20 Lines |