// schema · cuprate · alternative monero node

One implementation is
a single point of failure.

Every Monero node on the network today runs the same software: monerod, a 250,000-line C++ codebase maintained by the same team since 2014. A consensus bug or a memory-safety vulnerability would affect 100% of the network at once. Cuprate is the antidote — an independent Monero node implementation written from scratch in Rust, with a modular crate-based architecture, full Tor support, and an async tower::Service design that lets it be embedded as a library rather than just run as a daemon. Still experimental as of v0.0.7 "Molybdenite" — but it's the most serious second implementation Monero has ever had.

rust · async · modular alpha · v0.0.7 molybdenite ~30 cuprate_* crates ccs-funded tor built-in via arti
01 · the case for it

§1Why Monero needs a second node

Bitcoin learned this lesson the hard way: a network running a single implementation is a network one bug away from a chain split or worse. Bitcoin Core's dominance has long been a debated risk. Ethereum split its implementation across Geth, Erigon, Nethermind, Besu, Reth — partly to avoid exactly that. Monero today is where Bitcoin was: monoculture. Every monerod shares the same bugs, the same parser, the same database engine, the same potential CVEs.

α

Consensus bug risk

If monerod has an edge case where two valid blocks are interpreted differently by different builds, the entire network forks. With one implementation, there's no "second opinion" to detect this before it ships.

β

Memory safety

monerod is C++. Buffer overflows, use-after-frees, signed-overflow UB — all classic remote attack surfaces. A bad incoming P2P message has historically been able to crash or worse. Rust eliminates entire classes of these by construction.

γ

Maintenance bottleneck

The monerod codebase is large, organic, and concentrated in a small group of maintainers. A clean-room rewrite in a modern language with a modular design is much easier to onboard new contributors into.

This is the same argument made for Reth and Erigon vs Geth on Ethereum

Cuprate's lead developer hinto-janai has explicitly drawn the analogy. Reth (Rust Ethereum) and Erigon proved that a clean-room alternative client can not only catch up to the reference implementation but often surpass it in performance and clarity. Cuprate is trying to do for Monero what Reth did for Ethereum — and it's borrowing many of the same architectural patterns (Tower services, modular crates, async-first design).

02 · contrast

§2Cuprate vs monerod, at a glance

The two implementations target the same protocol but make very different engineering choices. monerod is the product of a decade of incremental evolution from the original Bytecoin/CryptoNote codebase; Cuprate is a 2023-onwards clean-room rewrite that gets to pick modern defaults from day one.

MONEROD · the reference, since 2014
"Battle-tested monolith"
  • C++14/17 — manual memory management, ~250K LoC
  • Monolithic build — one binary, internal modules tightly coupled
  • LMDB as the storage engine
  • boost::asio for networking, manual thread pools
  • Inherits from the original CryptoNote codebase (2014)
  • Tor / I2P via external torsocks or proxy
  • Hard to embed — designed as a daemon, not a library
CUPRATE · the rewrite, since 2023
"Modular & embeddable"
  • Rust 2021 edition — memory-safe, compile-time race protection
  • ~30 independent crates — each does one thing, loosely coupled
  • heed / LMDB via abstracted database trait (swappable)
  • Tokio + Tower — async runtime, composable middleware
  • Clean-room — written against the Monero spec, not from monerod source
  • Tor first-class via Arti, plus Dandelion router built-in
  • Designed for embedding — any crate usable from other Rust projects
03 · architecture

§3The crate-based architecture

Cuprate isn't really "a program." It's a library of crates from which the cuprated binary is assembled. This is the deepest architectural break from monerod. Each crate is independently versioned, independently tested, independently usable by third-party Rust code (a wallet, a block explorer, a research tool) — and the daemon is just one consumer of them.

cuprate_p2p_core
networking · low-level

Connection handling, handshake state machine, network zone abstraction. Implements the Levin protocol from the P2P schema.

cuprate_p2p
networking · high-level

Peer set management, address book, sync logic. Built on cuprate_p2p_core. What cuprated actually uses to gossip.

cuprate_levin
wire protocol

Pure implementation of the Levin binary protocol that the previous P2P schema described. Codec only — no networking opinions.

cuprate_wire
message types

Strongly-typed Monero P2P message definitions. Replaces monerod's verbose epee glue with Rust enums and derive macros.

cuprate_dandelion_tower
privacy routing

Dandelion++ stem-then-fluff propagation. Built as a Tower middleware so it composes cleanly with the rest of the P2P stack.

cuprate_p2p_transport
tor · clearnet

Pluggable transport. Arti integration for Tor onion services, plus the standard clearnet TCP. Network zones are first-class.

cuprate_database
storage · trait layer

Abstract database traits. Defines what a Monero storage backend must do; the concrete backend is pluggable (currently heed/LMDB).

cuprate_blockchain
storage · blocks

The actual blockchain tables: blocks, transactions, outputs, key images. Implements the schema monerod's blockchain.db uses, but typed.

cuprate_txpool
mempool

The transaction pool. Holds pending txs, runs admission rules, evicts stale entries. Asynchronous from day one.

cuprate_fast_sync
bootstrap

Hard-coded block hashes up to a recent height. New nodes can skip full validation of ancient history and trust the binary's bundled checkpoints — drastically faster initial sync.

cuprate_consensus
block validation

The heart of Cuprate's correctness story. Validates block headers, transactions, ring signatures, fee rules, hard fork rules. Independent reimplementation of monerod's validation logic.

cuprate_consensus_rules
per-fork rules

Per-hard-fork rule definitions. Monero has had many forks (v1 → v16+), each with different rules; this crate encodes them all.

cuprate_cryptonight
pow · legacy

Pure-Rust CryptoNight implementation for validating pre-RandomX blocks. (RandomX itself uses tevador's reference library via FFI — see RandomX schema.)

cuprate_rpc_interface
rpc · server

Built on axum. Routes /get_block, /json_rpc, /send_raw_transaction etc. to handler services.

cuprate_rpc_types
rpc · schemas

Strongly-typed request/response definitions for every monerod RPC endpoint. Lets other Rust projects type-check their RPC calls.

cuprate_json_rpc
rpc · jsonrpc 2.0

JSON-RPC 2.0 framing layer. Generic — could be used for non-Monero projects.

cuprate_zmq_types
rpc · pub/sub

ZeroMQ message definitions for the pub/sub feed (block notifications, txpool notifications). Matches monerod's existing ZMQ contract.

cuprate_types
shared types

The kitchen-sink crate. Block, Transaction, Output, HardFork enum, RingCt variants, chain identifiers. The vocabulary all other crates share.

cuprate_epee_encoding
serialization

Pure-Rust implementation of monerod's "epee" binary format. The wire format that everything in the Monero ecosystem speaks.

cuprate_helper
utilities

Cross-cutting helpers: time, paths, encoding, math. The "everything-else" crate.

cuprate_pruning
storage · pruning

Block pruning logic for nodes that don't want to keep the entire history. Monero pruning preserves enough of each block to validate but discards old ring members.

cuprated
the binary

The actual daemon. Wires all the above crates together with a Tokio runtime, config loading, signal handling, RPC server, P2P server. ~5% of total LoC.

The point isn't just that this is cleaner code. It's that any of these crates can be used by other Rust projects. Want to build a block explorer? Pull in cuprate_blockchain and cuprate_types. Want to write a P2P scanner that connects to Monero peers and logs traffic? Use cuprate_p2p_core directly. monerod offers no such factoring.

04 · the tower pattern

§4Everything is a Service

Cuprate's biggest architectural innovation is its use of the Tower crate's Service trait — the same pattern Tokio uses for HTTP, Linkerd uses for service meshes, and Zcash's zebrad pioneered for blockchains. Every Cuprate subsystem (database, network, mempool, consensus) is a Tower service: an async function from a request to a response. They compose like Lego.

// the Service trait in one snippet pub trait Service<Request> { type Response; type Error; type Future: Future<Output = Result<Self::Response, Self::Error>>; fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>>; fn call(&mut self, req: Request) -> Self::Future; } // example: the consensus service takes a Block, returns whether it's valid let consensus: impl Service<VerifyBlockRequest, Response=VerifyBlockResponse> = ...; let result = consensus.call(VerifyBlockRequest::main_chain(block)).await?; // services compose via tower::Layer middleware: // buffer (queue) → rate-limit → timeout → retry → consensus let stack = ServiceBuilder::new() .buffer(100) .timeout(Duration::from_secs(30)) .service(consensus);

Why this matters in practice

i

Backpressure for free

poll_ready means a service can say "I'm overloaded, wait." This propagates up — a slow database means the P2P layer stops reading from peers, preventing memory blowup. monerod has had to hand-engineer this in many places.

ii

Middleware composability

Want to add rate limiting to RPC? Wrap the RPC service in RateLimitLayer. Want to add tracing? Wrap in TraceLayer. New behaviors are middleware crates that drop in.

iii

Testable in isolation

Mock services are trivial — just implement Service with a closure. The consensus crate can be tested without a real database; the P2P crate can be tested without a real consensus. monerod's tightly-coupled module structure makes equivalent testing far harder.

05 · current state

§5What Cuprate can & can't do (v0.0.7)

As of release 0.0.7 "Molybdenite" (late 2025), Cuprate is a real-but-experimental node. It can sync the Monero chain, validate consensus rules, gossip on the P2P network, and serve a useful subset of RPC. It cannot yet mine or fully replace monerod for an exchange. The roadmap is open and CCS-funded.

CapabilityStatusNotes
Block validation✓ Workingcuprate_consensus validates the chain through all hard forks back to genesis.
P2P networking✓ WorkingLevin handshake, peer discovery, block/tx propagation, Dandelion++.
Tor support✓ WorkingBuilt-in via Arti as of v0.0.6 (Aug 2025). No external torsocks needed.
Initial sync✓ WorkingFast-sync to height ~3.45M using bundled checkpoints; full validation thereafter.
RPC (read)~ Partialget_block, get_block_count, get_height, get_block_headers_range available. Many more pending.
RPC (write)~ Partialsubmit_block and send_raw_transaction enabled in v0.0.5. More endpoints landing per release.
Transaction pool✓ WorkingPool manager added in v0.0.6 with relay rules and persistence.
Block reorganization✓ WorkingIncluding recovery from failed reorgs (v0.0.3).
Mining (template assembly)○ Not yetNo get_block_template RPC, so no pool/solo mining yet.
Wallet protocol○ Not yetcuprate-wallet exists as a placeholder; no scanner/builder yet.
Pruning○ Crate existscuprate_pruning has the logic; integration into cuprated still in progress.

The people building it

Cuprate is community-built and funded through Monero's Community Crowdfunding System (CCS). Core contributors over the project's life: SyntheticBird45 (original founder), hinto-janai (current lead, RPC + binary), Boog900 (consensus, P2P), Asurar0, dimalinux, jomuel, kayabaNerve (also leads FCMP++ — see that schema). Multiple have had multiple full-time CCS-funded development periods. The Monero Research Lab and reference monerod developers have been broadly supportive.

06 · history

§6Cuprate's timeline

From a single contributor's hobby project to a serious second-implementation candidate.

2023 · feb
Initial commit
SyntheticBird45 starts the project. Initial scope: modular Monero node in Rust. Database layer first. Heavy inspiration from Zcash's zebrad.
2023 · jun
CCS funding begins
Boog900 receives the first Cuprate-related CCS proposal. Networking and consensus development accelerates. Multiple contributors onboard.
2024
~12 months of paid full-time work
Multiple CCS-funded development periods: SyntheticBird (database, P2P), Boog900 (consensus, dandelion), hinto-janai (RPC handlers, architecture book).
2024 · oct
v0.0.1 "Molybdenite" — first alpha
hinto-janai announces the first runnable alpha. "Ready for casual usage" — meaning ready to be experimented with, not production-ready. The project becomes real.
2025 · early
v0.0.2-0.0.3 — stability & reorgs
Block reorganization handling, peer list crash fixes, transaction pool relay rules. The node starts to behave like a node.
2025 · spring
v0.0.4-0.0.5 — RPC awakens
RPC interface gets initial integration. Read endpoints first, then submit_block and send_raw_transaction enabled. Now usable for many wallet/explorer flows.
2025 · aug
v0.0.6 — Tor & txpool
Full Tor integration via Arti (in-process, no external torsocks). Txpool manager. Network zones reach maturity. This is the first version that feels like "a real privacy-respecting Monero node."
2025 · late
v0.0.7 — current release
monero_oxide library update, pop_blocks command added, ongoing fast-sync checkpoint updates. Still alpha but increasingly stable.
2026 · planned
FCMP++ readiness
When Monero hard-forks to FCMP++ (mid-late 2026, see that schema), Cuprate needs to validate the new transaction format. kayabaNerve (lead of both projects) is well-positioned to coordinate this.
far future
First-class second implementation
Mining RPCs, wallet protocol, full feature parity. Long-term goal: a meaningful fraction of Monero nodes running Cuprate, ending the monoculture risk.