Skip to content

node-2.0.0-rc.1

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 17 Jun 10:44
c9ff165

Midnight Node 2.0.0-rc.1

Metadata

  • Type of release: major (release-candidate pre-release)
  • Date: 2026-06-17
  • Ships in bundle: TBD — rc pre-release (not bundled)
  • Git tag: node-2.0.0-rc.1
  • Environment: Supported environments: local env, Devnet.
  • Upgrade scope: binary (no runtime upgrade associated with this RC as state migration is not supported)
  • Reset required: Yes — fresh chain required; no in-place upgrade from any prior node version is supported in this rc
  • Governance action required: No (deployed as a fresh chain); enabling the Cardano→Midnight bridge later requires a governance action — it ships inert
  • Sister-line note: The 1.0.x maintenance line (e.g. node-1.0.1-rc.1) continues in parallel for networks staying on ledger 8. The 2.0.0 line is a fresh-chain development line and is not an upgrade target for 1.0.x chains yet.

High-level summary

First release candidate of the Midnight Node 2.0.0 line. Building on 2.0.0-alpha.1, it:

  • bumps the ledger to 9.1.0.0-rc.2 (dual v1/v2 ZK proving pipeline, on-chain contract IR and ContractOperation V4, ECDSA domain-separator change),
  • lands substantial sync-performance work,
  • narrows ledger-9 transaction validation to the guaranteed segment,
  • adds multi-destination toolkit transfers,
  • fixes genesis pool generation (no more empty locked pool),
  • and fixes the bridge claim path — alongside broad C2M-bridge and cNIGHT-observation e2e coverage.

This remains a binary only fresh chain release (spec_version 002_000_000, transaction_version 4 — unchanged since alpha.1). There is still no migration from ledger 8, and no in-place upgrade from any prior node version: 2.0.0 chains must start fresh.

Audience

These release notes are intended for:

  • Operators evaluating the 2.0.0 line — a fresh-chain start is mandatory; no rolling upgrade is supported yet.
  • Developers who build and sign extrinsics — transaction_version is 4; extrinsics signed against the 1.0.0 runtime do not decode (unchanged since alpha.1).
  • Toolkit users generating transactions or rehearsing the Cardano→Midnight bridge flow.
  • Integrators decoding runtime metadata or ledger state — metadata was regenerated for ledger 9.1.

Dependencies

  • Ledger: 9.1.0.0-rc.2 (midnight-ledger-v9 1.0.0). No v8 → v9 migration path; incompatible with ledger-8 chain state.
  • transaction_version 4: signed extrinsics built against the 1.0.0 runtime (tx version 3) will not decode.
  • Runtime metadata: regenerated for ledger 9.1 (new max_contract_metadata_size parameter; on-chain ContractOperation format changed). Re-pull metadata before pointing tooling at a 2.0.0-rc.1 chain.

Downstream impact (cascading effects): indexers, wallets, and SDKs that decode runtime metadata or ledger state must be rebuilt against the 2.0.0-rc.1 metadata / ledger 9.1 before they can follow a 2.0.0 chain. The C2M bridge is inert, so no downstream bridge integration is active yet.

For all other interop questions, see the bundle dependency matrix.

Deployment information

  • Upgrade scope: binary.
  • Reset required: Yes — fresh chain. Ledger 9 has no state transition from ledger 8, and this rc supports no in-place upgrade from any prior node version (including 2.0.0-alpha.1). Genesis state and chain-specs were regenerated for ledger 9.1 (ledger-state tag v17). Mixed pre-v9/post-v9 handling in block replay and toolkit caching remains deliberately relaxed and unsupported.
  • Governance action required: No — deploys as a fresh chain, not an on-chain upgrade. Enabling the C2M bridge separately requires a governance action (setting the bridge MainChainScripts addresses + a data checkpoint); until then the bridge inherent-data provider reports Inert everywhere.
  • Downtime / coordination: Not an in-place upgrade — existing chains cannot roll forward. New networks bootstrap from fresh genesis.

Artifacts

  • Docker: midnightntwrk/midnight-node:2.0.0-rc.1
  • Docker: midnightntwrk/midnight-node-toolkit:2.0.0-rc.1
  • Git tree hash: c7bc15c5ba02d2c5d8f6eca24893c6c411fd6c10
docker pull midnightntwrk/midnight-node:2.0.0-rc.1
docker pull midnightntwrk/midnight-node-toolkit:2.0.0-rc.1

Note: unlike 2.0.0-alpha.1, this rc does not publish a standalone runtime WASM release asset — only the node and toolkit binaries (linux-amd64 / linux-arm64 tarballs) and SHA256SUMS.

What changed

Delta since 2.0.0-alpha.1 (changes already announced in the alpha are not repeated here):

  • Ledger 9.1.0.0-rc.2 — dual v1/v2 ZK proving pipeline (zk-stdlib v2 / circuits v7), ProofVersioned::V3, on-chain contract IR with ContractOperation V4, ECDSA domain-separator change; metadata + genesis regenerated, new max_contract_metadata_size ledger parameter (#1692).
  • Sync performance — bulk-read cNIGHT observation cache (genesis→tip ~3 h 19 m) (#1436) and epoch-nonce + federated-ops caches (#1551).
  • Ledger-9 guaranteed-only validation — mempool and block-inclusion pre-checks dry-run only the guaranteed segment on ledger 9 (#1454).
  • Toolkit — multi-destination single-tx (multiple addresses/tokens in one tx) (#1560); contract-address --untagged flag cleanup (#1486).
  • Genesis — prevent empty locked pool when reserve config is empty; new --allow-empty-pools flag; testnet pool amounts now mirror mainnet (#1675).
  • C2M bridge — fix the claim path (uncovered by new e2e coverage) (#1697).
  • A batch of C2M-bridge / cNIGHT-observation e2e and CI work.
Change Upgrade Type PR
Bump ledger to 9.1.0.0-rc.2 (dual v1/v2 ZK pipeline, ContractOperation V4, max_contract_metadata_size) Runtime upgrade #1692
C2M bridge: fix claim path Runtime upgrade #1697
Prevent empty locked pool in genesis; --allow-empty-pools flag; testnet pools mirror mainnet Runtime upgrade #1675
Bulk-read cNIGHT observation cache (genesis→tip sync ~3 h 19 m) Node upgrade #1436
Epoch-nonce + federated-ops caches (sync perf) Node upgrade #1551
Ledger-9 apply_guaranteed_only guaranteed-segment validation Node upgrade #1454
Toolkit single-tx multiple-destination support Toolkit #1560
Toolkit contract-address --untagged cleanup Toolkit #1486
fork-network workflow: node-upgrade option Infrastructure #1469
cNIGHT observation e2e tests on Cardano Preview Infrastructure #1613
local-env: patch cnight mapping_validator_address from compiled contracts Infrastructure #1653
e2e tests for C2M bridge Infrastructure #1654
Nightly cNIGHT e2e job runs in a container Infrastructure #1658
compactc: arbitrary compact dependency via submodule in CI Infrastructure #1662
qanet e2e reads contracts from reserve-contracts submodule Infrastructure #1666
C2M-bridge subminimal-transfer edge-case tests Infrastructure #1677

New features

Ledger 9.1.0.0-rc.2

Description: Bumps the ledger from the 9.0.1.0-alpha.1 tags shipped in the alpha to 9.1.0.0-rc.2 (midnight-ledger-v9 crate 1.0.0). The headline upstream change is a dual v1/v2 ZK proving pipeline (zk-stdlib v2 / circuits v7): zkir 2.2.0 holds v1 or v2 prover keys behind VersionedInnerPK and defaults to the v1 pipeline; the ledger gains ProofVersioned::V3 for zk-stdlib-v2 proofs, and proof_verify dispatches v1/v2 by proof version while zswap verification stays on v1 for backwards compatibility. On-chain, ContractOperation gains a v3 verifier-key field (ContractOperationVersion::V4) and an ir field (contract IR on chain), with per-entry-point metadata checks capped by the new max_contract_metadata_size runtime parameter. coin-structure 3.0.0 updates the ECDSA domain separator. Upstream correctness fixes include value-only communication_commitment hashing, rejection of out-of-bounds MerkleTree update indices (previously silently updated the rightmost leaf), and an infallible post_block_update. Node-side, ledger 9 no longer shares one crypto stack with ledgers 7/8 — L9 uses 3.x coin-structure/transient-crypto aliases and zkir 2.2.0, while L7/L8 stay on the 2.x stack. Runtime metadata and undeployed genesis/test fixtures were regenerated (ledger-state tag v16 → v17). Runtime upgrade.

PR: #1692

Reference: ledger 9.1.0.0-rc.2 changelog · alpha.1 Ledger 9 & C2M bridge engineering notes

Toolkit multi-destination transfers

Description: generate-txs single-tx now accepts multiple --destination-address entries, each paired with its own shielded/unshielded amount and token type, so a single transaction can pay several recipients across both token types. Previously each single-tx invocation targeted one destination. Toolkit.

PR: #1560

New features requiring configuration updates

Genesis pool configuration (--allow-empty-pools)

Required updates:

  • Chain-spec / genesis generation now rejects an empty reserve, ICS, locked, or treasury pool unless you pass --allow-empty-pools. Previously, an absent reserve config silently assigned all remaining supply to the reserve pool, leaving the locked pool empty.
  • All res/* environment configs now carry valid (non-zero) Reserve and ICS values and mirror mainnet pool amounts; regenerate any custom chain-specs from the updated configs.

Impact: New chain-specs will have a correctly funded locked pool. Durable-environment genesis states are unchanged except Preview, whose existing genesis/chain-spec is still wrong (config is now correct) and will likely need a reset. Runtime upgrade (genesis/chainspec) + Toolkit.

PR: #1675

Improvements

  • Sync performance: bulk-read cNIGHT observation cache replaces per-query db-sync round-trips with an in-memory sliding-window cache, syncing mainnet genesis→tip in ~3 h 19 m (~572 k blocks) (#1436); added epoch-nonce and federated-ops caches to address residual slow-sync hot paths (#1551).
  • Validation efficiency: on ledger 9, mempool validate_transaction and block-inclusion pre-checks dry-run only the guaranteed transaction segment via apply_guaranteed_only, instead of a full apply() that also executed the fallible segment; ledger 7/8 keep the full-apply() path (#1454).
  • Toolkit UX: contract-address --untagged is hidden from --help (untagged is already the default), its deprecation warning moved from eprintln! to log::warn! (so it honours RUST_LOG/--quiet), and --tagged --untagged is now a parse error; the success path emits empty stderr (#1486).

Deprecations

None.

Breaking changes

⚠️ This is a major release: spec_version 002_000_000, transaction_version 4, ledger 9 with no migration path from ledger 8. Existing chains cannot roll forward — start fresh. No in-place upgrade from any prior node version (including 2.0.0-alpha.1) is supported in this rc.

No new breaking changes were introduced since 2.0.0-alpha.1. The 1.0.0 → 2.0.0 breaking set still applies in full:

transaction_version bumped 3 → 4

What changed: The runtime transaction version is 4 (was 3 in node 1.0.0); unchanged since alpha.1.

What breaks: Signed extrinsics constructed against the 1.0.0 runtime metadata will no longer decode/validate.

Required actions:

  • Rebuild runtime metadata against 2.0.0-rc.1 and regenerate any codegen/types derived from it.
  • Re-sign or re-construct pending extrinsics with the new metadata.
  • Pin integrators to the 2.0.0-rc.1 metadata before pointing them at a 2.0.0 chain.

Ledger 9 — no migration from ledger 8

What changed: The ledger is on version 9 (9.1.0.0-rc.2 in this rc); there is no v8 → v9 state transition or hard-fork.

What breaks: An existing ledger-8 chain cannot be upgraded in place. Block replay and toolkit caching across the v8/v9 boundary are unsupported.

Required actions:

  • Start a fresh ledger-9 chain from genesis.
  • Do not point ledger-8 state, snapshots, or caches at a 2.0.0 binary.

Partner-chains pallets removed

What changed: Partner-chains pallets not used by Midnight, and their related CLI commands, were removed (announced in alpha.1).

What breaks: Any caller of those pallets' extrinsics or the removed CLI commands. Their storage no longer exists in the runtime.

Required actions:

  • Drop usage of the removed extrinsics/commands. A fresh chain is required anyway, so no storage migration is involved.

Known issues

No state transition / upgrade path into 2.0.0

Description: 2.0.0-rc.1 runs ledger 9 but ships no migration or hard-fork path from ledger 8, and no in-place upgrade from any prior node version (including 2.0.0-alpha.1). Only a fresh ledger-9 chain can be started. Mixed pre-v9/post-v9 handling in block replay and toolkit caching is deliberately relaxed and unsupported; tests requiring intent[v7] or a v8 → v9 hard-fork are ignored.

Issue: #1579

Workaround (if any): Start a fresh chain. Migration / hard-fork support is planned for a later 2.0.0 pre-release.

Links and references

Fixed defect list

Defect number Description
#1674 Genesis generation left the locked pool empty when reserve config was absent (assigned all remaining supply to the reserve pool) (#1675)
#1531 Slow node sync from missing epoch-nonce / federated-ops caching (#1551)
#1158 Slow genesis→tip sync from per-query db-sync round-trips for cNIGHT observation data (#1436)
#1609 qanet e2e tests panicked at startup when local-env docker artefacts were absent (#1666)
C2M bridge claim Bridge claim path was broken on an earlier untested code path (#1697)

Other Changes

  • fork-network workflow gained a node-upgrade option (#1469).
  • compactc: arbitrary compact dependency now supported via submodule in CI, alongside the release-based flow (#1662).
  • cNIGHT observation e2e coverage restored against Cardano Preview (#1613); e2e tests added for the C2M bridge (#1654) and its subminimal-transfer edge cases (#1677).
  • local-env now patches the cNIGHT mapping_validator_address from freshly compiled contracts (#1653); the nightly cNIGHT e2e job runs inside a container (#1658).