Skip to content
Bitcoin Roots

v29.4-roots.1 · Commit 3: [PATCH 03/13] policy: restore conservative relay and network controls

src/rpc/net.cpp

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

File metadata
index 9942386c7fc0a990039723c331e5fa4710160eb4..69b7c82da345dbfebbade8b6ec33397f5947892a 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. The two line-number columns refer to before and after.

src/rpc/net.cpp CHANGED
@@ -143,6 +143,10 @@ static RPCHelpMan getpeerinfo()
143
143
  {RPCResult::Type::NUM_TIME, "last_block", "The " + UNIX_EPOCH_TIME + " of the last block received from this peer"},
144
144
  {RPCResult::Type::NUM, "bytessent", "The total bytes sent"},
145
145
  {RPCResult::Type::NUM, "bytesrecv", "The total bytes received"},
146
+ {RPCResult::Type::NUM, "cpu_load", /*optional=*/true, "Total CPU time spent processing "
147
+ "messages to/from the peer, in per milles (‰) of the connection duration, if "
148
+ "supported by the platform and measured. High CPU time is not necessarily a bad "
149
+ "thing - new valid transactions and blocks require it be validated."},
146
150
  {RPCResult::Type::NUM_TIME, "conntime", "The " + UNIX_EPOCH_TIME + " of the connection"},
147
151
  {RPCResult::Type::NUM, "timeoffset", "The time offset in seconds"},
148
152
  {RPCResult::Type::NUM, "pingtime", /*optional=*/true, "The last ping time in seconds, if any"},
@@ -157,6 +161,7 @@ static RPCHelpMan getpeerinfo()
157
161
  {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"},
158
162
  {RPCResult::Type::NUM, "synced_headers", "The last header we have in common with this peer"},
159
163
  {RPCResult::Type::NUM, "synced_blocks", "The last block we have in common with this peer"},
164
+ {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"},
160
165
  {RPCResult::Type::ARR, "inflight", "",
161
166
  {
162
167
  {RPCResult::Type::NUM, "n", "The heights of blocks we're currently asking from this peer"},
@@ -168,6 +173,7 @@ static RPCHelpMan getpeerinfo()
168
173
  {
169
174
  {RPCResult::Type::STR, "permission_type", Join(NET_PERMISSIONS_DOC, ",\n") + ".\n"},
170
175
  }},
176
+ {RPCResult::Type::BOOL, "forced_inbound", "Whether this peer forced a connection by evicting another."},
171
177
  {RPCResult::Type::NUM, "minfeefilter", "The minimum fee rate for transactions this peer accepts"},
172
178
  {RPCResult::Type::OBJ_DYN, "bytessent_per_msg", "",
173
179
  {
@@ -187,6 +193,7 @@ static RPCHelpMan getpeerinfo()
187
193
  "best capture connection behaviors."},
188
194
  {RPCResult::Type::STR, "transport_protocol_type", "Type of transport protocol: \n" + Join(TRANSPORT_TYPE_DOC, ",\n") + ".\n"},
189
195
  {RPCResult::Type::STR, "session_id", "The session ID for this connection, or \"\" if there is none (\"v2\" transport protocol only).\n"},
196
+ {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"},
190
197
  }},
191
198
  }},
192
199
  },
@@ -204,6 +211,7 @@ static RPCHelpMan getpeerinfo()
204
211
  connman.GetNodeStats(vstats);
205
212
 
206
213
  UniValue ret(UniValue::VARR);
214
+ const auto now{GetTime<std::chrono::seconds>()};
207
215
 
208
216
  for (const CNodeStats& stats : vstats) {
209
217
  UniValue obj(UniValue::VOBJ);
@@ -239,6 +247,9 @@ static RPCHelpMan getpeerinfo()
239
247
  obj.pushKV("last_block", count_seconds(stats.m_last_block_time));
240
248
  obj.pushKV("bytessent", stats.nSendBytes);
241
249
  obj.pushKV("bytesrecv", stats.nRecvBytes);
250
+ if (stats.m_cpu_time > 0s && now > stats.m_connected) {
251
+ obj.pushKV("cpu_load", /* ‰ */1000.0 * stats.m_cpu_time / (now - stats.m_connected));
252
+ }
242
253
  obj.pushKV("conntime", count_seconds(stats.m_connected));
243
254
  obj.pushKV("timeoffset", Ticks<std::chrono::seconds>(statestats.time_offset));
244
255
  if (stats.m_last_ping_time > 0us) {
@@ -262,6 +273,7 @@ static RPCHelpMan getpeerinfo()
262
273
  obj.pushKV("presynced_headers", statestats.presync_height);
263
274
  obj.pushKV("synced_headers", statestats.nSyncHeight);
264
275
  obj.pushKV("synced_blocks", statestats.nCommonHeight);
276
+ obj.pushKV("last_block_announcement", TicksSinceEpoch<std::chrono::seconds>(statestats.m_last_block_announcement));
265
277
  UniValue heights(UniValue::VARR);
266
278
  for (const int height : statestats.vHeightInFlight) {
267
279
  heights.push_back(height);
@@ -275,6 +287,7 @@ static RPCHelpMan getpeerinfo()
275
287
  permissions.push_back(permission);
276
288
  }
277
289
  obj.pushKV("permissions", std::move(permissions));
290
+ obj.pushKV("forced_inbound", stats.m_forced_inbound);
278
291
  obj.pushKV("minfeefilter", ValueFromAmount(statestats.m_fee_filter_received));
279
292
 
280
293
  UniValue sendPerMsgType(UniValue::VOBJ);
@@ -293,6 +306,7 @@ static RPCHelpMan getpeerinfo()
293
306
  obj.pushKV("connection_type", ConnectionTypeAsString(stats.m_conn_type));
294
307
  obj.pushKV("transport_protocol_type", TransportTypeAsString(stats.m_transport_type));
295
308
  obj.pushKV("session_id", stats.m_session_id);
309
+ obj.pushKV("misbehavior_score", statestats.m_misbehavior_score);
296
310
 
297
311
  ret.push_back(std::move(obj));
298
312
  }
@@ -434,7 +448,7 @@ static RPCHelpMan disconnectnode()
434
448
  "\nStrictly one out of 'address' and 'nodeid' can be provided to identify the node.\n"
435
449
  "\nTo disconnect by nodeid, either set 'address' to the empty string, or call using the named 'nodeid' argument only.\n",
436
450
  {
437
- {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node"},
451
+ {"address", RPCArg::Type::STR, RPCArg::DefaultHint{"fallback to nodeid"}, "The IP address/port of the node or subnet"},
438
452
  {"nodeid", RPCArg::Type::NUM, RPCArg::DefaultHint{"fallback to address"}, "The node ID (see getpeerinfo for node IDs)"},
439
453
  },
440
454
  RPCResult{RPCResult::Type::NONE, "", ""},
@@ -455,7 +469,20 @@ static RPCHelpMan disconnectnode()
455
469
 
456
470
  if (!address_arg.isNull() && id_arg.isNull()) {
457
471
  /* handle disconnect-by-address */
458
- success = connman.DisconnectNode(address_arg.get_str());
472
+ const bool only_subnet{address_arg.get_str().find('/') != std::string::npos};
473
+ if (only_subnet) {
474
+ success = false;
475
+ } else {
476
+ success = connman.DisconnectNode(address_arg.get_str());
477
+ }
478
+ if (!success) {
479
+ const CSubNet subnet = LookupSubNet(address_arg.get_str());
480
+ if (subnet.IsValid()) {
481
+ success = connman.DisconnectNode(subnet);
482
+ } else if (only_subnet) {
483
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid subnet");
484
+ }
485
+ }
459
486
  } else if (!id_arg.isNull() && (address_arg.isNull() || (address_arg.isStr() && address_arg.get_str().empty()))) {
460
487
  /* handle disconnect-by-id */
461
488
  NodeId nodeid = (NodeId) id_arg.getInt<int64_t>();