Skip to content

Commit cdaab90

Browse files
jonatackjnewberymzumsande
committed
Add test for addrman consistency check on restart with asmap
PR #22697 introduced a reproducible issue in commit 181a120 that causes the addrman tried table to fail consistency checks and significantly lose peer entries when the `-asmap` configuration option is used. The issue occurs on bitcoind restart due to an initialization order change in `src/init.cpp` in that commit whereby CAddrman asmap is set after deserializing `peers.dat`, rather than before. Issue reported on the `#bitcoin-core-dev` IRC channel starting at https://www.erisian.com.au/bitcoin-core-dev/log-2021-08-23.html#l-263. ``` addrman lost 22813 new and 2 tried addresses due to collisions or invalid addresses ADDRMAN CONSISTENCY CHECK FAILED!!! err=-17 bitcoind: ./addrman.h:707: void CAddrMan::Check() const: Assertion `false' failed. Aborted ``` How to reproduce: - `git checkout 181a120` and recompile - launch bitcoind with `-asmap` and `-checkaddrman=1` config options - restart bitcoind - bitcoind aborts on second call to `CAddrMan::Check()` This commit adds a regression test to reproduce the case; it passes or fails with the same error. Co-authored-by: John Newbery <[email protected]> Co-authored-by: Martin Zumsande <[email protected]>
1 parent 869f136 commit cdaab90

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

test/functional/feature_asmap.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
1515
4. `bitcoind -asmap/-asmap=` with no file specified, using the default asmap
1616
17-
5. `bitcoind -asmap` with no file specified and a missing default asmap file
17+
5. `bitcoind -asmap` restart with an addrman containing new and tried entries
1818
19-
6. `bitcoind -asmap` with an empty (unparsable) default asmap file
19+
6. `bitcoind -asmap` with no file specified and a missing default asmap file
20+
21+
7. `bitcoind -asmap` with an empty (unparsable) default asmap file
2022
2123
The tests are order-independent.
2224
@@ -37,6 +39,12 @@ def expected_messages(filename):
3739
class AsmapTest(BitcoinTestFramework):
3840
def set_test_params(self):
3941
self.num_nodes = 1
42+
self.extra_args = [["-checkaddrman=1"]] # Do addrman checks on all operations.
43+
44+
def fill_addrman(self, node_id):
45+
"""Add 2 tried addresses to the addrman, followed by 2 new addresses."""
46+
for addr, tried in [[0, True], [1, True], [2, False], [3, False]]:
47+
self.nodes[node_id].addpeeraddress(address=f"101.{addr}.0.0", tried=tried, port=8333)
4048

4149
def test_without_asmap_arg(self):
4250
self.log.info('Test bitcoind with no -asmap arg passed')
@@ -72,6 +80,22 @@ def test_default_asmap(self):
7280
self.start_node(0, [arg])
7381
os.remove(self.default_asmap)
7482

83+
def test_asmap_interaction_with_addrman_containing_entries(self):
84+
self.log.info("Test bitcoind -asmap restart with addrman containing new and tried entries")
85+
self.stop_node(0)
86+
shutil.copyfile(self.asmap_raw, self.default_asmap)
87+
self.start_node(0, ["-asmap", "-checkaddrman=1"])
88+
self.fill_addrman(node_id=0)
89+
self.restart_node(0, ["-asmap", "-checkaddrman=1"])
90+
with self.node.assert_debug_log(
91+
expected_msgs=[
92+
"Addrman checks started: new 2, tried 2, total 4",
93+
"Addrman checks completed successfully",
94+
]
95+
):
96+
self.node.getnodeaddresses() # getnodeaddresses re-runs the addrman checks
97+
os.remove(self.default_asmap)
98+
7599
def test_default_asmap_with_missing_file(self):
76100
self.log.info('Test bitcoind -asmap with missing default map file')
77101
self.stop_node(0)
@@ -97,6 +121,7 @@ def run_test(self):
97121
self.test_asmap_with_absolute_path()
98122
self.test_asmap_with_relative_path()
99123
self.test_default_asmap()
124+
self.test_asmap_interaction_with_addrman_containing_entries()
100125
self.test_default_asmap_with_missing_file()
101126
self.test_empty_asmap()
102127

0 commit comments

Comments
 (0)