Skip to content

Commit 949dce6

Browse files
committed
Fix canonical CBOR bug
The current canonicalization functionality does not canonicalize CBOR maps in CBOR lists
1 parent 4c5b798 commit 949dce6

File tree

2 files changed

+21
-6
lines changed
  • cardano-api

2 files changed

+21
-6
lines changed

cardano-api/src/Cardano/Api/Serialise/Cbor/Canonical.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ canonicaliseTerm = \case
6767
(TTagged tag term) ->
6868
TTagged tag $ canonicaliseTerm term
6969
(TListI terms) ->
70-
TList terms
70+
TList $ map canonicaliseTerm terms
71+
(TList terms) ->
72+
TList $ map canonicaliseTerm terms
7173
term -> term
7274

7375
-- | Implements sorting of CBOR terms for canonicalisation. CBOR terms are compared by lexical order of their

cardano-api/test/cardano-api-test/Test/Cardano/Api/CBOR.hs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Data.ByteString.Short qualified as SBS
2727
import Data.List (sortOn)
2828
import Data.Text (Text)
2929
import Data.Text qualified as T
30+
import GHC.Stack (callStack)
3031
import GHC.Stack qualified as GHC
3132

3233
import Test.Gen.Cardano.Api.Hardcoded
@@ -415,15 +416,27 @@ prop_canonicalise_cbor = property $ do
415416
, (TBytes "bb", TString "h")
416417
, (TBytes "ba", TListI [TString "i", TString "j"])
417418
]
418-
inputMapBs = CBOR.serialize' inputMap
419-
inputMapTerm <- decodeExampleTerm inputMapBs
419+
inputMapInIndefiniteList = TListI [inputMap]
420+
inputMapInDefiniteList = TList [inputMap]
420421

421-
inputMapCanonicalisedBs <- H.leftFail $ canonicaliseCborBs inputMapBs
422+
input <- forAll $ Gen.element [inputMap, inputMapInIndefiniteList, inputMapInDefiniteList]
423+
let inputBs = CBOR.serialize' input
422424

423-
inputMapCanonicalisedTerm@(TMap elemTerms) <- decodeExampleTerm inputMapCanonicalisedBs
425+
inputTerm <- decodeExampleTerm inputBs
426+
427+
inputCanonicalisedBs <- H.leftFail $ canonicaliseCborBs inputBs
428+
429+
decodedTerm <- decodeExampleTerm inputCanonicalisedBs
430+
inputMapCanonicalisedTerm@(TMap elemTerms) <-
431+
case decodedTerm of
432+
TMap elemTerms -> pure $ TMap elemTerms
433+
TList [TMap elemTerms] -> pure $ TMap elemTerms
434+
t ->
435+
H.failMessage callStack $
436+
"Expected canonicalised term to be a map or a list with a single map: " <> show t
424437

425438
H.annotate "sanity check that cbor round trip does not change the order"
426-
inputMap === inputMapTerm
439+
input === inputTerm
427440

428441
H.annotate "Print bytes hex representation of the keys in the map"
429442
H.annotateShow

0 commit comments

Comments
 (0)