Systemd Setup
Hardware Requirements
- Mainnet
- Testnet
- 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)
- RAM: 64 GB
- CPU: 8-core processor / 16 vCPUs
- Storage: 2 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/Port | Reachability | Purpose | Description |
---|---|---|---|
TCP/8080 | Inbound | Validator/transaction interface | full nodes connect to validators to collect partial signatures for transactions |
TCP/8081 | Inbound/Outbound | Consensus interface | validator nodes send consensus blocks to each other |
UDP/8084 | Inbound/Outbound | Peer-to-peer state sync interface | nodes sync their state with each other |
TCP/8443 | Outbound | Metrics pushing | validator metrics get pushed to IOTA Foundation monitoring |
TCP/9184 | Localhost | Metrics scraping | for local monitoring only |
1. Generate Validator Information
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; theed25519
is the standard scheme, used most of the time, while theBLS12381
scheme is used for theauthority_key
.recoveryPhrase
: A list of 12 words used by the cryptographic scheme used to derive the key pair.
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 validatornetwork_address
,p2p-address
andprimary_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.key
contains 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 theaccount key
public key.authority-key
: The public key derived from theauthority key
private key.protocol-key
: The public key derived from theprotocol key
private key.network-key
: The public key derived from thenetwork 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 thehost_name
.p2p-address
: The address of the validator used for p2p activities such as state sync, defined using thehost_name
.primary-address
: The primary address of the validator used for the consensus, defined using thehost_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 theauthority-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" andapp_id
as "Iota".pubkey
is the serialized public key bytes of theauthority-key
.address
is theaccount-address
.epoch
is serialized to[0, 0, 0, 0, 0, 0, 0, 0]
.
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.
Make sure your client is configured to use the correct environment.
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
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.
- Mainnet
- Testnet
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
git clone https://github.com/iotaledger/iota.git && cd iota
git checkout testnet
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:
- Mainnet
- Testnet
curl -fLJ -o validator.yaml https://github.com/iotaledger/iota/raw/refs/heads/develop/setups/validator/validator-mainnet.yaml
curl -fLJ -o validator.yaml https://github.com/iotaledger/iota/raw/refs/heads/develop/setups/validator/validator-testnet.yaml
2.5. Configure the P2P Settings
Configure the P2P settings in your validator.yaml
file by following these steps:
- Update the external address:
p2p-config:
external-address: /dns/<YOUR-DOMAIN>/udp/8084
Replace <YOUR-DOMAIN>
with the hostname you used while generating the validator info.
This address must be accessible from the internet.
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
- Mainnet
- Testnet
curl -fLJO https://dbfiles.mainnet.iota.cafe/genesis.blob
curl -fLJO https://dbfiles.mainnet.iota.cafe/migration.blob
curl -fLJO https://dbfiles.testnet.iota.cafe/genesis.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
- Mainnet
- Testnet
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
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 testnet --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
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.
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.