Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(local-ic): bash driver #1207

Merged
merged 19 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/local-interchain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,39 @@ jobs:
name: local-ic
path: ~/go/bin/local-ic

bash-e2e:
name: bash
needs: build
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./local-interchain
strategy:
fail-fast: false

steps:
- name: checkout chain
uses: actions/checkout@v4

- name: Download Tarball Artifact
uses: actions/download-artifact@v3
with:
name: local-ic
path: /tmp

- name: Make local-ic executable
run: chmod +x /tmp/local-ic

- name: Start background ibc local-interchain
run: /tmp/local-ic start juno_ibc --api-port 8080 &

- name: Run Bash Script
run: |
cd bash
bash ./test.bash

- name: Cleanup
run: killall local-ic && exit 0

rust-e2e:
name: rust
Expand Down
184 changes: 184 additions & 0 deletions local-interchain/bash/source.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# IMPORT ME WITH: source <(curl -s https://raw.githubusercontent.com/strangelove-ventures/interchaintest/main/local-interchain/bash/source.bash)

# exitIfEmpty "$someKey" someKey
function ICT_exitIfEmpty() {
if [ -z "$1" ]; then
echo "Exiting because ${2} is empty"
exit 1
fi
}

# === BASE ===

# ICT_MAKE_REQUEST http://127.0.0.1:8080 localjuno-1 "q" "bank total"
ICT_MAKE_REQUEST() {
API=$1

CHAIN_ID=$2
ACTION=$3
shift 3 # get the 4th argument and up as the command
COMMAND="$*"

DATA=`printf '{"chain_id":"%s","action":"%s","cmd":"MYCOMMAND"}' $CHAIN_ID $ACTION`
DATA=`echo $DATA | sed "s/MYCOMMAND/$COMMAND/g"`

curl "$API" -ss --no-progress-meter --header "Content-Type: application/json" -X POST -d "$DATA"
}

# ICT_QUERY "http://localhost:8080" "localjuno-1" "bank balances juno10r39fueph9fq7a6lgswu4zdsg8t3gxlq670lt0"
ICT_QUERY() {
API=$1
CHAIN_ID=$2
CMD=$3 # can be multiple words
ICT_MAKE_REQUEST "$API" $CHAIN_ID "q" "$CMD"
}

# ICT_BIN "http://localhost:8080" "localjuno-1" "decode"
ICT_BIN() {
API=$1
CHAIN_ID=$2
CMD=$3 # can be multiple words
ICT_MAKE_REQUEST "$API" $CHAIN_ID "bin" "$CMD"
}

# ICT_SH_EXEC "http://localhost:8080" "localjuno-1" "ls -l"
# NOTE: if using a /, make sure to escape it with \
ICT_SH_EXEC() {
API=$1
CHAIN_ID=$2
CMD=$3 # can be multiple words
ICT_MAKE_REQUEST "$API" $CHAIN_ID "exec" "$CMD"
}

# === RELAYER ===

# ICT_RELAYER_STOP http://127.0.0.1 "localjuno-1"
ICT_RELAYER_STOP() {
API=$1
CHAIN_ID=$2

# TODO: how does this function?
ICT_MAKE_REQUEST $API $CHAIN_ID "stop-relayer" ""
}

# ICT_RELAYER_START http://127.0.0.1 "localjuno-1" "demo-path2 --max-tx-size 10"
ICT_RELAYER_START() {
API=$1
CHAIN_ID=$2
CMD=$3

ICT_MAKE_REQUEST $API $CHAIN_ID "start-relayer" "$CMD"
}

# RELAYER_EXEC http://127.0.0.1:8080 "localjuno-1" "rly paths list"
ICT_RELAYER_EXEC() {
API=$1
CHAIN_ID=$2
shift 2 # get the 3rd argument and up as the command
CMD="$*"

ICT_MAKE_REQUEST $API $CHAIN_ID "relayer-exec" "$CMD"
}

# RELAYER_CHANNELS http://127.0.0.1:8080 "localjuno-1"
ICT_RELAYER_CHANNELS() {
API=$1
CHAIN_ID=$2

ICT_MAKE_REQUEST $API $CHAIN_ID "get_channels" ""
}

# === COSMWASM ===

# ICT_WASM_DUMP_CONTRACT_STATE "http://localhost:8080" "localjuno-1" "cosmos1contractaddress" "100"
ICT_WASM_DUMP_CONTRACT_STATE() {
API=$1
CHAIN_ID=$2
CONTRACT=$3
HEIGHT=$4

ICT_MAKE_REQUEST $API $CHAIN_ID "recover-key" "contract=$CONTRACT;height=$HEIGHT"
}

# ICT_WASM_STORE_FILE "http://localhost:8080" "localjuno-1" "/host/absolute/path.wasm" "keyName"
# returns the code_id of the uploaded contract
ICT_WASM_STORE_FILE() {
API=$1
CHAIN_ID=$2
FILE=$3
KEYNAME=$4

DATA=`printf '{"chain_id":"%s","file_path":"%s","key_name":"%s"}' $CHAIN_ID $FILE $KEYNAME`
curl "$API/upload" --header "Content-Type: application/json" --header "Upload-Type: cosmwasm" -X POST -d "$DATA"
}

# === OTHER ===

# ICT_POLL_FOR_START "http://localhost:8080" 50
ICT_POLL_FOR_START() {
API=$1
ATTEMPTS_MAX=$2

curl --head -X GET --retry $ATTEMPTS_MAX --retry-connrefused --retry-delay 3 $API
}

# ICT_KILL_ALL "http://localhost:8080" "localjuno-1"
# (Kills all running, keeps local-ic process. `killall local-ic` to kill that as well)
ICT_KILL_ALL() {
API=$1
CHAIN_ID=$2
ICT_MAKE_REQUEST $API $CHAIN_ID "kill-all" ""
}

# ICT_GET_PEER "http://localhost:8080" "localjuno-1"
ICT_GET_PEER() {
API=$1
CHAIN_ID=$2

if [[ $API != */info ]]; then
API="$API/info"
fi

curl -G -d "chain_id=$CHAIN_ID" -d "request=peer" $API
}

# ICT_FAUCET_REQUEST "http://localhost:8080" "localjuno-1" "1000000000ujuno" "juno1qk7zqy3k2v3jx2zq2z2zq2zq2zq2zq2zq2zq"
ICT_FAUCET_REQUEST() {
API=$1
CHAIN_ID=$2
AMOUNT=$3
ADDRESS=$4
ICT_MAKE_REQUEST $API $CHAIN_ID "faucet" "amount=$AMOUNT;address=$ADDRESS"
}

# ICT_ADD_FULL_NODE http://127.0.0.1:8080 "localjuno-1" "1"
ICT_ADD_FULL_NODE() {
API=$1
CHAIN_ID=$2
AMOUNT=$3

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would consider using local

local API=$1, CHAIN_ID=$2, AMOUNT=$3

in this way variables will not leak into outside context which might make debugging harder especially if multiple functions are called in succession with different args

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good call

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved in: 92e712f


ICT_MAKE_REQUEST $API $CHAIN_ID "add-full-nodes" "amount=$AMOUNT"
}

# ICT_RECOVER_KEY "http://localhost:8080" "localjuno-1" "mykey" "my mnemonic string here"
ICT_RECOVER_KEY() {
API=$1
CHAIN_ID=$2
KEYNAME=$3
shift 3 # get the 4th argument and up as the command
MNEMONIC="$*"

ICT_MAKE_REQUEST $API $CHAIN_ID "recover-key" "keyname=$KEYNAME;mnemonic=$MNEMONIC"
}

# ICT_STORE_FILE "http://localhost:8080" "localjuno-1" "/host/absolute/path"
# Uploads any arbitrary host file to the chain node.
ICT_STORE_FILE() {
API=$1
CHAIN_ID=$2
FILE=$3

DATA=`printf '{"chain_id":"%s","file_path":"%s"}' $CHAIN_ID $FILE`
curl "$API/upload" --header "Content-Type: application/json" -X POST -d "$DATA"
}

88 changes: 88 additions & 0 deletions local-interchain/bash/test.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash
# local-ic start juno_ibc
#
# bash local-interchain/bash/test.bash

# exits if any command is non 0 status
set -e

thisDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
# EXTERNAL: source <(curl -s https://raw.githubusercontent.com/strangelove-ventures/interchaintest/main/local-interchain/bash/source.bash)
source "$thisDir/source.bash"
API_ADDR="http://localhost:8080"

# === BEGIN TESTS ===

ICT_POLL_FOR_START $API_ADDR 50

# Set standard interaction defaults
ICT_BIN "$API_ADDR" "localjuno-1" "config keyring-backend test"
ICT_BIN "$API_ADDR" "localjuno-1" "config output json"

# Get total bank supply
BANK_TOTAL=`ICT_QUERY $API_ADDR "localjuno-1" "bank total"` && echo "BANK_TOTAL: $BANK_TOTAL"
ICT_exitIfEmpty "$BANK_TOTAL" "BANK_TOTAL"
echo $BANK_TOTAL | jq -r '.supply'

# Get total bank supply another way (directly)
BANK_TOTAL=`ICT_MAKE_REQUEST $API_ADDR "localjuno-1" "q" "bank total"` && echo "BANK_TOTAL: $BANK_TOTAL"
ICT_exitIfEmpty "$BANK_TOTAL" "BANK_TOTAL"
echo $BANK_TOTAL | jq -r '.supply'

# faucet to user
FAUCET_RES=`ICT_FAUCET_REQUEST "$API_ADDR" "localjuno-1" "7" "juno10r39fueph9fq7a6lgswu4zdsg8t3gxlq670lt0"` && echo "FAUCET_RES: $FAUCET_RES"
FAUCET_CONFIRM=`ICT_QUERY $API_ADDR "localjuno-1" "bank balances juno10r39fueph9fq7a6lgswu4zdsg8t3gxlq670lt0"` && echo "FAUCET_CONFIRM: $FAUCET_CONFIRM"
ICT_exitIfEmpty "$FAUCET_CONFIRM" "FAUCET_CONFIRM"

if [ $(echo $FAUCET_CONFIRM | jq -r '.balances[0].amount') -lt 7 ]; then
echo "FAUCET_CONFIRM is less than 7"
exit 1
fi

# CosmWasm - Upload source file to chain & store
parent_dir=$(dirname $thisDir) # local-interchain folder
contract_source="$parent_dir/contracts/cw_ibc_example.wasm"
CODE_ID_JSON=`ICT_WASM_STORE_FILE $API_ADDR "localjuno-1" "$contract_source" "acc0"` && echo "CODE_ID_JSON: $CODE_ID_JSON"
CODE_ID=`echo $CODE_ID_JSON | jq -r '.code_id'` && echo "CODE_ID: $CODE_ID"
ICT_exitIfEmpty "$CODE_ID" "CODE_ID"

# Upload random file
FILE_RESP=`ICT_STORE_FILE $API_ADDR "localjuno-1" "$thisDir/test.bash"` && echo "FILE_RESP: $FILE_RESP"
FILE_LOCATION=`echo $FILE_RESP | jq -r '.location'` && echo "FILE_LOCATION: $FILE_LOCATION"
ICT_exitIfEmpty "$FILE_LOCATION" "FILE_LOCATION"

# Verify file contents are there
FILE_LOCATION_ESC=$(echo $FILE_LOCATION | sed 's/\//\\\//g')
MISC_BASH_CMD=`ICT_SH_EXEC "$API_ADDR" "localjuno-1" "cat $FILE_LOCATION_ESC"` && echo "MISC_BASH_CMD: $MISC_BASH_CMD"
ICT_exitIfEmpty "$MISC_BASH_CMD" "MISC_BASH_CMD"

PEER=`ICT_GET_PEER $API_ADDR "localjuno-1"` && echo "PEER: $PEER"
ICT_exitIfEmpty "$PEER" "PEER"

# RELAYER
CHANNELS=`ICT_RELAYER_CHANNELS $API_ADDR "localjuno-1"` && echo "CHANNELS: $CHANNELS"
ICT_exitIfEmpty "$CHANNELS" "CHANNELS"

ICT_RELAYER_EXEC $API_ADDR "localjuno-1" "rly paths list"
ICT_RELAYER_EXEC $API_ADDR "localjuno-1" "rly chains list"
RLY_BALANCE=`ICT_RELAYER_EXEC $API_ADDR "localjuno-1" "rly q balance localjuno-1 --output=json"` && echo "RLY_BALANCE: $RLY_BALANCE"
ICT_exitIfEmpty "$RLY_BALANCE" "RLY_BALANCE"
echo $RLY_BALANCE | jq -r '.balance'


# Recover a key and validate
COSMOS_KEY_STATUS=`ICT_RECOVER_KEY $API_ADDR "localjuno-1" "mynewkey" "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art"` && echo "COSMOS_KEY_STATUS: $COSMOS_KEY_STATUS"

COSMOS_KEY_ADDRESS=`ICT_BIN "$API_ADDR" "localjuno-1" "keys show mynewkey -a"` && echo "COSMOS_KEY_ADDRESS: $COSMOS_KEY_ADDRESS"
ICT_exitIfEmpty "$COSMOS_KEY_ADDRESS" "COSMOS_KEY_ADDRESS"

FULL_NODE_ADDED=`ICT_ADD_FULL_NODE $API_ADDR "localjuno-1" "1"`
ICT_exitIfEmpty "$FULL_NODE_ADDED" "FULL_NODE_ADDED"

# Stop the relayer
ICT_RELAYER_STOP $API_ADDR "localjuno-1"

# Kills all containers, not the local-ic process. Use `killall local-ic` to kill that as well
ICT_KILL_ALL $API_ADDR "localjuno-1"

exit 0
20 changes: 16 additions & 4 deletions local-interchain/interchain/handlers/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,21 +151,29 @@ func (a *actions) PostActions(w http.ResponseWriter, r *http.Request) {

// Relayer Actions if the above is not used.
if len(stdout) == 0 && len(stderr) == 0 && err == nil {
if err := a.relayerCheck(w, r); err != nil {
return
}

switch action {
case "stop-relayer", "stop_relayer", "stopRelayer":
if err := a.relayerCheck(w, r); err != nil {
return
}

err = a.relayer.StopRelayer(a.ctx, a.eRep)

case "start-relayer", "start_relayer", "startRelayer":
if err := a.relayerCheck(w, r); err != nil {
return
}

paths := strings.FieldsFunc(ah.Cmd, func(c rune) bool {
return c == ',' || c == ' '
})
err = a.relayer.StartRelayer(a.ctx, a.eRep, paths...)

case "relayer", "relayer-exec", "relayer_exec", "relayerExec":
if err := a.relayerCheck(w, r); err != nil {
return
}

if !strings.Contains(ah.Cmd, "--home") {
// does this ever change for any other relayer?
cmd = append(cmd, "--home", "/home/relayer")
Expand All @@ -177,6 +185,10 @@ func (a *actions) PostActions(w http.ResponseWriter, r *http.Request) {
err = res.Err

case "get_channels", "get-channels", "getChannels":
if err := a.relayerCheck(w, r); err != nil {
return
}

res, err := a.relayer.GetChannels(a.ctx, a.eRep, chainId)
if err != nil {
util.WriteError(w, err)
Expand Down
Loading