If you are up for a challenge and want to participate in the network by running your own Guild Network node you need the following
- a linux-based machine running either
- Debian (
bullseye
orbookworm
version) - Ubuntu (at least
20.04-focal
version, our nodes run on22.04-jammy
) - Arch Linux (we only checked with the
6.1.12
kernel version)
- Debian (
- you need to install the Rust toolchain and
cargo
(Rust's package manager)
# install rustup
curl https://sh.rustup.rs -sSf | sh
- you need to add the
wasm32-unknown-unknown
target on thenightly
channel:
rustup update nightly
rustup target add wasm32-unknown-unknown --toolchain nightly
- some packages that might not be pre-installed on a fresh build (package names may differ depending on the installed OS)
librocksdb-dev
libclang-dev
clang
,cmake
g++-multilib
libssl-dev
llvm
,llvm-dev
pkg-config
protobuf-compiler
- for our nodes we use servers with the following setup
- hardware - we use a setup recommended for Polkadot validators
- costs - depends on the service you are using, but for our nodes currently
- €70/month/node
- €50/node one-time setup fee
To make life easier, here's a checklist you need to go through to become a validator:
- clone the repository (you might need to set up an SSH key first)
- build the source code
- download the genesis chain specification
chain-spec-raw.json
- generate cryptographic validator keys
- Sr25519 for
aura
- Ed25519 for
grandpa
- Sr25519 for
- add the cryptographic validator keys to your node's local keystore
- add the
aura
key - add the
grandpa
key
- add the
- start your validator node
- set your public session keys
- make an RPC call to rotate your keys
- notify us so we can register you as a validator via the
sudo
account (this step will be replaced by governance on the mainnet)
Running a validator requires you to generate a couple of cryptographic keys for which you need to build the source code first.
To build the source code you need to clone it first:
# ssh (recommended)
git clone [email protected]:agoraxyz/guild-network.git
# https
git clone https://github.com/agoraxyz/guild-network.git
cd guild-network
cargo build --release
NOTE: the build process will take somewhere between 20-30 minutes
(depending on the hardware) to build in --release
mode. For optimal
performance, however, it is highly advised to build the code in --release
mode.
TROUBLESHOOTING: if you get secp256k1
-related warnings/errors like No available targets are compatible with this triple
and the code fails to build
you might need to run export CC=gcc
before cargo build --release
.
In case you want to quickly check your node, run the following from the workspace root
./scripts/dev.sh
This will spin up a clean node that you can interact with from the browser. You should see it importing and finalizing blocks in the logs, something along the lines of:
2023-03-06 10:13:11 Substrate Node
2023-03-06 10:13:11 ✌️ version 0.0.0-alpha-2d65307203d
2023-03-06 10:13:11 ❤️ by , 2017-2023
2023-03-06 10:13:11 📋 Chain specification: Development
2023-03-06 10:13:11 🏷 Node name: common-flag-2215
2023-03-06 10:13:11 👤 Role: AUTHORITY
2023-03-06 10:13:11 💾 Database: RocksDb at /tmp/substrateJDibik/chains/dev/db/full
2023-03-06 10:13:11 ⛓ Native runtime: guild-network-101 (guild-network-1.tx1.au1)
2023-03-06 10:13:11 🔨 Initializing Genesis block/state (state: 0xee74…0185, header-hash: 0x9fc1…2e54)
2023-03-06 10:13:11 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2023-03-06 10:13:11 Using default protocol ID "sup" because none is configured in the chain specs
2023-03-06 10:13:11 🏷 Local node identity is: 12D3KooWJVrSt1ukXdmM94Tu2RSCkRnzumYtmFJuWRZcwVXCuHti
2023-03-06 10:13:11 💻 Operating system: linux
2023-03-06 10:13:11 💻 CPU architecture: x86_64
2023-03-06 10:13:11 💻 Target environment: gnu
2023-03-06 10:13:11 💻 CPU: AMD Ryzen 5 3600 6-Core Processor
2023-03-06 10:13:11 💻 CPU cores: 6
2023-03-06 10:13:11 💻 Memory: 7872MB
2023-03-06 10:13:11 💻 Kernel: 6.1.12-arch1-1
2023-03-06 10:13:11 💻 Linux distribution: Arch Linux
2023-03-06 10:13:11 💻 Virtual machine: no
2023-03-06 10:13:11 📦 Highest known block at #0
2023-03-06 10:13:11 〽️ Prometheus exporter started at 127.0.0.1:9615
2023-03-06 10:13:11 Running JSON-RPC HTTP server: addr=127.0.0.1:9933, allowed origins=["*"]
2023-03-06 10:13:11 Running JSON-RPC WS server: addr=127.0.0.1:9944, allowed origins=["*"]
2023-03-06 10:13:12 🙌 Starting consensus session on top of parent 0x9fc14b5ce5543f8ce21e87a91b094df4ea2e03f1960fcf39e1cf49ffbfa72e54
2023-03-06 10:13:12 🎁 Prepared block for proposing at 1 (0 ms) [hash: 0x178ec36ac2a9e9f7613816cd1ba8f978a6052471f8ee703a6e75a419e287e446; parent_hash: 0x9fc1…2e54; extrinsics (1): [0x286a…46d6]]
2023-03-06 10:13:12 🔖 Pre-sealed block for proposal at 1. Hash now 0xbb88abc6ffaa246af0d67a90688cbd26b02eca8e0407d61e76e05e5621af9c0c, previously 0x178ec36ac2a9e9f7613816cd1ba8f978a6052471f8ee703a6e75a419e287e446.
2023-03-06 10:13:12 ✨ Imported #1 (0xbb88…9c0c)
2023-03-06 10:13:16 💤 Idle (0 peers), best: #1 (0xbb88…9c0c), finalized #0 (0x9fc1…2e54), ⬇ 0 ⬆ 0
NOTE: This command does not deploy your node, it only starts a local development node to ensure the source was built properly and the node behaves as it should.
Every validator node will need to generate two cryptographic keys for aura
(block creation) and grandpa
(block finalization)
consensus.
./target/release/gn-node key generate --scheme Sr25519 --password-interactive
This will prompt the user to provide a password and will output something like
Secret phrase: pig giraffe ceiling enter weird liar orange decline behind total despair fly
Secret seed: 0x0087016ebbdcf03d1b7b2ad9a958e14a43f2351cd42f2f0a973771b90fb0112f
Public key (hex): 0x1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
Account ID: 0x1a4cc824f6585859851f818e71ac63cf6fdc81018189809814677b2a4699cf45
Public key (SS58): 5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW
SS58 Address: 5CfBuoHDvZ4fd8jkLQicNL8tgjnK8pVG9AiuJrsNrRAx6CNW
Here the SS58
address is the encoded public key which will be needed at later
steps.
Using the secret phase from the Sr25519 key generation output run the following with the same password as before
./target/release/gn-node key inspect --password-interactive --scheme Ed25519 \
"pig giraffe ceiling enter weird liar orange decline behind total despair fly"
which will output something like
Secret phrase `pig giraffe ceiling enter weird liar orange decline behind total despair fly` is account:
Secret seed: 0x0087016ebbdcf03d1b7b2ad9a958e14a43f2351cd42f2f0a973771b90fb0112f
Public key (hex): 0x2577ba03f47cdbea161851d737e41200e471cd7a31a5c88242a527837efc1e7b
Public key (SS58): 5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN
Account ID: 0x2577ba03f47cdbea161851d737e41200e471cd7a31a5c88242a527837efc1e7b
SS58 Address: 5CuqCGfwqhjGzSqz5mnq36tMe651mU9Ji8xQ4JRuUTvPcjVN
where the SS58
address will be needed for later steps.
Every validator node needs to insert their aura
and grandpa
keys into their
keystore which requires the following steps.
./target/release/gn-node key insert \
--base-path [data-dir] \
--chain chain-spec-raw.json \
--scheme Sr25519 \
--suri [your-secret-seed] \
--password-interactive \
--key-type aura
NOTE: use the same secret seeds and password as during the key generation step.
./target/release/gn-node key insert \
--base-path [data-dir] \
--chain chain-spec-raw.json \
--scheme Ed25519 \
--suri [your-secret-seed] \
--password-interactive \
--key-type gran
NOTE: use the same secret seeds and password as during the key generation step.
Finally, verify that the output of
ls [data-dir]/chains/[chain name]/keystore # e.g. /tmp/mynode/chains/testnet/keystore
resembles this:
617572611441ddcb22724420b87ee295c6d47c5adff0ce598c87d3c749b776ba9a647f04
6772616e1441ddcb22724420b87ee295c6d47c5adff0ce598c87d3c749b776ba9a647f04
NOTE: Leaving unsafe RPC endpoints exposed towards the internet is dangerous as they can be used to interfere with the function of your node if called by malicious actors. When running a validator node with unsafe rpc methods enabled, it's critical to filter out unsafe RPC calls detailed in this article.
In order to register as a validator you will need to call the
author_rotateKey
RPC method at one point which is an unsafe RPC call. Thus,
when you first start your node you need to enable unsafe RPC calls until
you've successfully joined the validator set. A Substrate
seminar
also suggests starting a node like this.
./target/release/gn-node \
--base-path [data dir] \
--chain [raw-chain-spec] \
--validator \
--name [name] \
--bootnodes [bootnode multiaddr] \
--enable-offchain-indexing true \
--unsafe-ws-external \
--unsafe-rpc-external \
--rpc-methods=Unsafe \
--rpc-cors=all \
--ws-max-connections 5000 \
--pruning=archive
--no-private-ipv4
You should download the raw chain specification from
here
and plug that into [raw-chain-spec]
. [data-dir]
and [name]
are free to
choose. However, line --bootnodes [bootnode multiaddress]
should look like
this
--bootnodes /ip4/65.108.10.251/tcp/30333/p2p/12D3KooWFFsqmfq77obEVLuZFzEZatogmPeLHYrZQh1j82nUBctu
For this step you'll need to connect to a node via a secure websocket connection using the polkadot.js app. In case you cannot connect to your node, here is the link to the node explorer connected to our bootnode.
Make sure you have installed the polkadot.js wallet extension. If you already have a Polkadot address in your wallet, you don't need to generate a fresh keypair, otherwise make sure you generate a new one and save its mnemonic seed. Reach out to us for some testnet tokens before the next steps.
aura
and grandpa
consensus happens in sessions with each session holding a
set of validators to particpate in the consensus. Therefore, after the node is
up and running, you need to get your public aura
and grandpa
keys from the
node.
You need to perform steps 4 to
6.
First, you should call author_rotateKeys
on your local node, so if you cannot
connect to your node via the polkadot app, just run the following command
locally on your validator's machine:
# on your validator's local machine
curl -H 'Content-Type: application/json' --data '{ "jsonrpc":"2.0", "method":"author_rotateKeys", "id":1 }' http://127.0.0.1:9933
The above command should return something like
{"jsonrpc":"2.0","result":"0xc94ac23bb8f077a7ba274d1c3253c26890844452f14820241d40536e310aef43fc4bbb402fba885dd4a94f65858c3fc5d5117848dbf5536b60cba624476ee12f","id":1}
where you need to split the result into two 32-byte keys, one for aura
and
one for grandpa
. Then you should perform step 6 in the tutorial linked above,
from the node explorer.
Make sure to add the 0x
prefix to both keys and for the proof just simply
write 0x
. This will tell the session
pallet what your validator keys should
be.
After you've successfully submitted the transaction (you should get a green
tick icon in the upper right corner) let us know so we can register your
validator via the sudo
pallet.
After you've successfully joined as a validator, you may choose to restart your
node via one of the following options. Note, that if you haven't started your
node with --pruning=archive
before, then you won't be able to start an
archive node unless you prune the node database and start syncing again.
- archive node (recommended, because it keeps the whole chain state in the database - for reference, a Polkadot archive node has a ~560GB state as of nov. 2022)
./target/release/gn-node \
--base-path [data dir] \
--chain [raw-chain-spec] \
--validator \
--name [name] \
--bootnodes [bootnode multiaddr] \
--enable-offchain-indexing true \
--pruning=archive
--no-private-ipv4
- rpc node (keeps rpc ports open for safe rpc methods)
./target/release/gn-node \
--base-path [data dir] \
--chain [raw-chain-spec] \
--validator \
--name [name] \
--bootnodes [bootnode multiaddr] \
--enable-offchain-indexing true \
--unsafe-ws-external \
--rpc-methods Safe \
--rpc-cors=all \
--ws-max-connections 5000 \
--pruning=archive
--no-private-ipv4
- pruning validator node (prunes old blocks from the database while only keeping the most recent 256)
./target/release/gn-node \
--base-path [data dir] \
--chain [raw-chain-spec] \
--validator \
--name [name] \
--bootnodes [bootnode multiaddr] \
--enable-offchain-indexing true \
--pruning=256
--no-private-ipv4
NOTE: None of the above nodes will expose unsafe RPC methods.
If you want the chain explorer and the frontend to be able to connect to your
node via a secure websocket connection (wss
) you need to set up your server
accordingly. We use caddy on our bootnode's server
to enable secure connections.
If you have experience with such setups than go ahead and do it, otherwise, details coming soon...