mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-11 22:50:59 +01:00
[rpc] Add getnodeaddresses RPC command
New getnodeaddresses call gives access via RPC to the peers known by the node. It may be useful for bitcoin wallets to broadcast their transactions over tor for improved privacy without using the centralized DNS seeds. getnodeaddresses is very similar to the getaddr p2p method. Tests the new rpc call by feeding IP address to a test node via the p2p protocol, then obtaining someone of those addresses with getnodeaddresses and checking that they are a subset.
This commit is contained in:
@@ -626,6 +626,58 @@ static UniValue setnetworkactive(const JSONRPCRequest& request)
|
||||
return g_connman->GetNetworkActive();
|
||||
}
|
||||
|
||||
static UniValue getnodeaddresses(const JSONRPCRequest& request)
|
||||
{
|
||||
if (request.fHelp || request.params.size() > 1) {
|
||||
throw std::runtime_error(
|
||||
"getnodeaddresses ( count )\n"
|
||||
"\nReturn known addresses which can potentially be used to find new nodes in the network\n"
|
||||
"\nArguments:\n"
|
||||
"1. \"count\" (numeric, optional) How many addresses to return. Limited to the smaller of " + std::to_string(ADDRMAN_GETADDR_MAX) +
|
||||
" or " + std::to_string(ADDRMAN_GETADDR_MAX_PCT) + "% of all known addresses. (default = 1)\n"
|
||||
"\nResult:\n"
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"time\": ttt, (numeric) Timestamp in seconds since epoch (Jan 1 1970 GMT) keeping track of when the node was last seen\n"
|
||||
" \"services\": n, (numeric) The services offered\n"
|
||||
" \"address\": \"host\", (string) The address of the node\n"
|
||||
" \"port\": n (numeric) The port of the node\n"
|
||||
" }\n"
|
||||
" ,....\n"
|
||||
"]\n"
|
||||
"\nExamples:\n"
|
||||
+ HelpExampleCli("getnodeaddresses", "8")
|
||||
+ HelpExampleRpc("getnodeaddresses", "8")
|
||||
);
|
||||
}
|
||||
if (!g_connman) {
|
||||
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
if (!request.params[0].isNull()) {
|
||||
count = request.params[0].get_int();
|
||||
if (count <= 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range");
|
||||
}
|
||||
}
|
||||
// returns a shuffled list of CAddress
|
||||
std::vector<CAddress> vAddr = g_connman->GetAddresses();
|
||||
UniValue ret(UniValue::VARR);
|
||||
|
||||
int address_return_count = std::min<int>(count, vAddr.size());
|
||||
for (int i = 0; i < address_return_count; ++i) {
|
||||
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());
|
||||
obj.pushKV("port", addr.GetPort());
|
||||
ret.push_back(obj);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) argNames
|
||||
@@ -642,6 +694,7 @@ static const CRPCCommand commands[] =
|
||||
{ "network", "listbanned", &listbanned, {} },
|
||||
{ "network", "clearbanned", &clearbanned, {} },
|
||||
{ "network", "setnetworkactive", &setnetworkactive, {"state"} },
|
||||
{ "network", "getnodeaddresses", &getnodeaddresses, {"count"} },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
Reference in New Issue
Block a user