Skip to content

Commit 7109d2c

Browse files
committed
Transaction relay
Add details on DoS prevention measures and broadcasting h/t ajtowns
1 parent 6d9520b commit 7109d2c

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

06_p2p.adoc

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -560,9 +560,33 @@ The `addrv2` message is required to support https://trac.torproject.org/projects
560560

561561
=== Transaction relay
562562

563-
TODO
563+
Relaying transactions is a core tenet of a Bitcoin node, along with <<Address relay>> and <<Block relay>>.
564+
However, we don't necessarily want to immediately relay transactions we accept into our mempool immediately for the following reasons:
564565

565-
==== `Tx` privacy
566+
. Privacy: Adding a small delay in transaction relay helps obscure the route transactions take, making it harder to use transaction timing to infer the structure of the network or the original source of the transaction.
567+
. Load balancing: Having a small delay in transaction relay helps avoid the possibility that all transactions will be requested from the peer with the lowest network latency simply because they announce the transaction first.
568+
. Saving bandwidth: Having a longer delay in transaction relay may allow some transactions to not be relayed at all, eg in the case where a low fee rate transaction is accepted into the mempool and then evicted due to being at the bottom of the mempool, or RBFed prior to being relayed.
569+
570+
==== Rejecting incoming transactions
571+
572+
In addition to being careful about transaction relay, we must also reject (some) incoming transactions before they enter our mempool, which acts as a DoS prevention measure for our node.
573+
If we were to accept and blindly relay all transactions INVed to us by our peers, then an attacker could cheaply use (waste) a node's system resources and bandwidth, and have their attack amplified by the transaction flooding mechanism.
574+
575+
How do we currently limit incoming transactions?
576+
577+
. We reject transactions which don't pass policy checks e.g.:
578+
.. We reject transactions that don't pay the https://github.com/bitcoin/bitcoin/blob/v23.0/src/validation.cpp#L833[mempool min fee] (set based on maximum mempool size)
579+
.. We reject RBF transactions that don't https://github.com/bitcoin/bitcoin/blob/v23.0/src/validation.cpp#L927-L928[increase the fee rate] by more than `-incrementalrelayfee`
580+
. We reject transactions which don't pass replacement/package checks.
581+
. We reject transactions which don't pass consensus checks.
582+
583+
What other mechanisms _could_ we consider using before the <<Single transactions,ATMP>> checks are performed?
584+
585+
. We _could_ reject transactions from individual peers that send transactions at too high a rate, however this would just encourage attackers to make multiple connections, using up additional inbound slots
586+
. We _could_ ignore transactions from any peer once some rate limit is hit, however this would drop high feerate transactions from innocent peers which would be doubly undesirable
587+
. We _could_ artificially increase our mempool min fee when a rate limit is exceeded, even if the mempool is not full?
588+
589+
==== Initial broadcast
566590

567591
If a spy is able to identify which node initially broadcast a transaction, there's a high probability that that node is the source wallet for the transaction.
568592
To avoid that privacy leak, we try to be intentional about how we relay and request transactions.

0 commit comments

Comments
 (0)