-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


@package ouroboros-network-framework
@version 0.1.0.0

module Ouroboros.Network.Channel

-- | One end of a duplex channel. It is a reliable, ordered channel of some
--   medium. The medium does not imply message boundaries, it can be just
--   bytes.
data Channel m a
Channel :: (a -> m ()) -> m (Maybe a) -> Channel m a

-- | Write output to the channel.
--   
--   It may raise exceptions (as appropriate for the monad and kind of
--   channel).
[send] :: Channel m a -> a -> m ()

-- | Read some input from the channel, or <tt>Nothing</tt> to indicate EOF.
--   
--   Note that having received EOF it is still possible to send. The EOF
--   condition is however monotonic.
--   
--   It may raise exceptions (as appropriate for the monad and kind of
--   channel).
[recv] :: Channel m a -> m (Maybe a)
toChannel :: Channel m ByteString -> Channel m
fromChannel :: Channel m -> Channel m ByteString

-- | Create a local pipe, with both ends in this process, and expose that
--   as a pair of <a>Channel</a>s, one for each end.
--   
--   This is primarily for testing purposes since it does not allow actual
--   IPC.
createPipeConnectedChannels :: IO (Channel IO ByteString, Channel IO ByteString)
hoistChannel :: (forall x. m x -> n x) -> Channel m a -> Channel n a

-- | Given an isomorphism between <tt>a</tt> and <tt>b</tt> (in Kleisli
--   category), transform a <tt><a>Channel</a> m a</tt> into
--   <tt><a>Channel</a> m b</tt>.
isoKleisliChannel :: forall a b m. Monad m => (a -> m b) -> (b -> m a) -> Channel m a -> Channel m b

-- | A <a>Channel</a> with a fixed input, and where all output is
--   discarded.
--   
--   The input is guaranteed to be supplied via <a>read</a> with the given
--   chunk boundaries.
--   
--   This is only useful for testing. In particular the fixed chunk
--   boundaries can be used to test that framing and other codecs work with
--   any possible chunking.
fixedInputChannel :: MonadSTM m => [a] -> m (Channel m a)

-- | Make a <a>Channel</a> from a pair of <a>TMVar</a>s, one for reading
--   and one for writing.
mvarsAsChannel :: MonadSTM m => TMVar m a -> TMVar m a -> Channel m a

-- | Make a <a>Channel</a> from a pair of IO <tt>Handle</tt>s, one for
--   reading and one for writing.
--   
--   The Handles should be open in the appropriate read or write mode, and
--   in binary mode. Writes are flushed after each write, so it is safe to
--   use a buffering mode.
--   
--   For bidirectional handles it is safe to pass the same handle for both.
handlesAsChannel :: Handle -> Handle -> Channel IO ByteString

-- | Create a pair of channels that are connected via one-place buffers.
--   
--   This is primarily useful for testing protocols.
createConnectedChannels :: MonadSTM m => m (Channel m a, Channel m a)

-- | Create a pair of channels that are connected via N-place buffers.
--   
--   This variant <i>blocks</i> when <a>send</a> would exceed the maximum
--   buffer size. Use this variant when you want the environment rather
--   than the <tt>Peer</tt> to limit the pipelining.
--   
--   This is primarily useful for testing protocols.
createConnectedBufferedChannels :: MonadSTM m => Natural -> m (Channel m a, Channel m a)

-- | Create a pair of channels that are connected via N-place buffers.
--   
--   This variant <i>fails</i> when <a>send</a> would exceed the maximum
--   buffer size. Use this variant when you want the <tt>PeerPipelined</tt>
--   to limit the pipelining itself, and you want to check that it does not
--   exceed the expected level of pipelining.
--   
--   This is primarily useful for testing protocols.
createPipelineTestChannels :: MonadSTM m => Natural -> m (Channel m a, Channel m a)

-- | Transform a channel to add an extra action before <i>every</i> send
--   and after <i>every</i> receive.
channelEffect :: forall m a. Monad m => (a -> m ()) -> (Maybe a -> m ()) -> Channel m a -> Channel m a

-- | Delay a channel on the receiver end.
--   
--   This is intended for testing, as a crude approximation of network
--   delays. More accurate models along these lines are of course possible.
delayChannel :: (MonadSTM m, MonadTimer m) => DiffTime -> Channel m a -> Channel m a

-- | Channel which logs sent and received messages.
loggingChannel :: (MonadSay m, Show id, Show a) => id -> Channel m a -> Channel m a

module Ouroboros.Network.Codec
type DeserialiseFailure = DeserialiseFailure

-- | Construct a <a>Codec</a> for a CBOR based serialisation format, using
--   lazy <a>ByteString</a>s.
--   
--   This is an adaptor between the <tt>cborg</tt> library and the
--   <a>Codec</a> abstraction.
--   
--   It takes encode and decode functions for the protocol messages that
--   use the CBOR library encoder and decoder.
mkCodecCborLazyBS :: forall ps m. MonadST m => (forall (pr :: PeerRole) (st :: ps) (st' :: ps). PeerHasAgency pr st -> Message ps st st' -> Encoding) -> (forall (pr :: PeerRole) (st :: ps) s. PeerHasAgency pr st -> Decoder s (SomeMessage st)) -> Codec ps DeserialiseFailure m ByteString

-- | Construct a <a>Codec</a> for a CBOR based serialisation format, using
--   strict <a>ByteString</a>s.
--   
--   This is an adaptor between the <tt>cborg</tt> library and the
--   <a>Codec</a> abstraction.
--   
--   It takes encode and decode functions for the protocol messages that
--   use the CBOR library encoder and decoder.
--   
--   Note that this is <i>less</i> efficient than the
--   <a>mkCodecCborLazyBS</a> variant because it has to copy and
--   concatenate the result of the encoder (which natively produces
--   chunks).
mkCodecCborStrictBS :: forall ps m. MonadST m => (forall (pr :: PeerRole) (st :: ps) (st' :: ps). PeerHasAgency pr st -> Message ps st st' -> Encoding) -> (forall (pr :: PeerRole) (st :: ps) s. PeerHasAgency pr st -> Decoder s (SomeMessage st)) -> Codec ps DeserialiseFailure m ByteString

module Ouroboros.Network.CodecCBORTerm

-- | A pure codec which encodes to / decodes from <a>Term</a>. This is
--   useful if one expects a valid <tt>cbor</tt> encoding, which one might
--   not know how to decode like in the <tt>Handshake</tt> protocol.
data CodecCBORTerm fail a
CodecCBORTerm :: (a -> Term) -> (Term -> Either fail a) -> CodecCBORTerm fail a
[encodeTerm] :: CodecCBORTerm fail a -> a -> Term
[decodeTerm] :: CodecCBORTerm fail a -> Term -> Either fail a

module Ouroboros.Network.ConnectionId

-- | Connection is identified by local and remote address.
--   
--   TODO: the type variable which this data type fills in is called
--   <tt>peerid</tt>. We should renamed to <tt>connectionId</tt>.
data ConnectionId addr
ConnectionId :: !addr -> !addr -> ConnectionId addr
[localAddress] :: ConnectionId addr -> !addr
[remoteAddress] :: ConnectionId addr -> !addr
instance Data.Typeable.Internal.Typeable addr => NoThunks.Class.NoThunks (Ouroboros.Network.ConnectionId.ConnectionId addr)
instance GHC.Generics.Generic (Ouroboros.Network.ConnectionId.ConnectionId addr)
instance GHC.Show.Show addr => GHC.Show.Show (Ouroboros.Network.ConnectionId.ConnectionId addr)
instance GHC.Classes.Ord addr => GHC.Classes.Ord (Ouroboros.Network.ConnectionId.ConnectionId addr)
instance GHC.Classes.Eq addr => GHC.Classes.Eq (Ouroboros.Network.ConnectionId.ConnectionId addr)
instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Ouroboros.Network.ConnectionId.ConnectionId a)


-- | A shim layer for `Win32-network`'s <a>IOManager</a>
module Ouroboros.Network.IOManager

module Ouroboros.Network.Protocol.Handshake.Version

-- | The set of versions supported by the local agent are described by a
--   map keyed on the version identifier.
--   
--   If one needs to combine multiple versions the simplest way is to use
--   one of the combinators: <a>foldMapVersions</a>, <a>combineVersions</a>
--   or the <a>Semigroup</a> instance directly:
--   
--   <pre>
--   fold $ (simpleSingletonVersions ...)
--         :| [ (simpleSingletonVersions ...)
--            , (simpleSingletonVersions ...)
--            , ...
--            ]
--   </pre>
newtype Versions vNum vData r
Versions :: Map vNum (Version vData r) -> Versions vNum vData r
[getVersions] :: Versions vNum vData r -> Map vNum (Version vData r)

-- | Takes a pair of version data: local then remote.
newtype Application vData r
Application :: (vData -> r) -> Application vData r
[runApplication] :: Application vData r -> vData -> r
data Version vData r
Version :: Application vData r -> vData -> Version vData r
[versionApplication] :: Version vData r -> Application vData r
[versionData] :: Version vData r -> vData

-- | A <tt><a>Maybe</a></tt> like type which better explains its purpose.
data Accept vData
Accept :: vData -> Accept vData
Refuse :: !Text -> Accept vData
class Acceptable v
acceptableVersion :: Acceptable v => v -> v -> Accept v
data VersionMismatch vNum
[NoCommonVersion] :: VersionMismatch vNum
[InconsistentVersion] :: vNum -> VersionMismatch vNum

-- | Singleton smart constructor for <a>Versions</a>.
simpleSingletonVersions :: vNum -> vData -> r -> Versions vNum vData r

-- | Useful for folding multiple <a>Versions</a>.
--   
--   A <a>foldMap</a> restricted to the <a>Versions</a> <a>Semigroup</a>.
--   
--   PRECONDITION: <tt>f x</tt> is non-empty.
foldMapVersions :: (Ord vNum, Foldable f, HasCallStack) => (x -> Versions vNum extra r) -> f x -> Versions vNum extra r
combineVersions :: (Ord vNum, Foldable f, HasCallStack) => f (Versions vNum extra r) -> Versions vNum extra r
instance GHC.Show.Show vData => GHC.Show.Show (Ouroboros.Network.Protocol.Handshake.Version.Accept vData)
instance GHC.Classes.Eq vData => GHC.Classes.Eq (Ouroboros.Network.Protocol.Handshake.Version.Accept vData)
instance GHC.Base.Functor (Ouroboros.Network.Protocol.Handshake.Version.Application vData)
instance GHC.Base.Functor (Ouroboros.Network.Protocol.Handshake.Version.Version vData)
instance GHC.Classes.Ord vNum => GHC.Base.Semigroup (Ouroboros.Network.Protocol.Handshake.Version.Versions vNum vData r)
instance GHC.Base.Functor (Ouroboros.Network.Protocol.Handshake.Version.Versions vNum extra)


-- | Common values for size and time limits used by ourobors-network.
module Ouroboros.Network.Protocol.Limits
largeByteLimit :: Word
smallByteLimit :: Word
shortWait :: Maybe DiffTime
longWait :: Maybe DiffTime
waitForever :: Maybe DiffTime

module Ouroboros.Network.Server.ConnectionTable
data ConnectionTable m addr
data ConnectionTableRef

-- | No connection to peer exists, attempt to create one.
ConnectionTableCreate :: ConnectionTableRef

-- | A connection to the peer existed, either from another subscriber or
--   the peer opened one towards us.
ConnectionTableExist :: ConnectionTableRef

-- | This subscriber already has counted a connection to this peer. It must
--   try another target.
ConnectionTableDuplicate :: ConnectionTableRef

-- | ValencyCounter represents how many active connections we have towards
--   a given peer. It starts out with a positive value representing a
--   desired number of connections for a specific subscription worker. It
--   can become negative, for example if a peer opens multiple connections
--   to us. The vcId is unique per ConnectionTable and ensures that we
--   won't count the same connection twice.
data ValencyCounter m

-- | Create a new ConnectionTable.
newConnectionTableSTM :: MonadSTM m => STM m (ConnectionTable m addr)
newConnectionTable :: MonadSTM m => m (ConnectionTable m addr)

-- | Try to see if it is possible to reference an existing connection
--   rather than creating a new one to the provied peer.
refConnectionSTM :: (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> ValencyCounter m -> STM m ConnectionTableRef
refConnection :: (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> ValencyCounter m -> m ConnectionTableRef

-- | Insert a new connection into the ConnectionTable.
addConnection :: forall m addr. (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> addr -> Maybe (ValencyCounter m) -> STM m ()

-- | Remove a Connection.
removeConnectionSTM :: forall m addr. (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> addr -> STM m ()
removeConnection :: forall m addr. (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> addr -> m ()

-- | Create a new ValencyCounter
newValencyCounter :: MonadSTM m => ConnectionTable m addr -> Int -> STM m (ValencyCounter m)

-- | Add a connection.
addValencyCounter :: MonadSTM m => ValencyCounter m -> STM m ()

-- | Remove a connection.
remValencyCounter :: MonadSTM m => ValencyCounter m -> STM m ()

-- | Wait until ValencyCounter becomes positive, used for detecting when we
--   can create new connections.
waitValencyCounter :: MonadSTM m => ValencyCounter m -> STM m ()

-- | Returns current ValencyCounter value, represent the number of
--   additional connections that can be created. May be negative.
readValencyCounter :: MonadSTM m => ValencyCounter m -> STM m Int
instance GHC.Show.Show Ouroboros.Network.Server.ConnectionTable.ConnectionTableRef
instance GHC.Classes.Ord (Ouroboros.Network.Server.ConnectionTable.ValencyCounter m)
instance GHC.Classes.Eq (Ouroboros.Network.Server.ConnectionTable.ValencyCounter m)


-- | Rage limiting of accepted connections
module Ouroboros.Network.Server.RateLimiting

-- | Policy which governs how to limit the number of accepted connections.
data AcceptedConnectionsLimit
AcceptedConnectionsLimit :: !Word32 -> !Word32 -> !DiffTime -> AcceptedConnectionsLimit

-- | Hard limit of accepted connections.
[acceptedConnectionsHardLimit] :: AcceptedConnectionsLimit -> !Word32

-- | Soft limit of accepted connections. If we are above this threshold, we
--   will start rate limiting.
[acceptedConnectionsSoftLimit] :: AcceptedConnectionsLimit -> !Word32

-- | Max delay for limiting accepted connections. We use linear regression
--   starting from 0 at the soft limit up to
--   <tt>acceptedConnectionDelay</tt> at the hard limit.
[acceptedConnectionsDelay] :: AcceptedConnectionsLimit -> !DiffTime

-- | Get the number of current connections, make decision based on
--   <a>AcceptedConnectionsLimit</a> and execute it.
runConnectionRateLimits :: (MonadSTM m, MonadDelay m, MonadTime m) => Tracer m AcceptConnectionsPolicyTrace -> STM m Int -> AcceptedConnectionsLimit -> m ()

-- | Trace for the <tt>AcceptConnectionsLimit</tt> policy.
data AcceptConnectionsPolicyTrace
ServerTraceAcceptConnectionRateLimiting :: DiffTime -> Int -> AcceptConnectionsPolicyTrace
ServerTraceAcceptConnectionHardLimit :: Word32 -> AcceptConnectionsPolicyTrace
instance GHC.Show.Show Ouroboros.Network.Server.RateLimiting.AcceptedConnectionsLimit
instance GHC.Classes.Ord Ouroboros.Network.Server.RateLimiting.AcceptedConnectionsLimit
instance GHC.Classes.Eq Ouroboros.Network.Server.RateLimiting.AcceptedConnectionsLimit
instance GHC.Classes.Ord Ouroboros.Network.Server.RateLimiting.AcceptConnectionsPolicyTrace
instance GHC.Classes.Eq Ouroboros.Network.Server.RateLimiting.AcceptConnectionsPolicyTrace
instance GHC.Show.Show Ouroboros.Network.Server.RateLimiting.AcceptConnectionsPolicyTrace

module Ouroboros.Network.Snocket

-- | Named pipes and Berkeley sockets have different API when accepting a
--   connection. For named pipes the file descriptor created by
--   <tt>createNamedPipe</tt> is supposed to be used for the first
--   connected client. Named pipe accept loop looks this way:
--   
--   <pre>
--   acceptLoop k = do
--     h &lt;- createNamedPipe name
--     connectNamedPipe h
--     -- h is now in connected state
--     forkIO (k h)
--     acceptLoop k
--   </pre>
--   
--   For Berkeley sockets equivalent loop starts by creating a socket which
--   accepts connections and accept returns a new socket in connected state
--   
--   <pre>
--   acceptLoop k = do
--       s &lt;- socket ...
--       bind s address
--       listen s
--       loop s
--     where
--       loop s = do
--         (s' , _addr') &lt;- accept s
--         -- s' is in connected state
--         forkIO (k s')
--         loop s
--   </pre>
--   
--   To make common API for both we use a recursive type <a>Accept</a>, see
--   <a>berkeleyAccept</a> below. Creation of a socket / named pipe is part
--   of <a>Snocket</a>, but this means we need to have different recursion
--   step for named pipe &amp; sockets. For sockets its recursion step will
--   always return <a>accept</a> syscall; for named pipes the first
--   callback will reuse the file descriptor created by <a>open</a> and
--   only subsequent calls will create a new file descriptor by
--   <tt>createNamedPipe</tt>, see <tt>namedPipeSnocket</tt>.
newtype Accept m fd addr
Accept :: m (fd, addr, Accept m fd addr) -> Accept m fd addr
[runAccept] :: Accept m fd addr -> m (fd, addr, Accept m fd addr)

-- | We support either sockets or named pipes.
data AddressFamily addr
[SocketFamily] :: !Family -> AddressFamily SockAddr
[LocalFamily] :: AddressFamily LocalAddress

-- | Abstract communication interface that can be used by more than
--   <a>Socket</a>. Snockets are polymorphic over monad which is used, this
--   feature is useful for testing and/or simulations.
data Snocket m fd addr
Snocket :: (fd -> m addr) -> (fd -> m addr) -> (addr -> AddressFamily addr) -> (AddressFamily addr -> m fd) -> (addr -> m fd) -> (fd -> addr -> m ()) -> (fd -> addr -> m ()) -> (fd -> m ()) -> (fd -> Accept m fd addr) -> (fd -> m ()) -> (DiffTime -> Tracer m MuxTrace -> fd -> MuxBearer m) -> Snocket m fd addr
[getLocalAddr] :: Snocket m fd addr -> fd -> m addr
[getRemoteAddr] :: Snocket m fd addr -> fd -> m addr
[addrFamily] :: Snocket m fd addr -> addr -> AddressFamily addr

-- | Open a file descriptor (socket / namedPipe). For named pipes this is
--   using <tt>CreateNamedPipe</tt> syscall, for Berkeley sockets
--   <tt>socket</tt> is used..
[open] :: Snocket m fd addr -> AddressFamily addr -> m fd

-- | A way to create <tt>fd</tt> to pass to <a>connect</a>. For named pipes
--   it will use <tt>CreateFile</tt> syscall. For Berkeley sockets this the
--   same as <a>open</a>.
--   
--   For named pipes we need full <tt>addr</tt> rather than just address
--   family as it is for sockets.
[openToConnect] :: Snocket m fd addr -> addr -> m fd

-- | <a>connect</a> is only needed for Berkeley sockets, for named pipes
--   this is no-op.
[connect] :: Snocket m fd addr -> fd -> addr -> m ()
[bind] :: Snocket m fd addr -> fd -> addr -> m ()
[listen] :: Snocket m fd addr -> fd -> m ()
[accept] :: Snocket m fd addr -> fd -> Accept m fd addr
[close] :: Snocket m fd addr -> fd -> m ()
[toBearer] :: Snocket m fd addr -> DiffTime -> Tracer m MuxTrace -> fd -> MuxBearer m
type SocketSnocket = Snocket IO Socket SockAddr

-- | Create a <a>Snocket</a> for the given <a>Family</a>. In the
--   <a>bind</a> method set <a>ReuseAddr</a> and <a>ReusePort</a>.
socketSnocket :: IOManager -> SocketSnocket

-- | System dependent LocalSnocket
type LocalSnocket = Snocket IO LocalSocket LocalAddress
localSnocket :: IOManager -> FilePath -> LocalSnocket

-- | System dependent LocalSnocket type
newtype LocalSocket
LocalSocket :: LocalHandle -> LocalSocket
[getLocalHandle] :: LocalSocket -> LocalHandle

-- | Local address, on Unix is associated with <a>AF_UNIX</a> family, on
--   
--   Windows with `named-pipes`.
newtype LocalAddress
LocalAddress :: FilePath -> LocalAddress
[getFilePath] :: LocalAddress -> FilePath
localAddressFromPath :: FilePath -> LocalAddress

-- | Socket file descriptor.
data FileDescriptor

-- | We use <tt>unsafeFdSocket</tt> but <a>FileDescriptor</a> constructor
--   is not exposed. This forbids any usage of <a>FileDescriptor</a> (at
--   least in a straightforward way) using any low level functions which
--   operate on file descriptors.
socketFileDescriptor :: Socket -> IO FileDescriptor
localSocketFileDescriptor :: LocalSocket -> IO FileDescriptor
instance GHC.Show.Show Ouroboros.Network.Snocket.LocalAddress
instance GHC.Generics.Generic Ouroboros.Network.Snocket.LocalAddress
instance GHC.Classes.Ord Ouroboros.Network.Snocket.LocalAddress
instance GHC.Classes.Eq Ouroboros.Network.Snocket.LocalAddress
instance GHC.Show.Show Ouroboros.Network.Snocket.LocalSocket
instance GHC.Generics.Generic Ouroboros.Network.Snocket.LocalSocket
instance GHC.Classes.Eq Ouroboros.Network.Snocket.LocalSocket
instance GHC.Show.Show Ouroboros.Network.Snocket.FileDescriptor
instance GHC.Generics.Generic Ouroboros.Network.Snocket.FileDescriptor
instance GHC.Classes.Eq (Ouroboros.Network.Snocket.AddressFamily addr)
instance GHC.Show.Show (Ouroboros.Network.Snocket.AddressFamily addr)
instance Data.Hashable.Class.Hashable Ouroboros.Network.Snocket.LocalAddress
instance GHC.Base.Functor m => Data.Bifunctor.Bifunctor (Ouroboros.Network.Snocket.Accept m)


-- | This module contains peer state management and error policies.
module Ouroboros.Network.Subscription.PeerState

-- | Semigroup of commands which acts on <a>PeerState</a>. The <tt>t</tt>
--   variable might be initiated to <a>DiffTime</a> or <tt>Time m</tt>.
--   
--   This semigroup allows to either suspend both consumer and producer or
--   just the consumer part.
data SuspendDecision t

-- | peer is suspend; The first <tt>t</tt> is the time until which a local
--   producer is suspended, the second one is the time until which a local
--   consumer is suspended.
SuspendPeer :: !t -> !t -> SuspendDecision t

-- | suspend local consumer / initiator side until <tt>t</tt> (this mean we
--   are not allowing to communicate with the producer / responder of a
--   remote peer).
SuspendConsumer :: !t -> SuspendDecision t

-- | throw an error from the main thread.
Throw :: SuspendDecision t

-- | Action of <a>SuspendDecision</a> on <tt>Maybe <a>PeerState</a></tt>.
--   Action laws are only satisfied for the submonoid form by
--   <a>SuspendPeer</a> and <a>SuspendConsumer</a>.
suspend :: Ord (Async m ()) => Maybe (PeerState m) -> SuspendDecision Time -> (Set (Async m ()), Maybe (PeerState m))
data PeerState m

-- | active peer with its producers and consumer threads
HotPeer :: !Set (Async m ()) -> !Set (Async m ()) -> PeerState m

-- | suspended consumer: with producer threads and time until the consumer
--   is suspended
SuspendedConsumer :: !Set (Async m ()) -> !Time -> PeerState m

-- | suspended peer: producer &amp; consumer suspend time
SuspendedPeer :: !Time -> !Time -> PeerState m

-- | peer with no opened connections in either direction
ColdPeer :: PeerState m

-- | Threads which needs to be cancelled when updating the <a>PeerState</a>
--   with <a>SuspendDecision</a>.
threadsToCancel :: Ord (Async m ()) => PeerState m -> SuspendDecision diffTime -> Set (Async m ())

-- | Map from addresses to <a>PeerState</a>s; it will be be shared in a
--   <a>StrictTVar</a>.
--   
--   Abstracting <tt>t</tt> is useful for tests, the <tt>IO</tt> version
--   will use <tt>Time IO</tt>.
data PeerStates m addr

-- | Map of peer states
[PeerStates] :: !Map addr (PeerState m) -> PeerStates m addr

-- | Or an exception to throw
[ThrowException] :: Exception e => e -> PeerStates m addr
newPeerStatesVar :: MonadSTM m => m (StrictTVar m (PeerStates m addr))
newPeerStatesVarSTM :: MonadSTM m => STM m (StrictTVar m (PeerStates m addr))

-- | Periodically clean <a>PeerState</a>. It will stop when
--   <a>PeerState</a> becomes <a>ThrowException</a>.
cleanPeerStates :: (MonadSTM m, MonadAsync m, MonadTime m, MonadTimer m) => DiffTime -> StrictTVar m (PeerStates m addr) -> m ()

-- | Update <a>PeerStates</a> for a given <tt>addr</tt>, using
--   <a>suspend</a>, and return threads which must be cancelled.
--   
--   This is more efficient that using the action of <a>SuspendDecision</a>
--   on <a>PeerStates</a>, since it only uses a single dictionary lookup to
--   update the state and return the set of threads to be cancelled.
runSuspendDecision :: forall m addr e. (Ord addr, Ord (Async m ()), Exception e) => Time -> addr -> e -> SuspendDecision DiffTime -> PeerStates m addr -> (PeerStates m addr, Set (Async m ()))

-- | Register consumer in <a>PeerState</a>. This is a partial function
--   which assumes that the <a>PeerState</a> is <a>HotPeer</a>.
registerConsumer :: forall m addr. (Ord addr, Ord (Async m ())) => addr -> Async m () -> PeerStates m addr -> PeerStates m addr

-- | Unregister consumer from a <a>PeerState</a>.
unregisterConsumer :: forall m addr. (Ord addr, Ord (Async m ())) => addr -> Async m () -> PeerStates m addr -> PeerStates m addr

-- | Register producer in PeerStates. This is a partial function which
--   assumes that the <a>PeerState</a> is either <a>HotPeer</a> or
--   <a>SuspendedConsumer</a>.
registerProducer :: forall m addr. (Ord addr, Ord (Async m ())) => addr -> Async m () -> PeerStates m addr -> PeerStates m addr
unregisterProducer :: forall m addr. (Ord addr, Ord (Async m ())) => addr -> Async m () -> PeerStates m addr -> PeerStates m addr

-- | Check state before connecting to a remote peer. We will connect only
--   if it retuns <a>True</a>.
type BeforeConnect m s addr = Time -> addr -> s -> STM m (ConnectDecision s)

-- | Before connectin with a peer we make a decision to either connect to
--   it or not.
data ConnectDecision s
AllowConnection :: !s -> ConnectDecision s
DisallowConnection :: !s -> ConnectDecision s

-- | Run <a>BeforeConnect</a> callback in a <a>MonadTime</a> monad.
runBeforeConnect :: (MonadSTM m, MonadTime m) => StrictTVar m s -> BeforeConnect m s addr -> addr -> m Bool

-- | <a>BeforeConnect</a> callback: it updates peer state and return
--   boolean value wheather to connect to it or not. If a peer hasn't been
--   recorded in <a>PeerStates</a>, we add it and try to connect to it.
beforeConnectTx :: forall m addr. (MonadSTM m, Ord addr) => BeforeConnect m (PeerStates m addr) addr

-- | This is a length of time, as measured by a clock. Conversion functions
--   will treat it as seconds. It has a precision of 10^-12 s.
data DiffTime
alterAndLookup :: forall k s a. Ord k => (Maybe a -> (s, Maybe a)) -> k -> Map k a -> (Map k a, Maybe s)
instance GHC.Base.Functor Ouroboros.Network.Subscription.PeerState.SuspendDecision
instance GHC.Show.Show t => GHC.Show.Show (Ouroboros.Network.Subscription.PeerState.SuspendDecision t)
instance GHC.Classes.Ord t => GHC.Classes.Ord (Ouroboros.Network.Subscription.PeerState.SuspendDecision t)
instance GHC.Classes.Eq t => GHC.Classes.Eq (Ouroboros.Network.Subscription.PeerState.SuspendDecision t)
instance GHC.Base.Functor Ouroboros.Network.Subscription.PeerState.ConnectDecision
instance GHC.Classes.Eq (Control.Monad.Class.MonadAsync.Async m ()) => GHC.Classes.Eq (Ouroboros.Network.Subscription.PeerState.PeerState m)
instance GHC.Classes.Ord (Control.Monad.Class.MonadAsync.Async m ()) => GHC.Classes.Ord (Ouroboros.Network.Subscription.PeerState.PeerState m)
instance GHC.Show.Show addr => GHC.Show.Show (Ouroboros.Network.Subscription.PeerState.PeerStates GHC.Types.IO addr)
instance GHC.Classes.Eq addr => GHC.Classes.Eq (Ouroboros.Network.Subscription.PeerState.PeerStates GHC.Types.IO addr)
instance (Control.Monad.Class.MonadAsync.MonadAsync m, GHC.Show.Show (Control.Monad.Class.MonadFork.ThreadId m), GHC.Classes.Ord (Control.Monad.Class.MonadFork.ThreadId m)) => GHC.Show.Show (Ouroboros.Network.Subscription.PeerState.PeerState m)
instance Data.Semigroup.Action.SAct (Ouroboros.Network.Subscription.PeerState.SuspendDecision Control.Monad.Class.MonadTime.Time) (GHC.Maybe.Maybe (Ouroboros.Network.Subscription.PeerState.PeerState m))
instance GHC.Classes.Ord t => GHC.Base.Semigroup (Ouroboros.Network.Subscription.PeerState.SuspendDecision t)


-- | Error policies, and integration with <a>SuspendDecision</a>-semigroup
--   action on <a>PeerState</a>.
module Ouroboros.Network.ErrorPolicy

-- | List of error policies for exception handling and a policy for handing
--   application return values.
data ErrorPolicies
ErrorPolicies :: [ErrorPolicy] -> [ErrorPolicy] -> ErrorPolicies

-- | Application Error Policies
[epAppErrorPolicies] :: ErrorPolicies -> [ErrorPolicy]

-- | <tt>connect</tt> Error Policies
[epConErrorPolicies] :: ErrorPolicies -> [ErrorPolicy]
nullErrorPolicies :: ErrorPolicies
data ErrorPolicy
[ErrorPolicy] :: forall e. Exception e => (e -> Maybe (SuspendDecision DiffTime)) -> ErrorPolicy
evalErrorPolicy :: forall e. Exception e => e -> ErrorPolicy -> Maybe (SuspendDecision DiffTime)

-- | Evaluate a list of <a>ErrorPolicy</a>s; If none of them applies this
--   function returns <a>Nothing</a>, in this case the exception will be
--   traced and not thrown.
evalErrorPolicies :: forall e. Exception e => e -> [ErrorPolicy] -> Maybe (SuspendDecision DiffTime)

-- | Complete a connection, which receive application result (or
--   exception).
type CompleteApplication m s addr r = Result addr r -> s -> STM m (CompleteApplicationResult m addr s)
data CompleteApplicationResult m addr s
CompleteApplicationResult :: !s -> Set (Async m ()) -> Maybe (WithAddr addr ErrorPolicyTrace) -> CompleteApplicationResult m addr s

-- | new state
[carState] :: CompleteApplicationResult m addr s -> !s

-- | threads to kill
[carThreads] :: CompleteApplicationResult m addr s -> Set (Async m ())

-- | trace points
[carTrace] :: CompleteApplicationResult m addr s -> Maybe (WithAddr addr ErrorPolicyTrace)

-- | Result of the connection thread. It's either result of an application,
--   or an exception thrown by it.
data Result addr r
[ApplicationResult] :: !Time -> !addr -> !r -> Result addr r
[Connected] :: !Time -> !addr -> Result addr r
[ConnectionError] :: Exception e => !Time -> !addr -> !e -> Result addr r
[ApplicationError] :: Exception e => !Time -> !addr -> !e -> Result addr r

-- | <a>CompleteApplication</a> callback
completeApplicationTx :: forall m addr a. (MonadAsync m, Ord addr, Ord (Async m ())) => ErrorPolicies -> CompleteApplication m (PeerStates m addr) addr a

-- | Trace data for error policies
data ErrorPolicyTrace

-- | suspending peer with a given exception until
ErrorPolicySuspendPeer :: Maybe (ConnectionOrApplicationExceptionTrace SomeException) -> !DiffTime -> !DiffTime -> ErrorPolicyTrace

-- | suspending consumer until
ErrorPolicySuspendConsumer :: Maybe (ConnectionOrApplicationExceptionTrace SomeException) -> !DiffTime -> ErrorPolicyTrace

-- | caught a local exception
ErrorPolicyLocalNodeError :: ConnectionOrApplicationExceptionTrace SomeException -> ErrorPolicyTrace

-- | resume a peer (both consumer and producer)
ErrorPolicyResumePeer :: ErrorPolicyTrace

-- | consumer was suspended until producer will resume
ErrorPolicyKeepSuspended :: ErrorPolicyTrace

-- | resume consumer
ErrorPolicyResumeConsumer :: ErrorPolicyTrace

-- | resume producer
ErrorPolicyResumeProducer :: ErrorPolicyTrace

-- | an application throwed an exception, which was not handled by any
--   <a>ErrorPolicy</a>.
ErrorPolicyUnhandledApplicationException :: SomeException -> ErrorPolicyTrace

-- | <tt>connect</tt> throwed an exception, which was not handled by any
--   <a>ErrorPolicy</a>.
ErrorPolicyUnhandledConnectionException :: SomeException -> ErrorPolicyTrace

-- | <tt>accept</tt> throwed an exception
ErrorPolicyAcceptException :: IOException -> ErrorPolicyTrace
traceErrorPolicy :: Either (ConnectionOrApplicationExceptionTrace SomeException) r -> SuspendDecision DiffTime -> Maybe ErrorPolicyTrace
data WithAddr addr a
WithAddr :: !addr -> !a -> WithAddr addr a
[wiaAddr] :: WithAddr addr a -> !addr
[wiaEvent] :: WithAddr addr a -> !a

-- | Map from addresses to <a>PeerState</a>s; it will be be shared in a
--   <a>StrictTVar</a>.
--   
--   Abstracting <tt>t</tt> is useful for tests, the <tt>IO</tt> version
--   will use <tt>Time IO</tt>.
data PeerStates m addr

-- | Semigroup of commands which acts on <a>PeerState</a>. The <tt>t</tt>
--   variable might be initiated to <a>DiffTime</a> or <tt>Time m</tt>.
--   
--   This semigroup allows to either suspend both consumer and producer or
--   just the consumer part.
data SuspendDecision t

-- | peer is suspend; The first <tt>t</tt> is the time until which a local
--   producer is suspended, the second one is the time until which a local
--   consumer is suspended.
SuspendPeer :: !t -> !t -> SuspendDecision t

-- | suspend local consumer / initiator side until <tt>t</tt> (this mean we
--   are not allowing to communicate with the producer / responder of a
--   remote peer).
SuspendConsumer :: !t -> SuspendDecision t

-- | throw an error from the main thread.
Throw :: SuspendDecision t
instance GHC.Base.Functor Ouroboros.Network.ErrorPolicy.ConnectionOrApplicationExceptionTrace
instance GHC.Show.Show err => GHC.Show.Show (Ouroboros.Network.ErrorPolicy.ConnectionOrApplicationExceptionTrace err)
instance GHC.Show.Show Ouroboros.Network.ErrorPolicy.ErrorPolicyTrace
instance GHC.Base.Functor (Ouroboros.Network.ErrorPolicy.CompleteApplicationResult m addr)
instance (GHC.Show.Show addr, GHC.Show.Show a) => GHC.Show.Show (Ouroboros.Network.ErrorPolicy.WithAddr addr a)
instance GHC.Base.Semigroup Ouroboros.Network.ErrorPolicy.ErrorPolicies
instance GHC.Show.Show Ouroboros.Network.ErrorPolicy.ErrorPolicy

module Ouroboros.Network.Server.Socket

-- | Policy which governs how to limit the number of accepted connections.
data AcceptedConnectionsLimit
AcceptedConnectionsLimit :: !Word32 -> !Word32 -> !DiffTime -> AcceptedConnectionsLimit

-- | Hard limit of accepted connections.
[acceptedConnectionsHardLimit] :: AcceptedConnectionsLimit -> !Word32

-- | Soft limit of accepted connections. If we are above this threshold, we
--   will start rate limiting.
[acceptedConnectionsSoftLimit] :: AcceptedConnectionsLimit -> !Word32

-- | Max delay for limiting accepted connections. We use linear regression
--   starting from 0 at the soft limit up to
--   <tt>acceptedConnectionDelay</tt> at the hard limit.
[acceptedConnectionsDelay] :: AcceptedConnectionsLimit -> !DiffTime

-- | Trace for the <tt>AcceptConnectionsLimit</tt> policy.
data AcceptConnectionsPolicyTrace
ServerTraceAcceptConnectionRateLimiting :: DiffTime -> Int -> AcceptConnectionsPolicyTrace
ServerTraceAcceptConnectionHardLimit :: Word32 -> AcceptConnectionsPolicyTrace

-- | What to do on a new connection: accept and run this <a>IO</a>, or
--   reject.
type BeginConnection addr channel st r = Time -> addr -> st -> STM (HandleConnection channel st r)

-- | What to do with a new connection: reject it and give a new state, or
--   accept it and give a new state with a continuation to run against the
--   resulting channel. See also <a>CompleteConnection</a>, which is run
--   for every connection when it finishes, and can also update the state.
data HandleConnection channel st r
[Reject] :: !st -> HandleConnection channel st r
[Accept] :: !st -> !channel -> IO r -> HandleConnection channel st r

-- | A call back which runs when application starts;
--   
--   It is needed only because <a>BeginConnection</a> does not have access
--   to the thread which runs the application.
type ApplicationStart addr st = addr -> Async () -> st -> STM st

-- | How to update state when a connection finishes. Can use
--   <tt>throwSTM</tt> to terminate the server.
--   
--   TODO: remove <tt>async</tt>, use `Async m ()` from
--   <tt>MonadAsync</tt>.
type CompleteConnection addr st tr r = Result addr r -> st -> STM (CompleteApplicationResult IO addr st)
data CompleteApplicationResult m addr s
CompleteApplicationResult :: !s -> Set (Async m ()) -> Maybe (WithAddr addr ErrorPolicyTrace) -> CompleteApplicationResult m addr s

-- | new state
[carState] :: CompleteApplicationResult m addr s -> !s

-- | threads to kill
[carThreads] :: CompleteApplicationResult m addr s -> Set (Async m ())

-- | trace points
[carTrace] :: CompleteApplicationResult m addr s -> Maybe (WithAddr addr ErrorPolicyTrace)

-- | The product of a spawned thread. We catch all (even async) exceptions.
data Result addr r
Result :: !Async () -> !addr -> !Time -> !Either SomeException r -> Result addr r
[resultThread] :: Result addr r -> !Async ()
[resultAddr] :: Result addr r -> !addr
[resultTime] :: Result addr r -> !Time
[resultValue] :: Result addr r -> !Either SomeException r

-- | Given a current state, <tt>retry</tt> unless you want to stop the
--   server. When this transaction returns, any running threads spawned by
--   the server will be killed.
--   
--   It's possible that a connection is accepted after the main thread
--   returns, but before the server stops. In that case, it will be killed,
--   and the <a>CompleteConnection</a> will not run against it.
type Main st t = st -> STM t

-- | Run a server.
run :: Tracer IO (WithAddr addr ErrorPolicyTrace) -> Tracer IO AcceptConnectionsPolicyTrace -> Socket addr channel -> AcceptedConnectionsLimit -> (IOException -> IO ()) -> BeginConnection addr channel st r -> ApplicationStart addr st -> CompleteConnection addr st tr r -> Main st t -> TVar st -> IO t

-- | Abstraction of something that can provide connections. A <a>Socket</a>
--   can be used to get a `Socket SockAddr (Channel IO Lazy.ByteString)`
--   It's not defined in here, though, because we don't want the dependency
--   on typed-protocols or even on network.
data Socket addr channel
Socket :: IO (addr, channel, IO (), Socket addr channel) -> Socket addr channel

-- | The address, a channel, IO to close the channel.
[acceptConnection] :: Socket addr channel -> IO (addr, channel, IO (), Socket addr channel)

-- | Expected to be useful for testing.
ioSocket :: IO (addr, channel) -> Socket addr channel

module Ouroboros.Network.Subscription.Subscriber

-- | Generate subscription targets in some monad. Examples include
--   obtaining targets from a fixed list, or from a DNS lookup.
newtype SubscriptionTarget m target
SubscriptionTarget :: m (Maybe (target, SubscriptionTarget m target)) -> SubscriptionTarget m target

-- | This should be used with the exception that implementations can block
--   on the order of seconds.
[getSubscriptionTarget] :: SubscriptionTarget m target -> m (Maybe (target, SubscriptionTarget m target))
listSubscriptionTarget :: Applicative m => [target] -> SubscriptionTarget m target

module Ouroboros.Network.Subscription.Worker

-- | Callback which fires: when we create or close a socket.
type SocketStateChange m s addr = SocketState m addr -> s -> STM m s
data SocketState m addr
CreatedSocket :: !addr -> !Async m () -> SocketState m addr
ClosedSocket :: !addr -> !Async m () -> SocketState m addr

-- | Complete a connection, which receive application result (or
--   exception).
type CompleteApplication m s addr r = Result addr r -> s -> STM m (CompleteApplicationResult m addr s)

-- | GADT which classifies connection result.
data ConnectResult

-- | Successful connection.
ConnectSuccess :: ConnectResult

-- | Successfully connection, reached the valency target. Other ongoing
--   connection attempts will be killed.
ConnectSuccessLast :: ConnectResult

-- | Someone else manged to create the final connection to a target before
--   us.
ConnectValencyExceeded :: ConnectResult

-- | Result of the connection thread. It's either result of an application,
--   or an exception thrown by it.
data Result addr r
[ApplicationResult] :: !Time -> !addr -> !r -> Result addr r
[Connected] :: !Time -> !addr -> Result addr r
[ConnectionError] :: Exception e => !Time -> !addr -> !e -> Result addr r
[ApplicationError] :: Exception e => !Time -> !addr -> !e -> Result addr r

-- | Given current state <a>retry</a> too keep the subscription worker
--   going. When this transaction returns, all the threads spawned by the
--   worker will be killed.
type Main m s t = s -> STM m t

-- | Mutable state kept by the worker. All the workers in this module are
--   polymorphic over the state type. The state is updated with two
--   callbacks:
--   
--   <ul>
--   <li><tt>CompleteConnect</tt> - STM transaction which runs when the
--   connect call returned, if it thrown an exception it will be passed to
--   the callback.</li>
--   <li><a>CompleteApplication</a> - STM transaction which runs when
--   application returned. It will receive the result of the application or
--   an exception raised by it.</li>
--   </ul>
type StateVar m s = StrictTVar m s
data LocalAddresses addr
LocalAddresses :: Maybe addr -> Maybe addr -> Maybe addr -> LocalAddresses addr

-- | Local IPv4 address to use, Nothing indicates don't use IPv4
[laIpv4] :: LocalAddresses addr -> Maybe addr

-- | Local IPv6 address to use, Nothing indicates don't use IPv6
[laIpv6] :: LocalAddresses addr -> Maybe addr

-- | Local Unix address to use, Nothing indicates don't use Unix sockets
[laUnix] :: LocalAddresses addr -> Maybe addr

-- | Worker STM callbacks
data WorkerCallbacks m s addr a t
WorkerCallbacks :: SocketStateChange m s addr -> CompleteApplication m s addr a -> Main m s t -> WorkerCallbacks m s addr a t
[wcSocketStateChangeTx] :: WorkerCallbacks m s addr a t -> SocketStateChange m s addr
[wcCompleteApplicationTx] :: WorkerCallbacks m s addr a t -> CompleteApplication m s addr a
[wcMainTx] :: WorkerCallbacks m s addr a t -> Main m s t

-- | Worker parameters
data WorkerParams m localAddrs addr
WorkerParams :: localAddrs addr -> (addr -> localAddrs addr -> Maybe addr) -> (addr -> Maybe DiffTime) -> m (SubscriptionTarget m addr) -> Int -> WorkerParams m localAddrs addr

-- | local addresses of the server
[wpLocalAddresses] :: WorkerParams m localAddrs addr -> localAddrs addr

-- | given remote addr pick the local address
[wpSelectAddress] :: WorkerParams m localAddrs addr -> addr -> localAddrs addr -> Maybe addr

-- | delay after a connection attempt to <tt>addr</tt>
[wpConnectionAttemptDelay] :: WorkerParams m localAddrs addr -> addr -> Maybe DiffTime
[wpSubscriptionTarget] :: WorkerParams m localAddrs addr -> m (SubscriptionTarget m addr)
[wpValency] :: WorkerParams m localAddrs addr -> Int

-- | This is the most abstract worker, which puts all the pieces together.
--   It will execute until <tt>main :: Main m s t</tt> returns. It runs
--   <a>subscriptionLoop</a> in a new threads and will exit when it dies.
--   Spawn threads are cancelled in a <a>finally</a> callback by throwing
--   <a>SubscriberError</a>.
--   
--   Note: This function runs in <a>IO</a> only because <a>MonadSTM</a>
--   does not yet support <a>orElse</a>, PR #432.
worker :: forall s sock localAddrs addr a x. Ord addr => Tracer IO (SubscriptionTrace addr) -> Tracer IO (WithAddr addr ErrorPolicyTrace) -> ConnectionTable IO addr -> StateVar IO s -> Snocket IO sock addr -> WorkerCallbacks IO s addr a x -> WorkerParams IO localAddrs addr -> (sock -> IO a) -> IO x

-- | Allocate a socket and connect to a peer, execute the continuation with
--   async exceptions masked. The continuation receives the <tt>unmask</tt>
--   callback.
safeConnect :: (MonadThrow m, MonadMask m) => Snocket m sock addr -> addr -> addr -> m () -> m () -> ((forall x. m x -> m x) -> sock -> Either SomeException () -> m t) -> m t

-- | Time to wait between connection attempts when we don't have any DeltaQ
--   info.
defaultConnectionAttemptDelay :: DiffTime

-- | Minimum time to wait between connection attempts.
minConnectionAttemptDelay :: DiffTime

-- | Maximum time to wait between connection attempts.
maxConnectionAttemptDelay :: DiffTime

-- | Minimum time to wait between ip reconnects
ipRetryDelay :: DiffTime
data SubscriberError
SubscriberError :: !SubscriberErrorType -> !String -> !CallStack -> SubscriberError
[seType] :: SubscriberError -> !SubscriberErrorType
[seMessage] :: SubscriberError -> !String
[seStack] :: SubscriberError -> !CallStack
data SubscriptionTrace addr
SubscriptionTraceConnectStart :: addr -> SubscriptionTrace addr
SubscriptionTraceConnectEnd :: addr -> ConnectResult -> SubscriptionTrace addr
SubscriptionTraceSocketAllocationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceConnectException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceApplicationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceTryConnectToPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSkippingPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSubscriptionRunning :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaiting :: Int -> SubscriptionTrace addr
SubscriptionTraceSubscriptionFailed :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaitingNewConnection :: DiffTime -> SubscriptionTrace addr
SubscriptionTraceStart :: Int -> SubscriptionTrace addr
SubscriptionTraceRestart :: DiffTime -> Int -> Int -> SubscriptionTrace addr
SubscriptionTraceConnectionExist :: addr -> SubscriptionTrace addr
SubscriptionTraceUnsupportedRemoteAddr :: addr -> SubscriptionTrace addr
SubscriptionTraceMissingLocalAddress :: SubscriptionTrace addr
SubscriptionTraceAllocateSocket :: addr -> SubscriptionTrace addr
SubscriptionTraceCloseSocket :: addr -> SubscriptionTrace addr
instance GHC.Show.Show addr => GHC.Show.Show (Ouroboros.Network.Subscription.Worker.LocalAddresses addr)
instance GHC.Classes.Eq addr => GHC.Classes.Eq (Ouroboros.Network.Subscription.Worker.LocalAddresses addr)
instance GHC.Show.Show Ouroboros.Network.Subscription.Worker.ConnectResult
instance GHC.Classes.Ord Ouroboros.Network.Subscription.Worker.ConnectResult
instance GHC.Classes.Eq Ouroboros.Network.Subscription.Worker.ConnectResult
instance GHC.Show.Show Ouroboros.Network.Subscription.Worker.SubscriberErrorType
instance GHC.Classes.Eq Ouroboros.Network.Subscription.Worker.SubscriberErrorType
instance GHC.Show.Show Ouroboros.Network.Subscription.Worker.SubscriberError
instance GHC.Show.Show addr => GHC.Show.Show (Ouroboros.Network.Subscription.Worker.SubscriptionTrace addr)
instance GHC.Exception.Type.Exception Ouroboros.Network.Subscription.Worker.SubscriberError
instance GHC.Base.Semigroup (Ouroboros.Network.Subscription.Worker.LocalAddresses addr)

module Ouroboros.Network.Util.ShowProxy
class ShowProxy p
showProxy :: ShowProxy p => Proxy p -> String
showProxy :: (ShowProxy p, Typeable p) => Proxy p -> String

-- | <a>Proxy</a> is a type that holds no data, but has a phantom parameter
--   of arbitrary type (or even kind). Its use is to provide type
--   information, even though there is no value available of that type (or
--   it may be too costly to create one).
--   
--   Historically, <tt><a>Proxy</a> :: <a>Proxy</a> a</tt> is a safer
--   alternative to the <tt><a>undefined</a> :: a</tt> idiom.
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy (Void, Int -&gt; Int)
--   Proxy
--   </pre>
--   
--   Proxy can even hold types of higher kinds,
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Either
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy Functor
--   Proxy
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; Proxy :: Proxy complicatedStructure
--   Proxy
--   </pre>
data Proxy (t :: k)
Proxy :: Proxy (t :: k)
instance Ouroboros.Network.Util.ShowProxy.ShowProxy GHC.Types.Int

module Ouroboros.Network.Protocol.Handshake.Type

-- | The handshake mini-protocol is used initially to agree the version and
--   associated parameters of the protocol to use for all subsequent
--   communication.
data Handshake vNumber vParams
[StPropose] :: Handshake vNumber vParams
[StConfirm] :: Handshake vNumber vParams
[StDone] :: Handshake vNumber vParams

-- | The messages for this protocol. It is expected to be a GADT that is
--   indexed by the <tt>from</tt> and <tt>to</tt> protocol states. That is
--   the protocol state the message transitions from, and the protocol
--   state it transitions into. These are the edges of the protocol state
--   transition system.
data family Message ps (st :: ps) (st' :: ps)

-- | Tokens for those protocol states in which the client has agency.
data family ClientHasAgency (st :: ps)

-- | Tokens for those protocol states in which the server has agency.
data family ServerHasAgency (st :: ps)

-- | Tokens for terminal protocol states in which neither the client nor
--   server has agency.
data family NobodyHasAgency (st :: ps)

-- | Reasons by which a server can refuse proposed version.
data RefuseReason vNumber

-- | All of the prosed versions where not known to the server. Since the
--   server sends all versions that it can knows about, some of them we
--   might not be able to decode, so we include raw tags <tt>[Int]</tt>.
VersionMismatch :: [vNumber] -> [Int] -> RefuseReason vNumber

-- | The server failed to decode version parameters.
HandshakeDecodeError :: vNumber -> Text -> RefuseReason vNumber

-- | The server refused to run the proposed version parameters
Refused :: vNumber -> Text -> RefuseReason vNumber

-- | Client errors, which extends handshake error
--   <tt><a>RefuseReason</a></tt> type, by client specific errors.
data HandshakeClientProtocolError vNumber
HandshakeError :: RefuseReason vNumber -> HandshakeClientProtocolError vNumber
NotRecognisedVersion :: vNumber -> HandshakeClientProtocolError vNumber
InvalidServerSelection :: vNumber -> Text -> HandshakeClientProtocolError vNumber
instance GHC.Show.Show vNumber => GHC.Show.Show (Ouroboros.Network.Protocol.Handshake.Type.RefuseReason vNumber)
instance GHC.Classes.Eq vNumber => GHC.Classes.Eq (Ouroboros.Network.Protocol.Handshake.Type.RefuseReason vNumber)
instance GHC.Show.Show vNumber => GHC.Show.Show (Ouroboros.Network.Protocol.Handshake.Type.HandshakeClientProtocolError vNumber)
instance GHC.Classes.Eq vNumber => GHC.Classes.Eq (Ouroboros.Network.Protocol.Handshake.Type.HandshakeClientProtocolError vNumber)
instance forall vNumber vParams (from :: Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams) (to :: Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams). (GHC.Show.Show vNumber, GHC.Show.Show vParams) => GHC.Show.Show (Network.TypedProtocol.Core.Message (Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams) from to)
instance (Data.Typeable.Internal.Typeable vNumber, GHC.Show.Show vNumber) => GHC.Exception.Type.Exception (Ouroboros.Network.Protocol.Handshake.Type.HandshakeClientProtocolError vNumber)
instance (Data.Typeable.Internal.Typeable vNumber, GHC.Show.Show vNumber) => GHC.Exception.Type.Exception (Ouroboros.Network.Protocol.Handshake.Type.RefuseReason vNumber)
instance forall k1 k2 (vNumber :: k1) (vParams :: k2). Network.TypedProtocol.Core.Protocol (Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams)
instance forall k1 k2 (vNumber :: k1) (vParams :: k2). Ouroboros.Network.Util.ShowProxy.ShowProxy (Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams)
instance forall k1 k2 (vNumber :: k1) (vParams :: k2) (st :: Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams). GHC.Show.Show (Network.TypedProtocol.Core.ClientHasAgency st)
instance forall k1 k2 (vNumber :: k1) (vParams :: k2) (st :: Ouroboros.Network.Protocol.Handshake.Type.Handshake vNumber vParams). GHC.Show.Show (Network.TypedProtocol.Core.ServerHasAgency st)


-- | Drivers for running <a>Peer</a>s with a <a>Codec</a> and a
--   <a>Channel</a>.
module Ouroboros.Network.Driver.Simple

-- | Run a peer with the given channel via the given codec.
--   
--   This runs the peer to completion (if the protocol allows for
--   termination).
runPeer :: forall ps (st :: ps) pr failure bytes m a. (MonadThrow m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> Peer ps pr st m a -> m (a, Maybe bytes)

-- | Structured <a>Tracer</a> output for <a>runPeer</a> and derivitives.
data TraceSendRecv ps
[TraceSendMsg] :: AnyMessageAndAgency ps -> TraceSendRecv ps
[TraceRecvMsg] :: AnyMessageAndAgency ps -> TraceSendRecv ps
data DecoderFailure
[DecoderFailure] :: forall (pr :: PeerRole) ps (st :: ps) failure. (forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps, Show failure) => PeerHasAgency pr st -> failure -> DecoderFailure

-- | Run a pipelined peer with the given channel via the given codec.
--   
--   This runs the peer to completion (if the protocol allows for
--   termination).
--   
--   Unlike normal peers, running pipelined peers rely on concurrency,
--   hence the <a>MonadSTM</a> constraint.
runPipelinedPeer :: forall ps (st :: ps) pr failure bytes m a. (MonadAsync m, MonadThrow m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> PeerPipelined ps pr st m a -> m (a, Maybe bytes)

-- | Run two <a>Peer</a>s via a pair of connected <a>Channel</a>s and a
--   common <a>Codec</a>.
--   
--   This is useful for tests and quick experiments.
--   
--   The first argument is expected to create two channels that are
--   connected, for example <a>createConnectedChannels</a>.
runConnectedPeers :: (MonadSTM m, MonadAsync m, MonadCatch m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => m (Channel m bytes, Channel m bytes) -> Tracer m (PeerRole, TraceSendRecv ps) -> Codec ps failure m bytes -> Peer ps pr st m a -> Peer ps (FlipAgency pr) st m b -> m (a, b)
runConnectedPeersAsymmetric :: (MonadSTM m, MonadAsync m, MonadCatch m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => m (Channel m bytes, Channel m bytes) -> Tracer m (PeerRole, TraceSendRecv ps) -> Codec ps failure m bytes -> Codec ps failure m bytes -> Peer ps pr st m a -> Peer ps (FlipAgency pr) st m b -> m (a, b)
runConnectedPeersPipelined :: (MonadSTM m, MonadAsync m, MonadCatch m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => m (Channel m bytes, Channel m bytes) -> Tracer m (PeerRole, TraceSendRecv ps) -> Codec ps failure m bytes -> PeerPipelined ps pr st m a -> Peer ps (FlipAgency pr) st m b -> m (a, b)
instance GHC.Show.Show Ouroboros.Network.Driver.Simple.DecoderFailure
instance GHC.Exception.Type.Exception Ouroboros.Network.Driver.Simple.DecoderFailure
instance GHC.Show.Show (Network.TypedProtocol.Codec.AnyMessageAndAgency ps) => GHC.Show.Show (Ouroboros.Network.Driver.Simple.TraceSendRecv ps)


-- | Drivers for running <a>Peer</a>s.
module Ouroboros.Network.Driver.Limits
data ProtocolSizeLimits ps bytes
ProtocolSizeLimits :: (forall (pr :: PeerRole) (st :: ps). PeerHasAgency pr st -> Word) -> (bytes -> Word) -> ProtocolSizeLimits ps bytes
[sizeLimitForState] :: ProtocolSizeLimits ps bytes -> forall (pr :: PeerRole) (st :: ps). PeerHasAgency pr st -> Word
[dataSize] :: ProtocolSizeLimits ps bytes -> bytes -> Word
data ProtocolTimeLimits ps
ProtocolTimeLimits :: (forall (pr :: PeerRole) (st :: ps). PeerHasAgency pr st -> Maybe DiffTime) -> ProtocolTimeLimits ps
[timeLimitForState] :: ProtocolTimeLimits ps -> forall (pr :: PeerRole) (st :: ps). PeerHasAgency pr st -> Maybe DiffTime
data ProtocolLimitFailure
[ExceededSizeLimit] :: forall (pr :: PeerRole) ps (st :: ps). (forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => PeerHasAgency pr st -> ProtocolLimitFailure
[ExceededTimeLimit] :: forall (pr :: PeerRole) ps (st :: ps). (forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => PeerHasAgency pr st -> ProtocolLimitFailure
runPeerWithLimits :: forall ps (st :: ps) pr failure bytes m a. (MonadAsync m, MonadFork m, MonadMask m, MonadThrow (STM m), MonadMonotonicTime m, MonadTimer m, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> ProtocolSizeLimits ps bytes -> ProtocolTimeLimits ps -> Channel m bytes -> Peer ps pr st m a -> m (a, Maybe bytes)

-- | Structured <a>Tracer</a> output for <a>runPeer</a> and derivitives.
data TraceSendRecv ps
[TraceSendMsg] :: AnyMessageAndAgency ps -> TraceSendRecv ps
[TraceRecvMsg] :: AnyMessageAndAgency ps -> TraceSendRecv ps

-- | Run a pipelined peer with the given channel via the given codec.
--   
--   This runs the peer to completion (if the protocol allows for
--   termination).
--   
--   Unlike normal peers, running pipelined peers rely on concurrency,
--   hence the <a>MonadSTM</a> constraint.
runPipelinedPeerWithLimits :: forall ps (st :: ps) pr failure bytes m a. (MonadAsync m, MonadFork m, MonadMask m, MonadThrow (STM m), MonadMonotonicTime m, MonadTimer m, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> ProtocolSizeLimits ps bytes -> ProtocolTimeLimits ps -> Channel m bytes -> PeerPipelined ps pr st m a -> m (a, Maybe bytes)
driverWithLimits :: forall ps failure bytes m. (MonadThrow m, Show failure, ShowProxy ps, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st')) => Tracer m (TraceSendRecv ps) -> TimeoutFn m -> Codec ps failure m bytes -> ProtocolSizeLimits ps bytes -> ProtocolTimeLimits ps -> Channel m bytes -> Driver ps (Maybe bytes) m
instance GHC.Show.Show Ouroboros.Network.Driver.Limits.ProtocolLimitFailure
instance GHC.Exception.Type.Exception Ouroboros.Network.Driver.Limits.ProtocolLimitFailure

module Ouroboros.Network.Protocol.Handshake.Codec

-- | <tt><a>Handshake</a></tt> codec. The
--   <tt><a>MsgProposeVersions</a></tt> encodes proposed map in ascending
--   order and it expects to receive them in this order. This allows to
--   construct the map in linear time. There is also another limiting
--   factor to the number of versions on can present: the whole message
--   must fit into a single TCP segment.
codecHandshake :: forall vNumber m failure. (MonadST m, Ord vNumber, Show failure) => CodecCBORTerm (failure, Maybe Int) vNumber -> Codec (Handshake vNumber Term) DeserialiseFailure m ByteString

-- | Byte limits
byteLimitsHandshake :: forall vNumber. ProtocolSizeLimits (Handshake vNumber Term) ByteString

-- | Time limits.
--   
--   We use a bearer which has `10s` timeout on sending or receiving a
--   single <tt>MuxSDU</tt>. Handshake messages must fit into a single
--   <tt>MuxSDU</tt>, thus we don't set another timeout here.
timeLimitsHandshake :: forall vNumber. ProtocolTimeLimits (Handshake vNumber Term)
encodeRefuseReason :: CodecCBORTerm fail vNumber -> RefuseReason vNumber -> Encoding
decodeRefuseReason :: Show failure => CodecCBORTerm (failure, Maybe Int) vNumber -> Decoder s (RefuseReason vNumber)

-- | Codec for version data (<tt>vData</tt> in code) exchanged by the
--   handshake protocol.
--   
--   Note: <tt>extra</tt> type param is instantiated to
--   <tt>DictVersion</tt>; <tt>agreedOptions</tt> is instatiated to
--   <tt>NodeToNodeVersionData</tt> in <a>Ouroboros.Network.NodeToNode</a>
--   or to <tt>()</tt> in <a>Ouroboros.Network.NodeToClient</a>.
data VersionDataCodec bytes vNumber vData
VersionDataCodec :: (vNumber -> vData -> bytes) -> (vNumber -> bytes -> Either Text vData) -> VersionDataCodec bytes vNumber vData

-- | encoder of <tt>vData</tt> which has access to 'extra vData' which can
--   bring extra instances into the scope (by means of pattern matching on
--   a GADT).
[encodeData] :: VersionDataCodec bytes vNumber vData -> vNumber -> vData -> bytes

-- | decoder of <tt>vData</tt>.
[decodeData] :: VersionDataCodec bytes vNumber vData -> vNumber -> bytes -> Either Text vData
cborTermVersionDataCodec :: (vNumber -> CodecCBORTerm Text vData) -> VersionDataCodec Term vNumber vData


-- | Unversioned protocol, used in tests and demo applications.
module Ouroboros.Network.Protocol.Handshake.Unversioned

-- | Version negotiation for an unversioned protocol. We only use this for
--   tests and demos where proper versioning is excessive.
data UnversionedProtocol
UnversionedProtocol :: UnversionedProtocol
data UnversionedProtocolData
UnversionedProtocolData :: UnversionedProtocolData

-- | <a>Handshake</a> codec used in various tests.
unversionedHandshakeCodec :: MonadST m => Codec (Handshake UnversionedProtocol Term) DeserialiseFailure m ByteString
unversionedProtocolDataCodec :: UnversionedProtocol -> CodecCBORTerm Text UnversionedProtocolData

-- | Make a <a>Versions</a> for an unversioned protocol. Only use this for
--   tests and demos where proper versioning is excessive.
unversionedProtocol :: app -> Versions UnversionedProtocol UnversionedProtocolData app
instance GHC.Show.Show Ouroboros.Network.Protocol.Handshake.Unversioned.UnversionedProtocol
instance GHC.Classes.Ord Ouroboros.Network.Protocol.Handshake.Unversioned.UnversionedProtocol
instance GHC.Classes.Eq Ouroboros.Network.Protocol.Handshake.Unversioned.UnversionedProtocol
instance GHC.Show.Show Ouroboros.Network.Protocol.Handshake.Unversioned.UnversionedProtocolData
instance GHC.Classes.Eq Ouroboros.Network.Protocol.Handshake.Unversioned.UnversionedProtocolData
instance Ouroboros.Network.Protocol.Handshake.Version.Acceptable Ouroboros.Network.Protocol.Handshake.Unversioned.UnversionedProtocolData

module Ouroboros.Network.Protocol.Handshake.Server

-- | Server following the handshake protocol; it accepts highest version
--   offered by the peer that also belongs to the server <tt>versions</tt>.
--   
--   TODO: GADT encoding of the server (<tt>Handshake.Server</tt> module).
handshakeServerPeer :: Ord vNumber => VersionDataCodec vParams vNumber vData -> (vData -> vData -> Accept vData) -> Versions vNumber vData r -> Peer (Handshake vNumber vParams) AsServer StPropose m (Either (RefuseReason vNumber) (r, vNumber, vData))

module Ouroboros.Network.Protocol.Handshake.Client

-- | Handshake client which offers <tt><a>Versions</a> vNumber vData</tt>
--   to the remote peer.
--   
--   TODO: GADT encoding of the client (<tt>Handshake.Client</tt> module).
handshakeClientPeer :: Ord vNumber => VersionDataCodec Term vNumber vData -> (vData -> vData -> Accept vData) -> Versions vNumber vData r -> Peer (Handshake vNumber Term) AsClient StPropose m (Either (HandshakeClientProtocolError vNumber) (r, vNumber, vData))


-- | API for running <a>Handshake</a> protocol.
module Ouroboros.Network.Protocol.Handshake

-- | Run client side of the <a>Handshake</a> protocol
runHandshakeClient :: (MonadAsync m, MonadFork m, MonadMonotonicTime m, MonadTimer m, MonadMask m, MonadThrow (STM m), Ord vNumber) => MuxBearer m -> connectionId -> (vData -> vData -> Accept vData) -> HandshakeArguments connectionId vNumber vData m application -> m (Either (HandshakeException (HandshakeClientProtocolError vNumber)) (application, vNumber, vData))

-- | Run server side of the <a>Handshake</a> protocol.
runHandshakeServer :: (MonadAsync m, MonadFork m, MonadMonotonicTime m, MonadTimer m, MonadMask m, MonadThrow (STM m), Ord vNumber) => MuxBearer m -> connectionId -> (vData -> vData -> Accept vData) -> HandshakeArguments connectionId vNumber vData m application -> m (Either (HandshakeException (RefuseReason vNumber)) (application, vNumber, vData))

-- | Common arguments for both <a>Handshake</a> client &amp; server.
data HandshakeArguments connectionId vNumber vData m application
HandshakeArguments :: Tracer m (WithMuxBearer connectionId (TraceSendRecv (Handshake vNumber Term))) -> Codec (Handshake vNumber Term) DeserialiseFailure m ByteString -> VersionDataCodec Term vNumber vData -> Versions vNumber vData application -> HandshakeArguments connectionId vNumber vData m application

-- | <a>Handshake</a> tracer
[haHandshakeTracer] :: HandshakeArguments connectionId vNumber vData m application -> Tracer m (WithMuxBearer connectionId (TraceSendRecv (Handshake vNumber Term)))

-- | Codec for protocol messages.
[haHandshakeCodec] :: HandshakeArguments connectionId vNumber vData m application -> Codec (Handshake vNumber Term) DeserialiseFailure m ByteString

-- | A codec for protocol parameters.
[haVersionDataCodec] :: HandshakeArguments connectionId vNumber vData m application -> VersionDataCodec Term vNumber vData

-- | versioned application aggreed upon with the <a>Handshake</a> protocol.
[haVersions] :: HandshakeArguments connectionId vNumber vData m application -> Versions vNumber vData application

-- | Wrapper around initiator and responder errors experienced by
--   tryHandshake.
data HandshakeException a
HandshakeProtocolLimit :: ProtocolLimitFailure -> HandshakeException a
HandshakeProtocolError :: a -> HandshakeException a


-- | Drivers for running <tt>Peer</tt>s with a <tt>Codec</tt> and a
--   <tt>Channel</tt>.
module Ouroboros.Network.Driver

-- | Run a peer with the given channel via the given codec.
--   
--   This runs the peer to completion (if the protocol allows for
--   termination).
runPeer :: forall ps (st :: ps) pr failure bytes m a. (MonadThrow m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> Peer ps pr st m a -> m (a, Maybe bytes)
runPeerWithLimits :: forall ps (st :: ps) pr failure bytes m a. (MonadAsync m, MonadFork m, MonadMask m, MonadThrow (STM m), MonadMonotonicTime m, MonadTimer m, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> ProtocolSizeLimits ps bytes -> ProtocolTimeLimits ps -> Channel m bytes -> Peer ps pr st m a -> m (a, Maybe bytes)

-- | Structured <a>Tracer</a> output for <a>runPeer</a> and derivitives.
data TraceSendRecv ps
[TraceSendMsg] :: AnyMessageAndAgency ps -> TraceSendRecv ps
[TraceRecvMsg] :: AnyMessageAndAgency ps -> TraceSendRecv ps

-- | Run a pipelined peer with the given channel via the given codec.
--   
--   This runs the peer to completion (if the protocol allows for
--   termination).
--   
--   Unlike normal peers, running pipelined peers rely on concurrency,
--   hence the <a>MonadSTM</a> constraint.
runPipelinedPeer :: forall ps (st :: ps) pr failure bytes m a. (MonadAsync m, MonadThrow m, Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Channel m bytes -> PeerPipelined ps pr st m a -> m (a, Maybe bytes)

-- | Run a pipelined peer with the given channel via the given codec.
--   
--   This runs the peer to completion (if the protocol allows for
--   termination).
--   
--   Unlike normal peers, running pipelined peers rely on concurrency,
--   hence the <a>MonadSTM</a> constraint.
runPipelinedPeerWithLimits :: forall ps (st :: ps) pr failure bytes m a. (MonadAsync m, MonadFork m, MonadMask m, MonadThrow (STM m), MonadMonotonicTime m, MonadTimer m, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps, Show failure) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> ProtocolSizeLimits ps bytes -> ProtocolTimeLimits ps -> Channel m bytes -> PeerPipelined ps pr st m a -> m (a, Maybe bytes)

module Ouroboros.Network.Mux
data MuxMode
[InitiatorMode] :: MuxMode
[ResponderMode] :: MuxMode
[InitiatorResponderMode] :: MuxMode

-- | Like <tt>MuxApplication</tt> but using a <a>MuxPeer</a> rather than a
--   raw <tt>Channel -&gt; m a</tt> action.
newtype OuroborosApplication (mode :: MuxMode) addr bytes m a b
OuroborosApplication :: (ConnectionId addr -> ControlMessageSTM m -> [MiniProtocol mode bytes m a b]) -> OuroborosApplication (mode :: MuxMode) addr bytes m a b
data MiniProtocol (mode :: MuxMode) bytes m a b
MiniProtocol :: !MiniProtocolNum -> !MiniProtocolLimits -> !RunMiniProtocol mode bytes m a b -> MiniProtocol (mode :: MuxMode) bytes m a b
[miniProtocolNum] :: MiniProtocol (mode :: MuxMode) bytes m a b -> !MiniProtocolNum
[miniProtocolLimits] :: MiniProtocol (mode :: MuxMode) bytes m a b -> !MiniProtocolLimits
[miniProtocolRun] :: MiniProtocol (mode :: MuxMode) bytes m a b -> !RunMiniProtocol mode bytes m a b

-- | The wire format includes the protocol numbers, and it's vital that
--   these are stable. They are not necessarily dense however, as new ones
--   are added and some old ones retired. So we use a dedicated class for
--   this rather than reusing <a>Enum</a>. This also covers unrecognised
--   protocol numbers on the decoding side.
newtype MiniProtocolNum
MiniProtocolNum :: Word16 -> MiniProtocolNum

-- | Per Miniprotocol limits
data MiniProtocolLimits
MiniProtocolLimits :: !Int -> MiniProtocolLimits

-- | Limit on the maximum number of bytes that can be queued in the
--   miniprotocol's ingress queue.
[maximumIngressQueue] :: MiniProtocolLimits -> !Int
data RunMiniProtocol (mode :: MuxMode) bytes m a b
[InitiatorProtocolOnly] :: MuxPeer bytes m a -> RunMiniProtocol InitiatorMode bytes m a Void
[ResponderProtocolOnly] :: MuxPeer bytes m b -> RunMiniProtocol ResponderMode bytes m Void b
[InitiatorAndResponderProtocol] :: MuxPeer bytes m a -> MuxPeer bytes m b -> RunMiniProtocol InitiatorResponderMode bytes m a b
data MuxPeer bytes m a
[MuxPeer] :: forall (pr :: PeerRole) ps (st :: ps) failure bytes m a. (Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> Peer ps pr st m a -> MuxPeer bytes m a
[MuxPeerPipelined] :: forall (pr :: PeerRole) ps (st :: ps) failure bytes m a. (Show failure, forall (st' :: ps). Show (ClientHasAgency st'), forall (st' :: ps). Show (ServerHasAgency st'), ShowProxy ps) => Tracer m (TraceSendRecv ps) -> Codec ps failure m bytes -> PeerPipelined ps pr st m a -> MuxPeer bytes m a
[MuxPeerRaw] :: (Channel m bytes -> m (a, Maybe bytes)) -> MuxPeer bytes m a
toApplication :: (MonadCatch m, MonadAsync m) => ConnectionId addr -> ControlMessageSTM m -> OuroborosApplication mode addr ByteString m a b -> MuxApplication mode m a b

-- | Control signal sent to a mini-protocol. expected to exit, on
--   <a>Continue</a> it should continue its operation
data ControlMessage

-- | Continue operation.
Continue :: ControlMessage

-- | Hold on, e.g. do not sent messages until resumed. This is not used for
--   any hot protocol.
Quiesce :: ControlMessage

-- | The client is expected to terminate as soon as possible.
Terminate :: ControlMessage

-- | <a>ControlMessageSTM</a> should depend on <tt>muxMode</tt> (we only
--   need to shedule stop for intiator side). This is not done only because
--   this would break tests, but once the old api is removed it should be
--   possible.
type ControlMessageSTM m = STM m ControlMessage
continueForever :: Applicative (STM m) => proxy m -> ControlMessageSTM m

-- | First to finish synchronisation between <a>Terminate</a> state of
--   <a>ControlMessage</a> and an stm action.
--   
--   This should return <tt>STM m (Maybe a)</tt> but <a>STM</a> is a
--   non-injective type family, and we would need to pass <tt>Proxy m</tt>
--   to fix an ambiuous type (or use <tt>AllowAmbiguousTypes</tt>
--   extension).
timeoutWithControlMessage :: MonadSTM m => ControlMessageSTM m -> STM m a -> m (Maybe a)

-- | Error type used in accross the mux layer.
data MuxError
MuxError :: !MuxErrorType -> !String -> MuxError
[errorType] :: MuxError -> !MuxErrorType
[errorMsg] :: MuxError -> !String

-- | Enumeration of error conditions.
data MuxErrorType

-- | returned by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxUnknownMiniProtocol :: MuxErrorType

-- | return by <tt>decodeMuxSDUHeader</tt>, thrown by <a>MuxBearer</a>.
MuxDecodeError :: MuxErrorType

-- | thrown by <a>MuxBearer</a> when received a null byte.
MuxBearerClosed :: MuxErrorType

-- | thrown by <tt>demux</tt> when violating <a>maximumIngressQueue</a>
--   byte limit.
MuxIngressQueueOverRun :: MuxErrorType

-- | thrown when data arrives on a responder channel when the mux was set
--   up as an <tt>InitiatorApp</tt>.
MuxInitiatorOnly :: MuxErrorType

-- | <a>IOException</a> thrown by
MuxIOException :: IOException -> MuxErrorType

-- | thrown when reading of a single SDU takes too long
MuxSDUReadTimeout :: MuxErrorType

-- | thrown when writing a single SDU takes too long
MuxSDUWriteTimeout :: MuxErrorType

-- | Result of runMiniProtocol's completionAction in case of an error.
MuxShutdown :: !Maybe MuxErrorType -> MuxErrorType

-- | Mux stopped by <tt>stopMux</tt>
MuxCleanShutdown :: MuxErrorType

-- | Mux blocked on <tt>completionVar</tt>.
MuxBlockedOnCompletionVar :: !MiniProtocolNum -> MuxErrorType
type family HasInitiator (mode :: MuxMode) :: Bool
type family HasResponder (mode :: MuxMode) :: Bool
instance GHC.Show.Show Ouroboros.Network.Mux.ControlMessage
instance GHC.Classes.Eq Ouroboros.Network.Mux.ControlMessage


-- | Module exports interface for running a node over a socket over TCP /
--   IP.
module Ouroboros.Network.Socket
data ConnectionTable m addr
data ConnectionTableRef

-- | No connection to peer exists, attempt to create one.
ConnectionTableCreate :: ConnectionTableRef

-- | A connection to the peer existed, either from another subscriber or
--   the peer opened one towards us.
ConnectionTableExist :: ConnectionTableRef

-- | This subscriber already has counted a connection to this peer. It must
--   try another target.
ConnectionTableDuplicate :: ConnectionTableRef

-- | ValencyCounter represents how many active connections we have towards
--   a given peer. It starts out with a positive value representing a
--   desired number of connections for a specific subscription worker. It
--   can become negative, for example if a peer opens multiple connections
--   to us. The vcId is unique per ConnectionTable and ensures that we
--   won't count the same connection twice.
data ValencyCounter m

-- | Mutable state maintained by the network component.
data NetworkMutableState addr
NetworkMutableState :: ConnectionTable IO addr -> StrictTVar IO (PeerStates IO addr) -> NetworkMutableState addr

-- | <a>ConnectionTable</a> which maintains information about current
--   upstream and downstream connections.
[nmsConnectionTable] :: NetworkMutableState addr -> ConnectionTable IO addr

-- | <a>PeerStates</a> which maintains state of each downstream / upstream
--   peer that errored, misbehaved or was not interesting to us.
[nmsPeerStates] :: NetworkMutableState addr -> StrictTVar IO (PeerStates IO addr)

-- | Wrapper for OuroborosResponderApplication and
--   OuroborosInitiatorAndResponderApplication.
data SomeResponderApplication addr bytes m b
[SomeResponderApplication] :: forall appType addr bytes m a b. HasResponder appType ~ True => OuroborosApplication appType addr bytes m a b -> SomeResponderApplication addr bytes m b
newNetworkMutableState :: IO (NetworkMutableState addr)
newNetworkMutableStateSTM :: STM (NetworkMutableState addr)

-- | Clean <a>PeerStates</a> within <a>NetworkMutableState</a> every 200s
cleanNetworkMutableState :: NetworkMutableState addr -> IO ()

-- | Policy which governs how to limit the number of accepted connections.
data AcceptedConnectionsLimit
AcceptedConnectionsLimit :: !Word32 -> !Word32 -> !DiffTime -> AcceptedConnectionsLimit

-- | Hard limit of accepted connections.
[acceptedConnectionsHardLimit] :: AcceptedConnectionsLimit -> !Word32

-- | Soft limit of accepted connections. If we are above this threshold, we
--   will start rate limiting.
[acceptedConnectionsSoftLimit] :: AcceptedConnectionsLimit -> !Word32

-- | Max delay for limiting accepted connections. We use linear regression
--   starting from 0 at the soft limit up to
--   <tt>acceptedConnectionDelay</tt> at the hard limit.
[acceptedConnectionsDelay] :: AcceptedConnectionsLimit -> !DiffTime

-- | Connection is identified by local and remote address.
--   
--   TODO: the type variable which this data type fills in is called
--   <tt>peerid</tt>. We should renamed to <tt>connectionId</tt>.
data ConnectionId addr
ConnectionId :: !addr -> !addr -> ConnectionId addr
[localAddress] :: ConnectionId addr -> !addr
[remoteAddress] :: ConnectionId addr -> !addr

-- | Run a server application. It will listen on the given address for
--   incoming connection, otherwise like withServerNode'.
withServerNode :: forall vNumber vData t fd addr b. (Ord vNumber, Typeable vNumber, Show vNumber, Ord addr) => Snocket IO fd addr -> NetworkServerTracers addr vNumber -> NetworkMutableState addr -> AcceptedConnectionsLimit -> addr -> Codec (Handshake vNumber Term) DeserialiseFailure IO ByteString -> VersionDataCodec Term vNumber vData -> (vData -> vData -> Accept vData) -> Versions vNumber vData (SomeResponderApplication addr ByteString IO b) -> ErrorPolicies -> (addr -> Async Void -> IO t) -> IO t

-- | Run a server application on the provided socket. The socket must be
--   ready to accept connections. The server thread runs using
--   <tt>withAsync</tt> function, which means that it will terminate when
--   the callback terminates or throws an exception.
--   
--   TODO: we should track connections in the state and refuse connections
--   from peers we are already connected to. This is also the right place
--   to ban connection from peers which missbehaved.
--   
--   The server will run handshake protocol on each incoming connection. We
--   assume that each versin negotiation message should fit into
--   <tt><tt>maxTransmissionUnit</tt></tt> (~5k bytes).
--   
--   Note: it will open a socket in the current thread and pass it to the
--   spawned thread which runs the server. This makes it useful for
--   testing, where we need to guarantee that a socket is open before we
--   try to connect to it.
withServerNode' :: forall vNumber vData t fd addr b. (Ord vNumber, Typeable vNumber, Show vNumber, Ord addr) => Snocket IO fd addr -> NetworkServerTracers addr vNumber -> NetworkMutableState addr -> AcceptedConnectionsLimit -> fd -> Codec (Handshake vNumber Term) DeserialiseFailure IO ByteString -> VersionDataCodec Term vNumber vData -> (vData -> vData -> Accept vData) -> Versions vNumber vData (SomeResponderApplication addr ByteString IO b) -> ErrorPolicies -> (addr -> Async Void -> IO t) -> IO t

-- | Connect to a remote node. It is using bracket to enclose the
--   underlying socket acquisition. This implies that when the continuation
--   exits the underlying bearer will get closed.
--   
--   The connection will start with handshake protocol sending
--   <tt>Versions</tt> to the remote peer. It must fit into
--   <tt><tt>maxTransmissionUnit</tt></tt> (~5k bytes).
--   
--   Exceptions thrown by <tt><tt>MuxApplication</tt></tt> are rethrown by
--   <tt><tt>connectTo</tt></tt>.
connectToNode :: forall appType vNumber vData fd addr a b. (Ord vNumber, Typeable vNumber, Show vNumber, HasInitiator appType ~ True) => Snocket IO fd addr -> Codec (Handshake vNumber Term) DeserialiseFailure IO ByteString -> VersionDataCodec Term vNumber vData -> NetworkConnectTracers addr vNumber -> (vData -> vData -> Accept vData) -> Versions vNumber vData (OuroborosApplication appType addr ByteString IO a b) -> Maybe addr -> addr -> IO ()
connectToNodeSocket :: forall appType vNumber vData a b. (Ord vNumber, Typeable vNumber, Show vNumber, HasInitiator appType ~ True) => IOManager -> Codec (Handshake vNumber Term) DeserialiseFailure IO ByteString -> VersionDataCodec Term vNumber vData -> NetworkConnectTracers SockAddr vNumber -> (vData -> vData -> Accept vData) -> Versions vNumber vData (OuroborosApplication appType SockAddr ByteString IO a b) -> Socket -> IO ()

-- | Connect to a remote node using an existing socket. It is up to to
--   caller to ensure that the socket is closed in case of an exception.
--   
--   The connection will start with handshake protocol sending
--   <tt>Versions</tt> to the remote peer. It must fit into
--   <tt><tt>maxTransmissionUnit</tt></tt> (~5k bytes).
--   
--   Exceptions thrown by <tt><tt>MuxApplication</tt></tt> are rethrown by
--   <tt><tt>connectTo</tt></tt>.
connectToNode' :: forall appType vNumber vData fd addr a b. (Ord vNumber, Typeable vNumber, Show vNumber, HasInitiator appType ~ True) => Snocket IO fd addr -> Codec (Handshake vNumber Term) DeserialiseFailure IO ByteString -> VersionDataCodec Term vNumber vData -> NetworkConnectTracers addr vNumber -> (vData -> vData -> Accept vData) -> Versions vNumber vData (OuroborosApplication appType addr ByteString IO a b) -> fd -> IO ()

-- | Tracer used by <a>connectToNode</a> (and derivatives, like
--   <a>connectTo</a> or 'Ouroboros.Network.NodeToClient.connectTo).
data NetworkConnectTracers addr vNumber
NetworkConnectTracers :: Tracer IO (WithMuxBearer (ConnectionId addr) MuxTrace) -> Tracer IO (WithMuxBearer (ConnectionId addr) (TraceSendRecv (Handshake vNumber Term))) -> NetworkConnectTracers addr vNumber

-- | low level mux-network tracer, which logs mux sdu (send and received)
--   and other low level multiplexing events.
[nctMuxTracer] :: NetworkConnectTracers addr vNumber -> Tracer IO (WithMuxBearer (ConnectionId addr) MuxTrace)

-- | handshake protocol tracer; it is important for analysing version
--   negotation mismatches.
[nctHandshakeTracer] :: NetworkConnectTracers addr vNumber -> Tracer IO (WithMuxBearer (ConnectionId addr) (TraceSendRecv (Handshake vNumber Term)))
nullNetworkConnectTracers :: NetworkConnectTracers addr vNumber
debuggingNetworkConnectTracers :: (Show addr, Show vNumber) => NetworkConnectTracers addr vNumber

-- | Tracers required by a server which handles inbound connections.
data NetworkServerTracers addr vNumber
NetworkServerTracers :: Tracer IO (WithMuxBearer (ConnectionId addr) MuxTrace) -> Tracer IO (WithMuxBearer (ConnectionId addr) (TraceSendRecv (Handshake vNumber Term))) -> Tracer IO (WithAddr addr ErrorPolicyTrace) -> Tracer IO AcceptConnectionsPolicyTrace -> NetworkServerTracers addr vNumber

-- | low level mux-network tracer, which logs mux sdu (send and received)
--   and other low level multiplexing events.
[nstMuxTracer] :: NetworkServerTracers addr vNumber -> Tracer IO (WithMuxBearer (ConnectionId addr) MuxTrace)

-- | handshake protocol tracer; it is important for analysing version
--   negotation mismatches.
[nstHandshakeTracer] :: NetworkServerTracers addr vNumber -> Tracer IO (WithMuxBearer (ConnectionId addr) (TraceSendRecv (Handshake vNumber Term)))

-- | error policy tracer; must not be <a>nullTracer</a>, otherwise all the
--   exceptions which are not matched by any error policy will be caught
--   and not logged or rethrown.
[nstErrorPolicyTracer] :: NetworkServerTracers addr vNumber -> Tracer IO (WithAddr addr ErrorPolicyTrace)

-- | tracing rate limiting of accepting connections.
[nstAcceptPolicyTracer] :: NetworkServerTracers addr vNumber -> Tracer IO AcceptConnectionsPolicyTrace
nullNetworkServerTracers :: NetworkServerTracers addr vNumber
debuggingNetworkServerTracers :: (Show addr, Show vNumber) => NetworkServerTracers addr vNumber

-- | Trace for the <tt>AcceptConnectionsLimit</tt> policy.
data AcceptConnectionsPolicyTrace
ServerTraceAcceptConnectionRateLimiting :: DiffTime -> Int -> AcceptConnectionsPolicyTrace
ServerTraceAcceptConnectionHardLimit :: Word32 -> AcceptConnectionsPolicyTrace

-- | Make a server-compatible socket from a network socket.
fromSnocket :: forall fd addr. Ord addr => ConnectionTable IO addr -> Snocket IO fd addr -> fd -> Socket addr fd

-- | Accept or reject incoming connection based on the current state and
--   address of the incoming connection.
beginConnection :: forall vNumber vData addr st fd. (Ord vNumber, Typeable vNumber, Show vNumber) => Snocket IO fd addr -> Tracer IO (WithMuxBearer (ConnectionId addr) MuxTrace) -> Tracer IO (WithMuxBearer (ConnectionId addr) (TraceSendRecv (Handshake vNumber Term))) -> Codec (Handshake vNumber Term) DeserialiseFailure IO ByteString -> VersionDataCodec Term vNumber vData -> (vData -> vData -> Accept vData) -> (Time -> addr -> st -> STM (AcceptConnection st vNumber vData addr IO ByteString)) -> BeginConnection addr fd st ()

-- | Map from addresses to <a>PeerState</a>s; it will be be shared in a
--   <a>StrictTVar</a>.
--   
--   Abstracting <tt>t</tt> is useful for tests, the <tt>IO</tt> version
--   will use <tt>Time IO</tt>.
data PeerStates m addr
newConnectionTable :: MonadSTM m => m (ConnectionTable m addr)
refConnection :: (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> ValencyCounter m -> m ConnectionTableRef

-- | Insert a new connection into the ConnectionTable.
addConnection :: forall m addr. (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> addr -> Maybe (ValencyCounter m) -> STM m ()
removeConnection :: forall m addr. (MonadSTM m, Ord addr) => ConnectionTable m addr -> addr -> addr -> m ()

-- | Create a new ValencyCounter
newValencyCounter :: MonadSTM m => ConnectionTable m addr -> Int -> STM m (ValencyCounter m)

-- | Add a connection.
addValencyCounter :: MonadSTM m => ValencyCounter m -> STM m ()

-- | Remove a connection.
remValencyCounter :: MonadSTM m => ValencyCounter m -> STM m ()

-- | Wait until ValencyCounter becomes positive, used for detecting when we
--   can create new connections.
waitValencyCounter :: MonadSTM m => ValencyCounter m -> STM m ()

-- | Returns current ValencyCounter value, represent the number of
--   additional connections that can be created. May be negative.
readValencyCounter :: MonadSTM m => ValencyCounter m -> STM m Int
sockAddrFamily :: SockAddr -> Family
instance Data.Hashable.Class.Hashable Network.Socket.Types.SockAddr


-- | IP subscription worker implentation.
module Ouroboros.Network.Subscription.Ip

-- | <a>ipSubscriptionWorker</a> and <tt>dnsSubscriptionWorker</tt>
--   parameters
data SubscriptionParams a target
SubscriptionParams :: LocalAddresses SockAddr -> (SockAddr -> Maybe DiffTime) -> ErrorPolicies -> target -> SubscriptionParams a target
[spLocalAddresses] :: SubscriptionParams a target -> LocalAddresses SockAddr

-- | should return expected delay for the given address
[spConnectionAttemptDelay] :: SubscriptionParams a target -> SockAddr -> Maybe DiffTime
[spErrorPolicies] :: SubscriptionParams a target -> ErrorPolicies
[spSubscriptionTarget] :: SubscriptionParams a target -> target
type IPSubscriptionParams a = SubscriptionParams a IPSubscriptionTarget

-- | Spawns a subscription worker which will attempt to keep the specified
--   number of connections (Valency) active towards the list of IP
--   addresses given in IPSubscriptionTarget.
ipSubscriptionWorker :: forall a. Snocket IO Socket SockAddr -> Tracer IO (WithIPList (SubscriptionTrace SockAddr)) -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> NetworkMutableState SockAddr -> IPSubscriptionParams a -> (Socket -> IO a) -> IO Void

-- | Like <a>worker</a> but in <a>IO</a>; It provides address selection
--   function, <a>SocketStateChange</a> and <a>CompleteApplication</a>
--   callbacks. The <a>Main</a> callback is left as it's useful for testing
--   purposes.
subscriptionWorker :: Snocket IO Socket SockAddr -> Tracer IO (SubscriptionTrace SockAddr) -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> NetworkMutableState SockAddr -> WorkerParams IO LocalAddresses SockAddr -> ErrorPolicies -> Main IO (PeerStates IO SockAddr) x -> (Socket -> IO a) -> IO x
data IPSubscriptionTarget
IPSubscriptionTarget :: ![SockAddr] -> !Int -> IPSubscriptionTarget

-- | List of destinations to possibly connect to
[ispIps] :: IPSubscriptionTarget -> ![SockAddr]

-- | Number of parallel connections to keep actice.
[ispValency] :: IPSubscriptionTarget -> !Int
ipSubscriptionTarget :: forall m addr. (MonadSTM m, MonadTime m, Ord addr) => Tracer m (SubscriptionTrace addr) -> StrictTVar m (PeerStates m addr) -> [addr] -> SubscriptionTarget m addr
data SubscriptionTrace addr
SubscriptionTraceConnectStart :: addr -> SubscriptionTrace addr
SubscriptionTraceConnectEnd :: addr -> ConnectResult -> SubscriptionTrace addr
SubscriptionTraceSocketAllocationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceConnectException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceApplicationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceTryConnectToPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSkippingPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSubscriptionRunning :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaiting :: Int -> SubscriptionTrace addr
SubscriptionTraceSubscriptionFailed :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaitingNewConnection :: DiffTime -> SubscriptionTrace addr
SubscriptionTraceStart :: Int -> SubscriptionTrace addr
SubscriptionTraceRestart :: DiffTime -> Int -> Int -> SubscriptionTrace addr
SubscriptionTraceConnectionExist :: addr -> SubscriptionTrace addr
SubscriptionTraceUnsupportedRemoteAddr :: addr -> SubscriptionTrace addr
SubscriptionTraceMissingLocalAddress :: SubscriptionTrace addr
SubscriptionTraceAllocateSocket :: addr -> SubscriptionTrace addr
SubscriptionTraceCloseSocket :: addr -> SubscriptionTrace addr

-- | Trace data for error policies
data ErrorPolicyTrace

-- | suspending peer with a given exception until
ErrorPolicySuspendPeer :: Maybe (ConnectionOrApplicationExceptionTrace SomeException) -> !DiffTime -> !DiffTime -> ErrorPolicyTrace

-- | suspending consumer until
ErrorPolicySuspendConsumer :: Maybe (ConnectionOrApplicationExceptionTrace SomeException) -> !DiffTime -> ErrorPolicyTrace

-- | caught a local exception
ErrorPolicyLocalNodeError :: ConnectionOrApplicationExceptionTrace SomeException -> ErrorPolicyTrace

-- | resume a peer (both consumer and producer)
ErrorPolicyResumePeer :: ErrorPolicyTrace

-- | consumer was suspended until producer will resume
ErrorPolicyKeepSuspended :: ErrorPolicyTrace

-- | resume consumer
ErrorPolicyResumeConsumer :: ErrorPolicyTrace

-- | resume producer
ErrorPolicyResumeProducer :: ErrorPolicyTrace

-- | an application throwed an exception, which was not handled by any
--   <a>ErrorPolicy</a>.
ErrorPolicyUnhandledApplicationException :: SomeException -> ErrorPolicyTrace

-- | <tt>connect</tt> throwed an exception, which was not handled by any
--   <a>ErrorPolicy</a>.
ErrorPolicyUnhandledConnectionException :: SomeException -> ErrorPolicyTrace

-- | <tt>accept</tt> throwed an exception
ErrorPolicyAcceptException :: IOException -> ErrorPolicyTrace
data WithIPList a
WithIPList :: !LocalAddresses SockAddr -> ![SockAddr] -> !a -> WithIPList a
[wilSrc] :: WithIPList a -> !LocalAddresses SockAddr
[wilDsts] :: WithIPList a -> ![SockAddr]
[wilEvent] :: WithIPList a -> !a

-- | Check state before connecting to a remote peer. We will connect only
--   if it retuns <a>True</a>.
type BeforeConnect m s addr = Time -> addr -> s -> STM m (ConnectDecision s)

-- | Run <a>BeforeConnect</a> callback in a <a>MonadTime</a> monad.
runBeforeConnect :: (MonadSTM m, MonadTime m) => StrictTVar m s -> BeforeConnect m s addr -> addr -> m Bool

-- | <a>BeforeConnect</a> callback: it updates peer state and return
--   boolean value wheather to connect to it or not. If a peer hasn't been
--   recorded in <a>PeerStates</a>, we add it and try to connect to it.
beforeConnectTx :: forall m addr. (MonadSTM m, Ord addr) => BeforeConnect m (PeerStates m addr) addr

-- | <a>CompleteApplication</a> callback
completeApplicationTx :: forall m addr a. (MonadAsync m, Ord addr, Ord (Async m ())) => ErrorPolicies -> CompleteApplication m (PeerStates m addr) addr a
socketStateChangeTx :: Ord addr => SocketStateChange IO (PeerStates IO addr) addr

-- | Main callback. It throws an exception when the state becomes
--   <a>ThrowException</a>. This exception is thrown from the main thread.
mainTx :: (MonadThrow (STM m), MonadSTM m) => Main m (PeerStates m addr) Void
selectSockAddr :: SockAddr -> LocalAddresses SockAddr -> Maybe SockAddr
instance GHC.Show.Show Ouroboros.Network.Subscription.Ip.IPSubscriptionTarget
instance GHC.Classes.Eq Ouroboros.Network.Subscription.Ip.IPSubscriptionTarget
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Network.Subscription.Ip.WithIPList a)

module Ouroboros.Network.Subscription.Dns
data DnsSubscriptionTarget
DnsSubscriptionTarget :: !Domain -> !PortNumber -> !Int -> DnsSubscriptionTarget
[dstDomain] :: DnsSubscriptionTarget -> !Domain
[dstPort] :: DnsSubscriptionTarget -> !PortNumber
[dstValency] :: DnsSubscriptionTarget -> !Int
data Resolver m
Resolver :: (Domain -> m (Either DNSError [SockAddr])) -> (Domain -> m (Either DNSError [SockAddr])) -> Resolver m
[lookupA] :: Resolver m -> Domain -> m (Either DNSError [SockAddr])
[lookupAAAA] :: Resolver m -> Domain -> m (Either DNSError [SockAddr])
type DnsSubscriptionParams a = SubscriptionParams a DnsSubscriptionTarget
dnsSubscriptionWorker' :: Snocket IO Socket SockAddr -> Tracer IO (WithDomainName (SubscriptionTrace SockAddr)) -> Tracer IO (WithDomainName DnsTrace) -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> NetworkMutableState SockAddr -> IO b -> (b -> (Resolver IO -> IO (SubscriptionTarget IO SockAddr)) -> IO (SubscriptionTarget IO SockAddr)) -> DnsSubscriptionParams a -> Main IO (PeerStates IO SockAddr) x -> (Socket -> IO a) -> IO x
dnsSubscriptionWorker :: Snocket IO Socket SockAddr -> Tracer IO (WithDomainName (SubscriptionTrace SockAddr)) -> Tracer IO (WithDomainName DnsTrace) -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> NetworkMutableState SockAddr -> DnsSubscriptionParams a -> (Socket -> IO a) -> IO Void
dnsResolve :: forall a m s. (MonadAsync m, MonadCatch m, MonadTime m, MonadTimer m) => Tracer m DnsTrace -> m a -> (a -> (Resolver m -> m (SubscriptionTarget m SockAddr)) -> m (SubscriptionTarget m SockAddr)) -> StrictTVar m s -> BeforeConnect m s SockAddr -> DnsSubscriptionTarget -> m (SubscriptionTarget m SockAddr)

-- | Time to wait for an AAAA response after receiving an A response.
resolutionDelay :: DiffTime
data SubscriptionTrace addr
SubscriptionTraceConnectStart :: addr -> SubscriptionTrace addr
SubscriptionTraceConnectEnd :: addr -> ConnectResult -> SubscriptionTrace addr
SubscriptionTraceSocketAllocationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceConnectException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceApplicationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceTryConnectToPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSkippingPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSubscriptionRunning :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaiting :: Int -> SubscriptionTrace addr
SubscriptionTraceSubscriptionFailed :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaitingNewConnection :: DiffTime -> SubscriptionTrace addr
SubscriptionTraceStart :: Int -> SubscriptionTrace addr
SubscriptionTraceRestart :: DiffTime -> Int -> Int -> SubscriptionTrace addr
SubscriptionTraceConnectionExist :: addr -> SubscriptionTrace addr
SubscriptionTraceUnsupportedRemoteAddr :: addr -> SubscriptionTrace addr
SubscriptionTraceMissingLocalAddress :: SubscriptionTrace addr
SubscriptionTraceAllocateSocket :: addr -> SubscriptionTrace addr
SubscriptionTraceCloseSocket :: addr -> SubscriptionTrace addr
data DnsTrace
DnsTraceLookupException :: SomeException -> DnsTrace
DnsTraceLookupAError :: DNSError -> DnsTrace
DnsTraceLookupAAAAError :: DNSError -> DnsTrace
DnsTraceLookupIPv6First :: DnsTrace
DnsTraceLookupIPv4First :: DnsTrace
DnsTraceLookupAResult :: [SockAddr] -> DnsTrace
DnsTraceLookupAAAAResult :: [SockAddr] -> DnsTrace

-- | Trace data for error policies
data ErrorPolicyTrace

-- | suspending peer with a given exception until
ErrorPolicySuspendPeer :: Maybe (ConnectionOrApplicationExceptionTrace SomeException) -> !DiffTime -> !DiffTime -> ErrorPolicyTrace

-- | suspending consumer until
ErrorPolicySuspendConsumer :: Maybe (ConnectionOrApplicationExceptionTrace SomeException) -> !DiffTime -> ErrorPolicyTrace

-- | caught a local exception
ErrorPolicyLocalNodeError :: ConnectionOrApplicationExceptionTrace SomeException -> ErrorPolicyTrace

-- | resume a peer (both consumer and producer)
ErrorPolicyResumePeer :: ErrorPolicyTrace

-- | consumer was suspended until producer will resume
ErrorPolicyKeepSuspended :: ErrorPolicyTrace

-- | resume consumer
ErrorPolicyResumeConsumer :: ErrorPolicyTrace

-- | resume producer
ErrorPolicyResumeProducer :: ErrorPolicyTrace

-- | an application throwed an exception, which was not handled by any
--   <a>ErrorPolicy</a>.
ErrorPolicyUnhandledApplicationException :: SomeException -> ErrorPolicyTrace

-- | <tt>connect</tt> throwed an exception, which was not handled by any
--   <a>ErrorPolicy</a>.
ErrorPolicyUnhandledConnectionException :: SomeException -> ErrorPolicyTrace

-- | <tt>accept</tt> throwed an exception
ErrorPolicyAcceptException :: IOException -> ErrorPolicyTrace
data WithDomainName a
WithDomainName :: !Domain -> !a -> WithDomainName a
[wdnDomain] :: WithDomainName a -> !Domain
[wdnEvent] :: WithDomainName a -> !a
data WithAddr addr a
WithAddr :: !addr -> !a -> WithAddr addr a
[wiaAddr] :: WithAddr addr a -> !addr
[wiaEvent] :: WithAddr addr a -> !a
instance GHC.Show.Show Ouroboros.Network.Subscription.Dns.DnsSubscriptionTarget
instance GHC.Classes.Eq Ouroboros.Network.Subscription.Dns.DnsSubscriptionTarget
instance GHC.Show.Show Ouroboros.Network.Subscription.Dns.DnsTrace
instance GHC.Show.Show a => GHC.Show.Show (Ouroboros.Network.Subscription.Dns.WithDomainName a)


-- | Public interface of <a>Subscription</a> workers.
module Ouroboros.Network.Subscription

-- | Spawns a subscription worker which will attempt to keep the specified
--   number of connections (Valency) active towards the list of IP
--   addresses given in IPSubscriptionTarget.
ipSubscriptionWorker :: forall a. Snocket IO Socket SockAddr -> Tracer IO (WithIPList (SubscriptionTrace SockAddr)) -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> NetworkMutableState SockAddr -> IPSubscriptionParams a -> (Socket -> IO a) -> IO Void
data IPSubscriptionTarget
IPSubscriptionTarget :: ![SockAddr] -> !Int -> IPSubscriptionTarget

-- | List of destinations to possibly connect to
[ispIps] :: IPSubscriptionTarget -> ![SockAddr]

-- | Number of parallel connections to keep actice.
[ispValency] :: IPSubscriptionTarget -> !Int
dnsSubscriptionWorker :: Snocket IO Socket SockAddr -> Tracer IO (WithDomainName (SubscriptionTrace SockAddr)) -> Tracer IO (WithDomainName DnsTrace) -> Tracer IO (WithAddr SockAddr ErrorPolicyTrace) -> NetworkMutableState SockAddr -> DnsSubscriptionParams a -> (Socket -> IO a) -> IO Void
data DnsSubscriptionTarget
DnsSubscriptionTarget :: !Domain -> !PortNumber -> !Int -> DnsSubscriptionTarget
[dstDomain] :: DnsSubscriptionTarget -> !Domain
[dstPort] :: DnsSubscriptionTarget -> !PortNumber
[dstValency] :: DnsSubscriptionTarget -> !Int

-- | GADT which classifies connection result.
data ConnectResult

-- | Successful connection.
ConnectSuccess :: ConnectResult

-- | Successfully connection, reached the valency target. Other ongoing
--   connection attempts will be killed.
ConnectSuccessLast :: ConnectResult

-- | Someone else manged to create the final connection to a target before
--   us.
ConnectValencyExceeded :: ConnectResult

-- | Time to wait between connection attempts when we don't have any DeltaQ
--   info.
defaultConnectionAttemptDelay :: DiffTime

-- | Minimum time to wait between connection attempts.
minConnectionAttemptDelay :: DiffTime

-- | Maximum time to wait between connection attempts.
maxConnectionAttemptDelay :: DiffTime

-- | Minimum time to wait between ip reconnects
ipRetryDelay :: DiffTime

-- | Time to wait for an AAAA response after receiving an A response.
resolutionDelay :: DiffTime
data SubscriberError
SubscriberError :: !SubscriberErrorType -> !String -> !CallStack -> SubscriberError
[seType] :: SubscriberError -> !SubscriberErrorType
[seMessage] :: SubscriberError -> !String
[seStack] :: SubscriberError -> !CallStack
data SubscriptionTrace addr
SubscriptionTraceConnectStart :: addr -> SubscriptionTrace addr
SubscriptionTraceConnectEnd :: addr -> ConnectResult -> SubscriptionTrace addr
SubscriptionTraceSocketAllocationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceConnectException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceApplicationException :: addr -> e -> SubscriptionTrace addr
SubscriptionTraceTryConnectToPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSkippingPeer :: addr -> SubscriptionTrace addr
SubscriptionTraceSubscriptionRunning :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaiting :: Int -> SubscriptionTrace addr
SubscriptionTraceSubscriptionFailed :: SubscriptionTrace addr
SubscriptionTraceSubscriptionWaitingNewConnection :: DiffTime -> SubscriptionTrace addr
SubscriptionTraceStart :: Int -> SubscriptionTrace addr
SubscriptionTraceRestart :: DiffTime -> Int -> Int -> SubscriptionTrace addr
SubscriptionTraceConnectionExist :: addr -> SubscriptionTrace addr
SubscriptionTraceUnsupportedRemoteAddr :: addr -> SubscriptionTrace addr
SubscriptionTraceMissingLocalAddress :: SubscriptionTrace addr
SubscriptionTraceAllocateSocket :: addr -> SubscriptionTrace addr
SubscriptionTraceCloseSocket :: addr -> SubscriptionTrace addr
data WithIPList a
WithIPList :: !LocalAddresses SockAddr -> ![SockAddr] -> !a -> WithIPList a
[wilSrc] :: WithIPList a -> !LocalAddresses SockAddr
[wilDsts] :: WithIPList a -> ![SockAddr]
[wilEvent] :: WithIPList a -> !a
data DnsTrace
DnsTraceLookupException :: SomeException -> DnsTrace
DnsTraceLookupAError :: DNSError -> DnsTrace
DnsTraceLookupAAAAError :: DNSError -> DnsTrace
DnsTraceLookupIPv6First :: DnsTrace
DnsTraceLookupIPv4First :: DnsTrace
DnsTraceLookupAResult :: [SockAddr] -> DnsTrace
DnsTraceLookupAAAAResult :: [SockAddr] -> DnsTrace
data WithDomainName a
WithDomainName :: !Domain -> !a -> WithDomainName a
[wdnDomain] :: WithDomainName a -> !Domain
[wdnEvent] :: WithDomainName a -> !a

module Ouroboros.Network.Subscription.Client
data ClientSubscriptionParams a
ClientSubscriptionParams :: !LocalAddress -> !Maybe DiffTime -> !ErrorPolicies -> ClientSubscriptionParams a

-- | unix socket or named pipe address
[cspAddress] :: ClientSubscriptionParams a -> !LocalAddress

-- | delay between connection attempts
[cspConnectionAttemptDelay] :: ClientSubscriptionParams a -> !Maybe DiffTime

-- | error policies for subscription worker
[cspErrorPolicies] :: ClientSubscriptionParams a -> !ErrorPolicies

-- | Client subscription worker keeps subsribing to the <a>LocalAddress</a>
--   using either unix socket or named pipe.
clientSubscriptionWorker :: LocalSnocket -> Tracer IO (SubscriptionTrace LocalAddress) -> Tracer IO (WithAddr LocalAddress ErrorPolicyTrace) -> NetworkMutableState LocalAddress -> ClientSubscriptionParams a -> (LocalSocket -> IO a) -> IO Void
