Menu Close

Installation Steps

set hostname:

vi /etc/hostname

SSH

Start with securing your vps with a public key and disabling password access. Of course first create a key on another system and copy this to your new server to be able to access it after disabling the password authentication.

vi /etc/ssh/sshd_config
PasswordAuthentication no
systemctl restart sshd.service

Firewall

Enable firewall security to protect it from attacks from the outside. Depending on your p2p ports and prometheus monitoring you need to open soms ports.

ufw allow openssh
ufw enable

The polkadot binary needs some ports to be reachable, especially the p2p port

  • 30333: p2p port
  • 9933: HTTP RPC
  • 9944: WS RPC
  • 9615: prometheus port

I open a range of p2p ports so I can choose to setup multiple validators

ufw allow from any port 30300:30399 proto tcp

Update packages

apt update; apt upgrade

I prefer to lock the kernel updates so I have to manually upgrade them (which requires a restart)

apt-mark hold linux-generic linux-headers-generic linux-image-generic

Install polkadot apt repository

# Import the security@parity.io GPG key
gpg --recv-keys --keyserver hkps://keys.mailvelope.com 9D4B2B6EB8F97156D19669A9FF0812D491B96798
gpg --export 9D4B2B6EB8F97156D19669A9FF0812D491B96798 > /usr/share/keyrings/parity.gpg
# Add the Parity repository and update the package index
echo 'deb [signed-by=/usr/share/keyrings/parity.gpg] https://releases.parity.io/deb release main' > /etc/apt/sources.list.d/parity.list
apt update
# Install the `parity-keyring` package - This will ensure the GPG key
# used by APT remains up-to-date
apt install parity-keyring
# Install polkadot
apt install polkadot

Create the systemctl scripts

By default the is a “/usr/lib/systemd/system/polkadot.service” systemctl script which reads its defaults from “/etc/default/polkadot”. I find it handier to copy the scripts and put the appropriate command line config inside.

root@stakeworld:~# cp /usr/lib/systemd/system/polkadot.service /etc/systemd/system/kusama-stakeworld.service

Multiple instances

Theoretically it is possible to create multiple systemctl scripts and run multiple instances of the polkadot binary on the same system although this is not benificial for the polkadot ecosystem stability a demand higher resources on your server.

root@stakeworld:~# cp /etc/systemd/system/kusama-stakeworld.service /etc/systemd/system/kusama-stakeworld-01.service

Following my adapted systemctl script (/etc/systemd/system/kusama.service). As you can see i choose different ports to be able to use it alongside my polkadot validator. If you run more instances you need to adapt the ports and base directories alpongside the “Description” in the .service file.

  • –chain: kusam or polkadot (or westend)
  • –name: the name of the validator
  • –unsafe-pruning –pruning 1000: a pruned database is enough for a validator and saves precious ssd space
  • –validator: declare ourself a validator
  • –port 30334 –rpc-port 9934 –ws-port 9945: select alternative ports when using multiple instances
  • –prometheus-port 9621 needed for monitoring
  • –database rocksdb or paritydb to choose the database format
  • –base-path /home/polkadot/kusama-stakeworld-01: The base path allows for a different database location.
  • –telemetry-url ‘wss://telemetry.polkadot.io/submit/ 1’ , this is the default.
[Unit]
Description=Kusama Stakeworld
After=network.target
Documentation=https://github.com/paritytech/polkadot

[Service]
ExecStart=/usr/bin/polkadot --chain polkadot --name STAKEWORLD/01 --unsafe-pruning --pruning 1000 --validator --port 30321 --rpc-port 9921 --ws-port 9821 --prometheus-port 9621 --base-path /home/polkadot/polkadot-stakeworld-01 --database paritydb --telemetry-url 'wss://telemetry.polkadot.io/submit/ 1'
User=polkadot
Group=polkadot
Restart=always
RestartSec=120
CapabilityBoundingSet=
LockPersonality=true
NoNewPrivileges=true
PrivateDevices=true
PrivateMounts=true
PrivateTmp=true
PrivateUsers=true
ProtectClock=true
ProtectControlGroups=true
ProtectHostname=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectSystem=strict
RemoveIPC=true
RestrictAddressFamilies=AF_INET AF_INET6 AF_NETLINK AF_UNIX
RestrictNamespaces=true
RestrictSUIDSGID=true
SystemCallArchitectures=native
SystemCallFilter=@system-service
SystemCallFilter=~@clock @module @mount @reboot @swap @privileged
UMask=0027

[Install]
WantedBy=multi-user.target
sudo -u polkadot mkdir /home/polkadot/polkadot-stakeworld-01
systemctl daemon-reload
systemctl start polkadot-stakeworld-01.service
journalctl -u polkadot-stakeworld-01.service -f

If all went wel you can now see synchronisation starting in the logs and your node shows up in https://telemetry.polkadot.io/

If you fire up a fresh polkadot it starts to sync from scratch, which will take a while.

Using an up to date database you can speed up the process. Best is to shortly start the relevant polkadot binary, so the file structure gets created, then stop it and execute the code below. After this you can start the binary and it will only need a short period to sync and start validating.

Tip: there are different size databases, a “pruned” database is sufficient for a validator node.

curl -o - -L https://dot-rocksdb.polkashots.io/snapshot | lz4 -c -d - | tar -x -C /home/polkadot/.local/share/polkadot/chains/polkadot

The perfect but complicated setup

I have a ledger hardware wallet with polkadot and kusama accounts and I also have made a native account via https://polkadot.js.org/. Both are connected via the browser extension https://polkadot.js.org/extension/

If you are serious about validating and maybe want to fire up more instances in the future the perfect setup seems to be a stash account on a cold (hardware/ledger) wallet which you don’t have to use often, combined with a controller account on a hot wallet with easy (password) access. The idea is you use the hot wallet more often with more risk for exposure of the keys, while your stash account with the most value on it is relatively safe.

Problem with the setup using a ledger is that a lot of functions are more complicated, because the ledger app cannot execute all functions, most importantly:

  • A ledger account cannot have an “on chain identity” by itself. The workaround is giving a native account an identity (STAKEWORLD) and specifying the ledger accounts as sub-identities. In the validator lists they show as STAKEWORLD/01 , where the /01 is a sub-identity of stakeworld. The next one is STAKEWORLD/02 and so on. Every identity and sub identity locks up dot/ksm (polkadot: 20 dots, which you get back after clearing the identity).
  • A ledger account misses the democracy and council voting possibilities. Since this is a factor in the validator selection protocol and you want your validators to get elected it is wise to participate in democracy votes. The workaround here is to use a proxy. You can via ledger proxy your stash account to a native account, and with that native account can cast votes in democracy on behalf of the ledger stash account. Every proxy also locks up a certain amount of dot/ksm.

The easy setup

The more easy approach is to use a native account for as well stash as controller account. You can easily take on a chain identity, vote in democracy, etc. The downside being the lesser security and probably a lower score in the selection mechanism.