Two more findings from the general audit. Compile-verified only, like the rest of
this branch.
main.cpp SendMessages / ADDR: the per-address loop called
pto->PushAddrMessage(msgMaker.Make(flags, msg_type, pto->vAddrToSend))
i.e. it pushed the ENTIRE vector once per accepted address. One 24-byte getaddr
therefore produced N messages of N addresses each instead of one message of N --
on a live addrman (GetAddr returning ~494) that is ~494 x ~14.8 KB = ~7.3 MB of
upstream for a 24-byte request, and up to ~30 MB with a full addrman. All of it
serialized, with a double-SHA256 checksum per message, while cs_main is held, so
each burst also stalls block validation and RPC.
The locally built vAddr was accumulated and then discarded, and the
`vAddr.resize(MAX_ADDR_TO_SEND)` sat exactly where upstream has `vAddr.clear()` --
it can never fire, because vAddr.size() already equals MAX_ADDR_TO_SEND there.
This is a local regression, not inherited: 512da314a rewrote the correct upstream
form into this one.
Restores the upstream idiom (accumulate, flush in MAX_ADDR_TO_SEND batches, send
the remainder after the loop) and hoists the msg_type/make_flags selection out of
the loop, since neither varies per address.
wallet.cpp VerifyAndSetInitialWitness: five sites dereferenced
`*item.second.nullifier` on a boost::optional that can legitimately be unset. A
Sapling note discovered through an imported INCOMING viewing key has no nullifier
-- computing one requires the full viewing key, and z_importviewingkey calls only
AddSaplingIncomingViewingKey. Dereferencing it aborts the daemon with a boost
assertion rather than an RPC error, at the end of the import's own rescan; and
because the IVK-only note data is already persisted in the wallet transaction and
BuildWitnessCache is re-driven from ChainTip on every connected block, the node
then fails the same way on every restart.
The codebase already had the right pattern in the two neighbouring functions --
DecrementNoteWitnesses guards with `if (nd->nullifier && ...)` and BuildWitnessCache
with `if (!nd->nullifier) continue;` -- so only VerifyAndSetInitialWitness was
missing it. Those guards also establish the intended semantics: a note whose spend
depth cannot be computed is treated as UNSPENT, keeping its witness rather than
pruning a note we cannot prove spent. Adds a boost::optional overload of
SaplingWitnessMinimumHeight doing exactly that, and routes all five sites through it.
NOT fixed here, deliberately, because none can be done responsibly without tests:
- the inline TLS handshake on ThreadSocketHandler (architectural: one slow
unauthenticated connection can freeze all P2P I/O for up to 60s);
- the getblocktemplate function-static leaking a CBlockTemplate per concurrent
caller, assigned with cs_main released;
- z_sendmany's pre-flight size estimate omitting Sapling spends, so a wallet with
~499+ notes builds an oversize, unbroadcastable transaction after minutes of
proving;
- z_shieldcoinbase's opt-in donation paying a hardcoded upstream-Hush z-address
that no DragonX party can spend (a policy decision, not a code fix).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FU87LdsJZiZkfq1eXubpeo
DragonX
A fully-private, RandomX CPU-mineable cryptocurrency.
| Introduction | Build | Run | Mine |
|---|---|---|---|
| What is DragonX? | Build from source | Run a node | CPU mining |
| Key facts | Install a release | Fastest sync | Wallets |
What is DragonX?
DragonX implements extreme privacy via blockchain technology. It is private from
genesis: every ordinary transaction is shielded (z2z), so your transaction metadata
stays private. DragonX is based on Bitcoin code with Zcash's zero-knowledge Sapling
cryptography, and its defining feature is RandomX Proof-of-Work — it is mined with a
CPU, not ASICs or GPUs.
DragonX has its own genesis block. Its lineage is Bitcoin → Zcash → Komodo → Hush → DragonX; it is a fork of the Hush full node, with the Proof-of-Work changed from Equihash to RandomX and privacy enforced from the very first block.
This software is the DragonX full node and command-line client. It downloads and stores the entire history of DragonX transactions; depending on your computer and network connection this can take a while, so most users start from the bootstrap snapshot.
DragonX is experimental software. Use at your own risk, just like Bitcoin.
Key facts
| Ticker | DRAGONX |
| Proof-of-Work | RandomX (CPU-mineable) |
| Privacy | fully private from genesis (ac_private=1, Sapling active at height 1) |
| Block time | 36 seconds |
| Block reward | 3 DRAGONX, halving every 3,500,000 blocks |
| Max block size | 4 MB |
| RPC port | 21769 |
| P2P port | 18030 |
| Data directory | ~/.hush/DRAGONX (Linux) |
| Config file | DRAGONX.conf |
| Binaries | dragonxd, dragonx-cli, dragonx-tx |
Fastest way to sync (bootstrap)
The quickest way to get a fully-synced node is the signed bootstrap snapshot, which installs a pre-built blockchain so you skip re-validating the whole chain from genesis:
# Stop dragonxd first if it is running, then:
./util/bootstrap-dragonx.sh
The script preserves your wallet.dat and DRAGONX.conf, verifies the download's
checksums and (once a release key is published) its cryptographic signature, then starts
you near the chain tip. If you prefer to sync from the network instead, a larger
-dbcache (e.g. -dbcache=2048) noticeably speeds up the initial block download.
Build from source
Building uses 3 build processes by default; you need ~2GB of RAM for each.
Debian or Ubuntu
sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \
autoconf libtool ncurses-dev unzip git zlib1g-dev wget \
bsdmainutils automake curl unzip nano libsodium-dev cmake
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./build.sh -j3
Arch
sudo pacman -S gcc libsodium lib32-zlib unzip wget git python rust curl autoconf cmake
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./build.sh -j3
Fedora
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libtool ncurses-devel patch -y
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./build.sh -j3
macOS
Install Xcode Command Line Tools and Homebrew, then:
xcode-select --install
brew install gcc autoconf automake pkgconf libtool cmake curl
# Install Rust (needed for librustzcash on macOS Sequoia+)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
# Make sure libtool gnubin and cargo are on PATH
export PATH="$HOME/.cargo/bin:/usr/local/opt/libtool/libexec/gnubin:$PATH"
./build.sh -j3
For a release build:
export PATH="$HOME/.cargo/bin:/usr/local/opt/libtool/libexec/gnubin:$PATH"
./build.sh --mac-release -j$(sysctl -n hw.ncpu)
Windows (cross-compiled on Linux)
sudo apt-get install \
build-essential pkg-config libc6-dev m4 g++-multilib libdb++-dev \
autoconf libtool ncurses-dev unzip git zip \
zlib1g-dev wget bsdmainutils automake mingw-w64 cmake libsodium-dev
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./util/build-win.sh -j$(nproc)
ARM (Raspberry Pi)
Any ARMv7 machine cannot build this repo because the underlying zk-SNARK library does not
support that instruction set. You need an ARMv8-based board (Raspberry Pi 4 or newer). Either
install an aarch64 release package (see below) or cross-compile from amd64.
Installing DragonX binaries
- Download a release with a
.debextension. - Install it, substituting the version you downloaded:
sudo dpkg -i dragonx-VERSION-amd64.deb(or-aarch64.debon ARM). - Run with:
dragonxd.
Running a node
Start the daemon:
./src/dragonxd
It stores data in ~/.hush/DRAGONX and reads ~/.hush/DRAGONX/DRAGONX.conf. Query it with
./src/dragonx-cli, for example:
./src/dragonx-cli getinfo
To run DragonX as a background service, see doc/dragonxd-systemd.md.
CPU mining (RandomX)
DragonX is CPU-mineable via RandomX (the same algorithm family as Monero); ASICs and GPUs do not apply. To mine with your node, enable generation and choose how many threads to use:
# mine with 4 CPU threads
./src/dragonxd -gen=1 -genproclimit=4
or add to DRAGONX.conf:
gen=1
genproclimit=4
Mining rewards arrive as transparent coinbase, which is directly spendable; you can optionally
move it into the shielded pool with z_shieldcoinbase (see
doc/shield-coinbase.md). For more on the algorithm and its tuning
options, see doc/randomx.md.
Wallets
The DragonX full node includes a built-in wallet, managed via dragonx-cli (see
doc/wallet-backup.md and doc/seed-phrase.md).
Graphical and mobile wallets:
- ObsidianDragon — desktop wallet, available in both full-node and light-wallet modes.
- SilentDragonXAndroid — wallet for Android devices.
DragonX light and mobile wallets use BIP39 seed phrases that are compatible with the full node — see doc/seed-phrase.md.
Support and links
- Website: https://dragonx.is
- Source code: https://git.dragonx.is/DragonX
- Block explorer: https://explorer.dragonx.is
- Issues / bounties: https://git.dragonx.is/DragonX/dragonx/issues
- Telegram: https://dragonx.is/tg
- Matrix: https://dragonx.is/matrix
- Twitter / X: https://twitter.com/DragonXchain
License
For license information see the file COPYING.
