@@ -21,17 +21,20 @@ import Cardano.Testnet
21
21
import Prelude
22
22
23
23
import Control.Monad
24
+ import Data.Bifunctor (second )
24
25
import Data.Default.Class
25
26
import qualified Data.Map.Strict as M
26
27
import Data.Proxy
27
28
import Data.Set (Set )
28
29
import GHC.Exts (IsList (.. ))
30
+ import GHC.Stack
29
31
import Lens.Micro
30
32
31
33
import Testnet.Components.Query
32
34
import Testnet.Property.Util (integrationRetryWorkspace )
33
35
import Testnet.Types
34
36
37
+ import Hedgehog
35
38
import Hedgehog (Property , (===) )
36
39
import qualified Hedgehog as H
37
40
import qualified Hedgehog.Extras.Test.Base as H
@@ -84,11 +87,19 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
84
87
85
88
let scriptData1 = unsafeHashableScriptData $ ScriptDataBytes " CAFEBABE"
86
89
scriptData2 = unsafeHashableScriptData $ ScriptDataBytes " DEADBEEF"
87
- txDatum1 =
90
+ scriptData3 = unsafeHashableScriptData $ ScriptDataBytes " FEEDCOFFEE"
91
+ -- 4e548d257ab5309e4d029426a502e5609f7b0dbd1ac61f696f8373bd2b147e23
92
+ H. noteShow_ $ hashScriptDataBytes scriptData1
93
+ -- 24f56ef6459a29416df2e89d8df944e29591220283f198d39f7873917b8fa7c1
94
+ H. noteShow_ $ hashScriptDataBytes scriptData2
95
+ -- 5e47eaf4f0a604fcc939076f74ce7ed59d1503738973522e4d9cb99db703dcb8
96
+ H. noteShow_ $ hashScriptDataBytes scriptData3
97
+ let txDatum1 =
88
98
TxOutDatumHash
89
99
(convert beo)
90
100
(hashScriptDataBytes scriptData1)
91
- txDatum2 = TxOutDatumInline (convert ceo) scriptData2
101
+ txDatum2 = TxOutDatumInline beo scriptData2
102
+ txDatum3 = TxOutSupplementalDatum (convert beo) scriptData3
92
103
93
104
-- Build a first transaction with txout supplemental data
94
105
tx1Utxo <- do
@@ -99,6 +110,7 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
99
110
txOuts =
100
111
[ TxOut addr1 txOutValue txDatum1 ReferenceScriptNone
101
112
, TxOut addr1 txOutValue txDatum2 ReferenceScriptNone
113
+ , TxOut addr1 txOutValue txDatum3 ReferenceScriptNone
102
114
]
103
115
104
116
-- build a transaction
@@ -110,7 +122,7 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
110
122
111
123
utxo <- UTxO <$> findAllUtxos epochStateView sbe
112
124
113
- BalancedTxBody _ txBody _ fee <-
125
+ BalancedTxBody _ txBody@ ( ShelleyTxBody _ lbody _ ( TxBodyScriptData _ ( L. TxDats' datums) _) _ _) _ fee <-
114
126
H. leftFail $
115
127
makeTransactionBodyAutoBalance
116
128
sbe
@@ -126,39 +138,56 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
126
138
Nothing -- keys override
127
139
H. noteShow_ fee
128
140
141
+ H. noteShowPretty_ lbody
142
+
143
+ let bodyScriptData = fromList . map fromAlonzoData $ M. elems datums :: Set HashableScriptData
144
+ -- TODO: only inline datum gets included here, but should be all of them
145
+ -- TODO what's the actual purpose of TxSupplementalDatum - can we remove it?
146
+ -- TODO adding all datums breaks script integrity hash, might have to manually compute it?
147
+ -- https://github.com/tweag/cooked-validators/blob/9cb80810d982c9eccd3f7710a996d20f944a95ec/src/Cooked/MockChain/GenerateTx/Body.hs#L127
148
+ --
149
+ -- TODO getDataHashBabbageTxOut excludes inline datums - WHY IT HAPPENS ONLY HERE BUT NOT WHEN CALLING CLI?
150
+
151
+ -- TODO add scriptData1 when datum can be provided to transaction building
152
+ [ scriptData2
153
+ , scriptData3
154
+ ]
155
+ === bodyScriptData
156
+
129
157
let tx = signShelleyTransaction sbe txBody [wit0]
130
158
txId <- H. noteShow . getTxId $ getTxBody tx
131
159
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
160
+ H. noteShowPretty_ tx
161
+
162
+ submitTx sbe connectionInfo tx
135
163
136
164
-- wait till transaction gets included in the block
137
165
_ <- waitForBlocks epochStateView 1
138
166
139
167
-- test if it's in UTxO set
140
168
utxo1 <- findAllUtxos epochStateView sbe
141
169
let txUtxo = M. filterWithKey (\ (TxIn txId' _) _ -> txId == txId') utxo1
142
- 3 === length txUtxo
170
+ 4 === length txUtxo
143
171
144
172
let chainTxOuts =
145
173
reverse
146
174
. drop 1
147
175
. reverse
148
- . map (fromCtxUTxOTxOut . snd )
176
+ . map snd
149
177
. toList
150
178
$ M. filterWithKey (\ (TxIn txId' _) _ -> txId == txId') utxo1
151
179
152
- txOuts === chainTxOuts
180
+ (toCtxUTxOTxOut <$> txOuts) === chainTxOuts
153
181
154
182
pure txUtxo
155
183
156
184
do
157
185
[(txIn1, _)] <- pure $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum1) $ toList tx1Utxo
186
+ -- H.noteShowPretty_ tx1Utxo
158
187
[(txIn2, _)] <- pure $ filter (\ (_, TxOut _ _ datum _) -> datum == txDatum2) $ toList tx1Utxo
159
188
160
- let scriptData3 = unsafeHashableScriptData $ ScriptDataBytes " C0FFEE"
161
- txDatum = TxOutDatumInline (convert ceo) scriptData3
189
+ let scriptData4 = unsafeHashableScriptData $ ScriptDataBytes " C0FFEE"
190
+ txDatum = TxOutDatumInline beo scriptData4
162
191
txOutValue = lovelaceToTxOutValue sbe 99_999_500
163
192
txOut = TxOut addr0 txOutValue txDatum ReferenceScriptNone
164
193
@@ -172,23 +201,34 @@ hprop_tx_supp_datum = integrationRetryWorkspace 2 "api-tx-supp-dat" $ \tempAbsBa
172
201
txBody@ (ShelleyTxBody _ _ _ (TxBodyScriptData _ (L. TxDats' datums) _) _ _) <-
173
202
H. leftFail $ createTransactionBody sbe content
174
203
let bodyScriptData = fromList . map fromAlonzoData $ M. elems datums :: Set HashableScriptData
175
- -- TODO why bodyScriptData is empty here?
176
204
[scriptData1, scriptData2, scriptData3] === bodyScriptData
177
205
178
206
let tx = signShelleyTransaction sbe txBody [wit1]
179
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