Adding canoLiq (chain 29) to your validator
Prerequisites: a Canopy chain-1 validator.
You need a second node process. A Canopy node serves one chain, because chainId is a single value, so chain 29 runs alongside your chain-1 node, using the same validator key.
Never run two chain-29 nodes with the same key. Signing twice at the same height is a double-sign, and it is slashed. If your validator already runs a chain-29 node somewhere, don't start another one with its key. A second server should be a full node with its own key (Run a canoLiq Node).
1. Clone the repo
git clone https://github.com/Canoliq/node.git canoliq-node
cd canoliq-node
2. Create .env
cp .env.example .env
Then set DOMAIN in .env to your server's public hostname:
DOMAIN=<your-public-host>
DOMAIN overrides externalAddress in config.json, so don't skip it. If your chain-1 node runs on the same server, use the same DOMAIN as that node: one machine, one hostname, told apart by port (9001 for chain 1, 9029 for chain 29).
3. Install your validator key
To validate with your existing chain-1 validator, copy its key files into config/. Don't generate new ones:
cp /path/to/your/chain-1/config/validator_key.json /path/to/your/chain-1/config/keystore.json config/
Only use make gen-key if you're setting up a separate full node, not your validator.
4. Set the root chain
rootChain in config/config.json must point at a chain-1 RPC:
| Your setup | rootChain URL |
|---|---|
Chain-1 node on this same server (canopy-network/node, run as-is) | http://node:50002 |
| No chain-1 node on this server | https://root.net.app.canopynetwork.org, the default, so leave it as is |
Scheme, host and port only, with no path and no trailing slash. The details, including a chain-1 node in a non-default folder, are in Run a canoLiq Node → step 4.
5. Restore from a snapshot (optional)
To skip the ~25-minute sync from genesis:
make snapshot
6. Open the P2P port
Allow inbound TCP 9029 in the host firewall. With ufw:
sudo ufw allow 9029/tcp
Open it in your provider's firewall too, if it has one.
7. Start the node
If your chain-1 node runs on this same server (the usual case for validators):
make node-up-local-rootchain
Otherwise:
make node-up
8. Verify, before you stake
8a. Is the node at the latest height? The height should match the current block:
docker exec canoliq-node wget -qO- --post-data='{}' --header='Content-Type: application/json' http://127.0.0.1:50002/v1/query/height
8b. Is the node ready to be staked? Expect "genesisComplete": true:
docker exec canoliq-node wget -qO- http://127.0.0.1:8587/v1/health
8c. Is the P2P port open and reachable? Run this from another machine (a remote session, not this server):
nc -z <your-host> 9029
If the node has been running for more than 25 minutes and 8a is stuck at block 0, 2 or 4679, see Run a canoLiq Node → Troubleshooting. Block 0 almost always means rootChain (step 4).
9. Stake, last
Edit-stake your existing chain-1 validator:
- Committees:
1,29 - Validator address:
tcp://<your-public-host>, with no port
Two things that will break it:
- Don't add
:9029. Canopy adds the chain ID to any port you give, so:9029becomes 9058. With no port it derives 9029 correctly. - The address must resolve directly to your server. P2P is raw TCP and cannot pass through an HTTP proxy or CDN.
Stake last, not first. The edit-stake takes effect immediately, at your full stake weight, with no check that your node is running. If you hold a meaningful share of the committee and aren't serving, the chain halts.
Just want to participate? Delegate instead
Add chain ID 29 to your committees as a delegate. You don't need a node, and it can't affect the chain's liveness, because delegates count toward the committee's stake but never enter the validator set.
To earn canoLiq rewards on CNLQ without running anything, stake on canoliq.org.