|
12 | 12 | import time
|
13 | 13 |
|
14 | 14 | import test_framework.messages
|
| 15 | +from test_framework.netutil import ADDRMAN_NEW_BUCKET_COUNT, ADDRMAN_TRIED_BUCKET_COUNT, ADDRMAN_BUCKET_SIZE |
15 | 16 | from test_framework.p2p import (
|
16 | 17 | P2PInterface,
|
17 | 18 | P2P_SERVICES,
|
@@ -67,6 +68,7 @@ def run_test(self):
|
67 | 68 | self.test_addpeeraddress()
|
68 | 69 | self.test_sendmsgtopeer()
|
69 | 70 | self.test_getaddrmaninfo()
|
| 71 | + self.test_getrawaddrman() |
70 | 72 |
|
71 | 73 | def test_connection_count(self):
|
72 | 74 | self.log.info("Test getconnectioncount")
|
@@ -386,5 +388,115 @@ def test_getaddrmaninfo(self):
|
386 | 388 | assert_equal(res[net]["tried"], 0)
|
387 | 389 | assert_equal(res[net]["total"], 0)
|
388 | 390 |
|
| 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 | + |
389 | 501 | if __name__ == '__main__':
|
390 | 502 | NetTest().main()
|
0 commit comments