Skip to content

Commit 5714f92

Browse files
committed
cardano-rpc | Add UTxO RPC: submitTx method
1 parent 47f8b61 commit 5714f92

File tree

5 files changed

+112
-3
lines changed

5 files changed

+112
-3
lines changed

cardano-rpc/cardano-rpc.cabal

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,22 @@ library
5555
Cardano.Rpc.Client
5656
Cardano.Rpc.Proto.Api.Node
5757
Cardano.Rpc.Proto.Api.UtxoRpc.Query
58+
Cardano.Rpc.Proto.Api.UtxoRpc.Submit
5859
Cardano.Rpc.Server
5960
Cardano.Rpc.Server.Config
6061
Cardano.Rpc.Server.Internal.Env
6162
Cardano.Rpc.Server.Internal.Error
6263
Cardano.Rpc.Server.Internal.Monad
6364
Cardano.Rpc.Server.Internal.UtxoRpc.Query
65+
Cardano.Rpc.Server.Internal.UtxoRpc.Submit
6466
Proto.Cardano.Rpc.Node
6567
Proto.Cardano.Rpc.Node_Fields
6668
Proto.Utxorpc.V1alpha.Cardano.Cardano
6769
Proto.Utxorpc.V1alpha.Cardano.Cardano_Fields
6870
Proto.Utxorpc.V1alpha.Query.Query
6971
Proto.Utxorpc.V1alpha.Query.Query_Fields
72+
Proto.Utxorpc.V1alpha.Submit.Submit
73+
Proto.Utxorpc.V1alpha.Submit.Submit_Fields
7074

7175
other-modules:
7276
Cardano.Rpc.Server.Internal.Orphans
@@ -80,6 +84,8 @@ library
8084
Proto.Utxorpc.V1alpha.Cardano.Cardano_Fields
8185
Proto.Utxorpc.V1alpha.Query.Query
8286
Proto.Utxorpc.V1alpha.Query.Query_Fields
87+
Proto.Utxorpc.V1alpha.Submit.Submit
88+
Proto.Utxorpc.V1alpha.Submit.Submit_Fields
8389

8490
build-depends:
8591
base,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{-# LANGUAGE TypeFamilies #-}
2+
{-# OPTIONS_GHC -Wno-orphans #-}
3+
4+
module Cardano.Rpc.Proto.Api.UtxoRpc.Submit
5+
( module Proto.Utxorpc.V1alpha.Submit.Submit
6+
, module Proto.Utxorpc.V1alpha.Submit.Submit_Fields
7+
)
8+
where
9+
10+
import Network.GRPC.Common
11+
import Network.GRPC.Common.Protobuf
12+
13+
import Proto.Utxorpc.V1alpha.Submit.Submit
14+
import Proto.Utxorpc.V1alpha.Submit.Submit_Fields
15+
16+
type instance RequestMetadata (Protobuf SubmitService meth) = NoMetadata
17+
18+
type instance ResponseInitialMetadata (Protobuf SubmitService meth) = NoMetadata
19+
20+
type instance ResponseTrailingMetadata (Protobuf SubmitService meth) = NoMetadata

cardano-rpc/src/Cardano/Rpc/Server.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@ where
1717
import Cardano.Api
1818
import Cardano.Rpc.Proto.Api.Node qualified as Rpc
1919
import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as UtxoRpc
20+
import Cardano.Rpc.Proto.Api.UtxoRpc.Submit qualified as UtxoRpc
2021
import Cardano.Rpc.Server.Config
2122
import Cardano.Rpc.Server.Internal.Env
2223
import Cardano.Rpc.Server.Internal.Monad
2324
import Cardano.Rpc.Server.Internal.Orphans ()
2425
import Cardano.Rpc.Server.Internal.UtxoRpc.Query
26+
import Cardano.Rpc.Server.Internal.UtxoRpc.Submit
2527

2628
import RIO
2729

@@ -65,6 +67,12 @@ methodsUtxoRpc = do
6567
. Method (mkNonStreaming searchUtxosMethod)
6668
$ NoMoreMethods
6769

70+
methodsUtxoRpcSubmit
71+
:: MonadRpc e m
72+
=> Methods m (ProtobufMethodsOf UtxoRpc.SubmitService)
73+
methodsUtxoRpcSubmit =
74+
Method (mkNonStreaming submitTxMethod) NoMoreMethods
75+
6876
runRpcServer
6977
:: Tracer IO String
7078
-> IO (RpcConfig, NetworkMagic)
@@ -102,6 +110,7 @@ runRpcServer tracer loadRpcConfig = handleFatalExceptions $ do
102110
mconcat
103111
[ fromMethods methodsNodeRpc
104112
, fromMethods methodsUtxoRpc
113+
, fromMethods methodsUtxoRpcSubmit
105114
]
106115
where
107116
serverParams :: ServerParams

cardano-rpc/src/Cardano/Rpc/Server/Internal/Orphans.hs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,9 @@ import Cardano.Api.Plutus
1818
import Cardano.Api.Pretty
1919
import Cardano.Api.Serialise.Raw
2020
import Cardano.Api.Tx
21-
import Cardano.Api.UTxO (UTxO)
2221
import Cardano.Api.Value
2322
import Cardano.Rpc.Proto.Api.UtxoRpc.Query qualified as UtxoRpc
2423

25-
import Cardano.Ledger.Plutus qualified as L
26-
2724
import RIO hiding (toList)
2825

2926
import Data.ProtoLens (defMessage)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
{-# LANGUAGE ConstraintKinds #-}
2+
{-# LANGUAGE DataKinds #-}
3+
{-# LANGUAGE DerivingVia #-}
4+
{-# LANGUAGE FlexibleContexts #-}
5+
{-# LANGUAGE GADTs #-}
6+
{-# LANGUAGE LambdaCase #-}
7+
{-# LANGUAGE OverloadedLabels #-}
8+
{-# LANGUAGE QuantifiedConstraints #-}
9+
{-# LANGUAGE RankNTypes #-}
10+
{-# LANGUAGE ScopedTypeVariables #-}
11+
{-# LANGUAGE TupleSections #-}
12+
{-# LANGUAGE TypeApplications #-}
13+
14+
module Cardano.Rpc.Server.Internal.UtxoRpc.Submit
15+
( submitTxMethod
16+
)
17+
where
18+
19+
import Cardano.Api
20+
import Cardano.Api.Network.IPC qualified as Net.Tx
21+
import Cardano.Rpc.Proto.Api.UtxoRpc.Submit qualified as UtxoRpc
22+
import Cardano.Rpc.Server.Internal.Error
23+
import Cardano.Rpc.Server.Internal.Monad
24+
import Cardano.Rpc.Server.Internal.Orphans ()
25+
26+
import RIO hiding (toList)
27+
28+
import Data.ProtoLens (defMessage)
29+
import Network.GRPC.Spec
30+
31+
submitTxMethod
32+
:: forall e m
33+
. MonadRpc e m
34+
=> Proto UtxoRpc.SubmitTxRequest
35+
-> m (Proto UtxoRpc.SubmitTxResponse)
36+
submitTxMethod req = do
37+
let serialisedTxs = zip @Int [0 ..] $ req ^.. #tx . traverse . #raw
38+
39+
nodeConnInfo <- grab
40+
AnyCardanoEra era <- liftIO . throwExceptT $ determineEra nodeConnInfo
41+
eon <- forEraInEon era (error "Minimum Shelley era required") pure
42+
43+
let (failedTxs, txs) = partitionEithers $ serialisedTxs <&> \(i, tx) -> bimap (i,) (i,) $ deserialiseTx eon tx
44+
45+
-- TODO failures need to be included in the returned type, and not dumped to node logs
46+
forM_ failedTxs $ \(i, err) -> do
47+
putTrace $ "Failed to decode transaction with index: " <> show i <> " / " <> err
48+
49+
(failedSubmissionTxs, txIds) <- fmap partitionEithers . forM txs $ \(i, tx) -> bimap (i,) (i,) <$> submitTx eon tx
50+
51+
-- TODO failures need to be included in the returned type, and not dumped to node logs
52+
forM_ failedSubmissionTxs $ \(i, err) -> do
53+
putTrace $ "Failed to submit transaction with index: " <> show i <> " / " <> err
54+
55+
-- TODO: so now, to check if the submission has succeeded, one has to check if the TxId is in the returned list.
56+
pure $ defMessage & #ref .~ map (serialiseToRawBytes . snd) txIds
57+
where
58+
deserialiseTx :: ShelleyBasedEra era -> ByteString -> Either String (Tx era)
59+
deserialiseTx sbe = shelleyBasedEraConstraints sbe $ first show . deserialiseFromCBOR asType
60+
61+
submitTx
62+
:: ShelleyBasedEra era
63+
-> Tx era
64+
-> m (Either String TxId)
65+
submitTx sbe tx = do
66+
nodeConnInfo <- grab
67+
eRes <-
68+
tryAny $
69+
submitTxToNodeLocal nodeConnInfo (TxInMode sbe tx) >>= \case
70+
Net.Tx.SubmitFail reason -> pure . Left $ show reason
71+
Net.Tx.SubmitSuccess -> pure $ Right . getTxId $ getTxBody tx
72+
case eRes of
73+
Left err -> do
74+
let errString = displayException err
75+
putTrace $ "N2C connection error while trying to submit a transaction: " <> errString
76+
pure $ Left errString
77+
Right res -> pure res

0 commit comments

Comments
 (0)