From 81696a1d1b9cc2d5192e152f5a8b935a101705b0 Mon Sep 17 00:00:00 2001 From: Michael FIG Date: Mon, 27 Apr 2020 14:22:54 -0600 Subject: [PATCH] Merge PR #125: Refactor nchainz to use config instead of metaprogramming * fix: remove agoric-solo; ag-nchainz is in agoric-sdk More fixes for the general nchainz script and agoric.json. * refactor: remove metaprogramming from nchainz; use a config file * feat: factor nchainz run command into chains and clients --- configs/agoric.json | 4 +- scripts/agoric-solo | 121 --------- scripts/nchainz | 608 +++++++++++++++++++++----------------------- 3 files changed, 290 insertions(+), 443 deletions(-) delete mode 100755 scripts/agoric-solo diff --git a/configs/agoric.json b/configs/agoric.json index da2e913d9d7..439e67f0706 100644 --- a/configs/agoric.json +++ b/configs/agoric.json @@ -3,7 +3,9 @@ "url": "https://testnet.agoric.com", "daemon": "ag-chain-cosmos", "cli": "ag-cosmos-helper", - "daemon-start": "bootaddr=$($CLI --home \"$DATA/$ID/n0/$CLI\" keys show n0 --keyring-backend=test | jq -r .address)\necho bootaddr=$bootaddr, $chainid\nDEBUG=$CONFIG ROLE=two_chain BOOT_ADDRESS=$bootaddr $DAEMON --home \"$DAEMON_HOME\" start --pruning=nothing", + "daemon-testnet": "ag-nchainz testnet $chainid -o $chainid --v 1 --chain-id $chainid --node-dir-prefix n --keyring-backend test", + "daemon-start": "ag-nchainz start-daemon $chainid --home \"$DAEMON_HOME\" start --pruning=nothing", + "post-lite-client": "ag-nchainz start-solos $chainid", "link": { "account-prefix": "agoric", "gas": 200000, diff --git a/scripts/agoric-solo b/scripts/agoric-solo deleted file mode 100755 index 08b780d8046..00000000000 --- a/scripts/agoric-solo +++ /dev/null @@ -1,121 +0,0 @@ -#! /bin/bash -# agoric-solo - start a client for each nchainz-configured Agoric chain -# -# Usage: -# agoric-solo [skip] init configure the solo clients for each chain -# agoric-solo start run the solo client machines -# -# first run at least two Agoric chains: -# nchainz agoric agoric -# or something. See nchainz --help for more details. -set -e -progname=$(basename -- "$0") - -trap 'kill $(jobs -p) 2>/dev/null' EXIT - -CLI=ag-cosmos-helper -DAEMON=ag-chain-cosmos -SKIP=no -COMMAND= -SIM_CHAIN_DELAY=1 - -while [[ $# -gt 0 ]]; do - case $1 in - -*) - echo "unrecognized option \`$1'" - exit 1 - ;; - *) - home="nchainz/data/$1/solo/$CLI-statedir" - if [[ $SKIP == no && $1 == skip ]]; then - SKIP=yes - shift - elif [[ -d $home ]]; then - shift - case $1 in - keys|tx) - # Commands that need keyring. - exec $CLI --home=$home --keyring-backend=test ${1+"$@"} - ;; - *) - # Other commands cannot have keyring. - exec $CLI --home=$home ${1+"$@"} - ;; - esac - exit $? - elif [[ -z $COMMAND ]]; then - COMMAND=$1 - shift - break; - fi - ;; - esac -done - -case $COMMAND in -init) - port=8000 - for ach in nchainz/data/*/n0/"$CLI"; do - d=$(dirname -- "$(dirname -- "$ach")") - echo - echo "Initializing ag-solo in $d/solo" - ( - cd "$d" - BASEDIR=solo - if [[ -e $BASEDIR ]] && [[ $SKIP != yes ]]; then - read -p "$progname: will delete $BASEDIR folder. Do you wish to continue? (y/N): " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi - fi - rm -rf solo - - mkdir solo - cp -r "n0/$CLI" "solo/$CLI-statedir" - ( - cd "solo/$CLI-statedir" - rm -rf keyring-test - jq -r .secret key_seed.json | $CLI keys add --home=. --recover --keyring-backend=test ag-solo - $CLI keys show --home=. ag-solo -a --keyring-backend=test > ../ag-cosmos-helper-address - ) - ag-solo init solo --webport="$port" - - gci=`ag-solo calc-gci n0/$DAEMON/config/genesis.json` - chainid=`jq -r .chain_id n0/$DAEMON/config/genesis.json` - rpcport=`ag-solo calc-rpcport n0/$DAEMON/config/config.toml` - - # For each solo, run: - cd solo && ag-solo set-gci-ingress --chainID="$chainid" "$gci" "$rpcport" - ) - port=$(( $port + 1 )) - done - - echo - if [[ $SKIP != yes ]]; then - read -p "$progname: would you like to start the solo vats now? (y/N): " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi - fi - - exec "$0" start - ;; -start) - for solo in nchainz/data/*/solo; do - ( - cd "$solo" - echo "Logging to $PWD/solo.log" - # ag-solo set-fake-chain --role=two_chain --delay=$SIM_CHAIN_DELAY mySimGCI >>solo.log 2>&1 - DEBUG=agoric ag-solo start --role=two_client >>solo.log 2>&1 - ) & - done - echo "Hit Control-C to exit" - wait - ;; -*) - echo 1>&2 "$progname: unrecognized command \`$COMMAND'" - exit 1 - ;; -esac diff --git a/scripts/nchainz b/scripts/nchainz index 31634920ca3..4e84fcb5f34 100755 --- a/scripts/nchainz +++ b/scripts/nchainz @@ -52,7 +52,9 @@ IDS=() CONFIGS=() JSONS=() SRCS=() +SRCPORTS=() DSTS=() +DSTPORTS=() get_alphabetic() { id="$1" @@ -132,8 +134,8 @@ validate() { found_src=no found_dst=no for id in ${IDS[@]}; do - [[ $id == $src ]] && found_src=yes - [[ $id == $dst ]] && found_dst=yes + [[ $id != $src ]] || found_src=yes + [[ $id != $dst ]] || found_dst=yes done if [[ $found_src != yes ]]; then echo 1>&2 "$progname: error: LINK \`$link' source ID \`$src' does not match a CHAIN" @@ -179,9 +181,11 @@ Usage: $progname COMMAND [OPTIONS]... COMMAND is one of: help [CMD] display help information for CMD (default: main) - init ... create a configuration for \`link' and \`run' - link link chains together with relayers per \`init' - run start chains running per \`init' + init ... create a configuration directory + chains start chains running per \`init' + clients start clients running per \`init' + relay link chains together with relayers per \`init' + run both chains and clients EOF else echo "Try \`$progname --help' for more information" @@ -223,18 +227,27 @@ Create configuration in \`$DATA' for: If no LINKS are supplied, use a circuit around the CHAINS. EOF ;; - run) + chains) cat < /dev/null + $CLI config --home "$gclpth" output json &> /dev/null + $CLI config --home "$gclpth" node http://localhost:$p26657 &> /dev/null + done + + for i in ${!IDS[@]}; do + json=${JSONS[$i]} + CLI=$(jq -r .cli $json) + DAEMON=$(jq -r .daemon $json) + CONFIG=${CONFIGS[$i]} + ID=${IDS[$i]} + chainid=$ID + + # Allow the config to override the start command. + DAEMON_HOME="$DATA/$chainid/n0/$DAEMON" + DAEMON_START=$(jq -r '."daemon-start"' "$json") + [[ $DAEMON_START != null ]] || DAEMON_START='$DAEMON --home "$DAEMON_HOME" start --pruning=nothing' + + echo "'$DAEMON start' ($chainid) logs in $LOGS/$ID.log" + ( + eval $DAEMON_START + ) >> "$LOGS/$ID.log" 2>&1 & + done + + echo "Ctrl-C exits, or you can background this script..." + wait + exit 0 + ;; +clients) + source "$NCONFIG" + RELAYER_CONF="$HOME/.relayer" + + set -e + + # Ensure gopath is set and go is installed + GOBIN=${GOBIN-${GOPATH-$HOME/go}/bin} + if [[ ! -d $GOPATH ]] || [[ ! -d $GOBIN ]] || [[ ! -x "$(which go)" ]]; then + echo "Your \$GOPATH is not set or go is not installed," + echo "ensure you have a working installation of go before trying again..." + echo "https://golang.org/doc/install" + exit 1 + fi + + # Ensure user understands what will be deleted + if [[ -d $RELAYER_CONF ]] && [[ "$1" != "skip" ]]; then + read -p "$progname: will delete $RELAYER_CONF folder. Do you wish to continue? (y/n): " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + exit 1 + fi + fi + + ( + cd "$RELAYER_DIR" + rm -rf "$RELAYER_CONF" + + echo "Building Relayer..." + make install + ) + + echo "Generating rly configurations..." + rly config init + rly config add-dir "$BASEDIR/config/" + + sleep 2 + + for i in ${!IDS[@]}; do + ID=${IDS[$i]} + json=${JSONS[$i]} + CLI=$(jq -r .cli $json) + DAEMON=$(jq -r .daemon $json) + chainid=$ID + ( + try=0 + f="$DATA/$chainid/n0/$CLI/key_seed.json" + while [[ ! -f $f ]]; do + try=$(( $try + 1 )) + echo "no $f" + echo "$chainid $CLI is not yet ready (try=$try)" + sleep 1 + done + SEED=$(jq -r '.secret' "$f") + echo "Key $(rly keys restore $chainid testkey "$SEED") imported from $chainid to relayer..." + + try=0 + f="$DATA/$chainid/n0/$DAEMON/config/genesis.json" + while [[ ! -f $f ]]; do + try=$(( $try + 1 )) + echo "no $f" + echo "$chainid is not yet ready (try=$try)" + sleep 1 + done + echo "Creating lite client for $chainid ($DAEMON)..." + try=0 + while ! rly lite init $chainid -f >> "$LOGS/lite-$chainid.log" 2>&1; do + try=$(( $try + 1 )) + echo "$chainid lite client not yet ready (try=$try)" + sleep 1 + done + try=$(( $try + 1 )) + echo "$chainid lite client initialized (try=$try)" + ) & + done + + # Let all our chains initialise. + wait + + for i in ${!IDS[@]}; do + ID=${IDS[$i]} + json=${JSONS[$i]} + + CMD=$(jq -r '."post-lite-client"' $json) + + [[ $CMD != null ]] || continue + ( + chainid=$ID + eval $CMD + ) & + done + echo "Waiting for clients (Control-C to exit)..." + wait + exit 0 + ;; + +relay) + . "$NCONFIG" + + paths= + for i in ${!SRCS[@]}; do + src=${SRCS[$i]} + get_alphabetic "$src" + srca=$ida + + dst=${DSTS[$i]} + get_alphabetic "$dst" + dsta=$ida + + get_alphabetic "$i" + ia=$ida + path="$ia" + paths="$paths $path" + echo "Starting 'rly tx link $path' ($src<>$dst) logs in $LOGS/$path.log" + ( + try=0 + while ! rly tx link $path --timeout=3s -d >> "$LOGS/$path.log" 2>&1; do + try=$(( $try + 1 )) + echo "$path tx link not yet ready (try=$try)" + sleep 1 + done + try=$(( $try + 1 )) + echo "$path tx link initialized (try=$try)" + rly start "$path" & + ) & + done + + echo "Check the state of the links using 'rly paths list' to see when they are ready..." + echo "(Ctrl-C exits, or you can background this job)" + todo=$paths + while :; do + rly paths list + remaining=$todo + todo= + for path in $remaining; do + if [[ $(rly paths show "$path" --json | jq -r .status.channel) != true ]]; then + todo="$todo $path" + fi + done + if [[ -z $todo ]]; then + break + fi + sleep 5 + done + + echo "All paths initialized, waiting for relayers (Control-C to exit)..." + wait + exit 0 + ;; +run) + "$0" chains skip & + "$0" clients skip & + wait + exit 0 ;; *) echo 1>&2 "$progname: unrecognized COMMAND \`$COMMAND'" @@ -330,152 +590,22 @@ if [[ -e $BASEDIR ]] && [[ $SKIP != yes ]]; then fi rm -rf "$BASEDIR" -mkdir -p "$BASEDIR/config" +mkdir -p "$BASEDIR/config" "$LOGS" echo "creating $NCONFIG" cat <"$NCONFIG" -{ - "FIXME": "This file would be the $progname configuration" -} -EOF - -# FIXME: Use this when run and link are in this script and use $NCONFIG -# exit 0 - - -# Fail on error. -set -e - -##################### -# Create $BASEDIR/run - -run=$BASEDIR/run -echo "creating $run" -cat <<\EOF >"$run" -#! /bin/bash -# run - create all the chains +# $NCONFIG - $progname configuration script # DO NOT EDIT - Automatically generated by $progname $args - -progname=$(basename -- "$0") -cd $(dirname -- ${BASH_SOURCE[0]}) || exit $? -BASEDIR=$PWD -DATA="$BASEDIR/data" -trap 'kill $(jobs -p) 2>/dev/null' EXIT - -# Ensure gopath is set and go is installed -GOBIN=${GOBIN-${GOPATH-$HOME/go}/bin} -if [[ ! -d $GOPATH ]] || [[ ! -d $GOBIN ]] || [[ ! -x "$(which go)" ]]; then - echo "Your \$GOPATH is not set or go is not installed," - echo "ensure you have a working installation of go before trying again..." - echo "https://golang.org/doc/install" - exit 1 -fi - -# Ensure user understands what will be deleted -if [[ -d $DATA && $1 != skip ]]; then - read -p "$progname: will delete $DATA folder. Do you wish to continue? (y/N): " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi -fi -rm -rf "$DATA" - -echo "mkdir $DATA" -mkdir -p "$DATA" - -set -e - -echo "Generating chain configurations..." -cd "$DATA" -EOF - -if [[ "$(uname)" == Darwin ]]; then - sedi="sed -i ''" -else - sedi="sed -i" -fi - -base=0 -for i in ${!IDS[@]}; do - ID=${IDS[$i]} - json=${JSONS[$i]} - DAEMON=$(jq -r .daemon $json) - CLI=$(jq -r .cli $json) - - cat >>"$run" <>"$run" <<\EOF - -echo -e "\n" | $DAEMON testnet -o $chainid --v 1 --chain-id $chainid --node-dir-prefix n --keyring-backend test &> /dev/null - -cfgpth="$DATA/$chainid/n0/$DAEMON/config/config.toml" -# TODO: Just index *some* specified tags, not all -sed -i 's/index_all_keys = false/index_all_keys = true/g' "$cfgpth" - -# Set proper defaults and change ports -sed -i 's/"leveldb"/"goleveldb"/g' "$cfgpth" -sed -i "s#:26656#:$p26656#g" "$cfgpth" -sed -i "s#:26657#:$p26657#g" "$cfgpth" -sed -i "s#:26658#:$p26658#g" "$cfgpth" -sed -i "s#:26660#:$p26660#g" "$cfgpth" -sed -i "s#:6060#:$p6060#g" "$cfgpth" - -# Make blocks run faster than normal -sed -i 's/timeout_commit = "[0-9]*s"/timeout_commit = "1s"/g' "$cfgpth" -sed -i 's/timeout_propose = "[0-9]*s"/timeout_propose = "1s"/g' "$cfgpth" - -gclpth="$DATA/$chainid/n0/$CLI/" -$CLI config --home "$gclpth" chain-id $chainid &> /dev/null -$CLI config --home "$gclpth" output json &> /dev/null -$CLI config --home "$gclpth" node http://localhost:$p26657 &> /dev/null +DATA='$BASEDIR/data' +LOGS='$BASEDIR/logs' +IDS=( $(printf "'%s' " "${IDS[@]}")) +CONFIGS=( $(printf "'%s' " "${CONFIGS[@]}")) +JSONS=( $(printf "'%s' " "${JSONS[@]}")) +SRCS=( $(printf "'%s' " "${SRCS[@]}")) +SRCPORTS=( $(printf "'%s' " "${SRCPORTS[@]}")) +DSTS=( $(printf "'%s' " "${DSTS[@]}")) +DSTPORTS=( $(printf "'%s' " "${DSTPORTS[@]}")) EOF -done - -for i in ${!IDS[@]}; do - json=${JSONS[$i]} - CLI=$(jq -r .cli $json) - DAEMON=$(jq -r .daemon $json) - CONFIG=${CONFIGS[$i]} - ID=${IDS[$i]} - chainid=$ID - - # Allow the config to override the start command. - DAEMON_HOME="\$DATA/$chainid/n0/$DAEMON" - DAEMON_START=$(jq -r '."daemon-start"' "$json") - [[ $DAEMON_START == null ]] && DAEMON_START='$DAEMON --home "$DAEMON_HOME" start --pruning=nothing' - - # echo "START=$DAEMON_START" - cat >>"$run" <>"$run" < "\$DATA/$ID.log" 2>&1 & -EOF -done - -cat >>"$run" <<\EOF - -echo "Ctrl-C exits, or you can background this script..." -wait -EOF -chmod +x "$run" for i in ${!IDS[@]}; do id=${IDS[$i]} @@ -526,182 +656,18 @@ for i in ${!SRCS[@]}; do EOF done -###################### -# Create $BASEDIR/link - -link=$BASEDIR/link -echo "creating $link" -cat <<\EOF >"$link" -#! /bin/bash -# link - create specific relayers -# DO NOT EDIT - Automatically generated by $progname $args - -progname=$(basename -- "$0") -cd $(dirname -- ${BASH_SOURCE[0]}) || exit $? -BASEDIR=$PWD -DATA="$BASEDIR/data" -RELAYER_CONF="$HOME/.relayer" -EOF - -cat >>"$link" <>"$link" <<\EOF - -set -e -trap 'kill $(jobs -p) 2>/dev/null' EXIT - -# Ensure jq is installed -if [[ ! -x "$(which jq)" ]]; then - echo "jq (a tool for parsing json in the command line) is required..." - echo "https://stedolan.github.io/jq/download/" - exit 1 -fi - -# Ensure user understands what will be deleted -if [[ -d $RELAYER_CONF ]] && [[ "$1" != "skip" ]]; then - read -p "$progname: will delete $RELAYER_CONF folder. Do you wish to continue? (y/n): " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi -fi - -( - cd "$RELAYER_DIR" - rm -rf "$RELAYER_CONF" - - echo "Building Relayer..." - make install -) - -echo "Generating rly configurations..." -rly config init -rly config add-dir "$BASEDIR/config/" - -sleep 2 -EOF - -for i in ${!IDS[@]}; do - id=${IDS[$i]} - json=${JSONS[$i]} - CLI=$(jq -r .cli $json) - DAEMON=$(jq -r .daemon $json) - cat >>"$link" <>"$link" <<\EOF -( - try=0 - f="$DATA/$chainid/n0/$CLI/key_seed.json" - while [[ ! -f $f ]]; do - try=$(( $try + 1 )) - echo "no $f" - echo "$chainid $CLI is not yet ready (try=$try)" - sleep 1 - done - SEED=$(jq -r '.secret' "$f") - echo "Key $(rly keys restore $chainid testkey "$SEED") imported from $chainid to relayer..." - - try=0 - f="$DATA/$chainid/n0/$DAEMON/config/genesis.json" - while [[ ! -f $f ]]; do - try=$(( $try + 1 )) - echo "no $f" - echo "$chainid is not yet ready (try=$try)" - sleep 1 - done - echo "Creating lite client for $chainid ($DAEMON)..." - try=0 - while ! rly lite init $chainid -f >> "$DATA/lite-$chainid.log" 2>&1; do - try=$(( $try + 1 )) - echo "$chainid lite client not yet ready (try=$try)" - sleep 1 - done - try=$(( $try + 1 )) - echo "$chainid lite client initialized (try=$try)" -) & -EOF -done - -cat >>"$link" <<\EOF - -# Let all our chains initialise. -wait - -EOF - -for i in ${!SRCS[@]}; do - src=${SRCS[$i]} - get_alphabetic "$src" - srca=$ida - - dst=${DSTS[$i]} - get_alphabetic "$dst" - dsta=$ida - - get_alphabetic "$i" - ia=$ida - path="$ia" - cat >>"$link" <$dst) logs in \$DATA/$path.log" -( - try=0 - while ! rly tx link $path --timeout=3s -d >> "\$DATA/$path.log" 2>&1; do - try=\$(( \$try + 1 )) - echo "$path tx link not yet ready (try=\$try)" - sleep 1 - done - try=\$(( \$try + 1 )) - echo "$path tx link initialized (try=\$try)" - rly start "$path" & -) & -EOF -done - -cat >>"$link" <<\EOF - -echo "Check the state of the links using 'rly paths list' to see when they are ready..." -echo "(Ctrl-C exits, or you can background this job)" -todo=$paths -while :; do - rly paths list - remaining=$todo - todo= - for path in $remaining; do - if [[ $(rly paths show "$path" --json | jq -r .status.channel) != true ]]; then - todo="$todo $path" - fi - done - if [[ -z $todo ]]; then - break - fi - sleep 5 -done - -echo "All paths initialized, waiting for relayers (Control-C to exit)..." -wait -EOF -chmod +x "$link" - ##################### cat <