@@ -26,13 +26,14 @@ import qualified Data.Map.Strict as M
26
26
import Data.Proxy
27
27
import Data.Set (Set )
28
28
import GHC.Exts (IsList (.. ))
29
+ import GHC.Stack
29
30
import Lens.Micro
30
31
31
32
import Testnet.Components.Query
32
33
import Testnet.Property.Util (integrationRetryWorkspace )
33
34
import Testnet.Types
34
35
35
- import Hedgehog ( Property , (===) )
36
+ import Hedgehog
36
37
import qualified Hedgehog as H
37
38
import qualified Hedgehog.Extras.Test.Base as H
38
39
import qualified Hedgehog.Extras.Test.TestWatchdog as H
@@ -82,15 +83,22 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
82
83
executeLocalStateQueryExpr connectionInfo Net. VolatileTip $
83
84
fmap toLedgerEpochInfo <$> queryEraHistory
84
85
85
- let scriptData1 = unsafeHashableScriptData $ ScriptDataBytes " CAFEBABE"
86
- scriptData2 = unsafeHashableScriptData $ ScriptDataBytes " DEADBEEF"
87
- txDatum1 =
86
+ let scriptData1 = unsafeHashableScriptData $ ScriptDataBytes " HASH_1" -- hash
87
+ scriptData2 = unsafeHashableScriptData $ ScriptDataBytes " INLINE_1" -- inline
88
+ scriptData3 = unsafeHashableScriptData $ ScriptDataBytes " SUPPLEMENTAL_1" -- supplemental
89
+ -- 4e62677c3b9f3b247502efe39a85aadcc2f2d3a32aec544d62175ed86c57fe9b
90
+ H. noteShow_ $ hashScriptDataBytes scriptData1
91
+ -- c93bae5c7cb737e16eb224d1884e7fbe14dc038caf1b511e34a43e67d3eb9f63
92
+ H. noteShow_ $ hashScriptDataBytes scriptData2
93
+ -- 74ea77567269646d49e072bd83e701ff7e43574522ad90833bcfa554658c65bb
94
+ H. noteShow_ $ hashScriptDataBytes scriptData3
95
+ let txDatum1 =
88
96
TxOutDatumHash
89
97
(convert beo)
90
98
(hashScriptDataBytes scriptData1)
91
- txDatum2 = TxOutDatumInline (convert ceo) scriptData2
99
+ txDatum2 = TxOutDatumInline beo scriptData2
100
+ txDatum3 = TxOutSupplementalDatum (convert beo) scriptData3
92
101
93
- -- Build a first transaction with txout supplemental data
94
102
tx1Utxo <- do
95
103
txIn <- findLargestUtxoForPaymentKey epochStateView sbe wallet0
96
104
@@ -99,6 +107,7 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
99
107
txOuts =
100
108
[ TxOut addr1 txOutValue txDatum1 ReferenceScriptNone
101
109
, TxOut addr1 txOutValue txDatum2 ReferenceScriptNone
110
+ , TxOut addr1 txOutValue txDatum3 ReferenceScriptNone
102
111
]
103
112
104
113
-- build a transaction
@@ -110,7 +119,8 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
110
119
111
120
utxo <- UTxO <$> findAllUtxos epochStateView sbe
112
121
113
- BalancedTxBody _ txBody _ fee <-
122
+
123
+ BalancedTxBody _ txBody@ (ShelleyTxBody _ lbody _ (TxBodyScriptData _ (L. TxDats' datums) _) _ _) _ fee <-
114
124
H. leftFail $
115
125
makeTransactionBodyAutoBalance
116
126
sbe
@@ -126,69 +136,99 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
126
136
Nothing -- keys override
127
137
H. noteShow_ fee
128
138
139
+ H. noteShowPretty_ lbody
140
+
141
+ lbody ^. L. scriptIntegrityHashTxBodyL /== L. SNothing
142
+
143
+ let bodyScriptData = fromList . map fromAlonzoData $ M. elems datums :: Set HashableScriptData
144
+
145
+ -- Only supplemental datum are included here
146
+ [ scriptData3 ] === bodyScriptData
147
+
129
148
let tx = signShelleyTransaction sbe txBody [wit0]
130
149
txId <- H. noteShow . getTxId $ getTxBody tx
131
150
132
- H. evalIO (submitTxToNodeLocal connectionInfo ( TxInMode sbe tx)) >>= \ case
133
- Net.Tx. SubmitFail reason -> H. noteShow_ reason >> H. failure
134
- Net.Tx. SubmitSuccess -> H. success
151
+ H. noteShowPretty_ tx
152
+
153
+ submitTx sbe connectionInfo tx
135
154
136
155
-- wait till transaction gets included in the block
137
156
_ <- waitForBlocks epochStateView 1
138
157
139
158
-- test if it's in UTxO set
140
159
utxo1 <- findAllUtxos epochStateView sbe
141
160
let txUtxo = M. filterWithKey (\ (TxIn txId' _) _ -> txId == txId') utxo1
142
- 3 === length txUtxo
161
+ -- H.noteShowPretty_ txUtxo
162
+ (length txOuts + 1 ) === length txUtxo
143
163
144
164
let chainTxOuts =
145
165
reverse
146
166
. drop 1
147
167
. reverse
148
- . map (fromCtxUTxOTxOut . snd )
168
+ . map snd
149
169
. toList
150
170
$ M. filterWithKey (\ (TxIn txId' _) _ -> txId == txId') utxo1
151
171
152
- txOuts === chainTxOuts
172
+ (toCtxUTxOTxOut <$> txOuts) === chainTxOuts
153
173
154
174
pure txUtxo
155
175
156
176
do
157
- [(txIn1, _)] <- pure $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum1) $ toList tx1Utxo
158
- [(txIn2, _)] <- pure $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum2) $ toList tx1Utxo
177
+ let txDatum3' = TxOutDatumHash (convert beo) (hashScriptDataBytes scriptData3)
178
+ [(txIn1, _)] <- H. noteShowPretty $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum1) $ toList tx1Utxo
179
+ [(txIn2, _)] <- H. noteShowPretty $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum2) $ toList tx1Utxo
180
+ [(txIn3, _)] <- H. noteShowPretty $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum3') $ toList tx1Utxo
159
181
160
- let scriptData3 = unsafeHashableScriptData $ ScriptDataBytes " C0FFEE "
161
- txDatum = TxOutDatumInline (convert ceo) scriptData3
182
+ let scriptData4 = unsafeHashableScriptData $ ScriptDataBytes " SUPPLEMENTAL_2 "
183
+ txDatum = TxOutSupplementalDatum (convert beo) scriptData4
162
184
txOutValue = lovelaceToTxOutValue sbe 99_999_500
163
185
txOut = TxOut addr0 txOutValue txDatum ReferenceScriptNone
186
+ txInsReference = TxInsReference beo [txIn1, txIn3] $ pure [scriptData1, scriptData3, scriptData4]
164
187
165
188
let content =
166
189
defaultTxBodyContent sbe
167
- & setTxIns [(txIn1 , pure $ KeyWitness KeyWitnessForSpending )]
168
- & setTxInsReference ( TxInsReference beo [txIn2])
190
+ & setTxIns [(txIn2 , pure $ KeyWitness KeyWitnessForSpending )]
191
+ & setTxInsReference txInsReference
169
192
& setTxFee (TxFeeExplicit sbe 500 )
170
193
& setTxOuts [txOut]
194
+ & setTxProtocolParams (pure $ pure pparams)
171
195
172
- txBody@ (ShelleyTxBody _ _ _ (TxBodyScriptData _ (L. TxDats' datums) _) _ _) <-
196
+ txBody@ (ShelleyTxBody _ lbody _ (TxBodyScriptData _ (L. TxDats' datums) _) _ _) <-
173
197
H. leftFail $ createTransactionBody sbe content
198
+
174
199
let bodyScriptData = fromList . map fromAlonzoData $ M. elems datums :: Set HashableScriptData
175
- -- TODO why bodyScriptData is empty here?
176
- [scriptData1, scriptData2, scriptData3] === bodyScriptData
200
+ [scriptData1, scriptData3, scriptData4] === bodyScriptData
201
+
202
+ H. noteShowPretty_ txBody
203
+
204
+ lbody ^. L. scriptIntegrityHashTxBodyL /== L. SNothing
177
205
178
206
let tx = signShelleyTransaction sbe txBody [wit1]
179
- -- H.noteShowPretty_ tx
207
+ H. noteShowPretty_ tx
180
208
txId <- H. noteShow . getTxId $ getTxBody tx
181
209
182
- H. evalIO (submitTxToNodeLocal connectionInfo (TxInMode sbe tx)) >>= \ case
183
- Net.Tx. SubmitFail reason -> H. noteShow_ reason >> H. failure
184
- Net.Tx. SubmitSuccess -> H. success
210
+ submitTx sbe connectionInfo tx
185
211
186
212
-- wait till transaction gets included in the block
187
213
_ <- waitForBlocks epochStateView 1
188
214
189
215
-- test if it's in UTxO set
190
216
utxo1 <- findAllUtxos epochStateView sbe
191
217
let txUtxo = M. filterWithKey (\ (TxIn txId' _) _ -> txId == txId') utxo1
192
- [txOut] === M. elems txUtxo
218
+ [toCtxUTxOTxOut txOut] === M. elems txUtxo
193
219
194
220
H. failure
221
+
222
+ submitTx
223
+ :: MonadTest m
224
+ => MonadIO m
225
+ => HasCallStack
226
+ => ShelleyBasedEra era
227
+ -> LocalNodeConnectInfo
228
+ -> Tx era
229
+ -> m ()
230
+ submitTx sbe connectionInfo tx =
231
+ withFrozenCallStack $
232
+ H. evalIO (submitTxToNodeLocal connectionInfo (TxInMode sbe tx)) >>= \ case
233
+ Net.Tx. SubmitFail reason -> H. noteShowPretty_ reason >> H. failure
234
+ Net.Tx. SubmitSuccess -> H. success
0 commit comments