igneum/packaging/hive/h-run.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

86 lines
4.7 KiB
Bash
Executable file

#!/usr/bin/env bash
# Igneum Miner for HiveOS: starts the bundled node when asked, exports the hourly program pack, then one igneum-miner
# per GPU with the matching worker (igneum-worker-cuda on NVIDIA, igneum-worker-opencl on AMD). Each miner mines
# against the node for its own payout address; the software dev fee (1 template in 100) is the miner's default and
# DEV_FEE=0 in the Flight Sheet's extra config turns it off. Per-GPU logs: $CUSTOM_LOG_BASENAME.gpu<N>.log; the main
# log is their merged tail. Run by Hive with the working directory at the miner folder.
cd "$(dirname "$0")" || exit 1
HERE="$(pwd)"
[[ -z "$CUSTOM_LOG_BASENAME" || -z "$CUSTOM_CONFIG_FILENAME" ]] && . "$HERE/h-manifest.conf"
[[ -z "$CUSTOM_LOG_BASENAME" ]] && echo "No CUSTOM_LOG_BASENAME is set" && exit 1
[[ -f "$CUSTOM_CONFIG_FILENAME" ]] || { echo "No config at $CUSTOM_CONFIG_FILENAME (apply the Flight Sheet first)"; exit 1; }
. "$CUSTOM_CONFIG_FILENAME"
BIN="${IGNEUM_BIN:-$HERE/bin}"
mkdir -p "$(dirname "$CUSTOM_LOG_BASENAME")" "$HERE/packs" "$HERE/data"
date +%s > "$CUSTOM_LOG_BASENAME.started"
MAIN="$CUSTOM_LOG_BASENAME.log"
: > "$MAIN"
say() { printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" "$*" | tee -a "$MAIN"; }
echo $$ > "$CUSTOM_LOG_BASENAME.pid"
pids=()
cleanup() { say "stopping"; for p in "${pids[@]}"; do kill "$p" 2>/dev/null; done; pkill -TERM -P $$ 2>/dev/null; sleep 2; for p in "${pids[@]}"; do kill -9 "$p" 2>/dev/null; done; pkill -KILL -P $$ 2>/dev/null; exit 0; }
trap cleanup INT TERM
# 1. the node
if [[ "$NODE_URL" == "local" ]]; then
NODE_URL="grpc://127.0.0.1:26610"
peers=()
if [[ -n "$PEERS" ]]; then IFS=',' read -r -a plist <<< "$PEERS"; for p in "${plist[@]}"; do peers+=("--addpeer=$p"); done
else peers+=("--addpeer=188.245.5.161:26611"); fi # the public devnet seed (app/igneum-app/src/config.rs)
say "starting the bundled node (devnet v4, data $HERE/data, peers ${peers[*]#--addpeer=})"
"$BIN/igneumd" --devnet "--appdir=$HERE/data" --rpclisten=127.0.0.1:26610 --listen=0.0.0.0:26611 "${peers[@]}" \
--nodnsseed --disable-upnp --nologfiles --yes >> "$CUSTOM_LOG_BASENAME.node.log" 2>&1 &
pids+=($!)
fi
say "node $NODE_URL; waiting for it to answer"
for _ in $(seq 1 60); do
"$BIN/igneum-miner" watch 1 "$NODE_URL" >/dev/null 2>&1 && break
sleep 2
done
# 2. the GPUs: Hive's gpu-detect when present, else the driver tools
nv=0; amd=0
if command -v gpu-detect >/dev/null 2>&1; then nv=$(gpu-detect NVIDIA 2>/dev/null || echo 0); amd=$(gpu-detect AMD 2>/dev/null || echo 0)
else
command -v nvidia-smi >/dev/null 2>&1 && nv=$(nvidia-smi -L 2>/dev/null | grep -c '^GPU')
[[ -d /sys/bus/pci/drivers/amdgpu ]] && amd=$(ls /sys/bus/pci/drivers/amdgpu 2>/dev/null | grep -c '^0000:')
fi
nv=${nv:-0}; amd=${amd:-0}
say "GPUs: $nv NVIDIA, $amd AMD (worker setting: $WORKER)"
[[ "$nv" == "0" && "$amd" == "0" ]] && say "no GPU found; nothing to mine with" && sleep 30 && exit 1
# 3. the hourly program pack from the node (the workers read it with --pack; the miner writes the next one to packs/prepare)
export_pack() { rm -rf "$HERE/packs/devnet"; "$BIN/igneum-miner" export-pack "$NODE_URL" "$HERE/packs/devnet" >> "$MAIN" 2>&1; }
export_pack || say "pack export failed; the miners retry"
# 4. one miner per GPU, restarted on exit (exit 42 = the program changed and the worker cannot prepare: re-export the pack)
run_gpu() {
local idx="$1" worker="$2" dev="$3" tag="$4"
local log="$CUSTOM_LOG_BASENAME.gpu$idx.log"
local args=(mine "$NODE_URL" 1 100000000 "$LABEL-gpu$idx" --worker "$BIN/$worker" --worker-args "--device $dev --pack packs/devnet"
--prepare-packs packs/prepare --exit-on-seed-change --evm-address "$WALLET" --payout-label "$LABEL-gpu$idx" --status-secs 30)
[[ "$IDENTITIES" -gt 1 ]] && args+=(--identities "$IDENTITIES")
[[ "$VOTE" == "0" ]] && args+=(--no-vote)
[[ "$DEV_FEE" != "1" ]] && args+=(--dev-fee "$DEV_FEE")
[[ -n "$EXTRA" ]] && args+=($EXTRA)
while :; do
echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) gpu$idx ($tag $dev): igneum-miner ${args[*]}" >> "$log"
"$BIN/igneum-miner" "${args[@]}" >> "$log" 2>&1
rc=$?
if [[ $rc == 42 ]]; then export_pack; else sleep 5; fi
done
}
idx=0
if [[ "$nv" -gt 0 && "$WORKER" != "opencl" ]]; then
for ((d = 0; d < nv; d++)); do run_gpu "$idx" igneum-worker-cuda "$d" nvidia & pids+=($!); idx=$((idx + 1)); done
fi
if [[ "$amd" -gt 0 && "$WORKER" != "cuda" ]]; then
for ((d = 0; d < amd; d++)); do run_gpu "$idx" igneum-worker-opencl "$d" amd & pids+=($!); idx=$((idx + 1)); done
fi
say "$idx miner(s) started; dev fee ${DEV_FEE}% (the miner prints its own dev fee line below)"
# 5. the main log: every GPU's lines, merged
sleep 1
tail -q -n +1 -F "$CUSTOM_LOG_BASENAME".gpu*.log 2>/dev/null | tee -a "$MAIN" &
pids+=($!)
wait