Becoming a Validator
This guide will walk you through the process of setting up a Nimiq validator in the Albatross network.
Setup
This guide assumes the proof-of-stake network client (the node) has been compiled, or that you are running the node through other means, such as Docker. Check this guide for more information on compiling the code yourself.
This guide provides two methods for sending JSON-RPC commands to your node:
- arpl, an RPC client specific to Nimiq's PoS node
curl
, a general-purpose network request tool
Install ARPL
To install arpl, use npm
or a compatible package manager:
npm install -g @sisou/albatross-remote
Install CURL
If the curl
command is not already installed on your machine, try installing it through your software center or check out https://curl.se/download.html for installation instructions.
Configure and run your node
Generating your validator address and keys
For running a validator you need the following items wich we are generating now:
- A validator address: Nimiq address
- A voting keypair: BLS keypair
- A signing keypair: Schnorr keypair
- Optionally a fee keypair: Schnorr keypair
Note that we will use these in the following steps to configure your validator.
TIP
Keep your public and private keys accessible by writing them down or saving them on your computer. Make sure you save the private keys securely, there is no way to recover them!
We are generating these keys with utilities included in the nimiq/core-rs-albatross
repository. Refer to Setup above for installation instructions.
To generate the Schnorr keypairs and the validator address, you can use:
cargo run --release --bin nimiq-address
Note
Since we will need at least one Schnorr keypair and a Nimiq address, the command must be run 2 separate times and the output must be saved because it will be needed later in this guide.
Run the command a third time, if you want to set a specific fee keypair - otherwise it will be auto-generated when you start your node, which will still work for sending control transactions without a fee.
To generate a BLS keypair, you can use:
cargo run --release --bin nimiq-bls
Note
The output must be saved because it will be needed later in this guide.
Configuration
Run the node once. It will generate an example configuration file in the default config folder. On Linux, that's ~/.nimiq
. You need to copy ~/.nimiq/client.toml.example
to ~/.nimiq/client.toml
. You can leave most configuration options as they are for now to start a basic full node.
To be able to control your node and to stake and validate, you need to enable the JSON-RPC server in your client.toml
. Make sure the RPC section called [rpc-server]
in the configuration file is enabled by uncommenting it.
Note that you can also configure your node to use history
as the sync_mode
. For that, you could change the consensus
section of your config file to set sync_mode
like in the following example:
[consensus]
sync_mode = "history"
Note
History sync mode uses much more storage (disk) space and can take very long to sync. As such, we recommend opting for a full node setup to get started quicker.
The next step is to set up your validator address and keys in the [validator]
section of your config file:
[validator]
validator_address = "NQXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX"
signing_key_file = "signing_key.dat"
voting_key_file = "voting_key.dat"
fee_key_file = "fee_key.dat"
signing_key = "Schnorr Private Key"
fee_key = "Schnorr Private Key"
voting_key = "BLS Private Key"
automatic_reactivate = true
Replace the validator address and keys generated accordingly:
- The
validator_address
corresponds to the address output of animiq-address
command. Paste your generated validator address here. - Ignore the three lines specifying file names. These files are automatically generated by the node and filled with the data from in the next settings.
- The
signing_key
corresponds to the private key of animiq-address
command. Paste your Schnorr secret key here. - The
fee_key
corresponds to the private key of animiq-address
command. If you don't want to specify your own, comment that line out. - The
voting_key
in the config file corresponds to the secret key of thenimiq-bls
command. Paste your BLS secret key here. - Leave
automatic_reactivate
as is.
Note
As previously mentioned, if you are creating a new validator from scratch, and you need to generate all those keys, then you will need to use the nimiq-address
command three times and the nimiq-bls
command one time.
The fee_key
is used to pay the fees for automatic reactivate transactions (if enabled). Since these fees default to 0 NIM, having the node auto-generate a fee key is safe.
TLS Certificate
It is strongly recommended to set up a TLS certificate for your node, because the browser-based Nimiq Wallet can only connect to it via secure connections. In order to maintain a healthy decentralization level within the network, it is advisable for the Nimiq Wallet to connect to as many diverse nodes as possible.
There are different services where a TLS certificate can be obtained, such as Let's Encrypt.
Once the certificate is obtained, it can be specified in the Network-TLS section within the config file:
[network.tls]
private_key = "/path/to/private_key_file.pem"
certificates = "/path/to/full_certificates_file.pem"
Start your node and sync the blockchain
After you finish your configuration, run the client from inside the core-rs-albatross
directory with cargo run --release --bin nimiq-client
. It will connect to the seed node(s), then to other nodes in the network, and start syncing the blockchain. Next, we will query your node for its status.
Note
When running your node through other means, such as a Docker container, refer to their respective documentation on how to start you node with your own config.
Check your status with JSON-RPC
If you enabled the JSON-RPC Server in your node’s configuration, you can query your node and send commands with arpl
or curl
, as installed in step 1.
ARPL
To check the status of your client, first open an interactive session using the port set in your configuration. If you did not change it, the default port
is 8648
and the host
is localhost
:
arpl repl -u ws://<host>:<port>/ws
# -u is short for --url
# With default settings:
arpl repl -u ws://localhost:8648/ws
# You can also use other ways of specifying the connection parameters:
arpl repl -h localhost -p 8648
# -h is short for --host, -p is short for --port
# The defaults of the node configuration are also the defaults for
# arpl, so just this would work, too:
arpl repl
Once in the session, check the status with this command:
status
It will reply with a list of performance indicators, such as the consensus state, the current block height and number of connected peers.
CURL
To check the status of your client with curl
, send RPC requests to the port set in your configuration. If you did not change it, the default port
is 8648
and the host
is localhost
:
With curl
, you need to query the various properties of your node individually:
Query the consensus state:
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "isConsensusEstablished", "params": [], "jsonrpc": "2.0", "id": 1}'
The result is the result.data
value.
Query the node's current block height:
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "getBlockNumber", "params": [], "jsonrpc": "2.0", "id": 1}'
Query the number of connected peers:
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "getPeerCount", "params": [], "jsonrpc": "2.0", "id": 1}'
Become a Validator
To become a validator, you need to register it in the staking contract by sending a create_validator
transaction. For that you need to have an account with at least the validator deposit fee (100 000 NIM). This guide assumes that this amount is already present in the validator address. To check if that is the case, use this command:
ARPL
In the arpl session:
account:get <your_validator_address>
CURL
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "getAccountByAddress", "params": ["<your_validator_address>"], "jsonrpc": "2.0", "id": 1}'
Note that the balance
returned is in Luna. Devide by 100'000 to get NIM.
Import your validator keypair
To sign and send transactions from your validator account, you need to import its keypair.
In the following commands, validator_private_key
is the private key of the Schnorr keypair you generated for the validator address.
ARPL
account:import <validator_private_key> --unlock
Accounts are generally imported locked. The addition of the --unlock
parameter to the above command unlocked the account for us already. If you forgot to add --unlock
to the command above, or for any other reason, you can unlock your account in your node like this:
account:unlock <address>
CURL
Import your validator private key:
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "importRawKey", "params": ["<validator_private_key>", null], "jsonrpc": "2.0", "id": 1}'
Then unlock it:
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "unlockAccount", "params": ["<address>", null, null], "jsonrpc": "2.0", "id": 1}'
Note
In case you are wondering, the null
as the second parameter is an optional password. You can set a password to lock the account when you import it, which you then need to provide during unlocking, too. The other null
as the third parameter for unlocking is an unused duration parameter, that nontheless needs to be provided.
Send a validator-creation transaction
Finally, to register your validator, run this with all the keys generated in the beginning:
ARPL
validator:new <validator_address> <signing_private_key> <voting_private_key>
Where signing_private_key
is the private key of the Schnorr keypair generated for signing_key
, and voting_private_key
is the private key of the BLS keypair generated for voting_key
.
CURL
The manual way with curl
requires a few more parameters:
- The address of the account you are sending from
- The address of the validator you are creating
- The private signing Schnorr key you generated
- The private voting BLS key you generated
- The reward payout address (can be the same as the validator address)
- Signalling data (usually empty)
- The fee for the transaction (can be zero)
- The validity start height of the transaction (+0 means the node takes the current block height)
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "sendNewValidatorTransaction", "params": ["<validator_address>", "<validator_address>", "<signing_private_key>", "<voting_secret_key>", "<reward_address>", "", 0, "+0"], "jsonrpc": "2.0", "id": 1}'
Note
Your node must have established consensus and be up-to-date with the blockchain for the transaction to send successfully. Remember, you can check your node's status with the status
command.
💡
When sending the create transaction, the validator deposit will be deducted from the wallet linked to the validator address.
Note
Validators are only selected to produce blocks at the start of every epoch (every election block), so it may take some time for your validator to be elected to produce blocks.
Query your validator state
You can now query the staking contract for your validator registration:
ARPL
validator:get <validator_address>
CURL
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "getValidatorByAddress", "params": ["<validator_address>"], "jsonrpc": "2.0", "id": 1}'
It will tell your the public keys of your registered signing and voting keys, as well as which reward address is set to receive block rewards. It'll also tell you your validator's staking balance (which should be the same as the deposit for now), how many stakers are staking with your validator (none yet) and if the validator is inactive or retired (it should not be).
Note
If the command responds with an error, your validator creation transaction was likely not successfull. You can ask for support in our Telegram channels, in our Github, or in the community forum.
Add stake to your validator
A validator itself can only maintain the validator deposit as stake. To stake more than that, you need to add stake to your validator as a staker.
Note
You can stake your NIM on behalf of any registered validator. Your staked NIM then count towards that validator's stake, increasing their (randomly) assigned number of block production slots and thus rewards. Importantly, all staking rewards are received by the validator's reward address, not the stakers. The arrangement of distributing rewards among a validator's stakers is made off-chain and is usually handled by a pool operator or the people who are operating the validator themselves.
Stake from the Nimiq Wallet
You can stake with your validator from the Nimiq Wallet. Go to the staking menu in your NIM address and search for and select your validator's address from the list of validators. Then assign as much NIM to it as you like.
Stake from your node with JSON-RPC
You can also send the staking transactions from your node with JSON-RPC. For that, you need to import and unlock the account that holds the NIM you want to stake. Then run the following command to start staking:
ARPL
stake:start <staker_address> <validator_address> <amount_NIM>
CURL
The manual way with curl
requires a few more parameters:
- The address of the account you are sending from
- The address of the staker you are creating
- The address of the validator you are delegating to
- the amount (in Luna) you want to stake
- The fee for the transaction (can be zero)
- The validity start height of the transaction (+0 means the node takes the current block height)
curl 'http://localhost:8648' -H 'Content-Type: application/json' \
--data-raw '{"method": "sendNewStakerTransaction", "params": ["<staker_address>", "<staker_address>", "<validator_address>", <amount_luna>, 0, "+0"], "jsonrpc": "2.0", "id": 1}'