#36477 private broadcast: show finished transactions in getprivatebroadcastinfo

ReviewabilityReviewsAgreementSize
#36477 vasild private broadcast: show finished transactions in getprivatebroadcastinfoNeeds rebase0Strong107 + 90 tests
  • Keep finished private broadcast transactions in memory and expose them in getprivatebroadcastinfo
  • Gives node operators visibility into send history, peer acknowledgments, and network echo details
  • Ready to review
  • Concept approval because completed transaction info is useful to operators (optout21)
  • Verified fixes for retry exhaustion and peer overwrite logic (frankomosh)
  • Suggests retaining the received flag upon re-request if already in mempool (optout21)
  • Suggests adding a test verifying received_by_us is not overwritten (frankomosh)
  • 107 lines added or modified outside tests
  • 90 lines added or modified in tests
  • 71 lines removed in total
  • 8 files, 1 commits
P2P#40 of 71
P3 · new feature
  • P3 because it improves visibility into private broadcasts without altering core relay protocols
  • Benefit is limited to node operators inspecting local private broadcast send history
  • Ranking pass: Stated prerequisite for P2 #36607, so it must not be queued behind the rest of P3.
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

Retains completed and echoed private broadcast transactions in memory and exposes them in the getprivatebroadcastinfo RPC output instead of dropping them upon network echo. Adds a received_by_us object to the RPC response containing the peer address and timestamp when a transaction is received back from the network. When the private broadcast storage hits capacity, the oldest finished transaction is evicted to accommodate new entries.

Problem: Previously, privately broadcast transactions were pruned from memory once resolved or echoed back from the network. Operators using private broadcast lost visibility into send history, peer acknowledgment times, and echo reception details as soon as the transaction broadcast finished.

Evidence of importance:

  • PR description: 'For finished transactions, this allows the inspection of when and to whom the transaction was sent as well as when/if it was echoed from the network.'
  • Release note: 'The information will now not vanish as soon as the transaction is echoed from the network. In addition getprivatebroadcastinfo returns a received_by_us object for echoed transactions, containing the peer address and time of the reception.'

Risk of a mistake: medium (rpc_api, p2p). A bug in queue retention or eviction logic could leak memory or misreport private broadcast confirmation status over RPC.

Reviewability

Ready · Needs rebase

Conflicts with master; review the logic now, the rebase is mechanical.

Waiting on (from the thread read):

  • author: response to optout21's suggestion on mempool re-broadcasts 2026-10-28
  • author: response to frankomosh's suggestion to add a test 2026-10-27

Agreement

Strong

substantive support, no open objection (optout21)

Thread notes: optout21 reviewed again leaving nits and reminded the author about their open suggestion regarding keeping the received flag for transactions already in the mempool.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
frankomosh (contributor)question, scopeWhat was added or left out compared to #34707?answered · author replied to review this PR fresh as unrelatedansweredyes2026-10-19: 'I guess this is a continuation of #34707. Could you share what was added or left out compared to it?'
Status from: 2026-10-22: vasild: 'I am unsure. Better review this one as a fresh new unrelated one.'
frankomosh (contributor)objection, correctnessA transaction that exhausted send attempts without being echoed cannot be sent again because Add() only restarts resolved transactions but GetStale() skips itaccepted · fix pushed · frankomosh confirmed the fix looks goodchangedyes2026-10-19: 'A tx that used all its send attempts, but never came back from the network, can no longer be sent again. Now `Add()` can only restarts a tx that is resolved. But `GetStale()` skips such a tx, so nothi'
Status from: 2026-10-27: frankomosh: 'Looks good now.'
frankomosh (contributor)suggestion, interfaceKeep the first peer and time rather than overwriting received_by_us when another peer sends the same transaction lateraccepted · fix pushed · frankomosh checked the fix and confirmed it looks goodansweredyes2026-10-19: 'If another peer sends us the same tx later, this line replaces the saved peer and time. So `received_by_us` may not show the first peer that sent it back. Should we keep the first one?'
Status from: 2026-10-27: frankomosh: 'Checked on 295c961.., looks good.'
optout21 (contributor)suggestion, interfaceList the stored categories in RPC help: transactions being actively sent, sent but not echoed back, and echoed backfixed · fix pushed · author dropped the sentence and pushed an updateansweredyes2026-10-22: 'Maybe the text should list the stored categories: transactions being actively sent, sent but not echoed back, and echoed back.'
Status from: 2026-10-23: vasild: 'Dropped the sentence.'
optout21 (contributor)suggestion, interfaceUpdate this RPC documentation text as wellfixed · fix pushed · author shortened the documentation and pushed an updateansweredyes2026-10-22: 'This should also be updated.'
Status from: 2026-10-23: vasild: 'Shortened to just:'
optout21 (contributor)question, correctnessWhat happens when a previously-finished transaction is requested to be private-broadcast again, and is it intended that it may end up reported as failed?accepted · optout21 accepted the explanation of why received_by_us remains unset upon re-broadcastansweredyes2026-10-22: 'what happens when a previously-finished transaction is requested to be private-broadcast again?'
Status from: 2026-10-24: optout21: 'Case 2. could be argued about, but I think it's fine.'
optout21 (contributor)suggestion, approachConsider not clearing the received flag upon a re-request if the transaction is already in the mempoolopenansweredno2026-10-24: 'One idea that we could consider though: upon a re-request don't clean the "received" flag if the TX is already in the mempool'
frankomosh (contributor)suggestion, maintenanceAdd a test verifying that received_by_us is not overwritten if already setopenansweredno2026-10-27: 'Maybe later we could add a test for it. For now, removing `&& !state.received_by_us.has_value()`(mutant), and all tests still unnecesarily pass (unit, fuzz and functional).'

Support:

  • optout21 (contributor) (Concept ACK, 2026-10-22) [read]: Keeping info about completed transaction is useful for the user and may be useful for feature implementation

Participants:

  • frankomosh (contributor, objection, 5 statements 2026-10-19 to 2026-10-27): raised concern about broken retry logic (accepted fix), peer overwrite (accepted fix), suggested adding a test, and asked about relation to #34707 (answered)
  • optout21 (contributor, support, 11 statements 2026-10-22 to 2026-10-28): Concept ACK; suggested RPC doc updates (fixed), accepted answer on re-broadcast behavior, reminded author of suggestion to persist received flag on re-request, and left code comments/nits

Dependencies

Base for: #36607

Files

120 lines under test/bench/ci.

  • src/test/fuzz/private_broadcast.cpp +68/-20
  • src/private_broadcast.cpp +50/-18
  • src/private_broadcast.h +31/-17
  • 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/net_processing.cpp +1/-1

Card

The short text the ranking pass compares across PRs.

Extends getprivatebroadcastinfo to retain and report finished private broadcast transactions rather than dropping them immediately upon network receipt. Adds a received_by_us field indicating the peer address and timestamp when a transaction is echoed back from the network, and evicts the oldest finished transactions when the queue is full. Solves the lack of post-broadcast observability for operators using private transaction broadcast. No dependencies.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-29T01:23, confidence high, input hash bec66f0a8a6aef12
thread read through 2026-10-28 (23 statements), head 295c961c1f
labels: Needs rebase, Private Broadcast

Categories

P2P

P3 · new feature (ranking pass: Stated prerequisite for P2 #36607, so it must not be queued behind the rest of P3.)

Retaining finished private broadcast transactions provides operator visibility into send history and network echoes without altering core relay or origin privacy protocols. The PR description notes that 'this allows the inspection of when and to whom the transaction was sent as well as when/if it was echoed from the network.'

Membership: Carries the 'Private Broadcast' label and modifies private broadcast tracking and net processing in src/private_broadcast.cpp and src/net_processing.cpp.

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