Avail has been a project on my radar for some time now and I am excited to see they are starting their incentivized test net with Clash of Nodes. I put together this quick overview of how to spin up a node to participate in the event.
Commands have been updated for mainnet
Since Avail is a substrate-based network any experience or automation for any other network will carry over. We can refer to the system requirements so we have an idea of what we need. I wrote a longer blog post about physical hardware requirements for substrate nodes if you need more details.
There are 2 options for deployment Binaries or Docker. Since this guide is focused on a low barrier to entry we will focus on using a pre-built binary and leveraging systemd. Since this is a test net I am not opposed to running this node in your home either.
In this guide, we will be using an Ubuntu 22.04 LTS for the OS. Once you have your machine and have connected via SSH we will begin with setting up a service account and file system with permissions.
adduser --system --no-create-home --shell=/bin/nologin avail
addgroup avail
usermod -a -G avail avail
mkdir /opt/avail
chown avail:avail /opt/avail
chmod 770 /opt/avail
chmod g+s /opt/avail
You probably want to enable a firewall if you are running on physical hardware or don’t have a cloud-native firewall object to warp around the machine:
ufw allow ssh
ufw allow 30333
ufw --force enable
Next, we will download and set up the Avail binary:
curl -o /tmp/amd64-ubuntu-2204-avail-node.tar.gz -LJ https://github.com/availproject/avail/releases/download/v2.2.4.2/x86_64-ubuntu-2204-avail-node.tar.gz
tar -xvzf /tmp/amd64-ubuntu-2204-avail-node.tar.gz -C /usr/local/bin/
chown avail:avail /usr/local/bin/avail-node
chmod +x /usr/local/bin/avail-node
avail-node --version
Now check if your server is powerful enough to run the application:
/usr/local/bin/avail-node benchmark machine --chain mainnet
This should return all green and over 100%. If not find another VPS.
We will next create the systemd unit file, which will be used to make sure the binary keeps running and will restart on a reboot:
tee /etc/systemd/system/availd.service >> /dev/null <<'EOF'
[Unit]
Description=Avail Validator
After=network.target
StartLimitIntervalSec=0
[Service]
User=avail
Group=avail
Restart=always
RestartSec=120
ExecStart=/usr/local/bin/avail-node \
--base-path /opt/avail \
--state-pruning 1000 \
--chain mainnet \
--validator \
--name STKD-IS-AWESOME \
--port 30333 \
--rpc-port 9944 \
--prometheus-port 9615 \
--in-peers 40 \
--out-peers 40 \
--telemetry-url 'ws://telemetry.avail.tools:8001/submit/ 0'
[Install]
WantedBy=multi-user.target
EOF
You will want to update the name from STKD-IS-AWESOME to what you want the node called.
We are setting the chain data to be stored at: /opt/avail
We set the libp2p port: 30333 (This is the port we use to find other nodes)
The rpc port is exposed on: 9944
If you want to monitor the service the prometheus metrics are on port 9615.
Next, we will enable and start the service and watch the logs as the node syncs:
systemctl daemon-reload
systemctl enable availd.service
systemctl start availd.service
journalctl -efu availd.service
You should see the following output:
root@localhost:/tmp# journalctl -efu availd.service
Nov 10 21:41:08 localhost systemd[1]: Started Avail Validator.
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 Avail Node
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 ✌️ version 1.8.0-9c5f37b9230
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 ❤️ by Anonymous, 2017-2023
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 📋 Chain specification: Avail Goldberg Testnet
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 🏷 Node name: STKD-IS-AWESOME
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 👤 Role: AUTHORITY
Nov 10 21:41:08 localhost data-avail[1281]: 2023-11-10 21:41:08 💾 Database: RocksDb at /opt/avail/chains/avail_goldberg_testnet/db/full
Nov 10 21:41:12 localhost data-avail[1281]: 2023-11-10 21:41:12 🔨 Initializing Genesis block/state (state: 0x6bc7…ec83, header-hash: 0x6f09…a7ae)
Nov 10 21:41:12 localhost data-avail[1281]: 2023-11-10 21:41:12 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 👶 Creating empty BABE epoch changes on what appears to be first startup.
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 🏷 Local node identity is: 12D3KooWQJac44ubPnBS8uwdutKtSEksmc4Y2NFvGdG1MeWDA7xu
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 Prometheus metrics extended with avail metrics
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 Operating system: linux
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 CPU architecture: x86_64
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 Target environment: gnu
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 CPU: AMD EPYC 7713 64-Core Processor
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 CPU cores: 4
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 Memory: 7937MB
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 Kernel: 5.15.0-83-generic
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 Linux distribution: Ubuntu 22.04.3 LTS
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 💻 Virtual machine: yes
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 📦 Highest known block at #0
Nov 10 21:41:13 localhost data-avail[1281]: 2023-11-10 21:41:13 〽️ Prometheus exporter started at 127.0.0.1:9615
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 Running JSON-RPC server: addr=127.0.0.1:9944, allowed origins=["http://localhost:*", "http://127.0.0.1:*", "https://localhost:*", "https://127.0.0.1:*", "https://polkadot.js.org"]
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 🏁 CPU score: 914.62 MiBs
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 🏁 Memory score: 19.65 GiBs
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 🏁 Disk score (seq. writes): 2.54 GiBs
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 🏁 Disk score (rand. writes): 982.56 MiBs
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 👶 Starting BABE Authorship worker
Nov 10 21:41:14 localhost data-avail[1281]: 2023-11-10 21:41:14 🔍 Discovered new external address for our node: /ip4/172.234.30.47/tcp/30333/p2p/12D3KooWQJac44ubPnBS8uwdutKtSEksmc4Y2NFvGdG1MeWDA7xu
Nov 10 21:41:15 localhost data-avail[1281]: 2023-11-10 21:41:15 🔍 Discovered new external address for our node: /ip6/2600:3c06::f03c:93ff:fe61:b5e3/tcp/30333/p2p/12D3KooWQJac44ubPnBS8uwdutKtSEksmc4Y2NFvGdG1MeWDA7xu
Nov 10 21:41:19 localhost data-avail[1281]: 2023-11-10 21:41:19 ⚙️ Syncing, target=#14329 (8 peers), best: #19 (0x0f58…3fa7), finalized #0 (0x6f09…a7ae), ⬇ 314.7kiB/s ⬆ 46.8kiB/s
Nov 10 21:41:24 localhost data-avail[1281]: 2023-11-10 21:41:24 ⚙️ Syncing 4.6 bps, target=#14330 (8 peers), best: #42 (0x8a1a…c672), finalized #0 (0x6f09…a7ae), ⬇ 19.4kiB/s ⬆ 8.1kiB/s
Nov 10 21:41:29 localhost data-avail[1281]: 2023-11-10 21:41:29 ⚙️ Syncing 4.6 bps, target=#14330 (8 peers), best: #65 (0x5356…b9f7), finalized #0 (0x6f09…a7ae), ⬇ 18.0kiB/s ⬆ 6.4kiB/s
Nov 10 21:41:34 localhost data-avail[1281]: 2023-11-10 21:41:34 ⚙️ Syncing 4.4 bps, target=#14330 (8 peers), best: #87 (0x4753…9c9a), finalized #0 (0x6f09…a7ae), ⬇ 8.2kiB/s ⬆ 1.9kiB/s
Nov 10 21:41:39 localhost data-avail[1281]: 2023-11-10 21:41:39 ⚙️ Syncing 4.6 bps, target=#14330 (8 peers), best: #110 (0x237a…ff85), finalized #0 (0x6f09…a7ae), ⬇ 0.5kiB/s ⬆ 0.3kiB/s
After a while, you should see logs similar to the following once the node is synced:
Nov 10 19:39:20 localhost avail[1276]: 2023-11-10 19:39:20 ✨ Imported #13964 (0x9837…3ee1)
Nov 10 19:39:25 localhost avail[1276]: 2023-11-10 19:39:25 💤 Idle (12 peers), best: #13964 (0x9837…3ee1), finalized #13962 (0xc8d7…a027), ⬇ 15.1kiB/s ⬆ 14.9kiB/s
Nov 10 19:39:30 localhost avail[1276]: 2023-11-10 19:39:30 💤 Idle (12 peers), best: #13964 (0x9837…3ee1), finalized #13962 (0xc8d7…a027), ⬇ 17.2kiB/s ⬆ 14.5kiB/s
Nov 10 19:39:35 localhost avail[1276]: 2023-11-10 19:39:35 💤 Idle (12 peers), best: #13964 (0x9837…3ee1), finalized #13962 (0xc8d7…a027), ⬇ 14.7kiB/s ⬆ 14.2kiB/s
Nov 10 19:39:40 localhost avail[1276]: 2023-11-10 19:39:40 💤 Idle (12 peers), best: #13964 (0x9837…3ee1), finalized #13962 (0xc8d7…a027), ⬇ 15.0kiB/s ⬆ 15.6kiB/s
Nov 10 19:39:40 localhost avail[1276]: 2023-11-10 19:39:40 ✨ Imported #13965 (0xe8ea…31f5)
Nov 10 19:39:41 localhost avail[1276]: 2023-11-10 19:39:41 ✨ Imported #13965 (0xeb97…1927)
We can see we are connected to 12 peers and our best block is 13964 our finalized block is 13962 and we are importing block 13965. You can use ctrl+c to exit the journalctl.
You should also see your node name in the telemetry server. The interface of telemetry is Capped at 1000 servers so it may not show up.
If you are running for the Goldberg test net you will need to be selected to receive enough tokens to create the bond.
Next, we will use author_rotateKeys to get the session keys for our validator:
curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' http://localhost:9944
This will output something similar to the following. (I have removed characters and added some X’s too.):
{"jsonrpc":"2.0","result":"0xce61a24XXed2170ad19f547XX9cf42b0e0b62f27504e30781354eec37e0766b6bc673XX818e8c3abcf6855eb56760f888424cc26186907XXX4a5d9b998da535b1c4a492XXf3088edad7e429dc08b468edade9bf53150610612ee7b5b9c892195203aefc9947b31025","id":1}
You will need to use the session key your node provides. You will set the session key to link your wallet with your node. I put a link for the avail docs on how to set your session key.
Avail Docs to set session keys.
If you need to purge the database you can do this with the following command:
rm -rf /opt/avail/chains/avail_goldberg_testnet/db
Our Validators if you would like to nominate or tip:
Avail: 5FP6NChvSTDgeDjLvYLkK8ZfvgeHS9zane6rVYNBVJmP3YN2
Polkdot: 12pdN2XsNmG2yPAv5QCkq7YYUg1MM3prvGMgusH7S6FnDHAx
Kusama: Fq4YmiAq76DntjMKKjMiL98MYszoApUa9idSErvyzfdGoqG
Kusama: CpeX8UMVWUNJp5JrW7juUjfTtVhQENDApbAUKZ5AtQ36YmW