@@ -29,6 +29,7 @@ import Cardano.Ledger.Binary.Coders
2929import Cardano.Ledger.Core
3030import Cardano.Ledger.Plutus
3131import Cardano.Ledger.Shelley.BlockBody (auxDataSeqDecoder )
32+ import Data.Coerce (coerce )
3233import qualified Data.List.NonEmpty as NE
3334import Data.Map.Strict (Map )
3435import 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+
277298instance 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
287316deriving newtype instance Era era => DecCBOR (TxDats era )
0 commit comments