Repository navigation
fix(evolution): order withdrawal and voter redeemer indices type-first to match ledger Ord (#404) - #643
fix(evolution): order withdrawal and voter redeemer indices type-first to match ledger Ord (#404)#643Kshot3000 wants to merge 1 commit into
Conversation
…t to match ledger Ord (IntersectMBO#404)
56c5122 to
c34c2b6
Compare
|
Rebased onto current main (c34c2b6) — this PR had gone conflicting after the redeemer-indexing refactor landed upstream (#656/#658 series). The refactor moved the assembly loop's inline index lookups into a shared
Re-verified on the rebased branch: the three behavioural tests fail on current main run one at a time (the control passes both ways), and the full suite is 1747 passed / 75 skipped / 0 failed (main baseline 1743 + the 4 new tests), with Independent builder — not affiliated with the Cardano Foundation, IOG or Intersect. @Kshot9000 (https://x.com/kshot9000) · ADA donations: addr1q8hnl6vl5a6k3rw3n5g3jtte696zcl76kfatzv7gpswa9r0dj7fma6klq55y4ffm7tf0em09udnyhuk4ah92pl5x9jpqjae44v |
Summary
Fixes #404. The builder assigned reward and vote redeemer indices in hash-only order, but the ledger resolves a redeemer pointer by the key's position in a map ordered by
Ord— for credentials that is type-first (ScriptHashObjsorts beforeKeyHashObj), then by hash. When a transaction mixed a script credential and a key credential whose hashes interleaved against the type order, the SDK placed the redeemer at a different index than the ledger resolves, and the transaction was rejected (MissingRedeemers/ExtraRedeemers).What was wrong
txBuilder.ts(assembly) sorted withdrawals by credential hash only (localeCompareon the hash hex), discarding the credential type.Evaluation.tsmirrored the same hash-only withdrawal sort, so assembly and evaluation agreed with each other but not with the ledger.voterToKeygave key-hash and script-hash DRep/committee voters the same key prefix, so sorting voter keys again ordered purely by hash and discarded the type.Fix
compareCredentialsinTransactionBuilder.ts: rank script-hash credentials before key-hash credentials, then compare hash bytes (explicit</>on the hex, nolocaleCompare).Evaluation.tsand in the sharedmakeRedeemerIndexerhelper intxBuilder.ts(assembly and the fee estimate both resolve redeemer indices through it since the upstream refactor), so every path assigns the same, ledger-correct index. The vote side needs no indexer change: the helper already sortsvoterToKeykeys lexicographically, and the ranked key prefixes make that sort reproduceOrd Voter.voterToKeynow encodes the credential'sOrdrank in the key —cc:0:/drep:0:for script-hash credentials,cc:1:/drep:1:for key-hash credentials,pool:unchanged — so the existing lexicographic sort of voter keys reproducesOrd Voter(voter kind first, then script-before-key, then hash). All voter keys are produced throughvoterToKey, so the format change is internal and consistent across Vote, txBuilder and Evaluation.Note the direction trap from the issue: this is deliberately not serialized-byte order — a reward account's header byte puts key-stake (
0xE_) before script-stake (0xF_), the opposite ofOrd Credential— so the sort is by explicit type rank, never by address/credential bytes.Tests
New
test/TxBuilder.RedeemerIndexOrd.test.ts, built through the real txBuilder with a stub (echo) evaluator, using a Plutus V3 script whose hash (a24924…) interleaves against a0x11…key hash:Full suite: 1747 passed / 75 skipped / 0 failed (main baseline 1743 + 4 new),
tsc --noEmitand eslint clean, prettier parity with main exact on all touched files. Patch changeset added.Independent builder — not affiliated with the Cardano Foundation, IOG or Intersect.
@Kshot9000 (https://x.com/kshot9000) · ADA donations: addr1q8hnl6vl5a6k3rw3n5g3jtte696zcl76kfatzv7gpswa9r0dj7fma6klq55y4ffm7tf0em09udnyhuk4ah92pl5x9jpqjae44v
cc @cardano-foundation @IntersectMBO