Skip to content

Commit dde2afb

Browse files
auricomclaude
andcommitted
docs(ha): fix passphrase flag and failover kill cardinality check
Replace non-existent --evnode.signer.passphrase with the actual --evnode.signer.passphrase_file flag throughout cluster-setup and single-to-ha guides. Update passphrase setup to create a chmod 600 file at /etc/ev-node/passphrase referenced directly by the flag. Add mapfile-based cardinality check in the failover test fallback kill command to guard against killing the wrong process. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 516b533 commit dde2afb

2 files changed

Lines changed: 37 additions & 27 deletions

File tree

docs/guides/ha/cluster-setup.md

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,12 +72,22 @@ Do this for every node pair in both directions. If any check fails, fix your fir
7272

7373
Run this on every node. Each node gets its own home directory where the config, keys, and data live.
7474

75+
First, create a passphrase file that only root and the service account can read. This file is referenced by the binary at runtime — the passphrase never appears in process listings or logs.
76+
7577
```bash
76-
# Run on every node (the binary name depends on your chain)
77-
./evm init --evnode.node.aggregator=true --evnode.signer.passphrase "$EV_SIGNER_PASSPHRASE"
78+
# Run on every node
79+
sudo mkdir -p /etc/ev-node
80+
echo -n "<YOUR_PASSPHRASE>" | sudo tee /etc/ev-node/passphrase > /dev/null
81+
sudo chmod 600 /etc/ev-node/passphrase
82+
sudo chown ev-node:ev-node /etc/ev-node/passphrase
7883
```
7984

80-
> Set `EV_SIGNER_PASSPHRASE` in your shell session before running this command so the passphrase does not appear in `ps aux` or your shell history. The [EnvironmentFile setup](#running-as-a-systemd-service) later in this guide shows how to store it securely.
85+
Then initialize the node:
86+
87+
```bash
88+
# Run on every node (the binary name depends on your chain)
89+
./evm init --evnode.node.aggregator=true --evnode.signer.passphrase_file /etc/ev-node/passphrase
90+
```
8191

8292
This creates the home directory structure (default `~/.evm`) with a `config/evnode.yaml` file and generates the signer key.
8393

@@ -207,9 +217,6 @@ Raft requires a majority of configured peers to be online before it can elect a
207217
Start all five nodes as close together as possible. The order does not matter but they should all be up within a few seconds of each other.
208218

209219
```bash
210-
# Load the passphrase from the secure env file (avoids it appearing in ps aux)
211-
source /etc/ev-node/env
212-
213220
# Run this on each node, substituting the correct binary name and flags for your chain
214221
./evm start \
215222
--evnode.node.aggregator=true \
@@ -226,7 +233,7 @@ source /etc/ev-node/env
226233
--evnode.raft.snapshot_threshold=5000 \
227234
--evnode.p2p.listen_address="/ip4/0.0.0.0/tcp/26656" \
228235
--evnode.p2p.peers="/ip4/10.0.0.2/tcp/26656/p2p/<PEER_ID_NODE_2>,/ip4/10.0.0.3/tcp/26656/p2p/<PEER_ID_NODE_3>,/ip4/10.0.0.4/tcp/26656/p2p/<PEER_ID_NODE_4>,/ip4/10.0.0.5/tcp/26656/p2p/<PEER_ID_NODE_5>" \
229-
--evnode.signer.passphrase="$EV_SIGNER_PASSPHRASE" \
236+
--evnode.signer.passphrase_file=/etc/ev-node/passphrase \
230237
--evm.jwt-secret=$(cat /path/to/jwt.hex) \
231238
--evm.genesis-hash=<YOUR_GENESIS_HASH>
232239
```
@@ -287,10 +294,14 @@ With all five nodes running and producing blocks, simulate a leader failure:
287294
# Preferred: use the systemd unit if ev-node runs as a service
288295
sudo systemctl stop ev-node
289296
290-
# Fallback: stop the process directly (verify exactly one PID before killing)
291-
PID=$(pgrep -f "evm start")
292-
echo "Stopping PID $PID"
293-
kill -SIGTERM "$PID"
297+
# Fallback: stop the process directly
298+
mapfile -t PIDS < <(pgrep -f "evm start")
299+
if [ "${#PIDS[@]}" -ne 1 ]; then
300+
echo "Expected exactly 1 evm PID, found ${#PIDS[@]}: ${PIDS[*]}"
301+
exit 1
302+
fi
303+
echo "Stopping PID ${PIDS[0]}"
304+
kill -SIGTERM "${PIDS[0]}"
294305
```
295306

296307
Within `election_timeout` (368ms in this configuration), the remaining four nodes will elect a new leader and resume block production. Measure the actual gap in your logs:
@@ -308,16 +319,16 @@ The gap should be well under 1 second in most cases (a few election cycles at mo
308319

309320
For production, manage each node with systemd.
310321

311-
### Create the environment file
322+
### Create the passphrase file
312323

313-
Store secrets in a file that only the service user can read. systemd loads it at start time, so the passphrase never appears in `ps aux`, `journalctl`, or the unit file itself.
324+
If you did not create the passphrase file in Step 3, do it now. The file must exist on every node before the service starts:
314325

315326
```bash
316-
# Run on every node
327+
# Run on every node (skip if you already did this in Step 3)
317328
sudo mkdir -p /etc/ev-node
318-
echo "EV_SIGNER_PASSPHRASE=<YOUR_PASSPHRASE>" | sudo tee /etc/ev-node/env > /dev/null
319-
sudo chmod 600 /etc/ev-node/env
320-
sudo chown ev-node:ev-node /etc/ev-node/env
329+
echo -n "<YOUR_PASSPHRASE>" | sudo tee /etc/ev-node/passphrase > /dev/null
330+
sudo chmod 600 /etc/ev-node/passphrase
331+
sudo chown ev-node:ev-node /etc/ev-node/passphrase
321332
```
322333

323334
### Unit file
@@ -331,7 +342,6 @@ Wants=network-online.target
331342
332343
[Service]
333344
User=ev-node
334-
EnvironmentFile=/etc/ev-node/env
335345
ExecStart=/usr/local/bin/evm start \
336346
--evnode.node.aggregator=true \
337347
--evnode.raft.enable=true \
@@ -347,7 +357,7 @@ ExecStart=/usr/local/bin/evm start \
347357
--evnode.raft.snapshot_threshold=5000 \
348358
--evnode.p2p.listen_address=/ip4/0.0.0.0/tcp/26656 \
349359
--evnode.p2p.peers=/ip4/10.0.0.2/tcp/26656/p2p/<PEER_ID_NODE_2>,/ip4/10.0.0.3/tcp/26656/p2p/<PEER_ID_NODE_3>,/ip4/10.0.0.4/tcp/26656/p2p/<PEER_ID_NODE_4>,/ip4/10.0.0.5/tcp/26656/p2p/<PEER_ID_NODE_5> \
350-
--evnode.signer.passphrase=$EV_SIGNER_PASSPHRASE
360+
--evnode.signer.passphrase_file=/etc/ev-node/passphrase
351361
Restart=on-failure
352362
RestartSec=5s
353363

docs/guides/ha/single-to-ha.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -215,13 +215,18 @@ p2p:
215215

216216
---
217217

218-
## Step 8: Create Raft Data Directories
218+
## Step 8: Create Raft Data Directories and Passphrase File
219219

220220
Run on every node:
221221

222222
```bash
223223
sudo mkdir -p /var/lib/ev-node/raft
224224
sudo chown $(whoami) /var/lib/ev-node/raft
225+
226+
# Create the passphrase file — the binary reads this at startup
227+
sudo mkdir -p /etc/ev-node
228+
echo -n "<YOUR_PASSPHRASE>" | sudo tee /etc/ev-node/passphrase > /dev/null
229+
sudo chmod 600 /etc/ev-node/passphrase
225230
```
226231

227232
---
@@ -250,10 +255,6 @@ The key requirement here is that all nodes must start within a short window of e
250255
Use a coordination mechanism — a simple approach is to open five terminals (or tmux panes) and fire the start commands in quick succession:
251256

252257
```bash
253-
# Load the passphrase from the secure env file (avoids it appearing in ps aux)
254-
# See the cluster-setup guide for how to create /etc/ev-node/env with chmod 600
255-
source /etc/ev-node/env
256-
257258
# On node-1
258259
./evm start \
259260
--evnode.node.aggregator=true \
@@ -270,7 +271,7 @@ source /etc/ev-node/env
270271
--evnode.raft.snapshot_threshold=5000 \
271272
--evnode.p2p.listen_address="/ip4/0.0.0.0/tcp/26656" \
272273
--evnode.p2p.peers="/ip4/10.0.0.2/tcp/26656/p2p/<PEER_ID_NODE_2>,/ip4/10.0.0.3/tcp/26656/p2p/<PEER_ID_NODE_3>,/ip4/10.0.0.4/tcp/26656/p2p/<PEER_ID_NODE_4>,/ip4/10.0.0.5/tcp/26656/p2p/<PEER_ID_NODE_5>" \
273-
--evnode.signer.passphrase="$EV_SIGNER_PASSPHRASE" \
274+
--evnode.signer.passphrase_file=/etc/ev-node/passphrase \
274275
--evm.jwt-secret=$(cat /path/to/jwt.hex) \
275276
--evm.genesis-hash=<YOUR_GENESIS_HASH>
276277
```
@@ -354,11 +355,10 @@ If anything goes wrong during the cutover, you can revert to the single sequence
354355

355356
```bash
356357
# Emergency rollback — revert node-1 to single sequencer
357-
source /etc/ev-node/env
358358
./evm start \
359359
--evnode.node.aggregator=true \
360360
--evnode.raft.enable=false \
361-
--evnode.signer.passphrase="$EV_SIGNER_PASSPHRASE" \
361+
--evnode.signer.passphrase_file=/etc/ev-node/passphrase \
362362
# ... your original flags
363363
```
364364

0 commit comments

Comments
 (0)