Skip to content

Commit 2c89086

Browse files
committed
submitTx test
1 parent 724d4b4 commit 2c89086

File tree

2 files changed

+102
-10
lines changed

2 files changed

+102
-10
lines changed

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Rpc/Query.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,6 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
177177
-- Test readUtxos response
178178
--------------------------
179179

180-
H.noteShowPretty $ utxos
181-
H.noteShowPretty $ utxosResponse
180+
_ <- H.noteShowPretty $ utxos
181+
_ <- H.noteShowPretty $ utxosResponse
182182
H.failure
Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
{-# LANGUAGE DataKinds #-}
22
{-# LANGUAGE NamedFieldPuns #-}
3+
{-# LANGUAGE NumericUnderscores #-}
34
{-# LANGUAGE OverloadedLabels #-}
45
{-# LANGUAGE OverloadedLists #-}
56
{-# LANGUAGE OverloadedStrings #-}
67
{-# LANGUAGE ScopedTypeVariables #-}
78
{-# LANGUAGE TypeApplications #-}
9+
{-# LANGUAGE TypeOperators #-}
810

911
module Cardano.Testnet.Test.Rpc.Transaction
1012
( hprop_rpc_transaction
@@ -13,41 +15,54 @@ where
1315

1416
import Cardano.Api
1517
import qualified Cardano.Api.Ledger as L
18+
import qualified Cardano.Api.Parser.Text as P
1619

1720
import Cardano.CLI.Type.Output (QueryTipLocalStateOutput (..))
1821
import qualified Cardano.Ledger.Api as L
1922
import qualified Cardano.Ledger.Binary.Version as L
2023
import qualified Cardano.Ledger.Conway.Core as L
2124
import qualified Cardano.Ledger.Conway.PParams as L
2225
import qualified Cardano.Ledger.Plutus as L
26+
import Cardano.Rpc.Client (Proto)
2327
import qualified Cardano.Rpc.Client as Rpc
2428
import qualified Cardano.Rpc.Proto.Api.UtxoRpc.Query as UtxoRpc
29+
import qualified Cardano.Rpc.Proto.Api.UtxoRpc.Submit as UtxoRpc
2530
import Cardano.Rpc.Server.Internal.UtxoRpc.Query ()
31+
import Cardano.Rpc.Server.Internal.UtxoRpc.Type
2632
import Cardano.Testnet
2733

2834
import Prelude
2935

36+
import Control.Monad
37+
import Control.Monad.Fix
3038
import qualified Data.ByteString.Short as SBS
3139
import Data.Default.Class
3240
import qualified Data.Map.Strict as M
41+
import Data.Maybe
42+
import qualified Data.Text.Encoding as T
43+
import GHC.Stack
3344
import Lens.Micro
3445

3546
import Testnet.Components.Query
3647
import Testnet.Process.Run
3748
import Testnet.Property.Util (integrationRetryWorkspace)
3849
import Testnet.Start.Types
50+
import Testnet.Types
3951

4052
import Hedgehog
4153
import qualified Hedgehog as H
4254
import qualified Hedgehog.Extras.Test.Base as H
4355
import qualified Hedgehog.Extras.Test.TestWatchdog as H
4456

57+
import RIO (threadDelay)
58+
4559
hprop_rpc_transaction :: Property
4660
hprop_rpc_transaction = integrationRetryWorkspace 2 "rpc-tx" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
4761
conf@Conf{tempAbsPath} <- mkConf tempAbsBasePath'
4862
let tempAbsPath' = unTmpAbsPath tempAbsPath
4963

50-
let ceo = ConwayEraOnwardsConway
64+
let (ceo, eraProxy) =
65+
(conwayBasedEra, asType) :: era ~ ConwayEra => (ConwayEraOnwards era, AsType era)
5166
sbe = convert ceo
5267
eraName = eraToString sbe
5368
options = def{cardanoNodeEra = AnyShelleyBasedEra sbe, cardanoEnableRpc = True}
@@ -56,29 +71,106 @@ hprop_rpc_transaction = integrationRetryWorkspace 2 "rpc-tx" $ \tempAbsBasePath'
5671
{ testnetMagic
5772
, configurationFile
5873
, testnetNodes = node0@TestnetNode{nodeSprocket} : _
74+
, wallets = wallet0@(PaymentKeyInfo _ addrTxt0) : (PaymentKeyInfo _ addrTxt1) : _
5975
} <-
6076
createAndRunTestnet options def conf
6177

6278
execConfig <- mkExecConfig tempAbsPath' nodeSprocket testnetMagic
6379
epochStateView <- getEpochStateView configurationFile (nodeSocketPath node0)
64-
pparams <- unLedgerProtocolParameters <$> getProtocolParams epochStateView ceo
65-
-- H.noteShowPretty_ pparams
66-
utxos <- findAllUtxos epochStateView sbe
67-
H.noteShowPretty_ utxos
80+
6881
rpcSocket <- H.note . unFile $ nodeRpcSocketPath node0
6982

83+
-- prepare tx inputs and output address
84+
H.noteShow_ addrTxt0
85+
addr0 <- H.nothingFail $ deserialiseAddress (AsAddressInEra eraProxy) addrTxt0
86+
87+
H.noteShow_ addrTxt1
88+
addr1 <- H.nothingFail $ deserialiseAddress (AsAddressInEra eraProxy) addrTxt1
89+
90+
-- read key witnesses
91+
wit0 :: ShelleyWitnessSigningKey <-
92+
H.leftFailM . H.evalIO $
93+
readFileTextEnvelopeAnyOf
94+
[FromSomeType asType WitnessGenesisUTxOKey]
95+
(signingKey $ paymentKeyInfoPair wallet0)
96+
7097
--------------
7198
-- RPC queries
7299
--------------
73100
let rpcServer = Rpc.ServerUnix rpcSocket
74101
(pparamsResponse, utxosResponse) <- H.noteShowM . H.evalIO . Rpc.withConnection def rpcServer $ \conn -> do
75102
pparams' <- do
76-
let req = Rpc.defMessage
103+
let req = def
77104
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readParams")) req
78105

79106
utxos' <- do
80-
let req = Rpc.defMessage
107+
let req = def & #addresses . #items .~ [T.encodeUtf8 addrTxt0]
81108
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readUtxos")) req
82109
pure (pparams', utxos')
83110

84-
H.failure
111+
pparams <- H.leftFail $ utxoRpcPParamsToProtocolParams (convert ceo) $ pparamsResponse ^. #values . #cardano
112+
113+
txOut0 : _ <- H.noteShow $ utxosResponse ^. #items
114+
txIn0 <- txoRefToTxIn $ txOut0 ^. #txoRef
115+
116+
let outputCoin = txOut0 ^. #cardano . #coin . to fromIntegral
117+
amount = 200_000_000
118+
fee = 500
119+
change = outputCoin - amount - fee
120+
txOut = TxOut addr1 (lovelaceToTxOutValue sbe $ L.Coin amount) TxOutDatumNone ReferenceScriptNone
121+
changeTxOut = TxOut addr0 (lovelaceToTxOutValue sbe $ L.Coin change) TxOutDatumNone ReferenceScriptNone
122+
content =
123+
defaultTxBodyContent sbe
124+
& setTxIns [(txIn0, pure $ KeyWitness KeyWitnessForSpending)]
125+
& setTxFee (TxFeeExplicit sbe 500)
126+
& setTxOuts [txOut, changeTxOut]
127+
& setTxProtocolParams (pure . pure $ LedgerProtocolParameters pparams)
128+
129+
txBody <- H.leftFail $ createTransactionBody sbe content
130+
131+
let signedTx = signShelleyTransaction sbe txBody [wit0]
132+
txId <- H.noteShow . getTxId $ getTxBody signedTx
133+
134+
H.noteShowPretty_ utxosResponse
135+
136+
(utxos, submitResponse) <- H.noteShowM . H.evalIO . Rpc.withConnection def rpcServer $ \conn -> do
137+
submitResponse <-
138+
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.SubmitService "submitTx")) $
139+
def & #tx .~ [def & #raw .~ serialiseToCBOR signedTx]
140+
141+
fix $ \loop -> do
142+
resp <- Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readParams")) def
143+
144+
let previousBlockNo = pparamsResponse ^. #ledgerTip . #height
145+
currentBlockNo = resp ^. #ledgerTip . #height
146+
-- wait for 2 blocks
147+
when (previousBlockNo + 1 >= currentBlockNo) $ do
148+
threadDelay 500_000
149+
loop
150+
151+
utxos <-
152+
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readUtxos")) $
153+
def & #addresses . #items .~ [T.encodeUtf8 addrTxt1]
154+
pure (utxos, submitResponse)
155+
156+
submittedTxIds <- forM (submitResponse ^. #results) $ \res -> do
157+
let mErr = res ^. #maybe'errorMessage
158+
mTxId = res ^. #maybe'ref
159+
case (mErr, mTxId) of
160+
(Just err, Nothing) -> H.noteShow_ err >> H.failure
161+
(Nothing, Just txId) ->
162+
H.leftFail $ deserialiseFromRawBytes AsTxId txId
163+
_ -> do
164+
H.note_ $ "Protocol error: " <> show res
165+
H.failure
166+
167+
[txId] === submittedTxIds
168+
169+
2 === length (utxos ^. #items)
170+
let utxo0:_ = utxos ^. #items
171+
fromIntegral amount === utxo0 ^. #cardano . #coin
172+
173+
txoRefToTxIn :: (HasCallStack, MonadTest m) => Proto UtxoRpc.TxoRef -> m TxIn
174+
txoRefToTxIn r = withFrozenCallStack $ do
175+
txId' <- H.leftFail $ deserialiseFromRawBytes AsTxId $ r ^. #hash
176+
pure $ TxIn txId' (TxIx . fromIntegral $ r ^. #index)

0 commit comments

Comments
 (0)