Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

CBOR: repeated map keys are silently collapsed, where the ledger either rejects them or keeps every pair

Aperta
#578 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
58/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
typescript
Ambito
data

Direzione di ricerca

Start in packages/evolution/src/CBOR.ts at decodeMapAt and the captured-format map encoder; trace the transaction body, metadata-label, and metadatum paths. Run the regression cases through Transaction.fromCBORHex and compare re-encoded bytes, including controls and the multi-assets, withdrawals, and mint cases. Done means ledger-record and Map duplicates fail with a key-naming error while metadatum pairs round-trip byte-identically.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

The CBOR map decoder stores entries in a JS Map, so a repeated key keeps only its last value, and no error is raised. On re-encode the captured key order replays every key, so the output repeats the last value:

body   a4 ... 02 00 02 0a       → a4 ... 02 0a 02 0a       (fee 0 lost)
label  a2 00 01 00 02           → a2 00 02 00 02           ({0: 1} lost)
datum  a2 01 01 01 02           → a2 01 02 01 02           ({1: 1} lost)

The ledger treats repeated keys in two different ways, so a single rule at the CBOR layer cannot be right:

Where Ledger SDK today Should
transaction body, witness set reject: SparseKeyed decoders fail on a repeated field (Coders.hs L565-569, duplicateKey L634-640; Conway/TxBody.hs L183, Alonzo/TxWits.hs L609) accepts, rewrites reject on decode
metadata labels and other Map fields reject from protocol version 9: decodeMap uses decodeMapLikeEnforceNoDuplicates (Decoder.hs L748-753, L785-789) accepts, rewrites reject on decode
metadatum map values keep every pair: Metadatum Map is a list of pairs (Metadata.hs L161-172) drops the earlier pair keep every pair
Plutus data maps keep every pair: Map [(Data, Data)] (plutus Data.hs L44, L277-283) drops the earlier pair tracked in #397

Affected

packages/evolution/src/CBOR.ts

  • decodeMapAt (L1973-2035): map.set(k, v) overwrites a repeated key; the captured keyOrder still records both
  • map encode with a captured format (L1496-1525) replays every keyOrder entry, each with the surviving value

Every schema built on this decoder inherits the behavior. Tested here: the transaction body, metadata labels and metadatum values. Multi-assets, withdrawals and mint go through the same ledger decodeMap, but were not tested, so the fix should add one case for each.

Fix

Decide per schema, following the ledger:

  • ledger records and Map fields: reject a repeated key when decoding, with an error that names the key
  • metadatum map values: keep every pair in order, so decode then encode returns the same pairs

The Plutus data side is #397, and it needs the same answer as metadatum values. The devnet accepted {1: 1, 1: 2} as an inline datum and rejected the SDK's rewrite with 3100, so rejecting on decode would refuse valid on-chain datums.

Regression test

Oracle is the node.

  • body a4 00 [inputs] 01 [outputs] 02 00 02 0a: before fix, decodes and re-encodes as 02 0a 02 0a; after fix, Transaction.fromCBORHex fails with a duplicate key error
  • metadata a2 00 01 00 02 (label 0 twice): same, rejected after fix
  • metadatum a1 00 a2 01 01 01 02: before fix, written back as a1 00 a2 01 02 01 02; after fix, byte-identical
  • control: maps without repeated keys are unchanged

Devnet, raw submission through Ogmios:

  • body with the fee key twice: node rejects as malformed; the SDK decodes it
  • metadata with label 0 twice: node rejects as malformed; the SDK decodes it
  • metadatum {1: 1, 1: 2} under label 0: original accepted; after addVKeyWitnessesHex, rejected with 3107 metadata hash mismatch

Must FAIL on main today and PASS after the fix.

Reference

#397 covers the Plutus data side. #531 asks for rejecting repeated keys on decode before the signing fix hashes original bytes.

Lingua principale
TypeScript
Stelle
22
Fork
35
Merge medio
19h 56m
PR unite (30g)
58

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di IntersectMBO/evolution-sdk

Tutte le issue di IntersectMBO/evolution-sdk

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.