1+ {-# LANGUAGE DeriveGeneric #-}
2+ {-# LANGUAGE DeriveTraversable #-}
13{-# LANGUAGE FlexibleContexts #-}
24{-# LANGUAGE FlexibleInstances #-}
35{-# LANGUAGE NamedFieldPuns #-}
46{-# LANGUAGE OverloadedStrings #-}
57{-# LANGUAGE PackageImports #-}
8+ {-# LANGUAGE RankNTypes #-}
69
710module Cardano.Node.Configuration.TopologyP2P
811 ( TopologyError (.. )
@@ -38,7 +41,6 @@ import Cardano.Tracing.OrphanInstances.Network ()
3841import Ouroboros.Network.NodeToNode (DiffusionMode (.. ), PeerAdvertise (.. ))
3942import Ouroboros.Network.PeerSelection.LedgerPeers.Type (LedgerPeerSnapshot (.. ),
4043 UseLedgerPeers (.. ))
41- import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint (.. ))
4244import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (.. ),
4345 WarmValency (.. ))
4446
@@ -54,17 +56,18 @@ import qualified Data.ByteString.Lazy.Char8 as LBS
5456import Data.Text (Text )
5557import qualified Data.Text as Text
5658import Data.Word (Word64 )
59+ import GHC.Generics (Generic )
5760import System.FilePath (takeDirectory , (</>) )
5861
59- data NodeSetup = NodeSetup
62+ data NodeSetup adr = NodeSetup
6063 { nodeId :: ! Word64
6164 , nodeIPv4Address :: ! (Maybe NodeIPv4Address )
6265 , nodeIPv6Address :: ! (Maybe NodeIPv6Address )
63- , producers :: ! [RootConfig ]
66+ , producers :: ! [RootConfig adr ]
6467 , useLedger :: ! UseLedgerPeers
65- } deriving (Eq , Show )
68+ } deriving (Eq , Show , Generic , Functor , Foldable , Traversable )
6669
67- instance FromJSON NodeSetup where
70+ instance FromJSON adr => FromJSON ( NodeSetup adr ) where
6871 parseJSON = withObject " NodeSetup" $ \ o ->
6972 NodeSetup
7073 <$> o .: " nodeId"
@@ -73,7 +76,7 @@ instance FromJSON NodeSetup where
7376 <*> o .: " producers"
7477 <*> o .:? " useLedgerAfterSlot" .!= DontUseLedgerPeers
7578
76- instance ToJSON NodeSetup where
79+ instance ToJSON adr => ToJSON ( NodeSetup adr ) where
7780 toJSON ns =
7881 object
7982 [ " nodeId" .= nodeId ns
@@ -87,22 +90,22 @@ instance ToJSON NodeSetup where
8790-- | Each root peer consists of a list of access points and a shared
8891-- 'PeerAdvertise' field.
8992--
90- data RootConfig = RootConfig
91- { rootAccessPoints :: [RelayAccessPoint ]
93+ data RootConfig adr = RootConfig
94+ { rootAccessPoints :: [adr ]
9295 -- ^ a list of relay access points, each of which is either an ip address
9396 -- or domain name and a port number.
9497 , rootAdvertise :: PeerAdvertise
9598 -- ^ 'advertise' configures whether the root should be advertised through
9699 -- peer sharing.
97- } deriving (Eq , Show )
100+ } deriving (Eq , Show , Generic , Functor , Foldable , Traversable )
98101
99- instance FromJSON RootConfig where
102+ instance FromJSON adr => FromJSON ( RootConfig adr ) where
100103 parseJSON = withObject " RootConfig" $ \ o ->
101104 RootConfig
102105 <$> o .: " accessPoints"
103106 <*> o .:? " advertise" .!= DoNotAdvertisePeer
104107
105- instance ToJSON RootConfig where
108+ instance ToJSON adr => ToJSON ( RootConfig adr ) where
106109 toJSON ra =
107110 object
108111 [ " accessPoints" .= rootAccessPoints ra
@@ -112,9 +115,9 @@ instance ToJSON RootConfig where
112115-- | Transforms a 'RootConfig' into a pair of 'RelayAccessPoint' and its
113116-- corresponding 'PeerAdvertise' value.
114117--
115- rootConfigToRelayAccessPoint
116- :: RootConfig
117- -> [(RelayAccessPoint , PeerAdvertise )]
118+ rootConfigToRelayAccessPoint :: ()
119+ => forall adr . RootConfig adr
120+ -> [(adr , PeerAdvertise )]
118121rootConfigToRelayAccessPoint RootConfig { rootAccessPoints, rootAdvertise } =
119122 [ (accessPoint, rootAdvertise) | accessPoint <- rootAccessPoints ]
120123
@@ -125,21 +128,21 @@ rootConfigToRelayAccessPoint RootConfig { rootAccessPoints, rootAdvertise } =
125128-- 'warmValency' value is the value of warm/established connections that the node
126129-- will attempt to maintain. By default this value will be equal to 'hotValency'.
127130--
128- data LocalRootPeersGroup = LocalRootPeersGroup
129- { localRoots :: RootConfig
131+ data LocalRootPeersGroup adr = LocalRootPeersGroup
132+ { localRoots :: RootConfig adr
130133 , hotValency :: HotValency
131134 , warmValency :: WarmValency
132135 , trustable :: PeerTrustable
133136 -- ^ 'trustable' configures whether the root should be trusted in fallback
134137 -- state.
135138 , rootDiffusionMode :: DiffusionMode
136139 -- ^ diffusion mode; used for local root peers.
137- } deriving (Eq , Show )
140+ } deriving (Eq , Show , Generic , Functor , Foldable , Traversable )
138141
139142-- | Does not use the 'FromJSON' instance of 'RootConfig', so that
140143-- 'accessPoints', 'advertise', 'valency' and 'warmValency' fields are attached to the
141144-- same object.
142- instance FromJSON LocalRootPeersGroup where
145+ instance FromJSON adr => FromJSON ( LocalRootPeersGroup adr ) where
143146 parseJSON = withObject " LocalRootPeersGroup" $ \ o -> do
144147 hv@ (HotValency v) <- o .: " valency"
145148 <|> o .: " hotValency"
@@ -152,7 +155,7 @@ instance FromJSON LocalRootPeersGroup where
152155 <*> (maybe InitiatorAndResponderDiffusionMode getDiffusionMode
153156 <$> o .:? " diffusionMode" )
154157
155- instance ToJSON LocalRootPeersGroup where
158+ instance ToJSON adr => ToJSON ( LocalRootPeersGroup adr ) where
156159 toJSON lrpg =
157160 object
158161 [ " accessPoints" .= rootAccessPoints (localRoots lrpg)
@@ -164,47 +167,53 @@ instance ToJSON LocalRootPeersGroup where
164167 , " diffusionMode" .= NodeDiffusionMode (rootDiffusionMode lrpg)
165168 ]
166169
167- newtype LocalRootPeersGroups = LocalRootPeersGroups
168- { groups :: [LocalRootPeersGroup ]
169- } deriving (Eq , Show )
170+ newtype LocalRootPeersGroups adr = LocalRootPeersGroups
171+ { groups :: [LocalRootPeersGroup adr ]
172+ } deriving (Eq , Show , Generic , Functor , Foldable , Traversable )
170173
171- instance FromJSON LocalRootPeersGroups where
174+ instance FromJSON adr => FromJSON ( LocalRootPeersGroups adr ) where
172175 parseJSON = fmap LocalRootPeersGroups . parseJSONList
173176
174- instance ToJSON LocalRootPeersGroups where
177+ instance ToJSON adr => ToJSON ( LocalRootPeersGroups adr ) where
175178 toJSON = toJSONList . groups
176179
177- newtype PublicRootPeers = PublicRootPeers
178- { publicRoots :: RootConfig
179- } deriving (Eq , Show )
180+ newtype PublicRootPeers adr = PublicRootPeers
181+ { publicRoots :: RootConfig adr
182+ } deriving (Eq , Show , Generic , Functor , Foldable , Traversable )
180183
181- instance FromJSON PublicRootPeers where
184+ instance FromJSON adr => FromJSON ( PublicRootPeers adr ) where
182185 parseJSON = fmap PublicRootPeers . parseJSON
183186
184- instance ToJSON PublicRootPeers where
187+ instance ToJSON adr => ToJSON ( PublicRootPeers adr ) where
185188 toJSON = toJSON . publicRoots
186189
187- data NetworkTopology = RealNodeTopology { ntLocalRootPeersGroups :: ! LocalRootPeersGroups
188- , ntPublicRootPeers :: ! [PublicRootPeers ]
189- , ntUseLedgerPeers :: ! UseLedgerPeers
190- , ntUseBootstrapPeers :: ! UseBootstrapPeers
191- , ntPeerSnapshotPath :: ! (Maybe PeerSnapshotFile )
192- }
193- deriving (Eq , Show )
194-
195- instance AdjustFilePaths NetworkTopology where
190+ -- | Describes the P2P topology of a node. Whenever the node actually runs,
191+ -- the type parameter `adr` should be `RelayAccessPoint`. However, we might want to
192+ -- use and serialize this type with `adr` being `NodeId`, or another placeholder
193+ -- type, if we want the user to be able to edit the topology without knowing the
194+ -- actual addresses of the nodes: those might only be knowable at runtime.
195+ data NetworkTopology adr = RealNodeTopology
196+ { ntLocalRootPeersGroups :: ! (LocalRootPeersGroups adr )
197+ , ntPublicRootPeers :: ! [PublicRootPeers adr ]
198+ , ntUseLedgerPeers :: ! UseLedgerPeers
199+ , ntUseBootstrapPeers :: ! UseBootstrapPeers
200+ , ntPeerSnapshotPath :: ! (Maybe PeerSnapshotFile )
201+ }
202+ deriving (Eq , Show , Generic , Functor , Foldable , Traversable )
203+
204+ instance AdjustFilePaths (NetworkTopology adr ) where
196205 adjustFilePaths f nt@ (RealNodeTopology _ _ _ _ mPeerSnapshotPath) =
197206 nt{ntPeerSnapshotPath = PeerSnapshotFile . f . unPeerSnapshotFile <$> mPeerSnapshotPath}
198207
199- instance FromJSON NetworkTopology where
208+ instance FromJSON adr => FromJSON ( NetworkTopology adr ) where
200209 parseJSON = withObject " NetworkTopology" $ \ o ->
201210 RealNodeTopology <$> (o .: " localRoots" )
202211 <*> (o .: " publicRoots" )
203212 <*> (o .:? " useLedgerAfterSlot" .!= DontUseLedgerPeers )
204213 <*> (o .:? " bootstrapPeers" .!= DontUseBootstrapPeers )
205214 <*> (o .:? " peerSnapshotFile" )
206215
207- instance ToJSON NetworkTopology where
216+ instance ToJSON adr => ToJSON ( NetworkTopology adr ) where
208217 toJSON top =
209218 case top of
210219 RealNodeTopology { ntLocalRootPeersGroups
@@ -220,7 +229,9 @@ instance ToJSON NetworkTopology where
220229 ]
221230
222231-- | Read the `NetworkTopology` configuration from the specified file.
223- readTopologyFile :: NodeConfiguration -> CT. Tracer IO (StartupTrace blk ) -> IO (Either Text NetworkTopology )
232+ readTopologyFile :: ()
233+ => forall adr . FromJSON adr
234+ => NodeConfiguration -> CT. Tracer IO (StartupTrace blk ) -> IO (Either Text (NetworkTopology adr ))
224235readTopologyFile NodeConfiguration {ncTopologyFile= TopologyFile topologyFilePath, ncConsensusMode} tracer = runExceptT $ do
225236 bs <- handleIOExceptionsLiftWith handler $ BS. readFile topologyFilePath
226237 topology@ RealNodeTopology {ntUseBootstrapPeers} <-
@@ -269,7 +280,9 @@ readTopologyFile NodeConfiguration{ncTopologyFile=TopologyFile topologyFilePath,
269280 isGenesisCompatible GenesisMode UseBootstrapPeers {} = False
270281 isGenesisCompatible _ _ = True
271282
272- readTopologyFileOrError :: NodeConfiguration -> CT. Tracer IO (StartupTrace blk ) -> IO NetworkTopology
283+ readTopologyFileOrError :: ()
284+ => forall adr . FromJSON adr
285+ => NodeConfiguration -> CT. Tracer IO (StartupTrace blk ) -> IO (NetworkTopology adr )
273286readTopologyFileOrError nc tr =
274287 readTopologyFile nc tr
275288 >>= either (\ err -> error $ " Cardano.Node.Configuration.TopologyP2P.readTopologyFile: "
@@ -289,7 +302,7 @@ readPeerSnapshotFile (PeerSnapshotFile peerSnapshotFile) =
289302
290303-- | This function returns false if non-trustable peers are configured
291304--
292- isValidTrustedPeerConfiguration :: NetworkTopology -> Bool
305+ isValidTrustedPeerConfiguration :: NetworkTopology adr -> Bool
293306isValidTrustedPeerConfiguration (RealNodeTopology (LocalRootPeersGroups lprgs) _ _ ubp _) =
294307 case ubp of
295308 DontUseBootstrapPeers -> True
0 commit comments