Skip to content

node-2.0.0-rc.4

Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 09 Jul 17:20
651e043

Midnight Node 2.0.0-rc.4

Cumulative note. Unlike a normal release-candidate note (delta-only), this one is the superset of the entire 2.0.0 line — 2.0.0-alpha.1 + 2.0.0-rc.1 + 2.0.0-rc.2 + 2.0.0-rc.3 + 2.0.0-rc.4 — framed as the full change set from the last final release, node-1.0.0, to node-2.0.0-rc.4. This is expected to be the final release candidate of the 2.0.0 line. Per-pre-release deltas remain available in their own release notes (alpha.1, rc.1, rc.2, rc.3).

This release cannot upgrade mainnet — there is no mechanism by which it could. The 2.0.0 line is a binary-only, fresh-chain development line: it ships no on-chain runtime upgrade and no ledger 8 → 9 state migration, so no existing chain — mainnet included — can be forked, migrated, or rolled forward onto it. Mainnet's genesis state and chain-spec are byte-identical across the whole 2.0.0 line (genesis_state_mainnet.mn and res/mainnet/chain-spec.json are unchanged from node-1.0.0); nothing in this line regenerates a mainnet artifact. Mainnet stays on the 1.0.x / ledger-8 line and is untouched. A 2.0.0 binary can only bootstrap a fresh ledger-9 genesis (dev / devnet / stagenet) — which is a new chain, not mainnet.

Metadata

  • Type of release: major (release-candidate pre-release)
  • Date: 2026-07-09
  • Ships in bundle: TBD — rc pre-release (not bundled)
  • Git tag: node-2.0.0-rc.4
  • Environment: Development ledger-9 networks only — local env, Devnet, Stagenet. Deployed ledger-8 networks (mainnet, preprod, preview, qanet, govnet, perfnet) are not targets of this line. For the full compatibility matrix, see the release notes overview.
  • Upgrade scope: binary only — no on-chain runtime upgrade occurs; the node binary carries its bundled runtime and is not compatible with existing networks, so chains start fresh
  • Reset required: Yes — fresh chain required; no in-place upgrade from any prior node version (including earlier 2.0.0 pre-releases) is supported in this line
  • Governance action required: No (deployed as a fresh chain); enabling the Cardano→Midnight bridge later requires a governance action — it ships inert
  • Mainnet upgrade possible: No — structurally impossible (no runtime upgrade path, no ledger 8→9 migration; mainnet artifacts untouched)
  • Sister-line note: The 1.0.x maintenance line (e.g. node-1.0.1-rc.2) continues in parallel for networks staying on ledger 8, including mainnet. 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

Cumulative state of the Midnight Node 2.0.0 line through rc.4, expected to be the final RC. The line moves the ledger to version 9 (9.1.0.0-rc.3 at this rc), lands the (still-inert) Cardano→Midnight bridge pallet plus toolkit commands, removes unused partner-chains pallets, bumps the Rust toolchain to 1.95, and carries a large batch of Least Authority audit-hardening fixes across node and toolkit. It adds a dual v1/v2 ZK proving pipeline, on-chain contract IR (ContractOperation V4), substantial sync-performance work, guaranteed-segment-only ledger-9 validation, multi-destination toolkit transfers, fixed genesis pool generation, a fixed bridge claim path, cNIGHT contract-identifier root extrinsics, benchmarks/weights for the bridge pallets, a recreated devnet genesis, and a new stagenet network. rc.3 folds the L7/L8 (2.x) and L9 (3.x) crypto stacks into a single zkir crate and bumps the ledger patch set to 9.1.0.0-rc.3 (state encoding v17 → v18, revised cost-model factors). rc.4 regenerates the stagenet genesis + chain-spec, fixes node startup argument parsing (custom RunMidnight flags such as --no-hardware-benchmarks are accepted again), and moves devnet to a 7-seat committee (D-parameter 7:0) with a cleared NIGHT token_asset_name.

This is a binary-only release: the node binary carries its own bundled runtime, so no on-chain runtime upgrade happens. It is not compatible with existing networks — there is no migration from ledger 8 and no in-place upgrade from any prior node version: 2.0.0 chains must start fresh. Mainnet cannot be upgraded by this release under any circumstances. (For reference, the bundled runtime reports spec_version 002_000_000 and transaction_version 4, vs 1_000_000 / 3 in node 1.0.0; the runtime WASM is byte-identical across rc.2 → rc.4.)

Audience

These release notes are intended for:

  • Operators evaluating or running the 2.0.0 development line (local env, devnet, stagenet) — a fresh-chain start is mandatory; no rolling upgrade, and specifically no mainnet upgrade, is supported.
  • Developers who build and sign extrinsics — transaction_version is 4; extrinsics signed against the 1.0.0 runtime (tx version 3) no longer decode.
  • Toolkit users who generate transactions, manage wallets, or rehearse the Cardano→Midnight bridge flow against ledger 9.1.0.0-rc.3.
  • Integrators decoding runtime metadata or ledger state — metadata was regenerated for ledger 9.1 (new parameters; on-chain ContractOperation V4).
  • Administrators maintaining genesis state and chain-specs — devnet and stagenet were regenerated; ledger-state encoding moved v17 → v18.

Dependencies

  • Ledger: 9.1.0.0-rc.3 (midnight-ledger-v9, crate tag crate-ledger-9.1.0.0-rc.3). No v8 → v9 migration path; incompatible with ledger-8 chain state and with 2.0.0-rc.2 payloads.
  • CompactC: the toolkit defaults to 0.31.0.
  • 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; new cNIGHT contract-identifier root extrinsics). Unchanged since rc.2 — the rc.3/rc.4 ledger and config changes do not alter pallet storage or extrinsics. Re-pull metadata before pointing tooling at a 2.0.0 chain.

Downstream impact (cascading effects): indexers, wallets, and SDKs that decode runtime metadata or ledger-8 state must be rebuilt against the 2.0.0 metadata / ledger 9.1 before they can follow a 2.0.0 chain. Payloads built against rc.2 (ledger 9.1.0.0-rc.2) will not validate under rc.3/rc.4. The C2M bridge is inert, so no downstream bridge integration is active yet. Deployed ledger-8 networks (mainnet, preprod, preview, qanet, govnet, perfnet) read via the L7/L8 stacks and are entirely unaffected by this line.

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

Deployment information

  • Upgrade scope: binary only — there is no on-chain runtime upgrade. The runtime is baked into the node binary and is incompatible with existing networks, so deployment is a fresh chain, not an in-place upgrade.
  • Reset required: Yes — fresh chain. Ledger 9 has no state transition from ledger 8, and this line supports no in-place upgrade from any prior node version (including 2.0.0-alpha.1 through 2.0.0-rc.3). Genesis state and chain-specs were regenerated for ledger 9.1 (ledger-state encoding v18); devnet and stagenet genesis were recreated. Mixed pre-v9/post-v9 handling in block replay and toolkit caching remains deliberately relaxed and unsupported.
  • Mainnet: cannot be upgraded — no path exists. Mainnet runs ledger 8 on the 1.0.x line; a 2.0.0 node can neither join nor migrate it. Mainnet genesis/chain-spec are untouched by the entire 2.0.0 line.
  • Governance action required: No — deploys as a fresh chain, not an on-chain upgrade. A future non-2.0.0 line will require an on-chain runtime upgrade once ledger-8 → 9 state-migration work is complete, at which point existing chains roll forward instead of resetting. Separately, enabling the C2M bridge 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 development networks bootstrap from fresh genesis. No coordination with mainnet operators is required or possible.

Artifacts

  • Docker: midnightntwrk/midnight-node:2.0.0-rc.4
  • Docker: midnightntwrk/midnight-node-toolkit:2.0.0-rc.4
  • Git tree hash: 5c34f67538f20811d876f6463cf9aca5a3bc4fc9
docker pull midnightntwrk/midnight-node:2.0.0-rc.4
docker pull midnightntwrk/midnight-node-toolkit:2.0.0-rc.4

Note: like 2.0.0-rc.1/rc.2/rc.3 (and 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

Cumulative new features, improvements, and fixes across the 2.0.0 line (1.0.0 → 2.0.0-rc.4):

  • Ledger 9 — new ledger major; no migration from ledger 8, so 2.0.0 chains start fresh (#1604); bumped to 9.1.0.0-rc.2 with a dual v1/v2 ZK proving pipeline, on-chain contract IR and ContractOperation V4, ECDSA domain-separator change, and a new max_contract_metadata_size parameter (#1692); then to 9.1.0.0-rc.3 folding the L7/L8 (2.x) and L9 (3.x) crypto stacks into one zkir crate, with state encoding v17 → v18 and revised cost-model factors (#1738).
  • Cardano→Midnight bridge (inert) — new c2m-bridge pallet, genesis/runtime config, transfer classification, pre-approvals, subminimal-transfer holds, claim-path fix, benchmarks/weights, and a toolkit bridge-transfer command (#1386, #1333, #1513, #1477, #1393, #1608, #1697, #1635, #1340).
  • cNIGHT contract-identifier root extrinsics — set Cardano contract identifiers on-chain to exercise contract upgradeability in fork/local-env testing (#1602).
  • Sync performance — bulk-read cNIGHT observation cache (genesis→tip ~3 h 19 m) (#1436), epoch-nonce + federated-ops caches (#1551), cNIGHT UTXO overestimate 64× → 4× (#1367), Midnight parity-db fork (#1478), db-sync autovacuum tuning (#1434).
  • Ledger-9 guaranteed-only validation — mempool and block-inclusion pre-checks dry-run only the guaranteed segment on ledger 9 (#1454).
  • New / regenerated networks + genesis — recreate devnet genesis + chain-spec (#1698); add stagenet (Cardano Preview, 7 permissioned validators) (#1707); regenerate stagenet genesis + chain-spec (#1858); devnet 7-seat committee (D-parameter 7:0) + cleared NIGHT token_asset_name for devnet/qanet/preview/preprod (#1834); prevent empty locked pool + --allow-empty-pools, testnet pools mirror mainnet (#1675).
  • Node startup — parse custom RunMidnight args (e.g. --no-hardware-benchmarks, --rpc-max-finality-subscriptions) before applying config overrides (#1767/#1795).
  • Removed unused partner-chains pallets and their CLI commands (#1562).
  • SessionInfoApi runtime API exposing the substrate session index (#1534); storage_separation config option (#1278).
  • Toolkit — multi-destination single-tx (#1560), --coin-selection, --input-utxo pinning, --print-system-tx-hex, batched cache warmup (#1457, #1404, #1473, #1603), dual-stack verifier-key + intent-envelope adaptation for ledger 9.1.0.0-rc.3 (#1738).
  • Rust 1.95 toolchain (#1363); toolkit CompactC default 0.31.0 (#1555).
  • Granular ledger error variants surfaced through pallet + RPC error reporting (#1449, #1475, #916, #1359).
  • A batch of Least Authority audit-hardening fixes across node and toolkit.
Change Upgrade Type PR
Ledger 9 support Runtime upgrade #1604
Bump ledger to 9.1.0.0-rc.2 (dual v1/v2 ZK pipeline, ContractOperation V4, max_contract_metadata_size) Runtime upgrade #1692
Bump ledger to 9.1.0.0-rc.3 (fold crypto stacks into one zkir; encoding v17→v18; cost-model factors) Node upgrade + Toolkit #1738
Added c2m-bridge pallet Runtime upgrade #1386
C2M bridge: genesis / runtime configuration Runtime upgrade #1333
C2M bridge: Reserve Transfer classification Runtime upgrade #1513
C2M bridge: pre-approvals filter (→ treasury + UnapprovedTransfer) Runtime upgrade #1477
C2M bridge: hold + flush subminimal transfers Runtime upgrade #1393
C2M bridge: STAR denomination fix Runtime upgrade #1608
C2M bridge: fix claim path Runtime upgrade #1697
C2M bridge: benchmarks + weights (pallet_c2m_bridge, pallet_partner_chains_bridge) Runtime upgrade #1635
cNIGHT contract-identifier root extrinsics (upgradeability testing) Runtime upgrade #1602
Remove unused partner-chains pallets + commands Runtime upgrade #1562
SessionInfoApi runtime API Runtime upgrade #1534
cnight-observation: panic → typed error on inherent decode Runtime upgrade #1234
federated-authority: keep motion removal on failed dispatch Runtime upgrade #938
cNIGHT observation UTXO capacity −16× (API v2 gated) Runtime upgrade #1367
cNight observation: bounded storage (unbounded-alloc fix) Runtime upgrade #1423
Throttle AccountUsage storage-migration refactor Runtime upgrade #1526
Granular ledger error variants in pallet error reporting Runtime upgrade #1449
Session-change error log when D-parameter below permissioned count Runtime upgrade #1506
cnight-observation genesis panic diagnostics Runtime upgrade #1466
Prevent empty locked pool in genesis; --allow-empty-pools; testnet pools mirror mainnet Runtime upgrade #1675
Recreate devnet genesis state/block + chain-spec Runtime upgrade #1698
Update Rust toolchain to 1.95 Runtime upgrade (mixed) #1363
Add stagenet network genesis + chain specs Node upgrade #1707
Regenerate stagenet genesis + chain-spec Node upgrade #1858
Devnet 7-seat committee (D-parameter 7:0) + cleared NIGHT token_asset_name (devnet/qanet/preview/preprod) Node upgrade #1834
Parse RunMidnight args before applying config overrides (--no-hardware-benchmarks, --rpc-max-finality-subscriptions) Node upgrade #1767, #1795
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
Bound GRANDPA + BEEFY finality subscription fan-out Node upgrade #1075
Enforce TLS cert + hostname validation for DB connections Node upgrade #1104
Verify removal of WalletSeed Default implementation Node upgrade #1109
Return ContractNotPresent for missing contracts Node upgrade #916
Surface ContractNotPresent through midnight_contractState RPC Node upgrade #1475
Return BeneficiaryNotFound in get_unclaimed_amount Node upgrade #1359
Per-session validator committee-membership log Node upgrade #1534
Reject block headers with duplicate mainchain-ref-hash digests Node upgrade #1617
Complete zeroization of secret buffers Node upgrade #1379
Default unsafe_allow_symlinks to false when missing Node upgrade #1600
parity-db: Midnight fork (lower flush threshold, ahash) Node upgrade #1478
Silence cNIGHT observation noise logs Node upgrade #1324
Run hardware benchmarks on node startup Node upgrade #1394
Midnight-specific reference hardware profile Node upgrade #1511
Log sanitized db-sync startup probe results Node upgrade #1411
Tune autovacuum on db-sync hot tables Node upgrade #1434
Eliminate deadlock in LedgerContext::with_wallets_from_seeds Node upgrade #1471
New storage_separation config option Node upgrade #1278
Toolkit single-tx multiple-destination support Toolkit #1560
Toolkit bridge-transfer command Toolkit #1340
Toolkit contract-address --untagged cleanup Toolkit #1486
Enforce derivation-path role validation in wallet constructors Toolkit #1076
Improve wallet seed / keypair / address code quality Toolkit #1217
--coin-selection flag on coin-selecting commands Toolkit #1457
Batched dust_balance::execute_many for cache warmup Toolkit #1603
--input-utxo pinning for generate-txs single-tx Toolkit #1404
--print-system-tx-hex for update-ledger-parameters Toolkit #1473
Harden coin-selection arithmetic with checked operations Toolkit #1293
Enforce EOF on untagged CLI parser path (ADR-0022) Toolkit #1437
Abstract transaction builders over a BuilderContext trait Toolkit #1605
Fix dust-balance snapshot tagged at block_height = 0 under dust_warp Toolkit #1574
Lock redb fetch cache against concurrent toolkit processes Toolkit #1493
Terminal-status sender error handling Toolkit #1323
Dispatch toolkit-js variants by compactc version Toolkit #1555
Fix stack overflow in trusted_deserialize_tagged Toolkit #1576
Update default CompactC version to 0.31.0 Toolkit #1555
Restore cNIGHT observation e2e coverage against Cardano Preview Infrastructure #1578, #1613
Initial CI for fork testing Infrastructure #1353
fork-network workflow: node-upgrade option Infrastructure #1469
local-files secrets mode for mock authorities Infrastructure #1287
Remove Kubernetes + AWS coupling from local-environment Infrastructure #1470
local-env: patch cnight mapping_validator_address from compiled contracts Infrastructure #1653
e2e tests for C2M bridge Infrastructure #1654
C2M-bridge subminimal-transfer edge-case tests Infrastructure #1677
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
Remove local-env + e2e-tests in partner-chains Infrastructure #1351
e2e regression coverage for genesis_extrinsics parsing Infrastructure #1516
Per-test tracing logger for the e2e suite Infrastructure #1564
Local fork-testing for the 1.0.0 release train Infrastructure #1522
Read e2e contract values from runtime-values Infrastructure #1348
Split e2e suite into per-topic module files Infrastructure #1565
Remove unused/outdated ddosnet network Infrastructure #1343

New features

Ledger 9 (9.1.0.0-rc.3)

Description: Moves the node, runtime, and toolkit onto ledger version 9, ending at 9.1.0.0-rc.3 (midnight-ledger-v9) at this rc. There is no state transition from ledger 8 — an existing ledger-8 chain (mainnet included) cannot be hard-forked or migrated, so 2.0.0 chains must start fresh; mixed pre-v9/post-v9 handling in block replay and toolkit caching is deliberately relaxed and unsupported. Why ledger 9, not 8.1: 8.1 was a minor (storage stability + wallet WASM bindings); ledger 9 supplies the primitives 2.0.0 is built around — the UnlockToTreasury system transaction (locked pool → treasury), ECDSA signatures for the Cardano bridge, and an explicit governed fee price floor — plus split-phase execution and panic/cost-heuristic hardening. The 9.1.0.0-rc.2 bump added a dual v1/v2 ZK proving pipeline (zk-stdlib v2 / circuits v7): zkir holds v1 or v2 prover keys behind VersionedInnerPK and defaults to v1; 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 updates the ECDSA domain separator. The 9.1.0.0-rc.3 bump then folds the L7/L8 (2.x) and L9 (3.x) crypto stacks into a single midnight-zkir 2.2.0 (proving V0/V1 and V2 circuits), moves the ledger-state serialization encoding v17 → v18, adds IrInsert/IrRemove on-chain IR maintenance (L9-only), and replaces the parallelism_factor cost-model parameter with three FixedPoint factors (validation_factor 0.25, guaranteed_factor 1.0, fallible_factor 1.0) on new-ledger networks. Runtime metadata and undeployed genesis/test fixtures were regenerated. Runtime upgrade (ledger 9 major); the rc.2 → rc.3 patch bump is a node/toolkit upgrade — the runtime WASM is byte-identical, as the ledger is reached via host calls.

PR: #1604 (ledger 9), #1692 (9.1.0.0-rc.2), #1738 (9.1.0.0-rc.3)

Reference: ledger 9.1.0.0-rc.3 changelog · what the Ledger 9 upgrade unlocks

Cardano→Midnight bridge (inert)

Description: Introduces the c2m-bridge pallet, a stateful TransferHandler built on the partner-chains bridge pallet that holds the Midnight-specific bridge logic: it classifies Cardano transfers by distinguishing Reserve Validator and ICS Validator inputs (closing a metadata-spoofing attack on the M.R pool), redirects unapproved user transfers to the treasury while emitting UnapprovedTransfer, accumulates subminimal transfers and flushes them as one once a configured threshold is met, and treats amounts as STAR end-to-end (no NIGHT denomination conversion). The claim path was fixed (#1697) and the bridge pallets gained benchmarks + weights (#1635). Governance dispatchables set_subminimal_transfers_config and add_approved_mc_tx_hashes configure it. A toolkit bridge-transfer command submits the corresponding Cardano transaction. The bridge ships inert — its inherent-data provider reports Inert in every environment, and a governance action (setting MainChainScripts addresses + a data checkpoint) is required to enable it. Full surface (pallet extrinsics/events/storage, bridge-transfer flags, SessionInfoApi) is documented in the engineering notes. Runtime upgrade (+ Toolkit).

PR: #1386, #1333, #1513, #1477, #1393, #1608, #1697, #1635, #1340

cNIGHT contract-identifier root extrinsics

Description: Adds root extrinsics to set the Cardano cNIGHT contract identifiers on-chain, closing a gap in contract-upgradeability testing. The intended flow forks a network into local-env, swaps the contract UTXO to keep the same address while pointing at the contract's staging track, and lets the node observe the logic-round increment and adjust logic for the new version. Runtime upgrade.

PR: #1602

SessionInfoApi runtime API

Description: A new midnight-primitives-session-info::SessionInfoApi runtime API exposes current_session_index() -> u32, backed by pallet_partner_chains_session::Pallet::current_index(). Node-side code can now read the substrate session index through a typed runtime API instead of reaching into pallet storage directly. Requires a metadata rebuild. Runtime upgrade.

PR: #1534

Toolkit transaction-generation controls

Description: Adds operator-facing controls to the transaction generator: generate-txs single-tx now accepts multiple --destination-address entries, each with its own shielded/unshielded amount and token type, so one transaction can pay several recipients across both token types (#1560); --coin-selection <largest-first|smallest-first> orders coin/UTXO selection (largest-first default minimises inputs; smallest-first consolidates dust); --input-utxo <intent_hash>#<n> pins exact UTXOs as inputs, bypassing greedy selection; --print-system-tx-hex builds and prints the update-ledger-parameters system-transaction payload without submitting (no council/TC keys needed); and dust_balance::execute_many warms the wallet cache for many seeds in a single shared block replay. Toolkit.

PR: #1560, #1457, #1404, #1473, #1603

New features requiring configuration updates

storage_separation config option

Required updates:

  • Set storage_separation = "separate" (default) or "unified" in node config (TOML key, or the STORAGE_SEPARATION environment variable). There is no CLI flag.
  • Choose the value at chain initialisation — it cannot be changed on an existing database.

Impact: unified stores Midnight ledger and Substrate items in a single ParityDb instance, reducing the chance of cross-instance data-integrity errors on unexpected process termination. Switching modes against a populated database fails at open with IncompatibleColumnConfig; the node prints a clear error and you must delete the chain-data directory and resync. See the storage_separation operator guide.

PR: #1278

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

stagenet network (added + regenerated)

Required updates:

  • A stagenet preset (res/cfg/stagenet.toml) runs on Cardano Preview with 7 permissioned validators and governance split across a technical committee (validators 1-3) and council (validators 4-6).
  • Genesis ledger state (res/genesis/genesis_{state,block}_stagenet.mn), chain-specs (res/stagenet/chain-spec{,-raw,-abridged}.json), and Earthfile targets generate-stagenet-genesis-seeds / rebuild-genesis-state-stagenet ship with it. Genesis + chain-spec were regenerated at rc.4 (#1858) — any stagenet reset must use the rc.4 artifacts.

Impact: Operators can target stagenet directly. The cNIGHT observation state starts empty and is observed forward from genesis; reserve and ICS/treasury pools carry nominal genesis amounts (ledger 9 requires non-empty pools). Node upgrade (network config).

PR: #1707, #1858

Devnet committee + NIGHT token name

Required updates:

  • Devnet now runs a 7-seat committee (D-parameter 7:0, up from 6) to keep GRANDPA quorum healthy; regenerate devnet genesis/chain-spec from the updated config.
  • The NIGHT token_asset_name is cleared to "" for devnet, qanet, preview, and preprod (backport of #1730). Tooling that keyed off the previous asset name on those networks must be updated.

Impact: Affects the four development/test networks only; deployed mainnet configuration is untouched. Node upgrade (network config).

PR: #1834

Improvements

  • Ledger 9.1.0.0-rc.3 patch bump: folds the L7/L8 (2.x) vs L9 (3.x) crypto-stack split into one midnight-zkir 2.2.0 crate (proves V0/V1 and V2 circuits), retiring the frozen zkir-2.1.0 workspace dep; provides the dropped upstream verifier_key() locally so it works across all ledger versions; adds SingleUpdate::IrInsert/IrRemove (L9-only on-chain IR maintenance); and swaps the parallelism_factor cost parameter for validation_factor/guaranteed_factor/fallible_factor. Toolkit adapts: dual-stack ContractOperation verifier-key slot selection (fixes VerifierKeyNotSet on v1 contracts), dust_actions folded into the IntentSigningEnvelope before data_to_sign/signing (fixes InvalidDustRegistrationSignature/IntentSignatureVerificationFailure), and !Send-safe proving via a spawn_blocking current-thread runtime (#1738).
  • Node startup: RunMidnight wrapper flags (--no-hardware-benchmarks, --rpc-max-finality-subscriptions, …) are now parsed before config overrides are applied to the underlying sc_cli::RunCmd, instead of being stripped/rejected (#1767/#1795).
  • 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); epoch-nonce and federated-ops caches address residual slow-sync hot paths (#1551); the per-transaction UTXO overestimate drops from 64× to 4× (runtime-API-v2 gated so validators can't diverge mid-rollout) (#1367); the workspace parity-db switches to the Midnight fork with a lower background-flush threshold and ahash (#1478); autovacuum_analyze_scale_factor is tuned (0.1 → 0.01) on hot db-sync tables to avoid >400s worst-case query plans (#1434).
  • 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).
  • Bridge weights: pallet_c2m_bridge and pallet_partner_chains_bridge gained generated benchmarks and weights (#1635).
  • Observability: per-session log of whether the local AURA key is in the active committee (#1534); error log when the D-parameter is below the permissioned candidate count (#1506); sanitized db-sync startup probe timings (#1411); hardware benchmarks on startup against a Midnight reference profile, with --no-hardware-benchmarks to opt out (#1394, #1511); actionable cnight-observation genesis-failure diagnostics naming the offending chain-spec field (#1466).
  • Log hygiene: demote per-UTXO cNIGHT "no registration" / "no create event" warnings to trace and drop no-signal address debug lines (#1324).
  • Error reporting: granular inner-cause variants for InvalidError / MalformedError / SystemTransactionError (stable codes 212–250, metadata rebuild required) (#1449); ContractNotPresent distinguishable from empty state, end-to-end through the midnight_contractState RPC (#916, #1475); BeneficiaryNotFound vs zero unclaimed reward (#1359).
  • Block validation: reject headers carrying more than one mcsh pre-runtime digest, mirroring sc-consensus-aura (#1617).
  • Toolkit UX / robustness: contract-address --untagged hidden from --help with its deprecation warning routed through log::warn! and --tagged --untagged now a parse error (#1486); advisory lock on the redb fetch cache to stop concurrent-process corruption (#1493); stacker-based fix for stack overflow in trusted_deserialize_tagged on long chains (#1576); terminal-status sender error handling (#1323); BuilderContext trait so builders no longer require a full local chain replay (#1605); dispatch toolkit-js by compactc version rather than ledger version (#1555).

Deprecations

None.

Breaking changes

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

Mainnet (and any ledger-8 chain) cannot be upgraded

What changed: The 2.0.0 line ships no on-chain runtime-upgrade path and no ledger 8 → 9 state migration.

What breaks: There is no way to move mainnet — or any existing ledger-8 chain — onto a 2.0.0 node. A 2.0.0 binary loading a ledger-8 mainnet chain-spec cannot apply ledger-8 state under ledger 9. Mainnet remains on the 1.0.x / ledger-8 line.

Required actions:

  • Keep mainnet on the 1.0.x line (node-1.0.1-rc.2 and successors). Do not deploy a 2.0.0 binary to a mainnet validator expecting an upgrade — none occurs.
  • Use 2.0.0 only for fresh development networks (local env, devnet, stagenet).

transaction_version bumped 3 → 4

What changed: The runtime transaction version moved from 3 (node 1.0.0) to 4.

What breaks: Signed extrinsics constructed against the 1.0.0 runtime metadata will no longer decode/validate. Any tooling, SDK, or service that builds and signs extrinsics must refresh its metadata.

Required actions:

  • Rebuild runtime metadata against 2.0.0 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 metadata before pointing them at a 2.0.0 chain.

Ledger 9 — no migration from ledger 8

What changed: The ledger moves to version 9 (9.1.0.0-rc.3 at this rc); this line ships 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.

rc.3+ is not compatible with rc.2

What changed: The 9.1.0.0-rc.29.1.0.0-rc.3 ledger bump changes the ledger-state serialization encoding (v17 → v18), the cost-model parameters, the intent signing envelope (dust folded into data_to_sign), and the contract verifier-key layout (dual-stack v2/v3 slots) (#1738).

What breaks: A new-ledger network running rc.2 cannot fork or migrate to rc.3/rc.4 — there is no upgrade path between the pre-releases. Transactions and ledger state serialized against rc.2 will not validate or decode under rc.3/rc.4.

Required actions:

  • Reset new-ledger networks (dev/devnet/stagenet) and regenerate genesis state + chain-spec at the v18 encoding before running rc.3/rc.4.
  • Rebuild any toolkit-generated fixtures/transactions against ledger 9.1.0.0-rc.3.

Partner-chains pallets removed

What changed: Partner-chains pallets not used by Midnight, and their related CLI commands, were removed (#1562).

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: The 2.0.0 line 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 earlier 2.0.0 pre-releases). Only a fresh ledger-9 chain can be started, and no ledger-8 chain — mainnet included — can be moved onto it. 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 line, not this one.

Links and references

Fixed defect list

Defect number Description
PM-19967 Unbounded GRANDPA/BEEFY finality subscription fan-out could exhaust node resources (#1075)
PM-20015 Wallet constructors accepted derivation paths with mismatched roles (#1076)
PM-22023 DB connections allowed insecure SSL modes / unverified TLS (#1104)
PM-22024 Residual all-zero WalletSeed Default needed removal verification (#1109)
PM-21799 Malformed cnight-observation inherent data could panic all validators and halt the chain (#1234)
PM-22085 Approved-but-failed federated-authority motions became permanently stuck (#938)
PM-21800 Deadlock in LedgerContext::with_wallets_from_seeds (reentrant mutex) (#1471)
PM-21801 get_unclaimed_amount returned Ok(0) for absent beneficiaries (#1359)
PM-19896 cnight-observation genesis panics gave no actionable diagnostics (#1466)
PM-22034 Incomplete zeroization of secret buffers after conversion (#1379)
PM-22018 Unchecked arithmetic in coin selection could overflow/panic (#1293)
PM-22028 Untagged CLI parser accepted trailing bytes (silent-fallback ambiguity) (#1437)
PM-22038 Secret material lacked Zeroize/redacted Debug; unneeded Copy/Clone (#1217)
#116 Unbounded allocation storing cNight mappings per user (#1423)
#1573 dust-balance snapshot saved at block_height = 0 under dust_warp, corrupting later replays (#1574)
#1401 Concurrent toolkit processes corrupted the shared redb fetch cache (#1493)
#1575 Stack overflow in trusted_deserialize_tagged on long-running chains (#1576)
#1607 C2M bridge applied an unnecessary NIGHT denomination to STAR amounts (#1608)
#1599 New binary failed to start against an older default.toml missing unsafe_allow_symlinks (#1600)
#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)
Node startup args RunMidnight wrapper flags (--no-hardware-benchmarks, --rpc-max-finality-subscriptions) were rejected before config overrides were applied (#1767, #1795)

Other Changes

  • Regenerated the stagenet genesis + chain-spec (#1858) and moved devnet to a 7-seat committee with a cleared NIGHT token_asset_name across devnet/qanet/preview/preprod (#1834).
  • cNIGHT observation e2e coverage restored against Cardano Preview, with a multi-hour await_cnight_observations watermark helper and a Postgres-backed shared fetch cache on qanet (#1578, #1613).
  • fork-network workflow gained a node-upgrade option (#1469); initial CI for fork testing (#1353); local fork-testing for the 1.0.0 release train (#1522).
  • compactc: arbitrary compact dependency now supported via submodule in CI, alongside the release-based flow (#1662).
  • e2e tests added for the C2M bridge (#1654) and its subminimal-transfer edge cases (#1677); local-env patches the cNIGHT mapping_validator_address from freshly compiled contracts (#1653); the nightly cNIGHT e2e job runs inside a container (#1658); qanet e2e reads contracts from the reserve-contracts submodule (#1666).
  • e2e suite housekeeping: regression coverage for genesis_extrinsics parsing (#1516), per-test tracing logger (#1564), per-topic module split (#1565), contract values read from runtime-values (#1348).
  • Infra cleanup: local-files secrets mode for mock authorities (#1287); Kubernetes + AWS coupling removed from local-environment (#1470); local-env + e2e-tests removed from partner-chains (#1351); unused ddosnet network removed (#1343).