60 lines
5.2 KiB
Bash
Executable file
60 lines
5.2 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# The 0.3.13 node swap for a phase-2 box (6 October 2026, the shipper's two-word procedure).
|
|
# STEP=binary (publish 1): the fixed igneumd (/root/fleet/in/igneumd-0313, sha256 NODE_SHA256) replaces the running
|
|
# node over the observer's full-history datadir (pulled from the hub if not in place), the TEN-field file kept;
|
|
# the digest must read EXPECT_DIGEST (7bd98cc4...); the exec layer stays blocked by design; one status read, done.
|
|
# STEP=file (publish 2): ov13.json becomes the override, the node restarts, the digest must read b18ed271...;
|
|
# then eth_blockNumber is polled every 15 s until it reaches the tip (the replay time).
|
|
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}"
|
|
NODE_SHA256="${NODE_SHA256:?the fixed igneumd sha256}"
|
|
STEP="${STEP:-binary}"
|
|
EXPECT_DIGEST="${EXPECT_DIGEST:-7bd98cc4118616455709d5e32a30b799e6e67caa42d2b5d09875cd49848a7ed7}"
|
|
mkdir -p $OUT; exec >> $OUT/node-swap.log 2>&1
|
|
stamp() { date -u +%Y-%m-%dT%H:%M:%SZ; }
|
|
rpc() { curl -s -m 8 -X POST -H 'Content-Type: application/json' --data "{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"$1\",\"params\":[]}" http://127.0.0.1:26790/; }
|
|
echo "RESULT swap_start $(stamp) step=$STEP"
|
|
echo "$NODE_SHA256 $F/in/igneumd-0313" | sha256sum -c - >/dev/null || { echo "RESULT swap_failed sha256 mismatch: $(sha256sum $F/in/igneumd-0313 | cut -c1-16)"; exit 2; }
|
|
chmod +x $F/in/igneumd-0313
|
|
t0=$(date +%s)
|
|
bash $F/in/box-kill.sh >/dev/null 2>&1 # every stage process; the node is stopped on the next line
|
|
pkill -x igneumd; pkill -f '^/opt/igneum/pkg/bin/igneumd-0313'; sleep 4; pkill -9 -x igneumd 2>/dev/null; pkill -9 -f '^/opt/igneum/pkg/bin/igneumd-0313' 2>/dev/null; sleep 1
|
|
TGZ_SHA=e67cc6493cd86dc0a993c3e1005b1df43b661fc4973ef7f0095f602f1536cd85
|
|
if [ ! -f $F/node/.full-history ]; then
|
|
[ "$(sha256sum $F/observer-datadir.tgz 2>/dev/null | cut -c1-64)" = "$TGZ_SHA" ] || rm -f $F/observer-datadir.tgz # a partial pre-pull is not a tarball
|
|
[ -s $F/observer-datadir.tgz ] || 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 swap_failed pull"; exit 2; }
|
|
[ "$(sha256sum $F/observer-datadir.tgz | cut -c1-64)" = "$TGZ_SHA" ] || { echo "RESULT swap_failed tarball sha256 $(sha256sum $F/observer-datadir.tgz | cut -c1-16)"; exit 2; }
|
|
rm -rf $F/node.proof && mv $F/node $F/node.proof && mkdir -p $F/node && tar -C $F/node -xzf $F/observer-datadir.tgz 2>/dev/null && touch $F/node/.full-history || { echo "RESULT swap_failed untar"; exit 2; }
|
|
echo "RESULT datadir_in_place $(stamp) s=$(( $(date +%s) - t0 )) $(du -sh $F/node | cut -f1)"
|
|
fi
|
|
if [ "$STEP" = file ]; then
|
|
cp $F/override.json $F/override-10.json; cp $F/in/ov13.json $F/override.json
|
|
echo "RESULT override_swapped $(stamp) fields=$(python3 -c 'import json,sys; print(len(json.load(open(sys.argv[1]))))' $F/override.json)"
|
|
fi
|
|
cp $F/in/igneumd-0313 $B/igneumd-0313
|
|
IGNEUM_PROOF_VERIFIER=$HOST nohup $B/igneumd-0313 --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 ${NODE_EXTRA:-} >> $F/node.log 2>&1 &
|
|
t1=$(date +%s); sleep 12
|
|
d="$(grep -o 'digest: [0-9a-f]*' $F/node.log | tail -1 | awk '{print $2}')"
|
|
ok=DIGEST_MISMATCH; [ "$d" = "$EXPECT_DIGEST" ] && ok=digest_ok
|
|
echo "RESULT node_started $(stamp) step=$STEP pid=$(pgrep -f '^/opt/igneum/pkg/bin/igneumd-0313' | head -1) version=$($B/igneumd-0313 --version 2>&1 | head -1) digest=${d:0:16} expected=${EXPECT_DIGEST:0:16} $ok exec_restart=\"$(grep -o 'Exec restart from the override file.*' $F/node.log | tail -1 | cut -c1-120)\""
|
|
[ "$ok" = digest_ok ] || { echo "RESULT swap_failed digest mismatch"; exit 2; }
|
|
watch() { $B/igneum-miner watch 1 grpc://127.0.0.1:26610 2>/dev/null | grep -o 'blocks=[0-9]*.*synced=[a-z]*' | tail -1; }
|
|
if [ "$STEP" = binary ]; then
|
|
sleep 45
|
|
echo "RESULT exec_status $(rpc igneum_getExecStatus | cut -c1-240)"
|
|
echo "RESULT swap_done $(stamp) step=binary $(watch)"; exit 0
|
|
fi
|
|
for i in $(seq 1 240); do
|
|
sleep 15
|
|
h="$(rpc eth_blockNumber | grep -o '"result":"[^"]*"' | cut -d'"' -f4)"; n=$(( ${h:-0x0} )); w="$(watch)"
|
|
echo "RESULT replay $(stamp) s=$(( $(date +%s) - t1 )) evm_block=$n $w"
|
|
if [ "$n" -gt 0 ] && [[ "$w" == *synced=true* ]]; then
|
|
echo "RESULT exec_status $(rpc igneum_getExecStatus | cut -c1-240)"
|
|
st="$(rpc igneum_getProvingStatus | 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 swap_done $(stamp) step=file replay_s=$(( $(date +%s) - t1 )) $st"; exit 0; fi
|
|
fi
|
|
done
|
|
echo "RESULT swap_failed replay did not reach the tip in 60 min"
|