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 all 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
34 changes: 34 additions & 0 deletions .github/workflows/local-interchain.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,40 @@ 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
needs: build
Expand Down
152 changes: 152 additions & 0 deletions local-interchain/bash/source.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# 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() {
local API=$1 CHAIN_ID=$2 ACTION=$3
shift 3 # get the 4th argument and up as the command
local 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() {
local 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() {
local 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() {
local 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() {
local 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() {
local 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() {
local API=$1 CHAIN_ID=$2
shift 2 # get the 3rd argument and up as the command
local CMD="$*"

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

# RELAYER_CHANNELS http://127.0.0.1:8080 "localjuno-1"
ICT_RELAYER_CHANNELS() {
local 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() {
local 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() {
local 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() {
local 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() {
local API=$1 CHAIN_ID=$2
ICT_MAKE_REQUEST $API $CHAIN_ID "kill-all" ""
}

# ICT_GET_PEER "http://localhost:8080" "localjuno-1"
ICT_GET_PEER() {
local 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() {
local 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() {
local API=$1 CHAIN_ID=$2 AMOUNT=$3

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() {
local API=$1 CHAIN_ID=$2 KEYNAME=$3
shift 3 # get the 4th argument and up as the command
local 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() {
local 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