Skip to content

Commit cf0ba30

Browse files
committed
Remove TxOut CtxTx/CtxUTxO usage from cardano-cli (non-Byron)
Eliminate the legacy 'TxOut CtxTx era' and 'TxOut CtxUTxO era' type signatures and pattern matches from cardano-cli's non-Byron code paths. Byron-era code is left alone — Byron uses a separate pre-Shelley tx output model and 'Exp.TxOut' is not applicable. Surfaces migrated: * 'Cardano.CLI.Compatible.Transaction.TxOut': 'mkTxOut' and 'toTxOutInAnyEra' now return '(Exp.TxOut, Map DataHash (L.Data ...))' directly. The legacy 'TxOut CtxTx era' is still used internally as a stepping stone to reuse the api's 'toShelleyTxOutAny' field-level conversion logic; it does not leak to callers. * 'Cardano.CLI.Compatible.Transaction.Run': the 'createCompatibleTx' call site now just splits the tuple returned by 'toTxOutInAnyEra'. * 'Cardano.CLI.EraBased.Transaction.Run': 'toTxOutInEra' and 'toTxOutInShelleyBasedEra' delegate straight to 'mkTxOut' now that it produces the tuple itself. * 'Cardano.CLI.Compatible.Json.Friendly.friendlyTxOut': now takes 'Exp.TxOut (LedgerEra era)' and reads address / value / datum / reference script directly via the ledger lenses ('addrTxOutL', 'valueTxOutL', 'datumTxOutL', 'referenceScriptTxOutL'). The two call sites in 'basePairs' and 'friendlyReturnCollateral' wrap the body's ledger outputs with 'Exp.TxOut' directly instead of going through 'fromShelleyTxOut → fromCtxUTxOTxOut'. The dead 'friendlyTxOutValue' helper is dropped. * 'Cardano.CLI.EraBased.Query.Run.filteredUTxOsToText': now takes a 'ShelleyBasedEra era' witness; converts the api 'UTxO era' to the ledger UTxO once via 'toLedgerUTxO', then renders each entry from '(api TxIn, Exp.TxOut (ShelleyLedgerEra era))' using ledger lenses. The pre-Babbage datum slot has no uniform ledger representation, so the text renderer emits an empty placeholder there and shows the babbage+ ledger datum elsewhere — debug-style output, no golden tests. * 'Cardano.CLI.Type.Error.TxValidationError': removed 'validateTxReturnCollateral', which was exported but never called anywhere outside its own module (the actual return-collateral construction in 'EraBased/Transaction/Run' builds 'Exp.TxReturnCollateral' directly). Remaining uses of legacy ctx-typed tx outputs in cardano-cli are confined to Byron-only modules and to the internal stepping-stone use inside 'mkTxOut'.
1 parent 4d4f884 commit cf0ba30

6 files changed

Lines changed: 122 additions & 102 deletions

File tree

cardano-cli/src/Cardano/CLI/Compatible/Json/Friendly.hs

Lines changed: 55 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ where
3333
import Cardano.Api as Api
3434
import Cardano.Api.Experimental (obtainCommonConstraints)
3535
import Cardano.Api.Experimental qualified as Exp
36+
import Cardano.Api.Experimental.Tx qualified as Exp
3637
import Cardano.Api.Ledger (ExUnits (..), extractHash, strictMaybeToMaybe)
3738
import Cardano.Api.Ledger qualified as Alonzo
3839
import Cardano.Api.Ledger qualified as L
@@ -219,8 +220,7 @@ basePairs
219220
-> [Aeson.Pair]
220221
basePairs era body mAuxData =
221222
Exp.obtainCommonConstraints era $
222-
let sbe = convert era :: ShelleyBasedEra era
223-
certs = toList (body ^. L.certsTxBodyL)
223+
let certs = toList (body ^. L.certsTxBodyL)
224224
in [ "auxiliary scripts" .= friendlyAuxScripts era mAuxData
225225
, "certificates"
226226
.= if null certs
@@ -232,7 +232,7 @@ basePairs era body mAuxData =
232232
, "metadata" .= friendlyMetadata mAuxData
233233
, "outputs"
234234
.= map
235-
(friendlyTxOut era . fromCtxUTxOTxOut . fromShelleyTxOut sbe)
235+
(friendlyTxOut era . Exp.TxOut)
236236
(toList (body ^. L.outputsTxBodyL))
237237
, "withdrawals" .= friendlyWithdrawals (body ^. L.withdrawalsTxBodyL)
238238
]
@@ -472,8 +472,7 @@ friendlyReturnCollateral era = \case
472472
L.SNothing -> Aeson.Null
473473
L.SJust collOut ->
474474
Exp.obtainCommonConstraints era $
475-
let sbe = convert era :: ShelleyBasedEra era
476-
in friendlyTxOut era (fromCtxUTxOTxOut (fromShelleyTxOut sbe collOut))
475+
friendlyTxOut era (Exp.TxOut collOut)
477476

478477
friendlyExtraKeyWits :: Set.Set (L.KeyHash L.Guard) -> Aeson.Value
479478
friendlyExtraKeyWits keyhashes
@@ -499,35 +498,59 @@ friendlyStakeAddress (StakeAddress net cred) =
499498
, friendlyStakeCredential cred
500499
]
501500

502-
friendlyTxOut :: Exp.Era era -> TxOut CtxTx era -> Aeson.Value
503-
friendlyTxOut era (TxOut addr amount mdatum script) =
501+
friendlyTxOut
502+
:: forall era
503+
. Exp.Era era
504+
-> Exp.TxOut (Exp.LedgerEra era)
505+
-> Aeson.Value
506+
friendlyTxOut era (Exp.TxOut ledgerTxOut) =
504507
Exp.obtainCommonConstraints era $
505-
object $
506-
case addr of
507-
AddressInEra ByronAddressInAnyEra byronAdr ->
508-
[ "address era" .= String "Byron"
509-
, "address" .= serialiseAddress byronAdr
510-
, "amount" .= friendlyTxOutValue era amount
511-
]
512-
AddressInEra (ShelleyAddressInEra _) saddr@(ShelleyAddress net cred stake) ->
513-
let preAlonzo =
514-
friendlyPaymentCredential (fromShelleyPaymentCredential cred)
515-
: [ "address era" .= Aeson.String "Shelley"
516-
, "network" .= net
517-
, "address" .= serialiseAddress saddr
518-
, "amount" .= friendlyTxOutValue era amount
519-
, "stake reference" .= friendlyStakeReference (fromShelleyStakeReference stake)
520-
]
521-
datum = ["datum" .= d | d <- maybeToList $ renderDatum mdatum]
522-
sinceAlonzo = ["reference script" .= script]
523-
in preAlonzo ++ datum ++ sinceAlonzo
508+
babbageEraOnwardsConstraints beo $
509+
let addr = fromShelleyAddr sbe (ledgerTxOut ^. L.addrTxOutL)
510+
ledgerValue = ledgerTxOut ^. L.valueTxOutL
511+
refScript = case ledgerTxOut ^. L.referenceScriptTxOutL of
512+
L.SNothing -> ReferenceScriptNone
513+
L.SJust s -> fromShelleyScriptToReferenceScript sbe s
514+
in object $
515+
case addr of
516+
AddressInEra ByronAddressInAnyEra byronAdr ->
517+
[ "address era" .= String "Byron"
518+
, "address" .= serialiseAddress byronAdr
519+
, "amount" .= friendlyLedgerValue era ledgerValue
520+
]
521+
AddressInEra (ShelleyAddressInEra _) saddr@(ShelleyAddress net cred stake) ->
522+
let preAlonzo =
523+
friendlyPaymentCredential (fromShelleyPaymentCredential cred)
524+
: [ "address era" .= Aeson.String "Shelley"
525+
, "network" .= net
526+
, "address" .= serialiseAddress saddr
527+
, "amount" .= friendlyLedgerValue era ledgerValue
528+
, "stake reference"
529+
.= friendlyStakeReference (fromShelleyStakeReference stake)
530+
]
531+
datumField =
532+
[ "datum" .= d
533+
| d <- maybeToList $ renderLedgerDatum beo (ledgerTxOut ^. L.datumTxOutL)
534+
]
535+
sinceAlonzo = ["reference script" .= refScript]
536+
in preAlonzo ++ datumField ++ sinceAlonzo
524537
where
525-
renderDatum :: TxOutDatum CtxTx era -> Maybe Aeson.Value
526-
renderDatum = \case
527-
TxOutDatumNone -> Nothing
528-
TxOutDatumHash _ h -> Just $ toJSON h
529-
TxOutSupplementalDatum _ sData -> Just $ scriptDataToJson ScriptDataJsonDetailedSchema sData
530-
TxOutDatumInline _ sData -> Just $ scriptDataToJson ScriptDataJsonDetailedSchema sData
538+
beo = convert era :: BabbageEraOnwards era
539+
sbe = convert era :: ShelleyBasedEra era
540+
541+
renderLedgerDatum
542+
:: BabbageEraOnwards era
543+
-> L.Datum (Exp.LedgerEra era)
544+
-> Maybe Aeson.Value
545+
renderLedgerDatum w = \case
546+
L.NoDatum -> Nothing
547+
L.DatumHash dh -> Just $ toJSON (ScriptDataHash dh)
548+
L.Datum binData ->
549+
babbageEraOnwardsConstraints w $
550+
Just $
551+
scriptDataToJson
552+
ScriptDataJsonDetailedSchema
553+
(fromAlonzoData (L.binaryDataToData binData))
531554

532555
friendlyStakeReference :: StakeAddressReference -> Aeson.Value
533556
friendlyStakeReference = \case
@@ -690,12 +713,6 @@ friendlyPaymentCredential = \case
690713
friendlyLovelace :: Lovelace -> Aeson.Value
691714
friendlyLovelace value = String $ docToText (pretty value)
692715

693-
friendlyTxOutValue :: Exp.Era era -> TxOutValue era -> Aeson.Value
694-
friendlyTxOutValue era = \case
695-
TxOutValueByron lovelace -> friendlyLovelace lovelace
696-
TxOutValueShelleyBased _ v ->
697-
Exp.obtainCommonConstraints era $ friendlyLedgerValue era v
698-
699716
friendlyLedgerValue
700717
:: ()
701718
=> Exp.Era era

cardano-cli/src/Cardano/CLI/Compatible/Transaction/Run.hs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,9 @@ runCompatibleTransactionCmd
6161
) = shelleyBasedEraConstraints sbe $ do
6262
sks <- mapM (fromEitherIOCli . readWitnessSigningData) witnesses
6363

64-
legacyOuts <- mapM (toTxOutInAnyEra sbe) outs
65-
let convertedOuts = map (convertLegacyTxOut sbe) legacyOuts
66-
allOuts = map fst convertedOuts
67-
extraDatums = Map.unions (map snd convertedOuts)
64+
outsAndDatums <- mapM (toTxOutInAnyEra sbe) outs
65+
let allOuts = map fst outsAndDatums
66+
extraDatums = Map.unions (map snd outsAndDatums)
6867

6968
certFilesAndMaybeScriptWits <-
7069
readCertificateScriptWitnesses' sbe certificates

cardano-cli/src/Cardano/CLI/Compatible/Transaction/TxOut.hs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
module Cardano.CLI.Compatible.Transaction.TxOut
77
( mkTxOut
88
, toTxOutInAnyEra
9-
, convertLegacyTxOut
109
)
1110
where
1211

@@ -28,40 +27,27 @@ import Data.Map.Strict qualified as Map
2827
toTxOutInAnyEra
2928
:: ShelleyBasedEra era
3029
-> TxOutAnyEra
31-
-> CIO e (TxOut CtxTx era)
30+
-> CIO e (Exp.TxOut (ShelleyLedgerEra era), Map DataHash (L.Data (ShelleyLedgerEra era)))
3231
toTxOutInAnyEra era (TxOutAnyEra addr' val' mDatumHash refScriptFp) = do
3332
let addr = anyAddressInShelleyBasedEra era addr'
3433
mkTxOut era addr val' mDatumHash refScriptFp
3534

36-
-- | Convert a legacy 'TxOut CtxTx era' into the experimental 'Exp.TxOut' plus
37-
-- the supplemental datums it carried. The legacy 'TxOut CtxTx era' bundled
38-
-- supplemental datum bodies inside 'TxOutSupplementalDatum'; 'Exp.TxOut' only
39-
-- carries the datum hash, so the body is returned separately in the map for
40-
-- callers to thread into the witness set (e.g. via 'createCompatibleTx').
41-
convertLegacyTxOut
42-
:: ShelleyBasedEra era
43-
-> TxOut CtxTx era
44-
-> (Exp.TxOut (ShelleyLedgerEra era), Map DataHash (L.Data (ShelleyLedgerEra era)))
45-
convertLegacyTxOut sbe tOut@(TxOut _ _ d _) =
46-
shelleyBasedEraConstraints sbe $
47-
(Exp.TxOut (toShelleyTxOutAny sbe tOut), supplementalsOf d)
48-
where
49-
supplementalsOf
50-
:: L.Era (ShelleyLedgerEra era)
51-
=> TxOutDatum CtxTx era
52-
-> Map DataHash (L.Data (ShelleyLedgerEra era))
53-
supplementalsOf (TxOutSupplementalDatum _ h) =
54-
let ld = toAlonzoData h
55-
in Map.singleton (L.hashData ld) ld
56-
supplementalsOf _ = mempty
57-
35+
-- | Build an output for a transaction body. Produces the experimental
36+
-- 'Exp.TxOut' plus any supplemental datum bodies that the caller-supplied
37+
-- datum carries. The legacy 'TxOut CtxTx era' bundled supplemental datums
38+
-- inside outputs; 'Exp.TxOut' only carries the datum hash, so callers thread
39+
-- the full datum bodies in separately (e.g. via 'createCompatibleTx').
40+
--
41+
-- The legacy 'TxOut CtxTx era' is used internally as a stepping stone to
42+
-- reuse the api's 'toShelleyTxOutAny' field-level conversion logic; it is
43+
-- not exposed.
5844
mkTxOut
5945
:: ShelleyBasedEra era
6046
-> AddressInEra era
6147
-> Value
6248
-> TxOutDatumAnyEra
6349
-> ReferenceScriptAnyEra
64-
-> CIO e (TxOut CtxTx era)
50+
-> CIO e (Exp.TxOut (ShelleyLedgerEra era), Map DataHash (L.Data (ShelleyLedgerEra era)))
6551
mkTxOut sbe addr val' mDatumHash refScriptFp = do
6652
let era = toCardanoEra sbe
6753
val <- toTxOutValueInShelleyBasedEra sbe val'
@@ -78,7 +64,19 @@ mkTxOut sbe addr val' mDatumHash refScriptFp = do
7864
(`getReferenceScript` refScriptFp)
7965
era
8066

81-
pure $ TxOut addr val datum refScript
67+
let legacyTxOut = TxOut addr val datum refScript
68+
pure $
69+
shelleyBasedEraConstraints sbe $
70+
(Exp.TxOut (toShelleyTxOutAny sbe legacyTxOut), supplementalsOf datum)
71+
where
72+
supplementalsOf
73+
:: L.Era (ShelleyLedgerEra era)
74+
=> TxOutDatum CtxTx era
75+
-> Map DataHash (L.Data (ShelleyLedgerEra era))
76+
supplementalsOf (TxOutSupplementalDatum _ h) =
77+
let ld = toAlonzoData h
78+
in Map.singleton (L.hashData ld) ld
79+
supplementalsOf _ = mempty
8280

8381
toTxOutValueInShelleyBasedEra
8482
:: ShelleyBasedEra era

cardano-cli/src/Cardano/CLI/EraBased/Query/Run.hs

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import Cardano.Api qualified as Api
4141
import Cardano.Api.Consensus qualified as Consensus
4242
import Cardano.Api.Experimental (obtainCommonConstraints)
4343
import Cardano.Api.Experimental qualified as Exp
44+
import Cardano.Api.Experimental.Tx qualified as Exp
4445
import Cardano.Api.Ledger (strictMaybeToMaybe)
4546
import Cardano.Api.Ledger qualified as L
4647
import Cardano.Api.Network qualified as Consensus
@@ -67,6 +68,7 @@ import Cardano.CLI.Type.Output qualified as O
6768
import Cardano.Crypto.Hash (hashToBytesAsHex)
6869
import Cardano.Ledger.Address qualified as L
6970
import Cardano.Ledger.Api.State.Query qualified as L
71+
import Cardano.Ledger.Api.Tx qualified as L
7072
import Cardano.Ledger.Conway.State (ChainAccountState (..))
7173
import Cardano.Slotting.EpochInfo (EpochInfo (..), epochInfoSlotToUTCTime, hoistEpochInfo)
7274
import Cardano.Slotting.Time (RelativeTime (..), toRelativeTime)
@@ -1191,7 +1193,7 @@ writeFilteredUTxOs era format mOutFile utxo = do
11911193
. Vary.on (\FormatCborBin -> CBOR.serialize $ toLedgerUTxO era utxo)
11921194
. Vary.on (\FormatCborHex -> Base16.encode . CBOR.serialize $ toLedgerUTxO era utxo)
11931195
. Vary.on (\FormatJson -> Json.encodeJson utxo)
1194-
. Vary.on (\FormatText -> strictTextToLazyBytestring $ filteredUTxOsToText utxo)
1196+
. Vary.on (\FormatText -> strictTextToLazyBytestring $ filteredUTxOsToText era utxo)
11951197
. Vary.on (\FormatYaml -> Json.encodeYaml utxo)
11961198
$ Vary.exhaustiveCase
11971199
)
@@ -1200,40 +1202,53 @@ writeFilteredUTxOs era format mOutFile utxo = do
12001202
. newExceptT
12011203
$ writeLazyByteStringOutput mOutFile output
12021204

1203-
filteredUTxOsToText :: UTxO era -> Text
1204-
filteredUTxOsToText (UTxO utxo) = do
1205-
mconcat
1206-
[ Text.unlines [title, Text.replicate (Text.length title + 2) "-"]
1207-
, Text.unlines $
1208-
map utxoToText $
1209-
toList utxo
1210-
]
1205+
filteredUTxOsToText :: ShelleyBasedEra era -> UTxO era -> Text
1206+
filteredUTxOsToText sbe utxo =
1207+
shelleyBasedEraConstraints sbe $
1208+
let entries =
1209+
[ (fromShelleyTxIn ledgerTxIn, Exp.TxOut ledgerTxOut)
1210+
| (ledgerTxIn, ledgerTxOut) <- Map.toList . L.unUTxO $ toLedgerUTxO sbe utxo
1211+
]
1212+
in mconcat
1213+
[ Text.unlines [title, Text.replicate (Text.length title + 2) "-"]
1214+
, Text.unlines $ map (utxoToText sbe) entries
1215+
]
12111216
where
12121217
title :: Text
12131218
title =
12141219
" TxHash TxIx Amount"
12151220

12161221
utxoToText
1217-
:: (TxIn, TxOut CtxUTxO era)
1222+
:: ShelleyBasedEra era
1223+
-> (TxIn, Exp.TxOut (ShelleyLedgerEra era))
12181224
-> Text
1219-
utxoToText txInOutTuple =
1220-
let (TxIn (TxId txhash) (TxIx index), TxOut _ value mDatum _) = txInOutTuple
1221-
in mconcat
1222-
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1223-
, textShowN 6 index
1224-
, " " <> printableValue value <> " + " <> Text.pack (show mDatum)
1225-
]
1225+
utxoToText sbe (TxIn (TxId txhash) (TxIx index), Exp.TxOut ledgerTxOut) =
1226+
shelleyBasedEraConstraints sbe $
1227+
mconcat
1228+
[ Text.decodeLatin1 (hashToBytesAsHex txhash)
1229+
, textShowN 6 index
1230+
, " " <> printableValue <> " + " <> printableDatum
1231+
]
12261232
where
12271233
textShowN :: Show a => Int -> a -> Text
12281234
textShowN len x =
12291235
let str = show x
12301236
slen = length str
12311237
in Text.pack $ replicate (max 1 (len - slen)) ' ' ++ str
12321238

1233-
printableValue :: TxOutValue era -> Text
1234-
printableValue = \case
1235-
TxOutValueByron (L.Coin i) -> Text.pack $ show i
1236-
TxOutValueShelleyBased sbe2 val -> renderValue $ Api.fromLedgerValue sbe2 val
1239+
printableValue :: Text
1240+
printableValue =
1241+
renderValue $ Api.fromLedgerValue sbe (ledgerTxOut ^. L.valueTxOutL)
1242+
1243+
-- Debug-style datum rendering — pre-Babbage outputs have no datum
1244+
-- representation we can read uniformly, so show the babbage+ ledger
1245+
-- datum where it exists and an empty placeholder otherwise.
1246+
printableDatum :: Text
1247+
printableDatum =
1248+
caseShelleyToAlonzoOrBabbageEraOnwards
1249+
(const "")
1250+
(\beo -> babbageEraOnwardsConstraints beo $ Text.pack $ show (ledgerTxOut ^. L.datumTxOutL))
1251+
sbe
12371252

12381253
runQueryStakePoolsCmd
12391254
:: ()

cardano-cli/src/Cardano/CLI/EraBased/Transaction/Run.hs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ toTxOutInEra
373373
toTxOutInEra (TxOutAnyEra addr' val' mDatumHash refScriptFp) = do
374374
let sbe = convert (Exp.useEra @era)
375375
addr = anyAddressInShelleyBasedEra sbe addr'
376-
o <- mkTxOut sbe addr val' mDatumHash refScriptFp
377-
pure $ obtainCommonConstraints (Exp.useEra @era) $ convertLegacyTxOut sbe o
376+
obtainCommonConstraints (Exp.useEra @era) $
377+
mkTxOut sbe addr val' mDatumHash refScriptFp
378378

379379
runTransactionBuildEstimateCmd
380380
:: forall era e
@@ -1185,8 +1185,8 @@ toTxOutInShelleyBasedEra
11851185
toTxOutInShelleyBasedEra (TxOutShelleyBasedEra addr' val' mDatumHash refScriptFp) = do
11861186
let sbe = convert (Exp.useEra @era)
11871187
addr = shelleyAddressInEra sbe addr'
1188-
o <- mkTxOut sbe addr val' mDatumHash refScriptFp
1189-
pure $ obtainCommonConstraints (Exp.useEra @era) $ convertLegacyTxOut sbe o
1188+
obtainCommonConstraints (Exp.useEra @era) $
1189+
mkTxOut sbe addr val' mDatumHash refScriptFp
11901190

11911191
-- TODO: Currently we specify the policyId with the '--mint' option on the cli
11921192
-- and we added a separate '--policy-id' parser that parses the policy id for the

cardano-cli/src/Cardano/CLI/Type/Error/TxValidationError.hs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ module Cardano.CLI.Type.Error.TxValidationError
1313
, validateScriptSupportedInEra
1414
, validateTxAuxScripts
1515
, validateRequiredSigners
16-
, validateTxReturnCollateral
1716
, validateTxScriptValidity
1817
, validateTxTotalCollateral
1918
, validateTxValidityLowerBound
@@ -88,14 +87,6 @@ validateTxTreasuryDonation mTreasuryDonation = do
8887

8988
Exp.obtainCommonConstraints (Exp.useEra @era) $ mkFeatured unTxTreasuryDonation
9089

91-
validateTxReturnCollateral
92-
:: IsEra era
93-
=> Maybe (TxOut CtxTx era)
94-
-> TxReturnCollateral CtxTx era
95-
validateTxReturnCollateral Nothing = TxReturnCollateralNone
96-
validateTxReturnCollateral (Just retColTxOut) = do
97-
TxReturnCollateral (convert useEra) retColTxOut
98-
9990
validateTxValidityLowerBound
10091
:: IsEra era
10192
=> Maybe SlotNo

0 commit comments

Comments
 (0)