Skip to content

Commit 51a5f4b

Browse files
committed
Add SerialiseAsCBOR instance for TxOut
1 parent 9f0d0bb commit 51a5f4b

File tree

2 files changed

+38
-2
lines changed
  • cardano-api
    • src/Cardano/Api/Tx/Internal
    • test/cardano-api-test/Test/Cardano/Api

2 files changed

+38
-2
lines changed

cardano-api/src/Cardano/Api/Tx/Internal/Output.hs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
{-# LANGUAGE DataKinds #-}
2+
{-# LANGUAGE DeriveAnyClass #-}
23
{-# LANGUAGE DerivingVia #-}
34
{-# LANGUAGE DisambiguateRecordFields #-}
45
{-# LANGUAGE EmptyCase #-}
56
{-# LANGUAGE FlexibleContexts #-}
67
{-# LANGUAGE FlexibleInstances #-}
78
{-# LANGUAGE GADTs #-}
9+
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10+
{-# LANGUAGE InstanceSigs #-}
811
{-# LANGUAGE LambdaCase #-}
912
{-# LANGUAGE RankNTypes #-}
1013
{-# LANGUAGE ScopedTypeVariables #-}
1114
{-# LANGUAGE StandaloneDeriving #-}
1215
{-# LANGUAGE TypeApplications #-}
1316
{-# LANGUAGE TypeFamilies #-}
1417
{-# LANGUAGE TypeOperators #-}
18+
{-# LANGUAGE UndecidableInstances #-}
1519

1620
module Cardano.Api.Tx.Internal.Output
1721
( -- * Transaction outputs
@@ -62,7 +66,7 @@ import Cardano.Api.Era.Internal.Eon.BabbageEraOnwards
6266
import Cardano.Api.Era.Internal.Eon.Convert
6367
import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra
6468
import Cardano.Api.Error (Error (..), displayError)
65-
import Cardano.Api.Hash
69+
import Cardano.Api.HasTypeProxy qualified as HTP
6670
import Cardano.Api.Ledger.Internal.Reexport qualified as Ledger
6771
import Cardano.Api.Monad.Error
6872
import Cardano.Api.Parser.Text qualified as P
@@ -81,11 +85,11 @@ import Cardano.Ledger.Alonzo.Core qualified as L
8185
import Cardano.Ledger.Api qualified as L
8286
import Cardano.Ledger.BaseTypes (StrictMaybe (..))
8387
import Cardano.Ledger.Coin qualified as L
84-
import Cardano.Ledger.Core ()
8588
import Cardano.Ledger.Core qualified as Core
8689
import Cardano.Ledger.Core qualified as Ledger
8790
import Cardano.Ledger.Plutus.Data qualified as Plutus
8891

92+
import Codec.CBOR.Encoding (Encoding)
8993
import Data.Aeson (object, withObject, (.:), (.:?), (.=))
9094
import Data.Aeson qualified as Aeson
9195
import Data.Aeson.Key qualified as Aeson
@@ -99,6 +103,7 @@ import Data.Sequence.Strict qualified as Seq
99103
import Data.Text (Text)
100104
import Data.Text.Encoding qualified as Text
101105
import Data.Type.Equality
106+
import Data.Typeable (Typeable)
102107
import Data.Word
103108
import GHC.Exts (IsList (..))
104109
import GHC.Stack
@@ -120,6 +125,24 @@ data TxOut ctx era
120125
(TxOutValue era)
121126
(TxOutDatum ctx era)
122127
(ReferenceScript era)
128+
deriving SerialiseAsCBOR
129+
130+
instance (Typeable ctx, IsShelleyBasedEra era) => HTP.HasTypeProxy (TxOut ctx era) where
131+
data AsType (TxOut ctx era) = AsTxOut (AsType era)
132+
proxyToAsType :: HTP.Proxy (TxOut ctx era) -> AsType (TxOut ctx era)
133+
proxyToAsType _ = AsTxOut (HTP.asType @era)
134+
135+
instance (Typeable ctx, IsShelleyBasedEra era) => ToCBOR (TxOut ctx era) where
136+
toCBOR :: TxOut ctx era -> Encoding
137+
toCBOR txOut =
138+
shelleyBasedEraConstraints (shelleyBasedEra @era) $
139+
Ledger.toEraCBOR @(ShelleyLedgerEra era) (toShelleyTxOutAny shelleyBasedEra txOut)
140+
141+
instance (Typeable ctx, IsShelleyBasedEra era) => FromCBOR (TxOut ctx era) where
142+
fromCBOR :: Ledger.Decoder s (TxOut ctx era)
143+
fromCBOR =
144+
shelleyBasedEraConstraints (shelleyBasedEra @era) $
145+
fromShelleyTxOut <$> pure shelleyBasedEra <*> L.fromEraCBOR @(ShelleyLedgerEra era)
123146

124147
deriving instance Eq (TxOut ctx era)
125148

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,18 @@ prop_roundtrip_tx_CBOR = H.property $ do
110110
x <- H.forAll $ genTx era
111111
shelleyBasedEraConstraints era $ H.trippingCbor (proxyToAsType Proxy) x
112112

113+
prop_roundtrip_tx_out_CBOR :: Property
114+
prop_roundtrip_tx_out_CBOR = H.property $ do
115+
AnyShelleyBasedEra era <- H.noteShowM . H.forAll $ Gen.element [minBound .. maxBound]
116+
x <- H.forAll $ genTx era
117+
txOut <- H.forAll $ Gen.element $ txOuts $ getTxBodyContent $ getTxBody x
118+
txOutRT <- H.evalEither $ rtOnce era txOut -- We do this because some information gets lost on serialisation
119+
shelleyBasedEraConstraints era $ H.trippingCbor (proxyToAsType Proxy) txOutRT
120+
where
121+
rtOnce
122+
:: ShelleyBasedEra era -> TxOut CtxTx era -> Either CBOR.DecoderError (TxOut CtxTx era)
123+
rtOnce sbe t = shelleyBasedEraConstraints sbe $ deserialiseFromCBOR (proxyToAsType Proxy) (serialiseToCBOR t)
124+
113125
prop_roundtrip_witness_CBOR :: Property
114126
prop_roundtrip_witness_CBOR = H.property $ do
115127
AnyShelleyBasedEra era <- H.noteShowM . H.forAll $ Gen.element [minBound .. maxBound]
@@ -521,6 +533,7 @@ tests =
521533
, testProperty "roundtrip ScriptData CBOR" prop_roundtrip_ScriptData_CBOR
522534
, testProperty "roundtrip TxWitness Cddl" prop_roundtrip_TxWitness_Cddl
523535
, testProperty "roundtrip tx CBOR" prop_roundtrip_tx_CBOR
536+
, testProperty "roundtrip tx out CBOR" prop_roundtrip_tx_out_CBOR
524537
, testProperty
525538
"roundtrip GovernancePoll CBOR"
526539
prop_roundtrip_GovernancePoll_CBOR

0 commit comments

Comments
 (0)