From b0ad1455d04165753aec656ea35a5092f757b7a7 Mon Sep 17 00:00:00 2001 From: Marcin Szamotulski Date: Fri, 6 Dec 2024 06:48:26 +0100 Subject: [PATCH] Added diffusionMode to local root peers group configuration "diffusionMode" can be either `"InitiatorOnly"` or `"InitiatorAndResponder"`. If not given, the latter is the default - for backward compatibility. When "InitiatorOnly" is used, the connections to these local roots will only negotiate `InitiatorOnly` mode (it won't be possible to be reused by the other side) and will not bind to the server address, e.g. it will be made from an ephemeral port. See https://github.com/IntersectMBO/ouroboros-network/issues/5020 why this feature was requested by some SPOs. An example configuration: ```json { "localRoots": [ { "accessPoints": [ { "address": "10.0.0.1" , "port": 3001 } ] , "advertise": false , "diffusionMode": "InitiatorOnly" , "warmValency": 1 , "hotValency": 1 } , { "accessPoints": [ { "address": "10.0.0.2" , "port": 3001 } ] , "advertise": true , "diffusionMode": "InititiatorAndResponder" , "warmValency": 1 , "hotValency": 1 } ] , "publicRoots": [] , "useLedgerAfterSlot": -1 } ``` --- cabal.project | 2 +- .../Cardano/Node/Configuration/TopologyP2P.hs | 13 ++++--- cardano-node/src/Cardano/Node/Run.hs | 34 +++++++++++++------ cardano-node/src/Cardano/Node/Startup.hs | 5 ++- cardano-node/src/Cardano/Node/Types.hs | 11 ++++-- .../Tracing/OrphanInstances/Network.hs | 11 ++++++ 6 files changed, 56 insertions(+), 20 deletions(-) diff --git a/cabal.project b/cabal.project index 19d0079e880..e291fb7e60c 100644 --- a/cabal.project +++ b/cabal.project @@ -72,7 +72,7 @@ allow-newer: source-repository-package type: git location: https://github.com/IntersectMBO/ouroboros-network - tag: e8896feaf2ffb9758d27c00d842237e2dbd56592 + tag: b55f22a32f3ec61e5e68c374156fa7c9bc14eef1 --sha256: sha256-78ulTpgwJuccs3ntjHebkIyrdT7Id572fk0xwianOe0= subdir: network-mux ouroboros-network-framework diff --git a/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs b/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs index dfad181fa7f..2a383db1e9b 100644 --- a/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs +++ b/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs @@ -27,7 +27,7 @@ import Cardano.Node.Configuration.POM (NodeConfiguration (..)) import Cardano.Node.Configuration.Topology (TopologyError (..)) import Cardano.Node.Types import Cardano.Tracing.OrphanInstances.Network () -import Ouroboros.Network.NodeToNode (PeerAdvertise (..)) +import Ouroboros.Network.NodeToNode (DiffusionMode (..), PeerAdvertise (..)) import Ouroboros.Network.PeerSelection.Bootstrap (UseBootstrapPeers (..)) import Ouroboros.Network.PeerSelection.LedgerPeers.Type (UseLedgerPeers (..)) import Ouroboros.Network.PeerSelection.PeerTrustable (PeerTrustable (..)) @@ -105,7 +105,7 @@ instance ToJSON RootConfig where rootConfigToRelayAccessPoint :: RootConfig -> [(RelayAccessPoint, PeerAdvertise)] -rootConfigToRelayAccessPoint RootConfig { rootAccessPoints, rootAdvertise } = +rootConfigToRelayAccessPoint RootConfig { rootAccessPoints, rootAdvertise } = [ (ap, rootAdvertise) | ap <- rootAccessPoints ] @@ -122,6 +122,8 @@ data LocalRootPeersGroup = LocalRootPeersGroup , trustable :: PeerTrustable -- ^ 'trustable' configures whether the root should be trusted in fallback -- state. + , rootDiffusionMode :: NodeDiffusionMode + -- ^ diffusion mode; used for local root peers. } deriving (Eq, Show) -- | Does not use the 'FromJSON' instance of 'RootConfig', so that @@ -136,6 +138,7 @@ instance FromJSON LocalRootPeersGroup where <*> pure hv <*> o .:? "warmValency" .!= WarmValency v <*> o .:? "trustable" .!= IsNotTrustable + <*> o .:? "diffusionMode" .!= (NodeDiffusionMode InitiatorAndResponderDiffusionMode) instance ToJSON LocalRootPeersGroup where toJSON lrpg = @@ -145,6 +148,7 @@ instance ToJSON LocalRootPeersGroup where , "hotValency" .= hotValency lrpg , "warmValency" .= warmValency lrpg , "trustable" .= trustable lrpg + , "diffusionMode" .= rootDiffusionMode lrpg ] newtype LocalRootPeersGroups = LocalRootPeersGroups @@ -252,10 +256,11 @@ isValidTrustedPeerConfiguration (RealNodeTopology (LocalRootPeersGroups lprgs) _ UseBootstrapPeers (_:_) -> True where anyTrustable = - any (\(LocalRootPeersGroup lr _ _ pt) -> case pt of + any (\LocalRootPeersGroup {localRoots, trustable} -> + case trustable of IsNotTrustable -> False IsTrustable -> not . null . rootAccessPoints - $ lr + $ localRoots ) lprgs diff --git a/cardano-node/src/Cardano/Node/Run.hs b/cardano-node/src/Cardano/Node/Run.hs index 3b88274a99e..87f8a7e13f7 100644 --- a/cardano-node/src/Cardano/Node/Run.hs +++ b/cardano-node/src/Cardano/Node/Run.hs @@ -82,7 +82,7 @@ import Ouroboros.Network.PeerSelection.LedgerPeers.Type (UseLedgerPeer import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..)) import Ouroboros.Network.PeerSelection.PeerTrustable (PeerTrustable) import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint (..)) -import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency, WarmValency) +import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency, LocalRootConfig (..), WarmValency) import Ouroboros.Network.Protocol.ChainSync.Codec import Ouroboros.Network.Subscription (DnsSubscriptionTarget (..), IPSubscriptionTarget (..)) @@ -661,7 +661,7 @@ installP2PSigHUPHandler :: Tracer IO (StartupTrace blk) -> Api.BlockType blk -> NodeConfiguration -> NodeKernel IO RemoteAddress (ConnectionId LocalAddress) blk - -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] + -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint LocalRootConfig)] -> StrictTVar IO (Map RelayAccessPoint PeerAdvertise) -> StrictTVar IO UseLedgerPeers -> StrictTVar IO UseBootstrapPeers @@ -756,7 +756,7 @@ updateBlockForging startupTracer blockType nodeKernel nc = do updateTopologyConfiguration :: Tracer IO (StartupTrace blk) -> NodeConfiguration - -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] + -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint LocalRootConfig)] -> StrictTVar IO (Map RelayAccessPoint PeerAdvertise) -> StrictTVar IO UseLedgerPeers -> StrictTVar IO UseBootstrapPeers @@ -843,7 +843,7 @@ checkVRFFilePermissions (File vrfPrivKey) = do mkP2PArguments :: NodeConfiguration - -> STM IO [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] + -> STM IO [(HotValency, WarmValency, Map RelayAccessPoint LocalRootConfig)] -- ^ non-overlapping local root peers groups; the 'Int' denotes the -- valency of its group. -> STM IO (Map RelayAccessPoint PeerAdvertise) @@ -921,18 +921,32 @@ producerAddressesNonP2P nt = producerAddresses :: NetworkTopology - -> ( [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] - , Map RelayAccessPoint PeerAdvertise) + -> ( [(HotValency, WarmValency, Map RelayAccessPoint LocalRootConfig)] + , Map RelayAccessPoint PeerAdvertise + ) + -- ^ local roots & public roots producerAddresses RealNodeTopology { ntLocalRootPeersGroups , ntPublicRootPeers } = ( map (\lrp -> ( hotValency lrp , warmValency lrp - , Map.fromList $ map (fmap (, trustable lrp)) - $ rootConfigToRelayAccessPoint - $ localRoots lrp + , Map.fromList + . map (\(addr, peerAdvertise) -> + ( addr + , LocalRootConfig { + diffusionMode = getDiffusionMode (rootDiffusionMode lrp), + peerAdvertise, + peerTrustable = trustable lrp + } + ) + ) + . rootConfigToRelayAccessPoint + $ localRoots lrp ) ) (groups ntLocalRootPeersGroups) - , foldMap (Map.fromList . rootConfigToRelayAccessPoint . publicRoots) ntPublicRootPeers + , foldMap ( Map.fromList + . rootConfigToRelayAccessPoint + . publicRoots + ) ntPublicRootPeers ) diff --git a/cardano-node/src/Cardano/Node/Startup.hs b/cardano-node/src/Cardano/Node/Startup.hs index 9f75890bafc..4260e2fe75c 100644 --- a/cardano-node/src/Cardano/Node/Startup.hs +++ b/cardano-node/src/Cardano/Node/Startup.hs @@ -34,9 +34,8 @@ import Ouroboros.Network.NodeToClient (LocalAddress (..), LocalSocket, NodeToClientVersion) import Ouroboros.Network.NodeToNode (DiffusionMode (..), NodeToNodeVersion, PeerAdvertise) import Ouroboros.Network.PeerSelection.LedgerPeers.Type (UseLedgerPeers) -import Ouroboros.Network.PeerSelection.PeerTrustable (PeerTrustable) import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint) -import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency, WarmValency) +import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency, LocalRootConfig, WarmValency) import Ouroboros.Network.Subscription.Dns (DnsSubscriptionTarget (..)) import Ouroboros.Network.Subscription.Ip (IPSubscriptionTarget (..)) @@ -106,7 +105,7 @@ data StartupTrace blk = -- | Log peer-to-peer network configuration, either on startup or when its -- updated. -- - | NetworkConfig [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] + | NetworkConfig [(HotValency, WarmValency, Map RelayAccessPoint LocalRootConfig)] (Map RelayAccessPoint PeerAdvertise) UseLedgerPeers diff --git a/cardano-node/src/Cardano/Node/Types.hs b/cardano-node/src/Cardano/Node/Types.hs index 87cc9c72685..edd2f01996f 100644 --- a/cardano-node/src/Cardano/Node/Types.hs +++ b/cardano-node/src/Cardano/Node/Types.hs @@ -96,11 +96,18 @@ newtype MaxConcurrencyDeadline = MaxConcurrencyDeadline deriving newtype (FromJSON, Show) --- | Newtype wrapper which provides 'FromJSON' instance for 'DiffusionMode'. +-- | Newtype wrapper which provides 'ToJSON' and 'FromJSON' instances for +-- 'DiffusionMode'. -- newtype NodeDiffusionMode = NodeDiffusionMode { getDiffusionMode :: DiffusionMode } - deriving newtype Show + deriving newtype (Eq, Show) + +instance ToJSON NodeDiffusionMode where + toJSON (NodeDiffusionMode InitiatorOnlyDiffusionMode) + = String "InitiatorOnly" + toJSON (NodeDiffusionMode InitiatorAndResponderDiffusionMode) + = String "InitiatorAndResponder" instance FromJSON NodeDiffusionMode where parseJSON (String str) = diff --git a/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs b/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs index 333a4a0162a..dc3d08a8771 100644 --- a/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs +++ b/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs @@ -80,6 +80,7 @@ import Ouroboros.Network.PeerSelection.State.KnownPeers (KnownPeerInfo import qualified Ouroboros.Network.PeerSelection.State.KnownPeers as KnownPeers import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (..), LocalRootPeers, WarmValency (..)) +import Ouroboros.Network.PeerSelection.State.LocalRootPeers (LocalRootConfig (..)) import qualified Ouroboros.Network.PeerSelection.State.LocalRootPeers as LocalRootPeers import Ouroboros.Network.PeerSelection.Types (PeerStatus (..)) import Ouroboros.Network.Protocol.BlockFetch.Type (BlockFetch, Message (..)) @@ -1493,6 +1494,16 @@ instance FromJSON HotValency where instance FromJSON WarmValency where parseJSON v = WarmValency <$> parseJSON v +instance ToJSON LocalRootConfig where + toJSON LocalRootConfig { peerAdvertise, + peerTrustable, + diffusionMode } = + Aeson.object + [ "peerAdvertise" .= peerAdvertise + , "peerTrustable" .= peerTrustable + , "diffusionMode" .= show diffusionMode + ] + instance Show exception => ToObject (TraceLocalRootPeers RemoteAddress exception) where toObject _verb (TraceLocalRootDomains groups) = mconcat [ "kind" .= String "LocalRootDomains"