publish-manifest.sh: the activation height check as a function with --self-test-height (the known-bad case 33000 against 201776, at the DAA, pending, unknown), the shape the shipper's 0.3.15 guard had; the public /api/live stays the source

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit e54a87bc44)
This commit is contained in:
igneum-labs 2026-10-06 20:29:45 +00:00
parent 39b8df93cd
commit c1e3204481

View file

@ -8,6 +8,7 @@
# [--win packaging/windows/dist/Igneum-Miner-Setup-0.3.1.exe] --notes "one line of what changed" \
# [--activation-height 120000 --deadline-note "difficulty v2"] [--min-supported 0.3.0] [--channel devnet] [--deploy]
# [--allow-passed-activation] (Horizon polish Q4: an activation height at or below the live DAA is refused otherwise)
# --self-test-height proves the height check on known values (33000 against 201776 refused; 300000 passes) and exits
# [--override '{"difficulty_v2_activation_daa":33000,"proving_v0_activation_daa":120000}']
# consensus.override: the exact object every app writes to its override.json (the node's
# --override-params-file), so it carries EVERY height switch, not just the new one;
@ -40,26 +41,6 @@ TOKEN_FILE="$HOME/.config/igneum/dl-token"
SIGNER="$ROOT/app/igneum-app/target/release/igneum-ota-sign"
VERSION="" MAC="" WIN="" NOTES="" ACTIVATION="" DEADLINE="" MIN_SUPPORTED="" CHANNEL="devnet" BASE="" DEST="" DEPLOY=0 VERIFY_ONLY=0 TRIES=12
# An activation height at or below the live DAA makes every app treat the update as urgent (manifest::fork_is_close counts
# any height already passed as "close"), which skips the slot, the patience and the busy rule; PC 1 took an install under a
# running job on 6 October 2026 on that path. The live DAA comes from the observer's exec status (igneum_getExecStatus,
# executedTipDaa) at 127.0.0.1:26790; a height at or below it is refused. IGNEUM_MANIFEST_ALLOW_PAST_HEIGHT=1 overrides for a
# deliberate replay. `--self-test-height` exercises the rule on a known-bad and a known-good value against DAA 1000.
height_rule() { # <height> <live daa> -> 0 ok, 1 refused
local h="$1" daa="$2"
[ -z "$h" ] && return 0
[[ "$h" =~ ^[0-9]+$ ]] || { echo "activation height $h is not a number" >&2; return 1; }
if [ "$h" -le "$daa" ]; then echo "activation height $h is at or below the live DAA $daa: every app would treat the update as urgent (fork_is_close); refused (IGNEUM_MANIFEST_ALLOW_PAST_HEIGHT=1 overrides a deliberate replay)" >&2; return 1; fi
return 0
}
if [ "${1:-}" = "--self-test-height" ]; then
height_rule 900 1000 2>/dev/null && { echo "self-test failed: a passed height was accepted"; exit 1; }
height_rule 1000 1000 2>/dev/null && { echo "self-test failed: the live height was accepted"; exit 1; }
height_rule 1001 1000 || { echo "self-test failed: a future height was refused"; exit 1; }
height_rule "" 1000 || { echo "self-test failed: no height was refused"; exit 1; }
echo "self-test passed: a height at or below the live DAA is refused, a future one and none pass"; exit 0
fi
OVERRIDE="" TUNING_FILE="" NO_TUNING=0 PUBLIC=0
while [ $# -gt 0 ]; do
case "$1" in
@ -69,6 +50,7 @@ while [ $# -gt 0 ]; do
--notes) NOTES="$2"; shift 2 ;;
--activation-height) ACTIVATION="$2"; shift 2 ;;
--allow-passed-activation) ALLOW_PASSED=1; shift ;;
--self-test-height) SELF_TEST_HEIGHT=1; shift ;;
--deadline-note) DEADLINE="$2"; shift 2 ;;
--override) OVERRIDE="$2"; shift 2 ;; # consensus.override: the exact JSON object every app writes to its override.json (all height switches, not just the new one)
--min-supported) MIN_SUPPORTED="$2"; shift 2 ;;
@ -85,12 +67,23 @@ while [ $# -gt 0 ]; do
*) echo "unknown argument: $1" >&2; exit 2 ;;
esac
done
if [ -n "$ACTIVATION" ] && [ "${IGNEUM_MANIFEST_ALLOW_PAST_HEIGHT:-0}" != "1" ]; then
LIVE_DAA="$(curl -s -m 5 -X POST -H 'content-type: application/json' --data '{"jsonrpc":"2.0","id":1,"method":"igneum_getExecStatus","params":[]}' http://127.0.0.1:26790 2>/dev/null | python3 -c 'import json,sys; print(int(json.load(sys.stdin)["result"]["executedTipDaa"],16))' 2>/dev/null || true)"
[ -n "$LIVE_DAA" ] || { echo "cannot read the live DAA from the observer (127.0.0.1:26790) to check --activation-height $ACTIVATION; start it or set IGNEUM_MANIFEST_ALLOW_PAST_HEIGHT=1 knowingly" >&2; exit 1; }
height_rule "$ACTIVATION" "$LIVE_DAA" || exit 1
echo "activation height $ACTIVATION is above the live DAA $LIVE_DAA ($((ACTIVATION - LIVE_DAA)) ahead)"
# Horizon polish Q4 (6 October 2026): has an activation height passed? 0 = pending (above the DAA), 1 = passed (at or
# below it), 2 = unknown (no DAA). A passed activation made every app since the 0.3.14 manifest read the fork as
# close ("0 blocks away, installing now", every safe-moment guard skipped).
activation_passed() { # <height> <live daa>
local h="$1" daa="$2"
[ "${daa:-0}" -gt 0 ] || return 2
[ "$h" -le "$daa" ] && return 1 || return 0
}
if [ "${SELF_TEST_HEIGHT:-0}" = 1 ]; then
# (set -e: a non-zero return is captured with `|| v=$?`, never left bare)
fail=0; v=0
v=0; activation_passed 33000 201776 || v=$?; [ "$v" -eq 1 ] || { echo "self-test: 33000 against 201776 should read as passed (got $v)" >&2; fail=1; }
v=0; activation_passed 201776 201776 || v=$?; [ "$v" -eq 1 ] || { echo "self-test: a height at the DAA should read as passed (got $v)" >&2; fail=1; }
v=0; activation_passed 300000 201776 || v=$?; [ "$v" -eq 0 ] || { echo "self-test: 300000 against 201776 should read as pending (got $v)" >&2; fail=1; }
v=0; activation_passed 300000 0 || v=$?; [ "$v" -eq 2 ] || { echo "self-test: no DAA should read as unknown (got $v)" >&2; fail=1; }
[ $fail -eq 0 ] && echo "self-test: the activation height check holds (passed, at the DAA, pending, unknown)"
exit $fail
fi
[ -n "$VERSION" ] || [ "$VERIFY_ONLY" = 1 ] || { echo "--version is required" >&2; exit 2; }
[ -n "$VERSION" ] || VERSION="(the folder's)"
@ -208,14 +201,15 @@ NEW="$DEST/igneum-app-latest.json.new"
# below it is refused unless --allow-passed-activation says so.
if [ -n "$ACTIVATION" ]; then
LIVE_DAA="$(curl -fsS --max-time 10 "${IGNEUM_LIVE_API:-https://igneum.network/api/live}" 2>/dev/null | python3 -c 'import json,sys; print(int((json.load(sys.stdin).get("state") or {}).get("daa") or 0))' 2>/dev/null || echo 0)"
if [ "${LIVE_DAA:-0}" -gt 0 ] && [ "$ACTIVATION" -le "$LIVE_DAA" ]; then
verdict=0; activation_passed "$ACTIVATION" "${LIVE_DAA:-0}" || verdict=$?
if [ "$verdict" -eq 1 ]; then
if [ "${ALLOW_PASSED:-0}" = 1 ]; then
echo "activation height $ACTIVATION is at or below the live DAA $LIVE_DAA (passed); published anyway on --allow-passed-activation" >&2
else
echo "refused: activation height $ACTIVATION is at or below the live DAA $LIVE_DAA, so it has passed; a passed activation makes every app read the fork as close (0.3.14 manifest). Drop --activation-height or pass --allow-passed-activation" >&2
exit 2
fi
elif [ "${LIVE_DAA:-0}" -eq 0 ]; then
elif [ "$verdict" -eq 2 ]; then
echo "note: the live DAA could not be read from /api/live; the activation height $ACTIVATION is not checked against it" >&2
fi
fi