Skip to content

task(nto): PM-19778 CNGD extrinsic dispatch class#798

Merged
gilescope merged 16 commits into
mainfrom
task/PM-19778-cngd-extrinsic-dispatch-class
Mar 2, 2026
Merged

task(nto): PM-19778 CNGD extrinsic dispatch class#798
gilescope merged 16 commits into
mainfrom
task/PM-19778-cngd-extrinsic-dispatch-class

Conversation

@m2ux

@m2ux m2ux commented Feb 26, 2026

Copy link
Copy Markdown
Contributor

Summary

Add benchmarked weight infrastructure, UTXO count validation, and actual-weight correction to the process_tokens inherent extrinsic, enabling accurate block weight accounting for the cnight-observation pallet.

🎫 Ticket 📐 Engineering


Motivation

The process_tokens inherent extrinsic previously declared zero weight with DispatchClass::Mandatory, bypassing block weight accounting entirely. Least Authority audit finding Issue H flagged this: without benchmarked weights, the runtime cannot accurately track block capacity consumed by UTXO processing, and there is no upper bound on UTXO batch size.

This implementation adds the FRAME benchmarking infrastructure needed to derive accurate weights, a runtime safety guard on input size, and actual-weight correction via PostDispatchInfo so that block capacity reflects the true processing cost.


Changes

  • WeightInfo trait (weights.rs) — New WeightInfo trait with fn process_tokens(n: u32) -> Weight, placeholder SubstrateWeight<T> implementation with conservative estimates, and zero-weight () impl for tests
  • Weight annotation (lib.rs) — process_tokens weight changed from (0, DispatchClass::Mandatory) to (T::WeightInfo::process_tokens(MAX_UTXO_COUNT), DispatchClass::Mandatory) declaring worst-case weight up front
  • UTXO count guard (lib.rs) — New TooManyUtxos error variant; ensure! guard rejects batches exceeding CardanoTxCapacityPerBlock * UTXO_PER_TX_OVERESTIMATE (default 200 × 64 = 12,800)
  • Actual-weight correction (lib.rs) — Return type changed from DispatchResult to DispatchResultWithPostInfo; returns PostDispatchInfo { actual_weight: Some(T::WeightInfo::process_tokens(utxo_count)), pays_fee: Pays::No }
  • Pallet constants (lib.rs) — UTXO_PER_TX_OVERESTIMATE = 64, MAX_UTXO_COUNT = 12,800
  • Benchmark (benchmarking.rs) — FRAME v2 parameterized benchmark using Registration UTXOs with Linear<0, MAX_UTXO_COUNT>
  • Config updatestype WeightInfo: WeightInfo added to pallet Config trait; wired as () in mock runtimes and runtime
  • Runtime registration — Pallet registered in define_benchmarks! macro
  • Validation tests (validation_tests.rs) — 3 tests using lightweight mock: UTXO guard rejection (TC-01), exact boundary acceptance (TC-02), PostDispatchInfo actual-weight verification (TC-06b)

📌 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
  • Run benchmarks on target hardware to generate production weights (post-merge deployment step)

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

github-actions Bot commented Feb 26, 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 11

@m2ux

m2ux commented Feb 27, 2026

Copy link
Copy Markdown
Contributor Author

/bot rebuild-metadata

@github-actions

Copy link
Copy Markdown
Contributor

✅ Metadata rebuild complete! Changes have been committed.

m2ux and others added 11 commits February 28, 2026 11:39
…me-benchmarks feature

Add frame-benchmarking as an optional dependency and configure the
runtime-benchmarks feature flag to enable benchmark compilation for
the cnight-observation pallet. Follows the pattern established by
pallet-federated-authority-observation.

Ticket: PM-19778
Co-authored-by: Cursor <cursoragent@cursor.com>
Define the WeightInfo trait with fn process_tokens(n: u32) -> Weight
for the cnight-observation pallet. Includes SubstrateWeight<T>
placeholder impl with conservative estimates (to be replaced by
benchmark output) and impl WeightInfo for () returning zero weight
for tests and mocks.

Refs: PM-19778
- Add pallet constants UTXO_PER_TX_OVERESTIMATE (64) and
  MAX_UTXO_COUNT (12,800) matching mainchain follower buffer bounds
- Add WeightInfo associated type to Config trait
- Add TooManyUtxos error variant with dynamic UTXO count guard
- Change weight annotation from (0, Mandatory) to
  (T::WeightInfo::process_tokens(MAX_UTXO_COUNT), Mandatory)
- Change return type to DispatchResultWithPostInfo with actual-weight
  correction via PostDispatchInfo { pays_fee: Pays::No }
- Wire weights and benchmarking modules

Refs: PM-19778
Add `type WeightInfo = ();` to both mock runtime Config impls
(mock.rs and mock_with_capture.rs), satisfying the new associated
type added to the pallet's Config trait.

Refs: PM-19778
…tration

Add `type WeightInfo = ();` to the runtime's pallet_cnight_observation
Config impl and register the pallet in `define_benchmarks!` so the
benchmark CLI discovers its extrinsics.

Refs: PM-19778
FRAME v2 benchmark for process_tokens using Registration UTXOs as
the benchmark input type. Registration handlers exercise the
storage-dominant path (2R + 1W + events per UTXO) without requiring
LedgerApi, making them suitable for deterministic benchmarking.

- Linear<0, MAX_UTXO_COUNT> parameter (0..12,800 UTXOs)
- RawOrigin::None for inherent dispatch
- Synthetic UTXOs with unique CardanoRewardAddressBytes
- impl_benchmark_test_suite with mock_with_capture runtime

Refs: PM-19778
- Mark shell command in weights.rs doc comment as ```text to prevent
  doctest from parsing it as Rust code
- Remove impl_benchmark_test_suite! from benchmarking.rs — the
  external mock crate cannot propagate runtime-benchmarks feature
  without a circular dependency; benchmark smoke tests run via the
  runtime crate instead

Refs: PM-19778
…ion tests

Add validation_tests.rs covering PM-19778 code review findings M1/M2:
- TC-01: TooManyUtxos rejection when UTXO count exceeds capacity bound
- TC-02: Exact boundary acceptance at capacity limit
- TC-06b: PostDispatchInfo returns actual_weight and Pays::No
Use capacity=2 instead of 1 to avoid `1u32 * UTXO_PER_TX_OVERESTIMATE`
which clippy flags as identity_op (no-op multiplication by 1).

Made-with: Cursor
@m2ux m2ux force-pushed the task/PM-19778-cngd-extrinsic-dispatch-class branch from 6806d29 to 0cf6397 Compare February 28, 2026 11:40
@m2ux

m2ux commented Feb 28, 2026

Copy link
Copy Markdown
Contributor Author

/bot rebuild-metadata

@m2ux m2ux marked this pull request as ready for review February 28, 2026 11:51
@m2ux m2ux requested a review from a team as a code owner February 28, 2026 11:51
@github-actions

Copy link
Copy Markdown
Contributor

✅ Metadata rebuild complete! Changes have been committed.

Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
@gilescope gilescope enabled auto-merge February 28, 2026 19:05
Signed-off-by: Giles Cope <gilescope@gmail.com>
Signed-off-by: Giles Cope <gilescope@gmail.com>
@gilescope gilescope added this pull request to the merge queue Mar 2, 2026
Merged via the queue into main with commit b6f0c27 Mar 2, 2026
36 checks passed
@gilescope gilescope deleted the task/PM-19778-cngd-extrinsic-dispatch-class branch March 2, 2026 10:09
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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants