#!/usr/bin/env bash # The joiner stop-gap of 6 October 2026 (docs/analysis/prover-tiers-real-cards.md, the fleet night): a node that synced # through the headers proof holds no genesis header, so the in-memory exec state never rebuilds and eth_blockNumber # stays 0. This swaps the box's consensus datadir for a copy of the observer's full-history datadir (pulled from the # hub over the throwaway fleet-internal key), restarts the node with the hub and the seed as peers and the proof # verifier, and reports the follower's replay: eth_blockNumber every 15 s until it reaches the node's DAA tip. set -uo pipefail F=/root/fleet; OUT=$F/out; B=/opt/igneum/pkg/bin; FLOOR=/opt/igneum-floor; HOST=$FLOOR/bin/igneum-prove-host HUB_SSH="${HUB_SSH:-213.173.107.74}"; HUB_PORT="${HUB_PORT:-16515}"; HUB_PEER="${HUB_PEER:-213.173.107.74:16516}" mkdir -p $OUT; exec >> $OUT/datadir.log 2>&1 stamp() { date -u +%Y-%m-%dT%H:%M:%SZ; } echo "RESULT datadir_start $(stamp)" t0=$(date +%s) if [ ! -s $F/observer-datadir.tgz ]; then scp -i $F/in/fleet-internal -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P "$HUB_PORT" "root@$HUB_SSH:/root/fleet/share/observer-datadir.tgz" $F/observer-datadir.tgz || { echo "RESULT datadir_failed pull"; exit 2; } fi echo "RESULT datadir_pulled $(stamp) bytes=$(stat -c %s $F/observer-datadir.tgz) s=$(( $(date +%s) - t0 ))" bash $F/in/box-kill.sh >/dev/null 2>&1 # every stage process; never the node (next line) pkill -x igneumd; sleep 4; pkill -9 -x igneumd 2>/dev/null; sleep 1 rm -rf $F/node.proof && mv $F/node $F/node.proof && mkdir -p $F/node && tar -C $F/node -xzf $F/observer-datadir.tgz || { echo "RESULT datadir_failed untar"; exit 2; } echo "RESULT datadir_swapped $(stamp) $(du -sh $F/node | cut -f1)" IGNEUM_PROOF_VERIFIER=$HOST nohup $B/igneumd --devnet --appdir=$F/node --rpclisten=127.0.0.1:26610 --evm-rpclisten=127.0.0.1:26790 --listen=0.0.0.0:26611 \ --addpeer=$HUB_PEER --addpeer=188.245.5.161:26611 --override-params-file=$F/override.json --nodnsseed --disable-upnp --nologfiles --yes >> $F/node.log 2>&1 & t1=$(date +%s) bn() { curl -s -m 8 -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}' http://127.0.0.1:26790/ | grep -o '"result":"[^"]*"' | cut -d'"' -f4; } for i in $(seq 1 240); do sleep 15 h="$(bn)"; w="$($B/igneum-miner watch 1 grpc://127.0.0.1:26610 2>/dev/null | grep -o 'blocks=[0-9]*.*synced=[a-z]*' | tail -1)" n=$(( ${h:-0x0} )) echo "RESULT replay $(stamp) s=$(( $(date +%s) - t1 )) evm_block=$n $w" if [ "$n" -gt 0 ] && [[ "$w" == *synced=true* ]]; then st="$(curl -s -m 8 -X POST -H 'Content-Type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"igneum_getProvingStatus","params":[]}' http://127.0.0.1:26790/ | python3 -c 'import sys,json; d=json.load(sys.stdin).get("result",{}); print("tipDaa", int(d.get("tipDaa","0x0"),16), "active", d.get("v1",{}).get("active"), "fresh", d.get("v1",{}).get("freshRuleActive"))' 2>/dev/null)" daa=$(printf '%s' "$w" | grep -o 'daa=[0-9]*' | cut -d= -f2) tip=$(printf '%s' "$st" | awk '{print $2}') if [ -n "$tip" ] && [ "$tip" -ge $(( ${daa:-0} - 20 )) ]; then echo "RESULT datadir_done $(stamp) replay_s=$(( $(date +%s) - t1 )) total_s=$(( $(date +%s) - t0 )) $st"; exit 0; fi fi done echo "RESULT datadir_failed replay did not reach the tip in 60 min"