This guide assumes you have environment capable of building the substrate node. Follow Build, run & test using source code guide to setup it.
Tag the commit from which you'll build the chain spec and run initial nodes. Use this version of code for all following commands.
For each of your initial nodes/validators, you need following keys:
- controller account, that will allow starting/stopping validation
- stash account, that will actually hold staked LLD
- sessions keys:
- grandpa (ed25519)
- babe (sr25519)
- im_online (sr25519)
- authority_discovery (sr25519)
Commands below require the LIBERLAND_NODE
variable to be set to command of node binary. Examples:
liberland_substrate (develop)> export LIBERLAND_NODE="cargo run -q --release --" # build from source
liberland_substrate (develop)> export LIBERLAND_NODE="./target/release/substrate" # use locally built binary
liberland_substrate (develop)> export LIBERLAND_NODE="$HOME/linux_x86_node" # use downloaded prebuilt binary
Scripts also respect the LIBERLAND_NODE
variable, but default to running cargo
if variable is unset.
These are regular accounts, you can use Polkadot Extension to generate them.
If you prefer, you can also generate them manually from seed:
liberland_substrate (develop)> $LIBERLAND_NODE key inspect '<<YOUR_SEED_HERE>>'
liberland_substrate (develop)> $LIBERLAND_NODE key inspect '<<YOUR_SEED_HERE>>//stash'
Make sure you're using different seed for each node.
Use the get_session_keys_from_seed.sh
:
liberland_substrate (develop)> ./scripts/get_session_keys_from_seed.sh
Provide your seed. If you don't have one, feel free to copy this freshly generated one:
strong uncover fossil tag because announce coast mom blue endless file warrior
Seed: <<YOUR_SEED_HERE>>
gran (ed25519): 8280a7b1f74bc53e6fb2cf686566fbdcc850a61014e96a457e7d763a5e67a3e7
babe (sr25519): 0caf07d84a96f800892699d69eb74d963ae2d8c5ced5c54199c061a270d2b827
imon (sr25519): 509cd46a791813b05615a14b240319c56bc2f7a19106aadb26193bb126e27c40
audi (sr25519): 7c5f75b761139f09b612b4457f24615080dcb0721ba8eb88ee7571d9f4589731
Notice that first command (for grandpa
) uses ed25519
scheme and others use sr25519
scheme.
liberland_substrate (develop)> $LIBERLAND_NODE key inspect --scheme ed25519 '<<YOUR_SEED_HERE>>//gran' # grandpa
liberland_substrate (develop)> $LIBERLAND_NODE key inspect --scheme sr25519 '<<YOUR_SEED_HERE>>//babe' # babe
liberland_substrate (develop)> $LIBERLAND_NODE key inspect --scheme sr25519 '<<YOUR_SEED_HERE>>//imon' # im_online
liberland_substrate (develop)> $LIBERLAND_NODE key inspect --scheme sr25519 '<<YOUR_SEED_HERE>>//audi' # authority_discovery
While it's possible to create the spec file manually, it's recommended to build it from code.
Make sure you have the correct version of code checked out. Go to bin/node/cli/src/chain_spec.rs
and find the fn staging_testnet_config_genesis()
function. In there, do the
following changes:
- Update
initial_authorities
. This is the place were you need to put your initial nodes' keys from Step 2. The order for each item is:- Stash's public key (SS58)
- Controller's public key (SS58)
- Grandpa public key (hex)
- Babe public key (hex)
- Im_online public key (hex)
- Authority_discovery public key (hex)
- Update the
citizens
. Each address on this list will be a valid citizen with a KnownGood judgement and will receive10^18
LLD. - Update the
registrar_key
- it's the address of Citizenship Registrar that will be able to provide identity judgements for citizenship. - Update the
root_key
- it's the account capable of executing sudo calls - Update the
technical_committee
After updating the code, we may now generate the human-readable template for spec:
liberland_substrate (develop)> $LIBERLAND_NODE build-spec --chain staging --disable-default-bootnode > new_chain_spec.json
Open the generated new_chain_spec.json
file in your editor. You may want to adjust things like name
, id
, properties.displayName
to match your new testnet.
Generate the raw chain spec:
liberland_substrate (develop)> $LIBERLAND_NODE build-spec --chain new_chain_spec.json --disable-default-bootnode > new_chain_spec.raw.json
The generated new_chain_spec.raw.json
is the file that should be distributed to all participants of the network and will be used to run our initial nodes.
If you've generated session keys using get_session_keys_from_seed.sh
, you may now run insert_session_keys_from_seed.sh
with the same seed. Make sure you pass the correct chain spec and path where node should store its data:
liberland_substrate (develop)> ./scripts/insert_session_keys_from_seed.sh --chain new_chain_spec.raw.json -d /data/liberland_node/
Provide your seed. If you don't have one, feel free to copy this freshly generated one:
strong uncover fossil tag because announce coast mom blue endless file warrior
Seed: <<YOUR_SEED_HERE>>
gran (ed25519): 8280a7b1f74bc53e6fb2cf686566fbdcc850a61014e96a457e7d763a5e67a3e7
babe (sr25519): 0caf07d84a96f800892699d69eb74d963ae2d8c5ced5c54199c061a270d2b827
imon (sr25519): 509cd46a791813b05615a14b240319c56bc2f7a19106aadb26193bb126e27c40
audi (sr25519): 7c5f75b761139f09b612b4457f24615080dcb0721ba8eb88ee7571d9f4589731
Run following commands. Make sure you pass proper chain spec file, path to node storage and insert the same seed as one used for preparing keys for chain spec.
Notice that first command (for grandpa
) uses ed25519
scheme and others use sr25519
scheme.
liberland_substrate (develop)> $LIBERLAND_NODE key insert --chain new_chain_spec.raw.json -d /data/liberland_node --scheme ed25519 --key-type gran --suri '<<YOUR_SEED_HERE>>//gran'
liberland_substrate (develop)> $LIBERLAND_NODE key insert --chain new_chain_spec.raw.json -d /data/liberland_node --scheme sr25519 --key-type babe --suri '<<YOUR_SEED_HERE>>//babe'
liberland_substrate (develop)> $LIBERLAND_NODE key insert --chain new_chain_spec.raw.json -d /data/liberland_node --scheme sr25519 --key-type imon --suri '<<YOUR_SEED_HERE>>//imon'
liberland_substrate (develop)> $LIBERLAND_NODE key insert --chain new_chain_spec.raw.json -d /data/liberland_node --scheme sr25519 --key-type audi --suri '<<YOUR_SEED_HERE>>//audi'
Make sure you pass the same chain spec and path to data as when inserting session keys:
liberland_substrate (develop)> $LIBERLAND_NODE --chain new_chain_spec.raw.json -d /data/liberland_node --force-authoring --validator
2023-01-03 12:27:50 Substrate Node
2023-01-03 12:27:50 ✌️ version 3.0.0-dev-2c2aac70051
2023-01-03 12:27:50 ❤️ by Parity Technologies <[email protected]>, 2017-2023
2023-01-03 12:27:50 📋 Chain specification: Staging Testnet
2023-01-03 12:27:50 🏷 Node name: energetic-button-0223
2023-01-03 12:27:50 👤 Role: AUTHORITY
2023-01-03 12:27:50 💾 Database: RocksDb at ../test1/chains/staging_testnet/db/full
2023-01-03 12:27:50 ⛓ Native runtime: liberland-4 (liberland-node-0.tx1.au10)
2023-01-03 12:27:53 [0] 💸 generated 3 npos voters, 3 from validators and 0 nominators
2023-01-03 12:27:53 [0] 💸 generated 3 npos targets
2023-01-03 12:27:54 🔨 Initializing Genesis block/state (state: 0x50e6…fc65, header-hash: 0x7899…7aac)
2023-01-03 12:27:54 👴 Loading GRANDPA authority set from genesis on what appears to be first startup.
2023-01-03 12:27:55 👶 Creating empty BABE epoch changes on what appears to be first startup.
2023-01-03 12:27:55 Using default protocol ID "sup" because none is configured in the chain specs
2023-01-03 12:27:55 🏷 Local node identity is: 12D3KooWL8az46KDc6d4iMCtwwx2RW7fxP7DfNYMVQRX7STWzBcj
2023-01-03 12:27:55 💻 Operating system: linux
2023-01-03 12:27:55 💻 CPU architecture: x86_64
2023-01-03 12:27:55 💻 Target environment: gnu
Note the Local node identity is: 12D3KooWL8az46KDc6d4iMCtwwx2RW7fxP7DfNYMVQRX7STWzBcj
in output. Copy this ID from your output, we'll need it later.
Follow the same procedure as for the first node. Make sure you're using different seed for each node.
Create the bootstrap node address. The format is:
/ip4/<IP_ADDRESS>/tcp/30333/p2p/<ID>
Where:
<IP_ADDRESS>
must be replaced with the IP address of your initial nodeID
must be replaced with theLocal node identity
printed in startup log of your initial node.
Make sure you pass the same chain spec and path to data as when inserting session keys.
liberland_substrate (develop)> $LIBERLAND_NODE --chain new_chain_spec.raw.json -d /data/liberland_node --validator --bootnodes /ip4/<IP_ADDRESS>/tcp/30333/p2p/<ID>
2023-01-03 12:27:50 Substrate Node
2023-01-03 12:27:50 ✌️ version 3.0.0-dev-2c2aac70051
2023-01-03 12:27:50 ❤️ by Parity Technologies <[email protected]>, 2017-2023
[...]
2023-01-03 12:34:12 💤 Idle (1 peers), best: #0 (0x7899…7aac), finalized #0 (0x7899…7aac), ⬇ 0 ⬆ 0
Make sure it shows (1 peers)
(or more) in the logs after a minute. If not,
verify that your initial node is running and bootnode address is correct. It's
OK if it doesn't produce/finalize blocks yet, we need all nodes for that.
Now that we've added all initial nodes, we should see that blocks are getting finalized.
Good (notice finalized #9
):
2023-01-03 12:34:12 💤 Idle (2 peers), best: #12 (0x608e…ba6f), finalized #9 (0xb83d…0e43), ⬇ 0 ⬆ 0
Bad (notice finalized #0
):
2023-01-03 12:34:12 💤 Idle (2 peers), best: #12 (0x608e…ba6f), finalized #0 (0x7899…7aac), ⬇ 0 ⬆ 0
If blocks aren't finalized, verify that correct session keys were inserted to each node.