igneum/tools/ca3-v4/g2-recheck.sh

45 lines
3.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# Counter ASIC 3.0 gate G2, the Mac re-check (6 October 2026). Derives the found-lines file a serve-mode G2 job writes
# (g2-<pack>.found: "found g2 <nonce> <hash>" for nonces 0..1023 at prehash 00..01, LF, nonce order) from the Rust
# verifier on the same pack, and compares by sha256 digest. A digest match is 1,024 of 1,024 with no file moved; on a
# mismatch, or when a found file is given, the lines are compared one by one and the differing nonces printed.
# tools/ca3-v4/g2-recheck.sh <pack dir> [--digest <sha256 from the job's RESULT g2 line>] [--file <g2-<pack>.found>]
# The pack's seeds come from its program.h (IGNEUM_SEED_BYTES_HEX, IGNEUM_DAY_BYTES_HEX, IGNEUM_ERA_SEED_HEX) and its class
# from IGNEUM_LOAD_CLASS ("<base>-era<label>+sh<S>x<R>" is run as --class <base>+sh<S>x<R> --era 0:<era hex>;
# "<base>-era<label>" as --program-class v3 --era-hex <era hex>; a class without an era as --class <class>).
# Exit 0 on a match, 1 on a mismatch, 2 on a usage or build error. Runs igneum-pow from the tree this script sits in.
set -u
here=$(cd "$(dirname "$0")/../.." && pwd)
POW=${IGNEUM_POW:-$here/igneum-pow/target/release/igneum-pow}
PRE=0000000000000000000000000000000000000000000000000000000000000001
pack=${1:-}; shift || true
[ -d "$pack" ] || { echo "usage: g2-recheck.sh <pack dir> [--digest <hex>] [--file <found file>]" >&2; exit 2; }
digest=""; file=""
while [ $# -gt 0 ]; do case "$1" in --digest) digest=$2; shift 2 ;; --file) file=$2; shift 2 ;; *) echo "unknown $1" >&2; exit 2 ;; esac; done
[ -x "$POW" ] || { echo "no igneum-pow at $POW (cargo build --release in igneum-pow)" >&2; exit 2; }
ph=$pack/program.h
epoch=$(sed -n 's/^#define IGNEUM_SEED_BYTES_HEX "\(.*\)"/\1/p' "$ph"); day=$(sed -n 's/^#define IGNEUM_DAY_BYTES_HEX "\(.*\)"/\1/p' "$ph")
era=$(sed -n 's/^#define IGNEUM_ERA_SEED_HEX "\(.*\)"/\1/p' "$ph"); cls=$(sed -n 's/^#define IGNEUM_LOAD_CLASS "\(.*\)"/\1/p' "$ph")
base=${cls%%-era*}; sh=""; case "$cls" in *+sh*) sh="+sh${cls##*+sh}" ;; esac
if [ -n "$era" ] && [ -n "$sh" ]; then args="--class $base$sh --era 0:$era"
elif [ -n "$era" ]; then args="--program-class v3 --era-hex $era"
else args="--class $cls"; fi
tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
"$POW" hash-bound --prehash $PRE --nonce 0 --count 1024 --epoch-hex "$epoch" --day-hex "$day" $args 2>/dev/null | awk '{printf "found g2 %s %s\n", $1, $2}' > "$tmp/expected.found"
n=$(wc -l < "$tmp/expected.found" | tr -d ' ')
[ "$n" = 1024 ] || { echo "verifier gave $n lines, not 1024 (class $cls, args $args)" >&2; exit 2; }
exp=$(shasum -a 256 "$tmp/expected.found" | cut -c1-64)
echo "RECHECK pack $(basename "$pack") class $cls verifier sha256 $exp (1,024 lines, $args)"
rc=0
if [ -n "$digest" ]; then
if [ "$digest" = "$exp" ]; then echo "RECHECK digest MATCH: 1,024 of 1,024 (the job's file equals the verifier's)"; else echo "RECHECK digest MISMATCH: job $digest, verifier $exp (collect the found file and run with --file)"; rc=1; fi
fi
if [ -n "$file" ]; then
cp "$file" "$tmp/job.found" || exit 2 # one copy, read twice below (a pipe or /dev/fd input reads once)
file=$tmp/job.found
got=$(shasum -a 256 "$file" | cut -c1-64)
eq=$(awk 'NR==FNR { e[$3]=$4; next } /^found g2 / { if (e[$3]==$4) c++ } END { print c+0 }' "$tmp/expected.found" "$file")
tot=$(grep -c '^found g2 ' "$file")
if [ "$got" = "$exp" ]; then echo "RECHECK file $file sha256 $got MATCH: $eq of $tot equal, 1,024 of 1,024"; else echo "RECHECK file $file sha256 $got differs from the verifier's: $eq of $tot lines equal"; awk 'NR==FNR { e[$3]=$4; next } /^found g2 / && e[$3]!=$4 { printf " nonce %s: job %s verifier %s\n", $3, $4, e[$3] }' "$tmp/expected.found" "$file" | head -20; rc=1; fi
fi
exit $rc