Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC: chainsync client as pipe producer #5027

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ library
Ouroboros.Network.Protocol.BlockFetch.Type
Ouroboros.Network.Protocol.ChainSync.Client
Ouroboros.Network.Protocol.ChainSync.ClientPipelined
Ouroboros.Network.Protocol.ChainSync.PipeClient
Ouroboros.Network.Protocol.ChainSync.Codec
Ouroboros.Network.Protocol.ChainSync.PipelineDecision
Ouroboros.Network.Protocol.ChainSync.Server
Expand Down Expand Up @@ -104,6 +105,7 @@ library
io-classes ^>=1.5.0,
nothunks,
ouroboros-network-api ^>=0.11,
pipes,
quiet,
serialise,
si-timers,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeOperators #-}

module Ouroboros.Network.Protocol.ChainSync.PipeClient
where

import Ouroboros.Network.Protocol.ChainSync.Client
import Pipes
import Pipes.Core
import Control.Monad (forever)

data ChainSyncResponse block point tip
= RollForward block tip
| RollBackward point tip
| IntersectNotFound tip
deriving (Show)

data ChainSyncRequest point
= RequestIntersect [point]
| RequestNext
deriving (Show)

example :: ( Monad m
, p ~ Proxy X () (ChainSyncRequest point) (ChainSyncResponse block point tip) m
)
=> [point]
-> (ChainSyncResponse block point tip -> m ())
-> (ChainSyncClient block point tip p () -> p ())
-> m ()
example initialPoints handleMutation runClient =
runEffect
$ chainSyncClient initialPoints handleMutation
<<+ chainSyncServer runClient

chainSyncClient :: forall block point tip m p
. ( Monad m
, p ~ Client
(ChainSyncRequest point)
(ChainSyncResponse block point tip)
m
)
=> [point]
-> (ChainSyncResponse block point tip -> m ())
-> p ()
chainSyncClient known handleResponse = do
request (RequestIntersect known) >>= lift . handleResponse
forever $ do
request RequestNext >>= lift . handleResponse


chainSyncServer :: forall block point tip m p
. ( Monad m
, p ~ Server
(ChainSyncRequest point)
(ChainSyncResponse block point tip)
m
)
=> (ChainSyncClient block point tip p () -> p ())
-> ChainSyncRequest point -> p ()
chainSyncServer runClient rq0 =
runClient $ ChainSyncClient (handleRequest rq0)
where
handleRequest rq = case rq of
RequestIntersect known ->
pure . SendMsgFindIntersect known $
ClientStIntersect
{ recvMsgIntersectFound = \p t -> ChainSyncClient $ do
respond (RollBackward p t) >>= handleRequest
, recvMsgIntersectNotFound = \t -> ChainSyncClient $ do
respond (IntersectNotFound t) >>= handleRequest
}
RequestNext ->
pure . SendMsgRequestNext (pure ()) $
ClientStNext
{ recvMsgRollForward = \h t -> ChainSyncClient $ do
respond (RollForward h t) >>= handleRequest
, recvMsgRollBackward = \p t -> ChainSyncClient $ do
respond (RollBackward p t) >>= handleRequest
}
Loading