#!/usr/bin/env sh set -e snapshot_protocol () { f_proto_name="$1" f_proto_dir="$2" # snapshot protocol alpha into new directory echo " Calling: ./scripts/snapshot_alpha $f_proto_name." ./scripts/snapshot_alpha.sh "$f_proto_name" # link new protocol for the shell and client echo " Calling: ./scripts/link_protocol.sh $f_proto_dir." # $f_proto_dir might contain a wildcard # shellcheck disable=SC2086 ./scripts/link_protocol.sh $f_proto_dir } user_activated_upgrade () { f_proto_dir="$1" f_mig_level="$2" # activate the migration at a specific level echo " Calling: ./scripts/user_activated_upgrade.sh $f_proto_dir $f_mig_level." ./scripts/user_activated_upgrade.sh "$f_proto_dir" "$f_mig_level" } import_snapshot () { f_snapshot_path="$1" f_blockhash="$2" [ -n "$f_blockhash" ] && f_blockhash_opt="--block $f_blockhash" # The command ${snapshot%.(rolling|full|archive} did not worked for no # found reason context_dir="${f_snapshot_path%.rolling}" context_dir="${context_dir%.full}" context_dir="${context_dir%.archive}" context_dir="$tmp_dir/tezos-node-${context_dir##*/}" if [ -d "$context_dir" ] then echo " Found existing context in directory ${context_dir} If you want to re-import the context from ${f_snapshot_path} please delete directory ${context_dir} The context in ${context_dir} will be used for the test." else echo " Importing context from $f_snapshot_path into $context_dir." # $f_snapshot_path might be empty # shellcheck disable=SC2086 ./tezos-node snapshot import "$f_snapshot_path" --data-dir "$context_dir" $f_blockhash_opt fi } generate_identities (){ f_context_dir="$1" ./tezos-node identity generate --data-dir "$f_context_dir" } patch_yes_node () { echo " Patching the code to obtain a yes-node." patch -p1 < ./scripts/yes-node.patch } create_yes_wallet () { yes_wallet="$tmp_dir/yes-wallet" if [ -d "$yes_wallet" ] then echo " Found existing yes-wallet in directory ${yes_wallet}. The yes-wallet in ${yes_wallet} will be used for the test after deleting spurious files ${yes_wallet}/{blocks,wallet_locks}." [ -f "${yes_wallet}/blocks" ] && rm "${yes_wallet}/blocks" [ -f "${yes_wallet}/wallet_lock" ] && rm "${yes_wallet}/wallet_lock" else echo " Creating a yes-wallet in directory ${yes_wallet}." dune exec devtools/yes_wallet/yes_wallet.exe -- create minimal in "$yes_wallet" fi echo "You can now bake for foundation{1..8}." } first_hash() { jq -r .hash < "$1" } #setting tmp dir if [ -n "$TMP" ] then tmp_dir="$TMP" elif [ -n "$TMPDIR" ] then tmp_dir="$TMPDIR" else tmp_dir="/tmp" fi usage="Usage: This script prepares the environment to perform migration tests. Use the parameter 'manual' or 'auto' for respectively the manual or the automatic procedure. ## MANUAL PROCEDURE ## #### Migration on the sandbox #### $ ./scripts/prepare_migration_test.sh manual \\ [_] When passing a low level (less or equal than 28082) the script assumes that migration is run on the sandbox: When the optional parameter _ is provided, then the script snapshots the Alpha protocol and renames the sandbox command tezos-activate-alpha that activates the Alpha protocol to the command tezos-activate-_ which activates the predecessor of the Alpha protocol. The coincides with minus one, and the coincides the the short hash in the name of the folder that contains the predecessor of the Alpha protocol in the src directory, i.e., the folder ./src/proto__ #### Migration on a context imported from Mainnet #### $ ./scripts/prepare_migration_test.sh manual \\ [_] [] \\ [] When passing a high level (greater than 28082) the script assumes that migration is run on a context imported from Mainnet: The script patches the code to produce a yes-node, and creates a yes-wallet folder in the system's temp folder when such folder does not exist already. If the optional parameter is provided, then the script imports a context from the file specified by the parameter and places it in a folder with the same name than the snapshot file (without the extension) under the system's temp directory. If the optional parameter is provided, then the script checks that the hash of the last block in the imported chain is . ## AUTOMATIC PROCEDURE ## $ ./scripts/prepare_migration_test.sh auto \\ [_] [] If the optional parameter _ is provided, then the script snapshots the Alpha protocol into a new folder src/proto__ and computes a realistic hash of the protocol. Otherwise the script prepares the migration for the Alpha protocol in the folder src/proto_alpha. It also patches the code to produce a yes-node. The script imports a context from the snapshot file and places it in a folder with the same name than the snapshot file (without the extension) under the system's temp directory. If the optional parameter is provided, then the script checks that the hash of the last block in the imported chain is . " # manual or auto mode # if ! { [ "$1" = "manual" ] || [ "$1" = "auto" ] ;} || [ $# -lt 2 ] then echo "$usage" exit 1 else mode="$1" fi #set variable related to protocol, in particular \$proto_version and \$pred_proto_version if echo "$2" | grep -q '^[a-z]\+_[0-9][0-9][0-9]$'; then proto_name="$2" proto_version=$(echo "$proto_name" | cut -d'_' -f2) proto_dir="src/proto_${proto_version}_*/" # strip leading zeros to prevent version being treated as octal proto_version=$(echo "$proto_version" | sed 's/^0*//') pred_proto_version=$(printf "%03d" $((proto_version - 1))) else pred_proto_name=$(find src -name "proto_[0-9][0-9][0-9]_*" | awk -F'/' '{print $NF}' | sort -r | head -1) pred_proto_version=$(echo "$pred_proto_name" | cut -d'_' -f2) proto_dir="src/proto_alpha/" fi # now calls correct scripts and renaming if [ -n "$proto_name" ] then snapshot_protocol "$proto_name" $proto_dir fi echo " Setting environment for $mode test" if [ "$mode" = "auto" ] then #set \$snapshot_path if [ -n "$proto_name" ] then snapshot_path="$3" blockhash="$4" else snapshot_path="$2" blockhash="$3" fi # check if path exists if ! [ -f "$snapshot_path" ] then echo "$usage" exit 1 fi patch_yes_node make tezt_env="" if [ -n "$proto_name" ] then full_hash=$(first_hash ${proto_dir}/lib_protocol/TEZOS_PROTOCOL) tezt_env="TEZT_MIGRATION_TEST_PROTOCOL=$full_hash " fi import_snapshot "$snapshot_path" "$blockhash" [ -f "$context_dir/identity.json" ] && rm "$context_dir/identity.json" tezt_env="${tezt_env}TEZT_MIGRATION_TEST_CONTEXT=$context_dir " # remove files generated by sed find . -name '*.old' -exec rm {} \; echo " Use the following commands to run the test: $ ${tezt_env}dune exec ./tezt/manual_tests/main.exe -- --keep-temp migration After the test ends, note down the path of the temporary files $tmp_dir/tezt-XXXXXX, where XXXXXX are six random decimal figures. Use the following commands to start the node in the resulting context after migration, replacing the XXXXXX below with the value that you noted down before: $ ./tezos-node run --connections 0 --data-dir $tmp_dir/tezt-XXXXXX/tezos-node-test --rpc-addr localhost & You can then inspect the storage, or bake blocks with the command: $ ./tezos-client -d $tmp_dir/tezt-XXXXXX/yes-wallet bake for foundation1 --minimal-timestamp In order to re-run the migration test, kill any node that may be running and use the command for running the test above (the script needs not to be run again). Please adapt the test file ./tezt/manual_tests/migration.ml to your specific needs." elif [ "$mode" = "manual" ] then #set \$mig_level \$snapshot_path if [ -n "$proto_name" ] then mig_level=$3 snapshot_path=$4 blockhash=$5 else mig_level=$2 snapshot_path=$3 blockhash=$4 fi # check if \$mig_level is set if [ -z "$mig_level" ] then echo "$usage" exit 1 fi user_activated_upgrade $proto_dir "$mig_level" pred_full_hash=$(first_hash src/proto_"${pred_proto_version}"_*/lib_protocol/TEZOS_PROTOCOL) pred_short_hash=$(echo "$pred_full_hash" | head -c 8) # now calls correct scripts and renaming if [ "$mig_level" -le 28082 ]; then # Env test use a fresh context and no yes-node/wallet echo " The script detected that you will do a migration on the sandbox." make echo " Use the following commands to start the sandboxed node: $ ./src/bin_node/tezos-sandboxed-node.sh 1 --connections 0 & $ eval \`./src/bin_client/tezos-init-sandboxed-client.sh 1\` $ tezos-activate-${pred_proto_version}-${pred_short_hash} Then bake blocks until the chain reaches level $mig_level with: $ tezos-client bake for bootstrap1 --minimal-timestamp In order to re-run the migration test, kill the sandboxed node and run the commands above (the script needs not to be run again)." else # \$mig_level > 28082 patch_yes_node create_yes_wallet make if [ -n "$snapshot_path" ] && [ -f "$snapshot_path" ] then import_snapshot "$snapshot_path" "$blockhash" ! [ -f "$context_dir/identity.json" ] && generate_identities "$context_dir" else context_dir="path/to/tezos-node-context" echo " No snapshot file provided. Please use the following commands to import a context manually: $ ./tezos-node snapshot import --data-dir $ ./tezos-node identity generate --data-dir " fi echo " Use the following commands to start the node with the imported context: $ test_directory=\$(mktemp -d -t \"${context_dir##*/}-XXXX\") && cp -r \"$context_dir/.\" \"\$test_directory\" $ ./tezos-node run --connections 0 --data-dir \"\$test_directory\" --rpc-addr localhost & Then bake blocks until the chain reaches level $mig_level with: $ ./tezos-client -d $yes_wallet bake for foundation1 --minimal-timestamp In order to re-run the migration test, kill the node and delete spurious fil by using: $ rm -rf \"\$test_directory\" && rm -f $yes_wallet/{blocks,wallet_lock} Then run the commands to start the node and to bake blocks above (the script needs not to be run again). Please adapt these commands to your case if you are using different folders for the yes-wallet and/or the imported context." fi fi