1- {-# LANGUAGE NamedFieldPuns #-}
1+ {-# LANGUAGE DataKinds #-}
2+ {-# LANGUAGE RankNTypes #-}
23
34module DMQ.NodeToClient
4- ( LocalAddress (.. )
5- , module DMQ.NodeToClient.Version
5+ ( module DMQ.NodeToClient.Version
66 , Protocols (.. )
77 , HandshakeTr
8+ , Apps
9+ , dmqCodecs
10+ , ntcApps
811 , ntcHandshakeArguments
12+ , responders
913 ) where
1014
15+ import Data.ByteString.Lazy (ByteString )
16+ import Data.Void
17+ import Data.Word
18+
19+ import Control.Concurrent.Class.MonadSTM
20+ import Control.Monad.Class.MonadFork
1121import Control.Monad.Class.MonadST (MonadST )
22+ import Control.Monad.Class.MonadThrow
1223import Control.Tracer (Tracer , nullTracer )
1324
25+ import Codec.CBOR.Decoding qualified as CBOR
26+ import Codec.CBOR.Encoding qualified as CBOR
1427import Codec.CBOR.Term qualified as CBOR
1528
1629import Network.Mux qualified as Mx
30+ import Network.TypedProtocol.Codec hiding (decode , encode )
31+ import Network.TypedProtocol.Codec.CBOR qualified as CBOR
32+
33+ import DMQ.NodeToClient.LocalMsgNotification
34+ import DMQ.NodeToClient.LocalMsgSubmission
35+ import DMQ.NodeToClient.Version
36+ import DMQ.Protocol.LocalMsgNotification.Codec
37+ import DMQ.Protocol.LocalMsgNotification.Server
38+ import DMQ.Protocol.LocalMsgNotification.Type
39+ import DMQ.Protocol.LocalMsgSubmission.Codec
40+ import DMQ.Protocol.LocalMsgSubmission.Server
41+ import DMQ.Protocol.LocalMsgSubmission.Type
1742
18- import Ouroboros.Network.ConnectionId ( ConnectionId )
19- import Ouroboros.Network.Driver.Simple ( TraceSendRecv )
43+ import Ouroboros.Network.Context
44+ import Ouroboros.Network.Driver.Simple
2045import Ouroboros.Network.Handshake.Acceptable (Acceptable (.. ))
2146import Ouroboros.Network.Handshake.Queryable (Queryable (.. ))
47+ import Ouroboros.Network.Mux
2248import Ouroboros.Network.Protocol.Handshake (Handshake , HandshakeArguments (.. ))
2349import Ouroboros.Network.Protocol.Handshake.Codec (cborTermVersionDataCodec ,
2450 codecHandshake , noTimeLimitsHandshake )
25- import Ouroboros.Network.Snocket ( LocalAddress ( .. ))
26-
27- import DMQ.NodeToClient.Version
28-
51+ import Ouroboros.Network.TxSubmission.Inbound.V2.Types
52+ ( TxSubmissionMempoolWriter )
53+ import Ouroboros.Network.TxSubmission.Mempool.Reader
54+ import Ouroboros.Network.Util.ShowProxy
2955
30- data Protocols =
31- Protocols {
32- }
3356
3457type HandshakeTr ntcAddr = Mx. WithBearer (ConnectionId ntcAddr ) (TraceSendRecv (Handshake NodeToClientVersion CBOR. Term ))
3558
@@ -53,3 +76,154 @@ ntcHandshakeArguments tracer =
5376 , haQueryVersion = queryVersion
5477 , haTimeLimits = noTimeLimitsHandshake
5578 }
79+
80+
81+ data Codecs m sig reject =
82+ Codecs {
83+ msgSubmissionCodec
84+ :: !(Codec (LocalMsgSubmission sig reject)
85+ CBOR.DeserialiseFailure m ByteString)
86+ , msgNotificationCodec
87+ :: !(Codec (LocalMsgNotification sig)
88+ CBOR.DeserialiseFailure m ByteString)
89+ }
90+
91+ dmqCodecs :: MonadST m
92+ => (sig -> CBOR. Encoding )
93+ -> (forall s . CBOR. Decoder s sig )
94+ -> (reject -> CBOR. Encoding )
95+ -> (forall s . CBOR. Decoder s reject )
96+ -> Codecs m sig reject
97+ dmqCodecs encodeSig decodeSig encodeReject' decodeReject' =
98+ Codecs {
99+ msgSubmissionCodec = codecLocalMsgSubmission encodeSig decodeSig encodeReject' decodeReject'
100+ , msgNotificationCodec = codecLocalMsgNotification encodeSig decodeSig
101+ }
102+
103+
104+ -- | A node-to-client application
105+ --
106+ type App ntcAddr m a =
107+ NodeToClientVersion
108+ -> ResponderContext ntcAddr
109+ -> Mx. Channel m ByteString
110+ -> m (a , Maybe ByteString )
111+
112+
113+ data Apps ntcAddr m a =
114+ Apps {
115+ -- | Start a sig-submission client
116+ aLocalMsgSubmission :: ! (App ntcAddr m a )
117+
118+ -- | Start a sig-submission server
119+ , aLocalMsgNotification :: ! (App ntcAddr m a )
120+ }
121+
122+
123+ -- | Construct applications for the node-to-client protocols
124+ --
125+ ntcApps
126+ :: (MonadThrow m , MonadThread m , MonadSTM m , ShowProxy reject , ShowProxy sig )
127+ => reject
128+ -> TxSubmissionMempoolReader msgid sig idx m
129+ -> TxSubmissionMempoolWriter msgid sig idx m
130+ -> Word16
131+ -> Codecs m sig reject
132+ -> Apps ntcAddr m ()
133+ ntcApps reject 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 reject 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