Run a Sequencer in Tanssi Using Docker¶
Introduction¶
One of Tanssi's core propositions is that it provides decentralized and trustless block production for its networks. Tanssi's runtime handles sequencer assignments to all the active networks in the Tanssi ecosystem.
Each time, the assignment algorithm distributes the available set of sequencers per session, assigning them to a random chain. Consequently, they would be producing blocks for the same network only for a relatively short period, increasing the overall security of the ecosystem.
To this end, Tanssi's binary file (the software used to run nodes) already has an embedded mechanism to switch block production automatically to the assigned chain without requiring the node operator to make any changes. The binary includes the logic to sync the new chain and produce blocks when the session changes. Consequently, sequencers need to run the Tanssi binary file, and not that of the networks (like full nodes do).
In this guide, you'll learn how to spin up a Tanssi sequencer to be part of the shared pool of sequencers using Docker on a Linux computer. However, it can be adapted to other operating systems.
Checking Prerequisites¶
Installing Docker¶
To get started, you'll need access to a computer running a Linux OS and install Docker.
Run the following command to install Docker on a Linux Ubuntu platform:
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
And the following command to check the installation:
sudo docker run hello-world
This is what a successful execution in the terminal looks like:
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Pulling the Docker Image¶
A Docker image is built and published in every release, containing all the necessary dependencies a Tanssi sequencer requires and the binary file itself.
A Docker image combines the binary corresponding to the latest stable release of the client node, along with the Tanssi orchestrator specification file.
The following command to pull the Docker image:
docker pull moondancelabs/tanssi
The command will download and extract the image and show the status upon execution:
Using default tag: latest
latest: Pulling from moondancelabs/dancelight-collators:2
e1caac4eb9d2: Pull complete
1d4409959e6d: Pull complete
b8beed19c122: Pull complete
c0fab1f18601: Pull complete
d9dcf3cddfc5: Pull complete
Digest: sha256:0f717d6cf247bbb1b082f5f9e5761b23c44a0be8b704492a57fdbf8c63c0a91c
Status: Downloaded newer image for moondancelabs/dancelight-collators:2
docker.io/moondancelabs/dancelight-collators:2
Setup the Data Directory¶
Running a sequencer requires syncing with two chains: the Tanssi chain and the network it has been assigned to.
Run the following command to create the directory where your sequencer will store the databases containing blocks and chain states:
mkdir /var/lib/dancebox
Set the folder's ownership to the account that will run the Docker image to ensure writing permission:
chown INSERT_DOCKER_USER /var/lib/dancebox
Or run the following command if you want to run the sequencer with the current logged-in user:
sudo chown -R $(id -u):$(id -g) /var/lib/dancebox
Note
The directory is a parameter in the Docker start-up command. If you decide to create the directory elsewhere, update the command accordingly.
Generate the Node Key¶
Starting from runtime 700 release, Tanssi sequencer nodes don't generate the session keys automatically on start-up. To generate and store on disk the session keys that will be referenced on the start-up command, run the following command:
docker run --entrypoint bash --network="host" -v "/var/lib/dancebox:/data" \
-u $(id -u ${USER}):$(id -g ${USER}) \
moondancelabs/tanssi -c "/chain-network/tanssi-node key generate-node-key --file /data/node-key"
Note
This step could be avoided using the --unsafe-force-node-key-generation
parameter in the start-up command, although this is not the recommended practice.
Start-Up Command¶
To spin up your node, you must run the Docker image with the docker run
command.
Note that the command contains two sections, divided by -- \
:
- Tanssi protocol section - it contains the flags to run the Tanssi node
- Sequencer section - it contains the flags to run the sequencer node. It is abstract enough to be dynamically adapted in runtime to the specific chain the node will serve
Name each of the sections with a human-readable name by replacing the INSERT_YOUR_TANSSI_NODE_NAME
and INSERT_YOUR_SEQUENCER_NODE_NAME
tags in the --name
flags. These names will come in handy for connecting the log entries and metrics with the node that generates them.
Note
It is recommended that you run the optimized binary versions for either Intel's Skylake or AMD's Zen3 architectures for better performance.
docker run --entrypoint bash --network="host" -v "/var/lib/dancebox:/data" \
-u $(id -u ${USER}):$(id -g ${USER}) \
moondancelabs/tanssi -c "/chain-network/tanssi-node solo-chain \
--name=INSERT_YOUR_SEQUENCER_NODE_NAME \
--base-path=/data/container \
--node-key-file=/data/node-key \
--keystore-path=/data/keys/session \
--telemetry-url='wss://telemetry.polkadot.io/submit/ 0' \
--pool-type=fork-aware \
--database=paritydb \
--rpc-port=9944 \
--rpc-cors=all \
--rpc-max-connections 100 \
--unsafe-rpc-external \
--rpc-methods=unsafe \
--prometheus-port=9615 \
--prometheus-external \
--listen-addr=/ip4/0.0.0.0/tcp/30333 \
--state-pruning=2000 \
--blocks-pruning=2000 \
--db-cache=1024 \
--trie-cache-size=1073741824 \
--collator \
--in-peers=100 \
--detailed-log-output \
-- \
--chain=/chain-network/relay-raw-no-bootnodes-specs.json \
--name=INSERT_YOUR_TANSSI_NODE_NAME \
--sync=fast \
--base-path=/data/relay \
--node-key-file=/data/node-key \
--database=paritydb \
--rpc-port=9945 \
--rpc-cors=all \
--rpc-methods=safe \
--unsafe-rpc-external \
--prometheus-port=9616 \
--prometheus-external \
--listen-addr=/ip4/0.0.0.0/tcp/30334 \
--pool-limit=0 \
--db-cache=128 \
--out-peers=15 \
--state-pruning=2000 \
--blocks-pruning=2000 \
--telemetry-url='wss://telemetry.polkadot.io/submit/ 0' \
--bootnodes=/dns4/qco-dancelight-boot-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWCekAqk5hv2fZprhqVz8povpUKdJEiHSd3MALVDWNPFzY \
--bootnodes=/dns4/qco-dancelight-rpc-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWEwhUb3tVR5VhRBEqyH7S5hMpFoGJ9Anf31hGw7gpqoQY \
--bootnodes=/dns4/ukl-dancelight-rpc-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWPbVtdaGhcuDTTQ8giTUtGTEcUVWRg8SDWGdJEeYeyZcT"
docker run --entrypoint bash --network="host" -v "/var/lib/dancebox:/data" \
-u $(id -u ${USER}):$(id -g ${USER}) \
moondancelabs/tanssi -c "/chain-network/tanssi-node-skylake solo-chain \
--name=INSERT_YOUR_SEQUENCER_NODE_NAME \
--base-path=/data/container \
--node-key-file=/data/node-key \
--keystore-path=/data/keys/session \
--telemetry-url='wss://telemetry.polkadot.io/submit/ 0' \
--pool-type=fork-aware \
--database=paritydb \
--rpc-port=9944 \
--rpc-cors=all \
--rpc-max-connections 100 \
--unsafe-rpc-external \
--rpc-methods=unsafe \
--prometheus-port=9615 \
--prometheus-external \
--listen-addr=/ip4/0.0.0.0/tcp/30333 \
--state-pruning=2000 \
--blocks-pruning=2000 \
--db-cache=1024 \
--trie-cache-size=1073741824 \
--collator \
--in-peers=100 \
--detailed-log-output \
-- \
--chain=/chain-network/relay-raw-no-bootnodes-specs.json \
--name=INSERT_YOUR_TANSSI_NODE_NAME \
--sync=fast \
--base-path=/data/relay \
--node-key-file=/data/node-key \
--database=paritydb \
--rpc-port=9945 \
--rpc-cors=all \
--rpc-methods=safe \
--unsafe-rpc-external \
--prometheus-port=9616 \
--prometheus-external \
--listen-addr=/ip4/0.0.0.0/tcp/30334 \
--pool-limit=0 \
--db-cache=128 \
--out-peers=15 \
--state-pruning=2000 \
--blocks-pruning=2000 \
--telemetry-url='wss://telemetry.polkadot.io/submit/ 0' \
--bootnodes=/dns4/qco-dancelight-boot-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWCekAqk5hv2fZprhqVz8povpUKdJEiHSd3MALVDWNPFzY \
--bootnodes=/dns4/qco-dancelight-rpc-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWEwhUb3tVR5VhRBEqyH7S5hMpFoGJ9Anf31hGw7gpqoQY \
--bootnodes=/dns4/ukl-dancelight-rpc-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWPbVtdaGhcuDTTQ8giTUtGTEcUVWRg8SDWGdJEeYeyZcT"
```bash docker run --network="host" -v "/var/lib/dancebox:/data" \ moondancelabs/tanssi -c "/chain-network/tanssi-node-znver3 solo-chain \ --name=INSERT_YOUR_SEQUENCER_NODE_NAME \ --base-path=/data/container \ --node-key-file=/data/node-key \ --keystore-path=/data/keys/session \ --telemetry-url='wss://telemetry.polkadot.io/submit/ 0' \ --pool-type=fork-aware \ --database=paritydb \ --rpc-port=9944 \ --rpc-cors=all \ --rpc-max-connections 100 \ --unsafe-rpc-external \ --rpc-methods=unsafe \ --prometheus-port=9615 \ --prometheus-external \ --listen-addr=/ip4/0.0.0.0/tcp/30333 \ --state-pruning=2000 \ --blocks-pruning=2000 \ --db-cache=1024 \ --trie-cache-size=1073741824 \ --collator \ --in-peers=100 \ --detailed-log-output \ -- \ --chain=/chain-network/relay-raw-no-bootnodes-specs.json \ --name=INSERT_YOUR_TANSSI_NODE_NAME \ --sync=fast \ --base-path=/data/relay \
--node-key-file=/data/node-key \ --database=paritydb \ --rpc-port=9945 \ --rpc-cors=all \ --rpc-methods=safe \ --unsafe-rpc-external \ --prometheus-port=9616 \ --prometheus-external \ --listen-addr=/ip4/0.0.0.0/tcp/30334 \ --pool-limit=0 \ --db-cache=128 \ --out-peers=15 \ --state-pruning=2000 \ --blocks-pruning=2000 \ --telemetry-url='wss://telemetry.polkadot.io/submit/ 0' \ --bootnodes=/dns4/qco-dancelight-boot-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWCekAqk5hv2fZprhqVz8povpUKdJEiHSd3MALVDWNPFzY \ --bootnodes=/dns4/qco-dancelight-rpc-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWEwhUb3tVR5VhRBEqyH7S5hMpFoGJ9Anf31hGw7gpqoQY \ --bootnodes=/dns4/ukl-dancelight-rpc-1.rv.dancelight.tanssi.network/tcp/30334/p2p/12D3KooWPbVtdaGhcuDTTQ8giTUtGTEcUVWRg8SDWGdJEeYeyZcT"
Run Flags¶
The flags used in the docker run
command can be adjusted according to your preferences and hardware configuration. The following ones are some of the most note-worthy:
--name INSERT_NAME
- a human-readable name for this node--rpc-port INSERT_PORT
- specifies the JSON-RPC TCP port the node listens on--unsafe-rpc-external
- exposes the RPC service on all the interfaces--state-pruning INSERT_STATE_PRUNING_TYPE
- specifies when the Tanssi-powered network state should be removed from the database. The pruning type can be eitherarchive
(which makes the node behave as a full node keeping all the state),archive-canonical
(which keeps only the state of finalized blocks), or anynumber
(representing the number of blocks whose states are kept)--blocks-pruning INSERT_BLOCKS_PRUNING_TYPE
- specifies how many blocks should be kept in the database. The pruning type can be eitherarchive
(which makes the node behave as a full node keeping all the blocks),archive-canonical
(which keeps only finalized blocks), or anynumber
(representing the amount of finalized blocks to keep)--detailed-log-output
- enables detailed log output
Warning
The --unsafe-rpc-external
enables external access to your node’s RPC interface, making it accessible from any IP address. Make sure that proper security controls are in place.
For a complete list of available flags, their description, and possible values, run the following command:
docker run --entrypoint bash moondancelabs/tanssi -c "/chain-network/tanssi-node --help"
Syncing Your Node¶
The first time your node spins up, the syncing process displays lots of log information from the node configuration and the node itself. Some errors are expected to be displayed at the beginning of the process, disappearing once the chain gets synced to the last block.
2024-02-08 18:30:04.093 INFO tokio-runtime-worker substrate: [Parachain] 💤 Idle (0 peers), best: #0 (0x4a2b…7de3), finalized #0 (0x4a2b…7de3), ⬇ 0 ⬆ 0
2024-02-08 18:30:06.368 INFO tokio-runtime-worker substrate: [Relaychain] ✨ Imported #14139635 (0x8c41…8df6)
2024-02-08 18:30:08.809 INFO tokio-runtime-worker substrate: [Relaychain] 💤 Idle (8 peers), best: #14139635 (0x8c41…8df6), finalized #14139632 (0xa9a8…cab9), ⬇ 32.7kiB/s ⬆
When the syncing with the Tanssi orchestrator is finished, the node will still need to sync with the network it has been assigned to. The syncing with the chain served by the sequencer node will happen every time the sequencer is rotated.
| Created: February 10, 2024