Join The Testnet
Setup A Testnet Validator Node

Familiarize yourself with Gitian

Downloading and running a binary makes most sane people nervous. Gitian introduces a level of trust for binary artifacts and is the distribution method chosen by IOV and other blockchains including Bitcoin and Cosmos. We'll use binaries built using gitian and systemd to drive the IOV Name Service blockchain.

Use systemd for running a sentry node or validator

This document is not for beginners. It assumes that you know how to setup a sentry node architecture for Tendermint nodes. It also assumes that basename, curl, grep, jq, sed, sha256sum, and wget are installed on your system, and user $USER_IOV exists.
Given that, you should be able to copy-and-paste the following commands into a terminal and end up with a running node. It has been tested on Centos8, Ubuntu 19, and Fedora 31. You'll have to do this procedure on at least two machines to implement a sentry node architecture.
1
sudo su # make life easier for the next ~100 lines
2
3
cd /etc/systemd/system
4
5
export USER_IOV=iov # "iov" is not recommended
6
export SIGNER=dave # signer for the create-validator tx
7
8
# create an environment file for the IOV Name Service services
9
cat <<__EOF_IOVNS_ENV__ > starname.env
10
# operator variables
11
CHAIN_ID=iovns-galaxynet
12
MONIKER=$(hostname)
13
SIGNER=${SIGNER}
14
USER_IOV=${USER_IOV}
15
16
# directories (without spaces to ease pain)
17
DIR_IOVNS=/opt/iovns/bin
18
DIR_WORK=/home/${USER_IOV}/galaxynet
19
20
# artifacts
21
IOVNS=https://github.com/iov-one/iovns/releases/download/v0.9.7/iovns-0.9.7-linux-amd64.tar.gz
22
__EOF_IOVNS_ENV__
23
24
chgrp ${USER_IOV} starname.env
25
chmod g+r starname.env
26
27
set -o allexport ; source /etc/systemd/system/starname.env ; set +o allexport # pick-up env vars
28
29
# create starname.service
30
cat <<__EOF_STARNAME_SERVICE__ > starname.service
31
[Unit]
32
Description=IOV Name Service
33
After=network-online.target
34
#PartOf=iovnsapi.service
35
36
[Service]
37
Type=simple
38
User=$(id ${USER_IOV} -u -n)
39
Group=$(id ${USER_IOV} -g -n)
40
EnvironmentFile=/etc/systemd/system/starname.env
41
ExecStart=${DIR_IOVNS}/iovnsd.sh
42
LimitNOFILE=4096
43
#Restart=on-failure
44
#RestartSec=3
45
StandardError=journal
46
StandardOutput=journal
47
SyslogIdentifier=iovnsd
48
49
[Install]
50
WantedBy=multi-user.target
51
__EOF_STARNAME_SERVICE__
52
53
systemctl daemon-reload
54
55
# download gitian built binaries; iovnsd is the IOV Name Service daemon
56
mkdir -p ${DIR_IOVNS} && cd ${DIR_IOVNS}
57
wget ${IOVNS} && sha256sum $(basename ${IOVNS}) | grep b06575a0254ad1dceeabdb56de09cca0451173d57d3de43f060ff8be67fdf053 && tar xvf $(basename ${IOVNS}) || echo 'BAD BINARY!'
58
59
# create iovnsd.sh, a wrapper for iovnsd
60
cat <<__EOF_IOVNSD_SH__ > iovnsd.sh
61
#!/bin/bash
62
63
exec $PWD/iovnsd start \\
64
--home=${DIR_WORK} \\
65
--minimum-gas-prices='1.0uvoi' \\
66
--moniker='${MONIKER}' \\
67
--p2p.laddr='tcp://0.0.0.0:46656' \\
68
--p2p.persistent_peers='[email protected]:46656' \\
69
--rpc.laddr='tcp://127.0.0.1:46657' \\
70
--rpc.unsafe=true \\
71
72
__EOF_IOVNSD_SH__
73
74
chgrp ${USER_IOV} iovnsd.sh
75
chmod a+x iovnsd.sh
76
77
# initialize the IOV Name Service
78
su - ${USER_IOV}
79
set -o allexport ; source /etc/systemd/system/starname.env ; set +o allexport # pick-up env vars
80
81
rm -rf ${DIR_WORK} && mkdir -p ${DIR_WORK} && cd ${DIR_WORK}
82
83
# initialize IOV Name Service (iovnsd)
84
${DIR_IOVNS}/iovnsd init ${MONIKER} --chain-id ${CHAIN_ID} --home ${DIR_WORK} 2>&1 | jq -r .chain_id
85
86
curl --fail https://rpc.cluster-galaxynet.iov.one/genesis | jq -r .result.genesis > config/genesis.json
87
sha256sum config/genesis.json | grep d41378b0d21dd4c3bc7e0e77325df4adc7d801d6c804879946a001361f24056d || echo 'BAD GENESIS FILE!'
88
89
exit # ${USER_IOV}
90
91
journalctl -f -u starname.service & # watch the chain sync
92
systemctl start starname.service
93
94
exit # root
Copied!
At this point you're running a full-node that can be examined at http://localhost:46657/status. Repeat the above procedure on as many sentry nodes as you have and once more on your validator node.

Point the nodes at each other

Now that you have sentry node(s) and a validator, they need to be made aware of their role and pointed at each other.

Sentry node configuration

In the most rudimentary form, a sentry node is meant to gossip with other nodes but keep its associated validator hidden. Change ${DIR_IOVNS}/iovnsd.sh so that the node gossips while keeping its validator hidden. Be mindful of --rpc.unsafe true below, you might not want that. On the validator node, execute curl -s http://localhost:46657/status | jq -r .result.node_info.id to get the value for VALIDATOR_ID.
1
exec "$PWD/iovnsd start \
2
...
3
--moniker='sentry' \
4
--p2p.laddr='tcp://0.0.0.0:46656' \
5
--p2p.persistent_peers='[email protected]:46656' \
6
--rpc.laddr='tcp://127.0.0.1:46657' \
7
--rpc.unsafe=true \
8
"
Copied!
There are a lot more tendermint configuration options available than those shown above. Customize them as you see fit and then execute sudo systemctl restart starname.service.

Validator configuration

As mentioned, it's ${DIR_IOVNS}/iovnsd.sh that determines whether the node will act as a sentry or validator based on p2p.* options and priv_validator_laddr if you're using an HSM. Change ${DIR_IOVNS}/iovnsd.sh so that the node gossips with its sentry node(s) only, ie set p2p.pex=false and add an explicit list of p2p.persistent_peers. Obtain the sentry node ids for p2p.persistent_peers by executing curl -s http://localhost:46657/status | jq -r .result.node_info.id on each sentry node. You know the IP and PORT of the nodes, so include them appropriately.
1
exec "$PWD/iovnsd start \
2
...
3
--moniker='validator' \
4
--priv_validator_laddr='tcp://HSM_IP:HSM_PORT' \
5
--p2p.persistent_peers='[email protected]_IP0:SENTRY_PORT0,[email protected]_IP1:SENTRY_PORT1' \
6
--p2p.pex='false' \
7
--rpc.unsafe='false' \
8
"
Copied!
Execute sudo systemctl restart starname.service.

Hardware Security Module (HSM) configuration

The IOV Name Service is based on tendermint v0.33.x, which requires tmkms v0.8.0-rc0 or better.
Update your tmkms.toml file after you customize ADDR_VALIDATOR, FILE_SECRET and FILE_TMKMS in the following script:
1
sudo su # make life easier for the next 20 lines
2
3
export ADDR_VALIDATOR="tcp://[email protected]:46658" # or addr = "unix:///path/to/socket"
4
export FILE_SECRET=/path/to/kms-identity.key
5
export FILE_TMKMS=/path/to/tmkms.toml
6
7
set -o allexport ; source /etc/systemd/system/starname.env ; set +o allexport # pick-up env vars
8
9
grep ${CHAIN_ID} ${FILE_TMKMS} || { cat <<__EOF_TMKMS_UPDATE__ >> ${FILE_TMKMS}
10
[[chain]]
11
id = "${CHAIN_ID}"
12
key_format = { type = "bech32", account_key_prefix = "starpub", consensus_key_prefix = "starvalconspub" }
13
state_file = "${DIR_WORK}/data/priv_validator_state.json"
14
# state_hook = { cmd = ["/path/to/block/height_script", "--example-arg", "starname network"] }
15
16
[[validator]]
17
addr = "${ADDR_VALIDATOR}"
18
chain_id = "${CHAIN_ID}"
19
secret_key = "${FILE_SECRET}"
20
protocol_version = "v0.33"
21
__EOF_TMKMS_UPDATE__
22
23
sed --in-place "s/\(chain_ids.*\)\"/\\1\", \"${CHAIN_ID}\"/" ${FILE_TMKMS}
24
25
systemctl restart tmkms.service
26
}
27
28
exit # root
Copied!

Light-up the validator

Once your sentry nodes and validator are sync'ed then the final step to becoming a validator is to execute the create-validator command just like for any Cosmos-based chain. Get some tokens from our faucet with `curl https://faucet.cluster-galaxynet.iov.one/credit?address=${SIGNER}`. The testnet's token is denominated in uvoi, so your create validator command will look something like
1
set -o allexport ; source /etc/systemd/system/starname.env ; set +o allexport # pick-up env vars
2
3
export PATH=${DIR_IOVNS}:$PATH
4
5
iovnscli tx staking create-validator \
6
--moniker "${MONIKER}" \
7
--amount 100000000uvoi \
8
--commission-max-change-rate 0.01 \
9
--commission-max-rate 0.2 \
10
--commission-rate 0.1 \
11
--min-self-delegation 1 \
12
--from ${SIGNER} \
13
--pubkey $(iovnsd tendermint show-validator --home ${DIR_WORK}) \
14
--gas-prices 1.0uvoi \
15
--node https://rpc.cluster-galaxynet.iov.one:443 \
16
--chain-id ${CHAIN_ID}
17
18
Copied!
Happy validating!
Last modified 7mo ago