mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-18 08:32:30 +01:00
[refactor] move new tx logic to txdownload
Also delete external RecentRejectsReconsiderableFilter() access since it is no longer necessary.
This commit is contained in:
@@ -125,7 +125,6 @@ public:
|
||||
// temporary and removed later once logic has been moved internally.
|
||||
TxOrphanage& GetOrphanageRef();
|
||||
TxRequestTracker& GetTxRequestRef();
|
||||
CRollingBloomFilter& RecentRejectsReconsiderableFilter();
|
||||
|
||||
// Responses to chain events. TxDownloadManager is not an actual client of ValidationInterface, these are called through PeerManager.
|
||||
void ActiveTipChange();
|
||||
@@ -171,6 +170,11 @@ public:
|
||||
|
||||
/** Respond to package rejected from mempool */
|
||||
void MempoolRejectedPackage(const Package& package);
|
||||
|
||||
/** Marks a tx as ReceivedResponse in txrequest and checks whether AlreadyHaveTx.
|
||||
* Return a bool indicating whether this tx should be validated. If false, optionally, a
|
||||
* PackageToValidate. */
|
||||
std::pair<bool, std::optional<PackageToValidate>> ReceivedTx(NodeId nodeid, const CTransactionRef& ptx);
|
||||
};
|
||||
} // namespace node
|
||||
#endif // BITCOIN_NODE_TXDOWNLOADMAN_H
|
||||
|
||||
@@ -27,10 +27,6 @@ TxRequestTracker& TxDownloadManager::GetTxRequestRef()
|
||||
{
|
||||
return m_impl->m_txrequest;
|
||||
}
|
||||
CRollingBloomFilter& TxDownloadManager::RecentRejectsReconsiderableFilter()
|
||||
{
|
||||
return m_impl->RecentRejectsReconsiderableFilter();
|
||||
}
|
||||
void TxDownloadManager::ActiveTipChange()
|
||||
{
|
||||
m_impl->ActiveTipChange();
|
||||
@@ -83,6 +79,10 @@ void TxDownloadManager::MempoolRejectedPackage(const Package& package)
|
||||
{
|
||||
m_impl->MempoolRejectedPackage(package);
|
||||
}
|
||||
std::pair<bool, std::optional<PackageToValidate>> TxDownloadManager::ReceivedTx(NodeId nodeid, const CTransactionRef& ptx)
|
||||
{
|
||||
return m_impl->ReceivedTx(nodeid, ptx);
|
||||
}
|
||||
|
||||
// TxDownloadManagerImpl
|
||||
void TxDownloadManagerImpl::ActiveTipChange()
|
||||
@@ -450,4 +450,58 @@ void TxDownloadManagerImpl::MempoolRejectedPackage(const Package& package)
|
||||
{
|
||||
RecentRejectsReconsiderableFilter().insert(GetPackageHash(package));
|
||||
}
|
||||
|
||||
std::pair<bool, std::optional<PackageToValidate>> TxDownloadManagerImpl::ReceivedTx(NodeId nodeid, const CTransactionRef& ptx)
|
||||
{
|
||||
const uint256& txid = ptx->GetHash();
|
||||
const uint256& wtxid = ptx->GetWitnessHash();
|
||||
|
||||
// Mark that we have received a response
|
||||
m_txrequest.ReceivedResponse(nodeid, txid);
|
||||
if (ptx->HasWitness()) m_txrequest.ReceivedResponse(nodeid, wtxid);
|
||||
|
||||
// First check if we should drop this tx.
|
||||
// We do the AlreadyHaveTx() check using wtxid, rather than txid - in the
|
||||
// absence of witness malleation, this is strictly better, because the
|
||||
// recent rejects filter may contain the wtxid but rarely contains
|
||||
// the txid of a segwit transaction that has been rejected.
|
||||
// In the presence of witness malleation, it's possible that by only
|
||||
// doing the check with wtxid, we could overlook a transaction which
|
||||
// was confirmed with a different witness, or exists in our mempool
|
||||
// with a different witness, but this has limited downside:
|
||||
// mempool validation does its own lookup of whether we have the txid
|
||||
// already; and an adversary can already relay us old transactions
|
||||
// (older than our recency filter) if trying to DoS us, without any need
|
||||
// for witness malleation.
|
||||
if (AlreadyHaveTx(GenTxid::Wtxid(wtxid), /*include_reconsiderable=*/true)) {
|
||||
|
||||
if (RecentRejectsReconsiderableFilter().contains(wtxid)) {
|
||||
// When a transaction is already in m_lazy_recent_rejects_reconsiderable, we shouldn't submit
|
||||
// it by itself again. However, look for a matching child in the orphanage, as it is
|
||||
// possible that they succeed as a package.
|
||||
LogDebug(BCLog::TXPACKAGES, "found tx %s (wtxid=%s) in reconsiderable rejects, looking for child in orphanage\n",
|
||||
txid.ToString(), wtxid.ToString());
|
||||
return std::make_pair(false, Find1P1CPackage(ptx, nodeid));
|
||||
}
|
||||
|
||||
// If a tx is detected by m_lazy_recent_rejects it is ignored. Because we haven't
|
||||
// submitted the tx to our mempool, we won't have computed a DoS
|
||||
// score for it or determined exactly why we consider it invalid.
|
||||
//
|
||||
// This means we won't penalize any peer subsequently relaying a DoSy
|
||||
// tx (even if we penalized the first peer who gave it to us) because
|
||||
// we have to account for m_lazy_recent_rejects showing false positives. In
|
||||
// other words, we shouldn't penalize a peer if we aren't *sure* they
|
||||
// submitted a DoSy tx.
|
||||
//
|
||||
// Note that m_lazy_recent_rejects doesn't just record DoSy or invalid
|
||||
// transactions, but any tx not accepted by the mempool, which may be
|
||||
// due to node policy (vs. consensus). So we can't blanket penalize a
|
||||
// peer simply for relaying a tx that our m_lazy_recent_rejects has caught,
|
||||
// regardless of false positives.
|
||||
return {false, std::nullopt};
|
||||
}
|
||||
|
||||
return {true, std::nullopt};
|
||||
}
|
||||
} // namespace node
|
||||
|
||||
@@ -167,6 +167,8 @@ public:
|
||||
void MempoolAcceptedTx(const CTransactionRef& tx);
|
||||
RejectedTxTodo MempoolRejectedTx(const CTransactionRef& ptx, const TxValidationState& state, NodeId nodeid, bool first_time_failure);
|
||||
void MempoolRejectedPackage(const Package& package);
|
||||
|
||||
std::pair<bool, std::optional<PackageToValidate>> ReceivedTx(NodeId nodeid, const CTransactionRef& ptx);
|
||||
};
|
||||
} // namespace node
|
||||
#endif // BITCOIN_NODE_TXDOWNLOADMAN_IMPL_H
|
||||
|
||||
Reference in New Issue
Block a user