v29.4-roots.3 · Commit 3: [PATCH 03/30] 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>();
|