Skip to content

Run an Appchain Node Using Systemd

Introduction

Running a Tanssi appchain node allows you to connect to and interact with the network using your infrastructure via either HTTP or WebSocket protocols.

Nodes store block data and network state. However, developers can run different kinds of nodes:

  • Full Archive Node - a node storing the entire block data and network state at all block heights. Such nodes are helpful when querying historical data from old blocks. However, a full archive node takes up a lot of space

  • Full Pruned Node - a node storing block data and network state up to some specific number of blocks before the current block height. Such nodes are helpful when querying recent data or submitting transactions through your infrastructure. They require much less space than an archival node but don't store the full network state

In this guide, you'll learn how to spin up a Tanssi appchain node using a binary executable file and manage the service with Systemd on Linux systems.

The article follows the good practice of running the service with its own non-root account and granting that account write access to a specific directory. However, you can adapt this article's steps and instructions to your infrastructure configuration, preferences, and security policies.

Note

It is not possible to run an RPC node for Snap appchains as they run on a private network, and their nodes are, therefore, unreachable for syncing.

Checking Prerequisites

To get started, you'll need access to a computer running an Ubuntu Linux OS and root privileges. You will also need:

  • Node binary file - the instructions in this guide execute the latest official stable node release. If you want to build and run your own file, make sure to follow the instructions for building your appchain node

  • Appchain specifications file - the appchain specification file is needed to run the node. You can download it from the dashboard in the dApp by clicking the Appchain Data link

    Getting the chain specs

  • Relay chain specifications file - the relay chain specification file can be downloaded from this public GitHub repository

Download the Latest Release

Every new release includes two node binaries, one for EVM-compatible appchains and another for Substrate appchains. To get started, run the following command to get the latest release binary that matches your appchain type and make it executable:

wget https://github.com/moondance-labs/tanssi/releases/latest/download/container-chain-template-frontier-node && \
chmod +x ./container-chain-template-frontier-node
wget https://github.com/moondance-labs/tanssi/releases/latest/download/container-chain-template-simple-node && \
chmod +x ./container-chain-template-simple-node

Note

For better performance, it is recommended that you run the optimized binary versions for either Intel's Skylake or AMD's Zen3 architectures.

Download the Relay Chain Specs File

The node binary file includes also the necessary code to run a relay chain node. When launching your appchain's node, it will also be required to provide the relay chain's specification file as a parameter.

Download the relay chain specification file by executing:

wget https://raw.githubusercontent.com/papermoonio/external-files/main/Moonbeam/Moonbase-Alpha/westend-alphanet-raw-specs.json

Setup the Systemd Service

Systemd is a management system for Linux systems that manages services (daemons in Unix-like systems jargon), starting them automatically when the computer starts or reboots, or restarting them upon unexpected failures. The following commands configure a new account, the directory, and move the previously downloaded files to the right location.

Create a new account to run the service:

adduser appchain_node_service --system --no-create-home

Create a directory to store the required files and data:

mkdir /var/lib/appchain-data

Set the folder's ownership to the account that will run the service to ensure writing permission:

sudo chown -R appchain_node_service /var/lib/appchain-data

And finally, move the binary and the relay chain spec to the folder:

mv ./container-chain-template-*-node /var/lib/appchain-data && \
mv ./westend-alphanet-raw-specs.json /var/lib/appchain-data

Note

To keep all the necessary files grouped in the same directory, it is also recommended to copy your appchain's specification file there.

Create the Systemd Service Configuration File

The next step is to create the Systemd configuration file.

You can create the file by running the following command:

sudo touch /etc/systemd/system/appchain.service

Now, you can open the file using your favorite text editor (vim, emacs, nano, etc.) and add the configuration for the service.

Note that the ExecStart command has some parameters that need to be changed to match your specific appchain:

  • Specification file - replace YOUR_APPCHAIN_SPECS_FILE_LOCATION with your appchain's absolute path. If you copied the file in the same directory as the binary file and the relay chain specs, then your path will look like /var/lib/appchain-data/YOUR_FILENAME.json, e.g., /var/lib/appchain-data/spec-raw.json
  • Bootnode - a bootnode is a full archive node that is used to sync the network from scratch. You'll need to retrieve your Tanssi appchain bootnode and replace INSERT_YOUR_APPCHAIN_BOOTNODE with the actual bootnode information
[Unit]
Description="Appchain systemd service"
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=10
User=appchain_node_service
SyslogIdentifier=appchain
SyslogFacility=local7
KillSignal=SIGHUP
ExecStart=/var/lib/appchain-data/container-chain-template-frontier-node \
--chain=YOUR_APPCHAIN_SPECS_FILE_LOCATION \
--rpc-port=9944 \
--name=para \
--base-path=/var/lib/appchain-data \
--bootnodes=INSERT_YOUR_APPCHAIN_BOOTNODE \
-- \
--chain=/var/lib/appchain-data/westend-alphanet-raw-specs.json \
--rpc-port=9945 \
--name=relay \
--sync=fast \
--bootnodes=/dns4/frag3-stagenet-relay-val-0.g.moondev.network/tcp/30334/p2p/12D3KooWKvtM52fPRSdAnKBsGmST7VHvpKYeoSYuaAv5JDuAvFCc \
--bootnodes=/dns4/frag3-stagenet-relay-val-1.g.moondev.network/tcp/30334/p2p/12D3KooWQYLjopFtjojRBfTKkLFq2Untq9yG7gBjmAE8xcHFKbyq \
--bootnodes=/dns4/frag3-stagenet-relay-val-2.g.moondev.network/tcp/30334/p2p/12D3KooWMAtGe8cnVrg3qGmiwNjNaeVrpWaCTj82PGWN7PBx2tth \
--bootnodes=/dns4/frag3-stagenet-relay-val-3.g.moondev.network/tcp/30334/p2p/12D3KooWLKAf36uqBBug5W5KJhsSnn9JHFCcw8ykMkhQvW7Eus3U \
--bootnodes=/dns4/vira-stagenet-relay-validator-0.a.moondev.network/tcp/30334/p2p/12D3KooWSVTKUkkD4KBBAQ1QjAALeZdM3R2Kc2w5eFtVxbYZEGKd \
--bootnodes=/dns4/vira-stagenet-relay-validator-1.a.moondev.network/tcp/30334/p2p/12D3KooWFJoVyvLNpTV97SFqs91HaeoVqfFgRNYtUYJoYVbBweW4 \
--bootnodes=/dns4/vira-stagenet-relay-validator-2.a.moondev.network/tcp/30334/p2p/12D3KooWP1FA3dq1iBmEBYdQKAe4JNuzvEcgcebxBYMLKpTNirCR \
--bootnodes=/dns4/vira-stagenet-relay-validator-3.a.moondev.network/tcp/30334/p2p/12D3KooWDaTC6H6W1F4NkbaqK3Ema3jzc2BbhE2tyD3YEf84yNLE 

[Install]
WantedBy=multi-user.target
[Unit]
Description="Appchain systemd service"
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=10
User=appchain_node_service
SyslogIdentifier=appchain
SyslogFacility=local7
KillSignal=SIGHUP
ExecStart=/var/lib/appchain-data/container-chain-template-simple-node \
--chain=YOUR_APPCHAIN_SPECS_FILE_LOCATION \
--rpc-port=9944 \
--name=para \
--base-path=/var/lib/appchain-data \
--bootnodes=INSERT_YOUR_APPCHAIN_BOOTNODE \
-- \
--chain=/var/lib/appchain-data/westend-alphanet-raw-specs.json \
--rpc-port=9945 \
--name=relay \
--sync=fast \
--bootnodes=/dns4/frag3-stagenet-relay-val-0.g.moondev.network/tcp/30334/p2p/12D3KooWKvtM52fPRSdAnKBsGmST7VHvpKYeoSYuaAv5JDuAvFCc \
--bootnodes=/dns4/frag3-stagenet-relay-val-1.g.moondev.network/tcp/30334/p2p/12D3KooWQYLjopFtjojRBfTKkLFq2Untq9yG7gBjmAE8xcHFKbyq \
--bootnodes=/dns4/frag3-stagenet-relay-val-2.g.moondev.network/tcp/30334/p2p/12D3KooWMAtGe8cnVrg3qGmiwNjNaeVrpWaCTj82PGWN7PBx2tth \
--bootnodes=/dns4/frag3-stagenet-relay-val-3.g.moondev.network/tcp/30334/p2p/12D3KooWLKAf36uqBBug5W5KJhsSnn9JHFCcw8ykMkhQvW7Eus3U \
--bootnodes=/dns4/vira-stagenet-relay-validator-0.a.moondev.network/tcp/30334/p2p/12D3KooWSVTKUkkD4KBBAQ1QjAALeZdM3R2Kc2w5eFtVxbYZEGKd \
--bootnodes=/dns4/vira-stagenet-relay-validator-1.a.moondev.network/tcp/30334/p2p/12D3KooWFJoVyvLNpTV97SFqs91HaeoVqfFgRNYtUYJoYVbBweW4 \
--bootnodes=/dns4/vira-stagenet-relay-validator-2.a.moondev.network/tcp/30334/p2p/12D3KooWP1FA3dq1iBmEBYdQKAe4JNuzvEcgcebxBYMLKpTNirCR \
--bootnodes=/dns4/vira-stagenet-relay-validator-3.a.moondev.network/tcp/30334/p2p/12D3KooWDaTC6H6W1F4NkbaqK3Ema3jzc2BbhE2tyD3YEf84yNLE 

[Install]
WantedBy=multi-user.target

Fetching Bootnode Information

Bootnode information can be read directly from Tanssi itself. For example, you can use the Polkadot.js explorer to get the bootnodes for a specific appchain in the Dancebox TestNet.

To do so, take the following steps:

  1. Select dataPreservers as the module to query
  2. Set the storage query to bootNodes
  3. Provide your Tanssi appchain ID
  4. Click on the + sign

Getting the bootnode

Full Node Configuration Example for the Demo EVM Appchain

The following example deploys a fully functional full archive node for the demo EVM appchain deployed on Dancebox with an ID of 3001.

The raw chain specification file for the demo appchain is required to run the node, and can be downloaded from this public GitHub repository. Download the file and place it in the /var/lib/appchain-data/ directory.

[Unit]
Description="Appchain systemd service"
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=10
User=appchain_node_service
SyslogIdentifier=appchain
SyslogFacility=local7
KillSignal=SIGHUP
ExecStart=/var/lib/appchain-data/container-chain-template-frontier-node \
--chain=/var/lib/appchain-data/container-3001-raw-specs.json \
--rpc-port=9944 \
--name=para \
--state-pruning=archive \
--blocks-pruning=archive \
--base-path=/var/lib/appchain-data \
--bootnodes=/dns4/fraa-dancebox-3001-rpc-0.a.dancebox.tanssi.network/tcp/30333/p2p/12D3KooWQ9jVpatqmWS41Zf6PHncV4ZmEYvywifRTs9YVoz8HgTM \
-- \
--chain=/var/lib/appchain-data/westend-alphanet-raw-specs.json \
--rpc-port=9945 \
--name=relay \
--sync=fast \
--bootnodes=/dns4/frag3-stagenet-relay-val-0.g.moondev.network/tcp/30334/p2p/12D3KooWKvtM52fPRSdAnKBsGmST7VHvpKYeoSYuaAv5JDuAvFCc \
--bootnodes=/dns4/frag3-stagenet-relay-val-1.g.moondev.network/tcp/30334/p2p/12D3KooWQYLjopFtjojRBfTKkLFq2Untq9yG7gBjmAE8xcHFKbyq \
--bootnodes=/dns4/frag3-stagenet-relay-val-2.g.moondev.network/tcp/30334/p2p/12D3KooWMAtGe8cnVrg3qGmiwNjNaeVrpWaCTj82PGWN7PBx2tth \
--bootnodes=/dns4/frag3-stagenet-relay-val-3.g.moondev.network/tcp/30334/p2p/12D3KooWLKAf36uqBBug5W5KJhsSnn9JHFCcw8ykMkhQvW7Eus3U \
--bootnodes=/dns4/vira-stagenet-relay-validator-0.a.moondev.network/tcp/30334/p2p/12D3KooWSVTKUkkD4KBBAQ1QjAALeZdM3R2Kc2w5eFtVxbYZEGKd \
--bootnodes=/dns4/vira-stagenet-relay-validator-1.a.moondev.network/tcp/30334/p2p/12D3KooWFJoVyvLNpTV97SFqs91HaeoVqfFgRNYtUYJoYVbBweW4 \
--bootnodes=/dns4/vira-stagenet-relay-validator-2.a.moondev.network/tcp/30334/p2p/12D3KooWP1FA3dq1iBmEBYdQKAe4JNuzvEcgcebxBYMLKpTNirCR \
--bootnodes=/dns4/vira-stagenet-relay-validator-3.a.moondev.network/tcp/30334/p2p/12D3KooWDaTC6H6W1F4NkbaqK3Ema3jzc2BbhE2tyD3YEf84yNLE 

[Install]
WantedBy=multi-user.target

Run Flags

The flags used in the ExecStart 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 appchain state should be removed from the database. The pruning type can be either archive (which makes the node behave as a full node keeping all the state), archive-canonical (which keeps only the state of finalized blocks), or any number (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 either archive (which makes the node behave as a full node keeping all the blocks), archive-canonical (which keeps only finalized blocks), or any number (representing the amount of finalized blocks to keep)
  • --detailed-log-output - enables detailed log output

For a complete list of available flags, their description, and possible values, run the following command:

/var/lib/appchain-data/container-chain-template-frontier-node --help
/var/lib/appchain-data/container-chain-template-simple-node --help

Run the Service

Finally, enable the service and start it for the first time:

systemctl enable appchain.service && \
systemctl start appchain.service

You can verify that the service is up and running correctly running:

systemctl status appchain.service
systemctl status appchain.service
● appchain.service - "Appchain systemd service"
   Loaded: loaded (/etc/systemd/system/appchain.service; enabled; vendor preset: enabled)
   Active: active (running) since Sun 2024-02-18 18:16:40 EST; 14min ago
  Main PID: 4045278 (container-chain)
    Tasks: 44 (limit: 9462)
   Memory: 6.5G
   CGroup: /system.slice/appchain.service
           └─4045278 4045278 /var/lib/appchain-data/container-chain- ...

And check the logs, if needed, with the following command:

journalctl -f -u appchain.service
journalctl -f -u appchain.service
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 Parachain Collator Template
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 ✌️ version 0.1.0-3b1fbbfdfe7
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 ❤️ by Moondance Labs,
2020-2024
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 📋 Chain specification: Frontier Container 3001
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 🏷 Node name: para
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 👤 Role: FULL
Feb 19 20:05:53 tutorials appchain[4066765]: 2024-02-19 20:05:53 💾 Database: RocksDb at /var/lib/appchain-data/chains/frontier_container_3001/db/full
Feb 19 20:05:57 tutorials appchain[4066765]: 2024-02-19 20:05:57 Parachain id: Id(3001)
Feb 19 20:05:57 tutorials appchain[4066765]: 2024-02-19 20:05:57 Parachain Account: 5Ec4AhPQLGvfWywVhJZwufTDvknLT3BVPQcbV977JmBDUsHP
Feb 19 20:05:57 tutorials appchain[4066765]: 2024-02-19 20:05:57 Parachain genesis state V0: 0x000000000000000000000000000000000000000000000000000000000000000000e1324cc53e66
Feb 19 20:05:57 tutorials appchain[4066765]: 2024-02-19 20:05:57 Parachain genesis state V1: 0x000000000000000000000000000000000000000000000000000000000000000000327cfde8482b
Last update: March 21, 2024
| Created: February 16, 2024