From 19ce3d407ef546fa50d18b2ffbd67b7417797064 Mon Sep 17 00:00:00 2001 From: Fabian Jahr Date: Tue, 18 Jun 2024 14:34:50 +0200 Subject: [PATCH] assumeutxo: Check snapshot base block is not marked invalid Co-authored-by: Alfonso Roman Zubeldia --- src/validation.cpp | 5 +++++ test/functional/feature_assumeutxo.py | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/validation.cpp b/src/validation.cpp index 53db1cb5b12..27bc702eddf 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -5677,6 +5677,11 @@ util::Result ChainstateManager::ActivateSnapshot( base_blockhash.ToString())}; } + bool start_block_invalid = snapshot_start_block->nStatus & BLOCK_FAILED_MASK; + if (start_block_invalid) { + return util::Error{strprintf(_("The base block header (%s) is part of an invalid chain."), base_blockhash.ToString())}; + } + if (Assert(m_active_chainstate->GetMempool())->size() > 0) { return util::Error{_("Can't activate a snapshot when mempool not empty.")}; } diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index acee480d1f3..9febae5ec26 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -205,6 +205,19 @@ class AssumeutxoTest(BitcoinTestFramework): assert_raises_rpc_error(-32603, "Unable to load UTXO snapshot", node.loadtxoutset, dump_output_path) self.restart_node(0, extra_args=self.extra_args[0]) + def test_snapshot_block_invalidated(self, dump_output_path): + self.log.info("Test snapshot is not loaded when base block is invalid.") + node = self.nodes[0] + # We are testing the case where the base block is invalidated itself + # and also the case where one of its parents is invalidated. + for height in [SNAPSHOT_BASE_HEIGHT, SNAPSHOT_BASE_HEIGHT - 1]: + block_hash = node.getblockhash(height) + node.invalidateblock(block_hash) + assert_equal(node.getblockcount(), height - 1) + msg = "Unable to load UTXO snapshot: The base block header (3bb7ce5eba0be48939b7a521ac1ba9316afee2c7bada3a0cca24188e6d7d96c0) is part of an invalid chain." + assert_raises_rpc_error(-32603, msg, node.loadtxoutset, dump_output_path) + node.reconsiderblock(block_hash) + def run_test(self): """ Bring up two (disconnected) nodes, mine some new blocks on the first, @@ -291,6 +304,7 @@ class AssumeutxoTest(BitcoinTestFramework): self.test_invalid_snapshot_scenarios(dump_output['path']) self.test_invalid_chainstate_scenarios() self.test_invalid_file_path() + self.test_snapshot_block_invalidated(dump_output['path']) self.log.info(f"Loading snapshot into second node from {dump_output['path']}") loaded = n1.loadtxoutset(dump_output['path'])