Operators
Operator Guides
Nyx Validator Setup

Validators

Nym has two main codebases:

The validator is a Go application which implements it's functionalities using Cosmos SDK (opens in a new tab). The underlying state-replication engine is powered by CometBFT (opens in a new tab), where the consensus mechanism is based on the Tendermint Consensus Algorithm (opens in a new tab). Finally, a CosmWasm (opens in a new tab) smart contract module controls crucial mixnet functionalities like decentralised directory service, node bonding, and delegated mixnet staking.

ℹ️

We are currently running mainnet with a closed set of reputable validators. To ensure decentralisation of Nyx chain, we are working on a mechanism to onboard new validators to the network. To join the waitlist, please drop an email to validators [at] nymtech.net with details of your setup, experience and any other relevent information

Building your validator

ℹ️

Our documentation often refer to syntax annotated in <> brackets. We use this expression for variables that are unique to each user (like path, local moniker, versions etcetra). Any syntax in <> brackets needs to be substituted with your correct name or version, without the <> brackets. If you are unsure, please check our table of essential parameters and variables (opens in a new tab).

Prerequisites

Start with installing prerequisites needed for validator to work. Run following commands with root permissions or sudo prefix.

1. Install git, gcc, jq
  • Debian-based systems:
apt install git build-essential jq
  • optional additional manual pages can be installed with:
apt-get install manpages-dev
  • Arch-based systems: Install git, gcc and jq with the following:
pacman -S git gcc jq
2. Install Go language

Go can be installed via the following commands (taken from the Go Download and install page (opens in a new tab)):

  • First remove any existing old Go installation and extract the archive you just downloaded into /usr/local:
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.20.10.linux-amd64.tar.gz
  • Then add /usr/local/go/bin to the PATH environment variable
export PATH=$PATH:/usr/local/go/bin
source $HOME/.profile
  • Verify Go is installed with:
go version
  • Should return something like:
go version go1.20.10 linux/amd64

Download a precompiled validator binary

You can find pre-compiled binaries for Ubuntu 22.04 and 20.04 here (opens in a new tab).

Manually compiling your validator binary

The codebase for the Nyx validators can be found here (opens in a new tab).

The validator binary can be compiled by running the following commands:

git clone https://github.com/nymtech/nyxd.git
cd nyxd
 
# Make sure to check releases for the latest version information
git checkout release/<NYXD_VERSION>
 
# Build the binaries
make build

At this point, you will have a copy of the nyxd binary in your build/ directory. Test that it's compiled properly by running:

./build/nyxd

You should see a similar help menu printed to you:


Nyx Daemon (server)
 
Usage:
  nyxd [command]
 
Available Commands:
  completion  Generate the autocompletion script for the specified shell
  config      Create or query an application CLI configuration file
  debug       Tool for helping with debugging your application
  export      Export state to JSON
  genesis     Application's genesis-related subcommands
  help        Help about any command
  init        Initialize private validator, p2p, genesis, and application configuration files
  keys        Manage your application's keys
  prune       Prune app history states by keeping the recent heights and deleting old heights
  query       Querying subcommands
  rollback    rollback cosmos-sdk and tendermint state by one height
  rosetta     spin up a rosetta server
  start       Run the full node
  status      Query remote node for status
  tendermint  Tendermint subcommands
  testnet     subcommands for starting or configuring local testnets
  tx          Transactions subcommands
  version     Print the application binary version information
 
Flags:
  -h, --help                help for nyxd
      --home string         directory for config and data
      --log_format string   The logging format (json|plain) (default "plain")
      --log_level string    The logging level (trace|debug|info|warn|error|fatal|panic) (default "info")
      --trace               print out full stack trace on errors
 
Use "nyxd [command] --help" for more information about a command.

Linking nyxd to libwasmvm.so

libwasmvm.so is the wasm virtual machine which is needed to execute smart contracts in v0.26.1. This file is renamed in libwasmvm.x86_64.so in v0.31.1 and above.

If you downloaded your nyxd binary from Github, you will have seen this file when un-tar-ing the .tar.gz file from the releases page.

If you are seeing an error concerning this file when trying to run nyxd, then you need to move the libwasmvm.x86_64.so file to correct location.

Simply cp or mv that file to /lib/x86_64-linux-gnu/ and re-run nyxd.

Adding nyxd to your $PATH

You'll need to set LD_LIBRARY_PATH in your user's ~/.bashrc or ~/.zshrc file (depends on the terminal you use), and add that to our path. Replace /home/<USER>/<PATH-TO-NYM>/binaries in the command below to the locations of nyxd and libwasmvm.so and run it. If you have compiled these on the server, they will be in the build/ folder:

NYX_BINARIES=<PATH>/<BINARY>
  • If you are using another shell like zsh replace '.bashrc' with the relevant config file
echo 'export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:'NYX_BINARIES >> ~/.bashrc
echo 'export PATH=$PATH:'${NYX_BINARIES} >> ~/.bashrc
source ~/.bashrc
  • Test everything worked:
nyxd
  • This should return the regular help menu:

Nyx Daemon (server)
 
Usage:
  nyxd [command]
 
Available Commands:
  completion  Generate the autocompletion script for the specified shell
  config      Create or query an application CLI configuration file
  debug       Tool for helping with debugging your application
  export      Export state to JSON
  genesis     Application's genesis-related subcommands
  help        Help about any command
  init        Initialize private validator, p2p, genesis, and application configuration files
  keys        Manage your application's keys
  prune       Prune app history states by keeping the recent heights and deleting old heights
  query       Querying subcommands
  rollback    rollback cosmos-sdk and tendermint state by one height
  rosetta     spin up a rosetta server
  start       Run the full node
  status      Query remote node for status
  tendermint  Tendermint subcommands
  testnet     subcommands for starting or configuring local testnets
  tx          Transactions subcommands
  version     Print the application binary version information
 
Flags:
  -h, --help                help for nyxd
      --home string         directory for config and data
      --log_format string   The logging format (json|plain) (default "plain")
      --log_level string    The logging level (trace|debug|info|warn|error|fatal|panic) (default "info")
      --trace               print out full stack trace on errors
 
Use "nyxd [command] --help" for more information about a command.

Initialising your validator

Prerequisites:

  • FQDN Domain name
  • IPv4 and IPv6 connectivity

Choose a name for your validator and use it in place of <ID> in the following command:

# Mainnet
nyxd init <ID> --chain-id=nyx
 
# Sandbox testnet
nyxd init <ID> --chain-id=sandbox
⚠️

init generates priv_validator_key.json and node_key.json.

If you have already set up a validator on a network, make sure to back up the key located at ~/.nyxd/config/priv_validator_key.json.

If you don't save the validator key, then it can't sign blocks and will be jailed all the time, and there is no way to deterministically (re)generate this key.

At this point, you have a new validator, with its own genesis file located at $HOME/.nyxd/config/genesis.json. You will need to replace the contents of that file that with either the Nyx Mainnet or Sandbox Testnet genesis file.

You can use the following command to download them for the correct network:

# Mainnet
wget  -O $HOME/.nyxd/config/genesis.json https://nymtech.net/genesis/genesis.json
 
# Sandbox testnet
curl https://rpc.sandbox.nymtech.net/snapshots/genesis.json | jq '.result.genesis' > $HOME/.nyxd/config/genesis.json

config.toml configuration

Edit the following config options in $HOME/.nyxd/config/config.toml to match the information below for your network:

  • Mainnet:
persistent_peers = "ee03a6777fb76a2efd0106c3769daaa064a3fcb5@51.79.21.187:26656"
laddr = "tcp://0.0.0.0:26656"
  • Sandbox testnet:
cors_allowed_origins = ["*"]
persistent_peers = "26f7782aff699457c8e6dd9a845e5054c9b0707e@:3.72.19.120:26656"
laddr = "tcp://0.0.0.0:26656"

These affect the following:

  • persistent_peers = "<PEER_ADDRESS>@<DOMAIN>.nymtech.net:26666" allows your validator to start pulling blocks from other validators. The main sandbox validator listens on 26666 instead of the default 26656 for debugging. It is recommended you do not change your port from 26656.
  • laddr = "tcp://0.0.0.0:26656" is in your p2p configuration options

Optionally, if you want to enable Prometheus (opens in a new tab) metrics then the following must also match in the config.toml:

  • prometheus = true
  • prometheus_listen_addr = ":26660"

Remember to enable metrics in the 'Configuring Prometheus metrics' section below as well.

And if you wish to add a human-readable moniker to your node:

  • moniker = "<YOUR_VALIDATOR_NAME>"

Finally, if you plan on using Cockpit (opens in a new tab) on your server, change the grpc port from 9090 as this is the port used by Cockpit.

app.toml configuration

In the file $HOME/.nyxd/config/app.toml, set the following values:

  • Mainnet
minimum-gas-prices = "0.025unym,0.025unyx"
  • Sandbox testnet:
minimum-gas-prices = "0.025unym,0.025unyx"

Setting up your validator's admin user

You'll need an admin account to be in charge of your validator. Set that up with:

nyxd keys add nyxd-admin
💡

Cosmos SDK offers multiple backends for securing your keys. Please refer to the Cosmos SDK docs on available keyring backends (opens in a new tab) to learn more

While using the default settings, this will add keys for your account to your system's keychain and log your name, address, public key, and mnemonic. As the instructions say, remember to write down your mnemonic.

You can get the current account address with:

nyxd keys show nyxd-admin -a

Type in your keychain password, not the mnemonic, when asked.

Starting your validator

Everything should now be ready to go. You've got the validator set up, all changes made in config.toml and app.toml, the Nym genesis file copied into place (replacing the initial auto-generated one). Now let's validate the whole setup:

nyxd validate-genesis

If this check passes, you should receive the following output:

File at /path/to/genesis.json is a valid genesis file

If this test did not pass, check that you have replaced the contents of /<PATH>/.nyxd/config/genesis.json with that of the correct genesis file.

Setting up nyxd as full node (non-signing)

⚠️

Skip this section if you're planning to run a validator node to join network consensus. To ensure security & maximum availability of validators, do not expose additional services to the Internet

Unlike signing validators, full nodes do not propose / sign blocks. A full node is typically used for indexing blocks produced on the chain and for exposing web interfaces such as RPC, API and gRPC endpoints required for external applications/services to interact with the blockchain.

By default, API server is disabled and RPC/gRPC servers listen to the loopback address only. In a production setup, it is recommended to use a webserver such as Nginx or caddy to proxy requests to the endpoints as required.

To enable Cosmos REST API, you can enable it in $HOME/.nyxd/config/app.toml like :

[api]
 
# Enable defines if the API server should be enabled. Toggle this to `true`
enable = true
 
# Swagger defines if swagger documentation should automatically be registered.
# You can also expose swagger documentation by toggling the below configuration to true
swagger = true

For more information on enabling access to various endpoints via Nginx, refer to the example configuration here

Open firewall ports

Before starting the validator, we will need to open the firewall ports:

# if ufw is not already installed:
sudo apt install ufw
sudo ufw enable
 
# Customise according to your port bindings. This is only for reference
# 26656 : p2p gossip port
# 26660: If prometheus is enabled
# 22 : Default SSH port
sudo ufw allow 26656,26660,22
 
## !! FOR FULL NODES ONLY !! - exposing Nginx for serving web requests
sudo ufw allow 80,443
 
# to check everything worked
sudo ufw status

For more information about your validator's port configuration, check the validator port reference table below. These can be customised in app.toml and config.toml files.

If you are planning to use Cockpit (opens in a new tab) on your validator server then you will have defined a different grpc port in your config.toml above: remember to open this port as well.

Start the validator:

nyxd start

Once your validator starts, it will start requesting blocks from other validators. This may take several hours. Once it's up to date, you can issue a request to join the validator set with the command below.

Syncing from a snapshot

If you wish to sync from a snapshot on mainnet use Polkachu's mainnet (opens in a new tab) resources.

If you wish to sync from a snapshot on Sandbox testnet use the below commands, which are a modified version of Polkachu's excellent resources. These commands assume you are running an OS with apt as the package manager:

# install lz4 if necessary
sudo apt install snapd -y
sudo snap install lz4
 
# download the snapshot
wget -O nyxd-sandbox-snapshot-data.tar.lz4 https://rpc.sandbox.nymtech.net/snapshots/nyxd-sandbox-snapshot-data.tar.lz4
 
# reset your validator state
nyxd tendermint unsafe-reset-all
 
# unpack the snapshot
lz4 -c -d nyxd-sandbox-snapshot-data.tar.lz4 | tar -x -C $HOME/.nyxd

You can then restart nyxd - it should start syncing from a block > 2000000.

Joining Consensus

ℹ️

You can skip this section if you are planning to run a full-node. This step will make your node a signing validator which joins network consensus

Once your validator has synced and you have received tokens, you can join consensus and produce blocks.

  • Mainnet:
nyxd tx staking create-validator
  --amount=<10000000unyx>
  --pubkey=$(/home/<USER>/<PATH-TO>/nyxd/binaries/nyxd tendermint show-validator)
  --moniker="<YOUR_VALIDATOR_NAME>"
  --chain-id=nyx
  --commission-rate="0.10"
  --commission-max-rate="0.20"
  --commission-max-change-rate="0.01"
  --min-self-delegation="1"
  --gas="auto"
  --gas-adjustment=1.15
  --gas-prices=0.025unyx
  --from=<"KEYRING_NAME">
  --node=https://rpc.nymtech.net:443
  • Sandbox Testnet:
nyxd tx staking create-validator
  --amount=<10000000unyx>
  --pubkey=$(/home/<USER>/<PATH-TO>/nym/binaries/nyxd tendermint show-validator)
  --moniker="<YOUR_VALIDATOR_NAME>"
  --chain-id=sandbox
  --commission-rate="0.10"
  --commission-max-rate="0.20"
  --commission-max-change-rate="0.01"
  --min-self-delegation="1"
  --gas="auto"
  --gas-adjustment=1.15
  --gas-prices=0.025unyx
  --from=<"KEYRING_NAME">
  --node https://rpc.sandbox.nymtech.net:443

You'll need Nyx tokens on mainnet / sandbox to perform the above tasks.

If you want to edit some details for your node you will use a command like this:

  • Mainnet:
nyxd tx staking edit-validator
  --chain-id=nyx
  --moniker="<YOUR_VALIDATOR_NAME>"
  --details="Nyx validator"
  --security-contact="<YOUR_EMAIL>"
  --identity="<YOUR_IDENTITY>"
  --gas="auto"
  --gas-adjustment=1.15
  --gas-prices=0.025unyx
  --from="KEYRING_NAME"
  • Sandbox testnet
nyxd tx staking edit-validator
  --chain-id=sandbox
  --moniker="<YOUR_VALIDATOR_NAME>"
  --details="Sandbox testnet validator"
  --security-contact="your email"
  --identity="<YOUR_IDENTITY>"
  --gas="auto"
  --gas-adjustment=1.15
  --gas-prices=0.025unyx
  --from="KEYRING_NAME"

With above command you can specify the gpg key last numbers (as used in keybase) as well as validator details and your email for security contact.

Automating your validator with systemd

You will most likely want to automate your validator restarting if your server reboots. Checkout the maintenance page with a quick tutorial.

Setting the ulimit

Linux machines limit how many open files a user is allowed to have. This is called a ulimit. We need to set it to a higher value than the default 1024. Follow the instructions in the maintenance page to change the ulimit value for validators.

Using your validator

Un-jailing your validator

If your validator gets jailed, you can fix it with the following command:

  • Mainnet:
nyxd tx slashing unjail
  --broadcast-mode=block
  --from="KEYRING_NAME"
  --chain-id=nyx
  --gas=auto
  --gas-adjustment=1.4
  --gas-prices=0.025unyx
  • Sandbox Testnet:
nyxd tx slashing unjail
  --broadcast-mode=block
  --from="KEYRING_NAME"
  --chain-id=sandbox
  --gas=auto
  --gas-adjustment=1.4
  --gas-prices=0.025unyx

Upgrading your validator

To upgrade your validator, follow the steps on the maintenance page.

Common reasons for your validator being jailed

Your validator will be jailed if your node:

  • misses x amount of blocks in y interval, where x and y are parameters set by chain governance
  • performs double signing (two conflicting signatures on the same block using the same key)

Double signing is a serious infraction. If a node double signs, all the delegators to the node (including self-delegation) will be slashed by 5%. Additionally, the node will be permanently jailed and removed from consensus (called tombstoning)

One of the most common reason for your validator being jailed is that your validator is out of memory because of bloated syslogs.

Running the command df -H will return the size of the various partitions of your VPS. If the partition with blockchain data is almost full, try pruning the blockchain data or expanding the storage size.

Day 2 operations with your validator

You can check your current balances with:

nyxd query bank balances ${ADDRESS}

For example, on the Sandbox testnet this would return:

balances:
- amount: "919376"
denom: unym
pagination:
next_key: null
total: "0"

You can, of course, stake back the available balance to your validator with the following command.

Remember to save some tokens for gas costs!

  • Mainnet:
nyxd tx staking delegate VALOPERADDRESS AMOUNTunyx
  --from="KEYRING_NAME"
  --keyring-backend=os
  --chain-id=nyx
  --gas="auto"
  --gas-adjustment=1.15
  --gas-prices=0.025unyx
  • Sandbox Testnet:
nyxd tx staking delegate VALOPERADDRESS AMOUNTunyx
  --from="KEYRING_NAME"
  --keyring-backend=os
  --chain-id=sandbox
  --gas="auto"
  --gas-adjustment=1.15
  --gas-prices=0.025unyx