Skip to content

fix: Guards around setting Next Cardano Position [PM-19901]#763

Merged
gilescope merged 13 commits into
mainfrom
fix/PM-19901-guards-next-cardano-position
Feb 28, 2026
Merged

fix: Guards around setting Next Cardano Position [PM-19901]#763
gilescope merged 13 commits into
mainfrom
fix/PM-19901-guards-next-cardano-position

Conversation

@m2ux

@m2ux m2ux commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Add monotonicity and window-bound guards to NextCardanoPosition updates in process_tokens, preventing cursor regression and flagging unbounded forward jumps. Addresses Least Authority Q4 2025 audit issue R (Medium severity).

🎫 Ticket 📐 Engineering


Motivation

The process_tokens inherent extrinsic unconditionally writes NextCardanoPosition without validating that the new position advances beyond the stored value or stays within configurable bounds. A regressing cursor could replay already-handled Cardano UTXOs (risking duplicate DUST minting). An unbounded forward jump could permanently skip intermediate Cardano events (losing bridged tokens).


Changes

  • Error variantCardanoPositionRegression added to the pallet Error<T> enum
  • Monotonicity guardensure!(next_cardano_position >= prev) using the existing PartialOrd implementation on CardanoPosition, which orders lexicographically on (block_number, tx_index_in_block). Equal positions are allowed since the same Cardano block is routinely referenced across consecutive Midnight blocks.
  • Window-bound warninglog::warn! when the block_number delta exceeds CardanoBlockWindowSize (default: 1000 blocks). This is warn-only (not an assertion) because the inherent data provider does not enforce the window bound, and a fatal guard on a Mandatory dispatch would cause a network halt in legitimate catch-up scenarios.
  • Tests — 11 unit tests covering regression (3), acceptance (4), boundary (2), UTXO interaction (1), and multi-step sequence (1); shared establish_position() helper
  • Change filechanges/changed/guards-next-cardano-position.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

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Feb 24, 2026

Copy link
Copy Markdown
Contributor

kics-logo

KICS version: v2.1.16

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 self-assigned this Feb 24, 2026
m2ux and others added 6 commits February 25, 2026 15:41
Add CardanoPositionRegression and CardanoPositionExcessiveJump to the
pallet Error enum, preparing for monotonicity and window-bound guards
on NextCardanoPosition updates in process_tokens.

Refs: PM-19901
Co-authored-by: Cursor <cursoragent@cursor.com>
Read the previous NextCardanoPosition before updating and enforce:
1. Strict monotonicity via PartialOrd (block_number, tx_index_in_block)
2. Forward bound via CardanoBlockWindowSize (default 1000 blocks)

Guards use ensure! consistent with existing InherentAlreadyExecuted
pattern. On failure, Substrate rolls back all storage mutations and
rejects the block (Mandatory dispatch).

Refs: PM-19901
Co-authored-by: Cursor <cursoragent@cursor.com>
Add 9 tests covering monotonicity and window-bound guards:
- Regression: lower block_number, equal position, same-block lower tx_index
- Acceptance: same-block higher tx_index, within-window jump, normal advance
- Boundaries: default (zero) position, exact window boundary, exceeding window
- All existing tests pass without modification

Refs: PM-19901
Co-authored-by: Cursor <cursoragent@cursor.com>
Document the monotonicity and window-bound guard addition for the
release changelog, addressing audit issue R (PM-19901).

Refs: PM-19901
Co-authored-by: Cursor <cursoragent@cursor.com>
…into fix/PM-19901-guards-next-cardano-position
- Extract establish_position() helper to reduce boilerplate across
  8 guard tests
- Add position_guard_works_with_utxos_present test validating guards
  fire correctly when UTXOs are also present in the dispatch
- Add position_guards_hold_across_multiple_advances test verifying
  guards remain effective after 4 sequential position advances

Refs: PM-19901
Co-authored-by: Cursor <cursoragent@cursor.com>
@m2ux m2ux marked this pull request as ready for review February 25, 2026 16:57
@m2ux m2ux requested a review from a team as a code owner February 25, 2026 16:57
Comment thread pallets/cnight-observation/src/lib.rs Outdated
Comment thread pallets/cnight-observation/src/lib.rs Outdated
@gilescope gilescope enabled auto-merge February 27, 2026 12:17
@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.

…w equal positions, warn-only for window bound

Signed-off-by: Giles Cope <gilescope@gmail.com>
@gilescope gilescope force-pushed the fix/PM-19901-guards-next-cardano-position branch from 60f0a89 to 5ece691 Compare February 27, 2026 22:24
Comment thread docs/security/image-signing.md Outdated
Comment thread docs/security/image-signing.md Outdated
Comment thread docs/security/signing-runbook.md Outdated
Comment thread docs/security/image-signing.md Outdated
Comment thread docs/security/signing-runbook.md Outdated
Comment thread docs/security/signing-runbook.md Outdated
@gilescope gilescope added this pull request to the merge queue Feb 27, 2026
Merged via the queue into main with commit dabc41b Feb 28, 2026
37 checks passed
@gilescope gilescope deleted the fix/PM-19901-guards-next-cardano-position branch February 28, 2026 00:51
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