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 (.. ))
@@ -132,77 +138,120 @@ data LocalRootPeersGroup = LocalRootPeersGroup
132
138
, valency :: Int
133
139
} deriving (Eq , Show )
134
140
141
+ -- | Does not use the 'FromJSON' instance of 'RootConfig', so that
142
+ -- 'accessPoints', 'advertise' and 'valency' fields are attached to the same
143
+ -- object.
135
144
instance FromJSON LocalRootPeersGroup where
136
145
parseJSON = withObject " LocalRootPeersGroup" $ \ o ->
137
146
LocalRootPeersGroup
138
- <$> o .: " localRoots "
147
+ <$> parseJSON ( Object o)
139
148
<*> o .: " valency"
140
149
141
150
instance ToJSON LocalRootPeersGroup where
142
151
toJSON lrpg =
143
152
object
144
- [ " localRoots" .= localRoots lrpg
145
- , " valency" .= valency lrpg
153
+ [ " accessPoints" .= rootAccessPoints (localRoots lrpg)
154
+ , " advertise" .= rootAdvertise (localRoots lrpg)
155
+ , " valency" .= valency lrpg
146
156
]
147
157
148
158
newtype LocalRootPeersGroups = LocalRootPeersGroups
149
159
{ groups :: [LocalRootPeersGroup ]
150
160
} deriving (Eq , Show )
151
161
152
162
instance FromJSON LocalRootPeersGroups where
153
- parseJSON = withObject " LocalRootPeersGroups" $ \ o ->
154
- LocalRootPeersGroups
155
- <$> o .: " groups"
163
+ parseJSON = fmap LocalRootPeersGroups . parseJSONList
156
164
157
165
instance ToJSON LocalRootPeersGroups where
158
- toJSON lrpg =
159
- object
160
- [ " groups" .= groups lrpg
161
- ]
166
+ toJSON = toJSONList . groups
162
167
163
168
newtype PublicRootPeers = PublicRootPeers
164
169
{ publicRoots :: RootConfig
165
170
} deriving (Eq , Show )
166
171
167
172
instance FromJSON PublicRootPeers where
168
- parseJSON = withObject " PublicRootPeers" $ \ o ->
169
- PublicRootPeers
170
- <$> o .: " publicRoots"
173
+ parseJSON = fmap PublicRootPeers . parseJSON
171
174
172
175
instance ToJSON PublicRootPeers where
173
- toJSON prp =
174
- object
175
- [ " publicRoots" .= publicRoots prp
176
- ]
176
+ toJSON = toJSON . publicRoots
177
177
178
178
data NetworkTopology = RealNodeTopology ! LocalRootPeersGroups ! [PublicRootPeers ] ! UseLedger
179
179
deriving (Eq , Show )
180
180
181
181
instance FromJSON NetworkTopology where
182
182
parseJSON = withObject " NetworkTopology" $ \ o ->
183
- RealNodeTopology <$> (o .: " LocalRoots " )
184
- <*> (o .: " PublicRoots " )
183
+ RealNodeTopology <$> (o .: " localRoots " )
184
+ <*> (o .: " publicRoots " )
185
185
<*> (o .:? " useLedgerAfterSlot" .!= UseLedger DontUseLedger )
186
186
187
187
instance ToJSON NetworkTopology where
188
188
toJSON top =
189
189
case top of
190
- RealNodeTopology lrpg prp ul -> object [ " LocalRoots " .= lrpg
191
- , " PublicRoots " .= prp
190
+ RealNodeTopology lrpg prp ul -> object [ " localRoots " .= lrpg
191
+ , " publicRoots " .= prp
192
192
, " useLedgerAfterSlot" .= ul
193
193
]
194
194
195
+ --
196
+ -- Legacy p2p topology file format
197
+ --
198
+
199
+ -- | A newtype wrapper which provides legacy 'FromJSON' instances.
200
+ --
201
+ newtype Legacy a = Legacy { getLegacy :: a }
202
+
203
+ instance FromJSON (Legacy a ) => FromJSON (Legacy [a ]) where
204
+ parseJSON = fmap (Legacy . map getLegacy) . parseJSONList
205
+
206
+ instance FromJSON (Legacy LocalRootPeersGroup ) where
207
+ parseJSON = withObject " LocalRootPeersGroup" $ \ o ->
208
+ fmap Legacy $ LocalRootPeersGroup
209
+ <$> o .: " localRoots"
210
+ <*> o .: " valency"
211
+
212
+ instance FromJSON (Legacy LocalRootPeersGroups ) where
213
+ parseJSON = withObject " LocalRootPeersGroups" $ \ o ->
214
+ Legacy . LocalRootPeersGroups . getLegacy
215
+ <$> o .: " groups"
216
+
217
+ instance FromJSON (Legacy PublicRootPeers ) where
218
+ parseJSON = withObject " PublicRootPeers" $ \ o ->
219
+ Legacy . PublicRootPeers
220
+ <$> o .: " publicRoots"
221
+
222
+ instance FromJSON (Legacy NetworkTopology ) where
223
+ parseJSON = fmap Legacy
224
+ . withObject " NetworkTopology" (\ o ->
225
+ RealNodeTopology <$> fmap getLegacy (o .: " LocalRoots" )
226
+ <*> fmap getLegacy (o .: " PublicRoots" )
227
+ <*> (o .:? " useLedgerAfterSlot" .!= UseLedger DontUseLedger ))
228
+
195
229
-- | Read the `NetworkTopology` configuration from the specified file.
196
230
--
197
- readTopologyFile :: NodeConfiguration -> IO (Either Text NetworkTopology )
198
- readTopologyFile nc = do
231
+ readTopologyFile :: Tracer IO (StartupTrace blk )
232
+ -> NodeConfiguration -> IO (Either Text NetworkTopology )
233
+ readTopologyFile tr nc = do
199
234
eBs <- Exception. try $ BS. readFile (unTopology $ ncTopologyFile nc)
200
235
201
236
case eBs of
202
237
Left e -> return . Left $ handler e
203
- Right bs -> return . first handlerJSON . eitherDecode $ LBS. fromStrict bs
238
+ Right bs ->
239
+ let bs' = LBS. fromStrict bs in
240
+ first handlerJSON (eitherDecode bs')
241
+ `combine`
242
+ first handlerJSON (eitherDecode bs')
204
243
205
244
where
245
+ combine :: Either Text NetworkTopology
246
+ -> Either Text (Legacy NetworkTopology )
247
+ -> IO (Either Text NetworkTopology )
248
+ combine a b = case (a, b) of
249
+ (Right {}, _) -> return a
250
+ (_, Right {}) -> traceWith tr NetworkConfigLegacy
251
+ >> return (getLegacy <$> b)
252
+ (Left _, Left _) -> -- ignore parsing error of legacy format
253
+ return a
254
+
206
255
handler :: IOException -> Text
207
256
handler e = Text. pack $ " Cardano.Node.Configuration.Topology.readTopologyFile: "
208
257
++ displayException e
@@ -214,9 +263,10 @@ readTopologyFile nc = do
214
263
\make sure that you correctly setup EnableP2P \
215
264
\configuration flag. " <> Text. pack err
216
265
217
- readTopologyFileOrError :: NodeConfiguration -> IO NetworkTopology
218
- readTopologyFileOrError nc =
219
- readTopologyFile nc
266
+ readTopologyFileOrError :: Tracer IO (StartupTrace blk )
267
+ -> NodeConfiguration -> IO NetworkTopology
268
+ readTopologyFileOrError tr nc =
269
+ readTopologyFile tr nc
220
270
>>= either (\ err -> panic $ " Cardano.Node.Configuration.TopologyP2P.readTopologyFile: "
221
271
<> err)
222
272
pure
0 commit comments