IntersectMBO / IntersectMBO/evolution-sdk
Signing: signTx hashes a re-encoded body when given a Transaction object
Dieses Issue hat noch niemand übernommen.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 22
- Forks
- 30
- Ø Merge
- 13 Std.
- Gemergte PRs (30 T.)
- 14
Beschreibung
Summary
signTx accepts Transaction | string and computes the message to sign two different ways. Given a
hex string it hashes the original body bytes; given a decoded Transaction it calls
TransactionBody.toHash(tx.body), which re-encodes the body canonically. Since #236, submission
replays the original bytes through the formatCache, so for a body decoded from a valid but
non-canonical encoding (indefinite-length arrays, non-minimal integers) the object path signs a
transaction id the node will not compute, and the witness does not validate. The cause is the lookup:
formatCache is keyed on Transaction (Transaction.ts L130), so passing tx.body cannot find the
cached format, while tx itself is in scope on the line above.
Affected
packages/evolution/src/sdk/client/internal/Signing.ts
- signTx message selection (L328-331): string branch hashes original bytes via
toHashFromBytes;
object branch re-encodes viaTransactionBody.toHash(tx.body)(L331), whiletxis in scope (L323)
packages/evolution/src/Transaction.ts
- formatCache (L130) keyed on
Transaction; written only byfromCBORBytes(L141) and
fromCBORHex(L150), transferred throughaddVKeyWitnesses(L363-364) - contrast: the object call sites in sdk/builders/SignBuilderImpl.ts (L119, L281) are fed only by
sdk/builders/internal/build.ts (L41) with freshly built transactions, which carry no cached format,
so the two paths agree there
Fix
Make the object overload hash the bytes that will actually be submitted, so both overloads agree:
: TransactionBody.toHashFromBytes(Transaction.extractBodyBytes(Transaction.toCBORBytes(tx)))
One caveat before applying it. Hashing original bytes means signing entries the decoded body dropped,
including duplicate CBOR map keys, which decodeMapAt currently accepts with last-writer-wins. That
exposure exists on the string path today and this change extends it to both. Pair it with rejecting
duplicate keys on decode, the same fail-closed approach taken for Data in #397, or the fix trades one
inconsistency for a wider one.
Regression test
- given: a transaction decoded from a body with a non-minimal fee (
1a0000000awhere canonical is0a)
that round-trips exactly throughTransaction.toCBORBytes - before fix: the object overload signs
233fb742...while the node txid over the submitted bytes is
1d043700...; the string overload signs1d043700... - after fix: object overload, string overload, and node txid all agree
- control: a fully canonical body must match on all three before and after
Must FAIL on main today and PASS after the fix.
Reference
Residual inconsistency after #236 made submission byte-preserving while the object signing path kept
canonicalizing. Adjacent to #235, the same class in redeemer PlutusData, and to #480, the same
re-encode-instead-of-preserve pattern in COSE.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne in packages/evolution/src/sdk/client/internal/Signing.ts bei signTx in den Zeilen 323-331 und untersuche anschließend die formatCache-Behandlung in packages/evolution/src/Transaction.ts in den Zeilen 130-150 und 363-364. Füge den beschriebenen Regressionstest mit einer nicht-minimalen Gebührenkodierung sowie die kanonische Kontrollvariante hinzu und überprüfe, dass Objektsignierung, String-Signierung und die Transaktions-ID des Nodes nach der Behebung übereinstimmen.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- typescript
- Bereich
- blockchain, cryptography
- Issue-Typ
- Bug
- Schwierigkeit
- 3/5
- Geschätzter Aufwand
- 1-2 Tage
- Aktivitätsstatus
- Aktiv
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 76/100