mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 22:50:59 +01:00
Merge #19658: [rpc] Allow RPC to fetch all addrman records and add records to addrman
37a480e0cd[net] Add addpeeraddress RPC method (John Newbery)ae8051bbd8[test] Test that getnodeaddresses() can return all known addresses (John Newbery)f26502e9fc[addrman] Specify max addresses and pct when calling GetAddresses() (John Newbery) Pull request description: Currently addrman only allows a maximum of 1000 records or 23% of all records to be returned in a call to `GetAddr()`. Relax this limit and have the client specify the max records they want. For p2p, behaviour is unchanged (but the rate limiting is set inside net_processing, where it belongs). For RPC, `getnodeaddresses` can now return the complete addrman, which is helpful for testing and monitoring. Also add a test-only RPC `addpeeraddress`, which adds an IP address:port to addrman. This is helpful for testing (eg #18991). ACKs for top commit: naumenkogs: utACK37a480e0cdlaanwj: Code review and lightly manually tested ACK37a480e0cdTree-SHA512: f86dcd410aaebaf6e9ca18ce6f23556e5e4649c1325577213d873aa09967298e65ab2dc19a72670641ae92211a923afda1fe124a82e9d2c1cad73d478ef27fdc
This commit is contained in:
@@ -727,7 +727,7 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
|
||||
RPCHelpMan{"getnodeaddresses",
|
||||
"\nReturn known addresses which can potentially be used to find new nodes in the network\n",
|
||||
{
|
||||
{"count", RPCArg::Type::NUM, /* default */ "1", "How many addresses to return. Limited to the smaller of " + ToString(ADDRMAN_GETADDR_MAX) + " or " + ToString(ADDRMAN_GETADDR_MAX_PCT) + "% of all known addresses."},
|
||||
{"count", RPCArg::Type::NUM, /* default */ "1", "The maximum number of addresses to return. Specify 0 to return all known addresses."},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::ARR, "", "",
|
||||
@@ -754,18 +754,16 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
|
||||
int count = 1;
|
||||
if (!request.params[0].isNull()) {
|
||||
count = request.params[0].get_int();
|
||||
if (count <= 0) {
|
||||
if (count < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
|
||||
}
|
||||
}
|
||||
// returns a shuffled list of CAddress
|
||||
std::vector<CAddress> vAddr = node.connman->GetAddresses();
|
||||
std::vector<CAddress> vAddr = node.connman->GetAddresses(count, /* max_pct */ 0);
|
||||
UniValue ret(UniValue::VARR);
|
||||
|
||||
int address_return_count = std::min<int>(count, vAddr.size());
|
||||
for (int i = 0; i < address_return_count; ++i) {
|
||||
for (const CAddress& addr : vAddr) {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
const CAddress& addr = vAddr[i];
|
||||
obj.pushKV("time", (int)addr.nTime);
|
||||
obj.pushKV("services", (uint64_t)addr.nServices);
|
||||
obj.pushKV("address", addr.ToStringIP());
|
||||
@@ -775,6 +773,54 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static UniValue addpeeraddress(const JSONRPCRequest& request)
|
||||
{
|
||||
RPCHelpMan{"addpeeraddress",
|
||||
"\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n",
|
||||
{
|
||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The IP address of the peer"},
|
||||
{"port", RPCArg::Type::NUM, RPCArg::Optional::NO, "The port of the peer"},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::OBJ, "", "",
|
||||
{
|
||||
{RPCResult::Type::BOOL, "success", "whether the peer address was successfully added to the address manager"},
|
||||
},
|
||||
},
|
||||
RPCExamples{
|
||||
HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 8333")
|
||||
+ HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 8333")
|
||||
},
|
||||
}.Check(request);
|
||||
|
||||
NodeContext& node = EnsureNodeContext(request.context);
|
||||
if (!node.connman) {
|
||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||
}
|
||||
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
|
||||
std::string addr_string = request.params[0].get_str();
|
||||
uint16_t port = request.params[1].get_int();
|
||||
|
||||
CNetAddr net_addr;
|
||||
if (!LookupHost(addr_string, net_addr, false)) {
|
||||
obj.pushKV("success", false);
|
||||
return obj;
|
||||
}
|
||||
CAddress address = CAddress({net_addr, port}, ServiceFlags(NODE_NETWORK|NODE_WITNESS));
|
||||
address.nTime = GetAdjustedTime();
|
||||
// The source address is set equal to the address. This is equivalent to the peer
|
||||
// announcing itself.
|
||||
if (!node.connman->AddNewAddresses({address}, address)) {
|
||||
obj.pushKV("success", false);
|
||||
return obj;
|
||||
}
|
||||
|
||||
obj.pushKV("success", true);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void RegisterNetRPCCommands(CRPCTable &t)
|
||||
{
|
||||
// clang-format off
|
||||
@@ -794,6 +840,7 @@ static const CRPCCommand commands[] =
|
||||
{ "network", "clearbanned", &clearbanned, {} },
|
||||
{ "network", "setnetworkactive", &setnetworkactive, {"state"} },
|
||||
{ "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
|
||||
{ "hidden", "addpeeraddress", &addpeeraddress, {"address", "port"} },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
Reference in New Issue
Block a user