node and validator
Run a node or a validator
A full node follows the Dendra chain and checks every block for itself. A validator is a full node that also signs blocks and locks a stake. This page is for anyone with a Linux server that stays on: neither role needs a GPU.
choose a role
Other operator guides
How it works
A full node
Syncs the chain from the public seeds and serves RPC and REST on your machine. It signs nothing, has nothing at stake and earns nothing.
A validator
Also signs blocks, and its VRF key adds to the random seed that draws juries and work. Its stake answers for downtime and double-signing.
What validators are paid
Every paid job carries a protocol cut (protocol_fee_bps), and validator_reward_bps of that cut goes to validators, at the job’s finality.
No kit version
Neither role declares a kit version, so the kit deadline for miners does not apply to either of them.
What you need
A validator is the demanding case: it should run on a server that stays on.
| Item | Requirement |
|---|---|
| Machine | No GPU. For a validator, a server that stays on, such as a VPS: long downtime gets a validator jailed and slashed. |
| System | Linux, or Windows with WSL 2. Docker with Compose v2. |
| Disk and RAM | Free disk above MIN_DISK_GB and RAM above MIN_RAM_MB, the floors deploy/install.sh applies. Without a prebuilt image the node compiles the chain binary from your clone, which is what the RAM floor is for. |
| Network | Port 26656 (P2P) reachable from outside for a validator; for a full node it helps the network. The RPC port, 26657, stays on 127.0.0.1 by default. |
Read the floors from a clone of the repository:
$ git clone https://github.com/DendraNetwork/dendra-network.git && cd dendra-network $ grep -E '^MIN_(DISK_GB|RAM_MB)=' deploy/install.sh
Join as a full node
Three steps. The node has no bond, so nothing here puts funds at risk.
Clone
$ git clone https://github.com/DendraNetwork/dendra-network.git $ cd dendra-network/deploy/testnet-node
Fill the configuration from the network’s own file
The first command prints the network’s values. Copy its
CHAIN_ID,GENESIS_URL,GENESIS_SHA256,SEEDSandPERSISTENT_PEERSlines into.env, and setMONIKERto the name your node shows to its peers.$ curl -s https://testnet-api.dendranetwork.com/network-info.txt $ cp .env.example .env $ nano .env
Start it
The node checks the genesis it downloads against
GENESIS_SHA256and refuses to start on a mismatch.$ docker compose up -d --build $ docker compose logs -f node
Join as a validator
A validator starts from a node that join.sh sets up and syncs. join.sh never bonds: the bond is a separate command, and nothing is bonded without --yes-bond.
Clone, read the launcher, join as a validator
Run
lesson its own: a pager swallows anything pasted after it. Quit withq.$ git clone https://github.com/DendraNetwork/dendra-network.git && cd dendra-network$ less deploy/join.sh$ CONFIG_URL=https://testnet-api.dendranetwork.com/network-info.txt bash deploy/join.sh --validatorOn a bare machine, the installer prepares Docker and runs the same join:
bash install.sh --yes --validator(-Validatorwithinstall.ps1on Windows). How to download it: install.Read what bonding commits you to
The slashing terms (
signed_blocks_window,min_signed_per_window,downtime_jail_duration,slash_fraction_downtime,slash_fraction_double_sign) and the staking terms (unbonding_time,max_validators) are read on chain:$ curl -s https://testnet-api.dendranetwork.com/rest/cosmos/slashing/v1beta1/params $ curl -s https://testnet-api.dendranetwork.com/rest/cosmos/staking/v1beta1/params
Not ready for that uptime? A full node has no bond and nothing at stake.
Create your key and see the plan
Run it once the node is synced. It creates the operator key, prints your validator address, then refuses for lack of funds: that refusal is expected, and it is how you get the address.
$ bash deploy/bond_validator.shFund the address
The public faucet asks for a short proof of work, computed in a terminal: the faucet claim, with the address from step 3. Then run
bash deploy/bond_validator.shagain: it prints the largest bond your balance covers, in udndr.Bond
There is no confirmation prompt: the flag is what bonds. It also anchors your VRF key and restarts the node with it.
$ bash deploy/bond_validator.sh --amount <udndr printed in step 4> --yes-bondThe script refuses a bond that would leave any validator with two thirds of the voting power or more. If it refuses yours, ask in #operator-support before going further.
Check
A node is synced
When this prints "catching_up":false:
$ curl -s http://localhost:26657/status | grep -o '"catching_up":[a-z]*'
A validator
Whether it is jailed or slashed, and the margin left before the next jail, from the clone’s root:
$ bash deploy/validator_health.sh
The validator set and the seed
The validator set and each one’s voting power:
$ curl -s https://testnet-api.dendranetwork.com/rpc/validators
The seed’s contributors. After you bond, latest_contributors goes up:
$ curl -s https://testnet-api.dendranetwork.com/rest/dendra/jobs/v1/committee_seed_health
Open the port
Allow 26656/tcp in the host firewall and, on a VPS, in your provider’s firewall, which is a separate setting in their console. At home, forward 26656 to the machine on your router. Then give the node its public address, in deploy/testnet-node:
$ sed -i 's|^DENDRA_EXTERNAL_ADDRESS=.*|DENDRA_EXTERNAL_ADDRESS=YOUR.PUBLIC.IP:26656|' .env $ docker compose up -d
The node refuses to start on a private or loopback address. To see whether peers reach you, from the clone’s root:
$ bash deploy/node_reachability.sh
Keep the RPC local. 26657 is published on 127.0.0.1 by default (DENDRA_RPC_BIND in .env), and a miner on the same machine still reaches the node over Docker. Set 0.0.0.0 only for a public RPC on purpose: on a VPS, that is an unauthenticated RPC open to the internet.
Update
Do not use git pull: each release republishes the repository, so it refuses with “refusing to merge unrelated histories” and the old kit stays. First move the clone; the tree you leave stays on the branch kit-before-update, and this line alone changes nothing that runs:
$ git fetch origin && git branch -f kit-before-update && git checkout -B main origin/main
A full node started with docker compose
Run docker compose up -d --build again, in deploy/testnet-node.
A validator set up by join.sh
Run the same join.sh command again, CONFIG_URL and --validator included. A re-run bonds nothing.
Installed with install.sh --ref
Download the installer of the newer release tag and run it with --yes, --ref set to that tag, and your first options.
A miner on the same machine
Help
Ask in #operator-support on the Discord, with the last lines of the node’s log (docker compose logs --tail 40 node, in deploy/testnet-node).