Skip to content

Commit 5488f01

Browse files
wen-codingclaude
andcommitted
feat: add autobahn integration tests (CON-247)
5 tests with autobahn-enabled guard on each: 1. Block production (height advancing) 2. Bank transfer (send and verify balance) 3. Fault tolerance - one node down (3/4 quorum continues) 4. Two nodes down (chain halts, no quorum) 5. Recovery (restart node, chain resumes) Usage: make autobahn-integration-test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 21433ce commit 5488f01

3 files changed

Lines changed: 157 additions & 1 deletion

File tree

Makefile

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,37 @@ giga-integration-test:
347347
@echo "=== GIGA Integration Tests Complete ==="
348348
.PHONY: giga-integration-test
349349

350+
# Run Autobahn integration tests with an Autobahn-enabled cluster.
351+
autobahn-integration-test:
352+
@echo "=== Starting Autobahn Integration Tests ==="
353+
@$(MAKE) docker-cluster-stop || true
354+
@rm -rf $(PROJECT_HOME)/build/generated
355+
@AUTOBAHN=true DOCKER_DETACH=true $(MAKE) docker-cluster-start
356+
@echo "Waiting for cluster to be ready..."
357+
@timeout=300; elapsed=0; \
358+
while [ $$elapsed -lt $$timeout ]; do \
359+
if [ -f "build/generated/launch.complete" ] && [ $$(cat build/generated/launch.complete | wc -l) -ge 4 ]; then \
360+
echo "All 4 nodes are ready (took $${elapsed}s)"; \
361+
break; \
362+
fi; \
363+
sleep 5; \
364+
elapsed=$$((elapsed + 5)); \
365+
echo " Waiting... ($${elapsed}s elapsed)"; \
366+
done; \
367+
if [ $$elapsed -ge $$timeout ]; then \
368+
echo "ERROR: Cluster failed to start within $${timeout}s"; \
369+
$(MAKE) docker-cluster-stop; \
370+
exit 1; \
371+
fi
372+
@echo "Waiting 10s for nodes to stabilize..."
373+
@sleep 10
374+
@echo "=== Running Autobahn Tests ==="
375+
@./integration_test/autobahn/scripts/autobahn_tests.sh || ($(MAKE) docker-cluster-stop && exit 1)
376+
@echo "=== Stopping cluster ==="
377+
@$(MAKE) docker-cluster-stop
378+
@echo "=== Autobahn Integration Tests Complete ==="
379+
.PHONY: autobahn-integration-test
380+
350381
# Run a mixed-mode cluster: node 0 uses GIGA_EXECUTOR, nodes 1-3 use standard V2.
351382
# Any determinism divergence between giga and V2 will cause the giga node to halt.
352383
docker-cluster-start-giga-mixed: docker-cluster-stop build-docker-node
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#!/bin/bash
2+
set -e
3+
4+
LOG_DIR="build/generated/logs"
5+
6+
echo "============================================"
7+
echo " Autobahn Integration Tests"
8+
echo "============================================"
9+
10+
get_height() {
11+
local retries=5
12+
for i in $(seq 1 $retries); do
13+
HEIGHT=$(curl -s http://localhost:26657/status 2>/dev/null | python3 -c "import sys,json; print(json.load(sys.stdin)['sync_info']['latest_block_height'])" 2>/dev/null)
14+
if [ -n "$HEIGHT" ]; then
15+
echo "$HEIGHT"
16+
return 0
17+
fi
18+
sleep 2
19+
done
20+
echo "FAIL: Could not get block height after $retries retries" >&2
21+
return 1
22+
}
23+
24+
# Assert autobahn is enabled on all running nodes.
25+
# Called before each test to guard against accidental disablement.
26+
assert_autobahn_enabled() {
27+
for i in 0 1 2 3; do
28+
LOG="$LOG_DIR/seid-$i.log"
29+
if [ ! -f "$LOG" ]; then continue; fi
30+
if ! grep -q "GigaRouter initialized" "$LOG"; then
31+
echo "FAIL: Autobahn not enabled on node $i (missing 'GigaRouter initialized' in $LOG)"
32+
exit 1
33+
fi
34+
done
35+
}
36+
37+
# ---- Test 1: Blocks are being produced ----
38+
echo ""
39+
echo "=== Test 1: Block production ==="
40+
assert_autobahn_enabled
41+
HEIGHT1=$(get_height)
42+
echo " Height: $HEIGHT1"
43+
sleep 5
44+
HEIGHT2=$(get_height)
45+
echo " Height: $HEIGHT2 (after 5s)"
46+
if [ "$HEIGHT2" -le "$HEIGHT1" ]; then
47+
echo "FAIL: Block height not advancing ($HEIGHT1 -> $HEIGHT2)"
48+
exit 1
49+
fi
50+
echo "PASS: Blocks advancing ($HEIGHT1 -> $HEIGHT2)"
51+
52+
# ---- Test 2: Bank transfer ----
53+
echo ""
54+
echo "=== Test 2: Bank transfer ==="
55+
assert_autobahn_enabled
56+
# Create a test recipient address
57+
RECIPIENT=$(docker exec sei-node-0 sh -c "printf '12345678\n12345678\n' | seid keys add test_recipient --output json 2>/dev/null" | python3 -c "import sys,json; print(json.load(sys.stdin)['address'])")
58+
echo " Recipient: $RECIPIENT"
59+
60+
# Send from node_admin (genesis account) to recipient
61+
docker exec sei-node-0 sh -c "printf '12345678\n' | seid tx bank send node_admin $RECIPIENT 1000000usei --chain-id sei --fees 2000usei -b block -y --output json" > /dev/null 2>&1
62+
63+
# Check balance
64+
BALANCE=$(docker exec sei-node-0 seid q bank balances "$RECIPIENT" --denom usei --output json | python3 -c "import sys,json; print(json.load(sys.stdin)['amount'])")
65+
echo " Balance: $BALANCE usei"
66+
if [ "$BALANCE" != "1000000" ]; then
67+
echo "FAIL: Expected balance 1000000, got $BALANCE"
68+
exit 1
69+
fi
70+
echo "PASS: Bank transfer successful"
71+
72+
# ---- Test 3: Fault tolerance - one node down ----
73+
echo ""
74+
echo "=== Test 3: One node down (3/4 quorum) ==="
75+
assert_autobahn_enabled
76+
HEIGHT_BEFORE=$(get_height)
77+
echo " Height before: $HEIGHT_BEFORE"
78+
echo " Killing seid on node 3..."
79+
docker exec sei-node-3 pkill seid || true
80+
sleep 10
81+
HEIGHT_AFTER=$(get_height)
82+
echo " Height after: $HEIGHT_AFTER"
83+
if [ "$HEIGHT_AFTER" -le "$HEIGHT_BEFORE" ]; then
84+
echo "FAIL: Chain should continue with 3/4 validators"
85+
exit 1
86+
fi
87+
echo "PASS: Chain continues with one node down ($HEIGHT_BEFORE -> $HEIGHT_AFTER)"
88+
89+
# ---- Test 4: Two nodes down (no quorum) ----
90+
echo ""
91+
echo "=== Test 4: Two nodes down (no quorum) ==="
92+
assert_autobahn_enabled
93+
echo " Killing seid on node 2..."
94+
docker exec sei-node-2 pkill seid || true
95+
sleep 5
96+
HEIGHT_BEFORE=$(get_height)
97+
echo " Height: $HEIGHT_BEFORE"
98+
sleep 15
99+
HEIGHT_AFTER=$(get_height)
100+
echo " Height after 15s: $HEIGHT_AFTER"
101+
if [ "$HEIGHT_AFTER" -ne "$HEIGHT_BEFORE" ]; then
102+
echo "FAIL: Chain should halt with 2/4 validators (height changed: $HEIGHT_BEFORE -> $HEIGHT_AFTER)"
103+
exit 1
104+
fi
105+
echo "PASS: Chain halted with two nodes down"
106+
107+
# ---- Test 5: Recovery ----
108+
echo ""
109+
echo "=== Test 5: Recovery (restart one node) ==="
110+
assert_autobahn_enabled
111+
echo " Restarting seid on node 2..."
112+
docker exec sei-node-2 sh -c "seid start --chain-id sei > $LOG_DIR/seid-2-recovery.log 2>&1 &"
113+
sleep 20
114+
HEIGHT_AFTER=$(get_height)
115+
echo " Height after recovery: $HEIGHT_AFTER"
116+
if [ "$HEIGHT_AFTER" -le "$HEIGHT_BEFORE" ]; then
117+
echo "FAIL: Chain should resume after restoring quorum (height: $HEIGHT_BEFORE -> $HEIGHT_AFTER)"
118+
exit 1
119+
fi
120+
echo "PASS: Chain recovered ($HEIGHT_BEFORE -> $HEIGHT_AFTER)"
121+
122+
echo ""
123+
echo "============================================"
124+
echo " All Autobahn Integration Tests PASSED"
125+
echo "============================================"

sei-tendermint/cmd/tendermint/commands/gen_autobahn_config.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ Output is written to the file specified by --output.`,
7575
MaxTxsPerBlock: 5_000,
7676
MempoolSize: 5_000,
7777
BlockInterval: utils.Duration(400 * time.Millisecond),
78-
AllowEmptyBlocks: false,
78+
AllowEmptyBlocks: true,
7979
ViewTimeout: utils.Duration(1500 * time.Millisecond),
8080
DialInterval: utils.Duration(10 * time.Second),
8181
}

0 commit comments

Comments
 (0)