diff --git a/CHANGELOG.md b/CHANGELOG.md index 3907102..b7627e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Various optimisations in `dict` and `assets` methods. +- ⚠️ BREAKING-CHANGE ⚠️ [`cardano/transaction/script_purpose.{compare}`](https://aiken-lang.github.io/stdlib/cardano/transaction/script_purpose.html#compare) now follows the ledger's ordering of script purposes, which is the ordering of the `redeemers` list in the script context: `Spend` < `Mint` < `Publish` < `Withdraw` < `Vote` < `Propose`. It previously followed the constructor order of `ScriptPurpose` (`Mint` first, `Withdraw` before `Publish`), which does not match the on-chain ordering. See [#125](https://github.com/aiken-lang/stdlib/issues/125). + ## v3.0.0 - 2025-10-21 ### Added diff --git a/lib/cardano/transaction.ak b/lib/cardano/transaction.ak index 12f8ec8..0e7d2b3 100644 --- a/lib/cardano/transaction.ak +++ b/lib/cardano/transaction.ak @@ -65,7 +65,7 @@ pub type Transaction { validity_range: ValidityRange, extra_signatories: List, /// > [!IMPORTANT] - /// > Redeemers are ordered by ascending [ScriptPurpose](./transaction.html#ScriptPurpose). + /// > Redeemers are ordered by ascending [ScriptPurpose](./transaction.html#ScriptPurpose), following the internal ledger's ordering of script purposes: [`Spend`](./transaction.html#ScriptPurpose) < [`Mint`](./transaction.html#ScriptPurpose) < [`Publish`](./transaction.html#ScriptPurpose) < [`Withdraw`](./transaction.html#ScriptPurpose) < [`Vote`](./transaction.html#ScriptPurpose) < [`Propose`](./transaction.html#ScriptPurpose). Note that this ordering **differs from the constructor order** of [ScriptPurpose](./transaction.html#ScriptPurpose); see [script_purpose.compare](./transaction/script_purpose.html#compare). redeemers: Pairs, datums: Dict, id: TransactionId, diff --git a/lib/cardano/transaction/script_purpose.ak b/lib/cardano/transaction/script_purpose.ak index 13c7783..9b98ca8 100644 --- a/lib/cardano/transaction/script_purpose.ak +++ b/lib/cardano/transaction/script_purpose.ak @@ -10,32 +10,42 @@ use cardano/transaction.{ } use cardano/transaction/output_reference +/// Compare two script purposes, using the same ordering as the one used by +/// the ledger when constructing the +/// [redeemers](./transaction.html#Transaction) list: +/// +/// [`Spend`](./transaction.html#ScriptPurpose) < [`Mint`](./transaction.html#ScriptPurpose) < [`Publish`](./transaction.html#ScriptPurpose) < [`Withdraw`](./transaction.html#ScriptPurpose) < [`Vote`](./transaction.html#ScriptPurpose) < [`Propose`](./transaction.html#ScriptPurpose) +/// +/// Note that this ordering follows the internal ledger types, and thus +/// differs from the constructor order of +/// [ScriptPurpose](./transaction.html#ScriptPurpose): `Spend` comes before +/// `Mint`, and `Publish` comes before `Withdraw`. pub fn compare(left: ScriptPurpose, right: ScriptPurpose) -> Ordering { when left is { - Mint(left) -> + Spend(left) -> when right is { - Mint(right) -> bytearray.compare(left, right) + Spend(right) -> output_reference.compare(left, right) _ -> Less } - Spend(left) -> + Mint(left) -> when right is { - Spend(right) -> output_reference.compare(left, right) - Mint(_) -> Greater + Mint(right) -> bytearray.compare(left, right) + Spend(_) -> Greater _ -> Less } - Withdraw(left) -> + Publish { at: left, .. } -> when right is { - Withdraw(right) -> credential.compare(left, right) + Publish { at: right, .. } -> int.compare(left, right) Spend(_) | Mint(_) -> Greater _ -> Less } - Publish { at: left, .. } -> + Withdraw(left) -> when right is { - Publish { at: right, .. } -> int.compare(left, right) - Spend(_) | Mint(_) | Withdraw(_) -> Greater + Withdraw(right) -> credential.compare(left, right) + Spend(_) | Mint(_) | Publish { .. } -> Greater _ -> Less } @@ -77,7 +87,7 @@ test compare_matrix() { (compare(mint0, mint0) == Equal)?, (compare(mint0, mint1) == Less)?, (compare(mint1, mint0) == Greater)?, - (compare(mint0, spend0) == Less)?, + (compare(mint0, spend0) == Greater)?, (compare(mint0, withdraw0) == Less)?, (compare(mint0, publish0) == Less)?, (compare(mint0, vote0) == Less)?, @@ -85,7 +95,7 @@ test compare_matrix() { (compare(spend0, spend0) == Equal)?, (compare(spend0, spend1) == Less)?, (compare(spend1, spend0) == Greater)?, - (compare(spend0, mint0) == Greater)?, + (compare(spend0, mint0) == Less)?, (compare(spend0, withdraw0) == Less)?, (compare(spend0, publish0) == Less)?, (compare(spend0, vote0) == Less)?, @@ -95,7 +105,7 @@ test compare_matrix() { (compare(withdraw1, withdraw0) == Greater)?, (compare(withdraw0, mint0) == Greater)?, (compare(withdraw0, spend0) == Greater)?, - (compare(withdraw0, publish0) == Less)?, + (compare(withdraw0, publish0) == Greater)?, (compare(withdraw0, vote0) == Less)?, (compare(withdraw0, propose0) == Less)?, (compare(publish0, publish0) == Equal)?, @@ -103,7 +113,7 @@ test compare_matrix() { (compare(publish1, publish0) == Greater)?, (compare(publish0, mint0) == Greater)?, (compare(publish0, spend0) == Greater)?, - (compare(publish0, withdraw0) == Greater)?, + (compare(publish0, withdraw0) == Less)?, (compare(publish0, vote0) == Less)?, (compare(publish0, propose0) == Less)?, (compare(vote0, vote0) == Equal)?,