Skip to main content

Join a Network

This guide covers how to join an existing Monolythium network as a full node operator.

!!! danger "Do Not Create Your Own Genesis" All participants must join the official published networks using the official genesis file and seed nodes. Creating your own genesis chain will result in a separate, incompatible network.

Prerequisites

  • Server meeting the hardware requirements
  • Linux (Ubuntu 22.04+ recommended) or macOS
  • Root or sudo access
  • Ports 26656 (P2P) and optionally 26657 (RPC) open
  • Dedicated user for running the node (recommended - see Installation)
  • Understanding of peer roles (seeds vs bootstrap vs persistent peers)

!!! tip "Create a User First" For production deployments, create a dedicated user before proceeding:

sudo adduser monouser
sudo mkdir -p /home/monouser/.monod
sudo chown -R monouser:monouser /home/monouser/.monod

See the User Setup guide for details.

Step 1: Install monod Binary

Download the official monod binary from the releases page or build from source:

# Download the latest release (example)
curl -LO https://github.com/monolythium/mono-core/releases/download/v1.0.0/monod-linux-amd64
chmod +x monod-linux-amd64
sudo mv monod-linux-amd64 /usr/local/bin/monod

# Verify installation
monod version

!!! tip "Cosmovisor Recommended" For production deployments, use Cosmovisor to manage binary upgrades automatically.

Step 2: Initialize Node Home

Initialize your node with the appropriate chain ID:

=== "Sprintnet"

monod init <your-moniker> --chain-id mono-sprint-1

=== "Testnet"

monod init <your-moniker> --chain-id mono-test-1

=== "Mainnet"

monod init <your-moniker> --chain-id mono-1

Replace <your-moniker> with a name for your node (e.g., my-validator-node).

This creates the node home directory at ~/.monod/ with default configuration.

Step 3: Download and Verify Genesis

Download the official genesis file and verify its checksum:

=== "Sprintnet"

curl -LO https://raw.githubusercontent.com/monolythium/networks/main/sprintnet/genesis.json

# Verify checksum (check official repo for current hash)
sha256sum genesis.json
# Expected: <published_hash>

mv genesis.json ~/.monod/config/genesis.json

=== "Testnet"

curl -LO https://raw.githubusercontent.com/monolythium/networks/main/testnet/genesis.json

# Verify checksum
sha256sum genesis.json
# Expected: <published_hash>

mv genesis.json ~/.monod/config/genesis.json

=== "Mainnet"

curl -LO https://raw.githubusercontent.com/monolythium/networks/main/mainnet/genesis.json

# Verify checksum
sha256sum genesis.json
# Expected: <published_hash>

mv genesis.json ~/.monod/config/genesis.json

!!! warning "Always Verify Genesis" Never skip genesis verification. An incorrect genesis file will cause your node to fork from the canonical chain.

Step 4: Configure Seeds and Peers

Edit ~/.monod/config/config.toml to add seed nodes:

=== "Sprintnet"

seeds = "seed1.sprintnet.mononodes.xyz:26656,seed2.sprintnet.mononodes.xyz:26656,seed3.sprintnet.mononodes.xyz:26656"

=== "Testnet"

seeds = "seed1.testnet.mononodes.xyz:26656,seed2.testnet.mononodes.xyz:26656,seed3.testnet.mononodes.xyz:26656"

=== "Mainnet"

seeds = "seed1.mainnet.mononodes.xyz:26656,seed2.mainnet.mononodes.xyz:26656,seed3.mainnet.mononodes.xyz:26656"

See Seeds and Peers for additional configuration options.

Step 5: Configure systemd Service

Create a systemd service file for automatic startup and management:

sudo tee /etc/systemd/system/monod.service > /dev/null <<EOF
[Unit]
Description=Monolythium Node
After=network-online.target

[Service]
User=$USER
WorkingDirectory=$HOME
ExecStart=/usr/local/bin/monod start --home $HOME/.monod
Restart=always
RestartSec=3
LimitNOFILE=65535
Environment="HOME=$HOME"

[Install]
WantedBy=multi-user.target
EOF

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable monod
sudo systemctl start monod

Step 6: Verify Node is Syncing

Check the node status:

# View logs
sudo journalctl -u monod -f

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

Key fields to verify:

  • catching_up: Should be true initially, then false when synced
  • latest_block_height: Should be increasing
  • latest_block_time: Should be recent when synced

Sync Options

Bootstrap sync uses trusted peers with PEX disabled for deterministic genesis sync. This prevents "peer poisoning" where random peers may serve incomplete or corrupted block data.

When to use: New nodes syncing from scratch, especially if you've experienced sync issues.

# Using mono-commander (recommended)
monoctl join --network Sprintnet --bootstrap

# Manual configuration in config.toml
[p2p]
pex = false
seeds = ""
persistent_peers = "<bootstrap_peers_from_registry>"

!!! warning "PEX Disabled During Sync" Bootstrap mode disables peer exchange (PEX) to ensure you only connect to trusted archive nodes. After syncing, you can re-enable PEX for better peer diversity.

Re-enabling PEX after sync:

# After catching_up=false
sed -i 's/pex = false/pex = true/' ~/.monod/config/config.toml
sudo systemctl restart monod

Full Sync (Default)

Syncs from genesis block using seed nodes and PEX. Works well but can be vulnerable to peer poisoning if random peers serve bad block data.

State Sync

Syncs from a recent snapshot for faster startup. See State Sync for configuration.

Snapshot Restore

Download and restore from a community snapshot. See Snapshots for details.

Edit ~/.monod/config/config.toml for production:

# Logging
log_level = "info"

# P2P
max_num_inbound_peers = 40
max_num_outbound_peers = 10

# Mempool
size = 5000
cache_size = 10000

Edit ~/.monod/config/app.toml if enabling EVM RPC:

[json-rpc]
enable = true
address = "0.0.0.0:8545"

[json-rpc.ws]
enable = true
address = "0.0.0.0:8546"

Firewall Configuration

Minimum required ports:

PortProtocolPurposeRequired
26656TCPP2PYes
26657TCPRPCOptional (validators should restrict)
8545TCPEVM JSON-RPCOptional
8546TCPEVM WebSocketOptional
# UFW example
sudo ufw allow 26656/tcp
sudo ufw allow 26657/tcp # Only if exposing RPC

Troubleshooting

Node Won't Start

  1. Check logs: sudo journalctl -u monod -n 100
  2. Verify genesis file is correct: monod validate-genesis
  3. Ensure ports are not in use: ss -tlnp | grep 26656

"invalid chain-id on InitChain" Error

If you see an error like:

error on replay: invalid chain-id on InitChain; expected: , got: mono-sprint-1

This means the node home has stale state from a failed initialization. To fix:

# Stop the node
sudo systemctl stop monod

# Reset and re-join
monoctl node reset --home ~/.monod --force
monoctl join --network Sprintnet --bootstrap --home ~/.monod

# Start the node
sudo systemctl start monod

!!! warning "Always Use monoctl join" This error commonly occurs when manually setting up a node. Always use monoctl join which handles all required configuration automatically, including setting the chain-id in client.toml.

Permission Denied on Database

If you see failed to initialize database ... LOCK: permission denied:

  1. Stop the service: sudo systemctl stop monod
  2. Fix ownership: sudo chown -R monouser:monouser /home/monouser/.monod
  3. Verify systemd User matches directory owner
  4. Restart: sudo systemctl start monod

See Installation Troubleshooting for details.

Not Finding Peers

  1. Verify seed configuration in config.toml
  2. Check firewall allows outbound connections on port 26656
  3. Try adding persistent peers manually

Sync Stalled

  1. Check node health: curl localhost:26657/health
  2. Verify network connectivity to seeds
  3. Consider using state sync for faster initial sync

Sync Stuck Around Height ~140,000

If your node stalls around height 140,000-141,000 during initial sync, this is typically caused by connecting to pruned peers that don't have historical blocks. To resolve:

  1. Stop the node:

    sudo systemctl stop monod
  2. Clear data and addrbook (preserves config):

    rm -rf ~/.monod/data/*
    rm -f ~/.monod/config/addrbook.json
    echo '{"height": "0", "round": 0, "step": 0}' > ~/.monod/data/priv_validator_state.json
  3. Re-join using bootstrap mode:

    monoctl join --network Sprintnet --bootstrap --clear-addrbook
  4. Restart:

    sudo systemctl start monod

!!! tip "Use Bootstrap Mode for Reliable Sync" Bootstrap mode connects only to trusted archive nodes that maintain full block history, avoiding peers that may have pruned historical data.

Mono Commander is the recommended single path for joining networks. It handles all configuration automatically, including critical settings that are easy to miss with manual setup.

# Install monoctl
curl -LO https://github.com/monolythium/mono-commander/releases/latest/download/monoctl-linux-amd64
chmod +x monoctl-linux-amd64
sudo mv monoctl-linux-amd64 /usr/local/bin/monoctl

# Join network with bootstrap mode (recommended for reliable sync)
monoctl join --network Sprintnet --bootstrap --home ~/.monod

# Generate and install systemd service
monoctl systemd install --network Sprintnet --user $USER

# Start the node
sudo systemctl start monod

# Verify node is syncing
monoctl status --network Sprintnet

!!! success "monoctl join Handles Everything" monoctl join automatically:

  • Downloads and verifies the genesis file
  • Runs preflight checks to detect stale state
  • Initializes the node home if needed
  • Configures seeds and peers from the registry
  • Sets the chain-id in client.toml (critical for node startup)
  • Clears addrbook for clean peer discovery

See the Mono Commander documentation for complete usage details.

Next Steps