Skip to content

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

Open
m2ux wants to merge 7 commits intomainfrom
fix/PM-19901-guards-next-cardano-position
Open

fix: Guards around setting Next Cardano Position [PM-19901]#763
m2ux wants to merge 7 commits intomainfrom
fix/PM-19901-guards-next-cardano-position

Conversation

@m2ux
Copy link
Contributor

@m2ux m2ux commented Feb 24, 2026

Summary

Add monotonicity and window-bound guards to NextCardanoPosition updates in process_tokens, preventing cursor regression and 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 variantsCardanoPositionRegression and CardanoPositionExcessiveJump 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)
  • Window-bound guardensure!(block_number delta <= CardanoBlockWindowSize) preventing forward jumps exceeding the configured window (default: 1000 blocks)
  • 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
Copy link
Contributor

kics-logo

KICS version: v2.1.16

Category Results
CRITICAL CRITICAL 0
HIGH HIGH 0
MEDIUM MEDIUM 96
LOW LOW 12
INFO INFO 83
TRACE TRACE 0
TOTAL TOTAL 191
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 9

@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
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.

2 participants