igneum/packaging/hive/selftest.sh
igneum-labs 1028c2579f Miner dev fee: app switch and UI line, HiveOS package, Linux worker cross-build, docs and public text
Decision of 4 October 2026 (evening): the Igneum Miner software takes a visible, switchable 1% dev fee, the norm
for GPU miners; the protocol stays fee-free. The miner side (--dev-fee, the 1-in-100 template counter, the audit
command) is on branch dev-fee of the node fork.

- app: settings.dev_fee (default on) passes --dev-fee 0 to igneum-miner when off; Settings shows the miner's own
  "dev fee 1% (1 block in 100) to 0x..." line next to the rewards address with a switch; the engine parses the
  miner's start line and its dev-fee block lines (fee_session, lifetime fee_total, an event per fee block)
- packaging/hive: h-manifest.conf, h-config.sh, h-run.sh, h-stats.sh, make-hive-package.sh (igneum-hive-<v>.tar.gz
  with the Linux igneumd, igneum-miner and both GPU workers), README with the Flight Sheet, selftest.sh (bash -n,
  stub binaries, the three hooks the way Hive runs them, the stats JSON parsed). Hive itself is untested
- infra/cross/build-workers-linux.sh: the NVRTC and OpenCL workers cross-compiled for Linux with zig;
  proto-opencl/cl_dynamic.h gains the Linux dlopen branch (libOpenCL.so.1)
- tools/dev-fee/run.mjs: the fee-block test network (two nodes on 29900+, three CPU miners, payouts audit)
- docs/design/miner-dev-fee.md (mechanism, flag, lines, the DEV_FEE_ADDRESS placeholder and the devnet address),
  docs/fud-ledger.md E18 and the E5/L9 status line, litepaper "What a miner's hour looks like" paragraph, homepage
  miner section note

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 21:46:41 +00:00

64 lines
5.1 KiB
Bash
Executable file

#!/usr/bin/env bash
# Self-test of the HiveOS package on a machine without Hive (the Mac): bash -n on every script, a package built from
# stub binaries, then the three hooks run the way Hive runs them (h-config.sh sourced with the Flight Sheet variables,
# h-run.sh with fake GPUs and a fake miner that prints the real miner's lines, h-stats.sh sourced and its JSON parsed).
# This proves the scripts' logic and the stats shape, not Hive itself: nothing here talks to a GPU or to Hive's agent.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
T="$(mktemp -d)"
cleanup() {
_pid="$(cat "$T/log/igneum.pid" 2>/dev/null)"; [[ -n "$_pid" ]] && kill -TERM "$_pid" 2>/dev/null; sleep 2
pkill -KILL -f "$T/" 2>/dev/null || true
[[ -n "${KEEP:-}" ]] && echo "kept $T" || rm -rf "$T"
}
trap cleanup EXIT
echo "== bash -n"
for f in "$HERE"/h-*.sh "$HERE"/make-hive-package.sh; do bash -n "$f" && echo " $(basename "$f") ok"; done
echo "== package from stub binaries"
OUT="$T/build" VERSION=0.0.0-test "$HERE/make-hive-package.sh" --fake >/dev/null
tar -tzf "$T/build/igneum-hive-0.0.0-test.tar.gz" | sed 's/^/ /'
mkdir -p "$T/hive/miners/custom" "$T/log"
tar -C "$T/hive/miners/custom" -xzf "$T/build/igneum-hive-0.0.0-test.tar.gz"
M="$T/hive/miners/custom/igneum"
# the fake miner: records its argv, prints the real miner's start and STATUS lines, exits 42 once (the pack path)
cat > "$M/bin/igneum-miner" <<'FAKE'
#!/usr/bin/env bash
case "$1" in
watch) exit 0 ;;
export-pack) mkdir -p "$3"; echo "fake pack in $3"; exit 0 ;;
mine)
echo "$@" >> "$(dirname "$0")/../argv.log"
fee=1; for ((i=1;i<=$#;i++)); do [[ "${!i}" == "--dev-fee" ]] && j=$((i+1)) && fee="${!j}"; done
if [[ "$fee" == "0" ]]; then echo "t dev fee off (--dev-fee 0); the default is 1% (1 block in 100) to 0x1111111111111111111111111111111111111111"
else echo "t dev fee ${fee}% (1 block in 100) to 0x1111111111111111111111111111111111111111; --dev-fee 0 turns it off"; fi
n=0; while :; do n=$((n+1)); echo "t STATUS 'x' [worker]: ${n}0s jobs=$n accepted=$((n*2)) rejected=0 fee=$((n/50)) mismatched=0 extra=0 rate=0.10 blocks/s hash=120.00 MH/s wall (121.00 MH/s inside jobs) now=118.5 MH/s wall (119.0 MH/s inside jobs, 10 jobs, seed walk 0 calls) template_age=0.50s synced=true idle=1.0% (last 10s: 1.0%) queued=2 restarts=0 faults=0 identities=8 accepted_by_identity=1/1"; sleep 1; [[ $n == 2 && ! -f "$(dirname "$0")/../exited42" ]] && touch "$(dirname "$0")/../exited42" && exit 42; done ;;
esac
FAKE
chmod +x "$M/bin/igneum-miner"
mkdir -p "$T/bin"
printf '#!/bin/sh\n[ "$1" = NVIDIA ] && echo 2 || echo 0\n' > "$T/bin/gpu-detect"
cat > "$T/bin/gpu-stats" <<'GS'
#!/bin/sh
echo '{"temp":[61,58],"fan":[55,50],"busids":["01:00.0","02:00.0"]}'
GS
chmod +x "$T/bin/gpu-detect" "$T/bin/gpu-stats"
export PATH="$T/bin:$PATH"
echo "== h-config.sh (sourced, Flight Sheet variables)"
export CUSTOM_URL="local" CUSTOM_TEMPLATE="0xAbCd000000000000000000000000000000000001.rig7" CUSTOM_PASS="" CUSTOM_USER_CONFIG=$'DEV_FEE=0\nIDENTITIES=4' WORKER_NAME=rig7
export CUSTOM_CONFIG_FILENAME="$M/igneum.conf" CUSTOM_LOG_BASENAME="$T/log/igneum"
( . "$M/h-config.sh" ) || { echo "h-config.sh failed"; exit 1; }
grep -q '^WALLET=0xabcd000000000000000000000000000000000001$' "$M/igneum.conf" && grep -q '^DEV_FEE=0$' "$M/igneum.conf" && grep -q '^LABEL=rig7$' "$M/igneum.conf" && grep -q '^IDENTITIES=4$' "$M/igneum.conf" && echo " conf ok: $(tr '\n' ' ' < "$M/igneum.conf" | cut -c1-160)"
( CUSTOM_TEMPLATE="notanaddress" . "$M/h-config.sh" >/dev/null 2>&1 ) && { echo "h-config.sh accepted a bad wallet"; exit 1; } || echo " bad wallet refused ok"
echo "== h-run.sh (fake GPUs: 2 NVIDIA, fake node, fake miner)"
( cd "$M" && CUSTOM_CONFIG_FILENAME="$M/igneum.conf" CUSTOM_LOG_BASENAME="$T/log/igneum" ./h-run.sh > "$T/log/run.out" 2>&1 ) &
disown
sleep 8
ls "$T/log" | sed 's/^/ /'
_lines=$(grep -c "dev fee off (--dev-fee 0)" "$T/log/igneum.log" || true); echo " dev fee lines in the main log: $_lines"; [[ "$_lines" -ge 2 ]] || { echo "FAIL: expected the two miners' dev fee lines in the main log"; cat "$T/log/run.out"; exit 1; }
grep -q -- "--dev-fee 0" "$M/argv.log" && echo " DEV_FEE=0 reached the miner as --dev-fee 0 ok" || { echo "FAIL: --dev-fee 0 missing"; exit 1; }
grep -q -- "--identities 4" "$M/argv.log" && echo " IDENTITIES=4 reached the miner ok" || { echo "FAIL: --identities 4 missing"; exit 1; }
grep -q "igneum-worker-cuda" "$M/argv.log" && echo " NVIDIA cards got the cuda worker ok" || { echo "FAIL: cuda worker missing"; exit 1; }
[[ -f "$M/exited42" && $(grep -c "^mine" "$M/argv.log") -ge 3 ]] && echo " exit 42 restarted the miner and re-exported the pack ok" || { echo "FAIL: no restart after exit 42"; exit 1; }
echo "== h-stats.sh (sourced)"
( . "$M/h-stats.sh"; echo " khs=$khs"; echo " stats=$stats"; python3 -c "import json,sys; s=json.loads(sys.argv[1]); assert s['hs_units']=='khs' and len(s['hs'])==2 and s['ar'][0]>0 and s['algo']=='igneum' and len(s['temp'])==2, s; print(' stats JSON ok: hs', s['hs'], 'temp', s['temp'], 'ar', s['ar'], 'bus', s['bus_numbers'])" "$stats" )
echo "== self-test passed (scripts and stats shape; Hive itself is untested)"