Skip to content

Commit 1c0334d

Browse files
committed
Fixed unannotated TxDats decoder
1 parent b5ee8da commit 1c0334d

File tree

2 files changed

+47
-3
lines changed
  • eras/alonzo/impl/testlib/Test/Cardano/Ledger/Alonzo/Binary
  • libs/cardano-ledger-binary/testlib/Test/Cardano/Ledger

2 files changed

+47
-3
lines changed

eras/alonzo/impl/testlib/Test/Cardano/Ledger/Alonzo/Binary/Annotator.hs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import Cardano.Ledger.Binary.Coders
2929
import Cardano.Ledger.Core
3030
import Cardano.Ledger.Plutus
3131
import Cardano.Ledger.Shelley.BlockBody (auxDataSeqDecoder)
32+
import Data.Coerce (coerce)
3233
import qualified Data.List.NonEmpty as NE
3334
import Data.Map.Strict (Map)
3435
import qualified Data.Map.Strict as Map
@@ -274,14 +275,42 @@ instance (AlonzoEraScript era, DecCBOR (NativeScript era)) => DecCBOR (AlonzoScr
274275
decodePlutus slang =
275276
SumD PlutusScript <! D (decodePlutusScript slang)
276277

278+
-- | Decodes a set of `a`'s and maps a function over it to get key-value pairs.
279+
-- If the key-value pairs create a non-empty Map without duplicates, then that map is returned,
280+
-- otherwise fail
281+
noDuplicateNonEmptySetAsMapDecoder ::
282+
(Ord k, DecCBOR a) =>
283+
(a -> (k, v)) ->
284+
Decoder s (Map k v)
285+
noDuplicateNonEmptySetAsMapDecoder toKV = do
286+
allowTag setTag
287+
vals <- decodeList decCBOR
288+
go (Map.empty, 0) vals
289+
where
290+
go (m, n) []
291+
| Map.null m = fail "Empty script Set is not allowed"
292+
| length m /= n = fail "Duplicate elements in the scripts Set were encountered"
293+
| otherwise = pure m
294+
go (!m, !n) (x : xs) = do
295+
let (k, v) = toKV x
296+
go (Map.insert k v m, n + 1) xs
297+
277298
instance Era era => DecCBOR (TxDatsRaw era) where
278299
decCBOR =
279300
ifDecoderVersionAtLeast
280301
(natVersion @9)
281-
( allowTag setTag
282-
>> TxDatsRaw . Map.fromElems hashData . NE.toList <$> decodeNonEmptyList decCBOR
302+
( ifDecoderVersionAtLeast
303+
(natVersion @12)
304+
noDuplicatesDatsDecoder
305+
( allowTag setTag
306+
>> TxDatsRaw . Map.fromElems hashData . NE.toList <$> decodeNonEmptyList decCBOR
307+
)
283308
)
284309
(TxDatsRaw . Map.fromElems hashData <$> decodeList decCBOR)
310+
where
311+
noDuplicatesDatsDecoder :: Decoder s (TxDatsRaw era)
312+
noDuplicatesDatsDecoder =
313+
coerce . noDuplicateNonEmptySetAsMapDecoder $ \dat -> (hashData dat, dat)
285314
{-# INLINE decCBOR #-}
286315

287316
deriving newtype instance Era era => DecCBOR (TxDats era)

libs/cardano-ledger-binary/testlib/Test/Cardano/Ledger/Binary.hs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ module Test.Cardano.Ledger.Binary (
1212
) where
1313

1414
import Cardano.Ledger.Binary
15+
import Codec.CBOR.Pretty (prettyHexEnc)
16+
import Codec.CBOR.Read (deserialiseFromBytes)
17+
import qualified Codec.CBOR.Term as C
1518
import Control.Monad (forM_)
1619
import qualified Data.ByteString.Lazy as BSL
1720
import Data.Proxy
@@ -21,6 +24,7 @@ import Test.Cardano.Ledger.Binary.RoundTrip (embedTripAnnExpectation)
2124
import Test.Hspec
2225
import Test.Hspec.QuickCheck (prop)
2326
import Test.QuickCheck hiding (label)
27+
import Text.Show.Pretty (ppShow)
2428

2529
-- | Generates arbitrary values, encodes them, and verifies that
2630
-- decoding with `DecCBOR (Annotator)` produces the same result as decoding with `DecCBOR`.
@@ -76,4 +80,15 @@ decoderEquivalenceExpectation version bs = do
7680
(Left _, Left _) -> pure ()
7781
_ ->
7882
expectationFailure $
79-
"Decoding result: " ++ show dec ++ " did not match the one via Annotator: " ++ show decAnn
83+
unlines
84+
[ "Decoding result:"
85+
, ppShow dec
86+
, "did not match the one via Annotator:"
87+
, ppShow decAnn
88+
, "CBOR:"
89+
, hexDebug
90+
]
91+
where
92+
hexDebug = case deserialiseFromBytes C.decodeTerm bs of
93+
Right (_, res) -> prettyHexEnc $ C.encodeTerm res
94+
Left err -> "Failed to decode CBOR: " <> show err

0 commit comments

Comments
 (0)