Skip to content

Commit 28b1c2a

Browse files
committed
cardano-testnet: adapt to NetworkTopology type changes
NetworkTopology was moved to ouroboros-netowork and refactored, which causes the following changes in cardano-testnet: - `createTestnetEnv` now creates a concrete topology, instead of an abstract one - `createTestnetEnv` now allocates random ports to nodes and writes them both to the concrete topology file and the to the nodes config directories - `cardanoTestnet` now does not generate the ports and instead reads the ones assigned by `createTestnetEnv` from disk
1 parent a0ab118 commit 28b1c2a

6 files changed

Lines changed: 85 additions & 66 deletions

File tree

cardano-testnet/cardano-testnet.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ library
8484
, network
8585
, network-mux
8686
, optparse-applicative-fork
87-
, ouroboros-network:{api, ouroboros-network} ^>= 1.0
87+
, ouroboros-network:{api, framework, ouroboros-network} ^>= 1.0
8888
, cardano-diffusion:{api, cardano-diffusion} ^>= 1.0
8989
, prettyprinter
9090
, process
@@ -276,6 +276,7 @@ test-suite cardano-testnet-test
276276
, microlens
277277
, monad-control
278278
, mtl
279+
, ouroboros-network:api
279280
, process
280281
, resourcet
281282
, regex-compat

cardano-testnet/src/Parsers/Run.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ createEnvOptions CardanoTestnetCreateEnvOptions
6262
, createEnvCreateEnvOptions=ceOptions
6363
} = do
6464
conf <- mkConfigAbs outputDir
65-
createTestnetEnv
65+
void $ createTestnetEnv
6666
testnetOptions genesisOptions ceOptions
6767
-- Do not add hashes to the main config file, so that genesis files
6868
-- can be modified without having to recompute hashes every time.

cardano-testnet/src/Testnet/Defaults.hs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,17 @@ import qualified Cardano.Ledger.Shelley as Ledger
6565
import Cardano.Ledger.Shelley.Genesis
6666
import Cardano.Network.PeerSelection.Bootstrap (UseBootstrapPeers (..))
6767
import Cardano.Network.PeerSelection.PeerTrustable (PeerTrustable (..))
68-
import Cardano.Node.Configuration.TopologyP2P (LocalRootPeersGroup (..),
69-
LocalRootPeersGroups (..), NetworkTopology (..), PublicRootPeers (..),
70-
RootConfig (..))
71-
import qualified Cardano.Node.Configuration.TopologyP2P as P2P
72-
import qualified Cardano.Node.Configuration.TopologyP2P as Topology
7368
import Cardano.Tracing.Config
7469
import Cardano.Network.NodeToNode (DiffusionMode (..))
7570
import Ouroboros.Network.PeerSelection (AfterSlot (..), PeerAdvertise (..),
7671
RelayAccessPoint (..), UseLedgerPeers (..))
7772
import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (..),
7873
WarmValency (..))
74+
import Ouroboros.Network.Diffusion.Topology (LocalRootPeersGroup (..),
75+
LocalRootPeersGroups (..), NetworkTopology (..), PublicRootPeers (..),
76+
RootConfig (..), LocalRoots (..))
77+
import Cardano.Network.Diffusion.Topology (CardanoNetworkTopology)
78+
import Ouroboros.Network.ConnectionManager.Types (Provenance (..))
7979

8080
import Prelude
8181

@@ -466,27 +466,30 @@ mkProtVer (majorProtVer, minorProtVer) =
466466
ppProtocolVersionL' :: Lens' (PParams Ledger.ShelleyEra) ProtVer
467467
ppProtocolVersionL' = Ledger.ppLensHKD . Ledger.hkdProtocolVersionL @Ledger.ShelleyEra @Identity
468468

469-
defaultMainnetTopology :: Topology.NetworkTopology RelayAccessPoint
469+
defaultMainnetTopology :: CardanoNetworkTopology
470470
defaultMainnetTopology =
471-
Topology.RealNodeTopology {
472-
ntLocalRootPeersGroups = LocalRootPeersGroups [
471+
NetworkTopology {
472+
localRootPeersGroups = LocalRootPeersGroups [
473473
LocalRootPeersGroup {
474-
localRoots = RootConfig {
475-
rootAccessPoints =
476-
[ RelayAccessDomain "relays-new.cardano-mainnet.iohk.io" 3_001
477-
],
478-
rootAdvertise = DoAdvertisePeer
474+
localRoots = LocalRoots {
475+
rootConfig = RootConfig {
476+
rootAccessPoints =
477+
[ RelayAccessDomain "relays-new.cardano-mainnet.iohk.io" 3_001
478+
],
479+
rootAdvertise = DoAdvertisePeer
480+
},
481+
provenance = Outbound
479482
},
480483
hotValency = 2,
481484
warmValency = 2,
482-
trustable = IsTrustable,
483-
rootDiffusionMode = InitiatorAndResponderDiffusionMode
485+
rootDiffusionMode = InitiatorAndResponderDiffusionMode,
486+
extraFlags = IsTrustable
484487
}
485488
],
486-
ntPublicRootPeers = [],
487-
ntUseLedgerPeers = UseLedgerPeers Always,
488-
ntUseBootstrapPeers = DontUseBootstrapPeers,
489-
ntPeerSnapshotPath = Nothing
489+
extraConfig = DontUseBootstrapPeers,
490+
publicRootPeers = [],
491+
useLedgerPeers = UseLedgerPeers Always,
492+
peerSnapshotPath = Nothing
490493
}
491494

492495
defaultGenesisFilepath :: CardanoEra a -> FilePath
@@ -596,9 +599,9 @@ defaultUtxoKeys n =
596599

597600

598601
simpleScript :: Text -> Text
599-
simpleScript signerRequired =
602+
simpleScript signerRequired =
600603
"{ \"scripts\": [ { \"keyHash\": \"" <> signerRequired <> "\", \"type\": \"sig\" } ], \"type\": \"all\" }"
601-
604+
602605

603606
plutusV2Script :: Text
604607
plutusV2Script =
@@ -620,30 +623,33 @@ plutusV2StakeScript :: Text
620623
plutusV2StakeScript =
621624
"{ \"type\": \"PlutusScriptV2\", \"description\": \"\", \"cborHex\": \"5907655907620100003232323232323232323232323232332232323232322232325335320193333573466e1cd55cea80124000466442466002006004646464646464646464646464646666ae68cdc39aab9d500c480008cccccccccccc88888888888848cccccccccccc00403403002c02802402001c01801401000c008cd4050054d5d0a80619a80a00a9aba1500b33501401635742a014666aa030eb9405cd5d0a804999aa80c3ae501735742a01066a02803e6ae85401cccd54060081d69aba150063232323333573466e1cd55cea801240004664424660020060046464646666ae68cdc39aab9d5002480008cc8848cc00400c008cd40a9d69aba15002302b357426ae8940088c98c80b4cd5ce01701681589aab9e5001137540026ae854008c8c8c8cccd5cd19b8735573aa004900011991091980080180119a8153ad35742a00460566ae84d5d1280111931901699ab9c02e02d02b135573ca00226ea8004d5d09aba2500223263202933573805405204e26aae7940044dd50009aba1500533501475c6ae854010ccd540600708004d5d0a801999aa80c3ae200135742a004603c6ae84d5d1280111931901299ab9c026025023135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d5d1280089aba25001135744a00226ae8940044d55cf280089baa00135742a004601c6ae84d5d1280111931900b99ab9c018017015101613263201633573892010350543500016135573ca00226ea800448c88c008dd6000990009aa80a911999aab9f0012500a233500930043574200460066ae880080508c8c8cccd5cd19b8735573aa004900011991091980080180118061aba150023005357426ae8940088c98c8050cd5ce00a80a00909aab9e5001137540024646464646666ae68cdc39aab9d5004480008cccc888848cccc00401401000c008c8c8c8cccd5cd19b8735573aa0049000119910919800801801180a9aba1500233500f014357426ae8940088c98c8064cd5ce00d00c80b89aab9e5001137540026ae854010ccd54021d728039aba150033232323333573466e1d4005200423212223002004357426aae79400c8cccd5cd19b875002480088c84888c004010dd71aba135573ca00846666ae68cdc3a801a400042444006464c6403666ae7007006c06406005c4d55cea80089baa00135742a00466a016eb8d5d09aba2500223263201533573802c02a02626ae8940044d5d1280089aab9e500113754002266aa002eb9d6889119118011bab00132001355012223233335573e0044a010466a00e66442466002006004600c6aae754008c014d55cf280118021aba200301213574200222440042442446600200800624464646666ae68cdc3a800a40004642446004006600a6ae84d55cf280191999ab9a3370ea0049001109100091931900819ab9c01101000e00d135573aa00226ea80048c8c8cccd5cd19b875001480188c848888c010014c01cd5d09aab9e500323333573466e1d400920042321222230020053009357426aae7940108cccd5cd19b875003480088c848888c004014c01cd5d09aab9e500523333573466e1d40112000232122223003005375c6ae84d55cf280311931900819ab9c01101000e00d00c00b135573aa00226ea80048c8c8cccd5cd19b8735573aa004900011991091980080180118029aba15002375a6ae84d5d1280111931900619ab9c00d00c00a135573ca00226ea80048c8cccd5cd19b8735573aa002900011bae357426aae7940088c98c8028cd5ce00580500409baa001232323232323333573466e1d4005200c21222222200323333573466e1d4009200a21222222200423333573466e1d400d2008233221222222233001009008375c6ae854014dd69aba135744a00a46666ae68cdc3a8022400c4664424444444660040120106eb8d5d0a8039bae357426ae89401c8cccd5cd19b875005480108cc8848888888cc018024020c030d5d0a8049bae357426ae8940248cccd5cd19b875006480088c848888888c01c020c034d5d09aab9e500b23333573466e1d401d2000232122222223005008300e357426aae7940308c98c804ccd5ce00a00980880800780700680600589aab9d5004135573ca00626aae7940084d55cf280089baa0012323232323333573466e1d400520022333222122333001005004003375a6ae854010dd69aba15003375a6ae84d5d1280191999ab9a3370ea0049000119091180100198041aba135573ca00c464c6401866ae700340300280244d55cea80189aba25001135573ca00226ea80048c8c8cccd5cd19b875001480088c8488c00400cdd71aba135573ca00646666ae68cdc3a8012400046424460040066eb8d5d09aab9e500423263200933573801401200e00c26aae7540044dd500089119191999ab9a3370ea00290021091100091999ab9a3370ea00490011190911180180218031aba135573ca00846666ae68cdc3a801a400042444004464c6401466ae7002c02802001c0184d55cea80089baa0012323333573466e1d40052002200723333573466e1d40092000212200123263200633573800e00c00800626aae74dd5000a4c2400292010350543100122002112323001001223300330020020011\" }"
622625

623-
defaultP2PTopology :: [adr] -> P2P.NetworkTopology adr
624-
defaultP2PTopology addresses = P2P.RealNodeTopology
625-
{ ntLocalRootPeersGroups = LocalRootPeersGroups
626+
defaultP2PTopology :: [RelayAccessPoint] -> CardanoNetworkTopology
627+
defaultP2PTopology addresses = NetworkTopology
628+
{ localRootPeersGroups = LocalRootPeersGroups
626629
{ groups = [
627630
LocalRootPeersGroup
628-
{ localRoots = RootConfig
629-
{ rootAccessPoints = addresses
630-
, rootAdvertise = DoNotAdvertisePeer
631+
{ localRoots = LocalRoots
632+
{ rootConfig = RootConfig
633+
{ rootAccessPoints = addresses
634+
, rootAdvertise = DoNotAdvertisePeer
635+
}
636+
, provenance = Outbound
631637
}
632638
, hotValency = HotValency $ length addresses
633639
, warmValency = WarmValency $ length addresses
634-
, trustable = IsTrustable
635640
, rootDiffusionMode = InitiatorAndResponderDiffusionMode
641+
, extraFlags = IsTrustable
636642
}
637643
]
638644
}
639-
, ntPublicRootPeers =
645+
, extraConfig = DontUseBootstrapPeers
646+
, publicRootPeers =
640647
[ PublicRootPeers
641648
RootConfig
642649
{ rootAccessPoints = []
643650
, rootAdvertise = DoNotAdvertisePeer
644651
}
645652
]
646-
, ntUseLedgerPeers = DontUseLedgerPeers
647-
, ntUseBootstrapPeers = DontUseBootstrapPeers
648-
, ntPeerSnapshotPath = Nothing
653+
, useLedgerPeers = DontUseLedgerPeers
654+
, peerSnapshotPath = Nothing
649655
}

cardano-testnet/src/Testnet/Start/Cardano.hs

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ import qualified Cardano.Api.Byron as Byron
3535

3636
import Cardano.CLI.Type.Common (SigningKeyFile)
3737
import Cardano.Node.Configuration.NodeAddress (NodeAddress' (..),
38-
NodeHostIPv4Address (..))
39-
import qualified Cardano.Node.Configuration.TopologyP2P as P2P
38+
NodeHostIPv4Address (..), PortNumber)
4039
import Cardano.Prelude (NonEmpty ((:|)), canonicalEncodePretty)
4140
import Cardano.TxGenerator.Setup.NixService (NixServiceOptions (..), NodeDescription (..))
4241
import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint (..))
42+
import Cardano.Network.Diffusion.Topology (CardanoNetworkTopology)
4343

4444
import Prelude hiding (lines)
4545

@@ -107,6 +107,7 @@ createTestnetEnv :: ()
107107
=> HasCallStack
108108
=> MonadIO m
109109
=> MonadThrow m
110+
=> MonadFail m
110111
=> CardanoTestnetOptions
111112
-> GenesisOptions
112113
-> CreateEnvOptions
@@ -142,14 +143,24 @@ createTestnetEnv
142143

143144
liftIOAnnotated . LBS.writeFile configurationFile $ A.encodePretty $ Object config
144145

145-
-- Create network topology, with abstract IDs in lieu of addresses
146+
portNumbers <- forM (NEL.zip (1 :| [2..]) cardanoNodes)
147+
(\(i, _nodeOption) -> (i,) <$> H.randomPort testnetDefaultIpv4Address)
148+
149+
let portNumbersMap = Map.fromList (NEL.toList portNumbers)
150+
151+
-- Create network topology and write port files
146152
let nodeIds = fst <$> NEL.zip (1 :| [2..]) cardanoNodes
147153
forM_ nodeIds $ \i -> do
148154
let nodeDataDir = tmpAbsPath </> Defaults.defaultNodeDataDir i
149155
liftIOAnnotated $ IO.createDirectoryIfMissing True nodeDataDir
150156

151-
let producers = NodeId <$> NEL.filter (/= i) nodeIds
152-
topology = Defaults.defaultP2PTopology producers
157+
-- Write port file
158+
case Map.lookup i portNumbersMap of
159+
Just port -> liftIOAnnotated $ writeFile (nodeDataDir </> "port") (show port)
160+
Nothing -> error $ "Port not found for node " <> show i
161+
162+
producers <- mapM (idToRemoteAddressP2P portNumbersMap) $ NodeId <$> NEL.filter (/= i) nodeIds
163+
let topology = Defaults.defaultP2PTopology producers
153164
liftIOAnnotated . LBS.writeFile (nodeDataDir </> "topology.json") $ A.encodePretty topology
154165

155166
-- | Starts a number of nodes, as configured by the value of the 'cardanoNodes'
@@ -268,38 +279,23 @@ cardanoTestnet
268279
, paymentKeyInfoAddr = Text.pack paymentAddr
269280
}
270281

271-
portNumbersWithNodeOptions <- forM cardanoNodes
272-
(\nodeOption -> (nodeOption,) <$> H.randomPort testnetDefaultIpv4Address)
273-
274-
let portNumbers = NEL.zip (1 :| [2..]) $ snd <$> portNumbersWithNodeOptions
275-
portNumbersMap = Map.fromList (NEL.toList portNumbers)
276-
277-
idToRemoteAddressP2P :: ()
278-
=> MonadIO m
279-
=> HasCallStack
280-
=> NodeId -> m RelayAccessPoint
281-
idToRemoteAddressP2P (NodeId i) = case Map.lookup i portNumbersMap of
282-
Just port -> pure $ RelayAccessAddress
283-
(showIpv4Address testnetDefaultIpv4Address)
284-
port
285-
Nothing -> do
286-
throwString $ "Found node id that was unaccounted for: " ++ show i
287-
288-
forM_ portNumbers $ \(i, portNumber) -> do
282+
-- Read port numbers from disk (written by createTestnetEnv)
283+
portNumbers <- forM (NEL.zip (1 :| [2..]) cardanoNodes) $ \(i, _nodeOption) -> do
289284
let nodeDataDir = tmpAbsPath </> Defaults.defaultNodeDataDir i
290-
liftIOAnnotated $ IO.createDirectoryIfMissing True nodeDataDir
291-
liftIOAnnotated $ writeFile (nodeDataDir </> "port") (show portNumber)
292-
let topologyPath = tmpAbsPath </> Defaults.defaultNodeDataDir i </> "topology.json"
285+
portPath = nodeDataDir </> "port"
286+
portStr <- liftIOAnnotated $ readFile portPath
287+
let port = read portStr :: PortNumber
288+
let topologyPath = nodeDataDir </> "topology.json"
293289
tBytes <- liftIOAnnotated $ LBS.readFile topologyPath
294290
case eitherDecode tBytes of
295-
Right (abstractTopology :: P2P.NetworkTopology NodeId) -> do
296-
topology <- mapM idToRemoteAddressP2P abstractTopology
297-
liftIOAnnotated $ LBS.writeFile topologyPath $ encode topology
291+
Right (abstractTopology :: CardanoNetworkTopology) -> do
292+
liftIOAnnotated $ LBS.writeFile topologyPath $ encode abstractTopology
298293
Left e -> do
299294
-- There can be multiple reasons for why both decodings have failed.
300295
-- Here we assume, very optimistically, that the user has already
301296
-- instantiated it with a concrete topology file.
302297
liftIOAnnotated . putStrLn $ "Could not decode topology file: " <> topologyPath <> ". This may be okay. Reason for decoding failure is:\n" ++ e
298+
pure (i, port)
303299

304300
-- If necessary, update the time stamps in Byron and Shelley Genesis files.
305301
-- This is a QoL feature so that users who edit their configuration files don't
@@ -321,7 +317,12 @@ cardanoTestnet
321317
let shelleyGenesis' = shelleyGenesis{sgSystemStart = startTime}
322318
liftIOAnnotated . LBS.writeFile shelleyGenesisFile $ A.encodePretty shelleyGenesis'
323319

324-
eTestnetNodes <- forConcurrently (NEL.zip (1 :| [2..]) portNumbersWithNodeOptions) $ \(i, (nodeOptions, port)) -> do
320+
let portNumbersMap = Map.fromList (NEL.toList portNumbers)
321+
322+
eTestnetNodes <- forConcurrently (NEL.zip (1 :| [2..]) cardanoNodes) $ \(i, nodeOptions) -> do
323+
port <- case Map.lookup i portNumbersMap of
324+
Just p -> pure p
325+
Nothing -> throwString $ "Port not found for node " <> show i
325326
let nodeName = Defaults.defaultNodeName i
326327
nodeDataDir = tmpAbsPath </> Defaults.defaultNodeDataDir i
327328
nodePoolKeysDir = tmpAbsPath </> Defaults.defaultSpoKeysDir i
@@ -490,6 +491,17 @@ cardanoTestnet
490491
throwString $ nodeName <> " was unable to produce any blocks for " <> show timeoutSeconds <> "s"
491492

492493

494+
idToRemoteAddressP2P :: ()
495+
=> MonadIO m
496+
=> HasCallStack
497+
=> Map.Map Int PortNumber -> NodeId -> m RelayAccessPoint
498+
idToRemoteAddressP2P portNumbersMap (NodeId i) = case Map.lookup i portNumbersMap of
499+
Just port -> pure $ RelayAccessAddress
500+
(showIpv4Address testnetDefaultIpv4Address)
501+
port
502+
Nothing -> do
503+
throwString $ "Found node id that was unaccounted for: " ++ show i
504+
493505
-- | A convenience wrapper around `createTestnetEnv` and `cardanoTestnet`
494506
createAndRunTestnet :: ()
495507
=> HasCallStack

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/KesPeriodInfo.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ module Cardano.Testnet.Test.Cli.KesPeriodInfo
1414
import Cardano.Api as Api
1515

1616
import Cardano.CLI.Type.Output
17-
import Cardano.Node.Configuration.TopologyP2P
1817
import Cardano.Testnet
1918
import Cardano.Testnet.Test.Misc
19+
import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint (..))
2020

2121
import Prelude
2222

cardano-testnet/test/cardano-testnet-test/Cardano/Testnet/Test/Cli/LeadershipSchedule.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ module Cardano.Testnet.Test.Cli.LeadershipSchedule
1616
import Cardano.Api
1717
import qualified Cardano.Api as Api
1818

19-
import Cardano.Node.Configuration.TopologyP2P
2019
import Cardano.Testnet
20+
import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint (..))
2121

2222
import Prelude
2323

0 commit comments

Comments
 (0)