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>();
|