Releases: midnightntwrk/midnight-node
node-2.0.0-alpha.1
Midnight Node 2.0.0-alpha.1
Metadata
- Type of release: major (alpha pre-release)
- Date: 2026-06-03
- Ships in bundle: TBD — alpha pre-release (not bundled)
- Git tag: node-2.0.0-alpha.1
- Environment: All public networks at time of release. For the full compatibility matrix, see the release notes overview.
- Upgrade scope: binary + runtime (
spec_version1_000_000 → 2_000_000) - Reset required: Yes — Ledger 9 currently has no state transition from ledger 8; a fresh chain is required
- Governance action required: No for this alpha (deployed as a fresh chain). Later RCs will require an on-chain runtime upgrade once state-migration work is complete; enabling the Cardano→Midnight bridge also requires a governance action (the bridge is inert in all environments here)
High-level summary
First alpha of the Midnight Node 2.0.0 line. It moves the ledger to version 9, lands the (still-inert) Cardano→Midnight bridge pallet plus toolkit commands, removes unused partner-chains pallets, and bumps the Rust toolchain to 1.95 — alongside a batch of Least Authority audit-hardening fixes across the node and toolkit. This is a runtime upgrade (spec_version 1_000_000 → 2_000_000, transaction_version 3 → 4) and a binary upgrade. There is currently no migration from ledger 8 — 2.0.0 chains must start fresh.
Audience
These release notes are intended for:
- Operators who run a node on any network and want to evaluate the 2.0.0 line — a fresh-chain start is mandatory.
- Developers who build and sign extrinsics —
transaction_versionbumped 3 → 4, so extrinsics signed against the 1.0.0 runtime no longer decode. - Toolkit users who generate transactions, manage wallets, or rehearse the Cardano→Midnight bridge flow.
- Integrators tracking the Cardano→Midnight bridge surface — it ships inert in this alpha.
Dependencies
- Ledger: 9 (
midnight-ledger-v90.1.0). No v8 → v9 migration path; incompatible with ledger-8 chain state. - CompactC: the toolkit defaults to 0.31.0.
transaction_version4: signed extrinsics built against the 1.0.0 runtime (tx version 3) will not decode.
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 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 + runtime (
spec_version1_000_000 → 2_000_000,transaction_version3 → 4). - Reset required: Yes — Ledger 9 currently has no state transition from ledger 8. An existing ledger-8 chain cannot be upgraded in place; start a fresh chain. Mixed pre-v9/post-v9 handling in block replay and toolkit caching is deliberately relaxed and unsupported in this alpha.
- Governance action required: No for this alpha — it deploys as a fresh chain, not an on-chain upgrade. Later RCs will require an on-chain runtime upgrade once state-migration (ledger 8 → 9) 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
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-alpha.1 - Docker:
midnightntwrk/midnight-node-toolkit:2.0.0-alpha.1 - Runtime WASM:
midnight_node_runtime-2.0.0-alpha.1.compact.compressed.wasm(release asset) - Git tree hash:
04caf1b8210b4633c22ace70ae8046ba49b2a1a3
docker pull midnightntwrk/midnight-node:2.0.0-alpha.1
docker pull midnightntwrk/midnight-node-toolkit:2.0.0-alpha.1What changed
- Ledger 9 — new ledger major; no migration from ledger 8, so 2.0.0 chains start fresh (#1604).
- Cardano→Midnight bridge (inert) — new
c2m-bridgepallet, genesis/runtime config, transfer classification, pre-approvals, subminimal-transfer holds, and a toolkitbridge-transfercommand (#1386, #1333, #1513, #1477, #1393, #1608, #1340). - Removed unused partner-chains pallets and their CLI commands (#1562).
SessionInfoApiruntime API exposing the substrate session index (#1534).storage_separationconfig option — optionally unify Midnight ledger + Substrate storage into one ParityDb instance (#1278).- 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 |
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 |
| 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 |
| Update Rust toolchain to 1.95 | Runtime upgrade (mixed) | #1363 |
| 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 |
| Surface nested ledger error variants in flat error enums | Node upgrade | #1449 |
| 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](https://github.com/midnightntwrk/midnight... |
node-1.0.1-rc.1
Functionally identical to node-1.0.0, with a single small fix (#1601):
- The
unsafe_allow_symlinksnode config field is now optional (#[serde(default)]),
defaulting tofalse. Existing configs that omit the field now parse cleanly
instead of failing to load. Symlink loading remains disabled by default.
No runtime, consensus, or ledger changes.
node-1.0.0
Midnight Node 1.0.0
Release date: 2026-05-20
Git tag: node-1.0.0
Tree hash: a748db6ce78ccbd9b6bb3571686b83f849c7dc59
Environment: All public networks at time of release. For the full compatibility matrix, see the release notes overview.
Docker Images
docker pull midnightntwrk/midnight-node:1.0.0
docker pull midnightntwrk/midnight-node-toolkit:1.0.0High-level summary
Midnight Node 1.0.0 is the mainnet GA release. It bumps spec_version to 1_000_000 and bumps transaction_version to 3. The runtime adopts TransactionExtension (replacing the deprecated SignedExtension), tightens the throttle pallet, lands the Midnight-side handler hooks for the Cardano-to-Midnight bridge (the bridge itself is not enabled at this release — preparatory plumbing only), and migrates to measured benchmark weights. The node aligns with the polkadot-stable2603 Substrate SDK, gains a self-describing rpc.discover OpenRPC v1.4 endpoint, and picks up midnight-ledger 8.1.0 along with a number of audit-driven hardenings. The toolkit ships as an independently versioned image with substantial new transaction-generation, caching and observability features. Runtime upgrade required. SDK consumers using polkadot.js or subxt see no breakage — the new AuthorizeCall and WeightReclaim extensions are zero-sized, so the encoded transaction bytes are unchanged; only the implicit transaction_version mixed into the signature hash differs, which live signers fetch from chain state on every sign. The only genuine breakage is pre-signed extrinsics held across the upgrade boundary, and that is true for any spec_version bump.
Audience
These release notes are intended for:
- Node operators (all networks): Required upgrade. Roll the binary, then submit the runtime upgrade. Re-check
networkIdagainst your chainspec (now validated on boot). - DApp developers / SDK consumers: No action required for live signing. polkadot.js / subxt fetch
transaction_versionandspec_versionfrom chain state on every sign, and the two newTransactionExtensionentries are zero-sized — encoded tx bytes are unchanged. Pre-signed extrinsics held across the upgrade need re-signing (same as anyspec_versionbump). Userpc.discoverif you generate clients from spec. - Toolkit users / load-test operators: Required upgrade. Toolkit is now independently versioned and ships a new structured-logging stack, new
show-block,batch-single-tx, and per-seed caching subcommands. - Governance signers: New
proposal_weight_boundparameter required onmotion_close. Toolkitruntime-upgrade/update-ledger-parametersnow accept long-form--council-members/--technical-committee-members. - Cardano bridge consumers: Heads up — the Cardano-to-Midnight bridge is not enabled at 1.0.0. The handler hooks ship in the runtime so you can develop against the on-chain shape (handlers return a value attached to bridge events, each transfer carries
McTxHash), but no transfers flow until the bridge is turned on in a later release.
What Changed
| Change | Upgrade Type | PR |
|---|---|---|
| Cardano-to-Midnight bridge handler implementation (events, McTxHash, handler return value) — preparatory only, bridge not enabled | Runtime upgrade | #1188 |
Migrate runtime from SignedExtension to TransactionExtension (adds AuthorizeCall, WeightReclaim); transaction_version 2→3 |
Runtime upgrade (wire-format change, SDK-transparent via metadata) | #597 |
Align node, runtime, relay and partner-chains with polkadot-stable2603 SDK |
Runtime upgrade | #1299 |
Align node and runtime with polkadot-stable2512-3 SDK |
Runtime upgrade | #1262 |
Throttle pallet: per-account transaction-count limit (MaxTxs); AccountUsage migration |
Runtime upgrade (storage migration) | #1060 |
motion_close gains proposal_weight_bound; promoted to DispatchClass::Operational |
Runtime upgrade (extrinsic signature change) | #1032 |
| Use measured benchmark weights across FRAME and local pallets | Runtime upgrade | #1495 |
Early block-weight check in midnight pallet pre_dispatch |
Runtime upgrade | #1305 |
Remove stale cost model stubs; re-enable test_get_mn_transaction_fee |
Runtime upgrade (audit) | #839 |
Bump midnight-ledger to 8.1.0 (storage-core 1.2.0 incremental GC; race-condition, panic, leak, lock-ordering fixes) |
Node upgrade | #1301, #1510 |
Bump midnight-storage-core to 1.2.0-rc.2 |
Node upgrade | #1388 |
rpc.discover endpoint serving OpenRPC v1.4 spec (16 custom + 52 Substrate methods, JSON Schema types) |
Node upgrade (new API) | #869 |
Validate networkId on node boot against genesis state |
Node upgrade | #1265 |
Reject unsupported system transaction types (no more wildcard "unknown" accept) |
Node upgrade (audit) | #840 |
| Validate genesis file type / size (>10 MB, symlinks, non-regular files rejected) | Node upgrade (audit) | #832 |
unsafe_allow_symlinks config option (default off) |
Node upgrade | #1372 |
| Redact DB host/port/dbname from error logs (full details at debug level) | Node upgrade | #1067 |
ssl_root_cert configuration option for Postgres |
Node upgrade | #1029 |
| Per-SQL-query Prometheus timing for midnight data-source queries | Node upgrade | #904 |
In-memory cache for multi_asset.id lookups (removes repeated JOIN multi_asset from cNight queries) |
Node upgrade (perf) | #934 |
Coarse tx / tx_out / ma_tx_out id-range bounds for cNight observation queries (prune before joins) |
Node upgrade (perf) | #1365 |
| Improve logging for malformed ledger transactions | Node upgrade | #961 |
| Reduce cNIGHT observation address logs from error to debug | Node upgrade | #905 |
| Fix chain-state truncation after unclean shutdown (explicit DB drop) | Node upgrade (correctness) | #1140 |
| Drop ledger default storage on graceful shutdown | Node upgrade | #886 |
Remove hard-fork test ledger version dependencies / cfg(hardfork_test) |
Node upgrade | #1024 |
| Point to midnightntwrk partner-chains fork | Node upgrade | #948 |
| Bump vulnerable deps (rustls-webpki, astral-tokio-tar) — RUSTSEC-2026-0049 / 0066 | Node upgrade (security) | #1079 |
| Bump node version to 1.0.0 | Node upgrade | #919 |
Toolkit images versioned independently (toolkit-X.Y.Z tags) |
Toolkit | #1261 |
Toolkit JSON log format change (drops structured_logger for tracing_subscriber) |
Toolkit (BREAKING — log format) | #899 |
Toolkit --log-json, --verbose, --quiet, --verbose-fetch, --verbose-ledger; pretty default |
Toolkit | #859, #899 |
Toolkit show-block diagnostic command |
Toolkit | #1068 |
Toolkit batch-single-tx bulk transaction generation; file-based caches; --seeds on fetch |
Toolkit (perf) | #820, #939 |
Toolkit support for multiple shielded coin inputs in single-tx / batch-single-tx / batches |
Toolkit | #1216 |
| Toolkit support for fallible contract calls and fallible inputs | Toolkit | #888, #966 |
| Toolkit zswap state chaining in batched intents | Toolkit | #879 |
Toolkit LEDGER_VERSION override for multiple ledger stacks |
Toolkit | #946 |
| Tool... |
node-1.0.0-rc.8
Midnight Node 1.0.0
Release date: TBD (dry run from node-1.0.0-rc.8, published 2026-05-14)
Git tag: TBD (dry run tree from node-1.0.0-rc.8)
Tree hash: e34b648e6d735db4ebde0d1a450701f3d22eef3d (rc.8 tree — re-cut at final tag)
Environment: All public networks at time of release. For the full compatibility matrix, see the release notes overview.
Dry-run note: this file is generated from
node-1.0.0-rc.8ahead of the final 1.0.0 cut. The release date, tag, tree hash, Docker pull lines, and QA sign-off link must be updated before publishing. Diff against the actual final tag once it lands.
Docker Images
docker pull midnightntwrk/midnight-node:1.0.0
docker pull midnightntwrk/midnight-node-toolkit:1.0.0High-level summary
Midnight Node 1.0.0 is the mainnet GA release. It bumps spec_version from 22_000 to 1_000_000 and bumps transaction_version from 2 to 3. The runtime adopts TransactionExtension (replacing the deprecated SignedExtension), tightens the throttle pallet, lands the Midnight-side handler hooks for the Cardano-to-Midnight bridge (the bridge itself is not enabled at this release — preparatory plumbing only), and migrates to measured benchmark weights. The node aligns with the polkadot-stable2603 Substrate SDK, gains a self-describing rpc.discover OpenRPC v1.4 endpoint, and picks up midnight-ledger 8.1.0 along with a number of audit-driven hardenings. The toolkit ships as an independently versioned image with substantial new transaction-generation, caching and observability features. Runtime upgrade required. SDK consumers using polkadot.js or subxt see no breakage — the new AuthorizeCall and WeightReclaim extensions are zero-sized, so the encoded transaction bytes are unchanged; only the implicit transaction_version mixed into the signature hash differs, which live signers fetch from chain state on every sign. The only genuine breakage is pre-signed extrinsics held across the upgrade boundary, and that is true for any spec_version bump.
Audience
These release notes are intended for:
- Node operators (all networks): Required upgrade. Roll the binary, then submit the runtime upgrade. Re-check
networkIdagainst your chainspec (now validated on boot). - DApp developers / SDK consumers: No action required for live signing. polkadot.js / subxt fetch
transaction_versionandspec_versionfrom chain state on every sign, and the two newTransactionExtensionentries are zero-sized — encoded tx bytes are unchanged. Pre-signed extrinsics held across the upgrade need re-signing (same as anyspec_versionbump). Userpc.discoverif you generate clients from spec. - Toolkit users / load-test operators: Required upgrade. Toolkit is now independently versioned and ships a new structured-logging stack, new
show-block,batch-single-tx, and per-seed caching subcommands. - Governance signers: New
proposal_weight_boundparameter required onmotion_close. Toolkitruntime-upgrade/update-ledger-parametersnow accept long-form--council-members/--technical-committee-members. - Cardano bridge consumers: Heads up — the Cardano-to-Midnight bridge is not enabled at 1.0.0. The handler hooks ship in the runtime so you can develop against the on-chain shape (handlers return a value attached to bridge events, each transfer carries
McTxHash), but no transfers flow until the bridge is turned on in a later release.
What Changed
| Change | Upgrade Type | PR |
|---|---|---|
| Cardano-to-Midnight bridge handler implementation (events, McTxHash, handler return value) — preparatory only, bridge not enabled | Runtime upgrade | #1188 |
Migrate runtime from SignedExtension to TransactionExtension (adds AuthorizeCall, WeightReclaim); transaction_version 2→3 |
Runtime upgrade (wire-format change, SDK-transparent via metadata) | #597 |
Align node, runtime, relay and partner-chains with polkadot-stable2603 SDK |
Runtime upgrade | #1299 |
Align node and runtime with polkadot-stable2512-3 SDK |
Runtime upgrade | #1262 |
Throttle pallet: per-account transaction-count limit (MaxTxs); AccountUsage migration |
Runtime upgrade (storage migration) | #1060 |
motion_close gains proposal_weight_bound; promoted to DispatchClass::Operational |
Runtime upgrade (extrinsic signature change) | #1032 |
| Use measured benchmark weights across FRAME and local pallets | Runtime upgrade | #1495 |
Early block-weight check in midnight pallet pre_dispatch |
Runtime upgrade | #1305 |
Remove stale cost model stubs; re-enable test_get_mn_transaction_fee |
Runtime upgrade (audit) | #839 |
Bump midnight-ledger to 8.1.0 (storage-core 1.2.0 incremental GC; race-condition, panic, leak, lock-ordering fixes) |
Node upgrade | #1301, #1510 |
Bump midnight-storage-core to 1.2.0-rc.2 |
Node upgrade | #1388 |
rpc.discover endpoint serving OpenRPC v1.4 spec (16 custom + 52 Substrate methods, JSON Schema types) |
Node upgrade (new API) | #869 |
Validate networkId on node boot against genesis state |
Node upgrade | #1265 |
Reject unsupported system transaction types (no more wildcard "unknown" accept) |
Node upgrade (audit) | #840 |
| Validate genesis file type / size (>10 MB, symlinks, non-regular files rejected) | Node upgrade (audit) | #832 |
unsafe_allow_symlinks config option (default off) |
Node upgrade | #1372 |
| Redact DB host/port/dbname from error logs (full details at debug level) | Node upgrade | #1067 |
ssl_root_cert configuration option for Postgres |
Node upgrade | #1029 |
| Per-SQL-query Prometheus timing for midnight data-source queries | Node upgrade | #904 |
| Improve logging for malformed ledger transactions | Node upgrade | #961 |
| Reduce cNIGHT observation address logs from error to debug | Node upgrade | #905 |
| Fix chain-state truncation after unclean shutdown (explicit DB drop) | Node upgrade (correctness) | #1140 |
| Drop ledger default storage on graceful shutdown | Node upgrade | #886 |
Remove hard-fork test ledger version dependencies / cfg(hardfork_test) |
Node upgrade | #1024 |
| Point to midnightntwrk partner-chains fork | Node upgrade | #948 |
| Bump vulnerable deps (rustls-webpki, astral-tokio-tar) — RUSTSEC-2026-0049 / 0066 | Node upgrade (security) | #1079 |
| Bump node version to 1.0.0 | Node upgrade | #919 |
Toolkit images versioned independently (toolkit-X.Y.Z tags) |
Toolkit | #1261 |
Toolkit JSON log format change (drops structured_logger for tracing_subscriber) |
Toolkit (BREAKING — log format) | #899 |
Toolkit --log-json, --verbose, --quiet, --verbose-fetch, --verbose-ledger; pretty default |
Toolkit | #859, #899 |
Toolkit show-block diagnostic command |
Toolkit | #1068 |
Toolkit batch-single-tx bulk transaction generation; file-based caches; --seeds on fetch |
Toolkit (perf) | #820, #939 |
Toolkit support for multiple shielded coin inputs in single-tx / batch-single-tx / batches |
Toolkit | #1216 |
| Toolkit support for fallible contract calls and fallible inputs | Toolkit | #888, #966 |
| Toolkit zswap state chaining in batched intents | Toolkit | #879 |
Toolkit LEDGER_VERSION override for multiple ledger stacks |
Toolkit | #946 |
Toolkit contract_custom builder enabled for ledger 7 |
Toolkit | [#864](ht... |
node-1.0.0-rc.7
Git tag: node-1.0.0-rc.7
Components
- 📦
node-1.0.0 - 🧰
toolkit-1.0.0 - ⚙️
runtime-1.0.0
Added
Upgrade ledger from 8.0.2 to 8.1.0-rc.1 (#1301) (#node)
Bumps the midnight-ledger dependency from 8.0.2 to 8.1.0-rc.1, picking up
new ledger types and conversion support.
Changed
Add regression tests for nonce/nullifier distinction in zswap serialization (#1128, PM-22025) (#toolkit)
Add unit tests verifying that serialized zswap local state uses the coin
nonce (randomness), not the nullifier (spend identifier), for the nonce
field. Addresses Least Authority Q1 2026 Node DIFF audit Issue E.
PR: #1128
JIRA: https://shielded.atlassian.net/browse/PM-22025
Redact database connection details from error logs (#1067, PM-19904) (#node)
Database connection error messages no longer include the host, port, or database name at error level. Full connection details are available at debug log level for authorized troubleshooting.
PR: #1067
JIRA: https://shielded.atlassian.net/browse/PM-19904
Implements handler for C-to-M brige (#1188) (#node, #runtime)
Updates bridge to emit events.
Updates call by adding McTxHash to each transfer.
Updates handler API: handler is expected to return a value that is attached to events.
Implements the handler in Midnight runtime.
Add validation for `networkId` on node boot to avoid mismatch with genesis state (#1265, PM-22422) (#node, #binary)
Adds validation to ensure the networkId set in the chainspec matches the
networkId used to generate the genesis state.
PR: #1265
Fix for: https://shielded.atlassian.net/browse/PM-22422
Speed up cNight db-sync observation queries (#1365) (#node)
Pre-query coarse tx / tx_out / ma_tx_out id bounds for the requested
block-range window, then constrain the four cNight observation queries
(registration, deregistration, asset create, asset spend) by primary-key
range so postgres can prune rows before doing expensive joins. Extends the
same tx.id bounding to the tx_in-keyed spend/deregistration queries.
PR: #1365
Fix DustWallet spend state propagation (#877, PM-20016) (#toolkit)
Fix DustWallet::speculative_spend to return the updated DustLocalState
alongside spends, and extend mark_spent to commit the state atomically
with nullifier recording. This ensures DustLocalState::spend's
pending_until flags are propagated, preventing utxos() from returning
already-spent outputs in consecutive spend operations.
Addresses Least Authority audit finding Issue AO.
PR: #877
JIRA: https://shielded.atlassian.net/browse/PM-20016
Align node and runtime with polkadot-stable2512-3 SDK (#1262) (#node, #runtime)
Bumps Substrate dependencies to the polkadot-stable2512-3 tag and updates call sites for breaking API changes: Core::execute_block and BlockBuilder::check_inherents now use LazyBlock; SpawnTasksParams requires tracing_execute_block (set to None unless trace RPC is wired); MmrApi v3 gains generate_ancestry_proof while BeefyApi no longer exposes it; pallet-version test mock implements Core with LazyBlock. Partner-chains and lockfiles are updated in line with the same SDK line.
Align node, runtime, relay, and partner-chains with polkadot-stable2603 SDK (#1299) (#node, #runtime, #partner-chains)
Bumps Substrate dependencies to the polkadot-stable2603 tag and updates call sites for breaking API changes:
- Workspace: All
polkadot-stable2512-3git deps moved topolkadot-stable2603;tracing-subscriberpinned to=0.3.19(required bysp-tracingon this line) with toolkit using the workspace entry. - Node:
sc_service::build_networkgainsspawn_essential_handle;new_full_parts_with_genesis_builderkeeps the six-argument signature (no Grandpa pruning filters argument—unlikenew_full_parts). - Runtime:
sp_session::SessionKeys::generate_session_keysnow takesowner: Vec<u8>and returnsOpaqueGeneratedSessionKeys; opaque keygeneratecalls pass&owner. - Partner-chains (vendored subtree): Aura
ProposerusesProposeArgs; demo node usesGrandpaPruningFilterwithnew_full_partsandspawn_essential_handle; toolkit inherent errors useDebuginstead ofsp_runtime::RuntimeDebugwhere needed. - Ledger / primitives:
RuntimeDebugderives replaced withcore::fmt::Debugwheresp_runtime::RuntimeDebug/frame_support::RuntimeDebugwere removed. - Pallets:
RuntimeDebugNoBoundreplaced withDebugNoBound(e.g. federated-authority, throttle). - Relay (BEEFY):
BeefySignatureHasherremoved;SignedCommitment::verify_signaturescalled with a single inferred authority type parameter.
Partner-chains Cargo.toml / README / changelog are aligned with the same SDK tag where applicable.
Early weight check in midnight pallet pre_dispatch (#1305) (#node)
Add an early block weight check in ValidateUnsigned::pre_dispatch before
expensive ledger validation. Substrate's Bare extrinsic path runs the pallet's
pre_dispatch before the CheckWeight extension, which means transactions that
won't fit in the block still undergo costly ledger validation before being
rejected. The new check mirrors the logic in calculate_consumed_weight and
exits early with ExhaustsResources when the block is full.
PR: #1305
Speed up toolkit syncing (#1263) (#toolkit)
Batch block-number-to-hash RPC calls into a single request instead of one call per block, reducing round trips during sync. Also simplifies several function parameters across the fetcher.
PR: #1263
📦 Node
Git tag: node-1.0.0-rc.7
Docker Images
DockerHub
$ docker pull midnightntwrk/midnight-node:1.0.0-rc.7Added
Add per-SQL-query Prometheus timing for midnight data source queries (#904, PM-22100) (#node)
Midnight-specific data sources (cNight observation, federated authority,
candidates) now record individual Prometheus timing histograms for each
SQL query executed against DBSync. 13 sub-query timers provide per-query
latency visibility at :9615/metrics under the
midnight_data_source_query_time_elapsed metric with query_name labels.
PR: #904
JIRA: https://shielded.atlassian.net/browse/PM-22100
Add `rpc.discover` endpoint with OpenRPC v1.4 API specification (PM-6402, #869) (#client, #node, #rpc, #api)
Registers a standards-compliant rpc.discover JSON-RPC method that returns a complete OpenRPC v1.4 document describing the node's API. Enables client code generation, request validation, and developer discoverability without reading source code.
- 16 custom Midnight methods fully documented with parameter types, return types, error definitions, and descriptions
- 52 standard Substrate methods listed as reference entries
- JSON Schema type definitions generated via
schemarsfor all RPC response...
toolkit-1.0.0-rc.6
Git tag: toolkit-1.0.0-rc.6
Components
- 🧰
toolkit-1.0.0 - ⚙️
runtime-1.0.0
Added
Upgrade ledger from 8.0.2 to 8.1.0-rc.1 (#1301) (#node)
Bumps the midnight-ledger dependency from 8.0.2 to 8.1.0-rc.1, picking up
new ledger types and conversion support.
Changed
Add regression tests for nonce/nullifier distinction in zswap serialization (#1128, PM-22025) (#toolkit)
Add unit tests verifying that serialized zswap local state uses the coin
nonce (randomness), not the nullifier (spend identifier), for the nonce
field. Addresses Least Authority Q1 2026 Node DIFF audit Issue E.
PR: #1128
JIRA: https://shielded.atlassian.net/browse/PM-22025
Redact database connection details from error logs (#1067, PM-19904) (#node)
Database connection error messages no longer include the host, port, or database name at error level. Full connection details are available at debug log level for authorized troubleshooting.
PR: #1067
JIRA: https://shielded.atlassian.net/browse/PM-19904
Implements handler for C-to-M brige (#1188) (#node, #runtime)
Updates bridge to emit events.
Updates call by adding McTxHash to each transfer.
Updates handler API: handler is expected to return a value that is attached to events.
Implements the handler in Midnight runtime.
Add validation for `networkId` on node boot to avoid mismatch with genesis state (#1265, PM-22422) (#node, #binary)
Adds validation to ensure the networkId set in the chainspec matches the
networkId used to generate the genesis state.
PR: #1265
Fix for: https://shielded.atlassian.net/browse/PM-22422
Speed up cNight db-sync observation queries (#1365) (#node)
Pre-query coarse tx / tx_out / ma_tx_out id bounds for the requested
block-range window, then constrain the four cNight observation queries
(registration, deregistration, asset create, asset spend) by primary-key
range so postgres can prune rows before doing expensive joins. Extends the
same tx.id bounding to the tx_in-keyed spend/deregistration queries.
PR: #1365
Fix DustWallet spend state propagation (#877, PM-20016) (#toolkit)
Fix DustWallet::speculative_spend to return the updated DustLocalState
alongside spends, and extend mark_spent to commit the state atomically
with nullifier recording. This ensures DustLocalState::spend's
pending_until flags are propagated, preventing utxos() from returning
already-spent outputs in consecutive spend operations.
Addresses Least Authority audit finding Issue AO.
PR: #877
JIRA: https://shielded.atlassian.net/browse/PM-20016
Align node and runtime with polkadot-stable2512-3 SDK (#1262) (#node, #runtime)
Bumps Substrate dependencies to the polkadot-stable2512-3 tag and updates call sites for breaking API changes: Core::execute_block and BlockBuilder::check_inherents now use LazyBlock; SpawnTasksParams requires tracing_execute_block (set to None unless trace RPC is wired); MmrApi v3 gains generate_ancestry_proof while BeefyApi no longer exposes it; pallet-version test mock implements Core with LazyBlock. Partner-chains and lockfiles are updated in line with the same SDK line.
Align node, runtime, relay, and partner-chains with polkadot-stable2603 SDK (#1299) (#node, #runtime, #partner-chains)
Bumps Substrate dependencies to the polkadot-stable2603 tag and updates call sites for breaking API changes:
- Workspace: All
polkadot-stable2512-3git deps moved topolkadot-stable2603;tracing-subscriberpinned to=0.3.19(required bysp-tracingon this line) with toolkit using the workspace entry. - Node:
sc_service::build_networkgainsspawn_essential_handle;new_full_parts_with_genesis_builderkeeps the six-argument signature (no Grandpa pruning filters argument—unlikenew_full_parts). - Runtime:
sp_session::SessionKeys::generate_session_keysnow takesowner: Vec<u8>and returnsOpaqueGeneratedSessionKeys; opaque keygeneratecalls pass&owner. - Partner-chains (vendored subtree): Aura
ProposerusesProposeArgs; demo node usesGrandpaPruningFilterwithnew_full_partsandspawn_essential_handle; toolkit inherent errors useDebuginstead ofsp_runtime::RuntimeDebugwhere needed. - Ledger / primitives:
RuntimeDebugderives replaced withcore::fmt::Debugwheresp_runtime::RuntimeDebug/frame_support::RuntimeDebugwere removed. - Pallets:
RuntimeDebugNoBoundreplaced withDebugNoBound(e.g. federated-authority, throttle). - Relay (BEEFY):
BeefySignatureHasherremoved;SignedCommitment::verify_signaturescalled with a single inferred authority type parameter.
Partner-chains Cargo.toml / README / changelog are aligned with the same SDK tag where applicable.
Early weight check in midnight pallet pre_dispatch (#1305) (#node)
Add an early block weight check in ValidateUnsigned::pre_dispatch before
expensive ledger validation. Substrate's Bare extrinsic path runs the pallet's
pre_dispatch before the CheckWeight extension, which means transactions that
won't fit in the block still undergo costly ledger validation before being
rejected. The new check mirrors the logic in calculate_consumed_weight and
exits early with ExhaustsResources when the block is full.
PR: #1305
Speed up toolkit syncing (#1263) (#toolkit)
Batch block-number-to-hash RPC calls into a single request instead of one call per block, reducing round trips during sync. Also simplifies several function parameters across the fetcher.
PR: #1263
⚙️ Runtime
Git tag: runtime-1.0.0-rc.6
Added
Changed
Add proposal_weight_bound parameter to motion_close (#1032, PM-22326) (#runtime)
The motion_close extrinsic previously declared a constant weight that did not
account for the inner call dispatched as Root when a motion is approved.
Substrate can only refund weight post-dispatch, never increase it, so the inner
call's weight was never pre-charged. This adds a proposal_weight_bound parameter
following the pallet_collective::close pattern, ensuring the declared weight
includes the inner call's weight upfront. The extrinsic is also made
DispatchClass::Operational to match the other governance extrinsics. Toolkit and
upgrader are updated to pass the new parameter.
PR: #1032
Ticket: https://shielded.atlassian.net/browse/PM-22326
Use generated benchmark weights in runtime (#1495) (#runtime)
Connects generated runtime benchmark weights so the runtime uses measured
weights for core FRAME and local runtime pallets instead of generic defaults.
Includes GRANDPA, BEEFY MMR, timestamp, migrations, scheduler, preimage, tx-pause, council and technical committee
collectives and memberships, session validator management, federated authority
and observation, system parameters, and cNIGHT observation.
Add pe...
node-1.0.0-toolkit-1.0.0-runtime-1.0.0-rc.5
Git tag: node-1.0.0-toolkit-1.0.0-runtime-1.0.0-rc.5
Components
- 📦
node-1.0.0 - 🧰
toolkit-1.0.0 - ⚙️
runtime-1.0.0
⏺ Subxt Runtime Diff: 0.22.5 → 1.0.0-rc.3 — major upgrade
Versions: spec 22000 → 1000000, tx_version 2 → 3.
Summary:
Compatible: ❌ no
Requires transaction_version bump: ❌ no (subwasm view)
Requires storage migration: ✅ yes
New host-fn imports: 6 (old node binaries will fail)
Requires transaction_version bump: ❌ no (subwasm view)
Requires storage migration: ✅ yes
New host-fn imports: 6 (old node binaries will fail)
Pallet changes
Pallet 0 — System ❌ NOT COMPATIBLE
- Constants:
- BlockLength — different number of fields (12 → 13 bytes)
- Version — value changed (spec_version field bumped)
- Storages:
-
- BlockSize: u32
-
- BlocksTillUpgrade: u8
- − AllExtrinsicsLen removed
-
Pallet 5 — Midnight ❌ NOT COMPATIBLE
- NetworkId: Optional BoundedVec → Default BoundedString
- StateKey: Optional BoundedVec → Default Vec
(Modifier flips Optional→Default in both — needs migration to populate.)
Pallet 17 — PalletSession
-
- ExternallySetKeys map (AccountId32 → ())
Pallet 21 — Beefy (error renumbering)
- Error 5 renamed DuplicateOffenceReport → InvalidEquivocationProofSessionMember
- Error 6 renamed InvalidConfiguration → DuplicateOffenceReport
-
- Error 7 InvalidConfiguration
(Net effect: a new error variant inserted; old indices reshuffled — clients matching by index will be wrong.)
- Error 7 InvalidConfiguration
Pallet 32 — Bridge ❌ NOT COMPATIBLE
- Calls (signatures changed — same param names, different inner types):
- handle_transfers — BridgeTransferV1 shape changed; BridgeDataCheckpoint is now UtxoId
- set_main_chain_scripts — BridgeDataCheckpoint → UtxoId
- Events: + Transfer (mc_tx_hash, amount, result, recipient)
- Errors: + InherentAlreadyExecuted
- Storages:
- DataCheckpoint type changed (BridgeDataCheckpoint → UtxoId)
-
- InherentExecutedThisBlock: bool
Pallet 44 — FederatedAuthority ❌ NOT COMPATIBLE
- Call motion_close gained proposal_weight_bound: Weight param
-
- Error 9 MotionWeightBoundTooLow
Pallet 51 — Throttle ❌ NOT COMPATIBLE
- Constants:
-
- MaxTxs = 100
- WindowSize: 14400 → 600 (≈ 24h → 1h block window, assuming 6s slots)
-
- Storages:
- AccountUsage value type (u64, u32) → UsageStats (4 → 20 bytes default; needs migration)
New WASM host-function imports — node must support these
These are net-new host fns the runtime now calls. A node-0.22.5 binary running this runtime will fail at first call:
env.ext_crypto_ecdsa_sign_version_1
env.ext_crypto_ed25519_sign_version_1
env.ext_crypto_sr25519_sign_version_1
env.ext_ledger_8_bridge_construct_distribute_night_cardano_bridge_system_tx_version_1
env.ext_ledger_8_bridge_construct_distribute_reserve_system_tx_version_1
env.ext_ledger_8_bridge_construct_distribute_treasury_system_tx_version_1
Added
Upgrade ledger from 8.0.2 to 8.1.0-rc.1 (#1301) (#node)
Bumps the midnight-ledger dependency from 8.0.2 to 8.1.0-rc.1, picking up
new ledger types and conversion support.
Changed
Add regression tests for nonce/nullifier distinction in zswap serialization (#1128, PM-22025) (#toolkit)
Add unit tests verifying that serialized zswap local state uses the coin
nonce (randomness), not the nullifier (spend identifier), for the nonce
field. Addresses Least Authority Q1 2026 Node DIFF audit Issue E.
PR: #1128
JIRA: https://shielded.atlassian.net/browse/PM-22025
Redact database connection details from error logs (#1067, PM-19904) (#node)
Database connection error messages no longer include the host, port, or database name at error level. Full connection details are available at debug log level for authorized troubleshooting.
PR: #1067
JIRA: https://shielded.atlassian.net/browse/PM-19904
Implements handler for C-to-M brige (#1188) (#node, #runtime)
Updates bridge to emit events.
Updates call by adding McTxHash to each transfer.
Updates handler API: handler is expected to return a value that is attached to events.
Implements the handler in Midnight runtime.
Add validation for `networkId` on node boot to avoid mismatch with genesis state (#1265, PM-22422) (#node, #binary)
Adds validation to ensure the networkId set in the chainspec matches the
networkId used to generate the genesis state.
PR: #1265
Fix for: https://shielded.atlassian.net/browse/PM-22422
Speed up cNight db-sync observation queries (#1365) (#node)
Pre-query coarse tx / tx_out / ma_tx_out id bounds for the requested
block-range window, then constrain the four cNight observation queries
(registration, deregistration, asset create, asset spend) by primary-key
range so postgres can prune rows before doing expensive joins. Extends the
same tx.id bounding to the tx_in-keyed spend/deregistration queries.
PR: #1365
Fix DustWallet spend state propagation (#877, PM-20016) (#toolkit)
Fix DustWallet::speculative_spend to return the updated DustLocalState
alongside spends, and extend mark_spent to commit the state atomically
with nullifier recording. This ensures DustLocalState::spend's
pending_until flags are propagated, preventing utxos() from returning
already-spent outputs in consecutive spend operations.
Addresses Least Authority audit finding Issue AO.
PR: #877
JIRA: https://shielded.atlassian.net/browse/PM-20016
Align node and runtime with polkadot-stable2512-3 SDK (#1262) (#node, #runtime)
Bumps Substrate dependencies to the polkadot-stable2512-3 tag and updates call sites for breaking API changes: Core::execute_block and BlockBuilder::check_inherents now use LazyBlock; SpawnTasksParams requires tracing_execute_block (set to None unless trace RPC is wired); MmrApi v3 gains generate_ancestry_proof while BeefyApi no longer exposes it; pallet-version test mock implements Core with LazyBlock. Partner-chains and lockfiles are updated in line with the same SDK line.
Align node, runtime, relay, and partner-chains with polkadot-stable2603 SDK (#1299) (#node, #runtime, #partner-chains)
Bumps Substrate dependencies to the polkadot-stable2603 tag and updates call sites for breaking API changes:
- Workspace: All
polkadot-stable2512-3git deps moved topolkadot-stable2603;tracing-subscriberpinned to=0.3.19(required bysp-tracingon this line) with toolkit using the workspace entry. - Node:
sc_service::build_networkgainsspawn_essential_handle;new_full_parts_with_genesis_builderkeeps the six-argument signature (no Grandpa pruning filters argument—unlikenew_full_parts). - Runtime:
sp_session::SessionKeys::generate_session_keysnow takesowner: Vec<u8>and returnsOpaqueGeneratedSessionKeys; opaque keygeneratecalls pass&owner. - Partner-chains (vendored subtree): Aura
ProposerusesProposeArgs; demo node usesGrandpaPruningFilterwithnew_full_partsandspawn_essential_handle; toolkit inherent errors useDebuginstead ofsp_runtime::RuntimeDebugwhere needed. - Ledger / primitives:
RuntimeDebugderives replaced withcore::fmt::Debugwheresp_runtime::RuntimeDebug/frame_support::RuntimeDebugwere removed. - Pallets:
RuntimeDebugNoBoundreplaced withDebugNoBound(e.g. federated-authority, throttle). - Relay (BEEFY):
BeefySignatureHasherremoved;SignedCommitment::verify_signaturescalled with a single inferred authority type parameter.
Partner-chains Cargo.toml / README / changelog are aligned with the same SDK tag where applicable.
node-1.0.0-toolkit-1.0.0-runtime-1.0.0-rc.4
Git tag: node-1.0.0-toolkit-1.0.0-runtime-1.0.0-rc.4
Components
- 📦
node-1.0.0 - 🧰
toolkit-1.0.0 - ⚙️
runtime-1.0.0
Added
Upgrade ledger from 8.0.2 to 8.1.0-rc.1 (#1301) (#node)
Bumps the midnight-ledger dependency from 8.0.2 to 8.1.0-rc.1, picking up
new ledger types and conversion support.
Changed
Add regression tests for nonce/nullifier distinction in zswap serialization (#1128, PM-22025) (#toolkit)
Add unit tests verifying that serialized zswap local state uses the coin
nonce (randomness), not the nullifier (spend identifier), for the nonce
field. Addresses Least Authority Q1 2026 Node DIFF audit Issue E.
PR: #1128
JIRA: https://shielded.atlassian.net/browse/PM-22025
Redact database connection details from error logs (#1067, PM-19904) (#node)
Database connection error messages no longer include the host, port, or database name at error level. Full connection details are available at debug log level for authorized troubleshooting.
PR: #1067
JIRA: https://shielded.atlassian.net/browse/PM-19904
Implements handler for C-to-M brige (#1188) (#node, #runtime)
Updates bridge to emit events.
Updates call by adding McTxHash to each transfer.
Updates handler API: handler is expected to return a value that is attached to events.
Implements the handler in Midnight runtime.
Add validation for `networkId` on node boot to avoid mismatch with genesis state (#1265, PM-22422) (#node, #binary)
Adds validation to ensure the networkId set in the chainspec matches the
networkId used to generate the genesis state.
PR: #1265
Fix for: https://shielded.atlassian.net/browse/PM-22422
Speed up cNight db-sync observation queries (#1365) (#node)
Pre-query coarse tx / tx_out / ma_tx_out id bounds for the requested
block-range window, then constrain the four cNight observation queries
(registration, deregistration, asset create, asset spend) by primary-key
range so postgres can prune rows before doing expensive joins. Extends the
same tx.id bounding to the tx_in-keyed spend/deregistration queries.
PR: #1365
Fix DustWallet spend state propagation (#877, PM-20016) (#toolkit)
Fix DustWallet::speculative_spend to return the updated DustLocalState
alongside spends, and extend mark_spent to commit the state atomically
with nullifier recording. This ensures DustLocalState::spend's
pending_until flags are propagated, preventing utxos() from returning
already-spent outputs in consecutive spend operations.
Addresses Least Authority audit finding Issue AO.
PR: #877
JIRA: https://shielded.atlassian.net/browse/PM-20016
Align node and runtime with polkadot-stable2512-3 SDK (#1262) (#node, #runtime)
Bumps Substrate dependencies to the polkadot-stable2512-3 tag and updates call sites for breaking API changes: Core::execute_block and BlockBuilder::check_inherents now use LazyBlock; SpawnTasksParams requires tracing_execute_block (set to None unless trace RPC is wired); MmrApi v3 gains generate_ancestry_proof while BeefyApi no longer exposes it; pallet-version test mock implements Core with LazyBlock. Partner-chains and lockfiles are updated in line with the same SDK line.
Align node, runtime, relay, and partner-chains with polkadot-stable2603 SDK (#1299) (#node, #runtime, #partner-chains)
Bumps Substrate dependencies to the polkadot-stable2603 tag and updates call sites for breaking API changes:
- Workspace: All
polkadot-stable2512-3git deps moved topolkadot-stable2603;tracing-subscriberpinned to=0.3.19(required bysp-tracingon this line) with toolkit using the workspace entry. - Node:
sc_service::build_networkgainsspawn_essential_handle;new_full_parts_with_genesis_builderkeeps the six-argument signature (no Grandpa pruning filters argument—unlikenew_full_parts). - Runtime:
sp_session::SessionKeys::generate_session_keysnow takesowner: Vec<u8>and returnsOpaqueGeneratedSessionKeys; opaque keygeneratecalls pass&owner. - Partner-chains (vendored subtree): Aura
ProposerusesProposeArgs; demo node usesGrandpaPruningFilterwithnew_full_partsandspawn_essential_handle; toolkit inherent errors useDebuginstead ofsp_runtime::RuntimeDebugwhere needed. - Ledger / primitives:
RuntimeDebugderives replaced withcore::fmt::Debugwheresp_runtime::RuntimeDebug/frame_support::RuntimeDebugwere removed. - Pallets:
RuntimeDebugNoBoundreplaced withDebugNoBound(e.g. federated-authority, throttle). - Relay (BEEFY):
BeefySignatureHasherremoved;SignedCommitment::verify_signaturescalled with a single inferred authority type parameter.
Partner-chains Cargo.toml / README / changelog are aligned with the same SDK tag where applicable.
Early weight check in midnight pallet pre_dispatch (#1305) (#node)
Add an early block weight check in ValidateUnsigned::pre_dispatch before
expensive ledger validation. Substrate's Bare extrinsic path runs the pallet's
pre_dispatch before the CheckWeight extension, which means transactions that
won't fit in the block still undergo costly ledger validation before being
rejected. The new check mirrors the logic in calculate_consumed_weight and
exits early with ExhaustsResources when the block is full.
PR: #1305
Speed up toolkit syncing (#1263) (#toolkit)
Batch block-number-to-hash RPC calls into a single request instead of one call per block, reducing round trips during sync. Also simplifies several function parameters across the fetcher.
PR: #1263
📦 Node
Git tag: node-1.0.0-rc.4
Docker Images
DockerHub
$ docker pull midnightntwrk/midnight-node:1.0.0-rc.4Added
Add per-SQL-query Prometheus timing for midnight data source queries (#904, PM-22100) (#node)
Midnight-specific data sources (cNight observation, federated authority,
candidates) now record individual Prometheus timing histograms for each
SQL query executed against DBSync. 13 sub-query timers provide per-query
latency visibility at :9615/metrics under the
midnight_data_source_query_time_elapsed metric with query_name labels.
PR: #904
JIRA: https://shielded.atlassian.net/browse/PM-22100
Add `rpc.discover` endpoint with OpenRPC v1.4 API specification (PM-6402, #869) (#client, #node, #rpc, #api)
Registers a standards-compliant rpc.discover JSON-RPC method that returns a complete OpenRPC v1.4 document describing the node's API. Enables client code generation, request validation, and developer discoverability without reading source code.
- 16 custom Midnight methods fully documented with parameter types, return types, error definitions, and descriptions
- 52 standard Substrate methods listed as reference entries
- JSON Schema type d...
node-1.0.0-toolkit-1.0.0-rc.4
Midnight Node 1.0.0-toolkit-1.0.0-rc.4 Release Notes
Release date: 2026-04-27
Git tag: node-1.0.0-toolkit-1.0.0-rc.4
Tree hash: 530e9d26709c0ed163dcc4fb91f586c6774da3f2
Environment: All public networks (dev, qanet, preview, preprod).
Docker Images
docker pull midnightntwrk/midnight-node:1.0.0-rc.4
docker pull midnightntwrk/midnight-node-toolkit:1.0.0-rc.4Summary
Fourth 1.0.0 release candidate for the node and toolkit. This RC ships node-only changes since rc.3: a postgres query-planner improvement for the cNight observation data source, an opt-in symlink-allowance flag for config loading, and a bump of midnight-storage-core to 1.2.0-rc.2. No runtime upgrade is part of this release line — the runtime variant is published separately as node-1.0.0-toolkit-1.0.0-runtime-1.0.0-rc.4.
Audience
-
Node operators — node binary update; no runtime upgrade required for this tag
-
Toolkit users — no toolkit-only changes in this RC (delta vs
rc.3) -
DApp developers — no API changes
What Changed
| Change | Upgrade Type | PR |
|---|---|---|
| Speed up cNight db-sync observation queries via primary-key range bounding | Node upgrade | #1365 |
Add unsafe_allow_symlinks config option for file loading (off by default) |
Node upgrade | #1372 |
Bump midnight-storage-core to 1.2.0-rc.2 |
Node upgrade | #1388 |
New Features
unsafe_allow_symlinks config option (#1372) — Node upgrade
A new opt-in unsafe_allow_symlinks flag permits symlinks when loading configuration files at node boot. Disabled by default to preserve the symlink-rejection hardening landed in #832; operators who need symlinked configuration must set this flag explicitly.
Features Requiring Configuration Updates
- Symlinked config files: operators that previously relied on symlinks pointing to genesis/config files must now set
unsafe_allow_symlinksin their config to retain that behaviour. Without it, node boot will continue to reject symlinks as before.
Improvements
- Faster cNight observation queries: pre-queries coarse
tx/tx_out/ma_tx_outid bounds for the requested block-range window, then constrains the four cNight observation queries (registration, deregistration, asset create, asset spend) and thetx_in-keyed spend/deregistration queries by primary-key range so postgres prunes rows before doing expensive joins (#1365). midnight-storage-coreupgraded to 1.2.0-rc.2, picking up the latest storage-core fixes (#1388, tracking issue #1358).
Fixed Defects
No defect tickets are closed by the delta in this RC. Audit findings and bug fixes resolved in earlier 1.0.0 RCs (rc.1, rc.2/rc.3) carry through unchanged.
Links and References
- Pull requests: #1365, #1372, #1388
- Tracking issues: #1358
- Prior RC notes: rc.1, rc.2, rc.3
- Sibling release with runtime upgrade: node-1.0.0-toolkit-1.0.0-runtime-1.0.0-rc.4
Full Change Details
The following content is preserved verbatim from the auto-generated release body (covering the full set of 1.0.0 PRs to date, not just the rc.3 -> rc.4 delta).
Git tag: node-1.0.0-toolkit-1.0.0-rc.4
Components
- 📦
node-1.0.0 - 🧰
toolkit-1.0.0
Added
Upgrade ledger from 8.0.2 to 8.1.0-rc.1 (#1301) (#node)
Bumps the midnight-ledger dependency from 8.0.2 to 8.1.0-rc.1, picking up
new ledger types and conversion support.
Changed
Add regression tests for nonce/nullifier distinction in zswap serialization (#1128, PM-22025) (#toolkit)
Add unit tests verifying that serialized zswap local state uses the coin
nonce (randomness), not the nullifier (spend identifier), for the nonce
field. Addresses Least Authority Q1 2026 Node DIFF audit Issue E.
PR: #1128
JIRA: https://shielded.atlassian.net/browse/PM-22025
Redact database connection details from error logs (#1067, PM-19904) (#node)
Database connection error messages no longer include the host, port, or database name at error level. Full connection details are available at debug log level for authorized troubleshooting.
PR: #1067
JIRA: https://shielded.atlassian.net/browse/PM-19904
Implements handler for C-to-M brige (#1188) (#node, #runtime)
Updates bridge to emit events.
Updates call by adding McTxHash to each transfer.
Updates handler API: handler is expected to return a value that is attached to events.
Implements the handler in Midnight runtime.
Add validation for `networkId` on node boot to avoid mismatch with genesis state (#1265, PM-22422) (#node, #binary)
Adds validation to ensure the networkId set in the chainspec matches the
networkId used to generate the genesis state.
PR: #1265
Fix for: https://shielded.atlassian.net/browse/PM-22422
Speed up cNight db-sync observation queries (#1365) (#node)
Pre-query coarse tx / tx_out / ma_tx_out id bounds for the requested
block-range window, then constrain the four cNight observation queries
(registration, deregistration, asset create, asset spend) by primary-key
range so postgres can prune rows before doing expensive joins. Extends the
same tx.id bounding to the tx_in-keyed spend/deregistration queries.
PR: #1365
Fix DustWallet spend state propagation (#877, PM-20016) (#toolkit)
Fix DustWallet::speculative_spend to return the updated DustLocalState
alongside spends, and extend mark_spent to commit the state atomically
with nullifier recording. This ensures DustLocalState::spend's
pending_until flags are propagated, preventing utxos() from returning
already-spent outputs in consecutive spend operations.
Addresses Least Authority audit finding Issue AO.
PR: #877
JIRA: https://shielded.atlassian.net/browse/PM-20016
Align node and runtime with polkadot-stable2512-3 SDK (#1262) (#node, #runtime)
Bumps Substrate dependencies to the polkadot-stable2512-3 tag and updates call sites for breaking API changes: Core::execute_block and BlockBuilder::check_inherents now use LazyBlock; SpawnTasksParams requires tracing_execute_block (set to None unless trace RPC is wired); MmrApi v3 gains generate_ancestry_proof while BeefyApi no longer exposes it; pallet-version test mock implements Core with LazyBlock. Partner-chains and lockfiles are updated in line with the same SDK line.
Align node, runtime, relay, and partner-chains with polkadot-stable2603 SDK (#1299) (#node, #runtime, #partner-chains<...
node-0.22.5
Midnight Node 0.22.5
Release date: 2026-04-24
Git tag: node-0.22.5
Tree hash: b335248c509df1a853f98ac36554c2fe93614f62
Environment: All public networks at time of release. For the full compatibility matrix, see the release notes overview.
Docker Images
docker pull midnightntwrk/midnight-node:0.22.5
docker pull midnightntwrk/midnight-node-toolkit:0.22.5High-level summary
A node-only patch release. Adds an optional transaction-pool filter so operators can cap the per-transaction gas cost their node will accept, and lands two cNight observation query optimisations that materially reduce db-sync load. Devnet's bundled chain spec is reset to runtime version 0.22.0 to match mainnet. No runtime upgrade — operators only need to roll the binary.
Audience
These release notes are intended for:
- Node operators (all networks): Recommended upgrade. Pick up the cNight observation perf improvements and the new optional
--max-tx-gas-costfilter. - Node operators (devnet): Required if you rely on the bundled devnet chain spec — it now targets runtime 0.22.0 to align with mainnet.
- DApp developers: No action required.
- Toolkit users: No action required.
What Changed
| Change | Upgrade Type | PR |
|---|---|---|
Transaction pool gas cost filtering (--max-tx-gas-cost, MAX_TX_GAS_COST) |
Node upgrade | #1251 |
Cache multi_asset.id to avoid excessive db-sync joins |
Node upgrade | #934 |
| Speed up cNight db-sync observation queries with id-bound prefilter | Node upgrade | #1365 |
| Reset devnet bundled chain spec to runtime version 0.22.0 to match mainnet | Node upgrade (chainspec) | #1341 |
New Features
Transaction pool gas cost filtering
Description: Adds a new --max-tx-gas-cost CLI argument and MAX_TX_GAS_COST environment variable. Midnight transactions whose estimated gas cost exceeds the configured limit are rejected at the pool gateway level before they enter the node's transaction pool. The CLI argument takes precedence over the environment variable when both are set.
This matters because expensive transactions can otherwise pin a node's resources during validation; allowing operators to cap acceptance gives them a direct lever to protect their node from abuse. Operators interact with it through the node CLI / systemd unit / docker run env. Leaving the flag unset preserves the previous (unbounded) behaviour, so this is non-breaking.
Node upgrade. — #1251
Improvements
- Cache
multi_asset.idlookups for cNight observation queries, eliminating repeatedJOIN multi_assetclauses across registration, deregistration, asset create/spend, and candidate token paths. Materially reduces postgres query complexity on busy db-sync deployments. (#934, PM-21995) - Pre-query coarse
tx/tx_out/ma_tx_outid bounds for the requested block-range window so the four cNight observation queries (registration, deregistration, asset create, asset spend) can be constrained by primary-key range, allowing postgres to prune rows before doing expensive joins. The sametx.idbounding is also extended to thetx_in-keyed spend / deregistration queries. (#1365) - Devnet's bundled chain spec is regenerated to target runtime version 0.22.0, matching mainnet. (#1341)
Known Issues
Initial sync performance
Description: Initial sync times have improved in this release thanks to the cNight db-sync query optimisations (#934, #1365), but initial sync from genesis can still be slower than desired on some operator setups. Further sync performance work is scheduled for a later release.
Issue: #1298
Workaround: None at present. Track the issue for progress; faster bootstrap snapshots may be made available out-of-band.
Links and References
- PRs:
- Testing evidence: TODO: link QA sign-off — not yet provided at the time of writing.
- Known issues board: https://github.com/midnightntwrk/midnight-node/issues?q=is%3Aissue+is%3Aopen+label%3Abug
Full Change Details
Added
Transaction pool gas cost filtering (#1251) (#node)
Added --max-tx-gas-cost CLI arg and MAX_TX_GAS_COST env var to reject midnight
transactions whose estimated gas cost exceeds a configurable limit. This allows node
operators to protect their nodes from expensive transactions at the pool gateway level.
The CLI arg takes precedence over the env var when both are set.
PR: #1251
Changed
Cache multi_asset.id to avoid excessive joins (#934, PM-21995) (#node)
Add an in-memory cache for multi_asset.id lookups, replacing repeated JOIN multi_asset in
db-sync queries with a single cached lookup per (policy, name) pair. This eliminates the
multi_asset join from registration, deregistration, asset create/spend, and candidate token
queries, reducing query complexity and improving observation performance.
PR: #934
JIRA: https://shielded.atlassian.net/browse/PM-21995
Speed up cNight db-sync observation queries (#1365) (#node)
Pre-query coarse tx / tx_out / ma_tx_out id bounds for the requested
block-range window, then constrain the four cNight observation queries
(registration, deregistration, asset create, asset spend) by primary-key
range so postgres can prune rows before doing expensive joins. Extends the
same tx.id bounding to the tx_in-keyed spend/deregistration queries.
PR: #1365
Node 0.22.5 Patch Release Test Report
Smoke tests
Network-agnostic — applies on local, devnet, qanet, preview.
| ID | Check | How |
|---|---|---|
| SMK-01 | Node starts and stays up for ≥ 5 min | ./target/release/midnight-node runs without panics |
| SMK-02 | RPC reachable | curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc":"2.0","method":"sidechain_getStatus","params":[],"id":1}' https://rpc.<env>.midnight.network |
| SMK-03 | Chain producing blocks | Best block height increases over a 6s window |
| SMK-04 | Finality advancing | chain_getFinalizedHead block number increases |
| SMK-05 | Runtime version expected | state_getRuntimeVersion returns the expected specVersion for the network |
| SMK-06 | Sync from genesis | Wipe one node's data and let it sync |
| SMK-07 | Peer connectivity | system_peers returns ≥ 1 peer on a non-isolated network |
| SMK-08 | Submit a trivial signed extrinsic | Accepted into pool, included in a block, status becomes Finalized |
| SMK-09 | No errors in logs | No ERROR / panic lines in logs over the smoke window |
| SMK-10 | Dust generation | Register new wallet and receive tNIGHT, tDust starts generating |
0.22.5 patch — concrete test cases
Three highest-signal-per-minute checks for this patch.
TC-1 · Gas-cost filter rejects an over-limit midnight tx
https://github.com/midnightntwrk/midnight-security/issues/29
TC-2 · cNight observation parity over a fixed block range
Why: both #934 (multi-asset cache) and #1365 (tx-id range bounding) change how observations are computed; the contract is they must change nothing about the result.
- Pick a fixed Cardano block range with known registrations, deregistrations, asset creates, and asset spends.
- Verify Dust generation.
Expected: event sets are equal; sync from genesis is faster (~20-30 bps).
TC-3 · Devnet runtime reports 0.22.0 after upgrade to node 0.22.5
Why: this is the only behavior change of the devnet reset (#1341); cheap to verify, catches a wrong chainspec being shipped.
- Start a fresh devnet node from t...