# Subsocial validator guide
*Based on "[Run a validator (Kusama)](https://wiki.polkadot.network/docs/maintain-guides-how-to-validate-kusama)"*
This guide will instruct you on how to set up a validator node on the Subsocial network.
Link to Subsocial Node (staging) on Polkadot/Substrate portal:
https://polkadot.js.org/apps/?rpc=wss://staging.subsocial.network
## Table of Contents
* [Preliminaries](#Preliminaries)
* [How many SUB tokens do I need?](#How-many-SUB-tokens-do-I-need)
* [Initial Set-up](#Initial-Set-up)
* [Requirements](#Requirements)
* [Node Prerequisites: Install Rust and Dependencies](#Node-Prerequisites-Install-Rust-and-Dependencies)
* [Install & Configure Network Time Protocol (NTP) Client](#Install-amp-Configure-Network-Time-Protocol-NTP-Client)
* [Clone and Build Subsocial binary](#Clone-and-Build-Subsocial-binary)
* [Run as sync node](#Run-as-sync-node)
* [Bond SUB](#Bond-SUB)
* [Run as validator node](#Run-as-validator-node)
* [Generating the Session Keys](#Generating-the-Session-Keys)
* [Option 1: Polkadot-JS Apps](#Option-1-Polkadot-JS-Apps)
* [Option 2: CLI](#Option-2-CLI)
* [Submitting the `setKeys` Transaction](#Submitting-the-setKeys-Transaction)
* [Using Docker](#Using-Docker)
## Preliminaries
Running a validator on a live network is a lot of responsibility! You will be accountable for not only your own stake, but also the stake of your current nominators. If you make a mistake and get slashed, your money and your reputation will be at risk. However, running a validator can also be very rewarding, knowing that you contribute to the security of a decentralized network while growing your stash.
**Warning:** It is highly recommended that you have significant system administration experience before attempting to run your own validator.
Since security is so important to running a successful validator, you should take a look at the Polkadot [validator setup information](https://wiki.polkadot.network/docs/maintain-guides-secure-validator) to make you understand the factors to consider when building your infrastructure.
The Web3 Foundation also maintains a [reference implementation for a validator set-up](https://github.com/w3f/polkadot-validator-setup) that you can use by deploying yourself. As you progress in your journey as a validator, you will likely want to use this repository as a starting point for your own modifications and customizations.
If you need help, please reach out on the [Subsocial validator channel on Discord](https://discord.gg/FXnvpzqpfb). The team and other validators are there to help answer questions and provide experience. You can join directly in your web browser (link above) or using any other Discord client.
### How many SUB tokens do I need?
You can have a rough estimate on that by using the methods listed [here](https://wiki.polkadot.network/docs/faq#what-is-the-minimum-stake-necessary-to-be-elected-as-an-active-validator). Validators are elected based on Phragmén's algorithm. To be elected into the set, you need a minimum stake behind your validator. This stake can come from yourself or from nominators. This means that as a minimum, you will need enough SUB to set up Stash and Controller accounts with the existential deposit, plus a little extra for transaction fees. The rest can come from nominators.
**Warning:** Any SUB that you stake for your validator is liable to be slashed, meaning that an insecure or improper setup may result in loss of SUB tokens! If you are not confident in your ability to run a validator node, it is recommended to nominate your SUB to a trusted validator node instead.
## Initial Set-up
### Requirements
The most common way for a beginner to run a validator is on a cloud server running Linux. You may choose whatever VPS provider that your prefer, and whatever operating system you are comfortable with. For this guide we will be using Ubuntu 20.04, but the instructions should be similar for other platforms.
### Node Prerequisites: Install Rust and Dependencies
Once you choose your cloud service provider and set up your new server, the first thing you will do is install Rust.
If you have never installed Rust, you should do this first. This command will fetch the latest version of Rust and install it.
```sh=
# Install
curl https://sh.rustup.rs -sSf | sh -s -- -y
# Configure
source ~/.cargo/env
```
> If you do not have "curl" installed, run "sudo apt install curl"
Verify your installation.
```sh
rustc --version
```
Otherwise, if you have already installed Rust, run the following command to make sure you are using the latest version.
```sh
rustup update
```
Configure the Rust toolchain to default to the latest stable version:
```sh=
rustup update nightly
rustup default nightly
```
Finally, run this command to install the necessary dependencies for compiling and running the Polkadot node software.
```sh
sudo apt install make clang pkg-config libssl-dev build-essential
```
### Install & Configure Network Time Protocol (NTP) Client
[NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) is a networking protocol designed to synchronize the clocks of computers over a network. NTP allows you to synchronize the clocks of all the systems within the network. Currently it is required that validators' local clocks stay reasonably in sync, so you should be running NTP or a similar service. You can check whether you have the NTP client by running:
*If you are using Ubuntu 18.04 / 20.04, NTP Client should be installed by default.*
```sh
timedatectl
```
If NTP is installed and running, you should see `System clock synchronized: yes` (or a similar message). If you do not see it, you can install it by executing:
```sh
sudo apt-get install ntp
```
ntpd will be started automatically after install. You can query ntpd for status information to verify that everything is working:
```sh
sudo ntpq -p
```
> *WARNING:* Skipping this can result in the validator node missing block authorship opportunities. If the clock is out of sync (even by a small amount), the blocks the validator produces may not get accepted by the network. This will result in ImOnline heartbeats making it on chain, but zero allocated blocks making it on chain.
## Clone and Build Subsocial binary
> Currently we're running as a Staging Mainnet node, but the final algorithm may change when released.
Clone the `subsocial-node` repository and switch to the required branch: now it's `staging`.
```sh=
# Clone
git clone https://github.com/dappforce/subsocial-node.git
cd subsocial-node
# Switch branches
git fetch origin staging
git checkout staging
```
Built native code with cargo release profile:
```sh=
# Build
./scripts/init.sh
cargo build --release
```
***This step will take a while (generally 10 - 40 minutes, depending on your hardware).***
> Note if you run into compile errors, you may have to switch to a less recent nightly.
> `init.sh` scripts does this for you, but this can be done manually as well by running:
>
> ```sh
> rustup install nightly-2021-06-01
> rustup target add wasm32-unknown-unknown --toolchain nightly-2021-06-01
> cargo +nightly-2021-06-01 build --release
> ```
> You may also need to run the build more than once.
> If you would like to execute the tests, run the following command:
> ```sh
> cargo test --all
> ```
If you are interested in generating keys locally, you can also install `subkey` from the same directory. You may then take the generated `subkey` executable and transfer it to an air-gapped machine for extra security.
```sh
cargo install --force --git https://github.com/paritytech/substrate subkey
```
### Run as sync node
> **Note:** By default, Validator nodes are in archive mode. If you've already synced the chain not in archive mode, you must first remove the database with `subsocial-node purge-chain` and then ensure that you run Subsocial with the `--pruning=archive` option.
>
> You may run a validator node in non-archive mode by adding the following flags: `--unsafe-pruning --pruning <NUMBER OF BLOCKS>`, but note that an archive node and non-archive node's databases are not compatible with each other, and to switch you will need to purge the chain data.
You can begin syncing your node by running the following command:
```sh
./target/release/subsocial-node --name "MONIKER" --pruning archive --chain staging-testnet --rpc-port <port>
```
**Note:** `--rpc-port` is needed if you don't want your node to conflict with other substrate nodes you running on the same server (*which is not recommended*).
if you do not want to start in validator mode right away.
```
2021-08-18 17:06:01 Subsocial Node
2021-08-18 17:06:01 ✌️ version 0.7.0-a15df58-x86_64-linux-gnu
2021-08-18 17:06:01 ❤️ by DappForce <dappforce@pm.me>, 2019-2021
2021-08-18 17:06:01 📋 Chain specification: Subsocial-Staging
2021-08-18 17:06:01 🏷 Node name: Subsocial validator
2021-08-18 17:06:01 👤 Role: FULL
2021-08-18 17:06:01 💾 Database: RocksDb at /root/.local/share/subsocial-node/chains/subsocial/db
2021-08-18 17:06:01 ⛓ Native runtime: subsocial-11 (dappforce-subsocial-0.tx2.au0)
2021-08-18 17:06:03 🔨 Initializing Genesis block/state (state: 0x4cdc…d008, header-hash: 0x86df…58cd)
2021-08-18 17:06:04 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2021-08-18 17:06:04 ⏱ Loaded block-time = 6000 milliseconds from genesis on first-launch
2021-08-18 17:06:04 👶 Creating empty BABE epoch changes on what appears to be first startup.
2021-08-18 17:06:04 🏷 Local node identity is: 12D3KooWE4LVAeVQbEhCAY8D7pSEZ7kJvi5BmbKRPZvu2RLksPDt
2021-08-18 17:06:04 📦 Highest known block at #0
2021-08-18 17:06:04 〽️ Prometheus server started at 127.0.0.1:9615
2021-08-18 17:06:04 Listening for new connections on 127.0.0.1:9944.
```
Example of node sync:
```
2021-08-18 17:06:09 ⚙️ Syncing, target=#83341 (1 peers), best: #3825 (0x3fff…8dc3), finalized #3584 (0xc60e…0605), ⬇ 310.5kiB/s ⬆ 2.1kiB/s
2021-08-18 17:06:14 ⚙️ Syncing 276.2 bps, target=#83342 (1 peers), best: #5206 (0x57a4…bec0), finalized #5120 (0x3388…fd99), ⬇ 74.8kiB/s ⬆ 0.4kiB/s
2021-08-18 17:06:19 ⚙️ Syncing 260.4 bps, target=#83343 (1 peers), best: #6508 (0x8d8b…6e1e), finalized #6144 (0x68a9…7306), ⬇ 67.7kiB/s ⬆ 0.3kiB/s
2021-08-18 17:06:24 ⚙️ Syncing 243.6 bps, target=#83344 (1 peers), best: #7726 (0x1a7c…32a9), finalized #7680 (0x03e5…21d7), ⬇ 67.9kiB/s ⬆ 0.4kiB/s
2021-08-18 17:06:29 ⚙️ Syncing 254.0 bps, target=#83344 (1 peers), best: #8996 (0x99a7…50b5), finalized #8704 (0xb09f…7496), ⬇ 67.6kiB/s ⬆ 0.3kiB/s
2021-08-18 17:06:34 ⚙️ Syncing 285.2 bps, target=#83345 (1 peers), best: #10422 (0x2abe…ad77), finalized #10240 (0x132e…b463), ⬇ 74.3kiB/s ⬆ 0.4kiB/s
```
The `--pruning=archive` flag is implied by the `--validator` flag, so it is only required explicitly if you start your node without one of these two options. If you do not set your pruning to archive node, even when not running in validator, you will need to re-sync your database when you switch.
> **Note:** Validators should sync using the RocksDb backend. This is implicit by default, but can be explicit by passing the `--database RocksDb` flag.
Depending on the size of the chain when you do this, this step may take anywhere from a few minutes to a few hours.
If you are interested in determining how much longer you have to go, your server logs (printed to STDOUT from the `subsocial-node` process) will tell you the latest block your node has processed and verified. You can then compare that to the current highest block via [Telemetry](https://telemetry.polkadot.io/#list/Subsocial) or the [Polkadot-JS Block Explorer](https://polkadot.js.org/apps/?rpc=wss://staging.subsocial.network#/explorer).
## Bond SUB
It is highly recommended that you make your controller and stash accounts be two separate accounts. For this, you will create two accounts and make sure each of them have at least enough funds to pay the fees for making transactions. Keep most of your funds in the stash account since it is meant to be the custodian of your staking funds.
Make sure not to bond all your SUB balance since you will be unable to pay transaction fees from your bonded balance.
It is now time to set up our validator. We will do the following:
* Bond the SUB of the Stash account. These SUB will be put at stake for the security of the network and can be slashed.
* Select the Controller. This is the account that will decide when to start or stop validating.
First, go to the [Staking > Account Actions](https://polkadot.js.org/apps/?rpc=wss://staging.subsocial.network#/staking/actions) section and then click on the "Stash" button.

* **Stash account** - Select your Stash account. In this example, we will bond 100 milliSUB - make sure that your Stash account contains *at least* this much. You can, of course, stake more than this.
* **Controller account** - Select the Controller account created earlier. This account will also need a small amount of SUB in order to start and stop validating.
* **Value bonded** - How much SUB from the Stash account you want to bond/stake. Note that you do not need to bond all of the SUB in that account. Also note that you can always bond *more* SUB later. However, *unbonding* any bonded amount requires you to wait the duration of the unbonding period. On Staging Subsocial, the unbonding period is 7 days.
* **Payment destination** - The account where the rewards from validating are sent.
Once everything is filled in properly, click `Bond` and sign the transaction with your Stash account.
After a few seconds, you should see an "ExtrinsicSuccess" message. You should now see a new card with all your accounts (note: you may need to refresh the screen). The bonded amount on the right corresponds to the funds bonded by the Stash account.
## Run as validator node
* [How to generate keys](https://substrate.dev/docs/en/tutorials/start-a-private-network/keygen).
* [How to set keys](https://substrate.dev/docs/en/tutorials/start-a-private-network/customchain#add-keys-to-keystore).
* Note: you have to set `babe` and `gran` keys.
> **Note:** The session keys are consensus critical, so if you are not sure if your node has the current session keys that you made with the `setKeys` transaction, then you can use one of the two available RPC methods to query your node: [hasKey](https://polkadot.js.org/api/substrate/rpc.html#haskey-publickey-bytes-keytype-text-bool) to check for a specific key or [hasSessionKeys](https://polkadot.js.org/api/substrate/rpc.html#hassessionkeys-sessionkeys-bytes-bool) to check the full session key public key string.
Once your node is fully synced, stop the process by pressing Ctrl-C. At your terminal prompt, you will now start running the node in validator mode with a flag allowing unsafe RPC calls, needed for some advanced operations.
```sh
./target/release/subsocial-node --validator --name "MONIKER" --chain staging-testnet
```
**Note:** `--validator` is needed for you to run as validator. You will be offended and kicked from the elected validators set (as you won't produce blocks) if you validate, but haven't specified this parameter for your Subsocial node.
Similary:
```
2021-08-18 17:14:09 Subsocial Node
2021-08-18 17:14:09 ✌️ version 0.7.0-a15df58-x86_64-linux-gnu
2021-08-18 17:14:09 ❤️ by DappForce <dappforce@pm.me>, 2019-2021
2021-08-18 17:14:09 📋 Chain specification: Subsocial-Staging
2021-08-18 17:14:09 🏷 Node name: Subsocial validator
2021-08-18 17:14:09 👤 Role: AUTHORITY
2021-08-18 17:14:09 💾 Database: RocksDb at /root/.local/share/subsocial-node/chains/subsocial/db
2021-08-18 17:14:09 ⛓ Native runtime: subsocial-11 (dappforce-subsocial-0.tx2.au0)
2021-08-18 17:14:09 🏷 Local node identity is: 12D3KooWE4LVAeVQbEhCAY8D7pSEZ7kJvi5BmbKRPZvu2RLksPDt
2021-08-18 17:14:09 📦 Highest known block at #83416
2021-08-18 17:14:09 〽️ Prometheus server started at 127.0.0.1:9615
2021-08-18 17:14:09 Listening for new connections on 127.0.0.1:9944.
2021-08-18 17:14:09 👶 Starting BABE Authorship worker
```
You can give your validator any name that you like, but note that others will be able to see it, and it will be included in the list of all servers using the same telemetry server. Since numerous people are using telemetry, it is recommended that you choose something likely to be unique.
### Generating the Session Keys
You need to tell the chain your Session keys by signing and submitting an extrinsic. This is what associates your validator node with your Controller account on Polkadot.
#### Option 1: Polkadot-JS Apps
You can generate your [Session keys](https://wiki.polkadot.network/docs/learn-keys#session-keys) in the client via the apps RPC. If you are doing this, make sure that you have the Polkadot-JS Apps explorer attached to your validator node. You can configure the apps dashboard to connect to the endpoint of your validator in the Settings tab. If you are connected to a default endpoint hosted by Subsocial, you will not be able to use this method since making RPC requests to this node would effect the local keystore hosted on a *public* node and you want to make sure you are interacting with the keystore for *your* node.
Once ensuring that you have connected to your node, the easiest way to set session keys for your node is by calling the `author_rotateKeys` RPC request to create new keys in your validator's keystore. Navigate to the Toolbox tab and select RPC Calls, then select the author > rotateKeys() option and remember to save the output that it returns for a later step.

#### Option 2: CLI
If you are on a remote server, it is easier to run this command on the same machine (while the node is running with the default HTTP RPC port configured):
```sh
curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "author_rotateKeys", "params":[]}' http://localhost:9933
```
The output will have a hex-encoded "result" field. The result is the concatenation of the four public keys. Save this result for a later step.
### Submitting the `setKeys` Transaction
You need to tell the chain your Session keys by signing and submitting an extrinsic. This is what associates your validator with your Controller account.
Go to [Staking > Account Actions](https://polkadot.js.org/apps/?rpc=wss://staging.subsocial.network#/staking/actions), and click "Set Session Key" on the bonding account you generated earlier. Enter the output from `author_rotateKeys` in the field and click "Set Session Key".

Submit this extrinsic and you are now ready to start validating.
## Using Docker
If you have Docker installed, you can use it to start your validator node without needing to build the binary. You can do this with a simple command:
```sh=
docker run -dit \
--name subsocial \
--restart always \
--log-opt max-size=100m \
--log-opt max-file=5 \
-p 30333:30333 \
-p 127.0.0.1:9933:9933 \
dappforce/subsocial-node:staging subsocial-node \
--validator --name "<MONIKER>" \
--chain staging-testnet
```
If you want to insert validator keys with `author_insertKeys` or call `author_rotateKeys`, then you probably want to run Docker image with a few additional parameters, so the final command will look like:
```sh=
docker run -dit \
--name subsocial \
--restart always \
--log-opt max-size=100m \
--log-opt max-file=5 \
-p 30333:30333 \
-p 127.0.0.1:9933:9933 \
dappforce/subsocial-node:staging subsocial-node \
--validator --name "<MONIKER>" \
--chain staging-testnet \
--rpc-cors all \
--rpc-methods=unsafe \
--rpc-external
```