diff --git a/.github/workflows/check-mainnet-config.yml b/.github/workflows/check-mainnet-config.yml index ee3059ea722..451b1d310e8 100644 --- a/.github/workflows/check-mainnet-config.yml +++ b/.github/workflows/check-mainnet-config.yml @@ -50,7 +50,7 @@ jobs: for f in "${test_files[@]}"; do nix_file="result/$f" repo_file="configuration/cardano/$f" - if ! jq -e --argfile nix "$nix_file" --argfile repo "$repo_file" -n '$repo | reduce keys[] as $k (true; . and $repo[$k] == $nix[$k])' &>/dev/null ; then + if ! jq -e --slurpfile nix "$nix_file" --slurpfile repo "$repo_file" -n '$repo | reduce keys[] as $k (true; . and $repo[$k] == $nix[$k])' &>/dev/null ; then echo "Nix file $nix_file does not have all the same top-level entries as the file from repository $repo_file" diff "$nix_file" "$repo_file" exit 1 diff --git a/.github/workflows/haskell.yml b/.github/workflows/haskell.yml index 8e45e46aa02..81581785612 100644 --- a/.github/workflows/haskell.yml +++ b/.github/workflows/haskell.yml @@ -38,7 +38,7 @@ jobs: env: # Modify this value to "invalidate" the cabal cache. - CABAL_CACHE_VERSION: "2024-02-26-4" + CABAL_CACHE_VERSION: "2024-02-29" concurrency: group: > diff --git a/bench/locli/locli.cabal b/bench/locli/locli.cabal index f551c1b3c2c..1eb98f55af9 100644 --- a/bench/locli/locli.cabal +++ b/bench/locli/locli.cabal @@ -121,7 +121,7 @@ library , optparse-generic , ouroboros-consensus -- for Data.SOP.Strict: - , ouroboros-network ^>= 0.11 + , ouroboros-network ^>= 0.12 , ouroboros-network-api , process , quiet @@ -170,12 +170,12 @@ test-suite test-locli hs-source-dirs: test main-is: test-locli.hs type: exitcode-stdio-1.0 - ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" build-depends: cardano-prelude , containers , hedgehog - , hedgehog-extras ^>= 0.6.1.0 + , hedgehog-extras < 0.6.2 , locli , text diff --git a/bench/plutus-scripts-bench/plutus-scripts-bench.cabal b/bench/plutus-scripts-bench/plutus-scripts-bench.cabal index 6ecee48efef..b0dac39a86c 100644 --- a/bench/plutus-scripts-bench/plutus-scripts-bench.cabal +++ b/bench/plutus-scripts-bench/plutus-scripts-bench.cabal @@ -73,7 +73,7 @@ library -- IOG dependencies -------------------------- build-depends: - , cardano-api ^>= 8.39 + , cardano-api ^>= 8.39.2.0 , plutus-ledger-api >=1.0.0 , plutus-tx >=1.0.0 , plutus-tx-plugin ^>=1.21 diff --git a/bench/tx-generator/tx-generator.cabal b/bench/tx-generator/tx-generator.cabal index 81b11f45a95..b3eee7f8bff 100644 --- a/bench/tx-generator/tx-generator.cabal +++ b/bench/tx-generator/tx-generator.cabal @@ -100,9 +100,9 @@ library , attoparsec-aeson , base16-bytestring , bytestring - , cardano-api ^>= 8.39 + , cardano-api ^>= 8.39.2.0 , cardano-binary - , cardano-cli ^>= 8.20.2.0 + , cardano-cli ^>= 8.20.3.0 , cardano-crypto-class , cardano-crypto-wrapper , cardano-data @@ -238,7 +238,7 @@ test-suite tx-generator-test -fno-warn-missing-import-lists -fno-warn-safe -fno-warn-unsafe - -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + -threaded -rtsopts "-with-rtsopts=-N -T" benchmark tx-generator-bench import: project-config @@ -256,4 +256,4 @@ benchmark tx-generator-bench -fno-warn-missing-import-lists -fno-warn-safe -fno-warn-unsafe - -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + -threaded -rtsopts "-with-rtsopts=-N -T" diff --git a/cabal.project b/cabal.project index 6b03882b336..fbdb1810247 100644 --- a/cabal.project +++ b/cabal.project @@ -13,8 +13,8 @@ repository cardano-haskell-packages -- See CONTRIBUTING for information about these, including some Nix commands -- you need to run if you change them index-state: - , hackage.haskell.org 2024-02-21T10:56:14Z - , cardano-haskell-packages 2024-02-23T22:53:00Z + , hackage.haskell.org 2024-02-27T08:06:51Z + , cardano-haskell-packages 2024-02-26T17:55:44Z packages: cardano-git-rev diff --git a/cardano-node-chairman/app/Cardano/Chairman.hs b/cardano-node-chairman/app/Cardano/Chairman.hs index 0c5cd447486..325e700bb40 100644 --- a/cardano-node-chairman/app/Cardano/Chairman.hs +++ b/cardano-node-chairman/app/Cardano/Chairman.hs @@ -343,7 +343,7 @@ chainSyncClient tracer sockPath chainsVar secParam = ChainSyncClient $ pure $ } where clientStIdle :: ClientStIdle BlockInMode ChainPoint ChainTip IO () - clientStIdle = SendMsgRequestNext clientStNext (pure clientStNext) + clientStIdle = SendMsgRequestNext (pure ()) clientStNext clientStNext :: ClientStNext BlockInMode ChainPoint ChainTip IO () clientStNext = ClientStNext diff --git a/cardano-node-chairman/cardano-node-chairman.cabal b/cardano-node-chairman/cardano-node-chairman.cabal index d42897930e8..7142e606c37 100644 --- a/cardano-node-chairman/cardano-node-chairman.cabal +++ b/cardano-node-chairman/cardano-node-chairman.cabal @@ -44,7 +44,7 @@ executable cardano-node-chairman build-depends: cardano-api , cardano-crypto-class , cardano-git-rev - , cardano-node ^>= 8.8 + , cardano-node ^>= 8.9 , cardano-prelude , containers , contra-tracer @@ -72,7 +72,7 @@ test-suite chairman-tests , cardano-crypto-class ^>= 2.1.2 , filepath , hedgehog - , hedgehog-extras ^>= 0.6.1.0 + , hedgehog-extras < 0.6.2 , network , process , random @@ -85,8 +85,8 @@ test-suite chairman-tests Spec.Chairman.Cardano Spec.Network - ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" build-tool-depends: cardano-node:cardano-node - , cardano-cli:cardano-cli ^>= 8.20.2.0 + , cardano-cli:cardano-cli ^>= 8.20.3.0 , cardano-node-chairman:cardano-node-chairman diff --git a/cardano-node/cardano-node.cabal b/cardano-node/cardano-node.cabal index 36868f01048..7d425f8cd85 100644 --- a/cardano-node/cardano-node.cabal +++ b/cardano-node/cardano-node.cabal @@ -1,7 +1,7 @@ cabal-version: 3.0 name: cardano-node -version: 8.8.1 +version: 8.9.0 synopsis: The cardano full node description: The cardano full node. category: Cardano, @@ -144,7 +144,7 @@ library , async , base16-bytestring , bytestring - , cardano-api ^>= 8.39 + , cardano-api ^>= 8.39.2.0 , cardano-crypto-class , cardano-crypto-wrapper , cardano-git-rev @@ -171,7 +171,7 @@ library , formatting , generic-data , hostname - , io-classes >= 0.3 + , io-classes >= 1.4 , iohk-monitoring , iproute , lobemo-backend-aggregation @@ -183,14 +183,14 @@ library , network-mux >= 0.4 , nothunks , optparse-applicative-fork >= 0.18.1 - , ouroboros-consensus ^>= 0.15 - , ouroboros-consensus-cardano ^>= 0.13 - , ouroboros-consensus-diffusion ^>= 0.10 + , ouroboros-consensus ^>= 0.16 + , ouroboros-consensus-cardano ^>= 0.14 + , ouroboros-consensus-diffusion ^>= 0.11 , ouroboros-consensus-protocol , ouroboros-network-api - , ouroboros-network ^>= 0.11 + , ouroboros-network ^>= 0.12 , ouroboros-network-framework - , ouroboros-network-protocols ^>= 0.7 + , ouroboros-network-protocols ^>= 0.8 , prettyprinter , prettyprinter-ansi-terminal , psqueues @@ -276,4 +276,4 @@ test-suite cardano-node-test Test.Cardano.Tracing.NewTracing.Consistency Test.Cardano.Tracing.OrphanInstances.HardFork - ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" diff --git a/cardano-node/src/Cardano/Node/Configuration/POM.hs b/cardano-node/src/Cardano/Node/Configuration/POM.hs index 0162c68dbd1..b81c9afc453 100644 --- a/cardano-node/src/Cardano/Node/Configuration/POM.hs +++ b/cardano-node/src/Cardano/Node/Configuration/POM.hs @@ -34,7 +34,8 @@ import Cardano.Tracing.OrphanInstances.Network () import Ouroboros.Consensus.Mempool (MempoolCapacityBytes (..), MempoolCapacityBytesOverride (..)) import qualified Ouroboros.Consensus.Node as Consensus (NetworkP2PMode (..)) -import Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy (SnapshotInterval (..)) +import Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy (NumOfDiskSnapshots (..), + SnapshotInterval (..)) import Ouroboros.Network.NodeToNode (AcceptedConnectionsLimit (..), DiffusionMode (..)) import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..)) @@ -101,8 +102,9 @@ data NodeConfiguration , ncProtocolConfig :: !NodeProtocolConfiguration -- Node parameters, not protocol-specific: - , ncDiffusionMode :: !DiffusionMode - , ncSnapshotInterval :: !SnapshotInterval + , ncDiffusionMode :: !DiffusionMode + , ncNumOfDiskSnapshots :: !NumOfDiskSnapshots + , ncSnapshotInterval :: !SnapshotInterval -- | During the development and integration of new network protocols -- (node-to-node and node-to-client) we wish to be able to test them @@ -182,8 +184,9 @@ data PartialNodeConfiguration , pncProtocolConfig :: !(Last NodeProtocolConfiguration) -- Node parameters, not protocol-specific: - , pncDiffusionMode :: !(Last DiffusionMode) - , pncSnapshotInterval :: !(Last SnapshotInterval) + , pncDiffusionMode :: !(Last DiffusionMode ) + , pncNumOfDiskSnapshots :: !(Last NumOfDiskSnapshots) + , pncSnapshotInterval :: !(Last SnapshotInterval) , pncExperimentalProtocolsEnabled :: !(Last Bool) -- BlockFetch configuration @@ -241,6 +244,8 @@ instance FromJSON PartialNodeConfiguration where pncSocketPath <- Last <$> v .:? "SocketPath" pncDiffusionMode <- Last . fmap getDiffusionMode <$> v .:? "DiffusionMode" + pncNumOfDiskSnapshots + <- Last . fmap RequestedNumOfDiskSnapshots <$> v .:? "NumOfDiskSnapshots" pncSnapshotInterval <- Last . fmap RequestedSnapshotInterval <$> v .:? "SnapshotInterval" pncExperimentalProtocolsEnabled <- fmap Last $ do @@ -320,6 +325,7 @@ instance FromJSON PartialNodeConfiguration where pncProtocolConfig , pncSocketConfig = Last . Just $ SocketConfig mempty mempty mempty pncSocketPath , pncDiffusionMode + , pncNumOfDiskSnapshots , pncSnapshotInterval , pncExperimentalProtocolsEnabled , pncMaxConcurrencyBulkSync @@ -490,6 +496,7 @@ defaultPartialNodeConfiguration = , pncLoggingSwitch = Last $ Just True , pncSocketConfig = Last . Just $ SocketConfig mempty mempty mempty mempty , pncDiffusionMode = Last $ Just InitiatorAndResponderDiffusionMode + , pncNumOfDiskSnapshots = Last $ Just DefaultNumOfDiskSnapshots , pncSnapshotInterval = Last $ Just DefaultSnapshotInterval , pncExperimentalProtocolsEnabled = Last $ Just False , pncTopologyFile = Last . Just $ TopologyFile "configuration/cardano/mainnet-topology.json" @@ -541,6 +548,7 @@ makeNodeConfiguration pnc = do logMetrics <- lastToEither "Missing LogMetrics" $ pncLogMetrics pnc traceConfig <- first Text.unpack $ partialTraceSelectionToEither $ pncTraceConfig pnc diffusionMode <- lastToEither "Missing DiffusionMode" $ pncDiffusionMode pnc + numOfDiskSnapshots <- lastToEither "Missing NumOfDiskSnapshots" $ pncNumOfDiskSnapshots pnc snapshotInterval <- lastToEither "Missing SnapshotInterval" $ pncSnapshotInterval pnc shutdownConfig <- lastToEither "Missing ShutdownConfig" $ pncShutdownConfig pnc socketConfig <- lastToEither "Missing SocketConfig" $ pncSocketConfig pnc @@ -609,6 +617,7 @@ makeNodeConfiguration pnc = do , ncProtocolConfig = protocolConfig , ncSocketConfig = socketConfig , ncDiffusionMode = diffusionMode + , ncNumOfDiskSnapshots = numOfDiskSnapshots , ncSnapshotInterval = snapshotInterval , ncExperimentalProtocolsEnabled = experimentalProtocols , ncMaxConcurrencyBulkSync = getLast $ pncMaxConcurrencyBulkSync pnc diff --git a/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs b/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs index fa088fc4501..f1d8c29a3fd 100644 --- a/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs +++ b/cardano-node/src/Cardano/Node/Configuration/TopologyP2P.hs @@ -30,7 +30,9 @@ import Cardano.Node.Startup (StartupTrace (..)) import Cardano.Node.Types import Cardano.Tracing.OrphanInstances.Network () import Ouroboros.Network.NodeToNode (PeerAdvertise (..)) -import Ouroboros.Network.PeerSelection.LedgerPeers (UseLedgerAfter (..)) +import Ouroboros.Network.PeerSelection.Bootstrap (UseBootstrapPeers (..)) +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 (..)) @@ -53,7 +55,7 @@ data NodeSetup = NodeSetup , nodeIPv4Address :: !(Maybe NodeIPv4Address) , nodeIPv6Address :: !(Maybe NodeIPv6Address) , producers :: ![RootConfig] - , useLedger :: !UseLedger + , useLedger :: !UseLedgerPeers } deriving (Eq, Show) instance FromJSON NodeSetup where @@ -63,7 +65,7 @@ instance FromJSON NodeSetup where <*> o .: "nodeIPv4Address" <*> o .: "nodeIPv6Address" <*> o .: "producers" - <*> o .:? "useLedgerAfterSlot" .!= UseLedger DontUseLedger + <*> o .:? "useLedgerAfterSlot" .!= DontUseLedgerPeers instance ToJSON NodeSetup where toJSON ns = @@ -85,7 +87,7 @@ data RootConfig = RootConfig -- or domain name and a port number. , rootAdvertise :: PeerAdvertise -- ^ 'advertise' configures whether the root should be advertised through - -- gossip. + -- peer sharing. } deriving (Eq, Show) instance FromJSON RootConfig where @@ -121,6 +123,9 @@ data LocalRootPeersGroup = LocalRootPeersGroup { localRoots :: RootConfig , hotValency :: HotValency , warmValency :: WarmValency + , trustable :: PeerTrustable + -- ^ 'trustable' configures whether the root should be trusted in fallback + -- state. } deriving (Eq, Show) -- | Does not use the 'FromJSON' instance of 'RootConfig', so that @@ -134,6 +139,7 @@ instance FromJSON LocalRootPeersGroup where <$> parseJSON (Object o) <*> pure hv <*> o .:? "warmValency" .!= WarmValency v + <*> o .:? "trustable" .!= IsNotTrustable instance ToJSON LocalRootPeersGroup where toJSON lrpg = @@ -142,6 +148,7 @@ instance ToJSON LocalRootPeersGroup where , "advertise" .= rootAdvertise (localRoots lrpg) , "hotValency" .= hotValency lrpg , "warmValency" .= warmValency lrpg + , "trustable" .= trustable lrpg ] newtype LocalRootPeersGroups = LocalRootPeersGroups @@ -164,22 +171,32 @@ instance FromJSON PublicRootPeers where instance ToJSON PublicRootPeers where toJSON = toJSON . publicRoots -data NetworkTopology = RealNodeTopology !LocalRootPeersGroups ![PublicRootPeers] !UseLedger +data NetworkTopology = RealNodeTopology { ntLocalRootPeersGroups :: !LocalRootPeersGroups + , ntPublicRootPeers :: ![PublicRootPeers] + , ntUseLedgerPeers :: !UseLedgerPeers + , ntUseBootstrapPeers :: !UseBootstrapPeers + } deriving (Eq, Show) instance FromJSON NetworkTopology where parseJSON = withObject "NetworkTopology" $ \o -> - RealNodeTopology <$> (o .: "localRoots" ) - <*> (o .: "publicRoots" ) - <*> (o .:? "useLedgerAfterSlot" .!= UseLedger DontUseLedger) + RealNodeTopology <$> (o .: "localRoots" ) + <*> (o .: "publicRoots" ) + <*> (o .:? "useLedgerAfterSlot" .!= DontUseLedgerPeers ) + <*> (o .:? "bootstrapPeers" .!= DontUseBootstrapPeers) instance ToJSON NetworkTopology where toJSON top = case top of - RealNodeTopology lrpg prp ul -> object [ "localRoots" .= lrpg - , "publicRoots" .= prp - , "useLedgerAfterSlot" .= ul - ] + RealNodeTopology { ntLocalRootPeersGroups + , ntPublicRootPeers + , ntUseLedgerPeers + , ntUseBootstrapPeers + } -> object [ "localRoots" .= ntLocalRootPeersGroups + , "publicRoots" .= ntPublicRootPeers + , "useLedgerAfterSlot" .= ntUseLedgerPeers + , "bootstrapPeers" .= ntUseBootstrapPeers + ] -- -- Legacy p2p topology file format @@ -195,10 +212,12 @@ instance FromJSON (Legacy a) => FromJSON (Legacy [a]) where instance FromJSON (Legacy LocalRootPeersGroup) where parseJSON = withObject "LocalRootPeersGroup" $ \o -> do hv@(HotValency v) <- o .: "hotValency" + wv <- o .:? "warmValency" .!= WarmValency v fmap Legacy $ LocalRootPeersGroup <$> o .: "localRoots" <*> pure hv - <*> pure (WarmValency v) + <*> pure wv + <*> o .: "trustable" instance FromJSON (Legacy LocalRootPeersGroups) where parseJSON = withObject "LocalRootPeersGroups" $ \o -> @@ -213,9 +232,10 @@ instance FromJSON (Legacy PublicRootPeers) where instance FromJSON (Legacy NetworkTopology) where parseJSON = fmap Legacy . withObject "NetworkTopology" (\o -> - RealNodeTopology <$> fmap getLegacy (o .: "LocalRoots") - <*> fmap getLegacy (o .: "PublicRoots") - <*> (o .:? "useLedgerAfterSlot" .!= UseLedger DontUseLedger)) + RealNodeTopology <$> fmap getLegacy (o .: "LocalRoots") + <*> fmap getLegacy (o .: "PublicRoots") + <*> (o .:? "useLedgerAfterSlot" .!= DontUseLedgerPeers) + <*> pure DontUseBootstrapPeers) -- | Read the `NetworkTopology` configuration from the specified file. -- @@ -228,7 +248,12 @@ readTopologyFile tr nc = do Left e -> return . Left $ handler e Right bs -> let bs' = LBS.fromStrict bs in - first handlerJSON (eitherDecode bs') + (case eitherDecode bs' of + Left err -> Left (handlerJSON err) + Right t + | isValidTrustedPeerConfiguration t -> Right t + | otherwise -> Left handlerBootstrap + ) `combine` first handlerJSON (eitherDecode bs') @@ -256,6 +281,13 @@ readTopologyFile tr nc = do , "configuration flag. " , Text.pack err ] + handlerBootstrap :: Text + handlerBootstrap = mconcat + [ "You seem to have not configured any trustable peers. " + , "This is important in order for the node to make progress " + , "in bootstrap mode. Make sure you provide at least one bootstrap peer " + , "source. " + ] readTopologyFileOrError :: Tracer IO (StartupTrace blk) -> NodeConfiguration -> IO NetworkTopology @@ -264,3 +296,25 @@ readTopologyFileOrError tr nc = >>= either (\err -> error $ "Cardano.Node.Configuration.TopologyP2P.readTopologyFile: " <> Text.unpack err) pure + +-- +-- Checking for chance of progress in bootstrap phase +-- + +-- | This function returns false if non-trustable peers are configured +-- +isValidTrustedPeerConfiguration :: NetworkTopology -> Bool +isValidTrustedPeerConfiguration (RealNodeTopology (LocalRootPeersGroups lprgs) _ _ ubp) = + case ubp of + DontUseBootstrapPeers -> True + UseBootstrapPeers [] -> anyTrustable + UseBootstrapPeers (_:_) -> True + where + anyTrustable = + any (\(LocalRootPeersGroup lr _ _ pt) -> case pt of + IsNotTrustable -> False + IsTrustable -> not + . null + . rootAccessPoints + $ lr + ) lprgs diff --git a/cardano-node/src/Cardano/Node/Parsers.hs b/cardano-node/src/Cardano/Node/Parsers.hs index 24a0562b208..2faf78ffd65 100644 --- a/cardano-node/src/Cardano/Node/Parsers.hs +++ b/cardano-node/src/Cardano/Node/Parsers.hs @@ -22,7 +22,8 @@ import Cardano.Node.Types import Cardano.Prelude (ConvertText (..)) import Ouroboros.Consensus.Mempool (MempoolCapacityBytes (..), MempoolCapacityBytesOverride (..)) -import Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy (SnapshotInterval (..)) +import Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy (NumOfDiskSnapshots (..), + SnapshotInterval (..)) import Data.Foldable import Data.Maybe (fromMaybe) @@ -69,7 +70,8 @@ nodeRunParser = do -- NodeConfiguration filepath nodeConfigFp <- lastOption parseConfigFile - snapshotInterval <- lastOption parseSnapshotInterval + numOfDiskSnapshots <- lastOption parseNumOfDiskSnapshots + snapshotInterval <- lastOption parseSnapshotInterval validate <- lastOption parseValidateDB shutdownIPC <- lastOption parseShutdownIPC @@ -88,6 +90,7 @@ nodeRunParser = do , pncTopologyFile = TopologyFile <$> topFp , pncDatabaseFile = DbFile <$> dbFp , pncDiffusionMode = mempty + , pncNumOfDiskSnapshots = numOfDiskSnapshots , pncSnapshotInterval = snapshotInterval , pncExperimentalProtocolsEnabled = mempty , pncProtocolFiles = Last $ Just ProtocolFilepaths @@ -327,6 +330,15 @@ parseStartAsNonProducingNode = ] ] +parseNumOfDiskSnapshots :: Parser NumOfDiskSnapshots +parseNumOfDiskSnapshots = fmap RequestedNumOfDiskSnapshots parseNum + where + parseNum = Opt.option auto + ( long "num-of-disk-snapshots" + <> metavar "NUMOFDISKSNAPSHOTS" + <> help "Number of ledger snapshots stored on disk." + ) + -- TODO revisit because it sucks parseSnapshotInterval :: Parser SnapshotInterval parseSnapshotInterval = fmap (RequestedSnapshotInterval . secondsToDiffTime) parseDifftime @@ -334,7 +346,7 @@ parseSnapshotInterval = fmap (RequestedSnapshotInterval . secondsToDiffTime) par parseDifftime = Opt.option auto ( long "snapshot-interval" <> metavar "SNAPSHOTINTERVAL" - <> help "Snapshot Interval (in second)" + <> help "Snapshot Interval (in seconds)" ) -- | Produce just the brief help header for a given CLI option parser, diff --git a/cardano-node/src/Cardano/Node/Run.hs b/cardano-node/src/Cardano/Node/Run.hs index bff97954e8a..1b474f7c14c 100644 --- a/cardano-node/src/Cardano/Node/Run.hs +++ b/cardano-node/src/Cardano/Node/Run.hs @@ -9,6 +9,7 @@ {-# LANGUAGE PackageImports #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} +{-# LANGUAGE TupleSections #-} {-# OPTIONS_GHC -Wno-unused-imports #-} @@ -88,8 +89,8 @@ import Cardano.Tracing.Config (TraceOptions (..), TraceSelection (..)) import qualified Ouroboros.Consensus.Config as Consensus import Ouroboros.Consensus.Config.SupportsNode (ConfigSupportsNode (..)) -import Ouroboros.Consensus.Node (NetworkP2PMode (..), RunNodeArgs (..), - StdRunNodeArgs (..), stdChainSyncTimeout) +import Ouroboros.Consensus.Node (DiskPolicyArgs (..), NetworkP2PMode (..), + RunNodeArgs (..), StdRunNodeArgs (..), stdChainSyncTimeout) import qualified Ouroboros.Consensus.Node as Node (getChainDB, run) import Ouroboros.Consensus.Node.NetworkProtocolVersion import Ouroboros.Consensus.Node.ProtocolInfo @@ -100,11 +101,12 @@ import qualified Ouroboros.Network.Diffusion.P2P as P2P import Ouroboros.Network.NodeToClient (LocalAddress (..), LocalSocket (..)) import Ouroboros.Network.NodeToNode (AcceptedConnectionsLimit (..), ConnectionId, PeerSelectionTargets (..), RemoteAddress) -import Ouroboros.Network.PeerSelection.LedgerPeers (UseLedgerAfter (..)) import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint (..)) import Ouroboros.Network.Protocol.ChainSync.Codec import Ouroboros.Network.Subscription (DnsSubscriptionTarget (..), IPSubscriptionTarget (..)) +import Ouroboros.Network.PeerSelection.Bootstrap + (UseBootstrapPeers (..)) import Cardano.Node.Configuration.Socket (SocketOrSocketInfo (..), gatherConfiguredSockets, getSocketOrSocketInfoAddr) @@ -123,6 +125,9 @@ import Cardano.Node.TraceConstraints (TraceConstraints) import Cardano.Tracing.Tracers import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..)) import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency, WarmValency) +import Ouroboros.Network.PeerSelection.LedgerPeers.Type (UseLedgerPeers) +import Ouroboros.Network.PeerSelection.PeerTrustable (PeerTrustable) +import Ouroboros.Network.PeerSelection.Bootstrap (UseBootstrapPeers) {- HLINT ignore "Fuse concatMap/map" -} {- HLINT ignore "Redundant <$>" -} @@ -408,40 +413,45 @@ handleSimpleNode blockType runP p2pMode tracers nc onKernel = do )) withShutdownHandling (ncShutdownConfig nc) (shutdownTracer tracers) $ - let nodeArgs = RunNodeArgs - { rnTraceConsensus = consensusTracers tracers - , rnTraceNTN = nodeToNodeTracers tracers - , rnTraceNTC = nodeToClientTracers tracers - , rnProtocolInfo = pInfo - , rnNodeKernelHook = \registry nodeKernel -> do - -- set the initial block forging - blockForging <- snd (Api.protocolInfo runP) - - unless (ncStartAsNonProducingNode nc) $ - setBlockForging nodeKernel blockForging - - maybeSpawnOnSlotSyncedShutdownHandler - (ncShutdownConfig nc) - (shutdownTracer tracers) - registry - (Node.getChainDB nodeKernel) - onKernel nodeKernel - , rnEnableP2P = p2pMode - , rnPeerSharing = ncPeerSharing nc - } - in case p2pMode of + case p2pMode of EnabledP2PMode -> do traceWith (startupTracer tracers) (StartupP2PInfo (ncDiffusionMode nc)) - nt <- TopologyP2P.readTopologyFileOrError (startupTracer tracers) nc + nt@TopologyP2P.RealNodeTopology + { ntUseLedgerPeers + , ntUseBootstrapPeers + } <- TopologyP2P.readTopologyFileOrError (startupTracer tracers) nc let (localRoots, publicRoots) = producerAddresses nt traceWith (startupTracer tracers) $ NetworkConfig localRoots publicRoots - (useLedgerAfterSlot nt) + ntUseLedgerPeers localRootsVar <- newTVarIO localRoots publicRootsVar <- newTVarIO publicRoots - useLedgerVar <- newTVarIO (useLedgerAfterSlot nt) + useLedgerVar <- newTVarIO ntUseLedgerPeers + useBootstrapVar <- newTVarIO ntUseBootstrapPeers + let nodeArgs = RunNodeArgs + { rnTraceConsensus = consensusTracers tracers + , rnTraceNTN = nodeToNodeTracers tracers + , rnTraceNTC = nodeToClientTracers tracers + , rnProtocolInfo = pInfo + , rnNodeKernelHook = \registry nodeKernel -> do + -- set the initial block forging + blockForging <- snd (Api.protocolInfo runP) + + unless (ncStartAsNonProducingNode nc) $ + setBlockForging nodeKernel blockForging + + maybeSpawnOnSlotSyncedShutdownHandler + (ncShutdownConfig nc) + (shutdownTracer tracers) + registry + (Node.getChainDB nodeKernel) + onKernel nodeKernel + , rnEnableP2P = p2pMode + , rnPeerSharing = ncPeerSharing nc + , rnGetUseBootstrapPeers = readTVar useBootstrapVar + } #ifdef UNIX -- initial `SIGHUP` handler, which only rereads the topology file but -- doesn't update block forging. The latter is only possible once @@ -451,7 +461,7 @@ handleSimpleNode blockType runP p2pMode tracers nc onKernel = do (Signals.Catch $ do updateTopologyConfiguration (startupTracer tracers) nc - localRootsVar publicRootsVar useLedgerVar + localRootsVar publicRootsVar useLedgerVar useBootstrapVar traceWith (startupTracer tracers) (BlockForgingUpdate NotEffective) ) Nothing @@ -462,20 +472,21 @@ handleSimpleNode blockType runP p2pMode tracers nc onKernel = do (readTVar localRootsVar) (readTVar publicRootsVar) (readTVar useLedgerVar) + (readTVar useBootstrapVar) in Node.run nodeArgs { rnNodeKernelHook = \registry nodeKernel -> do -- reinstall `SIGHUP` handler installP2PSigHUPHandler (startupTracer tracers) blockType nc nodeKernel - localRootsVar publicRootsVar useLedgerVar + localRootsVar publicRootsVar useLedgerVar useBootstrapVar rnNodeKernelHook nodeArgs registry nodeKernel } StdRunNodeArgs { srnBfcMaxConcurrencyBulkSync = unMaxConcurrencyBulkSync <$> ncMaxConcurrencyBulkSync nc , srnBfcMaxConcurrencyDeadline = unMaxConcurrencyDeadline <$> ncMaxConcurrencyDeadline nc , srnChainDbValidateOverride = ncValidateDB nc - , srnSnapshotInterval = ncSnapshotInterval nc + , srnDiskPolicyArgs = diskPolicyArgs , srnDatabasePath = dbPath , srnDiffusionArguments = diffusionArguments , srnDiffusionArgumentsExtra = diffusionArgumentsExtra @@ -501,6 +512,29 @@ handleSimpleNode blockType runP p2pMode tracers nc onKernel = do | (NodeAddress (NodeHostIPAddress addr) port) <- ipProducerAddrs ] (length ipProducerAddrs) + + nodeArgs = RunNodeArgs + { rnTraceConsensus = consensusTracers tracers + , rnTraceNTN = nodeToNodeTracers tracers + , rnTraceNTC = nodeToClientTracers tracers + , rnProtocolInfo = pInfo + , rnNodeKernelHook = \registry nodeKernel -> do + -- set the initial block forging + blockForging <- snd (Api.protocolInfo runP) + + unless (ncStartAsNonProducingNode nc) $ + setBlockForging nodeKernel blockForging + + maybeSpawnOnSlotSyncedShutdownHandler + (ncShutdownConfig nc) + (shutdownTracer tracers) + registry + (Node.getChainDB nodeKernel) + onKernel nodeKernel + , rnEnableP2P = p2pMode + , rnPeerSharing = ncPeerSharing nc + , rnGetUseBootstrapPeers = pure DontUseBootstrapPeers + } #ifdef UNIX -- initial `SIGHUP` handler; it only warns that neither updating of -- topology is supported nor updating block forging is yet possible. @@ -525,7 +559,7 @@ handleSimpleNode blockType runP p2pMode tracers nc onKernel = do { srnBfcMaxConcurrencyBulkSync = unMaxConcurrencyBulkSync <$> ncMaxConcurrencyBulkSync nc , srnBfcMaxConcurrencyDeadline = unMaxConcurrencyDeadline <$> ncMaxConcurrencyDeadline nc , srnChainDbValidateOverride = ncValidateDB nc - , srnSnapshotInterval = ncSnapshotInterval nc + , srnDiskPolicyArgs = diskPolicyArgs , srnDatabasePath = dbPath , srnDiffusionArguments = diffusionArguments , srnDiffusionArgumentsExtra = mkNonP2PArguments ipProducers dnsProducers @@ -594,6 +628,12 @@ handleSimpleNode blockType runP p2pMode tracers nc onKernel = do Nothing -> id Just version_ -> Map.takeWhileAntitone (<= version_) + diskPolicyArgs :: DiskPolicyArgs + diskPolicyArgs = + DiskPolicyArgs + (ncSnapshotInterval nc) + (ncNumOfDiskSnapshots nc) + -------------------------------------------------------------------------------- -- SIGHUP Handlers -------------------------------------------------------------------------------- @@ -604,19 +644,21 @@ installP2PSigHUPHandler :: Tracer IO (StartupTrace blk) -> Api.BlockType blk -> NodeConfiguration -> NodeKernel IO RemoteAddress (ConnectionId LocalAddress) blk - -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint PeerAdvertise)] + -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] -> StrictTVar IO (Map RelayAccessPoint PeerAdvertise) - -> StrictTVar IO UseLedgerAfter + -> StrictTVar IO UseLedgerPeers + -> StrictTVar IO UseBootstrapPeers -> IO () #ifndef UNIX -installP2PSigHUPHandler _ _ _ _ _ _ _ = return () +installP2PSigHUPHandler _ _ _ _ _ _ _ _ = return () #else -installP2PSigHUPHandler startupTracer blockType nc nodeKernel localRootsVar publicRootsVar useLedgerVar = +installP2PSigHUPHandler startupTracer blockType nc nodeKernel localRootsVar publicRootsVar useLedgerVar + useBootstrapPeersVar = void $ Signals.installHandler Signals.sigHUP (Signals.Catch $ do updateBlockForging startupTracer blockType nodeKernel nc - updateTopologyConfiguration startupTracer nc localRootsVar publicRootsVar useLedgerVar + updateTopologyConfiguration startupTracer nc localRootsVar publicRootsVar useLedgerVar useBootstrapPeersVar ) Nothing #endif @@ -686,6 +728,10 @@ updateBlockForging startupTracer blockType nodeKernel nc = do wasFileRemovedFromScope (CardanoProtocolInstantiationError (CardanoProtocolInstantiationPraosLeaderCredentialsError (FileError fe))) = Just fe + wasFileRemovedFromScope (CardanoProtocolInstantiationError + (CardanoProtocolInstantiationPraosLeaderCredentialsError + (CredentialsReadError fp _))) = + Just (Api.FileDoesNotExistError fp) wasFileRemovedFromScope (ByronProtocolInstantiationError _) = Nothing wasFileRemovedFromScope (ShelleyProtocolInstantiationError _) = Nothing wasFileRemovedFromScope (CardanoProtocolInstantiationError _) = Nothing @@ -693,11 +739,13 @@ updateBlockForging startupTracer blockType nodeKernel nc = do updateTopologyConfiguration :: Tracer IO (StartupTrace blk) -> NodeConfiguration - -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint PeerAdvertise)] + -> StrictTVar IO [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] -> StrictTVar IO (Map RelayAccessPoint PeerAdvertise) - -> StrictTVar IO UseLedgerAfter + -> StrictTVar IO UseLedgerPeers + -> StrictTVar IO UseBootstrapPeers -> IO () -updateTopologyConfiguration startupTracer nc localRootsVar publicRootsVar useLedgerVar = do +updateTopologyConfiguration startupTracer nc localRootsVar publicRootsVar useLedgerVar + useBootsrapPeersVar = do traceWith startupTracer NetworkConfigUpdate result <- try $ readTopologyFileOrError startupTracer nc case result of @@ -705,14 +753,17 @@ updateTopologyConfiguration startupTracer nc localRootsVar publicRootsVar useLed traceWith startupTracer $ NetworkConfigUpdateError $ pack "Error reading topology configuration file:" <> err - Right nt -> do + Right nt@RealNodeTopology { ntUseLedgerPeers + , ntUseBootstrapPeers + } -> do let (localRoots, publicRoots) = producerAddresses nt traceWith startupTracer - $ NetworkConfig localRoots publicRoots (useLedgerAfterSlot nt) + $ NetworkConfig localRoots publicRoots ntUseLedgerPeers atomically $ do writeTVar localRootsVar localRoots writeTVar publicRootsVar publicRoots - writeTVar useLedgerVar (useLedgerAfterSlot nt) + writeTVar useLedgerVar ntUseLedgerPeers + writeTVar useBootsrapPeersVar ntUseBootstrapPeers #endif -------------------------------------------------------------------------------- @@ -766,11 +817,12 @@ checkVRFFilePermissions (File vrfPrivKey) = do mkP2PArguments :: NodeConfiguration - -> STM IO [(HotValency, WarmValency, Map RelayAccessPoint PeerAdvertise)] + -> STM IO [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] -- ^ non-overlapping local root peers groups; the 'Int' denotes the -- valency of its group. -> STM IO (Map RelayAccessPoint PeerAdvertise) - -> STM IO UseLedgerAfter + -> STM IO UseLedgerPeers + -> STM IO UseBootstrapPeers -> Diffusion.ExtraArguments 'Diffusion.P2P IO mkP2PArguments NodeConfiguration { ncTargetNumberOfRootPeers, @@ -786,12 +838,14 @@ mkP2PArguments NodeConfiguration { } daReadLocalRootPeers daReadPublicRootPeers - daReadUseLedgerAfter = + daReadUseLedgerPeers + daReadUseBootstrapPeers = Diffusion.P2PArguments P2P.ArgumentsExtra { P2P.daPeerSelectionTargets , P2P.daReadLocalRootPeers , P2P.daReadPublicRootPeers - , P2P.daReadUseLedgerAfter + , P2P.daReadUseLedgerPeers + , P2P.daReadUseBootstrapPeers , P2P.daProtocolIdleTimeout = ncProtocolIdleTimeout , P2P.daTimeWaitTimeout = ncTimeWaitTimeout , P2P.daDeadlineChurnInterval = 3300 @@ -833,27 +887,26 @@ producerAddressesNonP2P nt = $ producers' TopologyNonP2P.MockNodeTopology nodeSetup -> partitionEithers - . mapMaybe TopologyNonP2P.remoteAddressToNodeAddress - . concatMap TopologyNonP2P.producers + . concatMap + ( mapMaybe TopologyNonP2P.remoteAddressToNodeAddress + . TopologyNonP2P.producers + ) $ nodeSetup producerAddresses :: NetworkTopology - -> ([(HotValency, WarmValency, Map RelayAccessPoint PeerAdvertise)], Map RelayAccessPoint PeerAdvertise) -producerAddresses nt = - case nt of - RealNodeTopology lrpg prp _ -> - ( map (\lrp -> ( hotValency lrp - , warmValency lrp - , Map.fromList $ rootConfigToRelayAccessPoint - $ localRoots lrp - ) - ) - (groups lrpg) - , foldMap (Map.fromList . rootConfigToRelayAccessPoint . publicRoots) prp - ) - -useLedgerAfterSlot - :: NetworkTopology - -> UseLedgerAfter -useLedgerAfterSlot (RealNodeTopology _ _ (UseLedger ul)) = ul + -> ( [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] + , Map RelayAccessPoint PeerAdvertise) +producerAddresses RealNodeTopology { ntLocalRootPeersGroups + , ntPublicRootPeers + } = + ( map (\lrp -> ( hotValency lrp + , warmValency lrp + , Map.fromList $ map (fmap (, trustable lrp)) + $ rootConfigToRelayAccessPoint + $ localRoots lrp + ) + ) + (groups ntLocalRootPeersGroups) + , 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 24d6389580a..6b2289caaa9 100644 --- a/cardano-node/src/Cardano/Node/Startup.hs +++ b/cardano-node/src/Cardano/Node/Startup.hs @@ -32,7 +32,8 @@ import Ouroboros.Network.Magic (NetworkMagic (..)) import Ouroboros.Network.NodeToClient (LocalAddress (..), LocalSocket, NodeToClientVersion) import Ouroboros.Network.NodeToNode (DiffusionMode (..), NodeToNodeVersion, PeerAdvertise) -import Ouroboros.Network.PeerSelection.LedgerPeers (UseLedgerAfter (..)) +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.Subscription.Dns (DnsSubscriptionTarget (..)) @@ -108,16 +109,13 @@ data StartupTrace blk = -- | Log peer-to-peer network configuration, either on startup or when its -- updated. -- - | NetworkConfig [(HotValency, WarmValency, Map RelayAccessPoint PeerAdvertise)] + | NetworkConfig [(HotValency, WarmValency, Map RelayAccessPoint (PeerAdvertise, PeerTrustable))] (Map RelayAccessPoint PeerAdvertise) - UseLedgerAfter + UseLedgerPeers -- | Warn when 'EnableP2P' is set. | P2PWarning - -- | Warn when 'EnableP2P' is set. - | PeerSharingWarning - -- | Warn when 'ExperimentalProtocolsEnabled' is set and affects -- node-to-node protocol. -- diff --git a/cardano-node/src/Cardano/Node/Tracing/API.hs b/cardano-node/src/Cardano/Node/Tracing/API.hs index e0278a1c45d..b7859b1c26c 100644 --- a/cardano-node/src/Cardano/Node/Tracing/API.hs +++ b/cardano-node/src/Cardano/Node/Tracing/API.hs @@ -24,6 +24,8 @@ import Cardano.Node.Types import Ouroboros.Consensus.Ledger.Inspect (LedgerEvent) import Ouroboros.Consensus.MiniProtocol.ChainSync.Client (TraceChainSyncClientEvent) import Ouroboros.Consensus.Node (NetworkP2PMode) +import Ouroboros.Consensus.Node.GSM +import Ouroboros.Network.Block import Ouroboros.Network.ConnectionId (ConnectionId) import Ouroboros.Network.Magic (NetworkMagic) import Ouroboros.Network.NodeToClient (withIOManager) @@ -46,6 +48,7 @@ initTraceDispatcher :: , LogFormatting (LedgerEvent blk) , LogFormatting (TraceLabelPeer (ConnectionId RemoteAddress) (TraceChainSyncClientEvent blk)) + , LogFormatting (TraceGsmEvent (Tip blk)) ) => NodeConfiguration -> SomeConsensusProtocol diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers.hs index fea7d258fd7..b62ed90e8ac 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers.hs @@ -45,11 +45,13 @@ import qualified Ouroboros.Consensus.Network.NodeToClient as NtC import qualified Ouroboros.Consensus.Network.NodeToNode as NodeToNode import qualified Ouroboros.Consensus.Network.NodeToNode as NtN import Ouroboros.Consensus.Node (NetworkP2PMode (..)) +import Ouroboros.Consensus.Node.GSM import Ouroboros.Consensus.Node.NetworkProtocolVersion import qualified Ouroboros.Consensus.Node.Run as Consensus import qualified Ouroboros.Consensus.Node.Tracers as Consensus import qualified Ouroboros.Consensus.Storage.ChainDB as ChainDB import qualified Ouroboros.Consensus.Storage.LedgerDB as LedgerDB +import Ouroboros.Network.Block import qualified Ouroboros.Network.BlockFetch.ClientState as BlockFetch import Ouroboros.Network.ConnectionId (ConnectionId) import qualified Ouroboros.Network.Diffusion as Diffusion @@ -76,6 +78,8 @@ mkDispatchTracers , LogFormatting (TraceLabelPeer (ConnectionId RemoteAddress) (TraceChainSyncClientEvent blk)) + , LogFormatting (TraceGsmEvent (Tip blk)) + , MetaTrace (TraceGsmEvent (Tip blk)) ) => NodeKernelData blk -> Trace IO FormattedMessage @@ -194,6 +198,8 @@ mkConsensusTracers :: forall blk. , TraceConstraints blk , LogFormatting (TraceLabelPeer (ConnectionId RemoteAddress) (TraceChainSyncClientEvent blk)) + , LogFormatting (TraceGsmEvent (Tip blk)) + , MetaTrace (TraceGsmEvent (Tip blk)) ) => ConfigReflection -> Trace IO FormattedMessage @@ -302,6 +308,11 @@ mkConsensusTracers configReflection trBase trForward mbTrEKG _trDataPoint trConf !consensusStartupErrorTr <- mkCardanoTracer trBase trForward mbTrEKG ["Consensus", "Startup"] + + !consensusGsmTr <- mkCardanoTracer + trBase trForward mbTrEKG + ["Consensus", "GSM"] + configureTracers configReflection trConfig [consensusStartupErrorTr] pure $ Consensus.Tracers @@ -339,6 +350,8 @@ mkConsensusTracers configReflection trBase trForward mbTrEKG _trDataPoint trConf traceWith keepAliveClientTr , Consensus.consensusErrorTracer = Tracer $ traceWith consensusStartupErrorTr . ConsensusStartupException + , Consensus.gsmTracer = Tracer $ + traceWith consensusGsmTr } mkNodeToClientTracers :: forall blk. diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs index b4f4eefc3e2..0e2bfeb48f3 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/Consensus.hs @@ -47,6 +47,7 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Client import Ouroboros.Consensus.MiniProtocol.ChainSync.Server import Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server (TraceLocalTxSubmissionServerEvent (..)) +import Ouroboros.Consensus.Node.GSM import Ouroboros.Consensus.Node.Run (SerialiseNodeToNodeConstraints, estimateBlockSize) import Ouroboros.Consensus.Node.Tracers import qualified Ouroboros.Consensus.Protocol.Ledger.HotKey as HotKey @@ -75,7 +76,6 @@ import qualified Data.Text as Text import Data.Time (DiffTime, NominalDiffTime) import Data.Word (Word32, Word64) - instance (LogFormatting adr, Show adr) => LogFormatting (ConnectionId adr) where forMachine _dtal (ConnectionId local' remote) = mconcat [ "connectionId" .= String (showT local' @@ -1052,7 +1052,7 @@ instance LogFormatting TraceStartLeadershipCheckPlus where mconcat [ "kind" .= String "TraceStartLeadershipCheck" , "slot" .= toJSON (unSlotNo tsSlotNo) , "utxoSize" .= Number (fromIntegral tsUtxoSize) - , "delegMapSize" .= Number (fromIntegral tsUtxoSize) + , "delegMapSize" .= Number (fromIntegral tsDelegMapSize) , "chainDensity" .= Number (fromRational (toRational tsChainDensity)) ] forHuman TraceStartLeadershipCheckPlus {..} = @@ -1734,3 +1734,59 @@ instance MetaTrace (TraceKeepAliveClient remotePeer) where documentFor _ = Just "" allNamespaces = [Namespace [] ["KeepAliveClient"]] + +-------------------------------------------------------------------------------- +-- Gsm Tracer +-------------------------------------------------------------------------------- + +instance ( LogFormatting selection + , Show selection + ) => LogFormatting (TraceGsmEvent selection) where + forMachine dtal (GsmEventEnterCaughtUp i s) = + mconcat + [ "kind" .= String "GsmEventEnterCaughtUp" + , "peerNumber" .= i + , "currentSelection" .= forMachine dtal s + ] + forMachine dtal (GsmEventLeaveCaughtUp s a) = + mconcat + [ "kind" .= String "GsmEventLeaveCaughtUp" + , "currentSelection" .= forMachine dtal s + , "age" .= toJSON (show a) + ] + + forHuman = showT + +instance MetaTrace (TraceGsmEvent selection) where + namespaceFor GsmEventEnterCaughtUp {} = Namespace [] ["EnterCaughtUp"] + namespaceFor GsmEventLeaveCaughtUp {} = Namespace [] ["LeaveCaughtUp"] + + severityFor (Namespace _ ["EnterCaughtUp"]) _ = Just Info + severityFor (Namespace _ ["LeaveCaughtUp"]) _ = Just Info + severityFor (Namespace _ _ ) _ = Nothing + + documentFor (Namespace _ ["EnterCaughtUp"]) = Just + "Node is caught up" + documentFor (Namespace _ ["LeaveCaughtUp"]) = Just + "Node is not caught up" + documentFor (Namespace _ _) = Nothing + + allNamespaces = + [ + Namespace [] ["EnterCaughtUp"] + , Namespace [] ["LeaveCaughtUp"] + ] + +instance ( StandardHash blk + , ConvertRawHash blk + ) => LogFormatting (Tip blk) where + forMachine _dtal TipGenesis = + mconcat [ "kind" .= String "TipGenesis" ] + forMachine _dtal (Tip slotNo hash bNo) = + mconcat [ "kind" .= String "Tip" + , "tipSlotNo" .= toJSON (unSlotNo slotNo) + , "tipHash" .= renderHeaderHash (Proxy @blk) hash + , "tipBlockNo" .= toJSON bNo + ] + + forHuman = showT diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs index 3248c457769..72d69e6a1f6 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs @@ -23,14 +23,13 @@ import Network.Mux (MuxTrace (..), WithMuxBearer (..)) import Network.Mux.Types import Network.TypedProtocol.Codec (AnyMessageAndAgency (..)) -import Cardano.Node.Types (UseLedger (..)) - import qualified Data.List as List import qualified Ouroboros.Network.Diffusion as ND import qualified Ouroboros.Network.NodeToNode as NtN import Ouroboros.Network.PeerSelection.LedgerPeers (NumberOfPeers (..), PoolStake (..), TraceLedgerPeers (..)) import qualified Ouroboros.Network.Protocol.Handshake.Type as HS +import Cardano.Node.Configuration.TopologyP2P () -------------------------------------------------------------------------------- @@ -799,10 +798,10 @@ instance LogFormatting TraceLedgerPeers where mconcat [ "kind" .= String "DisabledLedgerPeers" ] - forMachine _dtal (TraceUseLedgerAfter ula) = + forMachine _dtal (TraceUseLedgerPeers ulp) = mconcat - [ "kind" .= String "UseLedgerAfter" - , "useLedgerAfter" .= UseLedger ula + [ "kind" .= String "UseLedgerPeers" + , "useLedgerPeers" .= ulp ] forMachine _dtal WaitingOnRequest = mconcat @@ -866,8 +865,8 @@ instance MetaTrace TraceLedgerPeers where Namespace [] ["FetchingNewLedgerState"] namespaceFor DisabledLedgerPeers {} = Namespace [] ["DisabledLedgerPeers"] - namespaceFor TraceUseLedgerAfter {} = - Namespace [] ["TraceUseLedgerAfter"] + namespaceFor TraceUseLedgerPeers {} = + Namespace [] ["TraceUseLedgerPeers"] namespaceFor WaitingOnRequest {} = Namespace [] ["WaitingOnRequest"] namespaceFor RequestForPeers {} = diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/P2P.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/P2P.hs index 2c9097fea59..3642e1be4f8 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/P2P.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/P2P.hs @@ -27,8 +27,8 @@ import qualified Ouroboros.Network.InboundGovernor as InboundGovernor import Ouroboros.Network.InboundGovernor.State (InboundGovernorCounters (..)) import qualified Ouroboros.Network.NodeToNode as NtN import Ouroboros.Network.PeerSelection.Governor (DebugPeerSelection (..), - PeerSelectionCounters (..), PeerSelectionState (..), PeerSelectionTargets (..), - TracePeerSelection (..)) + DebugPeerSelectionState (..), PeerSelectionCounters (..), + PeerSelectionState (..), PeerSelectionTargets (..), TracePeerSelection (..)) import Ouroboros.Network.PeerSelection.PeerStateActions (PeerSelectionActionsTrace (..)) import Ouroboros.Network.PeerSelection.RelayAccessPoint (RelayAccessPoint) import Ouroboros.Network.PeerSelection.RootPeersDNS.LocalRootPeers @@ -37,6 +37,8 @@ import Ouroboros.Network.PeerSelection.RootPeersDNS.PublicRootPeers (TracePublicRootPeers (..)) import qualified Ouroboros.Network.PeerSelection.State.EstablishedPeers as EstablishedPeers import qualified Ouroboros.Network.PeerSelection.State.KnownPeers as KnownPeers +import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (..), + WarmValency (..)) import Ouroboros.Network.PeerSelection.Types () import Ouroboros.Network.RethrowPolicy (ErrorCommand (..)) import Ouroboros.Network.Server2 (ServerTrace (..)) @@ -231,7 +233,7 @@ instance LogFormatting (TracePeerSelection SockAddr) where ] forMachine _dtal (TracePublicRootsResults res group dt) = mconcat [ "kind" .= String "PublicRootsResults" - , "result" .= toJSONList (toList res) + , "result" .= toJSON res , "group" .= group , "diffTime" .= dt ] @@ -492,6 +494,45 @@ instance LogFormatting (TracePeerSelection SockAddr) where mconcat [ "kind" .= String "KnownInboundConnection" , "peer" .= toJSON addr , "peerSharing" .= String (pack . show $ sharing) ] + forMachine _dtal (TraceLedgerStateJudgementChanged new) = + mconcat [ "kind" .= String "LedgerStateJudgementChanged" + , "new" .= show new ] + forMachine _dtal TraceOnlyBootstrapPeers = + mconcat [ "kind" .= String "LedgerStateJudgementChanged" ] + forMachine _dtal (TraceUseBootstrapPeersChanged ubp) = + mconcat [ "kind" .= String "UseBootstrapPeersChanged" + , "useBootstrapPeers" .= toJSON ubp ] + forMachine _dtal TraceBootstrapPeersFlagChangedWhilstInSensitiveState = + mconcat [ "kind" .= String "BootstrapPeersFlagChangedWhilstInSensitiveState" + ] + forMachine _dtal (TraceOutboundGovernorCriticalFailure err) = + mconcat [ "kind" .= String "OutboundGovernorCriticalFailure" + , "reason" .= show err + ] + forMachine _dtal (TraceDebugState mtime ds) = + mconcat [ "kind" .= String "DebugState" + , "monotonicTime" .= show mtime + , "targets" .= peerSelectionTargetsToObject (dpssTargets ds) + , "localRootPeers" .= dpssLocalRootPeers ds + , "publicRootPeers" .= dpssPublicRootPeers ds + , "knownPeers" .= KnownPeers.allPeers (dpssKnownPeers ds) + , "establishedPeers" .= dpssEstablishedPeers ds + , "activePeers" .= dpssActivePeers ds + , "publicRootBackoffs" .= dpssPublicRootBackoffs ds + , "publicRootRetryTime" .= dpssPublicRootRetryTime ds + , "bigLedgerPeerBackoffs" .= dpssBigLedgerPeerBackoffs ds + , "bigLedgerPeerRetryTime" .= dpssBigLedgerPeerRetryTime ds + , "inProgressBigLedgerPeersReq" .= dpssInProgressBigLedgerPeersReq ds + , "inProgressPeerShareReqs" .= dpssInProgressPeerShareReqs ds + , "inProgressPromoteCold" .= dpssInProgressPromoteCold ds + , "inProgressPromoteWarm" .= dpssInProgressPromoteWarm ds + , "inProgressDemoteWarm" .= dpssInProgressDemoteWarm ds + , "inProgressDemoteHot" .= dpssInProgressDemoteHot ds + , "inProgressDemoteToCold" .= dpssInProgressDemoteToCold ds + , "upstreamyness" .= dpssUpstreamyness ds + , "fetchynessBlocks" .= dpssFetchynessBlocks ds + ] + forHuman = pack . show instance MetaTrace (TracePeerSelection SockAddr) where @@ -593,6 +634,18 @@ instance MetaTrace (TracePeerSelection SockAddr) where Namespace [] ["ChurnMode"] namespaceFor TraceKnownInboundConnection {} = Namespace [] ["KnownInboundConnection"] + namespaceFor TraceLedgerStateJudgementChanged {} = + Namespace [] ["LedgerStateJudgementChanged"] + namespaceFor TraceOnlyBootstrapPeers {} = + Namespace [] ["OnlyBootstrapPeers"] + namespaceFor TraceUseBootstrapPeersChanged {} = + Namespace [] ["UseBootstrapPeersChanged"] + namespaceFor TraceBootstrapPeersFlagChangedWhilstInSensitiveState = + Namespace [] ["BootstrapPeersFlagChangedWhilstInSensitiveState"] + namespaceFor TraceOutboundGovernorCriticalFailure {} = + Namespace [] ["OutboundGovernorCriticalFailure"] + namespaceFor TraceDebugState {} = + Namespace [] ["DebugState"] severityFor (Namespace [] ["LocalRootPeersChanged"]) _ = Just Notice severityFor (Namespace [] ["TargetsChanged"]) _ = Just Notice @@ -624,6 +677,8 @@ instance MetaTrace (TracePeerSelection SockAddr) where severityFor (Namespace [] ["ChurnWait"]) _ = Just Info severityFor (Namespace [] ["ChurnMode"]) _ = Just Info severityFor (Namespace [] ["KnownInboundConnection"]) _ = Just Info + severityFor (Namespace [] ["OutboundGovernorCriticalFailure"]) _ = Just Error + severityFor (Namespace [] ["DebugState"]) _ = Just Info severityFor _ _ = Nothing documentFor (Namespace [] ["LocalRootPeersChanged"]) = Just "" @@ -678,6 +733,10 @@ instance MetaTrace (TracePeerSelection SockAddr) where documentFor (Namespace [] ["ChurnMode"]) = Just "" documentFor (Namespace [] ["KnownInboundConnection"]) = Just "An inbound connection was added to known set of outbound governor" + documentFor (Namespace [] ["OutboundGovernorCriticalFailure"]) = Just + "Outbound Governor was killed unexpectedly" + documentFor (Namespace [] ["DebugState"]) = Just + "peer selection internal state" documentFor _ = Nothing allNamespaces = [ @@ -711,6 +770,8 @@ instance MetaTrace (TracePeerSelection SockAddr) where , Namespace [] ["ChurnWait"] , Namespace [] ["ChurnMode"] , Namespace [] ["KnownInboundConnection"] + , Namespace [] ["OutboundGovernorCriticalFailure"] + , Namespace [] ["DebugState"] ] -------------------------------------------------------------------------------- @@ -743,12 +804,19 @@ peerSelectionTargetsToObject PeerSelectionTargets { targetNumberOfRootPeers, targetNumberOfKnownPeers, targetNumberOfEstablishedPeers, - targetNumberOfActivePeers } = + targetNumberOfActivePeers, + targetNumberOfKnownBigLedgerPeers, + targetNumberOfEstablishedBigLedgerPeers, + targetNumberOfActiveBigLedgerPeers + } = Object $ mconcat [ "roots" .= targetNumberOfRootPeers , "knownPeers" .= targetNumberOfKnownPeers , "established" .= targetNumberOfEstablishedPeers , "active" .= targetNumberOfActivePeers + , "knownBigLedgerPeers" .= targetNumberOfKnownBigLedgerPeers + , "establishedBigLedgerPeers" .= targetNumberOfEstablishedBigLedgerPeers + , "activeBigLedgerPeers" .= targetNumberOfActiveBigLedgerPeers ] instance MetaTrace (DebugPeerSelection SockAddr) where @@ -802,10 +870,10 @@ instance LogFormatting PeerSelectionCounters where (fromIntegral hotBigLedgerPeers) , IntM "Net.PeerSelection.WarmLocalRoots" - (fromIntegral $ foldl' (\a (b, _) -> a + b) 0 localRoots) + (fromIntegral $ getWarmValency $ foldl' (\a (_, b) -> a + b) 0 localRoots) , IntM "Net.PeerSelection.HotLocalRoots" - (fromIntegral $ foldl' (\a (_, b) -> a + b) 0 localRoots) + (fromIntegral $ getHotValency $ foldl' (\a (b, _) -> a + b) 0 localRoots) ] instance MetaTrace PeerSelectionCounters where diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/Startup.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/Startup.hs index b2f01644a65..341ab3dac10 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/Startup.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/Startup.hs @@ -25,7 +25,6 @@ import Cardano.Node.Configuration.POM (NodeConfiguration, ncProtocol) import Cardano.Node.Configuration.Socket import Cardano.Node.Protocol (SomeConsensusProtocol (..)) import Cardano.Node.Startup -import Cardano.Node.Types (UseLedger (..)) import Cardano.Slotting.Slot (EpochSize (..)) import qualified Ouroboros.Consensus.BlockchainTime.WallClock.Types as WCT import Ouroboros.Consensus.Byron.Ledger.Conversions (fromByronEpochSlots, @@ -41,7 +40,8 @@ import Ouroboros.Consensus.Node.ProtocolInfo (ProtocolInfo (..)) import Ouroboros.Consensus.Shelley.Ledger.Ledger (shelleyLedgerGenesis) import Ouroboros.Network.NodeToClient (LocalAddress (..), LocalSocket (..)) import Ouroboros.Network.NodeToNode (DiffusionMode (..)) -import Ouroboros.Network.PeerSelection.LedgerPeers (UseLedgerAfter (..)) +import Ouroboros.Network.PeerSelection.LedgerPeers.Type (AfterSlot (..), + UseLedgerPeers (..)) import Prelude @@ -220,11 +220,11 @@ instance ( Show (BlockNodeToNodeVersion blk) forMachine _dtal (NetworkConfigUpdateError err) = mconcat [ "kind" .= String "NetworkConfigUpdateError" , "error" .= String err ] - forMachine _dtal (NetworkConfig localRoots publicRoots useLedgerAfter) = + forMachine _dtal (NetworkConfig localRoots publicRoots useLedgerPeers) = mconcat [ "kind" .= String "NetworkConfig" , "localRoots" .= toJSON localRoots , "publicRoots" .= toJSON publicRoots - , "useLedgerAfter" .= UseLedger useLedgerAfter + , "useLedgerAfter" .= useLedgerPeers ] forMachine _dtal NetworkConfigLegacy = mconcat [ "kind" .= String "NetworkConfigLegacy" @@ -233,9 +233,6 @@ instance ( Show (BlockNodeToNodeVersion blk) forMachine _dtal P2PWarning = mconcat [ "kind" .= String "P2PWarning" , "message" .= String p2pWarningMessage ] - forMachine _dtal PeerSharingWarning = - mconcat [ "kind" .= String "PeerSharingWarning" - , "message" .= String peerSharingWarningMessage ] forMachine _ver (WarningDevelopmentNodeToNodeVersions ntnVersions) = mconcat [ "kind" .= String "WarningDevelopmentNodeToNodeVersions" , "message" .= String "enabled development network protocols" @@ -308,8 +305,6 @@ instance MetaTrace (StartupTrace blk) where Namespace [] ["NetworkConfigLegacy"] namespaceFor P2PWarning {} = Namespace [] ["P2PWarning"] - namespaceFor PeerSharingWarning {} = - Namespace [] ["PeerSharingWarning"] namespaceFor WarningDevelopmentNodeToNodeVersions {} = Namespace [] ["WarningDevelopmentNodeToNodeVersions"] namespaceFor WarningDevelopmentNodeToClientVersions {} = @@ -507,7 +502,7 @@ ppStartupInfoTrace NetworkConfigUpdate = "Performing topology configuration upda ppStartupInfoTrace NetworkConfigUpdateUnsupported = "Network topology reconfiguration is not supported in non-p2p mode" ppStartupInfoTrace (NetworkConfigUpdateError err) = err -ppStartupInfoTrace (NetworkConfig localRoots publicRoots useLedgerAfter) = +ppStartupInfoTrace (NetworkConfig localRoots publicRoots useLedgerPeers) = pack $ intercalate "\n" [ "\nLocal Root Groups:" @@ -515,17 +510,19 @@ ppStartupInfoTrace (NetworkConfig localRoots publicRoots useLedgerAfter) = localRoots) , "Public Roots:" , " " ++ intercalate "\n " (map show $ Map.assocs publicRoots) - , case useLedgerAfter of - UseLedgerAfter slotNo -> "Get root peers from the ledger after slot " - ++ show (unSlotNo slotNo) - DontUseLedger -> "Don't use ledger to get root peers." + , case useLedgerPeers of + DontUseLedgerPeers -> + "Don't use ledger to get root peers." + UseLedgerPeers (After slotNo) -> + "Get root peers from the ledger after slot " + ++ show (unSlotNo slotNo) + UseLedgerPeers Always -> + "Use ledger peers in any slot." ] ppStartupInfoTrace NetworkConfigLegacy = p2pNetworkConfigLegacyMessage ppStartupInfoTrace P2PWarning = p2pWarningMessage -ppStartupInfoTrace PeerSharingWarning = peerSharingWarningMessage - ppStartupInfoTrace (WarningDevelopmentNodeToNodeVersions ntnVersions) = "enabled development node-to-node versions: " <> showT ntnVersions @@ -573,16 +570,6 @@ p2pNetworkConfigLegacyMessage = , "Note that the legacy p2p format will be removed in `1.37` release." ] -peerSharingWarningMessage :: Text -peerSharingWarningMessage = - "Warning: Enabling PeerSharing can expose you to significant risks, including " - <> "the possibility of eclipse attacks. By turning on this feature, you may " - <> "inadvertently give malicious actors the ability to isolate your device, " - <> "manipulate your view of the network, and compromise your data integrity. " - <> "It is crucial to carefully consider the potential consequences before " - <> "enabling PeerSharing. If you are unsure, it is strongly advised to consult " - <> "a security expert for guidance. Proceed with caution." - -- | Pretty print 'SocketOrSocketInfo'. -- ppSocketInfo :: Show sock diff --git a/cardano-node/src/Cardano/Node/Types.hs b/cardano-node/src/Cardano/Node/Types.hs index a2cd1693a6e..a6a2b20a7c5 100644 --- a/cardano-node/src/Cardano/Node/Types.hs +++ b/cardano-node/src/Cardano/Node/Types.hs @@ -17,7 +17,6 @@ module Cardano.Node.Types , MaxConcurrencyBulkSync(..) , MaxConcurrencyDeadline(..) -- * Networking - , UseLedger(..) , TopologyFile(..) , NodeDiffusionMode (..) -- * Consensus protocol configuration @@ -37,10 +36,8 @@ import Cardano.Crypto (RequiresNetworkMagic (..)) import qualified Cardano.Crypto.Hash as Crypto import Cardano.Node.Configuration.Socket (SocketConfig (..)) import Ouroboros.Network.NodeToNode (DiffusionMode (..)) -import Ouroboros.Network.PeerSelection.LedgerPeers (UseLedgerAfter (..)) import Control.Exception -import Control.Monad (MonadPlus (..)) import Data.Aeson import Data.ByteString (ByteString) import Data.Monoid (Last) @@ -283,25 +280,6 @@ data NodeHardForkProtocolConfiguration = } deriving (Eq, Show) --- | A newtype wrapper around 'UseLedgerAfter' which provides 'FromJSON' and --- 'ToJSON' instances. --- --- 'UseLedgerAfter' is used to configure from which slot a p2p node can use on --- chain root peers. --- -newtype UseLedger = UseLedger UseLedgerAfter deriving (Eq, Show) - -instance FromJSON UseLedger where - parseJSON (Data.Aeson.Number n) = - if n >= 0 then return $ UseLedger $ UseLedgerAfter $ SlotNo $ floor n - else return $ UseLedger DontUseLedger - parseJSON _ = mzero - -instance ToJSON UseLedger where - toJSON (UseLedger (UseLedgerAfter (SlotNo n))) = Number $ fromIntegral n - toJSON (UseLedger DontUseLedger) = Number (-1) - - newtype TopologyFile = TopologyFile { unTopology :: FilePath } deriving newtype (Show, Eq) diff --git a/cardano-node/src/Cardano/Tracing/Config.hs b/cardano-node/src/Cardano/Tracing/Config.hs index 814ed210ceb..fb93f72115a 100644 --- a/cardano-node/src/Cardano/Tracing/Config.hs +++ b/cardano-node/src/Cardano/Tracing/Config.hs @@ -173,6 +173,7 @@ type TraceTxInbound = ("TraceTxInbound" :: Symbol) type TraceTxOutbound = ("TraceTxOutbound" :: Symbol) type TraceTxSubmissionProtocol = ("TraceTxSubmissionProtocol" :: Symbol) type TraceTxSubmission2Protocol = ("TraceTxSubmission2Protocol" :: Symbol) +type TraceGsm = ("TraceGsm" :: Symbol) newtype OnOff (name :: Symbol) = OnOff { isOn :: Bool } deriving (Eq, Show) @@ -241,6 +242,7 @@ data TraceSelection , traceTxOutbound :: OnOff TraceTxOutbound , traceTxSubmissionProtocol :: OnOff TraceTxSubmissionProtocol , traceTxSubmission2Protocol :: OnOff TraceTxSubmission2Protocol + , traceGsm :: OnOff TraceGsm } deriving (Eq, Show) @@ -303,6 +305,7 @@ data PartialTraceSelection , pTraceTxOutbound :: Last (OnOff TraceTxOutbound) , pTraceTxSubmissionProtocol :: Last (OnOff TraceTxSubmissionProtocol) , pTraceTxSubmission2Protocol :: Last (OnOff TraceTxSubmission2Protocol) + , pTraceGsm :: Last (OnOff TraceGsm) } deriving (Eq, Generic, Show) @@ -366,6 +369,7 @@ instance FromJSON PartialTraceSelection where <*> parseTracer (Proxy @TraceTxOutbound) v <*> parseTracer (Proxy @TraceTxSubmissionProtocol) v <*> parseTracer (Proxy @TraceTxSubmission2Protocol) v + <*> parseTracer (Proxy @TraceGsm) v defaultPartialTraceConfiguration :: PartialTraceSelection @@ -426,6 +430,7 @@ defaultPartialTraceConfiguration = , pTraceTxOutbound = pure $ OnOff False , pTraceTxSubmissionProtocol = pure $ OnOff False , pTraceTxSubmission2Protocol = pure $ OnOff False + , pTraceGsm = pure $ OnOff True } @@ -488,6 +493,7 @@ partialTraceSelectionToEither (Last (Just (PartialTraceDispatcher pTraceSelectio traceTxOutbound <- proxyLastToEither (Proxy @TraceTxOutbound) pTraceTxOutbound traceTxSubmissionProtocol <- proxyLastToEither (Proxy @TraceTxSubmissionProtocol) pTraceTxSubmissionProtocol traceTxSubmission2Protocol <- proxyLastToEither (Proxy @TraceTxSubmission2Protocol) pTraceTxSubmission2Protocol + traceGsm <- proxyLastToEither (Proxy @TraceGsm) pTraceGsm Right $ TraceDispatcher $ TraceSelection { traceVerbosity = traceVerbosity , traceAcceptPolicy = traceAcceptPolicy @@ -543,6 +549,7 @@ partialTraceSelectionToEither (Last (Just (PartialTraceDispatcher pTraceSelectio , traceTxOutbound = traceTxOutbound , traceTxSubmissionProtocol = traceTxSubmissionProtocol , traceTxSubmission2Protocol = traceTxSubmission2Protocol + , traceGsm = traceGsm } partialTraceSelectionToEither (Last (Just (PartialTracingOnLegacy pTraceSelection))) = do @@ -602,6 +609,7 @@ partialTraceSelectionToEither (Last (Just (PartialTracingOnLegacy pTraceSelectio traceTxOutbound <- proxyLastToEither (Proxy @TraceTxOutbound) pTraceTxOutbound traceTxSubmissionProtocol <- proxyLastToEither (Proxy @TraceTxSubmissionProtocol) pTraceTxSubmissionProtocol traceTxSubmission2Protocol <- proxyLastToEither (Proxy @TraceTxSubmission2Protocol) pTraceTxSubmission2Protocol + traceGsm <- proxyLastToEither (Proxy @TraceGsm) pTraceGsm Right $ TracingOnLegacy $ TraceSelection { traceVerbosity = traceVerbosity , traceAcceptPolicy = traceAcceptPolicy @@ -657,6 +665,7 @@ partialTraceSelectionToEither (Last (Just (PartialTracingOnLegacy pTraceSelectio , traceTxOutbound = traceTxOutbound , traceTxSubmissionProtocol = traceTxSubmissionProtocol , traceTxSubmission2Protocol = traceTxSubmission2Protocol + , traceGsm = traceGsm } proxyLastToEither :: KnownSymbol name => Proxy name -> Last (OnOff name) -> Either Text (OnOff name) diff --git a/cardano-node/src/Cardano/Tracing/OrphanInstances/Consensus.hs b/cardano-node/src/Cardano/Tracing/OrphanInstances/Consensus.hs index 1f0d414422e..ef2c3d373b4 100644 --- a/cardano-node/src/Cardano/Tracing/OrphanInstances/Consensus.hs +++ b/cardano-node/src/Cardano/Tracing/OrphanInstances/Consensus.hs @@ -48,6 +48,7 @@ import Ouroboros.Consensus.MiniProtocol.ChainSync.Server (BlockingType TraceChainSyncServerEvent (..)) import Ouroboros.Consensus.MiniProtocol.LocalTxSubmission.Server (TraceLocalTxSubmissionServerEvent (..)) +import Ouroboros.Consensus.Node.GSM import Ouroboros.Consensus.Node.Run (RunNode, estimateBlockSize) import Ouroboros.Consensus.Node.Tracers (TraceForgeEvent (..)) import qualified Ouroboros.Consensus.Node.Tracers as Consensus @@ -1509,3 +1510,33 @@ instance ( RunNode blk instance ToObject (TraceLocalTxSubmissionServerEvent blk) where toObject _verb _ = mconcat [ "kind" .= String "TraceLocalTxSubmissionServerEvent" ] + +instance HasPrivacyAnnotation (TraceGsmEvent selection) where +instance HasSeverityAnnotation (TraceGsmEvent selection) where + getSeverityAnnotation _ = Info +instance ToObject selection => Transformable Text IO (TraceGsmEvent selection) where + trTransformer = trStructured + +instance ToObject selection => ToObject (TraceGsmEvent selection) where + toObject verb (GsmEventEnterCaughtUp i s) = + mconcat + [ "kind" .= String "GsmEventEnterCaughtUp" + , "peerNumber" .= toJSON i + , "currentSelection" .= toObject verb s + ] + toObject verb (GsmEventLeaveCaughtUp s a) = + mconcat + [ "kind" .= String "GsmEventLeaveCaughtUp" + , "currentSelection" .= toObject verb s + , "age" .= toJSON (show a) + ] + +instance ConvertRawHash blk => ToObject (Tip blk) where + toObject _verb TipGenesis = + mconcat [ "kind" .= String "TipGenesis" ] + toObject _verb (Tip slotNo hash bNo) = + mconcat [ "kind" .= String "Tip" + , "tipSlotNo" .= toJSON (unSlotNo slotNo) + , "tipHash" .= renderHeaderHash (Proxy @blk) hash + , "tipBlockNo" .= toJSON bNo + ] diff --git a/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs b/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs index 6b1f4fb4855..f777e0a36ad 100644 --- a/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs +++ b/cardano-node/src/Cardano/Tracing/OrphanInstances/Network.hs @@ -17,7 +17,6 @@ module Cardano.Tracing.OrphanInstances.Network () where import Cardano.Node.Queries (ConvertTxId) -import Cardano.Node.Types (UseLedger (..)) import Cardano.Tracing.OrphanInstances.Common import Cardano.Tracing.Render import Ouroboros.Consensus.Block (ConvertRawHash (..), Header, getHeader) @@ -53,18 +52,22 @@ import qualified Ouroboros.Network.NodeToClient as NtC import Ouroboros.Network.NodeToNode (ErrorPolicyTrace (..), NodeToNodeVersion (..), NodeToNodeVersionData (..), RemoteAddress, TraceSendRecv (..), WithAddr (..)) import qualified Ouroboros.Network.NodeToNode as NtN +import Ouroboros.Network.PeerSelection.Bootstrap import Ouroboros.Network.PeerSelection.Governor (DebugPeerSelection (..), - PeerSelectionCounters (..), PeerSelectionState (..), PeerSelectionTargets (..), - TracePeerSelection (..)) + DebugPeerSelectionState (..), PeerSelectionCounters (..), + PeerSelectionState (..), PeerSelectionTargets (..), TracePeerSelection (..)) import Ouroboros.Network.PeerSelection.LedgerPeers -import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing) +import Ouroboros.Network.PeerSelection.PeerSharing (PeerSharing (..)) import Ouroboros.Network.PeerSelection.PeerStateActions (PeerSelectionActionsTrace (..)) -import Ouroboros.Network.PeerSelection.RelayAccessPoint +import Ouroboros.Network.PeerSelection.PeerTrustable +import Ouroboros.Network.PeerSelection.PublicRootPeers (PublicRootPeers) +import qualified Ouroboros.Network.PeerSelection.PublicRootPeers as PublicRootPeers import Ouroboros.Network.PeerSelection.RootPeersDNS.LocalRootPeers (TraceLocalRootPeers (..)) import Ouroboros.Network.PeerSelection.RootPeersDNS.PublicRootPeers (TracePublicRootPeers (..)) import qualified Ouroboros.Network.PeerSelection.State.EstablishedPeers as EstablishedPeers +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 (..)) @@ -115,7 +118,6 @@ import Network.Mux (MiniProtocolNum (..), MuxTrace (..), WithMuxBearer import Network.Socket (SockAddr (..)) import Network.TypedProtocol.Codec (AnyMessageAndAgency (..)) import Network.TypedProtocol.Core (PeerHasAgency (..)) -import qualified Text.Read as Text {- HLINT ignore "Use record patterns" -} @@ -223,7 +225,7 @@ instance HasSeverityAnnotation TraceLedgerPeers where PickedBigLedgerPeers {} -> Info FetchingNewLedgerState {} -> Info DisabledLedgerPeers {} -> Info - TraceUseLedgerAfter {} -> Info + TraceUseLedgerPeers {} -> Info WaitingOnRequest {} -> Debug RequestForPeers {} -> Debug ReusingLedgerState {} -> Debug @@ -461,6 +463,16 @@ instance HasSeverityAnnotation (TracePeerSelection addr) where TraceDemoteBigLedgerPeersAsynchronous {} -> Warning + TraceUseBootstrapPeersChanged {} -> Info + TraceBootstrapPeersFlagChangedWhilstInSensitiveState -> Info + + TraceLedgerStateJudgementChanged {} -> Notice + TraceOnlyBootstrapPeers {} -> Notice + + TraceOutboundGovernorCriticalFailure {} -> Error + + TraceDebugState {} -> Info + instance HasPrivacyAnnotation (DebugPeerSelection addr) instance HasSeverityAnnotation (DebugPeerSelection addr) where getSeverityAnnotation _ = Debug @@ -1343,10 +1355,10 @@ instance ToObject TraceLedgerPeers where mconcat [ "kind" .= String "DisabledLedgerPeers" ] - toObject _verb (TraceUseLedgerAfter ula) = + toObject _verb (TraceUseLedgerPeers ulp) = mconcat - [ "kind" .= String "UseLedgerAfter" - , "useLedgerAfter" .= UseLedger ula + [ "kind" .= String "UseLedgerPeers" + , "useLedgerPeers" .= ulp ] toObject _verb WaitingOnRequest = mconcat @@ -1517,6 +1529,22 @@ instance ToObject TracePublicRootPeers where , "reason" .= show d ] +instance ToJSON KnownPeerInfo where + toJSON (KnownPeerInfo + nKnownPeerFailCount + nKnownPeerTepid + nKnownPeerSharing + nKnownPeerAdvertise + nKnownSuccessfulConnection + ) = + Aeson.object [ "kind" .= String "KnownPeerInfo" + , "failCount" .= nKnownPeerFailCount + , "tepid" .= nKnownPeerTepid + , "peerSharing" .= nKnownPeerSharing + , "peerAdvertise" .= nKnownPeerAdvertise + , "successfulConnection" .= nKnownSuccessfulConnection + ] + instance ToJSON PeerStatus where toJSON = String . pack . show @@ -1548,6 +1576,15 @@ instance ToJSON PeerSelectionTargets where , "targetActiveBigLedgerPeers" .= nActiveBigLedgerPeers ] +instance ToJSON peerAddr => ToJSON (PublicRootPeers peerAddr) where + toJSON prp = + Aeson.object [ "kind" .= String "PublicRootPeers" + , "bootstrapPeers" .= PublicRootPeers.getBootstrapPeers prp + , "ledgerPeers" .= PublicRootPeers.getLedgerPeers prp + , "bigLedgerPeers" .= PublicRootPeers.getBigLedgerPeers prp + , "publicConfigPeers" .= Map.keysSet (PublicRootPeers.getPublicConfigPeers prp) + ] + instance ToJSON RepromoteDelay where toJSON = toJSON . repromoteDelay @@ -1573,7 +1610,7 @@ instance ToObject (TracePeerSelection SockAddr) where ] toObject _verb (TracePublicRootsResults res group dt) = mconcat [ "kind" .= String "PublicRootsResults" - , "result" .= Aeson.toJSONList (toList res) + , "result" .= toJSON res , "group" .= group , "diffTime" .= dt ] @@ -1834,6 +1871,44 @@ instance ToObject (TracePeerSelection SockAddr) where mconcat [ "kind" .= String "KnownInboundConnection" , "peer" .= show addr , "peerSharing" .= show sharing ] + toObject _verb (TraceLedgerStateJudgementChanged new) = + mconcat [ "kind" .= String "LedgerStateJudgementChanged" + , "new" .= show new ] + toObject _verb TraceOnlyBootstrapPeers = + mconcat [ "kind" .= String "OnlyBootstrapPeers" ] + toObject _verb (TraceUseBootstrapPeersChanged ubp) = + mconcat [ "kind" .= String "UseBootstrapPeersChanged" + , "bootstrapPeers" .= show ubp ] + toObject _verb TraceBootstrapPeersFlagChangedWhilstInSensitiveState = + mconcat [ "kind" .= String "BootstrapPeersFlagChangedWhilstInSensitiveState" + ] + toObject _verb (TraceOutboundGovernorCriticalFailure err) = + mconcat [ "kind" .= String "OutboundGovernorCriticalFailure" + , "reason" .= show err + ] + toObject _verb (TraceDebugState mtime ds) = + mconcat [ "kind" .= String "DebugState" + , "monotonicTime" .= mtime + , "targets" .= peerSelectionTargetsToObject (dpssTargets ds) + , "localRootPeers" .= dpssLocalRootPeers ds + , "publicRootPeers" .= dpssPublicRootPeers ds + , "knownPeers" .= KnownPeers.allPeers (dpssKnownPeers ds) + , "establishedPeers" .= dpssEstablishedPeers ds + , "activePeers" .= dpssActivePeers ds + , "publicRootBackoffs" .= dpssPublicRootBackoffs ds + , "publicRootRetryTime" .= dpssPublicRootRetryTime ds + , "bigLedgerPeerBackoffs" .= dpssBigLedgerPeerBackoffs ds + , "bigLedgerPeerRetryTime" .= dpssBigLedgerPeerRetryTime ds + , "inProgressBigLedgerPeersReq" .= dpssInProgressBigLedgerPeersReq ds + , "inProgressPeerShareReqs" .= dpssInProgressPeerShareReqs ds + , "inProgressPromoteCold" .= dpssInProgressPromoteCold ds + , "inProgressPromoteWarm" .= dpssInProgressPromoteWarm ds + , "inProgressDemoteWarm" .= dpssInProgressDemoteWarm ds + , "inProgressDemoteHot" .= dpssInProgressDemoteHot ds + , "inProgressDemoteToCold" .= dpssInProgressDemoteToCold ds + , "upstreamyness" .= dpssUpstreamyness ds + , "fetchynessBlocks" .= dpssFetchynessBlocks ds + ] -- Connection manager abstract state. For explanation of each state see -- @@ -1879,17 +1954,24 @@ peerSelectionTargetsToObject PeerSelectionTargets { targetNumberOfRootPeers, targetNumberOfKnownPeers, targetNumberOfEstablishedPeers, - targetNumberOfActivePeers } = + targetNumberOfActivePeers, + targetNumberOfKnownBigLedgerPeers, + targetNumberOfEstablishedBigLedgerPeers, + targetNumberOfActiveBigLedgerPeers + } = Object $ mconcat [ "roots" .= targetNumberOfRootPeers , "knownPeers" .= targetNumberOfKnownPeers , "established" .= targetNumberOfEstablishedPeers , "active" .= targetNumberOfActivePeers + , "knownBigLedgerPeers" .= targetNumberOfKnownBigLedgerPeers + , "establishedBigLedgerPeers" .= targetNumberOfEstablishedBigLedgerPeers + , "activeBigLedgerPeers" .= targetNumberOfActiveBigLedgerPeers ] instance ToObject (DebugPeerSelection SockAddr) where toObject verb (TraceGovernorState blockedAt wakeupAfter - PeerSelectionState { targets, knownPeers, establishedPeers, activePeers, bigLedgerPeers }) + PeerSelectionState { targets, knownPeers, establishedPeers, activePeers, publicRootPeers }) | verb <= NormalVerbosity = mconcat [ "kind" .= String "DebugPeerSelection" , "blockedAt" .= String (pack $ show blockedAt) @@ -1907,6 +1989,8 @@ instance ToObject (DebugPeerSelection SockAddr) where ]) ] + where + bigLedgerPeers = PublicRootPeers.getBigLedgerPeers publicRootPeers toObject _ (TraceGovernorState blockedAt wakeupAfter ev) = mconcat [ "kind" .= String "DebugPeerSelection" , "blockedAt" .= String (pack $ show blockedAt) @@ -2326,6 +2410,8 @@ instance ToObject NtN.RemoteAddress where toObject _verb (SockAddrUnix path) = mconcat [ "path" .= show path ] +instance ToJSON Time where + toJSON = String . pack . show instance ToObject NtN.RemoteConnectionId where toObject verb (NtN.ConnectionId l r) = @@ -2438,11 +2524,50 @@ instance ToJSON addr ] instance FromJSON PeerSharing where - parseJSON = Aeson.withText "PeerSharing" $ \t -> - case Text.readMaybe (Text.unpack t) of - Nothing -> fail ("PeerSharing.parseJSON: could not parse value: " - ++ Text.unpack t) - Just ps -> return ps + parseJSON = Aeson.withBool "PeerSharing" $ \b -> + pure $ if b then PeerSharingEnabled + else PeerSharingDisabled instance ToJSON PeerSharing where - toJSON = String . Text.pack . show + toJSON PeerSharingEnabled = Bool True + toJSON PeerSharingDisabled = Bool False + +instance FromJSON UseLedgerPeers where + parseJSON (Number slot) = return $ + case compare slot 0 of + GT -> UseLedgerPeers (After (SlotNo (floor slot))) + EQ -> UseLedgerPeers Always + LT -> DontUseLedgerPeers + parseJSON invalid = fail $ "Parsing of slot number failed due to type mismatch. " + <> "Encountered: " <> show invalid + +instance ToJSON LedgerStateJudgement where + toJSON YoungEnough = String "YoungEnough" + toJSON TooOld = String "TooOld" + +instance FromJSON LedgerStateJudgement where + parseJSON (String "YoungEnough") = pure YoungEnough + parseJSON (String "TooOld") = pure TooOld + parseJSON _ = fail "Invalid JSON for LedgerStateJudgement" + +instance ToJSON UseLedgerPeers where + toJSON DontUseLedgerPeers = Number (-1) + toJSON (UseLedgerPeers Always) = Number 0 + toJSON (UseLedgerPeers (After (SlotNo s))) = Number (fromIntegral s) + +instance ToJSON UseBootstrapPeers where + toJSON DontUseBootstrapPeers = Null + toJSON (UseBootstrapPeers dps) = toJSON dps + +instance FromJSON UseBootstrapPeers where + parseJSON Null = pure DontUseBootstrapPeers + parseJSON v = UseBootstrapPeers <$> parseJSON v + +instance FromJSON PeerTrustable where + parseJSON = Aeson.withBool "PeerTrustable" $ \b -> + pure $ if b then IsTrustable + else IsNotTrustable + +instance ToJSON PeerTrustable where + toJSON IsTrustable = Bool True + toJSON IsNotTrustable = Bool False diff --git a/cardano-node/src/Cardano/Tracing/Tracers.hs b/cardano-node/src/Cardano/Tracing/Tracers.hs index 61ff4e8302c..497e4879d0e 100644 --- a/cardano-node/src/Cardano/Tracing/Tracers.hs +++ b/cardano-node/src/Cardano/Tracing/Tracers.hs @@ -461,6 +461,7 @@ mkTracers _ _ _ _ _ enableP2P = , Consensus.forgeTracer = nullTracer , Consensus.blockchainTimeTracer = nullTracer , Consensus.consensusErrorTracer = nullTracer + , Consensus.gsmTracer = nullTracer } , nodeToClientTracers = NodeToClient.Tracers { NodeToClient.tChainSyncTracer = nullTracer @@ -739,6 +740,7 @@ mkConsensusTracers mbEKGDirect trSel verb tr nodeKern fStats = do traceWith (toLogObject tr) (readableTraceBlockchainTimeEvent ev) , Consensus.consensusErrorTracer = Tracer $ \err -> traceWith (toLogObject tr) (ConsensusStartupException err) + , Consensus.gsmTracer = tracerOnOff (traceGsm trSel) verb "GSM" tr } where mkForgeTracers :: IO ForgeTracers diff --git a/cardano-node/test/Test/Cardano/Node/Gen.hs b/cardano-node/test/Test/Cardano/Node/Gen.hs index 855d9b79aa9..3d68e505c1b 100644 --- a/cardano-node/test/Test/Cardano/Node/Gen.hs +++ b/cardano-node/test/Test/Cardano/Node/Gen.hs @@ -1,6 +1,7 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# OPTIONS_GHC -Wno-unticked-promoted-constructors #-} @@ -25,9 +26,11 @@ import Cardano.Node.Configuration.NodeAddress (NodeAddress' (..), Node import Cardano.Node.Configuration.TopologyP2P (LocalRootPeersGroup (..), LocalRootPeersGroups (..), NetworkTopology (..), NodeSetup (..), PeerAdvertise (..), PublicRootPeers (..), RootConfig (..)) -import Cardano.Node.Types (UseLedger (..)) import Cardano.Slotting.Slot (SlotNo (..)) -import Ouroboros.Network.PeerSelection.LedgerPeers (UseLedgerAfter (..)) +import Ouroboros.Network.PeerSelection.Bootstrap +import Ouroboros.Network.PeerSelection.LedgerPeers.Type (AfterSlot (..), + UseLedgerPeers (..)) +import Ouroboros.Network.PeerSelection.PeerTrustable import Ouroboros.Network.PeerSelection.RelayAccessPoint (DomainAccessPoint (..), RelayAccessPoint (..)) import Ouroboros.Network.PeerSelection.State.LocalRootPeers (HotValency (..), @@ -51,7 +54,8 @@ genNetworkTopology = Gen.choice [ RealNodeTopology <$> genLocalRootPeersGroups <*> Gen.list (Range.linear 0 10) genPublicRootPeers - <*> genUseLedger + <*> genUseLedgerPeers + <*> genUseBootstrapPeers ] -- | Generate valid encodings of p2p topology files @@ -146,7 +150,7 @@ genNodeSetup = <*> Gen.maybe (genNodeAddress' genNodeHostIPv4Address) <*> Gen.maybe (genNodeAddress' genNodeHostIPv6Address) <*> Gen.list (Range.linear 0 6) genRootConfig - <*> genUseLedger + <*> genUseLedgerPeers genDomainAddress :: Gen DomainAccessPoint genDomainAddress = @@ -177,7 +181,7 @@ genLocalRootPeersGroup = do ra <- genRootConfig hval <- Gen.int (Range.linear 0 (length (rootAccessPoints ra))) wval <- WarmValency <$> Gen.int (Range.linear 0 hval) - return (LocalRootPeersGroup ra (HotValency hval) wval) + LocalRootPeersGroup ra (HotValency hval) wval <$> genPeerTrustable genLocalRootPeersGroups :: Gen LocalRootPeersGroups genLocalRootPeersGroups = @@ -189,8 +193,18 @@ genPublicRootPeers = PublicRootPeers <$> genRootConfig -genUseLedger :: Gen UseLedger -genUseLedger = do +genUseLedgerPeers :: Gen UseLedgerPeers +genUseLedgerPeers = do slot <- Gen.integral (Range.linear (-1) 10) :: Gen Integer - if slot >= 0 then return $ UseLedger $ UseLedgerAfter $ SlotNo $ fromIntegral slot - else return $ UseLedger DontUseLedger + return $ case compare slot 0 of + GT -> UseLedgerPeers $ After $ SlotNo $ fromIntegral slot + EQ -> UseLedgerPeers Always + LT -> DontUseLedgerPeers + +genUseBootstrapPeers :: Gen UseBootstrapPeers +genUseBootstrapPeers = do + domains <- Gen.list (Range.linear 0 6) genRelayAddress + Gen.element [ DontUseBootstrapPeers , UseBootstrapPeers domains ] + +genPeerTrustable :: Gen PeerTrustable +genPeerTrustable = Gen.element [ IsNotTrustable, IsTrustable ] diff --git a/cardano-node/test/Test/Cardano/Node/Json.hs b/cardano-node/test/Test/Cardano/Node/Json.hs index 7ef2d4c67a6..2c6b8de7ce8 100644 --- a/cardano-node/test/Test/Cardano/Node/Json.hs +++ b/cardano-node/test/Test/Cardano/Node/Json.hs @@ -14,6 +14,7 @@ import Test.Cardano.Node.Gen import Hedgehog (Property, discover) import qualified Hedgehog + prop_roundtrip_NodeIPv4Address_JSON :: Property prop_roundtrip_NodeIPv4Address_JSON = Hedgehog.property $ do diff --git a/cardano-node/test/Test/Cardano/Node/POM.hs b/cardano-node/test/Test/Cardano/Node/POM.hs index 31541377560..20d8c99119f 100644 --- a/cardano-node/test/Test/Cardano/Node/POM.hs +++ b/cardano-node/test/Test/Cardano/Node/POM.hs @@ -13,7 +13,8 @@ import Cardano.Node.Types import Cardano.Tracing.Config (PartialTraceOptions (..), defaultPartialTraceConfiguration, partialTraceSelectionToEither) import qualified Ouroboros.Consensus.Node as Consensus (NetworkP2PMode (..)) -import Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy (SnapshotInterval (..)) +import Ouroboros.Consensus.Storage.LedgerDB.DiskPolicy (NumOfDiskSnapshots (..), + SnapshotInterval (..)) import Ouroboros.Network.Block (SlotNo (..)) import Ouroboros.Network.NodeToNode (AcceptedConnectionsLimit (..), DiffusionMode (InitiatorAndResponderDiffusionMode)) @@ -115,6 +116,7 @@ testPartialYamlConfig = , pncShutdownConfig = Last Nothing , pncStartAsNonProducingNode = Last $ Just False , pncDiffusionMode = Last Nothing + , pncNumOfDiskSnapshots = Last Nothing , pncSnapshotInterval = mempty , pncExperimentalProtocolsEnabled = Last Nothing , pncMaxConcurrencyBulkSync = Last Nothing @@ -156,6 +158,7 @@ testPartialCliConfig = , pncTopologyFile = mempty , pncDatabaseFile = mempty , pncDiffusionMode = mempty + , pncNumOfDiskSnapshots = Last Nothing , pncSnapshotInterval = Last . Just . RequestedSnapshotInterval $ secondsToDiffTime 100 , pncExperimentalProtocolsEnabled = Last $ Just True , pncProtocolFiles = Last . Just $ ProtocolFilepaths Nothing Nothing Nothing Nothing Nothing Nothing @@ -199,6 +202,7 @@ eExpectedConfig = do , ncValidateDB = True , ncProtocolConfig = testNodeProtocolConfiguration , ncDiffusionMode = InitiatorAndResponderDiffusionMode + , ncNumOfDiskSnapshots = DefaultNumOfDiskSnapshots , ncSnapshotInterval = RequestedSnapshotInterval $ secondsToDiffTime 100 , ncExperimentalProtocolsEnabled = True , ncMaxConcurrencyBulkSync = Nothing diff --git a/cardano-submit-api/cardano-submit-api.cabal b/cardano-submit-api/cardano-submit-api.cabal index 992048dcfb3..dfbc7cbd560 100644 --- a/cardano-submit-api/cardano-submit-api.cabal +++ b/cardano-submit-api/cardano-submit-api.cabal @@ -1,7 +1,7 @@ cabal-version: 3.0 name: cardano-submit-api -version: 3.2.1 +version: 3.2.2 synopsis: A web server that allows transactions to be POSTed to the cardano chain description: A web server that allows transactions to be POSTed to the cardano chain. homepage: https://github.com/intersectmbo/cardano-node @@ -39,9 +39,9 @@ library , aeson , async , bytestring - , cardano-api ^>= 8.39 + , cardano-api ^>= 8.39.2.0 , cardano-binary - , cardano-cli ^>= 8.20.2.0 + , cardano-cli ^>= 8.20.3.0 , cardano-crypto-class ^>= 2.1.2 , http-media , iohk-monitoring @@ -49,7 +49,7 @@ library , network , optparse-applicative-fork , ouroboros-consensus-cardano - , ouroboros-network ^>= 0.11 + , ouroboros-network ^>= 0.12 , ouroboros-network-protocols , prometheus >= 2.2.4 , servant diff --git a/cardano-testnet/cardano-testnet.cabal b/cardano-testnet/cardano-testnet.cabal index 61f744871fe..0f3d20e0f61 100644 --- a/cardano-testnet/cardano-testnet.cabal +++ b/cardano-testnet/cardano-testnet.cabal @@ -34,8 +34,8 @@ library build-depends: aeson , ansi-terminal , bytestring - , cardano-api ^>= 8.39 - , cardano-cli ^>= 8.20.2.0 + , cardano-api ^>= 8.39.2.0 + , cardano-cli ^>= 8.20.3.0 , cardano-crypto-class , cardano-crypto-wrapper , cardano-ledger-alonzo @@ -56,14 +56,14 @@ library , exceptions , filepath , hedgehog - , hedgehog-extras ^>= 0.6.1.0 + , hedgehog-extras < 0.6.2 , microlens , lens-aeson , mtl , network , network-mux , optparse-applicative-fork - , ouroboros-network ^>= 0.11 + , ouroboros-network ^>= 0.12 , ouroboros-network-api , prettyprinter , process @@ -122,7 +122,7 @@ executable cardano-testnet , cardano-testnet , optparse-applicative-fork - ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" test-suite cardano-testnet-golden import: project-config @@ -153,7 +153,7 @@ test-suite cardano-testnet-golden , tasty-hedgehog , text - ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" build-tool-depends: cardano-node:cardano-node , cardano-cli:cardano-cli @@ -215,7 +215,7 @@ test-suite cardano-testnet-test , time , transformers - ghc-options: -threaded -rtsopts -with-rtsopts=-N -with-rtsopts=-T + ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" build-tool-depends: cardano-node:cardano-node , cardano-cli:cardano-cli diff --git a/cardano-testnet/src/Testnet/Components/Configuration.hs b/cardano-testnet/src/Testnet/Components/Configuration.hs index f8426be3bfc..cacf9470e75 100644 --- a/cardano-testnet/src/Testnet/Components/Configuration.hs +++ b/cardano-testnet/src/Testnet/Components/Configuration.hs @@ -20,9 +20,9 @@ import Cardano.Api.Shelley hiding (Value, cardanoEra) import qualified Cardano.Node.Configuration.Topology as NonP2P import qualified Cardano.Node.Configuration.TopologyP2P as P2P -import Cardano.Node.Types +import Ouroboros.Network.PeerSelection.Bootstrap import Ouroboros.Network.PeerSelection.LedgerPeers -import Ouroboros.Network.PeerSelection.RelayAccessPoint +import Ouroboros.Network.PeerSelection.PeerTrustable import Ouroboros.Network.PeerSelection.State.LocalRootPeers import Control.Monad @@ -52,7 +52,6 @@ import qualified Hedgehog.Extras.Stock.Time as DTC import qualified Hedgehog.Extras.Test.Base as H import qualified Hedgehog.Extras.Test.File as H - createConfigYaml :: (MonadTest m, MonadIO m, HasCallStack) => TmpAbsolutePath @@ -201,6 +200,7 @@ mkTopologyConfig numNodes allPorts port True = Aeson.encode topologyP2P [ P2P.LocalRootPeersGroup rootConfig (HotValency (numNodes - 1)) (WarmValency (numNodes - 1)) + IsNotTrustable ] topologyP2P :: P2P.NetworkTopology @@ -208,4 +208,5 @@ mkTopologyConfig numNodes allPorts port True = Aeson.encode topologyP2P P2P.RealNodeTopology localRootPeerGroups [] - (UseLedger DontUseLedger) + DontUseLedgerPeers + DontUseBootstrapPeers diff --git a/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs b/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs index 9d48a6e65b3..14529d7681d 100644 --- a/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs +++ b/cardano-testnet/test/cardano-testnet-test/cardano-testnet-test.hs @@ -13,8 +13,6 @@ import qualified Cardano.Testnet.Test.Cli.Conway.Plutus import qualified Cardano.Testnet.Test.Cli.KesPeriodInfo import qualified Cardano.Testnet.Test.Cli.QuerySlotNumber import qualified Cardano.Testnet.Test.FoldBlocks -import qualified Cardano.Testnet.Test.LedgerEvents.Gov.InfoAction as LedgerEvents -import qualified Cardano.Testnet.Test.LedgerEvents.Gov.ProposeNewConstitution as LedgerEvents import qualified Cardano.Testnet.Test.LedgerEvents.Gov.ProposeNewConstitutionSPO as LedgerEvents import qualified Cardano.Testnet.Test.LedgerEvents.SanityCheck as LedgerEvents import qualified Cardano.Testnet.Test.Node.Shutdown @@ -31,30 +29,30 @@ import qualified Test.Tasty as T import Test.Tasty (TestTree) import qualified Test.Tasty.Ingredients as T - tests :: IO TestTree -tests = pure $ T.testGroup "test/Spec.hs" - [ T.testGroup "Spec" - [ T.testGroup "Ledger Events" +tests = pure $ sequentialTestGroup "test/Spec.hs" + [ sequentialTestGroup "Spec" + [ sequentialTestGroup "Ledger Events" [ H.ignoreOnWindows "Sanity Check" LedgerEvents.hprop_ledger_events_sanity_check -- TODO: Replace foldBlocks with checkLedgerStateCondition , T.testGroup "Governance" - [ H.ignoreOnMacAndWindows "ProposeAndRatifyNewConstitution" LedgerEvents.hprop_ledger_events_propose_new_constitution - , H.ignoreOnWindows "InfoAction" LedgerEvents.hprop_ledger_events_info_action - , H.ignoreOnWindows "ProposeNewConstitutionSPO" LedgerEvents.hprop_ledger_events_propose_new_constitution_spo + -- FIXME Those tests are flaky + [ -- H.ignoreOnMacAndWindows "ProposeAndRatifyNewConstitution" LedgerEvents.hprop_ledger_events_propose_new_constitution + -- , H.ignoreOnWindows "InfoAction" LedgerEvents.hprop_ledger_events_info_action + H.ignoreOnWindows "ProposeNewConstitutionSPO" LedgerEvents.hprop_ledger_events_propose_new_constitution_spo , H.ignoreOnWindows "DRepRetirement" DRepRetirement.hprop_drep_retirement ] , T.testGroup "Plutus" [ H.ignoreOnWindows "PlutusV3" Cardano.Testnet.Test.Cli.Conway.Plutus.hprop_plutus_v3] ] - , T.testGroup "CLI" + , sequentialTestGroup "CLI" [ H.ignoreOnWindows "Shutdown" Cardano.Testnet.Test.Node.Shutdown.hprop_shutdown -- ShutdownOnSigint fails on Mac with -- "Log file: /private/tmp/tmp.JqcjW7sLKS/kes-period-info-2-test-30c2d0d8eb042a37/logs/test-spo.stdout.log had no logs indicating the relevant node has minted blocks." , H.ignoreOnMacAndWindows "ShutdownOnSigint" Cardano.Testnet.Test.Node.Shutdown.hprop_shutdownOnSigint -- ShutdownOnSlotSynced FAILS Still. The node times out and it seems the "shutdown-on-slot-synced" flag does nothing -- , H.ignoreOnWindows "ShutdownOnSlotSynced" Cardano.Testnet.Test.Node.Shutdown.hprop_shutdownOnSlotSynced - , T.testGroup "Babbage" + , sequentialTestGroup "Babbage" -- TODO: Babbage --next leadership schedule still fails. Once this fix is propagated to the cli (https://github.com/input-output-hk/cardano-api/pull/274) -- this should remedy. Double check and make sure we have re-enabled it and remove this comment. [ H.ignoreOnMacAndWindows "leadership-schedule" Cardano.Testnet.Test.Cli.Babbage.LeadershipSchedule.hprop_leadershipSchedule -- FAILS @@ -62,7 +60,7 @@ tests = pure $ T.testGroup "test/Spec.hs" , H.ignoreOnWindows "transaction" Cardano.Testnet.Test.Cli.Babbage.Transaction.hprop_transaction ] -- TODO: Conway - Re-enable when create-staked is working in conway again - --, T.testGroup "Conway" + --, sequentialTestGroup "Conway" -- [ H.ignoreOnWindows "stake-snapshot" Cardano.Testnet.Test.Cli.Conway.StakeSnapshot.hprop_stakeSnapshot -- ] -- Ignored on Windows due to : cosmmitBuffer: invalid argument (invalid character) @@ -73,13 +71,17 @@ tests = pure $ T.testGroup "test/Spec.hs" ] ] - , T.testGroup "SubmitApi" - [ T.testGroup "Babbage" + , sequentialTestGroup "SubmitApi" + [ sequentialTestGroup "Babbage" [ H.ignoreOnWindows "transaction" Cardano.Testnet.Test.SubmitApi.Babbage.Transaction.hprop_transaction ] ] ] +-- FIXME Right now when running tests concurrently it makes tests flaky and sometimes stuck +sequentialTestGroup :: T.TestName -> [TestTree] -> TestTree +sequentialTestGroup name = T.sequentialTestGroup name T.AllFinish + ingredients :: [T.Ingredient] ingredients = T.defaultIngredients diff --git a/cardano-tracer/cardano-tracer.cabal b/cardano-tracer/cardano-tracer.cabal index bc6ca55bae1..3c5958eaca2 100644 --- a/cardano-tracer/cardano-tracer.cabal +++ b/cardano-tracer/cardano-tracer.cabal @@ -152,7 +152,7 @@ library , filepath , mime-mail , optparse-applicative - , ouroboros-network ^>= 0.11 + , ouroboros-network ^>= 0.12 , ouroboros-network-api , ouroboros-network-framework , signal diff --git a/configuration/cardano/mainnet-topology.json b/configuration/cardano/mainnet-topology.json index 902d14376c5..5290fbeb035 100644 --- a/configuration/cardano/mainnet-topology.json +++ b/configuration/cardano/mainnet-topology.json @@ -1,29 +1,27 @@ { + "bootstrapPeers": [ + { + "address": "backbone.cardano.iog.io", + "port": 3001 + }, + { + "address": "backbone.mainnet.emurgornd.com", + "port": 3001 + } + ], "localRoots": [ { "accessPoints": [], "advertise": false, + "trustable": false, "valency": 1 } ], "publicRoots": [ { - "accessPoints": [ - { - "address": "backbone.cardano-mainnet.iohk.io", - "port": 3001 - }, - { - "address": "backbone.cardano.iog.io", - "port": 3001 - }, - { - "address": "backbone.mainnet.emurgornd.com", - "port": 3001 - } - ], + "accessPoints": [], "advertise": false } ], - "useLedgerAfterSlot": 110332824 + "useLedgerAfterSlot": 116812831 } diff --git a/flake.lock b/flake.lock index 3e54e0c97d5..bd63cb4a4d6 100644 --- a/flake.lock +++ b/flake.lock @@ -3,11 +3,11 @@ "CHaP": { "flake": false, "locked": { - "lastModified": 1708729825, - "narHash": "sha256-mufjeGjZjgdfcxXzssMpRM/KggPVWQu6hFbYWPyBY78=", + "lastModified": 1708970955, + "narHash": "sha256-k6Y9WjDej7wCkUowVi/tdsWP6EWUMZTSRU9r+4lMJmU=", "owner": "intersectmbo", "repo": "cardano-haskell-packages", - "rev": "42963de660ded965e14477f91a4c5df53fb1072d", + "rev": "f09964311e8894a5f09e258f308a9c3d4221f029", "type": "github" }, "original": { @@ -624,11 +624,11 @@ "hackageNix": { "flake": false, "locked": { - "lastModified": 1708906978, - "narHash": "sha256-GTcMtNGWpRJ/LAFkcQjNS+mneNMjcRNyg3x11eKI62g=", + "lastModified": 1708993343, + "narHash": "sha256-8EbbR5ReQK61yP/7VYtFSCerBXSE59VtfV+Wahdsuqg=", "owner": "input-output-hk", "repo": "hackage.nix", - "rev": "93d5bc1145240077425ef31bb73eaa76a68e52fa", + "rev": "f823c9258e9316cb4da256fc93e9c0407f0c296a", "type": "github" }, "original": { @@ -922,11 +922,11 @@ "sodium": "sodium" }, "locked": { - "lastModified": 1707581561, - "narHash": "sha256-A9MT8D7M2We0HCBQbClrA91ZquGf7GU+T6tvjMeUUEA=", + "lastModified": 1709083850, + "narHash": "sha256-6DQ89ktt8rRVV1pXEyX2JwPjaqS0mQkelkmJmka04rg=", "owner": "input-output-hk", "repo": "iohk-nix", - "rev": "51469c3fc2c74e24b529f63615670259ba1fee38", + "rev": "1c793a53ac0bd99b795c2180eb23d37e8389a74b", "type": "github" }, "original": { diff --git a/nix/nixos/cardano-node-service.nix b/nix/nixos/cardano-node-service.nix index 636cdec5e84..ce603fba52d 100644 --- a/nix/nixos/cardano-node-service.nix +++ b/nix/nixos/cardano-node-service.nix @@ -17,11 +17,13 @@ let accessPoints = map (e: builtins.removeAttrs e ["valency"]) g.accessPoints; advertise = g.advertise or false; valency = g.valency or (length g.accessPoints); + trustable = g.trustable or false; }) (cfg.producers ++ (cfg.instanceProducers i)); publicRoots = map (g: { accessPoints = map (e: builtins.removeAttrs e ["valency"]) g.accessPoints; advertise = g.advertise or false; }) (cfg.publicProducers ++ (cfg.instancePublicProducers i)); + bootstrapPeers = cfg.bootstrapPeers; } // optionalAttrs (cfg.usePeersFromLedgerAfterSlot != null) { useLedgerAfterSlot = cfg.usePeersFromLedgerAfterSlot; }; @@ -36,10 +38,23 @@ let ); }; + assertNewTopology = i: + let + checkEval = tryEval ( + assert + if cfg.bootstrapPeers == [] && all (e: e.trustable != true) ((newTopology i).localRoots) + then false + else true; + newTopology i); + in + if checkEval.success + then checkEval.value + else abort "When bootstrapPeers is an empty list, at least one localRoot must be trustable, otherwise cardano node will fail to start."; + selectTopology = i: if cfg.topology != null then cfg.topology - else toFile "topology.yaml" (toJSON (if (cfg.useNewTopology) then newTopology i else oldTopology i)); + else toFile "topology.yaml" (toJSON (if (cfg.useNewTopology) then assertNewTopology i else oldTopology i)); topology = i: if cfg.useSystemdReload @@ -448,7 +463,8 @@ in { publicProducers = mkOption { type = types.listOf types.attrs; - default = [{ + default = []; + example = [{ accessPoints = [{ address = envConfig.relaysNew; port = envConfig.edgePort; @@ -513,6 +529,26 @@ in { ''; }; + bootstrapPeers = mkOption { + type = types.nullOr (types.listOf types.attrs); + default = + # Until legacy mainnet relays are deprecated and replaced by IOG bootstrap peers for relaysNew, + # filter the legacy relaysNew definition from the mainnet bootstrapPeers list. + # + # All other envs can use the edgeNodes list as bootstrapPeers. + if envConfig.name == "mainnet" + then + map (e: {address = e.addr; inherit (e) port;}) + (builtins.filter (e: e.addr != envConfig.relaysNew) envConfig.edgeNodes) + else + map (e: {address = e.addr; inherit (e) port;}) envConfig.edgeNodes; + description = '' + If set, it will enable bootstrap peers. + To disable, set this to null. + To enable, set this to a list of attributes of address and port, example: [{ address = "addr"; port = 3001; }] + ''; + }; + topology = mkOption { type = types.nullOr (types.either types.str types.path); default = null; diff --git a/trace-dispatcher/trace-dispatcher.cabal b/trace-dispatcher/trace-dispatcher.cabal index efbce11c7ed..b6cbc908018 100644 --- a/trace-dispatcher/trace-dispatcher.cabal +++ b/trace-dispatcher/trace-dispatcher.cabal @@ -1,7 +1,7 @@ cabal-version: 3.0 name: trace-dispatcher -version: 2.5.2 +version: 2.5.3 synopsis: Tracers for Cardano description: Package for development of simple and efficient tracers based on the arrow based contra-tracer package @@ -60,7 +60,7 @@ library , hostname , network , optparse-applicative-fork - , ouroboros-network ^>= 0.11 + , ouroboros-network ^>= 0.12 , ouroboros-network-api , ouroboros-network-framework , serialise diff --git a/trace-forward/trace-forward.cabal b/trace-forward/trace-forward.cabal index 54eaa9bb9b8..007e1540094 100644 --- a/trace-forward/trace-forward.cabal +++ b/trace-forward/trace-forward.cabal @@ -1,7 +1,7 @@ cabal-version: 3.0 name: trace-forward -version: 2.2.2 +version: 2.2.3 synopsis: The forwarding protocols library for cardano node. description: The library providing typed protocols for forwarding different information from the cardano node to an external application. @@ -64,7 +64,7 @@ library , deepseq , extra , io-classes - , ouroboros-network-api ^>= 0.6 + , ouroboros-network-api ^>= 0.7 , ouroboros-network-framework , serialise , stm