Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 3: [PATCH 03/68] feat(policy): preserve Roots relay and network controls on Core 30.3

src/rpc/net.cpp

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

File metadata
index fbb70d72161df03e81ef467cbd27af53a58fd74f..1c19ff26649731703dcf61f757b168bf966c92a1 100644

Download original patch · Release notes

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

+ Added− RemovedUnmarked lines are context.

Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/rpc/net.cpp CHANGED
@@ -148,6 +148,10 @@ static RPCHelpMan getpeerinfo()
148
  {RPCResult::Type::NUM_TIME, "last_block", "The " + UNIX_EPOCH_TIME + " of the last block received from this peer"},
149
  {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
150
  {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
 
 
 
 
151
  {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
152
  {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
153
  {RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in seconds, if any"},
@@ -162,6 +166,7 @@ static RPCHelpMan getpeerinfo()
162
  {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"},
163
  {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
164
  {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
 
165
  {RPCResult::Type::ARR, "inflight", "",
166
  {
167
  {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
@@ -173,6 +178,7 @@ static RPCHelpMan getpeerinfo()
173
  {
174
  {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"},
175
  }},
 
176
  {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
177
  {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
178
  {
@@ -192,6 +198,7 @@ static RPCHelpMan getpeerinfo()
192
  "best capture connection behaviors."},
193
  {RPCResult::Type::STR, "transport_protocol_type", "Type of transport protocol: \n" + Join(TRANSPORT_TYPE_DOC, ",\n") + ".\n"},
194
  {RPCResult::Type::STR, "session_id", "The session ID for this connection, or \"\" if there is none (\"v2\" transport protocol only).\n"},
 
195
  }},
196
  }},
197
  },
@@ -209,6 +216,7 @@ static RPCHelpMan getpeerinfo()
209
  connman.GetNodeStats(vstats);
210
 
211
  UniValue ret(UniValue::VARR);
 
212
 
213
  for (const CNodeStats& stats : vstats) {
214
  UniValue obj(UniValue::VOBJ);
@@ -244,6 +252,9 @@ static RPCHelpMan getpeerinfo()
244
  obj.pushKV("last_block", count_seconds(stats.m_last_block_time));
245
  obj.pushKV("bytessent", stats.nSendBytes);
246
  obj.pushKV("bytesrecv", stats.nRecvBytes);
 
 
 
247
  obj.pushKV("conntime", count_seconds(stats.m_connected));
248
  obj.pushKV("timeoffset", Ticks<std::chrono::seconds>(statestats.time_offset));
249
  if (stats.m_last_ping_time > 0us) {
@@ -267,6 +278,7 @@ static RPCHelpMan getpeerinfo()
267
  obj.pushKV("presynced_headers", statestats.presync_height);
268
  obj.pushKV("synced_headers", statestats.nSyncHeight);
269
  obj.pushKV("synced_blocks", statestats.nCommonHeight);
 
270
  UniValue heights(UniValue::VARR);
271
  for (const int height : statestats.vHeightInFlight) {
272
  heights.push_back(height);
@@ -280,6 +292,7 @@ static RPCHelpMan getpeerinfo()
280
  permissions.push_back(permission);
281
  }
282
  obj.pushKV("permissions", std::move(permissions));
 
283
  obj.pushKV("minfeefilter", ValueFromAmount(statestats.m_fee_filter_received));
284
 
285
  UniValue sendPerMsgType(UniValue::VOBJ);
@@ -298,6 +311,7 @@ static RPCHelpMan getpeerinfo()
298
  obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
299
  obj.pushKV("transport_protocol_type", TransportTypeAsString(stats.m_transport_type));
300
  obj.pushKV("session_id", stats.m_session_id);
 
301
 
302
  ret.push_back(std::move(obj));
303
  }
@@ -442,7 +456,7 @@ static RPCHelpMan disconnectnode()
442
  "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
443
  "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
444
  {
445
- {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"},
446
  {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"},
447
  },
448
  RPCResult{RPCResult::Type::NONE, "", ""},
@@ -463,7 +477,20 @@ static RPCHelpMan disconnectnode()
463
 
464
  if (!address_arg.isNull() && id_arg.isNull()) {
465
  /* handle disconnect-by-address */
466
- success = connman.DisconnectNode(address_arg.get_str());
 
 
 
 
 
 
 
 
 
 
 
 
 
467
  } else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
468
  /* handle disconnect-by-id */
469
  NodeId nodeid = (NodeId) id_arg.getInt<int64_t>();
 
148
  {RPCResult::Type::NUM_TIME, "last_block", "The " + UNIX_EPOCH_TIME + " of the last block received from this peer"},
149
  {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
150
  {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
151
+ {RPCResult::Type::NUM, "cpu_load", /*optional=*/true, "Total CPU time spent processing "
152
+ "messages to/from the peer, in per milles (‰) of the connection duration, if "
153
+ "supported by the platform and measured. High CPU time is not necessarily a bad "
154
+ "thing - new valid transactions and blocks require it be validated."},
155
  {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
156
  {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
157
  {RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in seconds, if any"},
 
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"},
167
  {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
168
  {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
169
+ {RPCResult::Type::NUM_TIME, "last_block_announcement", "The time of the last block announcement received from this peer, or 0 if none has been received"},
170
  {RPCResult::Type::ARR, "inflight", "",
171
  {
172
  {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
 
178
  {
179
  {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"},
180
  }},
181
+ {RPCResult::Type::BOOL, "forced_inbound", "Whether this peer forced a connection by evicting another."},
182
  {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
183
  {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
184
  {
 
198
  "best capture connection behaviors."},
199
  {RPCResult::Type::STR, "transport_protocol_type", "Type of transport protocol: \n" + Join(TRANSPORT_TYPE_DOC, ",\n") + ".\n"},
200
  {RPCResult::Type::STR, "session_id", "The session ID for this connection, or \"\" if there is none (\"v2\" transport protocol only).\n"},
201
+ {RPCResult::Type::NUM, "misbehavior_score", "The misbehavior score for this peer. Always 0, but may be 100 if the peer is about to be disconnected. (DEPRECATED)\n"},
202
  }},
203
  }},
204
  },
 
216
  connman.GetNodeStats(vstats);
217
 
218
  UniValue ret(UniValue::VARR);
219
+ const auto now{GetTime<std::chrono::seconds>()};
220
 
221
  for (const CNodeStats& stats : vstats) {
222
  UniValue obj(UniValue::VOBJ);
 
252
  obj.pushKV("last_block", count_seconds(stats.m_last_block_time));
253
  obj.pushKV("bytessent", stats.nSendBytes);
254
  obj.pushKV("bytesrecv", stats.nRecvBytes);
255
+ if (stats.m_cpu_time > 0s && now > stats.m_connected) {
256
+ obj.pushKV("cpu_load", /* ‰ */1000.0 * stats.m_cpu_time / (now - stats.m_connected));
257
+ }
258
  obj.pushKV("conntime", count_seconds(stats.m_connected));
259
  obj.pushKV("timeoffset", Ticks<std::chrono::seconds>(statestats.time_offset));
260
  if (stats.m_last_ping_time > 0us) {
 
278
  obj.pushKV("presynced_headers", statestats.presync_height);
279
  obj.pushKV("synced_headers", statestats.nSyncHeight);
280
  obj.pushKV("synced_blocks", statestats.nCommonHeight);
281
+ obj.pushKV("last_block_announcement", TicksSinceEpoch<std::chrono::seconds>(statestats.m_last_block_announcement));
282
  UniValue heights(UniValue::VARR);
283
  for (const int height : statestats.vHeightInFlight) {
284
  heights.push_back(height);
 
292
  permissions.push_back(permission);
293
  }
294
  obj.pushKV("permissions", std::move(permissions));
295
+ obj.pushKV("forced_inbound", stats.m_forced_inbound);
296
  obj.pushKV("minfeefilter", ValueFromAmount(statestats.m_fee_filter_received));
297
 
298
  UniValue sendPerMsgType(UniValue::VOBJ);
 
311
  obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
312
  obj.pushKV("transport_protocol_type", TransportTypeAsString(stats.m_transport_type));
313
  obj.pushKV("session_id", stats.m_session_id);
314
+ obj.pushKV("misbehavior_score", statestats.m_misbehavior_score);
315
 
316
  ret.push_back(std::move(obj));
317
  }
 
456
  "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
457
  "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
458
  {
459
+ {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node or subnet"},
460
  {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"},
461
  },
462
  RPCResult{RPCResult::Type::NONE, "", ""},
 
477
 
478
  if (!address_arg.isNull() && id_arg.isNull()) {
479
  /* handle disconnect-by-address */
480
+ const bool only_subnet{address_arg.get_str().find('/') != std::string::npos};
481
+ if (only_subnet) {
482
+ success = false;
483
+ } else {
484
+ success = connman.DisconnectNode(address_arg.get_str());
485
+ }
486
+ if (!success) {
487
+ const CSubNet subnet = LookupSubNet(address_arg.get_str());
488
+ if (subnet.IsValid()) {
489
+ success = connman.DisconnectNode(subnet);
490
+ } else if (only_subnet) {
491
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid subnet");
492
+ }
493
+ }
494
  } else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
495
  /* handle disconnect-by-id */
496
  NodeId nodeid = (NodeId) id_arg.getInt<int64_t>();