#36477 private broadcast: show finished transactions in getprivatebroadcastinfo
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #36477 private broadcast: show finished transactions in getprivatebroadcastinfo | Needs rebase | 0 | Strong | 107 + 90 tests | |||
|
|
|
|
| |||
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:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| frankomosh (contributor) | question, scope | What was added or left out compared to #34707? | answered · author replied to review this PR fresh as unrelated | answered | yes | 2026-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, correctness | A transaction that exhausted send attempts without being echoed cannot be sent again because Add() only restarts resolved transactions but GetStale() skips it | accepted · fix pushed · frankomosh confirmed the fix looks good | changed | yes | 2026-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, interface | Keep the first peer and time rather than overwriting received_by_us when another peer sends the same transaction later | accepted · fix pushed · frankomosh checked the fix and confirmed it looks good | answered | yes | 2026-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, interface | List the stored categories in RPC help: transactions being actively sent, sent but not echoed back, and echoed back | fixed · fix pushed · author dropped the sentence and pushed an update | answered | yes | 2026-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, interface | Update this RPC documentation text as well | fixed · fix pushed · author shortened the documentation and pushed an update | answered | yes | 2026-10-22: 'This should also be updated.' Status from: 2026-10-23: vasild: 'Shortened to just:' |
| optout21 (contributor) | question, correctness | What 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-broadcast | answered | yes | 2026-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, approach | Consider not clearing the received flag upon a re-request if the transaction is already in the mempool | open | answered | no | 2026-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, maintenance | Add a test verifying that received_by_us is not overwritten if already set | open | answered | no | 2026-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
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