node-2.0.0-rc.1
Pre-releaseMidnight 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
ContractOperationV4, 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_versionis 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-v91.0.0). No v8 → v9 migration path; incompatible with ledger-8 chain state. transaction_version4: 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_sizeparameter; on-chainContractOperationformat 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
MainChainScriptsaddresses + a data checkpoint); until then the bridge inherent-data provider reportsInerteverywhere. - 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.1Note: 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-arm64tarballs) andSHA256SUMS.
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 withContractOperationV4, ECDSA domain-separator change; metadata + genesis regenerated, newmax_contract_metadata_sizeledger 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 --untaggedflag cleanup (#1486). - Genesis — prevent empty locked pool when reserve config is empty; new
--allow-empty-poolsflag; 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_transactionand block-inclusion pre-checks dry-run only the guaranteed transaction segment viaapply_guaranteed_only, instead of a fullapply()that also executed the fallible segment; ledger 7/8 keep the full-apply()path (#1454). - Toolkit UX:
contract-address --untaggedis hidden from--help(untagged is already the default), its deprecation warning moved fromeprintln!tolog::warn!(so it honoursRUST_LOG/--quiet), and--tagged --untaggedis now a parse error; the success path emits empty stderr (#1486).
Deprecations
None.
Breaking changes
⚠️ This is a major release:spec_version002_000_000,transaction_version4, 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 (including2.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
- PRs: full set on the GitHub release page; every change above links its PR inline.
- Engineering docs:
- Ledger 9 and the Cardano→Midnight bridge (from alpha.1)
- storage_separation operator guide (from alpha.1)
- Migration guides: not produced — a fresh chain is required; a migration guide will accompany the pre-release that introduces an upgrade path.
- API documentation: ledger 9.1 regenerated runtime metadata (new
max_contract_metadata_sizeparameter; on-chainContractOperationV4). TheSessionInfoApiruntime API andmidnight_contractStateContractNotPresentsurfacing from alpha.1 are unchanged. - GitHub release: https://github.com/midnightntwrk/midnight-node/releases/tag/node-2.0.0-rc.1
- Known issues board: https://github.com/midnightntwrk/midnight-node/issues?q=is%3Aissue+is%3Aopen+label%3Abug
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_addressfrom freshly compiled contracts (#1653); the nightly cNIGHT e2e job runs inside a container (#1658).