#36607 private broadcast: Extra guard against unintended non-private broadcast of private transactions

ReviewabilityReviewsAgreementSize
#36607 optout21 private broadcast: Extra guard against unintended non-private broadcast of private transactionsReview #36477 first0Crickets149 + 353 tests
  • Prevent transactions intended for private broadcast from inadvertently leaking to public peers
  • Safeguards node origin privacy when local triggers like wallet rebroadcasts or RPCs re-announce them
  • No review verdicts recorded
  • No substantive comments either way
  • Addressed test determinism suggestion by disabling trickle delay globally (maflcko)
  • 149 lines added or modified outside tests
  • 353 lines added or modified in tests
  • 78 lines removed in total
  • 13 files, 4 commits
P2P#14 of 71
P2 · bug fix
  • P2 because it prevents node origin privacy leaks by ensuring private transactions stay off public peers
  • Eliminates recurring leak vectors from local triggers like wallet resends, GUI broadcasts, and retry timers
Reviewability: ReadyStalePaused
Agreement: StrongPositivePositive w/ caveatsNeutralMildDisputedBlockedCrickets
Reviews: current code-review ACKs, then (+stale ACKs) and -NACKs; greener = more ACKs.
Size: lines added or modified outside tests, then in tests; greener = smaller.

Goal

Adds a safeguard in PeerManager to prevent transactions tracked in private broadcast storage from being announced over public peer connections. It introduces a TxAnnounceReason parameter to distinguish transaction relay (received from network peers) from local announcement requests (such as RPC submissions, wallet rebroadcasts, and mempool unbroadcast retries). If a non-relay announcement is initiated for a transaction present in private broadcast storage, PeerManager suppresses the broadcast and removes the transaction from the mempool unbroadcast set.

Problem: Transactions broadcast via private broadcast can inadvertently be announced to public peers if re-triggered locally—such as through submitpackage RPC calls, periodic wallet resends after the transaction is echoed back from the network, GUI PSBT broadcasts, or unbroadcast retry timers. Announcing them to public peers exposes the node as the origin and undermines private broadcast protections.

Evidence of importance:

  • PR description: 'During the initial phase of private broadcast implementation there were unforeseen instances when a private transaction could get broadcast non-privately (see #35032 #35319 #35410 #36309 #36312 #36277 #36330)... Add a general, extra safeguard: whenever there is a transaction broadcast request, check if the given transaction has been previously broadcast privately, and if so, refuse to broadcast non-privately.'

Scope: Includes commits and diff from underlying PR #36477, which updates private broadcast queue retention and RPC metadata.

Risk of a mistake: medium (p2p, mempool_policy). Incorrectly identifying announcement reasons or false matches in private broadcast tracking could silence legitimate transaction broadcasts or mempool relay.

Changed since the previous assessment: Tests in test/functional/p2p_private_broadcast_then_public.py were split into separate commits for the submitpackage and wallet resend scenarios.

Reviewability

Ready · Review #36477 first

Stacked on #36477; the base PR's changes are included in this diff.

Waiting on (from the thread read):

  • author: author is keeping PR in draft pending prerequisite #36477

Agreement

Crickets

no substantive comment either way

Thread notes: Initial record for draft PR. maflcko suggested a cleaner approach to fixing a test CI failure, which the author implemented. / Initial record. maflcko suggested setting noban_tx_relay globally to resolve a CI timeout, which author implemented.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
maflcko (member)suggestion, approachMake the test deterministic using syncs if it cares about trickle delay, or set noban_tx_relay globally if it does notfixed · fix pushed · author agreed and updated the test to use global noban_tx_relayansweredyes2026-10-28: 'either the test here cares about trickle-delay, in which case it would be cleaner to not use `noban` permission and instead make the test deterministic with syncs or so? Or, the test doesn't care about trickle delay, and can just set `noban_tx_relay` globally?'
Status from: 2026-10-28: optout21: 'This test doesn't care about trickle delay, so disabling it globally is a simpler solution. Changed now.'

Participants:

  • maflcko (member, neutral, 1 statements 2026-10-28 to 2026-10-28): suggested cleaner approaches for the test trickle-delay fix

Dependencies

Depends on: #36477

Based on (shares commits with): #36477

Files

383 lines under test/bench/ci.

  • test/functional/p2p_private_broadcast_then_public.py +262/-0
  • src/test/fuzz/private_broadcast.cpp +68/-20
  • src/private_broadcast.cpp +57/-18
  • src/private_broadcast.h +38/-17
  • src/net_processing.cpp +16/-6
  • src/test/private_broadcast_tests.cpp +15/-7
  • src/rpc/mempool.cpp +14/-5
  • doc/release-notes-36477.md +11/-0
  • test/functional/p2p_private_broadcast.py +7/-3
  • src/node/types.h +8/-0
  • src/net_processing.h +4/-1
  • src/node/transaction.cpp +1/-1
  • test/functional/test_runner.py +1/-0

Card

The short text the ranking pass compares across PRs.

Adds a safeguard in PeerManager to block unintended public announcements of transactions previously sent via private broadcast. Subsystems like submitpackage, periodic wallet rebroadcast, and mempool unbroadcast retries could otherwise announce these transactions across public peer connections, leaking origin identity. PeerManager::InitiateTxBroadcastToAll distinguishes relay from requested announcements, dropping public announcements and clearing unbroadcast retries for transactions tracked in private broadcast storage. It depends on base PR #36477 to keep finished private broadcast records in memory so they can be matched.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-30T01:12, confidence high, input hash 07a3fc4020818340
thread read through 2026-10-28 (4 statements), head 350a7f3783
labels: Needs rebase, Private Broadcast · draft

Categories

P2P

P2 · bug fix

Prevents origin privacy leaks where transactions submitted via private broadcast are inadvertently broadcast to public peers by local re-triggers such as RPC calls, wallet resends, or unbroadcast timers. Protecting privacy of transaction origin is a top priority in p2p, and this adds a comprehensive safeguard against recurring leak vectors identified across earlier PRs (#35032, #35319, #36309).

Membership: Has the Private Broadcast label and modifies transaction announcement and relay logic in src/net_processing.cpp and src/private_broadcast.cpp.

Factors: security/stability 2, bug 2, performance 0, user value 1, leverage 0