mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-05 14:06:27 -05:00
[test] Use deterministic addrman in addrman info tests
The nodes are restarted with an empty addrman and populated with addresses from different networks using a helper function. We can safely add multiple addresses to addrman tables without worrying about unpredictable collisions since bucket:position is fixed in a deterministic addrman.
This commit is contained in:
parent
a897866109
commit
2cc8ca19f4
1 changed files with 100 additions and 71 deletions
|
@ -13,7 +13,6 @@ import platform
|
|||
import time
|
||||
|
||||
import test_framework.messages
|
||||
from test_framework.netutil import ADDRMAN_NEW_BUCKET_COUNT, ADDRMAN_TRIED_BUCKET_COUNT, ADDRMAN_BUCKET_SIZE
|
||||
from test_framework.p2p import (
|
||||
P2PInterface,
|
||||
P2P_SERVICES,
|
||||
|
@ -42,6 +41,20 @@ def assert_net_servicesnames(servicesflag, servicenames):
|
|||
assert servicesflag_generated == servicesflag
|
||||
|
||||
|
||||
def seed_addrman(node):
|
||||
""" Populate the addrman with addresses from different networks.
|
||||
Here 2 ipv4, 2 ipv6, 1 cjdns, 2 onion and 1 i2p addresses are added.
|
||||
"""
|
||||
node.addpeeraddress(address="1.2.3.4", tried=True, port=8333)
|
||||
node.addpeeraddress(address="2.0.0.0", port=8333)
|
||||
node.addpeeraddress(address="1233:3432:2434:2343:3234:2345:6546:4534", tried=True, port=8333)
|
||||
node.addpeeraddress(address="2803:0:1234:abcd::1", port=45324)
|
||||
node.addpeeraddress(address="fc00:1:2:3:4:5:6:7", port=8333)
|
||||
node.addpeeraddress(address="pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion", tried=True, port=8333)
|
||||
node.addpeeraddress(address="nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion", port=45324, tried=True)
|
||||
node.addpeeraddress(address="c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p", port=8333)
|
||||
|
||||
|
||||
class NetTest(BitcoinTestFramework):
|
||||
def set_test_params(self):
|
||||
self.num_nodes = 2
|
||||
|
@ -376,25 +389,33 @@ class NetTest(BitcoinTestFramework):
|
|||
|
||||
def test_getaddrmaninfo(self):
|
||||
self.log.info("Test getaddrmaninfo")
|
||||
self.restart_node(1, extra_args=["-cjdnsreachable", "-test=addrman"], clear_addrman=True)
|
||||
node = self.nodes[1]
|
||||
seed_addrman(node)
|
||||
|
||||
# current count of ipv4 addresses in addrman is {'new':1, 'tried':1}
|
||||
self.log.info("Test that count of addresses in addrman match expected values")
|
||||
expected_network_count = {
|
||||
'all_networks': {'new': 4, 'tried': 4, 'total': 8},
|
||||
'ipv4': {'new': 1, 'tried': 1, 'total': 2},
|
||||
'ipv6': {'new': 1, 'tried': 1, 'total': 2},
|
||||
'onion': {'new': 0, 'tried': 2, 'total': 2},
|
||||
'i2p': {'new': 1, 'tried': 0, 'total': 1},
|
||||
'cjdns': {'new': 1, 'tried': 0, 'total': 1},
|
||||
}
|
||||
|
||||
self.log.debug("Test that count of addresses in addrman match expected values")
|
||||
res = node.getaddrmaninfo()
|
||||
assert_equal(res["ipv4"]["new"], 1)
|
||||
assert_equal(res["ipv4"]["tried"], 1)
|
||||
assert_equal(res["ipv4"]["total"], 2)
|
||||
assert_equal(res["all_networks"]["new"], 1)
|
||||
assert_equal(res["all_networks"]["tried"], 1)
|
||||
assert_equal(res["all_networks"]["total"], 2)
|
||||
for net in ["ipv6", "onion", "i2p", "cjdns"]:
|
||||
assert_equal(res[net]["new"], 0)
|
||||
assert_equal(res[net]["tried"], 0)
|
||||
assert_equal(res[net]["total"], 0)
|
||||
for network, count in expected_network_count.items():
|
||||
assert_equal(res[network]['new'], count['new'])
|
||||
assert_equal(res[network]['tried'], count['tried'])
|
||||
assert_equal(res[network]['total'], count['total'])
|
||||
|
||||
def test_getrawaddrman(self):
|
||||
self.log.info("Test getrawaddrman")
|
||||
self.restart_node(1, extra_args=["-cjdnsreachable", "-test=addrman"], clear_addrman=True)
|
||||
node = self.nodes[1]
|
||||
self.addr_time = int(time.time())
|
||||
node.setmocktime(self.addr_time)
|
||||
seed_addrman(node)
|
||||
|
||||
self.log.debug("Test that getrawaddrman is a hidden RPC")
|
||||
# It is hidden from general help, but its detailed help may be called directly.
|
||||
|
@ -416,88 +437,96 @@ class NetTest(BitcoinTestFramework):
|
|||
getrawaddrman = node.getrawaddrman()
|
||||
getaddrmaninfo = node.getaddrmaninfo()
|
||||
for (table_name, table_info) in expected.items():
|
||||
assert_equal(len(getrawaddrman[table_name]), len(table_info["entries"]))
|
||||
assert_equal(len(getrawaddrman[table_name]), len(table_info))
|
||||
assert_equal(len(getrawaddrman[table_name]), getaddrmaninfo["all_networks"][table_name])
|
||||
|
||||
for bucket_position in getrawaddrman[table_name].keys():
|
||||
bucket = int(bucket_position.split("/")[0])
|
||||
position = int(bucket_position.split("/")[1])
|
||||
|
||||
# bucket and position only be sanity checked here as the
|
||||
# test-addrman isn't deterministic
|
||||
assert 0 <= int(bucket) < table_info["bucket_count"]
|
||||
assert 0 <= int(position) < ADDRMAN_BUCKET_SIZE
|
||||
|
||||
entry = getrawaddrman[table_name][bucket_position]
|
||||
expected_entry = list(filter(lambda e: e["address"] == entry["address"], table_info["entries"]))[0]
|
||||
expected_entry = list(filter(lambda e: e["address"] == entry["address"], table_info))[0]
|
||||
assert bucket_position == expected_entry["bucket_position"]
|
||||
check_addr_information(entry, expected_entry)
|
||||
|
||||
# we expect one addrman new and tried table entry, which were added in a previous test
|
||||
# we expect 4 new and 4 tried table entries in the addrman which were added using seed_addrman()
|
||||
expected = {
|
||||
"new": {
|
||||
"bucket_count": ADDRMAN_NEW_BUCKET_COUNT,
|
||||
"entries": [
|
||||
"new": [
|
||||
{
|
||||
"bucket_position": "82/8",
|
||||
"address": "2.0.0.0",
|
||||
"port": 8333,
|
||||
"services": 9,
|
||||
"network": "ipv4",
|
||||
"source": "2.0.0.0",
|
||||
"source_network": "ipv4",
|
||||
}
|
||||
]
|
||||
},
|
||||
"tried": {
|
||||
"bucket_count": ADDRMAN_TRIED_BUCKET_COUNT,
|
||||
"entries": [
|
||||
},
|
||||
{
|
||||
"bucket_position": "336/24",
|
||||
"address": "fc00:1:2:3:4:5:6:7",
|
||||
"port": 8333,
|
||||
"services": 9,
|
||||
"network": "cjdns",
|
||||
"source": "fc00:1:2:3:4:5:6:7",
|
||||
"source_network": "cjdns",
|
||||
},
|
||||
{
|
||||
"bucket_position": "963/46",
|
||||
"address": "c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p",
|
||||
"port": 8333,
|
||||
"services": 9,
|
||||
"network": "i2p",
|
||||
"source": "c4gfnttsuwqomiygupdqqqyy5y5emnk5c73hrfvatri67prd7vyq.b32.i2p",
|
||||
"source_network": "i2p",
|
||||
},
|
||||
{
|
||||
"bucket_position": "613/6",
|
||||
"address": "2803:0:1234:abcd::1",
|
||||
"services": 9,
|
||||
"network": "ipv6",
|
||||
"source": "2803:0:1234:abcd::1",
|
||||
"source_network": "ipv6",
|
||||
"port": 45324,
|
||||
}
|
||||
],
|
||||
"tried": [
|
||||
{
|
||||
"bucket_position": "6/33",
|
||||
"address": "1.2.3.4",
|
||||
"port": 8333,
|
||||
"services": 9,
|
||||
"network": "ipv4",
|
||||
"source": "1.2.3.4",
|
||||
"source_network": "ipv4",
|
||||
},
|
||||
{
|
||||
"bucket_position": "197/34",
|
||||
"address": "1233:3432:2434:2343:3234:2345:6546:4534",
|
||||
"port": 8333,
|
||||
"services": 9,
|
||||
"network": "ipv6",
|
||||
"source": "1233:3432:2434:2343:3234:2345:6546:4534",
|
||||
"source_network": "ipv6",
|
||||
},
|
||||
{
|
||||
"bucket_position": "72/61",
|
||||
"address": "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion",
|
||||
"port": 8333,
|
||||
"services": 9,
|
||||
"network": "onion",
|
||||
"source": "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion",
|
||||
"source_network": "onion"
|
||||
},
|
||||
{
|
||||
"bucket_position": "139/46",
|
||||
"address": "nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion",
|
||||
"services": 9,
|
||||
"network": "onion",
|
||||
"source": "nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion",
|
||||
"source_network": "onion",
|
||||
"port": 45324,
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
self.log.debug("Test that the getrawaddrman contains information about the addresses added in a previous test")
|
||||
check_getrawaddrman_entries(expected)
|
||||
|
||||
self.log.debug("Add one new address to each addrman table")
|
||||
expected["new"]["entries"].append({
|
||||
"address": "2803:0:1234:abcd::1",
|
||||
"services": 9,
|
||||
"network": "ipv6",
|
||||
"source": "2803:0:1234:abcd::1",
|
||||
"source_network": "ipv6",
|
||||
"port": -1, # set once addpeeraddress is successful
|
||||
})
|
||||
expected["tried"]["entries"].append({
|
||||
"address": "nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion",
|
||||
"services": 9,
|
||||
"network": "onion",
|
||||
"source": "nrfj6inpyf73gpkyool35hcmne5zwfmse3jl3aw23vk7chdemalyaqad.onion",
|
||||
"source_network": "onion",
|
||||
"port": -1, # set once addpeeraddress is successful
|
||||
})
|
||||
|
||||
port = 0
|
||||
for (table_name, table_info) in expected.items():
|
||||
# There's a slight chance that the to-be-added address collides with an already
|
||||
# present table entry. To avoid this, we increment the port until an address has been
|
||||
# added. Incrementing the port changes the position in the new table bucket (bucket
|
||||
# stays the same) and changes both the bucket and the position in the tried table.
|
||||
while True:
|
||||
if node.addpeeraddress(address=table_info["entries"][1]["address"], port=port, tried=table_name == "tried")["success"]:
|
||||
table_info["entries"][1]["port"] = port
|
||||
self.log.debug(f"Added {table_info['entries'][1]['address']} to {table_name} table")
|
||||
break
|
||||
else:
|
||||
port += 1
|
||||
|
||||
self.log.debug("Test that the newly added addresses appear in getrawaddrman")
|
||||
self.log.debug("Test that getrawaddrman contains information about newly added addresses in each addrman table")
|
||||
check_getrawaddrman_entries(expected)
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue