# how to run a quantus / resonance miner

> [!NOTE]
> ***resonance*** is the ***[quantus](https://quantus.com)*** canary network (testnet).
## linux
the following instructions have been tested and are known to work on recent versions of **fedora** and **ubuntu** linux. they *should* also work for most debian <sup>(systems with .deb apt package management)</sup> or redhat <sup>(systems with .rpm dnf/yum package management)</sup> based distros.
### download
```bash=
#!/usr/bin/env bash
#version=v0.1.0
# get latest release version
version=$(curl \
--fail \
--location \
--silent \
--url https://api.github.com/repos/Quantus-Network/chain/releases/latest \
| jq --raw-output .tag_name)
archive=quantus-node-${version}-x86_64-unknown-linux-gnu.tar.gz
# download the compressed quantus-node binary
curl \
--fail \
--location \
--output /tmp/${archive} \
--url https://github.com/Quantus-Network/chain/releases/download/${version}/${archive}
```
### install
#### option 1: extract and install for all users
use this if you plan to keep the node running always.
requires sudo in order to write to a protected system directory (`/usr/local/bin`), accessible to all users.
```bash=
#!/usr/bin/env bash
sudo tar \
--extract \
--gzip \
--directory /usr/local/bin \
--file /tmp/${archive}
```
#### option 2: extract and install for the current user
use this if you are just testing briefly.
```bash=
#!/usr/bin/env bash
[ -d ~/.local/bin ] || mkdir -p ~/.local/bin
tar \
--extract \
--gzip \
--directory ~/.local/bin \
--file /tmp/${archive}
```
### node key setup
```bash=
#!/usr/bin/env bash
# set base path to the folder where the chain database will be installed.
# consider that 500gb+ will be utilised.
base_path=/tmp
# create a node key. identifies this node to the network. no funds held.
# won't overwrite pre-existing key if it already exists at ${base_path}/chains/resonance/network/secret_ed25519
quantus-node key \
generate-node-key \
--base-path ${base_path} \
--bin \
--chain live_resonance
```
### mining account setup
> [!Caution]
> this step involves creating a private `${secret_phrase}` that must never be shared with anyone who does not require full access to your mining rewards. take precautions to follow the next step carefully, accurately and understanding that the consequences of making mistakes here, can (and probably will) result in loss of funds.
> [!Important]
> the secret phrase is not needed by the node. the node only ever needs to know the public account address stored below in the `${rewards_address}` environment variable. it is best practice to never keep any copy of the *secret phrase*, *seed* or *private key* on the node, or on any computer or device, that is ever connected to the internet.
```bash=
#!/usr/bin/env bash
# optional: generate a 24 word, bip39 private seed phrase.
# skip this if you already have an existing secret seed phrase or private-key seed.
# record the secret phrase:
# - on a piece of paper or otherwise suitable disconnected device
# - in a space where observation is impossible
# anyone with access to this phrase can access your funds without hindrance
secret_phrase="$(quantus-node key generate \
--words 24 \
--output-type json \
| jq -r .secretPhrase)"
# required: create a quantum-safe quantus/resonance account
# this account will receive all node mining rewards
rewards_address=$(quantus-node key quantus \
--scheme standard \
--words "${secret_phrase}" \
| grep Address \
| cut -d ' ' -f 2)
echo ${rewards_address}
```
### start mining
```bash=
#!/usr/bin/env bash
# a friendly name for the node at https://telemetry.res.fm
node_name="funds-are-quantum-safu"
quantus-node \
--validator \
--chain live_resonance \
--base-path ${base_path} \
--name "${node_name}" \
--rewards-address ${rewards_address}
```
### verify
- check that you can find the node at: https://telemetry.res.fm. look for the `${node_name}` you set earlier. the peers column must contain a number greater than 0. if it does not, the node is not in consensus with the network. it has either:
- failed to find bootnodes. make sure the network it is on can reach at least one of the following:
- https://a1.t.res.fm/health
- https://a2.t.res.fm/health
- https://a3.t.res.fm/health
- forked the chain (if the node row also shows finalised block numbers greater than 0). when a node begins producing blocks that peers do not accept, this is called a fork. if that node does not immediately discard its own blocks and rejoin the chain that has peer consensus, peers will add it to their internal ban (ignore) list. its chain database is no longer an accurate representation of the blockchain ledger. if this happens:
- stop the node (<kbd>ctrl</kbd>+<kbd>c</kbd>)
- delete the chain database (`${base_path}/chains/resonance/db/full`) folder:
```bash=
rm -rf ${base_path}/chains/resonance/db/full
```
- start your node again
- check that the mining rewards address (`${rewards_address}`) is producing blocks at: https://polkadot.js.org/apps/?rpc=wss://a.t.res.fm#/explorer
> [!TIP]
> add the mining rewards address to ***Accounts*** > ***[Address book](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fa.t.res.fm#/addresses)*** > ***Add contact***.
> give it an easily recognisable name, like whatever you used in the node start parameters (`--name "${node_name}"`) and you will see that name in the [polkadot.js explorer](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fa.t.res.fm#/explorer) whenever the node produces a block that is accepted by network consensus.
> 
### optional: keep the node running always
configure the computer to start and run the node whenever it is switched on. the instructions above have shown how to run the node in a terminal. if you would rather have the node start in the background every time you boot the computer, follow the steps below.
> [!Note]
> these instructions assume the computer is running systemd and have been tested and are known to work on recent versions of fedora and ubuntu.
- configure to your requirements
```bash=
#!/usr/bin/env bash
chain=resonance
username=resonance
# replace with a name that isn't already showing up at
# https://telemetry.res.fm
node_name="funds-are-quantum-safu"
# important: replace address below with your own mining account
rewards_address=5G28HeKSJD1qznaHxmfAEhUd1xK3vztWgwN198QJzQ2mwqQU
```
- create the unprivileged system user that will run the node:
```bash=
#!/usr/bin/env bash
sudo useradd \
--system \
--create-home \
--home-dir /var/lib/${username} \
--user-group \
${username}
```
- create the node key
```bash=
#!/usr/bin/env bash
sudo -u ${username} quantus-node key \
generate-node-key \
--base-path /var/lib/${username} \
--bin \
--chain live_${chain}
```
- create a systemd unit file
```bash=
#!/usr/bin/env bash
sudo tee /etc/systemd/system/${chain}.service <<EOF
[Unit]
Description=${chain} node
Wants=network-online.target
After=network-online.target
ConditionFileIsExecutable=/usr/local/bin/quantus-node
ConditionPathExists=/var/lib/${username}/chains/${chain}/network/secret_ed25519
[Service]
User=${username}
ExecStart=/usr/local/bin/quantus-node \
--chain live_${chain} \
--validator \
--name "${node_name}" \
--base-path /var/lib/${username} \
--rewards-address ${rewards_address}
Restart=always
RestartSec=120
[Install]
WantedBy=multi-user.target
EOF
```
- *enable* the service (causes the service to start on every system boot)
```bash=
#!/usr/bin/env bash
sudo systemctl enable ${chain}.service
```
- *start* the service (now)
```bash=
#!/usr/bin/env bash
sudo systemctl start ${chain}.service
```
- optional: add a firewall exception
opening port 30333/tcp allows other nodes to peer with this node and improves the peer count for this node and peered nodes which increases the security and decentralisation of the network.
- fedora (`firewall-cmd`)
```bash=
#!/usr/bin/env bash
# modify port number below if your node overrides the
# default p2p port (ie: with `--port ${custom_p2p_port}`)
resonance_p2p_port_proto=30333/tcp
firewall_default_zone=$(firewall-cmd --get-default-zone)
sudo firewall-cmd \
--zone=${firewall_default_zone} \
--add-port=${resonance_p2p_port_proto} \
--permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports --permanent
```
- ubuntu (`ufw`)
> [!Note]
> by default the ubuntu firewall is disabled. this means this configuration is unecessary on a default ubuntu system and only necessary if you have taken steps to enable the firewall.
```bash=
#!/usr/bin/env bash
# modify port number below if your node overrides the
# default p2p port (ie: with `--port ${custom_p2p_port}`)
resonance_p2p_port_proto=30333/tcp
sudo ufw allow ${resonance_p2p_port_proto} comment 'resonance p2p'
```
- *tail* (watch) the service logs. use <kbd>ctrl</kbd>+<kbd>c</kbd> to stop/exit.
```bash=
#!/usr/bin/env bash
journalctl -fu ${chain}.service
```
- *stop* the service (now)
```bash=
#!/usr/bin/env bash
sudo systemctl stop ${chain}.service
```
- *disable* the service (removes the trigger that would start the service on every boot)
```bash=
#!/usr/bin/env bash
sudo systemctl disable ${chain}.service
```
- *update* the node
```bash=
#!/usr/bin/env bash
chain=resonance
# obtain the latest release tag from github
version=$(curl \
--fail \
--location \
--silent \
--url https://api.github.com/repos/Quantus-Network/chain/releases/latest \
| jq --raw-output .tag_name)
# observe the locally installed version
local_version="v$(/usr/local/bin/quantus-node --version | cut -d ' ' -f 2 | cut -d '-' -f 1)"
archive=quantus-node-${version}-x86_64-unknown-linux-gnu.tar.gz
if [ "${local_version}" != "${version}" ]; then
# stop the service if it is running
if systemctl is-active --quiet ${chain}.service; then
if sudo systemctl stop ${chain}.service; then
echo "stopped ${chain}.service"
else
echo "failed to stop ${chain}.service"
fi
fi
if ! systemctl is-active --quiet ${chain}.service; then
# archive the installed binary if it exists
if [ -f /usr/local/bin/quantus-node ]; then
if sudo mv \
/usr/local/bin/quantus-node \
/usr/local/bin/quantus-node-${local_version} \
&& sudo chmod a-x /usr/local/bin/quantus-node-${local_version}; then
echo "archived /usr/local/bin/quantus-node-${local_version}"
else
echo "failed to archive /usr/local/bin/quantus-node-${local_version}"
fi
fi
# download the latest compressed binary
if curl \
--fail \
--location \
--output /tmp/${archive} \
--silent \
--url https://github.com/Quantus-Network/chain/releases/download/${version}/${archive}; then
echo "downloaded /tmp/${archive}"
# extract the latest binary
if sudo tar \
--extract \
--gzip \
--directory /usr/local/bin \
--file /tmp/${archive}; then
echo "extracted /usr/local/bin/quantus-node"
# start the service
if sudo systemctl start ${chain}.service; then
echo "started ${chain}.service"
else
echo "failed to start ${chain}.service"
fi
else
echo "failed to extract /usr/local/bin/quantus-node"
fi
else
echo "failed to download /tmp/${archive}"
fi
fi
else
echo "local version matches latest version: ${version}"
fi
```