#!/usr/bin/env bash # 空跑验全链:真连交易所读规则/持仓,**不下任何真单**。 # # 上真单之前必须过这一步。它验的是那些"上线才会暴露、且暴露方式是花钱"的 # 环节:密钥能不能用、IP 白名单对不对、时钟同不同步、搬运通不通、 # 数量与价位取整合不合交易所规则。 set -euo pipefail APP=/opt/chan CONF=/etc/chan-live/live.env STATE=/var/lib/chan-live USER_NAME=chan SECS="${SECS:-90}" die() { echo "⛔ $*" >&2; exit 1; } ok() { echo " ✓ $*"; } [[ $EUID -eq 0 ]] || die "要 root:sudo $0" [[ -f "$CONF" ]] || die "缺 $CONF,先跑 install.sh" set -a; . "$CONF"; set +a echo "── 1. 配置自检 ──" for v in BITGET_API_KEY BITGET_API_SECRET BITGET_PASSPHRASE SHIP_FROM; do [[ -n "${!v:-}" ]] || die "$CONF 里 $v 还是空的" done ok "密钥三项与 SHIP_FROM 都已填" [[ "$LIVE_HOME" != /opt/chan* ]] || die "LIVE_HOME 不能指到仓库里(会被 git 清掉)" ok "LIVE_HOME=$LIVE_HOME 在仓库外" echo "── 2. 时钟 ──" # staleness 闸靠两机时钟一致才有意义。这里只能验本机;跨机偏差由 # ship_signals 在收到信号时报「时间倒流」 if command -v chronyc >/dev/null; then chronyc tracking | grep -E "Reference ID|System time|Leap status" | sed 's/^/ /' src="$(chronyc tracking | awk '/Reference ID/{print $NF}')" [[ "$src" != "()" && -n "$src" ]] || die "chrony 还没同步上,等一会再跑" ok "chrony 已同步" else die "没装 chrony。staleness 闸不可信,先 apt install chrony" fi echo "── 3. 出口 IP 是否在白名单内 ──" myip="$(curl -s --max-time 10 https://api.ipify.org || true)" [[ -n "$myip" ]] && echo " 本机出口 IP:$myip" || echo " ⚠ 取不到出口 IP" echo " 对照 Bitget 后台该 key 的 IP 白名单,不一致下面会报 40018 之类" echo "── 4. 能否 ssh 到采集机 ──" if sudo -u "$USER_NAME" ssh -o BatchMode=yes -o ConnectTimeout=10 \ "$SHIP_FROM" 'echo ok' >/dev/null 2>&1; then ok "ssh $SHIP_FROM 通" rb="${SHIP_REMOTE_BUS:-~/chan-live/state/signals_live.jsonl}" n="$(sudo -u "$USER_NAME" ssh -o BatchMode=yes "$SHIP_FROM" \ "wc -l < $rb 2>/dev/null || echo 0")" echo " 对端总线现有 $n 条信号" [[ "$n" -gt 0 ]] || echo " ⚠ 对端总线是空的。采集机接总线了吗?" else die "ssh $SHIP_FROM 不通。装 key: sudo -u $USER_NAME ssh-keygen -t ed25519 -N '' -f $STATE/home/.ssh/id_ed25519 再把 $STATE/home/.ssh/id_ed25519.pub 加到采集机的 authorized_keys" fi echo "── 5. 执行器空跑 ${SECS}s(真连交易所,不下单)──" # --dry-run 下 Bitget 客户端只读不写:合约规则、持仓、费率照查, # 下单一律只打印。所以这一步会真实验到密钥与白名单 # 让 chan 自己 source 配置($CONF 是 640 root:chan,它读得到)。 # 不用 `env "$(grep ...)"` 那种拼法:值里有空格就会被切开 set +e sudo -u "$USER_NAME" bash -c \ "set -a; . '$CONF'; set +a; exec timeout $SECS \ '$APP/.venv/bin/python' '$APP/live/live_exec.py' --dry-run" rc=$? set -e # timeout 到点是 124,属于预期 [[ $rc -eq 124 || $rc -eq 0 ]] || die "空跑退出码 $rc,看上面报错" ok "空跑没有报错退出" echo echo "空跑过了。真跑:" echo " sudo systemctl enable --now chan-live-ship chan-live-exec" echo " $APP/live/deploy/status.sh"