IntersectMBO / IntersectMBO/evolution-sdk

Signing: signTx hashes a re-encoded body when given a Transaction object

Offen
#531 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

bug external-review
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 via TransactionBody.toHash(tx.body) (L331), while tx is in scope (L323)

packages/evolution/src/Transaction.ts

  • formatCache (L130) keyed on Transaction; written only by fromCBORBytes (L141) and
    fromCBORHex (L150), transferred through addVKeyWitnesses (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 (1a0000000a where canonical is 0a)
    that round-trips exactly through Transaction.toCBORBytes
  • before fix: the object overload signs 233fb742... while the node txid over the submitted bytes is
    1d043700...; the string overload signs 1d043700...
  • 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

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Ö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

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.