Skip to content
Bitcoin Roots

v31.1-roots.1 · Commit 5: [PATCH 05/17] feat(net): preserve Roots peer controls and health view on v31

src/rpc/net.cpp

Before: src/rpc/net.cpp · After: src/rpc/net.cpp

File metadata
index e9fbd31cc3c830009f3ae3c3fefd2726996dc3d0..d6903f6d3b3010ddbf4d685bd7732a125ade0db5 100644

Download original patch · Release notes

Diff rows 1–90 of 90. Line numbers refer to the original before/after files.

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.

src/rpc/net.cpp CHANGED
@@ -151,6 +151,7 @@ static RPCHelpMan getpeerinfo()
151
151
  {RPCResult::Type::NUM_TIME, "last_block", "The " + UNIX_EPOCH_TIME + " of the last block received from this peer"},
152
152
  {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
153
153
  {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
154
+ {RPCResult::Type::NUM, "cpu_load", /*optional=*/true, "Current connection message-processing CPU time in per mille of connection duration; omitted if measurement or positive duration is unavailable"},
154
155
  {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
155
156
  {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
156
157
  {RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in seconds, if any"},
@@ -165,6 +166,7 @@ static RPCHelpMan getpeerinfo()
165
166
  {RPCResult::Type::NUM, "presynced_headers", "The current height of header pre-synchronization with this peer, or -1 if no low-work sync is in progress"},
166
167
  {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
167
168
  {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
169
+ {RPCResult::Type::NUM_TIME, "last_block_announcement", "Time of the last block announcement received from this peer, or 0"},
168
170
  {RPCResult::Type::ARR, "inflight", "",
169
171
  {
170
172
  {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
@@ -176,6 +178,7 @@ static RPCHelpMan getpeerinfo()
176
178
  {
177
179
  {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"},
178
180
  }},
181
+ {RPCResult::Type::BOOL, "forced_inbound", "Whether this inbound connection displaced another peer"},
179
182
  {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
180
183
  {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
181
184
  {
@@ -194,6 +197,7 @@ static RPCHelpMan getpeerinfo()
194
197
  "Please note this output is unlikely to be stable in upcoming releases as we iterate to\n"
195
198
  "best capture connection behaviors."},
196
199
  {RPCResult::Type::STR, "transport_protocol_type", "Type of transport protocol: \n" + Join(TRANSPORT_TYPE_DOC, ",\n") + ".\n"},
200
+ {RPCResult::Type::NUM, "misbehavior_score", "Deprecated: 0, or 100 if discouragement is pending"},
197
201
  {RPCResult::Type::STR, "session_id", "The session ID for this connection, or \"\" if there is none (\"v2\" transport protocol only).\n"},
198
202
  }},
199
203
  }},
@@ -213,6 +217,7 @@ static RPCHelpMan getpeerinfo()
213
217
 
214
218
  UniValue ret(UniValue::VARR);
215
219
 
220
+ const auto now{GetTime<std::chrono::seconds>()};
216
221
  for (const CNodeStats& stats : vstats) {
217
222
  UniValue obj(UniValue::VOBJ);
218
223
  CNodeStateStats statestats;
@@ -249,6 +254,9 @@ static RPCHelpMan getpeerinfo()
249
254
  obj.pushKV("last_block", count_seconds(stats.m_last_block_time));
250
255
  obj.pushKV("bytessent", stats.nSendBytes);
251
256
  obj.pushKV("bytesrecv", stats.nRecvBytes);
257
+ if (stats.m_cpu_time > 0ns && now > stats.m_connected) {
258
+ obj.pushKV("cpu_load", 1000.0 * stats.m_cpu_time / (now - stats.m_connected));
259
+ }
252
260
  obj.pushKV("conntime", count_seconds(stats.m_connected));
253
261
  obj.pushKV("timeoffset", Ticks<std::chrono::seconds>(statestats.time_offset));
254
262
  if (stats.m_last_ping_time > 0us) {
@@ -274,6 +282,7 @@ static RPCHelpMan getpeerinfo()
274
282
  obj.pushKV("presynced_headers", statestats.presync_height);
275
283
  obj.pushKV("synced_headers", statestats.nSyncHeight);
276
284
  obj.pushKV("synced_blocks", statestats.nCommonHeight);
285
+ obj.pushKV("last_block_announcement", count_seconds(statestats.m_last_block_announcement));
277
286
  UniValue heights(UniValue::VARR);
278
287
  for (const int height : statestats.vHeightInFlight) {
279
288
  heights.push_back(height);
@@ -287,6 +296,7 @@ static RPCHelpMan getpeerinfo()
287
296
  permissions.push_back(permission);
288
297
  }
289
298
  obj.pushKV("permissions", std::move(permissions));
299
+ obj.pushKV("forced_inbound", stats.m_forced_inbound);
290
300
  obj.pushKV("minfeefilter", ValueFromAmount(statestats.m_fee_filter_received));
291
301
 
292
302
  UniValue sendPerMsgType(UniValue::VOBJ);
@@ -305,6 +315,7 @@ static RPCHelpMan getpeerinfo()
305
315
  obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
306
316
  obj.pushKV("transport_protocol_type", TransportTypeAsString(stats.m_transport_type));
307
317
  obj.pushKV("session_id", stats.m_session_id);
318
+ obj.pushKV("misbehavior_score", statestats.m_misbehavior_score);
308
319
 
309
320
  ret.push_back(std::move(obj));
310
321
  }
@@ -455,7 +466,7 @@ static RPCHelpMan disconnectnode()
455
466
  "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
456
467
  "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
457
468
  {
458
- {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"},
469
+ {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port or subnet of the node(s)"},
459
470
  {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"},
460
471
  },
461
472
  RPCResult{RPCResult::Type::NONE, "", ""},
@@ -476,7 +487,16 @@ static RPCHelpMan disconnectnode()
476
487
 
477
488
  if (address && !node_id) {
478
489
  /* handle disconnect-by-address */
479
- success = connman.DisconnectNode(*address);
490
+ const bool only_subnet{address->find('/') != std::string::npos};
491
+ success = !only_subnet && connman.DisconnectNode(*address);
492
+ if (!success) {
493
+ const CSubNet subnet{LookupSubNet(std::string{*address})};
494
+ if (subnet.IsValid()) {
495
+ success = connman.DisconnectNode(subnet);
496
+ } else if (only_subnet) {
497
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid subnet");
498
+ }
499
+ }
480
500
  } else if (node_id && (!address || address->empty())) {
481
501
  /* handle disconnect-by-id */
482
502
  success = connman.DisconnectNode(*node_id);