| 845 | } |
| 846 | |
| 847 | static RPCHelpMan getnodeaddresses() |
| 848 | { |
| 849 | return RPCHelpMan{"getnodeaddresses", |
| 850 | "Return known addresses, after filtering for quality and recency.\n" |
| 851 | "These can potentially be used to find new peers in the network.\n" |
| 852 | "The total number of addresses known to the node may be higher.", |
| 853 | { |
| 854 | {"count", RPCArg::Type::NUM, RPCArg::Default{1}, "The maximum number of addresses to return. Specify 0 to return all known addresses."}, |
| 855 | {"network", RPCArg::Type::STR, RPCArg::DefaultHint{"all networks"}, "Return only addresses of the specified network. Can be one of: " + Join(GetNetworkNames(), ", ") + "."}, |
| 856 | }, |
| 857 | RPCResult{ |
| 858 | RPCResult::Type::ARR, "", "", |
| 859 | { |
| 860 | {RPCResult::Type::OBJ, "", "", |
| 861 | { |
| 862 | {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"}, |
| 863 | {RPCResult::Type::NUM, "services", "The services offered by the node"}, |
| 864 | {RPCResult::Type::STR, "address", "The address of the node"}, |
| 865 | {RPCResult::Type::NUM, "port", "The port number of the node"}, |
| 866 | {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") the node connected through"}, |
| 867 | }}, |
| 868 | } |
| 869 | }, |
| 870 | RPCExamples{ |
| 871 | HelpExampleCli("getnodeaddresses", "8") |
| 872 | + HelpExampleCli("getnodeaddresses", "4 \"i2p\"") |
| 873 | + HelpExampleCli("-named getnodeaddresses", "network=onion count=12") |
| 874 | + HelpExampleRpc("getnodeaddresses", "8") |
| 875 | + HelpExampleRpc("getnodeaddresses", "4, \"i2p\"") |
| 876 | }, |
| 877 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 878 | { |
| 879 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 880 | const CConnman& connman = EnsureConnman(node); |
| 881 | |
| 882 | const int count{request.params[0].isNull() ? 1 : request.params[0].get_int()}; |
| 883 | if (count < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range"); |
| 884 | |
| 885 | const std::optional<Network> network{request.params[1].isNull() ? std::nullopt : std::optional<Network>{ParseNetwork(request.params[1].get_str())}}; |
| 886 | if (network == NET_UNROUTABLE) { |
| 887 | throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Network not recognized: %s", request.params[1].get_str())); |
| 888 | } |
| 889 | |
| 890 | // returns a shuffled list of CAddress |
| 891 | const std::vector<CAddress> vAddr{connman.GetAddresses(count, /* max_pct */ 0, network)}; |
| 892 | UniValue ret(UniValue::VARR); |
| 893 | |
| 894 | for (const CAddress& addr : vAddr) { |
| 895 | UniValue obj(UniValue::VOBJ); |
| 896 | obj.pushKV("time", (int)addr.nTime); |
| 897 | obj.pushKV("services", (uint64_t)addr.nServices); |
| 898 | obj.pushKV("address", addr.ToStringIP()); |
| 899 | obj.pushKV("port", addr.GetPort()); |
| 900 | obj.pushKV("network", GetNetworkName(addr.GetNetClass())); |
| 901 | ret.push_back(obj); |
| 902 | } |
| 903 | return ret; |
| 904 | }, |
nothing calls this directly
no test coverage detected