Skip to content

Commit 352d5eb

Browse files
committed
test: getrawaddrman RPC
Test that the getrawaddrman returns the addresses in the new and tried tables. We can't check the buckets and positions as these are not deterministic (yet).
1 parent da384a2 commit 352d5eb

File tree

1 file changed

+112
-0
lines changed

1 file changed

+112
-0
lines changed

test/functional/rpc_net.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import time
1313

1414
import test_framework.messages
15+
from test_framework.netutil import ADDRMAN_NEW_BUCKET_COUNT, ADDRMAN_TRIED_BUCKET_COUNT, ADDRMAN_BUCKET_SIZE
1516
from test_framework.p2p import (
1617
P2PInterface,
1718
P2P_SERVICES,
@@ -67,6 +68,7 @@ def run_test(self):
6768
self.test_addpeeraddress()
6869
self.test_sendmsgtopeer()
6970
self.test_getaddrmaninfo()
71+
self.test_getrawaddrman()
7072

7173
def test_connection_count(self):
7274
self.log.info("Test getconnectioncount")
@@ -386,5 +388,115 @@ def test_getaddrmaninfo(self):
386388
assert_equal(res[net]["tried"], 0)
387389
assert_equal(res[net]["total"], 0)
388390

391+
def test_getrawaddrman(self):
392+
self.log.info("Test getrawaddrman")
393+
node = self.nodes[1]
394+
395+
self.log.debug("Test that getrawaddrman is a hidden RPC")
396+
# It is hidden from general help, but its detailed help may be called directly.
397+
assert "getrawaddrman" not in node.help()
398+
assert "getrawaddrman" in node.help("getrawaddrman")
399+
400+
def check_addr_information(result, expected):
401+
"""Utility to compare a getrawaddrman result entry with an expected entry"""
402+
assert_equal(result["address"], expected["address"])
403+
assert_equal(result["port"], expected["port"])
404+
assert_equal(result["services"], expected["services"])
405+
assert_equal(result["network"], expected["network"])
406+
assert_equal(result["source"], expected["source"])
407+
assert_equal(result["source_network"], expected["source_network"])
408+
# To avoid failing on slow test runners, use a 10s vspan here.
409+
assert_approx(result["time"], time.time(), vspan=10)
410+
411+
def check_getrawaddrman_entries(expected):
412+
"""Utility to compare a getrawaddrman result with expected addrman contents"""
413+
getrawaddrman = node.getrawaddrman()
414+
getaddrmaninfo = node.getaddrmaninfo()
415+
for (table_name, table_info) in expected.items():
416+
assert_equal(len(getrawaddrman[table_name]), len(table_info["entries"]))
417+
assert_equal(len(getrawaddrman[table_name]), getaddrmaninfo["all_networks"][table_name])
418+
419+
for bucket_position in getrawaddrman[table_name].keys():
420+
bucket = int(bucket_position.split("/")[0])
421+
position = int(bucket_position.split("/")[1])
422+
423+
# bucket and position only be sanity checked here as the
424+
# test-addrman isn't deterministic
425+
assert 0 <= int(bucket) < table_info["bucket_count"]
426+
assert 0 <= int(position) < ADDRMAN_BUCKET_SIZE
427+
428+
entry = getrawaddrman[table_name][bucket_position]
429+
expected_entry = list(filter(lambda e: e["address"] == entry["address"], table_info["entries"]))[0]
430+
check_addr_information(entry, expected_entry)
431+
432+
# we expect one addrman new and tried table entry, which were added in a previous test
433+
expected = {
434+
"new": {
435+
"bucket_count": ADDRMAN_NEW_BUCKET_COUNT,
436+
"entries": [
437+
{
438+
"address": "2.0.0.0",
439+
"port": 8333,
440+
"services": 9,
441+
"network": "ipv4",
442+
"source": "2.0.0.0",
443+
"source_network": "ipv4",
444+
}
445+
]
446+
},
447+
"tried": {
448+
"bucket_count": ADDRMAN_TRIED_BUCKET_COUNT,
449+
"entries": [
450+
{
451+
"address": "1.2.3.4",
452+
"port": 8333,
453+
"services": 9,
454+
"network": "ipv4",
455+
"source": "1.2.3.4",
456+
"source_network": "ipv4",
457+
}
458+
]
459+
}
460+
}
461+
462+
self.log.debug("Test that the getrawaddrman contains information about the addresses added in a previous test")
463+
check_getrawaddrman_entries(expected)
464+
465+
self.log.debug("Add one new address to each addrman table")
466+
expected["new"]["entries"].append({
467+
"address": "2803:0:1234:abcd::1",
468+
"services": 9,
469+
"network": "ipv6",
470+
"source": "2803:0:1234:abcd::1",
471+
"source_network": "ipv6",
472+
"port": -1, # set once addpeeraddress is successful
473+
})
474+
expected["tried"]["entries"].append({
475+
"address": "nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion",
476+
"services": 9,
477+
"network": "onion",
478+
"source": "nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion",
479+
"source_network": "onion",
480+
"port": -1, # set once addpeeraddress is successful
481+
})
482+
483+
port = 0
484+
for (table_name, table_info) in expected.items():
485+
# There's a slight chance that the to-be-added address collides with an already
486+
# present table entry. To avoid this, we increment the port until an address has been
487+
# added. Incrementing the port changes the position in the new table bucket (bucket
488+
# stays the same) and changes both the bucket and the position in the tried table.
489+
while True:
490+
if node.addpeeraddress(address=table_info["entries"][1]["address"], port=port, tried=table_name == "tried")["success"]:
491+
table_info["entries"][1]["port"] = port
492+
self.log.debug(f"Added {table_info['entries'][1]['address']} to {table_name} table")
493+
break
494+
else:
495+
port += 1
496+
497+
self.log.debug("Test that the newly added addresses appear in getrawaddrman")
498+
check_getrawaddrman_entries(expected)
499+
500+
389501
if __name__ == '__main__':
390502
NetTest().main()

0 commit comments

Comments
 (0)