Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 2,052 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void static ProcessOrphanTx(const Config &config, CConnman *connman, | void static ProcessOrphanTx(const Config &config, CConnman *connman, | ||||
std::set<TxId> &orphan_work_set) | std::set<TxId> &orphan_work_set) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans) { | EXCLUSIVE_LOCKS_REQUIRED(cs_main, g_cs_orphans) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
AssertLockHeld(g_cs_orphans); | AssertLockHeld(g_cs_orphans); | ||||
std::unordered_map<NodeId, uint32_t> rejectCountPerNode; | std::unordered_map<NodeId, uint32_t> rejectCountPerNode; | ||||
while (!orphan_work_set.empty()) { | bool done = false; | ||||
while (!done && !orphan_work_set.empty()) { | |||||
const TxId orphanTxId = *orphan_work_set.begin(); | const TxId orphanTxId = *orphan_work_set.begin(); | ||||
orphan_work_set.erase(orphan_work_set.begin()); | orphan_work_set.erase(orphan_work_set.begin()); | ||||
auto orphan_it = mapOrphanTransactions.find(orphanTxId); | auto orphan_it = mapOrphanTransactions.find(orphanTxId); | ||||
if (orphan_it == mapOrphanTransactions.end()) { | if (orphan_it == mapOrphanTransactions.end()) { | ||||
continue; | continue; | ||||
} | } | ||||
Show All 24 Lines | while (!done && !orphan_work_set.empty()) { | ||||
mapOrphanTransactionsByPrev.find(COutPoint(orphanTxId, i)); | mapOrphanTransactionsByPrev.find(COutPoint(orphanTxId, i)); | ||||
if (it_by_prev != mapOrphanTransactionsByPrev.end()) { | if (it_by_prev != mapOrphanTransactionsByPrev.end()) { | ||||
for (const auto &elem : it_by_prev->second) { | for (const auto &elem : it_by_prev->second) { | ||||
orphan_work_set.insert(elem->first); | orphan_work_set.insert(elem->first); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
EraseOrphanTx(orphanTxId); | EraseOrphanTx(orphanTxId); | ||||
done = true; | |||||
} else if (!fMissingInputs2) { | } else if (!fMissingInputs2) { | ||||
int nDos = 0; | int nDos = 0; | ||||
if (stateDummy.IsInvalid(nDos)) { | if (stateDummy.IsInvalid(nDos)) { | ||||
rejectCountPerNode[fromPeer]++; | rejectCountPerNode[fromPeer]++; | ||||
if (nDos > 0) { | if (nDos > 0) { | ||||
// Punish peer that gave us an invalid orphan tx | // Punish peer that gave us an invalid orphan tx | ||||
Misbehaving(fromPeer, nDos, "invalid-orphan-tx"); | Misbehaving(fromPeer, nDos, "invalid-orphan-tx"); | ||||
LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", | LogPrint(BCLog::MEMPOOL, " invalid orphan tx %s\n", | ||||
Show All 10 Lines | while (!done && !orphan_work_set.empty()) { | ||||
// transactions or witness-stripped transactions, as | // transactions or witness-stripped transactions, as | ||||
// they can have been malleated. See | // they can have been malleated. See | ||||
// https://github.com/bitcoin/bitcoin/issues/8279 | // https://github.com/bitcoin/bitcoin/issues/8279 | ||||
// for details. | // for details. | ||||
assert(recentRejects); | assert(recentRejects); | ||||
recentRejects->insert(orphanTxId); | recentRejects->insert(orphanTxId); | ||||
} | } | ||||
EraseOrphanTx(orphanTxId); | EraseOrphanTx(orphanTxId); | ||||
done = true; | |||||
} | } | ||||
g_mempool.check(pcoinsTip.get()); | g_mempool.check(pcoinsTip.get()); | ||||
} | } | ||||
} | } | ||||
static bool ProcessMessage(const Config &config, CNode *pfrom, | static bool ProcessMessage(const Config &config, CNode *pfrom, | ||||
const std::string &strCommand, CDataStream &vRecv, | const std::string &strCommand, CDataStream &vRecv, | ||||
int64_t nTimeReceived, CConnman *connman, | int64_t nTimeReceived, CConnman *connman, | ||||
▲ Show 20 Lines • Show All 715 Lines • ▼ Show 20 Lines | if (strCommand == NetMsgType::TX) { | ||||
// whitelistrelay is off | // whitelistrelay is off | ||||
if (!fRelayTxes && !pfrom->HasPermission(PF_RELAY)) { | if (!fRelayTxes && !pfrom->HasPermission(PF_RELAY)) { | ||||
LogPrint(BCLog::NET, | LogPrint(BCLog::NET, | ||||
"transaction sent in violation of protocol peer=%d\n", | "transaction sent in violation of protocol peer=%d\n", | ||||
pfrom->GetId()); | pfrom->GetId()); | ||||
return true; | return true; | ||||
} | } | ||||
std::set<TxId> orphan_work_set; | |||||
CTransactionRef ptx; | CTransactionRef ptx; | ||||
vRecv >> ptx; | vRecv >> ptx; | ||||
const CTransaction &tx = *ptx; | const CTransaction &tx = *ptx; | ||||
const TxId &txid = tx.GetId(); | const TxId &txid = tx.GetId(); | ||||
CInv inv(MSG_TX, txid); | CInv inv(MSG_TX, txid); | ||||
pfrom->AddInventoryKnown(inv); | pfrom->AddInventoryKnown(inv); | ||||
Show All 13 Lines | if (strCommand == NetMsgType::TX) { | ||||
Amount::zero() /* nAbsurdFee */)) { | Amount::zero() /* nAbsurdFee */)) { | ||||
g_mempool.check(pcoinsTip.get()); | g_mempool.check(pcoinsTip.get()); | ||||
RelayTransaction(tx, connman); | RelayTransaction(tx, connman); | ||||
for (size_t i = 0; i < tx.vout.size(); i++) { | for (size_t i = 0; i < tx.vout.size(); i++) { | ||||
auto it_by_prev = | auto it_by_prev = | ||||
mapOrphanTransactionsByPrev.find(COutPoint(txid, i)); | mapOrphanTransactionsByPrev.find(COutPoint(txid, i)); | ||||
if (it_by_prev != mapOrphanTransactionsByPrev.end()) { | if (it_by_prev != mapOrphanTransactionsByPrev.end()) { | ||||
for (const auto &elem : it_by_prev->second) { | for (const auto &elem : it_by_prev->second) { | ||||
orphan_work_set.insert(elem->first); | pfrom->orphan_work_set.insert(elem->first); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
pfrom->nLastTXTime = GetTime(); | pfrom->nLastTXTime = GetTime(); | ||||
LogPrint(BCLog::MEMPOOL, | LogPrint(BCLog::MEMPOOL, | ||||
"AcceptToMemoryPool: peer=%d: accepted %s " | "AcceptToMemoryPool: peer=%d: accepted %s " | ||||
"(poolsz %u txn, %u kB)\n", | "(poolsz %u txn, %u kB)\n", | ||||
pfrom->GetId(), tx.GetId().ToString(), g_mempool.size(), | pfrom->GetId(), tx.GetId().ToString(), g_mempool.size(), | ||||
g_mempool.DynamicMemoryUsage() / 1000); | g_mempool.DynamicMemoryUsage() / 1000); | ||||
// Recursively process any orphan transactions that depended on this | // Recursively process any orphan transactions that depended on this | ||||
// one | // one | ||||
ProcessOrphanTx(config, connman, orphan_work_set); | ProcessOrphanTx(config, connman, pfrom->orphan_work_set); | ||||
} else if (fMissingInputs) { | } else if (fMissingInputs) { | ||||
// 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; | ||||
for (const CTxIn &txin : tx.vin) { | for (const CTxIn &txin : tx.vin) { | ||||
if (recentRejects->contains(txin.prevout.GetTxId())) { | if (recentRejects->contains(txin.prevout.GetTxId())) { | ||||
fRejectedParents = true; | fRejectedParents = true; | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 923 Lines • ▼ Show 20 Lines | bool PeerLogicValidation::ProcessMessages(const Config &config, CNode *pfrom, | ||||
// (x) data | // (x) data | ||||
// | // | ||||
bool fMoreWork = false; | bool fMoreWork = false; | ||||
if (!pfrom->vRecvGetData.empty()) { | if (!pfrom->vRecvGetData.empty()) { | ||||
ProcessGetData(config, pfrom, connman, interruptMsgProc); | 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) { | if (pfrom->fDisconnect) { | ||||
return false; | return false; | ||||
} | } | ||||
// this maintains the order of responses | // this maintains the order of responses | ||||
if (!pfrom->vRecvGetData.empty()) { | if (!pfrom->vRecvGetData.empty()) { | ||||
return true; | return true; | ||||
} | } | ||||
if (!pfrom->orphan_work_set.empty()) { | |||||
return true; | |||||
} | |||||
// Don't bother if send buffer is too full to respond anyway | // Don't bother if send buffer is too full to respond anyway | ||||
if (pfrom->fPauseSend) { | if (pfrom->fPauseSend) { | ||||
return false; | return false; | ||||
} | } | ||||
std::list<CNetMessage> msgs; | std::list<CNetMessage> msgs; | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 1,034 Lines • Show Last 20 Lines |