Skip to content

Commit 6196cf7

Browse files
committed
Merge bitcoin#19753: p2p: don't add AlreadyHave transactions to recentRejects
d419fde [net processing] Don't add AlreadyHave txs to recentRejects (Troy Giorshev) Pull request description: If we already have a transaction, don't add it to recentRejects Now, we only add a transaction to our recentRejects filter if we didn't already have it, meaning that it is added at most once, as intended. ACKs for top commit: jnewbery: Code review ACK d419fde laanwj: Code review ACK d419fde Tree-SHA512: cff5c1ba36c4700e2d6ab3eec4a3e51e1bef28fb3cc1bc850c84e06d6e5a9f6c32825207c253cc9cdf596b2eaadb6b5be68b3f8ca752b4ef6c31cf85138e3c99
2 parents 3f512f3 + d419fde commit 6196cf7

File tree

2 files changed

+29
-20
lines changed

2 files changed

+29
-20
lines changed

src/net_processing.cpp

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2946,13 +2946,9 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
29462946
pfrom.AddKnownTx(txid);
29472947
}
29482948

2949-
TxValidationState state;
2950-
29512949
m_txrequest.ReceivedResponse(pfrom.GetId(), txid);
29522950
if (tx.HasWitness()) m_txrequest.ReceivedResponse(pfrom.GetId(), wtxid);
29532951

2954-
std::list<CTransactionRef> lRemovedTxn;
2955-
29562952
// We do the AlreadyHaveTx() check using wtxid, rather than txid - in the
29572953
// absence of witness malleation, this is strictly better, because the
29582954
// recent rejects filter may contain the wtxid but rarely contains
@@ -2965,8 +2961,25 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
29652961
// already; and an adversary can already relay us old transactions
29662962
// (older than our recency filter) if trying to DoS us, without any need
29672963
// for witness malleation.
2968-
if (!AlreadyHaveTx(GenTxid(/* is_wtxid=*/true, wtxid), m_mempool) &&
2969-
AcceptToMemoryPool(m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */)) {
2964+
if (AlreadyHaveTx(GenTxid(/* is_wtxid=*/true, wtxid), m_mempool)) {
2965+
if (pfrom.HasPermission(PF_FORCERELAY)) {
2966+
// Always relay transactions received from peers with forcerelay
2967+
// permission, even if they were already in the mempool, allowing
2968+
// the node to function as a gateway for nodes hidden behind it.
2969+
if (!m_mempool.exists(tx.GetHash())) {
2970+
LogPrintf("Not relaying non-mempool transaction %s from forcerelay peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
2971+
} else {
2972+
LogPrintf("Force relaying tx %s from peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
2973+
RelayTransaction(tx.GetHash(), tx.GetWitnessHash(), m_connman);
2974+
}
2975+
}
2976+
return;
2977+
}
2978+
2979+
TxValidationState state;
2980+
std::list<CTransactionRef> lRemovedTxn;
2981+
2982+
if (AcceptToMemoryPool(m_mempool, state, ptx, &lRemovedTxn, false /* bypass_limits */)) {
29702983
m_mempool.check(&::ChainstateActive().CoinsTip());
29712984
// As this version of the transaction was acceptable, we can forget about any
29722985
// requests for it.
@@ -3088,19 +3101,6 @@ void PeerManager::ProcessMessage(CNode& pfrom, const std::string& msg_type, CDat
30883101
AddToCompactExtraTransactions(ptx);
30893102
}
30903103
}
3091-
3092-
if (pfrom.HasPermission(PF_FORCERELAY)) {
3093-
// Always relay transactions received from peers with forcerelay permission, even
3094-
// if they were already in the mempool,
3095-
// allowing the node to function as a gateway for
3096-
// nodes hidden behind it.
3097-
if (!m_mempool.exists(tx.GetHash())) {
3098-
LogPrintf("Not relaying non-mempool transaction %s from forcerelay peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
3099-
} else {
3100-
LogPrintf("Force relaying tx %s from peer=%d\n", tx.GetHash().ToString(), pfrom.GetId());
3101-
RelayTransaction(tx.GetHash(), tx.GetWitnessHash(), m_connman);
3102-
}
3103-
}
31043104
}
31053105

31063106
// If a tx has been detected by recentRejects, we will have reached

test/functional/p2p_permissions.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,20 @@ def check_tx_relay(self):
153153
self.log.debug("Check that node[1] will not send an invalid tx to node[0]")
154154
tx.vout[0].nValue += 1
155155
txid = tx.rehash()
156+
# Send the transaction twice. The first time, it'll be rejected by ATMP because it conflicts
157+
# with a mempool transaction. The second time, it'll be in the recentRejects filter.
156158
p2p_rebroadcast_wallet.send_txs_and_test(
157159
[tx],
158160
self.nodes[1],
159161
success=False,
160-
reject_reason='Not relaying non-mempool transaction {} from forcerelay peer=0'.format(txid),
162+
reject_reason='{} from peer=0 was not accepted: txn-mempool-conflict'.format(txid)
163+
)
164+
165+
p2p_rebroadcast_wallet.send_txs_and_test(
166+
[tx],
167+
self.nodes[1],
168+
success=False,
169+
reject_reason='Not relaying non-mempool transaction {} from forcerelay peer=0'.format(txid)
161170
)
162171

163172
def checkpermission(self, args, expectedPermissions, whitelisted):

0 commit comments

Comments
 (0)