Skip to content

Commit 52c9854

Browse files
authored
Merge pull request #1112 from IntersectMBO/jordan/supplemental-datum-fix
Fix supplemental datum handling in experimental API
2 parents a7bd74d + 59e5004 commit 52c9854

3 files changed

Lines changed: 43 additions & 21 deletions

File tree

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ module Cardano.Api.Experimental.Tx
147147
, setTxProposalProcedures
148148
, setTxProtocolParams
149149
, setTxScriptValidity
150+
, setTxSupplementalDatums
150151
, setTxTreasuryDonation
151152
, setTxValidityLowerBound
152153
, setTxValidityUpperBound
@@ -157,6 +158,7 @@ module Cardano.Api.Experimental.Tx
157158
, DatumDecodingError (..)
158159
, legacyDatumToDatum
159160
, fromLegacyTxOut
161+
, supplementalDatumFromLegacy
160162

161163
-- * TxBodyContent sub type
162164
, TxCertificates (..)

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

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New
5151
, setTxProposalProcedures
5252
, setTxProtocolParams
5353
, setTxScriptValidity
54+
, setTxSupplementalDatums
5455
, setTxTreasuryDonation
5556
, setTxValidityLowerBound
5657
, setTxValidityUpperBound
@@ -64,6 +65,7 @@ module Cardano.Api.Experimental.Tx.Internal.BodyContent.New
6465
, DatumDecodingError (..)
6566
, legacyDatumToDatum
6667
, fromLegacyTxOut
68+
, supplementalDatumFromLegacy
6769
)
6870
where
6971

@@ -363,11 +365,27 @@ legacyDatumToDatum (OldApi.TxOutDatumInline _ hd) = do
363365
legacyDatumToDatum OldApi.TxOutDatumNone = Nothing
364366

365367
fromLegacyTxOut
366-
:: forall era. IsEra era => OldApi.TxOut CtxTx era -> Either DatumDecodingError (TxOut (LedgerEra era))
368+
:: forall era
369+
. IsEra era
370+
=> OldApi.TxOut CtxTx era
371+
-> Either DatumDecodingError (TxOut (LedgerEra era), Map L.DataHash (L.Data (LedgerEra era)))
367372
fromLegacyTxOut tOut@(OldApi.TxOut _ _ d _) = do
368373
let o = OldApi.toShelleyTxOutAny (convert $ useEra @era) tOut
369374
newDatum :: L.Datum (LedgerEra era) <- obtainCommonConstraints (useEra @era) $ toLedgerDatum d
370-
return $ obtainCommonConstraints (useEra @era) $ TxOut $ o & L.datumTxOutL .~ newDatum
375+
let txOut = obtainCommonConstraints (useEra @era) $ TxOut $ o & L.datumTxOutL .~ newDatum
376+
suppDats = obtainCommonConstraints (useEra @era) $ supplementalDatumFromLegacy d
377+
return (txOut, suppDats)
378+
379+
-- | Extract supplemental datum data from a legacy 'TxOutDatum'.
380+
-- Returns 'mempty' for non-supplemental datums.
381+
supplementalDatumFromLegacy
382+
:: L.Era (LedgerEra era)
383+
=> OldApi.TxOutDatum CtxTx era
384+
-> Map L.DataHash (L.Data (LedgerEra era))
385+
supplementalDatumFromLegacy (OldApi.TxOutSupplementalDatum _ h) =
386+
let ledgerData = Api.toAlonzoData h
387+
in fromList [(L.hashData ledgerData, ledgerData)]
388+
supplementalDatumFromLegacy _ = mempty
371389

372390
newtype DatumDecodingError = DatumDecodingError String
373391
deriving (Show, Eq)
@@ -381,9 +399,7 @@ toLedgerDatum
381399
toLedgerDatum OldApi.TxOutDatumNone = Right L.NoDatum
382400
toLedgerDatum (OldApi.TxOutDatumHash _ (Api.ScriptDataHash h)) = Right $ L.DatumHash h
383401
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
402+
Right $ L.DatumHash (Api.unScriptDataHash $ Api.hashScriptDataBytes h)
387403
toLedgerDatum (OldApi.TxOutDatumInline _ h) =
388404
case L.makeBinaryData $ SBS.toShort $ Api.getOriginalScriptDataBytes h of
389405
Left e -> Left $ DatumDecodingError e
@@ -538,6 +554,9 @@ data TxBodyContent era
538554
-- ^ Current treasury value
539555
, txTreasuryDonation :: Maybe L.Coin
540556
-- ^ Treasury donation to perform
557+
, txSupplementalDatums :: Map L.DataHash (L.Data era)
558+
-- ^ Supplemental datums are datums whose hashes correspond to output datum hashes.
559+
-- They are included in the transaction witness set for communication purposes only.
541560
}
542561

543562
defaultTxBodyContent
@@ -565,6 +584,7 @@ defaultTxBodyContent =
565584
, txVotingProcedures = Nothing
566585
, txCurrentTreasuryValue = Nothing
567586
, txTreasuryDonation = Nothing
587+
, txSupplementalDatums = mempty
568588
}
569589

570590
extractAllIndexedPlutusScriptWitnesses
@@ -704,18 +724,18 @@ collectTxBodyScriptWitnessRequirements
704724
TxBodyContent
705725
{ txIns
706726
, txInsReference
707-
, txOuts
708727
, txCertificates
709728
, txMintValue
710729
, txWithdrawals
711730
, txVotingProcedures
712731
, txProposalProcedures
732+
, txSupplementalDatums
713733
} = obtainCommonConstraints (useEra @era) $ do
714734
let supplementaldatums =
715735
TxScriptWitnessRequirements
716736
mempty
717737
mempty
718-
(getDatums txInsReference txOuts)
738+
(getDatums txInsReference txSupplementalDatums)
719739
mempty
720740

721741
let txInWits =
@@ -756,34 +776,30 @@ obtainMonoidConstraint eon = case eon of
756776
ConwayEra -> id
757777
DijkstraEra -> id
758778

759-
-- | Extract datum:
760-
-- 1. supplemental datums from transaction outputs
779+
-- | Collect datums for the transaction witness set ('TxDats'):
780+
-- 1. supplemental datums provided explicitly
761781
-- 2. datums from reference inputs
762782
--
783+
-- Supplemental datums are datums whose hashes correspond to datum hashes
784+
-- in transaction outputs. They are included for communication purposes only
785+
-- (the Alonzo ledger spec uses subset equality for these).
786+
--
763787
-- Note that this function does not check whose datum hashes are present in the reference inputs. This means if there
764788
-- are redundant datums in 'TxInsReference', a submission of such transaction will fail.
765789
getDatums
766790
:: forall era
767791
. IsEra era
768792
=> TxInsReference (LedgerEra era)
769793
-- ^ reference inputs
770-
-> [TxOut (LedgerEra era)]
794+
-> Map L.DataHash (L.Data (LedgerEra era))
795+
-- ^ supplemental datums
771796
-> L.TxDats (LedgerEra era)
772-
getDatums txInsRef txOutsFromTx = do
797+
getDatums txInsRef supplementalDats = do
773798
let TxInsReference _ datumSet = txInsRef
774799
refInDatums = mapMaybe extractDatumsAndHashes $ Set.toList datumSet
775-
-- use only supplemental datum
776-
txOutsDats =
777-
[ (L.hashData d, d)
778-
| TxOut txout <- txOutsFromTx
779-
, d <-
780-
maybeToList $ L.strictMaybeToMaybe $ txout ^. obtainCommonConstraints (useEra @era) L.dataTxOutL
781-
]
782-
:: [(L.DataHash, L.Data (LedgerEra era))]
783800
obtainCommonConstraints (useEra @era) $
784801
L.TxDats $
785-
fromList $
786-
refInDatums <> txOutsDats
802+
fromList refInDatums <> supplementalDats
787803

788804
-- Getters and Setters
789805

@@ -850,6 +866,9 @@ setTxCurrentTreasuryValue v txBodyContent = txBodyContent{txCurrentTreasuryValue
850866
setTxTreasuryDonation :: L.Coin -> TxBodyContent era -> TxBodyContent era
851867
setTxTreasuryDonation v txBodyContent = txBodyContent{txTreasuryDonation = Just v}
852868

869+
setTxSupplementalDatums :: Map L.DataHash (L.Data era) -> TxBodyContent era -> TxBodyContent era
870+
setTxSupplementalDatums v txBodyContent = txBodyContent{txSupplementalDatums = v}
871+
853872
modTxOuts
854873
:: ([TxOut era] -> [TxOut era]) -> TxBodyContent era -> TxBodyContent era
855874
modTxOuts f txBodyContent = txBodyContent{txOuts = f (txOuts txBodyContent)}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,7 @@ substituteExecutionUnits
733733
txVotingProcedures
734734
_
735735
_
736+
_
736737
) = do
737738
mappedTxIns <- mapScriptWitnessesTxIns txIns
738739
mappedWithdrawals <- mapScriptWitnessesWithdrawals txWithdrawals

0 commit comments

Comments
 (0)