#34533 wallet: resubmit transactions with private broadcast if enabled

ReviewabilityReviewsAgreementSize
#34533 vasild wallet: resubmit transactions with private broadcast if enabledWaiting on author0 (+2)Mild11 + 43 tests
  • Prevent wallet rebroadcasts from leaking node IP addresses when private broadcast is enabled
  • Route periodic rebroadcasts through anonymized connections instead of public broadcast
  • Author silent for 159 days; reviews may wait a long time for a response
  • Support for routing wallet rebroadcasts through the private broadcast mechanism (pablomartin4btc, w0xlt)
  • Approval without stated reasons (andrewtoth)
  • Unaddressed objection: attacker can send dust to force public rebroadcasts unless IsMine is handled (mzumsande)
  • Answered objection: private broadcast to random peers delays dependent transactions like CPFP (achow101)
  • 11 lines added or modified outside tests
  • 43 lines added or modified in tests
  • 11 lines removed in total
  • 2 files, 2 commits
P2P#12 of 71
P2 · bug fix
  • P2 after comparing with the other PRs here (assessed alone as P1): Demoted to P2: the same rebroadcast leak is addressed by #36330 and more broadly by #36607, both P2; equal-consequence PRs must share a band.
  • P1 because periodic rebroadcasts bypass private broadcast and leak node IP addresses
  • It fixes a critical privacy break for users relying on anonymized origin connections
Wallet#19 of 92
P2 · bug fix
  • P2 after comparing with the other PRs here (assessed alone as P1): Lowered from P1: same defect as #36330 with an opposite approach, and scope is limited to the opt-in -privatebroadcast feature; the two must share a band.
  • P1 because the wallet resubmission logic exposes user IP addresses on public broadcast
  • It resolves a serious privacy defect for wallet users configuring private broadcast
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

Direct unconfirmed wallet transaction rebroadcasts through the private broadcast mechanism when -privatebroadcast=1 is enabled. Previously, periodic wallet rebroadcasts defaulted to public broadcast across all peer connections regardless of the private broadcast configuration. The change also improves wallet submission log messages by reporting both txid and wtxid alongside the submission result.

Problem: When -privatebroadcast=1 is configured, the wallet still rebroadcasts unconfirmed transactions every 12 to 36 hours using the public send-to-all broadcast path. This causes transactions intended to be broadcast only over short-lived anonymized connections to eventually leak the node's IP address over regular peer connections.

Evidence of importance:

  • PR description: 'If -privatebroadcast=1 and a transaction is submitted locally with the sendrawtransaction RPC and it is related to the wallet, then the rebroadcasts would use the send-to-all method. Change that to use the private broadcast method.'

Risk of a mistake: medium (wallet, p2p). A flaw in wallet rebroadcast logic or transaction broadcast flags could stall transaction propagation for unmined transactions or leak originating IP addresses.

Changed since the previous assessment: The implementation and full diff are now available; the diff modifies MaybeResendWalletTxs to check -privatebroadcast and updates the functional test wallet_resendwallettransactions.py with --privatebroadcast testing.

Reviewability

Paused · Waiting on author

Open objections from mzumsande, sedited with no author reply for 31 days; review would repeat what has been asked.

Waiting on (from the thread read):

  • author: addressing mzumsande's concern about IsMine dust transactions 2026-02-12
  • author: resolving CPFP/dependent transaction handling under private broadcast 2026-02-27
  • author: response to mzumsande's objection on IsMine dust and resolution to achow101's dependent broadcast objection 2026-02-27

Agreement

Mild

objection that needs a change was answered, no reply from the objector (achow101: private broadcast to random peers fails or indefinitely delays rebroadcasting dependent transactions (e.g. CPFP) because); objection that needs an answer has none yet (mzumsande)

Thread notes: Brought records up to schema. mzumsande's objection regarding IsMine dust transactions remains open, while achow101's objection regarding private rebroadcasting of dependent packages is answered pending resolution. / Added question from sedited (c:4037508223). The PR is currently marked draft.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
w0xlt (contributor)objection, approachprivately broadcast transactions could later be rebroadcast publicly via mempool if the node restarts without -privatebroadcastaccepted · reviewer accepted author's rationale to avoid state complexity across restartsansweredyes2026-02-08: 'if a user uses `sendrawtransaction` to submit a wallet-related transaction while `-privatebroadcast` is enabled and then restarts the node without `-privatebroadcast`, the transaction would be rebroad'
Status from: 2026-02-20: w0xlt: 'However, it’s probably better to keep things simple. ACK 16cd713073f45a5ddff1cdce73a7a8459bd8c618'
mzumsande (member)objection, scopean attacker can send dust to wallet addresses to trigger public rebroadcasts unless IsMine transactions are also handledopenansweredno2026-02-12: 'I think this is not complete unless we also do something about `IsMine()` transactions.'
achow101 (member)objection, correctnessprivate broadcast to random peers fails or indefinitely delays rebroadcasting dependent transactions (e.g. CPFP) because parent is missing from local mempoolanswered · author confirmed the issue and proposed solutions; andrewtoth noted PR #34707changedyes2026-02-27: 'I'm not convinced that this is ready for the wallet until there is support for private broadcasting of packages, and for the wallet to submit packages when rebroadcasting.'
Status from: 2026-03-04: vasild: 'Correct. Possible solutions to that:'
sedited (member)question, approachshould the PR be drafted while dependent rebroadcast solutions are being worked on?openansweredno2026-03-11: 'Should this PR be drafted while those things are being worked on?'

Support:

  • pablomartin4btc (member) (Concept ACK, 2026-02-07) [read]: This is necessary to support the private transaction broadcast mechanism introduced in #29415 when transactions are rebroadcast or resubmitted, which does not seem to be handled currently.
  • w0xlt (contributor) (ACK, 2026-02-20) [read]: Agreed keeping it simple without per-transaction state complexity across restarts is better
  • andrewtoth (member) (ACK, 2026-02-25): (no reason given) [not substantive]

Participants:

  • pablomartin4btc (member, support, 1 statements 2026-02-07 to 2026-02-07): Concept ACK: necessary to support private transaction broadcast mechanism when rebroadcasting
  • w0xlt (contributor, support, 2 statements 2026-02-08 to 2026-02-20): ACK: agreed to keep rebroadcast logic simple without per-transaction state tracking across restarts
  • mzumsande (member, objection, 1 statements 2026-02-12 to 2026-02-12): argued PR is incomplete unless IsMine() dust transactions are also addressed
  • andrewtoth (member, support, 2 statements 2026-02-25 to 2026-03-04): ACKed and noted #34707 could resolve CPFP rebroadcast issues
  • achow101 (member, objection, 2 statements 2026-02-27 to 2026-10-01): objected that private package broadcast is needed for dependent transactions like CPFP
  • sedited (member, question, 1 statements 2026-03-11 to 2026-03-11): asked whether the PR should be marked draft while dependent issues are addressed
  • instagibbs (member, neutral, 1 statements 2026-05-11 to 2026-05-11): noted package relay limits (1P1C) for fixing dependent transaction rebroadcasts

Files

52 lines under test/bench/ci.

  • test/functional/wallet_resendwallettransactions.py +43/-9
  • src/wallet/wallet.cpp +11/-2

Card

The short text the ranking pass compares across PRs.

Wallet rebroadcasts of unconfirmed transactions currently use standard network broadcast to all peers even when -privatebroadcast=1 is set. This PR updates periodic wallet rebroadcasts to route through private broadcast instead of standard connections when enabled, preventing transactions intended for Tor or I2P broadcast from leaking node IP addresses after 12 to 36 hours. It also expands wallet submission logging to include both txid and wtxid with the broadcast result.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-05T01:17, confidence high, input hash 0e77a558af69dd60
thread read through 2026-10-01 (15 statements), head 38f4715325
labels: Wallet, Needs rebase, Private Broadcast · draft

Categories

P2P

P2 · bug fix (assessed alone as P1; Demoted to P2: the same rebroadcast leak is addressed by #36330 and more broadly by #36607, both P2; equal-consequence PRs must share a band.)

Periodic wallet rebroadcasts bypass private broadcast settings and broadcast over regular peer connections, leaking the node's IP address and breaking origin privacy. In P2P, privacy of transaction origin is a primary priority, making an IP leak on rebroadcast when `-privatebroadcast=1` is explicitly configured a category-critical flaw.

Membership: Matches the 'Private Broadcast' label and directly affects transaction relay origin privacy by routing wallet rebroadcasts through anonymized connections instead of public broadcast.

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

Wallet

P2 · bug fix (assessed alone as P1; Lowered from P1: same defect as #36330 with an opposite approach, and scope is limited to the opt-in -privatebroadcast feature; the two must share a band.)

The wallet resubmission logic leaks user IP addresses by using the send-to-all broadcast path instead of respecting `-privatebroadcast=1`. Unresolved rebroadcast IP leakage is a serious privacy defect for wallet users relying on private broadcast.

Membership: Labeled Wallet and modifies wallet rebroadcast logic in src/wallet/wallet.cpp.

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