Skip to content

Commit

Permalink
[Net] Add addpeeraddress RPC method
Browse files Browse the repository at this point in the history
Allows addresses to be added to Address Manager for testing.
  • Loading branch information
Fuzzbawls committed Aug 12, 2021
1 parent 1a31b67 commit b4832b2
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/net.cpp
Expand Up @@ -2137,9 +2137,9 @@ void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int
addrman.Add(addr, addrFrom, nTimePenalty);
}

void CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
bool CConnman::AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty)
{
addrman.Add(vAddr, addrFrom, nTimePenalty);
return addrman.Add(vAddr, addrFrom, nTimePenalty);
}

std::vector<CAddress> CConnman::GetAddresses(size_t max_addresses, size_t max_pct)
Expand Down
2 changes: 1 addition & 1 deletion src/net.h
Expand Up @@ -216,7 +216,7 @@ class CConnman
void SetServices(const CService &addr, ServiceFlags nServices);
void MarkAddressGood(const CAddress& addr);
void AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
void AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
bool AddNewAddresses(const std::vector<CAddress>& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0);
std::vector<CAddress> GetAddresses(size_t max_addresses, size_t max_pct);

// Denial-of-service detection/prevention
Expand Down
1 change: 1 addition & 0 deletions src/rpc/client.cpp
Expand Up @@ -28,6 +28,7 @@ class CRPCConvertParam
static const CRPCConvertParam vRPCConvertParams[] = {
{ "addmultisigaddress", 0, "nrequired" },
{ "addmultisigaddress", 1, "keys" },
{ "addpeeraddress", 1, "port" },
{ "autocombinerewards", 0, "enable" },
{ "autocombinerewards", 1, "threshold" },
{ "createmultisig", 0, "nrequired" },
Expand Down
50 changes: 50 additions & 0 deletions src/rpc/net.cpp
Expand Up @@ -611,6 +611,53 @@ static UniValue getnodeaddresses(const JSONRPCRequest& request)
return ret;
}

static UniValue addpeeraddress(const JSONRPCRequest& request)
{
if (request.fHelp || request.params.size() != 2) {
throw std::runtime_error(
"addpeeraddress \"address\" port\n"
"\nAdd the address of a potential peer to the address manager. This RPC is for testing only.\n"

"\nArguments\n"
"1. \"address\" (string, required) The IP address of the peer\n"
"2. port (numeric, required) The port of the peer\n"

"\nResult:\n"
"{\n"
" \"success\": true|false (boolean) Whether the peer address was successfully added to the address manager\n"
"}\n"

"\nExamples:\n"
+ HelpExampleCli("addpeeraddress", "\"1.2.3.4\" 51472")
+ HelpExampleRpc("addpeeraddress", "\"1.2.3.4\", 51472"));
}
if (!g_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));
address.nTime = GetAdjustedTime();
// The source address is set equal to the address. This is equivalent to the peer
// announcing itself.
if (!g_connman->AddNewAddresses({address}, address)) {
obj.pushKV("success", false);
return obj;
}

obj.pushKV("success", true);
return obj;
}

static const CRPCCommand commands[] =
{ // category name actor (function) okSafe argNames
// --------------------- ------------------------ ----------------------- ------ --------
Expand All @@ -626,6 +673,9 @@ static const CRPCCommand commands[] =
{ "network", "listbanned", &listbanned, true, {} },
{ "network", "ping", &ping, true, {} },
{ "network", "setban", &setban, true, {"subnet", "command", "bantime", "absolute"} },

// Hidden, for testing only
{ "hidden", "addpeeraddress", &addpeeraddress, true, {"address", "port"} },
};

void RegisterNetRPCCommands(CRPCTable &tableRPC)
Expand Down
32 changes: 14 additions & 18 deletions test/functional/rpc_net.py
Expand Up @@ -7,7 +7,7 @@
Tests correspond to code in rpc/net.cpp.
"""

from test_framework.messages import CAddress, msg_addr, NODE_NETWORK
from test_framework.messages import NODE_NETWORK
from test_framework.mininode import P2PInterface
from test_framework.test_framework import PivxTestFramework
from test_framework.util import (
Expand Down Expand Up @@ -100,29 +100,25 @@ def _test_getpeerinfo(self):
def _test_getnodeaddresses(self):
self.nodes[0].add_p2p_connection(P2PInterface())

# send some addresses to the node via the p2p message addr
msg = msg_addr()
# Add some addresses to the Address Manager over RPC. Due to the way
# bucket and bucket position are calculated, some of these addresses
# will collide.
imported_addrs = []
for i in range(256):
a = "123.123.123.{}".format(i)
for i in range(10000):
first_octet = i >> 8
second_octet = i % 256
a = "{}.{}.1.1".format(first_octet, second_octet)
imported_addrs.append(a)
addr = CAddress()
addr.time = 100000000
addr.nServices = NODE_NETWORK
addr.ip = a
addr.port = 51472
msg.addrs.append(addr)
self.nodes[0].p2p.send_and_ping(msg)
self.nodes[0].addpeeraddress(a, 51472)

# Obtain addresses via rpc call and check they were ones sent in before.
#
# All addresses added above are in the same netgroup and so are assigned
# to the same bucket. Maximum possible addresses in addrman is therefore
# 64, although actual number will usually be slightly less due to
# BucketPosition collisions.
# Maximum possible addresses in addrman is 10000, although actual
# number will usually be less due to bucket and bucket position
# collisions.
node_addresses = self.nodes[0].getnodeaddresses(0)
assert_greater_than(len(node_addresses), 50)
assert_greater_than(65, len(node_addresses))
assert_greater_than(len(node_addresses), 5000)
assert_greater_than(10000, len(node_addresses))
for a in node_addresses:
assert_greater_than(a["time"], 1527811200) # 1st June 2018
assert_equal(a["services"], NODE_NETWORK)
Expand Down

0 comments on commit b4832b2

Please sign in to comment.