Skip to content

0.20.0

Latest

Choose a tag to compare

@garethtdavies garethtdavies released this 28 Oct 16:02
v0.20.0
2094a96

minanode 0.20.0 release notes

What 0.20.0 is

0.20.0 is the first public release of the revived Rust Mina node. It runs on the
public devnet as a full node, a SNARK worker or a block producer, and follows
Mesa chains next to OCaml peers. It is one program for Linux on x86-64 or ARM64,
with the dashboard built in. 0.20.0 is a beta release. Run it on devnet and in
test setups. Expect changes before it is ready for production.

The comparison baseline is o1Labs'
v0.17.0 release (17
September 2025, pre-Mesa OCaml 3.2.0-beta2 devnet). The inherited changelog also
has 0.18.x and 0.19.0 sections; they are not the baseline.

Highlights

  • Mesa support. The node follows Mesa devnet and mainnet chains. It serves
    history and ledgers to OCaml peers. It produces proved blocks on public
    devnet. Devnet circuits and genesis configurations are embedded.
  • Sync speed. A fresh devnet node syncs from OCaml peers in under a minute.
    Mainnet takes a few minutes from an empty store, most of it downloading the
    ledger. A restart replays its saved chain and is synced in seconds.
  • Memory. A synced devnet full node uses a few hundred MB of RAM. Epoch and
    root ledger accounts live on disk, proofs live in a checked disk cache, and
    scan trees share memory between snapshots. It runs on a Raspberry Pi 4 and on
    a 1 GB Raspberry Pi 3.
  • Dashboard. mina serves a dashboard for sync, blocks, accounts, block
    production and the SNARK worker, and prepares bug reports locally.
  • Light-client endpoints. /light/best-tip and /light/account/{pk} return
    the tip with its proof and account Merkle paths for a light client to check.
  • Web node relay readiness. A native node may serve browser web nodes
    through a signaling-only listener (--webrtc-signal-port). The web node and
    the relay guide launch separately from this release.
  • Docker. A multi-arch image is built from the signed release archives.

Upgrade notes

  • Key passwords. Key passwords come from the environment, never the command
    line: MINA_PRIVKEY_PASS for producer and wallet keys, MINA_LIBP2P_PASS for
    libp2p keys. A password given on the command line is refused at startup, with
    a message naming the variable. See
    key passwords.

  • Key file permissions. Encrypted key files must be accessible by their
    owner only, as the OCaml node requires. Run chmod 600 on a producer, libp2p
    or wallet key file before starting; the node refuses a file that group or
    other users can read or write. Key files the node writes are already private.
    See
    key file permissions.

  • HTTP binding and CORS. The operator HTTP API and dashboard listen on
    127.0.0.1 by default; --http-addr changes the binding. The dashboard works
    without a flag at localhost or an IP address. A dashboard opened at a host
    name needs --http-cors-origin http://NAME:PORT, and the refusal names the
    exact value. --http-cors-origin '*' restores the previous behaviour. See
    dashboard on a server.

  • GraphQL limits. The node now admits zkApp commands as o1js builds them, up
    to the largest Mesa accepts (15 proofs). A valid command padded with many
    empty events can still exceed the limits. A request may carry up to 1.25 MiB
    of query text and body and 24,576 tokens. --public-graphql keeps the earlier
    limits and refuses mutations. Transaction submission stays off unless the node
    starts with --enable-tx-submission. See
    GraphQL.

  • Proof cache on a producer. A block producer keeps proofs in memory unless
    started with --proof-cache. Full nodes and SNARK workers use the disk cache
    by default; --no-proof-cache turns it off. See
    proof cache.

  • CLI changes. Options were renamed before this first public release. Old
    names kept as hidden aliases still work; the rest are refused. See the
    CLI reference.

    • Every environment variable starts with MINA_. PORT, LIBP2P_PORT,
      SEED, CONFIG, GENESIS_CONFIG, PEER_LIST_FILE, PEER_LIST_URL,
      PRODUCER_KEY, RUN_SNARKER, SNARKER_FEE, SNARKER_STRATEGY,
      SNARKER_BLOCK_FIRST_LEAD, VERBOSITY, RECORD, RNG_SEED, ARCHIVE_*
      and FROM are read only with the prefix, as MINA_PORT. The bare names are
      ignored without a warning.
    • wallet send --amount and --fee, and wallet delegate --fee, take MINA
      with up to 9 decimal places (--fee 0.1), as OCaml does. A script that
      passed nanomina must divide by 1,000,000,000: the old value now means a
      billion times more. wallet status shows amounts and fees in MINA too.
    • --node <URL>, the node's HTTP base URL, with MINA_NODE_URL, names the
      node on every command that talks to one. It replaces node status --url and
      wallet balance --endpoint, which stay as hidden aliases.
    • mina misc is now mina keys. misc mina-encrypted-key runs
      wallet generate, which needs --output and a non-empty password.
      frontier-store-check is now mina node frontier-store-check. The old
      paths are hidden aliases.
    • A secret key argument reads MINA_SEC_KEY, as keys mina-key-pair did;
      MINA_ENC_KEY is read only when neither --secret-key nor MINA_SEC_KEY
      gives a key.
    • --no-frontier-store (MINA_NO_FRONTIER_STORE) and --no-proof-cache turn
      the frontier store and the proof cache off. --proof-cache takes no value,
      and --proof-cache=<BOOL> is refused. --frontier-store=<BOOL> and
      MINA_PROOF_CACHE still work but are hidden.
    • Removed: mina snark, --experimental-catchup-rpc, --catchup-rpc-peer
      and wallet send --fee-payer.
    • OCaml's --external-port, --run-snark-worker, --snark-worker-fee and
      --block-producer-key are accepted as aliases.
  • WebRTC backend. Server-side WebRTC (browser peers and web node relays) now
    uses rustrtc 0.4.9, pinned in vendor/rustrtc with our patches: resource
    limits, data channel and port fixes, no UPnP. mina --version and
    mina build-info name the backend. The default p2p-webrtc feature selects
    rustrtc. The p2p-webrtc-rs feature selects the previous backend at build
    time; there is no automatic fallback. See the
    fallback build command.

  • ARM64 allocator. ARM64 builds now use jemalloc, built for 64 KiB pages so
    it runs on 4, 16 and 64 KiB kernels, with the same narenas:4 default as
    x86-64. _RJEM_MALLOC_CONF overrides allocator options on both. See
    memory.

  • Data directories from release candidates. A work directory written by RC4
    restores on 0.20.0; the frontier-store format has not changed since. Accounts
    files from an earlier run are removed at start. Directories from earlier
    candidates were not tested. See
    upgrading.

Changes by area

Ledger and storage

  • The staking, next epoch and root snarked ledgers keep their accounts in files
    under <work dir>/ledger-accounts/. --no-ledger-disk keeps them in memory.
  • A bootstrap holds one full ledger in memory and syncs the others as masks over
    it.
  • A ledger read from disk is retried before the node gives up, and the node then
    exits cleanly instead of aborting.
  • A refreeze that fails, for example on a full disk, backs off from 60 seconds
    up to one hour.
  • An abandoned frontier-store restore is cancelled before the node bootstraps.
    If the cancellation does not finish within 30 seconds, the node bootstraps
    with the frontier store disabled until the next restart.
  • The restore timeout follows load progress.
  • The genesis ledger cache is written atomically.
  • The root staged ledger stays over the root snarked ledger across epoch
    boundaries, with bounded memory and ledger correctness matching OCaml.

Memory

  • Transaction, zkApp, scan-state and block proofs share memory and use a
    digest-checked disk cache under proof-cache/.
  • Scan trees share unchanged chunks between snapshots.
  • The last ledger write, diagnostic stats and action statistics are bounded.
  • x86-64 builds use jemalloc with narenas:4 by default.
  • The frontier-store load runs on at most four threads, which lowers the restart
    peak on machines with many CPUs.
  • The web node reports its heap and frees large WebRTC receive buffers.

Networking

  • Block fetch backs off after errors and fails over to other peers.

  • A peer's best tip is refreshed while no bootstrap target exists.

  • A ledger, block or staged-ledger query that never gets an answer is retried.

  • Useful advertised addresses are kept, Kademlia buffers are bounded, and
    OCaml's parallel Yamux RPCs are supported.

  • Reliability fixes for input checks, resource limits and request handling.

  • Server-side WebRTC uses rustrtc by default.

GraphQL and RPC

  • Large zkApp commands are admitted with bounded memory per request.
  • account { index leafHash merklePath } and
    encodedSnarkedLedgerAccountMembership match OCaml's names and shapes.
  • The light-client HTTP endpoints are on the operator router, with request
    limits and a 10 second deadline.
  • Answered ledger-read and transaction-submission requests are removed from the
    request map.

CLI

  • --network mainnet selects the embedded mainnet genesis; an explicit
    --genesis-config still wins.
  • Key passwords are read from the environment, never from the command line.
  • mina report and mina triage collect a local bug report.
  • The SNARK worker selects jobs randomly by default; --snarker-strategy seq
    selects them in order.
  • A node at genesis on an established network reports Listening, not Synced.

Release and Docker

  • Release tooling builds Linux x86-64 and arm64 archives with checksums, build
    information, the dashboard and third-party notices.
  • SHA256SUMS is signed with an SSH key published on minanode.org.
  • The release build checks the shipped binary's allocator settings.
  • The Docker image ghcr.io/minanode/mina-rust:0.20.0, for linux/amd64 and
    linux/arm64, is built from the archives and runs as a non-root user. Compose
    files cover a full node, a block producer and a relay. See
    run with Docker. Its digest is
    ghcr.io/minanode/mina-rust@sha256:66507e39fc2890ce37cf9d77b50517960b60887f5e655cfa2de5a35b2eeceab0;
    check its build provenance with
    gh attestation verify oci://ghcr.io/minanode/mina-rust:0.20.0 -R minanode/mina-rust.

Known issues and limitations

  • Devnet focus. Mainnet following has been tested. Mainnet block production
    is not recommended yet.
  • No archive API. The node has no archive GraphQL API, so o1js and Protokit
    queries for zkApp events and actions fail against it. Use an OCaml archive
    node for those.
  • ARM64. The Raspberry Pi 5 is untested on real hardware. A Raspberry Pi 4
    and a 1 GB Raspberry Pi 3 run devnet full nodes; no SNARK worker or producer
    on a Pi has been tested.
  • Memory. Memory rises slowly on a node that runs for days. Provision
    headroom and monitor RSS.
  • Unreadable ledger records. A node stops on a ledger record it cannot read.
    Run it under systemd or Docker so it restarts and restores. Repair without a
    restart is planned for 0.20.1.
  • Several nodes on one IP. Peers apply serving limits per IP, so many fresh
    nodes behind one address sync more slowly than one node alone.
  • Hard forks. Each future hard fork needs a new release.
  • Help text. mina wallet generate --help doesn't name MINA_PRIVKEY_PASS
    yet; the command stops without it. See
    key passwords.
  • Web node. The browser node is a separate build from this release.
  • Uptime reporting: coming soon. 0.20.0 doesn't send uptime reports to the
    Mina Foundation delegation program. See
    delegation program uptime.

Requirements

See requirements,
installation and
run a node. Use Linux with glibc 2.31
or newer. x86-64 requires both BMI2 and ADX; ARM64 requires AArch64 ARMv8-A.
Allow 5 GB free disk, stable broadband and an NTP-synchronized clock.

Verify the downloads

Download SHA256SUMS, SHA256SUMS.sig and the archive for your CPU from the
same approved GitHub release. Obtain allowed_signers from minanode.org and
compare its fingerprint with the
install guide. For a new or changed
key, confirm it through a separate trusted channel. Use OpenSSH 8.2 or newer.
Replace x86_64 with arm64 below if needed:

asset=mina-0.20.0-linux-x86_64.tar.gz
curl -fLO https://minanode.org/allowed_signers
ssh-keygen -lf allowed_signers -E sha256
ssh-keygen -Y verify -f allowed_signers -I release@minanode.org \
  -n file -s SHA256SUMS.sig < SHA256SUMS &&
sha256sum --check --ignore-missing SHA256SUMS
mkdir mina-0.20.0
# Continue only after the checksum reports OK.
tar -xzf "$asset" -C mina-0.20.0
./mina-0.20.0/mina --version
./mina-0.20.0/mina build-info
cat mina-0.20.0/build-info.json

The version must be 0.20.0; check the recorded commit against the approved
public import and confirm dirty_checkout is false. The SSH signature
authenticates the checksum list; the checksums detect changed archive bytes.
Stop on a signature or checksum failure. See
the release checklist.