Run a node
A pruned node validates everything and serves complete wallet history from the moment it first syncs. The one decision that matters is how far back you need to see.
Ports, and coexisting with Kaspa
| Purpose | ZKas | Kaspa | Note |
|---|---|---|---|
| RPC (gRPC) | 16810 | 16110 | bind to loopback; never expose |
| P2P listen / advertise | 16811 | 16111 | the free "8" block — no clash with a Kaspa parent |
| P2P dial | 16111 | 16111 | where the seeders and seed.zkas.info live |
Only outbound access to a peer's P2P port is required to sync. Inbound is optional — it lets others sync from you.
kaspad --appdir=./zkas-node \ --rpclisten=127.0.0.1:16810 \ --listen=0.0.0.0:16811 \ --utxoindex
--listen. That changes inbound only; outbound discovery still dials 16111, so the node syncs normally.Pruned, shielded-history, or archival
ZKas keeps two kinds of history — public block data and shielded note history — and they are pruned independently. This is the part people get wrong.
| Pruned (default) | + --shielded-history=on | --archival | |
|---|---|---|---|
| Public block bodies below the pruning point | discarded | discarded | kept |
| Notes from before the node first synced | not fetched | fetched + kept | fetched + kept |
| Notes from the node's first sync onward | all kept forever | all kept forever | all kept forever |
| Fully validates the chain and every spend | yes | yes | yes |
| Serves balances complete since first sync | yes | yes | yes |
| Serves balances complete back to genesis | no | yes | yes |
| Serves an explorer old public blocks | no | no | yes |
| Disk | light | light + note archive | heavy |
1. Pruned — the default, and what most people should run
Pruning deletes block bodies, UTXO state and acceptance data. It never touches the scan archive or the nullifier set — ZKas deliberately diverges from upstream here, and the reason is user funds. A pruned node keeps forever:
- the shielded consensus state — note-commitment tree frontier and nullifier set, everything needed to validate every future spend;
- the per-block scan archive — the compact note records a wallet replays to recover a balance, plus a chain index so they stay enumerable in chain order after the blocks are gone.
So a restore-from-seed against a plain pruned node returns a complete balance for everything at or after that node's first sync. Wallet recovery does not depend on an archival node existing somewhere.
missing_history and historyFromDaaScore.2. --shielded-history=on — the wallet-backend shape
Controls whether the node fetches shielded note history below its pruning point from peers during IBD. With it on, the scan archive and chain index survive pruning, so the node serves wallets complete history while still discarding bulky public block bodies. This is the right node behind a zkas-walletd or a hosted wallet.
kaspad --appdir=./zkas-node --utxoindex --shielded-history=on --verify-shielded-history
Default: on when --archival is set, off otherwise.
3. --archival — keep everything
kaspad --appdir=./zkas-node --utxoindex --archival --rocksdb-preset=hdd
- Archival only retains from now forward. Enabling it on an already-pruned node does not backfill what was pruned before. A complete archive means enabling it on a node syncing from genesis, or importing a full-history snapshot.
- It is heavy on disk. On spinning disks add
--rocksdb-preset=hdd. - Archival is not required for validation or mining. A fresh non-archival node still syncs genesis→tip to byte-identical state.
Flag reference
Every node flag13 rows
| Flag (env) | What it does |
|---|---|
--appdir=<dir> (KASPAD_APPDIR) | data directory |
--rpclisten=<ip:port> | bind the gRPC RPC. Keep on 127.0.0.1 |
--listen=<ip:port> | P2P listen/advertise address |
--connect=<ip:port> | connect only to these peers (repeatable); skips the DNS seeder |
--addpeer=<ip:port> | add a persistent peer but still discover others (repeatable) |
--utxoindex (KASPAD_UTXOINDEX) | build the UTXO index; needed for some RPCs |
--archival (KASPAD_ARCHIVAL) | retain public block data past the pruning point |
--shielded-history=on|off | fetch shielded note history below the pruning point |
--verify-shielded-history | verify transferred shielded history during IBD |
--rocksdb-preset=default|hdd | storage tuning; hdd for archival on spinning disks |
--ram-scale=<f> | scale in-memory caches, e.g. 2.0 on a large box |
--enable-unsynced-mining | bootstrap only, for a brand-new network with no peers. Never on a pool mining the live chain |
--wallet-api | embed zkas-walletd with auto-provisioned TLS and a pairing QR — see self-hosting |
kaspad --help lists the complete set.
Why history from a peer is trustworthy
cmx from genesis must reproduce exactly the frontier the node already holds — a value it never learned from the serving peer. A peer that fabricates, omits, reorders or truncates cannot match it. Completeness is established by that verify pass, which sets the history_complete flag; an offline import does not set it.Two RPC fields expose this to clients: historyFromDaaScore (oldest height this node can serve) and historyComplete (can enumerate to genesis). See Node RPC.
Recovery and common faults
- Node will not start, corrupt DB
- Stop it, move the appdir aside, resync from a peer. A pruned node resyncs quickly; snapshot an archival node rather than resyncing it.
- Balances look low for old coins after a resync
- The node is pruned and was not given
--shielded-history=on, so it lacks notes from before its first sync. Coins received since are complete; older ones read as a lower bound. Re-run with shielded history enabled and let the wallet rescan. invalid prefix zkas/invalid prefix kaspa- Address HRP does not match the node's network. A pre-rebrand node does not know
zkas:; a Kaspa node never will. - Wallet stops updating after a node restart
zkas-walletdpoints at the local node and does not reconnect. Always restart walletd after touching the node.- Node wedges under load after a hardlink snapshot
- Stop → snapshot → start under load can wedge template building. Take snapshots cleanly, then restart the node and any solo bridge.
zkas-rusty at zkas-v1.0.9. Byte layouts, endpoint shapes and parameters are read from source; figures marked measured come from the live mainnet node. If this page contradicts the code, the code is right — report it.