Skip to content

task(node): unify genesis state source for offline subcommands [PM-20203]#768

Merged
gilescope merged 5 commits into
mainfrom
task/PM-20203-offline-subcommands-undeployed-genesis
Mar 2, 2026
Merged

task(node): unify genesis state source for offline subcommands [PM-20203]#768
gilescope merged 5 commits into
mainfrom
task/PM-20203-offline-subcommands-undeployed-genesis

Conversation

@m2ux

@m2ux m2ux commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Offline subcommands now derive genesis state from the chain specification instead of the hardcoded UndeployedNetwork default, fixing a Least Authority audit finding (Issue L) where offline commands failed on deployed networks.

🎫 PM-20203 📐 Engineering


Motivation

Offline subcommands (CheckBlock, ExportBlocks, ExportState, ImportBlocks, Revert, and all benchmark variants) constructed StorageInit using UndeployedNetwork.genesis_state() at function scope, before the chain specification was available. This meant any network other than undeployed would initialize the ledger database with the wrong genesis state, causing silent data corruption or runtime panics.

This was identified as Issue L in the Least Authority security audit.


Changes

Architecture Summary

  • Genesis extraction — Added genesis_state_from_chain_spec and storage_init_from_chain_spec helpers that derive genesis state from config.chain_spec.properties() at the point where the chain specification is available
  • Closure migration — Moved StorageInit construction into each subcommand's async_run/sync_run closure (10 call sites across CheckBlock, ExportBlocks, ExportState, ImportBlocks, Revert, PartnerChains, and 4 benchmark variants)
  • Consistency utility — Added verify_genesis_consistency for future blake2_256-based genesis validation (currently unused, annotated #[allow(dead_code)])
  • Cleanup — Removed hardcoded UndeployedNetwork.genesis_state() call and its unused MidnightNetwork import
  • Tests — 6 unit tests covering genesis state decoding (valid hex, missing key, non-string value, invalid hex) and consistency verification (matching/mismatching hashes)
  • Changelog — Added changes/changed/offline-subcommands-undeployed-genesis.md

📌 Submission Checklist

  • Changes are backward-compatible (or flagged if breaking)
  • Pull request description explains why the change is needed
  • Self-reviewed the diff
  • I have included a change file, or skipped for this reason: included
  • If the changes introduce a new feature, I have bumped the node minor version
  • Update documentation (if relevant)
  • No new todos introduced

🔱 Fork Strategy

  • Node Runtime Update
  • Node Client Update
  • Other
  • N/A

🗹 TODO before merging

  • Ready for review

@m2ux m2ux self-assigned this Feb 24, 2026
@github-actions

github-actions Bot commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

kics-logo

KICS version: v2.1.19

Category Results
CRITICAL CRITICAL 0
HIGH HIGH 0
MEDIUM MEDIUM 99
LOW LOW 12
INFO INFO 83
TRACE TRACE 0
TOTAL TOTAL 194
Metric Values
Files scanned placeholder 31
Files parsed placeholder 31
Files failed to scan placeholder 0
Total executed queries placeholder 73
Queries failed to execute placeholder 0
Execution time placeholder 10

@m2ux m2ux marked this pull request as ready for review February 28, 2026 08:16
@m2ux m2ux requested a review from a team as a code owner February 28, 2026 08:16
m2ux added 3 commits February 28, 2026 11:36
All offline subcommands (check-block, export-blocks, export-state,
import-blocks, revert, partner-chains, and benchmark sub-arms) now
derive StorageInit.genesis_state from chain_spec.properties() via
genesis_state_from_chain_spec(), instead of hardcoding
UndeployedNetwork.genesis_state(). This ensures subcommands use the
correct genesis state for the active chain specification.

Changes:
- Add genesis_state_from_properties() and thin wrapper
  genesis_state_from_chain_spec() to extract hex-encoded genesis
  state from chain spec properties with descriptive error handling
- Add verify_genesis_consistency() for blake2_256 hash comparison
  between chain spec and compiled-in genesis
- Move StorageInit creation from function scope into 7 match arm
  closures (10 call sites) where config.chain_spec is available
- Remove unused MidnightNetwork trait import
- Add 6 unit tests covering valid extraction, missing key, non-string
  value, invalid hex, hash match, and hash mismatch

Made-with: Cursor
Add storage_init_from_chain_spec() to eliminate 10 repeated
StorageInit struct literals across subcommand match arms.
Add doc comments to all new functions.

Made-with: Cursor
Add #[allow(dead_code)] to verify_genesis_consistency (not yet
wired into a runtime call site). Add change file for CI.
@m2ux m2ux force-pushed the task/PM-20203-offline-subcommands-undeployed-genesis branch from 32e1d29 to 1ebefcd Compare February 28, 2026 11:36
Comment thread node/src/command.rs Outdated
Comment thread node/src/command.rs Outdated
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
@gilescope gilescope enabled auto-merge March 2, 2026 08:43

@gilescope gilescope left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

genesis_state_from_properties lacks MAX_GENESIS_STATE_BYTES size guard but that's the only nit.

@gilescope gilescope added this pull request to the merge queue Mar 2, 2026
Merged via the queue into main with commit 7a22b4c Mar 2, 2026
36 checks passed
@gilescope gilescope deleted the task/PM-20203-offline-subcommands-undeployed-genesis branch March 2, 2026 10:01
gilescope pushed a commit that referenced this pull request Apr 8, 2026
m2ux added a commit that referenced this pull request Apr 23, 2026
Signed-off-by: Mike Clay <mike.clay@shielded.io>
m2ux added a commit that referenced this pull request Apr 23, 2026
Signed-off-by: Mike Clay <mike.clay@shielded.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants