Skip to content

Commit 9620cb4

Browse files
committed
assumeutxo: fail early if snapshot block hash doesn't match AssumeUTXO parameters
1 parent 78b7e95 commit 9620cb4

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

src/rpc/blockchain.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2737,6 +2737,7 @@ static RPCHelpMan loadtxoutset()
27372737
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
27382738
{
27392739
NodeContext& node = EnsureAnyNodeContext(request.context);
2740+
ChainstateManager& chainman = EnsureChainman(node);
27402741
fs::path path{AbsPathForConfigVal(EnsureArgsman(node), fs::u8path(request.params[0].get_str()))};
27412742

27422743
FILE* file{fsbridge::fopen(path, "rb")};
@@ -2751,14 +2752,16 @@ static RPCHelpMan loadtxoutset()
27512752
afile >> metadata;
27522753

27532754
uint256 base_blockhash = metadata.m_base_blockhash;
2755+
if (!chainman.GetParams().AssumeutxoForBlockhash(base_blockhash).has_value()) {
2756+
throw JSONRPCError(RPC_INTERNAL_ERROR, strprintf("Unable to load UTXO snapshot, "
2757+
"assumeutxo block hash in snapshot metadata not recognized (%s)", base_blockhash.ToString()));
2758+
}
27542759
int max_secs_to_wait_for_headers = 60 * 10;
27552760
CBlockIndex* snapshot_start_block = nullptr;
27562761

27572762
LogPrintf("[snapshot] waiting to see blockheader %s in headers chain before snapshot activation\n",
27582763
base_blockhash.ToString());
27592764

2760-
ChainstateManager& chainman = EnsureChainman(node);
2761-
27622765
while (max_secs_to_wait_for_headers > 0) {
27632766
snapshot_start_block = WITH_LOCK(::cs_main,
27642767
return chainman.m_blockman.LookupBlockIndex(base_blockhash));

test/functional/feature_assumeutxo.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,12 @@ def test_invalid_snapshot_scenarios(self, valid_snapshot_path):
7373
bad_snapshot_path = valid_snapshot_path + '.mod'
7474

7575
self.log.info(" - snapshot file refering to a block that is not in the assumeutxo parameters")
76-
# we can only test this with a block that is already known, as otherwise the `loadtxoutset` RPC
77-
# would time out (waiting to see the hash in the headers chain), rather than error immediately
78-
bad_snapshot_height = SNAPSHOT_BASE_HEIGHT - 1
76+
bad_snapshot_block_hash = self.nodes[0].getblockhash(SNAPSHOT_BASE_HEIGHT - 1)
7977
with open(bad_snapshot_path, 'wb') as f:
80-
bad_snapshot_block_hash = self.nodes[0].getblockhash(bad_snapshot_height)
8178
# block hash of the snapshot base is stored right at the start (first 32 bytes)
8279
f.write(bytes.fromhex(bad_snapshot_block_hash)[::-1] + valid_snapshot_contents[32:])
83-
84-
expected_log = f"assumeutxo height in snapshot metadata not recognized ({bad_snapshot_height}) - refusing to load snapshot"
85-
with self.nodes[1].assert_debug_log([expected_log]):
86-
assert_raises_rpc_error(-32603, "Unable to load UTXO snapshot", self.nodes[1].loadtxoutset, bad_snapshot_path)
80+
error_details = f"assumeutxo block hash in snapshot metadata not recognized ({bad_snapshot_block_hash})"
81+
assert_raises_rpc_error(-32603, f"Unable to load UTXO snapshot, {error_details}", self.nodes[1].loadtxoutset, bad_snapshot_path)
8782

8883
self.log.info(" - snapshot file with wrong number of coins")
8984
valid_num_coins = struct.unpack("<I", valid_snapshot_contents[32:32 + 4])[0]

0 commit comments

Comments
 (0)