#!/bin/sh
# Mine Pearl (PRL) on AlphaPool with alpha-miner, and merge-mine NACRE (NACR)
# with the same work when you give a NACR address. Downloads the latest
# alpha-miner release from GitHub, checks its sha256, and starts on every GPU
# with enough free memory.
#
#   PRL=prl1p... sh pearl-mine.sh                    Pearl only
#   PRL=prl1p... NACR=nacr1p... sh pearl-mine.sh     Pearl + NACRE
#   WORKER=rig1    name this machine on the pool page (default: hostname)
#   CHECK=1        download, verify and print the command, do not mine
#   POOL=...       another AlphaPool endpoint (default us2, port 5566)
#   PASSWORD=...   x for variable difficulty (default), x;d=N for a fixed one
#
# From https://paraloncloud.com/resources/merge-mine-pearl-nacre-alphapool-rented-gpu
set -eu

PRL="${PRL:-}"
NACR="${NACR:-}"
POOL="${POOL:-stratum+tcp://us2.alphapool.tech:5566}"
PASSWORD="${PASSWORD:-x}"
WORKER="${WORKER:-$(hostname | tr -c 'A-Za-z0-9_-' '-' | sed 's/-*$//')}"
DIR="${DIR:-$HOME/alpha-miner}"
# alpha-miner refuses to start below 8 GiB of free memory on some cards.
MIN_FREE_MIB="${MIN_FREE_MIB:-8192}"

case "$PRL" in
  prl1p*) ;;
  *) echo "set PRL to your Pearl address (prl1p...): PRL=prl1p... sh pearl-mine.sh" >&2; exit 1 ;;
esac
case "$NACR" in
  ""|nacr1p*) ;;
  *) echo "NACR must be a mainnet address starting with nacr1p; the pool credits nothing else" >&2; exit 1 ;;
esac

# The GPUs with enough free memory. An 8 GB card never has 8 GiB free.
DEVICES=$(nvidia-smi --query-gpu=index,memory.free --format=csv,noheader,nounits \
  | awk -F', *' -v min="$MIN_FREE_MIB" '$2 >= min { printf "%s%s", sep, $1; sep="," }')
if [ -z "$DEVICES" ]; then
  echo "no GPU here has ${MIN_FREE_MIB} MiB free; alpha-miner needs a card with 12 GB or more" >&2
  nvidia-smi --query-gpu=index,name,memory.total,memory.free --format=csv >&2
  exit 1
fi

mkdir -p "$DIR"
cd "$DIR"

# The newest release, its Linux binary (the asset with no extension) and the
# sha256 GitHub records for it.
RELEASE=$(curl -fsSL https://api.github.com/repos/alphaminetech/alpha-miner/releases/latest) || {
  echo "could not reach GitHub for the latest alpha-miner release" >&2
  exit 1
}
ASSET=$(printf '%s' "$RELEASE" | python3 -c '
import json, re, sys
for a in json.load(sys.stdin)["assets"]:
    if re.fullmatch(r"alpha-miner-[0-9.]+", a["name"]):
        print(a["name"], a["browser_download_url"], (a.get("digest") or "").removeprefix("sha256:"))
        break
')
if [ -z "$ASSET" ]; then
  echo "could not find the latest alpha-miner Linux binary on GitHub" >&2
  exit 1
fi
set -- $ASSET
BIN=$1 URL=$2 WANT=${3:-}

if [ ! -f "$BIN" ]; then
  echo "downloading $BIN"
  curl -fL --retry 3 -o "$BIN.part" "$URL"
  mv "$BIN.part" "$BIN"
fi
if [ -n "$WANT" ]; then
  GOT=$(sha256sum "$BIN" | cut -d' ' -f1)
  if [ "$WANT" != "$GOT" ]; then
    echo "checksum mismatch for $BIN (want $WANT, got $GOT)" >&2
    rm -f "$BIN"
    exit 1
  fi
  echo "checksum ok"
else
  echo "no checksum published for this release, continuing without the check"
fi
chmod +x "$BIN"

ADDRESS="$PRL"
[ -n "$NACR" ] && ADDRESS="$PRL+$NACR"
if [ -n "$NACR" ]; then
  echo "mining PRL to $PRL and NACR to $NACR as $WORKER on GPUs $DEVICES"
else
  echo "mining PRL to $PRL as $WORKER on GPUs $DEVICES (add NACR=nacr1p... to merge-mine NACRE)"
fi

if [ -n "${CHECK:-}" ]; then
  echo "./$BIN --pool $POOL --address $ADDRESS --worker $WORKER --password '$PASSWORD' --devices $DEVICES"
  exit 0
fi
exec "./$BIN" --pool "$POOL" --address "$ADDRESS" --worker "$WORKER" --password "$PASSWORD" --devices "$DEVICES"
