Skip to main content

Running a Node

This guide will demonstrate how to setup and run a node that connects and synchronises with The Root Network blockchain. You can use your node as backend service for you dapps or participate in securing the network by producing blocks as validator node.

Types of Nodes

A blockchain's growth comes from a genesis block, extrinsics, and events.

When a validator seals block 1, it takes the blockchain's state at block 0. Subsequently, it then applies all pending changes on top of it and emits the events resulting from these changes. The chain’s state at block 1 is used the same way to build the chain’s state at block 2, and so on. When two-thirds of the validators agree on a specific block being valid, it is finalized.

A full node prunes historical states: all finalized blocks' states older than a configurable number except the genesis block's state. This is 256 blocks from the last finalized one by default. A pruned node this way requires much less space than an archive node - around 50GB depending on number of transactions within the 256 block range.

An archive node keeps all the past blocks and their states. An archive node makes it convenient to query the past state of the chain at any point in time. Finding out what an account's balance at a particular block was or which extrinsics resulted in a specific state change are fast operations when using an archive node. However, an archive node takes up a lot of disk space - around 500GB to 1TB depending on the number of blocks.

A validator node is a full node that is responsible for creating new blocks and validating transactions. These nodes play a crucial role in securing the network and reaching consensus on the state of the blockchain.

Run a Full Node with Docker

Use the latest TRN docker image to get your full node started quickly.

# Root Mainnet
docker run \
-p 9933:9933 -p 9944:9944 \
--name=root-full-node \
--volume=root-full-node:/root \
ghcr.io/futureversecom/seed:latest \
--chain=root \
--name="My Root Full Node" \
--sync=warp

# Porcini Testnet
docker run \
-p 9933:9933 -p 9944:9944 \
--name=porcini-full-node \
--volume=porcini-full-node:/root \
ghcr.io/futureversecom/seed:latest \
--chain=porcini \
--name="My Porcini Full Node" \
--sync=warp

The 9944 port mapping is for WebSocket endpoint, and 9933 is for HTTP endpoint. You only need the port mapping if you want to use your node as backend node for your dapps.

Run a Full Node from Source

First, install Rust. You may need to add Cargo's bin directory to your PATH environment variable.

curl https://sh.rustup.rs -sSf | sh

If you already have Rust installed, ensure you are using the latest version by running:

rustup update

Build the client by cloning this repository and running the following commands from the root directory of the repository:

git clone https://github.com/futureversecom/trn-seed trn-seed
cd trn-seed
cargo build --release

After the source code is built successfully, you can start your full node with the following command:

# Root Mainnet
./target/release/seed --chain=root --name="My Root Full Node"

# Porcini Testnet
./target/release/seed --chain=porcini --name="My Porcini Full Node"

Run an Archive Node

The instructions above will have your node running as a full node, to establish an archive node you will need to follow a few additional steps.

  1. Download the latest snapshot.
# Root Mainnet
BASE_URL="https://s3.ap-southeast-2.amazonaws.com/snapshots.cicd.rootnet.app/snapshots/archive.rootnet" && \
wget "$BASE_URL/`curl "$BASE_URL/latest-snapshot.txt"`"

# Porcini Testnet
BASE_URL="https://s3.ap-southeast-2.amazonaws.com/snapshots.cicd.rootnet.app/snapshots/archive.porcini" && \
wget "$BASE_URL/`curl "$BASE_URL/latest-snapshot.txt"`"
  1. Extract the snapshot to your node's data directory.

  2. Before running your node, include the following flags, ensuring that the --base-path points to the directory where the snapshot was extracted.

seed ... --state-pruning=archive --block-pruning=archive --base-path=<snapshot-path> --sync=full

Run a RPC Node

The fllowing flags will enable the RPC mode for your node, regardless of whether it's full or archive node.

seed ... --rpc-max-connections=100 --rpc-cors=all --rpc-methods=Safe

Secure the RPC Node

The node startup settings allow you to choose what to expose, how many connections to expose, and from where access should be granted through the RPC server.

  • How many: You can set your maximum connections using --rpc-max-connections; for example, --rpc-max-connections=100.

  • From where: By default, only localhost is allowed to access the RPC server. You can change this by setting --rpc-cors; to allow access from everywhere, use --rpc-cors=all.

  • And what: You can limit the methods available by using --rpc-methods. An easy way to set this to a safe mode is --rpc-methods=Safe.

Secure the WebSocket Port

To safely access your WebSocket (ws) connection over an SSL-enabled connection, you must convert the ws connection to a secure (wss) connection. This can be achieved by utilizing a proxy along with an SSL certificate.

Run a Validator Node

A validator node is essentially a full node with additional flags enabled to participate in securing the network by producing new blocks and validate transactions. For a comprehensive guide on how to become a validator, go here.

seed ... --validator \
--telemetry-url="wss://telemetry.rootnet.app:9443/submit 0" \
--sync=warp \
--name="My Validator Node"
info

Make sure you pick a unique value for the --name flag so you can identify your node on the Telemetry Hub.

If you are running the validator node in the Docker environment, make sure you have the correct volume mapping to make it easier to upgrade your node client version in the future without the need to re-sync the blocks again.

docker run \
--name=root-validator \
--volume=root-validator:/root \
ghcr.io/futureversecom/seed:latest ...

Useful Flags

There are a few useful flags that you can play around with to improve your node performance in various aspects.

Sync Mode

--sync <SYNC_MODE>
Blockchain syncing mode.
- `full`: Download and validate full blockchain history (default).
- `fast`: Download blocks and the latest state only.
- `fast-unsafe`: Same as `fast`, but skip downloading state proofs.
- `warp`: Download the latest state and proof.

It's recommended to use --synce=warp mode for full node and validator node as it can speed up the syncing process significantly.

Runtime Caching

--runtime-cache-size <RUNTIME_CACHE_SIZE>
Maximum number of different runtimes that can be cached

[default: 2]

--max-runtime-instances <MAX_RUNTIME_INSTANCES>
The size of the instances cache for each runtime.

The default value is 8 and the values higher than 256 are ignored.

Play around with different values of these flags to improve your node read performance.

Telemetry

--telemetry-url <URL VERBOSITY>
The URL of the telemetry server to connect to.

This flag can be passed multiple times as a means to specify multiple telemetry
endpoints. Verbosity levels range from 0-9, with 0 denoting the least verbosity.
Expected format is 'URL VERBOSITY', e.g. `--telemetry-url 'wss://foo/bar 0'`.

Add the following flags to enable telemetry reporting of your node on our official Telemetry Hub.

seed --telemetry-url="wss://telemetry.rootnet.app:9443/submit 0"

Known Issues

Peers connection intermittently drops to 0

The Root Network protocol uses libp2p to discover peer nodes that your node can connect to exchange and synchronise block information.

In case libp2p is not working as expected, you can try adding the --reserved-nodes args, as following, to your node run command to bootstrap it with a list of well-known boot nodes.

--reserved-nodes=/dns4/bootnode-0.root.rootnet.app/tcp/30333/p2p/12D3KooWAodjLARKrnfRsrKHfirjLqwve29mCzGoxmNqyo8eZSaw \
--reserved-nodes=/dns4/bootnode-1.root.rootnet.app/tcp/30333/p2p/12D3KooWMq7JM1AHdBr8Er3W71tztrLRya7SxLxK9E4JDu5Y1v82 \
--reserved-nodes=/dns4/bootnode-2.root.rootnet.app/tcp/30333/p2p/12D3KooWNRgQ8dorrfUdMFsr2BWNfk2tQd6Du9J15bSYkNxEcxCN \
--reserved-nodes=/dns4/bootnode-3.root.rootnet.app/tcp/30333/p2p/12D3KooWNngaW3a8Tjj9YfnhdzZa5TD7wpw1H8yq6x9HXNWQicX2 \
--reserved-nodes=/dns4/bootnode-4.root.rootnet.app/tcp/30333/p2p/12D3KooWHyaa2gV3PMXHNP2FuKRNhc1pyP9k5rCCuVkMrk5NsRqQ \
--reserved-nodes=/dns4/bootnode-5.root.rootnet.app/tcp/30333/p2p/12D3KooWPrpHKB5gkr16LCnRAUGcXwUN9ZiVczc3tqEAyTqg8oYS \
--reserved-nodes=/dns4/bootnode-6.root.rootnet.app/tcp/30333/p2p/12D3KooWRHjF27MLP7uxtPdx3qLVug4kutMuthvQttPy86LwJoca \
--reserved-nodes=/dns4/bootnode-7.root.rootnet.app/tcp/30333/p2p/12D3KooWSBt3LgCgFWdoNJdrYwo1T7dMjskimcVbCMuVjnQ14vQP \
--reserved-nodes=/dns4/bootnode-8.root.rootnet.app/tcp/30333/p2p/12D3KooWB9tZgZnypsE5zZ1E2255F12duh7Cu5Mqnx7dsc7Abk4S \
--reserved-nodes=/dns4/bootnode-9.root.rootnet.app/tcp/30333/p2p/12D3KooWLVitcGm9hFFGtzpTmgYLWNbG1k8wJBqNkULbubWzZAEy

Once the run command is updated, please restart your node and let it run for a few hours and see if the peers count is stabilized.