#29418 rpc: provide per message stats for global traffic via new field in 'getnettotals'

ReviewabilityReviewsAgreementSize
#29418 vasild rpc: provide per message stats for global traffic via new field in 'getnettotals'Ready0 (+1)Strong354 + 150 tests
  • Expose cumulative message and byte statistics broken down by direction, network, and connection type
  • Allows node operators and researchers to monitor network bandwidth without continuously polling peer stats
  • Ready for review
  • Tested on node monitoring dashboards with positive feedback (waketraindev)
  • Support for exposing detailed message metrics with minimal RPC layer logic (stickies-v)
  • Objection to server-side aggregation resolved by dropping the aggregation commit (stickies-v)
  • Concept approval without detailed rationale (danielabrozzoni, epiccurious)
  • 354 lines added or modified outside tests
  • 150 lines added or modified in tests
  • 14 lines removed in total
  • 8 files, 3 commits
P2P#55 of 71
P3 · user request
  • P3 because it adds cumulative message accounting without altering relay protocols or connection logic
  • Introduces atomic counters to message send and receive paths without changing peer behavior
  • Ranking pass: Operator observability ranks below behavioural fixes and structural work in this band.
RPC / REST / ZMQ#34 of 55
P3 · user request
  • P3 because it fulfills a user request by adding detailed message breakdowns to getnettotals
  • Saves node operators from having to poll and aggregate transient per-peer statistics
  • Ranking pass: Moved down 16: new aggregate statistics field with no evidence of a downstream consumer waiting on it beyond the originating issue.
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 global network traffic accounting in `CConnman` across node lifetime using a lock-free multidimensional array of atomic counters (`NetStats`). Exposes message count and byte totals broken down by direction, network protocol, connection type, and message type via a new `detailed` field in the `getnettotals` RPC.

Problem: Per-message network traffic statistics are currently only tracked on individual `CNode` instances and discarded when peers disconnect. Node operators and researchers cannot observe cumulative bandwidth consumption across message types, connection types, and network types over the node's uptime without continuous polling.

Evidence of importance:

  • Implements feature request #26337: 'Add per message stats to getnettotals rpc'.
  • Follows up on previous attempts #27534 and #28926 that sought to introduce network message statistics.

Scope: Implements accounting through fixed-size nested `std::array` instances indexed by enums with `std::atomic_uint64_t` counters to avoid mutex contention on socket send/receive paths.

Risk of a mistake: medium (p2p, rpc_api). Increases work and adds tracking calls in the P2P send/receive loops, and adds a potentially large nested JSON structure to the `getnettotals` RPC output.

Changed since the previous assessment: Switched from exposing statistics through a dedicated new `getnetmsgstats` RPC command to nesting them within a new `detailed` field inside the existing `getnettotals` RPC.

Reviewability

Ready

Nothing known that would invalidate a review now.

Waiting on (from the thread read):

  • reviewer: review of the updated PR after author declared it ready 2026-10-20

Agreement

Strong

substantive support, no open objection (waketraindev, waketraindev, stickies-v)

Thread notes: Author marked the pull request ready for review and pinged reviewers.

Objections, suggestions, and questions:

ReviewerTypeHarm, request, or questionStatusMust beAuthor repliedQuote
jonatack (member)question, maintenanceWhether there would be benefit to moving the NetStats class outside of net.{h,cpp} given its size.answered · Author replied having no opinionansweredyes2024-10-11: 'Would there be any benefit to moving this class outside of `net.{h,cpp}`? It's quite a lot of code.'
Status from: 2024-10-28: vasild: 'No opinion.'
jonatack (member)question, maintenanceWhether the ConnectionType utility methods should be moved to node/connection_types.{h,cpp} for wider reuse.answered · Author explained they are private internal index conversionsansweredyes2024-10-11: 'Would it make sense to put these 2 `ConnectionType` utility methods in `node/connection_types.{h,cpp}` where they could be more widely used?'
Status from: 2024-10-28: vasild: 'These are to/from "index". By "index" here I mean the index in some array that is private in `NetStats`.'
danielabrozzoni (member)question, correctnessasks if test code contains debug leftoversfixed · fix pushed · author confirmed and removed in pushansweredyes2026-02-10: 'Debug leftovers?'
Status from: 2026-05-18: vasild: 'Yes, removed.'
stickies-v (member)objection, interfaceAdding server-side aggregation options increases interface and code complexity and binds the project to backward-compatibility guarantees for formatting users can easily perform client-side.fixed · fix pushed · Author dropped the aggregation commit and updated testschangedyes2026-05-22: 'I quite strongly opppose the aggregation option, just a simple `bitcoin-cli getnetmsgstats` provides a user all the info they need. Visualization/aggregation can easily be done by the user, e.g. using'
Status from: 2026-06-12: vasild: 'I have now dropped the aggregation, which means removing commit d5a1ad981b `rpc: make it possible to aggregate the resul'

Support:

  • epiccurious (contributor) (Concept ACK, 2024-02-11): Concept ACK 91c90d759503aa3fa15b330bba2148698cdc271d. [not substantive]
  • waketraindev (contributor) (Concept ACK, 2025-12-29): Useful netstats for tracking. Normally, I'd sum and aggregate peer stats. This approach simplifies that.
  • waketraindev (contributor) (ACK, 2025-12-29) [tested]: lgtm. Tested on master and with v30.1 in my node monitoring dashboard.
  • danielabrozzoni (member) (Concept ACK, 2026-02-10) [read]: Concept ACK, reviewed up to 5ad1f5d83e1f8dddde90c81dab264df0d5e0dc5c, I still haven't finished the review of the last commit [not substantive]
  • stickies-v (member) (Concept ACK, 2026-05-22) [read]: Seems like useful info to expose. Approach-wise, I like that it adds very little logic in the RPC layer.

Participants:

  • epiccurious (contributor, support, 1 statements 2024-02-11 to 2024-02-11): Concept ACK
  • 0xB10C (member, neutral, 1 statements 2024-04-09 to 2024-04-09): noted existing tracepoints and operator use cases
  • jonatack (member, question, 9 statements 2024-10-10 to 2024-10-11): reviewed code and tests, asked about class and utility method placement
  • satsie (contributor, neutral, 1 statements 2024-10-11 to 2024-10-11): explained 4D array layout formatting
  • maflcko (member, neutral, 4 statements 2025-01-23 to 2026-05-22): style nits on RPC argument formatting and CI failure fix
  • waketraindev (contributor, support, 2 statements 2025-12-29 to 2025-12-29): Concept ACK and Tested ACK with node monitoring dashboard
  • danielabrozzoni (member, support, 3 statements 2026-02-10 to 2026-02-10): Concept ACK and review comments
  • sedited (member, neutral, 4 statements 2026-03-09 to 2026-09-22): asked if author is still working on PR and pinged for rebase
  • stickies-v (member, objection, 1 statements 2026-05-22 to 2026-05-22): Concept ACK, but objected to server-side aggregation

Files

156 lines under test/bench/ci.

  • src/net.cpp +177/-3
  • test/functional/rpc_net.py +143/-0
  • src/net.h +85/-2
  • src/rpc/net.cpp +84/-0
  • src/node/connection_types.h +8/-3
  • src/test/util/net.cpp +3/-3
  • src/test/util/net.h +2/-2
  • src/test/fuzz/net.cpp +2/-1

Card

The short text the ranking pass compares across PRs.

Adds global network message statistics collection to `CConnman` and exposes it through a new `detailed` field in the `getnettotals` RPC. Previously, per-message traffic stats existed only on active peer objects and were lost on disconnection, leaving operators without aggregate visibility into lifetime bandwidth usage by message type, network, and connection type. This resolves issue #26337 following earlier PRs #27534 and #28926. Counters use a static multidimensional array of atomics to prevent lock contention on the P2P hot path.

Data

dossier JSON · extract JSON · model ledger, generated 2026-10-21T01:17, confidence high, input hash ef42c43aa880aac8
thread read through 2026-10-20 (55 statements), head f33bcc5fd6
labels: RPC/REST/ZMQ

Categories

P2P

P3 · user request (ranking pass: Operator observability ranks below behavioural fixes and structural work in this band.)

The change adds global lifetime message accounting to CConnman to observe bandwidth consumption without polling peer stats. While it introduces atomic counters to the message send and receive paths reviewed by P2P maintainers, it does not alter peer relay protocols, connection logic, or DoS defenses.

Membership: Adds cumulative network traffic accounting across message, connection, and network types directly into CConnman (`src/net.cpp` and `src/net.h`).

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

RPC / REST / ZMQ

P3 · user request (ranking pass: Moved down 16: new aggregate statistics field with no evidence of a downstream consumer waiting on it beyond the originating issue.)

Exposes cumulative message and byte totals in `getnettotals` to satisfy longstanding feature request #26337. Reviewer comments confirm it eliminates existing operator workarounds of polling and aggregating transient per-peer stats for node monitoring dashboards.

Membership: Landed under the `RPC/REST/ZMQ` label, adding a `detailed` breakdown field to the `getnettotals` RPC in `src/rpc/net.cpp`.

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