Skip to main content

Systemd Setup

Hardware Requirements

  • RAM: 128 GB
  • CPU: 24-core processor / 48 vCPUs
  • Storage: 4 TB NVMe SSD
  • Network Uplink: 1 Gbps
  • Minimum Stake: 2 million IOTAs (can be delegated to your validator by someone else)

Required Network Ports

Ensure the following ports are open in your firewall:

Protocol/PortReachabilityPurposeDescription
TCP/8080InboundValidator/transaction interfacefull nodes connect to validators to collect partial signatures for transactions
TCP/8081Inbound/OutboundConsensus interfacevalidator nodes send consensus blocks to each other
UDP/8084Inbound/OutboundPeer-to-peer state sync interfacenodes sync their state with each other
TCP/8443OutboundMetrics pushingvalidator metrics get pushed to IOTA Foundation monitoring
TCP/9184LocalhostMetrics scrapingfor local monitoring only

1. Generate Validator Information

Key Security

It is recommended to run these steps in a secure local environment to avoid storing the private key controlling the validator rewards on the node.

How to Generate a New Set of Validator Information

1.1. Install and configure the IOTA CLI

See Install IOTA on how to install the iota CLI and Connect to an IOTA Network on how to select the correct environment (Mainnet or Testnet).

1.2. Generate a new key pair

iota client new-address

This generates a new key pair and stores the files within the standard working config folder, ~/.iota/iota_config/ (in Unix). You can skip this step if you already have an account configured. If you would like to import an existing keypair see iota keytool import -h.

Executing the above command provides the key pair info as output, e.g.:

╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ Created new keypair and saved it to keystore. │
├─────────────────────────┬──────────────────────────────────────────────────────────────────────────────┤
│ alias │ intelligent-chalcedony │
│ address │ 0x3607bc87821a13d861e1e09cd5a2525b272f8dbc3e00556a8baf940a39120f32 │
│ publicBase64Key │ m6mBnT0tq9CA1zgdwy9y6ag2e8sWyzHVAoca+zLKJq8= │
│ publicBase64KeyWithFlag │ AJupgZ09LavQgNc4HcMvcumoNnvLFssx1QKHGvsyyiav │
│ keyScheme │ ed25519 │
│ recoveryPhrase │ glimpse hard relax method kid deliver nominee wait brief surprise speed pond │
╰─────────────────────────┴──────────────────────────────────────────────────────────────────────────────╯
  • alias: A human-readable identifier to use within the CLI scope to refer to a key pair.
  • address: The public address representing the key pair.
  • publicBase64Key: The public key, base64 encoded.
  • publicBase64KeyWithFlag: The public key prefixed with the scheme flag byte, base64 encoded.
  • keyScheme: The cryptographic scheme used to derive the keypair; the ed25519 is the standard scheme, used most of the time, while the BLS12381 scheme is used for the authority_key.
  • recoveryPhrase: A list of 12 words used by the cryptographic scheme used to derive the key pair.
info

From now on, this key pair will be referred to as account-key.

1.3. Switch to the validator account key

This makes that key pair active in the CLI.

iota client switch --address <alias>

1.4. Generate the validator data

Finally, all validator's remaining key pairs and data can be generated using the following command:

iota validator make-validator-info \
<name> \
<description> \
<image_url> \
<project_url> \
<host_name> \
  • name: A human-readable validator name, e.g., validator1.
  • description: A human-readable validator description, e.g., this is a validator.
  • image_url: The validator image URL, e.g., https://www.iota.org/favicon.png.
  • project_url: The validator project URL, e.g., https://www.iota.org.
  • host_name: The host name that is used to generate the validator network_address, p2p-address and primary_address, e.g., validator1.iota.org.

This command generates a validator.info file and 4 key pair files in the same directory where the command was executed. All keys but the account.key will need to be copied over to the validator node and included in the YAML configuration of the node. See Validator Node Configuration.

  • account.key contains an ed25519 private key (keep this one private).
  • network.key contains an ed25519 private key (copy over to the validator node).
  • authority.key contains a BLS12381 private key (copy over to the validator node).
  • protocol.keycontains an ed25519 private key (copy over to the validator node).
  • validator.info contains the validator information, e.g.:
---
info:
name: validator1
account-address: "0x547b20ffca39cf1c9f57e7d1ff946d4720df48bb582e89b763b5d488ec23f5fa"
authority-key: h93SKC2tFXMDt+lu4SRb3KA668/lJCPREHnzYZelaQ3iAu0RuiHqETBg/1jkV9HFCECvBCrzKjTuVD/bt5yUDon5nPKQmCyYEmx0NRQmxfP7Szpg17YZ388eT+aTnGEK
protocol-key: Lm1Iy5KDV0qlMcGVnQNatAMLxhg8FOxE2q/QUkgLAYA=
network-key: ADBhWCBOzqIvsDa9cowpSQ4t1nz+ZQYeRLBGQYe1Dy8=
gas-price: 1000
commission-rate: 200
network-address: /dns/validator1.iota.org/tcp/8080/http
p2p-address: /dns/validator1.iota.org/udp/8084
primary-address: /dns/validator1.iota.org/udp/8081
description: validator-description1
image-url: "https://www.iota.org/favicon.png"
project-url: "https://www.iota.org"
proof_of_possession: hpep8yY/JCj/zTEv9Ws7Qow3KO+2jrsX/yAUAykfxzS5vsg7vlwsscJpspf4XF/u

Where:

  • name: human-readable validator name, defined above;
  • account-address: The address derived from the account key public key.
  • authority-key: The public key derived from the authority key private key.
  • protocol-key: The public key derived from the protocol key private key.
  • network-key: The public key derived from the network key private key.
  • gas-price: An unsigned integer value indicating the gas price proposed for the first epoch. This is unused as of protocol version v5.
  • commission-rate: The validator commission rate, i.e., the fee charged by the validator for staking services; the default set at 2% (200).
  • network-address: The network address of the validator, defined using the host_name.
  • p2p-address: The address of the validator used for p2p activities such as state sync, defined using the host_name.
  • primary-address: The primary address of the validator used for the consensus, defined using the host_name.
  • description: A human-readable validator description, defined above.
  • image-url: The validator image URL, defined above.
  • project-url: The validator project URL, defined above.
  • proof_of_possession: A BLS signature created using the authority-key, committed over the following message: intent || pubkey || address || epoch. intent is serialized to [5, 0, 0] representing an intent with scope as "Proof of Possession", version as "V0" and app_id as "Iota". pubkey is the serialized public key bytes of the authority-key. address is the account-address. epoch is serialized to [0, 0, 0, 0, 0, 0, 0, 0].
note

You may have noticed that port 8081 is using UDP, which conflicts with the firewall rules. This is a known bug, but the node is actually communicating via TCP.

1.5. Register as a Validator Candidate

Submit an on-chain transaction to become a validator candidate. The parameter is the file path to the validator.info generated by Make Validator Info.

Make sure your validator account has enough IOTA to cover the gas costs. On the Testnet you can use the Faucet to receive the necessary funds.

Environments
iota validator become-candidate <validator.info file path>

You can verify the status by running:

iota validator display-metadata --json true

You should see your validator's status is Candidate.

2. Setup Validator Node

Note

Perform these steps on the server that will be running the validator instance.

2.1. Prepare the Environment

sudo useradd iota
sudo mkdir -p /opt/iota/bin
sudo mkdir -p /opt/iota/config
sudo mkdir -p /opt/iota/db
sudo mkdir -p /opt/iota/key-pairs
sudo chown -R iota:iota /opt/iota

2.2. Build From Source

First make sure to install all pre-requisites:

sudo apt update && sudo apt install -y curl git-all cmake gcc libssl-dev pkg-config libclang-dev libpq-dev build-essential

Build and install the iota-node and iota-tool binaries from source.

git clone https://github.com/iotaledger/iota.git && cd iota
git checkout mainnet
cargo build --release --bin iota-node --bin iota-tool
mv ./target/release/iota-node /opt/iota/bin/iota-node
mv ./target/release/iota-tool /opt/iota/bin/iota-tool

2.3. Create a systemd Service

sudo tee /etc/systemd/system/iota-node.service > /dev/null <<EOF
[Unit]
Description=IOTA Node

[Service]
User=iota
WorkingDirectory=/opt/iota/
Environment=RUST_BACKTRACE=1
Environment=RUST_LOG=info,iota_core=debug,consensus=debug,jsonrpsee=error
ExecStart=/opt/iota/bin/iota-node --config-path /opt/iota/config/validator.yaml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

After creating the systemd service, you should reload the daemon and enable the service:

sudo systemctl daemon-reload
sudo systemctl enable iota-node.service

2.4. Download the Configuration Template

cd /opt/iota/config

Download the validator configuration file template:

curl -fLJ -o validator.yaml https://github.com/iotaledger/iota/raw/refs/heads/develop/setups/validator/validator-mainnet.yaml

2.5. Configure the P2P Settings

Configure the P2P settings in your validator.yaml file by following these steps:

  1. Update the external address:
p2p-config:
external-address: /dns/<YOUR-DOMAIN>/udp/8084
note

Replace <YOUR-DOMAIN> with the hostname you used while generating the validator info. This address must be accessible from the internet.

note

For better flexibility and faster disaster recovery, we suggest using a hostname with a very low TTL. This allows you to quickly relocate your validator to a new server if hardware fails. Direct IP addressing significantly complicates server migration.

2.6. Download the Genesis Blobs

cd /opt/iota/config
curl -fLJO https://dbfiles.mainnet.iota.cafe/genesis.blob
curl -fLJO https://dbfiles.mainnet.iota.cafe/migration.blob

2.7. Copy the Validator Keys

Copy the protocol.key, network.key and authority.key you created previously to the server and place them in /opt/iota/key-pairs.

2.8. Download the Latest Formal Snapshot

cd /opt/iota
sudo -u iota /opt/iota/bin/iota-tool download-formal-snapshot --latest --genesis /opt/iota/config/genesis.blob --path /opt/iota/db/authorities_db --num-parallel-downloads 50 --no-sign-request --verify normal --network mainnet --verbose

2.9. Start Your Validator Node

sudo systemctl start iota-node

You can follow the node logs with:

sudo journalctl -u iota-node -f

3. Join the Validators

Key Security

The following steps should be executed in the same environment you used while creating the validator keys.

Make sure your validator account created in Generate Validator Information has enough IOTA to cover the gas costs.

Tesnet Faucet

On the Testnet you can use the Faucet to receive the necessary funds.

Before joining the validators, ensure you have enough delegated stake by running the following command:

iota validator display-metadata --json true  | grep stakingPoolIotaBalance

You need at least 2M iota to join the validators. So make sure the stakingPoolIotaBalance is at least 2_000_000_000_000_000.

Once your have enough stake, submit your request to join the validators:

iota validator join-validators

4. Monitor Validator Status

iota validator display-metadata --json true

You should see your validator's status is Pending now, it will become active and join the validators starting from next epoch.

<YOUR-VALIDATOR_ADDRESS>'s validator status: Pending

You can also check the Monitoring about metrics endpoint.

5. State Sync Full Node (SSFN) Setup

Follow the State Sync Full Node (SSFN) Guide.