| 921 | } |
| 922 | |
| 923 | static RPCMethod getnodeaddresses() |
| 924 | { |
| 925 | return RPCMethod{"getnodeaddresses", |
| 926 | "Return known addresses, after filtering for quality and recency.\n" |
| 927 | "These can potentially be used to find new peers in the network.\n" |
| 928 | "The total number of addresses known to the node may be higher.", |
| 929 | { |
| 930 | {"count", RPCArg::Type::NUM, RPCArg::Default{1}, "The maximum number of addresses to return. Specify 0 to return all known addresses."}, |
| 931 | {"network", RPCArg::Type::STR, RPCArg::DefaultHint{"all networks"}, "Return only addresses of the specified network. Can be one of: " + Join(GetNetworkNames(), ", ") + "."}, |
| 932 | }, |
| 933 | RPCResult{ |
| 934 | RPCResult::Type::ARR, "", "", |
| 935 | { |
| 936 | {RPCResult::Type::OBJ, "", "", |
| 937 | { |
| 938 | {RPCResult::Type::NUM_TIME, "time", "The " + UNIX_EPOCH_TIME + " when the node was last seen"}, |
| 939 | {RPCResult::Type::NUM, "services", "The services offered by the node"}, |
| 940 | {RPCResult::Type::STR, "address", "The address of the node"}, |
| 941 | {RPCResult::Type::NUM, "port", "The port number of the node"}, |
| 942 | {RPCResult::Type::STR, "network", "The network (" + Join(GetNetworkNames(), ", ") + ") the node connected through"}, |
| 943 | }}, |
| 944 | } |
| 945 | }, |
| 946 | RPCExamples{ |
| 947 | HelpExampleCli("getnodeaddresses", "8") |
| 948 | + HelpExampleCli("getnodeaddresses", "4 \"i2p\"") |
| 949 | + HelpExampleCli("-named getnodeaddresses", "network=onion count=12") |
| 950 | + HelpExampleRpc("getnodeaddresses", "8") |
| 951 | + HelpExampleRpc("getnodeaddresses", "4, \"i2p\"") |
| 952 | }, |
| 953 | [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue |
| 954 | { |
| 955 | NodeContext& node = EnsureAnyNodeContext(request.context); |
| 956 | const CConnman& connman = EnsureConnman(node); |
| 957 | |
| 958 | const int count{request.params[0].isNull() ? 1 : request.params[0].getInt<int>()}; |
| 959 | if (count < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Address count out of range"); |
| 960 | |
| 961 | const std::optional<Network> network{request.params[1].isNull() ? std::nullopt : std::optional<Network>{ParseNetwork(request.params[1].get_str())}}; |
| 962 | if (network == NET_UNROUTABLE) { |
| 963 | throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Network not recognized: %s", request.params[1].get_str())); |
| 964 | } |
| 965 | |
| 966 | // returns a shuffled list of CAddress |
| 967 | const std::vector<CAddress> vAddr{connman.GetAddressesUnsafe(count, /*max_pct=*/0, network)}; |
| 968 | UniValue ret(UniValue::VARR); |
| 969 | |
| 970 | for (const CAddress& addr : vAddr) { |
| 971 | UniValue obj(UniValue::VOBJ); |
| 972 | obj.pushKV("time", TicksSinceEpoch<std::chrono::seconds>(addr.nTime)); |
| 973 | obj.pushKV("services", static_cast<std::underlying_type_t<decltype(addr.nServices)>>(addr.nServices)); |
| 974 | obj.pushKV("address", addr.ToStringAddr()); |
| 975 | obj.pushKV("port", addr.GetPort()); |
| 976 | obj.pushKV("network", GetNetworkName(addr.GetNetClass())); |
| 977 | ret.push_back(std::move(obj)); |
| 978 | } |
| 979 | return ret; |
| 980 | }, |
nothing calls this directly
no test coverage detected