Tutorial: Creating and Joining a Network
In this tutorial, we will:
- Create a node and start a new network.
- Create a second node and configure it to join the network.
- Add the second node to the network as a non-validating peer.
- Upgrade the second node to a validator.
In order to do this tutorial, you will need to install the kwild
binary,
as well as have docker
installed.
Creating The First Node
Creating The Node's Files
To create the node's configuration files, a new genesis.json
, and a new key pairs, we will use the kwild setup
command:
kwild setup init --root ./testnet/node0 --db-owner <YOUR_ETHEREUM_ADDRESS>
The ./testnet/node0
folder will be the "root" directory for kwild
that
contains the configuration files, including genesis.json
and config.toml
.
Running The Node
To run the first node, we will need to start a properly configured PostgreSQL instance. We will use a default pre-configured image provided by
Kwil. For information on how this can be configured manually, see the node's PostgreSQL configuration section.
Once the PostgreSQL instance is running, we can start the node using the kwild
binary:
# Run Postgres
docker run -d -p 5432:5432 --name kwil-postgres -e "POSTGRES_HOST_AUTH_METHOD=trust" \
kwildb/postgres:latest
# Run the node
kwild start --root ./testnet/node0 --admin.listen /tmp/node0.sock --db.port 5432
The command then runs the local Kwil network, and begins producing blocks.
We override the default admin.listen
because in this tutorial, we will be running two nodes on the same machine.
To allow us to interact with both nodes' admin RPCs, we will make them listen on different UNIX sockets.
Getting The Node's Info
In order to allow other nodes to join, we will need to expose our node's information publicly. Other operators can then set us as a peer, and request to join the network as a validator.
To get our node's information, we can use the kwild node
tool, specifying the UNIX socket that our admin RPC is listening on:
$ kwild admin status --rpcserver /tmp/node0.sock
{
"node": {
"chain_id": "kwil-test-chain",
"node_id": "02e804dfd8e28cbd791fd3439149b909e5300d7b7cc6cbd0e94e2178e7ed21e120#secp256k1", # node ID
"app_ver": 1,
"listen_addr": "127.0.0.1:6600", # p2p address
"role": "leader",
"rpc_addr": "/tmp/kwild.socket"
},
"sync": {
"app_hash": "2d8f3ceeff2c836527da823d7b654d33d3e44b6159b172235c160001e0c9b4db",
"best_block_hash": "3e044fb509b9e55c70f127ccae7884916a668ea389b71ee88a088cf172dd46a9",
"best_block_height": 1,
"best_block_time": "2025-01-27T11:28:02.336-06:00",
"syncing": false
},
"validator": {
"pubkey": "02e804dfd8e28cbd791fd3439149b909e5300d7b7cc6cbd0e94e2178e7ed21e120",
"type": "secp256k1",
"power": 1
}
}
The node.node_id
and node.listen_addr
fields can be given to the second node as a persistent peer, in the format: node-id@p2p-address
.
For the above node, we would have 02e804dfd8e28cbd791fd3439149b909e5300d7b7cc6cbd0e94e2178e7ed21e120#[email protected]:26656
.
Creating A Second Peer Node
Using kwild
to create the second node's directories and configs, we can specify where to find the genesis file and any
peers that it should try to connect to when starting up. Since both nodes are running locally, we need to specify
new addresses for the different endpoints, so that the second node does not conflict with the first node:
Ensure that you replace 02e804dfd8e28cbd791fd3439149b909e5300d7b7cc6cbd0e94e2178e7ed21e120
with your own node's ID obtained from the kwild admin status
command above.
kwild setup init --root ./testnet/node1 --genesis ./testnet/node0/genesis.json \
--p2p.bootnodes 02e804dfd8e28cbd791fd3439149b909e5300d7b7cc6cbd0e94e2178e7ed21e120#[email protected]:6600 \
--rpc.listen=localhost:8485 --admin.listen=/tmp/node1.sock \
--p2p.listen=127.0.0.1:6601
Start the second node to verify that it was created correctly:
# Run Postgres
docker run -d -p 5431:5432 --name kwil-postgres-1 -e "POSTGRES_HOST_AUTH_METHOD=trust" \
kwildb/postgres:latest
# Run the node
kwild start --root=./testnet/node1 --db.port 5431
If done correctly, you should be able to see the second node's logs, where it will have completed block synchronization with the first node. The first node's logs should also show that it has a new peer.
Upgrading The Second Node To A Validator
To upgrade the second node to a validator, we will use the kwild validators
command to:
- Request to join the network as a validator, from the second node
- Approve the request, from the first node
We will use the configured UNIX socket to communicate with the nodes.
Requesting To Upgrade
To request to join from the second node:
kwild validators join --rpcserver /tmp/node1.sock
To check that the request was successful, we can get a list of pending join requests:
$ kwild validators list-join-requests --rpcserver /tmp/node0.sock
Pending join requests (1 approval needed):
| Candidate | Power | Approvals | Expiration |
+--------------------------------------------------------------------------------+-------+-----------+-------------------------------+
| '0385480e6c66e9c98e05a4d7dd597a096058b918a0bac4e337c25363be649e484b#secp256k1' | 1 | 0 | 2025-01-28 14:42:10 -0600 CST |
Approving The Request
The first node can vote to approve the second node by running the kwild validators approve
command and passing the second node's public key:
kwild validators approve <node_pubkey> --rpcserver /tmp/node0.sock
For example, with second node above, <node_pubkey>
would be 0385480e6c66e9c98e05a4d7dd597a096058b918a0bac4e337c25363be649e484b#secp256k1
.
If the requesting node's public key is unknown, all pending requests and their public keys can be retrieved with the kwild validators list-join-requests
command.
The validators approve
command will return a transaction hash of the approval transaction.
When the transaction is included in a block, the second node will be promoted to a validator.
And that's it! The second node should now be a validator on the network. To verify this, we can use kwild validators list
to get the list of validators:
$ kwild validators list --rpcserver /tmp/node0.sock
| Identifier | Power |
+------------------------------------------------------------------------------+-------+
| '02e804dfd8e28cbd791fd3439149b909e5300d7b7cc6cbd0e94e2178e7ed21e120#secp256k1' | 1 |
| '0385480e6c66e9c98e05a4d7dd597a096058b918a0bac4e337c25363be649e484b#secp256k1' | 1 |
The logs for the second node should also show that it has been promoted to a validator: [INF] CONS: Role updated {from=sentry to=validator}
.
Cleanup
If you wish to reset this tutorial, you will need to stop the nodes and Postgres containers, remove the testnet
directory, and remove the Postgres container:
# Stop the nodes using Ctrl+C
# Stop and remove the Postgres containers and their volumes
docker rm -f -v kwil-postgres kwil-postgres-1
# Remove the testnet directory
rm -rf ./testnet
Conclusion
In this tutorial, we have:
- Created a node and started a network.
- Created a second node and configured it to join the network.
- Added the second node to the network as a non-validating peer.
- Promoted the second node to a validator.