π§ How to run a node
May 28, 2026 Β· View on GitHub
The official Dusk protocol node client and smart contract platform.
π§ How to run a node
This README is for people who want to develop, test nodes locally, and contribute to the Rusk codebase.
For more information on running a node for main- or testnet, see our Node operator docs
π Table of Contents
- Repo Overview
- Prerequisites
- Build and Tests
- Make Commands
- Run a local node for development
- Contracts compilation
- Docker support
πΊοΈ Overview
Code projects
| Name | Description |
|---|---|
| π rusk | Entrypoint for the blockchain node |
| π consensus | Implementation of Dusk's succinct attestation consensus |
| π contracts | Contains Dusk genesis, test and ecosystem contracts |
| π§© data-drivers | Tools to encode/decode contract arguments between RKYV and JS I/O |
| 𧬠dusk-core | Core types used for interacting with Dusk and writing smart contracts |
| π dusk-abi | Dusk application binary interface to develop smart contracts (part of core) |
| π node-data | Core datatypes for the blockchain node |
| βοΈ dusk-vm | The virtual machine to run Dusk smart contracts |
| πͺͺ rusk-profile | Utility to generate a genesis state based on a set profile |
| π¨ rusk-prover | Service exposing functionality to remotely prove zero knowledge proofs |
| β¬οΈ rusk-recovery | Utility to recover the state of a chain |
| β¨οΈ rusk-wallet | Dusk CLI wallet |
| π¨ w3sper.js | Js SDK to integrate Dusk features into applications |
| βοΈ wallet-core | WASM library providing core logic for Dusk wallet implementations |
Infrastructure & Testing
| Name | Description |
|---|---|
| π examples | Example data used for local chain spawning and development |
| π scripts | Utility scripts |
| π§ test-wallet | Wallet for testing against the specifications |
π Prerequisites
- Rust 1.82 nightly or higher
- GCC 13 or higher
- Clang 18 or higher
- Deno 2.x
Setup script
We provide a setup script in the scripts folder that can take care of
everything.
bash scripts/dev-setup.sh
Rust Installation
Rusk makes use of the nightly toolchain, make sure it is installed. Furthermore,
to build the WASM contracts, wasm-pack is required.
To install and set the nightly toolchain, and install wasm-pack, run:
rustup toolchain install nightly
rustup default nightly
cargo install wasm-pack
π οΈ Build and Tests
To build rusk from source, make sure the prerequisites are met. Then you can
simply run the following command to compile everything:
make
To run tests:
make test
That will also compile all the genesis contracts and its associated circuits.
See also make help for all the available commands.
π Make Commands
| Command | Description |
|---|---|
make | Build everything (keys, wasm, abi, state, rusk, rusk-wallet) |
make help | Display available make commands |
make abi | Build the ABI |
make keys | Generate ZK circuit proving keys |
make state | Create the network genesis state |
make wasm | Compile wallet-core to WASM |
make data-drivers | Build data-driver WASM files |
make data-drivers-js | Build data-driver WASM files with JS/alloc support |
make rusk | Build the rusk node binary |
make rusk-wallet | Build the CLI wallet binary |
make test | Run the full test suite |
make clippy | Run clippy on all crates (warnings = errors) |
make doc | Generate documentation for all crates |
make bench | Run benchmarks for node and rusk |
make prepare-dev | One-time setup for local development node |
make run-dev | Launch local ephemeral node |
make run-dev-archive | Launch local ephemeral archive node |
make run | Build and run the node (with keys and state) |
π» Run a local node for development
Spin up local node
Run a single full-node cluster with example state.
Prepare modules:
# Generate the keys used by the circuits
# Compile all the genesis contracts
# Copy example consensus.keys
make prepare-dev
make prepare-dev only prepares the example consensus keys and example state.
It does not create any rusk toml config.
If you change examples/genesis.toml, delete /tmp/example.state before
running make prepare-dev again. The target keeps an existing example state
instead of overwriting it.
Run a Node
# Launch a local ephemeral node
make run-dev
If no HTTP address override is provided, rusk falls back to 127.0.0.1:8080.
Override the local HTTP bind address for one run:
make run-dev RUSK_HTTP_ADDR=127.0.0.1:9080
Use a gitignored per-developer config file:
mkdir -p .rusk
cat > .rusk/local.toml <<'EOF'
[http]
listen_address = "127.0.0.1:9080"
EOF
make run-dev RUSK_CONFIG=.rusk/local.toml
Pass additional dusk-rusk CLI arguments through:
make run-dev RUSK_ARGS='--log-level debug'
If both RUSK_CONFIG and RUSK_HTTP_ADDR are set, RUSK_HTTP_ADDR wins because
the CLI flag overrides the TOML value.
Run an Archive node
make run-dev-archive
The same overrides work for archive mode:
make run-dev-archive RUSK_HTTP_ADDR=127.0.0.1:9080
make run-dev-archive RUSK_CONFIG=.rusk/local.toml
rusk/default.config.tomlandrusk/mainnet.config.tomlare templates for user-supplied config. They are not auto-discovered at runtime.
If you move rusk off 127.0.0.1:8080, point rusk-wallet at the same
address:
rusk-wallet --state http://127.0.0.1:9080 --prover http://127.0.0.1:9080
If archive endpoints matter for your workflow:
rusk-wallet --state http://127.0.0.1:9080 --prover http://127.0.0.1:9080 --archiver http://127.0.0.1:9080
For a persistent wallet-side override, update [network.local] in
~/.config/rusk-wallet/config.toml or {wallet_dir}/config.toml.
Use the unstaked example wallet
The default example recovery phrase in examples/recovery-phrase.txt is funded
and staked. For localnet testing with a funded wallet that has no active stake,
use make run-dev-second from rusk-wallet/. The target copies
examples/wallet-unstaked.dat into an explicit wallet directory on first use.
The matching recovery phrase is stored in examples/recovery-phrase-unstaked.txt.
Run a Prover Node
The node can be build as a prover only as follows:
cargo r --release --no-default-features --features prover -p dusk-rusk
This prover node will be accessible on https://localhost:8080. Apps like the
rusk-wallet can
be connected to it for quicker and more private local proving.
π Contracts compilation
Compile all the genesis contracts without running the server:
make contracts
Compile a specific genesis contract:
# generate the wasm for `transfer` contract
make wasm for=transfer
π³ Docker support
Local Ephemeral Node
It's also possible to run a local ephemeral node with Docker.
To build the Docker image with archive:
docker build -f Dockerfile.ephemeral -t rusk .
To build the Docker image without archive:
docker build -t -f Dockerfile.ephemeral rusk --build-arg CARGO_FEATURES="" .
To run Rusk inside a Docker container:
docker run -p 9000:9000/udp -p 8080:8080/tcp rusk
Port 9000 is used for Kadcast, port 8080 for the HTTP and GraphQL APIs.
Persistent Node
To build the docker image for a provisioner
docker build -f Dockerfile.persistent -t rusk --build-arg NODE_TYPE=provisioner .
To build for an archiver or prover instead, build with NODE_TYPE=archive or NODE_TYPE=prover, respectively.
To run:
docker run -it \
-v /path/to/consensus.keys:/opt/dusk/conf/consensus.keys \
-v /path/to/rusk/profile:/opt/dusk/rusk \
-e NETWORK=<mainnet|testnet> \
-e DUSK_CONSENSUS_KEYS_PASS=<consensus-keys-password> \
-p 9000:9000/udp \
-p 8080:8080/tcp \
rusk
Customizing Configuration
The configuration used for rusk is based on the template file at https://raw.githubusercontent.com/dusk-network/node-installer/ac1dd78eb31be4dba1c9c0986f6d6a06b5bd4fcc/conf/mainnet.toml for mainnet and https://raw.githubusercontent.com/dusk-network/node-installer/ac1dd78eb31be4dba1c9c0986f6d6a06b5bd4fcc/conf/testnet.toml for testnet.
As part of the node setup process when the container is started, the IP addresses used for listening in kadcast and, if
configured, http will be detected and automatically configured.
To customize the configuration, the configuration template file can be copied and modified. The custom configuration template
should be mounted on /opt/dusk/conf/rusk.template.toml.
docker run -it \
-v /path/to/consensus.keys:/opt/dusk/conf/consensus.keys
-v /path/to/rusk/profile:/opt/dusk/rusk \
-v /path/to/rusk.modified-template.toml:/opt/dusk/conf/rusk.template.toml \
-e NETWORK=<mainnet|testnet|devnet> \
-e DUSK_CONSENSUS_KEYS_PASS=<consensus-keys-password> \
-p 9000:9000/udp \
-p 8080:8080/tcp \
rusk
IP Addresses
When using a custom configuration file, properties that use IP addresses should be set to 'N/A'. For example, if you want HTTP to be configured:
[http]
listen_address = 'N/A'
This entry should be present in the template configuration file. When the node is starting, the address to be used will be detected and this configuration will be set to listen at port 8080.
Likewise, the kadcast.public_address and kadcast.listen_address properties in the configuration file should be set
to 'N/A'. During node startup, they will be detected and set to use port 9000.
License
The Rusk software is licensed under the Mozilla Public License Version 2.0.