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>
86 lines
4.7 KiB
Bash
Executable file
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
|