Zecnero is a fork of Zebra, the Zcash Foundation's Rust node, with the proof of work swapped from Equihash to RandomX. The public testnet went live on September 24, 2026. This post covers the parts of the fork that turned out to be interesting, plus two problems that only showed up late.
Source for everything below: https://gitlab.com/zecnero
The proof of work
RandomX makes every hash execute a randomly generated program in a virtual machine. The hardware that runs arbitrary programs fastest is a general-purpose CPU, which is the point.
Zecnero keeps the reference RandomX v1 configuration and changes only the Argon2 salt. That was the least invasive way to get a distinct algorithm: every other parameter keeps its audited default, and existing Monero hardware can't mine it without a miner change.
The node verifies RandomX through a forked Rust binding (randomx-rs-zecnero). The RandomX key, the "seed hash", rotates every 2048 blocks, the same scheme Monero uses. Before anything else was built, the hash was checked for agreement across four implementations: the reference C++, the Rust binding, XMRig on Linux and XMRig on Windows. All four agree on 17 published test vectors. That test set lives in its own repo so anyone building a miner can check against it.
Difficulty: ASERT
Zcash adjusts difficulty with an averaging window. Zecnero uses ASERT (aserti3-2d), the algorithm Bitcoin Cash adopted in 2020. It's anchored at genesis, and each block's target depends only on how far the chain is ahead of or behind the ideal schedule:
next_target = anchor_target * 2^((time_delta - spacing * height_delta) / half_life)
The exponent is computed in fixed point with a 2^16 radix, so every node gets bit-identical results. The half-life constant lives in zebra-chain/src/work/asert.rs and is currently 7,200 seconds.
Testnet stress-tested it on day one. A miner with about 70% of the network hashrate joined and then left, and blocks ran several minutes apart while ASERT caught up. The chain recovered on its own. The half-life for mainnet is now being tuned against simulated 3x and 8x hashrate swings.
Genesis had to be compiled in
This one only showed up in a launch rehearsal.
Zebra had only the Regtest genesis block compiled in. On other networks, the syncer downloaded block 0 from a peer. For Zcash that's fine, because peers have existed since 2016. For a brand new network nobody has block 0, so the first node could never start, and neither could the second.
The fix was to compile every network's genesis block into the node and commit it to an empty state at startup, the way zcashd does. Networks that haven't been mined yet ship an empty genesis file, and a startup gate refuses to run them.
The genesis block also commits to a recent Bitcoin block hash, and its timestamp is the public release time. Blocks mined before release would stand out against the difficulty schedule.
A founder stream in consensus
Zecnero has no premine. It does have one allocation: 3% of each block subsidy goes to a fixed P2SH multisig until the first halving. The rule is floor(subsidy × 3 / 100) from height 1 through 1,679,999, and it's enforced in consensus like Zcash's funding streams. Every block has to pay it regardless of who mined it, and it ends permanently at the first halving.
The Orchard proving key
Zecnero applies the Orchard soundness fix from Zcash NU6.2 at block 1, along with the canonical proof size rule. The node verifies Orchard proofs against the fixed circuit.
Reviewing the wallet plan turned up a trap. Zecnero transactions carry the NU6 branch ID. In the vendored zcash_protocol crate, the function that maps a branch ID to an Orchard protocol revision maps NU6 to the pre-fix revision. The node never calls that function, so it had no effect there. But a wallet using that crate to build transactions would prove every Orchard spend under the one circuit Zecnero nodes reject.
The fix is a one-line mapping change, and it's a hard gate before Orchard wallet support and before mainnet. Until then the testnet wallet supports transparent and Sapling only.
Getting work to miners
XMRig speaks Stratum. Zebra speaks getblocktemplate and submitblock. zecnero-bridge sits between them: it pulls templates from the node, hands out jobs with the right RandomX seed, and submits solved blocks. The miner itself is a fork of XMRig with an rx/zecnero algorithm and the dev donation set to zero.
What's next
- A decision on RandomX v2, which Monero plans to adopt at its next hard fork
- The ASERT half-life study
- The Orchard proving-key fix
- Several weeks of public testnet before a mainnet date
If you work on Zebra or librustzcash, review of the consensus changes is the most useful thing anyone could offer right now. The discussion thread is on BitcoinTalk: https://bitcointalk.org/index.php?topic=5594747.0
Testnet mining guide: https://zecnero.org/mine
Top comments (0)