IntersectMBO / IntersectMBO/evolution-sdk

txBuilder: order withdrawal and voter redeemer indices type-first to match ledger Ord

Ouverte
#404 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
bug external-review
Langage dominant
TypeScript
Étoiles
22
Forks
30
Merge moyen
13 h
PR mergées (30 j)
14

Description

## Summary
For Rewarding (withdrawals) and Voting (votes), the ledger resolves a script's redeemer pointer by the key's position in a Map ordered by Ord (Conway TxBody indexOf -> Map.lookupIndex). Ord Credential is type-first: ScriptHashObj sorts before KeyHashObj, then by hash. The SDK instead sorts withdrawals by credential hash only, and voterToKey gives key-hash and script-hash DRep/committee voters the same prefix, so the type is discarded. When a transaction mixes a key-hash and a script-hash credential whose hashes interleave against the type order, the SDK places the redeemer at a different index than the ledger resolves, and the transaction is rejected (MissingRedeemers / ExtraRedeemers). It is fail closed: no mis-validation or fund risk, but a legitimate mixed-credential withdrawal or governance vote cannot be built.

## Affected
packages/evolution/src/sdk/builders/internal/txBuilder.ts withdrawal sort (L441-445) and voter index assignment (L467-482)
packages/evolution/src/sdk/builders/phases/Evaluation.ts mirror withdrawal sort (L421-425)
packages/evolution/src/sdk/builders/TransactionBuilder.ts voterToKey (L736-748)
ground truth: cardano-ledger Ord Credential (ScriptHashObj < KeyHashObj), Conway TxBody indexOf over the withdrawals/voting-procedures Map

## Fix
Order withdrawals (and voters) by the ledger Ord, type-first then hash.
- withdrawals: rank ScriptHash credential before KeyHash credential, then compare hash bytes.
- voterToKey: give key-hash and script-hash voters distinct prefixes (e.g. drep-script / drep-key, cc-script / cc-key) and sort type-first then hash so the order reproduces Ord Voter.
- apply the identical ordering in Evaluation.ts so assembly and evaluation agree.
- compare hash by byte/codepoint, not localeCompare.

Direction trap: the correct order is ScriptHash before KeyHash (Ord Credential constructor order). This is the opposite of the reward-address header byte order (key-stake 0xE_ < script-stake 0xF_), so do NOT sort by serialized address/credential bytes. Sort by explicit type rank.

## Regression test
- given: one script-credential withdrawal carrying a redeemer (hash H_s) and one key-credential withdrawal (hash H_k) with H_k < H_s, built through the real txBuilder
- before fix: the reward redeemer is emitted at index 1
- after fix: it is emitted at index 0 (script credential first, matching Ord Credential)
- add the symmetric case for mixed DRep/committee voters

Must FAIL on main today and PASS after the fix.

## Reference
Report 15

Guide de contribution

Ouvrir le guide de contribution

Piste de recherche

Lisez le tri des withdrawals dans packages/evolution/src/sdk/builders/internal/txBuilder.ts et packages/evolution/src/sdk/builders/phases/Evaluation.ts, puis examinez l’attribution des index de voters dans packages/evolution/src/sdk/builders/TransactionBuilder.ts. Ajoutez les cas de régression indiqués pour les withdrawals avec des credentials mixtes et pour les DRep/committee voters via le véritable txBuilder. Le travail est terminé lorsqu’un tri explicite d’abord par type, puis octet par octet, produit les index de redeemer correspondant au ledger dans assembly et evaluation.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
blockchain
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
Calme
Clarté
Clairement spécifiée
Accessibilité débutants
55/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.