diff --git a/src/cardonnay_scripts/scripts/common/start-cluster b/src/cardonnay_scripts/scripts/common/common-start-fast similarity index 100% rename from src/cardonnay_scripts/scripts/common/start-cluster rename to src/cardonnay_scripts/scripts/common/common-start-fast diff --git a/src/cardonnay_scripts/scripts/common/common-start-slow b/src/cardonnay_scripts/scripts/common/common-start-slow new file mode 100644 index 0000000..7a8a7a8 --- /dev/null +++ b/src/cardonnay_scripts/scripts/common/common-start-slow @@ -0,0 +1,1205 @@ +#!/usr/bin/env bash + +# Cardano local cluster startup script +# This script sets up and starts a local Cardano test cluster, bootstrapping it through +# all eras from Byron to Conway, registering pools and governance entities. + +set -Eeuo pipefail +trap 'echo "Error at line $LINENO in ${BASH_SOURCE[0]}" >&2' ERR + +readonly PROTOCOL_VERSION="${PROTOCOL_VERSION:-10}" +readonly NUM_BFT_NODES=1 +readonly NUM_CC=5 +readonly NUM_DREPS=5 +readonly TX_SUBMISSION_DELAY=60 +readonly PROPOSAL_DELAY=5 +readonly SUBMIT_DELAY=5 +readonly POOL_PLEDGE=1000000000000 +readonly DREP_DELEGATED=500000000000 +readonly FEE=5000000 + +readonly INSTANCE_NUM="%%INSTANCE_NUM%%" +readonly NUM_POOLS=%%NUM_POOLS%% +readonly NODE_PORT_BASE=%%NODE_PORT_BASE%% +readonly PORTS_PER_NODE=%%PORTS_PER_NODE%% +readonly WEBSERVER_PORT=%%WEBSERVER_PORT%% + +initialize_globals() { + if [ -z "${CARDANO_NODE_SOCKET_PATH:-}" ]; then + echo "CARDANO_NODE_SOCKET_PATH is not set" >&2 + exit 1 + fi + + SCRIPT_DIR="$(readlink -m "${0%/*}")" + readonly SCRIPT_DIR + SOCKET_PATH="$(readlink -m "$CARDANO_NODE_SOCKET_PATH")" + readonly SOCKET_PATH + readonly STATE_CLUSTER="${SOCKET_PATH%/*}" + + if [ "$PWD" = "$STATE_CLUSTER" ]; then + echo "Please run this script from outside of '$STATE_CLUSTER'" >&2 + exit 1 + fi + + readonly STATE_CLUSTER_NAME="${STATE_CLUSTER##*/}" + readonly SUPERVISORD_SOCKET_PATH="${STATE_CLUSTER}/supervisord.sock" + readonly START_CLUSTER_STATUS="${STATE_CLUSTER}/status_started" + readonly PPARAMS_FILE="${STATE_CLUSTER}/pparams.json" + + if [[ "$SOCKET_PATH" != *"/state-cluster${INSTANCE_NUM}/"* ]]; then + echo "CARDANO_NODE_SOCKET_PATH must be set to a path containing 'state-cluster${INSTANCE_NUM}', line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi + + if [ -e "$SUPERVISORD_SOCKET_PATH" ]; then + echo "Cluster already running. Please run \`${STATE_CLUSTER}/stop-cluster\` first!" >&2 + exit 1 + fi + + if [ "$NUM_POOLS" -lt 3 ]; then + echo "NUM_POOLS must be at least 3" >&2 + exit 1 + fi + + case "${UTXO_BACKEND:=""}" in + "" | mem | disk) + ;; + *) + echo "Unknown \`UTXO_BACKEND\`: '$UTXO_BACKEND', line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + ;; + esac + readonly UTXO_BACKEND + + SECURITY_PARAM="$(jq '.securityParam' < "${SCRIPT_DIR}/genesis.spec.json")" + readonly SECURITY_PARAM + NETWORK_MAGIC="$(jq '.networkMagic' < "${SCRIPT_DIR}/genesis.spec.json")" + readonly NETWORK_MAGIC + MAX_SUPPLY="$(jq '.maxLovelaceSupply' < "${SCRIPT_DIR}/genesis.spec.json")" + readonly MAX_SUPPLY + POOL_COST="$(jq '.protocolParams.minPoolCost' < "${SCRIPT_DIR}/genesis.spec.json")" + if [ "$POOL_COST" -eq 0 ]; then + POOL_COST=600 + fi + readonly POOL_COST + + # shellcheck disable=SC1091 + source "${SCRIPT_DIR}/common.sh" + + if [ -e "${SCRIPT_DIR}/shell_env" ]; then + # shellcheck disable=SC1091 + source "${SCRIPT_DIR}/shell_env" + fi + + readonly FUNDS_PER_GENESIS_ADDRESS="$((MAX_SUPPLY / NUM_BFT_NODES))" + readonly FUNDS_PER_BYRON_ADDRESS="$((FUNDS_PER_GENESIS_ADDRESS * 8 / 10))" +} + +create_genesis() { + local start_time + local start_time_shelley + + start_time_shelley="$(date --utc +"%Y-%m-%dT%H:%M:%SZ" --date="5 seconds")" + start_time="$(date +%s --date="$start_time_shelley")" + echo "$start_time" > "${STATE_CLUSTER}/cluster_start_time" + + # Create Byron genesis + + cardano_cli_log byron genesis genesis \ + --protocol-magic "$NETWORK_MAGIC" \ + --k "$SECURITY_PARAM" \ + --n-poor-addresses 0 \ + --n-delegate-addresses "$NUM_BFT_NODES" \ + --total-balance "$MAX_SUPPLY" \ + --delegate-share 1 \ + --avvm-entry-count 0 \ + --avvm-entry-balance 0 \ + --protocol-parameters-file "${STATE_CLUSTER}/byron-params.json" \ + --genesis-output-dir "${STATE_CLUSTER}/byron" \ + --start-time "$start_time" + + mv "${STATE_CLUSTER}/byron-params.json" "${STATE_CLUSTER}/byron/params.json" + + # Create Shelley genesis and subsequent era genesis files + + local genesis_args=( \ + --genesis-dir "${STATE_CLUSTER}/shelley" \ + --testnet-magic "$NETWORK_MAGIC" \ + --gen-genesis-keys "$NUM_BFT_NODES" \ + --start-time "$start_time_shelley" \ + --gen-utxo-keys 1 + ) + + if ! cardano_cli_log legacy genesis create --shelley "${genesis_args[@]}"; then + echo "Never mind the error above, retrying the genesis create with legacy arguments" >&2 + cardano_cli_log legacy genesis create "${genesis_args[@]}" + fi + + if [ ! -e "${STATE_CLUSTER}/shelley/genesis.dijkstra.json" ] \ + && [ -e "${STATE_CLUSTER}/shelley/genesis.dijkstra.spec.json" ]; then + cp "${STATE_CLUSTER}/shelley/genesis.dijkstra.spec.json" \ + "${STATE_CLUSTER}/shelley/genesis.dijkstra.json" + fi + + jq -r ' + .initialFunds = {}' \ + < "${STATE_CLUSTER}/shelley/genesis.json" > "${STATE_CLUSTER}/shelley/genesis.json_jq" + cat "${STATE_CLUSTER}/shelley/genesis.json_jq" > "${STATE_CLUSTER}/shelley/genesis.json" + rm -f "${STATE_CLUSTER}/shelley/genesis.json_jq" + + jq '.costModels.PlutusV2 |= .[0:175]' \ + < "${STATE_CLUSTER}/shelley/genesis.alonzo.json" > "${STATE_CLUSTER}/shelley/genesis.alonzo.json_jq" + cat "${STATE_CLUSTER}/shelley/genesis.alonzo.json_jq" > "${STATE_CLUSTER}/shelley/genesis.alonzo.json" + rm -f "${STATE_CLUSTER}/shelley/genesis.alonzo.json_jq" +} + +get_genesis_data() { + KEY_DEPOSIT="$(jq '.protocolParams.keyDeposit' \ + < "${STATE_CLUSTER}/shelley/genesis.json")" + readonly KEY_DEPOSIT + POOL_DEPOSIT="$(jq '.protocolParams.poolDeposit' \ + < "${STATE_CLUSTER}/shelley/genesis.json")" + readonly POOL_DEPOSIT + DREP_DEPOSIT="$(jq '.dRepDeposit' \ + < "${STATE_CLUSTER}/shelley/genesis.conway.json")" + readonly DREP_DEPOSIT + GOV_ACTION_DEPOSIT="$(jq '.govActionDeposit' \ + < "${STATE_CLUSTER}/shelley/genesis.conway.json")" + readonly GOV_ACTION_DEPOSIT + + BYRON_GENESIS_HASH="$(cardano_cli_log byron genesis print-genesis-hash --genesis-json \ + "${STATE_CLUSTER}/byron/genesis.json")" + readonly BYRON_GENESIS_HASH + SHELLEY_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ + "${STATE_CLUSTER}/shelley/genesis.json")" + readonly SHELLEY_GENESIS_HASH + ALONZO_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ + "${STATE_CLUSTER}/shelley/genesis.alonzo.json")" + readonly ALONZO_GENESIS_HASH + CONWAY_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ + "${STATE_CLUSTER}/shelley/genesis.conway.json")" + readonly CONWAY_GENESIS_HASH + DIJKSTRA_GENESIS_HASH="" + if [ "$PROTOCOL_VERSION" -ge 11 ]; then + DIJKSTRA_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ + "${STATE_CLUSTER}/shelley/genesis.dijkstra.json")" + fi + readonly DIJKSTRA_GENESIS_HASH +} + +edit_node_configs() { + local live_tables_base="${STATE_CLUSTER_NAME}/lmdb" + local conf fname node_name pool_num + + for conf in "$SCRIPT_DIR"/config-*.json; do + [ -e "$conf" ] || { echo "No config files found in ${SCRIPT_DIR}, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + fname="${conf##*/}" + node_name="${fname##config-}" + node_name="${node_name%.json}" + + jq \ + --arg byron_hash "$BYRON_GENESIS_HASH" \ + --arg shelley_hash "$SHELLEY_GENESIS_HASH" \ + --arg alonzo_hash "$ALONZO_GENESIS_HASH" \ + --arg conway_hash "$CONWAY_GENESIS_HASH" \ + --arg dijkstra_hash "$DIJKSTRA_GENESIS_HASH" \ + --arg backend "$UTXO_BACKEND" \ + --arg live_tables_path "${live_tables_base}-${node_name}" \ + '.ByronGenesisHash = $byron_hash + | .ShelleyGenesisHash = $shelley_hash + | .AlonzoGenesisHash = $alonzo_hash + | .ConwayGenesisHash = $conway_hash + | if $dijkstra_hash != "" then + (.DijkstraGenesisFile = "shelley/genesis.dijkstra.json" + | .DijkstraGenesisHash = $dijkstra_hash + | .ExperimentalProtocolsEnabled = true + | .ExperimentalHardForksEnabled = true) + else + . + end + | if $backend == "mem" then + (.LedgerDB.Backend = "V2InMemory" + | .LedgerDB.NumOfDiskSnapshots = 2 + | .LedgerDB.QueryBatchSize = 100000 + | .LedgerDB.SnapshotInterval = 216) + elif $backend == "disk" then + (.LedgerDB.Backend = "V1LMDB" + | .LedgerDB.LiveTablesPath = $live_tables_path) + elif has("LedgerDB") then + .LedgerDB |= del(.Backend) + else + . + end + | if (.LedgerDB? // {}) == {} then del(.LedgerDB) else . end + ' "$conf" > "${STATE_CLUSTER}/${fname}" + + if [ -z "${ENABLE_LEGACY:-}" ]; then + if [ -n "${MIXED_P2P:-}" ]; then + if [ "$fname" = "config-bft1.json" ]; then + cp -f "$SCRIPT_DIR"/topology-bft1.json "$STATE_CLUSTER" + continue + fi + + pool_num="${fname##*-pool}" + pool_num="${pool_num%.json}" + if [ "$((pool_num % 2))" != 0 ]; then + cp -f "${SCRIPT_DIR}/topology-pool${pool_num}.json" "$STATE_CLUSTER" + continue + fi + fi + + jq \ + '.EnableP2P = true + | .MaxConcurrencyBulkSync = 2 + | .MaxConcurrencyDeadline = 4 + | .TargetNumberOfRootPeers = 100 + | .TargetNumberOfKnownPeers = 100 + | .TargetNumberOfEstablishedPeers = 50 + | .TargetNumberOfActivePeers = 20 + | .TraceBlockFetchClient = true + | .TraceChainSyncClient = true' \ + "${STATE_CLUSTER}/${fname}" > "${STATE_CLUSTER}/${fname}_jq" + cat "${STATE_CLUSTER}/${fname}_jq" > "${STATE_CLUSTER}/${fname}" + rm -f "${STATE_CLUSTER}/${fname}_jq" + fi + done +} + +create_bft_nodes_files() { + local i index bft_port + + for i in $(seq 1 "$NUM_BFT_NODES"); do + mkdir -p "${STATE_CLUSTER}/nodes/node-bft$i" + ln -s "../../shelley/delegate-keys/delegate${i}.vrf.skey" "${STATE_CLUSTER}/nodes/node-bft${i}/vrf.skey" + ln -s "../../shelley/delegate-keys/delegate${i}.vrf.vkey" "${STATE_CLUSTER}/nodes/node-bft${i}/vrf.vkey" + + cardano_cli_log latest node key-gen-KES \ + --verification-key-file "${STATE_CLUSTER}/nodes/node-bft${i}/kes.vkey" \ + --signing-key-file "${STATE_CLUSTER}/nodes/node-bft${i}/kes.skey" + + cardano_cli_log latest node issue-op-cert \ + --kes-period 0 \ + --cold-signing-key-file "${STATE_CLUSTER}/shelley/delegate-keys/delegate${i}.skey" \ + --kes-verification-key-file "${STATE_CLUSTER}/nodes/node-bft${i}/kes.vkey" \ + --operational-certificate-issue-counter-file \ + "${STATE_CLUSTER}/shelley/delegate-keys/delegate${i}.counter" \ + --out-file "${STATE_CLUSTER}/nodes/node-bft${i}/op.cert" + + index="$(printf "%03d" $((i - 1)))" + + cardano_cli_log byron key keygen \ + --secret "${STATE_CLUSTER}/byron/payment-keys.${index}.key" + + cardano_cli_log byron key signing-key-address \ + --byron-formats \ + --testnet-magic "$NETWORK_MAGIC" \ + --secret "${STATE_CLUSTER}/byron/payment-keys.${index}.key" > "${STATE_CLUSTER}/byron/address-${index}" + + cardano_cli_log byron key signing-key-address \ + --byron-formats \ + --testnet-magic "$NETWORK_MAGIC" \ + --secret "${STATE_CLUSTER}/byron/genesis-keys.${index}.key" \ + > "${STATE_CLUSTER}/byron/genesis-address-${index}" + + ln -s "../../byron/delegate-keys.${index}.key" "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.key" + ln -s "../../byron/delegation-cert.${index}.json" "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.json" + + cardano_cli_log byron transaction issue-genesis-utxo-expenditure \ + --genesis-json "${STATE_CLUSTER}/byron/genesis.json" \ + --testnet-magic "$NETWORK_MAGIC" \ + --byron-formats \ + --tx "${STATE_CLUSTER}/byron/tx${i}.tx" \ + --wallet-key "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.key" \ + --rich-addr-from "$(head -n 1 "${STATE_CLUSTER}/byron/genesis-address-${index}")" \ + --txout "(\"$(head -n 1 "${STATE_CLUSTER}/byron/address-${index}")\", ${FUNDS_PER_BYRON_ADDRESS})" + + cardano_cli_log latest key convert-byron-key \ + --byron-signing-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}.key" \ + --out-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.skey" \ + --byron-payment-key-type + + cardano_cli_log latest key verification-key \ + --signing-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.skey" \ + --verification-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.vkey" + + cardano_cli_log latest address build \ + --testnet-magic "$NETWORK_MAGIC" \ + --payment-verification-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.vkey" \ + > "${STATE_CLUSTER}/byron/address-${index}-converted" + + bft_port="$((NODE_PORT_BASE + (i - 1) * PORTS_PER_NODE ))" + echo "$bft_port" > "${STATE_CLUSTER}/nodes/node-bft${i}/port" + done +} + +_create_pool_node_keys() { + local pool_ix="${1:?}" + + mkdir -p "${STATE_CLUSTER}/nodes/node-pool${pool_ix}" + echo "Generating Pool $pool_ix Secrets" + + cardano_cli_log latest address key-gen \ + --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-utxo.skey" \ + --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-utxo.vkey" + cardano_cli_log latest stake-address key-gen \ + --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.skey" \ + --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" + cardano_cli_log latest address build \ + --payment-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-utxo.vkey" \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --testnet-magic "$NETWORK_MAGIC" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner.addr" + cardano_cli_log latest stake-address build \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --testnet-magic "$NETWORK_MAGIC" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.addr" + cardano_cli_log compatible shelley stake-address registration-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake.reg.shelley.cert" + cardano_cli_log conway stake-address registration-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --key-reg-deposit-amt "$KEY_DEPOSIT" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake.reg.cert" + + cardano_cli_log latest stake-address key-gen \ + --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.skey" \ + --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" + cardano_cli_log compatible shelley stake-address registration-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake-reward.reg.shelley.cert" + cardano_cli_log conway stake-address vote-delegation-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ + --always-abstain \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake-reward.vote_deleg.cert" + cardano_cli_log conway stake-address registration-and-vote-delegation-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ + --always-abstain \ + --key-reg-deposit-amt "$KEY_DEPOSIT" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake-reward.reg.cert" + + cardano_cli_log latest node key-gen \ + --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ + --cold-signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.skey" \ + --operational-certificate-issue-counter-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.counter" + cardano_cli_log latest node key-gen-KES \ + --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/kes.vkey" \ + --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/kes.skey" + cardano_cli_log latest node key-gen-VRF \ + --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.vkey" \ + --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.skey" + + cardano_cli_log compatible shelley stake-address stake-delegation-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.deleg.shelley.cert" + cardano_cli_log conway stake-address stake-delegation-certificate \ + --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.deleg.cert" + + cardano_cli_log latest node issue-op-cert \ + --kes-period 0 \ + --cold-signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.skey" \ + --kes-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/kes.vkey" \ + --operational-certificate-issue-counter-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.counter" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/op.cert" +} + +_create_pool_registration() { + local pool_ix="${1:?}" + local metadata_url="http://localhost:${WEBSERVER_PORT}/pool${pool_ix}.json" + local metadata_hash pool_port + + metadata_hash="$(cardano_cli_log latest stake-pool metadata-hash --pool-metadata-file \ + "${STATE_CLUSTER}/webserver/pool${pool_ix}.json")" + pool_port="$((NODE_PORT_BASE + (NUM_BFT_NODES + pool_ix - 1) * PORTS_PER_NODE))" + echo "$pool_port" > "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/port" + echo "$POOL_PLEDGE" > "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/pledge" + + cardano_cli_log compatible shelley stake-pool registration-certificate \ + --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ + --vrf-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.vkey" \ + --pool-pledge "$POOL_PLEDGE" \ + --pool-margin 0.35 \ + --pool-cost "$POOL_COST" \ + --pool-reward-account-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ + --pool-owner-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --metadata-url "$metadata_url" \ + --metadata-hash "$metadata_hash" \ + --pool-relay-port "$pool_port" \ + --pool-relay-ipv4 "127.0.0.1" \ + --testnet-magic "$NETWORK_MAGIC" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/register.shelley.cert" + cardano_cli_log conway stake-pool registration-certificate \ + --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ + --vrf-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.vkey" \ + --pool-pledge "$POOL_PLEDGE" \ + --pool-margin 0.35 \ + --pool-cost "$POOL_COST" \ + --pool-reward-account-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ + --pool-owner-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ + --metadata-url "$metadata_url" \ + --metadata-hash "$metadata_hash" \ + --pool-relay-port "$pool_port" \ + --pool-relay-ipv4 "127.0.0.1" \ + --testnet-magic "$NETWORK_MAGIC" \ + --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/register.cert" +} + +create_pools_files() { + local i + for i in $(seq 1 "$NUM_POOLS"); do + _create_pool_node_keys "$i" + create_pool_metadata "$i" + _create_pool_registration "$i" + done + + mv "${STATE_CLUSTER}/shelley/utxo-keys/utxo1.vkey" "${STATE_CLUSTER}/shelley/genesis-utxo.vkey" + mv "${STATE_CLUSTER}/shelley/utxo-keys/utxo1.skey" "${STATE_CLUSTER}/shelley/genesis-utxo.skey" + rmdir "${STATE_CLUSTER}/shelley/utxo-keys" +} + +create_byron_update_proposal() { + local proposal_file="${1:?Proposal file argument is required}" + local protocol_major="${2:?Protocol major version argument is required}" + local protocol_minor="${3:?Protocol minor version argument is required}" + + cardano_cli_log byron governance create-update-proposal \ + --filepath "$proposal_file" \ + --testnet-magic "$NETWORK_MAGIC" \ + --signing-key "${STATE_CLUSTER}/nodes/node-bft1/byron-deleg.key" \ + --protocol-version-major "$protocol_major" \ + --protocol-version-minor "$protocol_minor" \ + --protocol-version-alt 0 \ + --application-name "cardano-sl" \ + --software-version-num 1 \ + --system-tag "linux" \ + --installer-hash 0 +} + +submit_byron_proposal_with_votes() { + local proposal_file="${1:?Proposal file argument is required}" + local vote_base="${2:?Vote base argument is required}" + local i + + cardano_cli_log byron governance submit-update-proposal \ + --testnet-magic "$NETWORK_MAGIC" \ + --filepath "$proposal_file" + sleep 5 + + for i in $(seq 1 "$NUM_BFT_NODES"); do + cardano_cli_log byron governance create-proposal-vote \ + --proposal-filepath "$proposal_file" \ + --testnet-magic "$NETWORK_MAGIC" \ + --signing-key "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.key" \ + --vote-yes \ + --output-filepath "${vote_base}-${i}.vote" + + cardano_cli_log byron governance submit-proposal-vote \ + --testnet-magic "$NETWORK_MAGIC" \ + --filepath "${vote_base}-${i}.vote" + done + sleep 5 +} + +get_shelley_env() { + local vkey skey + + GENESIS_VERIFICATION=() + for vkey in "$STATE_CLUSTER"/shelley/genesis-keys/genesis?.vkey; do + [ -e "$vkey" ] || { echo "No genesis verification keys found in ${STATE_CLUSTER}/shelley/genesis-keys, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + GENESIS_VERIFICATION+=("--genesis-verification-key-file" "$vkey") + done + readonly GENESIS_VERIFICATION + + GENESIS_SIGNING=() + for skey in "$STATE_CLUSTER"/shelley/genesis-keys/genesis?.skey; do + [ -e "$skey" ] || { echo "No genesis signing keys found in ${STATE_CLUSTER}/shelley/genesis-keys, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + GENESIS_SIGNING+=("--signing-key-file" "$skey") + done + readonly GENESIS_SIGNING + + DELEGATE_SIGNING=() + for skey in "$STATE_CLUSTER"/shelley/delegate-keys/delegate?.skey; do + [ -e "$skey" ] || { echo "No delegate signing keys found in ${STATE_CLUSTER}/shelley/delegate-keys, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + DELEGATE_SIGNING+=("--signing-key-file" "$skey") + done + readonly DELEGATE_SIGNING + + FAUCET_ADDR="$(<"$STATE_CLUSTER"/byron/address-000-converted)" + readonly FAUCET_ADDR + readonly FAUCET_SKEY="${STATE_CLUSTER}/byron/payment-keys.000-converted.skey" +} + +create_legacy_update_proposal() { + local era="${1:?}" + local proposal_file="${2:?}" + local major_version="${3:?}" + shift 3 + + cardano_cli_log compatible "$era" governance action create-protocol-parameters-update \ + --out-file "$proposal_file" \ + --epoch "$(get_epoch)" \ + "${GENESIS_VERIFICATION[@]}" \ + --protocol-major-version "$major_version" \ + --protocol-minor-version 0 \ + "$@" +} + +submit_legacy_update_proposal() { + local era="${1:?}" + local proposal_file="${2:?}" + local tx_base="${3:?}" + + get_txins "$FAUCET_ADDR" "$FEE" + + local txout_amount="$((TXIN_AMOUNT - FEE))" + + cardano_cli_log compatible "$era" transaction signed-transaction \ + --fee "$FEE" \ + "${TXINS[@]}" \ + --tx-out "${FAUCET_ADDR}+${txout_amount}" \ + --update-proposal-file "$proposal_file" \ + --signing-key-file "$FAUCET_SKEY" \ + "${DELEGATE_SIGNING[@]}" \ + --testnet-magic "$NETWORK_MAGIC" \ + --out-file "${tx_base}-tx.tx" + + cardano_cli_log latest transaction submit \ + --tx-file "${tx_base}-tx.tx" \ + --testnet-magic "$NETWORK_MAGIC" + + sleep "$SUBMIT_DELAY" + if ! check_spend_success "${TXINS[@]}"; then + echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi +} + +do_legacy_hf() { + local from_era="${1:?}" + local to_era="${2:?}" + local major_version="${3:?}" + local wait_epoch="${4:?}" + shift 4 + + local proposal_file="${STATE_CLUSTER}/shelley/update-proposal-${to_era,,}.proposal" + local tx_base="${STATE_CLUSTER}/shelley/update-proposal-${to_era,,}" + + sleep "$PROPOSAL_DELAY" + echo "Submitting update proposal to transfer to $to_era" + + create_legacy_update_proposal "$from_era" "$proposal_file" "$major_version" "$@" + submit_legacy_update_proposal "$from_era" "$proposal_file" "$tx_base" + + echo "Waiting for $to_era era to start" + wait_for_epoch "$wait_epoch" +} + +_register_governance_in_conway() { + local deposits="$((KEY_DEPOSIT + DREP_DEPOSIT))" + local needed_amount="$(( (DREP_DELEGATED + deposits) * NUM_DREPS ))" + local stop_txin_amount="$((FEE + needed_amount))" + local f i + + get_txins "$FAUCET_ADDR" "$stop_txin_amount" + + local txout_amount="$((TXIN_AMOUNT - stop_txin_amount))" + local v9_tx="${STATE_CLUSTER}/governance_data/setup_governance" + + local -a cc_args=() + for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_hot_auth.cert; do + [ -e "$f" ] || continue + cc_args+=( "--certificate-file" "$f" ) + done + + local -a cc_signing=() + for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_cold.skey; do + [ -e "$f" ] || continue + cc_signing+=( "--signing-key-file" "$f" ) + done + + local -a dreps_args=() + local -a dreps_signing=() + for i in $(seq 1 "$NUM_DREPS"); do + dreps_args+=( \ + "--tx-out" "$(<"${STATE_CLUSTER}/governance_data/vote_stake_addr${i}.addr")+${DREP_DELEGATED}" \ + "--certificate-file" "${STATE_CLUSTER}/governance_data/default_drep_${i}_drep_reg.cert" \ + "--certificate-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}_stake.reg.cert" \ + "--certificate-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}_stake.vote_deleg.cert" \ + ) + dreps_signing+=( \ + "--signing-key-file" "${STATE_CLUSTER}/governance_data/default_drep_${i}_drep.skey" \ + "--signing-key-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}.skey" \ + "--signing-key-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}_stake.skey" \ + ) + done + + local -a pool_args=() + local -a pool_signing=() + for i in $(seq 1 "$NUM_POOLS"); do + pool_args+=( \ + "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/stake-reward.vote_deleg.cert" \ + ) + pool_signing+=( \ + "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/reward.skey" \ + ) + done + + cardano_cli_log conway transaction build-raw \ + --fee "$FEE" \ + "${TXINS[@]}" \ + "${cc_args[@]}" \ + "${dreps_args[@]}" \ + "${pool_args[@]}" \ + --tx-out "${FAUCET_ADDR}+${txout_amount}" \ + --out-file "${v9_tx}-tx.txbody" + + cardano_cli_log conway transaction sign \ + --signing-key-file "$FAUCET_SKEY" \ + "${cc_signing[@]}" \ + "${dreps_signing[@]}" \ + "${pool_signing[@]}" \ + --testnet-magic "$NETWORK_MAGIC" \ + --tx-body-file "${v9_tx}-tx.txbody" \ + --out-file "${v9_tx}-tx.tx" + + cardano_cli_log conway transaction submit \ + --tx-file "${v9_tx}-tx.tx" \ + --testnet-magic "$NETWORK_MAGIC" + + sleep "$SUBMIT_DELAY" + if ! check_spend_success "${TXINS[@]}"; then + echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi + + if [ -z "${NO_CC:-}" ]; then + local cc_size + cc_size="$(cardano-cli conway query committee-state --active --testnet-magic "$NETWORK_MAGIC" | + grep -c '"status": "Active"')" + [ "$cc_size" -ge "$NUM_CC" ] || \ + { echo "The CC members were not registered, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + fi +} + +submit_gov_action() { + local action_base="${1:?}" + local stop_txin_amount="$((FEE + GOV_ACTION_DEPOSIT))" + + get_txins "$FAUCET_ADDR" "$stop_txin_amount" + + local txout_amount="$((TXIN_AMOUNT - stop_txin_amount))" + + cardano_cli_log conway transaction build-raw \ + --fee "$FEE" \ + "${TXINS[@]}" \ + --proposal-file "${action_base}.action" \ + --tx-out "${FAUCET_ADDR}+${txout_amount}" \ + --out-file "${action_base}-tx.txbody" + + cardano_cli_log conway transaction sign \ + --signing-key-file "$FAUCET_SKEY" \ + --testnet-magic "$NETWORK_MAGIC" \ + --tx-body-file "${action_base}-tx.txbody" \ + --out-file "${action_base}-tx.tx" + + cardano_cli_log conway transaction submit \ + --tx-file "${action_base}-tx.tx" \ + --testnet-magic "$NETWORK_MAGIC" + + sleep "$SUBMIT_DELAY" + if ! check_spend_success "${TXINS[@]}"; then + echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi +} + +create_and_submit_hf_action() { + local hf_action="${1:?}" + local era="$2" + local major_version="$3" + local prev_txid="${4:-}" + local prev_index="${5:-0}" + + local -a prev_args=() + if [ -n "$prev_txid" ]; then + prev_args=( \ + "--prev-governance-action-tx-id" "$prev_txid" \ + "--prev-governance-action-index" "$prev_index" \ + ) + fi + + cardano_cli_log "$era" governance action create-hardfork \ + --testnet \ + --governance-action-deposit "$GOV_ACTION_DEPOSIT" \ + --deposit-return-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool1/reward.vkey" \ + "${prev_args[@]}" \ + --anchor-url "http://www.hardfork-pv${major_version}.com" \ + --anchor-data-hash 5d372dca1a4cc90d7d16d966c48270e33e3aa0abcb0e78f0d5ca7ff330d2245d \ + --protocol-major-version "$major_version" \ + --protocol-minor-version 0 \ + --out-file "${hf_action}.action" + + submit_gov_action "$hf_action" +} + +_update_cost_model_in_pv9() { + echo "Submitting cost model update proposal" + local cost_model_base="${STATE_CLUSTER}/governance_data/cost_model_conway" + local cost_model_action="${cost_model_base}_action" + + cardano_cli_log conway governance action create-protocol-parameters-update \ + --testnet \ + --governance-action-deposit "$GOV_ACTION_DEPOSIT" \ + --deposit-return-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool1/reward.vkey" \ + --anchor-url "http://www.cost-model-update.com" \ + --anchor-data-hash 5d372dca1a4cc90d7d16d966c48270e33e3aa0abcb0e78f0d5ca7ff330d2245d \ + --cost-model-file "${STATE_CLUSTER}/shelley/cost_models_list.json" \ + --out-file "${cost_model_action}.action" + + submit_gov_action "$cost_model_action" + + local cost_model_txid + cost_model_txid="$(cardano_cli_log conway transaction txid \ + --output-text --tx-body-file "${cost_model_action}-tx.txbody")" + vote_on_action "$cost_model_txid" "$cost_model_action" + submit_votes "${cost_model_base}_votes" "$cost_model_action" +} + +_wait_pv9_cost_model_enacted() { + local vote_epoch="${1:?}" + + echo "Waiting for cost model update to get enacted" + wait_for_epoch "$((vote_epoch + 2))" + + save_protocol_params "$PPARAMS_FILE" + local plutusv2_len + plutusv2_len="$(jq ".costModels.PlutusV2 | length" < "$PPARAMS_FILE")" + if [ "$plutusv2_len" != 185 ]; then + echo "Unexpected PlutusV2 cost model length '$plutusv2_len' on line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi +} + +vote_on_action() { + local action_txid="${1:?}" + local action_base="${2:?}" + local with_spos="${3:-no}" + local with_dreps="${4:-no}" + local f + + echo "Voting on $(basename "$action_base") proposal" + + local index=0 + for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_hot.vkey; do + [ -e "$f" ] || continue + index="$((index + 1))" + cardano_cli_log conway governance vote create \ + --yes \ + --governance-action-tx-id "$action_txid" \ + --governance-action-index 0 \ + --cc-hot-verification-key-file "$f" \ + --out-file "${action_base}_cc${index}.vote" + done + + if [ "$with_spos" = "yes" ]; then + index=0 + for f in "$STATE_CLUSTER"/nodes/node-pool*/cold.vkey; do + [ -e "$f" ] || continue + index="$((index + 1))" + cardano_cli_log conway governance vote create \ + --yes \ + --governance-action-tx-id "$action_txid" \ + --governance-action-index 0 \ + --cold-verification-key-file "$f" \ + --out-file "${action_base}_spo${index}.vote" + done + fi + + if [ "$with_dreps" = "yes" ]; then + index=0 + for f in "$STATE_CLUSTER"/governance_data/default_drep*_drep.vkey; do + [ -e "$f" ] || continue + index="$((index + 1))" + cardano_cli_log conway governance vote create \ + --yes \ + --governance-action-tx-id "$action_txid" \ + --governance-action-index 0 \ + --drep-verification-key-file "$f" \ + --out-file "${action_base}_drep${index}.vote" + done + fi +} + +submit_votes() { + local votes_base="${1:?}" + local action_base="${2:?}" + local f + + local -a vote_files=() + for f in "$action_base"_*.vote; do + [ -e "$f" ] || continue + vote_files+=( "--vote-file" "$f" ) + done + + local -a cc_signing=() + for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_hot.skey; do + [ -e "$f" ] || continue + cc_signing+=( "--signing-key-file" "$f" ) + done + + local -a pool_signing=() + if [ -e "${action_base}_spo1.vote" ]; then + for f in "$STATE_CLUSTER"/nodes/node-pool*/cold.skey; do + [ -e "$f" ] || continue + pool_signing+=( "--signing-key-file" "$f" ) + done + fi + + local -a drep_signing=() + if [ -e "${action_base}_drep1.vote" ]; then + for f in "$STATE_CLUSTER"/governance_data/default_drep*_drep.skey; do + [ -e "$f" ] || continue + drep_signing+=( "--signing-key-file" "$f" ) + done + fi + + get_txins "$FAUCET_ADDR" "$FEE" + + local txout_amount="$((TXIN_AMOUNT - FEE))" + + cardano_cli_log conway transaction build-raw \ + --fee "$FEE" \ + "${TXINS[@]}" \ + "${vote_files[@]}" \ + --tx-out "${FAUCET_ADDR}+${txout_amount}" \ + --out-file "${votes_base}-tx.txbody" + + cardano_cli_log conway transaction sign \ + --signing-key-file "$FAUCET_SKEY" \ + "${cc_signing[@]}" \ + "${pool_signing[@]}" \ + "${drep_signing[@]}" \ + --testnet-magic "$NETWORK_MAGIC" \ + --tx-body-file "${votes_base}-tx.txbody" \ + --out-file "${votes_base}-tx.tx" + + cardano_cli_log conway transaction submit \ + --tx-file "${votes_base}-tx.tx" \ + --testnet-magic "$NETWORK_MAGIC" + + sleep "$SUBMIT_DELAY" + if ! check_spend_success "${TXINS[@]}"; then + echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi +} + +submit_byron_genesis_txs() { + echo "Sleeping for initial Tx submission delay of $TX_SUBMISSION_DELAY seconds" + sleep "$TX_SUBMISSION_DELAY" + + echo "Moving funds out of Byron genesis" + local i + for i in $(seq 1 "$NUM_BFT_NODES"); do + cardano_cli_log byron transaction submit-tx \ + --testnet-magic "$NETWORK_MAGIC" \ + --tx "${STATE_CLUSTER}/byron/tx${i}.tx" + done + + echo "Waiting for next Byron epoch to start" + sleep "$((200 - TX_SUBMISSION_DELAY + 5))" +} + +hf_to_byron_pv1() { + local byron_v1_proposal="${STATE_CLUSTER}/byron/update-proposal-byron-v1.proposal" + + create_byron_update_proposal "$byron_v1_proposal" 1 0 + submit_byron_proposal_with_votes "$byron_v1_proposal" "${STATE_CLUSTER}/byron/update-proposal-byron-v1" + + echo "Waiting for Byron era with PV1 to start" + sleep 200 +} + +hf_to_shelley() { + local shelley_proposal="${STATE_CLUSTER}/byron/update-proposal-shelley.proposal" + + create_byron_update_proposal "$shelley_proposal" 2 0 + submit_byron_proposal_with_votes "$shelley_proposal" "${STATE_CLUSTER}/byron/update-proposal-shelley" + + local conf + for conf in "$STATE_CLUSTER"/config-*.json; do + [ -e "$conf" ] || { echo "No config files found in ${STATE_CLUSTER}, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + local fname="${conf##*/}" + jq ' + ."LastKnownBlockVersion-Major" = 2' \ + "$conf" > "${STATE_CLUSTER}/${fname}_jq" + cat "${STATE_CLUSTER}/${fname}_jq" > "${STATE_CLUSTER}/${fname}" + rm -f "${STATE_CLUSTER}/${fname}_jq" + done + + supervisorctl -s unix:///"$SUPERVISORD_SOCKET_PATH" restart nodes: + + echo "Waiting for Shelley era to start" + sleep 190 + wait_for_era "Shelley" +} + +hf_to_allegra() { + local cur_epoch="${1:?}" + + sleep "$PROPOSAL_DELAY" + echo "Submitting update proposal to transfer to Allegra, transferring funds to pool owners, registering pools and delegations" + + local allegra_proposal_file="${STATE_CLUSTER}/shelley/update-proposal-allegra.proposal" + local allegra_tx_base="${STATE_CLUSTER}/shelley/transfer-register-delegate" + + cardano_cli_log compatible shelley governance action create-protocol-parameters-update \ + --out-file "$allegra_proposal_file" \ + --epoch "$(get_epoch)" \ + "${GENESIS_VERIFICATION[@]}" \ + --protocol-major-version 3 \ + --protocol-minor-version 0 + + local deposits="$((POOL_DEPOSIT + (2 * KEY_DEPOSIT) ))" + local needed_amount="$(( (POOL_PLEDGE + deposits) * NUM_POOLS ))" + local stop_txin_amount="$((needed_amount + FEE))" + + get_txins "$FAUCET_ADDR" "$stop_txin_amount" + + local txout_amount="$((TXIN_AMOUNT - stop_txin_amount))" + + local -a pool_args=() + local -a pool_signing=() + local i + for i in $(seq 1 "$NUM_POOLS"); do + pool_args+=( \ + "--tx-out" "$(<"${STATE_CLUSTER}/nodes/node-pool${i}/owner.addr")+${POOL_PLEDGE}" \ + "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/stake.reg.shelley.cert" \ + "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/stake-reward.reg.shelley.cert" \ + "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/register.shelley.cert" \ + "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/owner-stake.deleg.shelley.cert" \ + ) + pool_signing+=( \ + "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/owner-stake.skey" \ + "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/reward.skey" \ + "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/cold.skey" \ + ) + done + + cardano_cli_log compatible shelley transaction signed-transaction \ + --fee "$FEE" \ + "${TXINS[@]}" \ + --tx-out "${FAUCET_ADDR}+${txout_amount}" \ + "${pool_args[@]}" \ + --update-proposal-file "$allegra_proposal_file" \ + "${pool_signing[@]}" \ + "${GENESIS_SIGNING[@]}" \ + "${DELEGATE_SIGNING[@]}" \ + --signing-key-file "$FAUCET_SKEY" \ + --testnet-magic "$NETWORK_MAGIC" \ + --out-file "${allegra_tx_base}-tx.tx" + + cardano_cli_log latest transaction submit \ + --tx-file "${allegra_tx_base}-tx.tx" \ + --testnet-magic "$NETWORK_MAGIC" + + sleep "$SUBMIT_DELAY" + if ! check_spend_success "${TXINS[@]}"; then + echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 + exit 1 + fi + + echo "Waiting for Allegra era to start" + wait_for_epoch "$((cur_epoch + 1))" + wait_for_era "Allegra" +} + +hf_to_mary() { + local cur_epoch="${1:?}" + do_legacy_hf "allegra" "Mary" 4 "$((cur_epoch + 1))" --decentralization-parameter 0 + wait_for_era "Mary" +} + +hf_to_alonzo() { + if [ "$PROTOCOL_VERSION" -lt 5 ]; then + echo "Skipping HF to Alonzo as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + return + fi + + local cur_epoch="${1:?}" + do_legacy_hf "mary" "Alonzo" 5 "$((cur_epoch + 1))" + wait_for_era "Alonzo" +} + +hf_to_alonzo_pv6() { + if [ "$PROTOCOL_VERSION" -lt 6 ]; then + echo "Skipping HF to Alonzo PV6 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + return + fi + + local cur_epoch="${1:?}" + + do_legacy_hf "alonzo" "Alonzo-PV6" 6 "$((cur_epoch + 1))" + + if save_protocol_params "$PPARAMS_FILE"; then + local cur_protver + cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" + [ "$cur_protver" = 6 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + fi +} + +hf_to_babbage() { + if [ "$PROTOCOL_VERSION" -lt 7 ]; then + echo "Skipping HF to Babbage as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + return + fi + + local cur_epoch="${1:?}" + + do_legacy_hf "alonzo" "Babbage" 7 "$((cur_epoch + 1))" + wait_for_era "Babbage" +} + +hf_to_babbage_pv8() { + if [ "$PROTOCOL_VERSION" -lt 8 ]; then + echo "Skipping HF to Babbage PV8 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + return + fi + + local cur_epoch="${1:?}" + + do_legacy_hf "babbage" "Babbage-PV8" 8 "$((cur_epoch + 1))" + + if save_protocol_params "$PPARAMS_FILE"; then + local cur_protver + cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" + [ "$cur_protver" = 8 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + fi +} + +hf_to_conway() { + if [ "$PROTOCOL_VERSION" -lt 9 ]; then + echo "Skipping HF to Conway as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + return + fi + + local cur_epoch="${1:?}" + + do_legacy_hf "babbage" "Conway" 9 "$((cur_epoch + 1))" + wait_for_era "Conway" + + save_protocol_params "$PPARAMS_FILE" + local cur_protver + cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" + [ "$cur_protver" = 9 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } + + _register_governance_in_conway +} + +hf_to_conway_pv10() { + local cur_epoch="${1:?}" + + _update_cost_model_in_pv9 + + if [ "$PROTOCOL_VERSION" -lt 10 ]; then + echo "Skipping HF to Conway PV10 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + _wait_pv9_cost_model_enacted "$cur_epoch" + return + fi + + wait_for_epoch "$((cur_epoch + 1))" + + echo "Submitting hard fork proposal to update to Conway PV10" + local pv10_hf_base="${STATE_CLUSTER}/governance_data/hardfork_pv10" + local pv10_hf_action="${pv10_hf_base}_action" + + create_and_submit_hf_action "$pv10_hf_action" "conway" 10 + + PV10_HF_ACTION_TXID="$(cardano_cli_log conway transaction txid \ + --output-text --tx-body-file "${pv10_hf_action}-tx.txbody")" + readonly PV10_HF_ACTION_TXID + + vote_on_action "$PV10_HF_ACTION_TXID" "$pv10_hf_action" "yes" + submit_votes "${pv10_hf_base}_votes" "$pv10_hf_action" + + _wait_pv9_cost_model_enacted "$cur_epoch" + + echo "Waiting for Conway PV10 to start" + wait_for_epoch "$((cur_epoch + 3))" + + save_protocol_params "$PPARAMS_FILE" + local cur_protver + cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" + [ "$cur_protver" = 10 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } +} + +hf_to_conway_pv11() { + if [ "$PROTOCOL_VERSION" -lt 11 ]; then + echo "Skipping HF to Conway PV11 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" + return + fi + + local cur_epoch="${1:?}" + + echo "Submitting hard fork proposal to update to Conway PV11" + + local pv11_hf_base="${STATE_CLUSTER}/governance_data/hardfork_pv11_action" + local pv11_hf_action="${pv11_hf_base}_action" + + create_and_submit_hf_action "$pv11_hf_action" "conway" 11 "${PV10_HF_ACTION_TXID:?"Must exist"}" + + PV11_HF_ACTION_TXID="$(cardano_cli_log conway transaction txid \ + --output-text --tx-body-file "${pv11_hf_action}-tx.txbody")" + readonly PV11_HF_ACTION_TXID + + vote_on_action "$PV11_HF_ACTION_TXID" "$pv11_hf_action" "yes" "yes" + submit_votes "${pv11_hf_base}_votes" "$pv11_hf_action" + + echo "Waiting for Conway PV11 to start" + wait_for_epoch "$((cur_epoch + 2))" + + save_protocol_params "$PPARAMS_FILE" + local cur_protver + cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" + [ "$cur_protver" = 11 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } +} + +main() { + initialize_globals + setup_state_cluster "${STATE_CLUSTER}/shelley" + configure_supervisor + create_genesis + create_committee_keys_in_genesis + get_genesis_data + edit_node_configs + create_bft_nodes_files + create_pools_files + create_dreps_files + create_cluster_scripts + get_shelley_env + + start_cluster_nodes + + submit_byron_genesis_txs + hf_to_byron_pv1 + hf_to_shelley + + start_optional_services + + hf_to_allegra "$(get_epoch)" + hf_to_mary "$(get_epoch)" + hf_to_alonzo "$(get_epoch)" + hf_to_alonzo_pv6 "$(get_epoch)" + hf_to_babbage "$(get_epoch)" + hf_to_babbage_pv8 "$(get_epoch)" + hf_to_conway "$(get_epoch)" + hf_to_conway_pv10 "$(get_epoch)" + hf_to_conway_pv11 "$(get_epoch)" + + : > "$START_CLUSTER_STATUS" + echo "Cluster started 🚀" +} + +main "$@" diff --git a/src/cardonnay_scripts/scripts/conway_fast/start-cluster b/src/cardonnay_scripts/scripts/conway_fast/start-cluster new file mode 100644 index 0000000..094bcc5 --- /dev/null +++ b/src/cardonnay_scripts/scripts/conway_fast/start-cluster @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$(readlink -m "${0%/*}")" +exec "${SCRIPT_DIR}/common-start-fast" "$@" diff --git a/src/cardonnay_scripts/scripts/conway_slow/start-cluster b/src/cardonnay_scripts/scripts/conway_slow/start-cluster index 7a8a7a8..49c7148 100644 --- a/src/cardonnay_scripts/scripts/conway_slow/start-cluster +++ b/src/cardonnay_scripts/scripts/conway_slow/start-cluster @@ -1,1205 +1,4 @@ #!/usr/bin/env bash -# Cardano local cluster startup script -# This script sets up and starts a local Cardano test cluster, bootstrapping it through -# all eras from Byron to Conway, registering pools and governance entities. - -set -Eeuo pipefail -trap 'echo "Error at line $LINENO in ${BASH_SOURCE[0]}" >&2' ERR - -readonly PROTOCOL_VERSION="${PROTOCOL_VERSION:-10}" -readonly NUM_BFT_NODES=1 -readonly NUM_CC=5 -readonly NUM_DREPS=5 -readonly TX_SUBMISSION_DELAY=60 -readonly PROPOSAL_DELAY=5 -readonly SUBMIT_DELAY=5 -readonly POOL_PLEDGE=1000000000000 -readonly DREP_DELEGATED=500000000000 -readonly FEE=5000000 - -readonly INSTANCE_NUM="%%INSTANCE_NUM%%" -readonly NUM_POOLS=%%NUM_POOLS%% -readonly NODE_PORT_BASE=%%NODE_PORT_BASE%% -readonly PORTS_PER_NODE=%%PORTS_PER_NODE%% -readonly WEBSERVER_PORT=%%WEBSERVER_PORT%% - -initialize_globals() { - if [ -z "${CARDANO_NODE_SOCKET_PATH:-}" ]; then - echo "CARDANO_NODE_SOCKET_PATH is not set" >&2 - exit 1 - fi - - SCRIPT_DIR="$(readlink -m "${0%/*}")" - readonly SCRIPT_DIR - SOCKET_PATH="$(readlink -m "$CARDANO_NODE_SOCKET_PATH")" - readonly SOCKET_PATH - readonly STATE_CLUSTER="${SOCKET_PATH%/*}" - - if [ "$PWD" = "$STATE_CLUSTER" ]; then - echo "Please run this script from outside of '$STATE_CLUSTER'" >&2 - exit 1 - fi - - readonly STATE_CLUSTER_NAME="${STATE_CLUSTER##*/}" - readonly SUPERVISORD_SOCKET_PATH="${STATE_CLUSTER}/supervisord.sock" - readonly START_CLUSTER_STATUS="${STATE_CLUSTER}/status_started" - readonly PPARAMS_FILE="${STATE_CLUSTER}/pparams.json" - - if [[ "$SOCKET_PATH" != *"/state-cluster${INSTANCE_NUM}/"* ]]; then - echo "CARDANO_NODE_SOCKET_PATH must be set to a path containing 'state-cluster${INSTANCE_NUM}', line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi - - if [ -e "$SUPERVISORD_SOCKET_PATH" ]; then - echo "Cluster already running. Please run \`${STATE_CLUSTER}/stop-cluster\` first!" >&2 - exit 1 - fi - - if [ "$NUM_POOLS" -lt 3 ]; then - echo "NUM_POOLS must be at least 3" >&2 - exit 1 - fi - - case "${UTXO_BACKEND:=""}" in - "" | mem | disk) - ;; - *) - echo "Unknown \`UTXO_BACKEND\`: '$UTXO_BACKEND', line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - ;; - esac - readonly UTXO_BACKEND - - SECURITY_PARAM="$(jq '.securityParam' < "${SCRIPT_DIR}/genesis.spec.json")" - readonly SECURITY_PARAM - NETWORK_MAGIC="$(jq '.networkMagic' < "${SCRIPT_DIR}/genesis.spec.json")" - readonly NETWORK_MAGIC - MAX_SUPPLY="$(jq '.maxLovelaceSupply' < "${SCRIPT_DIR}/genesis.spec.json")" - readonly MAX_SUPPLY - POOL_COST="$(jq '.protocolParams.minPoolCost' < "${SCRIPT_DIR}/genesis.spec.json")" - if [ "$POOL_COST" -eq 0 ]; then - POOL_COST=600 - fi - readonly POOL_COST - - # shellcheck disable=SC1091 - source "${SCRIPT_DIR}/common.sh" - - if [ -e "${SCRIPT_DIR}/shell_env" ]; then - # shellcheck disable=SC1091 - source "${SCRIPT_DIR}/shell_env" - fi - - readonly FUNDS_PER_GENESIS_ADDRESS="$((MAX_SUPPLY / NUM_BFT_NODES))" - readonly FUNDS_PER_BYRON_ADDRESS="$((FUNDS_PER_GENESIS_ADDRESS * 8 / 10))" -} - -create_genesis() { - local start_time - local start_time_shelley - - start_time_shelley="$(date --utc +"%Y-%m-%dT%H:%M:%SZ" --date="5 seconds")" - start_time="$(date +%s --date="$start_time_shelley")" - echo "$start_time" > "${STATE_CLUSTER}/cluster_start_time" - - # Create Byron genesis - - cardano_cli_log byron genesis genesis \ - --protocol-magic "$NETWORK_MAGIC" \ - --k "$SECURITY_PARAM" \ - --n-poor-addresses 0 \ - --n-delegate-addresses "$NUM_BFT_NODES" \ - --total-balance "$MAX_SUPPLY" \ - --delegate-share 1 \ - --avvm-entry-count 0 \ - --avvm-entry-balance 0 \ - --protocol-parameters-file "${STATE_CLUSTER}/byron-params.json" \ - --genesis-output-dir "${STATE_CLUSTER}/byron" \ - --start-time "$start_time" - - mv "${STATE_CLUSTER}/byron-params.json" "${STATE_CLUSTER}/byron/params.json" - - # Create Shelley genesis and subsequent era genesis files - - local genesis_args=( \ - --genesis-dir "${STATE_CLUSTER}/shelley" \ - --testnet-magic "$NETWORK_MAGIC" \ - --gen-genesis-keys "$NUM_BFT_NODES" \ - --start-time "$start_time_shelley" \ - --gen-utxo-keys 1 - ) - - if ! cardano_cli_log legacy genesis create --shelley "${genesis_args[@]}"; then - echo "Never mind the error above, retrying the genesis create with legacy arguments" >&2 - cardano_cli_log legacy genesis create "${genesis_args[@]}" - fi - - if [ ! -e "${STATE_CLUSTER}/shelley/genesis.dijkstra.json" ] \ - && [ -e "${STATE_CLUSTER}/shelley/genesis.dijkstra.spec.json" ]; then - cp "${STATE_CLUSTER}/shelley/genesis.dijkstra.spec.json" \ - "${STATE_CLUSTER}/shelley/genesis.dijkstra.json" - fi - - jq -r ' - .initialFunds = {}' \ - < "${STATE_CLUSTER}/shelley/genesis.json" > "${STATE_CLUSTER}/shelley/genesis.json_jq" - cat "${STATE_CLUSTER}/shelley/genesis.json_jq" > "${STATE_CLUSTER}/shelley/genesis.json" - rm -f "${STATE_CLUSTER}/shelley/genesis.json_jq" - - jq '.costModels.PlutusV2 |= .[0:175]' \ - < "${STATE_CLUSTER}/shelley/genesis.alonzo.json" > "${STATE_CLUSTER}/shelley/genesis.alonzo.json_jq" - cat "${STATE_CLUSTER}/shelley/genesis.alonzo.json_jq" > "${STATE_CLUSTER}/shelley/genesis.alonzo.json" - rm -f "${STATE_CLUSTER}/shelley/genesis.alonzo.json_jq" -} - -get_genesis_data() { - KEY_DEPOSIT="$(jq '.protocolParams.keyDeposit' \ - < "${STATE_CLUSTER}/shelley/genesis.json")" - readonly KEY_DEPOSIT - POOL_DEPOSIT="$(jq '.protocolParams.poolDeposit' \ - < "${STATE_CLUSTER}/shelley/genesis.json")" - readonly POOL_DEPOSIT - DREP_DEPOSIT="$(jq '.dRepDeposit' \ - < "${STATE_CLUSTER}/shelley/genesis.conway.json")" - readonly DREP_DEPOSIT - GOV_ACTION_DEPOSIT="$(jq '.govActionDeposit' \ - < "${STATE_CLUSTER}/shelley/genesis.conway.json")" - readonly GOV_ACTION_DEPOSIT - - BYRON_GENESIS_HASH="$(cardano_cli_log byron genesis print-genesis-hash --genesis-json \ - "${STATE_CLUSTER}/byron/genesis.json")" - readonly BYRON_GENESIS_HASH - SHELLEY_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ - "${STATE_CLUSTER}/shelley/genesis.json")" - readonly SHELLEY_GENESIS_HASH - ALONZO_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ - "${STATE_CLUSTER}/shelley/genesis.alonzo.json")" - readonly ALONZO_GENESIS_HASH - CONWAY_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ - "${STATE_CLUSTER}/shelley/genesis.conway.json")" - readonly CONWAY_GENESIS_HASH - DIJKSTRA_GENESIS_HASH="" - if [ "$PROTOCOL_VERSION" -ge 11 ]; then - DIJKSTRA_GENESIS_HASH="$(cardano_cli_log latest genesis hash --genesis \ - "${STATE_CLUSTER}/shelley/genesis.dijkstra.json")" - fi - readonly DIJKSTRA_GENESIS_HASH -} - -edit_node_configs() { - local live_tables_base="${STATE_CLUSTER_NAME}/lmdb" - local conf fname node_name pool_num - - for conf in "$SCRIPT_DIR"/config-*.json; do - [ -e "$conf" ] || { echo "No config files found in ${SCRIPT_DIR}, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - fname="${conf##*/}" - node_name="${fname##config-}" - node_name="${node_name%.json}" - - jq \ - --arg byron_hash "$BYRON_GENESIS_HASH" \ - --arg shelley_hash "$SHELLEY_GENESIS_HASH" \ - --arg alonzo_hash "$ALONZO_GENESIS_HASH" \ - --arg conway_hash "$CONWAY_GENESIS_HASH" \ - --arg dijkstra_hash "$DIJKSTRA_GENESIS_HASH" \ - --arg backend "$UTXO_BACKEND" \ - --arg live_tables_path "${live_tables_base}-${node_name}" \ - '.ByronGenesisHash = $byron_hash - | .ShelleyGenesisHash = $shelley_hash - | .AlonzoGenesisHash = $alonzo_hash - | .ConwayGenesisHash = $conway_hash - | if $dijkstra_hash != "" then - (.DijkstraGenesisFile = "shelley/genesis.dijkstra.json" - | .DijkstraGenesisHash = $dijkstra_hash - | .ExperimentalProtocolsEnabled = true - | .ExperimentalHardForksEnabled = true) - else - . - end - | if $backend == "mem" then - (.LedgerDB.Backend = "V2InMemory" - | .LedgerDB.NumOfDiskSnapshots = 2 - | .LedgerDB.QueryBatchSize = 100000 - | .LedgerDB.SnapshotInterval = 216) - elif $backend == "disk" then - (.LedgerDB.Backend = "V1LMDB" - | .LedgerDB.LiveTablesPath = $live_tables_path) - elif has("LedgerDB") then - .LedgerDB |= del(.Backend) - else - . - end - | if (.LedgerDB? // {}) == {} then del(.LedgerDB) else . end - ' "$conf" > "${STATE_CLUSTER}/${fname}" - - if [ -z "${ENABLE_LEGACY:-}" ]; then - if [ -n "${MIXED_P2P:-}" ]; then - if [ "$fname" = "config-bft1.json" ]; then - cp -f "$SCRIPT_DIR"/topology-bft1.json "$STATE_CLUSTER" - continue - fi - - pool_num="${fname##*-pool}" - pool_num="${pool_num%.json}" - if [ "$((pool_num % 2))" != 0 ]; then - cp -f "${SCRIPT_DIR}/topology-pool${pool_num}.json" "$STATE_CLUSTER" - continue - fi - fi - - jq \ - '.EnableP2P = true - | .MaxConcurrencyBulkSync = 2 - | .MaxConcurrencyDeadline = 4 - | .TargetNumberOfRootPeers = 100 - | .TargetNumberOfKnownPeers = 100 - | .TargetNumberOfEstablishedPeers = 50 - | .TargetNumberOfActivePeers = 20 - | .TraceBlockFetchClient = true - | .TraceChainSyncClient = true' \ - "${STATE_CLUSTER}/${fname}" > "${STATE_CLUSTER}/${fname}_jq" - cat "${STATE_CLUSTER}/${fname}_jq" > "${STATE_CLUSTER}/${fname}" - rm -f "${STATE_CLUSTER}/${fname}_jq" - fi - done -} - -create_bft_nodes_files() { - local i index bft_port - - for i in $(seq 1 "$NUM_BFT_NODES"); do - mkdir -p "${STATE_CLUSTER}/nodes/node-bft$i" - ln -s "../../shelley/delegate-keys/delegate${i}.vrf.skey" "${STATE_CLUSTER}/nodes/node-bft${i}/vrf.skey" - ln -s "../../shelley/delegate-keys/delegate${i}.vrf.vkey" "${STATE_CLUSTER}/nodes/node-bft${i}/vrf.vkey" - - cardano_cli_log latest node key-gen-KES \ - --verification-key-file "${STATE_CLUSTER}/nodes/node-bft${i}/kes.vkey" \ - --signing-key-file "${STATE_CLUSTER}/nodes/node-bft${i}/kes.skey" - - cardano_cli_log latest node issue-op-cert \ - --kes-period 0 \ - --cold-signing-key-file "${STATE_CLUSTER}/shelley/delegate-keys/delegate${i}.skey" \ - --kes-verification-key-file "${STATE_CLUSTER}/nodes/node-bft${i}/kes.vkey" \ - --operational-certificate-issue-counter-file \ - "${STATE_CLUSTER}/shelley/delegate-keys/delegate${i}.counter" \ - --out-file "${STATE_CLUSTER}/nodes/node-bft${i}/op.cert" - - index="$(printf "%03d" $((i - 1)))" - - cardano_cli_log byron key keygen \ - --secret "${STATE_CLUSTER}/byron/payment-keys.${index}.key" - - cardano_cli_log byron key signing-key-address \ - --byron-formats \ - --testnet-magic "$NETWORK_MAGIC" \ - --secret "${STATE_CLUSTER}/byron/payment-keys.${index}.key" > "${STATE_CLUSTER}/byron/address-${index}" - - cardano_cli_log byron key signing-key-address \ - --byron-formats \ - --testnet-magic "$NETWORK_MAGIC" \ - --secret "${STATE_CLUSTER}/byron/genesis-keys.${index}.key" \ - > "${STATE_CLUSTER}/byron/genesis-address-${index}" - - ln -s "../../byron/delegate-keys.${index}.key" "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.key" - ln -s "../../byron/delegation-cert.${index}.json" "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.json" - - cardano_cli_log byron transaction issue-genesis-utxo-expenditure \ - --genesis-json "${STATE_CLUSTER}/byron/genesis.json" \ - --testnet-magic "$NETWORK_MAGIC" \ - --byron-formats \ - --tx "${STATE_CLUSTER}/byron/tx${i}.tx" \ - --wallet-key "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.key" \ - --rich-addr-from "$(head -n 1 "${STATE_CLUSTER}/byron/genesis-address-${index}")" \ - --txout "(\"$(head -n 1 "${STATE_CLUSTER}/byron/address-${index}")\", ${FUNDS_PER_BYRON_ADDRESS})" - - cardano_cli_log latest key convert-byron-key \ - --byron-signing-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}.key" \ - --out-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.skey" \ - --byron-payment-key-type - - cardano_cli_log latest key verification-key \ - --signing-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.skey" \ - --verification-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.vkey" - - cardano_cli_log latest address build \ - --testnet-magic "$NETWORK_MAGIC" \ - --payment-verification-key-file "${STATE_CLUSTER}/byron/payment-keys.${index}-converted.vkey" \ - > "${STATE_CLUSTER}/byron/address-${index}-converted" - - bft_port="$((NODE_PORT_BASE + (i - 1) * PORTS_PER_NODE ))" - echo "$bft_port" > "${STATE_CLUSTER}/nodes/node-bft${i}/port" - done -} - -_create_pool_node_keys() { - local pool_ix="${1:?}" - - mkdir -p "${STATE_CLUSTER}/nodes/node-pool${pool_ix}" - echo "Generating Pool $pool_ix Secrets" - - cardano_cli_log latest address key-gen \ - --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-utxo.skey" \ - --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-utxo.vkey" - cardano_cli_log latest stake-address key-gen \ - --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.skey" \ - --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" - cardano_cli_log latest address build \ - --payment-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-utxo.vkey" \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --testnet-magic "$NETWORK_MAGIC" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner.addr" - cardano_cli_log latest stake-address build \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --testnet-magic "$NETWORK_MAGIC" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.addr" - cardano_cli_log compatible shelley stake-address registration-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake.reg.shelley.cert" - cardano_cli_log conway stake-address registration-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --key-reg-deposit-amt "$KEY_DEPOSIT" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake.reg.cert" - - cardano_cli_log latest stake-address key-gen \ - --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.skey" \ - --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" - cardano_cli_log compatible shelley stake-address registration-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake-reward.reg.shelley.cert" - cardano_cli_log conway stake-address vote-delegation-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ - --always-abstain \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake-reward.vote_deleg.cert" - cardano_cli_log conway stake-address registration-and-vote-delegation-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ - --always-abstain \ - --key-reg-deposit-amt "$KEY_DEPOSIT" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/stake-reward.reg.cert" - - cardano_cli_log latest node key-gen \ - --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ - --cold-signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.skey" \ - --operational-certificate-issue-counter-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.counter" - cardano_cli_log latest node key-gen-KES \ - --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/kes.vkey" \ - --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/kes.skey" - cardano_cli_log latest node key-gen-VRF \ - --verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.vkey" \ - --signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.skey" - - cardano_cli_log compatible shelley stake-address stake-delegation-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.deleg.shelley.cert" - cardano_cli_log conway stake-address stake-delegation-certificate \ - --stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.deleg.cert" - - cardano_cli_log latest node issue-op-cert \ - --kes-period 0 \ - --cold-signing-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.skey" \ - --kes-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/kes.vkey" \ - --operational-certificate-issue-counter-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.counter" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/op.cert" -} - -_create_pool_registration() { - local pool_ix="${1:?}" - local metadata_url="http://localhost:${WEBSERVER_PORT}/pool${pool_ix}.json" - local metadata_hash pool_port - - metadata_hash="$(cardano_cli_log latest stake-pool metadata-hash --pool-metadata-file \ - "${STATE_CLUSTER}/webserver/pool${pool_ix}.json")" - pool_port="$((NODE_PORT_BASE + (NUM_BFT_NODES + pool_ix - 1) * PORTS_PER_NODE))" - echo "$pool_port" > "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/port" - echo "$POOL_PLEDGE" > "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/pledge" - - cardano_cli_log compatible shelley stake-pool registration-certificate \ - --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ - --vrf-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.vkey" \ - --pool-pledge "$POOL_PLEDGE" \ - --pool-margin 0.35 \ - --pool-cost "$POOL_COST" \ - --pool-reward-account-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ - --pool-owner-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --metadata-url "$metadata_url" \ - --metadata-hash "$metadata_hash" \ - --pool-relay-port "$pool_port" \ - --pool-relay-ipv4 "127.0.0.1" \ - --testnet-magic "$NETWORK_MAGIC" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/register.shelley.cert" - cardano_cli_log conway stake-pool registration-certificate \ - --cold-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/cold.vkey" \ - --vrf-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/vrf.vkey" \ - --pool-pledge "$POOL_PLEDGE" \ - --pool-margin 0.35 \ - --pool-cost "$POOL_COST" \ - --pool-reward-account-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/reward.vkey" \ - --pool-owner-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/owner-stake.vkey" \ - --metadata-url "$metadata_url" \ - --metadata-hash "$metadata_hash" \ - --pool-relay-port "$pool_port" \ - --pool-relay-ipv4 "127.0.0.1" \ - --testnet-magic "$NETWORK_MAGIC" \ - --out-file "${STATE_CLUSTER}/nodes/node-pool${pool_ix}/register.cert" -} - -create_pools_files() { - local i - for i in $(seq 1 "$NUM_POOLS"); do - _create_pool_node_keys "$i" - create_pool_metadata "$i" - _create_pool_registration "$i" - done - - mv "${STATE_CLUSTER}/shelley/utxo-keys/utxo1.vkey" "${STATE_CLUSTER}/shelley/genesis-utxo.vkey" - mv "${STATE_CLUSTER}/shelley/utxo-keys/utxo1.skey" "${STATE_CLUSTER}/shelley/genesis-utxo.skey" - rmdir "${STATE_CLUSTER}/shelley/utxo-keys" -} - -create_byron_update_proposal() { - local proposal_file="${1:?Proposal file argument is required}" - local protocol_major="${2:?Protocol major version argument is required}" - local protocol_minor="${3:?Protocol minor version argument is required}" - - cardano_cli_log byron governance create-update-proposal \ - --filepath "$proposal_file" \ - --testnet-magic "$NETWORK_MAGIC" \ - --signing-key "${STATE_CLUSTER}/nodes/node-bft1/byron-deleg.key" \ - --protocol-version-major "$protocol_major" \ - --protocol-version-minor "$protocol_minor" \ - --protocol-version-alt 0 \ - --application-name "cardano-sl" \ - --software-version-num 1 \ - --system-tag "linux" \ - --installer-hash 0 -} - -submit_byron_proposal_with_votes() { - local proposal_file="${1:?Proposal file argument is required}" - local vote_base="${2:?Vote base argument is required}" - local i - - cardano_cli_log byron governance submit-update-proposal \ - --testnet-magic "$NETWORK_MAGIC" \ - --filepath "$proposal_file" - sleep 5 - - for i in $(seq 1 "$NUM_BFT_NODES"); do - cardano_cli_log byron governance create-proposal-vote \ - --proposal-filepath "$proposal_file" \ - --testnet-magic "$NETWORK_MAGIC" \ - --signing-key "${STATE_CLUSTER}/nodes/node-bft${i}/byron-deleg.key" \ - --vote-yes \ - --output-filepath "${vote_base}-${i}.vote" - - cardano_cli_log byron governance submit-proposal-vote \ - --testnet-magic "$NETWORK_MAGIC" \ - --filepath "${vote_base}-${i}.vote" - done - sleep 5 -} - -get_shelley_env() { - local vkey skey - - GENESIS_VERIFICATION=() - for vkey in "$STATE_CLUSTER"/shelley/genesis-keys/genesis?.vkey; do - [ -e "$vkey" ] || { echo "No genesis verification keys found in ${STATE_CLUSTER}/shelley/genesis-keys, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - GENESIS_VERIFICATION+=("--genesis-verification-key-file" "$vkey") - done - readonly GENESIS_VERIFICATION - - GENESIS_SIGNING=() - for skey in "$STATE_CLUSTER"/shelley/genesis-keys/genesis?.skey; do - [ -e "$skey" ] || { echo "No genesis signing keys found in ${STATE_CLUSTER}/shelley/genesis-keys, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - GENESIS_SIGNING+=("--signing-key-file" "$skey") - done - readonly GENESIS_SIGNING - - DELEGATE_SIGNING=() - for skey in "$STATE_CLUSTER"/shelley/delegate-keys/delegate?.skey; do - [ -e "$skey" ] || { echo "No delegate signing keys found in ${STATE_CLUSTER}/shelley/delegate-keys, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - DELEGATE_SIGNING+=("--signing-key-file" "$skey") - done - readonly DELEGATE_SIGNING - - FAUCET_ADDR="$(<"$STATE_CLUSTER"/byron/address-000-converted)" - readonly FAUCET_ADDR - readonly FAUCET_SKEY="${STATE_CLUSTER}/byron/payment-keys.000-converted.skey" -} - -create_legacy_update_proposal() { - local era="${1:?}" - local proposal_file="${2:?}" - local major_version="${3:?}" - shift 3 - - cardano_cli_log compatible "$era" governance action create-protocol-parameters-update \ - --out-file "$proposal_file" \ - --epoch "$(get_epoch)" \ - "${GENESIS_VERIFICATION[@]}" \ - --protocol-major-version "$major_version" \ - --protocol-minor-version 0 \ - "$@" -} - -submit_legacy_update_proposal() { - local era="${1:?}" - local proposal_file="${2:?}" - local tx_base="${3:?}" - - get_txins "$FAUCET_ADDR" "$FEE" - - local txout_amount="$((TXIN_AMOUNT - FEE))" - - cardano_cli_log compatible "$era" transaction signed-transaction \ - --fee "$FEE" \ - "${TXINS[@]}" \ - --tx-out "${FAUCET_ADDR}+${txout_amount}" \ - --update-proposal-file "$proposal_file" \ - --signing-key-file "$FAUCET_SKEY" \ - "${DELEGATE_SIGNING[@]}" \ - --testnet-magic "$NETWORK_MAGIC" \ - --out-file "${tx_base}-tx.tx" - - cardano_cli_log latest transaction submit \ - --tx-file "${tx_base}-tx.tx" \ - --testnet-magic "$NETWORK_MAGIC" - - sleep "$SUBMIT_DELAY" - if ! check_spend_success "${TXINS[@]}"; then - echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi -} - -do_legacy_hf() { - local from_era="${1:?}" - local to_era="${2:?}" - local major_version="${3:?}" - local wait_epoch="${4:?}" - shift 4 - - local proposal_file="${STATE_CLUSTER}/shelley/update-proposal-${to_era,,}.proposal" - local tx_base="${STATE_CLUSTER}/shelley/update-proposal-${to_era,,}" - - sleep "$PROPOSAL_DELAY" - echo "Submitting update proposal to transfer to $to_era" - - create_legacy_update_proposal "$from_era" "$proposal_file" "$major_version" "$@" - submit_legacy_update_proposal "$from_era" "$proposal_file" "$tx_base" - - echo "Waiting for $to_era era to start" - wait_for_epoch "$wait_epoch" -} - -_register_governance_in_conway() { - local deposits="$((KEY_DEPOSIT + DREP_DEPOSIT))" - local needed_amount="$(( (DREP_DELEGATED + deposits) * NUM_DREPS ))" - local stop_txin_amount="$((FEE + needed_amount))" - local f i - - get_txins "$FAUCET_ADDR" "$stop_txin_amount" - - local txout_amount="$((TXIN_AMOUNT - stop_txin_amount))" - local v9_tx="${STATE_CLUSTER}/governance_data/setup_governance" - - local -a cc_args=() - for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_hot_auth.cert; do - [ -e "$f" ] || continue - cc_args+=( "--certificate-file" "$f" ) - done - - local -a cc_signing=() - for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_cold.skey; do - [ -e "$f" ] || continue - cc_signing+=( "--signing-key-file" "$f" ) - done - - local -a dreps_args=() - local -a dreps_signing=() - for i in $(seq 1 "$NUM_DREPS"); do - dreps_args+=( \ - "--tx-out" "$(<"${STATE_CLUSTER}/governance_data/vote_stake_addr${i}.addr")+${DREP_DELEGATED}" \ - "--certificate-file" "${STATE_CLUSTER}/governance_data/default_drep_${i}_drep_reg.cert" \ - "--certificate-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}_stake.reg.cert" \ - "--certificate-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}_stake.vote_deleg.cert" \ - ) - dreps_signing+=( \ - "--signing-key-file" "${STATE_CLUSTER}/governance_data/default_drep_${i}_drep.skey" \ - "--signing-key-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}.skey" \ - "--signing-key-file" "${STATE_CLUSTER}/governance_data/vote_stake_addr${i}_stake.skey" \ - ) - done - - local -a pool_args=() - local -a pool_signing=() - for i in $(seq 1 "$NUM_POOLS"); do - pool_args+=( \ - "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/stake-reward.vote_deleg.cert" \ - ) - pool_signing+=( \ - "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/reward.skey" \ - ) - done - - cardano_cli_log conway transaction build-raw \ - --fee "$FEE" \ - "${TXINS[@]}" \ - "${cc_args[@]}" \ - "${dreps_args[@]}" \ - "${pool_args[@]}" \ - --tx-out "${FAUCET_ADDR}+${txout_amount}" \ - --out-file "${v9_tx}-tx.txbody" - - cardano_cli_log conway transaction sign \ - --signing-key-file "$FAUCET_SKEY" \ - "${cc_signing[@]}" \ - "${dreps_signing[@]}" \ - "${pool_signing[@]}" \ - --testnet-magic "$NETWORK_MAGIC" \ - --tx-body-file "${v9_tx}-tx.txbody" \ - --out-file "${v9_tx}-tx.tx" - - cardano_cli_log conway transaction submit \ - --tx-file "${v9_tx}-tx.tx" \ - --testnet-magic "$NETWORK_MAGIC" - - sleep "$SUBMIT_DELAY" - if ! check_spend_success "${TXINS[@]}"; then - echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi - - if [ -z "${NO_CC:-}" ]; then - local cc_size - cc_size="$(cardano-cli conway query committee-state --active --testnet-magic "$NETWORK_MAGIC" | - grep -c '"status": "Active"')" - [ "$cc_size" -ge "$NUM_CC" ] || \ - { echo "The CC members were not registered, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - fi -} - -submit_gov_action() { - local action_base="${1:?}" - local stop_txin_amount="$((FEE + GOV_ACTION_DEPOSIT))" - - get_txins "$FAUCET_ADDR" "$stop_txin_amount" - - local txout_amount="$((TXIN_AMOUNT - stop_txin_amount))" - - cardano_cli_log conway transaction build-raw \ - --fee "$FEE" \ - "${TXINS[@]}" \ - --proposal-file "${action_base}.action" \ - --tx-out "${FAUCET_ADDR}+${txout_amount}" \ - --out-file "${action_base}-tx.txbody" - - cardano_cli_log conway transaction sign \ - --signing-key-file "$FAUCET_SKEY" \ - --testnet-magic "$NETWORK_MAGIC" \ - --tx-body-file "${action_base}-tx.txbody" \ - --out-file "${action_base}-tx.tx" - - cardano_cli_log conway transaction submit \ - --tx-file "${action_base}-tx.tx" \ - --testnet-magic "$NETWORK_MAGIC" - - sleep "$SUBMIT_DELAY" - if ! check_spend_success "${TXINS[@]}"; then - echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi -} - -create_and_submit_hf_action() { - local hf_action="${1:?}" - local era="$2" - local major_version="$3" - local prev_txid="${4:-}" - local prev_index="${5:-0}" - - local -a prev_args=() - if [ -n "$prev_txid" ]; then - prev_args=( \ - "--prev-governance-action-tx-id" "$prev_txid" \ - "--prev-governance-action-index" "$prev_index" \ - ) - fi - - cardano_cli_log "$era" governance action create-hardfork \ - --testnet \ - --governance-action-deposit "$GOV_ACTION_DEPOSIT" \ - --deposit-return-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool1/reward.vkey" \ - "${prev_args[@]}" \ - --anchor-url "http://www.hardfork-pv${major_version}.com" \ - --anchor-data-hash 5d372dca1a4cc90d7d16d966c48270e33e3aa0abcb0e78f0d5ca7ff330d2245d \ - --protocol-major-version "$major_version" \ - --protocol-minor-version 0 \ - --out-file "${hf_action}.action" - - submit_gov_action "$hf_action" -} - -_update_cost_model_in_pv9() { - echo "Submitting cost model update proposal" - local cost_model_base="${STATE_CLUSTER}/governance_data/cost_model_conway" - local cost_model_action="${cost_model_base}_action" - - cardano_cli_log conway governance action create-protocol-parameters-update \ - --testnet \ - --governance-action-deposit "$GOV_ACTION_DEPOSIT" \ - --deposit-return-stake-verification-key-file "${STATE_CLUSTER}/nodes/node-pool1/reward.vkey" \ - --anchor-url "http://www.cost-model-update.com" \ - --anchor-data-hash 5d372dca1a4cc90d7d16d966c48270e33e3aa0abcb0e78f0d5ca7ff330d2245d \ - --cost-model-file "${STATE_CLUSTER}/shelley/cost_models_list.json" \ - --out-file "${cost_model_action}.action" - - submit_gov_action "$cost_model_action" - - local cost_model_txid - cost_model_txid="$(cardano_cli_log conway transaction txid \ - --output-text --tx-body-file "${cost_model_action}-tx.txbody")" - vote_on_action "$cost_model_txid" "$cost_model_action" - submit_votes "${cost_model_base}_votes" "$cost_model_action" -} - -_wait_pv9_cost_model_enacted() { - local vote_epoch="${1:?}" - - echo "Waiting for cost model update to get enacted" - wait_for_epoch "$((vote_epoch + 2))" - - save_protocol_params "$PPARAMS_FILE" - local plutusv2_len - plutusv2_len="$(jq ".costModels.PlutusV2 | length" < "$PPARAMS_FILE")" - if [ "$plutusv2_len" != 185 ]; then - echo "Unexpected PlutusV2 cost model length '$plutusv2_len' on line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi -} - -vote_on_action() { - local action_txid="${1:?}" - local action_base="${2:?}" - local with_spos="${3:-no}" - local with_dreps="${4:-no}" - local f - - echo "Voting on $(basename "$action_base") proposal" - - local index=0 - for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_hot.vkey; do - [ -e "$f" ] || continue - index="$((index + 1))" - cardano_cli_log conway governance vote create \ - --yes \ - --governance-action-tx-id "$action_txid" \ - --governance-action-index 0 \ - --cc-hot-verification-key-file "$f" \ - --out-file "${action_base}_cc${index}.vote" - done - - if [ "$with_spos" = "yes" ]; then - index=0 - for f in "$STATE_CLUSTER"/nodes/node-pool*/cold.vkey; do - [ -e "$f" ] || continue - index="$((index + 1))" - cardano_cli_log conway governance vote create \ - --yes \ - --governance-action-tx-id "$action_txid" \ - --governance-action-index 0 \ - --cold-verification-key-file "$f" \ - --out-file "${action_base}_spo${index}.vote" - done - fi - - if [ "$with_dreps" = "yes" ]; then - index=0 - for f in "$STATE_CLUSTER"/governance_data/default_drep*_drep.vkey; do - [ -e "$f" ] || continue - index="$((index + 1))" - cardano_cli_log conway governance vote create \ - --yes \ - --governance-action-tx-id "$action_txid" \ - --governance-action-index 0 \ - --drep-verification-key-file "$f" \ - --out-file "${action_base}_drep${index}.vote" - done - fi -} - -submit_votes() { - local votes_base="${1:?}" - local action_base="${2:?}" - local f - - local -a vote_files=() - for f in "$action_base"_*.vote; do - [ -e "$f" ] || continue - vote_files+=( "--vote-file" "$f" ) - done - - local -a cc_signing=() - for f in "$STATE_CLUSTER"/governance_data/cc_member*_committee_hot.skey; do - [ -e "$f" ] || continue - cc_signing+=( "--signing-key-file" "$f" ) - done - - local -a pool_signing=() - if [ -e "${action_base}_spo1.vote" ]; then - for f in "$STATE_CLUSTER"/nodes/node-pool*/cold.skey; do - [ -e "$f" ] || continue - pool_signing+=( "--signing-key-file" "$f" ) - done - fi - - local -a drep_signing=() - if [ -e "${action_base}_drep1.vote" ]; then - for f in "$STATE_CLUSTER"/governance_data/default_drep*_drep.skey; do - [ -e "$f" ] || continue - drep_signing+=( "--signing-key-file" "$f" ) - done - fi - - get_txins "$FAUCET_ADDR" "$FEE" - - local txout_amount="$((TXIN_AMOUNT - FEE))" - - cardano_cli_log conway transaction build-raw \ - --fee "$FEE" \ - "${TXINS[@]}" \ - "${vote_files[@]}" \ - --tx-out "${FAUCET_ADDR}+${txout_amount}" \ - --out-file "${votes_base}-tx.txbody" - - cardano_cli_log conway transaction sign \ - --signing-key-file "$FAUCET_SKEY" \ - "${cc_signing[@]}" \ - "${pool_signing[@]}" \ - "${drep_signing[@]}" \ - --testnet-magic "$NETWORK_MAGIC" \ - --tx-body-file "${votes_base}-tx.txbody" \ - --out-file "${votes_base}-tx.tx" - - cardano_cli_log conway transaction submit \ - --tx-file "${votes_base}-tx.tx" \ - --testnet-magic "$NETWORK_MAGIC" - - sleep "$SUBMIT_DELAY" - if ! check_spend_success "${TXINS[@]}"; then - echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi -} - -submit_byron_genesis_txs() { - echo "Sleeping for initial Tx submission delay of $TX_SUBMISSION_DELAY seconds" - sleep "$TX_SUBMISSION_DELAY" - - echo "Moving funds out of Byron genesis" - local i - for i in $(seq 1 "$NUM_BFT_NODES"); do - cardano_cli_log byron transaction submit-tx \ - --testnet-magic "$NETWORK_MAGIC" \ - --tx "${STATE_CLUSTER}/byron/tx${i}.tx" - done - - echo "Waiting for next Byron epoch to start" - sleep "$((200 - TX_SUBMISSION_DELAY + 5))" -} - -hf_to_byron_pv1() { - local byron_v1_proposal="${STATE_CLUSTER}/byron/update-proposal-byron-v1.proposal" - - create_byron_update_proposal "$byron_v1_proposal" 1 0 - submit_byron_proposal_with_votes "$byron_v1_proposal" "${STATE_CLUSTER}/byron/update-proposal-byron-v1" - - echo "Waiting for Byron era with PV1 to start" - sleep 200 -} - -hf_to_shelley() { - local shelley_proposal="${STATE_CLUSTER}/byron/update-proposal-shelley.proposal" - - create_byron_update_proposal "$shelley_proposal" 2 0 - submit_byron_proposal_with_votes "$shelley_proposal" "${STATE_CLUSTER}/byron/update-proposal-shelley" - - local conf - for conf in "$STATE_CLUSTER"/config-*.json; do - [ -e "$conf" ] || { echo "No config files found in ${STATE_CLUSTER}, line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - local fname="${conf##*/}" - jq ' - ."LastKnownBlockVersion-Major" = 2' \ - "$conf" > "${STATE_CLUSTER}/${fname}_jq" - cat "${STATE_CLUSTER}/${fname}_jq" > "${STATE_CLUSTER}/${fname}" - rm -f "${STATE_CLUSTER}/${fname}_jq" - done - - supervisorctl -s unix:///"$SUPERVISORD_SOCKET_PATH" restart nodes: - - echo "Waiting for Shelley era to start" - sleep 190 - wait_for_era "Shelley" -} - -hf_to_allegra() { - local cur_epoch="${1:?}" - - sleep "$PROPOSAL_DELAY" - echo "Submitting update proposal to transfer to Allegra, transferring funds to pool owners, registering pools and delegations" - - local allegra_proposal_file="${STATE_CLUSTER}/shelley/update-proposal-allegra.proposal" - local allegra_tx_base="${STATE_CLUSTER}/shelley/transfer-register-delegate" - - cardano_cli_log compatible shelley governance action create-protocol-parameters-update \ - --out-file "$allegra_proposal_file" \ - --epoch "$(get_epoch)" \ - "${GENESIS_VERIFICATION[@]}" \ - --protocol-major-version 3 \ - --protocol-minor-version 0 - - local deposits="$((POOL_DEPOSIT + (2 * KEY_DEPOSIT) ))" - local needed_amount="$(( (POOL_PLEDGE + deposits) * NUM_POOLS ))" - local stop_txin_amount="$((needed_amount + FEE))" - - get_txins "$FAUCET_ADDR" "$stop_txin_amount" - - local txout_amount="$((TXIN_AMOUNT - stop_txin_amount))" - - local -a pool_args=() - local -a pool_signing=() - local i - for i in $(seq 1 "$NUM_POOLS"); do - pool_args+=( \ - "--tx-out" "$(<"${STATE_CLUSTER}/nodes/node-pool${i}/owner.addr")+${POOL_PLEDGE}" \ - "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/stake.reg.shelley.cert" \ - "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/stake-reward.reg.shelley.cert" \ - "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/register.shelley.cert" \ - "--certificate-file" "${STATE_CLUSTER}/nodes/node-pool${i}/owner-stake.deleg.shelley.cert" \ - ) - pool_signing+=( \ - "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/owner-stake.skey" \ - "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/reward.skey" \ - "--signing-key-file" "${STATE_CLUSTER}/nodes/node-pool${i}/cold.skey" \ - ) - done - - cardano_cli_log compatible shelley transaction signed-transaction \ - --fee "$FEE" \ - "${TXINS[@]}" \ - --tx-out "${FAUCET_ADDR}+${txout_amount}" \ - "${pool_args[@]}" \ - --update-proposal-file "$allegra_proposal_file" \ - "${pool_signing[@]}" \ - "${GENESIS_SIGNING[@]}" \ - "${DELEGATE_SIGNING[@]}" \ - --signing-key-file "$FAUCET_SKEY" \ - --testnet-magic "$NETWORK_MAGIC" \ - --out-file "${allegra_tx_base}-tx.tx" - - cardano_cli_log latest transaction submit \ - --tx-file "${allegra_tx_base}-tx.tx" \ - --testnet-magic "$NETWORK_MAGIC" - - sleep "$SUBMIT_DELAY" - if ! check_spend_success "${TXINS[@]}"; then - echo "Failed to spend Tx inputs, line $LINENO in ${BASH_SOURCE[0]}" >&2 - exit 1 - fi - - echo "Waiting for Allegra era to start" - wait_for_epoch "$((cur_epoch + 1))" - wait_for_era "Allegra" -} - -hf_to_mary() { - local cur_epoch="${1:?}" - do_legacy_hf "allegra" "Mary" 4 "$((cur_epoch + 1))" --decentralization-parameter 0 - wait_for_era "Mary" -} - -hf_to_alonzo() { - if [ "$PROTOCOL_VERSION" -lt 5 ]; then - echo "Skipping HF to Alonzo as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - return - fi - - local cur_epoch="${1:?}" - do_legacy_hf "mary" "Alonzo" 5 "$((cur_epoch + 1))" - wait_for_era "Alonzo" -} - -hf_to_alonzo_pv6() { - if [ "$PROTOCOL_VERSION" -lt 6 ]; then - echo "Skipping HF to Alonzo PV6 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - return - fi - - local cur_epoch="${1:?}" - - do_legacy_hf "alonzo" "Alonzo-PV6" 6 "$((cur_epoch + 1))" - - if save_protocol_params "$PPARAMS_FILE"; then - local cur_protver - cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" - [ "$cur_protver" = 6 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - fi -} - -hf_to_babbage() { - if [ "$PROTOCOL_VERSION" -lt 7 ]; then - echo "Skipping HF to Babbage as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - return - fi - - local cur_epoch="${1:?}" - - do_legacy_hf "alonzo" "Babbage" 7 "$((cur_epoch + 1))" - wait_for_era "Babbage" -} - -hf_to_babbage_pv8() { - if [ "$PROTOCOL_VERSION" -lt 8 ]; then - echo "Skipping HF to Babbage PV8 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - return - fi - - local cur_epoch="${1:?}" - - do_legacy_hf "babbage" "Babbage-PV8" 8 "$((cur_epoch + 1))" - - if save_protocol_params "$PPARAMS_FILE"; then - local cur_protver - cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" - [ "$cur_protver" = 8 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - fi -} - -hf_to_conway() { - if [ "$PROTOCOL_VERSION" -lt 9 ]; then - echo "Skipping HF to Conway as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - return - fi - - local cur_epoch="${1:?}" - - do_legacy_hf "babbage" "Conway" 9 "$((cur_epoch + 1))" - wait_for_era "Conway" - - save_protocol_params "$PPARAMS_FILE" - local cur_protver - cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" - [ "$cur_protver" = 9 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } - - _register_governance_in_conway -} - -hf_to_conway_pv10() { - local cur_epoch="${1:?}" - - _update_cost_model_in_pv9 - - if [ "$PROTOCOL_VERSION" -lt 10 ]; then - echo "Skipping HF to Conway PV10 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - _wait_pv9_cost_model_enacted "$cur_epoch" - return - fi - - wait_for_epoch "$((cur_epoch + 1))" - - echo "Submitting hard fork proposal to update to Conway PV10" - local pv10_hf_base="${STATE_CLUSTER}/governance_data/hardfork_pv10" - local pv10_hf_action="${pv10_hf_base}_action" - - create_and_submit_hf_action "$pv10_hf_action" "conway" 10 - - PV10_HF_ACTION_TXID="$(cardano_cli_log conway transaction txid \ - --output-text --tx-body-file "${pv10_hf_action}-tx.txbody")" - readonly PV10_HF_ACTION_TXID - - vote_on_action "$PV10_HF_ACTION_TXID" "$pv10_hf_action" "yes" - submit_votes "${pv10_hf_base}_votes" "$pv10_hf_action" - - _wait_pv9_cost_model_enacted "$cur_epoch" - - echo "Waiting for Conway PV10 to start" - wait_for_epoch "$((cur_epoch + 3))" - - save_protocol_params "$PPARAMS_FILE" - local cur_protver - cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" - [ "$cur_protver" = 10 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } -} - -hf_to_conway_pv11() { - if [ "$PROTOCOL_VERSION" -lt 11 ]; then - echo "Skipping HF to Conway PV11 as PROTOCOL_VERSION is set to $PROTOCOL_VERSION" - return - fi - - local cur_epoch="${1:?}" - - echo "Submitting hard fork proposal to update to Conway PV11" - - local pv11_hf_base="${STATE_CLUSTER}/governance_data/hardfork_pv11_action" - local pv11_hf_action="${pv11_hf_base}_action" - - create_and_submit_hf_action "$pv11_hf_action" "conway" 11 "${PV10_HF_ACTION_TXID:?"Must exist"}" - - PV11_HF_ACTION_TXID="$(cardano_cli_log conway transaction txid \ - --output-text --tx-body-file "${pv11_hf_action}-tx.txbody")" - readonly PV11_HF_ACTION_TXID - - vote_on_action "$PV11_HF_ACTION_TXID" "$pv11_hf_action" "yes" "yes" - submit_votes "${pv11_hf_base}_votes" "$pv11_hf_action" - - echo "Waiting for Conway PV11 to start" - wait_for_epoch "$((cur_epoch + 2))" - - save_protocol_params "$PPARAMS_FILE" - local cur_protver - cur_protver="$(jq ".protocolVersion.major" < "$PPARAMS_FILE")" - [ "$cur_protver" = 11 ] || { echo "Unexpected protocol version '$cur_protver' on line $LINENO in ${BASH_SOURCE[0]}" >&2; exit 1; } -} - -main() { - initialize_globals - setup_state_cluster "${STATE_CLUSTER}/shelley" - configure_supervisor - create_genesis - create_committee_keys_in_genesis - get_genesis_data - edit_node_configs - create_bft_nodes_files - create_pools_files - create_dreps_files - create_cluster_scripts - get_shelley_env - - start_cluster_nodes - - submit_byron_genesis_txs - hf_to_byron_pv1 - hf_to_shelley - - start_optional_services - - hf_to_allegra "$(get_epoch)" - hf_to_mary "$(get_epoch)" - hf_to_alonzo "$(get_epoch)" - hf_to_alonzo_pv6 "$(get_epoch)" - hf_to_babbage "$(get_epoch)" - hf_to_babbage_pv8 "$(get_epoch)" - hf_to_conway "$(get_epoch)" - hf_to_conway_pv10 "$(get_epoch)" - hf_to_conway_pv11 "$(get_epoch)" - - : > "$START_CLUSTER_STATUS" - echo "Cluster started 🚀" -} - -main "$@" +SCRIPT_DIR="$(readlink -m "${0%/*}")" +exec "${SCRIPT_DIR}/common-start-slow" "$@" diff --git a/src/cardonnay_scripts/scripts/mainnet_fast/start-cluster b/src/cardonnay_scripts/scripts/mainnet_fast/start-cluster new file mode 100644 index 0000000..094bcc5 --- /dev/null +++ b/src/cardonnay_scripts/scripts/mainnet_fast/start-cluster @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +SCRIPT_DIR="$(readlink -m "${0%/*}")" +exec "${SCRIPT_DIR}/common-start-fast" "$@"