aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@protonmail.com>2020-08-12 11:55:48 +0200
committerWladimir J. van der Laan <laanwj@protonmail.com>2020-08-12 15:23:06 +0200
commitbd00d3b1f2036893419d1e8c514a8af2c4e4b1fb (patch)
tree53e1c1ff06ebc0a99b32f65eaebf60c6c8c6cad3 /src/rpc
parentce3bdd0ed1bbfeaa19a5b75dc07943118826f930 (diff)
parent37a480e0cd94895b6051abef12d984ff74bdc4a3 (diff)
downloadbitcoin-bd00d3b1f2036893419d1e8c514a8af2c4e4b1fb.tar.xz
Merge #19658: [rpc] Allow RPC to fetch all addrman records and add records to addrman
37a480e0cd94895b6051abef12d984ff74bdc4a3 [net] Add addpeeraddress RPC method (John Newbery) ae8051bbd8377f2458ff1f167dc30c2d5f83e317 [test] Test that getnodeaddresses() can return all known addresses (John Newbery) f26502e9fc8a669b30717525597e3f468eaecf79 [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: utACK 37a480e0cd94895b6051abef12d984ff74bdc4a3 laanwj: Code review and lightly manually tested ACK 37a480e0cd94895b6051abef12d984ff74bdc4a3 Tree-SHA512: f86dcd410aaebaf6e9ca18ce6f23556e5e4649c1325577213d873aa09967298e65ab2dc19a72670641ae92211a923afda1fe124a82e9d2c1cad73d478ef27fdc
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/client.cpp1
-rw-r--r--src/rpc/net.cpp59
2 files changed, 54 insertions, 6 deletions
diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp
index 66ace7263a..97d1c00369 100644
--- a/src/rpc/client.cpp
+++ b/src/rpc/client.cpp
@@ -173,6 +173,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "createwallet", 4, "avoid_reuse"},
{ "createwallet", 5, "descriptors"},
{ "getnodeaddresses", 0, "count"},
+ { "addpeeraddress", 1, "port"},
{ "stop", 0, "wait" },
};
// clang-format on
diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp
index 09265bc480..0dfd560896 100644
--- a/src/rpc/net.cpp
+++ b/src/rpc/net.cpp
@@ -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