Skip to main content

Seed Node Deployment

This guide covers deploying a seed node for any Monolythium network (Sprintnet, Testnet, or Mainnet). Seed nodes help new nodes discover peers and are essential network infrastructure.

Prerequisites

  • Hardware: 4+ vCPU, 8GB+ RAM, 500GB+ SSD
  • OS: Ubuntu 22.04 LTS or Debian 12
  • Network: Static public IP, open firewall for P2P port
  • Software: Docker (recommended) or Go 1.24+

Network Selection

Choose your target network. All configuration is fetched from the canonical registry:

NetworkChain IDStatusRegistry URL
Sprintnetmono-sprint-1Activepeers.json
Testnetmono-test-1Plannedpeers.json
Mainnetmono-1Plannedpeers.json

Quick Start (Docker)

# Set your network (sprintnet, testnet, or mainnet)
NETWORK=sprintnet

# Fetch network configuration
REGISTRY_URL="https://raw.githubusercontent.com/monolythium/mono-core-peers/prod/networks/${NETWORK}/peers.json"
GENESIS_URL=$(curl -s $REGISTRY_URL | jq -r '.genesis_url')
GENESIS_SHA=$(curl -s $REGISTRY_URL | jq -r '.genesis_sha256')
CHAIN_ID=$(curl -s $REGISTRY_URL | jq -r '.chain_id')
PERSISTENT_PEERS=$(curl -s $REGISTRY_URL | jq -r '.persistent_peers | join(",")')

echo "Network: $NETWORK"
echo "Chain ID: $CHAIN_ID"
echo "Genesis SHA256: $GENESIS_SHA"

# Create data directory
sudo mkdir -p /opt/monod/config /opt/monod/data
cd /opt/monod

# Download and verify genesis
curl -sL $GENESIS_URL -o config/genesis.json
echo "$GENESIS_SHA config/genesis.json" | sha256sum -c -

# Run seed node container
docker run -d \
--name ${NETWORK}-seed \
--restart unless-stopped \
-v /opt/monod:/root/.monod \
-p 26656:26656 \
-p 26657:26657 \
ghcr.io/monolythium/monod:latest \
monod start \
--p2p.seed_mode=true \
--p2p.persistent_peers="$PERSISTENT_PEERS"

Full Setup (Systemd)

1. Install Binary

# Download latest release
VERSION=$(curl -s https://api.github.com/repos/monolythium/mono-core/releases/latest | jq -r '.tag_name')
curl -sL "https://github.com/monolythium/mono-core/releases/download/${VERSION}/monod-linux-amd64" -o /usr/local/bin/monod
chmod +x /usr/local/bin/monod
monod version

2. Fetch Network Configuration

# Set your network
NETWORK=sprintnet

# Fetch all configuration from registry
REGISTRY_URL="https://raw.githubusercontent.com/monolythium/mono-core-peers/prod/networks/${NETWORK}/peers.json"
GENESIS_URL=$(curl -s $REGISTRY_URL | jq -r '.genesis_url')
GENESIS_SHA=$(curl -s $REGISTRY_URL | jq -r '.genesis_sha256')
CHAIN_ID=$(curl -s $REGISTRY_URL | jq -r '.chain_id')
SEEDS=$(curl -s $REGISTRY_URL | jq -r '.seeds | join(",")')
PERSISTENT_PEERS=$(curl -s $REGISTRY_URL | jq -r '.persistent_peers | join(",")')
P2P_PORT=$(curl -s $REGISTRY_URL | jq -r '.port_scheme.seeds.p2p')
RPC_PORT=$(curl -s $REGISTRY_URL | jq -r '.port_scheme.seeds.rpc')

# Display configuration
echo "=== Network Configuration ==="
echo "Network: $NETWORK"
echo "Chain ID: $CHAIN_ID"
echo "P2P Port: $P2P_PORT"
echo "RPC Port: $RPC_PORT"
echo "Persistent Peers: $PERSISTENT_PEERS"

3. Initialize Node

# Create monod user
sudo useradd -r -s /sbin/nologin -m -d /var/lib/monod monod

# Initialize node
sudo -u monod monod init "seed-$(hostname)" --chain-id $CHAIN_ID --home /var/lib/monod

# Download genesis
sudo curl -sL $GENESIS_URL -o /var/lib/monod/config/genesis.json
sudo chown monod:monod /var/lib/monod/config/genesis.json

# Verify genesis SHA256
echo "$GENESIS_SHA /var/lib/monod/config/genesis.json" | sha256sum -c -

4. Configure Seed Mode

Edit /var/lib/monod/config/config.toml:

[p2p]
# Enable seed mode - node will crawl network and respond to peer requests
seed_mode = true

# Listen address for P2P connections
laddr = "tcp://0.0.0.0:26656"

# Advertise your public IP
external_address = "YOUR_PUBLIC_IP:26656"

# Persistent peers to connect to (validators or other seeds)
# Get this from the network registry
persistent_peers = "nodeid@host:port,..."

# Increase peer limits for seed nodes
max_num_inbound_peers = 100
max_num_outbound_peers = 50

Apply peers from registry:

# Use monoctl (recommended) or manual sed
monoctl config apply \
--home /var/lib/monod \
--persistent-peers "$PERSISTENT_PEERS"

# Or manually (be careful with sed!):
# Only replace exact key matches to avoid corrupting other config values
sudo -u monod sed -i "s|^persistent_peers = .*|persistent_peers = \"$PERSISTENT_PEERS\"|" /var/lib/monod/config/config.toml
sudo -u monod sed -i "s|^seed_mode = .*|seed_mode = true|" /var/lib/monod/config/config.toml

5. Create Systemd Service

cat <<EOF | sudo tee /etc/systemd/system/${NETWORK}-seed.service
[Unit]
Description=Monolythium Seed Node (${NETWORK})
After=network-online.target
Wants=network-online.target

[Service]
User=monod
Group=monod
Type=simple
ExecStart=/usr/local/bin/monod start --home /var/lib/monod
Restart=always
RestartSec=3
LimitNOFILE=65535

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable ${NETWORK}-seed

6. Configure Firewall

# Required: P2P port (default 26656)
sudo ufw allow 26656/tcp comment "Monolythium P2P"

# Optional: RPC port (only if you need remote access)
# sudo ufw allow 26657/tcp comment "Monolythium RPC"

sudo ufw reload

Network-specific ports:

Check the registry for custom port schemes:

curl -s $REGISTRY_URL | jq '.port_scheme'

Some networks (like Sprintnet) use non-standard ports for multi-validator setups. If connecting to validators on custom ports, ensure those ports are allowed.

7. Start and Verify

# Start the service
sudo systemctl start ${NETWORK}-seed

# Check status
sudo systemctl status ${NETWORK}-seed

# View logs
sudo journalctl -u ${NETWORK}-seed -f

# Verify sync status
curl -s localhost:26657/status | jq '.result.sync_info'

# Check peer count
curl -s localhost:26657/net_info | jq '.result.n_peers'

Seed Mode Configuration

Seeds have specific configuration requirements:

SettingValueDescription
seed_modetrueEnable seed mode behavior
max_num_inbound_peers100+Accept many incoming connections
max_num_outbound_peers50+Actively discover peers
addr_book_stricttrueOnly allow routable addresses
pextrueEnable peer exchange

Pruning Policy

Seeds don't need full block history. Use aggressive pruning:

In app.toml:

[pruning]
pruning = "custom"
pruning-keep-recent = "100"
pruning-keep-every = "0"
pruning-interval = "10"

This keeps only the last 100 blocks, significantly reducing disk usage.

Common Issues

No Peers Found

  1. Verify firewall allows P2P port:

    sudo ufw status | grep 26656
  2. Check persistent_peers format:

    grep persistent_peers /var/lib/monod/config/config.toml
    # Should be: nodeid@host:port
  3. Verify validators are reachable:

    # From the registry
    PEERS=$(curl -s $REGISTRY_URL | jq -r '.persistent_peers[]')
    for peer in $PEERS; do
    HOST=$(echo $peer | cut -d@ -f2 | cut -d: -f1)
    PORT=$(echo $peer | cut -d: -f2)
    echo "Testing $HOST:$PORT"
    nc -zv $HOST $PORT 2>&1
    done

Config Corruption

If config.toml was corrupted by manual editing, regenerate it:

sudo systemctl stop ${NETWORK}-seed
sudo -u monod monod init "seed-$(hostname)" --chain-id $CHAIN_ID --home /var/lib/monod --overwrite
# Re-apply genesis and config

AppHash Mismatch

If the seed reports an AppHash mismatch, reset state:

sudo systemctl stop ${NETWORK}-seed
sudo -u monod monod tendermint unsafe-reset-all --home /var/lib/monod --keep-addr-book
sudo systemctl start ${NETWORK}-seed

Register Your Seed

Once your seed is stable and synced, submit it to the network registry:

  1. Get your node ID:

    monod tendermint show-node-id --home /var/lib/monod
  2. Submit a PR to mono-core-peers adding your seed to networks/<network>/peers.json:

    {
    "seeds": [
    "your_node_id@your_ip:26656"
    ]
    }

See Also