11#! /usr/bin/env bash
22#
3- # Copyright (c) 2019 The Bitcoin Core developers
3+ # Copyright (c) 2019-2023 The Bitcoin Core developers
44# Distributed under the MIT software license, see the accompanying
55# file COPYING or http://www.opensource.org/licenses/mit-license.php.
66#
77export LC_ALL=C
88
99set -ueo pipefail
1010
11+ NETWORK_DISABLED=false
12+
1113if (( $# < 3 )) ; then
1214 echo ' Usage: utxo_snapshot.sh <generate-at-height> <snapshot-out-path> <bitcoin-cli-call ...>'
1315 echo
@@ -26,9 +28,60 @@ OUTPUT_PATH="${1}"; shift;
2628# Most of the calls we make take a while to run, so pad with a lengthy timeout.
2729BITCOIN_CLI_CALL=" ${* } -rpcclienttimeout=9999999"
2830
31+ # Check if the node is pruned and get the pruned block height
32+ PRUNED=$( ${BITCOIN_CLI_CALL} getblockchaininfo | awk ' /pruneheight/ {print $2}' | tr -d ' ,' )
33+
34+ if (( GENERATE_AT_HEIGHT < PRUNED )) ; then
35+ echo " Error: The requested snapshot height (${GENERATE_AT_HEIGHT} ) should be greater than the pruned block height (${PRUNED} )."
36+ exit 1
37+ fi
38+
39+ # Early exit if file at OUTPUT_PATH already exists
40+ if [[ -e " $OUTPUT_PATH " ]]; then
41+ (>&2 echo " Error: $OUTPUT_PATH already exists or is not a valid path." )
42+ exit 1
43+ fi
44+
45+ # Validate that the path is correct
46+ if [[ " ${OUTPUT_PATH} " != " -" && ! -d " $( dirname " ${OUTPUT_PATH} " ) " ]]; then
47+ (>&2 echo " Error: The directory $( dirname " ${OUTPUT_PATH} " ) does not exist." )
48+ exit 1
49+ fi
50+
51+ function cleanup {
52+ (>&2 echo " Restoring chain to original height; this may take a while" )
53+ ${BITCOIN_CLI_CALL} reconsiderblock " ${PIVOT_BLOCKHASH} "
54+
55+ if $NETWORK_DISABLED ; then
56+ (>&2 echo " Restoring network activity" )
57+ ${BITCOIN_CLI_CALL} setnetworkactive true
58+ fi
59+ }
60+
61+ function early_exit {
62+ (>&2 echo " Exiting due to Ctrl-C" )
63+ cleanup
64+ exit 1
65+ }
66+
67+ # Prompt the user to disable network activity
68+ read -p " Do you want to disable network activity (setnetworkactive false) before running invalidateblock? (Y/n): " -r
69+ if [[ " $REPLY " =~ ^[Yy]* $ || -z " $REPLY " ]]; then
70+ # User input is "Y", "y", or Enter key, proceed with the action
71+ NETWORK_DISABLED=true
72+ (>&2 echo " Disabling network activity" )
73+ ${BITCOIN_CLI_CALL} setnetworkactive false
74+ else
75+ (>&2 echo " Network activity remains enabled" )
76+ fi
77+
2978# Block we'll invalidate/reconsider to rewind/fast-forward the chain.
3079PIVOT_BLOCKHASH=$( $BITCOIN_CLI_CALL getblockhash $(( GENERATE_AT_HEIGHT + 1 )) )
3180
81+ # Trap for normal exit and Ctrl-C
82+ trap cleanup EXIT
83+ trap early_exit INT
84+
3285(>&2 echo " Rewinding chain back to height ${GENERATE_AT_HEIGHT} (by invalidating ${PIVOT_BLOCKHASH} ); this may take a while" )
3386${BITCOIN_CLI_CALL} invalidateblock " ${PIVOT_BLOCKHASH} "
3487
3992 (>&2 echo " Generating UTXO snapshot..." )
4093 ${BITCOIN_CLI_CALL} dumptxoutset " ${OUTPUT_PATH} "
4194fi
42-
43- (>&2 echo " Restoring chain to original height; this may take a while" )
44- ${BITCOIN_CLI_CALL} reconsiderblock " ${PIVOT_BLOCKHASH} "
0 commit comments