From 2bc1ecfaa9b69a20388e913ec64967de2f506cd3 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Mon, 19 Feb 2024 17:47:34 +0100 Subject: [PATCH 1/2] test: Remove unnecessary sync_blocks in assumeutxo tests The nodes are not connected at this point and no blocks have been mined, so it does not seem do anything --- test/functional/feature_assumeutxo.py | 2 -- test/functional/wallet_assumeutxo.py | 2 -- 2 files changed, 4 deletions(-) diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index 60dd751ff80..d313f0ee278 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -166,8 +166,6 @@ class AssumeutxoTest(BitcoinTestFramework): for n in self.nodes: n.setmocktime(n.getblockheader(n.getbestblockhash())['time']) - self.sync_blocks() - # Generate a series of blocks that `n0` will have in the snapshot, # but that n1 doesn't yet see. In order for the snapshot to activate, # though, we have to ferry over the new headers to n1 so that it diff --git a/test/functional/wallet_assumeutxo.py b/test/functional/wallet_assumeutxo.py index 3c1a997bd17..30396da0152 100755 --- a/test/functional/wallet_assumeutxo.py +++ b/test/functional/wallet_assumeutxo.py @@ -62,8 +62,6 @@ class AssumeutxoTest(BitcoinTestFramework): for n in self.nodes: n.setmocktime(n.getblockheader(n.getbestblockhash())['time']) - self.sync_blocks() - n0.createwallet('w') w = n0.get_wallet_rpc("w") From 1ec6684b08614f593b37e627a0a08e54b19318b6 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Mon, 19 Feb 2024 17:50:06 +0100 Subject: [PATCH 2/2] test: Add test for loadtxoutset when headers are not synced --- test/functional/feature_assumeutxo.py | 37 +++++++++++++++++---------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index d313f0ee278..a9ed4a09cea 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -113,6 +113,12 @@ class AssumeutxoTest(BitcoinTestFramework): f.write(valid_snapshot_contents[(32 + 8 + offset + len(content)):]) expected_error(log_msg=f"[snapshot] bad snapshot content hash: expected a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27, got {wrong_hash}") + def test_headers_not_synced(self, valid_snapshot_path): + for node in self.nodes[1:]: + assert_raises_rpc_error(-32603, "The base block header (3bb7ce5eba0be48939b7a521ac1ba9316afee2c7bada3a0cca24188e6d7d96c0) must appear in the headers chain. Make sure all headers are syncing, and call this RPC again.", + node.loadtxoutset, + valid_snapshot_path) + def test_invalid_chainstate_scenarios(self): self.log.info("Test different scenarios of invalid snapshot chainstate in datadir") @@ -167,23 +173,11 @@ class AssumeutxoTest(BitcoinTestFramework): n.setmocktime(n.getblockheader(n.getbestblockhash())['time']) # Generate a series of blocks that `n0` will have in the snapshot, - # but that n1 doesn't yet see. In order for the snapshot to activate, - # though, we have to ferry over the new headers to n1 so that it - # isn't waiting forever to see the header of the snapshot's base block - # while disconnected from n0. + # but that n1 and n2 don't yet see. for i in range(100): if i % 3 == 0: self.mini_wallet.send_self_transfer(from_node=n0) self.generate(n0, nblocks=1, sync_fun=self.no_op) - newblock = n0.getblock(n0.getbestblockhash(), 0) - - # make n1 aware of the new header, but don't give it the block. - n1.submitheader(newblock) - n2.submitheader(newblock) - - # Ensure everyone is seeing the same headers. - for n in self.nodes: - assert_equal(n.getblockchaininfo()["headers"], SNAPSHOT_BASE_HEIGHT) self.log.info("-- Testing assumeutxo + some indexes + pruning") @@ -193,6 +187,23 @@ class AssumeutxoTest(BitcoinTestFramework): self.log.info(f"Creating a UTXO snapshot at height {SNAPSHOT_BASE_HEIGHT}") dump_output = n0.dumptxoutset('utxos.dat') + self.log.info("Test loading snapshot when headers are not synced") + self.test_headers_not_synced(dump_output['path']) + + # In order for the snapshot to activate, we have to ferry over the new + # headers to n1 and n2 so that they see the header of the snapshot's + # base block while disconnected from n0. + for i in range(1, 300): + block = n0.getblock(n0.getblockhash(i), 0) + # make n1 and n2 aware of the new header, but don't give them the + # block. + n1.submitheader(block) + n2.submitheader(block) + + # Ensure everyone is seeing the same headers. + for n in self.nodes: + assert_equal(n.getblockchaininfo()["headers"], SNAPSHOT_BASE_HEIGHT) + assert_equal( dump_output['txoutset_hash'], "a4bf3407ccb2cc0145c49ebba8fa91199f8a3903daf0883875941497d2493c27")