Skip to content

fix: split system transaction executor into per-pallet allow-listed traits - #2080

Open
ozgb wants to merge 2 commits into
mainfrom
ozgb-system-tx-executor-hardening
Open

fix: split system transaction executor into per-pallet allow-listed traits#2080
ozgb wants to merge 2 commits into
mainfrom
ozgb-system-tx-executor-hardening

Conversation

@ozgb

@ozgb ozgb commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Overview

MidnightSystemTransactionExecutor::execute_system_transaction let a caller apply
any serialized SystemTransaction variant to the ledger, with no restriction.
The root-origin send_mn_system_transaction extrinsic already gated on an
allow-list (only OverwriteParameters passes), but the trait path used by
pallet-cnight-observation and pallet-c2m-bridge bypassed that gate entirely.
Both callers only ever construct a fixed set of transaction kinds today, so this
was latent rather than exploited, but nothing at the trait boundary stopped a
future bug or compromised caller from submitting any other ledger-recognized
variant (e.g. treasury payouts, reserve distribution) through either pallet.

This replaces the single shared trait with per-caller traits, each restricted at
the trait boundary to the system transaction variants that pallet is actually
allowed to construct:

  • MidnightSystemTransactionCNightExecutor (cnight-observation): only
    CNightGeneratesDustUpdate.
  • MidnightSystemTransactionBridgeExecutor (c2m-bridge): only
    UnlockToTreasury, DistributeReserve, and
    DistributeNight(ClaimKind::CardanoBridge, _).
  • The governance extrinsic path keeps its existing allow-list
    (OverwriteParameters only).

Each is backed by a dedicated ledger host function
(apply_governance_system_transaction, apply_cnight_system_transaction,
apply_bridge_system_transaction) that deserializes the transaction once and
checks its allow-list before applying, rather than a separate classifier call
ahead of apply_system_transaction (which would deserialize and cross the
WASM host-function boundary twice per call). The previous
apply_system_transaction and is_governance_allowed_system_tx host functions
are kept in place, unused by new pallet code, since host functions are part of
the node<->runtime ABI and removing one an already-published runtime WASM can
call would break replay of historical blocks.

runtime/src/lib.rs needs no changes: pallet-midnight-system now implements
both new traits, and the runtime's existing
type MidnightSystemTransactionExecutor = MidnightSystem; wiring for both
pallets keeps compiling as-is.

🗹 TODO before merging

  • Ready

📌 Submission Checklist

  • All commits are signed off (git commit -s) for the DCO
  • 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:
  • If the changes introduce a new feature, I have bumped the node minor version
  • Update documentation (if relevant)
  • Updated AGENTS.md if build commands, architecture, or workflows changed
  • No new todos introduced

🧪 Testing Evidence

  • cargo check -p pallet-midnight-system -p pallet-cnight-observation -p pallet-c2m-bridge -p midnight-primitives -p midnight-node-runtime -p midnight-node-ledger

  • cargo test -p pallet-midnight-system -p pallet-cnight-observation -p pallet-c2m-bridge — all pass, including 5 new unit tests in pallet-midnight-system that construct real system transactions against a real ledger (via init_storage_paritydb_separate) and assert each executor's allow-list accepts/rejects the right variants.

  • cargo test -p midnight-node-ledger (error-code uniqueness tests, to confirm the new SystemTransactionError::NotAllowedForCaller variant doesn't collide with an existing or retired wire code).

  • cargo clippy / cargo fmt on all touched crates.

  • Full workspace cargo check --all-targets — confirms runtime/src/lib.rs compiles unmodified.

  • Additional tests are provided (if possible)

🔱 Fork Strategy

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

Links

…raits

Replace the single MidnightSystemTransactionExecutor trait with
MidnightSystemTransactionCNightExecutor and
MidnightSystemTransactionBridgeExecutor, so pallet-cnight-observation and
pallet-c2m-bridge can each only submit the SystemTransaction variants they
actually construct, instead of being able to pass through any variant the
ledger recognizes.

Each new trait is backed by a dedicated ledger host function
(apply_cnight_system_transaction / apply_bridge_system_transaction) that
deserializes once and checks its allow-list before applying, rather than a
separate classifier call ahead of apply_system_transaction. The governance
extrinsic path is rebuilt the same way onto a new
apply_governance_system_transaction host function. The previous
apply_system_transaction and is_governance_allowed_system_tx host functions
are kept in place, unused by new code, since they remain part of the
node<->runtime ABI for already-published runtime WASM and historical block
replay.

Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>
@ozgb
ozgb requested a review from a team as a code owner September 1, 2026 14:24
@ozgb ozgb added skip-changes-check-issue bot:ai-assisted Authored or substantially edited by an AI agent labels Sep 1, 2026
Assisted-by: Claude:claude-sonnet-5
Signed-off-by: Oscar Bailey <79094698+ozgb@users.noreply.github.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 800158528e

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +80 to +83
#[codec(index = 15)]
SystemTransactionNotAllowedForCNight,
#[codec(index = 16)]
SystemTransactionNotAllowedForBridge,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Rebuild the checked-in runtime metadata

Adding these pallet error variants changes the runtime metadata, but both metadata/static/midnight_metadata.scale and metadata/static/midnight_metadata_2.1.0.scale remain unchanged. Since metadata/src/lib.rs:17 generates midnight_metadata_latest from the latter file, consumers of the metadata crate cannot identify or decode the new module error indices 15 and 16 when either allow-list rejects a transaction; regenerate both current metadata artifacts with the repository's rebuild target.

AGENTS.md reference: AGENTS.md:L146-L149

Useful? React with 👍 / 👎.

@datadog-official

datadog-official Bot commented Sep 1, 2026

Copy link
Copy Markdown

Pipelines

⚠️ Warnings

Your PR has failed checks. Please review the issues below and take necessary action before merging.

🚦 5 Pipeline jobs failed

CI + E2E | Local Environment Tests

View in Datadog · View in GitHub Actions

Panic in c2m_bridge::bridge_transfer_cnight_to_midnight_address at tests/e2e/tests/c2m_bridge.rs:188:10: Failed to read ledger parameters for bridge-fee computation: IncompatibleCodegen

CI + E2E | Metadata Check

View in Datadog · View in GitHub Actions

Binary files image_metadata.scale and repo_metadata.scale differ. Error occurred in Earthfile: line 1113

CI + E2E | Toolkit Contracts E2E

View in Datadog · View in GitHub Actions

Runtime API address incompatible with the live chain. Recipe 'toolkit-contracts-e2e' failed on line 31 with exit code 1.

View all 5 failed jobs.

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 908c383 | Docs | View more details | Give us feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:ai-assisted Authored or substantially edited by an AI agent skip-changes-check-issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant