Skip to content

Commit f686e52

Browse files
authored
Merge pull request #1093 from IntersectMBO/jordan/tx-body-content-refactoring-fixes
TxBodyContent refactoring related fixes
2 parents 2aac61d + 02f3830 commit f686e52

13 files changed

Lines changed: 202 additions & 86 deletions

File tree

cardano-api-gen/cardano-api-gen.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ category:
88
API,
99
Test,
1010

11-
copyright: 2020-2024 Input Output Global Inc (IOG).
11+
copyright: 2020-2026 Input Output Global Inc (IOG).
1212
author: IOHK
1313
maintainer: operations@iohk.io
1414
license: Apache-2.0

cardano-api/src/Cardano/Api/Experimental.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ module Cardano.Api.Experimental
8686
, AsType (..)
8787

8888
-- ** Internal
89+
, anyScriptWitnessToAnyWitness
8990
, getAnyWitnessRedeemerPointerMap
9091
, toPlutusScriptPurpose
9192

@@ -103,5 +104,6 @@ import Cardano.Api.Experimental.Plutus.Internal.ScriptWitness
103104
import Cardano.Api.Experimental.Plutus.Internal.Shim.LegacyScripts
104105
import Cardano.Api.Experimental.Simple.Script
105106
import Cardano.Api.Experimental.Tx
107+
import Cardano.Api.Experimental.Tx.Internal.AnyWitness
106108
import Cardano.Api.Experimental.Tx.Internal.Fee
107109
import Cardano.Api.Tx.Internal.Fee (evaluateTransactionExecutionUnitsShelley)

cardano-api/src/Cardano/Api/Experimental/AnyScriptWitness.hs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Cardano.Api.Experimental.AnyScriptWitness
99
( AnyScriptWitness (..)
1010
, AnyPlutusScriptWitness (..)
1111
, PlutusSpendingScriptWitness (..)
12+
, getAnyScriptWitnessReferenceInput
1213
, createPlutusSpendingScriptWitness
1314
, getAnyPlutusScriptData
1415
, getAnyPlutusScriptWitnessExecutionUnits
@@ -180,6 +181,16 @@ getAnyPlutusScriptWitnessLanguage (AnyPlutusCertifyingScriptWitness s) = getPlut
180181
getAnyPlutusScriptWitnessLanguage (AnyPlutusProposingScriptWitness s) = getPlutusScriptWitnessLanguage s
181182
getAnyPlutusScriptWitnessLanguage (AnyPlutusVotingScriptWitness s) = getPlutusScriptWitnessLanguage s
182183

184+
getAnyScriptWitnessReferenceInput
185+
:: AnyScriptWitness era
186+
-> Maybe TxIn
187+
getAnyScriptWitnessReferenceInput (AnyScriptWitnessSimple s) =
188+
case s of
189+
SReferenceScript txin -> Just txin
190+
SScript{} -> Nothing
191+
getAnyScriptWitnessReferenceInput (AnyScriptWitnessPlutus psw) =
192+
getAnyPlutusScriptWitnessReferenceInput psw
193+
183194
getAnyPlutusScriptWitnessReferenceInput
184195
:: AnyPlutusScriptWitness lang purpose era
185196
-> Maybe TxIn

cardano-api/src/Cardano/Api/Experimental/Era.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import Cardano.Api.Era.Internal.Eon.ConwayEraOnwards
4444
import Cardano.Api.Era.Internal.Eon.MaryEraOnwards
4545
import Cardano.Api.Era.Internal.Eon.ShelleyBasedEra (ShelleyBasedEra (..), ShelleyLedgerEra)
4646
import Cardano.Api.Error
47+
import Cardano.Api.HasTypeProxy
4748
import Cardano.Api.Ledger.Internal.Reexport qualified as L
4849
import Cardano.Api.Pretty.Internal.ShowOf
4950

@@ -311,6 +312,7 @@ type EraCommonConstraints era =
311312
, L.EraTxCert (LedgerEra era)
312313
, L.EraTxOut (LedgerEra era)
313314
, L.EraUTxO (LedgerEra era)
315+
, HasTypeProxy era
314316
, Ord (L.PlutusPurpose L.AsIx (LedgerEra era))
315317
, L.ScriptsNeeded (LedgerEra era) ~ L.AlonzoScriptsNeeded (LedgerEra era)
316318
, L.Val (L.Value (LedgerEra era))

cardano-api/src/Cardano/Api/Experimental/Tx.hs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ module Cardano.Api.Experimental.Tx
154154
, setTxWithdrawals
155155

156156
-- * Legacy Conversions
157+
, DatumDecodingError (..)
157158
, legacyDatumToDatum
158159
, fromLegacyTxOut
159160

@@ -181,13 +182,19 @@ module Cardano.Api.Experimental.Tx
181182
-- ** All the parts that constitute a plutus script witness but also including simple scripts
182183
, TxScriptWitnessRequirements (..)
183184

185+
-- ** Plutus related
186+
, Datum (..)
187+
, getDatums
188+
, extractDatumsAndHashes
189+
184190
-- ** Collecting plutus script witness related transaction requirements.
185191
, collectPlutusScriptHashes
186192
, extractAllIndexedPlutusScriptWitnesses
187193
, getTxScriptWitnessesRequirements
188194
, obtainMonoidConstraint
189195

190196
-- * Balancing transactions
197+
, calculateMinimumUTxO
191198
, evaluateTransactionExecutionUnits
192199
, makeTransactionBodyAutoBalance
193200
, TxBodyErrorAutoBalance (..)
@@ -247,7 +254,7 @@ hashTxBody = L.extractHash . L.hashAnnotated
247254

248255
makeKeyWitness
249256
:: Era era
250-
-> UnsignedTx era
257+
-> UnsignedTx (LedgerEra era)
251258
-> ShelleyWitnessSigningKey
252259
-> L.WitVKey L.Witness
253260
makeKeyWitness era (UnsignedTx unsignedTx) wsk =
@@ -297,7 +304,7 @@ signTx
297304
:: Era era
298305
-> [L.BootstrapWitness]
299306
-> [L.WitVKey L.Witness]
300-
-> UnsignedTx era
307+
-> UnsignedTx (LedgerEra era)
301308
-> SignedTx era
302309
signTx era bootstrapWits shelleyKeyWits (UnsignedTx unsigned) =
303310
obtainCommonConstraints era $
@@ -315,7 +322,7 @@ signTx era bootstrapWits shelleyKeyWits (UnsignedTx unsigned) =
315322
-- Compatibility related. Will be removed once the old api has been deprecated and deleted.
316323

317324
convertTxBodyToUnsignedTx
318-
:: HasCallStack => ShelleyBasedEra era -> TxBody era -> UnsignedTx era
325+
:: HasCallStack => ShelleyBasedEra era -> TxBody era -> UnsignedTx (LedgerEra era)
319326
convertTxBodyToUnsignedTx sbe txbody =
320327
Api.forEraInEon
321328
(Api.toCardanoEra sbe)
@@ -330,7 +337,7 @@ convertTxBodyToUnsignedTx sbe txbody =
330337
collectPlutusScriptHashes
331338
:: forall era
332339
. IsEra era
333-
=> UnsignedTx era
340+
=> UnsignedTx (LedgerEra era)
334341
-> L.UTxO (LedgerEra era)
335342
-> Map Api.ScriptWitnessIndex Api.ScriptHash
336343
collectPlutusScriptHashes (UnsignedTx tx) utxo =
@@ -346,10 +353,9 @@ getPurposes (L.AlonzoScriptsNeeded purposes) =
346353
Map.fromList $
347354
Prelude.map
348355
( bimap
349-
( \pp ->
350-
obtainCommonConstraints (useEra @era) $
351-
Api.toScriptIndex (convert (useEra @era)) $
352-
purposeAsIxItemToAsIx pp
356+
( obtainCommonConstraints (useEra @era) $
357+
Api.toScriptIndex (convert (useEra @era))
358+
. purposeAsIxItemToAsIx
353359
)
354360
Api.fromShelleyScriptHash
355361
)

cardano-api/src/Cardano/Api/Experimental/Tx/Internal/AnyWitness.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
module Cardano.Api.Experimental.Tx.Internal.AnyWitness
88
( -- * Any witness (key, simple script, plutus script).
99
AnyWitness (..)
10+
, anyScriptWitnessToAnyWitness
1011
, getAnyWitnessScript
1112
, getAnyWitnessSimpleScript
1213
, getAnyWitnessPlutusLanguage
@@ -127,3 +128,9 @@ getPlutusDatum L.SPlutusV3 (SpendingScriptDatum d) = d
127128
getPlutusDatum L.SPlutusV4 (SpendingScriptDatum _d) = error "dijkstra"
128129
getPlutusDatum _ InlineDatum = Nothing
129130
getPlutusDatum _ NoScriptDatum = Nothing
131+
132+
anyScriptWitnessToAnyWitness
133+
:: AnyScriptWitness era
134+
-> AnyWitness era
135+
anyScriptWitnessToAnyWitness (AnyScriptWitnessSimple s) = AnySimpleScriptWitness s
136+
anyScriptWitnessToAnyWitness (AnyScriptWitnessPlutus sw) = AnyPlutusScriptWitness sw

cardano-api/src/Cardano/Api/Experimental/Tx/Internal/BodyContent/New.hs

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New
2323
, TxBodyContent (..)
2424
, Datum (..)
2525
, defaultTxBodyContent
26+
, extractDatumsAndHashes
27+
, getDatums
2628
, collectTxBodyScriptWitnessRequirements
2729
, makeUnsignedTx
2830
, extractAllIndexedPlutusScriptWitnesses
@@ -59,12 +61,15 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New
5961
, convProposalProcedures
6062

6163
-- * Legacy conversions
64+
, DatumDecodingError (..)
6265
, legacyDatumToDatum
6366
, fromLegacyTxOut
6467
)
6568
where
6669

6770
import Cardano.Api.Address
71+
import Cardano.Api.Error
72+
import Cardano.Api.Experimental.AnyScriptWitness
6873
import Cardano.Api.Experimental.Certificate qualified as Exp
6974
import Cardano.Api.Experimental.Era
7075
import Cardano.Api.Experimental.Plutus
@@ -76,6 +81,7 @@ import Cardano.Api.Experimental.Plutus
7681
import Cardano.Api.Experimental.Simple.Script
7782
import Cardano.Api.Experimental.Tx.Internal.AnyWitness
7883
( AnyWitness (..)
84+
, anyScriptWitnessToAnyWitness
7985
)
8086
import Cardano.Api.Experimental.Tx.Internal.Certificate.Compatible (getTxCertWitness)
8187
import Cardano.Api.Experimental.Tx.Internal.TxScriptWitnessRequirements
@@ -91,6 +97,7 @@ import Cardano.Api.Key.Internal
9197
import Cardano.Api.Ledger.Internal.Reexport (StrictMaybe (..))
9298
import Cardano.Api.Ledger.Internal.Reexport qualified as L
9399
import Cardano.Api.Plutus.Internal.ScriptData qualified as Api
100+
import Cardano.Api.Pretty
94101
import Cardano.Api.Tx.Internal.Body
95102
( CtxTx
96103
, TxIn
@@ -113,6 +120,7 @@ import Cardano.Ledger.Keys qualified as L
113120
import Cardano.Ledger.Plutus.Language qualified as Plutus
114121

115122
import Control.Monad
123+
import Data.ByteString.Short qualified as SBS
116124
import Data.Functor
117125
import Data.List qualified as List
118126
import Data.Map.Ordered.Strict (OMap)
@@ -132,7 +140,7 @@ makeUnsignedTx
132140
:: forall era
133141
. Era era
134142
-> TxBodyContent (LedgerEra era)
135-
-> UnsignedTx era
143+
-> UnsignedTx (LedgerEra era)
136144
makeUnsignedTx DijkstraEra _ = error "makeUnsignedTx: Dijkstra era not supported yet"
137145
makeUnsignedTx era@ConwayEra bc = obtainCommonConstraints era $ do
138146
let TxScriptWitnessRequirements languages scripts datums redeemers = collectTxBodyScriptWitnessRequirements bc
@@ -146,7 +154,7 @@ makeUnsignedTx era@ConwayEra bc = obtainCommonConstraints era $ do
146154
txins = convTxIns $ txIns bc
147155
collTxIns = convCollateralTxIns bc
148156
refTxIns = convReferenceInputs apiReferenceInputs
149-
outs = fromList [o | TxOut o _ <- txOuts bc]
157+
outs = fromList [o | TxOut o <- txOuts bc]
150158
protocolParameters = txProtocolParams bc
151159
fee = txFee bc
152160
withdrawals = convWithdrawals $ txWithdrawals bc
@@ -310,12 +318,12 @@ eraSpecificLedgerTxBody era ledgerbody bc =
310318
& L.currentTreasuryValueTxBodyL
311319
.~ L.maybeToStrictMaybe currentTreasuryValue
312320

313-
data TxOut ctx era where
314-
TxOut :: L.EraTxOut era => L.TxOut era -> Maybe (Datum ctx era) -> TxOut ctx era
321+
data TxOut era where
322+
TxOut :: L.EraTxOut era => L.TxOut era -> TxOut era
315323

316-
deriving instance (Show (TxOut ctx era))
324+
deriving instance (Show (TxOut era))
317325

318-
deriving instance (Eq (TxOut ctx era))
326+
deriving instance (Eq (TxOut era))
319327

320328
data Datum ctx era where
321329
TxOutDatumHash
@@ -354,10 +362,32 @@ legacyDatumToDatum (OldApi.TxOutDatumInline _ hd) = do
354362
Just (TxOutDatumInline hash d)
355363
legacyDatumToDatum OldApi.TxOutDatumNone = Nothing
356364

357-
fromLegacyTxOut :: forall era. IsEra era => OldApi.TxOut CtxTx era -> TxOut CtxTx (LedgerEra era)
358-
fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) =
365+
fromLegacyTxOut
366+
:: forall era. IsEra era => OldApi.TxOut CtxTx era -> Either DatumDecodingError (TxOut (LedgerEra era))
367+
fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) = do
359368
let o = OldApi.toShelleyTxOutAny (convert $ useEra @era) tOut
360-
in obtainCommonConstraints (useEra @era) $ TxOut o (legacyDatumToDatum d)
369+
newDatum :: L.Datum (LedgerEra era) <- obtainCommonConstraints (useEra @era) $ toLedgerDatum d
370+
return $ obtainCommonConstraints (useEra @era) $ TxOut $ o & L.datumTxOutL .~ newDatum
371+
372+
newtype DatumDecodingError = DatumDecodingError String
373+
deriving (Show, Eq)
374+
375+
instance Error DatumDecodingError where
376+
prettyError (DatumDecodingError msg) = "Datum decoding error: " <> pshow msg
377+
378+
toLedgerDatum
379+
:: L.Era (LedgerEra era)
380+
=> OldApi.TxOutDatum CtxTx era -> Either DatumDecodingError (L.Datum (LedgerEra era))
381+
toLedgerDatum OldApi.TxOutDatumNone = Right L.NoDatum
382+
toLedgerDatum (OldApi.TxOutDatumHash _ (Api.ScriptDataHash h)) = Right $ L.DatumHash h
383+
toLedgerDatum (OldApi.TxOutSupplementalDatum _ h) =
384+
case L.makeBinaryData $ SBS.toShort $ Api.getOriginalScriptDataBytes h of
385+
Left e -> Left $ DatumDecodingError e
386+
Right bd -> Right $ L.Datum bd
387+
toLedgerDatum (OldApi.TxOutDatumInline _ h) =
388+
case L.makeBinaryData $ SBS.toShort $ Api.getOriginalScriptDataBytes h of
389+
Left e -> Left $ DatumDecodingError e
390+
Right bd -> Right $ L.Datum bd
361391

362392
data TxInsReference era = TxInsReference [TxIn] (Set (Datum CtxTx era))
363393

@@ -399,14 +429,13 @@ mkTxCertificates era certs = TxCertificates . OMap.fromList $ map getStakeCred c
399429
getStakeCred (c@(Exp.Certificate cert), wit) =
400430
(c, (,wit) <$> getTxCertWitness (convert era) (obtainCommonConstraints era cert))
401431

402-
-- This is incorrect. Only scripts can witness minting!
403432
newtype TxMintValue era
404433
= TxMintValue
405434
{ unTxMintValue
406435
:: Map
407436
PolicyId
408437
( PolicyAssets
409-
, AnyWitness era
438+
, AnyScriptWitness era
410439
)
411440
}
412441
deriving (Eq, Show)
@@ -489,7 +518,7 @@ data TxBodyContent era
489518
{ txIns :: [(TxIn, AnyWitness era)]
490519
, txInsCollateral :: [TxIn]
491520
, txInsReference :: TxInsReference era
492-
, txOuts :: [TxOut CtxTx era]
521+
, txOuts :: [TxOut era]
493522
, txTotalCollateral :: Maybe TxTotalCollateral
494523
, txReturnCollateral :: Maybe (TxReturnCollateral era)
495524
, txFee :: L.Coin
@@ -548,7 +577,7 @@ extractAllIndexedPlutusScriptWitnesses
548577
extractAllIndexedPlutusScriptWitnesses era b = obtainCommonConstraints era $ do
549578
let txInWits = extractWitnessableTxIns $ txIns b
550579
certWits = extractWitnessableCertificates $ txCertificates b
551-
mintWits = extractWitnessableMints $ txMintValue b
580+
mintWits = [(wit, anyScriptWitnessToAnyWitness sw) | (wit, sw) <- extractWitnessableMints $ txMintValue b]
552581
withdrawalWits = extractWitnessableWithdrawals $ txWithdrawals b
553582
proposalScriptWits = extractWitnessableProposals $ txProposalProcedures b
554583
voteWits = extractWitnessableVotes $ txVotingProcedures b
@@ -598,7 +627,7 @@ extractWitnessableMints
598627
:: forall era
599628
. IsEra era
600629
=> TxMintValue (LedgerEra era)
601-
-> [(Witnessable MintItem (LedgerEra era), AnyWitness (LedgerEra era))]
630+
-> [(Witnessable MintItem (LedgerEra era), AnyScriptWitness (LedgerEra era))]
602631
extractWitnessableMints mVal =
603632
obtainCommonConstraints (useEra @era) $
604633
List.nub
@@ -700,7 +729,7 @@ collectTxBodyScriptWitnessRequirements
700729
extractWitnessableCertificates txCertificates
701730
txMintWits =
702731
obtainMonoidConstraint (useEra @era) getTxScriptWitnessesRequirements $
703-
extractWitnessableMints txMintValue
732+
[(wit, anyScriptWitnessToAnyWitness sw) | (wit, sw) <- extractWitnessableMints txMintValue]
704733
txVotingWits =
705734
obtainMonoidConstraint (useEra @era) getTxScriptWitnessesRequirements $
706735
extractWitnessableVotes txVotingProcedures
@@ -738,14 +767,18 @@ getDatums
738767
. IsEra era
739768
=> TxInsReference (LedgerEra era)
740769
-- ^ reference inputs
741-
-> [TxOut CtxTx (LedgerEra era)]
770+
-> [TxOut (LedgerEra era)]
742771
-> L.TxDats (LedgerEra era)
743772
getDatums txInsRef txOutsFromTx = do
744773
let TxInsReference _ datumSet = txInsRef
745774
refInDatums = mapMaybe extractDatumsAndHashes $ Set.toList datumSet
746775
-- use only supplemental datum
747776
txOutsDats =
748-
[(h, d) | TxOut _ (Just (TxOutSupplementalDatum h d)) <- txOutsFromTx]
777+
[ (L.hashData d, d)
778+
| TxOut txout <- txOutsFromTx
779+
, d <-
780+
maybeToList $ L.strictMaybeToMaybe $ txout ^. obtainCommonConstraints (useEra @era) L.dataTxOutL
781+
]
749782
:: [(L.DataHash, L.Data (LedgerEra era))]
750783
obtainCommonConstraints (useEra @era) $
751784
L.TxDats $
@@ -790,7 +823,7 @@ setTxMetadata v txBodyContent = txBodyContent{txMetadata = v}
790823
setTxFee :: L.Coin -> TxBodyContent era -> TxBodyContent era
791824
setTxFee v txBodyContent = txBodyContent{txFee = v}
792825

793-
setTxOuts :: [TxOut CtxTx era] -> TxBodyContent era -> TxBodyContent era
826+
setTxOuts :: [TxOut era] -> TxBodyContent era -> TxBodyContent era
794827
setTxOuts v txBodyContent = txBodyContent{txOuts = v}
795828

796829
setTxMintValue :: TxMintValue era -> TxBodyContent era -> TxBodyContent era
@@ -818,5 +851,5 @@ setTxTreasuryDonation :: L.Coin -> TxBodyContent era -> TxBodyContent era
818851
setTxTreasuryDonation v txBodyContent = txBodyContent{txTreasuryDonation = Just v}
819852

820853
modTxOuts
821-
:: ([TxOut CtxTx era] -> [TxOut CtxTx era]) -> TxBodyContent era -> TxBodyContent era
854+
:: ([TxOut era] -> [TxOut era]) -> TxBodyContent era -> TxBodyContent era
822855
modTxOuts f txBodyContent = txBodyContent{txOuts = f (txOuts txBodyContent)}

0 commit comments

Comments
 (0)