This guide will help you install and run a Quantus Network node for mining.
🚀 Quick Start Mining: See our Mining Guide for a comprehensive setup tutorial with troubleshooting and optimization tips.
Install rustup. This repository pins the compiler in rust-toolchain: stable 1.93.0, the clippy component, and the wasm32v1-none target. cargo installs and selects that toolchain when you build inside the repo. Leave your global default toolchain alone.
Host packages match CI:
- Ubuntu/Debian:
clang,libclang-dev,protobuf-compiler - macOS (Homebrew):
protobuf,llvm,cmake,openssl. Point bindgen at Homebrew LLVM withexport LIBCLANG_PATH="$(brew --prefix llvm)/lib". - Windows:
protocand LLVM (choco install protoc llvm), withLIBCLANG_PATHset toC:\Program Files\LLVM\bin.
Formatting uses a different compiler. Nightly rustfmt is pinned in rustfmt-toolchain and installed by scripts/fmt.sh. Full steps are in docs/rust-setup.md.
Check the active toolchain from the repository root:
rustup show
# active toolchain: 1.93.0Use the following command to build the node:
cargo build --releaseThe compiled binary will be available at ./target/release/quantus-node.
./target/release/quantus-node key quantusThis creates a new 24-word phrase, seed, and public and private keys.
./target/release/quantus-node key quantus --wordsYou will be prompted for the phrase (input is not echoed). Non-interactively, pipe it in: ./target/release/quantus-node key quantus --words < mnemonic.txt.
Words should be a 24-word list separated by spaces, like "autumn bear...". The words must be from the BIP39 wordlist.
./target/release/quantus-node key quantus --seedYou will be prompted for the seed (input is not echoed). Non-interactively, pipe it in: ./target/release/quantus-node key quantus --seed < seed.txt.
Seed must be a 128-character hexadecimal string (64 bytes).
Secrets are deliberately read from stdin rather than accepted as command-line arguments: argv is world-readable via
/proc/<pid>/cmdline, recorded in shell history, and commonly captured by audit and orchestration logs.
For complete mining setup instructions, including wormhole address requirements and external miner configuration, see MINING.md.
Start a single-node development chain (state is not persisted):
./target/release/quantus-node --devTo purge the development chain's state:
./target/release/quantus-node purge-chain --devTo start with detailed logging:
RUST_BACKTRACE=1 ./target/release/quantus-node -ldebug --dev- Maintains state in a
tmpfolder while the node is running - Uses the Alice and Bob accounts as default validator authorities
- Governance is bootstrapped via the tech collective (no sudo pallet)
- Preconfigured with a genesis state (
/node/src/chain_spec.rs) that includes several pre-funded development accounts
To persist chain state between runs, specify a base path:
# Create a folder to use as the db base path
mkdir my-chain-state
# Use that folder to store the chain state
./target/release/quantus-node --dev --base-path ./my-chain-state/
# Check the folder structure created inside the base path after running the chain
ls ./my-chain-state
# chains
ls ./my-chain-state/chains/
# dev
ls ./my-chain-state/chains/dev
# db keystore networkTo run a local testnet with multiple validator nodes, use the provided script:
# From workspace root
./scripts/run_local_nodes.shThis script handles building the node and launching two validator nodes and a listener node connected to each other. Refer to the script comments for configuration details.
If you want to see the multi-node consensus algorithm in action, see Simulate a network.
We use taplo for formatting TOML files and nightly rustfmt for Rust code. The rustfmt nightly is pinned in
rustfmt-toolchain; scripts/fmt.sh installs it on first use and forwards its arguments to cargo fmt.
taplo format --config taplo.toml
scripts/fmt.sh --all -- --checkThis chain has mandatory storage configuration settings that cannot be overridden by command-line parameters:
Blocks Pruning: KeepFinalized
State Pruning: ArchiveCanonical
ArchiveCanonical State Pruning: The node will keep the state for all blocks that are part of the canonical chain. This ensures you can query historical state for any finalized block, while non-canonical blocks' states are pruned to save disk space.
KeepFinalized Blocks Pruning: The node will keep all finalized blocks and prune non-finalized blocks that become stale.
Note that any command-line parameters related to pruning (--state-pruning, --blocks-pruning) will be ignored as these settings are enforced at the code level for all node operators.
The runtime's storage weights are priced for ParityDb, and new nodes use it by default
(--database auto: an existing RocksDB database under <base-path>/chains/<id>/db is reused,
otherwise ParityDb is created under <base-path>/chains/<id>/paritydb).
Nodes still on RocksDB log a warning at startup. They keep working, but state access is several times slower than the weights assume, so DB-heavy blocks take longer to import. To migrate without a full resync:
./target/release/quantus-node export-blocks --chain <chain> --base-path <old-path> --binary blocks.bin
./target/release/quantus-node import-blocks --chain <chain> --base-path <new-path> --database paritydb --state-pruning archive-canonical --binary blocks.bin--state-pruning archive-canonical is required: the pruning mode is fixed when the database is
created, and a database imported with the backend's default constrained pruning cannot be
reopened by the node (which enforces archive-canonical). Then start the node with
--base-path <new-path>. Node keys and keystore files live outside
the database directory and should be copied over from the old base path.
This configuration provides a good balance between storage efficiency and data availability. You should expect your database to grow steadily over time as the blockchain progresses, though at a slower rate than a full archive node. If you're running a validator or service that needs access to historical chain state, this configuration will meet your needs while optimizing disk usage.
After you start the node locally, you can interact with it using the hosted version of the Polkadot/Substrate Portal front-end by connecting to the local node endpoint. A hosted version is also available on IPFS. You can also find the source code and instructions for hosting your own instance in the polkadot-js/apps repository.
After you build the project, you can use the following command to explore its parameters and subcommands:
./target/release/quantus-node -hYou can generate and view the Rust Docs for this project with this command:
cargo doc --openA Substrate project such as this consists of a number of components that are spread across a few directories.
A blockchain node is an application that allows users to participate in a blockchain network. Substrate-based blockchain nodes expose a number of capabilities:
- Networking: Substrate nodes use the
libp2pnetworking stack to allow the nodes in the network to communicate with one another. - Consensus: Blockchains must have a way to come to consensus on the state of the network. Substrate makes it possible to supply custom consensus engines and also ships with several consensus mechanisms that have been built on top of Web3 Foundation research.
- RPC Server: A remote procedure call (RPC) server is used to interact with Substrate nodes.
There are several files in the node directory. Take special note of the following:
chain_spec.rs: A chain specification is a source code file that defines a Substrate chain's initial (genesis) state. Chain specifications are useful for development and testing, and critical when architecting the launch of a production chain. Take note of thedevelopment_configandtestnet_genesisfunctions. These functions are used to define the genesis state for the local development chain configuration. These functions identify some well-known accounts and use them to configure the blockchain's initial state.service.rs: This file defines the node implementation, including the QPoW import queue and mining worker (sc_consensus_qpow).
In Substrate, the terms "runtime" and "state transition function" are analogous. Both terms refer to the core logic of the blockchain that is responsible for validating blocks and executing the state changes they define. The Substrate project in this repository uses FRAME to construct a blockchain runtime. FRAME allows runtime developers to declare domain-specific logic in modules called "pallets". At the heart of FRAME is a helpful macro language that makes it easy to create pallets and flexibly compose them to create blockchains that can address a variety of needs.
Review the FRAME runtime implementation and note the following:
- This file configures several pallets to include in the runtime. Each pallet configuration is defined by a code block that begins with
impl $PALLET_NAME::Config for Runtime. - The pallets are composed into a single runtime by way of the
construct_runtime!macro, which is part of the core FRAME pallet library.
The runtime is composed from the FRAME pallets under pallets/. Quantus-specific pallets include qpow, mining-rewards, reversible-transfers, wormhole, and zk-tree. Governance uses the local ranked-collective and referenda forks.
A FRAME pallet is comprised of a number of blockchain primitives, including:
- Storage: FRAME defines a rich set of powerful storage abstractions that makes it easy to use Substrate's efficient key-value database to manage the evolving state of a blockchain.
- Dispatchables: FRAME pallets define special types of functions that can be invoked (dispatched) from outside of the runtime in order to update its state.
- Events: Substrate uses events to notify users of significant state changes.
- Errors: When a dispatchable fails, it returns an error.
Each pallet has its own Config trait which serves as a configuration interface to generically define the types and parameters it depends on.
Dockerfile is the image CI and releases publish. The release workflow unpacks quantus-node into dist/<arch>/ before the build; the image copies that binary and starts it with --chain planck_live_spec.
Dockerfile.local compiles the node from this tree for a local image.
env-setup/flake.nix provides a dev shell with rustup, clang, and protobuf. From env-setup/:
nix developBuild from the repository root afterward so cargo selects rust-toolchain (1.93.0).
Compile the node with the try-runtime feature enabled to use the runtime wasm for try-runtime check:
cargo build --release --features try-runtime
try-runtime --runtime target/release/wbuild/quantus-runtime/quantus_runtime.wasm on-runtime-upgrade --disable-spec-version-check --blocktime 10000 live --uri <WS_URL>| Guide | What it covers |
|---|---|
| MINING.md | Mining setup, wormhole addresses, and the external miner |
| docs/rust-setup.md | Compiler pin, host packages, and rustfmt |
| docs/CHAINSPEC_CREATION.md | Producing a raw JSON chain spec |
| docs/RELEASE_PREFLIGHT.md | Checks to run before tagging a node or runtime release |
| docs/RUNTIME_UPDATE.md | Shipping a runtime to Heisenberg and Planck |
| docs/RUNTIME_UPGRADE_VIA_GOVERNANCE.md | Authorize-then-apply upgrade flow |
| docs/RUNTIME_SURFACE.md | Call surface and why sudo is gone |
| docs/TECH_COLLECTIVE_GOVERNANCE_TUNING.md | Tech-collective track parameters |
| docs/TECH_REFERENDA_FEATURES.md | Referenda features wired in the runtime |
| docs/wormhole-zk.md | Leaf, private-batch, and public-batch proofs |
| docs/zk-trie-architecture.md | Poseidon Merkle tree used by wormhole |
Got a technical question about the codebase? Feel free to ask it on our DeepWiki page:
