Run a Stake Pool Part II — Configure Guided mode

Part II — Configure

Folders, the chain, topology, the offline machine, the service.

  1. Start hereThe picture, the dangers, how BRIAN runs it4 steps
  2. IInstallMachines, a hardened Ubuntu, the node5 steps
  3. IIConfigureChain, topology, offline machine, service5 steps
  4. IIIRegisterKeys, stake address, the pool5 steps
  5. IVRunKES, rewards, votes, upgrades8 steps
  6. VTipsPayments, files, swap, checklist4 steps

II-1 Folders and configuration

A system user for the node, config in /etc/cardano, data in /var/lib/cardano.

All nodes
sudo useradd -r -m -d /var/lib/cardano -s /sbin/nologin cardano
sudo mkdir -p /etc/cardano /var/lib/cardano/db
sudo cp ~/.local/share/mainnet/*.json /etc/cardano/
sudo chown -R cardano:cardano /etc/cardano /var/lib/cardano
sudo usermod -aG cardano $USER

Log out and in again. The block producer shares no peers:

Block producer
sudo jq '.PeerSharing = false' /etc/cardano/config.json > /tmp/config.json
sudo install -o cardano -g cardano -m 644 /tmp/config.json /etc/cardano/config.json
Next: Download the chain with Mithril →

II-2 Download the chain with Mithril

A certified snapshot: hours instead of days.

All nodes
curl --proto '=https' --tlsv1.2 -sSfL \
  https://raw.githubusercontent.com/IntersectMBO/mithril/refs/heads/main/mithril-install.sh \
  | sh -s -- -c mithril-client -d latest -p $HOME/.local/bin

export AGGREGATOR_ENDPOINT=https://aggregator.release-mainnet.api.mithril.network/aggregator
export GENESIS_VERIFICATION_KEY=$(wget -q -O - \
  https://raw.githubusercontent.com/IntersectMBO/mithril/main/mithril-infra/configuration/release-mainnet/genesis.vkey)
export ANCILLARY_VERIFICATION_KEY=$(wget -q -O - \
  https://raw.githubusercontent.com/IntersectMBO/mithril/main/mithril-infra/configuration/release-mainnet/ancillary.vkey)

mkdir -p ~/mithril && cd ~/mithril
~/.local/bin/mithril-client cardano-db download latest --include-ancillary
sudo rm -rf /var/lib/cardano/db
sudo mv ~/mithril/db /var/lib/cardano/db
sudo chown -R cardano:cardano /var/lib/cardano/db

Note The client checks the snapshot's certificate chain against the genesis key — a tampered snapshot fails. GitHub rate limit? Take mithril-client from the Mithril releases.

Next: Topology →

II-3 Topology

Relays talk to the network and your block producer; the block producer only to your relays.

Relay — /etc/cardano/topology.json:

File
{
  "bootstrapPeers": [
    { "address": "backbone.cardano.iog.io", "port": 3001 },
    { "address": "backbone.mainnet.cardanofoundation.org", "port": 3001 }
  ],
  "localRoots": [
    {
      "accessPoints": [
        { "address": "<block-producer-ip>", "port": 6000 }
      ],
      "advertise": false,
      "trustable": true,
      "valency": 1
    }
  ],
  "peerSnapshotFile": "peer-snapshot.json",
  "publicRoots": [
    { "accessPoints": [], "advertise": false }
  ],
  "useLedgerAfterSlot": 194140785
}

Block producer — /etc/cardano/topology.json:

File
{
  "bootstrapPeers": [],
  "localRoots": [
    {
      "accessPoints": [
        { "address": "<relay-1-ip>", "port": 6000 },
        { "address": "<relay-2-ip>", "port": 6000 },
        { "address": "<relay-3-ip>", "port": 6000 }
      ],
      "advertise": false,
      "trustable": true,
      "valency": 3
    }
  ],
  "publicRoots": [],
  "useLedgerAfterSlot": -1
}

Take useLedgerAfterSlot for the relays from your release's topology file. Reload without restart:

Block producer or relay
sudo systemctl reload cardano-node
Next: The air-gapped machine →

II-4 The air-gapped machine

A computer that never connects — for the cold keys and every signature.

A spare laptop with fresh Ubuntu. After installing: Wi-Fi and Bluetooth off for good, no cable. Bring the checked node archive on a USB stick:

Air-gapped machine
cd /media/$USER/<usb-stick>
sha256sum --ignore-missing -c cardano-node-11.1.3-sha256sums.txt
mkdir -p ~/cardano && tar -xzf cardano-node-11.1.3-linux-amd64.tar.gz -C ~/cardano
sudo install -m 755 ~/cardano/bin/cardano-cli /usr/local/bin/
cardano-cli --version
mkdir -p ~/cold-keys && chmod 700 ~/cold-keys

Important Two encrypted backups of ~/cold-keys, in two places, restore-tested. Whoever holds these files owns the pool.

Next: Run the node as a service →

II-5 Run the node as a service

systemd starts it at boot and restarts it when it stops.

/etc/systemd/system/cardano-node.service on a relay:

File
[Unit]
Description=Cardano Node
Wants=network-online.target
After=network-online.target

[Service]
User=cardano
Group=cardano
Type=simple
WorkingDirectory=/var/lib/cardano
ExecStart=/usr/local/bin/cardano-node run \
  --config        /etc/cardano/config.json \
  --topology      /etc/cardano/topology.json \
  --database-path /var/lib/cardano/db \
  --socket-path   /run/cardano/node.socket \
  --host-addr     0.0.0.0 \
  --port          6000
ExecReload=pkill -HUP cardano-node
KillSignal=SIGINT
RestartKillSignal=SIGINT
TimeoutStopSec=300
LimitNOFILE=131072
Restart=always
RestartSec=5
SyslogIdentifier=cardano-node
RuntimeDirectory=cardano
RuntimeDirectoryMode=0750

[Install]
WantedBy=multi-user.target

On the block producer, ExecStart also names the pool files (from Part III, step 3):

File
ExecStart=/usr/local/bin/cardano-node run \
  --config        /etc/cardano/config.json \
  --topology      /etc/cardano/topology.json \
  --database-path /var/lib/cardano/db \
  --socket-path   /run/cardano/node.socket \
  --host-addr     0.0.0.0 \
  --port          6000 \
  --shelley-kes-key                 /var/lib/cardano/keys/kes.skey \
  --shelley-vrf-key                 /var/lib/cardano/keys/vrf.skey \
  --shelley-operational-certificate /var/lib/cardano/keys/node.cert
All nodes
sudo systemctl daemon-reload
sudo systemctl enable --now cardano-node
journalctl -fu cardano-node

Check cardano-cli latest query tip shows "syncProgress": "100.00" before you go on.

Sources and license

Text, pictures and order are BRIAN's. Commands for system setup, the firewall, Mithril and the service file are adapted from the Cardano Developer Portal; every cardano-cli command was written for and run against cardano-cli 11.2.3. The node's own documentation always takes precedence.

Developer Portal license (MIT) — Copyright (c) 2021 Cardano Foundation

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.