1- {-# LANGUAGE NamedFieldPuns #-}
1+ {-# LANGUAGE DataKinds #-}
2+ {-# LANGUAGE FlexibleContexts #-}
3+ {-# LANGUAGE RankNTypes #-}
24
35module DMQ.NodeToClient
4- ( LocalAddress (.. )
5- , module DMQ.NodeToClient.Version
6+ ( module DMQ.NodeToClient.Version
67 , Protocols (.. )
78 , HandshakeTr
9+ , Apps
10+ , dmqCodecs
11+ , ntcApps
812 , ntcHandshakeArguments
13+ , responders
914 ) where
1015
16+ import Data.ByteString.Lazy (ByteString )
17+ import Data.Void
18+ import Data.Word
19+
20+ import Control.Concurrent.Class.MonadSTM
21+ import Control.Monad.Class.MonadFork
1122import Control.Monad.Class.MonadST (MonadST )
23+ import Control.Monad.Class.MonadThrow
1224import Control.Tracer (Tracer , nullTracer )
1325
26+ import Codec.CBOR.Decoding qualified as CBOR
27+ import Codec.CBOR.Encoding qualified as CBOR
1428import Codec.CBOR.Term qualified as CBOR
1529
1630import Network.Mux qualified as Mx
31+ import Network.TypedProtocol.Codec hiding (decode , encode )
32+ import Network.TypedProtocol.Codec.CBOR qualified as CBOR
33+
34+ import DMQ.NodeToClient.LocalMsgNotification
35+ import DMQ.NodeToClient.LocalMsgSubmission
36+ import DMQ.NodeToClient.Version
37+ import DMQ.Protocol.LocalMsgNotification.Codec
38+ import DMQ.Protocol.LocalMsgNotification.Server
39+ import DMQ.Protocol.LocalMsgNotification.Type
40+ import DMQ.Protocol.LocalMsgSubmission.Codec
41+ import DMQ.Protocol.LocalMsgSubmission.Server
42+ import DMQ.Protocol.LocalMsgSubmission.Type
1743
18- import Ouroboros.Network.ConnectionId ( ConnectionId )
19- import Ouroboros.Network.Driver.Simple ( TraceSendRecv )
44+ import Ouroboros.Network.Context
45+ import Ouroboros.Network.Driver.Simple
2046import Ouroboros.Network.Handshake.Acceptable (Acceptable (.. ))
2147import Ouroboros.Network.Handshake.Queryable (Queryable (.. ))
48+ import Ouroboros.Network.Mux
2249import Ouroboros.Network.Protocol.Handshake (Handshake , HandshakeArguments (.. ))
2350import Ouroboros.Network.Protocol.Handshake.Codec (cborTermVersionDataCodec ,
2451 codecHandshake , noTimeLimitsHandshake )
25- import Ouroboros.Network.Snocket ( LocalAddress ( .. ))
26-
27- import DMQ.NodeToClient.Version
28-
52+ import Ouroboros.Network.TxSubmission.Inbound.V2.Types
53+ ( TxSubmissionMempoolWriter )
54+ import Ouroboros.Network.TxSubmission.Mempool.Reader
55+ import Ouroboros.Network.Util.ShowProxy
2956
30- data Protocols =
31- Protocols {
32- }
3357
3458type HandshakeTr ntcAddr = Mx. WithBearer (ConnectionId ntcAddr ) (TraceSendRecv (Handshake NodeToClientVersion CBOR. Term ))
3559
@@ -53,3 +77,153 @@ ntcHandshakeArguments tracer =
5377 , haQueryVersion = queryVersion
5478 , haTimeLimits = noTimeLimitsHandshake
5579 }
80+
81+
82+ data Codecs m sig reject =
83+ Codecs {
84+ msgSubmissionCodec
85+ :: !(Codec (LocalMsgSubmission sig reject)
86+ CBOR.DeserialiseFailure m ByteString)
87+ , msgNotificationCodec
88+ :: !(Codec (LocalMsgNotification sig)
89+ CBOR.DeserialiseFailure m ByteString)
90+ }
91+
92+ dmqCodecs :: MonadST m
93+ => (sig -> CBOR. Encoding )
94+ -> (forall s . CBOR. Decoder s sig )
95+ -> (SigMempoolFail reason -> CBOR. Encoding )
96+ -> (forall s . CBOR. Decoder s (SigMempoolFail reason ))
97+ -> Codecs m sig reason
98+ dmqCodecs encodeSig decodeSig encodeReject' decodeReject' =
99+ Codecs {
100+ msgSubmissionCodec = codecLocalMsgSubmission encodeSig decodeSig encodeReject' decodeReject'
101+ , msgNotificationCodec = codecLocalMsgNotification encodeSig decodeSig
102+ }
103+
104+
105+ -- | A node-to-client application
106+ --
107+ type App ntcAddr m a =
108+ NodeToClientVersion
109+ -> ResponderContext ntcAddr
110+ -> Mx. Channel m ByteString
111+ -> m (a , Maybe ByteString )
112+
113+
114+ data Apps ntcAddr m a =
115+ Apps {
116+ -- | Start a sig-submission client
117+ aLocalMsgSubmission :: ! (App ntcAddr m a )
118+
119+ -- | Start a sig-submission server
120+ , aLocalMsgNotification :: ! (App ntcAddr m a )
121+ }
122+
123+
124+ -- | Construct applications for the node-to-client protocols
125+ --
126+ ntcApps
127+ :: (MonadThrow m , MonadThread m , MonadSTM m , ShowProxy (SigMempoolFail reason ), ShowProxy sig )
128+ => TxSubmissionMempoolReader msgid sig idx m
129+ -> TxSubmissionMempoolWriter msgid sig idx m
130+ -> Word16
131+ -> Codecs m sig reason
132+ -> Apps ntcAddr m ()
133+ ntcApps mempoolReader mempoolWriter maxMsgs
134+ Codecs { msgSubmissionCodec, msgNotificationCodec } =
135+ Apps {
136+ aLocalMsgSubmission
137+ , aLocalMsgNotification
138+ }
139+ where
140+ aLocalMsgSubmission _version _ctx channel = do
141+ labelThisThread " LocalMsgSubmissionServer"
142+ runPeer
143+ nullTracer
144+ msgSubmissionCodec
145+ channel
146+ (localMsgSubmissionServerPeer $
147+ localMsgSubmissionServer nullTracer mempoolWriter)
148+
149+ aLocalMsgNotification _version _ctx channel = do
150+ labelThisThread " LocalMsgNotificationServer"
151+ runPeer
152+ nullTracer
153+ msgNotificationCodec
154+ channel
155+ (localMsgNotificationServerPeer $
156+ localMsgNotificationServer nullTracer (pure () ) maxMsgs mempoolReader)
157+
158+
159+ data Protocols appType ntcAddr bytes m a b =
160+ Protocols {
161+ msgSubmissionProtocol :: ! (RunMiniProtocolWithMinimalCtx appType ntcAddr bytes m a b )
162+ , msgNotificationProtocol :: ! (RunMiniProtocolWithMinimalCtx appType ntcAddr bytes m a b )
163+ }
164+
165+ responders
166+ :: Apps ntcAddr m a
167+ -> NodeToClientVersion
168+ -> NodeToClientVersionData
169+ -> OuroborosApplicationWithMinimalCtx Mx. ResponderMode ntcAddr ByteString m Void a
170+ responders Apps {
171+ aLocalMsgSubmission
172+ , aLocalMsgNotification
173+ }
174+ version =
175+ nodeToClientProtocols
176+ Protocols {
177+ msgSubmissionProtocol =
178+ ResponderProtocolOnly $
179+ MiniProtocolCb $ aLocalMsgSubmission version
180+ , msgNotificationProtocol =
181+ ResponderProtocolOnly $
182+ MiniProtocolCb $ aLocalMsgNotification version
183+ }
184+ version
185+
186+
187+ -- | Make an 'OuroborosApplication' for the bundle of mini-protocols that
188+ -- make up the overall node-to-client protocol.
189+ --
190+ -- This function specifies the wire format protocol numbers as well as the
191+ -- protocols that run for each 'NodeToClientVersion'.
192+ --
193+ -- They are chosen to not overlap with the node to node protocol numbers.
194+ -- This is not essential for correctness, but is helpful to allow a single
195+ -- shared implementation of tools that can analyse both protocols, e.g.
196+ -- wireshark plugins.
197+ --
198+ nodeToClientProtocols
199+ :: Protocols appType ntcAddr bytes m a b
200+ -> NodeToClientVersion
201+ -> NodeToClientVersionData
202+ -> OuroborosApplicationWithMinimalCtx appType ntcAddr bytes m a b
203+ nodeToClientProtocols protocols _version _versionData =
204+ OuroborosApplication $
205+ case protocols of
206+ Protocols {
207+ msgSubmissionProtocol
208+ , msgNotificationProtocol
209+ } ->
210+ [ localMsgSubmission msgSubmissionProtocol
211+ , localMsgNotification msgNotificationProtocol
212+ ]
213+ where
214+ localMsgSubmission protocol = MiniProtocol {
215+ miniProtocolNum = MiniProtocolNum 14 ,
216+ miniProtocolStart = StartOnDemand ,
217+ miniProtocolLimits = maximumMiniProtocolLimits,
218+ miniProtocolRun = protocol
219+ }
220+ localMsgNotification protocol = MiniProtocol {
221+ miniProtocolNum = MiniProtocolNum 15 ,
222+ miniProtocolStart = StartOnDemand ,
223+ miniProtocolLimits = maximumMiniProtocolLimits,
224+ miniProtocolRun = protocol
225+ }
226+ maximumMiniProtocolLimits =
227+ MiniProtocolLimits {
228+ maximumIngressQueue = 0xffffffff
229+ }
0 commit comments