-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathentrypoint.sh
More file actions
120 lines (103 loc) · 4.83 KB
/
entrypoint.sh
File metadata and controls
120 lines (103 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/bin/bash
# ============================================================================
# Handshake58 Subnet 58 - Neuron Entrypoint
#
# Decodes Bittensor wallet files from base64 env vars and starts the neuron.
# Supports both validator and miner modes via NEURON_TYPE env var.
#
# NEURON_TYPE=validator (default) → neurons/validator.py
# NEURON_TYPE=miner → neurons/miner.py
# Miner is a Neutral Monitor — no Polygon wallet needed
# ============================================================================
NEURON_TYPE="${NEURON_TYPE:-validator}"
WALLET_NAME="${WALLET_NAME:-hs58}"
HOTKEY_NAME="${HOTKEY_NAME:-validator}"
WALLET_DIR="$HOME/.bittensor/wallets/${WALLET_NAME}"
echo "[entrypoint] Neuron type: ${NEURON_TYPE}"
echo "[entrypoint] Setting up wallet: ${WALLET_NAME} / ${HOTKEY_NAME}"
# Create wallet directory structure
mkdir -p "${WALLET_DIR}/hotkeys"
# Check if wallet keys are configured
if [ -z "$BT_HOTKEY_B64" ] || [ -z "$BT_COLDKEYPUB_B64" ]; then
echo "[entrypoint] ================================================"
echo "[entrypoint] Wallet keys not configured yet."
echo "[entrypoint] Set these env vars and redeploy:"
echo "[entrypoint] BT_HOTKEY_B64 (required)"
echo "[entrypoint] BT_COLDKEYPUB_B64 (required)"
echo "[entrypoint] BT_COLDKEY_B64 (optional - only for staking/transfer from this wallet)"
echo "[entrypoint] ================================================"
echo "[entrypoint] Waiting for configuration... (sleeping)"
# Sleep forever so Railway doesn't restart-loop
while true; do sleep 3600; done
fi
# Decode hotkey
echo "$BT_HOTKEY_B64" | base64 -d > "${WALLET_DIR}/hotkeys/${HOTKEY_NAME}"
echo "[entrypoint] Hotkey written to ${WALLET_DIR}/hotkeys/${HOTKEY_NAME}"
# Decode coldkey public (write both formats for bittensor compatibility)
echo "$BT_COLDKEYPUB_B64" | base64 -d > "${WALLET_DIR}/coldkeypub"
cp "${WALLET_DIR}/coldkeypub" "${WALLET_DIR}/coldkeypub.txt"
echo "[entrypoint] Coldkeypub written (coldkeypub + coldkeypub.txt)"
# Decode coldkey (optional: set_weights is signed by hotkey; coldkey only needed for staking/transfer from this wallet)
if [ -z "$BT_COLDKEY_B64" ]; then
echo "[entrypoint] BT_COLDKEY_B64 not set (optional - validator only needs hotkey + coldkeypub for set_weights)"
else
echo "$BT_COLDKEY_B64" | base64 -d > "${WALLET_DIR}/coldkey"
echo "[entrypoint] Coldkey written"
fi
echo "[entrypoint] Wallet setup complete."
# Auto-restart loop: restarts the neuron on crash with backoff (max 120s)
MAX_RESTART_DELAY=120
restart_delay=5
run_neuron() {
if [ "$NEURON_TYPE" = "miner" ]; then
AXON_PORT="${AXON_PORT:-8091}"
echo "[entrypoint] Starting MINER (Neutral Monitor, port=${AXON_PORT})..."
MINER_ARGS="--netuid 58 --wallet.name $WALLET_NAME --wallet.hotkey $HOTKEY_NAME --axon.port $AXON_PORT --logging.debug"
# If external host is set, resolve domain to IP (Bittensor only accepts IP addresses)
if [ -n "$AXON_EXTERNAL_IP" ]; then
if echo "$AXON_EXTERNAL_IP" | grep -qP '^\d+\.\d+\.\d+\.\d+$'; then
RESOLVED_IP="$AXON_EXTERNAL_IP"
else
echo "[entrypoint] Resolving ${AXON_EXTERNAL_IP} to IP..."
RESOLVED_IP=$(python3 -c "import socket; print(socket.getaddrinfo('${AXON_EXTERNAL_IP}', None, socket.AF_INET)[0][4][0])")
echo "[entrypoint] Resolved to ${RESOLVED_IP}"
fi
MINER_ARGS="$MINER_ARGS --axon.external_ip $RESOLVED_IP"
fi
if [ -n "$AXON_EXTERNAL_PORT" ]; then
MINER_ARGS="$MINER_ARGS --axon.external_port $AXON_EXTERNAL_PORT"
else
MINER_ARGS="$MINER_ARGS --axon.external_port $AXON_PORT"
fi
python neurons/miner.py $MINER_ARGS "$@"
else
echo "[entrypoint] Starting VALIDATOR (axon disabled - validators don't need incoming connections)..."
python neurons/validator.py \
--netuid 58 \
--wallet.name "$WALLET_NAME" \
--wallet.hotkey "$HOTKEY_NAME" \
--neuron.axon_off \
--logging.debug \
"$@"
fi
}
# Restart loop with exponential backoff
while true; do
run_neuron "$@"
exit_code=$?
if [ $exit_code -eq 42 ]; then
echo "[entrypoint] Auto-update triggered (exit code 42). Pulling latest code..."
git pull origin "${AUTOUPDATE_BRANCH:-main}" --ff-only
pip install -e . --quiet
echo "[entrypoint] Update complete. Restarting immediately..."
restart_delay=5
continue
fi
echo "[entrypoint] Neuron exited with code ${exit_code}. Restarting in ${restart_delay}s..."
sleep $restart_delay
# Exponential backoff, capped at MAX_RESTART_DELAY
restart_delay=$((restart_delay * 2))
if [ $restart_delay -gt $MAX_RESTART_DELAY ]; then
restart_delay=$MAX_RESTART_DELAY
fi
done