1
+ {-# LANGUAGE FlexibleContexts #-}
2
+ {-# LANGUAGE FlexibleInstances #-}
1
3
{-# LANGUAGE NamedFieldPuns #-}
2
4
{-# LANGUAGE OverloadedStrings #-}
5
+ {-# LANGUAGE PackageImports #-}
3
6
4
7
module Cardano.Node.Configuration.TopologyP2P
5
8
( TopologyError (.. )
@@ -30,11 +33,14 @@ import qualified Data.ByteString as BS
30
33
import qualified Data.ByteString.Lazy.Char8 as LBS
31
34
import qualified Data.Text as Text
32
35
36
+ import "contra-tracer" Control.Tracer (Tracer , traceWith )
37
+
33
38
import Cardano.Node.Configuration.POM (NodeConfiguration (.. ))
34
39
import Cardano.Slotting.Slot (SlotNo (.. ))
35
40
36
41
import Cardano.Node.Configuration.NodeAddress
37
42
import Cardano.Node.Types
43
+ import Cardano.Node.Startup (StartupTrace (.. ))
38
44
import Cardano.Node.Configuration.Topology (TopologyError (.. ))
39
45
40
46
import Ouroboros.Network.NodeToNode (PeerAdvertise (.. ))
@@ -135,45 +141,35 @@ data LocalRootPeersGroup = LocalRootPeersGroup
135
141
instance FromJSON LocalRootPeersGroup where
136
142
parseJSON = withObject " LocalRootPeersGroup" $ \ o ->
137
143
LocalRootPeersGroup
138
- <$> o .: " localRoots "
144
+ <$> o .: " localGroup "
139
145
<*> o .: " valency"
140
146
141
147
instance ToJSON LocalRootPeersGroup where
142
148
toJSON lrpg =
143
149
object
144
- [ " localRoots " .= localRoots lrpg
145
- , " valency" .= valency lrpg
150
+ [ " localGroup " .= localRoots lrpg
151
+ , " valency" .= valency lrpg
146
152
]
147
153
148
154
newtype LocalRootPeersGroups = LocalRootPeersGroups
149
155
{ groups :: [LocalRootPeersGroup ]
150
156
} deriving (Eq , Show )
151
157
152
158
instance FromJSON LocalRootPeersGroups where
153
- parseJSON = withObject " LocalRootPeersGroups" $ \ o ->
154
- LocalRootPeersGroups
155
- <$> o .: " groups"
159
+ parseJSON = fmap LocalRootPeersGroups . parseJSONList
156
160
157
161
instance ToJSON LocalRootPeersGroups where
158
- toJSON lrpg =
159
- object
160
- [ " groups" .= groups lrpg
161
- ]
162
+ toJSON = toJSON . groups
162
163
163
164
newtype PublicRootPeers = PublicRootPeers
164
165
{ publicRoots :: RootConfig
165
166
} deriving (Eq , Show )
166
167
167
168
instance FromJSON PublicRootPeers where
168
- parseJSON = withObject " PublicRootPeers" $ \ o ->
169
- PublicRootPeers
170
- <$> o .: " publicRoots"
169
+ parseJSON = fmap PublicRootPeers . parseJSON
171
170
172
171
instance ToJSON PublicRootPeers where
173
- toJSON prp =
174
- object
175
- [ " publicRoots" .= publicRoots prp
176
- ]
172
+ toJSON = toJSON . publicRoots
177
173
178
174
data NetworkTopology = RealNodeTopology ! LocalRootPeersGroups ! [PublicRootPeers ] ! UseLedger
179
175
deriving (Eq , Show )
@@ -192,17 +188,66 @@ instance ToJSON NetworkTopology where
192
188
, " useLedgerAfterSlot" .= ul
193
189
]
194
190
191
+ --
192
+ -- Legacy p2p topology file format
193
+ --
194
+
195
+ -- | A newtype wrapper which provides legacy 'FromJSON' instances.
196
+ --
197
+ newtype Legacy a = Legacy { getLegacy :: a }
198
+
199
+ instance FromJSON (Legacy a ) => FromJSON (Legacy [a ]) where
200
+ parseJSON = fmap (Legacy . map getLegacy) . parseJSONList
201
+
202
+ instance FromJSON (Legacy LocalRootPeersGroup ) where
203
+ parseJSON = withObject " LocalRootPeersGroup" $ \ o ->
204
+ fmap Legacy $ LocalRootPeersGroup
205
+ <$> o .: " localRoots"
206
+ <*> o .: " valency"
207
+
208
+ instance FromJSON (Legacy LocalRootPeersGroups ) where
209
+ parseJSON = withObject " LocalRootPeersGroups" $ \ o ->
210
+ (Legacy . LocalRootPeersGroups . getLegacy)
211
+ <$> o .: " groups"
212
+
213
+ instance FromJSON (Legacy PublicRootPeers ) where
214
+ parseJSON = withObject " PublicRootPeers" $ \ o ->
215
+ (Legacy . PublicRootPeers )
216
+ <$> o .: " publicRoots"
217
+
218
+ instance FromJSON (Legacy NetworkTopology ) where
219
+ parseJSON = fmap Legacy
220
+ . withObject " NetworkTopology" (\ o ->
221
+ RealNodeTopology <$> (fmap getLegacy $ o .: " LocalRoots" )
222
+ <*> (fmap getLegacy $ o .: " PublicRoots" )
223
+ <*> (o .:? " useLedgerAfterSlot" .!= UseLedger DontUseLedger ))
224
+
195
225
-- | Read the `NetworkTopology` configuration from the specified file.
196
226
--
197
- readTopologyFile :: NodeConfiguration -> IO (Either Text NetworkTopology )
198
- readTopologyFile nc = do
227
+ readTopologyFile :: Tracer IO (StartupTrace blk )
228
+ -> NodeConfiguration -> IO (Either Text NetworkTopology )
229
+ readTopologyFile tr nc = do
199
230
eBs <- Exception. try $ BS. readFile (unTopology $ ncTopologyFile nc)
200
231
201
232
case eBs of
202
233
Left e -> return . Left $ handler e
203
- Right bs -> return . first handlerJSON . eitherDecode $ LBS. fromStrict bs
234
+ Right bs ->
235
+ let bs' = LBS. fromStrict bs in
236
+ first handlerJSON (eitherDecode bs')
237
+ `combine`
238
+ first handlerJSON (eitherDecode bs')
204
239
205
240
where
241
+ combine :: Either Text NetworkTopology
242
+ -> Either Text (Legacy NetworkTopology )
243
+ -> IO (Either Text NetworkTopology )
244
+ combine a b = case (a, b) of
245
+ (Right {}, _) -> return a
246
+ (_, Right {}) -> traceWith tr NetworkConfigLegacy
247
+ >> return (getLegacy <$> b)
248
+ (Left _, Left _) -> -- ignore parsing error of legacy format
249
+ return a
250
+
206
251
handler :: IOException -> Text
207
252
handler e = Text. pack $ " Cardano.Node.Configuration.Topology.readTopologyFile: "
208
253
++ displayException e
@@ -214,9 +259,10 @@ readTopologyFile nc = do
214
259
\make sure that you correctly setup EnableP2P \
215
260
\configuration flag. " <> Text. pack err
216
261
217
- readTopologyFileOrError :: NodeConfiguration -> IO NetworkTopology
218
- readTopologyFileOrError nc =
219
- readTopologyFile nc
262
+ readTopologyFileOrError :: Tracer IO (StartupTrace blk )
263
+ -> NodeConfiguration -> IO NetworkTopology
264
+ readTopologyFileOrError tr nc =
265
+ readTopologyFile tr nc
220
266
>>= either (\ err -> panic $ " Cardano.Node.Configuration.TopologyP2P.readTopologyFile: "
221
267
<> err)
222
268
pure
0 commit comments