Merge bitcoin/bitcoin#34628: p2p: Replace per-peer transaction rate-limiting with global rate limits

349c72ee00 net_processing: Drop unnecessary txid arg from InitiateTxBroadcastToAll (Anthony Towns)
12b0dc33c4 doc: Add release note for -txsendrate etc (Anthony Towns)
5cde66341a tests: basic functional test for tx rate limiting (Anthony Towns)
4842903ac1 rpc: report -txsendrate and bucket info via getnetworkinfo (Anthony Towns)
74a47a5207 init: add -txsendrate configuration parameter (Anthony Towns)
6307bd034b net_processing: Provide a 30bpm heartbeat log while inv backlog is in use (Anthony Towns)
df31ee57aa net_processing: add a global delay queue for sending txs (Anthony Towns)
7927650e56 util/tokenbucket.h: Provide a generic TokenBucket class (Anthony Towns)
749bb447f8 txmempool: Drop CompareMiningScoreWithTopology (Anthony Towns)
e1b7490fbc net_processing: Replace CompareInvMempoolOrder (Anthony Towns)
6cfc65d210 txmempool: Add ExtractBestByMiningScoreWithTopology (Anthony Towns)
026f70e05f net_processing: Remove per-peer rate-limiting (Anthony Towns)
46c8c471dc net_processing: bump last_inv_sequence for bip35 messages explicitly (Anthony Towns)

Pull request description:

  Per-peer `m_tx_inventory_to_send` queues have CPU and memory costs that scale with both queue size and peer count. Under high transaction volume, this has previously caused severe issues ([May 2023 disclosure][1]) and still can cause measurable delays ([Feb 2026 Runestone surge][2], with the msghand thread observed hitting 100% CPU and queue memory reaching ~95MB).

  This PR replaces the per-peer rate limiting with a global queue using dual token buckets (limiting transaction by both count and serialized size). Transactions that arrive within the bucket capacity still relay nearly immediately, but excess transactions queue in a global backlog and drain as the token buckets refill.

  Key parameters:
    - Count bucket: 14 tx/s, 420 capacity (30s buffer)
    - Size bucket: 20 kB/s (~12 MB/600s), 50 MB capacity
    - Outbound peers refill faster by a factor of 2.5

  Per-peer queues are retained solely for privacy batching and are always fully emptied, removing the old `INVENTORY_BROADCAST_MAX` cap.

  This reduces the memory and CPU burden during transaction spikes when the queuing logic is engaged from O(queue * peers) to O(queue), as the queued transactions no longer need to be retained per-peer or re-sorted per-peer.

  Design discussion: https://gist.github.com/ajtowns/d61bea974a07190fa6c6c8eaef3638b9

  [1]: https://bitcoincore.org/en/2024/10/08/disclose-large-inv-to-send/
  [2]: https://bnoc.xyz/t/increased-b-msghand-thread-utilization-due-to-runestone-transactions-on-2026-02-17/81

ACKs for top commit:
  sipa:
    Code review ACK 349c72ee00. I haven't tested it myself yet (though switched my well-connected node to it now), but the posted benchmarks and analyses look convincing.
  instagibbs:
    reACK 349c72ee00
  mzumsande:
    ACK 349c72ee00

Tree-SHA512: 2196a23308cb7fe36738cf638edf5c5b0e9ba32b11c083609fd8b50291e05bb33484f9921f8beab28d94c58d1adddea4c8ae1182a60a7f53f54be7370e2a0e47
This commit is contained in:
merge-script
2026-07-25 12:15:44 +02:00
15 changed files with 707 additions and 120 deletions

View File

@@ -0,0 +1,13 @@
P2P and network changes
-----------------------
- To reduce memory and CPU usage during periods of high transaction
volume, rate-limiting of outgoing transaction relay has been changed
to use a global backlog instead of being done on a per-peer basis. The
default rate-limit remains as 14 tx/s (boosted by 2.5x for outbound
peers), though this can be changed via the `-txsendrate` configuration
option. An additional bandwidth rate-limit has also been introduced
at 12MB of transactions per 10 minutes, with a high burst rate. The
size of the global backlog and the token bucket values for the rate
limits can be queried via the `getnetworkinfo` RPC. (#34628)