Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

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

未关闭
#578 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
58/100
Issue 类型
缺陷
描述清晰度
描述清楚
活跃度
活跃
技术栈
typescript
领域
data

调研方向

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.

由索引模型根据 Issue 内容生成。

描述

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.

主要语言
TypeScript
星标
22
派生
35
平均合并
19 小时 56 分钟
30 天内合并 PR
58

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

IntersectMBO/evolution-sdk 的其他 Issue

查看 IntersectMBO/evolution-sdk 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。