IntersectMBO / IntersectMBO/evolution-sdk

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

Abierto
#404 0 comentarios 0 reacciones 0 asignados Ver en GitHub
bug external-review
Lenguaje dominante
TypeScript
Estrellas
22
Forks
30
Merge medio
5 h 29 min
PR fusionados (30 d)
12

Descripción

## 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

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Read the withdrawal sort in packages/evolution/src/sdk/builders/internal/txBuilder.ts and packages/evolution/src/sdk/builders/phases/Evaluation.ts, then inspect voter index assignment in packages/evolution/src/sdk/builders/TransactionBuilder.ts. Add the stated mixed-credential withdrawal and DRep/committee voter regression cases through the real txBuilder. Done means explicit type-first, bytewise ordering produces the ledger-matching redeemer indices in both assembly and evaluation.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
typescript
Área
blockchain
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bien especificado
Aptitud para principiantes
55/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.