#34271 net_processing: make m_tx_for_private_broadcast optional
| Reviewability | Reviews | Agreement | Size | ||||
|---|---|---|---|---|---|---|---|
| #34271 net_processing: make m_tx_for_private_broadcast optional | Waiting on author | 0 (+1) | Mild | 91 | |||
|
|
|
|
| |||
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
Make `PeerManagerImpl::m_tx_for_private_broadcast` an `std::optional<PrivateBroadcast>`, instantiating it only when private broadcast mode is enabled (`-privatebroadcast=1`). Guard all private broadcast access paths in `net_processing` to handle uninitialized state, disconnecting peers or returning early if private broadcast methods or messages are reached while disabled.
Problem: When `-privatebroadcast` is disabled (the default), `PeerManagerImpl` still constructs and retains an idle `PrivateBroadcast` object in memory throughout the lifetime of the node.
Evidence of importance:
- PR description: 'Make `PeerManagerImpl::m_tx_for_private_broadcast` optional because it is needed only in private broadcast mode (`-privatebroadcast=1`). A followup to #29415, requested in: https://github.com/bitcoin/bitcoin/pull/29415#discussion_r2620864832'
Risk of a mistake: medium (p2p). A missed null check or incorrect conditional branch during P2P message processing could trigger a std::bad_optional_access crash or inadvertently disconnect peers.
Changed since the previous assessment: No substantial changes to the patch; previous description already reflected this commit.
Reviewability
Paused · Waiting on author
Open objection from l0rinc with no author reply for 90 days; review would repeat what has been asked.
Agreement
Mild
objection that needs an answer has none yet (l0rinc)
Thread notes: Initial implementation of optional private broadcast storage was reviewed and received support, but l0rinc requested initialization be moved to the constructor to avoid creating state on direct calls when disabled, which the author resolved in a push. mzumsande raised an open question on whether this refactoring is desirable given broader private-broadcast architectural proposals, prompting fanquake to move the PR to draft.
Objections, suggestions, and questions:
| Reviewer | Type | Harm, request, or question | Status | Must be | Author replied | Quote |
|---|---|---|---|---|---|---|
| l0rinc (contributor) | objection, correctness | Direct calls to InitiateTxBroadcastPrivate could instantiate private-broadcast state even when the peer manager was configured with private broadcast disabled | fixed · fix pushed · v1, not yet re-checked | changed | yes | 2026-05-15: 'my main concern is that the optional is currently initialized from InitiateTxBroadcastPrivate() instead of from the peer manager’s private-broadcast option.' Status from: 2026-06-30: vasild: 'Moved the initialization to PeerManagerImpl::PeerManagerImpl().' |
| l0rinc (contributor) | objection, approach | std::optional preserves inline storage for PrivateBroadcast inside PeerManagerImpl and does not reduce object size without indirection | open · v1, not yet re-checked | answered | no | 2026-05-15: 'Note that this still reserves storage for a PrivateBroadcast inside every PeerManagerImpl, even when private broadcast is disabled. This only skips construction and active state - avoiding the object-size footprint too would require indirection' |
| mzumsande (contributor) | objection, approach | Making private broadcast storage optional conflicts with proposals that make private broadcast core functionality rather than strictly opt-in | answered · reply on record; standing not assessed yet · v1, not yet re-checked | answered | yes | 2026-06-24: 'If in the future even nodes that don't opt into private broadcast (-privatebroadcast=0) would send private transactions, then this would move private broadcast into core functionality, and making m_tx_for_private_broadcast optional wouldn't make sense.' |
Support:
- optout21 (contributor) (Concept ACK, 2026-01-13): Review code; verified that all occurence of m_tx_for_private_broadcast is touched, verified building and unit tests locally
- polespinasa (member) (Concept ACK, 2026-01-14): Concept ACK [not substantive]
- w0xlt (contributor) (Approach ACK, 2026-01-14): Appraoch ACK [not substantive]
- optout21 (contributor) (ACK, 2026-05-15): Review code; verified that all occurrences of m_tx_for_private_broadcast are touched, verified building and unit tests locally.
- l0rinc (contributor) (Approach ACK, 2026-05-15): Making the private-broadcast transaction state optional is a useful cleanup for the default net-processing path
Participants:
- optout21 (contributor, support, 8 statements 2026-01-13 to 2026-05-15): Concept ACK and full ACK after reviewing code and testing locally
- polespinasa (member, support, 3 statements 2026-01-14 to 2026-01-14): Concept ACK; asked about the necessity of defensive optional checks in private-broadcast-specific functions
- w0xlt (contributor, support, 1 statements 2026-01-14 to 2026-01-14): Approach ACK
- l0rinc (contributor, objection, 5 statements 2026-05-15 to 2026-05-15): Approach ACK with changes requested regarding initialization timing; noted std::optional preserves inline storage footprint
- mzumsande (contributor, objection, 1 statements 2026-06-24 to 2026-06-24): Questioned whether making the member optional makes sense if private broadcast moves into core functionality
- fanquake (member, neutral, 1 statements 2026-08-03 to 2026-08-03): Moved PR to draft pending rebase and architectural direction on private broadcast
Dependencies
Depends on: #29415
Files
0 lines under test/bench/ci.
- src/net_processing.cpp +82/-39
- src/net_processing.h +9/-1
Card
The short text the ranking pass compares across PRs.
This PR makes PeerManagerImpl's private broadcast tracker an std::optional, constructing it only when running in private broadcast mode (-privatebroadcast=1). It addresses review feedback from the merged private broadcast PR #29415 to avoid constructing unused subsystem state by default. Because std::optional retains inline storage space on the class, memory savings are minimal while requiring defensive checks across P2P message handling paths. PR #29415 is already merged.
Data
thread read through 2026-08-03 (37 statements), head 14a241f3b3
Discussion read under schema 1 rules: suggestions and questions may be missing, and an objection may combine several harms (schema history).
labels: Needs rebase, Private Broadcast · draft
Categories
P2P
P4 · cleanup
Avoids instantiating an idle PrivateBroadcast struct when -privatebroadcast is disabled. This is a minor internal followup cleanup to #29415 with negligible runtime impact on default nodes.
Membership: Changes PeerManagerImpl in src/net_processing.cpp and src/net_processing.h under the 'Private Broadcast' label.
Factors: security/stability 0, bug 0, performance 0, user value 0, leverage 0