Skip to content
Draft
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
128 changes: 128 additions & 0 deletions scripts/e2e/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
SHELL := /bin/bash

COMPOSE := docker compose -f docker-compose.yml

# Default ports exposed in compose
RPC_A ?= 26657
GRPC_A ?= 9090
RPC_B ?= 26657
GRPC_B ?= 9090
RPC_C ?= 26657
GRPC_C ?= 9090

# Migration window and height (set MIG when running backfill)
WINDOW ?= 30
MIG ?=

.PHONY: help
help:
@echo "E2E orchestration targets:"
@echo " make up - start chains (wait for height >= 1)"
@echo " make down - stop containers"
@echo " make ps - list containers"
@echo " make logs-a/b/c - tail chain logs"
@echo " make hermes-start - start Hermes only (after chains ready)"
@echo " make ibc-setup - fund relayer and create A<->B, A<->C channels"
@echo " make ibc-transfer - send IBC transfer from gm-a to gm-b (can be called multiple times)"
@echo " make ibc-transfer-verify - verify IBC transfer completed"
@echo " make migrate - submit StayOnComet migration on A (WINDOW=$(WINDOW))"
@echo " make backfill MIG=<height> [WINDOW=$(WINDOW)] - run client backfill"
@echo " make clean - down and remove volumes"

.PHONY: up
up:
$(COMPOSE) up -d gm-a-val-0 gm-a-val-1 gm-a-val-2 gm-b-val-0 gm-c-val-0 hermes
@echo "[wait] waiting for chains to reach height >= 1"
@bash -c 'set -e; \
parse_height() { \
url="$$1"; \
if command -v jq >/dev/null 2>&1; then \
curl -s "$$url" | jq -r .result.sync_info.latest_block_height 2>/dev/null || true; \
else \
curl -s "$$url" | sed -n "s/.*\"latest_block_height\":\"\([0-9]\+\)\".*/\1/p"; \
fi; \
}; \
endpoints=("http://localhost:26657/status" "http://localhost:27657/status" "http://localhost:28657/status"); \
for ep in "$${endpoints[@]}"; do \
echo " waiting on $$ep"; \
ok=0; \
for i in $$(seq 1 120); do \
h=$$(parse_height $$ep); \
if [ -n "$$h" ] && [ "$$h" -ge 1 ] 2>/dev/null; then \
echo " ok height=$$h"; ok=1; break; \
fi; \
sleep 1; \
done; \
if [ $$ok -ne 1 ]; then echo " timeout waiting for $$ep" >&2; exit 1; fi; \
done'
@echo "[up] Hermes started (gated by chain healthchecks)"

.PHONY: down
down:
$(COMPOSE) down

.PHONY: ps
ps:
$(COMPOSE) ps

.PHONY: logs-a logs-b logs-c
logs-a:
docker logs -f gm-a-val-0
logs-b:
docker logs -f gm-b-val-0
logs-c:
docker logs -f gm-c-val-0

.PHONY: init

.PHONY: hermes-start
hermes-start:
$(COMPOSE) up -d hermes

.PHONY: ibc-setup
ibc-setup:
bash ./ibc-setup.sh

.PHONY: ibc-transfer
ibc-transfer:
@echo "[ibc-transfer] Sending 1000000stake from gm-a to gm-b"
@docker exec -i gm-a-val-0 gmd tx ibc-transfer transfer transfer channel-0 \
$$(docker exec -i gm-b-val-0 gmd keys show faucet -a --keyring-backend test --home /home/gm/.gm) \
1000000stake \
--from faucet \
--keyring-backend test \
--chain-id gm-a \
--home /home/gm/.gm \
--yes \
--output json | jq -r '.txhash // "Transaction submitted"'

.PHONY: ibc-transfer-verify
ibc-transfer-verify:
@echo "[ibc-transfer-verify] Checking IBC balance on gm-b..."
@sleep 5
@IBC_DENOM=$$(docker exec -i gm-b-val-0 gmd query bank balances \
$$(docker exec -i gm-b-val-0 gmd keys show faucet -a --keyring-backend test --home /home/gm/.gm) \
--home /home/gm/.gm \
--output json 2>/dev/null | jq -r '.balances[] | select(.denom | startswith("ibc/")) | .denom' | head -1); \
if [ -n "$$IBC_DENOM" ]; then \
BALANCE=$$(docker exec -i gm-b-val-0 gmd query bank balances \
$$(docker exec -i gm-b-val-0 gmd keys show faucet -a --keyring-backend test --home /home/gm/.gm) \
--home /home/gm/.gm \
--output json 2>/dev/null | jq -r ".balances[] | select(.denom == \"$$IBC_DENOM\") | .amount"); \
echo "[ibc-transfer-verify] ✓ IBC balance: $$BALANCE $$IBC_DENOM"; \
else \
echo "[ibc-transfer-verify] ✗ No IBC tokens found yet"; \
fi

.PHONY: migrate
migrate:
WINDOW=$(WINDOW) bash ./migrate-stayoncomet.sh $(WINDOW)

.PHONY: backfill
backfill:
@if [ -z "$(MIG)" ]; then echo "Set MIG=<migration_start_height> (e.g., MIG=120)" >&2; exit 2; fi
python3 ./update_ibc_clients_backfill.py gm-a gm-b gm-c --migration-height $(MIG) --window $(WINDOW)

.PHONY: clean
clean:
$(COMPOSE) down -v
46 changes: 46 additions & 0 deletions scripts/e2e/chain-entry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/sh
set -e

CHAIN_ID="${CHAIN_ID:-gm-a}"
RPC_PORT="${RPC_PORT:-26657}"
GRPC_PORT="${GRPC_PORT:-9090}"
DENOM="stake"
HOME_DIR="/home/gm/.gm"
MNEMONIC_FILE="/scripts/relayer.mnemonic"

echo "[chain] init $CHAIN_ID (rpc=$RPC_PORT grpc=$GRPC_PORT)"

# initialize chain
gmd init "$HOSTNAME" --chain-id "$CHAIN_ID" --home "$HOME_DIR"

# create faucet key
gmd keys add faucet --keyring-backend test --home "$HOME_DIR" >/dev/null 2>&1
FAUCET_ADDR=$(gmd keys show faucet -a --keyring-backend test --home "$HOME_DIR")

# add faucet as genesis account
gmd genesis add-genesis-account "$FAUCET_ADDR" 100000000000"$DENOM" --home "$HOME_DIR"

# recover relayer key from shared mnemonic
gmd keys add relayer --recover --keyring-backend test --home "$HOME_DIR" < "$MNEMONIC_FILE" >/dev/null 2>&1
RELAYER_ADDR=$(gmd keys show relayer -a --keyring-backend test --home "$HOME_DIR")

# add relayer as genesis account
gmd genesis add-genesis-account "$RELAYER_ADDR" 100000000000"$DENOM" --home "$HOME_DIR"

# create genesis transaction
gmd genesis gentx faucet 10000000000"$DENOM" --moniker "$HOSTNAME" --chain-id "$CHAIN_ID" --keyring-backend test --home "$HOME_DIR"
gmd genesis collect-gentxs --home "$HOME_DIR"

# configure app
sed -i "s/^minimum-gas-prices.*/minimum-gas-prices = \"0.0$DENOM\"/" "$HOME_DIR/config/app.toml"
sed -i "s/^indexer.*/indexer = \"kv\"/" "$HOME_DIR/config/config.toml"
sed -i "s|127.0.0.1:26657|0.0.0.0:26657|" "$HOME_DIR/config/config.toml"
sed -i "s|127.0.0.1:9090|0.0.0.0:9090|" "$HOME_DIR/config/app.toml"

# reduce voting period for testing (30 seconds instead of 48 hours)
sed -i "s/\"voting_period\": \"172800s\"/\"voting_period\": \"30s\"/" "$HOME_DIR/config/genesis.json"
sed -i "s/\"expedited_voting_period\": \"86400s\"/\"expedited_voting_period\": \"15s\"/" "$HOME_DIR/config/genesis.json"
sed -i "s/\"max_deposit_period\": \"172800s\"/\"max_deposit_period\": \"30s\"/" "$HOME_DIR/config/genesis.json"

echo "[chain] starting $CHAIN_ID"
exec gmd start --home "$HOME_DIR" --rpc.laddr tcp://0.0.0.0:"$RPC_PORT" --grpc.address 0.0.0.0:"$GRPC_PORT"
125 changes: 125 additions & 0 deletions scripts/e2e/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
version: "3.8"

services:
gm-a-val-0:
image: cosmos-gm:test
container_name: gm-a-val-0
entrypoint: ["/bin/sh", "/scripts/chain-entry.sh"]
volumes:
- gm_a_val0:/home/gm/.gm
- ./:/scripts:ro
networks: [gmnet]
user: "0:0"
ports:
- "26657:26657" # RPC
- "9090:9090" # gRPC
environment:
- CHAIN_ID=gm-a
- RPC_PORT=26657
- GRPC_PORT=9090
healthcheck:
test: ["CMD-SHELL", "gmd status 2>/dev/null | tr -d '\n' | grep -q '\"latest_block_height\":\"[1-9]' "]
interval: 2s
timeout: 2s
retries: 60

gm-a-val-1:
image: cosmos-gm:test
container_name: gm-a-val-1
entrypoint: ["/bin/sh", "/scripts/chain-entry.sh"]
volumes:
- gm_a_val1:/home/gm/.gm
- ./:/scripts:ro
networks: [gmnet]
user: "0:0"
environment:
- CHAIN_ID=gm-a
- RPC_PORT=26657
- GRPC_PORT=9090

gm-a-val-2:
image: cosmos-gm:test
container_name: gm-a-val-2
entrypoint: ["/bin/sh", "/scripts/chain-entry.sh"]
volumes:
- gm_a_val2:/home/gm/.gm
- ./:/scripts:ro
networks: [gmnet]
user: "0:0"
environment:
- CHAIN_ID=gm-a
- RPC_PORT=26657
- GRPC_PORT=9090

gm-b-val-0:
image: cosmos-gm:test
container_name: gm-b-val-0
entrypoint: ["/bin/sh", "/scripts/chain-entry.sh"]
volumes:
- gm_b_val0:/home/gm/.gm
- ./:/scripts:ro
networks: [gmnet]
user: "0:0"
ports:
- "27657:26657"
- "9190:9090"
environment:
- CHAIN_ID=gm-b
- RPC_PORT=26657
- GRPC_PORT=9090
healthcheck:
test: ["CMD-SHELL", "gmd status 2>/dev/null | tr -d '\n' | grep -q '\"latest_block_height\":\"[1-9]' "]
interval: 2s
timeout: 2s
retries: 60

gm-c-val-0:
image: cosmos-gm:test
container_name: gm-c-val-0
entrypoint: ["/bin/sh", "/scripts/chain-entry.sh"]
volumes:
- gm_c_val0:/home/gm/.gm
- ./:/scripts:ro
networks: [gmnet]
user: "0:0"
ports:
- "28657:26657"
- "9290:9090"
environment:
- CHAIN_ID=gm-c
- RPC_PORT=26657
- GRPC_PORT=9090
healthcheck:
test: ["CMD-SHELL", "gmd status 2>/dev/null | tr -d '\n' | grep -q '\"latest_block_height\":\"[1-9]' "]
interval: 2s
timeout: 2s
retries: 60

hermes:
image: ghcr.io/informalsystems/hermes:1.13.1
container_name: hermes
entrypoint: ["/bin/sh", "/scripts/hermes-entry.sh"]
volumes:
- hermes_home:/home/hermes/.hermes
- ./:/scripts:ro
networks: [gmnet]
depends_on:
gm-a-val-0:
condition: service_healthy
gm-b-val-0:
condition: service_healthy
gm-c-val-0:
condition: service_healthy
restart: unless-stopped
user: "0:0"

networks:
gmnet: {}

volumes:
gm_a_val0: {}
gm_a_val1: {}
gm_a_val2: {}
gm_b_val0: {}
gm_c_val0: {}
hermes_home: {}
Loading