Skip to content

Commit 8da9a7e

Browse files
authored
Merge pull request #6577 from IntersectMBO/mgalazyn/test/rewrite-rpc-test-exp
cardano-testnet | Rewrite rpc tests using experimental api
2 parents 9c20173 + 6c6e3fa commit 8da9a7e

4 files changed

Lines changed: 48 additions & 41 deletions

File tree

.github/workflows/haskell.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,13 @@ jobs:
9999
with:
100100
use-sodium-vrf: true # default is true
101101

102-
- name: Install gRPC dependencies
103-
uses: intersectmbo/cardano-api/.github/actions/grpc-deps@a7bd74dfa6ccb1eb04f69791f978a3b9e0cc63ca
102+
- name: Install gRPC system dependencies
103+
uses: input-output-hk/cardano-dev/actions/grpc-deps@grpc-deps-0.0.1.0
104104

105105
- uses: actions/checkout@v4
106106

107107
- name: Cache and install Cabal dependencies
108-
uses: intersectmbo/cardano-api/.github/actions/cabal-cache@a7bd74dfa6ccb1eb04f69791f978a3b9e0cc63ca
108+
uses: input-output-hk/cardano-dev/actions/cabal-cache@cabal-cache-0.0.1.0
109109
with:
110110
cabal-store: ${{ steps.setup-haskell.outputs.cabal-store }}
111111
cache-version: ${{ env.CABAL_CACHE_VERSION }}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### Changed
2+
3+
- Migrated RPC transaction and query tests from the old `Cardano.Api` transaction-building API to `Cardano.Api.Experimental`, using `Exp.ConwayEra` as the single era definition point, experimental tx body construction with direct ledger types, and `makeUnsignedTx`/`signTx` for transaction creation.

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ module Cardano.Testnet.Test.Rpc.Query
1111
where
1212

1313
import Cardano.Api
14+
import qualified Cardano.Api.Experimental as Exp
1415
import qualified Cardano.Api.Ledger as L
1516

1617
import Cardano.CLI.Type.Output (QueryTipLocalStateOutput (..))
@@ -50,8 +51,8 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
5051
conf@Conf{tempAbsPath} <- mkConf tempAbsBasePath'
5152
let tempAbsPath' = unTmpAbsPath tempAbsPath
5253

53-
let ceo = ConwayEraOnwardsConway
54-
sbe = convert ceo
54+
let era = Exp.ConwayEra
55+
sbe = convert era
5556
eraName = eraToString sbe
5657
creationOptions = def{creationEra = AnyShelleyBasedEra sbe}
5758
runtimeOptions = def{runtimeEnableRpc = RpcEnabled}
@@ -65,7 +66,7 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
6566

6667
execConfig <- mkExecConfig tempAbsPath' nodeSprocket testnetMagic
6768
epochStateView <- getEpochStateView configurationFile (nodeSocketPath node0)
68-
pparams <- unLedgerProtocolParameters <$> getProtocolParams epochStateView ceo
69+
pparams <- unLedgerProtocolParameters <$> getProtocolParams epochStateView (convert era)
6970
utxos <- findAllUtxos epochStateView sbe
7071
H.noteShowPretty_ utxos
7172
rpcSocket <- H.note . unFile $ nodeRpcSocketPath node0
@@ -103,7 +104,7 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
103104

104105
-- https://docs.cardano.org/about-cardano/explore-more/parameter-guide
105106
let chainParams = pparamsResponse ^. U5c.values . U5c.cardano
106-
babbageEraOnwardsConstraints (convert ceo) $ do
107+
Exp.obtainCommonConstraints era $ do
107108
pparams ^. L.ppCoinsPerUTxOByteL . to L.unCoinPerByte . to L.fromCompact . to L.unCoin
108109
===^ chainParams ^. U5c.coinsPerUtxoByte . to utxoRpcBigIntToInteger
109110
pparams ^. L.ppMaxTxSizeL === chainParams ^. U5c.maxTxSize . to fromIntegral
@@ -142,7 +143,7 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
142143
pparams ^. L.ppMinFeeRefScriptCostPerByteL . to L.unboundRational
143144
=== chainParams ^. U5c.minFeeScriptRefCostPerByte . to inject
144145
let poolVotingThresholds :: L.PoolVotingThresholds =
145-
conwayEraOnwardsConstraints ceo $
146+
conwayEraOnwardsConstraints (convert era) $
146147
pparams ^. L.ppPoolVotingThresholdsL
147148
( L.unboundRational
148149
<$> [ poolVotingThresholds ^. L.pvtMotionNoConfidenceL
@@ -154,7 +155,7 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
154155
)
155156
=== chainParams ^. U5c.poolVotingThresholds . U5c.thresholds . to (map inject)
156157
let drepVotingThresholds :: L.DRepVotingThresholds =
157-
conwayEraOnwardsConstraints ceo $
158+
conwayEraOnwardsConstraints (convert era) $
158159
pparams ^. L.ppDRepVotingThresholdsL
159160
( L.unboundRational
160161
<$> [ drepVotingThresholds ^. L.dvtMotionNoConfidenceL
@@ -183,7 +184,7 @@ hprop_rpc_query_pparams = integrationRetryWorkspace 2 "rpc-query-pparams" $ \tem
183184
-- Test readUtxos response
184185
--------------------------
185186

186-
utxoFromUtxoRpc <- H.leftFail $ utxosResponse ^. U5c.items . to (anyUtxoDataUtxoRpcToUtxo $ convert ceo)
187+
utxoFromUtxoRpc <- H.leftFail $ utxosResponse ^. U5c.items . to (anyUtxoDataUtxoRpcToUtxo era)
187188
utxos === utxoFromUtxoRpc
188189

189190
(===^) :: (Eq a, Show a, H.MonadTest m) => a -> Either SomeException a -> m ()

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

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
{-# LANGUAGE OverloadedStrings #-}
66
{-# LANGUAGE ScopedTypeVariables #-}
77
{-# LANGUAGE TypeApplications #-}
8-
{-# LANGUAGE TypeOperators #-}
98

109
module Cardano.Testnet.Test.Rpc.Transaction
1110
( hprop_rpc_transaction
1211
)
1312
where
1413

1514
import Cardano.Api
15+
import qualified Cardano.Api.Experimental as Exp
16+
import qualified Cardano.Api.Experimental.Tx as Exp
1617
import qualified Cardano.Api.Ledger as L
1718

1819
import Cardano.Rpc.Client (Proto)
@@ -49,29 +50,28 @@ import RIO (ByteString)
4950
hprop_rpc_transaction :: Property
5051
hprop_rpc_transaction = integrationRetryWorkspace 2 "rpc-tx" $ \tempAbsBasePath' -> H.runWithDefaultWatchdog_ $ do
5152
conf <- mkConf tempAbsBasePath'
52-
let (ceo, eraProxy) =
53-
(conwayBasedEra, asType) :: era ~ ConwayEra => (ConwayEraOnwards era, AsType era)
54-
sbe = convert ceo
53+
let era = Exp.ConwayEra
54+
sbe = convert era
5555
creationOptions = def{creationEra = AnyShelleyBasedEra sbe}
5656
runtimeOptions = def{runtimeEnableRpc = RpcEnabled}
57-
addrInEra = AsAddressInEra eraProxy
57+
addressInEra = asAddressInEra sbe
5858

5959
TestnetRuntime
6060
{ configurationFile
6161
, testnetNodes = node0 : _
62-
, wallets = wallet0@(PaymentKeyInfo _ addrTxt0) : (PaymentKeyInfo _ addrTxt1) : _
62+
, wallets = wallet0@(PaymentKeyInfo _ addressText0) : (PaymentKeyInfo _ addressText1) : _
6363
} <-
6464
createAndRunTestnet creationOptions runtimeOptions conf
6565

6666
epochStateView <- getEpochStateView configurationFile $ nodeSocketPath node0
6767
rpcSocket <- H.note . unFile $ nodeRpcSocketPath node0
6868

6969
-- prepare tx inputs and output address
70-
H.noteShow_ addrTxt0
71-
addr0 <- H.nothingFail $ deserialiseAddress addrInEra addrTxt0
70+
H.noteShow_ addressText0
71+
address0 <- H.nothingFail $ deserialiseAddress addressInEra addressText0
7272

73-
H.noteShow_ addrTxt1
74-
addr1 <- H.nothingFail $ deserialiseAddress addrInEra addrTxt1
73+
H.noteShow_ addressText1
74+
address1 <- H.nothingFail $ deserialiseAddress addressInEra addressText1
7575

7676
-- read key witnesses
7777
wit0 :: ShelleyWitnessSigningKey <-
@@ -90,66 +90,69 @@ hprop_rpc_transaction = integrationRetryWorkspace 2 "rpc-tx" $ \tempAbsBasePath'
9090
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readParams")) req
9191

9292
utxos' <- do
93-
let req = def -- & # U5c.keys .~ [T.encodeUtf8 addrTxt0]
93+
let req = def -- & # U5c.keys .~ [T.encodeUtf8 addressText0]
9494
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readUtxos")) req
9595
pure (pparams', utxos')
9696

97-
pparams <- H.leftFail $ utxoRpcPParamsToProtocolParams (convert ceo) $ pparamsResponse ^. U5c.values . U5c.cardano
97+
pparams <- H.leftFail $ utxoRpcPParamsToProtocolParams era $ pparamsResponse ^. U5c.values . U5c.cardano
9898

9999
txOut0 : _ <- H.noteShowM . flip filterM (utxosResponse ^. U5c.items) $ \utxo -> do
100-
utxoAddress <- deserialiseAddressBs addrInEra $ utxo ^. U5c.cardano . U5c.address
101-
pure $ addr0 == utxoAddress
100+
utxoAddress <- deserialiseAddressBs addressInEra $ utxo ^. U5c.cardano . U5c.address
101+
pure $ address0 == utxoAddress
102102
txIn0 <- txoRefToTxIn $ txOut0 ^. U5c.txoRef
103103

104104
outputCoin <- H.leftFail $ txOut0 ^. U5c.cardano . U5c.coin . to utxoRpcBigIntToInteger
105105
let amount = 200_000_000
106106
fee = 500
107107
change = outputCoin - amount - fee
108-
txOut = TxOut addr1 (lovelaceToTxOutValue sbe $ L.Coin amount) TxOutDatumNone ReferenceScriptNone
109-
changeTxOut = TxOut addr0 (lovelaceToTxOutValue sbe $ L.Coin change) TxOutDatumNone ReferenceScriptNone
108+
mkOut ledgerAddress coin = Exp.obtainCommonConstraints era $
109+
Exp.TxOut $ L.mkBasicTxOut ledgerAddress $ L.inject $ L.Coin coin
110110
content =
111-
defaultTxBodyContent sbe
112-
& setTxIns [(txIn0, pure $ KeyWitness KeyWitnessForSpending)]
113-
& setTxFee (TxFeeExplicit sbe (L.Coin fee))
114-
& setTxOuts [txOut, changeTxOut]
115-
& setTxProtocolParams (pure . pure $ LedgerProtocolParameters pparams)
111+
Exp.defaultTxBodyContent
112+
& Exp.setTxIns [(txIn0, Exp.AnyKeyWitnessPlaceholder)]
113+
& Exp.setTxFee (L.Coin fee)
114+
& Exp.setTxOuts [mkOut (toShelleyAddr address1) amount, mkOut (toShelleyAddr address0) change]
115+
& Exp.setTxProtocolParams pparams
116116

117-
txBody <- H.leftFail $ createTransactionBody sbe content
118-
119-
let signedTx = signShelleyTransaction sbe txBody [wit0]
120-
txId' <- H.noteShow . getTxId $ getTxBody signedTx
117+
unsignedTx <- H.leftFail $ Exp.makeUnsignedTx era content
118+
let keyWit = Exp.makeKeyWitness era unsignedTx wit0
119+
Exp.SignedTx signedLedgerTx = Exp.signTx era [] [keyWit] unsignedTx
120+
txId' <- H.noteShow . Exp.obtainCommonConstraints era . TxId $ Exp.hashTxBody (signedLedgerTx ^. L.bodyTxL)
121121

122122
H.noteShowPretty_ utxosResponse
123123

124124
liftBaseOp (Rpc.withConnection def rpcServer) $ \conn -> do
125125
submitResponse <- H.noteShowM . H.evalIO $
126126
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.SubmitService "submitTx")) $
127-
def & U5c.tx .~ (def & U5c.raw .~ serialiseToCBOR signedTx)
127+
def & U5c.tx .~ (def & U5c.raw .~ serialiseToRawBytes (Exp.SignedTx signedLedgerTx))
128128

129129
submittedTxId <- H.leftFail . deserialiseFromRawBytes AsTxId $ submitResponse ^. U5c.ref
130130

131131
H.note_ "Ensure that submitTx returns the same transaction ID as the locally computed signed transaction ID"
132132
txId' === submittedTxId
133133

134134
-- TODO use searchUtxos when available
135-
H.note_ $ "Ensure that there are 2 UTXOs in the address " <> show addrTxt1
135+
H.note_ $ "Ensure that there are 2 UTXOs in the address " <> show addressText1
136136
utxosForAddress <- retryUntilM epochStateView (WaitForBlocks 10)
137137
(do utxos <- H.evalIO $
138138
Rpc.nonStreaming conn (Rpc.rpc @(Rpc.Protobuf UtxoRpc.QueryService "readUtxos")) def
139139
flip filterM (utxos ^. U5c.items) $ \utxo -> do
140-
utxoAddress <- deserialiseAddressBs addrInEra $ utxo ^. U5c.cardano . U5c.address
141-
pure $ addr1 == utxoAddress
140+
utxoAddress <- deserialiseAddressBs addressInEra $ utxo ^. U5c.cardano . U5c.address
141+
pure $ address1 == utxoAddress
142142
)
143143
(\xs -> length xs == 2)
144144

145145
let outputsAmounts = map (^. U5c.cardano . U5c.coin) utxosForAddress
146-
H.note_ $ "Ensure that the output sent is one of the utxos for the address " <> show addrTxt1
146+
H.note_ $ "Ensure that the output sent is one of the utxos for the address " <> show addressText1
147147
H.assertWith outputsAmounts $ elem (inject amount)
148148

149+
asAddressInEra :: ShelleyBasedEra era -> AsType (AddressInEra era)
150+
asAddressInEra s = shelleyBasedEraConstraints s $ AsAddressInEra asType
151+
149152
txoRefToTxIn :: (HasCallStack, MonadTest m) => Proto UtxoRpc.TxoRef -> m TxIn
150153
txoRefToTxIn r = withFrozenCallStack $ do
151154
txId' <- H.leftFail $ deserialiseFromRawBytes AsTxId $ r ^. U5c.hash
152155
pure $ TxIn txId' (TxIx . fromIntegral $ r ^. U5c.index)
153156

154157
deserialiseAddressBs :: (MonadTest m, SerialiseAddress c) => AsType c -> ByteString -> m c
155-
deserialiseAddressBs addrInEra = H.nothingFail . deserialiseAddress addrInEra <=< H.leftFail . T.decodeUtf8'
158+
deserialiseAddressBs addressInEra = H.nothingFail . deserialiseAddress addressInEra <=< H.leftFail . T.decodeUtf8'

0 commit comments

Comments
 (0)