rpc/net: add per-peer inv_to_send sizes
What changed, and why it matters
This commit adds a new read-only diagnostic field called 'inv_to_send' to the getpeerinfo RPC output. It simply reports how many transaction announcements are queued for each peer. There is no change to network behavior, transaction relay logic, or access controls.
No security action needed. This is a benign observability enhancement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch exposes the size of tx_relay->m_tx_inventory_to_send through CNodeStateStats and the getpeerinfo RPC. It is purely observability/instrumentation: it adds a field to the stats struct, populates it under the existing m_tx_inventory_mutex lock, documents it in RPC help, and updates the functional test’s expected output. No logic that modifies the inventory queue or peer handling is changed.
Changed components
src/net_processing.cppsrc/net_processing.hsrc/rpc/net.cpptest/functional/rpc_net.pyInspect captured patch +6 / −0
diff --git a/src/net_processing.cpp b/src/net_processing.cpp
index ec6f55cf..373169c0 100644
--- a/src/net_processing.cpp
+++ b/src/net_processing.cpp
@@ -1728,9 +1728,11 @@ bool PeerManagerImpl::GetNodeStateStats(NodeId nodeid, CNodeStateStats& stats) c
if (auto tx_relay = peer->GetTxRelay(); tx_relay != nullptr) {
stats.m_relay_txs = WITH_LOCK(tx_relay->m_bloom_filter_mutex, return tx_relay->m_relay_txs);
stats.m_fee_filter_received = tx_relay->m_fee_filter_received.load();
+ stats.m_inv_to_send = WITH_LOCK(tx_relay->m_tx_inventory_mutex, return tx_relay->m_tx_inventory_to_send.size());
} else {
stats.m_relay_txs = false;
stats.m_fee_filter_received = 0;
+ stats.m_inv_to_send = 0;
}
stats.m_ping_wait = ping_wait;
diff --git a/src/net_processing.h b/src/net_processing.h
index 8c140d98..ee12bd08 100644
--- a/src/net_processing.h
+++ b/src/net_processing.h
@@ -54,6 +54,7 @@ struct CNodeStateStats {
std::chrono::microseconds m_ping_wait;
std::vector<int> vHeightInFlight;
bool m_relay_txs;
+ int m_inv_to_send = 0;
CAmount m_fee_filter_received;
uint64_t m_addr_processed = 0;
uint64_t m_addr_rate_limited = 0;
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index fbb70d72..e5b9880a 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -142,6 +142,7 @@ static RPCHelpMan getpeerinfo()
{RPCResult::Type::STR, "SERVICE_NAME", "the service name if it is recognised"}
}},
{RPCResult::Type::BOOL, "relaytxes", "Whether we relay transactions to this peer"},
+ {RPCResult::Type::NUM, "inv_to_send", "How many txs we have queued to announce to this peer"},
{RPCResult::Type::NUM_TIME, "lastsend", "The " + UNIX_EPOCH_TIME + " of the last send"},
{RPCResult::Type::NUM_TIME, "lastrecv", "The " + UNIX_EPOCH_TIME + " of the last receive"},
{RPCResult::Type::NUM_TIME, "last_transaction", "The " + UNIX_EPOCH_TIME + " of the last valid transaction received from this peer"},
@@ -238,6 +239,7 @@ static RPCHelpMan getpeerinfo()
obj.pushKV("services", strprintf("%016x", services));
obj.pushKV("servicesnames", GetServicesNames(services));
obj.pushKV("relaytxes", statestats.m_relay_txs);
+ obj.pushKV("inv_to_send", statestats.m_inv_to_send);
obj.pushKV("lastsend", count_seconds(stats.m_last_send));
obj.pushKV("lastrecv", count_seconds(stats.m_last_recv));
obj.pushKV("last_transaction", count_seconds(stats.m_last_tx_time));
diff --git a/test/functional/rpc_net.py b/test/functional/rpc_net.py
index 41ecbbed..f52d59d7 100755
--- a/test/functional/rpc_net.py
+++ b/test/functional/rpc_net.py
@@ -166,6 +166,7 @@ class NetTest(BitcoinTestFramework):
"permissions": [],
"presynced_headers": -1,
"relaytxes": False,
+ "inv_to_send": 0,
"services": "0000000000000000",
"servicesnames": [],
"session_id": "" if not self.options.v2transport else no_version_peer.v2_state.peer['session_id'].hex(),
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.