From 9620cb449374f234f72c1a9e1bae3d4b8c0ff171 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Sun, 15 Oct 2023 16:34:15 +0200 Subject: [PATCH] assumeutxo: fail early if snapshot block hash doesn't match AssumeUTXO parameters --- src/rpc/blockchain.cpp | 7 +++++-- test/functional/feature_assumeutxo.py | 11 +++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 37a28e414a..51d0879b12 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2737,6 +2737,7 @@ static RPCHelpMan loadtxoutset() [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue { NodeContext& node = EnsureAnyNodeContext(request.context); + ChainstateManager& chainman = EnsureChainman(node); fs::path path{AbsPathForConfigVal(EnsureArgsman(node), fs::u8path(request.params[0].get_str()))}; FILE* file{fsbridge::fopen(path, "rb")}; @@ -2751,14 +2752,16 @@ static RPCHelpMan loadtxoutset() afile >> metadata; uint256 base_blockhash = metadata.m_base_blockhash; + if (!chainman.GetParams().AssumeutxoForBlockhash(base_blockhash).has_value()) { + throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Unable to load UTXO snapshot, " + "assumeutxo block hash in snapshot metadata not recognized (%s)", base_blockhash.ToString())); + } int max_secs_to_wait_for_headers = 60 * 10; CBlockIndex* snapshot_start_block = nullptr; LogPrintf("[snapshot] waiting to see blockheader %s in headers chain before snapshot activation\n", base_blockhash.ToString()); - ChainstateManager& chainman = EnsureChainman(node); - while (max_secs_to_wait_for_headers > 0) { snapshot_start_block = WITH_LOCK(::cs_main, return chainman.m_blockman.LookupBlockIndex(base_blockhash)); diff --git a/test/functional/feature_assumeutxo.py b/test/functional/feature_assumeutxo.py index c900736ae9..376e35da3b 100755 --- a/test/functional/feature_assumeutxo.py +++ b/test/functional/feature_assumeutxo.py @@ -73,17 +73,12 @@ class AssumeutxoTest(BitcoinTestFramework): bad_snapshot_path = valid_snapshot_path + '.mod' self.log.info(" - snapshot file refering to a block that is not in the assumeutxo parameters") - # we can only test this with a block that is already known, as otherwise the `loadtxoutset` RPC - # would time out (waiting to see the hash in the headers chain), rather than error immediately - bad_snapshot_height = SNAPSHOT_BASE_HEIGHT - 1 + bad_snapshot_block_hash = self.nodes[0].getblockhash(SNAPSHOT_BASE_HEIGHT - 1) with open(bad_snapshot_path, 'wb') as f: - bad_snapshot_block_hash = self.nodes[0].getblockhash(bad_snapshot_height) # block hash of the snapshot base is stored right at the start (first 32 bytes) f.write(bytes.fromhex(bad_snapshot_block_hash)[::-1] + valid_snapshot_contents[32:]) - - expected_log = f"assumeutxo height in snapshot metadata not recognized ({bad_snapshot_height}) - refusing to load snapshot" - with self.nodes[1].assert_debug_log([expected_log]): - assert_raises_rpc_error(-32603, "Unable to load UTXO snapshot", self.nodes[1].loadtxoutset, bad_snapshot_path) + error_details = f"assumeutxo block hash in snapshot metadata not recognized ({bad_snapshot_block_hash})" + assert_raises_rpc_error(-32603, f"Unable to load UTXO snapshot, {error_details}", self.nodes[1].loadtxoutset, bad_snapshot_path) self.log.info(" - snapshot file with wrong number of coins") valid_num_coins = struct.unpack("