@@ -301,6 +301,8 @@ module Cardano.Api.Internal.Tx.Body
301
301
-- ** Other transaction body types
302
302
, TxInsCollateral (.. )
303
303
, TxInsReference (.. )
304
+ , TxInsReferenceDatums
305
+ , getReferenceInputDatumMap
304
306
, TxReturnCollateral (.. )
305
307
, TxTotalCollateral (.. )
306
308
, TxFee (.. )
@@ -570,16 +572,31 @@ deriving instance Eq (TxTotalCollateral era)
570
572
571
573
deriving instance Show (TxTotalCollateral era )
572
574
573
- data TxInsReference era where
574
- TxInsReferenceNone :: TxInsReference era
575
+ data TxInsReference build era where
576
+ TxInsReferenceNone :: TxInsReference build era
575
577
TxInsReference
576
578
:: BabbageEraOnwards era
577
579
-> [TxIn ]
578
- -> TxInsReference era
580
+ -- ^ A list of reference inputs
581
+ -> TxInsReferenceDatums build
582
+ -- ^ A set of datums, whose hashes are referenced in UTXO of reference inputs. Those datums will be inserted
583
+ -- to the datum map available to the scripts. Note that inserting a datum with hash not present in the reference
584
+ -- input will result in an error on transaction submission.
585
+ -> TxInsReference build era
579
586
580
- deriving instance Eq (TxInsReference era )
587
+ deriving instance Eq (TxInsReference build era )
581
588
582
- deriving instance Show (TxInsReference era )
589
+ deriving instance Show (TxInsReference build era )
590
+
591
+ -- | The actual datums, referenced by hash in the transaction reference inputs.
592
+ type TxInsReferenceDatums build = BuildTxWith build (Set HashableScriptData )
593
+
594
+ getReferenceInputDatumMap
595
+ :: TxInsReferenceDatums build
596
+ -> Map (Hash ScriptData ) HashableScriptData
597
+ getReferenceInputDatumMap = \ case
598
+ ViewTx -> mempty
599
+ BuildTxWith datumSet -> fromList $ map (\ h -> (hashScriptDataBytes h, h)) $ toList datumSet
583
600
584
601
-- ----------------------------------------------------------------------------
585
602
-- Transaction fees
@@ -984,7 +1001,7 @@ data TxBodyContent build era
984
1001
= TxBodyContent
985
1002
{ txIns :: TxIns build era
986
1003
, txInsCollateral :: TxInsCollateral era
987
- , txInsReference :: TxInsReference era
1004
+ , txInsReference :: TxInsReference build era
988
1005
, txOuts :: [TxOut CtxTx era ]
989
1006
, txTotalCollateral :: TxTotalCollateral era
990
1007
, txReturnCollateral :: TxReturnCollateral CtxTx era
@@ -1075,25 +1092,36 @@ addTxInCollateral
1075
1092
:: IsAlonzoBasedEra era => TxIn -> TxBodyContent build era -> TxBodyContent build era
1076
1093
addTxInCollateral txInCollateral = addTxInsCollateral [txInCollateral]
1077
1094
1078
- setTxInsReference :: TxInsReference era -> TxBodyContent build era -> TxBodyContent build era
1095
+ setTxInsReference :: TxInsReference build era -> TxBodyContent build era -> TxBodyContent build era
1079
1096
setTxInsReference v txBodyContent = txBodyContent{txInsReference = v}
1080
1097
1081
1098
modTxInsReference
1082
- :: (TxInsReference era -> TxInsReference era ) -> TxBodyContent build era -> TxBodyContent build era
1099
+ :: (TxInsReference build era -> TxInsReference build era )
1100
+ -> TxBodyContent build era
1101
+ -> TxBodyContent build era
1083
1102
modTxInsReference f txBodyContent = txBodyContent{txInsReference = f (txInsReference txBodyContent)}
1084
1103
1085
1104
addTxInsReference
1086
- :: IsBabbageBasedEra era => [TxIn ] -> TxBodyContent build era -> TxBodyContent build era
1087
- addTxInsReference txInsReference =
1088
- modTxInsReference
1089
- ( \ case
1090
- TxInsReferenceNone -> TxInsReference babbageBasedEra txInsReference
1091
- TxInsReference era xs -> TxInsReference era (xs <> txInsReference)
1092
- )
1105
+ :: Applicative (BuildTxWith build )
1106
+ => IsBabbageBasedEra era
1107
+ => [TxIn ]
1108
+ -> Set HashableScriptData
1109
+ -> TxBodyContent build era
1110
+ -> TxBodyContent build era
1111
+ addTxInsReference txInsReference scriptData =
1112
+ modTxInsReference $
1113
+ \ case
1114
+ TxInsReferenceNone -> TxInsReference babbageBasedEra txInsReference (pure scriptData)
1115
+ TxInsReference era xs bScriptData' -> TxInsReference era (xs <> txInsReference) ((<> scriptData) <$> bScriptData')
1093
1116
1094
1117
addTxInReference
1095
- :: IsBabbageBasedEra era => TxIn -> TxBodyContent build era -> TxBodyContent build era
1096
- addTxInReference txInReference = addTxInsReference [txInReference]
1118
+ :: Applicative (BuildTxWith build )
1119
+ => IsBabbageBasedEra era
1120
+ => TxIn
1121
+ -> Maybe HashableScriptData
1122
+ -> TxBodyContent build era
1123
+ -> TxBodyContent build era
1124
+ addTxInReference txInReference mDatum = addTxInsReference [txInReference] . fromList $ maybeToList mDatum
1097
1125
1098
1126
setTxOuts :: [TxOut CtxTx era ] -> TxBodyContent build era -> TxBodyContent build era
1099
1127
setTxOuts v txBodyContent = txBodyContent{txOuts = v}
@@ -1742,11 +1770,11 @@ fromLedgerTxInsCollateral sbe body =
1742
1770
sbe
1743
1771
1744
1772
fromLedgerTxInsReference
1745
- :: ShelleyBasedEra era -> Ledger. TxBody (ShelleyLedgerEra era ) -> TxInsReference era
1773
+ :: ShelleyBasedEra era -> Ledger. TxBody (ShelleyLedgerEra era ) -> TxInsReference ViewTx era
1746
1774
fromLedgerTxInsReference sbe txBody =
1747
1775
caseShelleyToAlonzoOrBabbageEraOnwards
1748
1776
(const TxInsReferenceNone )
1749
- (\ w -> TxInsReference w $ map fromShelleyTxIn . toList $ txBody ^. L. referenceInputsTxBodyL)
1777
+ (\ w -> TxInsReference w ( map fromShelleyTxIn . toList $ txBody ^. L. referenceInputsTxBodyL) ViewTx )
1750
1778
sbe
1751
1779
1752
1780
fromLedgerTxTotalCollateral
@@ -2108,11 +2136,11 @@ convPParamsToScriptIntegrityHash
2108
2136
-> Alonzo. TxDats (ShelleyLedgerEra era )
2109
2137
-> Set Plutus. Language
2110
2138
-> StrictMaybe L. ScriptIntegrityHash
2111
- convPParamsToScriptIntegrityHash w txProtocolParams redeemers datums languages =
2139
+ convPParamsToScriptIntegrityHash w ( BuildTxWith mTxProtocolParams) redeemers datums languages =
2112
2140
alonzoEraOnwardsConstraints w $
2113
- case txProtocolParams of
2114
- BuildTxWith Nothing -> SNothing
2115
- BuildTxWith ( Just (LedgerProtocolParameters pp) ) ->
2141
+ case mTxProtocolParams of
2142
+ Nothing -> SNothing
2143
+ Just (LedgerProtocolParameters pp) ->
2116
2144
Alonzo. hashScriptIntegrity (Set. map (L. getLanguageView pp) languages) redeemers datums
2117
2145
2118
2146
convLanguages :: [(ScriptWitnessIndex , AnyScriptWitness era )] -> Set Plutus. Language
@@ -2122,11 +2150,11 @@ convLanguages witnesses =
2122
2150
| (_, AnyScriptWitness (PlutusScriptWitness _ v _ _ _ _)) <- witnesses
2123
2151
]
2124
2152
2125
- convReferenceInputs :: TxInsReference era -> Set Ledger. TxIn
2153
+ convReferenceInputs :: TxInsReference build era -> Set Ledger. TxIn
2126
2154
convReferenceInputs txInsReference =
2127
2155
case txInsReference of
2128
2156
TxInsReferenceNone -> mempty
2129
- TxInsReference _ refTxins -> fromList $ map toShelleyTxIn refTxins
2157
+ TxInsReference _ refTxins _ -> fromList $ map toShelleyTxIn refTxins
2130
2158
2131
2159
-- | Returns an OSet of proposals from 'TxProposalProcedures'.
2132
2160
convProposalProcedures
@@ -2993,11 +3021,17 @@ collectTxBodyScriptWitnessRequirements
2993
3021
collectTxBodyScriptWitnessRequirements
2994
3022
aEon
2995
3023
bc@ TxBodyContent
2996
- { txOuts
3024
+ { txInsReference
3025
+ , txOuts
2997
3026
} =
2998
3027
obtainAlonzoScriptPurposeConstraints aEon $ do
2999
3028
let sbe = shelleyBasedEra @ era
3000
- supplementaldatums = TxScriptWitnessRequirements mempty mempty (getSupplementalDatums aEon txOuts) mempty
3029
+ supplementaldatums =
3030
+ TxScriptWitnessRequirements
3031
+ mempty
3032
+ mempty
3033
+ (getDatums aEon txInsReference txOuts)
3034
+ mempty
3001
3035
txInWits <-
3002
3036
first TxBodyPlutusScriptDecodeError $
3003
3037
legacyWitnessToScriptRequirements aEon $
@@ -3051,19 +3085,32 @@ collectTxBodyScriptWitnessRequirements
3051
3085
, txProposalWits
3052
3086
]
3053
3087
3054
- getSupplementalDatums
3088
+ -- | Extract datum:
3089
+ -- 1. supplemental datums from transaction outputs
3090
+ -- 2. datums from reference inputs
3091
+ --
3092
+ -- Note that this function does not check whose datum datum hashes are present in the reference inputs. This means
3093
+ -- if there are redundant datums in 'TxInsReference', a submission of such transaction will fail.
3094
+ getDatums
3055
3095
:: AlonzoEraOnwards era
3096
+ -> TxInsReference BuildTx era
3097
+ -- ^ reference inputs
3056
3098
-> [TxOut CtxTx era ]
3057
3099
-> L. TxDats (ShelleyLedgerEra era )
3058
- getSupplementalDatums eon [] = alonzoEraOnwardsConstraints eon mempty
3059
- getSupplementalDatums eon txouts =
3060
- alonzoEraOnwardsConstraints eon $
3061
- L. TxDats $
3062
- fromList
3063
- [ (L. hashData ledgerData, ledgerData)
3064
- | TxOut _ _ (TxOutSupplementalDatum _ d) _ <- txouts
3065
- , let ledgerData = toAlonzoData d
3100
+ getDatums eon txInsRef txOutsFromTx = alonzoEraOnwardsConstraints eon $ do
3101
+ let refTxInsDats =
3102
+ [ d
3103
+ | TxInsReference _ _ (BuildTxWith datumSet) <- [txInsRef]
3104
+ , d <- toList datumSet
3066
3105
]
3106
+ -- use only supplemental datum
3107
+ txOutsDats = [d | TxOut _ _ (TxOutSupplementalDatum _ d) _ <- txOutsFromTx]
3108
+ L. TxDats $
3109
+ fromList $
3110
+ [ (L. hashData ledgerData, ledgerData)
3111
+ | d <- refTxInsDats <> txOutsDats
3112
+ , let ledgerData = toAlonzoData d
3113
+ ]
3067
3114
3068
3115
extractWitnessableTxIns
3069
3116
:: AlonzoEraOnwards era
0 commit comments