From dc4485fd94e227b0c28920b999b0a8ab9a193d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Mon, 9 Feb 2026 12:39:46 +0100 Subject: [PATCH 01/11] trace-dispatcher: namespace generation --- .../src/Cardano/Logging/DocuGenerator.hs | 610 ++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs diff --git a/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs b/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs new file mode 100644 index 00000000000..997f2626d4d --- /dev/null +++ b/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs @@ -0,0 +1,610 @@ +{-# LANGUAGE DerivingVia #-} +{-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} + +{- HLINT ignore "Use map" -} +{- HLINT ignore "Use map with tuple-section" -} + +module Cardano.Logging.DocuGenerator ( + -- First call documentTracer for every tracer and then + -- docuResultToText on all results + documentTracer + , documentTracer' + , docuResultsToText + , docuResultsToNamespaces + , docuResultsToMetricsHelptext + -- Callbacks + , docTracer + , docTracerDatapoint + , docIt + , addFiltered + , addLimiter + , addSilent + , addDocumentedNamespace + , DocuResult + , DocTracer(..) +) where + +import Cardano.Logging.ConfigurationParser () +import Cardano.Logging.DocuGenerator.Tree +import Cardano.Logging.DocuGenerator.Result (DocuResult (..)) +import qualified Cardano.Logging.DocuGenerator.Result as DocuResult +import Cardano.Logging.Types + +import Prelude hiding (lines, unlines) + +import Control.Monad (mfilter) +import Control.Monad.IO.Class (MonadIO, liftIO) +import qualified Control.Tracer as TR +import Data.Aeson (ToJSON) +import qualified Data.Aeson.Encode.Pretty as AE +import Data.IORef (modifyIORef, newIORef, readIORef) +import Data.List (find, groupBy, intersperse, isPrefixOf, nub, sort, sortBy) +import qualified Data.Map.Strict as Map +import Data.Maybe (fromJust, fromMaybe, mapMaybe) +import Data.Text (split) +import Data.Text as T (Text, empty, intercalate, lines, pack, stripPrefix, toLower, + unlines) +import Data.Text.Internal.Builder (toLazyText) +import Data.Text.Lazy (toStrict) +import Data.Text.Lazy.Builder (Builder, fromString, fromText, singleton) + +type InconsistencyWarning = Text + +utf16CircledT :: Text +utf16CircledT = "\x24E3" + +utf16CircledS :: Text +utf16CircledS = "\x24E2" + +utf16CircledM :: Text +utf16CircledM = "\x24DC" + +-- | Convenience function for adding a namespace prefix to a documented +addDocumentedNamespace :: [Text] -> Documented a -> Documented a +addDocumentedNamespace out (Documented list) = + Documented $ map + (\ dm@DocMsg {} -> dm {dmNamespace = nsReplacePrefix out (dmNamespace dm)}) + list + +data DocTracer = DocTracer { + dtTracerNames :: [[Text]] + , dtSilent :: [[Text]] + , dtNoMetrics :: [[Text]] + , dtBuilderList :: [([Text], DocuResult)] + , dtWarnings :: [InconsistencyWarning] +} deriving (Show) + +instance Semigroup DocTracer where + dtl <> dtr = DocTracer + (dtTracerNames dtl <> dtTracerNames dtr) + (dtSilent dtl <> dtSilent dtr) + (dtNoMetrics dtl <> dtNoMetrics dtr) + (dtBuilderList dtl <> dtBuilderList dtr) + (dtWarnings dtl <> dtWarnings dtr) + +documentTracer' :: forall a a1. + MetaTrace a + => (Trace IO a1 -> IO (Trace IO a)) + -> Trace IO a1 + -> IO DocTracer +documentTracer' hook tracer = do + tr' <- hook tracer + documentTracer tr' + +-- This function calls document tracers and returns a DocTracer result +documentTracer :: forall a. + MetaTrace a + => Trace IO a + -> IO DocTracer +documentTracer tracer = do + DocCollector docRef <- documentTracersRun [tracer] + items <- fmap Map.toList (liftIO (readIORef docRef)) + let sortedItems = sortBy + (\ (_,l) (_,r) -> compare (ldNamespace l) (ldNamespace r)) + items + let messageDocs = map (\(i, ld) -> case ldNamespace ld of + (prn,pon) : _ -> (prn ++ pon, documentItem (i, ld)) + [] -> (["No ns"], documentItem (i, ld))) sortedItems + metricsItems = map snd $ filter (not . Map.null . ldMetricsDoc . snd) sortedItems + metricsDocs = documentMetrics metricsItems + tracerName = case sortedItems of + ((_i, ld) : _) -> case ldNamespace ld of + (prn, _pon) : _ -> prn + [] -> [] + [] -> [] + silent = case sortedItems of + ((_i, ld) : _) -> ldSilent ld + [] -> False + hasNoMetrics = null metricsItems + warnings = concatMap (\(i, ld) -> case ldNamespace ld of + (_,_): _ -> warningItem (i, ld) + [] -> (pack "No ns for " <> ldDoc ld) : + warningItem (i, ld)) sortedItems + pure $ DocTracer + [tracerName] + [tracerName | silent] + [tracerName | hasNoMetrics] + (messageDocs ++ metricsDocs) + warnings + + where + documentItem :: (Int, LogDoc) -> DocuResult + documentItem (_idx, ld@LogDoc {..}) = + case ldBackends of + [DatapointBackend] -> DocuDatapoint $ + mconcat $ intersperse (fromText "\n\n") + [ namespacesBuilder (nub ldNamespace) + , accentuated ldDoc + ] + _ -> DocuTracer $ + mconcat $ intersperse (fromText "\n\n") + [ namespacesBuilder (nub ldNamespace) + , accentuated ldDoc + , propertiesBuilder ld + , configBuilder ld + ] + + warningItem :: (Int, LogDoc) -> [InconsistencyWarning] + warningItem (_idx, ld@LogDoc {..}) = + case ldBackends of + [DatapointBackend] -> namespacesWarning (nub ldNamespace) ld + _ -> namespacesWarning (nub ldNamespace) ld + ++ propertiesWarning ld + + documentMetrics :: [LogDoc] -> [([Text],DocuResult)] + documentMetrics logDocs = + let nameCommentNamespaceList = + concatMap (\ld -> zip (Map.toList (ldMetricsDoc ld)) (repeat (ldNamespace ld))) logDocs + sortedNameCommentNamespaceList = + sortBy (\a b -> compare ((fst . fst) a) ((fst . fst) b)) nameCommentNamespaceList + groupedNameCommentNamespaceList = + groupBy (\a b -> (fst . fst) a == (fst . fst) b) sortedNameCommentNamespaceList + in mapMaybe documentMetrics' groupedNameCommentNamespaceList + + documentMetrics' :: [( (Text, Text) , [([Text],[Text])] )] -> Maybe ([Text], DocuResult) + documentMetrics' ncns@(((name, comment), _) : _tail) = + Just ([name], DocuMetric + $ mconcat $ intersperse (fromText "\n\n") + [ metricToBuilder (name,comment) + , namespacesMetricsBuilder (nub (concatMap snd ncns)) + ]) + documentMetrics' [] = Nothing + + namespacesBuilder :: [([Text], [Text])] -> Builder + namespacesBuilder [ns] = namespaceBuilder ns + namespacesBuilder [] = fromText "__Warning__: namespace missing" + namespacesBuilder nsl = + mconcat (intersperse (singleton '\n') (map namespaceBuilder nsl)) + + namespaceBuilder :: ([Text], [Text]) -> Builder + namespaceBuilder (nsPr, nsPo) = fromText "### " <> + mconcat (intersperse (singleton '.') (map fromText (nsPr ++ nsPo))) + + namespacesMetricsBuilder :: [ ([Text], [Text])] -> Builder + namespacesMetricsBuilder [ns] = fromText "Dispatched by: \n" <> namespaceMetricsBuilder ns + namespacesMetricsBuilder [] = mempty + namespacesMetricsBuilder nsl = fromText "Dispatched by: \n" <> + mconcat (intersperse (singleton '\n') (map namespaceMetricsBuilder nsl)) + + namespaceMetricsBuilder :: ([Text], [Text]) -> Builder + namespaceMetricsBuilder (nsPr, nsPo) = mconcat (intersperse (singleton '.') + (map fromText (nsPr ++ nsPo))) + + namespacesWarning :: [([Text], [Text])] -> LogDoc -> [InconsistencyWarning] + namespacesWarning [] ld = ["Namespace missing " <> ldDoc ld] + namespacesWarning _ _ = [] + + propertiesBuilder :: LogDoc -> Builder + propertiesBuilder LogDoc {..} = + case ldSeverityCoded of + Just s -> fromText "Severity: " <> asCode (fromString (show s)) <> "\n" + Nothing -> fromText "Severity missing: " <> "\n" + <> + case ldPrivacyCoded of + Just p -> fromText "Privacy: " <> asCode (fromString (show p)) <> "\n" + Nothing -> fromText "Privacy missing: " <> "\n" + <> + case ldDetailsCoded of + Just d -> fromText "Details: " <> asCode (fromString (show d)) <> "\n" + Nothing -> fromText "Details missing: " <> "\n" + + propertiesWarning :: LogDoc ->[InconsistencyWarning] + propertiesWarning LogDoc {..} = + case ldSeverityCoded of + Just _s -> [] + Nothing -> map (\ns -> pack "Severity missing: " <> nsRawToText ns) ldNamespace + <> + case ldPrivacyCoded of + Just _p -> [] + Nothing -> map (\ns -> pack "Privacy missing: " <> nsRawToText ns) ldNamespace + <> + case ldDetailsCoded of + Just _d -> [] + Nothing -> map (\ns -> pack "Details missing: " <> nsRawToText ns) ldNamespace + + configBuilder :: LogDoc -> Builder + configBuilder LogDoc {..} = + fromText "From current configuration:\n" + <> case nub ldDetails of + [] -> mempty + [d] -> if Just d /= ldDetailsCoded + then fromText "Details: " + <> asCode (fromString (show d)) + else mempty + l -> fromText "Details: " + <> mconcat (intersperse (fromText ",\n ") + (map (asCode . fromString . show) l)) + <> fromText "\n" + <> backendsBuilder (nub ldBackends) + <> fromText "\n" + <> filteredBuilder (nub ldFiltered) ldSeverityCoded + <> limiterBuilder (nub ldLimiter) + + backendsBuilder :: [BackendConfig] -> Builder + backendsBuilder [] = fromText "No backends found" + backendsBuilder l = fromText "Backends:\n " + <> mconcat (intersperse (fromText ",\n ") + (map backendFormatToText l)) + + backendFormatToText :: BackendConfig -> Builder + backendFormatToText be = asCode (fromString (show be)) + + filteredBuilder :: [SeverityF] -> Maybe SeverityS -> Builder + filteredBuilder [] _ = mempty + filteredBuilder _ Nothing = mempty + filteredBuilder l (Just r) = + fromText "Filtered " + <> case l of + [SeverityF (Just lh)] -> + if fromEnum r >= fromEnum lh + then (asCode . fromString) "Visible" + else (asCode . fromString) "Invisible" + [SeverityF Nothing] -> "Invisible" + _ -> mempty + <> fromText " by config value: " + <> mconcat (intersperse (fromText ", ") + (map (asCode . fromString . show) l)) + + limiterBuilder :: + [(Text, Double)] + -> Builder + limiterBuilder [] = mempty + limiterBuilder l = + mconcat (intersperse (fromText ", ") + (map (\ (n, d) -> fromText "\nLimiter " + <> (asCode . fromText) n + <> fromText " with frequency " + <> (asCode . fromString. show) d) + l)) + + metricToBuilder :: (Text, Text) -> Builder + metricToBuilder (name, text) = + fromText "### " + <> fromText name + <> fromText "\n" + <> accentuated text + + + +-- | Calls the tracers in a documentation control mode, +-- and returns a DocCollector, from which the documentation gets generated +documentTracersRun :: forall a. MetaTrace a => [Trace IO a] -> IO DocCollector +documentTracersRun tracers = do + let nss = allNamespaces :: [Namespace a] + nsIdx = zip nss [0..] + coll <- fmap DocCollector (liftIO $ newIORef (Map.empty :: Map.Map Int LogDoc)) + mapM_ (docTrace nsIdx coll) tracers + pure coll + where + docTrace nsIdx dc@(DocCollector docRef) (Trace tr) = + mapM_ + (\ (ns, idx) -> do + let condDoc = documentFor ns + doc = fromMaybe mempty condDoc + + modifyIORef docRef + (Map.insert + idx + ((emptyLogDoc + doc + (metricsDocFor ns)) + { ldSeverityCoded = severityFor ns Nothing + , ldPrivacyCoded = privacyFor ns Nothing + , ldDetailsCoded = detailsFor ns Nothing + })) + TR.traceWith tr (emptyLoggingContext {lcNSInner = nsInner ns}, + Left (TCDocument idx dc))) + nsIdx + +-------------------- Callbacks --------------------------- + +docTracer :: MonadIO m => + BackendConfig + -> Trace m FormattedMessage +docTracer backendConfig = Trace $ TR.arrow $ TR.emit output + where + output p@(_, Left TCDocument {}) = + docIt backendConfig p + output (_, _) = pure () + +docTracerDatapoint :: MonadIO m => + BackendConfig + -> Trace m a +docTracerDatapoint backendConfig = Trace $ TR.arrow $ TR.emit output + where + output p@(_, Left TCDocument {}) = + docItDatapoint backendConfig p + output (_, _) = pure () + + +-- | Callback for doc collection +addFiltered :: MonadIO m => TraceControl -> Maybe SeverityF -> m () +addFiltered (TCDocument idx (DocCollector docRef)) (Just sev) = do + liftIO $ modifyIORef docRef (\ docMap -> + Map.insert + idx + ((\e -> e { ldFiltered = seq sev (sev : ldFiltered e)}) + (case Map.lookup idx docMap of + Just e -> e + Nothing -> error "DocuGenerator>>missing log doc")) + docMap) +addFiltered _ _ = pure () + +-- | Callback for doc collection +addLimiter :: MonadIO m => TraceControl -> (Text, Double) -> m () +addLimiter (TCDocument idx (DocCollector docRef)) (ln, lf) = do + liftIO $ modifyIORef docRef (\ docMap -> + Map.insert + idx + ((\e -> e { ldLimiter = seq ln (seq lf ((ln, lf) : ldLimiter e))}) + (case Map.lookup idx docMap of + Just e -> e + Nothing -> error "DocuGenerator>>missing log doc")) + docMap) +addLimiter _ _ = pure () + +addSilent :: MonadIO m => TraceControl -> Maybe Bool -> m () +addSilent (TCDocument idx (DocCollector docRef)) (Just silent) = do + liftIO $ modifyIORef docRef (\ docMap -> + Map.insert + idx + ((\e -> e { ldSilent = silent}) + (case Map.lookup idx docMap of + Just e -> e + Nothing -> error "DocuGenerator>>missing log doc")) + docMap) +addSilent _ _ = pure () + +-- | Callback for doc collection +docIt :: MonadIO m + => BackendConfig + -> (LoggingContext, Either TraceControl a) + -> m () +docIt EKGBackend (LoggingContext{}, + Left (TCDocument idx (DocCollector docRef))) = do + liftIO $ modifyIORef docRef (\ docMap -> + Map.insert + idx + ((\e -> e { ldBackends = EKGBackend : ldBackends e + }) + (case Map.lookup idx docMap of + Just e -> e + Nothing -> error "DocuGenerator>>missing log doc")) + docMap) +docIt backend (LoggingContext {..}, + Left (TCDocument idx (DocCollector docRef))) = do + liftIO $ modifyIORef docRef (\ docMap -> + Map.insert + idx + ((\e -> e { ldBackends = backend : ldBackends e + , ldNamespace = nub ((lcNSPrefix,lcNSInner) : ldNamespace e) + , ldDetails = case lcDetails of + Nothing -> ldDetails e + Just d -> d : ldDetails e + }) + (case Map.lookup idx docMap of + Just e -> e + Nothing -> error "DocuGenerator>>missing log doc")) + docMap) +docIt _ (_, _) = pure () + +-- | Callback for doc collection +docItDatapoint :: MonadIO m => + BackendConfig + -> (LoggingContext, Either TraceControl a) + -> m () +docItDatapoint _backend (LoggingContext {..}, + Left (TCDocument idx (DocCollector docRef))) = do + liftIO $ modifyIORef docRef (\ docMap -> + Map.insert + idx + ((\e -> e { ldNamespace = nub ((lcNSPrefix, lcNSInner) : ldNamespace e) + , ldBackends = [DatapointBackend] + }) + (case Map.lookup idx docMap of + Just e -> e + Nothing -> error "DocuGenerator>>missing log doc")) + docMap) +docItDatapoint _backend (LoggingContext {}, _) = pure () + + +-- Finally generate a text from all the builders +docuResultsToText :: DocTracer -> TraceConfig -> Text +docuResultsToText dt@DocTracer {..} configuration = + let traceBuilders = sortBy (\ (l,_) (r,_) -> compare l r) + (filter (DocuResult.isTracer . snd) dtBuilderList) + metricsBuilders = sortBy (\ (l,_) (r,_) -> compare l r) + (filter (DocuResult.isMetric .snd) dtBuilderList) + datapointBuilders = sortBy (\ (l,_) (r,_) -> compare l r) + (filter (DocuResult.isDatapoint . snd) dtBuilderList) + header = fromText "# Cardano Trace Documentation\n\n" + header1 = fromText "## Table Of Contents\n\n" + toc = generateTOC dt + (map fst traceBuilders) + (map fst metricsBuilders) + (map fst datapointBuilders) + + header2 = fromText "\n## Trace Messages\n\n" + contentT = mconcat $ intersperse (fromText "\n\n") + (map (DocuResult.unpackDocu . snd) traceBuilders) + header3 = fromText "\n## Metrics\n\n" + contentM = mconcat $ intersperse (fromText "\n\n") + (map (DocuResult.unpackDocu . snd) metricsBuilders) + header4 = fromText "\n## Datapoints\n\n" + contentD = mconcat $ intersperse (fromText "\n\n") + (map (DocuResult.unpackDocu . snd) datapointBuilders) + config = fromText "\n## Configuration: \n```\n" + <> AE.encodePrettyToTextBuilder configuration + <> fromText "\n```\n" + numbers = fromString $ show (length traceBuilders) <> " log messages, " <> "\n" <> + show (length metricsBuilders) <> " metrics," <> "\n" <> + show (length datapointBuilders) <> " datapoints." <> "\n\n" + + legend = fromText $ utf16CircledT <> "- This is the root of a tracer\n\n" <> + utf16CircledS <> "- This is the root of a tracer that is silent because of the current configuration\n\n" <> + utf16CircledM <> "- This is the root of a tracer, that provides metrics\n\n" in + toStrict $ toLazyText $ + header + <> header1 + <> toc + <> header2 + <> contentT + <> header3 + <> contentM + <> header4 + <> contentD + <> config + <> numbers + <> legend + +generateTOC :: DocTracer -> [[Text]] -> [[Text]] -> [[Text]] -> Builder +generateTOC DocTracer {..} traces metrics datapoints = + generateTOCTraces + <> generateTOCMetrics + <> generateTOCDatapoints + <> generateTOCRest + where + tracesTree = mapMaybe (trim []) (toForest traces) + metricsTree = toForest (fmap splitToNS metrics) + datapointsTree = toForest datapoints + + generateTOCTraces = + fromText "### [Trace Messages](#trace-messages)\n\n" + <> mconcat (map (namespaceToToc traces False []) tracesTree) + <> fromText "\n" + generateTOCMetrics = + fromText "### [Metrics](#metrics)\n\n" + <> mconcat (map (namespaceToToc (fmap splitToNS metrics) True []) metricsTree) + <> fromText "\n" + generateTOCDatapoints = + fromText "### [Datapoints](#datapoints)\n\n" + <> mconcat (map (namespaceToToc datapoints True []) datapointsTree) + <> fromText "\n" + generateTOCRest = + fromText "### [Configuration](#configuration)\n\n" + <> fromText "\n" + + splitToNS :: [Text] -> [Text] + splitToNS [sym] = split (== '.') sym + splitToNS other = other + + isTracerSymbol :: [Text] -> Bool + isTracerSymbol tracer = tracer `elem` dtTracerNames + + -- Modify the given tracer tree so that the result is a tree where entries which + -- are not tracers are removed. In case the whole tree doesn't contain a tracer, return Nothing. + trim :: [Text] {- accumulated namespace in reverse -} -> Tree Text -> Maybe (Tree Text) + trim ns (Node x nested) = + let that = reverse (x : ns) + -- List of all nested tracers that we shall render + nestedTrimmed = mapMaybe (trim (x : ns)) nested in + mfilter (\_ -> not (null nestedTrimmed) || isTracerSymbol that) (Just (Node x nestedTrimmed)) + + namespaceToToc :: + [[Text]] + -> Bool + -> [Text] {- Accumulated namespace in reverse -} + -> Tree Text + -> Builder + namespaceToToc allTracers skipSymbols accns (Node x nested) = text + where + ns = reverse (x : accns) + + inner = mconcat (map (namespaceToToc allTracers skipSymbols (x : accns)) nested) + + indent lvl txt = mconcat (replicate lvl "\t") <> txt + + text :: Builder + text = + indent (length accns) + ( + "1. " + <> "[" <> fromText x <> fromText symbolsText <> "]" + <> "(#" <> link <> ")\n" + ) <> inner + + symbolsText :: Text + symbolsText = if skipSymbols then "" else + let isTracer = elem ns dtTracerNames + isSilent = elem ns dtSilent + isMetric = notElem ns dtNoMetrics + in + (if isTracer then utf16CircledT else "") + <> (if isSilent then utf16CircledS else "") + <> (if isMetric then utf16CircledM else "") + + -- The link to the description of the first tracer in that namespace + link :: Builder + link = mconcat (map (fromText . toLower) firstTracer) + + -- The first tracer in the list of tracers that has that namespace prefix + firstTracer :: [Text] + firstTracer = fromJust $ find (ns `isPrefixOf`) allTracers + + +asCode :: Builder -> Builder +asCode b = singleton '`' <> b <> singleton '`' + +accentuated :: Text -> Builder +accentuated t = if t == "" + then fromText "\n" + else fromText "\n" + <> fromText (unlines $ map addAccent (lines t)) + where + addAccent :: Text -> Text + addAccent t' = if t' == "" + then ">" + else "> " <> t' + +-- this reflects the type cardano-tracer expects the metrics help texts to be serialized from: +-- simple key-value map +newtype MetricsHelp = MH (Map.Map Text Text) + deriving ToJSON via (Map.Map Text Text) + +docuResultsToMetricsHelptext :: DocTracer -> Text +docuResultsToMetricsHelptext DocTracer{dtBuilderList} = + toStrict $ toLazyText $ + AE.encodePrettyToTextBuilder' conf mh + where + conf = AE.defConfig { AE.confCompare = compare, AE.confTrailingNewline = True } + mh = MH $ Map.fromList + [(intercalate "." ns, fromMaybe T.empty x) + | (ns, DocuMetric helpDescr) <- dtBuilderList + + -- for now, just extract the helptext (if any) from the markdown paragraph: + -- it's the line that starts with "> " + , let xs = T.lines $ toStrict $ toLazyText helpDescr + , let x = mconcat $ map (stripPrefix "> ") xs + ] + +docuResultsToNamespaces :: DocTracer -> Text +docuResultsToNamespaces DocTracer{dtBuilderList} = + T.unlines uniqueSorted + where + namespaces = + [ intercalate "." ns + | (ns, doc) <- dtBuilderList + , DocuResult.isTracer doc || DocuResult.isDatapoint doc + ] + uniqueSorted = map head $ groupBy (==) $ sort namespaces From c5d545f6f5150ea7e8e649728f5270c1fdaea416 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Mon, 9 Feb 2026 12:40:19 +0100 Subject: [PATCH 02/11] cardano-node: trace docu with optional namespaces --- .../src/Cardano/Node/Tracing/Documentation.hs | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/cardano-node/src/Cardano/Node/Tracing/Documentation.hs b/cardano-node/src/Cardano/Node/Tracing/Documentation.hs index 311a5da279c..d8936b3e683 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Documentation.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Documentation.hs @@ -129,9 +129,10 @@ import Paths_cardano_node (version) data TraceDocumentationCmd = TraceDocumentationCmd - { tdcConfigFile :: FilePath - , tdcOutput :: FilePath - , tdMetricsHelp :: Maybe FilePath + { tdcConfigFile :: FilePath + , tdcOutput :: FilePath + , tdMetricsHelp :: Maybe FilePath + , tdNamespaceList :: Maybe FilePath } parseTraceDocumentationCmd :: Opt.Parser TraceDocumentationCmd @@ -160,6 +161,12 @@ parseTraceDocumentationCmd = <> Opt.help "Metrics helptext file for cardano-tracer (JSON)" ) ) + <*> Opt.optional (Opt.strOption + ( Opt.long "output-namespace-list" + <> Opt.metavar "FILE" + <> Opt.help "Namespace list file (text)" + ) + ) Opt.<**> Opt.helper) $ mconcat [ Opt.progDesc "Generate the trace documentation" ] ] @@ -172,7 +179,7 @@ runTraceDocumentationCmd :: TraceDocumentationCmd -> IO () runTraceDocumentationCmd TraceDocumentationCmd{..} = do - docTracers tdcConfigFile tdcOutput tdMetricsHelp + docTracers tdcConfigFile tdcOutput tdMetricsHelp tdNamespaceList -- Have to repeat the construction of the tracers here, -- as the tracers are behind old tracer interface after construction in mkDispatchTracers. @@ -181,10 +188,11 @@ docTracers :: FilePath -> FilePath -> Maybe FilePath + -> Maybe FilePath -> IO () -docTracers configFileName outputFileName mbMetricsHelpFilename = do +docTracers configFileName outputFileName mbMetricsHelpFilename mbNamespaceList = do (bl, trConfig) <- docTracersFirstPhase (Just configFileName) - docTracersSecondPhase outputFileName mbMetricsHelpFilename trConfig bl + docTracersSecondPhase outputFileName mbMetricsHelpFilename mbNamespaceList trConfig bl -- Have to repeat the construction of the tracers here, @@ -773,10 +781,11 @@ docTracersFirstPhase condConfigFileName = do docTracersSecondPhase :: FilePath -> Maybe FilePath + -> Maybe FilePath -> TraceConfig -> DocTracer -> IO () -docTracersSecondPhase outputFileName mbMetricsHelpFilename trConfig bl = do +docTracersSecondPhase outputFileName mbMetricsHelpFilename mbNamespaceList trConfig bl = do let text = docuResultsToText bl trConfig time <- getZonedTime let stamp = "Generated at " @@ -788,6 +797,8 @@ docTracersSecondPhase outputFileName mbMetricsHelpFilename trConfig bl = do doWrite outputFileName (text <> stamp) forM_ mbMetricsHelpFilename $ \f -> doWrite f (docuResultsToMetricsHelptext bl) + forM_ mbNamespaceList $ \f -> + doWrite f (docuResultsToNamespaces bl) where doWrite outfile text = withFile outfile WriteMode $ \handle -> From 3eaa9f2677f0e27b6b69f30107771ba7a483fc97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Wed, 11 Feb 2026 15:50:28 +0100 Subject: [PATCH 03/11] Json schema generation for trace messages --- .codex | 0 .gitignore | 2 + Makefile | 12 + bench/trace-schemas/TraceMessage.schema.json | 51 + bench/trace-schemas/meta.schema.json | 65 + bench/trace-schemas/newNamespaces.txt | 665 + bench/trace-schemas/overrides/README.md | 181 + ...-startup-info.schema.override.example.json | 13 + ...r-local-error.schema.override.example.json | 16 + ...connection-id.schema.override.example.json | 6 + .../schema-gen/ApplySchemaOverrides.hs | 253 + .../schema-gen/CheckOverrideCoverage.hs | 106 + .../scripts/schema-gen/GhciSchemaGen.hs | 2032 +++ .../scripts/schema-gen/README.md | 85 + .../schema-gen/RegenerateTraceSchemas.sh | 27 + .../scripts/schema-gen/ValidateTraceLog.hs | 354 + .../schema-gen/ValidateTraceSchemas.hs | 124 + .../scripts/schema-gen/trace-schema-gen.cabal | 78 + bench/trace-schemas/trace-documentation.md | 14096 ++++++++++++++++ .../trace-schemas-presentation.odp | Bin 0 -> 46829 bytes .../trace-schemas-presentation.pptx | Bin 0 -> 35056 bytes .../trace-schemas-speaker-notes.md | 46 + cabal.project | 13 + .../src/Cardano/Node/Tracing/Documentation.hs | 22 +- .../Cardano/Node/Tracing/Tracers/Diffusion.hs | 993 ++ 25 files changed, 19229 insertions(+), 11 deletions(-) create mode 100644 .codex create mode 100644 bench/trace-schemas/TraceMessage.schema.json create mode 100644 bench/trace-schemas/meta.schema.json create mode 100644 bench/trace-schemas/newNamespaces.txt create mode 100644 bench/trace-schemas/overrides/README.md create mode 100644 bench/trace-schemas/overrides/examples/01-startup-info.schema.override.example.json create mode 100644 bench/trace-schemas/overrides/examples/02-net-server-local-error.schema.override.example.json create mode 100644 bench/trace-schemas/overrides/examples/03-connection-id.schema.override.example.json create mode 100644 bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/README.md create mode 100644 bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh create mode 100644 bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal create mode 100644 bench/trace-schemas/trace-documentation.md create mode 100644 bench/trace-schemas/trace-schemas-presentation.odp create mode 100644 bench/trace-schemas/trace-schemas-presentation.pptx create mode 100644 bench/trace-schemas/trace-schemas-speaker-notes.md create mode 100644 cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs diff --git a/.codex b/.codex new file mode 100644 index 00000000000..e69de29bb2d diff --git a/.gitignore b/.gitignore index 32dffbd5d4a..2094d806f33 100644 --- a/.gitignore +++ b/.gitignore @@ -63,6 +63,8 @@ logs # Ignore files generated by scripts /example /testnet +bench/trace-schemas/types/ +bench/trace-schemas/messages/ .vscode/ diff --git a/Makefile b/Makefile index 9c95950da3b..7c469228364 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,18 @@ cli node: trace-documentation: cabal run -- exe:cardano-node trace-documentation --config 'configuration/cardano/mainnet-config.yaml' --output-file 'doc/new-tracing/tracers_doc_generated.md' +trace-schemas-regenerate: ## Regenerate trace schemas, apply overrides, validate + bash bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh + +trace-schemas-overrides-check: ## Check whether all schema overrides are applied + nix develop -c bash -lc "GHC_ENVIRONMENT=- runghc -package-env - bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --check --verbose" + +trace-schemas-overrides-coverage: ## Fail when generated schema files change without matching override sidecars (use RANGE=origin/master...HEAD in CI) + nix develop -c bash -lc "GHC_ENVIRONMENT=- runghc -package-env - bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs ${if ${RANGE},--range ${RANGE}}" + +trace-schemas-validate: ## Validate trace message schemas against meta.schema.json + nix develop -c bash -lc "GHC_ENVIRONMENT=- runghc -package-env - bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs" + ### ### Workbench ### diff --git a/bench/trace-schemas/TraceMessage.schema.json b/bench/trace-schemas/TraceMessage.schema.json new file mode 100644 index 00000000000..71ddbb4c889 --- /dev/null +++ b/bench/trace-schemas/TraceMessage.schema.json @@ -0,0 +1,51 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "io.example.tracing/TraceMessage.schema.json", + "title": "TraceMessage", + "description": "Common envelope for trace messages.", + "type": "object", + "additionalProperties": false, + "required": [ + "at", + "ns", + "sev", + "thread", + "host", + "data" + ], + "properties": { + "at": { + "type": "string", + "format": "date-time", + "description": "Timestamp of the trace event (RFC 3339 / ISO 8601)." + }, + "ns": { + "type": "string", + "description": "Trace namespace." + }, + "sev": { + "type": "string", + "description": "Severity level.", + "enum": [ + "Debug", + "Info", + "Notice", + "Warning", + "Error", + "Critical" + ] + }, + "thread": { + "type": "string", + "description": "Thread identifier." + }, + "host": { + "type": "string", + "description": "Host name or node identifier." + }, + "data": { + "description": "Payload of the trace message.", + "type": "object" + } + } +} diff --git a/bench/trace-schemas/meta.schema.json b/bench/trace-schemas/meta.schema.json new file mode 100644 index 00000000000..fc718c7c522 --- /dev/null +++ b/bench/trace-schemas/meta.schema.json @@ -0,0 +1,65 @@ +{ + "$id": "io.example.tracing/generated-schema-entry.json", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "additionalProperties": false, + "oneOf": [ + { + "not": { + "required": [ + "variants" + ] + }, + "required": [ + "data" + ] + }, + { + "not": { + "required": [ + "data" + ] + }, + "required": [ + "variants" + ] + } + ], + "properties": { + "data": { + "type": "object" + }, + "ns": { + "type": "string" + }, + "variants": { + "items": { + "additionalProperties": false, + "properties": { + "data": { + "type": "object" + }, + "detailLevel": { + "enum": [ + "Minimal", + "Normal", + "Detailed", + "Maximum" + ], + "type": "string" + } + }, + "required": [ + "detailLevel", + "data" + ], + "type": "object" + }, + "type": "array" + } + }, + "required": [ + "ns" + ], + "title": "GeneratedTraceSchemaEntry", + "type": "object" +} diff --git a/bench/trace-schemas/newNamespaces.txt b/bench/trace-schemas/newNamespaces.txt new file mode 100644 index 00000000000..fe7cdae72ae --- /dev/null +++ b/bench/trace-schemas/newNamespaces.txt @@ -0,0 +1,665 @@ +BlockFetch.Client.AcknowledgedFetchRequest +BlockFetch.Client.AddedFetchRequest +BlockFetch.Client.ClientMetrics +BlockFetch.Client.ClientTerminating +BlockFetch.Client.CompletedBlockFetch +BlockFetch.Client.CompletedFetchBatch +BlockFetch.Client.RejectedFetchBatch +BlockFetch.Client.SendFetchRequest +BlockFetch.Client.StartedFetchBatch +BlockFetch.Decision.Accept +BlockFetch.Decision.Decline +BlockFetch.Decision.EmptyPeersFetch +BlockFetch.Remote.Receive.BatchDone +BlockFetch.Remote.Receive.Block +BlockFetch.Remote.Receive.ClientDone +BlockFetch.Remote.Receive.NoBlocks +BlockFetch.Remote.Receive.RequestRange +BlockFetch.Remote.Receive.StartBatch +BlockFetch.Remote.Send.BatchDone +BlockFetch.Remote.Send.Block +BlockFetch.Remote.Send.ClientDone +BlockFetch.Remote.Send.NoBlocks +BlockFetch.Remote.Send.RequestRange +BlockFetch.Remote.Send.StartBatch +BlockFetch.Remote.Serialised.Receive.BatchDone +BlockFetch.Remote.Serialised.Receive.Block +BlockFetch.Remote.Serialised.Receive.ClientDone +BlockFetch.Remote.Serialised.Receive.NoBlocks +BlockFetch.Remote.Serialised.Receive.RequestRange +BlockFetch.Remote.Serialised.Receive.StartBatch +BlockFetch.Remote.Serialised.Send.BatchDone +BlockFetch.Remote.Serialised.Send.Block +BlockFetch.Remote.Serialised.Send.ClientDone +BlockFetch.Remote.Serialised.Send.NoBlocks +BlockFetch.Remote.Serialised.Send.RequestRange +BlockFetch.Remote.Serialised.Send.StartBatch +BlockFetch.Server.SendBlock +BlockchainTime.CurrentSlotUnknown +BlockchainTime.StartTimeInTheFuture +BlockchainTime.SystemClockMovedBack +ChainDB.AddBlockEvent.AddBlockValidation.InvalidBlock +ChainDB.AddBlockEvent.AddBlockValidation.UpdateLedgerDb +ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate +ChainDB.AddBlockEvent.AddedBlockToQueue +ChainDB.AddBlockEvent.AddedBlockToVolatileDB +ChainDB.AddBlockEvent.AddedReprocessLoEBlocksToQueue +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.ChainSelectionLoEDebug +ChainDB.AddBlockEvent.ChangingSelection +ChainDB.AddBlockEvent.IgnoreBlockAlreadyInVolatileDB +ChainDB.AddBlockEvent.IgnoreBlockOlderThanK +ChainDB.AddBlockEvent.IgnoreInvalidBlock +ChainDB.AddBlockEvent.PipeliningEvent.OutdatedTentativeHeader +ChainDB.AddBlockEvent.PipeliningEvent.SetTentativeHeader +ChainDB.AddBlockEvent.PipeliningEvent.TrapTentativeHeader +ChainDB.AddBlockEvent.PoppedBlockFromQueue +ChainDB.AddBlockEvent.PoppedReprocessLoEBlocksFromQueue +ChainDB.AddBlockEvent.PoppingFromQueue +ChainDB.AddBlockEvent.StoreButDontChange +ChainDB.AddBlockEvent.SwitchedToAFork +ChainDB.AddBlockEvent.TryAddToCurrentChain +ChainDB.AddBlockEvent.TrySwitchToAFork +ChainDB.AddPerasCertEvent.AddedPerasCertToQueue +ChainDB.AddPerasCertEvent.ChainSelectionForBoostedBlock +ChainDB.AddPerasCertEvent.IgnorePerasCertTooOld +ChainDB.AddPerasCertEvent.PerasCertBoostsBlockNotYetReceived +ChainDB.AddPerasCertEvent.PerasCertBoostsCurrentChain +ChainDB.AddPerasCertEvent.PerasCertBoostsGenesis +ChainDB.AddPerasCertEvent.PoppedPerasCertFromQueue +ChainDB.ChainSelStarvationEvent +ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB +ChainDB.CopyToImmutableDBEvent.NoBlocksToCopyToImmutableDB +ChainDB.FollowerEvent.FollowerNewImmIterator +ChainDB.FollowerEvent.FollowerNoLongerInMem +ChainDB.FollowerEvent.FollowerSwitchToMem +ChainDB.FollowerEvent.NewFollower +ChainDB.GCEvent.PerformedGC +ChainDB.GCEvent.ScheduledGC +ChainDB.ImmDbEvent.CacheEvent.CurrentChunkHit +ChainDB.ImmDbEvent.CacheEvent.PastChunkEvict +ChainDB.ImmDbEvent.CacheEvent.PastChunkExpired +ChainDB.ImmDbEvent.CacheEvent.PastChunkHit +ChainDB.ImmDbEvent.CacheEvent.PastChunkMiss +ChainDB.ImmDbEvent.ChunkFileDoesntFit +ChainDB.ImmDbEvent.ChunkValidation.InvalidChunkFile +ChainDB.ImmDbEvent.ChunkValidation.InvalidPrimaryIndex +ChainDB.ImmDbEvent.ChunkValidation.InvalidSecondaryIndex +ChainDB.ImmDbEvent.ChunkValidation.MissingChunkFile +ChainDB.ImmDbEvent.ChunkValidation.MissingPrimaryIndex +ChainDB.ImmDbEvent.ChunkValidation.MissingSecondaryIndex +ChainDB.ImmDbEvent.ChunkValidation.RewritePrimaryIndex +ChainDB.ImmDbEvent.ChunkValidation.RewriteSecondaryIndex +ChainDB.ImmDbEvent.ChunkValidation.StartedValidatingChunk +ChainDB.ImmDbEvent.ChunkValidation.ValidatedChunk +ChainDB.ImmDbEvent.DBAlreadyClosed +ChainDB.ImmDbEvent.DBClosed +ChainDB.ImmDbEvent.DeletingAfter +ChainDB.ImmDbEvent.Migrating +ChainDB.ImmDbEvent.NoValidLastLocation +ChainDB.ImmDbEvent.ValidatedLastLocation +ChainDB.InitChainSelEvent.InitialChainSelected +ChainDB.InitChainSelEvent.StartedInitChainSelection +ChainDB.InitChainSelEvent.Validation.InvalidBlock +ChainDB.InitChainSelEvent.Validation.UpdateLedgerDb +ChainDB.InitChainSelEvent.Validation.ValidCandidate +ChainDB.IteratorEvent.BlockGCedFromVolatileDB +ChainDB.IteratorEvent.BlockMissingFromVolatileDB +ChainDB.IteratorEvent.BlockWasCopiedToImmutableDB +ChainDB.IteratorEvent.StreamFromBoth +ChainDB.IteratorEvent.StreamFromImmutableDB +ChainDB.IteratorEvent.StreamFromVolatileDB +ChainDB.IteratorEvent.SwitchBackToVolatileDB +ChainDB.IteratorEvent.UnknownRangeRequested.ForkTooOld +ChainDB.IteratorEvent.UnknownRangeRequested.MissingBlock +ChainDB.LastShutdownUnclean +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.AlreadyClosed +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Closed +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Closing +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Copied +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Copying +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.CreatedValueHandle +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.CreatingValueHandle +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisedFromCopy +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisedFromValues +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisingFromCopy +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisingFromValues +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Opened +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Opening +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.AlreadyClosed +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Closed +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Closing +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.RangeRead +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.RangeReading +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Read +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Reading +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Statted +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Statting +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Writing +ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Written +ChainDB.LedgerEvent.Flavor.V1.LMDB.Initialise +ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMLookup +ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMOpenSession +ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMSnap +ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMTrace +ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMUpdate +ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleClose +ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleCreate +ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleCreateFirst +ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleDuplicate +ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandlePush +ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleRead +ChainDB.LedgerEvent.Forker.Close +ChainDB.LedgerEvent.Forker.Open +ChainDB.LedgerEvent.Forker.Push +ChainDB.LedgerEvent.Forker.RangeRead +ChainDB.LedgerEvent.Forker.Read +ChainDB.LedgerEvent.Forker.Statistics +ChainDB.LedgerEvent.Replay.ReplayProgress.ReplayedBlock +ChainDB.LedgerEvent.Replay.ReplayStart.ReplayFromGenesis +ChainDB.LedgerEvent.Replay.ReplayStart.ReplayFromSnapshot +ChainDB.LedgerEvent.Snapshot.DeletedSnapshot +ChainDB.LedgerEvent.Snapshot.InvalidSnapshot +ChainDB.LedgerEvent.Snapshot.TookSnapshot +ChainDB.OpenEvent.ClosedDB +ChainDB.OpenEvent.OpenedDB +ChainDB.OpenEvent.OpenedImmutableDB +ChainDB.OpenEvent.OpenedLgrDB +ChainDB.OpenEvent.OpenedVolatileDB +ChainDB.OpenEvent.StartedOpeningDB +ChainDB.OpenEvent.StartedOpeningImmutableDB +ChainDB.OpenEvent.StartedOpeningLgrDB +ChainDB.OpenEvent.StartedOpeningVolatileDB +ChainDB.PerasCertDbEvent.AddedPerasCert +ChainDB.PerasCertDbEvent.AddingPerasCert +ChainDB.PerasCertDbEvent.ClosedPerasCertDB +ChainDB.PerasCertDbEvent.IgnoredCertAlreadyInDB +ChainDB.PerasCertDbEvent.OpenedPerasCertDB +ChainDB.ReplayBlock.LedgerReplay +ChainDB.VolatileDbEvent.BlockAlreadyHere +ChainDB.VolatileDbEvent.DBAlreadyClosed +ChainDB.VolatileDbEvent.DBClosed +ChainDB.VolatileDbEvent.InvalidFileNames +ChainDB.VolatileDbEvent.Truncate +ChainSync.Client.AccessingForecastHorizon +ChainSync.Client.DownloadedHeader +ChainSync.Client.DrainingThePipe +ChainSync.Client.Exception +ChainSync.Client.FoundIntersection +ChainSync.Client.GaveLoPToken +ChainSync.Client.JumpResult +ChainSync.Client.JumpingInstructionIs +ChainSync.Client.JumpingWaitingForNextInstruction +ChainSync.Client.OfferJump +ChainSync.Client.RolledBack +ChainSync.Client.Termination +ChainSync.Client.ValidatedHeader +ChainSync.Client.WaitingBeyondForecastHorizon +ChainSync.Local.Receive.AwaitReply +ChainSync.Local.Receive.Done +ChainSync.Local.Receive.FindIntersect +ChainSync.Local.Receive.IntersectFound +ChainSync.Local.Receive.IntersectNotFound +ChainSync.Local.Receive.RequestNext +ChainSync.Local.Receive.RollBackward +ChainSync.Local.Receive.RollForward +ChainSync.Local.Send.AwaitReply +ChainSync.Local.Send.Done +ChainSync.Local.Send.FindIntersect +ChainSync.Local.Send.IntersectFound +ChainSync.Local.Send.IntersectNotFound +ChainSync.Local.Send.RequestNext +ChainSync.Local.Send.RollBackward +ChainSync.Local.Send.RollForward +ChainSync.Remote.Receive.AwaitReply +ChainSync.Remote.Receive.Done +ChainSync.Remote.Receive.FindIntersect +ChainSync.Remote.Receive.IntersectFound +ChainSync.Remote.Receive.IntersectNotFound +ChainSync.Remote.Receive.RequestNext +ChainSync.Remote.Receive.RollBackward +ChainSync.Remote.Receive.RollForward +ChainSync.Remote.Send.AwaitReply +ChainSync.Remote.Send.Done +ChainSync.Remote.Send.FindIntersect +ChainSync.Remote.Send.IntersectFound +ChainSync.Remote.Send.IntersectNotFound +ChainSync.Remote.Send.RequestNext +ChainSync.Remote.Send.RollBackward +ChainSync.Remote.Send.RollForward +ChainSync.Remote.Serialised.Receive.AwaitReply +ChainSync.Remote.Serialised.Receive.Done +ChainSync.Remote.Serialised.Receive.FindIntersect +ChainSync.Remote.Serialised.Receive.IntersectFound +ChainSync.Remote.Serialised.Receive.IntersectNotFound +ChainSync.Remote.Serialised.Receive.RequestNext +ChainSync.Remote.Serialised.Receive.RollBackward +ChainSync.Remote.Serialised.Receive.RollForward +ChainSync.Remote.Serialised.Send.AwaitReply +ChainSync.Remote.Serialised.Send.Done +ChainSync.Remote.Serialised.Send.FindIntersect +ChainSync.Remote.Serialised.Send.IntersectFound +ChainSync.Remote.Serialised.Send.IntersectNotFound +ChainSync.Remote.Serialised.Send.RequestNext +ChainSync.Remote.Serialised.Send.RollBackward +ChainSync.Remote.Serialised.Send.RollForward +ChainSync.ServerBlock.Update +ChainSync.ServerHeader.Update +Consensus.CSJ.BecomingObjector +Consensus.CSJ.BlockedOnJump +Consensus.CSJ.InitializedAsDynamo +Consensus.CSJ.NoLongerDynamo +Consensus.CSJ.NoLongerObjector +Consensus.CSJ.SentJumpInstruction +Consensus.DevotedBlockFetch.RotatedDynamo +Consensus.GDD.TraceGDDEvent +Consensus.GSM.EnterCaughtUp +Consensus.GSM.InitializedInCaughtUp +Consensus.GSM.InitializedInPreSyncing +Consensus.GSM.LeaveCaughtUp +Consensus.GSM.PreSyncingToSyncing +Consensus.GSM.SyncingToPreSyncing +Consensus.SanityCheck.SanityCheckIssue +Consensus.Startup.ConsensusStartupException +Forge.Loop.AdoptedBlock +Forge.Loop.AdoptionThreadDied +Forge.Loop.BlockContext +Forge.Loop.BlockFromFuture +Forge.Loop.DidntAdoptBlock +Forge.Loop.ForgeStateUpdateError +Forge.Loop.ForgeTickedLedgerState +Forge.Loop.ForgedBlock +Forge.Loop.ForgedInvalidBlock +Forge.Loop.ForgingMempoolSnapshot +Forge.Loop.LedgerState +Forge.Loop.LedgerView +Forge.Loop.NoLedgerState +Forge.Loop.NoLedgerView +Forge.Loop.NodeCannotForge +Forge.Loop.NodeIsLeader +Forge.Loop.NodeNotLeader +Forge.Loop.SlotIsImmutable +Forge.Loop.StartLeadershipCheck +Forge.StateInfo +Forge.ThreadStats.ForgingStats +LedgerMetrics +Mempool.AddedTx +Mempool.AttemptAdd +Mempool.ManuallyRemovedTxs +Mempool.RejectedTx +Mempool.RemoveTxs +Mempool.SyncNotNeeded +Mempool.Synced +Mempool.TipMovedBetweenSTMBlocks +Net.AcceptPolicy.ConnectionHardLimit +Net.AcceptPolicy.ConnectionLimitResume +Net.AcceptPolicy.ConnectionRateLimiting +Net.ConnectionManager.Local.Connect +Net.ConnectionManager.Local.ConnectError +Net.ConnectionManager.Local.ConnectionCleanup +Net.ConnectionManager.Local.ConnectionExists +Net.ConnectionManager.Local.ConnectionFailure +Net.ConnectionManager.Local.ConnectionHandler.Error +Net.ConnectionManager.Local.ConnectionHandler.HandshakeClientError +Net.ConnectionManager.Local.ConnectionHandler.HandshakeQuery +Net.ConnectionManager.Local.ConnectionHandler.HandshakeServerError +Net.ConnectionManager.Local.ConnectionHandler.HandshakeSuccess +Net.ConnectionManager.Local.ConnectionManagerCounters +Net.ConnectionManager.Local.ConnectionNotFound +Net.ConnectionManager.Local.ConnectionTimeWait +Net.ConnectionManager.Local.ConnectionTimeWaitDone +Net.ConnectionManager.Local.ForbiddenConnection +Net.ConnectionManager.Local.ForbiddenOperation +Net.ConnectionManager.Local.IncludeConnection +Net.ConnectionManager.Local.PruneConnections +Net.ConnectionManager.Local.Shutdown +Net.ConnectionManager.Local.State +Net.ConnectionManager.Local.TerminatedConnection +Net.ConnectionManager.Local.TerminatingConnection +Net.ConnectionManager.Local.UnexpectedlyFalseAssertion +Net.ConnectionManager.Local.UnregisterConnection +Net.ConnectionManager.Remote.Connect +Net.ConnectionManager.Remote.ConnectError +Net.ConnectionManager.Remote.ConnectionCleanup +Net.ConnectionManager.Remote.ConnectionExists +Net.ConnectionManager.Remote.ConnectionFailure +Net.ConnectionManager.Remote.ConnectionHandler.Error +Net.ConnectionManager.Remote.ConnectionHandler.HandshakeClientError +Net.ConnectionManager.Remote.ConnectionHandler.HandshakeQuery +Net.ConnectionManager.Remote.ConnectionHandler.HandshakeServerError +Net.ConnectionManager.Remote.ConnectionHandler.HandshakeSuccess +Net.ConnectionManager.Remote.ConnectionManagerCounters +Net.ConnectionManager.Remote.ConnectionNotFound +Net.ConnectionManager.Remote.ConnectionTimeWait +Net.ConnectionManager.Remote.ConnectionTimeWaitDone +Net.ConnectionManager.Remote.ForbiddenConnection +Net.ConnectionManager.Remote.ForbiddenOperation +Net.ConnectionManager.Remote.IncludeConnection +Net.ConnectionManager.Remote.PruneConnections +Net.ConnectionManager.Remote.Shutdown +Net.ConnectionManager.Remote.State +Net.ConnectionManager.Remote.TerminatedConnection +Net.ConnectionManager.Remote.TerminatingConnection +Net.ConnectionManager.Remote.UnexpectedlyFalseAssertion +Net.ConnectionManager.Remote.UnregisterConnection +Net.ConnectionManager.Transition.Transition +Net.InboundGovernor.Local.DemotedToColdRemote +Net.InboundGovernor.Local.DemotedToWarmRemote +Net.InboundGovernor.Local.Inactive +Net.InboundGovernor.Local.InboundGovernorCounters +Net.InboundGovernor.Local.InboundGovernorError +Net.InboundGovernor.Local.MaturedConnections +Net.InboundGovernor.Local.MuxCleanExit +Net.InboundGovernor.Local.MuxErrored +Net.InboundGovernor.Local.NewConnection +Net.InboundGovernor.Local.PromotedToHotRemote +Net.InboundGovernor.Local.PromotedToWarmRemote +Net.InboundGovernor.Local.RemoteState +Net.InboundGovernor.Local.ResponderErrored +Net.InboundGovernor.Local.ResponderRestarted +Net.InboundGovernor.Local.ResponderStartFailure +Net.InboundGovernor.Local.ResponderStarted +Net.InboundGovernor.Local.ResponderTerminated +Net.InboundGovernor.Local.UnexpectedlyFalseAssertion +Net.InboundGovernor.Local.WaitIdleRemote +Net.InboundGovernor.Remote.DemotedToColdRemote +Net.InboundGovernor.Remote.DemotedToWarmRemote +Net.InboundGovernor.Remote.Inactive +Net.InboundGovernor.Remote.InboundGovernorCounters +Net.InboundGovernor.Remote.InboundGovernorError +Net.InboundGovernor.Remote.MaturedConnections +Net.InboundGovernor.Remote.MuxCleanExit +Net.InboundGovernor.Remote.MuxErrored +Net.InboundGovernor.Remote.NewConnection +Net.InboundGovernor.Remote.PromotedToHotRemote +Net.InboundGovernor.Remote.PromotedToWarmRemote +Net.InboundGovernor.Remote.RemoteState +Net.InboundGovernor.Remote.ResponderErrored +Net.InboundGovernor.Remote.ResponderRestarted +Net.InboundGovernor.Remote.ResponderStartFailure +Net.InboundGovernor.Remote.ResponderStarted +Net.InboundGovernor.Remote.ResponderTerminated +Net.InboundGovernor.Remote.UnexpectedlyFalseAssertion +Net.InboundGovernor.Remote.WaitIdleRemote +Net.InboundGovernor.Transition.Transition +Net.KeepAliveClient +Net.Mux.Local.CleanExit +Net.Mux.Local.ExceptionExit +Net.Mux.Local.NewMux +Net.Mux.Local.StartEagerly +Net.Mux.Local.StartOnDemand +Net.Mux.Local.StartOnDemandAny +Net.Mux.Local.StartedOnDemand +Net.Mux.Local.Starting +Net.Mux.Local.State +Net.Mux.Local.Stopped +Net.Mux.Local.Stopping +Net.Mux.Local.Terminating +Net.Mux.Remote.CleanExit +Net.Mux.Remote.ExceptionExit +Net.Mux.Remote.NewMux +Net.Mux.Remote.StartEagerly +Net.Mux.Remote.StartOnDemand +Net.Mux.Remote.StartOnDemandAny +Net.Mux.Remote.StartedOnDemand +Net.Mux.Remote.Starting +Net.Mux.Remote.State +Net.Mux.Remote.Stopped +Net.Mux.Remote.Stopping +Net.Mux.Remote.Terminating +Net.PeerSelection.Actions.ConnectionError +Net.PeerSelection.Actions.MonitoringError +Net.PeerSelection.Actions.MonitoringResult +Net.PeerSelection.Actions.PeerHotDuration +Net.PeerSelection.Actions.StatusChangeFailure +Net.PeerSelection.Actions.StatusChanged +Net.PeerSelection.Counters.Counters +Net.PeerSelection.Initiator.GovernorState +Net.PeerSelection.Responder.GovernorState +Net.PeerSelection.Selection.BigLedgerPeersFailure +Net.PeerSelection.Selection.BigLedgerPeersRequest +Net.PeerSelection.Selection.BigLedgerPeersResults +Net.PeerSelection.Selection.BootstrapPeersFlagChangedWhilstInSensitiveState +Net.PeerSelection.Selection.ChurnAction +Net.PeerSelection.Selection.ChurnTimeout +Net.PeerSelection.Selection.ChurnWait +Net.PeerSelection.Selection.DebugState +Net.PeerSelection.Selection.DemoteAsynchronous +Net.PeerSelection.Selection.DemoteBigLedgerPeersAsynchronous +Net.PeerSelection.Selection.DemoteHotBigLedgerPeerDone +Net.PeerSelection.Selection.DemoteHotBigLedgerPeerFailed +Net.PeerSelection.Selection.DemoteHotBigLedgerPeerFailed.CoolingToColdTimeout +Net.PeerSelection.Selection.DemoteHotBigLedgerPeers +Net.PeerSelection.Selection.DemoteHotDone +Net.PeerSelection.Selection.DemoteHotFailed +Net.PeerSelection.Selection.DemoteHotFailed.CoolingToColdTimeout +Net.PeerSelection.Selection.DemoteHotPeers +Net.PeerSelection.Selection.DemoteLocalAsynchronous +Net.PeerSelection.Selection.DemoteLocalHotPeers +Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerDone +Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerFailed +Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerFailed.CoolingToColdTimeout +Net.PeerSelection.Selection.DemoteWarmBigLedgerPeers +Net.PeerSelection.Selection.DemoteWarmDone +Net.PeerSelection.Selection.DemoteWarmFailed +Net.PeerSelection.Selection.DemoteWarmFailed.CoolingToColdTimeout +Net.PeerSelection.Selection.DemoteWarmPeers +Net.PeerSelection.Selection.ForgetBigLedgerPeers +Net.PeerSelection.Selection.ForgetColdPeers +Net.PeerSelection.Selection.GovernorWakeup +Net.PeerSelection.Selection.LedgerStateJudgementChanged +Net.PeerSelection.Selection.LocalRootPeersChanged +Net.PeerSelection.Selection.OnlyBootstrapPeers +Net.PeerSelection.Selection.OutboundGovernorCriticalFailure +Net.PeerSelection.Selection.PeerShareRequests +Net.PeerSelection.Selection.PeerShareResults +Net.PeerSelection.Selection.PeerShareResultsFiltered +Net.PeerSelection.Selection.PickInboundPeers +Net.PeerSelection.Selection.PromoteColdBigLedgerPeerDone +Net.PeerSelection.Selection.PromoteColdBigLedgerPeerFailed +Net.PeerSelection.Selection.PromoteColdBigLedgerPeers +Net.PeerSelection.Selection.PromoteColdDone +Net.PeerSelection.Selection.PromoteColdFailed +Net.PeerSelection.Selection.PromoteColdLocalPeers +Net.PeerSelection.Selection.PromoteColdPeers +Net.PeerSelection.Selection.PromoteWarmAborted +Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerAborted +Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerDone +Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerFailed +Net.PeerSelection.Selection.PromoteWarmBigLedgerPeers +Net.PeerSelection.Selection.PromoteWarmDone +Net.PeerSelection.Selection.PromoteWarmFailed +Net.PeerSelection.Selection.PromoteWarmLocalPeers +Net.PeerSelection.Selection.PromoteWarmPeers +Net.PeerSelection.Selection.PublicRootsFailure +Net.PeerSelection.Selection.PublicRootsRequest +Net.PeerSelection.Selection.PublicRootsResults +Net.PeerSelection.Selection.TargetsChanged +Net.PeerSelection.Selection.UseBootstrapPeersChanged +Net.PeerSelection.Selection.VerifyPeerSnapshot +Net.Peers.Ledger.DisabledLedgerPeers +Net.Peers.Ledger.FallingBackToPublicRootPeers +Net.Peers.Ledger.FetchingNewLedgerState +Net.Peers.Ledger.NotEnoughBigLedgerPeers +Net.Peers.Ledger.NotEnoughLedgerPeers +Net.Peers.Ledger.PickedBigLedgerPeer +Net.Peers.Ledger.PickedBigLedgerPeers +Net.Peers.Ledger.PickedLedgerPeer +Net.Peers.Ledger.PickedLedgerPeers +Net.Peers.Ledger.RequestForPeers +Net.Peers.Ledger.ReusingLedgerState +Net.Peers.Ledger.TraceLedgerPeersDomains +Net.Peers.Ledger.TraceUseLedgerAfter +Net.Peers.Ledger.UsingBigLedgerPeerSnapshot +Net.Peers.Ledger.WaitingOnRequest +Net.Peers.LocalRoot.LocalRootDNSMap +Net.Peers.LocalRoot.LocalRootDomains +Net.Peers.LocalRoot.LocalRootError +Net.Peers.LocalRoot.LocalRootFailure +Net.Peers.LocalRoot.LocalRootGroups +Net.Peers.LocalRoot.LocalRootReconfigured +Net.Peers.LocalRoot.LocalRootWaiting +Net.Peers.PublicRoot.PublicRootDomains +Net.Peers.PublicRoot.PublicRootRelayAccessPoint +Net.Server.Local.AcceptConnection +Net.Server.Local.AcceptError +Net.Server.Local.AcceptPolicy +Net.Server.Local.Error +Net.Server.Local.Started +Net.Server.Local.Stopped +Net.Server.Remote.AcceptConnection +Net.Server.Remote.AcceptError +Net.Server.Remote.AcceptPolicy +Net.Server.Remote.Error +Net.Server.Remote.Started +Net.Server.Remote.Stopped +NodeInfo +NodeStartupInfo +NodeState.NodeAddBlock +NodeState.NodeInitChainSelection +NodeState.NodeKernelOnline +NodeState.NodeReplays +NodeState.NodeShutdown +NodeState.NodeStartup +NodeState.NodeTracingFailure +NodeState.NodeTracingForwardingInterrupted +NodeState.NodeTracingOnlineConfiguring +NodeState.OpeningDbs +NodeState.PrometheusSimple.Start +NodeState.PrometheusSimple.Stop +RPC.Error +RPC.FatalError +RPC.QueryService.ReadParams.Span +RPC.QueryService.ReadUtxos.Span +RPC.SubmitService.N2cConnectionError +RPC.SubmitService.SubmitTx.Span +RPC.SubmitService.TxDecodingError +RPC.SubmitService.TxValidationError +Reflection.MetricsInfo +Reflection.RememberLimiting +Reflection.StartLimiting +Reflection.StopLimiting +Reflection.TracerConfigInfo +Reflection.TracerConsistencyWarnings +Reflection.TracerInfo +Reflection.UnknownNamespace +Resources +Shutdown.Abnormal +Shutdown.ArmedAt +Shutdown.Requested +Shutdown.Requesting +Shutdown.UnexpectedInput +Startup.BlockForgingBlockTypeMismatch +Startup.BlockForgingUpdate +Startup.Byron +Startup.Common +Startup.DBValidation +Startup.DiffusionInit.ConfiguringLocalSocket +Startup.DiffusionInit.ConfiguringServerSocket +Startup.DiffusionInit.CreateSystemdSocketForSnocketPath +Startup.DiffusionInit.CreatedLocalSocket +Startup.DiffusionInit.CreatingServerSocket +Startup.DiffusionInit.DiffusionErrored +Startup.DiffusionInit.ListeningLocalSocket +Startup.DiffusionInit.ListeningServerSocket +Startup.DiffusionInit.LocalSocketUp +Startup.DiffusionInit.RunLocalServer +Startup.DiffusionInit.RunServer +Startup.DiffusionInit.ServerSocketUp +Startup.DiffusionInit.SystemdSocketConfiguration +Startup.DiffusionInit.UnsupportedLocalSystemdSocket +Startup.DiffusionInit.UnsupportedReadySocketCase +Startup.DiffusionInit.UsingSystemdSocket +Startup.Info +Startup.LedgerPeerSnapshot +Startup.LedgerPeerSnapshot.Incompatible +Startup.MovedTopLevelOption +Startup.Network +Startup.NetworkConfig +Startup.NetworkConfigUpdate +Startup.NetworkConfigUpdateError +Startup.NetworkConfigUpdateUnsupported +Startup.NetworkMagic +Startup.NonP2PWarning +Startup.P2PInfo +Startup.ShelleyBased +Startup.SocketConfigError +Startup.Time +Startup.WarningDevelopmentNodeToClientVersions +Startup.WarningDevelopmentNodeToNodeVersions +StateQueryServer.Receive.Acquire +StateQueryServer.Receive.Acquired +StateQueryServer.Receive.Done +StateQueryServer.Receive.Failure +StateQueryServer.Receive.Query +StateQueryServer.Receive.ReAcquire +StateQueryServer.Receive.Release +StateQueryServer.Receive.Result +StateQueryServer.Send.Acquire +StateQueryServer.Send.Acquired +StateQueryServer.Send.Done +StateQueryServer.Send.Failure +StateQueryServer.Send.Query +StateQueryServer.Send.ReAcquire +StateQueryServer.Send.Release +StateQueryServer.Send.Result +TxSubmission.Local.Receive.AcceptTx +TxSubmission.Local.Receive.Done +TxSubmission.Local.Receive.RejectTx +TxSubmission.Local.Receive.SubmitTx +TxSubmission.Local.Send.AcceptTx +TxSubmission.Local.Send.Done +TxSubmission.Local.Send.RejectTx +TxSubmission.Local.Send.SubmitTx +TxSubmission.LocalServer.ReceivedTx +TxSubmission.MonitorClient.Receive.Acquire +TxSubmission.MonitorClient.Receive.Acquired +TxSubmission.MonitorClient.Receive.AwaitAcquire +TxSubmission.MonitorClient.Receive.Done +TxSubmission.MonitorClient.Receive.GetMeasures +TxSubmission.MonitorClient.Receive.GetSizes +TxSubmission.MonitorClient.Receive.HasTx +TxSubmission.MonitorClient.Receive.NextTx +TxSubmission.MonitorClient.Receive.Release +TxSubmission.MonitorClient.Receive.ReplyGetMeasures +TxSubmission.MonitorClient.Receive.ReplyGetSizes +TxSubmission.MonitorClient.Receive.ReplyHasTx +TxSubmission.MonitorClient.Receive.ReplyNextTx +TxSubmission.MonitorClient.Send.Acquire +TxSubmission.MonitorClient.Send.Acquired +TxSubmission.MonitorClient.Send.AwaitAcquire +TxSubmission.MonitorClient.Send.Done +TxSubmission.MonitorClient.Send.GetMeasures +TxSubmission.MonitorClient.Send.GetSizes +TxSubmission.MonitorClient.Send.HasTx +TxSubmission.MonitorClient.Send.NextTx +TxSubmission.MonitorClient.Send.Release +TxSubmission.MonitorClient.Send.ReplyGetMeasures +TxSubmission.MonitorClient.Send.ReplyGetSizes +TxSubmission.MonitorClient.Send.ReplyHasTx +TxSubmission.MonitorClient.Send.ReplyNextTx +TxSubmission.Remote.Receive.Done +TxSubmission.Remote.Receive.MsgInit +TxSubmission.Remote.Receive.ReplyTxIds +TxSubmission.Remote.Receive.ReplyTxs +TxSubmission.Remote.Receive.RequestTxIds +TxSubmission.Remote.Receive.RequestTxs +TxSubmission.Remote.Send.Done +TxSubmission.Remote.Send.MsgInit +TxSubmission.Remote.Send.ReplyTxIds +TxSubmission.Remote.Send.ReplyTxs +TxSubmission.Remote.Send.RequestTxIds +TxSubmission.Remote.Send.RequestTxs +TxSubmission.TxInbound.AddedToMempool +TxSubmission.TxInbound.CanRequestMoreTxs +TxSubmission.TxInbound.CannotRequestMoreTxs +TxSubmission.TxInbound.Collected +TxSubmission.TxInbound.Decision +TxSubmission.TxInbound.Error +TxSubmission.TxInbound.Processed +TxSubmission.TxInbound.RejectedFromMempool +TxSubmission.TxInbound.Terminated +TxSubmission.TxOutbound.ControlMessage +TxSubmission.TxOutbound.RecvMsgRequest +TxSubmission.TxOutbound.SendMsgReply +Version.NodeVersion diff --git a/bench/trace-schemas/overrides/README.md b/bench/trace-schemas/overrides/README.md new file mode 100644 index 00000000000..593a5443126 --- /dev/null +++ b/bench/trace-schemas/overrides/README.md @@ -0,0 +1,181 @@ +# Trace Schema Overrides + +Use this directory for human-maintained patches that must survive schema regeneration. + +## Why + +Files under `bench/trace-schemas/messages` and `bench/trace-schemas/types` are generated. +Direct edits in those generated files are hard to track and can be overwritten. + +Store manual changes as sidecar override files here instead. + +## Layout + +Mirror the generated tree, with `.override.json` suffix: + +- `bench/trace-schemas/overrides/messages/.../Foo.schema.override.json` +- `bench/trace-schemas/overrides/types/.../Bar.schema.override.json` + +Each override maps to a target by: + +- removing the `overrides/` path segment +- replacing `.schema.override.json` with `.schema.json` + +Example: + +- Override: `bench/trace-schemas/overrides/messages/Startup/Info.schema.override.json` +- Target: `bench/trace-schemas/messages/Startup/Info.schema.json` + +## Override format + +Override files use JSON Merge Patch semantics (RFC 7396). + +You can use either: + +1. A raw patch object. +2. An envelope with metadata: + +```json +{ + "_meta": { + "owner": "tracing-team", + "reason": "Keep strict enum until upstream type metadata is available", + }, + "patch": { + "data": { + "properties": { + "kind": { + "enum": ["ExpectedKindA", "ExpectedKindB"] + } + } + } + } +} +``` + +Notes: + +- Set a key to `null` in a patch to delete it. +- Arrays are replaced as whole values (standard merge-patch behavior). + +### RFC 7396 behavior summary + +Merge Patch is value-oriented and simple: + +- If the patch is an object, it is merged key-by-key into the target object. +- If a patch key value is `null`, that key is removed from the target object. +- If a patch key value is an object, merge continues recursively. +- If a patch key value is a scalar (`string`, `number`, `boolean`) or an array, that value fully replaces the target value. +- If the patch itself is not an object (for example an array or string), it replaces the whole target document. + +Practical implications for schema overrides: + +- Prefer object patches to avoid replacing entire schema files. +- Be explicit when patching `required`: it is an array, so your patch replaces the full `required` list. +- Deleting one item from an array is not supported directly by merge patch; replace the array with the exact desired final array. +- Keep patches focused to the minimal affected subtree to reduce conflicts during regeneration. + +### Mini before/after example + +Target fragment: + +```json +{ + "data": { + "properties": { + "kind": { "type": "string" }, + "error": { "type": "string" } + }, + "required": ["kind"] + } +} +``` + +Patch: + +```json +{ + "data": { + "properties": { + "error": null, + "kind": { + "enum": ["A", "B"] + } + }, + "required": ["kind", "code"] + } +} +``` + +Result: + +- `data.properties.error` is removed. +- `data.properties.kind` is updated (merged/replaced under that key). +- `data.required` becomes exactly `["kind", "code"]`. + +## Examples + +Concrete example files are also available in: + +`bench/trace-schemas/overrides/examples/` + +### 1) Raw patch: tighten an enum in a message schema + +`bench/trace-schemas/overrides/messages/Startup/Info.schema.override.json` + +```json +{ + "data": { + "properties": { + "kind": { + "enum": ["StartupInfo", "StartupInfoLegacy"] + } + } + } +} +``` + +### 2) Envelope patch with metadata: add description and required field + +`bench/trace-schemas/overrides/messages/Net/Server/Local/Error.schema.override.json` + +```json +{ + "_meta": { + "owner": "tracing-team", + "reason": "Document operator-facing semantics", + }, + "patch": { + "data": { + "description": "Local server accept loop error payload", + "required": ["kind", "error"] + } + } +} +``` + +### 3) Delete generated key: remove an unwanted property + +`bench/trace-schemas/overrides/types/ConnectionId.schema.override.json` + +```json +{ + "properties": { + "legacyDebugField": null + } +} +``` + +## Apply / Check + +Apply overrides: + +`nix develop -c bash -lc "runghc -package-env - bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --verbose"` + +Check that overrides are already applied: + +`nix develop -c bash -lc "runghc -package-env - bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --check --verbose"` + +Fail when generated schema files changed without matching override file updates: + +`nix develop -c bash -lc "runghc -package-env - bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs --range origin/master...HEAD"` diff --git a/bench/trace-schemas/overrides/examples/01-startup-info.schema.override.example.json b/bench/trace-schemas/overrides/examples/01-startup-info.schema.override.example.json new file mode 100644 index 00000000000..e121b260fea --- /dev/null +++ b/bench/trace-schemas/overrides/examples/01-startup-info.schema.override.example.json @@ -0,0 +1,13 @@ +{ + "_target": "bench/trace-schemas/messages/Startup/Info.schema.json", + "data": { + "properties": { + "kind": { + "enum": [ + "StartupInfo", + "StartupInfoLegacy" + ] + } + } + } +} diff --git a/bench/trace-schemas/overrides/examples/02-net-server-local-error.schema.override.example.json b/bench/trace-schemas/overrides/examples/02-net-server-local-error.schema.override.example.json new file mode 100644 index 00000000000..0ec68cd5f9a --- /dev/null +++ b/bench/trace-schemas/overrides/examples/02-net-server-local-error.schema.override.example.json @@ -0,0 +1,16 @@ +{ + "_target": "bench/trace-schemas/messages/Net/Server/Local/Error.schema.json", + "_meta": { + "owner": "tracing-team", + "reason": "Document operator-facing semantics" + }, + "patch": { + "data": { + "description": "Local server accept loop error payload", + "required": [ + "kind", + "error" + ] + } + } +} \ No newline at end of file diff --git a/bench/trace-schemas/overrides/examples/03-connection-id.schema.override.example.json b/bench/trace-schemas/overrides/examples/03-connection-id.schema.override.example.json new file mode 100644 index 00000000000..513e2cf3520 --- /dev/null +++ b/bench/trace-schemas/overrides/examples/03-connection-id.schema.override.example.json @@ -0,0 +1,6 @@ +{ + "_target": "bench/trace-schemas/types/ConnectionId.schema.json", + "properties": { + "legacyDebugField": null + } +} diff --git a/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs b/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs new file mode 100644 index 00000000000..3067875627d --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs @@ -0,0 +1,253 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Main (main) where + +import qualified Data.Aeson as A +import qualified Data.Aeson.Encode.Pretty as AP +import qualified Data.Aeson.Key as K +import qualified Data.Aeson.KeyMap as KM +import qualified Data.ByteString.Lazy as BL +import Control.Monad (forM, unless, when) +import Data.List (isSuffixOf, sort) +import System.Directory + ( createDirectoryIfMissing + , doesDirectoryExist + , doesFileExist + , listDirectory + ) +import System.Environment (getArgs) +import System.Exit (exitFailure, exitSuccess) +import System.FilePath ((), takeDirectory, takeFileName) + +defaultRoot :: FilePath +defaultRoot = "bench/trace-schemas" + +data Config = Config + { cfgRoot :: FilePath + , cfgCheck :: Bool + , cfgVerbose :: Bool + , cfgAllowDestructive :: Bool + } + +defaultConfig :: Config +defaultConfig = + Config + { cfgRoot = defaultRoot + , cfgCheck = False + , cfgVerbose = False + , cfgAllowDestructive = False + } + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + let overridesRoot = cfgRoot config "overrides" + overridesExists <- doesDirectoryExist overridesRoot + if not overridesExists + then do + when (cfgVerbose config) $ + putStrLn $ "No overrides directory at " <> overridesRoot + exitSuccess + else do + overrideFiles <- sort <$> listOverrideFiles overridesRoot + results <- forM overrideFiles (processOverride config) + let changedTargets = [target | (target, True) <- results] + when (cfgCheck config && not (null changedTargets)) $ do + putStrLn "Schema overrides are not applied (or generated files were edited directly):" + mapM_ (\fp -> putStrLn $ " " <> fp) changedTargets + exitFailure + when (cfgVerbose config) $ do + putStrLn $ "Processed " <> show (length overrideFiles) <> " override file(s)." + putStrLn $ "Updated " <> show (length changedTargets) <> " target schema file(s)." + exitSuccess + +parseArgs :: Config -> [String] -> IO Config +parseArgs config args = go config args + where + go cfg [] = pure cfg + go cfg ("--root" : root : rest) = go cfg {cfgRoot = root} rest + go cfg ("--check" : rest) = go cfg {cfgCheck = True} rest + go cfg ("--verbose" : rest) = go cfg {cfgVerbose = True} rest + go cfg ("--allow-destructive" : rest) = go cfg {cfgAllowDestructive = True} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs [options]" + , "" + , "Options:" + , " --root PATH trace-schemas root path (default: bench/trace-schemas)" + , " --check Dry-run; fail if any target file would change" + , " --verbose Print each override mapping" + , " --allow-destructive Allow overrides that delete or replace existing fields" + ] + +listOverrideFiles :: FilePath -> IO [FilePath] +listOverrideFiles root = do + entries <- listDirectory root + fmap concat $ + forM entries $ \name -> do + let path = root name + isDir <- doesDirectoryExist path + if isDir + then listOverrideFiles path + else pure [path | ".override.json" `isSuffixOf` name] + +processOverride :: Config -> FilePath -> IO (FilePath, Bool) +processOverride config overrideFile = do + let overridesRoot = cfgRoot config "overrides" + rel <- stripPrefixPath overridesRoot overrideFile + targetRel <- overrideRelToTarget rel + let targetFile = cfgRoot config targetRel + + targetExists <- doesFileExist targetFile + unless targetExists $ + failWith $ + "Override target does not exist: " <> targetFile + <> " (from " <> overrideFile <> ")" + + targetValue <- readJsonFile targetFile + overrideValue <- readJsonFile overrideFile + patchValue <- normalizePatch overrideFile overrideValue + + unless (cfgAllowDestructive config) $ do + let destructiveOps = findDestructiveOps targetValue patchValue + unless (null destructiveOps) $ + failWith $ + "Override " <> overrideFile <> " contains destructive operations:\n" + <> unlines (map (" " <>) destructiveOps) + <> "Pass --allow-destructive to permit destructive overrides." + + let mergedValue = mergePatch targetValue patchValue + let changed = mergedValue /= targetValue + + when (cfgVerbose config) $ + putStrLn $ overrideFile <> " -> " <> targetFile + + when (changed && not (cfgCheck config)) $ do + createDirectoryIfMissing True (takeDirectory targetFile) + BL.writeFile targetFile (AP.encodePretty mergedValue) + + pure (targetFile, changed) + +readJsonFile :: FilePath -> IO A.Value +readJsonFile fp = do + bs <- BL.readFile fp + case A.eitherDecode bs of + Left err -> failWith $ "Invalid JSON in " <> fp <> ": " <> err + Right v -> pure v + +normalizePatch :: FilePath -> A.Value -> IO A.Value +normalizePatch source v@(A.Object o) = + case KM.lookup (K.fromString "patch") o of + Nothing -> pure v + Just patch@(A.Object _) -> pure patch + Just _ -> + failWith $ + "Override \"patch\" must be an object in " <> source +normalizePatch source _ = + failWith $ "Override must be a JSON object: " <> source + +-- | Returns human-readable descriptions of operations that would delete or +-- replace existing fields when applying @patch@ to @target@. An empty list +-- means the patch is non-destructive (only adds new keys or deep-merges +-- objects). +findDestructiveOps :: A.Value -> A.Value -> [String] +findDestructiveOps target patch = goObj "" targetObj patchObj + where + targetObj = case target of { A.Object o -> o; _ -> KM.empty } + patchObj = case patch of { A.Object o -> o; _ -> KM.empty } + + goObj path tObj pObj = concatMap (checkKey path tObj) (KM.toList pObj) + + checkKey path tObj (k, pv) = + let kStr = K.toString k + keyPath = if null path then kStr else path <> "." <> kStr + in case (KM.lookup k tObj, pv) of + (Nothing, _) -> [] -- new key: not destructive + (Just _, A.Null) -> [keyPath <> ": field deletion"] + (Just (A.Object tv), A.Object pv') -> + goObj keyPath tv pv' -- recurse: only destructive if inner keys are + (Just _, _) -> [keyPath <> ": field replacement"] + +mergePatch :: A.Value -> A.Value -> A.Value +mergePatch _ patch@(A.Null) = patch +mergePatch _ patch@(A.Bool _) = patch +mergePatch _ patch@(A.String _) = patch +mergePatch _ patch@(A.Number _) = patch +mergePatch _ patch@(A.Array _) = patch +mergePatch target (A.Object patchObj) = + let targetObj = + case target of + A.Object o -> o + _ -> KM.empty + in A.Object (mergeObject targetObj patchObj) + +mergeObject :: A.Object -> A.Object -> A.Object +mergeObject target patch = KM.foldrWithKey step target patch + where + step key value acc = + case value of + A.Null -> KM.delete key acc + A.Object _ -> + let existing = + case KM.lookup key acc of + Just v -> v + Nothing -> A.Null + merged = mergePatch existing value + in KM.insert key merged acc + _ -> KM.insert key value acc + +stripPrefixPath :: FilePath -> FilePath -> IO FilePath +stripPrefixPath prefix full = + case stripPrefixList (splitPath prefix) (splitPath full) of + Just suffix -> pure (joinPath suffix) + Nothing -> + failWith $ + "Path " <> full <> " is not under " <> prefix + +overrideRelToTarget :: FilePath -> IO FilePath +overrideRelToTarget rel = do + let name = takeFileName rel + let suffix = ".override.json" :: String + unless (suffix `isSuffixOf` name) $ + failWith $ "Override must end with .override.json: " <> rel + let targetName = take (length name - length suffix) name <> ".json" + pure (replaceFileName rel targetName) + +splitPath :: FilePath -> [FilePath] +splitPath path = filter (not . null) (go path) + where + go "" = [] + go p = + case break (== '/') p of + (a, []) -> [a] + (a, _:rest) -> a : go rest + +joinPath :: [FilePath] -> FilePath +joinPath [] = "" +joinPath (x:xs) = foldl () x xs + +replaceFileName :: FilePath -> FilePath -> FilePath +replaceFileName path newName = + case reverse (splitPath path) of + [] -> newName + (_old:dirsRev) -> joinPath (reverse dirsRev <> [newName]) + +stripPrefixList :: Eq a => [a] -> [a] -> Maybe [a] +stripPrefixList [] ys = Just ys +stripPrefixList _ [] = Nothing +stripPrefixList (x:xs) (y:ys) + | x == y = stripPrefixList xs ys + | otherwise = Nothing + +failWith :: String -> IO a +failWith msg = putStrLn ("ERROR: " <> msg) >> exitFailure diff --git a/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs b/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs new file mode 100644 index 00000000000..c8ab9608b6d --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs @@ -0,0 +1,106 @@ +{-# LANGUAGE ScopedTypeVariables #-} + +module Main (main) where + +import Control.Monad (unless, when) +import Data.List (isPrefixOf, isSuffixOf, sort) +import qualified Data.Set as Set +import System.Environment (getArgs) +import System.Exit (ExitCode (..), exitFailure, exitSuccess) +import System.Process (proc, readCreateProcessWithExitCode) + +generatedRoots :: [FilePath] +generatedRoots = + [ "bench/trace-schemas/messages" + , "bench/trace-schemas/types" + ] + +overridesRoot :: FilePath +overridesRoot = "bench/trace-schemas/overrides" + +data Config = Config + { cfgRange :: Maybe String + } + +defaultConfig :: Config +defaultConfig = Config {cfgRange = Nothing} + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + generatedChanged <- listChangedPaths config generatedRoots + overrideChanged <- Set.fromList <$> listChangedPaths config [overridesRoot] + + let generatedChangedSet = Set.fromList (filter isGeneratedJson generatedChanged) + let requiredOverrideFiles = Set.map generatedToOverride generatedChangedSet + let missing = sort (Set.toList (Set.difference requiredOverrideFiles overrideChanged)) + + when (null generatedChangedSet) $ do + putStrLn "No generated trace-schema files changed." + exitSuccess + + unless (null missing) $ do + putStrLn "Generated schema files changed without matching override sidecar updates:" + mapM_ (\fp -> putStrLn $ " " <> fp) missing + putStrLn "" + putStrLn "Update corresponding files under bench/trace-schemas/overrides/." + exitFailure + + putStrLn "Override coverage check passed." + exitSuccess + +parseArgs :: Config -> [String] -> IO Config +parseArgs config args = go config args + where + go cfg [] = pure cfg + go cfg ("--range" : r : rest) = go cfg {cfgRange = Just r} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs [options]" + , "" + , "Options:" + , " --range GIT_RANGE Diff range to inspect, e.g. origin/master...HEAD" + ] + +listChangedPaths :: Config -> [FilePath] -> IO [FilePath] +listChangedPaths config paths = do + let baseArgs = + case cfgRange config of + Just r -> ["diff", "--name-only", r, "--"] + Nothing -> ["diff", "--name-only", "--"] + args = baseArgs <> paths + (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "git" args) "" + case exitCode of + ExitSuccess -> pure (filter (not . null) (lines stdoutText)) + ExitFailure _ -> do + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + exitFailure + +isGeneratedJson :: FilePath -> Bool +isGeneratedJson path = + any (`isPrefixOf` path) generatedRoots + && ".schema.json" `isSuffixOf` path + +generatedToOverride :: FilePath -> FilePath +generatedToOverride generatedPath = + case stripPrefixPath "bench/trace-schemas/" generatedPath of + Just rel -> + let withoutSuffix = take (length rel - length ".json") rel + in overridesRoot <> "/" <> withoutSuffix <> ".override.json" + Nothing -> generatedPath + +stripPrefixPath :: FilePath -> FilePath -> Maybe FilePath +stripPrefixPath prefix path = + if prefix `isPrefixOf` path + then Just (drop (length prefix) path) + else Nothing diff --git a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs new file mode 100644 index 00000000000..073a1f1dd79 --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs @@ -0,0 +1,2032 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module Main (main) where + +import qualified Data.Text as T +import qualified Data.Text.IO as T +import qualified Data.Map.Strict as Map +import qualified Data.Set as Set +import qualified Data.Aeson.KeyMap as KM +import qualified Data.Aeson.Key as K +import qualified Data.Vector as V +import Data.Char (isAlphaNum, isLower, isUpper, isSpace, toLower) +import Data.List (elemIndex, isPrefixOf, isSuffixOf, sortOn) +import Data.Maybe (catMaybes, listToMaybe, mapMaybe) +import System.Directory +import System.Environment (getArgs) +import System.FilePath +import System.Process +import System.Exit +import System.IO +import Data.IORef +import Control.Exception (catch, IOException) +import System.IO.Unsafe (unsafePerformIO) +import Control.Exception (bracket) +import qualified Data.Aeson as A +import qualified Data.Aeson.Encode.Pretty as AP +import qualified Data.ByteString.Lazy as BL +import qualified Data.ByteString.Lazy.Char8 as BL8 +import Control.Monad (forM, guard, unless, when) + +-------------------------------------------------------------------------------- +-- Entry point / high-level flow +-------------------------------------------------------------------------------- + +rootDirs :: [FilePath] +rootDirs = + [ "cardano-node/src" + , "cardano-submit-api/src" + , "cardano-tracer/src" + , "../ouroboros-network/ouroboros-network/lib" + , "../ouroboros-network/ouroboros-network/tracing" + , "../ouroboros-network/ouroboros-network/protocols/lib" + , "../ouroboros-network/ouroboros-network/api/lib" + , "../ouroboros-network/network-mux/src" + , "../ouroboros-network/cardano-diffusion/lib" + , "../ouroboros-network/cardano-diffusion/tracing" + , "../ouroboros-network/cardano-diffusion/protocols/lib" + , "../ouroboros-network/cardano-diffusion/api/lib" + , "../ouroboros-network/cardano-diffusion/subscription" + , "../ouroboros-consensus/ouroboros-consensus/src/ouroboros-consensus" + , "../ouroboros-consensus/ouroboros-consensus-protocol/src/ouroboros-consensus-protocol" + , "../ouroboros-consensus/ouroboros-consensus-diffusion/src/ouroboros-consensus-diffusion" + , "../ouroboros-consensus/ouroboros-consensus-cardano/src" + , "../hermod-tracing/trace-dispatcher/src" + , "trace-forward/src" + , "trace-resources/src" + ] + +type ConstructorName = String +type TypeName = String +type NamespaceParts = [String] +type DetailLevel = String +type HelperFieldMap = Map.Map String (Map.Map String String) + +diffusionHandshakeCtor :: ConstructorName +diffusionHandshakeCtor = "__DiffusionHandshakeAnyMessageAndAgency__" + +serialisedBlockFetchMsgBlockCtor :: ConstructorName +serialisedBlockFetchMsgBlockCtor = "__SerialisedBlockFetchMsgBlock__" + +connectionManagerStateCtor :: ConstructorName +connectionManagerStateCtor = "TrState" + +muxStateCtor :: ConstructorName +muxStateCtor = "TraceState" + +connectionManagerUnexpectedlyFalseAssertionCtor :: ConstructorName +connectionManagerUnexpectedlyFalseAssertionCtor = "__ConnectionManagerUnexpectedlyFalseAssertion__" + +inboundGovernorUnexpectedlyFalseAssertionCtor :: ConstructorName +inboundGovernorUnexpectedlyFalseAssertionCtor = "__InboundGovernorUnexpectedlyFalseAssertion__" + +detailLevels :: [DetailLevel] +detailLevels = ["Minimal", "Normal", "Detailed", "Maximum"] + +data Config = Config + { cfgPruneStaleProperties :: Bool + } + +main :: IO () +main = do + warningsRef <- newIORef [] + let emitWarning msg = do + hPutStrLn stderr msg + modifyIORef' warningsRef (<> [msg]) + config <- parseArgs =<< getArgs + let nsFile = "bench/trace-schemas/newNamespaces.txt" + putStrLn $ "Reading namespaces from " <> nsFile + namespaces <- filter (not . null) . map T.unpack . T.lines <$> T.readFile nsFile + putStrLn $ "Loaded " <> show (length namespaces) <> " namespace(s)" + + validatedRootDirs <- validateSourceDirs emitWarning rootDirs + putStrLn "Collecting Haskell source files..." + hsFiles <- collectTargets validatedRootDirs + putStrLn $ "Found " <> show (length hsFiles) <> " candidate source file(s)" + + -- Build constructor -> namespace map from namespaceFor clauses + putStrLn "Building namespace map..." + let sources = map (\fp -> (fp, readFileSafe fp)) hsFiles + let nsMap = foldl' mergeNs Map.empty [ normalizeNamespaceMap fp (parseNamespaceMap src) | (fp, src) <- sources ] + -- Parse forMachine clauses and map their field bindings to variables + putStrLn "Parsing forMachine clauses..." + let helperFieldMaps = map (parseObjectHelperMap . snd) sources + let clausesByFile = + [ (fp, parseForMachineClauses src, helpers) + | ((fp, src), helpers) <- zip sources helperFieldMaps + ] + + let fieldVarMap = + foldl' + (Map.unionWith (Map.unionWith Map.union)) + Map.empty + [ normalizeFieldVarMap fp (parseFieldVarMap helpers clauses) + | (fp, clauses, helpers) <- clausesByFile + ] + + -- Ask GHCi for variable types used in forMachine patterns + putStrLn "Querying GHCi for field types..." + varTypesMaps <- forM (zip [1 :: Int ..] clausesByFile) $ \(idx, (fp, clauses, _helpers)) -> do + putStrLn $ + "[ghci " <> show idx <> "/" <> show (length clausesByFile) <> "] " + <> fp + normalizeVarTypesMap fp <$> ghciTypesForFile fp clauses + let varTypes = foldl' (Map.unionWith Map.union) Map.empty varTypesMaps + + let msgOutDir = "bench/trace-schemas/messages" + let typeOutDir = "bench/trace-schemas/types" + createDirectoryIfMissing True msgOutDir + createDirectoryIfMissing True typeOutDir + + putStrLn "Generating schema files..." + mapM_ + (\(idx, ns) -> do + putStrLn $ + "[schema " <> show idx <> "/" <> show (length namespaces) <> "] " + <> ns + updateSchemaForNamespaceWithWarning emitWarning config msgOutDir typeOutDir nsMap fieldVarMap varTypes ns) + (zip [1 :: Int ..] namespaces) + putStrLn "Schema generation complete." + warnings <- readIORef warningsRef + unless (null warnings) $ do + let uniqueWarnings = nubPreserve warnings + putStrLn "" + putStrLn $ + "Schema generation warnings summary (" <> show (length uniqueWarnings) <> " unique warning(s)):" + mapM_ putStrLn uniqueWarnings + putStrLn $ + "Schema generation problems: " <> show (length (nubPreserve warnings)) + +parseArgs :: [String] -> IO Config +parseArgs args = + case args of + [] -> pure (Config False) + ["--prune-stale-properties"] -> pure (Config True) + ["--help"] -> printHelp >> exitSuccess + ["-h"] -> printHelp >> exitSuccess + _ -> do + putStrLn $ "Unrecognized arguments: " <> unwords args + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: nix develop -c bash -c 'runghc bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs [--prune-stale-properties]'" + , "" + , "Options:" + , " --prune-stale-properties Remove data.properties not supported by current inference." + ] + +-- Utilities + +foldl' :: (b -> a -> b) -> b -> [a] -> b +foldl' f z xs = go z xs where go acc [] = acc; go acc (y:ys) = let acc' = f acc y in acc' `seq` go acc' ys + +validateSourceDirs :: (String -> IO ()) -> [FilePath] -> IO [FilePath] +validateSourceDirs emitWarning dirs = do + dirPresence <- forM dirs $ \dir -> do + exists <- doesDirectoryExist dir + pure (dir, exists) + let missingDirs = [dir | (dir, False) <- dirPresence] + existingDirs = [dir | (dir, True) <- dirPresence] + mapM_ (\dir -> emitWarning $ "Warning: source directory missing: " <> dir) missingDirs + when (null existingDirs) $ do + hPutStrLn stderr "Error: no configured source directories exist for schema generation." + exitFailure + pure existingDirs + +-- Read file for quick text parsing; tolerate missing files. +readFileSafe :: FilePath -> String +readFileSafe fp = unsafePerformIO (readFile fp `catch` (\(_e :: IOException) -> pure "")) + +collectTargets :: [FilePath] -> IO [FilePath] +collectTargets roots = do + files <- fmap concat $ mapM listHsFiles roots + fmap catMaybes $ mapM (\fp -> do + content <- T.readFile fp + if "forMachine" `T.isInfixOf` content || "namespaceFor" `T.isInfixOf` content + then pure (Just fp) + else pure Nothing) files + +listHsFiles :: FilePath -> IO [FilePath] +listHsFiles root = do + exists <- doesDirectoryExist root + if not exists then pure [] else go root + where + go dir = do + entries <- listDirectory dir + fmap concat $ mapM (\e -> do + let p = dir e + isDir <- doesDirectoryExist p + if isDir then go p else pure [p | ".hs" `isSuffixOf` p]) entries + +-- Namespace mapping + +mergeNs :: Map.Map ConstructorName [NamespaceParts] + -> Map.Map ConstructorName [NamespaceParts] + -> Map.Map ConstructorName [NamespaceParts] +mergeNs = Map.unionWith (++) + +-- Parse namespaceFor clauses and collect constructor -> namespace mappings. +parseNamespaceMap :: String -> Map.Map ConstructorName [NamespaceParts] +parseNamespaceMap src = go Nothing (lines src) Map.empty + where + typeConstructors = parseTypeConstructors src + + startsHeader line = + "namespaceFor" `isPrefixOf` trim line + + go _ [] acc = acc + go currentType allLines@(l:ls) acc + | startsMetaTraceInstance l = + let (_hdr, rest, nextType) = spanMetaTraceInstanceHeader allLines + in go nextType rest acc + | startsTopLevelDecl l = + go Nothing ls acc + | startsHeader l = + let (headerLines, afterHeader) = spanUntilHeaderEnd [l] ls + (bodyLines, rest) = spanNamespaceBody afterHeader + clauseLines = headerLines ++ bodyLines + header = unwords headerLines + bodyAfterLambda = dropLeadingLambdaCase bodyLines + acc' = + if "\\case" `isInfix` header || isLambdaCaseBody bodyLines + then foldl' insertNamespaceClause acc (parseNamespaceLambdaClauses bodyAfterLambda) + else if hasBranchArrows bodyLines + then case ctorsAfter "namespaceFor" (takeWhile (/= '=') (unwords headerLines)) of + [] -> acc + ctors -> foldl' insertNamespaceClause acc (parseNamespaceCaseBranches ctors bodyLines) + else case extractNamespaceClause currentType typeConstructors (unwords clauseLines) of + Just clauseInfo -> insertNamespaceClause acc clauseInfo + Nothing -> acc + in go currentType rest acc' + | otherwise = go currentType ls acc + + spanUntilHeaderEnd acc [] = (reverse acc, []) + spanUntilHeaderEnd acc (x:xs) + | any ("=" `isInfix`) acc = (reverse acc, x:xs) + | otherwise = spanUntilHeaderEnd (x:acc) xs + + spanNamespaceBody [] = ([], []) + spanNamespaceBody allLines@(x:xs) + | startsTopLevelMethod x = ([], allLines) + | otherwise = + let (body, rest) = span (not . startsTopLevelMethod) xs + in (x : body, rest) + + startsTopLevelMethod line = + let t = trim line + in any (`isPrefixOf` t) + [ "namespaceFor" + , "severityFor" + , "privacyFor" + , "detailsFor" + , "documentFor" + , "allNamespaces" + , "metricsDocFor" + ] + + startsTopLevelDecl line = + let t = trim line + in not (null line) + && not (isSpace (head line)) + && not ("--" `isPrefixOf` t) + && any (`isPrefixOf` t) + [ "instance" + , "data " + , "newtype " + , "type " + , "class " + ] + + startsMetaTraceInstance line = + let t = trim line + in "instance" `isPrefixOf` t && "MetaTrace" `isInfix` t + + spanMetaTraceInstanceHeader :: [String] -> ([String], [String], Maybe TypeName) + spanMetaTraceInstanceHeader [] = ([], [], Nothing) + spanMetaTraceInstanceHeader (x:xs) = finish [x] xs + where + finish acc [] = + let hdr = reverse acc + in (hdr, [], parseMetaTraceInstanceType (unwords hdr)) + finish acc rest@(y:ys) + | any ("where" `isInfix`) acc = + let hdr = reverse acc + in (hdr, rest, parseMetaTraceInstanceType (unwords hdr)) + | otherwise = finish (y:acc) ys + + extractNamespaceClause currentType ctorMap clause = do + guard ("namespaceFor" `isInfix` clause) + let lhs = takeWhile (/= '=') clause + parts <- extractNamespaceParts clause + let ctors = ctorsAfter "namespaceFor" lhs + let inferredCtors = + case ctors of + [] | isWildcardNamespaceLhs lhs -> + maybe [] (\ty -> singletonConstructors ty ctorMap) currentType + [] | isListEmptyNamespaceLhs lhs -> + [listEmptyCtor] + _ -> ctors + guard (not (null inferredCtors)) + pure (inferredCtors, parts) + +parseMetaTraceInstanceType :: String -> Maybe TypeName +parseMetaTraceInstanceType hdr = do + (_, rest) <- breakSub "MetaTrace" hdr + let tyExpr = trim . takeWhile (/= '=') . fst $ breakOn "where" (stripOuterParens (trim rest)) + guard (not (null tyExpr)) + guard (head tyExpr /= '[') + firstCtorToken tyExpr + +isWildcardNamespaceLhs :: String -> Bool +isWildcardNamespaceLhs lhs = + let marker = ("namespaceFor" :: String) + after = trim (drop (length marker) lhs) + in after == "_" + +isListEmptyNamespaceLhs :: String -> Bool +isListEmptyNamespaceLhs lhs = + let marker = ("namespaceFor" :: String) + after = trim (drop (length marker) lhs) + in after == "[]" + +listEmptyCtor :: ConstructorName +listEmptyCtor = "__list_empty__" + +singletonConstructors :: TypeName -> Map.Map TypeName [ConstructorName] -> [ConstructorName] +singletonConstructors ty ctorMap = + case Map.lookup ty ctorMap of + Just [ctor] -> [ctor] + _ -> [] + +parseTypeConstructors :: String -> Map.Map TypeName [ConstructorName] +parseTypeConstructors src = go (lines src) Map.empty + where + go [] acc = acc + go allLines@(l:ls) acc + | startsTypeDecl l = + let (declLines, rest) = spanTypeDecl allLines + acc' = case parseTypeDecl (unwords declLines) of + Just (ty, ctors) | not (null ctors) -> Map.insert ty ctors acc + _ -> acc + in go rest acc' + | otherwise = go ls acc + + startsTypeDecl line = + let t = trim line + in not (null line) + && not (isSpace (head line)) + && (("data " `isPrefixOf` t) || ("newtype " `isPrefixOf` t)) + + spanTypeDecl [] = ([], []) + spanTypeDecl (x:xs) = step [x] xs + where + step acc [] = (reverse acc, []) + step acc rest@(y:ys) + | any hasDeclBody acc && startsNextTopLevel y = (reverse acc, rest) + | otherwise = step (y:acc) ys + + hasDeclBody line = + "=" `isInfix` line || " where" `isInfix` line + + startsNextTopLevel line = + let t = trim line + in not (null line) + && not (isSpace (head line)) + && not ("--" `isPrefixOf` t) + + parseTypeDecl decl = do + let t = trim decl + keyword <- if ("data " :: String) `isPrefixOf` t + then Just ("data " :: String) + else if ("newtype " :: String) `isPrefixOf` t + then Just ("newtype " :: String) + else Nothing + let afterKeyword = trim (drop (length keyword) t) + tyName = takeWhile (\c -> isAlphaNum c || c == '_' || c == '\'') afterKeyword + guard (not (null tyName)) + (_, rhsText0) <- breakSub "=" afterKeyword + let rhsText = trim rhsText0 + let ctorSegments = splitTopLevelBars rhsText + ctors = mapMaybe firstCtorToken ctorSegments + guard (not (null ctors)) + pure (tyName, nubPreserve ctors) + +splitTopLevelBars :: String -> [String] +splitTopLevelBars s = go 0 0 0 "" [] s + where + go _ _ _ cur acc [] = reverse (trim cur : acc) + go paren bracket brace cur acc (c:cs) + | c == '(' = go (paren + 1) bracket brace (cur ++ [c]) acc cs + | c == ')' = go (paren - 1) bracket brace (cur ++ [c]) acc cs + | c == '[' = go paren (bracket + 1) brace (cur ++ [c]) acc cs + | c == ']' = go paren (bracket - 1) brace (cur ++ [c]) acc cs + | c == '{' = go paren bracket (brace + 1) (cur ++ [c]) acc cs + | c == '}' = go paren bracket (brace - 1) (cur ++ [c]) acc cs + | c == '|' && paren == 0 && bracket == 0 && brace == 0 = + go paren bracket brace "" (trim cur : acc) cs + | otherwise = go paren bracket brace (cur ++ [c]) acc cs + +extractNamespaceParts :: String -> Maybe NamespaceParts +extractNamespaceParts clause = + case extractNsPrependInnerParts clause ++ extractNamespaceLiteralParts clause of + [] -> Nothing + parts -> Just parts + +extractNsPrependInnerParts :: String -> NamespaceParts +extractNsPrependInnerParts clause = + case breakOn "nsPrependInner" clause of + (_, "") -> [] + (_, rhs) -> take 1 (quotedStrings rhs) + +extractNamespaceLiteralParts :: String -> NamespaceParts +extractNamespaceLiteralParts clause = + case breakOn "Namespace" clause of + (_, "") -> [] + (_, rhs) -> quotedStrings rhs + +insertNamespaceClause :: Map.Map ConstructorName [NamespaceParts] + -> ([ConstructorName], NamespaceParts) + -> Map.Map ConstructorName [NamespaceParts] +insertNamespaceClause acc (ctors, parts) = + foldl' (\m ctor -> Map.insertWith (++) ctor [parts] m) acc ctors + +isLambdaCaseBody :: [String] -> Bool +isLambdaCaseBody (l:_) = "\\case" `isInfix` trim l +isLambdaCaseBody _ = False + +dropLeadingLambdaCase :: [String] -> [String] +dropLeadingLambdaCase (l:ls) + | "\\case" `isInfix` trim l = ls +dropLeadingLambdaCase ls = ls + +hasBranchArrows :: [String] -> Bool +hasBranchArrows = any ("->" `isInfix`) + +parseNamespaceLambdaClauses :: [String] -> [([ConstructorName], NamespaceParts)] +parseNamespaceLambdaClauses = mapMaybe parseBranch . go + where + go [] = [] + go (l:ls) + | "->" `isInfix` l = + let (pat0, rhs0) = case breakSub "->" l of + Just (a, b) -> (trim a, trim b) + Nothing -> ("", "") + (more, rest) = spanBranchLines ls + body = unwords ([rhs0 | not (null rhs0)] ++ more) + in (pat0, body) : go rest + | otherwise = go ls + + spanBranchLines = step [] + where + step acc [] = (reverse acc, []) + step acc allLines@(x:xs) + | isBranchStart x = (reverse acc, allLines) + | otherwise = step (x:acc) xs + + isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + + parseBranch (pat, body) = do + let parts = quotedStrings body + let ctors = ctorTokens pat + if null parts || null ctors then Nothing else Just (ctors, parts) + +parseNamespaceCaseBranches :: [ConstructorName] -> [String] -> [([ConstructorName], NamespaceParts)] +parseNamespaceCaseBranches ctors = mapMaybe parseBranch . go + where + go [] = [] + go (l:ls) + | "->" `isInfix` l = + let (_pat0, rhs0) = case breakSub "->" l of + Just (a, b) -> (trim a, trim b) + Nothing -> ("", "") + (more, rest) = spanBranchLines ls + body = unwords ([rhs0 | not (null rhs0)] ++ more) + in body : go rest + | otherwise = go ls + + spanBranchLines = step [] + where + step acc [] = (reverse acc, []) + step acc allLines@(x:xs) + | isBranchStart x = (reverse acc, allLines) + | otherwise = step (x:acc) xs + + isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + + parseBranch body = do + let parts = quotedStrings body + if null parts then Nothing else Just (ctors, parts) + + +firstCtorAfter :: String -> String -> Maybe String +firstCtorAfter marker line = + case ctorsAfter marker line of + (x:_) -> Just x + [] -> Nothing + +ctorsAfter :: String -> String -> [String] +ctorsAfter marker line = + case T.splitOn (T.pack marker) (T.pack line) of + (_:rest:_) -> ctorTokens (T.unpack rest) + _ -> ctorTokens line + +firstCtorToken :: String -> Maybe String +firstCtorToken s = + case normalizedCtorTokens s of + [] -> Nothing + xs -> Just (selectCtorToken xs) + +ctorTokens :: String -> [String] +ctorTokens s = nubPreserve (normalizedCtorTokens s) + +quotedStrings :: String -> [String] +quotedStrings [] = [] +quotedStrings ('"':xs) = + let (a, b) = break (== '"') xs + in a : quotedStrings (drop 1 b) +quotedStrings (_:xs) = quotedStrings xs + +-- forMachine parsing + +data Clause = Clause + { clauseLevel :: String + , clauseType :: Maybe TypeName + , clauseCtor :: Maybe ConstructorName + , clausePattern :: String + , clauseBody :: [String] + } + +parseObjectHelperMap :: String -> HelperFieldMap +parseObjectHelperMap src = + Map.fromList + [ (name, fields) + | (name, body) <- helperBodies (lines src) + , let fields = parseHelperFields body + , not (Map.null fields) + ] + where + helperNames = + Set.fromList + [ trim (takeWhile (\c -> isAlphaNum c || c == '_') l) + | l <- lines src + , "::" `isInfix` l + , "Aeson.Object" `isInfix` l + ] + + helperBodies [] = [] + helperBodies (l:ls) + | Just name <- helperDefName l + , name `Set.member` helperNames + , "= \\case" `isInfix` l = + let (body, rest) = spanIndented ls + in (name, body) : helperBodies rest + | otherwise = helperBodies ls + + helperDefName l = + let t = trim l + nm = takeWhile (\c -> isAlphaNum c || c == '_') t + in if null nm then Nothing else Just nm + + spanIndented = go [] + where + go acc [] = (reverse acc, []) + go acc allLines@(x:xs) + | isTopLevelDecl x = (reverse acc, allLines) + | otherwise = go (x:acc) xs + + isTopLevelDecl l = + not (null l) + && not (isSpace (head l)) + && not ("--" `isPrefixOf` trim l) + + parseHelperFields body = + foldl' (Map.unionWith preferSpecific) Map.empty (mapMaybe parseBranch (helperBranches body)) + + helperBranches [] = [] + helperBranches (l:ls) + | "->" `isInfix` l = + let (pat0, rhs0) = case breakSub "->" l of + Just (a, b) -> (trim a, trim b) + Nothing -> ("", "") + (more, rest) = spanBranchLines ls + body = [rhs0 | not (null rhs0)] ++ more + in Clause "" Nothing Nothing pat0 body : helperBranches rest + | otherwise = helperBranches ls + + spanBranchLines = go [] + where + go acc [] = (reverse acc, []) + go acc allLines@(x:xs) + | isBranchStart x = (reverse acc, allLines) + | isTopLevelDecl x = (reverse acc, allLines) + | otherwise = go (x:acc) xs + + isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + + parseBranch cl = + let vars = Set.fromList (extractVars (clausePattern cl)) + pairs = mapMaybe (parseFieldLine vars) (collectFieldEntries (clauseBody cl)) + in if null pairs then Nothing else Just (Map.fromListWith preferSpecific pairs) + + preferSpecific old new + | old == literalStringVar = new + | otherwise = old + +-- Extract forMachine function clauses with their patterns and bodies. +parseForMachineClauses :: String -> [Clause] +parseForMachineClauses src = go Nothing (lines src) + where + typeConstructors = parseTypeConstructors src + + startsHeader line = + let t = trim line + in "forMachine" `isPrefixOf` t || "forMachineGov" `isPrefixOf` t + hasEquals line = "=" `isInfix` line + go _ [] = [] + go currentType allLines@(l:ls) + | startsLogFormattingInstance l = + let (_hdr, rest, nextType) = spanInstanceHeader "LogFormatting" allLines + in go nextType rest + | startsTopLevelDeclForMachine l = + go Nothing ls + | startsHeader l = + let (headerLines, afterHeader) = spanUntilHeaderEnd [l] ls + header = unwords headerLines + (lvlTok, pat) = parseHeader header + (body, rest) = span (not . startsHeader) afterHeader + bodyAfterLambda = dropLeadingLambdaCase body + mkClause pat' body' = Clause lvlTok currentType (inferClauseCtor typeConstructors currentType pat') pat' body' + in if "\\case" `isInfix` header || isLambdaCaseBody body + then parseLambdaCaseClauses lvlTok currentType typeConstructors bodyAfterLambda ++ go currentType rest + else expandNestedCaseClauses lvlTok currentType typeConstructors pat body ++ go currentType rest + | otherwise = go currentType ls + + spanUntilHeaderEnd acc [] = (reverse acc, []) + spanUntilHeaderEnd acc (x:xs) + | any hasEquals acc = (reverse acc, x:xs) + | otherwise = spanUntilHeaderEnd (x:acc) xs + + startsLogFormattingInstance line = + let t = trim line + in "instance" `isPrefixOf` t && "LogFormatting" `isInfix` t + + startsTopLevelDeclForMachine line = + let t = trim line + in not (null line) + && not (isSpace (head line)) + && not ("--" `isPrefixOf` t) + && any (`isPrefixOf` t) + [ "instance" + , "data " + , "newtype " + , "type " + , "class " + ] + +parseLambdaCaseClauses :: String -> Maybe TypeName -> Map.Map TypeName [ConstructorName] -> [String] -> [Clause] +parseLambdaCaseClauses lvl currentType typeConstructors = go + where + go [] = [] + go (l:ls) + | "->" `isInfix` l = + let (pat0, rhs0) = case breakSub "->" l of + Just (a, b) -> (trim a, trim b) + Nothing -> ("", "") + (more, rest) = spanBranchLines ls + body = [rhs0 | not (null rhs0)] ++ more + in expandNestedCaseClauses lvl currentType typeConstructors pat0 body ++ go rest + | otherwise = go ls + + spanBranchLines = step [] + where + step acc [] = (reverse acc, []) + step acc allLines@(x:xs) + | isBranchStart x = (reverse acc, allLines) + | otherwise = step (x:acc) xs + + isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + +expandNestedCaseClauses :: String -> Maybe TypeName -> Map.Map TypeName [ConstructorName] -> String -> [String] -> [Clause] +expandNestedCaseClauses lvl currentType typeConstructors pat body = + case splitCaseOnBoundVar (Set.fromList (extractVars pat)) body of + Just (prefix, branchLines) -> + Clause lvl currentType (inferClauseCtor typeConstructors currentType pat) pat body + : concatMap descend (parseLambdaCaseClauses lvl currentType typeConstructors branchLines) + where + descend cl = expandNestedCaseClauses lvl currentType typeConstructors (clausePattern cl) (prefix ++ clauseBody cl) + Nothing -> + [Clause lvl currentType (inferClauseCtor typeConstructors currentType pat) pat body] + +splitCaseOnBoundVar :: Set.Set String -> [String] -> Maybe ([String], [String]) +splitCaseOnBoundVar boundVars = go [] + where + go _ [] = Nothing + go acc (line:rest) = + case splitCaseLine boundVars line of + Just prefixLine -> + let prefix = reverse acc ++ [prefixLine | not (null (trim prefixLine))] + in Just (prefix, rest) + Nothing -> go (line:acc) rest + +splitCaseLine :: Set.Set String -> String -> Maybe String +splitCaseLine boundVars line = + listToMaybe + [ trim prefix + | var <- Set.toList boundVars + , let needle = "case " <> var <> " of" + , Just (prefix, _) <- [breakSub needle line] + ] + +parseHeader :: String -> (String, String) +parseHeader line = + let ws = words line + keyword = case () of + _ | "forMachineGov" `isInfix` line -> "forMachineGov" + | otherwise -> "forMachine" + lvl = case dropWhile (/= keyword) ws of + (_:l:_) -> l + _ -> "_" + pat = case breakSub keyword line of + Just (_, rest) -> + let rhs = dropWhile isSpace rest + afterLvl = dropWhile isSpace (drop (length lvl) rhs) + in stripOuterParens (trim (takeWhile (/= '=') afterLvl)) + Nothing -> "" + in (lvl, pat) + +spanInstanceHeader :: String -> [String] -> ([String], [String], Maybe TypeName) +spanInstanceHeader className [] = ([], [], Nothing) +spanInstanceHeader className (x:xs) = finish [x] xs + where + finish acc [] = + let hdr = reverse acc + in (hdr, [], parseInstanceTypeForClass className (unwords hdr)) + finish acc rest@(y:ys) + | any ("where" `isInfix`) acc = + let hdr = reverse acc + in (hdr, rest, parseInstanceTypeForClass className (unwords hdr)) + | otherwise = finish (y:acc) ys + +parseInstanceTypeForClass :: String -> String -> Maybe TypeName +parseInstanceTypeForClass className hdr = do + (_, rest) <- breakSub className hdr + let tyExpr = trim . takeWhile (/= '=') . fst $ breakOn "where" (stripOuterParens (trim rest)) + guard (not (null tyExpr)) + guard (head tyExpr /= '[') + firstCtorToken tyExpr + +stripOuterParens :: String -> String +stripOuterParens s + | headMay s == Just '(' + , lastMay s == Just ')' + , parensWrapWhole s = trim (init (tail s)) + | otherwise = s + +parensWrapWhole :: String -> Bool +parensWrapWhole = go 0 + where + go _ [] = True + go depth (c:cs) + | c == '(' = go (depth + 1) cs + | c == ')' = + let depth' = depth - 1 + in depth' >= 0 + && (depth' /= 0 || null cs) + && go depth' cs + | otherwise = go depth cs + +-- Variables that appear in a forMachine pattern. +extractVars :: String -> [String] +extractVars s = filter (not . null) $ filter isVarToken (tokenize s) + where + isVarToken (c:_) = isLower c || c == '_' + isVarToken _ = False + +isRelevantVar :: String -> Bool +isRelevantVar [] = False +isRelevantVar ('_':_) = False +isRelevantVar _ = True + +tokenize :: String -> [String] +tokenize = filter (not . null) . splitTokens + where + splitTokens [] = [] + splitTokens xs = + let (tok, rest) = span isTokenChar xs + rest' = dropWhile (not . isTokenChar) rest + in tok : splitTokens rest' + isTokenChar c = isAlphaNum c || c == '_' || c == '\'' || c == '.' + +ctorFromPattern :: String -> Maybe String +ctorFromPattern pat = case normalizedCtorTokens pat of + [] -> Nothing + xs -> Just (selectCtorToken xs) + where + isCtorToken (c:_) = isUpper c + isCtorToken _ = False + +normalizeCtorToken :: String -> String +normalizeCtorToken tok = + case reverse (splitOn "." tok) of + (x:_) -> x + [] -> tok + +normalizedCtorTokens :: String -> [String] +normalizedCtorTokens = + map normalizeCtorToken . filter isCtorToken . tokenize + where + isCtorToken (c:_) = isUpper c + isCtorToken _ = False + +nubPreserve :: Ord a => [a] -> [a] +nubPreserve = go Set.empty + where + go _ [] = [] + go seen (x:xs) + | Set.member x seen = go seen xs + | otherwise = x : go (Set.insert x seen) xs + +selectCtorToken :: [String] -> String +selectCtorToken [] = "" +selectCtorToken [x] = x +selectCtorToken xs@(x:_) + | x `elem` ["AnyMessageAndAgency", "AnyMessage"] = last xs + | otherwise = x + +inferClauseCtor :: Map.Map TypeName [ConstructorName] -> Maybe TypeName -> String -> Maybe ConstructorName +inferClauseCtor typeConstructors currentType pat = + case ctorFromPattern pat of + Just ctor -> Just ctor + Nothing + | trim pat == "[]" -> Just listEmptyCtor + Nothing + | isVariableOnlyPattern pat -> + currentType >>= \ty -> + case Map.lookup ty typeConstructors of + Just [ctor] -> Just ctor + _ -> Nothing + | otherwise -> Nothing + +isVariableOnlyPattern :: String -> Bool +isVariableOnlyPattern pat = + case filter isRelevantVar (extractVars pat) of + [_] -> null (normalizedCtorTokens pat) + _ -> False + +-- Map JSON field keys to the pattern variable they come from. +parseFieldVarMap :: HelperFieldMap -> [Clause] -> Map.Map ConstructorName (Map.Map DetailLevel (Map.Map String String)) +parseFieldVarMap helperMap clauses = foldl' step Map.empty clauses + where + step acc cl = + case clauseCtor cl of + Nothing -> acc + Just ctor -> + let vars = Set.fromList (filter isRelevantVar (extractVars (clausePattern cl))) + lvls = case clauseLevel cl of + "DMinimal" -> ["Minimal"] + "DNormal" -> ["Normal"] + "DDetailed" -> ["Detailed"] + "DMaximum" -> ["Maximum"] + _ -> detailLevels + sanitizedBody = stripCommentBlocks (clauseBody cl) + directPairs = mapMaybe (parseFieldLine vars) (collectFieldEntries sanitizedBody) + helperPairs = concatMap helperPairsForLine sanitizedBody + pairs = Map.toList (Map.fromListWith preferSpecific (directPairs ++ helperPairs)) + addOne m (k,v) = foldl' (\mm lvl -> Map.insertWith (Map.union) lvl (Map.singleton k v) mm) m lvls + in Map.insertWith (Map.unionWith Map.union) ctor (foldl' addOne Map.empty pairs) acc + + helperPairsForLine line = + concatMap helperPairsForName (tokenize line) + + helperPairsForName name = + maybe [] Map.toList (Map.lookup name helperMap) + + preferSpecific old new + | old == literalStringVar = new + | old == renderedStringVar && new /= renderedStringVar = new + | otherwise = old + +collectFieldEntries :: [String] -> [String] +collectFieldEntries = finalize . foldl' step [] + where + step :: [String] -> String -> [String] + step [] line + | ".=" `isInfix` line = [line] + | otherwise = [] + step acc@(cur:rest) line + | fieldEntryNeedsContinuation cur = (cur <> " " <> trim line) : rest + | ".=" `isInfix` line = line : acc + | otherwise = acc + + finalize = concatMap splitFieldFragments . reverse . filter (".=" `isInfix`) + + splitFieldFragments :: String -> [String] + splitFieldFragments = + filter (".=" `isInfix`) . map trim . splitTopLevelCommasGeneral . stripOuterList . trim + + stripOuterList s + | headMay s == Just '[' && lastMay s == Just ']' = init (tail s) + | otherwise = + case outerBracketSpan s of + Just (i, j) + | trim (take i s) /= "" + , j == length s - 1 -> + trim (take (j - i - 1) (drop (i + 1) s)) + _ -> s + + outerBracketSpan :: String -> Maybe (Int, Int) + outerBracketSpan s = + case elemIndex '[' s of + Nothing -> Nothing + Just start -> matchBracket start 0 start + where + matchBracket _ _ i | i >= length s = Nothing + matchBracket start depth i = + case s !! i of + '[' -> + let depth' = depth + 1 + in matchBracket start depth' (i + 1) + ']' -> + let depth' = depth - 1 + in if depth' == 0 + then Just (start, i) + else matchBracket start depth' (i + 1) + _ -> matchBracket start depth (i + 1) + +fieldEntryNeedsContinuation :: String -> Bool +fieldEntryNeedsContinuation = hasOpenBalance . trim + where + hasOpenBalance s = + case go 0 0 0 s of + (paren, bracket, brace) -> paren > 0 || bracket > 0 || brace > 0 + + go paren bracket brace [] = (paren, bracket, brace) + go paren bracket brace (c:cs) + | c == '(' = go (paren + 1) bracket brace cs + | c == ')' = go (paren - 1) bracket brace cs + | c == '[' = go paren (bracket + 1) brace cs + | c == ']' = go paren (bracket - 1) brace cs + | c == '{' = go paren bracket (brace + 1) cs + | c == '}' = go paren bracket (brace - 1) cs + | otherwise = go paren bracket brace cs + +stripCommentBlocks :: [String] -> [String] +stripCommentBlocks = snd . foldl' step (0 :: Int, []) + where + step (depth, acc) line = + let (depth', cleaned) = stripLine depth line + in (depth', acc ++ [cleaned]) + + stripLine depth [] = (depth, []) + stripLine depth ('{':'-':cs) = stripLine (depth + 1) cs + stripLine depth ('-':'}':cs) + | depth > 0 = stripLine (depth - 1) cs + stripLine depth ('-':'-':_) + | depth == 0 = (depth, []) + stripLine depth (c:cs) + | depth > 0 = stripLine depth cs + | otherwise = + let (depth', rest) = stripLine depth cs + in (depth', c : rest) + +splitTopLevelCommasGeneral :: String -> [String] +splitTopLevelCommasGeneral s = go 0 0 0 "" [] s + where + go _ _ _ cur acc [] = reverse (trim cur : acc) + go paren bracket brace cur acc (c:cs) + | c == '(' = go (paren + 1) bracket brace (cur ++ [c]) acc cs + | c == ')' = go (paren - 1) bracket brace (cur ++ [c]) acc cs + | c == '[' = go paren (bracket + 1) brace (cur ++ [c]) acc cs + | c == ']' = go paren (bracket - 1) brace (cur ++ [c]) acc cs + | c == '{' = go paren bracket (brace + 1) (cur ++ [c]) acc cs + | c == '}' = go paren bracket (brace - 1) (cur ++ [c]) acc cs + | c == ',' && paren == 0 && bracket == 0 && brace == 0 = + go paren bracket brace "" (trim cur : acc) cs + | otherwise = go paren bracket brace (cur ++ [c]) acc cs + +parseFieldLine :: Set.Set String -> String -> Maybe (String, String) +parseFieldLine vars line = do + key <- parseQuotedKey line + rhs <- parseDotEqRhs line + case extractForwardedVar vars rhs of + Just v -> Just (key, v) + Nothing -> + case inferRhsMarker rhs of + Just marker -> Just (key, marker) + Nothing -> do + let rhsTokens = Set.fromList (tokenize rhs) + let hits = filter (`Set.member` rhsTokens) (Set.toList vars) + case hits of + [v] -> Just (key, v) + _ -> + if isStringLiteral rhs + then Just (key, literalStringVar) + else Nothing + +extractForwardedVar :: Set.Set String -> String -> Maybe String +extractForwardedVar vars rhs = + listToMaybe + [ v + | v <- Set.toList vars + , isDirectForwardTo v (trim rhs) + ] + +isDirectForwardTo :: String -> String -> Bool +isDirectForwardTo var rhs = + any (`matchesCall` rhs) + [ "forMachine" + , "forMachineGov" + , "toObject" + , "toJSON" + ] + where + matchesCall fn s = + case words s of + [] -> False + (w:rest) + | w == fn -> + case reverse rest of + (lastArg:_) -> normalizeForwardedArg lastArg == var + _ -> False + | otherwise -> False + +normalizeForwardedArg :: String -> String +normalizeForwardedArg = + trim . dropTrailingPunctuation . takeWhile (\c -> isAlphaNum c || c == '_' || c == '\'' || c == '.') + +dropTrailingPunctuation :: String -> String +dropTrailingPunctuation = reverse . dropWhile (`elem` (")],}" :: String)) . reverse + +-- Special marker for string literals (e.g. "kind" .= String "..."). +literalStringVar :: String +literalStringVar = "__literal_string__" + +renderedStringVar :: String +renderedStringVar = "__rendered_string__" + +integerExprVar :: String +integerExprVar = "__integer_expr__" + +numberExprVar :: String +numberExprVar = "__number_expr__" + +booleanExprVar :: String +booleanExprVar = "__boolean_expr__" + +objectExprVar :: String +objectExprVar = "__object_expr__" + +arrayExprVar :: String +arrayExprVar = "__array_expr__" + +stringArrayExprVar :: String +stringArrayExprVar = "__string_array_expr__" + +-- Heuristic detection for String-literal RHS. +isStringLiteral :: String -> Bool +isStringLiteral s = + "String \"" `isInfix` s || "String '" `isInfix` s + +inferRhsMarker :: String -> Maybe String +inferRhsMarker rhs + | isStringLiteral rhs = Just literalStringVar + | "Number (fromIntegral" `isInfix` rhs = Just integerExprVar + | "Number (fromRational" `isInfix` rhs = Just numberExprVar + | "Number " `isPrefixOf` trim rhs = Just numberExprVar + | "String " `isPrefixOf` trim rhs = Just renderedStringVar + | "forMachine " `isInfix` rhs = Just objectExprVar + | "toObject " `isInfix` rhs = Just objectExprVar + | "Aeson.object" `isInfix` rhs = Just objectExprVar + | "object [" `isInfix` rhs = Just objectExprVar + | "mconcat [" `isInfix` rhs = Just objectExprVar + | "toJSON [" `isInfix` rhs = Just arrayExprVar + | "toJSONList (map show" `isInfix` rhs = Just stringArrayExprVar + | "toJSONList (map showT" `isInfix` rhs = Just stringArrayExprVar + | "toJSONList (map textShow" `isInfix` rhs = Just stringArrayExprVar + | "toJSONList (map (show" `isInfix` rhs = Just stringArrayExprVar + | "toJSONList " `isInfix` rhs = Just arrayExprVar + | "toJSON (map show" `isInfix` rhs = Just stringArrayExprVar + | "toJSON (map showT" `isInfix` rhs = Just stringArrayExprVar + | "toJSON (map textShow" `isInfix` rhs = Just stringArrayExprVar + | "toJSON (map (show" `isInfix` rhs = Just stringArrayExprVar + | "toJSON (map (" `isInfix` rhs = Just arrayExprVar + | "toJSON (Set.toList" `isInfix` rhs = Just arrayExprVar + | "toJSON (Map.keys" `isInfix` rhs = Just arrayExprVar + | "toJSON (Map.elems" `isInfix` rhs = Just arrayExprVar + | "toJSON True" `isInfix` rhs = Just booleanExprVar + | "toJSON False" `isInfix` rhs = Just booleanExprVar + | "toJSON (" `isInfix` rhs && any (`isInfix` rhs) [" is", "==", "/=", "&&", "||", " not "] = Just booleanExprVar + | "String (" `isInfix` rhs = Just renderedStringVar + | "textShow" `isInfix` rhs = Just renderedStringVar + | "showT" `isInfix` rhs = Just renderedStringVar + | "renderHeaderHash" `isInfix` rhs = Just renderedStringVar + | "renderChainHash" `isInfix` rhs = Just renderedStringVar + | "renderPoint" `isInfix` rhs = Just renderedStringVar + | "toJSON (unBlockNo" `isInfix` rhs = Just integerExprVar + | "toJSON (unSlotNo" `isInfix` rhs = Just integerExprVar + | "toJSON (fromIntegral" `isInfix` rhs = Just integerExprVar + | "toJSON (" `isInfix` rhs && any (`isInfix` rhs) ["Word", "Int", "SlotNo", "BlockNo", "EpochNo", "length ", "length(", "fragmentLength"] = Just integerExprVar + | "toJSON (" `isInfix` rhs && any (`isInfix` rhs) ["Double", "Float", "NominalDiffTime", "DiffTime"] = Just numberExprVar + | otherwise = Nothing + +parseQuotedKey :: String -> Maybe String +parseQuotedKey s = case dropWhile (/= '"') s of + [] -> Nothing + (_:rest) -> Just (takeWhile (/= '"') rest) + +parseDotEqRhs :: String -> Maybe String +parseDotEqRhs s = + case breakSub ".=" s of + Nothing -> Nothing + Just (_, rhs) -> Just (dropWhile (== ' ') rhs) + +breakSub :: String -> String -> Maybe (String, String) +breakSub needle hay = + let (a, b) = breakOn needle hay + in if null b then Nothing else Just (a, drop (length needle) b) + +breakOn :: String -> String -> (String, String) +breakOn needle hay = + case T.breakOn (T.pack needle) (T.pack hay) of + (a, b) -> (T.unpack a, T.unpack b) + +-- GHCI type extraction + +type VarTypes = Map.Map ConstructorName (Map.Map String String) + +-- For each file, ask GHCi for the types of variables extracted from forMachine clauses. +ghciTypesForFile :: FilePath -> [Clause] -> IO VarTypes +ghciTypesForFile fp clauses = do + let src = readFileSafe fp + moduleName = extractModuleName src + imports = extractImports src + let queries = mapMaybe buildQuery clauses + if null queries then pure Map.empty else do + out <- runGhci moduleName imports (map (fst . snd) queries) + let outputs = splitOutputs out (length queries) + let pairs = zip queries outputs + pure $ foldl' mergeVarTypes Map.empty (map parseQueryResult pairs) + where + mergeVarTypes = Map.unionWith Map.union + +extractImports :: String -> [String] +extractImports src = + [ stripComment l + | l <- lines src + , let l' = dropWhile (== ' ') l + , "import " `isPrefixOf` l' + ] + where + stripComment l = takeWhile (/= '-') l + +extractModuleName :: String -> Maybe String +extractModuleName src = + listToMaybe + [ takeWhile (\c -> isAlphaNum c || c == '_' || c == '.') rest + | l <- lines src + , let t = trim l + , "module " `isPrefixOf` t + , let rest = drop (length ("module " :: String)) t + ] + +buildQuery :: Clause -> Maybe (ConstructorName, (String, [String])) +buildQuery cl = do + ctor <- clauseCtor cl + let vars = filter isRelevantVar (extractVars (clausePattern cl)) + if null vars then Nothing else do + let body = if length vars == 1 then head vars else "(" ++ commaSep vars ++ ")" + let expr = "(\\(" ++ clausePattern cl ++ ") -> " ++ body ++ ")" + let cmd = ":t " ++ expr + Just (ctor, (cmd, vars)) + +commaSep :: [String] -> String +commaSep = foldr1 (\a b -> a ++ ", " ++ b) + +runGhci :: Maybe String -> [String] -> [String] -> IO String +runGhci moduleName imports cmds = + withFilteredGhciProjectFile $ \projectFile -> do + let ghciCmd = + [ "cabal" + , "--project-file=" ++ projectFile + , "repl" + , "cardano-node" + , "--repl-options=-ignore-dot-ghci" + , "--repl-options=-v0" + ] + let marker i = "__CMD_" ++ show i ++ "__" + let cmdLines = + [":set -XGADTs -XTypeFamilies -XDataKinds -XTypeOperators -XRankNTypes -XScopedTypeVariables"] + ++ maybe [] (\m -> [":module + *" ++ m]) moduleName + ++ imports + ++ concat [ [cmd, ":! echo " ++ marker i] | (i, cmd) <- zip [0..] cmds ] + ++ [":quit"] + (code, out, err) <- readCreateProcessWithExitCode (proc (head ghciCmd) (tail ghciCmd)) (unlines cmdLines) + let combined = out ++ err + case code of + ExitSuccess -> pure combined + _ -> pure combined + +withFilteredGhciProjectFile :: (FilePath -> IO a) -> IO a +withFilteredGhciProjectFile action = + bracket create remove action + where + create = do + let fp = ".ghci-schema.cabal.project.tmp" + src <- readFile "cabal.project" + writeFile fp (filterGhciProject src) + pure fp + remove fp = removeFile fp `catch` (\(_ :: IOException) -> pure ()) + +filterGhciProject :: String -> String +filterGhciProject src = unlines (go False (lines src)) + where + go _ [] = [] + go True (l:ls) + | startsTopLevel l = go False (l:ls) + | otherwise = go True ls + go False (l:ls) + | trim l == "source-repository-package" = go True ls + | "extra-packages:" `isPrefixOf` trim l = go False ls + | otherwise = l : go False ls + + startsTopLevel line = + case line of + [] -> False + (c:_) -> not (isSpace c) + +splitOutputs :: String -> Int -> [String] +splitOutputs out n = map snd (take n (splitMarkers out)) + where + splitMarkers s = + let ls = lines s + go _ [] acc = reverse acc + go cur (l:rest) acc + | "__CMD_" `isPrefixOf` l = + go "" rest ((l, cur) : acc) + | otherwise = go (cur ++ l ++ "\n") rest acc + in go "" ls [] + +parseQueryResult :: ((ConstructorName, (String, [String])), String) -> VarTypes +parseQueryResult ((ctor, (_cmd, vars)), out) = + let isErr = "error:" `isInfix` out + varTypes = if isErr + then parseBindings out + else parseSignature out vars + in case varTypes of + Nothing -> Map.empty + Just vt -> Map.singleton ctor vt + +parseSignature :: String -> [String] -> Maybe (Map.Map String String) +parseSignature out vars = do + sig <- findSigBlock out + let parts = parseSigTypes sig + let pairs = zip vars parts + pure $ Map.fromList pairs + +findSigBlock :: String -> Maybe String +findSigBlock out = + case break (isInfix "::") (lines out) of + (_, []) -> Nothing + (_, sigStart:rest) -> + let sigLines = sigStart : takeWhile isSigContinuation rest + in Just (unwords (map trim sigLines)) + +isSigContinuation :: String -> Bool +isSigContinuation l = + case l of + [] -> False + (c:_) -> + isSpace c + && let t = trim l + in not (null t) + && not ("ghci>" `isPrefixOf` t) + && not ("__CMD_" `isPrefixOf` t) + +parseSigTypes :: String -> [String] +parseSigTypes line = + case breakSub "::" line of + Nothing -> [] + Just (_, rhs0) -> + let rhs = dropWhile (== ' ') rhs0 + tailTy = last (splitOn "->" rhs) + in parseTupleTypes (trim tailTy) + +parseTupleTypes :: String -> [String] +parseTupleTypes s + | headMay s == Just '(' && lastMay s == Just ')' && ',' `elem` s = + splitTopLevelCommas (init (tail s)) + | otherwise = [s] + +splitTopLevelCommas :: String -> [String] +splitTopLevelCommas s = go 0 "" [] s + where + go _ cur acc [] = reverse (trim cur : acc) + go depth cur acc (c:cs) + | c == '(' = go (depth + 1) (cur ++ [c]) acc cs + | c == ')' = go (depth - 1) (cur ++ [c]) acc cs + | c == ',' && depth == 0 = go depth "" (trim cur : acc) cs + | otherwise = go depth (cur ++ [c]) acc cs + +-- Parse "x :: T" bindings (and constraints) emitted by GHCi on errors. +parseBindings :: String -> Maybe (Map.Map String String) +parseBindings out = + let constraints = parseConstraints out + bindings = mapMaybe parseBindingLine (lines out) + applyConstraints ty = foldl' (\t (v, rep) -> replaceToken v rep t) ty constraints + fixed = [ (name, applyConstraints ty) | (name, ty) <- bindings ] + in if null fixed then Nothing else Just (Map.fromList fixed) + +parseConstraints :: String -> [(String, String)] +parseConstraints out = mapMaybe parseConstraintLine (lines out) + where + parseConstraintLine l = + case breakSub "~" l of + Nothing -> Nothing + Just (lhs, rhs) -> + let v = lastWord lhs + r = headWord rhs + in if null v || null r then Nothing else Just (v, r) + +-- Parse a single binding line "x :: T". +parseBindingLine :: String -> Maybe (String, String) +parseBindingLine l = + case breakSub "::" l of + Nothing -> Nothing + Just (lhs, rhs) -> + let name = trim (lastWord lhs) + ty = trim (takeWhile (/= '(') rhs) + in if null name || null ty then Nothing else Just (name, ty) + +replaceToken :: String -> String -> String -> String +replaceToken tok rep s = unwords (map (\w -> if w == tok then rep else w) (words s)) + +headMay :: [a] -> Maybe a +headMay [] = Nothing +headMay (x:_) = Just x + +lastMay :: [a] -> Maybe a +lastMay [] = Nothing +lastMay xs = Just (last xs) + +splitOn :: String -> String -> [String] +splitOn needle hay = map T.unpack (T.splitOn (T.pack needle) (T.pack hay)) + +trim :: String -> String +trim = T.unpack . T.strip . T.pack + +lastWord :: String -> String +lastWord s = case words s of + [] -> "" + xs -> last xs + +headWord :: String -> String +headWord s = case words s of + [] -> "" + (x:_) -> x + +isInfix :: String -> String -> Bool +isInfix needle hay = T.isInfixOf (T.pack needle) (T.pack hay) + +-- Schema update + +type FieldVarMap = Map.Map ConstructorName (Map.Map DetailLevel (Map.Map String String)) + +-- Update a single namespace schema on disk. +updateSchemaForNamespace :: Config + -> FilePath + -> FilePath + -> Map.Map ConstructorName [NamespaceParts] + -> FieldVarMap + -> VarTypes + -> String + -> IO () +updateSchemaForNamespace = updateSchemaForNamespaceWithWarning (\_ -> pure ()) + +updateSchemaForNamespaceWithWarning :: (String -> IO ()) + -> Config + -> FilePath + -> FilePath + -> Map.Map ConstructorName [NamespaceParts] + -> FieldVarMap + -> VarTypes + -> String + -> IO () +updateSchemaForNamespaceWithWarning emitWarning config msgOutDir typeOutDir nsMap fieldVarMap varTypes ns = do + let parts = splitDot ns + let ctor = + case fallbackCtorForNamespace parts of + Just c -> Just c + Nothing -> + case findCtor nsMap parts of + Just c -> Just c + Nothing -> Nothing + let out = msgOutDir foldr () (last parts ++ ".schema.json") (init parts) + let histOutDir = "bench/trace-schemas/messages-hist" + let histOut = histOutDir foldr () (last parts ++ ".schema.json") (init parts) + exists <- doesFileExist out + schema <- if exists + then do + bs <- BL.readFile out + case A.decode bs of + Just v -> pure v + Nothing -> pure (baseSchema ns) + else pure (baseSchema ns) + schema' <- updateSchema config typeOutDir ctor fieldVarMap varTypes schema + -- If we couldn't infer any data properties, fall back to messages-hist. + schema'' <- mergeHistDataIfEmpty histOut schema' + unless (schemaHasMeaningfulContent schema'') $ + case ctor of + Nothing -> + emitWarning $ + "Warning: no source found for namespace: " <> ns + Just c + | Map.notMember c fieldVarMap && Map.notMember c varTypes -> + emitWarning $ + "Warning: namespace resolved to constructor without parsed source/GHCi data: " + <> ns <> " -> " <> c + _ -> pure () + createDirectoryIfMissing True (takeDirectory out) + BL.writeFile out (AP.encodePretty schema'') + +fallbackCtorForNamespace :: [String] -> Maybe ConstructorName +fallbackCtorForNamespace parts + | ["Net", "Handshake"] `isListPrefixOf` parts = Just diffusionHandshakeCtor + | ["BlockFetch", "Decision"] `isListPrefixOf` parts + , lastMay parts == Just "EmptyPeersFetch" = + Just listEmptyCtor + | ["Net", "ConnectionManager"] `isListPrefixOf` parts + , lastMay parts == Just "UnexpectedlyFalseAssertion" = + Just connectionManagerUnexpectedlyFalseAssertionCtor + | ["Net", "InboundGovernor"] `isListPrefixOf` parts + , lastMay parts == Just "UnexpectedlyFalseAssertion" = + Just inboundGovernorUnexpectedlyFalseAssertionCtor + | ["Net", "ConnectionManager"] `isListPrefixOf` parts + , lastMay parts == Just "State" = Just connectionManagerStateCtor + | ["Net", "Mux"] `isListPrefixOf` parts + , lastMay parts == Just "State" = Just muxStateCtor + | ["BlockFetch"] `isListPrefixOf` parts + , "Serialised" `elem` parts + , lastMay parts == Just "Block" = Just serialisedBlockFetchMsgBlockCtor + | otherwise = Nothing + +isListPrefixOf :: Eq a => [a] -> [a] -> Bool +isListPrefixOf xs ys = xs == take (length xs) ys + +normalizeNamespaceMap :: FilePath -> Map.Map ConstructorName [NamespaceParts] -> Map.Map ConstructorName [NamespaceParts] +normalizeNamespaceMap fp + | takeFileName fp == "Diffusion.hs" = + renameCtor "AnyMessageAndAgency" diffusionHandshakeCtor + | takeFileName fp == "P2P.hs" = + insertAliasFrom "TrUnexpectedlyFalseAssertion" connectionManagerUnexpectedlyFalseAssertionCtor + . insertAliasFrom "TrUnexpectedlyFalseAssertion" inboundGovernorUnexpectedlyFalseAssertionCtor + | otherwise = id + +normalizeFieldVarMap :: FilePath -> FieldVarMap -> FieldVarMap +normalizeFieldVarMap fp + | takeFileName fp == "Diffusion.hs" = + renameCtor "AnyMessageAndAgency" diffusionHandshakeCtor + | takeFileName fp == "P2P.hs" = + splitUnexpectedlyFalseAssertion + | takeFileName fp == "NodeToNode.hs" = + splitSerialisedBlockFetchMsgBlock + | otherwise = id + +normalizeVarTypesMap :: FilePath -> VarTypes -> VarTypes +normalizeVarTypesMap fp + | takeFileName fp == "Diffusion.hs" = + renameCtor "AnyMessageAndAgency" diffusionHandshakeCtor + | takeFileName fp == "P2P.hs" = + insertAliasFrom "TrUnexpectedlyFalseAssertion" connectionManagerUnexpectedlyFalseAssertionCtor + . insertAliasFrom "TrUnexpectedlyFalseAssertion" inboundGovernorUnexpectedlyFalseAssertionCtor + | takeFileName fp == "NodeToNode.hs" = + insertAliasFrom "MsgBlock" serialisedBlockFetchMsgBlockCtor + | otherwise = id + +renameCtor :: ConstructorName -> ConstructorName -> Map.Map ConstructorName a -> Map.Map ConstructorName a +renameCtor from to m = + case Map.lookup from m of + Just v -> Map.insert to v (Map.delete from m) + Nothing -> m + +insertAliasFrom :: ConstructorName -> ConstructorName -> Map.Map ConstructorName a -> Map.Map ConstructorName a +insertAliasFrom from to m = + case Map.lookup from m of + Just v -> Map.insert to v m + Nothing -> m + +splitSerialisedBlockFetchMsgBlock :: FieldVarMap -> FieldVarMap +splitSerialisedBlockFetchMsgBlock m = + case Map.lookup "MsgBlock" m of + Nothing -> m + Just byLevel -> + let serialisedKeys = Set.fromList ["agency", "bytes", "kind"] + regular = Map.map (Map.filterWithKey (\k _ -> k /= "bytes")) byLevel + serialised = Map.map (Map.filterWithKey (\k _ -> Set.member k serialisedKeys)) byLevel + in Map.insert serialisedBlockFetchMsgBlockCtor serialised (Map.insert "MsgBlock" regular m) + +splitUnexpectedlyFalseAssertion :: FieldVarMap -> FieldVarMap +splitUnexpectedlyFalseAssertion m = + case Map.lookup "TrUnexpectedlyFalseAssertion" m of + Nothing -> m + Just byLevel -> + let connectionManagerKeys = Set.fromList ["kind", "info"] + inboundGovernorKeys = Set.fromList ["kind", "remoteSt"] + connectionManager = + Map.map (Map.filterWithKey (\k _ -> Set.member k connectionManagerKeys)) byLevel + inboundGovernor = + Map.map (Map.filterWithKey (\k _ -> Set.member k inboundGovernorKeys)) byLevel + in Map.insert connectionManagerUnexpectedlyFalseAssertionCtor connectionManager + (Map.insert inboundGovernorUnexpectedlyFalseAssertionCtor inboundGovernor m) + +-- Merge "data" from messages-hist when we couldn't infer any properties. +mergeHistDataIfEmpty :: FilePath -> A.Value -> IO A.Value +mergeHistDataIfEmpty histOut v@(A.Object o) = do + hasProps <- pure (hasDataProps o) + if hasProps + then pure v + else do + histExists <- doesFileExist histOut + if not histExists + then pure v + else do + bs <- BL.readFile histOut + case A.decode bs of + Just (A.Object ho) -> + case KM.lookup (K.fromString "data") ho of + Just d -> pure (A.Object (KM.insert (K.fromString "data") d o)) + Nothing -> pure v + _ -> pure v +mergeHistDataIfEmpty _ v = pure v + +schemaHasMeaningfulContent :: A.Value -> Bool +schemaHasMeaningfulContent (A.Object o) = + hasNonEmptyData o || hasNonEmptyVariants o + where + hasNonEmptyData obj = + case KM.lookup (K.fromString "data") obj of + Just (A.Object d) -> not (KM.null d) + _ -> False + + hasNonEmptyVariants obj = + case KM.lookup (K.fromString "variants") obj of + Just (A.Array arr) -> not (V.null arr) + _ -> False +schemaHasMeaningfulContent _ = False + +-- True if data.properties exists and is non-empty. +hasDataProps :: A.Object -> Bool +hasDataProps o = + case KM.lookup (K.fromString "data") o of + Just (A.Object d) -> + case KM.lookup (K.fromString "properties") d of + Just (A.Object props) -> not (null (KM.toList props)) + _ -> False + _ -> False + +baseSchema :: String -> A.Value +baseSchema ns = A.object ["ns" A..= ns, "data" A..= A.object []] + +updateSchema :: Config + -> FilePath + -> Maybe ConstructorName + -> FieldVarMap + -> VarTypes + -> A.Value + -> IO A.Value +updateSchema _ _ Nothing _ _ v = pure v +updateSchema config typeOutDir (Just ctor) fieldVarMap varTypes (A.Object o) = do + case KM.lookup (K.fromString "variants") o of + Just (A.Array arr) -> do + updated <- V.mapM (updateVariant config typeOutDir ctor fieldVarMap varTypes) arr + pure (A.Object (KM.insert (K.fromString "variants") (A.Array updated) o)) + _ -> do + updated <- updateData config typeOutDir ctor fieldVarMap varTypes "Minimal" o + pure (A.Object updated) +updateSchema _ _ _ _ _ v = pure v + +updateVariant :: Config + -> FilePath + -> ConstructorName + -> FieldVarMap + -> VarTypes + -> A.Value + -> IO A.Value +updateVariant config typeOutDir ctor fieldVarMap varTypes (A.Object o) = + case KM.lookup (K.fromString "detailLevel") o of + Just (A.String lvl) -> do + updated <- updateData config typeOutDir ctor fieldVarMap varTypes (T.unpack lvl) o + pure (A.Object updated) + _ -> pure (A.Object o) +updateVariant _ _ _ _ _ v = pure v + +-- Update or synthesize the "data" schema from forMachine mapping + type info. +updateData :: Config + -> FilePath + -> ConstructorName + -> FieldVarMap + -> VarTypes + -> DetailLevel + -> A.Object + -> IO A.Object +updateData config typeOutDir ctor fieldVarMap varTypes lvl o = + case KM.lookup (K.fromString "data") o of + Just (A.Object d) -> + case KM.lookup (K.fromString "properties") d of + Just (A.Object props) -> do + inferredProps <- inferredProperties typeOutDir ctor fieldVarMap varTypes lvl + let propsToUpdate = + if cfgPruneStaleProperties config + then KM.filterWithKey (\k _ -> KM.member k inferredProps) props + else props + updatedProps <- KM.traverseWithKey (updateProp typeOutDir ctor fieldVarMap varTypes lvl) propsToUpdate + let mergedProps = + if cfgPruneStaleProperties config + then KM.union updatedProps inferredProps + else KM.union updatedProps inferredProps + let d' = KM.insert (K.fromString "properties") (A.Object mergedProps) d + let d'' = setRequiredFields ctor fieldVarMap varTypes lvl d' + pure (KM.insert (K.fromString "data") (A.Object d'') o) + _ -> do + d' <- buildDataFromFieldMap typeOutDir ctor fieldVarMap varTypes lvl d + let d'' = setRequiredFields ctor fieldVarMap varTypes lvl d' + pure (KM.insert (K.fromString "data") (A.Object d'') o) + _ -> do + d <- buildDataFromFieldMap typeOutDir ctor fieldVarMap varTypes lvl KM.empty + let d' = setRequiredFields ctor fieldVarMap varTypes lvl d + pure (KM.insert (K.fromString "data") (A.Object d') o) + +-- Build a data.schema from the key->var mapping (if available). +buildDataFromFieldMap :: FilePath + -> ConstructorName + -> FieldVarMap + -> VarTypes + -> DetailLevel + -> A.Object + -> IO A.Object +buildDataFromFieldMap typeOutDir ctor fieldVarMap varTypes lvl base = do + props <- inferredProperties typeOutDir ctor fieldVarMap varTypes lvl + if KM.null props + then pure base + else do + let base' = + KM.insert (K.fromString "type") (A.String "object") $ + KM.insert (K.fromString "additionalProperties") (A.Bool True) base + pure (KM.insert (K.fromString "properties") (A.Object props) base') + +inferredProperties :: FilePath + -> ConstructorName + -> FieldVarMap + -> VarTypes + -> DetailLevel + -> IO A.Object +inferredProperties typeOutDir ctor fieldVarMap varTypes lvl = + case Map.lookup ctor fieldVarMap >>= Map.lookup lvl of + Nothing -> pure KM.empty + Just m -> KM.fromList <$> mapM (buildProp typeOutDir ctor fieldVarMap varTypes) (Map.toList m) + +setRequiredFields :: ConstructorName + -> FieldVarMap + -> VarTypes + -> DetailLevel + -> A.Object + -> A.Object +setRequiredFields ctor fieldVarMap varTypes lvl o = + case requiredFieldNames ctor fieldVarMap varTypes lvl of + [] -> o + reqs -> KM.insert (K.fromString "required") (A.toJSON reqs) o + +requiredFieldNames :: ConstructorName + -> FieldVarMap + -> VarTypes + -> DetailLevel + -> [String] +requiredFieldNames ctor fieldVarMap varTypes lvl = + case Map.lookup ctor fieldVarMap >>= Map.lookup lvl of + Nothing -> [] + Just m -> + [ key + | (key, varName) <- Map.toList m + , isRequiredField varName + ] + where + isRequiredField v + | v `elem` [ literalStringVar, renderedStringVar, integerExprVar, numberExprVar + , booleanExprVar, objectExprVar, arrayExprVar, stringArrayExprVar ] = True + | otherwise = + case Map.lookup ctor varTypes >>= Map.lookup v of + Just ty -> not (isMaybe ty) + Nothing -> True + +buildProp :: FilePath + -> ConstructorName + -> FieldVarMap + -> VarTypes + -> (String, String) + -> IO (A.Key, A.Value) +buildProp typeOutDir ctor fieldVarMap varTypes (k, v) + | v `elem` [literalStringVar, renderedStringVar] = + pure (K.fromString k, A.object ["type" A..= ("string" :: String)]) + | v == integerExprVar = + pure (K.fromString k, A.object ["type" A..= ("integer" :: String)]) + | v == numberExprVar = + pure (K.fromString k, A.object ["type" A..= ("number" :: String)]) + | v == booleanExprVar = + pure (K.fromString k, A.object ["type" A..= ("boolean" :: String)]) + | v == objectExprVar = + pure (K.fromString k, A.object ["type" A..= ("object" :: String), "additionalProperties" A..= True]) + | v == arrayExprVar = + pure (K.fromString k, A.object ["type" A..= ("array" :: String)]) + | v == stringArrayExprVar = + pure (K.fromString k, A.object ["type" A..= ("array" :: String), "items" A..= A.object ["type" A..= ("string" :: String)]]) + | otherwise = + case Map.lookup ctor varTypes >>= Map.lookup v of + Nothing -> pure (K.fromString k, fallbackSchemaForUnknownBindingForCtor ctor k v) + Just ty -> do + schema <- typeToSchema typeOutDir fieldVarMap varTypes Set.empty ty + pure (K.fromString k, schema) + +updateProp :: FilePath + -> ConstructorName + -> FieldVarMap + -> VarTypes + -> DetailLevel + -> A.Key + -> A.Value + -> IO A.Value +updateProp typeOutDir ctor fieldVarMap varTypes lvl key old = + case Map.lookup ctor fieldVarMap >>= Map.lookup lvl >>= Map.lookup (T.unpack (K.toText key)) of + Nothing -> pure old + Just v -> snd <$> buildProp typeOutDir ctor fieldVarMap varTypes (T.unpack (K.toText key), v) + +-- Namespace matching uses suffix match, so full path or tail matches work. +splitDot :: String -> [String] +splitDot s = case break (== '.') s of + (a, []) -> [a] + (a, _:b) -> a : splitDot b + +findCtor :: Map.Map ConstructorName [NamespaceParts] -> [String] -> Maybe ConstructorName +findCtor nsMap parts = + case rankedMatches of + ((_, ctor):_) -> Just ctor + [] -> Nothing + where + rankedMatches = + reverse . sortOn fst $ + [ (scoreMatch ctor nsParts, ctor) + | (ctor, nss) <- Map.toList nsMap + , nsParts <- nss + , nsParts `isListSuffixOf` parts + ] + + scoreMatch :: ConstructorName -> NamespaceParts -> (Int, Int, Int) + scoreMatch ctor nsParts = + ( length nsParts + , overlapScore ctor parts + , overlapScore ctor nsParts + ) + +isListSuffixOf :: Eq a => [a] -> [a] -> Bool +isListSuffixOf xs ys = xs == drop (length ys - length xs) ys + +overlapScore :: ConstructorName -> NamespaceParts -> Int +overlapScore ctor nsParts = + length $ + filter (`Set.member` ctorWords) nsWords + where + ctorWords = Set.fromList (splitCamelWords ctor) + nsWords = concatMap splitCamelWords nsParts + +splitCamelWords :: String -> [String] +splitCamelWords = + filter (not . null) + . map (map toLower) + . concatMap splitWord + . splitOnNonAlphaNum + where + splitOnNonAlphaNum [] = [] + splitOnNonAlphaNum xs = + let xs' = dropWhile (not . isAlphaNum) xs + in case span isAlphaNum xs' of + ("", []) -> [] + ("", rest) -> splitOnNonAlphaNum rest + (tok, rest) -> tok : splitOnNonAlphaNum rest + + splitWord [] = [] + splitWord (c:cs) = go [c] cs + + go cur [] = [reverse cur] + go cur (x:xs) + | isUpper x && any isLower cur = reverse cur : go [x] xs + | otherwise = go (x:cur) xs + +-- Type mapping + +typeToSchema :: FilePath -> FieldVarMap -> VarTypes -> Set.Set String -> String -> IO A.Value +typeToSchema typeOutDir fieldVarMap varTypes seen ty + | isList ty = do + item <- typeToSchema typeOutDir fieldVarMap varTypes seen (listElem ty) + pure (A.object ["type" A..= ("array" :: String), "items" A..= item]) + | isMaybe ty = do + item <- typeToSchema typeOutDir fieldVarMap varTypes seen (maybeElem ty) + pure (A.object ["anyOf" A..= [A.object ["type" A..= ("null" :: String)], item]]) + | baseTypeName ty `elem` ["Text","String","ByteString","ShortByteString","ShortText"] = pure (A.object ["type" A..= ("string" :: String)]) + | baseTypeName ty == "Bool" = pure (A.object ["type" A..= ("boolean" :: String)]) + | baseTypeName ty `elem` ["Int","Integer","Word","Word8","Word16","Word32","Word64","Natural","SlotNo","EpochNo","BlockNo"] = pure (A.object ["type" A..= ("integer" :: String)]) + | baseTypeName ty `elem` ["Double","Float","NominalDiffTime","DiffTime"] = pure (A.object ["type" A..= ("number" :: String)]) + | otherwise = do + let name = baseTypeName ty + case name of + (c:_) | isLower c -> pure (A.object []) + _ -> do + let ref = "types/" ++ name ++ ".schema.json" + let out = typeOutDir name ++ ".schema.json" + if Set.member name seen + then pure () + else ensureTypeSchema out name fieldVarMap varTypes (Set.insert name seen) + pure (A.object ["$ref" A..= ref]) + +isList :: String -> Bool +isList s = headMay s == Just '[' && lastMay s == Just ']' + +listElem :: String -> String +listElem s = trim (init (tail s)) + +isMaybe :: String -> Bool +isMaybe s = "Maybe " `isPrefixOf` trim s + +maybeElem :: String -> String +maybeElem s = trim (drop (length ("Maybe " :: String)) (trim s)) + +baseTypeName :: String -> String +baseTypeName s = + let s' = trim s + s'' = case stripPrefix "forall " s' of + Just rest -> case break (== '.') rest of + (_vars, '.':r) -> trim r + _ -> s' + _ -> s' + tokens = filter (not . null) (tokenize s'') + in case filter (\t -> case t of (c:_) -> isUpper c; _ -> False) tokens of + (x:_) -> x + [] -> s'' + +stripPrefix :: String -> String -> Maybe String +stripPrefix pre s = if pre `isPrefixOf` s then Just (drop (length pre) s) else Nothing + +ensureTypeSchema :: FilePath -> String -> FieldVarMap -> VarTypes -> Set.Set String -> IO () +ensureTypeSchema out name fieldVarMap varTypes seen = do + createDirectoryIfMissing True (takeDirectory out) + schema <- namedTypeSchema fieldVarMap varTypes seen name + BL.writeFile out (AP.encodePretty schema) + +namedTypeSchema :: FieldVarMap -> VarTypes -> Set.Set String -> String -> IO A.Value +namedTypeSchema fieldVarMap varTypes seen name = do + structural <- structuralTypeSchema fieldVarMap varTypes seen name + pure $ + case structural of + A.Object o -> + A.Object $ + KM.insert (K.fromString "$schema") (A.String "https://json-schema.org/draft/2020-12/schema") $ + KM.insert (K.fromString "title") (A.String (T.pack name)) o + v -> v + +structuralTypeSchema :: FieldVarMap -> VarTypes -> Set.Set String -> String -> IO A.Value +structuralTypeSchema fieldVarMap varTypes seen name + | isNamedStringType name = pure (A.object ["type" A..= ("string" :: String)]) + | isNamedIntegerType name = pure (A.object ["type" A..= ("integer" :: String)]) + | isNamedNumberType name = pure (A.object ["type" A..= ("number" :: String)]) + | isNamedBooleanType name = pure (A.object ["type" A..= ("boolean" :: String)]) + | isNamedNonEmptyType name = + pure (A.object ["type" A..= ("array" :: String), "minItems" A..= (1 :: Int)]) + | isNamedWithOriginType name = + pure (A.object + [ "oneOf" A..= + [ A.object + [ "type" A..= ("object" :: String) + , "properties" A..= A.object + [ "tag" A..= A.object ["type" A..= ("string" :: String)] ] + , "required" A..= ["tag" :: String] + , "additionalProperties" A..= True + ] + , A.object ["type" A..= ("string" :: String)] + ] + ]) + | otherwise = + case Map.lookup name fieldVarMap of + Just byLevel | not (Map.null byLevel) -> do + props <- mergedPropsForType fieldVarMap varTypes seen name byLevel + pure (A.object + [ "type" A..= ("object" :: String) + , "additionalProperties" A..= True + , "properties" A..= A.Object props + ]) + _ -> + pure (A.object + [ "type" A..= ("object" :: String) + , "additionalProperties" A..= True + ]) + +mergedPropsForType + :: FieldVarMap + -> VarTypes + -> Set.Set String + -> String + -> Map.Map DetailLevel (Map.Map String String) + -> IO A.Object +mergedPropsForType fieldVarMap varTypes seen ctor byLevel = do + let fieldVars = + foldl' (Map.unionWith (++)) Map.empty + [ Map.map (:[]) lvlMap + | lvlMap <- Map.elems byLevel + ] + props <- mapM buildMergedProp (Map.toList fieldVars) + pure (KM.fromList props) + where + buildMergedProp (fieldName, vars) = do + schemas <- mapM (schemaForVar fieldName) vars + pure (K.fromString fieldName, mergeSchemas schemas) + + schemaForVar fieldName var + | var `elem` [literalStringVar, renderedStringVar] = + pure (A.object ["type" A..= ("string" :: String)]) + | var == integerExprVar = + pure (A.object ["type" A..= ("integer" :: String)]) + | var == numberExprVar = + pure (A.object ["type" A..= ("number" :: String)]) + | var == booleanExprVar = + pure (A.object ["type" A..= ("boolean" :: String)]) + | var == objectExprVar = + pure (A.object ["type" A..= ("object" :: String), "additionalProperties" A..= True]) + | var == arrayExprVar = + pure (A.object ["type" A..= ("array" :: String)]) + | var == stringArrayExprVar = + pure (A.object ["type" A..= ("array" :: String), "items" A..= A.object ["type" A..= ("string" :: String)]]) + | otherwise = + case Map.lookup ctor varTypes >>= Map.lookup var of + Nothing -> pure (fallbackSchemaForUnknownBindingForCtor ctor fieldName var) + Just ty -> typeToSchema "bench/trace-schemas/types" fieldVarMap varTypes seen ty + +fallbackSchemaForUnknownBindingForCtor :: ConstructorName -> String -> String -> A.Value +fallbackSchemaForUnknownBindingForCtor ctor key var + | ctor == "TracePickInboundPeers" + , lowerKey `elem` ["selected", "available"] = + A.object ["type" A..= ("array" :: String)] + | ctor == "FetchingNewLedgerState" + , lowerKey `elem` ["numberofledgerpeers", "numberofbigledgerpeers"] = + A.object ["type" A..= ("integer" :: String)] + | ctor `elem` ["TracePublicRootsResults", "TracePublicRootsFailure", "TraceBigLedgerPeersResults", "TraceBigLedgerPeersFailure"] + , lowerKey == "difftime" = + A.object ["type" A..= ("number" :: String)] + | otherwise = fallbackSchemaForUnknownBinding key var + where + lowerKey = map toLower key + +fallbackSchemaForUnknownBinding :: String -> String -> A.Value +fallbackSchemaForUnknownBinding key var + | lowerKey == "port" || lowerVar == "port" || lowerVar == "portno" = + A.object ["type" A..= ("integer" :: String)] + | lowerKey `elem` peerSelectionCounterKeys = + A.object ["type" A..= ("integer" :: String)] + | otherwise = + A.object ["type" A..= ("string" :: String)] + where + lowerKey = map toLower key + lowerVar = map toLower var + peerSelectionCounterKeys = + [ "targetknown" + , "actualknown" + , "targetestablished" + , "actualestablished" + , "targetactive" + , "actualactive" + ] + +mergeSchemas :: [A.Value] -> A.Value +mergeSchemas [] = A.object [] +mergeSchemas [x] = x +mergeSchemas xs = + let unique = dedupeValues xs + in if length unique == 1 then head unique else A.object ["anyOf" A..= unique] + +dedupeValues :: [A.Value] -> [A.Value] +dedupeValues = reverse . foldl' step [] + where + step acc v = + let key = BL8.unpack (A.encode v) + in if any (\existing -> BL8.unpack (A.encode existing) == key) acc + then acc + else v : acc + +isNamedStringType, isNamedIntegerType, isNamedNumberType, isNamedBooleanType, isNamedNonEmptyType, isNamedWithOriginType :: String -> Bool +isNamedStringType name = name `elem` ["Text", "String", "ByteString", "ShortByteString", "ShortText", "HeaderHash"] +isNamedIntegerType name = name `elem` ["Int", "Integer", "Word", "Word8", "Word16", "Word32", "Word64", "Natural", "SlotNo", "EpochNo", "BlockNo"] +isNamedNumberType name = name `elem` ["Double", "Float", "NominalDiffTime", "DiffTime"] +isNamedBooleanType name = name == "Bool" +isNamedNonEmptyType name = name == "NonEmpty" || ".NonEmpty" `isSuffixOf` name +isNamedWithOriginType name = name == "WithOrigin" || ".WithOrigin" `isSuffixOf` name diff --git a/bench/trace-schemas/scripts/schema-gen/README.md b/bench/trace-schemas/scripts/schema-gen/README.md new file mode 100644 index 00000000000..fa8948c3e9f --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/README.md @@ -0,0 +1,85 @@ +# GhciSchemaGen overview + +`make trace-schemas-regenerate` + +or the step-by-step commands: + +`GHC_ENVIRONMENT=- nix develop -c cabal run cardano-node -- trace-documentation --config configuration/cardano/mainnet-config.yaml --output-namespace-list bench/trace-schemas/newNamespaces.txt --output-file bench/trace-schemas/trace-documentation.md` + +`nix develop -c bash -c 'runghc bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs'` + +`nix develop -c bash -c "runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --verbose"` + +`nix develop -c bash -c "runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs"` + +`nix develop -c bash -c "runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs --log-file run/.../stdout"` + +## What it does + +- Generates JSON schemas for trace messages in `bench/trace-schemas/messages` and type schemas in `bench/trace-schemas/types`. +- Uses the trace-documentation command to generate `bench/trace-schemas/newNamespaces.txt` from `MetaTrace` namespaces. +- Parses `namespaceFor` and `forMachine` clauses in source files, then asks `cabal repl` (GHCi) for types of variables used in those `forMachine` patterns. + +## High-level flow + +1. **Find relevant Haskell files** + - Scans `cardano-node/src`, `cardano-submit-api/src`, `cardano-tracer/src`, `trace-dispatcher/src`, `trace-forward/src`, `trace-resources/src`. + - Warns when any configured source directory is missing, instead of silently ignoring it. + - Keeps only `.hs` files that contain `forMachine` or `namespaceFor`. + +2. **Build namespace mapping** + - Parses `namespaceFor` clauses to map a constructor (e.g. `ReplayBlockStats`) to namespace parts (e.g. `["LedgerReplay"]`). + - This tells it which constructor corresponds to each namespace in `bench/trace-schemas/newNamespaces.txt`. + +3. **Parse `forMachine`** + - Extracts: + - The constructor pattern in each clause. + - The JSON keys from lines like `"foo" .= ...`. + - Which pattern variable supplies each key. + - Literal string RHS like `"kind" .= String "X"` are treated as string fields. + +4. **Ask GHCi for types** + - For each file, it runs `cabal repl cardano-node` and issues `:t` queries for patterns. + - Extracts variable types from the returned type signatures or error output. + - This becomes a map `constructor -> variable -> type`. + +5. **Build/update schemas** + - For each namespace in `newNamespaces.txt`: + - Finds the matching constructor via the namespace map. + - Builds or updates the `data.properties` schema using: + - key -> variable mapping from `forMachine` + - variable types from GHCi + - If `data.properties` is still empty, it optionally pulls `data` from `bench/trace-schemas/messages-hist`. + +## Key heuristics + +- Namespace matching uses suffix match so `Namespace [] ["LedgerReplay"]` can match `ChainDB.ReplayBlock.LedgerReplay`. +- If a field uses a literal string (`String "..."`), it is treated as `type: string`. +- If `data.properties` does not exist, it synthesizes an object schema and fills properties from `forMachine`. + +## Where to look in code + +- Entry point and flow: `main` +- Namespace mapping: `parseNamespaceMap`, `findCtor` +- forMachine parsing: `parseForMachineClauses`, `parseFieldVarMap`, `parseFieldLine` +- GHCi type extraction: `ghciTypesForFile`, `runGhci` +- Schema update: `updateSchemaForNamespace`, `updateData`, `buildDataFromFieldMap` + +## Validation + +- `ValidateTraceSchemas.hs` checks `meta.schema.json` with `check-jsonschema`, then validates every file in `bench/trace-schemas/messages` against that meta-schema. +- The Haskell script controls discovery and execution; the actual JSON Schema validation is delegated to `check-jsonschema` via `nix run nixpkgs#check-jsonschema`. +- Run it with `runghc -package-env - ...` so the standalone script does not inherit the repo's package environment. +- `ValidateTraceLog.hs` validates a real cardano-node log file: it skips the non-JSON preamble, validates the common envelope against `TraceMessage.schema.json`, validates known namespaces against the matching schema in `bench/trace-schemas/messages`, and reports namespaces that do not have a corresponding message schema. + +## Human changes that survive regeneration + +- Treat `bench/trace-schemas/messages` and `bench/trace-schemas/types` as generated outputs. +- Put manual edits in sidecar override patches under `bench/trace-schemas/overrides`. +- Apply overrides with `ApplySchemaOverrides.hs` after every generation. +- Enforce in CI with: + - `make trace-schemas-regenerate` + - `make trace-schemas-overrides-check` + - `make trace-schemas-overrides-coverage RANGE=origin/master...HEAD` + +See `bench/trace-schemas/overrides/README.md` for override format and file layout. diff --git a/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh b/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh new file mode 100644 index 00000000000..77fd65a9659 --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../../../.." && pwd)" +cd "$ROOT_DIR" + +echo "[trace-schemas] Generating namespace list and documentation..." +GHC_ENVIRONMENT=- nix develop -c cabal run cardano-node -- \ + trace-documentation \ + --config configuration/cardano/mainnet-config.yaml \ + --output-namespace-list bench/trace-schemas/newNamespaces.txt \ + --output-file bench/trace-schemas/trace-documentation.md + +echo "[trace-schemas] Generating schemas..." +nix develop -c bash -c \ + 'runghc bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs' + +echo "[trace-schemas] Applying human overrides..." +nix develop -c bash -c \ + "runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --verbose" + +echo "[trace-schemas] Validating generated schemas..." +nix develop -c bash -c \ + "runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs" + +echo "[trace-schemas] Done." diff --git a/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs b/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs new file mode 100644 index 00000000000..7539ea1109b --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs @@ -0,0 +1,354 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main (main) where + +import Control.Exception (bracket) +import Control.Monad (forM, forM_, unless, when) +import qualified Data.Aeson as A +import qualified Data.Aeson.KeyMap as KM +import qualified Data.ByteString as BS +import qualified Data.ByteString.Char8 as BS8 +import qualified Data.ByteString.Lazy as BL +import qualified Data.Map.Strict as Map +import Data.List (foldl', isSuffixOf, sortOn) +import qualified Data.Text as T +import Data.Word (Word8) +import System.Directory + ( createDirectoryIfMissing + , doesDirectoryExist + , doesFileExist + , listDirectory + , removePathForcibly + ) +import System.Environment (getArgs) +import System.Exit (ExitCode (..), exitFailure, exitSuccess) +import System.FilePath ((), takeBaseName) +import System.Process (proc, readCreateProcessWithExitCode, readProcess) + +defaultTraceSchema :: FilePath +defaultTraceSchema = "bench/trace-schemas/TraceMessage.schema.json" + +defaultMessagesDir :: FilePath +defaultMessagesDir = "bench/trace-schemas/messages" + +data Config = Config + { cfgLogFile :: FilePath + , cfgTraceSchema :: FilePath + , cfgMessagesDir :: FilePath + } + +data LogEntry = LogEntry + { leLineNo :: Int + , leNamespace :: Maybe String + , leInstancePath :: FilePath + } + +data ExtractedLog = ExtractedLog + { elSkippedPreamble :: Int + , elEntries :: [LogEntry] + , elMalformedLines :: [Int] + } + +defaultConfig :: Config +defaultConfig = + Config + { cfgLogFile = "" + , cfgTraceSchema = defaultTraceSchema + , cfgMessagesDir = defaultMessagesDir + } + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + checkInputs config + namespaceSchemas <- loadNamespaceSchemas (cfgMessagesDir config) + + withTempDir "cardano-trace-log-validate" $ \tempDir -> do + extracted <- extractLogEntries (cfgLogFile config) tempDir + let entries = elEntries extracted + + when (null entries) $ do + putStrLn "No JSON trace messages found in the log file." + exitFailure + + putStrLn $ + "Skipped " + <> show (elSkippedPreamble extracted) + <> " non-log line(s) before the first JSON trace message." + + unless (null (elMalformedLines extracted)) $ + putStrLn $ + "Malformed post-preamble line(s): " + <> commaList (map show (elMalformedLines extracted)) + + envelopeOk <- + validateBatches + "Validating common trace envelope..." + (validatorArgs ["--schemafile", cfgTraceSchema config]) + (map leInstancePath entries) + + let (knownEntries, unknownEntries) = partitionKnown namespaceSchemas entries + namespaceOk <- validateKnownNamespaces knownEntries + unknownOk <- reportUnknownNamespaces unknownEntries + + let overallOk = + envelopeOk + && namespaceOk + && unknownOk + && null (elMalformedLines extracted) + + if overallOk + then do + putStrLn $ + "Validated " + <> show (length entries) + <> " trace message(s) from " + <> cfgLogFile config + exitSuccess + else exitFailure + +parseArgs :: Config -> [String] -> IO Config +parseArgs config args = go config args + where + go cfg [] = + if null (cfgLogFile cfg) + then do + putStrLn "Missing required argument: --log-file PATH" + printHelp + exitFailure + else pure cfg + go cfg ("--log-file" : path : rest) = go cfg {cfgLogFile = path} rest + go cfg ("--trace-schema" : path : rest) = go cfg {cfgTraceSchema = path} rest + go cfg ("--messages-dir" : path : rest) = go cfg {cfgMessagesDir = path} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc -package-env - bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs --log-file PATH [options]" + , "" + , "Options:" + , " --log-file PATH Path to a cardano-node stdout/stderr log file." + , " --trace-schema PATH Path to TraceMessage.schema.json." + , " --messages-dir PATH Directory containing namespace message schemas." + ] + +checkInputs :: Config -> IO () +checkInputs config = do + logExists <- doesFileExist (cfgLogFile config) + unless logExists $ do + putStrLn $ "Log file not found: " <> cfgLogFile config + exitFailure + + traceSchemaExists <- doesFileExist (cfgTraceSchema config) + unless traceSchemaExists $ do + putStrLn $ "Trace schema not found: " <> cfgTraceSchema config + exitFailure + + messagesDirExists <- doesDirectoryExist (cfgMessagesDir config) + unless messagesDirExists $ do + putStrLn $ "Messages directory not found: " <> cfgMessagesDir config + exitFailure + +loadNamespaceSchemas :: FilePath -> IO (Map.Map String FilePath) +loadNamespaceSchemas root = do + schemaFiles <- listJsonFilesRecursive root + pairs <- fmap concat $ forM schemaFiles $ \path -> do + bytes <- BL.readFile path + case A.eitherDecode bytes :: Either String A.Value of + Left err -> do + putStrLn $ "Failed to parse schema file " <> path <> ": " <> err + exitFailure + Right (A.Object obj) -> + case KM.lookup "ns" obj of + Just (A.String ns) -> pure [(T.unpack ns, path)] + _ -> pure [] + Right _ -> pure [] + + let grouped = Map.fromListWith (++) [(ns, [path]) | (ns, path) <- pairs] + let duplicates = Map.toList (Map.filter ((> 1) . length) grouped) + unless (null duplicates) $ do + putStrLn "Duplicate namespaces found in message schemas:" + forM_ duplicates $ \(ns, paths) -> + putStrLn $ " " <> ns <> " -> " <> commaList paths + exitFailure + + pure (Map.map head grouped) + +extractLogEntries :: FilePath -> FilePath -> IO ExtractedLog +extractLogEntries logPath tempDir = do + bytes <- BS.readFile logPath + go False 1 (BS8.lines bytes) 0 [] [] + where + go _ _ [] skipped entries malformed = + pure + ExtractedLog + { elSkippedPreamble = skipped + , elEntries = reverse entries + , elMalformedLines = reverse malformed + } + go started lineNo (line : rest) skipped entries malformed = + case decodeLogLine line of + Just value -> do + instancePath <- writeInstance tempDir lineNo value + let entry = + LogEntry + { leLineNo = lineNo + , leNamespace = extractNamespace value + , leInstancePath = instancePath + } + go True (lineNo + 1) rest skipped (entry : entries) malformed + Nothing + | not started -> go False (lineNo + 1) rest (skipped + 1) entries malformed + | BS.all isIgnorableWhitespace line -> go True (lineNo + 1) rest skipped entries malformed + | otherwise -> go True (lineNo + 1) rest skipped entries (lineNo : malformed) + +decodeLogLine :: BS.ByteString -> Maybe A.Value +decodeLogLine line = + case A.decodeStrict' line of + Just value@(A.Object _) -> Just value + _ -> Nothing + +extractNamespace :: A.Value -> Maybe String +extractNamespace (A.Object obj) = + case KM.lookup "ns" obj of + Just (A.String ns) -> Just (T.unpack ns) + _ -> Nothing +extractNamespace _ = Nothing + +writeInstance :: FilePath -> Int -> A.Value -> IO FilePath +writeInstance tempDir lineNo value = do + let path = tempDir ("line-" <> padLineNo lineNo <> ".json") + BL.writeFile path (A.encode value) + pure path + +padLineNo :: Int -> String +padLineNo n = + let s = show n + width = 8 + in replicate (max 0 (width - length s)) '0' <> s + +partitionKnown :: + Map.Map String FilePath -> + [LogEntry] -> + (Map.Map FilePath [LogEntry], [LogEntry]) +partitionKnown namespaceSchemas = + foldl' step (Map.empty, []) + where + step (known, unknown) entry = + case leNamespace entry >>= (`Map.lookup` namespaceSchemas) of + Just schemaPath -> + (Map.insertWith (++) schemaPath [entry] known, unknown) + Nothing -> (known, entry : unknown) + +validateKnownNamespaces :: Map.Map FilePath [LogEntry] -> IO Bool +validateKnownNamespaces groups = do + results <- + forM (sortOn fst (Map.toList groups)) $ \(schemaPath, groupEntries) -> do + let namespaceLabel = maybe (takeBaseName schemaPath) id (leNamespace =<< safeHead groupEntries) + let header = + "Validating namespace " + <> namespaceLabel + <> " (" <> show (length groupEntries) <> " message(s))..." + validateBatches header (validatorArgs ["--schemafile", schemaPath]) (map leInstancePath groupEntries) + pure (and results) + +reportUnknownNamespaces :: [LogEntry] -> IO Bool +reportUnknownNamespaces [] = pure True +reportUnknownNamespaces entries = do + putStrLn "Namespaces not found in message schemas:" + let grouped = + Map.fromListWith (++) + [ (renderNamespace (leNamespace entry), [leLineNo entry]) + | entry <- entries + ] + forM_ (sortOn fst (Map.toList grouped)) $ \(ns, lineNos) -> + putStrLn $ + " " + <> ns + <> " at line(s) " + <> commaList (map show (sortOn id lineNos)) + pure False + +renderNamespace :: Maybe String -> String +renderNamespace (Just ns) = ns +renderNamespace Nothing = "" + +validateBatches :: String -> [String] -> [FilePath] -> IO Bool +validateBatches _ _ [] = pure True +validateBatches header baseArgs files = do + putStrLn header + let batches = chunksOf 200 files + totalBatches = length batches + results <- + forM (zip [1 :: Int ..] batches) $ \(batchNo, batch) -> do + putStrLn $ + " validating batch " + <> show batchNo + <> " of " + <> show totalBatches + <> " (" + <> show (length batch) + <> " message(s))..." + runValidator (baseArgs <> batch) + pure (and results) + +runValidator :: [String] -> IO Bool +runValidator args = do + (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "nix" args) "" + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + pure (exitCode == ExitSuccess) + +validatorArgs :: [String] -> [String] +validatorArgs args = + [ "run" + , "nixpkgs#check-jsonschema" + , "--" + ] + <> args + +listJsonFilesRecursive :: FilePath -> IO [FilePath] +listJsonFilesRecursive root = do + entries <- listDirectory root + fmap concat $ + forM entries $ \name -> do + let path = root name + isDir <- doesDirectoryExist path + if isDir + then listJsonFilesRecursive path + else pure [path | ".json" `isSuffixOf` path] + +chunksOf :: Int -> [a] -> [[a]] +chunksOf _ [] = [] +chunksOf n xs = + let (prefix, suffix) = splitAt n xs + in prefix : chunksOf n suffix + +commaList :: [String] -> String +commaList = foldr join "" + where + join item "" = item + join item acc = item <> ", " <> acc + +isIgnorableWhitespace :: Word8 -> Bool +isIgnorableWhitespace c = c == 32 || c == 9 || c == 13 + +withTempDir :: String -> (FilePath -> IO a) -> IO a +withTempDir prefix action = do + tmp <- fmap trimTrailingNewline $ readProcess "mktemp" ["-d", "/tmp/" <> prefix <> ".XXXXXX"] "" + createDirectoryIfMissing True tmp + bracket (pure tmp) removePathForcibly action + +trimTrailingNewline :: String -> String +trimTrailingNewline = reverse . dropWhile (== '\n') . reverse + +safeHead :: [a] -> Maybe a +safeHead (x : _) = Just x +safeHead [] = Nothing diff --git a/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs b/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs new file mode 100644 index 00000000000..3ebfa7bbf3a --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs @@ -0,0 +1,124 @@ +{-# LANGUAGE ScopedTypeVariables #-} + +module Main (main) where + +import Control.Monad (unless, when) +import Data.List (isSuffixOf) +import System.Directory + ( doesDirectoryExist + , doesFileExist + , listDirectory + ) +import System.Environment (getArgs) +import System.Exit (ExitCode (..), exitFailure, exitSuccess) +import System.FilePath (()) +import System.Process (proc, readCreateProcessWithExitCode) + +defaultMetaSchema :: FilePath +defaultMetaSchema = "bench/trace-schemas/meta.schema.json" + +defaultMessagesDir :: FilePath +defaultMessagesDir = "bench/trace-schemas/messages" + +data Config = Config + { cfgMetaSchema :: FilePath + , cfgMessagesDir :: FilePath + } + +defaultConfig :: Config +defaultConfig = + Config + { cfgMetaSchema = defaultMetaSchema + , cfgMessagesDir = defaultMessagesDir + } + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + checkInputs config + schemaFiles <- listJsonFilesRecursive (cfgMessagesDir config) + when (null schemaFiles) $ do + putStrLn $ "No schema files found under " <> cfgMessagesDir config + exitFailure + + runValidator "Validating meta schema..." (validatorArgs ["--check-metaschema", cfgMetaSchema config]) + runValidator + ("Validating " <> show (length schemaFiles) <> " trace schema files...") + (validatorArgs (["--schemafile", cfgMetaSchema config] <> schemaFiles)) + + putStrLn $ + "Validated " + <> show (length schemaFiles) + <> " trace schema file(s) against " + <> cfgMetaSchema config + exitSuccess + +parseArgs :: Config -> [String] -> IO Config +parseArgs config args = go config args + where + go cfg [] = pure cfg + go cfg ("--meta-schema" : path : rest) = go cfg {cfgMetaSchema = path} rest + go cfg ("--messages-dir" : path : rest) = go cfg {cfgMessagesDir = path} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs [options]" + , "" + , "Options:" + , " --meta-schema PATH Path to the meta schema." + , " --messages-dir PATH Directory containing trace schema files." + ] + +checkInputs :: Config -> IO () +checkInputs config = do + metaExists <- doesFileExist (cfgMetaSchema config) + unless metaExists $ do + putStrLn $ "Meta schema not found: " <> cfgMetaSchema config + exitFailure + + messagesExists <- doesDirectoryExist (cfgMessagesDir config) + unless messagesExists $ do + putStrLn $ "Messages directory not found: " <> cfgMessagesDir config + exitFailure + +listJsonFilesRecursive :: FilePath -> IO [FilePath] +listJsonFilesRecursive root = do + entries <- listDirectory root + paths <- mapM descend entries + pure (concat paths) + where + descend name = do + let path = root name + isDir <- doesDirectoryExist path + if isDir + then listJsonFilesRecursive path + else pure [path | ".json" `isSuffixOf` path] + +validatorArgs :: [String] -> [String] +validatorArgs args = + [ "run" + , "nixpkgs#check-jsonschema" + , "--" + ] + <> args + +runValidator :: String -> [String] -> IO () +runValidator message args = do + putStrLn message + (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "nix" args) "" + case exitCode of + ExitSuccess -> do + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + ExitFailure _ -> do + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + exitFailure diff --git a/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal b/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal new file mode 100644 index 00000000000..78a9738b3aa --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal @@ -0,0 +1,78 @@ +cabal-version: 3.0 + +name: trace-schema-gen +version: 0.1.0.0 +synopsis: Scripts for generating and validating cardano-node trace JSON schemas +category: Cardano, Tracing +copyright: 2024-2026 Input Output Global Inc (IOG), 2024-2026 Intersect. +author: IOHK +maintainer: operations@iohk.io +license: Apache-2.0 +build-type: Simple + +common common + default-language: Haskell2010 + ghc-options: + -Wall + -Wincomplete-record-updates + -Wincomplete-uni-patterns + -Wredundant-constraints + -Wcompat + build-depends: + base >= 4.14 && < 5, + +executable schema-gen + import: common + main-is: GhciSchemaGen.hs + hs-source-dirs: . + build-depends: + aeson, + aeson-pretty, + bytestring, + containers, + directory, + filepath, + process, + text, + vector, + +executable apply-schema-overrides + import: common + main-is: ApplySchemaOverrides.hs + hs-source-dirs: . + build-depends: + aeson, + aeson-pretty, + bytestring, + directory, + filepath, + +executable validate-trace-schemas + import: common + main-is: ValidateTraceSchemas.hs + hs-source-dirs: . + build-depends: + directory, + filepath, + process, + +executable validate-trace-log + import: common + main-is: ValidateTraceLog.hs + hs-source-dirs: . + build-depends: + aeson, + bytestring, + containers, + directory, + filepath, + process, + text, + +executable check-override-coverage + import: common + main-is: CheckOverrideCoverage.hs + hs-source-dirs: . + build-depends: + containers, + process, diff --git a/bench/trace-schemas/trace-documentation.md b/bench/trace-schemas/trace-documentation.md new file mode 100644 index 00000000000..19f538498c8 --- /dev/null +++ b/bench/trace-schemas/trace-documentation.md @@ -0,0 +1,14096 @@ +# Cardano Trace Documentation + +## Table Of Contents + +### [Trace Messages](#trace-messages) + +1. [BlockFetchⓜ](#blockfetchclientacknowledgedfetchrequest) + 1. [Clientⓣⓢ](#blockfetchclientacknowledgedfetchrequest) + 1. [Decisionⓣⓜ](#blockfetchdecisionaccept) + 1. [Remoteⓣⓢ](#blockfetchremotereceivebatchdone) + 1. [Serialisedⓣⓢ](#blockfetchremoteserialisedreceivebatchdone) + 1. [Serverⓣⓜ](#blockfetchserversendblock) +1. [BlockchainTimeⓣ](#blockchaintimecurrentslotunknown) +1. [ChainDBⓣⓜ](#chaindbaddblockeventaddblockvalidationinvalidblock) + 1. [ReplayBlockⓣⓜ](#chaindbreplayblockledgerreplay) +1. [ChainSyncⓜ](#chainsyncclientaccessingforecasthorizon) + 1. [Clientⓣ](#chainsyncclientaccessingforecasthorizon) + 1. [Localⓣⓢ](#chainsynclocalreceiveawaitreply) + 1. [Remoteⓣⓢ](#chainsyncremotereceiveawaitreply) + 1. [Serialisedⓣⓢ](#chainsyncremoteserialisedreceiveawaitreply) + 1. [ServerBlockⓣⓢⓜ](#chainsyncserverblockupdate) + 1. [ServerHeaderⓣⓢⓜ](#chainsyncserverheaderupdate) +1. [Consensusⓜ](#consensuscsjbecomingobjector) + 1. [CSJⓣⓢ](#consensuscsjbecomingobjector) + 1. [DevotedBlockFetchⓣⓢ](#consensusdevotedblockfetchrotateddynamo) + 1. [GDDⓣⓢ](#consensusgddtracegddevent) + 1. [GSMⓣⓜ](#consensusgsmentercaughtup) + 1. [SanityCheckⓣ](#consensussanitychecksanitycheckissue) + 1. [Startupⓣ](#consensusstartupconsensusstartupexception) +1. [Forgeⓣⓜ](#forgeloopadoptedblock) + 1. [Loopⓣⓜ](#forgeloopadoptedblock) + 1. [ThreadStatsⓣⓢⓜ](#forgethreadstatsforgingstats) +1. [Mempoolⓣⓢⓜ](#mempooladdedtx) +1. [Netⓣⓢ](#netacceptpolicyconnectionhardlimit) + 1. [AcceptPolicyⓣ](#netacceptpolicyconnectionhardlimit) + 1. [ConnectionManagerⓜ](#netconnectionmanagerlocalconnect) + 1. [Localⓣⓜ](#netconnectionmanagerlocalconnect) + 1. [Remoteⓣⓜ](#netconnectionmanagerremoteconnect) + 1. [Transitionⓣⓢ](#netconnectionmanagertransitiontransition) + 1. [InboundGovernorⓜ](#netinboundgovernorlocaldemotedtocoldremote) + 1. [Localⓣⓜ](#netinboundgovernorlocaldemotedtocoldremote) + 1. [Remoteⓣⓜ](#netinboundgovernorremotedemotedtocoldremote) + 1. [Transitionⓣ](#netinboundgovernortransitiontransition) + 1. [Muxⓜ](#netmuxlocalcleanexit) + 1. [Localⓣⓜ](#netmuxlocalcleanexit) + 1. [Remoteⓣⓜ](#netmuxremotecleanexit) + 1. [PeerSelectionⓜ](#netpeerselectionactionsconnectionerror) + 1. [Actionsⓣ](#netpeerselectionactionsconnectionerror) + 1. [Countersⓣⓢⓜ](#netpeerselectioncounterscounters) + 1. [Initiatorⓣⓢ](#netpeerselectioninitiatorgovernorstate) + 1. [Responderⓣⓢ](#netpeerselectionrespondergovernorstate) + 1. [Selectionⓣⓜ](#netpeerselectionselectionbigledgerpeersfailure) + 1. [Peersⓜ](#netpeersledgerdisabledledgerpeers) + 1. [Ledgerⓣ](#netpeersledgerdisabledledgerpeers) + 1. [LocalRootⓣ](#netpeerslocalrootlocalrootdnsmap) + 1. [PublicRootⓣ](#netpeerspublicrootpublicrootdomains) + 1. [Serverⓜ](#netserverlocalacceptconnection) + 1. [Localⓣ](#netserverlocalacceptconnection) + 1. [Remoteⓣ](#netserverremoteacceptconnection) +1. [NodeStateⓣ](#nodestatenodeaddblock) +1. [RPCⓣⓜ](#rpcerror) +1. [Reflectionⓣⓜ](#reflectionmetricsinfo) +1. [Shutdownⓣ](#shutdownabnormal) +1. [Startupⓣⓜ](#startupblockforgingblocktypemismatch) + 1. [DiffusionInitⓣ](#startupdiffusioninitconfiguringlocalsocket) +1. [StateQueryServerⓣ](#statequeryserverreceiveacquire) +1. [TxSubmissionⓜ](#txsubmissionlocalreceiveaccepttx) + 1. [Localⓣⓢ](#txsubmissionlocalreceiveaccepttx) + 1. [LocalServerⓣⓢ](#txsubmissionlocalserverreceivedtx) + 1. [MonitorClientⓣⓢ](#txsubmissionmonitorclientreceiveacquire) + 1. [Remoteⓣⓢ](#txsubmissionremotereceivedone) + 1. [TxInboundⓣⓜ](#txsubmissiontxinboundaddedtomempool) + 1. [TxOutboundⓣⓢ](#txsubmissiontxoutboundcontrolmessage) +1. [Versionⓣⓢⓜ](#versionnodeversion) + +### [Metrics](#metrics) + +1. [Forge](#forgeabout-to-lead) + 1. [about-to-lead](#forgeabout-to-lead) + 1. [adopted](#forgeadopted) + 1. [adoption-thread-died](#forgeadoption-thread-died) + 1. [block-from-future](#forgeblock-from-future) + 1. [could-not-forge](#forgecould-not-forge) + 1. [didnt-adopt](#forgedidnt-adopt) + 1. [forged](#forgeforged) + 1. [forged-invalid](#forgeforged-invalid) + 1. [node-is-leader](#forgenode-is-leader) + 1. [node-not-leader](#forgenode-not-leader) + 1. [slot-is-immutable](#forgeslot-is-immutable) +1. [GSM](#gsmstate) + 1. [state](#gsmstate) +1. [Mem](#memresident) + 1. [resident](#memresident) +1. [RTS](#rtsalloc) + 1. [alloc](#rtsalloc) + 1. [gcHeapBytes](#rtsgcheapbytes) + 1. [gcLiveBytes](#rtsgclivebytes) + 1. [gcMajorNum](#rtsgcmajornum) + 1. [gcMinorNum](#rtsgcminornum) + 1. [gcticks](#rtsgcticks) + 1. [mutticks](#rtsmutticks) + 1. [threads](#rtsthreads) +1. [Stat](#statcputicks) + 1. [cputicks](#statcputicks) + 1. [fsRd](#statfsrd) + 1. [fsWr](#statfswr) + 1. [netRd](#statnetrd) + 1. [netWr](#statnetwr) +1. [SuppressedMessages](#suppressedmessages) + 1. [](#suppressedmessages) + 1. [](#suppressedmessages) +1. [blockNum](#blocknum) +1. [blockReplayProgress](#blockreplayprogress) +1. [blockfetchclient](#blockfetchclientblockdelay) + 1. [blockdelay](#blockfetchclientblockdelay) + 1. [cdfFive](#blockfetchclientblockdelaycdffive) + 1. [cdfOne](#blockfetchclientblockdelaycdfone) + 1. [cdfThree](#blockfetchclientblockdelaycdfthree) + 1. [blocksize](#blockfetchclientblocksize) + 1. [lateblocks](#blockfetchclientlateblocks) +1. [blocksForged](#blocksforged) +1. [cardano_build_info](#cardano_build_info) +1. [cardano_version_major](#cardano_version_major) +1. [cardano_version_minor](#cardano_version_minor) +1. [cardano_version_patch](#cardano_version_patch) +1. [connectedPeers](#connectedpeers) +1. [connectionManager](#connectionmanagerduplexconns) + 1. [duplexConns](#connectionmanagerduplexconns) + 1. [fullDuplexConns](#connectionmanagerfullduplexconns) + 1. [inboundConns](#connectionmanagerinboundconns) + 1. [outboundConns](#connectionmanageroutboundconns) + 1. [prunableConns](#connectionmanagerprunableconns) + 1. [unidirectionalConns](#connectionmanagerunidirectionalconns) +1. [currentKESPeriod](#currentkesperiod) +1. [delegMapSize](#delegmapsize) +1. [density](#density) +1. [epoch](#epoch) +1. [forgedSlotLast](#forgedslotlast) +1. [forging_enabled](#forging_enabled) +1. [forks](#forks) +1. [haskell_compiler_major](#haskell_compiler_major) +1. [haskell_compiler_minor](#haskell_compiler_minor) +1. [haskell_compiler_patch](#haskell_compiler_patch) +1. [inboundGovernor](#inboundgovernorcold) + 1. [Cold](#inboundgovernorcold) + 1. [Hot](#inboundgovernorhot) + 1. [Idle](#inboundgovernoridle) + 1. [Warm](#inboundgovernorwarm) +1. [localInboundGovernor](#localinboundgovernorcold) + 1. [cold](#localinboundgovernorcold) + 1. [hot](#localinboundgovernorhot) + 1. [idle](#localinboundgovernoridle) + 1. [warm](#localinboundgovernorwarm) +1. [mempoolBytes](#mempoolbytes) +1. [node](#nodestarttime) + 1. [start](#nodestarttime) + 1. [time](#nodestarttime) +1. [nodeCannotForge](#nodecannotforge) +1. [nodeIsLeader](#nodeisleader) +1. [operationalCertificateExpiryKESPeriod](#operationalcertificateexpirykesperiod) +1. [operationalCertificateStartKESPeriod](#operationalcertificatestartkesperiod) +1. [peerSelection](#peerselectionactivebigledgerpeers) + 1. [ActiveBigLedgerPeers](#peerselectionactivebigledgerpeers) + 1. [ActiveBigLedgerPeersDemotions](#peerselectionactivebigledgerpeersdemotions) + 1. [ActiveBootstrapPeers](#peerselectionactivebootstrappeers) + 1. [ActiveBootstrapPeersDemotions](#peerselectionactivebootstrappeersdemotions) + 1. [ActiveLocalRootPeers](#peerselectionactivelocalrootpeers) + 1. [ActiveLocalRootPeersDemotions](#peerselectionactivelocalrootpeersdemotions) + 1. [ActiveNonRootPeers](#peerselectionactivenonrootpeers) + 1. [ActiveNonRootPeersDemotions](#peerselectionactivenonrootpeersdemotions) + 1. [ActivePeers](#peerselectionactivepeers) + 1. [ActivePeersDemotions](#peerselectionactivepeersdemotions) + 1. [Cold](#peerselectioncold) + 1. [ColdBigLedgerPeers](#peerselectioncoldbigledgerpeers) + 1. [ColdBigLedgerPeersPromotions](#peerselectioncoldbigledgerpeerspromotions) + 1. [ColdBootstrapPeersPromotions](#peerselectioncoldbootstrappeerspromotions) + 1. [ColdNonRootPeersPromotions](#peerselectioncoldnonrootpeerspromotions) + 1. [ColdPeersPromotions](#peerselectioncoldpeerspromotions) + 1. [EstablishedBigLedgerPeers](#peerselectionestablishedbigledgerpeers) + 1. [EstablishedBootstrapPeers](#peerselectionestablishedbootstrappeers) + 1. [EstablishedLocalRootPeers](#peerselectionestablishedlocalrootpeers) + 1. [EstablishedNonRootPeers](#peerselectionestablishednonrootpeers) + 1. [EstablishedPeers](#peerselectionestablishedpeers) + 1. [Hot](#peerselectionhot) + 1. [HotBigLedgerPeers](#peerselectionhotbigledgerpeers) + 1. [KnownBigLedgerPeers](#peerselectionknownbigledgerpeers) + 1. [KnownBootstrapPeers](#peerselectionknownbootstrappeers) + 1. [KnownLocalRootPeers](#peerselectionknownlocalrootpeers) + 1. [KnownNonRootPeers](#peerselectionknownnonrootpeers) + 1. [KnownPeers](#peerselectionknownpeers) + 1. [LocalRoots](#peerselectionlocalroots) + 1. [RootPeers](#peerselectionrootpeers) + 1. [Warm](#peerselectionwarm) + 1. [WarmBigLedgerPeers](#peerselectionwarmbigledgerpeers) + 1. [WarmBigLedgerPeersDemotions](#peerselectionwarmbigledgerpeersdemotions) + 1. [WarmBigLedgerPeersPromotions](#peerselectionwarmbigledgerpeerspromotions) + 1. [WarmBootstrapPeersDemotions](#peerselectionwarmbootstrappeersdemotions) + 1. [WarmBootstrapPeersPromotions](#peerselectionwarmbootstrappeerspromotions) + 1. [WarmLocalRootPeersPromotions](#peerselectionwarmlocalrootpeerspromotions) + 1. [WarmNonRootPeersDemotions](#peerselectionwarmnonrootpeersdemotions) + 1. [WarmNonRootPeersPromotions](#peerselectionwarmnonrootpeerspromotions) + 1. [WarmPeersDemotions](#peerselectionwarmpeersdemotions) + 1. [WarmPeersPromotions](#peerselectionwarmpeerspromotions) + 1. [churn](#peerselectionchurndecreasedactivebigledgerpeersduration) + 1. [DecreasedActiveBigLedgerPeers](#peerselectionchurndecreasedactivebigledgerpeersduration) + 1. [duration](#peerselectionchurndecreasedactivebigledgerpeersduration) + 1. [DecreasedActivePeers](#peerselectionchurndecreasedactivepeersduration) + 1. [duration](#peerselectionchurndecreasedactivepeersduration) + 1. [DecreasedEstablishedBigLedgerPeers](#peerselectionchurndecreasedestablishedbigledgerpeersduration) + 1. [duration](#peerselectionchurndecreasedestablishedbigledgerpeersduration) + 1. [DecreasedEstablishedPeers](#peerselectionchurndecreasedestablishedpeersduration) + 1. [duration](#peerselectionchurndecreasedestablishedpeersduration) + 1. [DecreasedKnownBigLedgerPeers](#peerselectionchurndecreasedknownbigledgerpeersduration) + 1. [duration](#peerselectionchurndecreasedknownbigledgerpeersduration) + 1. [DecreasedKnownPeers](#peerselectionchurndecreasedknownpeersduration) + 1. [duration](#peerselectionchurndecreasedknownpeersduration) +1. [remainingKESPeriods](#remainingkesperiods) +1. [rpc](#rpcrequestqueryservicereadparams) + 1. [request](#rpcrequestqueryservicereadparams) + 1. [QueryService](#rpcrequestqueryservicereadparams) + 1. [ReadParams](#rpcrequestqueryservicereadparams) + 1. [ReadUtxos](#rpcrequestqueryservicereadutxos) + 1. [SubmitService](#rpcrequestsubmitservicesubmittx) + 1. [SubmitTx](#rpcrequestsubmitservicesubmittx) +1. [served](#servedblock) + 1. [block](#servedblock) + 1. [latest](#servedblocklatest) + 1. [header](#servedheader) +1. [slotInEpoch](#slotinepoch) +1. [slotNum](#slotnum) +1. [slotsMissed](#slotsmissed) +1. [submissions](#submissionsaccepted) + 1. [accepted](#submissionsaccepted) + 1. [rejected](#submissionsrejected) + 1. [submitted](#submissionssubmitted) +1. [systemStartTime](#systemstarttime) +1. [tipBlock](#tipblock) +1. [txsInMempool](#txsinmempool) +1. [txsMempoolTimeoutHard](#txsmempooltimeouthard) +1. [txsMempoolTimeoutSoft](#txsmempooltimeoutsoft) +1. [txsProcessedNum](#txsprocessednum) +1. [txsSyncDuration](#txssyncduration) +1. [utxoSize](#utxosize) + +### [Datapoints](#datapoints) + +1. [NodeInfo](#nodeinfo) +1. [NodeStartupInfo](#nodestartupinfo) + +### [Configuration](#configuration) + + + +## Trace Messages + +### BlockFetch.Client.AcknowledgedFetchRequest + + +> Mark the point when the fetch client picks up the request added by the block fetch decision thread. Note that this event can happen fewer times than the 'AddedFetchRequest' due to fetch request merging. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Client.AddedFetchRequest + + +> The block fetch decision thread has added a new fetch instruction consisting of one or more individual request ranges. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Client.ClientMetrics + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Client.ClientTerminating + + +> The client is terminating. Log the number of outstanding requests. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### BlockFetch.Client.CompletedBlockFetch + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` +Limiter `BlockFetch.Client.CompletedBlockFetch` with frequency `2.0` + +### BlockFetch.Client.CompletedFetchBatch + + +> Mark the successful end of receiving a streaming batch of blocks. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Client.RejectedFetchBatch + + +> If the other peer rejects our request then we have this event instead of 'StartedFetchBatch' and 'CompletedFetchBatch'. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Client.SendFetchRequest + + +> Mark the point when fetch request for a fragment is actually sent over the wire. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Client.StartedFetchBatch + + +> Mark the start of receiving a streaming batch of blocks. This will be followed by one or more 'CompletedBlockFetch' and a final 'CompletedFetchBatch' + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Decision.Accept + + +> Throughout the decision making process we accumulate reasons to decline to fetch any blocks. This message carries the intermediate and final results. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### BlockFetch.Decision.Decline + + +> Throughout the decision making process we accumulate reasons to decline to fetch any blocks. This message carries the intermediate and final results. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### BlockFetch.Decision.EmptyPeersFetch + + +> Throughout the decision making process we accumulate reasons to decline to fetch any blocks. This message carries the intermediate and final results. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### BlockFetch.Remote.Receive.BatchDone + + +> End of block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Receive.Block + + +> Stream a single block. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Receive.ClientDone + + +> Client termination message. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Receive.NoBlocks + + +> Respond that there are no blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Receive.RequestRange + + +> Request range of blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Receive.StartBatch + + +> Start block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Send.BatchDone + + +> End of block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Send.Block + + +> Stream a single block. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Send.ClientDone + + +> Client termination message. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Send.NoBlocks + + +> Respond that there are no blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Send.RequestRange + + +> Request range of blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Send.StartBatch + + +> Start block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Receive.BatchDone + + +> End of block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Receive.Block + + +> Stream a single block. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Receive.ClientDone + + +> Client termination message. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Receive.NoBlocks + + +> Respond that there are no blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Receive.RequestRange + + +> Request range of blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Receive.StartBatch + + +> Start block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Send.BatchDone + + +> End of block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Send.Block + + +> Stream a single block. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Send.ClientDone + + +> Client termination message. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Send.NoBlocks + + +> Respond that there are no blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Send.RequestRange + + +> Request range of blocks. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Remote.Serialised.Send.StartBatch + + +> Start block streaming. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockFetch.Server.SendBlock + + +> The server sent a block to the peer. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### BlockchainTime.CurrentSlotUnknown + + +> Current slot is not yet known +> This happens when the tip of our current chain is so far in the past that we cannot translate the current wallclock to a slot number, typically during syncing. Until the current slot number is known, we cannot produce blocks. Seeing this message during syncing therefore is normal and to be expected. +> We record the current time (the time we tried to translate to a 'SlotNo') as well as the 'PastHorizonException', which provides detail on the bounds between which we /can/ do conversions. The distance between the current time and the upper bound should rapidly decrease with consecutive 'CurrentSlotUnknown' messages during syncing. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### BlockchainTime.StartTimeInTheFuture + + +> The start time of the blockchain time is in the future +> We have to block (for 'NominalDiffTime') until that time comes. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### BlockchainTime.SystemClockMovedBack + + +> The system clock moved back an acceptable time span, e.g., because of an NTP sync. +> The system clock moved back such that the new current slot would be smaller than the previous one. If this is within the configured limit, we trace this warning but *do not change the current slot*. The current slot never decreases, but the current slot may stay the same longer than expected. +> When the system clock moved back more than the configured limit, we shut down with a fatal exception. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### ChainDB.AddBlockEvent.AddBlockValidation.InvalidBlock + + +> An event traced during validating performed while adding a block. A point was found to be invalid. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.AddBlockEvent.AddBlockValidation.UpdateLedgerDb + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate + + +> An event traced during validating performed while adding a block. A candidate chain was valid. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` +Limiter `ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate` with frequency `2.0` + +### ChainDB.AddBlockEvent.AddedBlockToQueue + + +> The block was added to the queue and will be added to the ChainDB by the background thread. The size of the queue is included.. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` +Limiter `ChainDB.AddBlockEvent.AddedBlockToQueue` with frequency `2.0` + +### ChainDB.AddBlockEvent.AddedBlockToVolatileDB + + +> A block was added to the Volatile DB + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` +Limiter `ChainDB.AddBlockEvent.AddedBlockToVolatileDB` with frequency `2.0` + +### ChainDB.AddBlockEvent.AddedReprocessLoEBlocksToQueue + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.AddedToCurrentChain + + +> The new block fits onto the current chain (first fragment) and we have successfully used it to extend our (new) current chain (second fragment). + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddBlockEvent.ChainSelectionLoEDebug + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.ChangingSelection + + +> The new block fits onto the current chain (first fragment) and we have successfully used it to extend our (new) current chain (second fragment). + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.IgnoreBlockAlreadyInVolatileDB + + +> A block that is already in the Volatile DB was ignored. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddBlockEvent.IgnoreBlockOlderThanK + + +> A block with a 'BlockNo' more than @k@ back than the current tip was ignored. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddBlockEvent.IgnoreInvalidBlock + + +> A block that is invalid was ignored. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddBlockEvent.PipeliningEvent.OutdatedTentativeHeader + + +> We selected a new (better) chain, which cleared the previous tentative header. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.PipeliningEvent.SetTentativeHeader + + +> A new tentative header got set + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.PipeliningEvent.TrapTentativeHeader + + +> The body of tentative block turned out to be invalid. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.PoppedBlockFromQueue + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.PoppedReprocessLoEBlocksFromQueue + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.PoppingFromQueue + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.StoreButDontChange + + +> The block fits onto some fork, we'll try to switch to that fork (if it is preferable to our chain). + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.SwitchedToAFork + + +> The new block fits onto some fork and we have switched to that fork (second fragment), as it is preferable to our (previous) current chain (first fragment). + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddBlockEvent.TryAddToCurrentChain + + +> The block fits onto the current chain, we'll try to use it to extend our chain. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddBlockEvent.TrySwitchToAFork + + +> The block fits onto some fork, we'll try to switch to that fork (if it is preferable to our chain) + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.AddedPerasCertToQueue + + +> Peras certificate added to processing queue + + +Severity: `Debug` +Privacy: `Public` +Details: `DDetailed` + + +From current configuration: +Details: `DNormal` +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.ChainSelectionForBoostedBlock + + +> Perform chain selection for block boosted by Peras certificate + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.IgnorePerasCertTooOld + + +> Peras certificate ignored as it is too old compared to immutable slot + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.PerasCertBoostsBlockNotYetReceived + + +> Peras certificate boosts a block not yet received + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.PerasCertBoostsCurrentChain + + +> Peras certificate boosts a block on the current selection + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.PerasCertBoostsGenesis + + +> Peras certificate boosts the Genesis point + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.AddPerasCertEvent.PoppedPerasCertFromQueue + + +> Peras certificate popped from processing queue + + +Severity: `Debug` +Privacy: `Public` +Details: `DDetailed` + + +From current configuration: +Details: `DNormal` +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ChainSelStarvationEvent + + +> ChainSel is waiting for a next block to process, but there is no block in the queue. Despite the name, it is a pretty normal (and frequent) event. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB + + +> A block was successfully copied to the ImmDB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` +Limiter `ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB` with frequency `2.0` + +### ChainDB.CopyToImmutableDBEvent.NoBlocksToCopyToImmutableDB + + +> There are no block to copy to the ImmDB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.FollowerEvent.FollowerNewImmIterator + + +> The follower is in the 'FollowerInImmutableDB' state but the iterator is exhausted while the ImmDB has grown, so we open a new iterator to stream these blocks too. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.FollowerEvent.FollowerNoLongerInMem + + +> The follower was in 'FollowerInMem' state and is switched to the 'FollowerInImmutableDB' state. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.FollowerEvent.FollowerSwitchToMem + + +> The follower was in the 'FollowerInImmutableDB' state and is switched to the 'FollowerInMem' state. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.FollowerEvent.NewFollower + + +> A new follower was created. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.GCEvent.PerformedGC + + +> A garbage collection for the given 'SlotNo' was performed. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.GCEvent.ScheduledGC + + +> A garbage collection for the given 'SlotNo' was scheduled to happen at the given time. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.CacheEvent.CurrentChunkHit + + +> Current chunk found in the cache. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.CacheEvent.PastChunkEvict + + +> The least recently used past chunk was evicted because the cache was full. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.CacheEvent.PastChunkExpired + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.CacheEvent.PastChunkHit + + +> Past chunk found in the cache + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.CacheEvent.PastChunkMiss + + +> Past chunk was not found in the cache + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkFileDoesntFit + + +> The hash of the last block in the previous epoch doesn't match the previous hash of the first block in the current epoch + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.InvalidChunkFile + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.InvalidPrimaryIndex + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.InvalidSecondaryIndex + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.MissingChunkFile + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.MissingPrimaryIndex + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.MissingSecondaryIndex + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.RewritePrimaryIndex + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.RewriteSecondaryIndex + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.StartedValidatingChunk + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ChunkValidation.ValidatedChunk + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.DBAlreadyClosed + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.DBClosed + + +> Closing the immutable DB + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.DeletingAfter + + +> Delete after + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.Migrating + + +> Performing a migration of the on-disk files. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.ImmDbEvent.NoValidLastLocation + + +> No valid last location was found + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ImmDbEvent.ValidatedLastLocation + + +> The last location was validatet + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.InitChainSelEvent.InitialChainSelected + + +> A garbage collection for the given 'SlotNo' was performed. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.InitChainSelEvent.StartedInitChainSelection + + +> A garbage collection for the given 'SlotNo' was scheduled to happen at the given time. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.InitChainSelEvent.Validation.InvalidBlock + + +> An event traced during validating performed while adding a block. A point was found to be invalid. + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.InitChainSelEvent.Validation.UpdateLedgerDb + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.InitChainSelEvent.Validation.ValidCandidate + + +> An event traced during validating performed while adding a block. A candidate chain was valid. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.IteratorEvent.BlockGCedFromVolatileDB + + +> A block is no longer in the VolatileDB and isn't in the ImmDB either; it wasn't part of the current chain. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.BlockMissingFromVolatileDB + + +> A block is no longer in the VolatileDB because it has been garbage collected. It might now be in the ImmDB if it was part of the current chain. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.BlockWasCopiedToImmutableDB + + +> A block that has been garbage collected from the VolatileDB is now found and streamed from the ImmDB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.StreamFromBoth + + +> Stream from both the VolatileDB and the ImmDB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.StreamFromImmutableDB + + +> Stream only from the ImmDB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.StreamFromVolatileDB + + +> Stream only from the VolatileDB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.SwitchBackToVolatileDB + + +> We have streamed one or more blocks from the ImmDB that were part of the VolatileDB when initialising the iterator. Now, we have to look back in the VolatileDB again because the ImmDB doesn't have the next block we're looking for. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.UnknownRangeRequested.ForkTooOld + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.IteratorEvent.UnknownRangeRequested.MissingBlock + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LastShutdownUnclean + + +> Last shutdown of the node didn't leave the ChainDB directory in a clean state. Therefore, revalidating all the immutable chunks is necessary to ensure the correctness of the chain. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.AlreadyClosed + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Closed + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Closing + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Copied + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Copying + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.CreatedValueHandle + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.CreatingValueHandle + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisedFromCopy + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisedFromValues + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisingFromCopy + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisingFromValues + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Opened + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Opening + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.AlreadyClosed + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Closed + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Closing + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.RangeRead + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.RangeReading + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Read + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Reading + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Statted + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Statting + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Writing + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Written + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V1.LMDB.Initialise + + +> An LMDB trace + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMLookup + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMOpenSession + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMSnap + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMTrace + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMUpdate + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleClose + + +> Closed a ledger tables handle + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleCreate + + +> Created a ledger tables handle + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleCreateFirst + + +> Creating the first ledger tables handle + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleDuplicate + + +> Duplicating a ledger tables handle + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandlePush + + +> Pushing to a ledger tables handle + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleRead + + +> Reading from ledger tables handle + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Forker.Close + + +> A forker was closed + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.LedgerEvent.Forker.Open + + +> A forker is being opened + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.LedgerEvent.Forker.Push + + +> A forker is pushing a new ledger state + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.LedgerEvent.Forker.RangeRead + + +> A forker is range reading values + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.LedgerEvent.Forker.Read + + +> A forker is reading values + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.LedgerEvent.Forker.Statistics + + +> Statistics were gathered from the forker + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### ChainDB.LedgerEvent.Replay.ReplayProgress.ReplayedBlock + + +> We replayed the given block (reference) on the genesis snapshot during the initialisation of the LedgerDB. +> The @blockInfo@ parameter corresponds replayed block and the @replayTo@ parameter corresponds to the block at the tip of the ImmDB, i.e., the last block to replay. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.LedgerEvent.Replay.ReplayStart.ReplayFromGenesis + + +> There were no LedgerDB snapshots on disk, so we're replaying all blocks starting from Genesis against the initial ledger. The @replayTo@ parameter corresponds to the block at the tip of the ImmDB, i.e., the last block to replay. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.LedgerEvent.Replay.ReplayStart.ReplayFromSnapshot + + +> There was a LedgerDB snapshot on disk corresponding to the given tip. We're replaying more recent blocks against it. The @replayTo@ parameter corresponds to the block at the tip of the ImmDB, i.e., the last block to replay. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.LedgerEvent.Snapshot.DeletedSnapshot + + +> A snapshot was deleted from the disk. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.LedgerEvent.Snapshot.InvalidSnapshot + + +> An on disk snapshot was invalid. Unless it was suffixed or seems to be from an old node or different backend, it will be deleted + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.LedgerEvent.Snapshot.TookSnapshot + + +> A snapshot is being written to disk. Two events will be traced, one for when the node starts taking the snapshot and another one for when the snapshot has been written to the disk. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.ClosedDB + + +> The ChainDB was closed. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.OpenedDB + + +> The ChainDB was opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.OpenedImmutableDB + + +> The ImmDB was opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.OpenedLgrDB + + +> The LedgerDB was opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.OpenedVolatileDB + + +> The VolatileDB was opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.StartedOpeningDB + + +> The ChainDB is being opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.StartedOpeningImmutableDB + + +> The ImmDB is being opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.StartedOpeningLgrDB + + +> The LedgerDB is being opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.OpenEvent.StartedOpeningVolatileDB + + +> The VolatileDB is being opened. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.PerasCertDbEvent.AddedPerasCert + + +> Certificate added to Peras certificate database + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.PerasCertDbEvent.AddingPerasCert + + +> Adding certificate to Peras certificate database + + +Severity: `Debug` +Privacy: `Public` +Details: `DDetailed` + + +From current configuration: +Details: `DNormal` +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.PerasCertDbEvent.ClosedPerasCertDB + + +> Peras certificate database closed + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.PerasCertDbEvent.IgnoredCertAlreadyInDB + + +> Certificate ignored as it was already in the database + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.PerasCertDbEvent.OpenedPerasCertDB + + +> Peras certificate database opened + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.ReplayBlock.LedgerReplay + + +> Counts block replays and calculates the percent. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### ChainDB.VolatileDbEvent.BlockAlreadyHere + + +> A block was found to be already in the DB. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.VolatileDbEvent.DBAlreadyClosed + + +> When closing the DB it was found it is closed already. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.VolatileDbEvent.DBClosed + + +> Closing the volatile DB + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.VolatileDbEvent.InvalidFileNames + + +> Reports a list of invalid file paths. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainDB.VolatileDbEvent.Truncate + + +> Truncates a file up to offset because of the error. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### ChainSync.Client.AccessingForecastHorizon + + +> The slot number, which was previously beyond the forecast horizon, has now entered it + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.DownloadedHeader + + +> While following a candidate chain, we rolled forward by downloading a header. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.DrainingThePipe + + +> The client is draining the pipe of messages + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.Exception + + +> An exception was thrown by the Chain Sync Client. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Warning` + +### ChainSync.Client.FoundIntersection + + +> We found an intersection between our chain fragment and the candidate's chain. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.GaveLoPToken + + +> May have added atoken to the LoP bucket of the peer + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.JumpResult + + +> Response to a jump offer (accept or reject) + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.JumpingInstructionIs + + +> The client got its next instruction + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.JumpingWaitingForNextInstruction + + +> The client is waiting for the next instruction + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.OfferJump + + +> Offering a jump to the remote peer + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.RolledBack + + +> While following a candidate chain, we rolled back to the given point. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.Termination + + +> The client has terminated. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.ValidatedHeader + + +> The header has been validated + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Client.WaitingBeyondForecastHorizon + + +> The slot number is beyond the forecast horizon + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### ChainSync.Local.Receive.AwaitReply + + +> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.Done + + +> We have to explain to the framework what our states mean, in terms of which party has agency in each state. +> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.FindIntersect + + +> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.IntersectFound + + +> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.IntersectNotFound + + +> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.RequestNext + + +> Request the next update from the producer. The response can be a roll forward, a roll back or wait. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.RollBackward + + +> Tell the consumer to roll back to a given point on their chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Receive.RollForward + + +> Tell the consumer to extend their chain with the given header. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.AwaitReply + + +> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.Done + + +> We have to explain to the framework what our states mean, in terms of which party has agency in each state. +> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.FindIntersect + + +> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.IntersectFound + + +> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.IntersectNotFound + + +> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.RequestNext + + +> Request the next update from the producer. The response can be a roll forward, a roll back or wait. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.RollBackward + + +> Tell the consumer to roll back to a given point on their chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Local.Send.RollForward + + +> Tell the consumer to extend their chain with the given header. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.AwaitReply + + +> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.Done + + +> We have to explain to the framework what our states mean, in terms of which party has agency in each state. +> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.FindIntersect + + +> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.IntersectFound + + +> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.IntersectNotFound + + +> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.RequestNext + + +> Request the next update from the producer. The response can be a roll forward, a roll back or wait. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.RollBackward + + +> Tell the consumer to roll back to a given point on their chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Receive.RollForward + + +> Tell the consumer to extend their chain with the given header. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.AwaitReply + + +> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.Done + + +> We have to explain to the framework what our states mean, in terms of which party has agency in each state. +> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.FindIntersect + + +> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.IntersectFound + + +> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.IntersectNotFound + + +> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.RequestNext + + +> Request the next update from the producer. The response can be a roll forward, a roll back or wait. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.RollBackward + + +> Tell the consumer to roll back to a given point on their chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Send.RollForward + + +> Tell the consumer to extend their chain with the given header. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.AwaitReply + + +> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.Done + + +> We have to explain to the framework what our states mean, in terms of which party has agency in each state. +> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.FindIntersect + + +> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.IntersectFound + + +> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.IntersectNotFound + + +> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.RequestNext + + +> Request the next update from the producer. The response can be a roll forward, a roll back or wait. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.RollBackward + + +> Tell the consumer to roll back to a given point on their chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Receive.RollForward + + +> Tell the consumer to extend their chain with the given header. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.AwaitReply + + +> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.Done + + +> We have to explain to the framework what our states mean, in terms of which party has agency in each state. +> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.FindIntersect + + +> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.IntersectFound + + +> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.IntersectNotFound + + +> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.RequestNext + + +> Request the next update from the producer. The response can be a roll forward, a roll back or wait. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.RollBackward + + +> Tell the consumer to roll back to a given point on their chain. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.Remote.Serialised.Send.RollForward + + +> Tell the consumer to extend their chain with the given header. +> The message also tells the consumer about the head point of the producer. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.ServerBlock.Update + + +> A server read has occurred, either for an add block or a rollback + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### ChainSync.ServerHeader.Update + + +> A server read has occurred, either for an add block or a rollback + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.CSJ.BecomingObjector + + +> This peer is becoming the CSJ objector + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.CSJ.BlockedOnJump + + +> This peer is blocked on a CSJ jump + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.CSJ.InitializedAsDynamo + + +> This peer has been initialized as the CSJ dynamo + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.CSJ.NoLongerDynamo + + +> This peer no longer is the CSJ dynamo + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.CSJ.NoLongerObjector + + +> This peer no longer is the CSJ objector + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.CSJ.SentJumpInstruction + + +> This peer has been instructed to jump via CSJ + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.DevotedBlockFetch.RotatedDynamo + + +> The ChainSync Jumping module has been asked to rotate its dynamo + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.GDD.TraceGDDEvent + + +> The Genesis Density Disconnection governor has updated its state + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Consensus.GSM.EnterCaughtUp + + +> Node is caught up + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.GSM.InitializedInCaughtUp + + +> The GSM was initialized in the 'CaughtUp' state + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.GSM.InitializedInPreSyncing + + +> The GSM was initialized in the 'PreSyncing' state + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.GSM.LeaveCaughtUp + + +> Node is not caught up + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.GSM.PreSyncingToSyncing + + +> The Honest Availability Assumption is now satisfied + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.GSM.SyncingToPreSyncing + + +> The Honest Availability Assumption is no longer satisfied + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.SanityCheck.SanityCheckIssue + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Consensus.Startup.ConsensusStartupException + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Forge.Loop.AdoptedBlock + + +> We adopted the block we produced, we also trace the transactions that were adopted. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.AdoptionThreadDied + + +> Block adoption thread died + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.BlockContext + + +> We found out to which block we are going to connect the block we are about to forge. We record the current slot number, the block number of the block to connect to and its point. Note that block number of the block we will try to forge is one more than the recorded block number. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Forge.Loop.BlockFromFuture + + +> Leadership check failed: the current chain contains a block from a slot /after/ the current slot This can only happen if the system is under heavy load. We record both the current slot number as well as the slot number of the block at the tip of the chain. See also + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.DidntAdoptBlock + + +> We did not adopt the block we produced, but the block was valid. We must have adopted a block that another leader of the same slot produced before we got the chance of adopting our own block. This is very rare, this warrants a warning. + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.ForgeStateUpdateError + + +> Updating the forge state failed. For example, the KES key could not be evolved anymore. We record the error returned by 'updateForgeState'. + + +Severity: `Critical` +Privacy: `Confidential` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.ForgeTickedLedgerState + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Forge.Loop.ForgedBlock + + +> We forged a block. +> We record the current slot number, the point of the predecessor, the block itself, and the total size of the mempool snapshot at the time we produced the block (which may be significantly larger than the block, due to maximum block size) +> This will be followed by one of three messages: +> * AdoptedBlock (normally) +> * DidntAdoptBlock (rarely) +> * ForgedInvalidBlock (hopefully never, this would indicate a bug) + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.ForgedInvalidBlock + + +> We forged a block that is invalid according to the ledger in the ChainDB. This means there is an inconsistency between the mempool validation and the ledger validation. This is a serious error! + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.ForgingMempoolSnapshot + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Forge.Loop.LedgerState + + +> We obtained a ledger state for the point of the block we want to connect to We record both the current slot number as well as the point of the block we attempt to connect the new block to (that we requested the ledger state for). + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Forge.Loop.LedgerView + + +> We obtained a ledger view for the current slot number We record the current slot number. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Forge.Loop.NoLedgerState + + +> Leadership check failed: we were unable to get the ledger state for the point of the block we want to connect to This can happen if after choosing which block to connect to the node switched to a different fork. We expect this to happen only rather rarely, so this certainly merits a warning; if it happens a lot, that merits an investigation. We record both the current slot number as well as the point of the block we attempt to connect the new block to (that we requested the ledger state for). + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.NoLedgerView + + +> Leadership check failed: we were unable to get the ledger view for the current slot number This will only happen if there are many missing blocks between the tip of our chain and the current slot. We record also the failure returned by 'forecastFor'. + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.NodeCannotForge + + +> We did the leadership check and concluded that we should lead and forge a block, but cannot. This should only happen rarely and should be logged with warning severity. Records why we cannot forge a block. + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.NodeIsLeader + + +> We did the leadership check and concluded we /are/ the leader +> The node will soon forge; it is about to read its transactions from the Mempool. This will be followed by ForgedBlock. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.NodeNotLeader + + +> We did the leadership check and concluded we are not the leader We record the current slot number + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.SlotIsImmutable + + +> Leadership check failed: the tip of the ImmutableDB inhabits the current slot This might happen in two cases. 1. the clock moved backwards, on restart we ignored everything from the VolatileDB since it's all in the future, and now the tip of the ImmutableDB points to a block produced in the same slot we're trying to produce a block in 2. k = 0 and we already adopted a block from another leader of the same slot. We record both the current slot number as well as the tip of the ImmutableDB. See also + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.Loop.StartLeadershipCheck + + +> Start of the leadership check. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.StateInfo + + +> kesStartPeriod +> kesEndPeriod is kesStartPeriod + tpraosMaxKESEvo +> kesEvolution is the current evolution or /relative period/. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Forge.ThreadStats.ForgingStats + + +> nodeCannotForgeNum shows how many times this node could not forge. +> nodeIsLeaderNum shows how many times this node was leader. +> blocksForgedNum shows how many blocks did forge in this node. +> slotsMissed shows how many slots were missed in this node. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### LedgerMetrics + + +> Periodic trace emitted every Nth slot, approximately 700 milliseconds after slot start. +> It queries the current ledger and chain to report metrics such as UTxO set and delegation map sizes. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Mempool.AddedTx + + +> New, valid transaction that was added to the Mempool. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.AttemptAdd + + +> Mempool is about to try to validate and add a transaction. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.ManuallyRemovedTxs + + +> Transactions that have been manually removed from the Mempool. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.RejectedTx + + +> New, invalid transaction that was rejected and thus not added to the Mempool. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.RemoveTxs + + +> Previously valid transactions that are no longer valid because of changes in the ledger state. These transactions have been removed from the Mempool. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.SyncNotNeeded + + +> The mempool and the LedgerDB are in sync already. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.Synced + + +> The mempool and the LedgerDB are syncing or in sync depending on the argument on the trace. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Mempool.TipMovedBetweenSTMBlocks + + +> LedgerDB moved to an alternative fork between two reads during re-sync. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Net.AcceptPolicy.ConnectionHardLimit + + +> Hard rate limit reached, waiting until the number of connections drops below n. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.AcceptPolicy.ConnectionLimitResume + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.AcceptPolicy.ConnectionRateLimiting + + +> Rate limiting accepting connections, delaying next accept for given time, currently serving n connections. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.Connect + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionCleanup + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionExists + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionFailure + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionHandler.Error + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionHandler.HandshakeClientError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionHandler.HandshakeQuery + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionHandler.HandshakeServerError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionHandler.HandshakeSuccess + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionManagerCounters + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionNotFound + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionTimeWait + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ConnectionTimeWaitDone + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ForbiddenConnection + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.ForbiddenOperation + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.IncludeConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.PruneConnections + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.ConnectionManager.Local.Shutdown + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.State + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.TerminatedConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.TerminatingConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Local.UnexpectedlyFalseAssertion + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.ConnectionManager.Local.UnregisterConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.ConnectionManager.Remote.Connect + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionCleanup + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionExists + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionFailure + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionHandler.Error + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeClientError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeQuery + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeServerError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeSuccess + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionManagerCounters + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionNotFound + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionTimeWait + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.ConnectionTimeWaitDone + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ForbiddenConnection + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.ForbiddenOperation + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.IncludeConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.PruneConnections + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.Shutdown + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.State + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.TerminatedConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.TerminatingConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Remote.UnexpectedlyFalseAssertion + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.ConnectionManager.Remote.UnregisterConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.ConnectionManager.Transition.Transition + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.InboundGovernor.Local.DemotedToColdRemote + + +> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.DemotedToWarmRemote + + +> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.Inactive + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.InboundGovernorCounters + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.InboundGovernorError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Warning` + +### Net.InboundGovernor.Local.MaturedConnections + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.MuxCleanExit + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.MuxErrored + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.NewConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.PromotedToHotRemote + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.PromotedToWarmRemote + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.RemoteState + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.ResponderErrored + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.ResponderRestarted + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.ResponderStartFailure + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.ResponderStarted + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.ResponderTerminated + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Local.UnexpectedlyFalseAssertion + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Warning` + +### Net.InboundGovernor.Local.WaitIdleRemote + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.InboundGovernor.Remote.DemotedToColdRemote + + +> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.DemotedToWarmRemote + + +> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.Inactive + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.InboundGovernorCounters + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.InboundGovernorError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.MaturedConnections + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.MuxCleanExit + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.MuxErrored + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.NewConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.PromotedToHotRemote + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.PromotedToWarmRemote + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.RemoteState + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.ResponderErrored + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.ResponderRestarted + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.ResponderStartFailure + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.ResponderStarted + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.ResponderTerminated + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Remote.UnexpectedlyFalseAssertion + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.InboundGovernor.Remote.WaitIdleRemote + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.InboundGovernor.Transition.Transition + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Warning` + +### Net.KeepAliveClient + + +> A server read has occurred, either for an add block or a rollback + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.CleanExit + + +> Miniprotocol terminated cleanly. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Mux.Local.ExceptionExit + + +> Miniprotocol terminated with exception. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Mux.Local.NewMux + + +> New Mux + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.StartEagerly + + +> Eagerly started. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.StartOnDemand + + +> Preparing to start. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.StartOnDemandAny + + +> Start whenever any other protocol has started. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.StartedOnDemand + + +> Started on demand. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.Starting + + +> Mux Starting + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.State + + +> State. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.Stopped + + +> Mux shutdown. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.Stopping + + +> Mux shutdown. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Local.Terminating + + +> Terminating. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Mux.Remote.CleanExit + + +> Miniprotocol terminated cleanly. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.Mux.Remote.ExceptionExit + + +> Miniprotocol terminated with exception. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.Mux.Remote.NewMux + + +> New Mux + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.StartEagerly + + +> Eagerly started. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.StartOnDemand + + +> Preparing to start. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.StartOnDemandAny + + +> Start whenever any other protocol has started. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.StartedOnDemand + + +> Started on demand. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.Starting + + +> Mux Starting + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.State + + +> State. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.Mux.Remote.Stopped + + +> Mux shutdown. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.Stopping + + +> Mux shutdown. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.Mux.Remote.Terminating + + +> Terminating. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Actions.ConnectionError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Actions.MonitoringError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Actions.MonitoringResult + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Actions.PeerHotDuration + + +> Reports how long the outbound connection was in hot state + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Actions.StatusChangeFailure + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Actions.StatusChanged + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Counters.Counters + + +> Peer selection peer counters + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Initiator.GovernorState + + +> Outbound peer selection internal state + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Responder.GovernorState + + +> Outbound peer selection internal state + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Selection.BigLedgerPeersFailure + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.BigLedgerPeersRequest + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.BigLedgerPeersResults + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.BootstrapPeersFlagChangedWhilstInSensitiveState + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.ChurnAction + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.ChurnTimeout + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.ChurnWait + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DebugState + + +> peer selection internal state + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteAsynchronous + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteBigLedgerPeersAsynchronous + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotBigLedgerPeerDone + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotBigLedgerPeerFailed + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotBigLedgerPeerFailed.CoolingToColdTimeout + + +> Impossible asynchronous demotion timeout + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotBigLedgerPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotDone + + +> target active, actual active, peer + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotFailed + + +> target active, actual active, peer, reason + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotFailed.CoolingToColdTimeout + + +> Impossible asynchronous demotion timeout + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteHotPeers + + +> target active, actual active, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteLocalAsynchronous + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteLocalHotPeers + + +> local per-group (target active, actual active), selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerDone + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerFailed + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerFailed.CoolingToColdTimeout + + +> Impossible asynchronous demotion timeout + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmDone + + +> target established, actual established, peer + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmFailed + + +> target established, actual established, peer, reason + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmFailed.CoolingToColdTimeout + + +> Impossible asynchronous demotion timeout + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.DemoteWarmPeers + + +> target established, actual established, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.ForgetBigLedgerPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.ForgetColdPeers + + +> target known peers, actual known peers, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.GovernorWakeup + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.LedgerStateJudgementChanged + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.LocalRootPeersChanged + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.OnlyBootstrapPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.OutboundGovernorCriticalFailure + + +> Outbound Governor was killed unexpectedly + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PeerShareRequests + + +> target known peers, actual known peers, peers available for gossip, peers selected for gossip + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Selection.PeerShareResults + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Info` + +### Net.PeerSelection.Selection.PeerShareResultsFiltered + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PickInboundPeers + + +> An inbound connection was added to known set of outbound governor + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdBigLedgerPeerDone + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdBigLedgerPeerFailed + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdBigLedgerPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdDone + + +> target active, actual active, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdFailed + + +> target established, actual established, peer, delay until next promotion, reason + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdLocalPeers + + +> target local established, actual local established, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteColdPeers + + +> target established, actual established, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmAborted + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerAborted + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerDone + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerFailed + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmDone + + +> target active, actual active, peer + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmFailed + + +> target active, actual active, peer, reason + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmLocalPeers + + +> local per-group (target active, actual active), selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PromoteWarmPeers + + +> target active, actual active, selected peers + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PublicRootsFailure + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PublicRootsRequest + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.PublicRootsResults + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.TargetsChanged + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.UseBootstrapPeersChanged + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.PeerSelection.Selection.VerifyPeerSnapshot + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Net.Peers.Ledger.DisabledLedgerPeers + + +> Trace for when getting peers from the ledger is disabled, that is DontUseLedger. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.FallingBackToPublicRootPeers + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.FetchingNewLedgerState + + +> Trace for fetching a new list of peers from the ledger. Int is the number of peers returned. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.NotEnoughBigLedgerPeers + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Peers.Ledger.NotEnoughLedgerPeers + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Peers.Ledger.PickedBigLedgerPeer + + +> Trace for a big ledger peer picked with accumulated and relative stake of its pool. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.PickedBigLedgerPeers + + +> Trace for the number of big ledger peers we wanted to pick and the list of peers picked. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.PickedLedgerPeer + + +> Trace for a peer picked with accumulated and relative stake of its pool. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.PickedLedgerPeers + + +> Trace for the number of peers we wanted to pick and the list of peers picked. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.RequestForPeers + + +> RequestForPeers (NumberOfPeers 1) + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.ReusingLedgerState + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.TraceLedgerPeersDomains + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.TraceUseLedgerAfter + + +> Trace UseLedgerAfter value. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.UsingBigLedgerPeerSnapshot + + +> Trace for when a request for big ledger peers is fulfilled from the snapshot file specified in the topology file. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.Ledger.WaitingOnRequest + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootDNSMap + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootDomains + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootError + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootFailure + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootGroups + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootReconfigured + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.LocalRoot.LocalRootWaiting + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.PublicRoot.PublicRootDomains + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Peers.PublicRoot.PublicRootRelayAccessPoint + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Server.Local.AcceptConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Server.Local.AcceptError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Local.AcceptPolicy + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Local.Error + + + + +Severity: `Critical` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Local.Started + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Local.Stopped + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Remote.AcceptConnection + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Net.Server.Remote.AcceptError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Remote.AcceptPolicy + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Remote.Error + + + + +Severity: `Critical` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Remote.Started + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Net.Server.Remote.Stopped + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeAddBlock + + +> Applying block + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeInitChainSelection + + +> Performing initial chain selection + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeKernelOnline + + +> Tracing system configured and node kernel is online + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### NodeState.NodeReplays + + +> Replaying chain + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeShutdown + + +> Node shutting down + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeStartup + + +> Node startup + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### NodeState.NodeTracingFailure + + +> Tracing system experienced a non-fatal failure during startup + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeTracingForwardingInterrupted + + +> Trace/metrics forwarding connection was interrupted + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### NodeState.NodeTracingOnlineConfiguring + + +> Tracing system came online, system configuring now + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### NodeState.OpeningDbs + + +> ChainDB components being opened + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### NodeState.PrometheusSimple.Start + + +> PrometheusSimple backend is starting + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### NodeState.PrometheusSimple.Stop + + +> PrometheusSimple backend stopped + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### RPC.Error + + +> Normal operation errors such as request errors. Those are not harmful to the RPC server itself. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### RPC.FatalError + + +> RPC startup critical error. + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### RPC.QueryService.ReadParams.Span + + +> Span for the ReadParams UTXORPC method. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### RPC.QueryService.ReadUtxos.Span + + +> Span for the ReadUtxos UTXORPC method. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### RPC.SubmitService.N2cConnectionError + + +> Node connection error. This should not happen, as this means that there is an issue in cardano-rpc configuration. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### RPC.SubmitService.SubmitTx.Span + + +> Span for the SubmitTx UTXORPC method. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### RPC.SubmitService.TxDecodingError + + +> A regular request error, when submitted transaction decoding fails. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### RPC.SubmitService.TxValidationError + + +> A regular request error, when submitted transaction is invalid. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Reflection.MetricsInfo + + +> Writes out numbers for metrics delivered. +> This internal message can't be filtered by the current configuration + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Reflection.RememberLimiting + + +> ^ This message remembers of ongoing frequency limiting, and gives the number of messages that has been suppressed +> This internal message can't be filtered by the current configuration + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Reflection.StartLimiting + + +> This message indicates the start of frequency limiting +> This internal message can't be filtered by the current configuration + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Reflection.StopLimiting + + +> This message indicates the stop of frequency limiting, and gives the number of messages that has been suppressed +> This internal message can't be filtered by the current configuration + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Reflection.TracerConfigInfo + + +> Trace the tracer configuration which is effectively used. +> This internal message can't be filtered by the current configuration + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Reflection.TracerConsistencyWarnings + + +> Tracer consistency check found errors. +> This internal message can't be filtered by the current configuration + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Reflection.TracerInfo + + +> Writes out tracers with metrics and silent tracers. +> This internal message can't be filtered by the current configuration + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Reflection.UnknownNamespace + + +> A value was queried for a namespaces from a tracer,which is unknown. This indicates a bug in the tracer implementation. +> This internal message can't be filtered by the current configuration + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Resources + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered Invisible by config value: `Silence` + +### Shutdown.Abnormal + + +> non-isEOFerror shutdown request + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Shutdown.ArmedAt + + +> Setting up node shutdown at given slot / block. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Shutdown.Requested + + +> Node shutdown was requested. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Shutdown.Requesting + + +> Ringing the node shutdown doorbell + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Shutdown.UnexpectedInput + + +> Received shutdown request but found unexpected input in --shutdown-ipc FD: + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.BlockForgingBlockTypeMismatch + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.BlockForgingUpdate + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.Byron + + +> _bibSystemStartTime_: +> _bibSlotLength_: gives the length of a slot as time interval. +> _bibEpochLength_: gives the number of slots which forms an epoch. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.Common + + +> _biConfigPath_: is the path to the config in use. +> _biProtocol_: is the name of the protocol, e.g. "Byron", "Shelley" or "Byron; Shelley". +> _biVersion_: is the version of the node software running. +> _biCommit_: is the commit revision of the software running. +> _biNodeStartTime_: gives the time this node was started. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.DBValidation + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.DiffusionInit.ConfiguringLocalSocket + + +> ConfiguringLocalSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.ConfiguringServerSocket + + +> ConfiguringServerSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.CreateSystemdSocketForSnocketPath + + +> CreateSystemdSocketForSnocketPath + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.CreatedLocalSocket + + +> CreatedLocalSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.CreatingServerSocket + + +> CreatingServerSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.DiffusionErrored + + +> DiffusionErrored + + +Severity: `Critical` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.ListeningLocalSocket + + +> ListeningLocalSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.ListeningServerSocket + + +> ListeningServerSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.LocalSocketUp + + +> LocalSocketUp + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.RunLocalServer + + +> RunLocalServer + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.RunServer + + +> RunServer + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.ServerSocketUp + + +> ServerSocketUp + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.SystemdSocketConfiguration + + +> SystemdSocketConfiguration + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.UnsupportedLocalSystemdSocket + + +> UnsupportedLocalSystemdSocket + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.UnsupportedReadySocketCase + + +> UnsupportedReadySocketCase + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.DiffusionInit.UsingSystemdSocket + + +> UsingSystemdSocket + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Info` + +### Startup.Info + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.LedgerPeerSnapshot + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.LedgerPeerSnapshot.Incompatible + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.MovedTopLevelOption + + +> An option was moved from the top level of the config file to a subsection + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.Network + + +> _niAddresses_: IPv4 or IPv6 socket ready to accept connectionsor diffusion addresses. +> _niDiffusionMode_: shows if the node runs only initiator or bothinitiator or responder node. +> _niDnsProducers_: shows the list of domain names to subscribe to. +> _niIpProducers_: shows the list of ip subscription addresses. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.NetworkConfig + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.NetworkConfigUpdate + + + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.NetworkConfigUpdateError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.NetworkConfigUpdateUnsupported + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.NetworkMagic + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.NonP2PWarning + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.P2PInfo + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.ShelleyBased + + +> bisEra is the current era, e.g. "Shelley", "Allegra", "Mary" or "Alonzo". +> _bisSystemStartTime_: +> _bisSlotLength_: gives the length of a slot as time interval. +> _bisEpochLength_: gives the number of slots which forms an epoch. +> _bisSlotsPerKESPeriod_: gives the slots per KES period. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.SocketConfigError + + + + +Severity: `Error` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.Time + + + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Startup.WarningDevelopmentNodeToClientVersions + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### Startup.WarningDevelopmentNodeToNodeVersions + + + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### StateQueryServer.Receive.Acquire + + +> The client requests that the state as of a particular recent point on the server's chain (within K of the tip) be made available to query, and waits for confirmation or failure. +> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Receive.Acquired + + +> The server can confirm that it has the state at the requested point. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Receive.Done + + +> The client can terminate the protocol. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Receive.Failure + + +> The server can report that it cannot obtain the state for the requested point. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### StateQueryServer.Receive.Query + + +> The client can perform queries on the current acquired state. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Receive.ReAcquire + + +> This is like 'MsgAcquire' but for when the client already has a state. By moving to another state directly without a 'MsgRelease' it enables optimisations on the server side (e.g. moving to the state for the immediate next block). +> Note that failure to re-acquire is equivalent to 'MsgRelease', rather than keeping the exiting acquired state. +> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Receive.Release + + +> The client can instruct the server to release the state. This lets the server free resources. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Receive.Result + + +> The server must reply with the queries. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.Acquire + + +> The client requests that the state as of a particular recent point on the server's chain (within K of the tip) be made available to query, and waits for confirmation or failure. +> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.Acquired + + +> The server can confirm that it has the state at the requested point. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.Done + + +> The client can terminate the protocol. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.Failure + + +> The server can report that it cannot obtain the state for the requested point. + + +Severity: `Warning` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### StateQueryServer.Send.Query + + +> The client can perform queries on the current acquired state. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.ReAcquire + + +> This is like 'MsgAcquire' but for when the client already has a state. By moving to another state directly without a 'MsgRelease' it enables optimisations on the server side (e.g. moving to the state for the immediate next block). +> Note that failure to re-acquire is equivalent to 'MsgRelease', rather than keeping the exiting acquired state. +> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.Release + + +> The client can instruct the server to release the state. This lets the server free resources. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### StateQueryServer.Send.Result + + +> The server must reply with the queries. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Receive.AcceptTx + + +> The server can reply to inform the client that it has accepted the transaction. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Receive.Done + + +> The client can terminate the protocol. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Receive.RejectTx + + +> The server can reply to inform the client that it has rejected the transaction. A reason for the rejection is included. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Receive.SubmitTx + + +> The client submits a single transaction and waits a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Send.AcceptTx + + +> The server can reply to inform the client that it has accepted the transaction. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Send.Done + + +> The client can terminate the protocol. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Send.RejectTx + + +> The server can reply to inform the client that it has rejected the transaction. A reason for the rejection is included. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Local.Send.SubmitTx + + +> The client submits a single transaction and waits a reply. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.LocalServer.ReceivedTx + + +> A transaction was received. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.Acquire + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.Acquired + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.AwaitAcquire + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.Done + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.GetMeasures + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.GetSizes + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.HasTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.NextTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.Release + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.ReplyGetMeasures + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.ReplyGetSizes + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.ReplyHasTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Receive.ReplyNextTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.Acquire + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.Acquired + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.AwaitAcquire + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.Done + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.GetMeasures + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.GetSizes + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.HasTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.NextTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.Release + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.ReplyGetMeasures + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.ReplyGetSizes + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.ReplyHasTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.MonitorClient.Send.ReplyNextTx + + + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Receive.Done + + +> Termination message, initiated by the client when the server is making a blocking call for more transaction identifiers. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Receive.MsgInit + + +> Client side hello message. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Receive.ReplyTxIds + + +> Reply with a list of transaction identifiers for available transactions, along with the size of each transaction. +> The list must not be longer than the maximum number requested. +> In the 'StTxIds' 'StBlocking' state the list must be non-empty while in the 'StTxIds' 'StNonBlocking' state the list may be empty. +> These transactions are added to the notional FIFO of outstanding transaction identifiers for the protocol. +> The order in which these transaction identifiers are returned must be the order in which they are submitted to the mempool, to preserve dependent transactions. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Receive.ReplyTxs + + +> Reply with the requested transactions, or implicitly discard. +> Transactions can become invalid between the time the transaction identifier was sent and the transaction being requested. Invalid (including committed) transactions do not need to be sent. +> Any transaction identifiers requested but not provided in this reply should be considered as if this peer had never announced them. (Note that this is no guarantee that the transaction is invalid, it may still be valid and available from another peer). + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Receive.RequestTxIds + + +> Request a non-empty list of transaction identifiers from the client, and confirm a number of outstanding transaction identifiers. +> With 'TokBlocking' this is a blocking operation: the response will always have at least one transaction identifier, and it does not expect a prompt response: there is no timeout. This covers the case when there is nothing else to do but wait. For example this covers leaf nodes that rarely, if ever, create and submit a transaction. +> With 'TokNonBlocking' this is a non-blocking operation: the response may be an empty list and this does expect a prompt response. This covers high throughput use cases where we wish to pipeline, by interleaving requests for additional transaction identifiers with requests for transactions, which requires these requests not block. +> The request gives the maximum number of transaction identifiers that can be accepted in the response. This must be greater than zero in the 'TokBlocking' case. In the 'TokNonBlocking' case either the numbers acknowledged or the number requested must be non-zero. In either case, the number requested must not put the total outstanding over the fixed protocol limit. +> The request also gives the number of outstanding transaction identifiers that can now be acknowledged. The actual transactions to acknowledge are known to the peer based on the FIFO order in which they were provided. +> There is no choice about when to use the blocking case versus the non-blocking case, it depends on whether there are any remaining unacknowledged transactions (after taking into account the ones acknowledged in this message): +> * The blocking case must be used when there are zero remaining unacknowledged transactions. +> * The non-blocking case must be used when there are non-zero remaining unacknowledged transactions. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Receive.RequestTxs + + +> Request one or more transactions corresponding to the given transaction identifiers. +> While it is the responsibility of the replying peer to keep within pipelining in-flight limits, the sender must also cooperate by keeping the total requested across all in-flight requests within the limits. +> It is an error to ask for transaction identifiers that were not previously announced (via 'MsgReplyTxIds'). +> It is an error to ask for transaction identifiers that are not outstanding or that were already asked for. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Send.Done + + +> Termination message, initiated by the client when the server is making a blocking call for more transaction identifiers. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Send.MsgInit + + +> Client side hello message. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Send.ReplyTxIds + + +> Reply with a list of transaction identifiers for available transactions, along with the size of each transaction. +> The list must not be longer than the maximum number requested. +> In the 'StTxIds' 'StBlocking' state the list must be non-empty while in the 'StTxIds' 'StNonBlocking' state the list may be empty. +> These transactions are added to the notional FIFO of outstanding transaction identifiers for the protocol. +> The order in which these transaction identifiers are returned must be the order in which they are submitted to the mempool, to preserve dependent transactions. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Send.ReplyTxs + + +> Reply with the requested transactions, or implicitly discard. +> Transactions can become invalid between the time the transaction identifier was sent and the transaction being requested. Invalid (including committed) transactions do not need to be sent. +> Any transaction identifiers requested but not provided in this reply should be considered as if this peer had never announced them. (Note that this is no guarantee that the transaction is invalid, it may still be valid and available from another peer). + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Send.RequestTxIds + + +> Request a non-empty list of transaction identifiers from the client, and confirm a number of outstanding transaction identifiers. +> With 'TokBlocking' this is a blocking operation: the response will always have at least one transaction identifier, and it does not expect a prompt response: there is no timeout. This covers the case when there is nothing else to do but wait. For example this covers leaf nodes that rarely, if ever, create and submit a transaction. +> With 'TokNonBlocking' this is a non-blocking operation: the response may be an empty list and this does expect a prompt response. This covers high throughput use cases where we wish to pipeline, by interleaving requests for additional transaction identifiers with requests for transactions, which requires these requests not block. +> The request gives the maximum number of transaction identifiers that can be accepted in the response. This must be greater than zero in the 'TokBlocking' case. In the 'TokNonBlocking' case either the numbers acknowledged or the number requested must be non-zero. In either case, the number requested must not put the total outstanding over the fixed protocol limit. +> The request also gives the number of outstanding transaction identifiers that can now be acknowledged. The actual transactions to acknowledge are known to the peer based on the FIFO order in which they were provided. +> There is no choice about when to use the blocking case versus the non-blocking case, it depends on whether there are any remaining unacknowledged transactions (after taking into account the ones acknowledged in this message): +> * The blocking case must be used when there are zero remaining unacknowledged transactions. +> * The non-blocking case must be used when there are non-zero remaining unacknowledged transactions. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.Remote.Send.RequestTxs + + +> Request one or more transactions corresponding to the given transaction identifiers. +> While it is the responsibility of the replying peer to keep within pipelining in-flight limits, the sender must also cooperate by keeping the total requested across all in-flight requests within the limits. +> It is an error to ask for transaction identifiers that were not previously announced (via 'MsgReplyTxIds'). +> It is an error to ask for transaction identifiers that are not outstanding or that were already asked for. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.AddedToMempool + + +> Transactions added to the mempool and processing time + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.CanRequestMoreTxs + + +> There are no replies in flight, but we do know some more txs we can ask for, so lets ask for them and more txids. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.CannotRequestMoreTxs + + +> There's no replies in flight, and we have no more txs we can ask for so the only remaining thing to do is to ask for more txids. Since this is the only thing to do now, we make this a blocking call. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.Collected + + +> Number of transactions just about to be inserted. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.Decision + + +> Decision to advance the protocol + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.Error + + +> Protocol violation causing connection reset + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.Processed + + +> Just processed transaction pass/fail breakdown. + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.RejectedFromMempool + + +> Transactions rejected from mempool and processing time + + +Severity: `Debug` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxInbound.Terminated + + +> Server received 'MsgDone'. + + +Severity: `Notice` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Visible` by config value: `Notice` + +### TxSubmission.TxOutbound.ControlMessage + + +> Peer selection control instruction + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxOutbound.RecvMsgRequest + + +> The IDs of the transactions requested. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### TxSubmission.TxOutbound.SendMsgReply + + +> The transactions to be sent in the response. + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` + +### Version.NodeVersion + + +> Node version information + + +Severity: `Info` +Privacy: `Public` +Details: `DNormal` + + +From current configuration: + +Backends: + `EKGBackend`, + `Stdout MachineFormat`, + `Forwarder` +Filtered `Invisible` by config value: `Notice` +## Metrics + +### Forge.about-to-lead + + + +Dispatched by: +Forge.Loop.StartLeadershipCheck + +### Forge.adopted + + + +Dispatched by: +Forge.Loop.AdoptedBlock + +### Forge.adoption-thread-died + + + +Dispatched by: +Forge.Loop.AdoptionThreadDied + +### Forge.block-from-future + + + +Dispatched by: +Forge.Loop.BlockFromFuture + +### Forge.could-not-forge + + + +Dispatched by: +Forge.Loop.NoLedgerState +Forge.Loop.NoLedgerView +Forge.Loop.NodeCannotForge + +### Forge.didnt-adopt + + + +Dispatched by: +Forge.Loop.DidntAdoptBlock + +### Forge.forged + +> Counter of forged blocks + + +Dispatched by: +Forge.Loop.ForgedBlock + +### Forge.forged-invalid + + + +Dispatched by: +Forge.Loop.ForgedInvalidBlock + +### Forge.node-is-leader + + + +Dispatched by: +Forge.Loop.NodeIsLeader + +### Forge.node-not-leader + + + +Dispatched by: +Forge.Loop.NodeNotLeader + +### Forge.slot-is-immutable + + + +Dispatched by: +Forge.Loop.SlotIsImmutable + +### GSM.state + +> The state of the Genesis State Machine. 0 = PreSyncing, 1 = Syncing, 2 = CaughtUp. + + +Dispatched by: +Consensus.GSM.EnterCaughtUp +Consensus.GSM.InitializedInCaughtUp +Consensus.GSM.InitializedInPreSyncing +Consensus.GSM.LeaveCaughtUp +Consensus.GSM.PreSyncingToSyncing +Consensus.GSM.SyncingToPreSyncing + +### Mem.resident + +> Kernel-reported RSS (resident set size) + + +Dispatched by: +Resources + +### RTS.alloc + +> RTS-reported bytes allocated + + +Dispatched by: +Resources + +### RTS.gcHeapBytes + +> RTS-reported heap bytes + + +Dispatched by: +Resources + +### RTS.gcLiveBytes + +> RTS-reported live bytes + + +Dispatched by: +Resources + +### RTS.gcMajorNum + +> Major GCs + + +Dispatched by: +Resources + +### RTS.gcMinorNum + +> Minor GCs + + +Dispatched by: +Resources + +### RTS.gcticks + +> RTS-reported CPU ticks spent on GC + + +Dispatched by: +Resources + +### RTS.mutticks + +> RTS-reported CPU ticks spent on mutator + + +Dispatched by: +Resources + +### RTS.threads + +> RTS green thread count + + +Dispatched by: +Resources + +### Stat.cputicks + +> Kernel-reported CPU ticks (1/100th of a second), since process start + + +Dispatched by: +Resources + +### Stat.fsRd + +> FS bytes read + + +Dispatched by: +Resources + +### Stat.fsWr + +> FS bytes written + + +Dispatched by: +Resources + +### Stat.netRd + +> IP packet bytes read + + +Dispatched by: +Resources + +### Stat.netWr + +> IP packet bytes written + + +Dispatched by: +Resources + +### SuppressedMessages.. + +> Number of suppressed messages of a certain namespace + + +Dispatched by: +Reflection.StartLimiting + +### blockNum + +> Number of blocks in this chain fragment. + + +Dispatched by: +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.SwitchedToAFork + +### blockReplayProgress + +> Progress in percent + + +Dispatched by: +ChainDB.ReplayBlock.LedgerReplay + +### blockfetchclient.blockdelay + +> delay (s) of the latest block fetch + + +Dispatched by: +BlockFetch.Client.ClientMetrics + +### blockfetchclient.blockdelay.cdfFive + +> probability for block fetch to complete within 5s + + +Dispatched by: +BlockFetch.Client.ClientMetrics + +### blockfetchclient.blockdelay.cdfOne + +> probability for block fetch to complete within 1s + + +Dispatched by: +BlockFetch.Client.ClientMetrics + +### blockfetchclient.blockdelay.cdfThree + +> probability for block fetch to complete within 3s + + +Dispatched by: +BlockFetch.Client.ClientMetrics + +### blockfetchclient.blocksize + +> block size (bytes) of the latest block fetch + + +Dispatched by: +BlockFetch.Client.ClientMetrics + +### blockfetchclient.lateblocks + +> number of block fetches that took longer than 5s + + +Dispatched by: +BlockFetch.Client.ClientMetrics + +### blocksForged + +> How many blocks did this node forge? + + +Dispatched by: +Forge.ThreadStats.ForgingStats + +### cardano_build_info + +> Cardano node build info + + +Dispatched by: +Version.NodeVersion + +### cardano_version_major + +> Cardano node version information + + +Dispatched by: +Version.NodeVersion + +### cardano_version_minor + +> Cardano node version information + + +Dispatched by: +Version.NodeVersion + +### cardano_version_patch + +> Cardano node version information + + +Dispatched by: +Version.NodeVersion + +### connectedPeers + +> Number of connected peers + + +Dispatched by: +BlockFetch.Decision.Accept +BlockFetch.Decision.Decline + +### connectionManager.duplexConns + + + +Dispatched by: +Net.ConnectionManager.Remote.ConnectionManagerCounters + +### connectionManager.duplexConns + + + +Dispatched by: +Net.ConnectionManager.Local.ConnectionManagerCounters + +### connectionManager.fullDuplexConns + + + +Dispatched by: +Net.ConnectionManager.Remote.ConnectionManagerCounters + +### connectionManager.fullDuplexConns + + + +Dispatched by: +Net.ConnectionManager.Local.ConnectionManagerCounters + +### connectionManager.inboundConns + + + +Dispatched by: +Net.ConnectionManager.Remote.ConnectionManagerCounters + +### connectionManager.inboundConns + + + +Dispatched by: +Net.ConnectionManager.Local.ConnectionManagerCounters + +### connectionManager.outboundConns + + + +Dispatched by: +Net.ConnectionManager.Remote.ConnectionManagerCounters + +### connectionManager.outboundConns + + + +Dispatched by: +Net.ConnectionManager.Local.ConnectionManagerCounters + +### connectionManager.prunableConns + + + +Dispatched by: +Net.ConnectionManager.Remote.ConnectionManagerCounters + +### connectionManager.prunableConns + + + +Dispatched by: +Net.ConnectionManager.Local.ConnectionManagerCounters + +### connectionManager.unidirectionalConns + + + +Dispatched by: +Net.ConnectionManager.Remote.ConnectionManagerCounters + +### connectionManager.unidirectionalConns + + + +Dispatched by: +Net.ConnectionManager.Local.ConnectionManagerCounters + +### currentKESPeriod + + + +Dispatched by: +Forge.StateInfo + +### currentKESPeriod + + + +Dispatched by: +Forge.Loop.ForgeStateUpdateError + +### delegMapSize + +> Delegation map size + + +Dispatched by: +LedgerMetrics + +### density + +> The actual number of blocks created over the maximum expected number of blocks that could be created over the span of the last @k@ blocks. + + +Dispatched by: +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.SwitchedToAFork + +### epoch + +> In which epoch is the tip of the current chain. + + +Dispatched by: +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.SwitchedToAFork + +### forgedSlotLast + +> Slot number of the last forged block + + +Dispatched by: +Forge.Loop.ForgedBlock + +### forging_enabled + +> A node without forger credentials or started as non-producing has forging disabled. + + +Dispatched by: +Startup.BlockForgingUpdate + +### forks + +> counter for forks + + +Dispatched by: +ChainDB.AddBlockEvent.SwitchedToAFork + +### haskell_compiler_major + +> Cardano compiler version information + + +Dispatched by: +Version.NodeVersion + +### haskell_compiler_minor + +> Cardano compiler version information + + +Dispatched by: +Version.NodeVersion + +### haskell_compiler_patch + +> Cardano compiler version information + + +Dispatched by: +Version.NodeVersion + +### inboundGovernor.Cold + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### inboundGovernor.Cold + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### inboundGovernor.Hot + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### inboundGovernor.Hot + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### inboundGovernor.Idle + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### inboundGovernor.Idle + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### inboundGovernor.Warm + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### inboundGovernor.Warm + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### localInboundGovernor.cold + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### localInboundGovernor.cold + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### localInboundGovernor.hot + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### localInboundGovernor.hot + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### localInboundGovernor.idle + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### localInboundGovernor.idle + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### localInboundGovernor.warm + + + +Dispatched by: +Net.InboundGovernor.Remote.InboundGovernorCounters + +### localInboundGovernor.warm + + + +Dispatched by: +Net.InboundGovernor.Local.InboundGovernorCounters + +### mempoolBytes + +> Byte size of the mempool + + +Dispatched by: +Mempool.AddedTx +Mempool.ManuallyRemovedTxs +Mempool.RejectedTx +Mempool.RemoveTxs + +### node.start.time + +> The UTC time this node was started represented in POSIX seconds. + + +Dispatched by: +Startup.Common + +### nodeCannotForge + +> How many times was this node unable to forge [a block]? + + +Dispatched by: +Forge.ThreadStats.ForgingStats + +### nodeIsLeader + +> How many times was this node slot leader? + + +Dispatched by: +Forge.ThreadStats.ForgingStats + +### operationalCertificateExpiryKESPeriod + + + +Dispatched by: +Forge.StateInfo + +### operationalCertificateExpiryKESPeriod + + + +Dispatched by: +Forge.Loop.ForgeStateUpdateError + +### operationalCertificateStartKESPeriod + + + +Dispatched by: +Forge.StateInfo + +### operationalCertificateStartKESPeriod + + + +Dispatched by: +Forge.Loop.ForgeStateUpdateError + +### peerSelection.ActiveBigLedgerPeers + +> Number of active big ledger peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveBigLedgerPeersDemotions + +> Number of active big ledger peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveBootstrapPeers + +> Number of active bootstrap peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveBootstrapPeersDemotions + +> Number of active bootstrap peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveLocalRootPeers + +> Number of active local root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveLocalRootPeersDemotions + +> Number of active local root peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveNonRootPeers + +> Number of active non root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActiveNonRootPeersDemotions + +> Number of active non root peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActivePeers + +> Number of active peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ActivePeersDemotions + +> Number of active peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.Cold + +> Number of cold peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ColdBigLedgerPeers + +> Number of cold big ledger peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ColdBigLedgerPeersPromotions + +> Number of cold big ledger peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ColdBootstrapPeersPromotions + +> Number of cold bootstrap peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ColdNonRootPeersPromotions + +> Number of cold non root peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.ColdPeersPromotions + +> Number of cold peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.EstablishedBigLedgerPeers + +> Number of established big ledger peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.EstablishedBootstrapPeers + +> Number of established bootstrap peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.EstablishedLocalRootPeers + +> Number of established local root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.EstablishedNonRootPeers + +> Number of established non root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.EstablishedPeers + +> Number of established peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.Hot + +> Number of hot peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.HotBigLedgerPeers + +> Number of hot big ledger peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.KnownBigLedgerPeers + +> Number of known big ledger peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.KnownBootstrapPeers + +> Number of known bootstrap peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.KnownLocalRootPeers + +> Number of known local root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.KnownNonRootPeers + +> Number of known non root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.KnownPeers + +> Number of known peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.LocalRoots + +> Numbers of warm & hot local roots + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.RootPeers + +> Number of root peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.Warm + +> Number of warm peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmBigLedgerPeers + +> Number of warm big ledger peers + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmBigLedgerPeersDemotions + +> Number of warm big ledger peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmBigLedgerPeersPromotions + +> Number of warm big ledger peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmBootstrapPeersDemotions + +> Number of warm bootstrap peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmBootstrapPeersPromotions + +> Number of warm bootstrap peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmLocalRootPeersPromotions + +> Number of warm local root peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmNonRootPeersDemotions + +> Number of warm non root peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmNonRootPeersPromotions + +> Number of warm non root peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmPeersDemotions + +> Number of warm peers demotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.WarmPeersPromotions + +> Number of warm peers promotions + + +Dispatched by: +Net.PeerSelection.Counters.Counters + +### peerSelection.churn.DecreasedActiveBigLedgerPeers.duration + + + +Dispatched by: +Net.PeerSelection.Selection.ChurnAction + +### peerSelection.churn.DecreasedActivePeers.duration + + + +Dispatched by: +Net.PeerSelection.Selection.ChurnAction + +### peerSelection.churn.DecreasedEstablishedBigLedgerPeers.duration + + + +Dispatched by: +Net.PeerSelection.Selection.ChurnAction + +### peerSelection.churn.DecreasedEstablishedPeers.duration + + + +Dispatched by: +Net.PeerSelection.Selection.ChurnAction + +### peerSelection.churn.DecreasedKnownBigLedgerPeers.duration + + + +Dispatched by: +Net.PeerSelection.Selection.ChurnAction + +### peerSelection.churn.DecreasedKnownPeers.duration + + + +Dispatched by: +Net.PeerSelection.Selection.ChurnAction + +### remainingKESPeriods + + + +Dispatched by: +Forge.StateInfo + +### remainingKESPeriods + + + +Dispatched by: +Forge.Loop.ForgeStateUpdateError + +### rpc.request.QueryService.ReadParams + +> Span for the ReadParams UTXORPC method. + + +Dispatched by: +RPC.QueryService.ReadParams.Span + +### rpc.request.QueryService.ReadUtxos + +> Span for the ReadUtxos UTXORPC method. + + +Dispatched by: +RPC.QueryService.ReadUtxos.Span + +### rpc.request.SubmitService.SubmitTx + +> Span for the SubmitTx UTXORPC method. + + +Dispatched by: +RPC.SubmitService.SubmitTx.Span + +### served.block + +> This counter metric indicates how many blocks this node has served. + + +Dispatched by: +BlockFetch.Server.SendBlock + +### served.block.latest + +> This counter metric indicates how many chain tip blocks this node has served. + + +Dispatched by: +BlockFetch.Server.SendBlock + +### served.header + +> A counter triggered only on header event with falling edge + + +Dispatched by: +ChainSync.ServerHeader.Update + +### served.header + +> A counter triggered only on header event with falling edge + + +Dispatched by: +ChainSync.ServerBlock.Update + +### slotInEpoch + +> Relative slot number of the tip of the current chain within the epoch.. + + +Dispatched by: +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.SwitchedToAFork + +### slotNum + +> Number of slots in this chain fragment. + + +Dispatched by: +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.SwitchedToAFork + +### slotsMissed + +> How many slots did this node miss? + + +Dispatched by: +Forge.ThreadStats.ForgingStats + +### submissions.accepted + + + +Dispatched by: +TxSubmission.TxInbound.Processed + +### submissions.rejected + + + +Dispatched by: +TxSubmission.TxInbound.Processed + +### submissions.submitted + + + +Dispatched by: +TxSubmission.TxInbound.Collected + +### systemStartTime + +> The UTC time this node was started. + + +Dispatched by: +Startup.Common + +### tipBlock + +> Values for hash, parent hash and issuer verification key hash + + +Dispatched by: +ChainDB.AddBlockEvent.AddedToCurrentChain +ChainDB.AddBlockEvent.SwitchedToAFork + +### txsInMempool + +> Transactions in mempool + + +Dispatched by: +Mempool.AddedTx +Mempool.ManuallyRemovedTxs +Mempool.RejectedTx +Mempool.RemoveTxs + +### txsMempoolTimeoutHard + +> Transactions that hard timed out in mempool + + +Dispatched by: +Net.Mux.Remote.ExceptionExit + +### txsMempoolTimeoutHard + +> Transactions that hard timed out in mempool + + +Dispatched by: +Net.Mux.Local.ExceptionExit + +### txsMempoolTimeoutSoft + +> Transactions that soft timed out in mempool + + +Dispatched by: +Mempool.RejectedTx + +### txsProcessedNum + + + +Dispatched by: +Mempool.ManuallyRemovedTxs + +### txsSyncDuration + +> Time to sync the mempool in ms after block adoption + + +Dispatched by: +Mempool.Synced + +### utxoSize + +> UTxO set size + + +Dispatched by: +LedgerMetrics +## Datapoints + +### NodeInfo + + +> Basic information about this node collected at startup +> +> _niName_: Name of the node. +> _niProtocol_: Protocol which this nodes uses. +> _niVersion_: Software version which this node is using. +> _niStartTime_: Start time of this node. +> _niSystemStartTime_: How long did the start of the node took. + + +### NodeStartupInfo + + +> Startup information about this node, required for RTView +> +> _suiEra_: Name of the current era. +> _suiSlotLength_: Slot length, in seconds. +> _suiEpochLength_: Epoch length, in slots. +> _suiSlotsPerKESPeriod_: KES period length, in slots. + +## Configuration: +``` +{ + "AppicationName": null, + "Forwarder": { + "maxReconnectDelay": 30, + "queueSize": 128, + "verbosity": "Minimum" + }, + "MetricsPrefix": "cardano.node.metrics.", + "Options": { + "": { + "backends": [ + "EKGBackend", + "Forwarder", + "PrometheusSimple 127.0.0.1 12798", + "Stdout HumanFormatColoured" + ], + "detail": "DNormal", + "severity": "Notice" + }, + "BlockFetch.Client.CompletedBlockFetch": { + "maxFrequency": 2 + }, + "BlockFetch.Decision": { + "severity": "Info" + }, + "ChainDB": { + "severity": "Info" + }, + "ChainDB.AddBlockEvent.AddBlockValidation": { + "severity": "Silence" + }, + "ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate": { + "maxFrequency": 2 + }, + "ChainDB.AddBlockEvent.AddedBlockToQueue": { + "maxFrequency": 2 + }, + "ChainDB.AddBlockEvent.AddedBlockToVolatileDB": { + "maxFrequency": 2 + }, + "ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB": { + "maxFrequency": 2 + }, + "ChainDB.LedgerEvent.Forker": { + "severity": "Silence" + }, + "ChainSync.Client": { + "severity": "Warning" + }, + "Forge.Loop": { + "severity": "Info" + }, + "Forge.StateInfo": { + "severity": "Info" + }, + "Mempool": { + "severity": "Silence" + }, + "Mempool.AttemptAdd": { + "severity": "Silence" + }, + "Mempool.SyncNotNeeded": { + "severity": "Silence" + }, + "Net.ConnectionManager.Remote": { + "severity": "Info" + }, + "Net.InboundGovernor": { + "severity": "Warning" + }, + "Net.InboundGovernor.Remote": { + "severity": "Info" + }, + "Net.Mux.Remote": { + "severity": "Info" + }, + "Net.PeerSelection": { + "severity": "Info" + }, + "Resources": { + "severity": "Silence" + }, + "Startup.DiffusionInit": { + "severity": "Info" + } + }, + "PrometheusSimpleRun": null +} +``` +663 log messages, +159 metrics, +2 datapoints. + +ⓣ- This is the root of a tracer + +ⓢ- This is the root of a tracer that is silent because of the current configuration + +ⓜ- This is the root of a tracer, that provides metrics + +Generated at 2026-04-13 11:05:00.121894722 CEST, git commit hash f28b2ab394330fc5ac35893f1337230d1262b712, node version 10.7.1 diff --git a/bench/trace-schemas/trace-schemas-presentation.odp b/bench/trace-schemas/trace-schemas-presentation.odp new file mode 100644 index 0000000000000000000000000000000000000000..0ae3414376029ac977538a997c5028542ec155b7 GIT binary patch literal 46829 zcmb5UV~{0L(=NK(*0k;EY1_7@F+FYWwry+Lw%yaVZQHhOYoB@FbG{RCf7}~!DnVPXGk!vCfI0|@`b(ALK3KlyQGY{YSrd*y>-qE{dwYa2u*`=LrGz}&d{!Kc}I^4Px zqBv7*0MzU1V`m5OdR^=vqk5+MMuej4LRY^`N@v${4i%A-)$RK+mFm>x@u;A8_qyS@ z5;dOn7!FmtdqWZo`u2k`6d%v6JSEE+W5bSy&mMgS6P>fxv0oIc(AdVs-5jxUb7W{i zvi9zy4HKwq=8Gvp&zf^s4oCi-q@be9#`%@ywT*!E?RI>MCAvSu#T@M zLFXr{!4ssr_~BB=OuglyNr|&AxQ`Vx6>fV@zG~Mb+o+ zt*+M{y47$zT@nL4E-SS$ejS=|zT;UL<%8yS8t%!9I~C)}*nZ%%&;Vb6Ec~dfzcoqMY`w{_`BDc~RV%yoXjghmK z2Wl7dF=k1K1gE6drkL(TzEznwV@o+SQIQEc;q2rrsYWNm(dgp<_ZoW0o4o2PgJny! zSK6p^+k`2X-E8AeT0=%Un2Y3CT1}$>v#DkOayPZv82&$WcT8b#bt{v)NS-28TW^iW znkG{z(XOA|8e9TqY18MTh-0f785l)hTth`VY1D#&&g*?0Bv1E*&IMgs-EP~HDN%hd zQi36yp+S7%_u5~vY)Qrp8Na7~4cNINgQF-;_QNk>KS!)NdUlrp=}n~z*6Qh4uN7F4 z_ZGY^$04~r8|}qW-r5bAE46U$kH+6V(7EW+inWnmX#yWDhVs_{;Dj2$`qp8uW+H}` z+HWDbJ#%Gkg+@~gxK6r%U83fA@-w_s1HBC=O8XI0xVzjQ|DLHorIl>2#H3^`FFc#X zEt3KY*${B3*L7r`-JrJXa!v)84j_=kq$zz1NwIxL4}TF8{VIJ7)g0B$N?lg30h}Q2 zX)ceHf^X^tD;f^l>59k1Oc zVt&(&-xh9?R)d}x5BksNJ7rh|;6_}ce8#WLg|HhExlue@#y=W5D~_gyC(JvMoy!lj z?y{;3qsLi?V;_wI6uvyG-)+o{qbRfF5n;&-5tgK7j|A~ZLrt&-iO`K~H`xoOHpxWf zAR;Jsr7>|NEoZ`2R$nemj|TRbc$=V=wnLJVcDjy_y8ObQxqlQ0PK4awW)dl1dXPPw zVpUiX6^y0-)+6A^If@gNc3!WI%$-d|^ORypLNXbC{>=qIzQOsAVamY&?Yfu1~fX zx-Goq2lJEp@0)=YA2xP8ziA^3bCN)cv7*^Qy(XD=!=S6n?IQl))Xh5cg5CVRxs%>o~3Kt0niH2LZ(TwZ}Suz^k4HMd( zk-4K!{arxCckZbJEuWJc>OzLM;M@RIf%Ig4KB?4OE(ws323|DkZ+N(0b5{(;5WkIX z6x|)bZFa7m5L>bbm1wW}ZazjrO;73k*!D{@uJ7qm^n=I3rWHJ$gJOg%{Z*#@RkaFK z3L23bp73)U87R;t{PSbFL|0b$bZl9XYjz?d2{RK$%0=)0SwS z_m|YL)qKm38kFJp6LY9T$<|Mo!f4}93j~pu({N@%ChWbkXZg*{%3IZYf+U>GaogDdfevnj!L^DkIS*PA%F^iH*BQEtLzO zHy|}2GZIv;1$Qaoubr9imeqQ&_btw8k>gdVL8^6f=I?rl+gaCf=kJ#7z770CI(g4` zYwP0~>4Dig19v#NudmDc-4RiI1!vfHEc@gJI$?uSRA$ps)H^~c?2aMs&od~7pC)q#bJxy01D4!} z-zpe+W$}bOBNDfmvwAP?XYBZ$L-=*4En{5S6XQ7k%4n)znCVEA(DAxB#! zkS-aj+X$A$nt8ePG`vR8LV8V8h7f>06mubx)DG0BPQ8oBxlSzM(pdSSOA=)u`lPy8T=!h+7MYNllS32&b!Q#&HZjXDPUEh}G-cmY zfcfa^NG!>Qdd7`xyd~V1x1|C(B7%ld=x}-K9O=!&)M*rdVc7vWZda>3BxGWvY82kA zuaO;#pr9ey$tcwYU-PdrLu zIh^v%>q$|=H(7VHPd_=)_6915?N=0A5{Yb+!Kl-_dQcLX+>wluQ569dF`$DZ1iJ}_ zXn2?ML%V)Apy0W_6ov`#t|{(S7XHIcsJailBb?h8Sryp3|MI%BF@;>HdzGkn#^*yv zw^}^2paCLvHzNenO1&5DQj|EXvmnCr-1ScE(R>JV2y(ZdtiAZSrLZ@i`%mBS8_t&Xf zg<40~GeW6t$JYXFngNG!T2y9zX>g~tHc{2kTtP-{VY@8x-%7T!^V~PwRU()1CQ0$n z%KWySnRzT{!U&HyFU88CxqNXQUElH&h89ltvTDn$m6?2-78ySMUpe|wFH#Y0J28t* z!_Jkc8S6xoOQFTqF-PSClCq~Fxg}4Y3vqMPL%f@I@1Vp)ABStF+dOFcqH}fy-Svti|kkF`T9nbdkJMSpAdPM1%)Id;KaoElr88p z2bb!AX7o0YE>L({AWK-rWfWDH*@=aM?y!Ye6w7O+%Fj{Ol?o*`L|t5j0Dp}f+J+N{ zE1!tQxaXRV@bOhTUuH)-Bno?{lb6L5`i7mCVixG83ja7QK|0=$Lm32ZS~zo{p=9R9 z0l#{*^A9+2z(3|tdJi2JOtU7`sA zpVijWXkQt1K3){dQS~2WX{~L!|5is`_#c!r+H$2=VE@@V``6mq+R{=>Yke&zLu74f zsi~={v9Yq!`m(&H5oX!UGDQr|Lb8dYit*pmmZhP_|E=tQ)Ovs4_i(!$a&|Bf#$R4* z>9T@1-`D&P`Y-eUta0|SNKt2s9 zrHxH!Hr#1W60l>$SKHoX`fSSwM`6Ny-ZRrnrGBi+6=|PL6to|0OgQ+!R`| zK`tpF07r}&M?K>X{kwQ*CJu#}@<(lvi5~w+0C9bW*QBs-rq2L*)sY*YwC{eL$vj>z z@=qY~_nisOtSot`5$M5(nAopo6u~ZX;!MgwZej4aWi|)%p3z}gMTT!3z*h`jeGw`w zx?3XPvN}_jfqjGA(NY8%(V=d@nlBBFw0w@=T2^0M6YNS_`n`GGEK zzp@XzTA1D>eEDag0K{9h#cZC6|Qsy^xFC))?Q` zXte@5U-RAdt|}pZM{pr&)ID`#-iCZ_NgxRK7=e3MhqqtdT)4b27rehT-o{tG^w2 zn&9C_I70Tnh=}D}yPI43QX}v2O3H;Rg+Ha!^%dbyg&`(^F}+?iA|8->lH5|qyL?PA z1;1Du0jJl?zeb>FQ(kkdN|AV~x8``0HB6Z`O$Yum2L*{Vxa>I(Y+w&SdAbH&%e2Zs z87DJ6e$s<2-5n8S`6H%*DfCr)GOEXVqciQ57rIz!RyhyYc7LU)hmgkH1i|zXFf;*s zszc9(llmf>>zJ{G7E{5n=#7S&2)aIn1_|%I?_s&^=#>a={k66OkJ96=@ps;N)qCl2 zUoV$Ia&O{%UJ%Rno*lwR0RWt>KarLR3wm)YL?jBCWM`)<+^L zy%KjcA*~J+*mv@!awncVj0o@(lZjTwgFge2eeox(4^N^5wLq{!WXP~ol-PSOF=+?A zZ>_~$$258OxE{~!0^wvMLlG&|f}c<4AXs%T5C8ojA$b8RqAmCanUoy(ZOWGF)z8fk zXdU9KYh}^^1KqfMbxSotH7hfG&!;pzDk9EC0@@ zm-lPg>&gP1I!E4(yxbv`Xb>kRV2>Xx$OMbG8qviG;5iyaji!23z2Is4gG4eZM^*S> z58xR!$eG>I3PFlp2a)0Tux-sb^xKy=q3AAd9zx_eGYw26UV41jvUPH_jGWL#iwWd3 z=N%r9pFO3Qfj`t`On*JCY*tOPe#K6963~DAkhe*P2y+~O(L1u?y$tNe2zhG>`&Kg< zw;3$@nTQNnA7_z1!~HN#`E|#x9$nq5lv2)y0Y;oTf?!C$)@WwCS}S0_r%s&KpGD%U zIsB$~3$8_G?_S^C!}Ci~YU-Pgu@0Dipv~pp{#1F6x<$@tC*wmXUlAAV!m!g4hAcfq z10q)j;*V|2RMj!RTXT9IW|+X+JjB%0&QY^z5`-XgQZ_v zxa5Fx5$^8Dg?{Q&Z&`ybE#*yUt9u45>$F=@FWIj@(HZOU`A1`&pZCnoMg`Hn-A;Um zzo4{wwBc8O?F!{B-2Qmsaaci6e-H<6&whI6CEAp+ou}V9qIXW#?XgK>T}C*n$5N>)tM~apH z6pwFS?DwTOKm2JG_(MJnxjVBRk(>dH1)(7+0h22a;iM&Wl>Ua8eNpY+6l`U#+?GCj zeQUSQ1IfBUxOdTcOoBJ09AP5mS$E`S(=W4l{AHi)Yh0cHWInnSM+G?Zm5-nE3q3GB zJDT$m(9PS)_1qGJ5g|x@j)HbzJ@aDlcD+ zY&(C~ZmpKQ_(N)eMY6r6aT<*x90BD-r6qb0Azo~*M`UVvQUJH4mm7M@Okyt5i9@1} zW1tEzrX5SDl$cetO|K1XHut;&n1sfLnl7GNO_i zo4VnG>RwzbbB-m}Je|vu;srcWIkGlCVFXgLn}0v_QA0pCbP;mTlA=u&y~LrA&9^Wp z6SeLZ?-|a@uPqiw>=epfKARHyB3|oR@4{|(2aDPH@pVTsR}=X`+2YHlnTwd&0O&2o znF}jf3JA3Aemgs&o^*|h-e|AkJ?uwU+1fd_5)R-HVqihN+my$k9%CuC*ZU;G9cj_8 z4&+9Q#k-TpvPM3(1-!;G&C1*Cby-Wbs3S+SWqa=Aj6W@;$(4OaG1kaM{oZ^rQ&oD0 z;1x)RZ|GVG?wL?pQkYfrQs`#n=mvndxdwi=-Ho}(}{if??V$d&LDl`?3L*cUr)(uK%=~az& zSccshsUuy{VSKJXjWk+b9|y$Nbvw)E?%E$cSu?~Ob_dgz zMy0A;49Gyv(uRE{^%Sy4A#`MC8w?UQ{w)aZBzzl?fISO_IqiizFpYK|)$`v9Bl2?Z z18}QdMx7>-#1W=HZ42j7IwMPuV1zW$L^UB zfZO zPs9TWS7M6(GluXJtY*r>O-T;mYwbaS=G!K;<#vdMfq-cLXSDVD4X?MhhdL+1{S~Ei z9^{i8zh;2v_YBG%X^o0FuXXWFx@(qUbU$ov`;!jQFzE!jWSS8({mP)nS8Wlw{JzWV zRmLrLkQhT=%tQ1n(&iQgc5IQnH_GM?_b-C)*n8B>l3}@yMSC4#1h{e8q~0>B_iNX~ zv}_Byc?u8km-B&xFE{BcwoZe$_9vbS60!%G9Gi0~>Fu5|+{N8iD0c^`WM<<6aZG@3w+{e*^2KlLOyD zo_}khVfHsJ5w{w+8~G-vk~qp3iebB)E?Njz0%n3n`(r_n$#=MwJ6pAO+DlutuZQEg z0^+Tj*gy5{+P8+J&tR+}?SCe(9g# zWBVv``w&a!HOVXcJ+-ph=fEJF5flFKwq5@r#P=QtrbC=heC&A_`SQ!C!>S>&!4R1WR3lZ{&Az98&5@=uXYJcN$uS&49T_v zhuaXJ&K5V=du8GTZ-(dM;Nfk^1<#k9Sjk9-f$dakSDk2kkZ)WeH86j zZ4Vs_*^ZKmc8xYBir&aTQqOvtMd!q(qJOVP&j-1{_Tz@THG%q~E#O;H8)Jz=D4pzR zO8K@5{Jq2`{;K1#iIpP;s=+XLl_0PY_lXo}a1{%ON#ZEA44=}lXu&Z25RHgfPYPcS z5}8}=NJ$Ec;P^Vp#VqXf_M*6*RKZL{E#LSwbaPGlDS^Tv5LA~uw>w4a;!8&cGAv=> z#JE^;!GgZN!z=#i3_lHYL{+4#`-$RV`H5)mC|FD1;-{{Fb0YdvAEB=bItHdorY#^} z-EGf?qg^fw26%)=IaMB(Qnni(D9t)4K?qkukD9R$rgwjHAAzg1XRz9D(9>VfBdkR^ z1TlM*$^`rZx!+k2@o|%)EO%56#l^nlJ}JgfKAdshkhc|!*n;cvmbmTlb&3mAIMbNP z&6E8d*7>0YrKFv?&9ePxA+If3O0pyMPezX`%XiR_*!R_+g_Pt)#e;0A-`QZ!Q!&!S z3rvN66lZ!)(|sTRw>xnr{OSC4vS4zyYf^s^x!e$Nmm^-(L+k$b(g|eG(?n`@n-o%x zVue2VgCHv*Pu!D&=jxq-oHP z{+6Wo!GPiFNd|dyt3huMMyf*IwxN;{l59@`RJad)SX%Y7O`EU^^S77+;WTQ?oY<4% zAbQf=qsrbLlafx#l4NFb@VTWMUEB3K%DRAR5_FGLYYMz?s7j4(`ZYqI@ym;6*G%%& zxS3hX*w_m(=oDMh`#eIgo>+3>Zp_vNv@?U<@5bWteSs-*P!Z(1J3T|2&?{Qcgo`(h zS6($U?yS#alk~n-$3@t4bUsGf4(_c)92U0;9u3St)Ft;YwTs#87dJr^$62X zwr~5tdXdYKT(y(tZ$E|}#(FWV7E;yDP4ZT*W1#DW9Tzz93r1TMFOcw5r_B(TdLBN7uoSP;}*Tz zR%`Y9OhgGsgGzDz*iQ)5i3LFx2)!6G{Rj4%qh30c znQ-8q3l41V?g&PbqQnyrPzK{?6T+rK}HyTgpFlN5o~F#pZq z@`cg-0$cDP*Ut)q6u#y;z+XUblU3oP`bo7p0E=`)iZg2n%Zw%LMZda3^77l;c0#R@cJah!w<{=wuF7PgKz4&X_cAo zZ3g6HZ)+{M1iB}Wh75k4OeH_3Q9w!M3oXTZ=CkJukT>;2##R>?w>9L$P1IxqH{NXl zZ#q2;!7MfL0%<(94@lkOIgZiBYT{G9@(Ooh=ZHvQJoP~-ij|UunHOV`;$!vsFGu|* zaFl$$r@bs$2nUS8{>R2nD~+>S0uI7mLT#eB7o1vkq>3e-iC|x*bg88N8&BXzB|9aR zN*7$o*WmgV@KtlI|O zJ1Ie-#FEd(IB1T#$RiO9#^0+)z-Ix_)!^z!o?7`e2>L&H*pQc?Mji$L$fO7Sf8^o+ z{=PPL(*I8mj#8G5Sz|)&dR7xVC0YyI?*K!nvp^{)YFbN5R_)9KqU>6k~MgzEpk_OHQ{W8^dE`PIOu* zfO8*C9x9U5cJWqR?r2lV?I)u-A1bS$#TjRVZ-C-?)jAx?tX)!NR?V`g*}e|+cHr|3 zXiiNk600V7B94iy3TQWD2xgwWuH7)kdGdzkusN^=625|K@%Z<$HAVRdLoUr1$pyXDt*%dxH_yaj{P&fV;lt={eqxpJXzDGd_XGskg*&$FnM) zv10-dKDQLH)@*(^x-Jga-ZIj6uVpL(8Q;Awp=iIr|Kn5!sknK>-~a#!@_(G_e|jPm zF5o9!^Z{- z2`t3F;c<`G@ZUtW;!kC90Duq*2_FEU06@|J;OGHJ%t)Bz;NRGxFu7oGcwn)45b*f0 zh-h($>2XQu2`O1fsMyG;IVkD4e=zXUum~U%384}Rp_7T?e3!(blESBvAz_dsWm2GL z6QX4O^@Bs1mP?hMSDlGNgq2&IgI|hEK!%xLi;G{2S456YSXV$?kwX;7En&bfZ6qY| zOH4*tLQY*uUj3(%wxWuj&`(ogIWzHJmhvhD7ff1Qu zQHi0^X_2wXQSs?7dA+dSk@dYs{C9%o5u_+}<>G=s6WocOjY1yS&xkZ_I zWtjzad4J1`N~=oBs`HBK3QOz%mbaEw)|FPZRn;_B)V9^sHPK_~%9GMy&pXwW$862A(pPU`@1EgpE+Y2NB zX)$4Cx3!DTC|9jzXR37UG|}%9TuE|iC#$) z%{sNei)rg@ z<1js6vRhlny0M7^DBiwX5CJX3$L|;Syq-CZPpdiQT32~4IpxdvOUHSicHlLcL4c)U z5x}?xEYO<{^8f$svA!6fX*b;ZJZ4jq%=nQv1+N};#{u4a!LmahhqbFxhNYVG3kSov z;~*vq<`McP2R~mSvK<o9x5bef5Ez4LIDOMG3SVFe2@NhUr<4@$ut?Dj?pE_wifQ zaxL<`Yj%mzfBbtFg>D8xbBM4wr26U1ua(h`Ad6i^jjQg61+FbmYWH;jGae=Jxxg9i z^%;eZpe|VR@ii`~`*KA9e9ZCKk3uWyP2=2Z11=F{x*v|jac;dEmy_WJCU`#43s;IG zKaMk=X$c-Xsrk5XqZ8)zVC@2TJF#Or+`Ou4rIiT?v)}i|Yfjr~<3Fxsw_k?FUp|L8 zv8pNjhd9!_03<*dNZ`#<)srK@wjs~+;NBNb<;6+wo!o8S9bD@xNr!M#7I1xWrVi+T zxA$878adX@!>UGmVda`#>I6guGsgq<%B!O&fFJuzQ@!ar!LJf`o_Zfc-9ngoKvAxG zIG_>A;oNXCm_{(Awwj0;j$XmOrDqbZZs@m%-t|>bDNhjtaJrHl-ymByv z&FUb#F+VS22%?YSA{5}eI{QhTd41t^xY7EXG5gQZUDwpr^Hh$9g~B?nUo+2>a|hIo z?(o((?R+eavn#LLeMeJW9~juq@CezE$#%~kKaeJ^{Aa>0MY9KRU1ec@vOlBIlb{Gjge z@E?XbB!7Rp@Vpv<;(Gt+x`MFPe*``BunKzD-^*?Nxj3ETC;n}bgh#O5?K<6MI!!{; zSqrL+K_QvV=Barujp<%`B4gVccJ<7`6_)8yo+eyr1|jOIZt=`?UR#<1qhL~3=j{m! zJg!QAU%LwGfWE#uv)+FoB3n#fueV>*S5ziUJGlyqrhyK)Czkxt+;-6XETG|be!mnJ zyq8~lcl?1}d0E45la10u$_9ahzq_s>cWgXC6I`EgpaJvV!yv9RsTX&@(OueJbKM~B zL4Ff@-n!zqF1D*MJ9qnPjc!6SBIaL>p~#a(${60+5>rk-E%fk*1}W%jXp>bbf5O0Ewp z`Zif_qw8I82`Z1%Cer@o;W#Trj_lrkIVKKPlsHZtu3)X!uwjz*U<8s9<&PxqUQ-# zh@6Yc?@iYF(mKmiPdDJqpOMcQO%~bq8;e)*XK9+Zp0-DK5MX7vWw?5J_hzQ+_&sW9 z13dHO#H;n|bSs(@XrnL;=TQqH>sVRk24}qN4Y_u8@j}FA021?UuDWBjMy1@=88Ia_ zB1|_6hLHF9M?)C9`6|3ib1mKu{AQH}^-220@Y;Vcw{}t<5YWIdwGG{8W%+vLse88? zZoA{0UU;D~(Cfog3(Q9s`jvLY{4^hi^_q!RJ1pkSE^C6$PzVD6^=+Tgiy0XTKc%MQZ38Xgy0hwz`< ztS9fr{q`*paP=KnzpDj=cV1pzpL;T|#(i@Frnn@JZbK9YRRzQTFT-JU+pha9*{rPN z-SbNrRW$tU)WCbs8vH(mZMUnm;`Ul&`HM53t0Z(;6Q>)Ibu^N`-YJdMJ5BIU?_IY!_;#3+r__cnrjbUizFGgm&Khf%WRe>=!5toq3IC~Ly z&32)fBM(<`w?qPx+jzGMe;xMOBi2{nYsef>7ryWG!L ziKtzm|4$&Cg`POLTeqRDsifrb7XNV#b+-6xF2w#@BJ56JQ`5HBSDHT&m+J>;2WtdT|3*q2MZ zShg_HPTyCPyw~!p6``)kx1l(QjEBEZ#jyo$IoQz%F3@0XGM?+(lE_1__1*g#T=V|g za!KL6tlc3jzGpqzO*+<$oJ8Q%JrsU_xz8}Kot<(*x-G87x`+j~=3g73zx8~v*aJ2< zgK<_$GO1#Ud3dIK?g`&hUNdLm@JM0-x_i^-NixoGA$}Zz02yd7zIA{4dub}9QAM4X z)SbRW@U?8)9?%=grR_H!!(%>U4qVr17czoet=y}yn4GH@9x|bIG>f$2+S^|!VtQu+0`-rpw3*SV&n3wG>ZhlPUgdUyVz^wjhitXiU zJpcs>JoB?}oJ!Ec*Y~&!UOD^h#Ap9O@ACZOg_?MZkwjr(Gb&(<@=RiIsyc`3u@|f? zGp=b0Tj2HZR-xwnf*jHe1g+dP=X0P(^A|-|{|{gR?3oPQ$<+&T+L=K82mk!%AR3Ol z@2**}_V%^utCvt?Oxe?l^JFOh;lB^Rq127^lqFfWyp4TazlQmxR zHQU|tOQ+6f3|-Liv}?h?14dP}O92beoYCFt+zrLHdw%vwYW;Y+$3Fdg*(HcCdWiVi zv#_%M@*W1qE9$FL(srux63-uHeSM8L`+Vau=4R=5jdy(w)$|n=Fzxe&dvGfYV@3vV z81%b+ZRr?lccLr$Uq)YZ_9JPpyzKeXSvk*n{is*$hQwwXsVeTSJ9j@oy50P(aLF^{ zN1h|-Cn_||aB#Hs4leGVyRfITlklWtOP=a<;eit3MPvf{-JWgJv+?yLxh4q0kjeEV zHh%}#6)v?_la$1l5kvt)0o=@C=ll@y-d%9r_PX!nHXJ*eaNTx0H%b#bQ0Nj=65k-k zea$sM4wWt5a=)K+<&x=db=`8i4}|}?8-T&ib2%H(up0fFVB2-K`CB$>X!Sa$w4YHS zxGevg=OwaKh8{?2(mf`bO<=zxqSva3YMDBllwp-&f;x*R%LcsMNqk!9aM2@5tsL ze^hMl#Q6#F?h#v3{ww~Z_+yH8n3lNP75=`1lk`H0pw%N=$J z{49#NYwmLp;yi+KL5qQXsT%*BR$RgQb?yZB%LtBf(#EU+yj{|26B6W*0yjcDmlASC!9XEf= z!)&8Tscd=qn*}{{M)|xY_W^D>J{r^2s}gO^Z6RjsYgH50ad6}kCr0q%l1THnYG&3& zJjQt3$G~npsm+~(460;c!fW2!W2g{PLBS2NBhug6*EgO0H?mEATA1~NaA2kVqUM48 zY2D@Bt=~NW&{#>^Wp7NWEo#}=v1zE}RIpVd7-<7T?N^z1@K!%mblED$&QTQ#^sb)4 zESz7dv$ftnZn{j&;B?%Vxy~^0EvF#Lr5Da=zx}GKHE|L0Bb@R4o!%1n)B5w_Ox4B; zt-~G(=gE$wr_rUnoH^It*qf8%^kUs*uhQG9-C?$*-$cXO3Jjp;u|eaQ5qs3{2Z+iT z2DE@lt;SQhfCmpn&+5UkFHa%xwS4qG!OpaBxUIlLEQJD(rSG%C42Hp4x|j#)XA68V zDXfkfYpHqE(}mX^%s2(y^w6OCbd0K5baJAqfuHZ~3>Gi`{;W#y& zE%Ac&Bv)4JCz??1H#~wW7>rZB z)GhVWhiF1_sl*~r%{lH9qSQ0B{nU+g)u!)PJW8!lBIsEUsQ%C|#H?Zl zL=MZJ2fom$ao{7S?j~^@?vAIic%)V=MX`5f6;W2_Ty{jlw15i{DKZ18ApQ1sHW;bS zqk_IE(;|!`{g|%xFgBOYq3z#eTF7ky|2s&$aDGqOqD+HV-mmk7A6N0qA%>XhEo#biT;_;F_mg zN|(eSWNzL9j)34iAq91oF-4+>j?vQ?ipa^7ck6cxKn#{qEbm8|_Hpugy>tvr8k}`3 zctr0zSua~++NnN==Lwp zweAMB&NFH9aPoNhm_trYWfIcd@)a|Fj`mTfZA&=h&2Hc6U;?}MN#8ajqaICm zkqJ>%=8UN?K#-6RCNSlJlt5G!-7rVzTEwSbn~PT={Ltxq0e>MtpKJqw@qyVFZP zd~rl5o?RPT8ze{(cVIX7R~8?fTGYFi0=5|yfRd$yO9@#rF(j$bv--Oj8w)Ml^4K)C{=G(tKMn8b+76b> zlcuvK_IsCgp~u_9%@1WS+E{!d0Tkj)qRetcELl_L2}xok-$IoBSI5P?`cK)J66BcZ zg`EK=Wy$&Ca?>MyCp0*q{mFy9i_gQu#@^|?sTMv@wJl4HJ-LX`KItJ?$<3iL#TUY% zX6IUoN?u#T+{`aK+GUGI8V?P9JN>^yK=)SYB$-P4bQe?=#yA_B0?oif%mb3-@kczt z1F%=2MosI?;oDsMJn*PBhsxmI>ElqG@kNVIGUakR`&O5*@33PPvoqyU65gds)k}CE zF>^pgjWYJ+ar|}ks_s0OZ&di4ysh5ds68$TfDQ?~qB{P?0m}HU$Vr_St%7Yl>hT0+ z)dJJSp})x$)>qvIDL`wNm_nYCOx<0FT}rR@!V;uUJ|gla_e$p?MDtV5A4oFsTR@7G z5p3fCcA~a^zN;%AKe^Dr%0`QGGeRplf#zn>WlKW5ffv4=;I5G+16^N(?8%-2<0vFY z?&S8-!6r){;vJ>SxumKg!AHEy+D;?4oi7VZ5JOswTy^84Uy81k@q-EmUX>v>-=bb1AS)&TfYaS2LVtJ!8UNf)gf;H zq&<(*5NvFgux@^+x%#9%qA`GFPnpy~2z5TcLm~s}o;|RC)vU7X-DGe&@R~xvIRAuF zj|pFosUT=@+SmBkQ2#i@$4Pg`(|h;3WOp6SlYT5X2e}`y@3~}(&qpN)#^*5t+9&Vp zUeEU_!S{W!n&Io>*eQ6O(dX`-r)Lm!Jq)@h`}(+#0WDhi!61S8d`#x_RQrH*UbZY# zZnQubTH9a!+nFeVe^tycQbIw{0M?^=xGu-`tr3adv2E*@0zV1TK`P}jy4B7rF;Q5&6^nFy=euMfr zzy4(Zn6#|+emA|5tOl(%gDyNl;}!w$YVa!-uq4k{pwDhW&(HP8X&+Gc?hL4N*#`-9 z-7N4<{Bo7k{pvcR?e%oIe0JRx+zDEC{`XoY>K#{~33~sJXWOo?&gEE`mm|IX{_D=K ztLEE1U*GrVE$>SdMxUoQJL`D-Q~=h~1O$V#-M=lfy#r3G5`1wBst zLZ|rLA>e^`J)aYQLcYIse_mYsIH2Ky?sLAbOhM2$t1+OZZxBRWkShzHyXQ#dMZ`kX zJLzycwxFf5lMr$EnhjA3DD`(RI-(v2lzI#xnqLqg*)#PoAOhz9c!8fd01L$~$&e=N zthC$`rS5`;@m2e^%x-OBGHKtWU+>hUA>57 zS3AfvvbDKX`=R?;!PFvm@bTA4Jd2A;SbhrumdV7CGjGQZSkG$Vp;G}6JaZis1OH1K zgHrdh7)6EX>4&Vr`O3^2*!9#`LRRpoI`Lyx#ZA#0Nn3MQ?N)C>)D-jF@-y80L{7#w zbfsnB98A!vhbnw3w5}@9(*mMRi0j`n-UISj4vS1~PJC7Rz=9C)@ckW?C8-}zbE0ri_bosi(q_daK|=P zrM(3VImov_At%-`Q33}^WBcH-TZ@%e3DdxM1m5bSs4?WiQS)C!7~EiHb?afuL*&ST zR*oV1L)64s{^6Wtye8k`L!D2PD2e-1vSHnne;9frkw3JGU&s$T><~hXN%488{q+;m z`woZ?fUVj1LyfjBiqei7n&37l8@?D>1-HVek_XNp9r6cu;xt%=!p#+YE(VkIAc&fP z*GqtiN@ag0fyR=-v1HjAJ=YRHpRNBK7OjeHz{8)t5zC4-LxfO#Xf1n1$1K2)G+HhI z=DiC(jzkE}v)IJ+Z9jBPw}RLG+aHVrmt!r;H*{h%ezZ^?|1jp0N5!6AAHPKWBBG2S zpaL47erR{N-?u+L6O9-Je16{(fm>kpF9WuE<-`X*@hm4XD56urY2$q>HpoYb?te;a z&~E=AMiNd5tp)4W%D5Dh+9&SkFv6Q-llj%aN|mQ#R!EAg2N`PI6bZ=#(BWNw!mmWa zNO`1X-f>>ynL+dlv`>lQT_c424vXZkl?SY_F#EpP`D;ctPqjpT80e`Zii`#Fi-P<9 z8Is>}M3r*W^2b94>fpVobMYmoGUZzZO~3R<3rnF6U<8mhPt4zX%!#Sv5@el##YOTV zL7RRf2e&iO3X{`O2m7?6OLBo?_a9neha`#bbrJR`C~IbPNCqEIyz47O$kDGzH7;e$ zf?r2__hS)qmx4PTcuBB;)E7ltI+H|#@r~22_OnV>46yp|d(J#F^$@o{G(4F=mXa*`|;R&gp@BuN0LW3P_ELL7A*L$YU&%EMAS&w$Ns6ulO(qfg6Tk_BENX_DloEaBFMJhYyN*@1Vw!p~UU`H|zd``4i zclpyBleLCT;Wg}+7(6ViY>Mg!6Cj+e`on?*fD9|1zxBPalz@XNsDWEoFGe^9^0OVO4?gL4TrzQ0Ak)k-P-u_LE?iL(+Ri|L~P z1aFLO>L4&du~))PdS$yYcYqsXK6u#}Ta%fk^I!}G14Cz)Kltg7uE^bF_0e}Z+!@iD;TTo z0eowR_g@#ehYrWO{n)j0nrjR{tPS*~YGxESEf{<(JR5M%F9M~?H^Tvn&6U(DtN5-V zFJ?klA(^C(e}X)VuSCLNtPEBsb^e8kv0a-@+y1IF)YldQ3wHgcf{Dz1>ay~H9pnrr zVWWP)jF*pVS-d`+-kE9r%_PG_YrrRpby^LPqXGwr(F zG6KbAU6t$)zb9q*XXc27{nor)&Ni}9XT8K=nV9I%-Ca1Y$z4lqW>bX}{Re04-a|$s zBc2}fupW|>tMuBaroBL;#Wce9TFwYl8fcvt+YHUtlN?u^%~}=C@?KEF{zd}yX3S4G z_|LSLrce zIDK>&Yn};Z2IWT8KV|Px&UlVOEci-Rt3*=tB|qWwIWc}CGqz0*)Ou|AQ-4iZ7&vEb zdR$SUy&x(FyK2VFy}1gnd>AyQ|M8qCy+{P-6viq!**#ySg!PDCBs4~bn=3gd*mGkZ zFj^8KF6;66A=7H0VEOE(fv{7ZKsZg`EjV+rpc1CU)8vMZjhKw!$T}HKLa+{8mJ90@ zoXhRgrfQ`)RDy)rAJG@SBv(lzzb6qJ4W(vrZ91_u3m4ym$b?|g{#2x^ zqnWR5=cMD5{O3a7aIwew*@A1Y_T&eA;#uT5(8!$G6G^TzKRGS`9~S^RJ|l`q)p(GN zjhdDeZa-Lz6>Ic4snX98RW9yEA*KHQb>wEHFHc*lRhrt4PDYTJ0K=zvKOBDaLeY*8 zy31srF>jWHKuq_}tl0bHP9YrWBFbZAsSQqr{3S(vq+3GndPG$yDzO1xl@jM`KeN)X z9ezntGv}{$8bxY$R8Nb2WPR5XYKm7PQLx?!#Bk%xMVC}G(=6wDLmstYK_tI|T55$& zKgvGHU_A?pCPtt!3We#eavoJgEGz^EGq4MIFXepiA&My~(r6r-m=EW}zrWK=FP2xf z;7%D@mSBqp#&)~+a%N>sgGJw=J%EY>q_oXBvqr$(y}D7cc45MfO5C&cxRP!}X6Wl@ zHi;To#bWJ`S3W07!Cdn&h=9<{0YAu0r4g9)!ueQ=>F8h-ZutU2lTgblP*dK#Sn|6D zFe$unhU>prP;SA5^AW+x6t+B;GAy;NND@%>%H0L$g?Nl>-|*y)I*@?2s#*av$i?gj zzVCSkbO=FhQUDzsD<$RO6?xZQ#iMylnqfQt__b114R5D{Sw2x5+}a3L3_J#j@5uRM z3~Bi7ChrcUgW?%*mXvJc&+t^Lf59BMO{e2-oOl)CJq9dd z#$s+#Wap1AYv)S8-eAEW@R{x-7IsExYjC8;MGr1N890;}t|I{GhRxPcLs7E3_N(*n_(&8QgEU|o{?HT~t^g$()dmePFGt1%AlDZgK*pP0 z!(PP+-~)QSsHX6AB?6{H=xB^l8@>g?#@cEVhSuMnwXL?v>f`>fECnkb16{f$?fiap zvl1-f#zLB|KQ!8@k(&gNEd@hfTZtupz&7_28dDJ*x9pux9NBB5ojIuS=Ln}vZL(Gf zm6`29SITH(MM_)4pp04$b>Wl`u$YU(+=T$DzH8jY94Et+H~tH;R29-b_aG$n`zIa7 z6HSvGPo&<@fJ5E9Gkp!!5t6_}S@uF?U+p{%X41G8?5i4vhx(}xfJ@`W#5+t!BQxu$l z*>rcav0`Q5JTgFrHJV6OrJtFRxR@MDCj1Vw*o+&q~m-DQjkVzXNIFi8jbaL;iNOcETz zRb&X&e;Js_>cJWdloYH~Aa3%K{w<4``0z4l9`Rxgr;LAfHPS=d`}Z5XWVv=d$<^pb zUqqd$F!gR;D#&5T1XVtA4M*gwvBHkPLNNMPxsu8slf8C(>IQFdH3H{Kr|%pT-W!*@ z4>(CHQ{`{jdghg#OEJ^#jQE`OD|)Wg?g;O9)eX+b4c^jPQ-6|r!AF;Q08>w+*;?;& z3dil6N>O=%bzP($y+_b(a(iiT5vc*#&S9$KPEBBpt+ADPv8a%}q+CS#n{?f1tL;rG z9$}+YaF#!mrOLQN&x9zQYrGs#z?9IxSG%im9jQHlzvq`;(p8dPnGkWXf>ro)uAaI> z^M>lruXY7b24llH6uwO6T;-_b#C}}V27kEPoF6#%AY9k(dfTu8uY!{nH4{H-DjD2H zG6v7(O5;Yds-wGDOYiJK&tb~H8EtHB^s2~OE2D?Wm~LNCH5TR>o|K!b5Xl|tRLXFp zbSB{&Ml`QApk9;ITi=0~1q@%0^`JC{Jn0>WLu@tbRbMrV;U)#iq0RH~J%r-nlo;SI zFU%G9g+jw(U{2~NZy&2wTLckJp<%|R)l<>+t*Me_zCno_x5;)|r$V(zwiTi;V~wm& z5MGvE4x=k4DI+YP%!nrH;>WXNA8aOGi4q%$-OJ%!lY+ukQQe;=lA!nNgxke|tLH8g z{FDa<$~9w``m$k0gIFn{U>wGq`9X;WKw@KKlBSlw4x1 z6h0_N(5Pg*DM+2}1e+bA>DRXh&vBq7I{DWEypa+T%yMZ$0QHkB9MoOd4l5vOCR+}= zL6~aW=j#N6#e)1i18I{2LZ0x#Nxky|MbYyg_|8zl6XN)ojeHl#twBy&aw~N8!vg6D zqe>`cl|2mU4TI@mg)D9S6wFUSp9ro0Z;}uo;yz3@i~Z{Rr#AAe(tCK&;!M zyktU9Nw(Dui;89qfvi|V0i4guBo`@4=Y-10wpb(#OTw}C9YN%3=#e;g>0c=UZ-^yk zY*pX2hEUHW4EOFNn$l|_yV4k`!kT9k`k2Qf4f{lO^;ZbEAmvl9b%G?quL08tDUT+~ zZluh^&ov(*sCjm($9TnTZ9K>p(k#zCeZLnwajf$gwmP1pfo#I4rwh&NA$LkuoP_9SMGgS505?VCO~>6Jgyo z#8B(6A<3rODxq0iKB5Y$mU3uX3==J=c{XBa4G_|_?E=_vKOOjhTZ64&lR-3FG!Z8? z5GiyVc7Fqv0u!lnQ|p7pig4bXLcNv8PjRcy z`6s&SsVHe1$H|k(Brd3E6jdavl~n15tbZ9ofzN34OMU#*F(9X{cFG5xW|vc)l}l#F{#V*iKLA(j)F`58^Qf zXx~3}$No7<>siEX@?d8R97lsr*tqTZ)QIdk9F&{P8W74YXdx~l6Vi!}5O<#J<)jZl zc0ts!MI^!J$MSc%s6UdfNnC6L*nR0_LJH5E$>kHgw^9hjkRAI=KM95)vqU&f%}-9w z%u4&{T4d84!Ehn{j%b=nYJy~_23&Ch)_8PX#8SpEGOtfCaY(cQoft%s7CUxauW)`y z3_{wJJn_o!0#{LJNuJw?S~(HwdB=VqK_e#&izKPOM9WnwO8XdgxzO=v5rH1Rs~O0u zZ+qgMD0~?zh$qNXu9>*wFut)FlFXd7`09?tgvOI*im3=9@QtT-iH7Corb)x=PYa9r zdjsxwYYLs#u)5V!|5RihOl*x`82F<@)Wz2*l`SO1GOOtoE#yx4OMftLoc4F9jK_2y zX;6Hn*v0DRTM^$Y!*jU|@3B1#dz~QWx=w;`(}c5;$F`Wxnc+_2yq)Q_wn&+-5b*FU z1rx1-g3z|xZnkr&|9mIQ7vJ=c3qe}HZFhlJziO^-r>&xPNre!5=eKAjZ@cK_!t%>r z1*xm4xs7G5HoXu<@>Opy1~u1sAW%#>j_bQljf``pt2sn%6DPC+rhdu88d<~WRR^Z^ zg2VBEH6H*JK9Ke!=(E&=xM(uZb>iw@A zKm}#Dmtj(qUM**RH>3!k&3K+_S?^OKIwI)x7^RQGuteZ+f0`yqTw1D8Vb``S1;-fd zJv^%65o6J&Z#`}J71{hv?aPL}{@Kjx6%n108nKa-*M;-X8=j5Bw9D+XS+6=3STbK> zg19JFeG3)OyP;OSa>bg?94{T02D={RmK4d?Hy+uP8cssZUxMOVn{4nkxnJ8d@yN#R z51%6KS5!q_YV|fm0;le(HrfQ)tz5;$ORsYeff<)PU3q@$oHe{y$cqCG?|!Bfn>{d# zfduYt4wT^+FEI~6&Q`Zwg$18=xNk{OjmT_PkfGeP_o<4WEsmnTdo`_Cf1WQ={D36zJAc160vy<(fF)c13Bsw%pXWSaq%|f#p9<1XiKok@gMp{GSndjLC(Vwk_hH0 z=@+<6Y4iH+&3(AvvXB{)pcDRejUWZ(f-6>T9y}=gAz^`o^6!3KtSG&vlD>J!2%zH1 zQ-wJNEwmtmanqYc0;%BBV1GjqDG;l|B_$PmS8{qLCu|j1i~JILjgU~F=(}4#p$ig3 za0;Z0Ia`$oP z4Ez&r&!i&K$a{kSCrRsYGjjy{u>$l3%@B?63LSB1`VS*rFD7y|t5ZV$yYi!SOj8On z1FCOMzDF6}=I;6ctdF@OjL^b_Q!Mk2??J_2IHv=2)?2d#ZlGYHbs0j|a5Y68&r^YNv?~p(-1s8+ zJQI=cv;hYnr24l(XygHX&!0Ezu-r-1mS=^25&5}zS;8Qgosgqne z$rdhxgVfkSDEYiBOjXK%4GaHsN&KiaA_q)EzM7+q(QAOoLb96r?NwPDr>DrT5l=x= zo1^H~dOlRStGH|II?ROlpDRM&>h_OPvF4YD-4Rlaz(@f57nbRU>S23LBMX_pk$EN3 zH*qwzA$O^+Aytv>zBgy~;2|bH^1b96BEAHrk|vo_C`J76f@FeM74oD;xGwX#@DvI` zjL3rn{t%t%+}0-Up#wR84_?yCe2aq&4EG>g`JL%h2@alcr)UzL1T4Q4Y(-w{e)aBGW)h z25fz7K_>+QyveFZ%`-fleML(UO5qguG_sHtaa7Mz`e)$DfCm?+W-j06ynCT6tTGQy zCo+`Up!LRfAI4~d*qXS_$ibYV6asV@m5*r_aP3sX@j1!2Kl7a!q!p7t?OkkvHT@$Z zrLhV>PO!RnGBR({Zqbpa)cEmMXyVJ(+uU=AIS`$B09j zfFCn778dM0d!MjNMHrjOG~r2QTD&M4-{iTE%4(6re2Sy+1|I?l>ntxc2nO_XhkiZS z*hNq2f(KKUlVnlOh_iFGSp1Ah!T%^z%AT|*b3910r3%$I?DZn6;`Q8DA zYBH$xEYb;JJS?8&{3TTYqE2H4>a`CG4Y+{N@W;FAJkCIJx#7`c^t|;VuR=B}R-u z4YCq*B-zWB1+ea1Ll0}*FCI&e@0uHD1o%blMeaOxcF?g01CGd;oR?JR10-b zOeYSNJPcGyM=x>GS5Bmq%Cv=Vwd1Q2BO@15@=Si@5q}%~0{t=Bv4^i#s2MFSwK{_$ zSJCIS13fI&-p^9vzI5R+OrSjJydScPiP+^m4)3S zg~hrhcNcKfDT*fOJx!!thimk+B9-u1^3o}D^ls22u$Im5lpgD1C~oo3zb1=qH{fvo zUgp77umMUXI!dr8sFf)ccWtGie%brk@C6d;=j*n*x-FBDE4t#k!y}?Fb_CM<>a6cO zMPi1K>)}vgV2F_WlkKj*0Yb+HM(3!5!AeC!SK3fOO5^fMuL_YeogP-PcXZT7k0z+W z15)P`lo<3A!BijhiUU^t!QsR}#!rxv1^C1!UI2NPon5I{THGB z527^OgFc7<11oIAA{=du*QwTReVW{^80Gk9p_}UONsV$^%=Ug>9DGdnt!0tj_T|oRu=0zf21@dN*_c-0}U$C*O zH)XZGlcJ_S(0^ruP4bd$dg}4#ZtK!KAU+iChB{pdime}X+HU^brmW^?&cPLmvGr8D z+BTdM6P;;vVcK4uvC`Qq6#MH`AqF`IhsoK>X4G5jS(~~u^&K6)hl+xmK0WGVJELYOQm zOFaUQ?KZLgS@W;_0jDNy9%*W75Y;gb8gFr%)&M!i(*)fg(uqwU!n4XCKF8m5$;vfJ zho>y9l#4UtI#1%K{Ax-8tAj`dU^jLOP8eWv4WOeK1tut+9LGF)I6luqsc%l6$*eyz?_E$)E z21`Wm2$QLSaoDV;4w=ExXK9j@DUD9r_a>t-xqnH2Yo(p@9c2clNXSv83{Z}8qPihg z8KAw%zE-?xpXMcjxc7k;#J)|{(VW4fJ!--UMq#C+eZWppN4Q@%CGb|hl=d#KY zcPd@N)z^W`@cTc4&%Of$z+Om*^&vF}KW+qKJzxp1)l`9ig)u;AO4K1x(qyZPi$D8E z=Xx<%(YlfD)kc>v zC@3$TT7?un&Y`;iCJT~8p%?KrC+cFx5C2CZ&qnyijeqRtw9!9f4NsY>xK81ktbr?Q zI*}{yi=BaA9#TH^buBnfg620)xKn@Jpb{Q^7f*9=*Dh-pm#|v8; z;I#QOp-73`tO*T+^nqdsDlv*1xRe0vHDf27{`@%16I?^U^>Rz9l7TyA4c_=664y%dhYABt}`#999CycvvV=Wfisi= z-ly$CZ%uSAaylfnNo*j?__4;qvf*Kp_XI`&dirOOMm|uT4>47VcJE9hSU5Ga?~rv`G4NY+6?!{sZ{ zORb0SLRzu0X9LVgd8)mNYQHT2*gBN}#3+P05TYw70n_=WWw8U&kg2D^@d>TwI;g$!AP z0unsBE(#+=l!+CZt-BJsV%yRGmap4Xr3!EqlJ2swgMvJP1WO|UO7?@gNebC<*5&HE7wIH(3zdXJ9)ikIc zwqDLy`Af-seB~BqKkxU-GKO`QqbrEdzYGz^+B;s5nfpy6yMSGopvaP)o--PwR*he? zjBBUo(oT16e0kI??744C0$4g;8QHYZGR0txOjOD_fWVNjg0+}8UT%qNoteR`+?Tb4 zQ9}Mh;f$i-cyamRzNN^vz|^kG!Y_J1s|}P@SK_`8oGzIm)777`$R@Pb-Q?EsD6+~B z5?M{1F(TKsKzGD)-Hvuqk+Egy;zI~?WMvi_g0spz21FZ9n&~<&(NpWNH4m~kS062l zXTodj;C*EcmhwB&nla<-C@%rS_|fw+mFx_7dipUHbRGsDwf)Un!_>cfiaL%MXyLK_su|FST+>9}D=+LzJnxLOQ7D)Le_Uyi`i)i7Ir%8k3_v@HHM zUlPr&8@UL+aY|RMG?#Di{Si%xaPz&Bye4;wrKPQ*5muPh<3kU&fd~}wukZYZWkOqv z7>tF*K6|N3av=^vt+%H&PI$DNAG690n(@+WOe>R_y15MAL;fj#q&ZzpNc8ML-GU9( zY-@BDsIA)1Ehw_Uidz^oom!VMb`(39Ulu22B$L#jHHr>o6MH3*exo?eBK2A7%5W37 zTelQq?u6B4Jx#LcJc@9(awFfS5uc@caVH0u1MtaStiA;IV5Xa4rHQ`-E(?TzQM_3M zn}Z3J*FD#HU{$wh$^c>L#3YoI*09O>Vx+Q(%u=M-!7+l26NH~j2{xjfj8Psqswf3mp7|v&#J2{t6P;v9bJ&^8^%{9A(1%CdD`Ct)df*f=Muwne;E}nM*1xuxP01KA6 z%sLA8jI_j@F(lMI5j3A_)Tgvf>H}s&V8i;o~B|uBB&$Kw2*a9gy36O{RS6N|< za#jbPR|NNK1jL4OAQurd5cRZ-%9O+F87KzUYsW5#D}P~o60z9tP*P4-w?{OCMj5mS zz?88?ADg!V^f#0gF?eimR~2vU^Tz4x z3>qQGQMFyG6JKK(4bEGWO8_05Ykp{zz$uMCFQ1gYiFE@bgE$>sus&!UPGI5V$3`|u z#VxS0I_NAEL9}ggveI9*gu!v|O3k-p8`tL_a<{kZ^g}4fGY@#Gv%o zT%Ds*5Mpt^^b}JQ5Rh}vpe}qUcE==V^X<@;^*Q8F?Q{jnmE}cU3POLke#MNq-c3XP zD3*^P3t{kDQnfolmz(tdTV8qfNk2`A=FYul{U(2OjjCWVh`B`2|ZEwqw%=X)03Sa(Q zwu0^51hj2P3+>MX2x8-F+ifjjJaekKK=CM}%eIrvt=LAj(87eUPGb+CKOS1Py7rD_ z;KTnmazG7{C^k^r2Z#;&6c2n}9se(aHIfCU8T>c=|D#W7!G96YI7G{AC(ok_%lUnK zvDysBEsI|961UFgQoRbbkZs(xI zSX#pX&!4(>*}S$irFi{Q=eyhtcYoshBQ`_t9~R1HCe5TxjceVVI(f~vafdRszF#jd z&X(KzBhSgevZtSKtxW=@jEx(~;1G>6%q}9^E90Yk8$m3JkRz$x;L;hK0CkR-1aiSu z?SL2F;pIiLbVp&Da>}bHQQ0H3d25|ND`3gRTU11uL?c}F`nPq;J{hSv^vKxBmIWu! zuEn@{MX?AuR*8N2{zOBKG*?8~hnombbkdvxbeV~`>ij%smh+V85Hpg+WU)xqv33SN zQ+|jTCmB=~+ihm-Zagxd-LE3)zZgXD;?H%XzXwwEh|LmYjdGBVn%+!MljB2iLww&w zWiVOKn_@(;IoL%V`Y*+BRf{T3iEAq8(pkvZlKsqng7_Gx8Z|pDemS)37P*YNu+o}R zb=d!fwE{L}sK&;0n{zQtMSDuZuZyuAOw`ekXaQc|o-@z?z&X*7Ug&0e3nE62m1&l+ z8ja9$9CVZRPZtN5IFeZmVCg#?ktm<`zALy{aIA3L(GNH7`3go6C${)$VahctIMdDt zI7wkhk(ukM+x2Y531nIz;^hrR(U%nbU?^Xl^$#zZy-(?9v7O`$5leW!E%|ekSQJT) znFTQ_dNT%EDN(ePj?I;W<5BoK+Hr)o$Y3%JyAyuFc2Uh2(Pcd8RZbMUE2ClZ7Z~Aj z$cYBG5gH@kCMG$(nJW1cktpTVmmzU&JR~fkY(=b-;9y|)Xi$zPicu$D6dHoCQWo}aIBpz5 z%qZ?>a`WOv5n1I3`q;vp4nc%)k#~Ihw``*QZx(dwh+56sSynZGoSl_x$BtI~{Rh+# zG>rX)Cc5c*4_Qyt%Zu?}I-Edz&GBr;bed6~tEZ*Y_ab=dX0zzP4X-6+!~_$Vjg;{Y zvI|Xw4dOn%loTCS=8biYC_zAFtP!PKkpPMjg?TWUEYkrBJ3D@Yhl?*t9#|JwU>YgD zaLyV3Ua18yK85zf?4N4C^QXbUll-l?0c85+o2EJx>)qCf*^nLLa^ zT|k8Fv`NV@&_vMCt3nSNjW7ZF5?4u&DIS6M+_oTv2O%lMLu?&dH#6+^WvqewQGoC%g7 z(So1BuNq7?2seH>USV_4i_uGRN)gE_Oq+L>7{pBk?5%5ih4bCW2N$ZO*wmAf!+Gz2 zS`Jj2)3I>M?UdpH;7A#zf(m6gy8q4|;=zWRpmI$I#CXdrk>x~2LIXQ!0#6*q=M;0i zc!9KHZtRRhEzu}{)ng=K(sKy^I`Q%vU~&GeKgbz%;S)vZ946OUA^VtU(SmhNrb=#; zp(Rw!6yJ~H%IfgBnuef_q+F=s(H_Tkq8%awbhlv;tl?3s5mD!BUF>pZWA~t9h|QCO zC)_n+aUb9{HSKZDQD^|XQ4h!XJFCLOlp$dWfcKrqgc}x)8w=&YthwM*2|+W=I0^s_ z7_Q;Q*b)^DP(14j8Bu!^$Uo35^tl}ZzKH@Xz&X*TNd2Rpf%EvT{9%x!1PyG=;87jY zi&8uXz7W{{Z0ZvHTW2b)WIz(;pap9|7;`Vh%v6JB9Z;cW&fY2gqCkrOYgKOhbCqeR z?Wi?*H-T!u2ZrbrOe8$JM^jLcV1En~u9JjOMf#=;;f1_+Y@n8}8^Gc(5omOQP6p1{ zU2ZQXFc5iAWEc--0Vh2XV1?s3iyeI*lE|4fP)FHbig_1kLV!qs{f%01!aq_g<~MQd zI;O*ysF;96YFu{peOy8KkB{-w2O2xmW$o!hCET<^TFvyed9tB1X<~4D@id+&v+sn04-;#u35z8P`+-@#C83!JweB|m`btsks!zAY1^O?N17raPGp--Q|ll8u19sgO2or2y?b zS8QlqVbOs-#cgyPwn7dI3I+sqM#q~(5Y-8hwcrcNOz>RWXyXz6R~x86q08(W5$4Sn zf}xPN^93}jx`o#3t{Nsw^lcC7>R%@dcCaKXsFFu(VujI2I5GfpUU_ZbT?OjAM=8n` z7^%^tF)4|^#h6Uv7mk?Kl!ozR6wey6?k!@@JJBBf7GnUk8wudaSDs&8Pc1e&6Nbr; z>U#^K*a-HDZGYXNHE}C_?$8BPSk-@C|2A2|Uf#EFY zp4mcse}jvqBEMgu6+weApJOeSyli^=xo>yGwF0;dA~vs&3=`LSu-qZcMa2>-LiFgxNKn-JXpYNj8!85 zB?l8#U{ceL_|s{FsKF8dZ6+F1ctR;nMAbItx6YY)^rt5)mMNuP*S!stNPj@dD30ir0NHCZGvjOj<#HD#dh) zUImFg>QoaEOF*s<+w&LKo@#Pz<*R~A39LSWS@Wl&^VeFPABNzkoDT&O#Oa^{U!f-u z^e14g1COpiHA~IMdXQO(PCn%#`md~?|^Gp zl3afDTB)I6<33wGj`Lqfo@s#qecR4jyXzD*D(*z0u<6`9!Pj~kvrPrzx5EPvVXd}s z$#n9wA;6<)iUCNlP8_m^frPO~R3_3jbGaWEA$#q~FdZ>}aA`)}eOiP)+x|Jm0`t4S zH~8WG!h^JanCM>p$1?`ri~>AVXNaygbbtjm{^>Psd*EJoZf;O&B@H0EqNjC3un!PP zf*(c=Apr8|9l`n4*&oOh{b6~I$g)Vb%sY95;LSLIMKXk?bUik5?VSDJeriR3eb{+j zag(FZ9)YvtH)D2Fk3G=4*Gd9eIOPHTbv|)aKo8Tebt9cOulz1%UOcxA!H%x_VTQQC zcKSswlm1pxK+VTKPI{??fKnT>j4rud?QchJaliD@;cE8&X_GC~>RwHVbbUjZVh5#e zRim1w+Ar^1S1V;#xuHEXct6fX!Tfq<*!Aj2ppaY8@*14`<5uTLnDZPrr4^}UCnUll z*YBFvHf={-w`tw`7;}!R4AF&AU6bC~)qjrn+pN9=qp;I`Eo7KaOFpVRzwO7zd>jV@ z8ot?NY_E}_k5`dURY{Y4tSufm!hDi40A+f*^uBBl3#i;fMLrz0pX*21#p zNDCMn@cuNWYq;JF*5LivELPFWsTS$gtu-_|gd$daxO8RZfJEx`0-mM%d@uc3Q8!YOIo}7x)UVr#om?wL`YAH6KYJ19i?G~ z7_07v=)k=(`K@vlj4(pQ%kyoY&5+eaLl;EUo6T319)+X(P>O?dhDm0u*XmOkVSR5{ zVe+G119sz;B_)jw)KkBl8CM!Kf-YP?&19napxZczQMa0Q+?c1yS|`Po(5*6*l(zdW z%dKUb;a!n_L~oIVNl?vMb<&MIhGP_}VtIIPU6FQF$GFJVsJGTi0*Ims3)sNLCkoq| zKgq}5Rl8XIp!oPwfb8_Q{cSFvBq+4sX@?Mzxt}C{(8|FfVob=-@8HrHR~SZIoJP9v z{c!?=5BKuRi$|;5r(f;|>&N5urt7oW3F9(t7)Bu0^U1;W4ZJV`Tn;|b>puH*kI?O- zH}7{puM^dq`0()URYeknKon@Ui<{lQa`x8;^VYLgJDyJ0L;X64TndGM-AV#*&xV3& z;?E!cVg#2qi&K20+7twI`0Xl(zs;%q#d($f`|oF6dHYwY$SdieZ#K+VGv+nN%7N5U zo#cHY*RxHFJ`{v3$>pfZDo6a|u5dVd2nbD2JL75C=!H^lir^l*Tb?zM-q*Zxak;etse34M-ymYqE^;$ zwK%d6d)z{{s=Vu-#q8>+BE2q=)d`aO?B`oOg;kCQfAwNiJ7R{KXO=lNpgqX~W!I^Q z+26^%afKEnt_W`sP8adtxrUl?TQJ{}`cO~%s8#Rs{=K1s5&L18ixPQ6X4$o9I7qh} zR5U^HuV_BhRT$qq<~@@0B7fd)TgLGO=L=?JfC(J zL`^%+BgGfn4w2x?-iK&qWL1IZ>}zs}Qp-iiT7fJ(AkY=5C5dFm15f(JQc?w*+HqDy zLi!4iU%e6f0f6^K0bSRBA$n0Jx?i3>yVDn5hM;3 z=@CCwTM+x!GG_6Ze!}GdfL|^8) z=xztHkp3kFK?)h?a%OfBRYVo=;!@mGf=<+&uX3cm?|obljRri1%15vs_i~&g!mec! zDJ>6bl^KAmh}dXE8hmvBThCKQK5*Zj<7y8vv z=tnoDFXRc`As>7ZW)&|V+=b!N3LK7|ncSlW(k0K-7&DooA!F{g-ke%eD7*V_1sM!s z65PVKon%o&hlT)R|4cKjrOYO!e_u_&uO3u%|HR60oT(ILQGUcVdJ3K6&ynARZiC)$ z))kEQqR$2UmpzIA=|HIvuD=wuJ*@is-@#6non|d;qO0kcIDOL)l#jeItlxqJKF`mA z<}9qPHK?u~o|5yA-d57MoZ|i9|-U847IfHOg?$c;Schv0?|FBwD-#Kl>8? zY!i1urZ6`KkbsTKt{DZS&>0>?$N6aDOz@pJrT?|GXiOCs&IukzZC!1(n@oQoO8AkV z8Fc28!9nC`R?6t-pryU6f{ZMFEkGX(5OH+061GtjTV3pVc=5qF zT45;GZq-5(%S^VUU#nf?F*Bv#yMG}Z173GC&@B>C8f?~_qrvv`Skbj*X*)PTDgW+^ zJV81*pJ@{;?{!7iV5R4NC<=UMPz&Q5N9YYwL`SQhsnS-S{1=MJ9sCIqm2YMfhWeMR zNCS%f0Nc8#=FODU;nVWMf$5vhH7=GNr}Rs(+Eb>QCO1g=R4~I|H&k5!Cu7f)I62J2 z`+CiU=-LvZaWRrNbQ6Ks_8b;mc66!hC$Y6Or80bSOcTo>L3t)?>{iN2sbZH+Ll1g2 z>QtF)cG&fshvRjH9arqGotVD|x55E(Fz7Oek}nYOy0OuO+;cCk2GI_gG9Jgu^=9mL zOEO+4`+OKE+}=zJDUl1Obffv;$X)}o?t`Y>cYWBs)S1qZBQxV5M0JIIUxiH5OUqK>zPbMO>!1QKT%y7=fK6#%+RY%9z2Vpq zUy_f5^jhIILT|AzrR-09X#tX*h+_9j{T^4|P&2%-JmfYcKo1uzy$V6NrPXIt#wafM zO}~#t!CSH$Og}esP6ZYFO9$#pKY_*b$TyLXiY?pb3M{t1zqn(z2^#;3(#4xgxIpfS z_~kJ_vX&^Ot_lxF|BVaw?>bsBytoganRMDAV+MvYu)L5vYc#& z{|1|SJ2>yRKw$f7t6ien$v?V0{!~Z#KZB;3lY@dKrKLdt&g{XwLztgy_$|<2E!TC@ zQzaZb?X6v}J4ZNxulx^!zmgeWR583Fp3+K1#vu9!x*qq>V|5__obk}zVm10g#_>e0 zeCiv>fVi)JNh;w4U3B>T3`*BMr7C)z>}`#Vo{C&x0UncG();sH^n2^L&(eVY_;JX; zn1~fRqWj)y`Vg(;OV|*)AOK;MGJfj{=4<;1I3EchtqJ)7iD-3I%94G_mO`-y?%k{q z2LSB1I^Y01>))?Y0AP>QE~YuCcNxTrfEv3-naiR^9O1Z!%wizmal#)K0450pe!&E^ zd7l1*IfW&riPvq<`E(-($Vw_n)QK4d{l6PAVSUb0lvEdGl2wvou{Uz{B zZSsH(1Q}}Bm3P$0n~k0iZIU8#ps?sGz{7J3mOrYP%=_&uNwFb^l+$-xD8S zmo`2z%Kb*u`u9*Sa4!jB9MRj)fHo4lZk^g(vEsm_oanL~@vb(aDYQ~8Gnpb65%z~g znErvM4IuT4uc4CCngj59mU(e?$a*!lI487aj<-U+jYY}{9#xTuj-hw845m{hBZs^C z$OForvBg{{&k?|{w+Wq!OoZXt=|I+Rq@Fzs2jG=u)0jM<$8+ZNRpT&D$8!|^n+3+tG^33 z1efG7cYQH?ik;L(w`TV4zxh9ZmcWq9(h z39qP=R*EPgAs|NILHxf=wDC6KfvcOBo%vtWUH$eQPudT2=!{6`B~*ZLgP=Aq z8KWRX6a4dV6TQ8R*8RL+TYGyDeVD_rf4-%VDR(BZXMB88)juBIAt?C5W$@$q%Hwrg zcmIC%dj=Y>rH>yw+UDI(*V>-7n1VnSQB3g7!`A5u5fS0GSvC>sP^FjmIS6fPmQSpd zPwzWEQQK;;f9=oV`AYL>g8P#rXZ;(S zS8-^6{x~{1Cbz5(I2)c4zq%>L$MRoQdJs4JIeYMSlr;-vPn{Z`dW2cV^l0s^35r{O z+3=|iwY18d+}jkyXW!tijghteQ#82pB*NnqRlnZ8G>auM@0fjZ*SL*HkPMQ~k!9$x zytejzW#vA2{V^>l{`*}mW|!_kaO5L*9M+Gx9Q3A$8Q>4N*Y0b%YXw8a+q+d`PrSB6 zf9uJF7LGFBSwDM6oEp@g3J0t>=BdQ(aK#o+jI&_z)OA&0Twbw(psB@NxW3 z_51G7Ak(Uzcm68EC)}xx>7v#D^HjM0Ck?2liCW3|<^$6HTSXr!eNy%j>k;%@+3#Fl zAP=vcx#X^i>}*SC9P<6c3w{(6@9uc}(`N~3q^Qkk5T!E5eIBm|2usixB%5b$K4VB zSEwG=SBs}zz6Ucx1sI(BSZ6nd9{DB&zcMG~>Tl|j<+gL6ZJaA1Bg($(Yro5hWwqqO zUHeh!yFn*_AYBUIf+BW(&l%s-rp0#zzRcrJ{P1?7SiMW_gH@}34x-cexczgCXx*j< zuEO}&$JZDEUk3k*I%9f;&uxci6HG&Wp3I1FmbVB@v1`6Ew+B@ws`YT~mV+(le|}Q# zcQ_u($*X)ZwM;bPxqSV=ck^d|KKlO2@YQ(D%;d%&EtxQB5g11BDq$hO68aq#;r8|V z;ii6dHTz-alv#hks$8@El;%259D4I5JQWv$8Q+E=cWOu(#+QB!peXk0vSgUz>j z;RbaTa3cNtGg4sdH;0<-RGr^*5@uBZk8%CkPS7m-cBI2QkC1_X z>+C3&E|`O+dv?;p^3X!L+J56*M5yDGHT3l&*%m){6eGUq%D{|n+Vk=^FBL{KGNgC> zAxHMEZg{qI8`crxOXxx4oh{yUm@kVdO`&XdS@9}=bmn}`F3%SM;5Mg=p<(~4VV8nV{905gYT5giGL zH*{AChQnW$iO(3RWKnWPG)5EO_sV6PTefy|9BtFbgu4YK9&>@3J7nY9IBg|0`Jk8> z@S=oIaN+vcd7KO8Rj-CysLYSZYUSDUFuwY>6E7eslmwETLh`cRNtU$`m_fw-iL-s) z$cHAw`?iEs|MX*udfMCXkMFtF$pOpOS7h=BnvCu|v}CUH9Zw?t4muu-%;}sTfhUm5 z-m9hYMJDR#Wl)VLvDrQEO@Dt*m!5ldCKP+USZ0$r3_c5mBNtmzeGvRb@M04rPd4>+ zTYJ<3bU)Y>JhWZfXrH-B!zJbahnnIww=bW0cTjNs`A^TY>`7Q;GzH(R;Qk^{jQw^b zVI;qiG>_ACl&UgUB;N}TCV^mAj{x^=wiL3gWa0fU0{@c>ZyiXuXGFp$Jc}nY0p1$C zz!||1i)PXy7{5*4kUe&?rc+9h=;%O;srQ+DsSPi{Xlj+t=+JA$$C>^O^V< zN0wPjCC$Q32O4<_gs4BZPqk}J^)Q3hGdtgP&7i`aVQ(Fa-kDw-B)+hFdPu)w_kcnK zANjs*B2S^gGhJ53XYI102+ym?Jr_%UfB4y28|K>FKk~-E%TbTKu)swp&>UNV)cj2H9U+;8=Jv^^;kryl%Le^ttXrBiq6( zuW8M&rHM4BQB2ZTv2-7#Nn(8_!lV*OgQnq~uE(FQa)H*kZgRpvp_)I&s-rG}2X0G8 z9&S%TB*E_y^W=!GCG9-fVuhiI6yCv#r_@M~+|UbbMID8Vi+`;f0Ic*5$m7lo46pwD zlySFd*-i9E;^$DC^IitXTmYxF>Z*9eG#Wo7aT`+{lTZi2V~_87a^2f8t%aI7R7HXT z6JX+j!dZhxyf1|*Fpce`=EoV5dxrCRe-MQ2EAj9nSoAg5Ao?YJ{o#@vhTMDRxqvnK^?ZSD^SJx;oOO!-$dAD#($(nyz@U!#S$ zHjKx+~r>H>~y#RSrbLo|gA*Z+PI00S4qs7239KU2Ti%*=4uRjqn9$h;Z z%X6q+O6nd&-`I2|;`1>CKLnR%cSrGGoXxk?@C2vJjiy(?_R(tBx9}L_3jU5Q^r~=J z{-HUM;xekEMx7)kSR*aHco{KuceS%-cl~g`v%>4l=0~Au%%a(~Y865g#hooQooqh$ zfjB4b7x4)zxh>lFm?V?|AG`wcIa!79UoNIO`i<%uc$Y)_DHH+sUA7r;j4b8YEdf+z zkDb^A#ZW0B;LE~zp`jKJ$rCiy(^5?nSFop#{_<_w_g@aj*^6kf=ThlC}&$2 z($fnt7I&7zU|DsBw4?@Qr70NI*NUaYQcs&n`=S$=aT}ObpwWcA&l{qP-WOW!PpacS zi{*5LGURS-Rg&i$awy0@VI?QsX2$p>ndH6;7<&L#amCWFRxVUzgzIm4#b7SZZ+a2r zqNU-~q^L_Cdkk4mN1;L*9AdkZV|xw7t&0a4J%~Mx5(?t2O*1imK>ax@Uj{6ko6IeaNSWBae@hp?7V`4bvjk$j+~S7EBm=)Hzn5G+ml>PE zM>tZV&@4wly+|xL%N5}xPGzD4oT?~s6c&QSmk0`wp*~@bY4Nq1E3^ z>))S~D9nc?!d&cZewaNl#WEN3GczUY5H`IygHc2S9MaNS1mQO@)?9q?3Httb4 z-~m4EkR{y!k;)v0vogo%nUeIog%)9{%nHo1#SPLT>kY)k8%GR8b|h@w)oejhrUTX; z=ISg}j#UCUmyL9u$kG8FnI^W0kZ3d) znnIy!HwogfAVwr|rHExLS1{1VCej8G8K$B`hl@l$@(qJG(1OdQ; zB_2=E6c3$wOT}!8&ipy-u}vv@+%e^60}JUTPn;|cmE*6pP(mD^tpsuWiwfkgPbmjb zQe3{1%)YdIzWNItEAyJOClrEc>KV3LbVfJOPN4PWROPzDKr1T32#aP|vaVDiHc=84 zZglw$tOy&!COf;`+QPty4$7uhb3mZgk_^clMg%%IwWCL1e+#rywk2sl@yAA@#pf-G zIDML0%{aF55^QUjF{O>UZqO*g2^RIHjJdARC`t!2K+JW!Mv*3%k;hzv2Wl<%3qQE| zT^=y)N?Gc1Xe3A`UfOQ;%&@kk%iL+&wlq%Kq`F}~2j_7>HejlL9ioQMebz0%;oqf8EHvIWI_Kg1i=&@b>urAmV8 zmH@Oj41J(oP%I`1dV}!hYq*>FxEVE?ON%)*e%i~^zPa28BD&=7Z8`+aDNaE;M>D0o zWyPqvfMyCYryEsZ;IR#0an1?ReX$RYF#;b|XQA$`K;y08_gewG1~lVavWWP3)X4H~ zc~Pgjc*_laNa7SEvgh3SW6)rM#;J(=HNU48yYcQ3h2SAG1!QaiqkKlsSp@1;O1ypYjZG}VoDJgD9O?6h)Vlz1Xca9t z_+f?K<1Dahj`f$Yi)(Q^YD!(^dupPpU4U$)yP)c-LnEz<7WrWKMcuMZksA$C;-Djd zn&YDOc<>wMdm}CC(njQgVa*uuEPMkZXZwIS0Ay2FL>%y`yB^l;0_1--Q+FIhpf1}) z^=%J6`c0zlC@u;udIO?x8m-uj3ReXe2sjDzxkUU*EFcZa_twR1ee>w2Rdd8>MF*#^ z|Cwv;zX&hRY*e_W>X=TFioi*BP zcM^(7A$_24;ZHDD$am49{-t%2Hss*kiWWe|*2Y8E}n2EY25LOv(~z$%ZQkpQ5-yDHYa zy71Q;Yi=%tE!UA+6sdS?1T{dB&7yWd@Eek$C~3{daENsWW$Q;IndQbt1+#HMho`Kz|*7#T*p1jek{RQ98B z9kvn8APaz`5<~Y0KDZe|6eGZSJC#2!}bAE7^JuMXYv8(pB@hwLVnIC6G*c7ejJ2RN>9!k4CXGTQz*9zzL$F zXT`zKpt2R%yK)z2HTKt1sd5j5fzhC;6A4rYw+0mbd#y!n)!;YG??r^s0RJSwuw)GA z6Ao-9Z^DwP2R5lH%G7tXLJuz+07{(9LN&ReF)1{|1>%KW+!K;2C%*Qg>jL7W8e}T7 zJmF&(`y?r(a8Z@NCE#J<9#srtNNeb%Vxf^%L`8&vlUpPLGWX)I2#U($vB>ae^=Z@3 z8Tq+7$Zb`gbi+U2g=CR_eG@u=i~NK)!S_!|6U!IxF#8<(I#_I zPD-AD_~$sye|`JF2?&E5D_ItrPGpz=h9a+8p0?OjY2$A>v2XgRe5e&~Jchn~1_w@-aU{NoTSs!&^mX zqfMNnJHi^$i@efkj4YPKkmvdk>9RODg$aNPkNkTsNQi=7ZwxU&3Gnd?Nsz=(batrd zcTl1YO(f`}N2v`^Bm**kAL8$1ieUn!G)huFKs;93YOb4x30XtVH5?T&AfcgHhcUj1 zf`0_zo6z}3AifFAHvwzi&0vXn7)KLt@I$anPRJaJ4l8P5T-dxI(wqAqtpp4h3;DI{ z@{!&yY>(#FNW}GhsB@%W{-@Kt6(Tud0Wp+@@J0dMNVtjx>rX;P0dL1^@X_I43ia;o z=n#;{`W+K|%tqiT>^Jw$V;wUCo9`;wza?G#P2#X3ySkQ804LPYLgvgN71SCjc}J^> zeD5l9CiqOPDsm#x1sJlY3gSe)u*Nc#Hq}PL^EwfB<=vMO|3Vr^5ieClvNv$m8dp%- zJc0ih0%c0|aUmIMTLHkUUtX*&ck)S_p2Hvd<0O&1#LO&VQJjSU?g*VJHVjRf393Mq zP>e%_iQByqNu{gy`@B5o$hshKatXCDR}MI;#nkC;X~0hr$Hv8UXoyPs8y^z>Mw@sr zLOXn%bztx|IT;)__;NC+SrmrobCFq=|Lslvl?66~vSmCPCy4A4C)vUH+48;eV z-0WOY=paJF!QRLH|pC+JHN-9*P^5?k_WN2j+Bc%|dp=0=}8G2LbL~ z`2!C+KW=o>y<#j@!-~9W$(Ry;6>YQpBn+MR5O8xbnh?1vmS#aHD3Vp8!u|E++-Pis zKyGk9CY-Mqpx+)r{?k9_(}_)CB`QLI`8@&LkDEyIQOc)u@ZJ!?Udl=o+>hS?)z%v2 zd&0+jpwj6?5zt%ZbiKK_xr)yW&z-!Ie3T@Hgp&KZ4M`;_I3hJv1VG{RRY zhw#h$AhC6H%3p}veR^z&qZMi_Cd46h7@_Fk#G;dGt}Laokc9F0Q2D5_vQ{T&PW9`Kqco?kl9!LraLOozaEer??7DQ%n z{iA2%1N=gMQ96I5HwaszzSR;r#u{{_@l*APFUBP(fSv8vj;j6!seZ_^LR=?k1U2omuAg?M?la1vZ07**qFa zh}vQ&w!sW!G8sy9MVs9m>|b%Gj&k6o--W>d#AyYr(M{tg>&AYP~S*FE5ldC zu$WLz;^Q)*tLvaMKk*C#>Os*sjAk4)~3|L#u#bnWvR4&teLPD1PRZn_C@&Tb- zN=h7D%L!2-YDGNbu5U@27NMGZIek@+S8MQ2BQwS#OAn4$n<*wJVAKa^Yl5>)fZ%Mzj0m;2 z1k-1%%&#&^=NuI>`7*Yi`o~Xu<9!25E}0**nQB!Ih;=)ZJi$ ze0{kCqV|m{Mh|WgZ39m^RLMa^lZ|M07z8}D5D7$qR46I5P)6COkiRt)BszQmje*fh zy^51mlZih)g^se!*8?0GgiJchs$jwjnWQpdB$MQVz4oxEKc!#L5q%sdSy^<>wW118}D zJ;Ds16HMxN`vOU^$D_fuTo0~glX`IFCm0bHK%06w8AS|UlBHH@RY|RcXfcp|0H@Se zEe0l)(Wt?<+DC*)`;!B9W(@_uC&CbU^*wUERt~M%po#dC$w&%l@Y+vZ*xNWN}$ znq0R_N6$z*Ynbg7F>_*48hyqZRmQdzNDC}`U!ax;ug$O(L1Z_0b_nXmAk(cFj#-?m zi9{uoh%G_~`?R6N8>qUBmcFPR>jL>ynP`0Y2jGxxWM zbcB~zG0MXGlX)g%FA(~lBV|6O41iKNNP>%rXvTN<`0EVYDz%h^S(Gx#$C8@7B*lIq z8rm;unrp8<_%<)oRx--=ZxZbbP*u)#9%sI5|1fHULPR6qQUZ1a(rGPm=qqKI%Xg5t zsBzge#?i^wEFG6UD<~CnFRlfx_n){?$rk&$8I0C0(UMkf1Q$U7tvfcUWece~YYnw& z@8;9^mC^)%SHu14DwF?{Tr7rl8ty^HW!0a3XL=kHTZJ@3s3{Y_u8c;-VQ1jT{957cOk=%kqZek zkQAm_PXLK*yURKT5Re7ZE=@HzA#nR{UFvVw|`&4 zO^+EYz#ezCU@_1i^*|7F_vgL>+xKc9khm_97+j>$gkV#=k)nh!meQyThB1s$7O?oEBk+V&>jWDh?3 zB?8GFd8_WeUngem!k+Ds^*&8Cy3UDv%;`Zh?kr$VfH22Vcf4-rR4HW0-9oJZe{)opf*$18uW@Botm>uNC;v_SE3B`T87wrAG zuNZkO{t1bRgvwoqnf&+kfEP=0h2b^M?=Ei!qbz^%risW_0 zFX~Eke!k;+L|vs)?p!%V;pD-+W<#v?xmrY?>|$M?*4eT0D?AVQL4!v${{j%ObBWY+ z?YDRqdtJUa#$w34HC@?B4>*b46@9Dtl4!bHOn*3Lr}7d>p4=AURh93G?bO z!jymHCYbpTRRDLD8Tc_4Y`B&vXc9v=9fIMz27{mMWWr(4HW4b6BK;y5j3EGKK*m%>*wwM4gc4*o&iySbK*e2 z)pR~$Am~CYPV8H8vbhrUBysU|_hmT=MBDHbGXi)k4`^3@LWUQlLaT@>Pk3Y9f(;X{?#9 zeMo{`G}T%oDCxId(kRLq!JtwX3(70_UR9A25<9w1c}Cdr)6eG93bYTUTPy-a6VO_X zXp8A#9t`b2NKg!K*(R%)Fbr?lA}g3Meq3YbKFm4USIFdPaH1_YIfNcnMBafHmph!lF6J^QMB^Z5eLlXWXv3feGdft(G_-$^0wx+KHX0C@Y{%(`l`Vi3N ztSXj8Q&QQEvFLx3HJNNpsq91^a(4|%_Z;~p9W)5xk{CHWAPbAR*;tflh@3W;ssXvG z#9x^%SHMgEmkzlCzFkZ3KIxqo^QFno;7D{LPGvIA58mnNrKK;QrgB7k!kbZ0v%n*O z_|9#zz5p)Im$Pj<`B#Q`pCb(}F3%EQmq`k#1i38Z1(Yr>qDxw(2=)&h_m+6;GaV36 zYfN2rIx~h2Pcqc*)*an*e@jB#ZIXEK`fTUT7Z%#)Oa$-yQ=O3B$6w5PG7k$giOT=^ z>%{p2F79gB{~6et?Z4bhu~j*IDs=<*{NvfR^ZEV;d@JGh;4(y9D@Fl)7A+#EtH?nh zm@)g~Hb01W6faHZn*4)Y{L72NRpp`{nqK2BukC|bNwuSktuK$Zq$9Td`a@X24@_sq zooU94halziUp8Am&x6g5R%##gL&MkQ*zD7Mr7(+^uLeXFu%-`Q`PpY$K+ZhAt!tS> zQ*MQQhl0z=SL|7qaa(o?-ZNUDTsh3}AlUdO;UkSc{$H)~)6p+}F+mHvQ-5%fYx`Uc zcyr9~^=i|}@=lTCxpH^?W0Y~1waxXm*VrJd{pd9pm$CG9>+*a*6V_V$qnysNlmYJO ziM0hyh@^U}U~3cBU`q`h&Nm$G&RPU{K;}dvXtgDenK)-H7z2?OnAojMW6lK=)N)q` z0G0KF!rj$9!<$1x!PO{GoIaWf4`(L=u z%$h!2RloevdeXa7n|ZhtP9NaZ3xd6`ZP9Cu_qnwOk6vH*ntmbP^t%4+earUSt6TfG zjAJ_QG}~l#`Nb3~NcUG;+kTc{Z8P;LN-&nI$GQT}d|Pj1<4I&@X=&+T$?ZAy2 zH|O;w7EYT$QeK^YT5jtEo^!MIR2%i_kN6k3WC5IelpinCarV59dkzzwLm7Ie*-!0G zb1n0Nd*oIw=hncHRD4rO1CF{XOnrCz2CaRU-g~q5rQ|L51|TEmtUL4S9iEl3)6Kz^ zC2HaygFlyjOs+WHml_dW(G4rIo9zPMmu{~{TqX9VE+quvYQMZ}Lkm}hNi(*tok?-9 zJS>6-0dCeycXMW3R1X4?mes4ootD$@+nl_CBs~TirUlEPi)L+FsiltY1a|5cb=r;G z22Pp8&rek5m0r9c9mNvYt_h9fQI}?H4vnwqOZMfHfX1PpM1B>_4~4l1#WBrF)<%h0 zE<9Ku4VKZWHM8$(W^T=2qe>n;NH(2+U0MuIz|4c6^5;%C_378%B1iI~MRsE?$E?Np zPUR}a4I=aG{m^6rNrB>7q3Ypb`p%)NYZFK2MB1naiEolgJSbzjW-kDo2D;K9oHX%l<+1TE6A!xnnJXxyjIP-Ix zs%hz&?W(qXsXlAu>{R5NkVoZE)UOrN-_I6TK5A#w4QzJ+uO3E$?cMC|lb#+m3Kojg z^W|ymo=3wBKsDaP$)oX^vfu1wza`3qQET!*$AO;jY#yn827T9v`mP{v3_OfgupV5v z4XusjJ~cB{TFV0o+qVeYTf&-X&+ar)CHXLGTVLtv86@%XUd^#DCz&VbwNY9-#Hya^ z#O{|c5qh8grgdybJjVLj*5?|$f66mmoiC9oJV-0$wrs)hX#)UW(Ev&toCWRUo5dYs z?&-JYR%$I_EDrZ1bVv*%rx~9lNdLsnz-&~%-^k7$6X1c1*K4i{;GIW);<&RvUmHtt zur1r@CN2LsG$iB3F$NO044#6`-XO`2ZMTQrC?U&^{q`HQX?mR3sNBX6&y#skvrdVf zxft4)xJ5$ms$5y#$1RlkDGI@hd z&V)2hIc#z~%BB^jl-XpEzUoOXtMem6WkH#A?W0URhiRaSo#+tmhlb$1_pXkg^vSTU z&;;4=l_gQ^SSgUvv}PjMjbrdv2=bBem1*%WE+%Q2e0^P&t`VUypbOfe$)XH8)UPXC zqYO+PlurObxT3nddn11DyQ1C$LE6`JDxTlfW-Fy`ELp{Cy=j?*fze?V1~85SAq~p~ zT&fbPEku^rqZ0EUBG_Ej$xxP&TJ^Q++MNnpDbG&U9T+Lwy)qA0m1uqzG*;kb>khu? zhG;R?94|Qy#%TViuv--&=J0;sI$o_|KE8BcH%l(q;MhXfp=M)ctbVIOzz?26Fg?wT zRZ*bzM$7Iv0WG1S*MuKL6;ofmEpcGNuTg%p5r|cW+N(mJrc=LAv95Al#kl%~ zp&3-CXgai7im|+kQ0spH!_aTjY?f&&Fq?klI6otcBUtv3fd9xwvD9mk<$bC1#fWFM z3fqoaOQGasQvIkZAhHU>-2+C>?74KA-pHg9Q45M*sAj?A;D|Y`_j~vkcv+*im{K!@ zs=b)ffbwZG@W|z46Y#|IUf&gsk49BwH2Q6(R4zY{o6~CdlPU`51o6RmAzr@Up=D1w zN?E{~;OZb$u9*K^K2QB8pVZ!%4T;R`ua?xg7Pyf++ngaKmodYg*RL zv$sI3lq!bXM^3q5o}!&*R=GlqdI{ro*Qkf}J=Rn4*^aZ?MP3w~I^U7nh12a|K~(7> zT@In9n#N$Ty*{F|xcM%}%2F|=rW!~u#$G@8XOxPxZTdmMbud~S^S6?ku+5hG@=C8E z_{?^P5Jp_`V%$PvyWsAlAOt8ZXsR-PDjG@FlmrpisU^l4Wczt!$}A=OA*e|uxJe}u z#Ad!GAy&Oq{fB!Q_aq~Z>5MR!E%mZr}wd$XzA;a@tBV;>#Ul#;F!*D$2}-l4?`Wn6*Y1qvnkKkq>zL6uX*c=;3vk+4TF z!c!E(7dZ)%>ce_9c6KqjS`r?zM<2%*Jcl=3(9B~#Vck)mD~_p=O>$?lSNKYM@&f_b z_bp7%BCH=Y$N)>fHONx^?|=>$>i63KSB2&_P}#MM@Fo_=eakSV*S>T&zXMe!kjjSL z+$^+duE=upbXixd`(kDR44ii* z#BUa5CEgD>6tvyqg%53H!3qu{zCb)UI>bw_jkCY?7%h(TnJ5omaL1g7+Wqfl0 zjt|gglT63P=jy^;KYDj|<*Mb|8q~215xp3m@oCR4w)aRh`M~5xxO_3(u)5mgv;5X# zcpbk6aot0}BHW-RG1r<=MYVucbfmzzWkvEJ-Ms^QuAN4vS%nPCDjq8`nh7LXR9XQN z`iT{Tdhbvj0Z`}$W!fouQLP6QAV1WQ#hGY(ps}e@EaPU&oU^m*0{Yn}?f2E8w^hSL z52tMT40T&4v%a?#1YY@?dRsRmoOda(KAPxpcj4l1w+nT7uzvY~ruC@?yo2#R1Mgsl zn$3r9HZQnG4~BorA6;Het>zexx);2AC03G!gEzk`zX!5FKuqAkf&*G0q25Ehhk$^G zfFRHb*JGusDq{kNvb?>(S^u@zTictvc{!Q?x7UBZ4gEg_ggRJ>IyzWbTe`a#yIDIr zxUw+)>kSVN|JQdi2VqP4U_(G?2tYz0{V(reurhUYa5H!KD`e@v9Zh)&>lEN1AhG}u z5Xk?_krM|TjbrZSX6<14S3J&tdzyU3%O{3{fOv)e@6GHX0taT9yBWWQNd4>eZ{;YS zAWnWZgn)Q^;r_4hdrt}hp=RZ7Z{lEVZRg75_Ah00ahX)ebbxzKUoRBg#Z8m literal 0 HcmV?d00001 diff --git a/bench/trace-schemas/trace-schemas-presentation.pptx b/bench/trace-schemas/trace-schemas-presentation.pptx new file mode 100644 index 0000000000000000000000000000000000000000..d99683ba0dd3fa55e605ea231a3af597a34c2a58 GIT binary patch literal 35056 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 z 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 9.12) proto-lens-tests-dep proto-lens-tests proto-lens + +source-repository-package + type: git + location: https://github.com/IntersectMBO/hermod-tracing + tag: e5d49217cc3cd1bc084c4a2b453f06f93bcb2006 + --sha256: sha256-eO7604L/xw+52K3jHLU2HbNz7kjCNUvL/DJmeOlP2lI= + subdir: + trace-dispatcher diff --git a/cardano-node/src/Cardano/Node/Tracing/Documentation.hs b/cardano-node/src/Cardano/Node/Tracing/Documentation.hs index d8936b3e683..c8478b5d8d6 100644 --- a/cardano-node/src/Cardano/Node/Tracing/Documentation.hs +++ b/cardano-node/src/Cardano/Node/Tracing/Documentation.hs @@ -1,9 +1,9 @@ +{-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} -{-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} @@ -20,18 +20,19 @@ module Cardano.Node.Tracing.Documentation , docTracersFirstPhase ) where +import Ouroboros.Network.Tracing.TxSubmission.Inbound () +import Ouroboros.Network.Tracing.TxSubmission.Outbound () +import Ouroboros.Network.Tracing.PeerSelection () +import Cardano.Network.Tracing.PeerSelection () +import Cardano.Network.Tracing.PeerSelectionCounters () import Cardano.Git.Rev (gitRev) import Cardano.Logging as Logging import Cardano.Logging.Resources import Cardano.Logging.Resources.Types () -import Cardano.Network.NodeToNode (RemoteAddress) -import qualified Cardano.Network.NodeToNode as NtN import qualified Cardano.Network.PeerSelection.ExtraRootPeers as Cardano.PublicRootPeers import qualified Cardano.Network.PeerSelection.Governor.PeerSelectionState as Cardano import qualified Cardano.Network.PeerSelection.Governor.Types as Cardano import Cardano.Network.PeerSelection.PeerTrustable (PeerTrustable (..)) -import Cardano.Network.Tracing.PeerSelection () -import Cardano.Network.Tracing.PeerSelectionCounters () import Cardano.Node.Handlers.Shutdown (ShutdownTrace) import Cardano.Node.Startup import Cardano.Node.Tracing.DefaultTraceConfig (defaultCardanoConfig) @@ -85,6 +86,8 @@ import Ouroboros.Network.Driver.Simple (TraceSendRecv) import qualified Ouroboros.Network.Driver.Stateful as Stateful (TraceSendRecv) import qualified Ouroboros.Network.InboundGovernor as InboundGovernor import Ouroboros.Network.KeepAlive (TraceKeepAliveClient (..)) +import Cardano.Network.NodeToNode (RemoteAddress) +import qualified Cardano.Network.NodeToNode as NtN import Ouroboros.Network.PeerSelection.Governor (DebugPeerSelection (..), PeerSelectionCounters, TracePeerSelection) import Ouroboros.Network.PeerSelection.LedgerPeers (TraceLedgerPeers) @@ -104,12 +107,11 @@ import qualified Ouroboros.Network.Protocol.LocalTxSubmission.Type as LTS import Ouroboros.Network.Protocol.TxSubmission2.Type (TxSubmission2) import qualified Ouroboros.Network.Server as Server (Trace (..)) import Ouroboros.Network.Snocket (LocalAddress (..)) -import Ouroboros.Network.Tracing () -import Ouroboros.Network.Tracing.PeerSelection () -import Ouroboros.Network.Tracing.TxSubmission.Inbound () -import Ouroboros.Network.Tracing.TxSubmission.Outbound () import Ouroboros.Network.TxSubmission.Inbound.V2 (TraceTxSubmissionInbound) import Ouroboros.Network.TxSubmission.Outbound (TraceTxSubmissionOutbound) +import Ouroboros.Network.Tracing () +import Network.Mux.Tracing () +import qualified Network.Mux as Mux import Control.Monad (forM_) import Data.Aeson.Types (ToJSON) @@ -118,8 +120,6 @@ import Data.Text (pack) import qualified Data.Text.IO as T import Data.Time (getZonedTime) import Data.Version (showVersion) -import qualified Network.Mux as Mux -import Network.Mux.Tracing () import qualified Network.Socket as Socket import qualified Options.Applicative as Opt import System.IO diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs new file mode 100644 index 00000000000..840076510db --- /dev/null +++ b/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs @@ -0,0 +1,993 @@ +{-# LANGUAGE AllowAmbiguousTypes #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE LambdaCase #-} +{-# LANGUAGE NamedFieldPuns #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE TypeApplications #-} + + + +{-# OPTIONS_GHC -Wno-orphans #-} + +module Cardano.Node.Tracing.Tracers.Diffusion + ( txsMempoolTimeoutHardCounterName + , impliesMempoolTimeoutHard + ) where + + +import Cardano.Logging +import Cardano.Node.Configuration.TopologyP2P () +import Control.Exception (fromException) +import Ouroboros.Consensus.Mempool.API (ExnMempoolTimeout) +import qualified Ouroboros.Network.Diffusion.Types as Diff +import Ouroboros.Network.PeerSelection.LedgerPeers (NumberOfPeers (..), PoolStake (..), + TraceLedgerPeers (..)) +import qualified Ouroboros.Network.Protocol.Handshake.Type as HS + +import Data.Aeson (Value (String), (.=)) +import qualified Data.List as List +import Data.Text (Text, pack) +import Data.Typeable +import Formatting + +import qualified Network.Mux as Mux +#ifdef linux_HOST_OS +import Network.Mux.TCPInfo (StructTCPInfo (..)) +#endif +import Network.Mux.Types (SDUHeader (..), unRemoteClockModel) +import Network.TypedProtocol.Codec (AnyMessage (..)) + +-------------------------------------------------------------------------------- +-- Mux Tracer +-------------------------------------------------------------------------------- + +instance (LogFormatting peer, LogFormatting tr, Typeable tr) => + LogFormatting (Mux.WithBearer peer tr) where + forMachine dtal (Mux.WithBearer b ev) = + mconcat [ "kind" .= (show . typeOf $ ev) + , "bearer" .= forMachine dtal b + , "event" .= forMachine dtal ev ] + forHuman (Mux.WithBearer b ev) = "With mux bearer " <> forHuman b + <> ". " <> forHuman ev + +instance MetaTrace tr => MetaTrace (Mux.WithBearer peer tr) where + namespaceFor (Mux.WithBearer _peer obj) = (nsCast . namespaceFor) obj + severityFor ns Nothing = severityFor (nsCast ns :: Namespace tr) Nothing + severityFor ns (Just (Mux.WithBearer _peer obj)) = + severityFor (nsCast ns) (Just obj) + privacyFor ns Nothing = privacyFor (nsCast ns :: Namespace tr) Nothing + privacyFor ns (Just (Mux.WithBearer _peer obj)) = + privacyFor (nsCast ns) (Just obj) + detailsFor ns Nothing = detailsFor (nsCast ns :: Namespace tr) Nothing + detailsFor ns (Just (Mux.WithBearer _peer obj)) = + detailsFor (nsCast ns) (Just obj) + documentFor ns = documentFor (nsCast ns :: Namespace tr) + metricsDocFor ns = metricsDocFor (nsCast ns :: Namespace tr) + allNamespaces = map nsCast (allNamespaces :: [Namespace tr]) + +instance LogFormatting Mux.BearerTrace where + forMachine _dtal Mux.TraceRecvHeaderStart = mconcat + [ "kind" .= String "Mux.TraceRecvHeaderStart" + , "msg" .= String "Bearer Receive Header Start" + ] + forMachine _dtal (Mux.TraceRecvHeaderEnd SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = mconcat + [ "kind" .= String "Mux.TraceRecvHeaderStart" + , "msg" .= String "Bearer Receive Header End" + , "timestamp" .= String (showTHex (unRemoteClockModel mhTimestamp)) + , "miniProtocolNum" .= String (showT mhNum) + , "miniProtocolDir" .= String (showT mhDir) + , "length" .= String (showT mhLength) + ] + forMachine _dtal (Mux.TraceRecvDeltaQObservation SDUHeader { mhTimestamp, mhLength } ts) = mconcat + [ "kind" .= String "Mux.TraceRecvDeltaQObservation" + , "msg" .= String "Bearer DeltaQ observation" + , "timeRemote" .= String (showT ts) + , "timeLocal" .= String (showTHex (unRemoteClockModel mhTimestamp)) + , "length" .= String (showT mhLength) + ] + forMachine _dtal (Mux.TraceRecvDeltaQSample d sp so dqs dqvm dqvs estR sdud) = mconcat + [ "kind" .= String "Mux.TraceRecvDeltaQSample" + , "msg" .= String "Bearer DeltaQ Sample" + , "duration" .= String (showT d) + , "packets" .= String (showT sp) + , "sumBytes" .= String (showT so) + , "DeltaQ_S" .= String (showT dqs) + , "DeltaQ_VMean" .= String (showT dqvm) + , "DeltaQ_VVar" .= String (showT dqvs) + , "DeltaQ_estR" .= String (showT estR) + , "sizeDist" .= String (showT sdud) + ] + forMachine _dtal (Mux.TraceRecvStart len) = mconcat + [ "kind" .= String "Mux.TraceRecvStart" + , "msg" .= String "Bearer Receive Start" + , "length" .= String (showT len) + ] + forMachine _dtal (Mux.TraceRecvRaw len) = mconcat + [ "kind" .= String "Mux.TraceRecvRaw" + , "msg" .= String "Bearer Receive Raw" + , "length" .= String (showT len) + ] + forMachine _dtal (Mux.TraceRecvEnd len) = mconcat + [ "kind" .= String "Mux.TraceRecvEnd" + , "msg" .= String "Bearer Receive End" + , "length" .= String (showT len) + ] + forMachine _dtal (Mux.TraceSendStart SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = mconcat + [ "kind" .= String "Mux.TraceSendStart" + , "msg" .= String "Bearer Send Start" + , "timestamp" .= String (showTHex (unRemoteClockModel mhTimestamp)) + , "miniProtocolNum" .= String (showT mhNum) + , "miniProtocolDir" .= String (showT mhDir) + , "length" .= String (showT mhLength) + ] + forMachine _dtal Mux.TraceSendEnd = mconcat + [ "kind" .= String "Mux.TraceSendEnd" + , "msg" .= String "Bearer Send End" + ] + forMachine _dtal Mux.TraceSDUReadTimeoutException = mconcat + [ "kind" .= String "Mux.TraceSDUReadTimeoutException" + , "msg" .= String "Timed out reading SDU" + ] + forMachine _dtal Mux.TraceSDUWriteTimeoutException = mconcat + [ "kind" .= String "Mux.TraceSDUWriteTimeoutException" + , "msg" .= String "Timed out writing SDU" + ] + forMachine _dtal Mux.TraceEmitDeltaQ = mempty +#ifdef linux_HOST_OS + forMachine _dtal (Mux.TraceTCPInfo StructTCPInfo + { tcpi_snd_mss, tcpi_rcv_mss, tcpi_lost, tcpi_retrans + , tcpi_rtt, tcpi_rttvar, tcpi_snd_cwnd } + len) = mconcat + [ "kind" .= String "Mux.TraceTCPInfo" + , "msg" .= String "TCPInfo" + , "rtt" .= (fromIntegral tcpi_rtt :: Word) + , "rttvar" .= (fromIntegral tcpi_rttvar :: Word) + , "snd_cwnd" .= (fromIntegral tcpi_snd_cwnd :: Word) + , "snd_mss" .= (fromIntegral tcpi_snd_mss :: Word) + , "rcv_mss" .= (fromIntegral tcpi_rcv_mss :: Word) + , "lost" .= (fromIntegral tcpi_lost :: Word) + , "retrans" .= (fromIntegral tcpi_retrans :: Word) + , "length" .= len + ] +#else + forMachine _dtal (Mux.TraceTCPInfo _ len) = mconcat + [ "kind" .= String "Mux.TraceTCPInfo" + , "msg" .= String "TCPInfo" + , "len" .= String (showT len) + ] +#endif + + forHuman Mux.TraceRecvHeaderStart = + "Bearer Receive Header Start" + forHuman (Mux.TraceRecvHeaderEnd SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = + sformat ("Bearer Receive Header End: ts:" % prefixHex % "(" % shown % ") " % shown % " len " % int) + (unRemoteClockModel mhTimestamp) mhNum mhDir mhLength + forHuman (Mux.TraceRecvDeltaQObservation SDUHeader { mhTimestamp, mhLength } ts) = + sformat ("Bearer DeltaQ observation: remote ts" % int % " local ts " % shown % " length " % int) + (unRemoteClockModel mhTimestamp) ts mhLength + forHuman (Mux.TraceRecvDeltaQSample d sp so dqs dqvm dqvs estR sdud) = + sformat ("Bearer DeltaQ Sample: duration " % fixed 3 % " packets " % int % " sumBytes " + % int % " DeltaQ_S " % fixed 3 % " DeltaQ_VMean " % fixed 3 % "DeltaQ_VVar " % fixed 3 + % " DeltaQ_estR " % fixed 3 % " sizeDist " % string) + d sp so dqs dqvm dqvs estR sdud + forHuman (Mux.TraceRecvStart len) = + sformat ("Bearer Receive Start: length " % int) len + forHuman (Mux.TraceRecvRaw len) = + sformat ("Bearer Receive Raw: length " % int) len + forHuman (Mux.TraceRecvEnd len) = + sformat ("Bearer Receive End: length " % int) len + forHuman (Mux.TraceSendStart SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = + sformat ("Bearer Send Start: ts: " % prefixHex % " (" % shown % ") " % shown % " length " % int) + (unRemoteClockModel mhTimestamp) mhNum mhDir mhLength + forHuman Mux.TraceSendEnd = + "Bearer Send End" + forHuman Mux.TraceSDUReadTimeoutException = + "Timed out reading SDU" + forHuman Mux.TraceSDUWriteTimeoutException = + "Timed out writing SDU" + forHuman Mux.TraceEmitDeltaQ = mempty +#ifdef linux_HOST_OS + forHuman (Mux.TraceTCPInfo StructTCPInfo + { tcpi_snd_mss, tcpi_rcv_mss, tcpi_lost, tcpi_retrans + , tcpi_rtt, tcpi_rttvar, tcpi_snd_cwnd } + len) = + sformat ("TCPInfo rtt " % int % " rttvar " % int % " snd_cwnd " % int % + " snd_mss " % int % " rcv_mss " % int % " lost " % int % + " retrans " % int % " len " % int) + (fromIntegral tcpi_rtt :: Word) + (fromIntegral tcpi_rttvar :: Word) + (fromIntegral tcpi_snd_cwnd :: Word) + (fromIntegral tcpi_snd_mss :: Word) + (fromIntegral tcpi_rcv_mss :: Word) + (fromIntegral tcpi_lost :: Word) + (fromIntegral tcpi_retrans :: Word) + len +#else + forHuman (Mux.TraceTCPInfo _ len) = sformat ("TCPInfo len " % int) len +#endif + +instance MetaTrace Mux.BearerTrace where + namespaceFor Mux.TraceRecvHeaderStart {} = + Namespace [] ["RecvHeaderStart"] + namespaceFor Mux.TraceRecvHeaderEnd {} = + Namespace [] ["RecvHeaderEnd"] + namespaceFor Mux.TraceRecvStart {} = + Namespace [] ["RecvStart"] + namespaceFor Mux.TraceRecvRaw {} = + Namespace [] ["RecvRaw"] + namespaceFor Mux.TraceRecvEnd {} = + Namespace [] ["RecvEnd"] + namespaceFor Mux.TraceSendStart {} = + Namespace [] ["SendStart"] + namespaceFor Mux.TraceSendEnd = + Namespace [] ["SendEnd"] + namespaceFor Mux.TraceRecvDeltaQObservation {} = + Namespace [] ["RecvDeltaQObservation"] + namespaceFor Mux.TraceRecvDeltaQSample {} = + Namespace [] ["RecvDeltaQSample"] + namespaceFor Mux.TraceSDUReadTimeoutException = + Namespace [] ["SDUReadTimeoutException"] + namespaceFor Mux.TraceSDUWriteTimeoutException = + Namespace [] ["SDUWriteTimeoutException"] + namespaceFor Mux.TraceEmitDeltaQ = + Namespace [] ["TraceEmitDeltaQ"] + namespaceFor Mux.TraceTCPInfo {} = + Namespace [] ["TCPInfo"] + + severityFor (Namespace _ ["RecvHeaderStart"]) _ = Just Debug + severityFor (Namespace _ ["RecvRaw"]) _ = Just Debug + severityFor (Namespace _ ["RecvHeaderEnd"]) _ = Just Debug + severityFor (Namespace _ ["RecvStart"]) _ = Just Debug + severityFor (Namespace _ ["RecvEnd"]) _ = Just Debug + severityFor (Namespace _ ["SendStart"]) _ = Just Debug + severityFor (Namespace _ ["SendEnd"]) _ = Just Debug + severityFor (Namespace _ ["RecvDeltaQObservation"]) _ = Just Debug + severityFor (Namespace _ ["RecvDeltaQSample"]) _ = Just Debug + severityFor (Namespace _ ["SDUReadTimeoutException"]) _ = Just Notice + severityFor (Namespace _ ["SDUWriteTimeoutException"]) _ = Just Notice + severityFor (Namespace _ ["TCPInfo"]) _ = Just Debug + severityFor (Namespace _ ["TraceEmitDeltaQ"]) _ = Nothing + severityFor _ _ = Nothing + + documentFor (Namespace _ ["RecvHeaderStart"]) = Just + "Bearer receive header start." + documentFor (Namespace _ ["RecvRaw"]) = Just + "Bearer receive raw." + documentFor (Namespace _ ["RecvHeaderEnd"]) = Just + "Bearer receive header end." + documentFor (Namespace _ ["RecvStart"]) = Just + "Bearer receive start." + documentFor (Namespace _ ["RecvEnd"]) = Just + "Bearer receive end." + documentFor (Namespace _ ["SendStart"]) = Just + "Bearer send start." + documentFor (Namespace _ ["SendEnd"]) = Just + "Bearer send end." + documentFor (Namespace _ ["RecvDeltaQObservation"]) = Just + "Bearer DeltaQ observation." + documentFor (Namespace _ ["RecvDeltaQSample"]) = Just + "Bearer DeltaQ sample." + documentFor (Namespace _ ["SDUReadTimeoutException"]) = Just + "Timed out reading SDU." + documentFor (Namespace _ ["SDUWriteTimeoutException"]) = Just + "Timed out writing SDU." + documentFor (Namespace _ ["TraceEmitDeltaQ"]) = Nothing + documentFor (Namespace _ ["TCPInfo"]) = Just + "TCPInfo." + documentFor _ = Nothing + + allNamespaces = [ + Namespace [] ["RecvHeaderStart"] + , Namespace [] ["RecvRaw"] + , Namespace [] ["RecvHeaderEnd"] + , Namespace [] ["RecvStart"] + , Namespace [] ["RecvEnd"] + , Namespace [] ["SendStart"] + , Namespace [] ["SendEnd"] + , Namespace [] ["RecvDeltaQObservation"] + , Namespace [] ["RecvDeltaQSample"] + , Namespace [] ["SDUReadTimeoutException"] + , Namespace [] ["SDUWriteTimeoutException"] + , Namespace [] ["TraceEmitDeltaQ"] + , Namespace [] ["TCPInfo"] + ] + +instance LogFormatting Mux.ChannelTrace where + forMachine _dtal (Mux.TraceChannelRecvStart mid) = mconcat + [ "kind" .= String "Mux.TraceChannelRecvStart" + , "msg" .= String "Channel Receive Start" + , "miniProtocolNum" .= String (showT mid) + ] + forMachine _dtal (Mux.TraceChannelRecvEnd mid len) = mconcat + [ "kind" .= String "Mux.TraceChannelRecvEnd" + , "msg" .= String "Channel Receive End" + , "miniProtocolNum" .= String (showT mid) + , "length" .= String (showT len) + ] + forMachine _dtal (Mux.TraceChannelSendStart mid len) = mconcat + [ "kind" .= String "Mux.TraceChannelSendStart" + , "msg" .= String "Channel Send Start" + , "miniProtocolNum" .= String (showT mid) + , "length" .= String (showT len) + ] + forMachine _dtal (Mux.TraceChannelSendEnd mid) = mconcat + [ "kind" .= String "Mux.TraceChannelSendEnd" + , "msg" .= String "Channel Send End" + , "miniProtocolNum" .= String (showT mid) + ] + + forHuman (Mux.TraceChannelRecvStart mid) = + sformat ("Channel Receive Start on " % shown) mid + forHuman (Mux.TraceChannelRecvEnd mid len) = + sformat ("Channel Receive End on (" % shown % ") " % int) mid len + forHuman (Mux.TraceChannelSendStart mid len) = + sformat ("Channel Send Start on (" % shown % ") " % int) mid len + forHuman (Mux.TraceChannelSendEnd mid) = + sformat ("Channel Send End on " % shown) mid + +instance MetaTrace Mux.ChannelTrace where + namespaceFor Mux.TraceChannelRecvStart {} = + Namespace [] ["ChannelRecvStart"] + namespaceFor Mux.TraceChannelRecvEnd {} = + Namespace [] ["ChannelRecvEnd"] + namespaceFor Mux.TraceChannelSendStart {} = + Namespace [] ["ChannelSendStart"] + namespaceFor Mux.TraceChannelSendEnd {} = + Namespace [] ["ChannelSendEnd"] + + severityFor (Namespace _ ["ChannelRecvStart"]) _ = Just Debug + severityFor (Namespace _ ["ChannelRecvEnd"]) _ = Just Debug + severityFor (Namespace _ ["ChannelSendStart"]) _ = Just Debug + severityFor (Namespace _ ["ChannelSendEnd"]) _ = Just Debug + severityFor _ _ = Nothing + + documentFor (Namespace _ ["ChannelRecvStart"]) = Just + "Channel receive start." + documentFor (Namespace _ ["ChannelRecvEnd"]) = Just + "Channel receive end." + documentFor (Namespace _ ["ChannelSendStart"]) = Just + "Channel send start." + documentFor (Namespace _ ["ChannelSendEnd"]) = Just + "Channel send end." + documentFor _ = Nothing + + allNamespaces = [ + Namespace [] ["ChannelRecvStart"] + , Namespace [] ["ChannelRecvEnd"] + , Namespace [] ["ChannelSendStart"] + , Namespace [] ["ChannelSendEnd"] + ] + +txsMempoolTimeoutHardCounterName :: Text +txsMempoolTimeoutHardCounterName = "txsMempoolTimeoutHard" + +impliesMempoolTimeoutHard :: Mux.Trace -> Bool +impliesMempoolTimeoutHard = \case + Mux.TraceExceptionExit _mid _dir e + | Just _ <- fromException @ExnMempoolTimeout e + -> True + _ -> False + +instance LogFormatting Mux.Trace where + forMachine _dtal (Mux.TraceState new) = mconcat + [ "kind" .= String "Mux.TraceState" + , "msg" .= String "MuxState" + , "state" .= String (showT new) + ] + forMachine _dtal (Mux.TraceCleanExit mid dir) = mconcat + [ "kind" .= String "Mux.TraceCleanExit" + , "msg" .= String "Miniprotocol terminated cleanly" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + ] + forMachine _dtal (Mux.TraceExceptionExit mid dir exc) = mconcat + [ "kind" .= String "Mux.TraceExceptionExit" + , "msg" .= String "Miniprotocol terminated with exception" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + , "exception" .= String (showT exc) + ] + forMachine _dtal (Mux.TraceStartEagerly mid dir) = mconcat + [ "kind" .= String "Mux.TraceStartEagerly" + , "msg" .= String "Eagerly started" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + ] + forMachine _dtal (Mux.TraceStartOnDemand mid dir) = mconcat + [ "kind" .= String "Mux.TraceStartOnDemand" + , "msg" .= String "Preparing to start" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + ] + forMachine _dtal (Mux.TraceStartOnDemandAny mid dir) = mconcat + [ "kind" .= String "Mux.TraceStartOnDemandAny" + , "msg" .= String "Preparing to start" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + ] + forMachine _dtal (Mux.TraceStartedOnDemand mid dir) = mconcat + [ "kind" .= String "Mux.TraceStartedOnDemand" + , "msg" .= String "Started on demand" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + ] + forMachine _dtal (Mux.TraceTerminating mid dir) = mconcat + [ "kind" .= String "Mux.TraceTerminating" + , "msg" .= String "Terminating" + , "miniProtocolNum" .= String (showT mid) + , "miniProtocolDir" .= String (showT dir) + ] + forMachine _dtal Mux.TraceStopping = mconcat + [ "kind" .= String "Mux.TraceStopping" + , "msg" .= String "Mux stopping" + ] + forMachine _dtal Mux.TraceStopped = mconcat + [ "kind" .= String "Mux.TraceStopped" + , "msg" .= String "Mux stoppped" + ] + + forHuman (Mux.TraceState new) = + sformat ("State: " % shown) new + forHuman (Mux.TraceCleanExit mid dir) = + sformat ("Miniprotocol (" % shown % ") " % shown % " terminated cleanly") + mid dir + forHuman (Mux.TraceExceptionExit mid dir e) = + sformat ("Miniprotocol (" % shown % ") " % shown % + " terminated with exception " % shown) mid dir e + forHuman (Mux.TraceStartEagerly mid dir) = + sformat ("Eagerly started (" % shown % ") in " % shown) mid dir + forHuman (Mux.TraceStartOnDemand mid dir) = + sformat ("Preparing to start (" % shown % ") in " % shown) mid dir + forHuman (Mux.TraceStartOnDemandAny mid dir) = + sformat ("Preparing to start (" % shown % ") in " % shown) mid dir + forHuman (Mux.TraceStartedOnDemand mid dir) = + sformat ("Started on demand (" % shown % ") in " % shown) mid dir + forHuman (Mux.TraceTerminating mid dir) = + sformat ("Terminating (" % shown % ") in " % shown) mid dir + forHuman Mux.TraceStopping = "Mux stopping" + forHuman Mux.TraceStopped = "Mux stoppped" + + asMetrics = \case + Mux.TraceState{} -> [] + Mux.TraceCleanExit{} -> [] + ev@Mux.TraceExceptionExit{} -> + -- Somewhat awkward to "catch" this Consensus exception here, but + -- Diffusion Layer is indeed the ultimate manager of the per-peer + -- threads. + [ CounterM txsMempoolTimeoutHardCounterName Nothing + | impliesMempoolTimeoutHard ev + ] + Mux.TraceStartEagerly{} -> [] + Mux.TraceStartOnDemand{} -> [] + Mux.TraceStartOnDemandAny{} -> [] + Mux.TraceStartedOnDemand{} -> [] + Mux.TraceTerminating{} -> [] + Mux.TraceStopping{} -> [] + Mux.TraceStopped{} -> [] + +instance MetaTrace Mux.Trace where + namespaceFor Mux.TraceState {} = + Namespace [] ["State"] + namespaceFor Mux.TraceCleanExit {} = + Namespace [] ["CleanExit"] + namespaceFor Mux.TraceExceptionExit {} = + Namespace [] ["ExceptionExit"] + namespaceFor Mux.TraceStartEagerly {} = + Namespace [] ["StartEagerly"] + namespaceFor Mux.TraceStartOnDemand {} = + Namespace [] ["StartOnDemand"] + namespaceFor Mux.TraceStartOnDemandAny {} = + Namespace [] ["StartOnDemandAny"] + namespaceFor Mux.TraceStartedOnDemand {} = + Namespace [] ["StartedOnDemand"] + namespaceFor Mux.TraceTerminating {} = + Namespace [] ["Terminating"] + namespaceFor Mux.TraceStopping = + Namespace [] ["Stopping"] + namespaceFor Mux.TraceStopped = + Namespace [] ["Stopped"] + + severityFor (Namespace _ ["State"]) _ = Just Info + severityFor (Namespace _ ["CleanExit"]) _ = Just Notice + severityFor (Namespace _ ["ExceptionExit"]) _ = Just Notice + severityFor (Namespace _ ["StartEagerly"]) _ = Just Debug + severityFor (Namespace _ ["StartOnDemand"]) _ = Just Debug + severityFor (Namespace _ ["StartOnDemandAny"]) _ = Just Debug + severityFor (Namespace _ ["StartedOnDemand"]) _ = Just Debug + severityFor (Namespace _ ["Terminating"]) _ = Just Debug + severityFor (Namespace _ ["Stopping"]) _ = Just Debug + severityFor (Namespace _ ["Stopped"]) _ = Just Debug + severityFor _ _ = Nothing + + documentFor (Namespace _ ["State"]) = Just + "State." + documentFor (Namespace _ ["CleanExit"]) = Just + "Miniprotocol terminated cleanly." + documentFor (Namespace _ ["ExceptionExit"]) = Just + "Miniprotocol terminated with exception." + documentFor (Namespace _ ["StartEagerly"]) = Just + "Eagerly started." + documentFor (Namespace _ ["StartOnDemand"]) = Just + "Preparing to start." + documentFor (Namespace _ ["StartedOnDemand"]) = Just + "Started on demand." + documentFor (Namespace _ ["StartOnDemandAny"]) = Just + "Start whenever any other protocol has started." + documentFor (Namespace _ ["Terminating"]) = Just + "Terminating." + documentFor (Namespace _ ["Stopping"]) = Just + "Mux shutdown." + documentFor (Namespace _ ["Stopped"]) = Just + "Mux shutdown." + documentFor _ = Nothing + + metricsDocFor (Namespace _ ["State"]) = [] + metricsDocFor (Namespace _ ["CleanExit"]) = [] + metricsDocFor (Namespace _ ["ExceptionExit"]) = + [ (txsMempoolTimeoutHardCounterName, "Transactions that hard timed out in mempool") + ] + metricsDocFor (Namespace _ ["StartEagerly"]) = [] + metricsDocFor (Namespace _ ["StartOnDemand"]) = [] + metricsDocFor (Namespace _ ["StartedOnDemand"]) = [] + metricsDocFor (Namespace _ ["StartOnDemandAny"]) = [] + metricsDocFor (Namespace _ ["Terminating"]) = [] + metricsDocFor (Namespace _ ["Stopping"]) = [] + metricsDocFor (Namespace _ ["Stopped"]) = [] + metricsDocFor _ = [] + + allNamespaces = [ + Namespace [] ["State"] + , Namespace [] ["CleanExit"] + , Namespace [] ["ExceptionExit"] + , Namespace [] ["StartEagerly"] + , Namespace [] ["StartOnDemand"] + , Namespace [] ["StartOnDemandAny"] + , Namespace [] ["StartedOnDemand"] + , Namespace [] ["Terminating"] + , Namespace [] ["Stopping"] + , Namespace [] ["Stopped"] + ] + + +-------------------------------------------------------------------------------- +-- Handshake Tracer +-------------------------------------------------------------------------------- + +instance (Show term, Show ntcVersion) => + LogFormatting (AnyMessage (HS.Handshake ntcVersion term)) where + forMachine _dtal (AnyMessageAndAgency stok msg) = + mconcat [ "kind" .= String kind + , "msg" .= (String . showT $ msg) + , "agency" .= String (pack $ show stok) + ] + where + kind = case msg of + HS.MsgProposeVersions {} -> "ProposeVersions" + HS.MsgReplyVersions {} -> "ReplyVersions" + HS.MsgQueryReply {} -> "QueryReply" + HS.MsgAcceptVersion {} -> "AcceptVersion" + HS.MsgRefuse {} -> "Refuse" + + forHuman (AnyMessageAndAgency stok msg) = + "Handshake (agency, message) = " <> "(" <> showT stok <> "," <> showT msg <> ")" + +instance MetaTrace (AnyMessage (HS.Handshake a b)) where + namespaceFor (AnyMessage msg) = Namespace [] $ case msg of + HS.MsgProposeVersions {} -> ["ProposeVersions"] + HS.MsgReplyVersions {} -> ["ReplyVersions"] + HS.MsgQueryReply {} -> ["QueryReply"] + HS.MsgAcceptVersion {} -> ["AcceptVersion"] + HS.MsgRefuse {} -> ["Refuse"] + + severityFor (Namespace _ [sym]) _ = case sym of + "ProposeVersions" -> Just Debug + "ReplyVersions" -> Just Debug + "QueryReply" -> Just Debug + "AcceptVersion" -> Just Debug + "Refuse" -> Just Debug + _otherwise -> Nothing + severityFor _ _ = Nothing + + documentFor (Namespace _ sym) = wrap . mconcat $ case sym of + ["ProposeVersions"] -> + [ "Propose versions together with version parameters. It must be" + , " encoded to a sorted list.." + ] + ["ReplyVersions"] -> + [ "`MsgReplyVersions` received as a response to 'MsgProposeVersions'. It" + , " is not supported to explicitly send this message. It can only be" + , " received as a copy of 'MsgProposeVersions' in a simultaneous open" + , " scenario." + ] + ["QueryReply"] -> + [ "`MsgQueryReply` received as a response to a handshake query in " + , " 'MsgProposeVersions' and lists the supported versions." + ] + ["AcceptVersion"] -> + [ "The remote end decides which version to use and sends chosen version." + , "The server is allowed to modify version parameters." + ] + ["Refuse"] -> ["It refuses to run any version."] + _otherwise -> [] :: [Text] + where + wrap it = case it of + "" -> Nothing + it' -> Just it' + + allNamespaces = [ + Namespace [] ["ProposeVersions"] + , Namespace [] ["ReplyVersions"] + , Namespace [] ["QueryReply"] + , Namespace [] ["AcceptVersion"] + , Namespace [] ["Refuse"] + ] + + +-------------------------------------------------------------------------------- +-- DiffusionInit Tracer +-------------------------------------------------------------------------------- + +instance (Show ntnAddr, Show ntcAddr) => + LogFormatting (Diff.DiffusionTracer ntnAddr ntcAddr) where + forMachine _dtal (Diff.RunServer sockAddr) = mconcat + [ "kind" .= String "RunServer" + , "socketAddress" .= String (pack (show sockAddr)) + ] + + forMachine _dtal (Diff.RunLocalServer localAddress) = mconcat + [ "kind" .= String "RunLocalServer" + , "localAddress" .= String (pack (show localAddress)) + ] + forMachine _dtal (Diff.UsingSystemdSocket localAddress) = mconcat + [ "kind" .= String "UsingSystemdSocket" + , "path" .= String (pack . show $ localAddress) + ] + + forMachine _dtal (Diff.CreateSystemdSocketForSnocketPath localAddress) = mconcat + [ "kind" .= String "CreateSystemdSocketForSnocketPath" + , "path" .= String (pack . show $ localAddress) + ] + forMachine _dtal (Diff.CreatedLocalSocket localAddress) = mconcat + [ "kind" .= String "CreatedLocalSocket" + , "path" .= String (pack . show $ localAddress) + ] + forMachine _dtal (Diff.ConfiguringLocalSocket localAddress socket) = mconcat + [ "kind" .= String "ConfiguringLocalSocket" + , "path" .= String (pack . show $ localAddress) + , "socket" .= String (pack (show socket)) + ] + forMachine _dtal (Diff.ListeningLocalSocket localAddress socket) = mconcat + [ "kind" .= String "ListeningLocalSocket" + , "path" .= String (pack . show $ localAddress) + , "socket" .= String (pack (show socket)) + ] + forMachine _dtal (Diff.LocalSocketUp localAddress fd) = mconcat + [ "kind" .= String "LocalSocketUp" + , "path" .= String (pack . show $ localAddress) + , "socket" .= String (pack (show fd)) + ] + forMachine _dtal (Diff.CreatingServerSocket socket) = mconcat + [ "kind" .= String "CreatingServerSocket" + , "socket" .= String (pack (show socket)) + ] + forMachine _dtal (Diff.ListeningServerSocket socket) = mconcat + [ "kind" .= String "ListeningServerSocket" + , "socket" .= String (pack (show socket)) + ] + forMachine _dtal (Diff.ServerSocketUp socket) = mconcat + [ "kind" .= String "ServerSocketUp" + , "socket" .= String (pack (show socket)) + ] + forMachine _dtal (Diff.ConfiguringServerSocket socket) = mconcat + [ "kind" .= String "ConfiguringServerSocket" + , "socket" .= String (pack (show socket)) + ] + forMachine _dtal (Diff.UnsupportedLocalSystemdSocket path) = mconcat + [ "kind" .= String "UnsupportedLocalSystemdSocket" + , "path" .= String (pack (show path)) + ] + forMachine _dtal Diff.UnsupportedReadySocketCase = mconcat + [ "kind" .= String "UnsupportedReadySocketCase" + ] + forMachine _dtal (Diff.DiffusionErrored exception) = mconcat + [ "kind" .= String "DiffusionErrored" + , "error" .= String (pack (show exception)) + ] + forMachine _dtal (Diff.SystemdSocketConfiguration config) = mconcat + [ "kind" .= String "SystemdSocketConfiguration" + , "path" .= String (pack (show config)) + ] + +instance MetaTrace (Diff.DiffusionTracer ntnAddr ntcAddr) where + namespaceFor Diff.RunServer {} = + Namespace [] ["RunServer"] + namespaceFor Diff.RunLocalServer {} = + Namespace [] ["RunLocalServer"] + namespaceFor Diff.UsingSystemdSocket {} = + Namespace [] ["UsingSystemdSocket"] + namespaceFor Diff.CreateSystemdSocketForSnocketPath {} = + Namespace [] ["CreateSystemdSocketForSnocketPath"] + namespaceFor Diff.CreatedLocalSocket {} = + Namespace [] ["CreatedLocalSocket"] + namespaceFor Diff.ConfiguringLocalSocket {} = + Namespace [] ["ConfiguringLocalSocket"] + namespaceFor Diff.ListeningLocalSocket {} = + Namespace [] ["ListeningLocalSocket"] + namespaceFor Diff.LocalSocketUp {} = + Namespace [] ["LocalSocketUp"] + namespaceFor Diff.CreatingServerSocket {} = + Namespace [] ["CreatingServerSocket"] + namespaceFor Diff.ListeningServerSocket {} = + Namespace [] ["ListeningServerSocket"] + namespaceFor Diff.ServerSocketUp {} = + Namespace [] ["ServerSocketUp"] + namespaceFor Diff.ConfiguringServerSocket {} = + Namespace [] ["ConfiguringServerSocket"] + namespaceFor Diff.UnsupportedLocalSystemdSocket {} = + Namespace [] ["UnsupportedLocalSystemdSocket"] + namespaceFor Diff.UnsupportedReadySocketCase {} = + Namespace [] ["UnsupportedReadySocketCase"] + namespaceFor Diff.DiffusionErrored {} = + Namespace [] ["DiffusionErrored"] + namespaceFor Diff.SystemdSocketConfiguration {} = + Namespace [] ["SystemdSocketConfiguration"] + + severityFor (Namespace _ ["RunServer"]) _ = Just Info + severityFor (Namespace _ ["RunLocalServer"]) _ = Just Info + severityFor (Namespace _ ["UsingSystemdSocket"]) _ = Just Info + severityFor (Namespace _ ["CreateSystemdSocketForSnocketPath"]) _ = Just Info + severityFor (Namespace _ ["CreatedLocalSocket"]) _ = Just Info + severityFor (Namespace _ ["ConfiguringLocalSocket"]) _ = Just Info + severityFor (Namespace _ ["ListeningLocalSocket"]) _ = Just Info + severityFor (Namespace _ ["LocalSocketUp"]) _ = Just Info + severityFor (Namespace _ ["CreatingServerSocket"]) _ = Just Info + severityFor (Namespace _ ["ListeningServerSocket"]) _ = Just Info + severityFor (Namespace _ ["ServerSocketUp"]) _ = Just Info + severityFor (Namespace _ ["ConfiguringServerSocket"]) _ = Just Info + severityFor (Namespace _ ["UnsupportedLocalSystemdSocket"]) _ = Just Warning + severityFor (Namespace _ ["UnsupportedReadySocketCase"]) _ = Just Info + severityFor (Namespace _ ["DiffusionErrored"]) _ = Just Critical + severityFor (Namespace _ ["SystemdSocketConfiguration"]) _ = Just Warning + severityFor _ _ = Nothing + + documentFor (Namespace _ ["RunServer"]) = Just + "RunServer" + documentFor (Namespace _ ["RunLocalServer"]) = Just + "RunLocalServer" + documentFor (Namespace _ ["UsingSystemdSocket"]) = Just + "UsingSystemdSocket" + documentFor (Namespace _ ["CreateSystemdSocketForSnocketPath"]) = Just + "CreateSystemdSocketForSnocketPath" + documentFor (Namespace _ ["CreatedLocalSocket"]) = Just + "CreatedLocalSocket" + documentFor (Namespace _ ["ConfiguringLocalSocket"]) = Just + "ConfiguringLocalSocket" + documentFor (Namespace _ ["ListeningLocalSocket"]) = Just + "ListeningLocalSocket" + documentFor (Namespace _ ["LocalSocketUp"]) = Just + "LocalSocketUp" + documentFor (Namespace _ ["CreatingServerSocket"]) = Just + "CreatingServerSocket" + documentFor (Namespace _ ["ListeningServerSocket"]) = Just + "ListeningServerSocket" + documentFor (Namespace _ ["ServerSocketUp"]) = Just + "ServerSocketUp" + documentFor (Namespace _ ["ConfiguringServerSocket"]) = Just + "ConfiguringServerSocket" + documentFor (Namespace _ ["UnsupportedLocalSystemdSocket"]) = Just + "UnsupportedLocalSystemdSocket" + documentFor (Namespace _ ["UnsupportedReadySocketCase"]) = Just + "UnsupportedReadySocketCase" + documentFor (Namespace _ ["DiffusionErrored"]) = Just + "DiffusionErrored" + documentFor (Namespace _ ["SystemdSocketConfiguration"]) = Just + "SystemdSocketConfiguration" + documentFor _ = Nothing + + allNamespaces = [ + Namespace [] ["RunServer"] + , Namespace [] ["RunLocalServer"] + , Namespace [] ["UsingSystemdSocket"] + , Namespace [] ["CreateSystemdSocketForSnocketPath"] + , Namespace [] ["CreatedLocalSocket"] + , Namespace [] ["ConfiguringLocalSocket"] + , Namespace [] ["ListeningLocalSocket"] + , Namespace [] ["LocalSocketUp"] + , Namespace [] ["CreatingServerSocket"] + , Namespace [] ["ListeningServerSocket"] + , Namespace [] ["ServerSocketUp"] + , Namespace [] ["ConfiguringServerSocket"] + , Namespace [] ["UnsupportedLocalSystemdSocket"] + , Namespace [] ["UnsupportedReadySocketCase"] + , Namespace [] ["DiffusionErrored"] + , Namespace [] ["SystemdSocketConfiguration"] + ] + +-------------------------------------------------------------------------------- +-- LedgerPeers Tracer +-------------------------------------------------------------------------------- + +instance LogFormatting TraceLedgerPeers where + forMachine _dtal (PickedLedgerPeer addr _ackStake stake) = + mconcat + [ "kind" .= String "PickedLedgerPeer" + , "address" .= show addr + , "relativeStake" .= (realToFrac (unPoolStake stake) :: Double) + ] + forMachine _dtal (PickedLedgerPeers (NumberOfPeers n) addrs) = + mconcat + [ "kind" .= String "PickedLedgerPeers" + , "desiredCount" .= n + , "count" .= List.length addrs + , "addresses" .= show addrs + ] + forMachine _dtal (PickedBigLedgerPeer addr _ackStake stake) = + mconcat + [ "kind" .= String "PickedBigLedgerPeer" + , "address" .= show addr + , "relativeStake" .= (realToFrac (unPoolStake stake) :: Double) + ] + forMachine _dtal (PickedBigLedgerPeers (NumberOfPeers n) addrs) = + mconcat + [ "kind" .= String "PickedBigLedgerPeers" + , "desiredCount" .= n + , "count" .= List.length addrs + , "addresses" .= show addrs + ] + forMachine _dtal (FetchingNewLedgerState cnt bigCnt) = + mconcat + [ "kind" .= String "FetchingNewLedgerState" + , "numberOfLedgerPeers" .= cnt + , "numberOfBigLedgerPeers" .= bigCnt + ] + forMachine _dtal DisabledLedgerPeers = + mconcat + [ "kind" .= String "DisabledLedgerPeers" + ] + forMachine _dtal (TraceUseLedgerPeers ulp) = + mconcat + [ "kind" .= String "UseLedgerPeers" + , "useLedgerPeers" .= ulp + ] + forMachine _dtal WaitingOnRequest = + mconcat + [ "kind" .= String "WaitingOnRequest" + ] + forMachine _dtal (RequestForPeers (NumberOfPeers np)) = + mconcat + [ "kind" .= String "RequestForPeers" + , "numberOfPeers" .= np + ] + forMachine _dtal (ReusingLedgerState cnt age) = + mconcat + [ "kind" .= String "ReusingLedgerState" + , "numberOfPools" .= cnt + , "ledgerStateAge" .= age + ] + forMachine _dtal FallingBackToPublicRootPeers = + mconcat + [ "kind" .= String "FallingBackToPublicRootPeers" + ] + forMachine _dtal (NotEnoughLedgerPeers (NumberOfPeers target) numOfLedgerPeers) = + mconcat + [ "kind" .= String "NotEnoughLedgerPeers" + , "target" .= target + , "numOfLedgerPeers" .= numOfLedgerPeers + ] + forMachine _dtal (NotEnoughBigLedgerPeers (NumberOfPeers target) numOfBigLedgerPeers) = + mconcat + [ "kind" .= String "NotEnoughBigLedgerPeers" + , "target" .= target + , "numOfBigLedgerPeers" .= numOfBigLedgerPeers + ] + forMachine _dtal (TraceLedgerPeersDomains daps) = + mconcat + [ "kind" .= String "TraceLedgerPeersDomains" + , "domainAccessPoints" .= daps + ] + forMachine _dtal UsingBigLedgerPeerSnapshot = + mconcat + [ "kind" .= String "UsingBigLedgerPeerSnapshot" + ] + +instance MetaTrace TraceLedgerPeers where + namespaceFor PickedLedgerPeer {} = + Namespace [] ["PickedLedgerPeer"] + namespaceFor PickedLedgerPeers {} = + Namespace [] ["PickedLedgerPeers"] + namespaceFor PickedBigLedgerPeer {} = + Namespace [] ["PickedBigLedgerPeer"] + namespaceFor PickedBigLedgerPeers {} = + Namespace [] ["PickedBigLedgerPeers"] + namespaceFor FetchingNewLedgerState {} = + Namespace [] ["FetchingNewLedgerState"] + namespaceFor DisabledLedgerPeers {} = + Namespace [] ["DisabledLedgerPeers"] + namespaceFor TraceUseLedgerPeers {} = + Namespace [] ["TraceUseLedgerPeers"] + namespaceFor WaitingOnRequest {} = + Namespace [] ["WaitingOnRequest"] + namespaceFor RequestForPeers {} = + Namespace [] ["RequestForPeers"] + namespaceFor ReusingLedgerState {} = + Namespace [] ["ReusingLedgerState"] + namespaceFor FallingBackToPublicRootPeers {} = + Namespace [] ["FallingBackToPublicRootPeers"] + namespaceFor NotEnoughLedgerPeers {} = + Namespace [] ["NotEnoughLedgerPeers"] + namespaceFor NotEnoughBigLedgerPeers {} = + Namespace [] ["NotEnoughBigLedgerPeers"] + namespaceFor TraceLedgerPeersDomains {} = + Namespace [] ["TraceLedgerPeersDomains"] + namespaceFor UsingBigLedgerPeerSnapshot {} = + Namespace [] ["UsingBigLedgerPeerSnapshot"] + + severityFor (Namespace _ ["PickedLedgerPeer"]) _ = Just Debug + severityFor (Namespace _ ["PickedLedgerPeers"]) _ = Just Info + severityFor (Namespace _ ["PickedBigLedgerPeer"]) _ = Just Debug + severityFor (Namespace _ ["PickedBigLedgerPeers"]) _ = Just Info + severityFor (Namespace _ ["FetchingNewLedgerState"]) _ = Just Info + severityFor (Namespace _ ["DisabledLedgerPeers"]) _ = Just Info + severityFor (Namespace _ ["TraceUseLedgerAfter"]) _ = Just Info + severityFor (Namespace _ ["WaitingOnRequest"]) _ = Just Debug + severityFor (Namespace _ ["RequestForPeers"]) _ = Just Debug + severityFor (Namespace _ ["ReusingLedgerState"]) _ = Just Debug + severityFor (Namespace _ ["FallingBackToPublicRootPeers"]) _ = Just Info + severityFor (Namespace _ ["NotEnoughLedgerPeers"]) _ = Just Warning + severityFor (Namespace _ ["NotEnoughBigLedgerPeers"]) _ = Just Warning + severityFor (Namespace _ ["TraceLedgerPeersDomains"]) _ = Just Debug + severityFor (Namespace _ ["UsingBigLedgerPeerSnapshot"]) _ = Just Debug + severityFor _ _ = Nothing + + documentFor (Namespace _ ["PickedLedgerPeer"]) = Just + "Trace for a peer picked with accumulated and relative stake of its pool." + documentFor (Namespace _ ["PickedLedgerPeers"]) = Just + "Trace for the number of peers we wanted to pick and the list of peers picked." + documentFor (Namespace _ ["PickedBigLedgerPeer"]) = Just + "Trace for a big ledger peer picked with accumulated and relative stake of its pool." + documentFor (Namespace _ ["PickedBigLedgerPeers"]) = Just + "Trace for the number of big ledger peers we wanted to pick and the list of peers picked." + documentFor (Namespace _ ["FetchingNewLedgerState"]) = Just $ mconcat + [ "Trace for fetching a new list of peers from the ledger. Int is the number of peers" + , " returned." + ] + documentFor (Namespace _ ["DisabledLedgerPeers"]) = Just + "Trace for when getting peers from the ledger is disabled, that is DontUseLedger." + documentFor (Namespace _ ["TraceUseLedgerAfter"]) = Just + "Trace UseLedgerAfter value." + documentFor (Namespace _ ["WaitingOnRequest"]) = Just + "" + documentFor (Namespace _ ["RequestForPeers"]) = Just + "RequestForPeers (NumberOfPeers 1)" + documentFor (Namespace _ ["ReusingLedgerState"]) = Just + "" + documentFor (Namespace _ ["FallingBackToPublicRootPeers"]) = Just + "" + documentFor (Namespace _ ["TraceLedgerPeersDomains"]) = Just + "" + documentFor (Namespace _ ["UsingBigLedgerPeerSnapshot"]) = Just $ mconcat + [ "Trace for when a request for big ledger peers is fulfilled from the snapshot file" + , " specified in the topology file."] + documentFor _ = Nothing + + allNamespaces = [ + Namespace [] ["PickedLedgerPeer"] + , Namespace [] ["PickedLedgerPeers"] + , Namespace [] ["PickedBigLedgerPeer"] + , Namespace [] ["PickedBigLedgerPeers"] + , Namespace [] ["FetchingNewLedgerState"] + , Namespace [] ["DisabledLedgerPeers"] + , Namespace [] ["TraceUseLedgerAfter"] + , Namespace [] ["WaitingOnRequest"] + , Namespace [] ["RequestForPeers"] + , Namespace [] ["ReusingLedgerState"] + , Namespace [] ["FallingBackToPublicRootPeers"] + , Namespace [] ["NotEnoughLedgerPeers"] + , Namespace [] ["NotEnoughBigLedgerPeers"] + , Namespace [] ["TraceLedgerPeersDomains"] + , Namespace [] ["UsingBigLedgerPeerSnapshot"] + ] From 957ae2aa9072070791d75bf6ca8565aacfe80369 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Mon, 13 Apr 2026 12:30:23 +0200 Subject: [PATCH 04/11] Patching CI warnings --- .../schema-gen/ApplySchemaOverrides.hs | 12 +- .../schema-gen/CheckOverrideCoverage.hs | 4 +- .../scripts/schema-gen/GhciSchemaGen.hs | 266 +++++++++--------- .../scripts/schema-gen/ValidateTraceLog.hs | 14 +- .../schema-gen/ValidateTraceSchemas.hs | 2 +- bench/trace-schemas/trace-documentation.md | 2 +- cabal.project | 4 - .../src/Cardano/Logging/DocuGenerator.hs | 4 +- 8 files changed, 153 insertions(+), 155 deletions(-) diff --git a/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs b/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs index 3067875627d..6db1317dff4 100644 --- a/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs +++ b/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs @@ -10,6 +10,7 @@ import qualified Data.Aeson.KeyMap as KM import qualified Data.ByteString.Lazy as BL import Control.Monad (forM, unless, when) import Data.List (isSuffixOf, sort) +import Data.Maybe (fromMaybe) import System.Directory ( createDirectoryIfMissing , doesDirectoryExist @@ -63,7 +64,7 @@ main = do exitSuccess parseArgs :: Config -> [String] -> IO Config -parseArgs config args = go config args +parseArgs = go where go cfg [] = pure cfg go cfg ("--root" : root : rest) = go cfg {cfgRoot = root} rest @@ -179,7 +180,7 @@ findDestructiveOps target patch = goObj "" targetObj patchObj (Just _, _) -> [keyPath <> ": field replacement"] mergePatch :: A.Value -> A.Value -> A.Value -mergePatch _ patch@(A.Null) = patch +mergePatch _ A.Null = A.Null mergePatch _ patch@(A.Bool _) = patch mergePatch _ patch@(A.String _) = patch mergePatch _ patch@(A.Number _) = patch @@ -192,16 +193,13 @@ mergePatch target (A.Object patchObj) = in A.Object (mergeObject targetObj patchObj) mergeObject :: A.Object -> A.Object -> A.Object -mergeObject target patch = KM.foldrWithKey step target patch +mergeObject = KM.foldrWithKey step where step key value acc = case value of A.Null -> KM.delete key acc A.Object _ -> - let existing = - case KM.lookup key acc of - Just v -> v - Nothing -> A.Null + let existing = fromMaybe A.Null (KM.lookup key acc) merged = mergePatch existing value in KM.insert key merged acc _ -> KM.insert key value acc diff --git a/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs b/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs index c8ab9608b6d..cd962545822 100644 --- a/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs +++ b/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs @@ -18,7 +18,7 @@ generatedRoots = overridesRoot :: FilePath overridesRoot = "bench/trace-schemas/overrides" -data Config = Config +newtype Config = Config { cfgRange :: Maybe String } @@ -50,7 +50,7 @@ main = do exitSuccess parseArgs :: Config -> [String] -> IO Config -parseArgs config args = go config args +parseArgs = go where go cfg [] = pure cfg go cfg ("--range" : r : rest) = go cfg {cfgRange = Just r} rest diff --git a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs index 073a1f1dd79..d3108c9d39b 100644 --- a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs +++ b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs @@ -13,7 +13,8 @@ import qualified Data.Aeson.Key as K import qualified Data.Vector as V import Data.Char (isAlphaNum, isLower, isUpper, isSpace, toLower) import Data.List (elemIndex, isPrefixOf, isSuffixOf, sortOn) -import Data.Maybe (catMaybes, listToMaybe, mapMaybe) +import Data.Maybe (catMaybes, fromMaybe, listToMaybe, mapMaybe) +import Data.Ord (Down (..)) import System.Directory import System.Environment (getArgs) import System.FilePath @@ -21,9 +22,8 @@ import System.Process import System.Exit import System.IO import Data.IORef -import Control.Exception (catch, IOException) +import Control.Exception (catch, IOException, bracket) import System.IO.Unsafe (unsafePerformIO) -import Control.Exception (bracket) import qualified Data.Aeson as A import qualified Data.Aeson.Encode.Pretty as AP import qualified Data.ByteString.Lazy as BL @@ -85,7 +85,7 @@ inboundGovernorUnexpectedlyFalseAssertionCtor = "__InboundGovernorUnexpectedlyFa detailLevels :: [DetailLevel] detailLevels = ["Minimal", "Normal", "Detailed", "Maximum"] -data Config = Config +newtype Config = Config { cfgPruneStaleProperties :: Bool } @@ -109,7 +109,7 @@ main = do -- Build constructor -> namespace map from namespaceFor clauses putStrLn "Building namespace map..." let sources = map (\fp -> (fp, readFileSafe fp)) hsFiles - let nsMap = foldl' mergeNs Map.empty [ normalizeNamespaceMap fp (parseNamespaceMap src) | (fp, src) <- sources ] + let nsMap = foldlStrict mergeNs Map.empty [ normalizeNamespaceMap fp (parseNamespaceMap src) | (fp, src) <- sources ] -- Parse forMachine clauses and map their field bindings to variables putStrLn "Parsing forMachine clauses..." let helperFieldMaps = map (parseObjectHelperMap . snd) sources @@ -119,7 +119,7 @@ main = do ] let fieldVarMap = - foldl' + foldlStrict (Map.unionWith (Map.unionWith Map.union)) Map.empty [ normalizeFieldVarMap fp (parseFieldVarMap helpers clauses) @@ -133,7 +133,7 @@ main = do "[ghci " <> show idx <> "/" <> show (length clausesByFile) <> "] " <> fp normalizeVarTypesMap fp <$> ghciTypesForFile fp clauses - let varTypes = foldl' (Map.unionWith Map.union) Map.empty varTypesMaps + let varTypes = foldlStrict (Map.unionWith Map.union) Map.empty varTypesMaps let msgOutDir = "bench/trace-schemas/messages" let typeOutDir = "bench/trace-schemas/types" @@ -183,8 +183,8 @@ printHelp = -- Utilities -foldl' :: (b -> a -> b) -> b -> [a] -> b -foldl' f z xs = go z xs where go acc [] = acc; go acc (y:ys) = let acc' = f acc y in acc' `seq` go acc' ys +foldlStrict :: (b -> a -> b) -> b -> [a] -> b +foldlStrict f = go where go acc [] = acc; go acc (y:ys) = let acc' = f acc y in acc' `seq` go acc' ys validateSourceDirs :: (String -> IO ()) -> [FilePath] -> IO [FilePath] validateSourceDirs emitWarning dirs = do @@ -205,8 +205,8 @@ readFileSafe fp = unsafePerformIO (readFile fp `catch` (\(_e :: IOException) -> collectTargets :: [FilePath] -> IO [FilePath] collectTargets roots = do - files <- fmap concat $ mapM listHsFiles roots - fmap catMaybes $ mapM (\fp -> do + files <- concat <$> mapM listHsFiles roots + catMaybes <$> mapM (\fp -> do content <- T.readFile fp if "forMachine" `T.isInfixOf` content || "namespaceFor" `T.isInfixOf` content then pure (Just fp) @@ -219,7 +219,7 @@ listHsFiles root = do where go dir = do entries <- listDirectory dir - fmap concat $ mapM (\e -> do + concat <$> mapM (\e -> do let p = dir e isDir <- doesDirectoryExist p if isDir then go p else pure [p | ".hs" `isSuffixOf` p]) entries @@ -253,16 +253,17 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty clauseLines = headerLines ++ bodyLines header = unwords headerLines bodyAfterLambda = dropLeadingLambdaCase bodyLines - acc' = - if "\\case" `isInfix` header || isLambdaCaseBody bodyLines - then foldl' insertNamespaceClause acc (parseNamespaceLambdaClauses bodyAfterLambda) - else if hasBranchArrows bodyLines - then case ctorsAfter "namespaceFor" (takeWhile (/= '=') (unwords headerLines)) of + acc' + | "\\case" `isInfix` header || isLambdaCaseBody bodyLines = + foldlStrict insertNamespaceClause acc (parseNamespaceLambdaClauses bodyAfterLambda) + | hasBranchArrows bodyLines = + case ctorsAfter "namespaceFor" (takeWhile (/= '=') (unwords headerLines)) of [] -> acc - ctors -> foldl' insertNamespaceClause acc (parseNamespaceCaseBranches ctors bodyLines) - else case extractNamespaceClause currentType typeConstructors (unwords clauseLines) of - Just clauseInfo -> insertNamespaceClause acc clauseInfo - Nothing -> acc + ctors -> foldlStrict insertNamespaceClause acc (parseNamespaceCaseBranches ctors bodyLines) + | otherwise = + case extractNamespaceClause currentType typeConstructors (unwords clauseLines) of + Just clauseInfo -> insertNamespaceClause acc clauseInfo + Nothing -> acc in go currentType rest acc' | otherwise = go currentType ls acc @@ -275,7 +276,7 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty spanNamespaceBody allLines@(x:xs) | startsTopLevelMethod x = ([], allLines) | otherwise = - let (body, rest) = span (not . startsTopLevelMethod) xs + let (body, rest) = break startsTopLevelMethod xs in (x : body, rest) startsTopLevelMethod line = @@ -293,7 +294,7 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty startsTopLevelDecl line = let t = trim line in not (null line) - && not (isSpace (head line)) + && not (startsIndented line) && not ("--" `isPrefixOf` t) && any (`isPrefixOf` t) [ "instance" @@ -328,7 +329,7 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty let inferredCtors = case ctors of [] | isWildcardNamespaceLhs lhs -> - maybe [] (\ty -> singletonConstructors ty ctorMap) currentType + maybe [] (`singletonConstructors` ctorMap) currentType [] | isListEmptyNamespaceLhs lhs -> [listEmptyCtor] _ -> ctors @@ -340,7 +341,7 @@ parseMetaTraceInstanceType hdr = do (_, rest) <- breakSub "MetaTrace" hdr let tyExpr = trim . takeWhile (/= '=') . fst $ breakOn "where" (stripOuterParens (trim rest)) guard (not (null tyExpr)) - guard (head tyExpr /= '[') + guard (headMay tyExpr /= Just '[') firstCtorToken tyExpr isWildcardNamespaceLhs :: String -> Bool @@ -380,7 +381,7 @@ parseTypeConstructors src = go (lines src) Map.empty startsTypeDecl line = let t = trim line in not (null line) - && not (isSpace (head line)) + && not (startsIndented line) && (("data " `isPrefixOf` t) || ("newtype " `isPrefixOf` t)) spanTypeDecl [] = ([], []) @@ -397,7 +398,7 @@ parseTypeConstructors src = go (lines src) Map.empty startsNextTopLevel line = let t = trim line in not (null line) - && not (isSpace (head line)) + && not (startsIndented line) && not ("--" `isPrefixOf` t) parseTypeDecl decl = do @@ -418,19 +419,20 @@ parseTypeConstructors src = go (lines src) Map.empty pure (tyName, nubPreserve ctors) splitTopLevelBars :: String -> [String] -splitTopLevelBars s = go 0 0 0 "" [] s +splitTopLevelBars = go (0 :: Int) (0 :: Int) (0 :: Int) "" [] where + go :: Int -> Int -> Int -> String -> [String] -> String -> [String] go _ _ _ cur acc [] = reverse (trim cur : acc) - go paren bracket brace cur acc (c:cs) - | c == '(' = go (paren + 1) bracket brace (cur ++ [c]) acc cs - | c == ')' = go (paren - 1) bracket brace (cur ++ [c]) acc cs - | c == '[' = go paren (bracket + 1) brace (cur ++ [c]) acc cs - | c == ']' = go paren (bracket - 1) brace (cur ++ [c]) acc cs - | c == '{' = go paren bracket (brace + 1) (cur ++ [c]) acc cs - | c == '}' = go paren bracket (brace - 1) (cur ++ [c]) acc cs - | c == '|' && paren == 0 && bracket == 0 && brace == 0 = - go paren bracket brace "" (trim cur : acc) cs - | otherwise = go paren bracket brace (cur ++ [c]) acc cs + go paren bracketDepth brace cur acc (c:cs) + | c == '(' = go (paren + 1) bracketDepth brace (cur ++ [c]) acc cs + | c == ')' = go (paren - 1) bracketDepth brace (cur ++ [c]) acc cs + | c == '[' = go paren (bracketDepth + 1) brace (cur ++ [c]) acc cs + | c == ']' = go paren (bracketDepth - 1) brace (cur ++ [c]) acc cs + | c == '{' = go paren bracketDepth (brace + 1) (cur ++ [c]) acc cs + | c == '}' = go paren bracketDepth (brace - 1) (cur ++ [c]) acc cs + | c == '|' && paren == 0 && bracketDepth == 0 && brace == 0 = + go paren bracketDepth brace "" (trim cur : acc) cs + | otherwise = go paren bracketDepth brace (cur ++ [c]) acc cs extractNamespaceParts :: String -> Maybe NamespaceParts extractNamespaceParts clause = @@ -454,7 +456,7 @@ insertNamespaceClause :: Map.Map ConstructorName [NamespaceParts] -> ([ConstructorName], NamespaceParts) -> Map.Map ConstructorName [NamespaceParts] insertNamespaceClause acc (ctors, parts) = - foldl' (\m ctor -> Map.insertWith (++) ctor [parts] m) acc ctors + foldlStrict (\m ctor -> Map.insertWith (++) ctor [parts] m) acc ctors isLambdaCaseBody :: [String] -> Bool isLambdaCaseBody (l:_) = "\\case" `isInfix` trim l @@ -489,7 +491,7 @@ parseNamespaceLambdaClauses = mapMaybe parseBranch . go | isBranchStart x = (reverse acc, allLines) | otherwise = step (x:acc) xs - isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + isBranchStart l = "->" `isInfix` l && startsIndented l parseBranch (pat, body) = do let parts = quotedStrings body @@ -517,19 +519,13 @@ parseNamespaceCaseBranches ctors = mapMaybe parseBranch . go | isBranchStart x = (reverse acc, allLines) | otherwise = step (x:acc) xs - isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + isBranchStart l = "->" `isInfix` l && startsIndented l parseBranch body = do let parts = quotedStrings body if null parts then Nothing else Just (ctors, parts) -firstCtorAfter :: String -> String -> Maybe String -firstCtorAfter marker line = - case ctorsAfter marker line of - (x:_) -> Just x - [] -> Nothing - ctorsAfter :: String -> String -> [String] ctorsAfter marker line = case T.splitOn (T.pack marker) (T.pack line) of @@ -556,7 +552,6 @@ quotedStrings (_:xs) = quotedStrings xs data Clause = Clause { clauseLevel :: String - , clauseType :: Maybe TypeName , clauseCtor :: Maybe ConstructorName , clausePattern :: String , clauseBody :: [String] @@ -602,11 +597,11 @@ parseObjectHelperMap src = isTopLevelDecl l = not (null l) - && not (isSpace (head l)) + && not (startsIndented l) && not ("--" `isPrefixOf` trim l) parseHelperFields body = - foldl' (Map.unionWith preferSpecific) Map.empty (mapMaybe parseBranch (helperBranches body)) + foldlStrict (Map.unionWith preferSpecific) Map.empty (mapMaybe parseBranch (helperBranches body)) helperBranches [] = [] helperBranches (l:ls) @@ -616,7 +611,7 @@ parseObjectHelperMap src = Nothing -> ("", "") (more, rest) = spanBranchLines ls body = [rhs0 | not (null rhs0)] ++ more - in Clause "" Nothing Nothing pat0 body : helperBranches rest + in Clause "" Nothing pat0 body : helperBranches rest | otherwise = helperBranches ls spanBranchLines = go [] @@ -627,7 +622,7 @@ parseObjectHelperMap src = | isTopLevelDecl x = (reverse acc, allLines) | otherwise = go (x:acc) xs - isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + isBranchStart l = "->" `isInfix` l && startsIndented l parseBranch cl = let vars = Set.fromList (extractVars (clausePattern cl)) @@ -659,9 +654,8 @@ parseForMachineClauses src = go Nothing (lines src) let (headerLines, afterHeader) = spanUntilHeaderEnd [l] ls header = unwords headerLines (lvlTok, pat) = parseHeader header - (body, rest) = span (not . startsHeader) afterHeader + (body, rest) = break startsHeader afterHeader bodyAfterLambda = dropLeadingLambdaCase body - mkClause pat' body' = Clause lvlTok currentType (inferClauseCtor typeConstructors currentType pat') pat' body' in if "\\case" `isInfix` header || isLambdaCaseBody body then parseLambdaCaseClauses lvlTok currentType typeConstructors bodyAfterLambda ++ go currentType rest else expandNestedCaseClauses lvlTok currentType typeConstructors pat body ++ go currentType rest @@ -679,7 +673,7 @@ parseForMachineClauses src = go Nothing (lines src) startsTopLevelDeclForMachine line = let t = trim line in not (null line) - && not (isSpace (head line)) + && not (startsIndented line) && not ("--" `isPrefixOf` t) && any (`isPrefixOf` t) [ "instance" @@ -710,18 +704,18 @@ parseLambdaCaseClauses lvl currentType typeConstructors = go | isBranchStart x = (reverse acc, allLines) | otherwise = step (x:acc) xs - isBranchStart l = "->" `isInfix` l && not (null l) && isSpace (head l) + isBranchStart l = "->" `isInfix` l && startsIndented l expandNestedCaseClauses :: String -> Maybe TypeName -> Map.Map TypeName [ConstructorName] -> String -> [String] -> [Clause] expandNestedCaseClauses lvl currentType typeConstructors pat body = case splitCaseOnBoundVar (Set.fromList (extractVars pat)) body of Just (prefix, branchLines) -> - Clause lvl currentType (inferClauseCtor typeConstructors currentType pat) pat body + Clause lvl (inferClauseCtor typeConstructors currentType pat) pat body : concatMap descend (parseLambdaCaseClauses lvl currentType typeConstructors branchLines) where descend cl = expandNestedCaseClauses lvl currentType typeConstructors (clausePattern cl) (prefix ++ clauseBody cl) Nothing -> - [Clause lvl currentType (inferClauseCtor typeConstructors currentType pat) pat body] + [Clause lvl (inferClauseCtor typeConstructors currentType pat) pat body] splitCaseOnBoundVar :: Set.Set String -> [String] -> Maybe ([String], [String]) splitCaseOnBoundVar boundVars = go [] @@ -761,7 +755,7 @@ parseHeader line = in (lvl, pat) spanInstanceHeader :: String -> [String] -> ([String], [String], Maybe TypeName) -spanInstanceHeader className [] = ([], [], Nothing) +spanInstanceHeader _className [] = ([], [], Nothing) spanInstanceHeader className (x:xs) = finish [x] xs where finish acc [] = @@ -778,19 +772,20 @@ parseInstanceTypeForClass className hdr = do (_, rest) <- breakSub className hdr let tyExpr = trim . takeWhile (/= '=') . fst $ breakOn "where" (stripOuterParens (trim rest)) guard (not (null tyExpr)) - guard (head tyExpr /= '[') + guard (headMay tyExpr /= Just '[') firstCtorToken tyExpr stripOuterParens :: String -> String stripOuterParens s | headMay s == Just '(' , lastMay s == Just ')' - , parensWrapWhole s = trim (init (tail s)) + , parensWrapWhole s = trim (dropOuterDelims s) | otherwise = s parensWrapWhole :: String -> Bool -parensWrapWhole = go 0 +parensWrapWhole = go (0 :: Int) where + go :: Int -> String -> Bool go _ [] = True go depth (c:cs) | c == '(' = go (depth + 1) cs @@ -827,9 +822,6 @@ ctorFromPattern :: String -> Maybe String ctorFromPattern pat = case normalizedCtorTokens pat of [] -> Nothing xs -> Just (selectCtorToken xs) - where - isCtorToken (c:_) = isUpper c - isCtorToken _ = False normalizeCtorToken :: String -> String normalizeCtorToken tok = @@ -881,7 +873,7 @@ isVariableOnlyPattern pat = -- Map JSON field keys to the pattern variable they come from. parseFieldVarMap :: HelperFieldMap -> [Clause] -> Map.Map ConstructorName (Map.Map DetailLevel (Map.Map String String)) -parseFieldVarMap helperMap clauses = foldl' step Map.empty clauses +parseFieldVarMap helperMap = foldlStrict step Map.empty where step acc cl = case clauseCtor cl of @@ -898,8 +890,8 @@ parseFieldVarMap helperMap clauses = foldl' step Map.empty clauses directPairs = mapMaybe (parseFieldLine vars) (collectFieldEntries sanitizedBody) helperPairs = concatMap helperPairsForLine sanitizedBody pairs = Map.toList (Map.fromListWith preferSpecific (directPairs ++ helperPairs)) - addOne m (k,v) = foldl' (\mm lvl -> Map.insertWith (Map.union) lvl (Map.singleton k v) mm) m lvls - in Map.insertWith (Map.unionWith Map.union) ctor (foldl' addOne Map.empty pairs) acc + addOne m (k,v) = foldlStrict (\mm lvl -> Map.insertWith Map.union lvl (Map.singleton k v) mm) m lvls + in Map.insertWith (Map.unionWith Map.union) ctor (foldlStrict addOne Map.empty pairs) acc helperPairsForLine line = concatMap helperPairsForName (tokenize line) @@ -913,7 +905,7 @@ parseFieldVarMap helperMap clauses = foldl' step Map.empty clauses | otherwise = old collectFieldEntries :: [String] -> [String] -collectFieldEntries = finalize . foldl' step [] +collectFieldEntries = finalize . foldlStrict step [] where step :: [String] -> String -> [String] step [] line @@ -931,7 +923,7 @@ collectFieldEntries = finalize . foldl' step [] filter (".=" `isInfix`) . map trim . splitTopLevelCommasGeneral . stripOuterList . trim stripOuterList s - | headMay s == Just '[' && lastMay s == Just ']' = init (tail s) + | headMay s == Just '[' && lastMay s == Just ']' = dropOuterDelims s | otherwise = case outerBracketSpan s of Just (i, j) @@ -944,8 +936,9 @@ collectFieldEntries = finalize . foldl' step [] outerBracketSpan s = case elemIndex '[' s of Nothing -> Nothing - Just start -> matchBracket start 0 start + Just start -> matchBracket start (0 :: Int) start where + matchBracket :: Int -> Int -> Int -> Maybe (Int, Int) matchBracket _ _ i | i >= length s = Nothing matchBracket start depth i = case s !! i of @@ -963,21 +956,22 @@ fieldEntryNeedsContinuation :: String -> Bool fieldEntryNeedsContinuation = hasOpenBalance . trim where hasOpenBalance s = - case go 0 0 0 s of - (paren, bracket, brace) -> paren > 0 || bracket > 0 || brace > 0 - - go paren bracket brace [] = (paren, bracket, brace) - go paren bracket brace (c:cs) - | c == '(' = go (paren + 1) bracket brace cs - | c == ')' = go (paren - 1) bracket brace cs - | c == '[' = go paren (bracket + 1) brace cs - | c == ']' = go paren (bracket - 1) brace cs - | c == '{' = go paren bracket (brace + 1) cs - | c == '}' = go paren bracket (brace - 1) cs - | otherwise = go paren bracket brace cs + case go (0 :: Int) (0 :: Int) (0 :: Int) s of + (paren, bracketDepth, brace) -> paren > 0 || bracketDepth > 0 || brace > 0 + + go :: Int -> Int -> Int -> String -> (Int, Int, Int) + go paren bracketDepth brace [] = (paren, bracketDepth, brace) + go paren bracketDepth brace (c:cs) + | c == '(' = go (paren + 1) bracketDepth brace cs + | c == ')' = go (paren - 1) bracketDepth brace cs + | c == '[' = go paren (bracketDepth + 1) brace cs + | c == ']' = go paren (bracketDepth - 1) brace cs + | c == '{' = go paren bracketDepth (brace + 1) cs + | c == '}' = go paren bracketDepth (brace - 1) cs + | otherwise = go paren bracketDepth brace cs stripCommentBlocks :: [String] -> [String] -stripCommentBlocks = snd . foldl' step (0 :: Int, []) +stripCommentBlocks = snd . foldlStrict step (0 :: Int, []) where step (depth, acc) line = let (depth', cleaned) = stripLine depth line @@ -996,19 +990,20 @@ stripCommentBlocks = snd . foldl' step (0 :: Int, []) in (depth', c : rest) splitTopLevelCommasGeneral :: String -> [String] -splitTopLevelCommasGeneral s = go 0 0 0 "" [] s +splitTopLevelCommasGeneral = go (0 :: Int) (0 :: Int) (0 :: Int) "" [] where + go :: Int -> Int -> Int -> String -> [String] -> String -> [String] go _ _ _ cur acc [] = reverse (trim cur : acc) - go paren bracket brace cur acc (c:cs) - | c == '(' = go (paren + 1) bracket brace (cur ++ [c]) acc cs - | c == ')' = go (paren - 1) bracket brace (cur ++ [c]) acc cs - | c == '[' = go paren (bracket + 1) brace (cur ++ [c]) acc cs - | c == ']' = go paren (bracket - 1) brace (cur ++ [c]) acc cs - | c == '{' = go paren bracket (brace + 1) (cur ++ [c]) acc cs - | c == '}' = go paren bracket (brace - 1) (cur ++ [c]) acc cs - | c == ',' && paren == 0 && bracket == 0 && brace == 0 = - go paren bracket brace "" (trim cur : acc) cs - | otherwise = go paren bracket brace (cur ++ [c]) acc cs + go paren bracketDepth brace cur acc (c:cs) + | c == '(' = go (paren + 1) bracketDepth brace (cur ++ [c]) acc cs + | c == ')' = go (paren - 1) bracketDepth brace (cur ++ [c]) acc cs + | c == '[' = go paren (bracketDepth + 1) brace (cur ++ [c]) acc cs + | c == ']' = go paren (bracketDepth - 1) brace (cur ++ [c]) acc cs + | c == '{' = go paren bracketDepth (brace + 1) (cur ++ [c]) acc cs + | c == '}' = go paren bracketDepth (brace - 1) (cur ++ [c]) acc cs + | c == ',' && paren == 0 && bracketDepth == 0 && brace == 0 = + go paren bracketDepth brace "" (trim cur : acc) cs + | otherwise = go paren bracketDepth brace (cur ++ [c]) acc cs parseFieldLine :: Set.Set String -> String -> Maybe (String, String) parseFieldLine vars line = do @@ -1171,7 +1166,7 @@ ghciTypesForFile fp clauses = do out <- runGhci moduleName imports (map (fst . snd) queries) let outputs = splitOutputs out (length queries) let pairs = zip queries outputs - pure $ foldl' mergeVarTypes Map.empty (map parseQueryResult pairs) + pure $ foldlStrict mergeVarTypes Map.empty (map parseQueryResult pairs) where mergeVarTypes = Map.unionWith Map.union @@ -1183,7 +1178,7 @@ extractImports src = , "import " `isPrefixOf` l' ] where - stripComment l = takeWhile (/= '-') l + stripComment = takeWhile (/= '-') extractModuleName :: String -> Maybe String extractModuleName src = @@ -1200,7 +1195,7 @@ buildQuery cl = do ctor <- clauseCtor cl let vars = filter isRelevantVar (extractVars (clausePattern cl)) if null vars then Nothing else do - let body = if length vars == 1 then head vars else "(" ++ commaSep vars ++ ")" + let body = singletonOrTuple vars let expr = "(\\(" ++ clausePattern cl ++ ") -> " ++ body ++ ")" let cmd = ":t " ++ expr Just (ctor, (cmd, vars)) @@ -1224,17 +1219,21 @@ runGhci moduleName imports cmds = [":set -XGADTs -XTypeFamilies -XDataKinds -XTypeOperators -XRankNTypes -XScopedTypeVariables"] ++ maybe [] (\m -> [":module + *" ++ m]) moduleName ++ imports - ++ concat [ [cmd, ":! echo " ++ marker i] | (i, cmd) <- zip [0..] cmds ] + ++ concat [ [cmd, ":! echo " ++ marker i] | (i, cmd) <- zip [(0 :: Int)..] cmds ] ++ [":quit"] - (code, out, err) <- readCreateProcessWithExitCode (proc (head ghciCmd) (tail ghciCmd)) (unlines cmdLines) + let (ghciProg, ghciArgs) = + case ghciCmd of + prog:args -> (prog, args) + [] -> ("cabal", []) + (code, out, err) <- readCreateProcessWithExitCode (proc ghciProg ghciArgs) (unlines cmdLines) let combined = out ++ err case code of ExitSuccess -> pure combined _ -> pure combined withFilteredGhciProjectFile :: (FilePath -> IO a) -> IO a -withFilteredGhciProjectFile action = - bracket create remove action +withFilteredGhciProjectFile = + bracket create remove where create = do let fp = ".ghci-schema.cabal.project.tmp" @@ -1320,12 +1319,13 @@ parseSigTypes line = parseTupleTypes :: String -> [String] parseTupleTypes s | headMay s == Just '(' && lastMay s == Just ')' && ',' `elem` s = - splitTopLevelCommas (init (tail s)) + splitTopLevelCommas (dropOuterDelims s) | otherwise = [s] splitTopLevelCommas :: String -> [String] -splitTopLevelCommas s = go 0 "" [] s +splitTopLevelCommas = go (0 :: Int) "" [] where + go :: Int -> String -> [String] -> String -> [String] go _ cur acc [] = reverse (trim cur : acc) go depth cur acc (c:cs) | c == '(' = go (depth + 1) (cur ++ [c]) acc cs @@ -1338,7 +1338,7 @@ parseBindings :: String -> Maybe (Map.Map String String) parseBindings out = let constraints = parseConstraints out bindings = mapMaybe parseBindingLine (lines out) - applyConstraints ty = foldl' (\t (v, rep) -> replaceToken v rep t) ty constraints + applyConstraints ty = foldlStrict (\t (v, rep) -> replaceToken v rep t) ty constraints fixed = [ (name, applyConstraints ty) | (name, ty) <- bindings ] in if null fixed then Nothing else Just (Map.fromList fixed) @@ -1370,9 +1370,28 @@ headMay :: [a] -> Maybe a headMay [] = Nothing headMay (x:_) = Just x +singleElement :: [a] -> Maybe a +singleElement [x] = Just x +singleElement _ = Nothing + +startsIndented :: String -> Bool +startsIndented = maybe False isSpace . headMay + +dropOuterDelims :: String -> String +dropOuterDelims [] = [] +dropOuterDelims [_] = [] +dropOuterDelims (_:xs) = + case reverse xs of + [] -> [] + (_:restRev) -> reverse restRev + +singletonOrTuple :: [String] -> String +singletonOrTuple [v] = v +singletonOrTuple vars = "(" ++ commaSep vars ++ ")" + lastMay :: [a] -> Maybe a lastMay [] = Nothing -lastMay xs = Just (last xs) +lastMay xs = headMay (reverse xs) splitOn :: String -> String -> [String] splitOn needle hay = map T.unpack (T.splitOn (T.pack needle) (T.pack hay)) @@ -1397,17 +1416,6 @@ isInfix needle hay = T.isInfixOf (T.pack needle) (T.pack hay) type FieldVarMap = Map.Map ConstructorName (Map.Map DetailLevel (Map.Map String String)) --- Update a single namespace schema on disk. -updateSchemaForNamespace :: Config - -> FilePath - -> FilePath - -> Map.Map ConstructorName [NamespaceParts] - -> FieldVarMap - -> VarTypes - -> String - -> IO () -updateSchemaForNamespace = updateSchemaForNamespaceWithWarning (\_ -> pure ()) - updateSchemaForNamespaceWithWarning :: (String -> IO ()) -> Config -> FilePath @@ -1422,10 +1430,7 @@ updateSchemaForNamespaceWithWarning emitWarning config msgOutDir typeOutDir nsMa let ctor = case fallbackCtorForNamespace parts of Just c -> Just c - Nothing -> - case findCtor nsMap parts of - Just c -> Just c - Nothing -> Nothing + Nothing -> findCtor nsMap parts let out = msgOutDir foldr () (last parts ++ ".schema.json") (init parts) let histOutDir = "bench/trace-schemas/messages-hist" let histOut = histOutDir foldr () (last parts ++ ".schema.json") (init parts) @@ -1547,7 +1552,7 @@ splitUnexpectedlyFalseAssertion m = -- Merge "data" from messages-hist when we couldn't infer any properties. mergeHistDataIfEmpty :: FilePath -> A.Value -> IO A.Value mergeHistDataIfEmpty histOut v@(A.Object o) = do - hasProps <- pure (hasDataProps o) + let hasProps = hasDataProps o if hasProps then pure v else do @@ -1645,10 +1650,7 @@ updateData config typeOutDir ctor fieldVarMap varTypes lvl o = then KM.filterWithKey (\k _ -> KM.member k inferredProps) props else props updatedProps <- KM.traverseWithKey (updateProp typeOutDir ctor fieldVarMap varTypes lvl) propsToUpdate - let mergedProps = - if cfgPruneStaleProperties config - then KM.union updatedProps inferredProps - else KM.union updatedProps inferredProps + let mergedProps = KM.union updatedProps inferredProps let d' = KM.insert (K.fromString "properties") (A.Object mergedProps) d let d'' = setRequiredFields ctor fieldVarMap varTypes lvl d' pure (KM.insert (K.fromString "data") (A.Object d'') o) @@ -1777,7 +1779,7 @@ findCtor nsMap parts = [] -> Nothing where rankedMatches = - reverse . sortOn fst $ + sortOn (Down . fst) $ [ (scoreMatch ctor nsParts, ctor) | (ctor, nss) <- Map.toList nsMap , nsParts <- nss @@ -1855,7 +1857,7 @@ isList :: String -> Bool isList s = headMay s == Just '[' && lastMay s == Just ']' listElem :: String -> String -listElem s = trim (init (tail s)) +listElem s = trim (dropOuterDelims s) isMaybe :: String -> Bool isMaybe s = "Maybe " `isPrefixOf` trim s @@ -1872,7 +1874,7 @@ baseTypeName s = _ -> s' _ -> s' tokens = filter (not . null) (tokenize s'') - in case filter (\t -> case t of (c:_) -> isUpper c; _ -> False) tokens of + in case filter (\case (c:_) -> isUpper c; _ -> False) tokens of (x:_) -> x [] -> s'' @@ -1941,7 +1943,7 @@ mergedPropsForType -> IO A.Object mergedPropsForType fieldVarMap varTypes seen ctor byLevel = do let fieldVars = - foldl' (Map.unionWith (++)) Map.empty + foldlStrict (Map.unionWith (++)) Map.empty [ Map.map (:[]) lvlMap | lvlMap <- Map.elems byLevel ] @@ -2012,10 +2014,10 @@ mergeSchemas [] = A.object [] mergeSchemas [x] = x mergeSchemas xs = let unique = dedupeValues xs - in if length unique == 1 then head unique else A.object ["anyOf" A..= unique] + in fromMaybe (A.object ["anyOf" A..= unique]) (singleElement unique) dedupeValues :: [A.Value] -> [A.Value] -dedupeValues = reverse . foldl' step [] +dedupeValues = reverse . foldlStrict step [] where step acc v = let key = BL8.unpack (A.encode v) diff --git a/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs b/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs index 7539ea1109b..f1c8e358474 100644 --- a/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs +++ b/bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs @@ -10,7 +10,9 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Char8 as BS8 import qualified Data.ByteString.Lazy as BL import qualified Data.Map.Strict as Map -import Data.List (foldl', isSuffixOf, sortOn) +import qualified Data.List as List +import Data.List (isSuffixOf, sortOn) +import Data.Maybe (fromMaybe, listToMaybe) import qualified Data.Text as T import Data.Word (Word8) import System.Directory @@ -108,7 +110,7 @@ main = do else exitFailure parseArgs :: Config -> [String] -> IO Config -parseArgs config args = go config args +parseArgs = go where go cfg [] = if null (cfgLogFile cfg) @@ -179,7 +181,7 @@ loadNamespaceSchemas root = do putStrLn $ " " <> ns <> " -> " <> commaList paths exitFailure - pure (Map.map head grouped) + pure (Map.mapMaybe listToMaybe grouped) extractLogEntries :: FilePath -> FilePath -> IO ExtractedLog extractLogEntries logPath tempDir = do @@ -239,7 +241,7 @@ partitionKnown :: [LogEntry] -> (Map.Map FilePath [LogEntry], [LogEntry]) partitionKnown namespaceSchemas = - foldl' step (Map.empty, []) + List.foldl' step (Map.empty, []) where step (known, unknown) entry = case leNamespace entry >>= (`Map.lookup` namespaceSchemas) of @@ -251,7 +253,7 @@ validateKnownNamespaces :: Map.Map FilePath [LogEntry] -> IO Bool validateKnownNamespaces groups = do results <- forM (sortOn fst (Map.toList groups)) $ \(schemaPath, groupEntries) -> do - let namespaceLabel = maybe (takeBaseName schemaPath) id (leNamespace =<< safeHead groupEntries) + let namespaceLabel = fromMaybe (takeBaseName schemaPath) (leNamespace =<< safeHead groupEntries) let header = "Validating namespace " <> namespaceLabel @@ -342,7 +344,7 @@ isIgnorableWhitespace c = c == 32 || c == 9 || c == 13 withTempDir :: String -> (FilePath -> IO a) -> IO a withTempDir prefix action = do - tmp <- fmap trimTrailingNewline $ readProcess "mktemp" ["-d", "/tmp/" <> prefix <> ".XXXXXX"] "" + tmp <- trimTrailingNewline <$> readProcess "mktemp" ["-d", "/tmp/" <> prefix <> ".XXXXXX"] "" createDirectoryIfMissing True tmp bracket (pure tmp) removePathForcibly action diff --git a/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs b/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs index 3ebfa7bbf3a..f594193204e 100644 --- a/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs +++ b/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs @@ -54,7 +54,7 @@ main = do exitSuccess parseArgs :: Config -> [String] -> IO Config -parseArgs config args = go config args +parseArgs = go where go cfg [] = pure cfg go cfg ("--meta-schema" : path : rest) = go cfg {cfgMetaSchema = path} rest diff --git a/bench/trace-schemas/trace-documentation.md b/bench/trace-schemas/trace-documentation.md index 19f538498c8..7f605b040b5 100644 --- a/bench/trace-schemas/trace-documentation.md +++ b/bench/trace-schemas/trace-documentation.md @@ -14093,4 +14093,4 @@ LedgerMetrics ⓜ- This is the root of a tracer, that provides metrics -Generated at 2026-04-13 11:05:00.121894722 CEST, git commit hash f28b2ab394330fc5ac35893f1337230d1262b712, node version 10.7.1 +Generated at 2026-04-13 12:16:53.097436005 CEST, git commit hash f28b2ab394330fc5ac35893f1337230d1262b712, node version 10.7.1 diff --git a/cabal.project b/cabal.project index 68fb8db7676..1634685ec26 100644 --- a/cabal.project +++ b/cabal.project @@ -76,10 +76,6 @@ package bitvec package plutus-scripts-bench haddock-options: "--optghc=-fplugin-opt PlutusTx.Plugin:defer-errors" --- standalone scripts; not held to the project-wide -Werror standard -package trace-schema-gen - ghc-options: -Wwarn - allow-newer: , katip:Win32 diff --git a/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs b/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs index 997f2626d4d..e7d6f1b49c1 100644 --- a/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs +++ b/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs @@ -39,7 +39,7 @@ import qualified Control.Tracer as TR import Data.Aeson (ToJSON) import qualified Data.Aeson.Encode.Pretty as AE import Data.IORef (modifyIORef, newIORef, readIORef) -import Data.List (find, groupBy, intersperse, isPrefixOf, nub, sort, sortBy) +import Data.List (find, group, groupBy, intersperse, isPrefixOf, nub, sort, sortBy) import qualified Data.Map.Strict as Map import Data.Maybe (fromJust, fromMaybe, mapMaybe) import Data.Text (split) @@ -607,4 +607,4 @@ docuResultsToNamespaces DocTracer{dtBuilderList} = | (ns, doc) <- dtBuilderList , DocuResult.isTracer doc || DocuResult.isDatapoint doc ] - uniqueSorted = map head $ groupBy (==) $ sort namespaces + uniqueSorted = map head $ group $ sort namespaces From 93fa1f589383f5345d4b5f17d4addeb4b526b7de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Wed, 22 Apr 2026 12:18:02 +0200 Subject: [PATCH 05/11] Review changes 1 Remove unnecessary artefacts --- .codex | 0 bench/trace-schemas/trace-documentation.md | 14096 ---------------- .../trace-schemas-presentation.odp | Bin 46829 -> 0 bytes .../trace-schemas-presentation.pptx | Bin 35056 -> 0 bytes .../trace-schemas-speaker-notes.md | 46 - cabal.project | 8 +- .../Cardano/Node/Tracing/Tracers/Diffusion.hs | 993 -- .../src/Cardano/Logging/DocuGenerator.hs | 610 - 8 files changed, 1 insertion(+), 15752 deletions(-) delete mode 100644 .codex delete mode 100644 bench/trace-schemas/trace-documentation.md delete mode 100644 bench/trace-schemas/trace-schemas-presentation.odp delete mode 100644 bench/trace-schemas/trace-schemas-presentation.pptx delete mode 100644 bench/trace-schemas/trace-schemas-speaker-notes.md delete mode 100644 cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs delete mode 100644 trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs diff --git a/.codex b/.codex deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/bench/trace-schemas/trace-documentation.md b/bench/trace-schemas/trace-documentation.md deleted file mode 100644 index 7f605b040b5..00000000000 --- a/bench/trace-schemas/trace-documentation.md +++ /dev/null @@ -1,14096 +0,0 @@ -# Cardano Trace Documentation - -## Table Of Contents - -### [Trace Messages](#trace-messages) - -1. [BlockFetchⓜ](#blockfetchclientacknowledgedfetchrequest) - 1. [Clientⓣⓢ](#blockfetchclientacknowledgedfetchrequest) - 1. [Decisionⓣⓜ](#blockfetchdecisionaccept) - 1. [Remoteⓣⓢ](#blockfetchremotereceivebatchdone) - 1. [Serialisedⓣⓢ](#blockfetchremoteserialisedreceivebatchdone) - 1. [Serverⓣⓜ](#blockfetchserversendblock) -1. [BlockchainTimeⓣ](#blockchaintimecurrentslotunknown) -1. [ChainDBⓣⓜ](#chaindbaddblockeventaddblockvalidationinvalidblock) - 1. [ReplayBlockⓣⓜ](#chaindbreplayblockledgerreplay) -1. [ChainSyncⓜ](#chainsyncclientaccessingforecasthorizon) - 1. [Clientⓣ](#chainsyncclientaccessingforecasthorizon) - 1. [Localⓣⓢ](#chainsynclocalreceiveawaitreply) - 1. [Remoteⓣⓢ](#chainsyncremotereceiveawaitreply) - 1. [Serialisedⓣⓢ](#chainsyncremoteserialisedreceiveawaitreply) - 1. [ServerBlockⓣⓢⓜ](#chainsyncserverblockupdate) - 1. [ServerHeaderⓣⓢⓜ](#chainsyncserverheaderupdate) -1. [Consensusⓜ](#consensuscsjbecomingobjector) - 1. [CSJⓣⓢ](#consensuscsjbecomingobjector) - 1. [DevotedBlockFetchⓣⓢ](#consensusdevotedblockfetchrotateddynamo) - 1. [GDDⓣⓢ](#consensusgddtracegddevent) - 1. [GSMⓣⓜ](#consensusgsmentercaughtup) - 1. [SanityCheckⓣ](#consensussanitychecksanitycheckissue) - 1. [Startupⓣ](#consensusstartupconsensusstartupexception) -1. [Forgeⓣⓜ](#forgeloopadoptedblock) - 1. [Loopⓣⓜ](#forgeloopadoptedblock) - 1. [ThreadStatsⓣⓢⓜ](#forgethreadstatsforgingstats) -1. [Mempoolⓣⓢⓜ](#mempooladdedtx) -1. [Netⓣⓢ](#netacceptpolicyconnectionhardlimit) - 1. [AcceptPolicyⓣ](#netacceptpolicyconnectionhardlimit) - 1. [ConnectionManagerⓜ](#netconnectionmanagerlocalconnect) - 1. [Localⓣⓜ](#netconnectionmanagerlocalconnect) - 1. [Remoteⓣⓜ](#netconnectionmanagerremoteconnect) - 1. [Transitionⓣⓢ](#netconnectionmanagertransitiontransition) - 1. [InboundGovernorⓜ](#netinboundgovernorlocaldemotedtocoldremote) - 1. [Localⓣⓜ](#netinboundgovernorlocaldemotedtocoldremote) - 1. [Remoteⓣⓜ](#netinboundgovernorremotedemotedtocoldremote) - 1. [Transitionⓣ](#netinboundgovernortransitiontransition) - 1. [Muxⓜ](#netmuxlocalcleanexit) - 1. [Localⓣⓜ](#netmuxlocalcleanexit) - 1. [Remoteⓣⓜ](#netmuxremotecleanexit) - 1. [PeerSelectionⓜ](#netpeerselectionactionsconnectionerror) - 1. [Actionsⓣ](#netpeerselectionactionsconnectionerror) - 1. [Countersⓣⓢⓜ](#netpeerselectioncounterscounters) - 1. [Initiatorⓣⓢ](#netpeerselectioninitiatorgovernorstate) - 1. [Responderⓣⓢ](#netpeerselectionrespondergovernorstate) - 1. [Selectionⓣⓜ](#netpeerselectionselectionbigledgerpeersfailure) - 1. [Peersⓜ](#netpeersledgerdisabledledgerpeers) - 1. [Ledgerⓣ](#netpeersledgerdisabledledgerpeers) - 1. [LocalRootⓣ](#netpeerslocalrootlocalrootdnsmap) - 1. [PublicRootⓣ](#netpeerspublicrootpublicrootdomains) - 1. [Serverⓜ](#netserverlocalacceptconnection) - 1. [Localⓣ](#netserverlocalacceptconnection) - 1. [Remoteⓣ](#netserverremoteacceptconnection) -1. [NodeStateⓣ](#nodestatenodeaddblock) -1. [RPCⓣⓜ](#rpcerror) -1. [Reflectionⓣⓜ](#reflectionmetricsinfo) -1. [Shutdownⓣ](#shutdownabnormal) -1. [Startupⓣⓜ](#startupblockforgingblocktypemismatch) - 1. [DiffusionInitⓣ](#startupdiffusioninitconfiguringlocalsocket) -1. [StateQueryServerⓣ](#statequeryserverreceiveacquire) -1. [TxSubmissionⓜ](#txsubmissionlocalreceiveaccepttx) - 1. [Localⓣⓢ](#txsubmissionlocalreceiveaccepttx) - 1. [LocalServerⓣⓢ](#txsubmissionlocalserverreceivedtx) - 1. [MonitorClientⓣⓢ](#txsubmissionmonitorclientreceiveacquire) - 1. [Remoteⓣⓢ](#txsubmissionremotereceivedone) - 1. [TxInboundⓣⓜ](#txsubmissiontxinboundaddedtomempool) - 1. [TxOutboundⓣⓢ](#txsubmissiontxoutboundcontrolmessage) -1. [Versionⓣⓢⓜ](#versionnodeversion) - -### [Metrics](#metrics) - -1. [Forge](#forgeabout-to-lead) - 1. [about-to-lead](#forgeabout-to-lead) - 1. [adopted](#forgeadopted) - 1. [adoption-thread-died](#forgeadoption-thread-died) - 1. [block-from-future](#forgeblock-from-future) - 1. [could-not-forge](#forgecould-not-forge) - 1. [didnt-adopt](#forgedidnt-adopt) - 1. [forged](#forgeforged) - 1. [forged-invalid](#forgeforged-invalid) - 1. [node-is-leader](#forgenode-is-leader) - 1. [node-not-leader](#forgenode-not-leader) - 1. [slot-is-immutable](#forgeslot-is-immutable) -1. [GSM](#gsmstate) - 1. [state](#gsmstate) -1. [Mem](#memresident) - 1. [resident](#memresident) -1. [RTS](#rtsalloc) - 1. [alloc](#rtsalloc) - 1. [gcHeapBytes](#rtsgcheapbytes) - 1. [gcLiveBytes](#rtsgclivebytes) - 1. [gcMajorNum](#rtsgcmajornum) - 1. [gcMinorNum](#rtsgcminornum) - 1. [gcticks](#rtsgcticks) - 1. [mutticks](#rtsmutticks) - 1. [threads](#rtsthreads) -1. [Stat](#statcputicks) - 1. [cputicks](#statcputicks) - 1. [fsRd](#statfsrd) - 1. [fsWr](#statfswr) - 1. [netRd](#statnetrd) - 1. [netWr](#statnetwr) -1. [SuppressedMessages](#suppressedmessages) - 1. [](#suppressedmessages) - 1. [](#suppressedmessages) -1. [blockNum](#blocknum) -1. [blockReplayProgress](#blockreplayprogress) -1. [blockfetchclient](#blockfetchclientblockdelay) - 1. [blockdelay](#blockfetchclientblockdelay) - 1. [cdfFive](#blockfetchclientblockdelaycdffive) - 1. [cdfOne](#blockfetchclientblockdelaycdfone) - 1. [cdfThree](#blockfetchclientblockdelaycdfthree) - 1. [blocksize](#blockfetchclientblocksize) - 1. [lateblocks](#blockfetchclientlateblocks) -1. [blocksForged](#blocksforged) -1. [cardano_build_info](#cardano_build_info) -1. [cardano_version_major](#cardano_version_major) -1. [cardano_version_minor](#cardano_version_minor) -1. [cardano_version_patch](#cardano_version_patch) -1. [connectedPeers](#connectedpeers) -1. [connectionManager](#connectionmanagerduplexconns) - 1. [duplexConns](#connectionmanagerduplexconns) - 1. [fullDuplexConns](#connectionmanagerfullduplexconns) - 1. [inboundConns](#connectionmanagerinboundconns) - 1. [outboundConns](#connectionmanageroutboundconns) - 1. [prunableConns](#connectionmanagerprunableconns) - 1. [unidirectionalConns](#connectionmanagerunidirectionalconns) -1. [currentKESPeriod](#currentkesperiod) -1. [delegMapSize](#delegmapsize) -1. [density](#density) -1. [epoch](#epoch) -1. [forgedSlotLast](#forgedslotlast) -1. [forging_enabled](#forging_enabled) -1. [forks](#forks) -1. [haskell_compiler_major](#haskell_compiler_major) -1. [haskell_compiler_minor](#haskell_compiler_minor) -1. [haskell_compiler_patch](#haskell_compiler_patch) -1. [inboundGovernor](#inboundgovernorcold) - 1. [Cold](#inboundgovernorcold) - 1. [Hot](#inboundgovernorhot) - 1. [Idle](#inboundgovernoridle) - 1. [Warm](#inboundgovernorwarm) -1. [localInboundGovernor](#localinboundgovernorcold) - 1. [cold](#localinboundgovernorcold) - 1. [hot](#localinboundgovernorhot) - 1. [idle](#localinboundgovernoridle) - 1. [warm](#localinboundgovernorwarm) -1. [mempoolBytes](#mempoolbytes) -1. [node](#nodestarttime) - 1. [start](#nodestarttime) - 1. [time](#nodestarttime) -1. [nodeCannotForge](#nodecannotforge) -1. [nodeIsLeader](#nodeisleader) -1. [operationalCertificateExpiryKESPeriod](#operationalcertificateexpirykesperiod) -1. [operationalCertificateStartKESPeriod](#operationalcertificatestartkesperiod) -1. [peerSelection](#peerselectionactivebigledgerpeers) - 1. [ActiveBigLedgerPeers](#peerselectionactivebigledgerpeers) - 1. [ActiveBigLedgerPeersDemotions](#peerselectionactivebigledgerpeersdemotions) - 1. [ActiveBootstrapPeers](#peerselectionactivebootstrappeers) - 1. [ActiveBootstrapPeersDemotions](#peerselectionactivebootstrappeersdemotions) - 1. [ActiveLocalRootPeers](#peerselectionactivelocalrootpeers) - 1. [ActiveLocalRootPeersDemotions](#peerselectionactivelocalrootpeersdemotions) - 1. [ActiveNonRootPeers](#peerselectionactivenonrootpeers) - 1. [ActiveNonRootPeersDemotions](#peerselectionactivenonrootpeersdemotions) - 1. [ActivePeers](#peerselectionactivepeers) - 1. [ActivePeersDemotions](#peerselectionactivepeersdemotions) - 1. [Cold](#peerselectioncold) - 1. [ColdBigLedgerPeers](#peerselectioncoldbigledgerpeers) - 1. [ColdBigLedgerPeersPromotions](#peerselectioncoldbigledgerpeerspromotions) - 1. [ColdBootstrapPeersPromotions](#peerselectioncoldbootstrappeerspromotions) - 1. [ColdNonRootPeersPromotions](#peerselectioncoldnonrootpeerspromotions) - 1. [ColdPeersPromotions](#peerselectioncoldpeerspromotions) - 1. [EstablishedBigLedgerPeers](#peerselectionestablishedbigledgerpeers) - 1. [EstablishedBootstrapPeers](#peerselectionestablishedbootstrappeers) - 1. [EstablishedLocalRootPeers](#peerselectionestablishedlocalrootpeers) - 1. [EstablishedNonRootPeers](#peerselectionestablishednonrootpeers) - 1. [EstablishedPeers](#peerselectionestablishedpeers) - 1. [Hot](#peerselectionhot) - 1. [HotBigLedgerPeers](#peerselectionhotbigledgerpeers) - 1. [KnownBigLedgerPeers](#peerselectionknownbigledgerpeers) - 1. [KnownBootstrapPeers](#peerselectionknownbootstrappeers) - 1. [KnownLocalRootPeers](#peerselectionknownlocalrootpeers) - 1. [KnownNonRootPeers](#peerselectionknownnonrootpeers) - 1. [KnownPeers](#peerselectionknownpeers) - 1. [LocalRoots](#peerselectionlocalroots) - 1. [RootPeers](#peerselectionrootpeers) - 1. [Warm](#peerselectionwarm) - 1. [WarmBigLedgerPeers](#peerselectionwarmbigledgerpeers) - 1. [WarmBigLedgerPeersDemotions](#peerselectionwarmbigledgerpeersdemotions) - 1. [WarmBigLedgerPeersPromotions](#peerselectionwarmbigledgerpeerspromotions) - 1. [WarmBootstrapPeersDemotions](#peerselectionwarmbootstrappeersdemotions) - 1. [WarmBootstrapPeersPromotions](#peerselectionwarmbootstrappeerspromotions) - 1. [WarmLocalRootPeersPromotions](#peerselectionwarmlocalrootpeerspromotions) - 1. [WarmNonRootPeersDemotions](#peerselectionwarmnonrootpeersdemotions) - 1. [WarmNonRootPeersPromotions](#peerselectionwarmnonrootpeerspromotions) - 1. [WarmPeersDemotions](#peerselectionwarmpeersdemotions) - 1. [WarmPeersPromotions](#peerselectionwarmpeerspromotions) - 1. [churn](#peerselectionchurndecreasedactivebigledgerpeersduration) - 1. [DecreasedActiveBigLedgerPeers](#peerselectionchurndecreasedactivebigledgerpeersduration) - 1. [duration](#peerselectionchurndecreasedactivebigledgerpeersduration) - 1. [DecreasedActivePeers](#peerselectionchurndecreasedactivepeersduration) - 1. [duration](#peerselectionchurndecreasedactivepeersduration) - 1. [DecreasedEstablishedBigLedgerPeers](#peerselectionchurndecreasedestablishedbigledgerpeersduration) - 1. [duration](#peerselectionchurndecreasedestablishedbigledgerpeersduration) - 1. [DecreasedEstablishedPeers](#peerselectionchurndecreasedestablishedpeersduration) - 1. [duration](#peerselectionchurndecreasedestablishedpeersduration) - 1. [DecreasedKnownBigLedgerPeers](#peerselectionchurndecreasedknownbigledgerpeersduration) - 1. [duration](#peerselectionchurndecreasedknownbigledgerpeersduration) - 1. [DecreasedKnownPeers](#peerselectionchurndecreasedknownpeersduration) - 1. [duration](#peerselectionchurndecreasedknownpeersduration) -1. [remainingKESPeriods](#remainingkesperiods) -1. [rpc](#rpcrequestqueryservicereadparams) - 1. [request](#rpcrequestqueryservicereadparams) - 1. [QueryService](#rpcrequestqueryservicereadparams) - 1. [ReadParams](#rpcrequestqueryservicereadparams) - 1. [ReadUtxos](#rpcrequestqueryservicereadutxos) - 1. [SubmitService](#rpcrequestsubmitservicesubmittx) - 1. [SubmitTx](#rpcrequestsubmitservicesubmittx) -1. [served](#servedblock) - 1. [block](#servedblock) - 1. [latest](#servedblocklatest) - 1. [header](#servedheader) -1. [slotInEpoch](#slotinepoch) -1. [slotNum](#slotnum) -1. [slotsMissed](#slotsmissed) -1. [submissions](#submissionsaccepted) - 1. [accepted](#submissionsaccepted) - 1. [rejected](#submissionsrejected) - 1. [submitted](#submissionssubmitted) -1. [systemStartTime](#systemstarttime) -1. [tipBlock](#tipblock) -1. [txsInMempool](#txsinmempool) -1. [txsMempoolTimeoutHard](#txsmempooltimeouthard) -1. [txsMempoolTimeoutSoft](#txsmempooltimeoutsoft) -1. [txsProcessedNum](#txsprocessednum) -1. [txsSyncDuration](#txssyncduration) -1. [utxoSize](#utxosize) - -### [Datapoints](#datapoints) - -1. [NodeInfo](#nodeinfo) -1. [NodeStartupInfo](#nodestartupinfo) - -### [Configuration](#configuration) - - - -## Trace Messages - -### BlockFetch.Client.AcknowledgedFetchRequest - - -> Mark the point when the fetch client picks up the request added by the block fetch decision thread. Note that this event can happen fewer times than the 'AddedFetchRequest' due to fetch request merging. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Client.AddedFetchRequest - - -> The block fetch decision thread has added a new fetch instruction consisting of one or more individual request ranges. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Client.ClientMetrics - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Client.ClientTerminating - - -> The client is terminating. Log the number of outstanding requests. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### BlockFetch.Client.CompletedBlockFetch - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` -Limiter `BlockFetch.Client.CompletedBlockFetch` with frequency `2.0` - -### BlockFetch.Client.CompletedFetchBatch - - -> Mark the successful end of receiving a streaming batch of blocks. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Client.RejectedFetchBatch - - -> If the other peer rejects our request then we have this event instead of 'StartedFetchBatch' and 'CompletedFetchBatch'. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Client.SendFetchRequest - - -> Mark the point when fetch request for a fragment is actually sent over the wire. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Client.StartedFetchBatch - - -> Mark the start of receiving a streaming batch of blocks. This will be followed by one or more 'CompletedBlockFetch' and a final 'CompletedFetchBatch' - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Decision.Accept - - -> Throughout the decision making process we accumulate reasons to decline to fetch any blocks. This message carries the intermediate and final results. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### BlockFetch.Decision.Decline - - -> Throughout the decision making process we accumulate reasons to decline to fetch any blocks. This message carries the intermediate and final results. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### BlockFetch.Decision.EmptyPeersFetch - - -> Throughout the decision making process we accumulate reasons to decline to fetch any blocks. This message carries the intermediate and final results. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### BlockFetch.Remote.Receive.BatchDone - - -> End of block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Receive.Block - - -> Stream a single block. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Receive.ClientDone - - -> Client termination message. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Receive.NoBlocks - - -> Respond that there are no blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Receive.RequestRange - - -> Request range of blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Receive.StartBatch - - -> Start block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Send.BatchDone - - -> End of block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Send.Block - - -> Stream a single block. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Send.ClientDone - - -> Client termination message. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Send.NoBlocks - - -> Respond that there are no blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Send.RequestRange - - -> Request range of blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Send.StartBatch - - -> Start block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Receive.BatchDone - - -> End of block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Receive.Block - - -> Stream a single block. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Receive.ClientDone - - -> Client termination message. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Receive.NoBlocks - - -> Respond that there are no blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Receive.RequestRange - - -> Request range of blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Receive.StartBatch - - -> Start block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Send.BatchDone - - -> End of block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Send.Block - - -> Stream a single block. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Send.ClientDone - - -> Client termination message. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Send.NoBlocks - - -> Respond that there are no blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Send.RequestRange - - -> Request range of blocks. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Remote.Serialised.Send.StartBatch - - -> Start block streaming. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockFetch.Server.SendBlock - - -> The server sent a block to the peer. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### BlockchainTime.CurrentSlotUnknown - - -> Current slot is not yet known -> This happens when the tip of our current chain is so far in the past that we cannot translate the current wallclock to a slot number, typically during syncing. Until the current slot number is known, we cannot produce blocks. Seeing this message during syncing therefore is normal and to be expected. -> We record the current time (the time we tried to translate to a 'SlotNo') as well as the 'PastHorizonException', which provides detail on the bounds between which we /can/ do conversions. The distance between the current time and the upper bound should rapidly decrease with consecutive 'CurrentSlotUnknown' messages during syncing. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### BlockchainTime.StartTimeInTheFuture - - -> The start time of the blockchain time is in the future -> We have to block (for 'NominalDiffTime') until that time comes. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### BlockchainTime.SystemClockMovedBack - - -> The system clock moved back an acceptable time span, e.g., because of an NTP sync. -> The system clock moved back such that the new current slot would be smaller than the previous one. If this is within the configured limit, we trace this warning but *do not change the current slot*. The current slot never decreases, but the current slot may stay the same longer than expected. -> When the system clock moved back more than the configured limit, we shut down with a fatal exception. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### ChainDB.AddBlockEvent.AddBlockValidation.InvalidBlock - - -> An event traced during validating performed while adding a block. A point was found to be invalid. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.AddBlockEvent.AddBlockValidation.UpdateLedgerDb - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate - - -> An event traced during validating performed while adding a block. A candidate chain was valid. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` -Limiter `ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate` with frequency `2.0` - -### ChainDB.AddBlockEvent.AddedBlockToQueue - - -> The block was added to the queue and will be added to the ChainDB by the background thread. The size of the queue is included.. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` -Limiter `ChainDB.AddBlockEvent.AddedBlockToQueue` with frequency `2.0` - -### ChainDB.AddBlockEvent.AddedBlockToVolatileDB - - -> A block was added to the Volatile DB - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` -Limiter `ChainDB.AddBlockEvent.AddedBlockToVolatileDB` with frequency `2.0` - -### ChainDB.AddBlockEvent.AddedReprocessLoEBlocksToQueue - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.AddedToCurrentChain - - -> The new block fits onto the current chain (first fragment) and we have successfully used it to extend our (new) current chain (second fragment). - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddBlockEvent.ChainSelectionLoEDebug - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.ChangingSelection - - -> The new block fits onto the current chain (first fragment) and we have successfully used it to extend our (new) current chain (second fragment). - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.IgnoreBlockAlreadyInVolatileDB - - -> A block that is already in the Volatile DB was ignored. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddBlockEvent.IgnoreBlockOlderThanK - - -> A block with a 'BlockNo' more than @k@ back than the current tip was ignored. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddBlockEvent.IgnoreInvalidBlock - - -> A block that is invalid was ignored. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddBlockEvent.PipeliningEvent.OutdatedTentativeHeader - - -> We selected a new (better) chain, which cleared the previous tentative header. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.PipeliningEvent.SetTentativeHeader - - -> A new tentative header got set - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.PipeliningEvent.TrapTentativeHeader - - -> The body of tentative block turned out to be invalid. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.PoppedBlockFromQueue - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.PoppedReprocessLoEBlocksFromQueue - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.PoppingFromQueue - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.StoreButDontChange - - -> The block fits onto some fork, we'll try to switch to that fork (if it is preferable to our chain). - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.SwitchedToAFork - - -> The new block fits onto some fork and we have switched to that fork (second fragment), as it is preferable to our (previous) current chain (first fragment). - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddBlockEvent.TryAddToCurrentChain - - -> The block fits onto the current chain, we'll try to use it to extend our chain. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddBlockEvent.TrySwitchToAFork - - -> The block fits onto some fork, we'll try to switch to that fork (if it is preferable to our chain) - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.AddedPerasCertToQueue - - -> Peras certificate added to processing queue - - -Severity: `Debug` -Privacy: `Public` -Details: `DDetailed` - - -From current configuration: -Details: `DNormal` -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.ChainSelectionForBoostedBlock - - -> Perform chain selection for block boosted by Peras certificate - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.IgnorePerasCertTooOld - - -> Peras certificate ignored as it is too old compared to immutable slot - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.PerasCertBoostsBlockNotYetReceived - - -> Peras certificate boosts a block not yet received - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.PerasCertBoostsCurrentChain - - -> Peras certificate boosts a block on the current selection - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.PerasCertBoostsGenesis - - -> Peras certificate boosts the Genesis point - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.AddPerasCertEvent.PoppedPerasCertFromQueue - - -> Peras certificate popped from processing queue - - -Severity: `Debug` -Privacy: `Public` -Details: `DDetailed` - - -From current configuration: -Details: `DNormal` -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ChainSelStarvationEvent - - -> ChainSel is waiting for a next block to process, but there is no block in the queue. Despite the name, it is a pretty normal (and frequent) event. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB - - -> A block was successfully copied to the ImmDB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` -Limiter `ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB` with frequency `2.0` - -### ChainDB.CopyToImmutableDBEvent.NoBlocksToCopyToImmutableDB - - -> There are no block to copy to the ImmDB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.FollowerEvent.FollowerNewImmIterator - - -> The follower is in the 'FollowerInImmutableDB' state but the iterator is exhausted while the ImmDB has grown, so we open a new iterator to stream these blocks too. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.FollowerEvent.FollowerNoLongerInMem - - -> The follower was in 'FollowerInMem' state and is switched to the 'FollowerInImmutableDB' state. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.FollowerEvent.FollowerSwitchToMem - - -> The follower was in the 'FollowerInImmutableDB' state and is switched to the 'FollowerInMem' state. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.FollowerEvent.NewFollower - - -> A new follower was created. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.GCEvent.PerformedGC - - -> A garbage collection for the given 'SlotNo' was performed. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.GCEvent.ScheduledGC - - -> A garbage collection for the given 'SlotNo' was scheduled to happen at the given time. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.CacheEvent.CurrentChunkHit - - -> Current chunk found in the cache. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.CacheEvent.PastChunkEvict - - -> The least recently used past chunk was evicted because the cache was full. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.CacheEvent.PastChunkExpired - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.CacheEvent.PastChunkHit - - -> Past chunk found in the cache - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.CacheEvent.PastChunkMiss - - -> Past chunk was not found in the cache - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkFileDoesntFit - - -> The hash of the last block in the previous epoch doesn't match the previous hash of the first block in the current epoch - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.InvalidChunkFile - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.InvalidPrimaryIndex - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.InvalidSecondaryIndex - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.MissingChunkFile - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.MissingPrimaryIndex - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.MissingSecondaryIndex - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.RewritePrimaryIndex - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.RewriteSecondaryIndex - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.StartedValidatingChunk - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ChunkValidation.ValidatedChunk - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.DBAlreadyClosed - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.DBClosed - - -> Closing the immutable DB - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.DeletingAfter - - -> Delete after - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.Migrating - - -> Performing a migration of the on-disk files. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.ImmDbEvent.NoValidLastLocation - - -> No valid last location was found - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ImmDbEvent.ValidatedLastLocation - - -> The last location was validatet - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.InitChainSelEvent.InitialChainSelected - - -> A garbage collection for the given 'SlotNo' was performed. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.InitChainSelEvent.StartedInitChainSelection - - -> A garbage collection for the given 'SlotNo' was scheduled to happen at the given time. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.InitChainSelEvent.Validation.InvalidBlock - - -> An event traced during validating performed while adding a block. A point was found to be invalid. - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.InitChainSelEvent.Validation.UpdateLedgerDb - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.InitChainSelEvent.Validation.ValidCandidate - - -> An event traced during validating performed while adding a block. A candidate chain was valid. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.IteratorEvent.BlockGCedFromVolatileDB - - -> A block is no longer in the VolatileDB and isn't in the ImmDB either; it wasn't part of the current chain. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.BlockMissingFromVolatileDB - - -> A block is no longer in the VolatileDB because it has been garbage collected. It might now be in the ImmDB if it was part of the current chain. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.BlockWasCopiedToImmutableDB - - -> A block that has been garbage collected from the VolatileDB is now found and streamed from the ImmDB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.StreamFromBoth - - -> Stream from both the VolatileDB and the ImmDB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.StreamFromImmutableDB - - -> Stream only from the ImmDB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.StreamFromVolatileDB - - -> Stream only from the VolatileDB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.SwitchBackToVolatileDB - - -> We have streamed one or more blocks from the ImmDB that were part of the VolatileDB when initialising the iterator. Now, we have to look back in the VolatileDB again because the ImmDB doesn't have the next block we're looking for. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.UnknownRangeRequested.ForkTooOld - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.IteratorEvent.UnknownRangeRequested.MissingBlock - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LastShutdownUnclean - - -> Last shutdown of the node didn't leave the ChainDB directory in a clean state. Therefore, revalidating all the immutable chunks is necessary to ensure the correctness of the chain. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.AlreadyClosed - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Closed - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Closing - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Copied - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Copying - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.CreatedValueHandle - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.CreatingValueHandle - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisedFromCopy - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisedFromValues - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisingFromCopy - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.InitialisingFromValues - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Opened - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Opening - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.AlreadyClosed - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Closed - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Closing - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.RangeRead - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.RangeReading - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Read - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Reading - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Statted - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.ValueHandleTrace.Statting - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Writing - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.BackingStoreEvent.Written - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V1.LMDB.Initialise - - -> An LMDB trace - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMLookup - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMOpenSession - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMSnap - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMTrace - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.BackendTrace.LSM.LSMUpdate - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleClose - - -> Closed a ledger tables handle - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleCreate - - -> Created a ledger tables handle - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleCreateFirst - - -> Creating the first ledger tables handle - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleDuplicate - - -> Duplicating a ledger tables handle - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandlePush - - -> Pushing to a ledger tables handle - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Flavor.V2.LedgerTablesHandleRead - - -> Reading from ledger tables handle - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Forker.Close - - -> A forker was closed - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.LedgerEvent.Forker.Open - - -> A forker is being opened - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.LedgerEvent.Forker.Push - - -> A forker is pushing a new ledger state - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.LedgerEvent.Forker.RangeRead - - -> A forker is range reading values - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.LedgerEvent.Forker.Read - - -> A forker is reading values - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.LedgerEvent.Forker.Statistics - - -> Statistics were gathered from the forker - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### ChainDB.LedgerEvent.Replay.ReplayProgress.ReplayedBlock - - -> We replayed the given block (reference) on the genesis snapshot during the initialisation of the LedgerDB. -> The @blockInfo@ parameter corresponds replayed block and the @replayTo@ parameter corresponds to the block at the tip of the ImmDB, i.e., the last block to replay. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.LedgerEvent.Replay.ReplayStart.ReplayFromGenesis - - -> There were no LedgerDB snapshots on disk, so we're replaying all blocks starting from Genesis against the initial ledger. The @replayTo@ parameter corresponds to the block at the tip of the ImmDB, i.e., the last block to replay. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.LedgerEvent.Replay.ReplayStart.ReplayFromSnapshot - - -> There was a LedgerDB snapshot on disk corresponding to the given tip. We're replaying more recent blocks against it. The @replayTo@ parameter corresponds to the block at the tip of the ImmDB, i.e., the last block to replay. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.LedgerEvent.Snapshot.DeletedSnapshot - - -> A snapshot was deleted from the disk. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.LedgerEvent.Snapshot.InvalidSnapshot - - -> An on disk snapshot was invalid. Unless it was suffixed or seems to be from an old node or different backend, it will be deleted - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.LedgerEvent.Snapshot.TookSnapshot - - -> A snapshot is being written to disk. Two events will be traced, one for when the node starts taking the snapshot and another one for when the snapshot has been written to the disk. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.ClosedDB - - -> The ChainDB was closed. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.OpenedDB - - -> The ChainDB was opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.OpenedImmutableDB - - -> The ImmDB was opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.OpenedLgrDB - - -> The LedgerDB was opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.OpenedVolatileDB - - -> The VolatileDB was opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.StartedOpeningDB - - -> The ChainDB is being opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.StartedOpeningImmutableDB - - -> The ImmDB is being opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.StartedOpeningLgrDB - - -> The LedgerDB is being opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.OpenEvent.StartedOpeningVolatileDB - - -> The VolatileDB is being opened. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.PerasCertDbEvent.AddedPerasCert - - -> Certificate added to Peras certificate database - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.PerasCertDbEvent.AddingPerasCert - - -> Adding certificate to Peras certificate database - - -Severity: `Debug` -Privacy: `Public` -Details: `DDetailed` - - -From current configuration: -Details: `DNormal` -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.PerasCertDbEvent.ClosedPerasCertDB - - -> Peras certificate database closed - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.PerasCertDbEvent.IgnoredCertAlreadyInDB - - -> Certificate ignored as it was already in the database - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.PerasCertDbEvent.OpenedPerasCertDB - - -> Peras certificate database opened - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.ReplayBlock.LedgerReplay - - -> Counts block replays and calculates the percent. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### ChainDB.VolatileDbEvent.BlockAlreadyHere - - -> A block was found to be already in the DB. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.VolatileDbEvent.DBAlreadyClosed - - -> When closing the DB it was found it is closed already. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.VolatileDbEvent.DBClosed - - -> Closing the volatile DB - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.VolatileDbEvent.InvalidFileNames - - -> Reports a list of invalid file paths. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainDB.VolatileDbEvent.Truncate - - -> Truncates a file up to offset because of the error. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### ChainSync.Client.AccessingForecastHorizon - - -> The slot number, which was previously beyond the forecast horizon, has now entered it - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.DownloadedHeader - - -> While following a candidate chain, we rolled forward by downloading a header. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.DrainingThePipe - - -> The client is draining the pipe of messages - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.Exception - - -> An exception was thrown by the Chain Sync Client. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Warning` - -### ChainSync.Client.FoundIntersection - - -> We found an intersection between our chain fragment and the candidate's chain. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.GaveLoPToken - - -> May have added atoken to the LoP bucket of the peer - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.JumpResult - - -> Response to a jump offer (accept or reject) - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.JumpingInstructionIs - - -> The client got its next instruction - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.JumpingWaitingForNextInstruction - - -> The client is waiting for the next instruction - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.OfferJump - - -> Offering a jump to the remote peer - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.RolledBack - - -> While following a candidate chain, we rolled back to the given point. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.Termination - - -> The client has terminated. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.ValidatedHeader - - -> The header has been validated - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Client.WaitingBeyondForecastHorizon - - -> The slot number is beyond the forecast horizon - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### ChainSync.Local.Receive.AwaitReply - - -> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.Done - - -> We have to explain to the framework what our states mean, in terms of which party has agency in each state. -> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.FindIntersect - - -> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.IntersectFound - - -> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.IntersectNotFound - - -> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.RequestNext - - -> Request the next update from the producer. The response can be a roll forward, a roll back or wait. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.RollBackward - - -> Tell the consumer to roll back to a given point on their chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Receive.RollForward - - -> Tell the consumer to extend their chain with the given header. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.AwaitReply - - -> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.Done - - -> We have to explain to the framework what our states mean, in terms of which party has agency in each state. -> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.FindIntersect - - -> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.IntersectFound - - -> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.IntersectNotFound - - -> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.RequestNext - - -> Request the next update from the producer. The response can be a roll forward, a roll back or wait. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.RollBackward - - -> Tell the consumer to roll back to a given point on their chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Local.Send.RollForward - - -> Tell the consumer to extend their chain with the given header. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.AwaitReply - - -> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.Done - - -> We have to explain to the framework what our states mean, in terms of which party has agency in each state. -> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.FindIntersect - - -> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.IntersectFound - - -> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.IntersectNotFound - - -> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.RequestNext - - -> Request the next update from the producer. The response can be a roll forward, a roll back or wait. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.RollBackward - - -> Tell the consumer to roll back to a given point on their chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Receive.RollForward - - -> Tell the consumer to extend their chain with the given header. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.AwaitReply - - -> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.Done - - -> We have to explain to the framework what our states mean, in terms of which party has agency in each state. -> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.FindIntersect - - -> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.IntersectFound - - -> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.IntersectNotFound - - -> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.RequestNext - - -> Request the next update from the producer. The response can be a roll forward, a roll back or wait. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.RollBackward - - -> Tell the consumer to roll back to a given point on their chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Send.RollForward - - -> Tell the consumer to extend their chain with the given header. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.AwaitReply - - -> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.Done - - -> We have to explain to the framework what our states mean, in terms of which party has agency in each state. -> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.FindIntersect - - -> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.IntersectFound - - -> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.IntersectNotFound - - -> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.RequestNext - - -> Request the next update from the producer. The response can be a roll forward, a roll back or wait. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.RollBackward - - -> Tell the consumer to roll back to a given point on their chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Receive.RollForward - - -> Tell the consumer to extend their chain with the given header. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.AwaitReply - - -> Acknowledge the request but require the consumer to wait for the next update. This means that the consumer is synced with the producer, and the producer is waiting for its own chain state to change. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.Done - - -> We have to explain to the framework what our states mean, in terms of which party has agency in each state. -> Idle states are where it is for the client to send a message, busy states are where the server is expected to send a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.FindIntersect - - -> Ask the producer to try to find an improved intersection point between the consumer and producer's chains. The consumer sends a sequence of points and it is up to the producer to find the first intersection point on its chain and send it back to the consumer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.IntersectFound - - -> The reply to the consumer about an intersection found. The consumer can decide weather to send more points. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.IntersectNotFound - - -> The reply to the consumer that no intersection was found: none of the points the consumer supplied are on the producer chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.RequestNext - - -> Request the next update from the producer. The response can be a roll forward, a roll back or wait. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.RollBackward - - -> Tell the consumer to roll back to a given point on their chain. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.Remote.Serialised.Send.RollForward - - -> Tell the consumer to extend their chain with the given header. -> The message also tells the consumer about the head point of the producer. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.ServerBlock.Update - - -> A server read has occurred, either for an add block or a rollback - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### ChainSync.ServerHeader.Update - - -> A server read has occurred, either for an add block or a rollback - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.CSJ.BecomingObjector - - -> This peer is becoming the CSJ objector - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.CSJ.BlockedOnJump - - -> This peer is blocked on a CSJ jump - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.CSJ.InitializedAsDynamo - - -> This peer has been initialized as the CSJ dynamo - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.CSJ.NoLongerDynamo - - -> This peer no longer is the CSJ dynamo - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.CSJ.NoLongerObjector - - -> This peer no longer is the CSJ objector - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.CSJ.SentJumpInstruction - - -> This peer has been instructed to jump via CSJ - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.DevotedBlockFetch.RotatedDynamo - - -> The ChainSync Jumping module has been asked to rotate its dynamo - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.GDD.TraceGDDEvent - - -> The Genesis Density Disconnection governor has updated its state - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Consensus.GSM.EnterCaughtUp - - -> Node is caught up - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.GSM.InitializedInCaughtUp - - -> The GSM was initialized in the 'CaughtUp' state - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.GSM.InitializedInPreSyncing - - -> The GSM was initialized in the 'PreSyncing' state - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.GSM.LeaveCaughtUp - - -> Node is not caught up - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.GSM.PreSyncingToSyncing - - -> The Honest Availability Assumption is now satisfied - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.GSM.SyncingToPreSyncing - - -> The Honest Availability Assumption is no longer satisfied - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.SanityCheck.SanityCheckIssue - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Consensus.Startup.ConsensusStartupException - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Forge.Loop.AdoptedBlock - - -> We adopted the block we produced, we also trace the transactions that were adopted. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.AdoptionThreadDied - - -> Block adoption thread died - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.BlockContext - - -> We found out to which block we are going to connect the block we are about to forge. We record the current slot number, the block number of the block to connect to and its point. Note that block number of the block we will try to forge is one more than the recorded block number. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Forge.Loop.BlockFromFuture - - -> Leadership check failed: the current chain contains a block from a slot /after/ the current slot This can only happen if the system is under heavy load. We record both the current slot number as well as the slot number of the block at the tip of the chain. See also - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.DidntAdoptBlock - - -> We did not adopt the block we produced, but the block was valid. We must have adopted a block that another leader of the same slot produced before we got the chance of adopting our own block. This is very rare, this warrants a warning. - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.ForgeStateUpdateError - - -> Updating the forge state failed. For example, the KES key could not be evolved anymore. We record the error returned by 'updateForgeState'. - - -Severity: `Critical` -Privacy: `Confidential` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.ForgeTickedLedgerState - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Forge.Loop.ForgedBlock - - -> We forged a block. -> We record the current slot number, the point of the predecessor, the block itself, and the total size of the mempool snapshot at the time we produced the block (which may be significantly larger than the block, due to maximum block size) -> This will be followed by one of three messages: -> * AdoptedBlock (normally) -> * DidntAdoptBlock (rarely) -> * ForgedInvalidBlock (hopefully never, this would indicate a bug) - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.ForgedInvalidBlock - - -> We forged a block that is invalid according to the ledger in the ChainDB. This means there is an inconsistency between the mempool validation and the ledger validation. This is a serious error! - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.ForgingMempoolSnapshot - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Forge.Loop.LedgerState - - -> We obtained a ledger state for the point of the block we want to connect to We record both the current slot number as well as the point of the block we attempt to connect the new block to (that we requested the ledger state for). - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Forge.Loop.LedgerView - - -> We obtained a ledger view for the current slot number We record the current slot number. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Forge.Loop.NoLedgerState - - -> Leadership check failed: we were unable to get the ledger state for the point of the block we want to connect to This can happen if after choosing which block to connect to the node switched to a different fork. We expect this to happen only rather rarely, so this certainly merits a warning; if it happens a lot, that merits an investigation. We record both the current slot number as well as the point of the block we attempt to connect the new block to (that we requested the ledger state for). - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.NoLedgerView - - -> Leadership check failed: we were unable to get the ledger view for the current slot number This will only happen if there are many missing blocks between the tip of our chain and the current slot. We record also the failure returned by 'forecastFor'. - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.NodeCannotForge - - -> We did the leadership check and concluded that we should lead and forge a block, but cannot. This should only happen rarely and should be logged with warning severity. Records why we cannot forge a block. - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.NodeIsLeader - - -> We did the leadership check and concluded we /are/ the leader -> The node will soon forge; it is about to read its transactions from the Mempool. This will be followed by ForgedBlock. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.NodeNotLeader - - -> We did the leadership check and concluded we are not the leader We record the current slot number - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.SlotIsImmutable - - -> Leadership check failed: the tip of the ImmutableDB inhabits the current slot This might happen in two cases. 1. the clock moved backwards, on restart we ignored everything from the VolatileDB since it's all in the future, and now the tip of the ImmutableDB points to a block produced in the same slot we're trying to produce a block in 2. k = 0 and we already adopted a block from another leader of the same slot. We record both the current slot number as well as the tip of the ImmutableDB. See also - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.Loop.StartLeadershipCheck - - -> Start of the leadership check. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.StateInfo - - -> kesStartPeriod -> kesEndPeriod is kesStartPeriod + tpraosMaxKESEvo -> kesEvolution is the current evolution or /relative period/. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Forge.ThreadStats.ForgingStats - - -> nodeCannotForgeNum shows how many times this node could not forge. -> nodeIsLeaderNum shows how many times this node was leader. -> blocksForgedNum shows how many blocks did forge in this node. -> slotsMissed shows how many slots were missed in this node. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### LedgerMetrics - - -> Periodic trace emitted every Nth slot, approximately 700 milliseconds after slot start. -> It queries the current ledger and chain to report metrics such as UTxO set and delegation map sizes. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Mempool.AddedTx - - -> New, valid transaction that was added to the Mempool. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.AttemptAdd - - -> Mempool is about to try to validate and add a transaction. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.ManuallyRemovedTxs - - -> Transactions that have been manually removed from the Mempool. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.RejectedTx - - -> New, invalid transaction that was rejected and thus not added to the Mempool. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.RemoveTxs - - -> Previously valid transactions that are no longer valid because of changes in the ledger state. These transactions have been removed from the Mempool. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.SyncNotNeeded - - -> The mempool and the LedgerDB are in sync already. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.Synced - - -> The mempool and the LedgerDB are syncing or in sync depending on the argument on the trace. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Mempool.TipMovedBetweenSTMBlocks - - -> LedgerDB moved to an alternative fork between two reads during re-sync. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Net.AcceptPolicy.ConnectionHardLimit - - -> Hard rate limit reached, waiting until the number of connections drops below n. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.AcceptPolicy.ConnectionLimitResume - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.AcceptPolicy.ConnectionRateLimiting - - -> Rate limiting accepting connections, delaying next accept for given time, currently serving n connections. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.Connect - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionCleanup - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionExists - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionFailure - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionHandler.Error - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionHandler.HandshakeClientError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionHandler.HandshakeQuery - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionHandler.HandshakeServerError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionHandler.HandshakeSuccess - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionManagerCounters - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionNotFound - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionTimeWait - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ConnectionTimeWaitDone - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ForbiddenConnection - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.ForbiddenOperation - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.IncludeConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.PruneConnections - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.ConnectionManager.Local.Shutdown - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.State - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.TerminatedConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.TerminatingConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Local.UnexpectedlyFalseAssertion - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.ConnectionManager.Local.UnregisterConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.ConnectionManager.Remote.Connect - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionCleanup - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionExists - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionFailure - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionHandler.Error - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeClientError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeQuery - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeServerError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionHandler.HandshakeSuccess - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionManagerCounters - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionNotFound - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionTimeWait - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.ConnectionTimeWaitDone - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ForbiddenConnection - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.ForbiddenOperation - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.IncludeConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.PruneConnections - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.Shutdown - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.State - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.TerminatedConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.TerminatingConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Remote.UnexpectedlyFalseAssertion - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.ConnectionManager.Remote.UnregisterConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.ConnectionManager.Transition.Transition - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.InboundGovernor.Local.DemotedToColdRemote - - -> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.DemotedToWarmRemote - - -> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.Inactive - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.InboundGovernorCounters - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.InboundGovernorError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Warning` - -### Net.InboundGovernor.Local.MaturedConnections - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.MuxCleanExit - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.MuxErrored - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.NewConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.PromotedToHotRemote - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.PromotedToWarmRemote - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.RemoteState - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.ResponderErrored - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.ResponderRestarted - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.ResponderStartFailure - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.ResponderStarted - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.ResponderTerminated - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Local.UnexpectedlyFalseAssertion - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Warning` - -### Net.InboundGovernor.Local.WaitIdleRemote - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.InboundGovernor.Remote.DemotedToColdRemote - - -> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.DemotedToWarmRemote - - -> All mini-protocols terminated. The boolean is true if this connection was not used by p2p-governor, and thus the connection will be terminated. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.Inactive - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.InboundGovernorCounters - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.InboundGovernorError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.MaturedConnections - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.MuxCleanExit - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.MuxErrored - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.NewConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.PromotedToHotRemote - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.PromotedToWarmRemote - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.RemoteState - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.ResponderErrored - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.ResponderRestarted - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.ResponderStartFailure - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.ResponderStarted - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.ResponderTerminated - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Remote.UnexpectedlyFalseAssertion - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.InboundGovernor.Remote.WaitIdleRemote - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.InboundGovernor.Transition.Transition - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Warning` - -### Net.KeepAliveClient - - -> A server read has occurred, either for an add block or a rollback - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.CleanExit - - -> Miniprotocol terminated cleanly. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Mux.Local.ExceptionExit - - -> Miniprotocol terminated with exception. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Mux.Local.NewMux - - -> New Mux - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.StartEagerly - - -> Eagerly started. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.StartOnDemand - - -> Preparing to start. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.StartOnDemandAny - - -> Start whenever any other protocol has started. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.StartedOnDemand - - -> Started on demand. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.Starting - - -> Mux Starting - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.State - - -> State. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.Stopped - - -> Mux shutdown. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.Stopping - - -> Mux shutdown. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Local.Terminating - - -> Terminating. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Mux.Remote.CleanExit - - -> Miniprotocol terminated cleanly. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.Mux.Remote.ExceptionExit - - -> Miniprotocol terminated with exception. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.Mux.Remote.NewMux - - -> New Mux - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.StartEagerly - - -> Eagerly started. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.StartOnDemand - - -> Preparing to start. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.StartOnDemandAny - - -> Start whenever any other protocol has started. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.StartedOnDemand - - -> Started on demand. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.Starting - - -> Mux Starting - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.State - - -> State. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.Mux.Remote.Stopped - - -> Mux shutdown. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.Stopping - - -> Mux shutdown. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.Mux.Remote.Terminating - - -> Terminating. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Actions.ConnectionError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Actions.MonitoringError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Actions.MonitoringResult - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Actions.PeerHotDuration - - -> Reports how long the outbound connection was in hot state - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Actions.StatusChangeFailure - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Actions.StatusChanged - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Counters.Counters - - -> Peer selection peer counters - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Initiator.GovernorState - - -> Outbound peer selection internal state - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Responder.GovernorState - - -> Outbound peer selection internal state - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Selection.BigLedgerPeersFailure - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.BigLedgerPeersRequest - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.BigLedgerPeersResults - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.BootstrapPeersFlagChangedWhilstInSensitiveState - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.ChurnAction - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.ChurnTimeout - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.ChurnWait - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DebugState - - -> peer selection internal state - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteAsynchronous - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteBigLedgerPeersAsynchronous - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotBigLedgerPeerDone - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotBigLedgerPeerFailed - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotBigLedgerPeerFailed.CoolingToColdTimeout - - -> Impossible asynchronous demotion timeout - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotBigLedgerPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotDone - - -> target active, actual active, peer - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotFailed - - -> target active, actual active, peer, reason - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotFailed.CoolingToColdTimeout - - -> Impossible asynchronous demotion timeout - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteHotPeers - - -> target active, actual active, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteLocalAsynchronous - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteLocalHotPeers - - -> local per-group (target active, actual active), selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerDone - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerFailed - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeerFailed.CoolingToColdTimeout - - -> Impossible asynchronous demotion timeout - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmBigLedgerPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmDone - - -> target established, actual established, peer - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmFailed - - -> target established, actual established, peer, reason - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmFailed.CoolingToColdTimeout - - -> Impossible asynchronous demotion timeout - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.DemoteWarmPeers - - -> target established, actual established, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.ForgetBigLedgerPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.ForgetColdPeers - - -> target known peers, actual known peers, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.GovernorWakeup - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.LedgerStateJudgementChanged - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.LocalRootPeersChanged - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.OnlyBootstrapPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.OutboundGovernorCriticalFailure - - -> Outbound Governor was killed unexpectedly - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PeerShareRequests - - -> target known peers, actual known peers, peers available for gossip, peers selected for gossip - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Selection.PeerShareResults - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Info` - -### Net.PeerSelection.Selection.PeerShareResultsFiltered - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PickInboundPeers - - -> An inbound connection was added to known set of outbound governor - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdBigLedgerPeerDone - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdBigLedgerPeerFailed - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdBigLedgerPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdDone - - -> target active, actual active, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdFailed - - -> target established, actual established, peer, delay until next promotion, reason - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdLocalPeers - - -> target local established, actual local established, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteColdPeers - - -> target established, actual established, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmAborted - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerAborted - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerDone - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeerFailed - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmBigLedgerPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmDone - - -> target active, actual active, peer - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmFailed - - -> target active, actual active, peer, reason - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmLocalPeers - - -> local per-group (target active, actual active), selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PromoteWarmPeers - - -> target active, actual active, selected peers - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PublicRootsFailure - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PublicRootsRequest - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.PublicRootsResults - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.TargetsChanged - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.UseBootstrapPeersChanged - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.PeerSelection.Selection.VerifyPeerSnapshot - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Net.Peers.Ledger.DisabledLedgerPeers - - -> Trace for when getting peers from the ledger is disabled, that is DontUseLedger. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.FallingBackToPublicRootPeers - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.FetchingNewLedgerState - - -> Trace for fetching a new list of peers from the ledger. Int is the number of peers returned. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.NotEnoughBigLedgerPeers - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Peers.Ledger.NotEnoughLedgerPeers - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Peers.Ledger.PickedBigLedgerPeer - - -> Trace for a big ledger peer picked with accumulated and relative stake of its pool. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.PickedBigLedgerPeers - - -> Trace for the number of big ledger peers we wanted to pick and the list of peers picked. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.PickedLedgerPeer - - -> Trace for a peer picked with accumulated and relative stake of its pool. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.PickedLedgerPeers - - -> Trace for the number of peers we wanted to pick and the list of peers picked. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.RequestForPeers - - -> RequestForPeers (NumberOfPeers 1) - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.ReusingLedgerState - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.TraceLedgerPeersDomains - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.TraceUseLedgerAfter - - -> Trace UseLedgerAfter value. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.UsingBigLedgerPeerSnapshot - - -> Trace for when a request for big ledger peers is fulfilled from the snapshot file specified in the topology file. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.Ledger.WaitingOnRequest - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootDNSMap - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootDomains - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootError - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootFailure - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootGroups - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootReconfigured - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.LocalRoot.LocalRootWaiting - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.PublicRoot.PublicRootDomains - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Peers.PublicRoot.PublicRootRelayAccessPoint - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Server.Local.AcceptConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Server.Local.AcceptError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Local.AcceptPolicy - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Local.Error - - - - -Severity: `Critical` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Local.Started - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Local.Stopped - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Remote.AcceptConnection - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Net.Server.Remote.AcceptError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Remote.AcceptPolicy - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Remote.Error - - - - -Severity: `Critical` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Remote.Started - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Net.Server.Remote.Stopped - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeAddBlock - - -> Applying block - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeInitChainSelection - - -> Performing initial chain selection - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeKernelOnline - - -> Tracing system configured and node kernel is online - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### NodeState.NodeReplays - - -> Replaying chain - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeShutdown - - -> Node shutting down - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeStartup - - -> Node startup - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### NodeState.NodeTracingFailure - - -> Tracing system experienced a non-fatal failure during startup - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeTracingForwardingInterrupted - - -> Trace/metrics forwarding connection was interrupted - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### NodeState.NodeTracingOnlineConfiguring - - -> Tracing system came online, system configuring now - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### NodeState.OpeningDbs - - -> ChainDB components being opened - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### NodeState.PrometheusSimple.Start - - -> PrometheusSimple backend is starting - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### NodeState.PrometheusSimple.Stop - - -> PrometheusSimple backend stopped - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### RPC.Error - - -> Normal operation errors such as request errors. Those are not harmful to the RPC server itself. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### RPC.FatalError - - -> RPC startup critical error. - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### RPC.QueryService.ReadParams.Span - - -> Span for the ReadParams UTXORPC method. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### RPC.QueryService.ReadUtxos.Span - - -> Span for the ReadUtxos UTXORPC method. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### RPC.SubmitService.N2cConnectionError - - -> Node connection error. This should not happen, as this means that there is an issue in cardano-rpc configuration. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### RPC.SubmitService.SubmitTx.Span - - -> Span for the SubmitTx UTXORPC method. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### RPC.SubmitService.TxDecodingError - - -> A regular request error, when submitted transaction decoding fails. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### RPC.SubmitService.TxValidationError - - -> A regular request error, when submitted transaction is invalid. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Reflection.MetricsInfo - - -> Writes out numbers for metrics delivered. -> This internal message can't be filtered by the current configuration - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Reflection.RememberLimiting - - -> ^ This message remembers of ongoing frequency limiting, and gives the number of messages that has been suppressed -> This internal message can't be filtered by the current configuration - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Reflection.StartLimiting - - -> This message indicates the start of frequency limiting -> This internal message can't be filtered by the current configuration - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Reflection.StopLimiting - - -> This message indicates the stop of frequency limiting, and gives the number of messages that has been suppressed -> This internal message can't be filtered by the current configuration - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Reflection.TracerConfigInfo - - -> Trace the tracer configuration which is effectively used. -> This internal message can't be filtered by the current configuration - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Reflection.TracerConsistencyWarnings - - -> Tracer consistency check found errors. -> This internal message can't be filtered by the current configuration - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Reflection.TracerInfo - - -> Writes out tracers with metrics and silent tracers. -> This internal message can't be filtered by the current configuration - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Reflection.UnknownNamespace - - -> A value was queried for a namespaces from a tracer,which is unknown. This indicates a bug in the tracer implementation. -> This internal message can't be filtered by the current configuration - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Resources - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered Invisible by config value: `Silence` - -### Shutdown.Abnormal - - -> non-isEOFerror shutdown request - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Shutdown.ArmedAt - - -> Setting up node shutdown at given slot / block. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Shutdown.Requested - - -> Node shutdown was requested. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Shutdown.Requesting - - -> Ringing the node shutdown doorbell - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Shutdown.UnexpectedInput - - -> Received shutdown request but found unexpected input in --shutdown-ipc FD: - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.BlockForgingBlockTypeMismatch - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.BlockForgingUpdate - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.Byron - - -> _bibSystemStartTime_: -> _bibSlotLength_: gives the length of a slot as time interval. -> _bibEpochLength_: gives the number of slots which forms an epoch. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.Common - - -> _biConfigPath_: is the path to the config in use. -> _biProtocol_: is the name of the protocol, e.g. "Byron", "Shelley" or "Byron; Shelley". -> _biVersion_: is the version of the node software running. -> _biCommit_: is the commit revision of the software running. -> _biNodeStartTime_: gives the time this node was started. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.DBValidation - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.DiffusionInit.ConfiguringLocalSocket - - -> ConfiguringLocalSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.ConfiguringServerSocket - - -> ConfiguringServerSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.CreateSystemdSocketForSnocketPath - - -> CreateSystemdSocketForSnocketPath - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.CreatedLocalSocket - - -> CreatedLocalSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.CreatingServerSocket - - -> CreatingServerSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.DiffusionErrored - - -> DiffusionErrored - - -Severity: `Critical` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.ListeningLocalSocket - - -> ListeningLocalSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.ListeningServerSocket - - -> ListeningServerSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.LocalSocketUp - - -> LocalSocketUp - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.RunLocalServer - - -> RunLocalServer - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.RunServer - - -> RunServer - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.ServerSocketUp - - -> ServerSocketUp - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.SystemdSocketConfiguration - - -> SystemdSocketConfiguration - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.UnsupportedLocalSystemdSocket - - -> UnsupportedLocalSystemdSocket - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.UnsupportedReadySocketCase - - -> UnsupportedReadySocketCase - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.DiffusionInit.UsingSystemdSocket - - -> UsingSystemdSocket - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Info` - -### Startup.Info - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.LedgerPeerSnapshot - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.LedgerPeerSnapshot.Incompatible - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.MovedTopLevelOption - - -> An option was moved from the top level of the config file to a subsection - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.Network - - -> _niAddresses_: IPv4 or IPv6 socket ready to accept connectionsor diffusion addresses. -> _niDiffusionMode_: shows if the node runs only initiator or bothinitiator or responder node. -> _niDnsProducers_: shows the list of domain names to subscribe to. -> _niIpProducers_: shows the list of ip subscription addresses. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.NetworkConfig - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.NetworkConfigUpdate - - - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.NetworkConfigUpdateError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.NetworkConfigUpdateUnsupported - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.NetworkMagic - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.NonP2PWarning - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.P2PInfo - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.ShelleyBased - - -> bisEra is the current era, e.g. "Shelley", "Allegra", "Mary" or "Alonzo". -> _bisSystemStartTime_: -> _bisSlotLength_: gives the length of a slot as time interval. -> _bisEpochLength_: gives the number of slots which forms an epoch. -> _bisSlotsPerKESPeriod_: gives the slots per KES period. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.SocketConfigError - - - - -Severity: `Error` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.Time - - - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Startup.WarningDevelopmentNodeToClientVersions - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### Startup.WarningDevelopmentNodeToNodeVersions - - - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### StateQueryServer.Receive.Acquire - - -> The client requests that the state as of a particular recent point on the server's chain (within K of the tip) be made available to query, and waits for confirmation or failure. -> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Receive.Acquired - - -> The server can confirm that it has the state at the requested point. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Receive.Done - - -> The client can terminate the protocol. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Receive.Failure - - -> The server can report that it cannot obtain the state for the requested point. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### StateQueryServer.Receive.Query - - -> The client can perform queries on the current acquired state. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Receive.ReAcquire - - -> This is like 'MsgAcquire' but for when the client already has a state. By moving to another state directly without a 'MsgRelease' it enables optimisations on the server side (e.g. moving to the state for the immediate next block). -> Note that failure to re-acquire is equivalent to 'MsgRelease', rather than keeping the exiting acquired state. -> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Receive.Release - - -> The client can instruct the server to release the state. This lets the server free resources. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Receive.Result - - -> The server must reply with the queries. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.Acquire - - -> The client requests that the state as of a particular recent point on the server's chain (within K of the tip) be made available to query, and waits for confirmation or failure. -> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.Acquired - - -> The server can confirm that it has the state at the requested point. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.Done - - -> The client can terminate the protocol. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.Failure - - -> The server can report that it cannot obtain the state for the requested point. - - -Severity: `Warning` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### StateQueryServer.Send.Query - - -> The client can perform queries on the current acquired state. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.ReAcquire - - -> This is like 'MsgAcquire' but for when the client already has a state. By moving to another state directly without a 'MsgRelease' it enables optimisations on the server side (e.g. moving to the state for the immediate next block). -> Note that failure to re-acquire is equivalent to 'MsgRelease', rather than keeping the exiting acquired state. -> From 'NodeToClient_V8' onwards if the point is not specified, current tip will be acquired. For previous versions of the protocol 'point' must be given. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.Release - - -> The client can instruct the server to release the state. This lets the server free resources. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### StateQueryServer.Send.Result - - -> The server must reply with the queries. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Receive.AcceptTx - - -> The server can reply to inform the client that it has accepted the transaction. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Receive.Done - - -> The client can terminate the protocol. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Receive.RejectTx - - -> The server can reply to inform the client that it has rejected the transaction. A reason for the rejection is included. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Receive.SubmitTx - - -> The client submits a single transaction and waits a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Send.AcceptTx - - -> The server can reply to inform the client that it has accepted the transaction. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Send.Done - - -> The client can terminate the protocol. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Send.RejectTx - - -> The server can reply to inform the client that it has rejected the transaction. A reason for the rejection is included. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Local.Send.SubmitTx - - -> The client submits a single transaction and waits a reply. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.LocalServer.ReceivedTx - - -> A transaction was received. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.Acquire - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.Acquired - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.AwaitAcquire - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.Done - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.GetMeasures - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.GetSizes - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.HasTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.NextTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.Release - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.ReplyGetMeasures - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.ReplyGetSizes - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.ReplyHasTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Receive.ReplyNextTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.Acquire - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.Acquired - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.AwaitAcquire - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.Done - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.GetMeasures - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.GetSizes - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.HasTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.NextTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.Release - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.ReplyGetMeasures - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.ReplyGetSizes - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.ReplyHasTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.MonitorClient.Send.ReplyNextTx - - - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Receive.Done - - -> Termination message, initiated by the client when the server is making a blocking call for more transaction identifiers. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Receive.MsgInit - - -> Client side hello message. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Receive.ReplyTxIds - - -> Reply with a list of transaction identifiers for available transactions, along with the size of each transaction. -> The list must not be longer than the maximum number requested. -> In the 'StTxIds' 'StBlocking' state the list must be non-empty while in the 'StTxIds' 'StNonBlocking' state the list may be empty. -> These transactions are added to the notional FIFO of outstanding transaction identifiers for the protocol. -> The order in which these transaction identifiers are returned must be the order in which they are submitted to the mempool, to preserve dependent transactions. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Receive.ReplyTxs - - -> Reply with the requested transactions, or implicitly discard. -> Transactions can become invalid between the time the transaction identifier was sent and the transaction being requested. Invalid (including committed) transactions do not need to be sent. -> Any transaction identifiers requested but not provided in this reply should be considered as if this peer had never announced them. (Note that this is no guarantee that the transaction is invalid, it may still be valid and available from another peer). - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Receive.RequestTxIds - - -> Request a non-empty list of transaction identifiers from the client, and confirm a number of outstanding transaction identifiers. -> With 'TokBlocking' this is a blocking operation: the response will always have at least one transaction identifier, and it does not expect a prompt response: there is no timeout. This covers the case when there is nothing else to do but wait. For example this covers leaf nodes that rarely, if ever, create and submit a transaction. -> With 'TokNonBlocking' this is a non-blocking operation: the response may be an empty list and this does expect a prompt response. This covers high throughput use cases where we wish to pipeline, by interleaving requests for additional transaction identifiers with requests for transactions, which requires these requests not block. -> The request gives the maximum number of transaction identifiers that can be accepted in the response. This must be greater than zero in the 'TokBlocking' case. In the 'TokNonBlocking' case either the numbers acknowledged or the number requested must be non-zero. In either case, the number requested must not put the total outstanding over the fixed protocol limit. -> The request also gives the number of outstanding transaction identifiers that can now be acknowledged. The actual transactions to acknowledge are known to the peer based on the FIFO order in which they were provided. -> There is no choice about when to use the blocking case versus the non-blocking case, it depends on whether there are any remaining unacknowledged transactions (after taking into account the ones acknowledged in this message): -> * The blocking case must be used when there are zero remaining unacknowledged transactions. -> * The non-blocking case must be used when there are non-zero remaining unacknowledged transactions. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Receive.RequestTxs - - -> Request one or more transactions corresponding to the given transaction identifiers. -> While it is the responsibility of the replying peer to keep within pipelining in-flight limits, the sender must also cooperate by keeping the total requested across all in-flight requests within the limits. -> It is an error to ask for transaction identifiers that were not previously announced (via 'MsgReplyTxIds'). -> It is an error to ask for transaction identifiers that are not outstanding or that were already asked for. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Send.Done - - -> Termination message, initiated by the client when the server is making a blocking call for more transaction identifiers. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Send.MsgInit - - -> Client side hello message. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Send.ReplyTxIds - - -> Reply with a list of transaction identifiers for available transactions, along with the size of each transaction. -> The list must not be longer than the maximum number requested. -> In the 'StTxIds' 'StBlocking' state the list must be non-empty while in the 'StTxIds' 'StNonBlocking' state the list may be empty. -> These transactions are added to the notional FIFO of outstanding transaction identifiers for the protocol. -> The order in which these transaction identifiers are returned must be the order in which they are submitted to the mempool, to preserve dependent transactions. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Send.ReplyTxs - - -> Reply with the requested transactions, or implicitly discard. -> Transactions can become invalid between the time the transaction identifier was sent and the transaction being requested. Invalid (including committed) transactions do not need to be sent. -> Any transaction identifiers requested but not provided in this reply should be considered as if this peer had never announced them. (Note that this is no guarantee that the transaction is invalid, it may still be valid and available from another peer). - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Send.RequestTxIds - - -> Request a non-empty list of transaction identifiers from the client, and confirm a number of outstanding transaction identifiers. -> With 'TokBlocking' this is a blocking operation: the response will always have at least one transaction identifier, and it does not expect a prompt response: there is no timeout. This covers the case when there is nothing else to do but wait. For example this covers leaf nodes that rarely, if ever, create and submit a transaction. -> With 'TokNonBlocking' this is a non-blocking operation: the response may be an empty list and this does expect a prompt response. This covers high throughput use cases where we wish to pipeline, by interleaving requests for additional transaction identifiers with requests for transactions, which requires these requests not block. -> The request gives the maximum number of transaction identifiers that can be accepted in the response. This must be greater than zero in the 'TokBlocking' case. In the 'TokNonBlocking' case either the numbers acknowledged or the number requested must be non-zero. In either case, the number requested must not put the total outstanding over the fixed protocol limit. -> The request also gives the number of outstanding transaction identifiers that can now be acknowledged. The actual transactions to acknowledge are known to the peer based on the FIFO order in which they were provided. -> There is no choice about when to use the blocking case versus the non-blocking case, it depends on whether there are any remaining unacknowledged transactions (after taking into account the ones acknowledged in this message): -> * The blocking case must be used when there are zero remaining unacknowledged transactions. -> * The non-blocking case must be used when there are non-zero remaining unacknowledged transactions. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.Remote.Send.RequestTxs - - -> Request one or more transactions corresponding to the given transaction identifiers. -> While it is the responsibility of the replying peer to keep within pipelining in-flight limits, the sender must also cooperate by keeping the total requested across all in-flight requests within the limits. -> It is an error to ask for transaction identifiers that were not previously announced (via 'MsgReplyTxIds'). -> It is an error to ask for transaction identifiers that are not outstanding or that were already asked for. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.AddedToMempool - - -> Transactions added to the mempool and processing time - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.CanRequestMoreTxs - - -> There are no replies in flight, but we do know some more txs we can ask for, so lets ask for them and more txids. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.CannotRequestMoreTxs - - -> There's no replies in flight, and we have no more txs we can ask for so the only remaining thing to do is to ask for more txids. Since this is the only thing to do now, we make this a blocking call. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.Collected - - -> Number of transactions just about to be inserted. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.Decision - - -> Decision to advance the protocol - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.Error - - -> Protocol violation causing connection reset - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.Processed - - -> Just processed transaction pass/fail breakdown. - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.RejectedFromMempool - - -> Transactions rejected from mempool and processing time - - -Severity: `Debug` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxInbound.Terminated - - -> Server received 'MsgDone'. - - -Severity: `Notice` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Visible` by config value: `Notice` - -### TxSubmission.TxOutbound.ControlMessage - - -> Peer selection control instruction - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxOutbound.RecvMsgRequest - - -> The IDs of the transactions requested. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### TxSubmission.TxOutbound.SendMsgReply - - -> The transactions to be sent in the response. - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` - -### Version.NodeVersion - - -> Node version information - - -Severity: `Info` -Privacy: `Public` -Details: `DNormal` - - -From current configuration: - -Backends: - `EKGBackend`, - `Stdout MachineFormat`, - `Forwarder` -Filtered `Invisible` by config value: `Notice` -## Metrics - -### Forge.about-to-lead - - - -Dispatched by: -Forge.Loop.StartLeadershipCheck - -### Forge.adopted - - - -Dispatched by: -Forge.Loop.AdoptedBlock - -### Forge.adoption-thread-died - - - -Dispatched by: -Forge.Loop.AdoptionThreadDied - -### Forge.block-from-future - - - -Dispatched by: -Forge.Loop.BlockFromFuture - -### Forge.could-not-forge - - - -Dispatched by: -Forge.Loop.NoLedgerState -Forge.Loop.NoLedgerView -Forge.Loop.NodeCannotForge - -### Forge.didnt-adopt - - - -Dispatched by: -Forge.Loop.DidntAdoptBlock - -### Forge.forged - -> Counter of forged blocks - - -Dispatched by: -Forge.Loop.ForgedBlock - -### Forge.forged-invalid - - - -Dispatched by: -Forge.Loop.ForgedInvalidBlock - -### Forge.node-is-leader - - - -Dispatched by: -Forge.Loop.NodeIsLeader - -### Forge.node-not-leader - - - -Dispatched by: -Forge.Loop.NodeNotLeader - -### Forge.slot-is-immutable - - - -Dispatched by: -Forge.Loop.SlotIsImmutable - -### GSM.state - -> The state of the Genesis State Machine. 0 = PreSyncing, 1 = Syncing, 2 = CaughtUp. - - -Dispatched by: -Consensus.GSM.EnterCaughtUp -Consensus.GSM.InitializedInCaughtUp -Consensus.GSM.InitializedInPreSyncing -Consensus.GSM.LeaveCaughtUp -Consensus.GSM.PreSyncingToSyncing -Consensus.GSM.SyncingToPreSyncing - -### Mem.resident - -> Kernel-reported RSS (resident set size) - - -Dispatched by: -Resources - -### RTS.alloc - -> RTS-reported bytes allocated - - -Dispatched by: -Resources - -### RTS.gcHeapBytes - -> RTS-reported heap bytes - - -Dispatched by: -Resources - -### RTS.gcLiveBytes - -> RTS-reported live bytes - - -Dispatched by: -Resources - -### RTS.gcMajorNum - -> Major GCs - - -Dispatched by: -Resources - -### RTS.gcMinorNum - -> Minor GCs - - -Dispatched by: -Resources - -### RTS.gcticks - -> RTS-reported CPU ticks spent on GC - - -Dispatched by: -Resources - -### RTS.mutticks - -> RTS-reported CPU ticks spent on mutator - - -Dispatched by: -Resources - -### RTS.threads - -> RTS green thread count - - -Dispatched by: -Resources - -### Stat.cputicks - -> Kernel-reported CPU ticks (1/100th of a second), since process start - - -Dispatched by: -Resources - -### Stat.fsRd - -> FS bytes read - - -Dispatched by: -Resources - -### Stat.fsWr - -> FS bytes written - - -Dispatched by: -Resources - -### Stat.netRd - -> IP packet bytes read - - -Dispatched by: -Resources - -### Stat.netWr - -> IP packet bytes written - - -Dispatched by: -Resources - -### SuppressedMessages.. - -> Number of suppressed messages of a certain namespace - - -Dispatched by: -Reflection.StartLimiting - -### blockNum - -> Number of blocks in this chain fragment. - - -Dispatched by: -ChainDB.AddBlockEvent.AddedToCurrentChain -ChainDB.AddBlockEvent.SwitchedToAFork - -### blockReplayProgress - -> Progress in percent - - -Dispatched by: -ChainDB.ReplayBlock.LedgerReplay - -### blockfetchclient.blockdelay - -> delay (s) of the latest block fetch - - -Dispatched by: -BlockFetch.Client.ClientMetrics - -### blockfetchclient.blockdelay.cdfFive - -> probability for block fetch to complete within 5s - - -Dispatched by: -BlockFetch.Client.ClientMetrics - -### blockfetchclient.blockdelay.cdfOne - -> probability for block fetch to complete within 1s - - -Dispatched by: -BlockFetch.Client.ClientMetrics - -### blockfetchclient.blockdelay.cdfThree - -> probability for block fetch to complete within 3s - - -Dispatched by: -BlockFetch.Client.ClientMetrics - -### blockfetchclient.blocksize - -> block size (bytes) of the latest block fetch - - -Dispatched by: -BlockFetch.Client.ClientMetrics - -### blockfetchclient.lateblocks - -> number of block fetches that took longer than 5s - - -Dispatched by: -BlockFetch.Client.ClientMetrics - -### blocksForged - -> How many blocks did this node forge? - - -Dispatched by: -Forge.ThreadStats.ForgingStats - -### cardano_build_info - -> Cardano node build info - - -Dispatched by: -Version.NodeVersion - -### cardano_version_major - -> Cardano node version information - - -Dispatched by: -Version.NodeVersion - -### cardano_version_minor - -> Cardano node version information - - -Dispatched by: -Version.NodeVersion - -### cardano_version_patch - -> Cardano node version information - - -Dispatched by: -Version.NodeVersion - -### connectedPeers - -> Number of connected peers - - -Dispatched by: -BlockFetch.Decision.Accept -BlockFetch.Decision.Decline - -### connectionManager.duplexConns - - - -Dispatched by: -Net.ConnectionManager.Remote.ConnectionManagerCounters - -### connectionManager.duplexConns - - - -Dispatched by: -Net.ConnectionManager.Local.ConnectionManagerCounters - -### connectionManager.fullDuplexConns - - - -Dispatched by: -Net.ConnectionManager.Remote.ConnectionManagerCounters - -### connectionManager.fullDuplexConns - - - -Dispatched by: -Net.ConnectionManager.Local.ConnectionManagerCounters - -### connectionManager.inboundConns - - - -Dispatched by: -Net.ConnectionManager.Remote.ConnectionManagerCounters - -### connectionManager.inboundConns - - - -Dispatched by: -Net.ConnectionManager.Local.ConnectionManagerCounters - -### connectionManager.outboundConns - - - -Dispatched by: -Net.ConnectionManager.Remote.ConnectionManagerCounters - -### connectionManager.outboundConns - - - -Dispatched by: -Net.ConnectionManager.Local.ConnectionManagerCounters - -### connectionManager.prunableConns - - - -Dispatched by: -Net.ConnectionManager.Remote.ConnectionManagerCounters - -### connectionManager.prunableConns - - - -Dispatched by: -Net.ConnectionManager.Local.ConnectionManagerCounters - -### connectionManager.unidirectionalConns - - - -Dispatched by: -Net.ConnectionManager.Remote.ConnectionManagerCounters - -### connectionManager.unidirectionalConns - - - -Dispatched by: -Net.ConnectionManager.Local.ConnectionManagerCounters - -### currentKESPeriod - - - -Dispatched by: -Forge.StateInfo - -### currentKESPeriod - - - -Dispatched by: -Forge.Loop.ForgeStateUpdateError - -### delegMapSize - -> Delegation map size - - -Dispatched by: -LedgerMetrics - -### density - -> The actual number of blocks created over the maximum expected number of blocks that could be created over the span of the last @k@ blocks. - - -Dispatched by: -ChainDB.AddBlockEvent.AddedToCurrentChain -ChainDB.AddBlockEvent.SwitchedToAFork - -### epoch - -> In which epoch is the tip of the current chain. - - -Dispatched by: -ChainDB.AddBlockEvent.AddedToCurrentChain -ChainDB.AddBlockEvent.SwitchedToAFork - -### forgedSlotLast - -> Slot number of the last forged block - - -Dispatched by: -Forge.Loop.ForgedBlock - -### forging_enabled - -> A node without forger credentials or started as non-producing has forging disabled. - - -Dispatched by: -Startup.BlockForgingUpdate - -### forks - -> counter for forks - - -Dispatched by: -ChainDB.AddBlockEvent.SwitchedToAFork - -### haskell_compiler_major - -> Cardano compiler version information - - -Dispatched by: -Version.NodeVersion - -### haskell_compiler_minor - -> Cardano compiler version information - - -Dispatched by: -Version.NodeVersion - -### haskell_compiler_patch - -> Cardano compiler version information - - -Dispatched by: -Version.NodeVersion - -### inboundGovernor.Cold - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### inboundGovernor.Cold - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### inboundGovernor.Hot - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### inboundGovernor.Hot - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### inboundGovernor.Idle - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### inboundGovernor.Idle - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### inboundGovernor.Warm - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### inboundGovernor.Warm - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### localInboundGovernor.cold - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### localInboundGovernor.cold - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### localInboundGovernor.hot - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### localInboundGovernor.hot - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### localInboundGovernor.idle - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### localInboundGovernor.idle - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### localInboundGovernor.warm - - - -Dispatched by: -Net.InboundGovernor.Remote.InboundGovernorCounters - -### localInboundGovernor.warm - - - -Dispatched by: -Net.InboundGovernor.Local.InboundGovernorCounters - -### mempoolBytes - -> Byte size of the mempool - - -Dispatched by: -Mempool.AddedTx -Mempool.ManuallyRemovedTxs -Mempool.RejectedTx -Mempool.RemoveTxs - -### node.start.time - -> The UTC time this node was started represented in POSIX seconds. - - -Dispatched by: -Startup.Common - -### nodeCannotForge - -> How many times was this node unable to forge [a block]? - - -Dispatched by: -Forge.ThreadStats.ForgingStats - -### nodeIsLeader - -> How many times was this node slot leader? - - -Dispatched by: -Forge.ThreadStats.ForgingStats - -### operationalCertificateExpiryKESPeriod - - - -Dispatched by: -Forge.StateInfo - -### operationalCertificateExpiryKESPeriod - - - -Dispatched by: -Forge.Loop.ForgeStateUpdateError - -### operationalCertificateStartKESPeriod - - - -Dispatched by: -Forge.StateInfo - -### operationalCertificateStartKESPeriod - - - -Dispatched by: -Forge.Loop.ForgeStateUpdateError - -### peerSelection.ActiveBigLedgerPeers - -> Number of active big ledger peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveBigLedgerPeersDemotions - -> Number of active big ledger peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveBootstrapPeers - -> Number of active bootstrap peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveBootstrapPeersDemotions - -> Number of active bootstrap peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveLocalRootPeers - -> Number of active local root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveLocalRootPeersDemotions - -> Number of active local root peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveNonRootPeers - -> Number of active non root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActiveNonRootPeersDemotions - -> Number of active non root peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActivePeers - -> Number of active peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ActivePeersDemotions - -> Number of active peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.Cold - -> Number of cold peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ColdBigLedgerPeers - -> Number of cold big ledger peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ColdBigLedgerPeersPromotions - -> Number of cold big ledger peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ColdBootstrapPeersPromotions - -> Number of cold bootstrap peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ColdNonRootPeersPromotions - -> Number of cold non root peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.ColdPeersPromotions - -> Number of cold peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.EstablishedBigLedgerPeers - -> Number of established big ledger peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.EstablishedBootstrapPeers - -> Number of established bootstrap peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.EstablishedLocalRootPeers - -> Number of established local root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.EstablishedNonRootPeers - -> Number of established non root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.EstablishedPeers - -> Number of established peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.Hot - -> Number of hot peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.HotBigLedgerPeers - -> Number of hot big ledger peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.KnownBigLedgerPeers - -> Number of known big ledger peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.KnownBootstrapPeers - -> Number of known bootstrap peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.KnownLocalRootPeers - -> Number of known local root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.KnownNonRootPeers - -> Number of known non root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.KnownPeers - -> Number of known peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.LocalRoots - -> Numbers of warm & hot local roots - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.RootPeers - -> Number of root peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.Warm - -> Number of warm peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmBigLedgerPeers - -> Number of warm big ledger peers - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmBigLedgerPeersDemotions - -> Number of warm big ledger peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmBigLedgerPeersPromotions - -> Number of warm big ledger peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmBootstrapPeersDemotions - -> Number of warm bootstrap peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmBootstrapPeersPromotions - -> Number of warm bootstrap peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmLocalRootPeersPromotions - -> Number of warm local root peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmNonRootPeersDemotions - -> Number of warm non root peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmNonRootPeersPromotions - -> Number of warm non root peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmPeersDemotions - -> Number of warm peers demotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.WarmPeersPromotions - -> Number of warm peers promotions - - -Dispatched by: -Net.PeerSelection.Counters.Counters - -### peerSelection.churn.DecreasedActiveBigLedgerPeers.duration - - - -Dispatched by: -Net.PeerSelection.Selection.ChurnAction - -### peerSelection.churn.DecreasedActivePeers.duration - - - -Dispatched by: -Net.PeerSelection.Selection.ChurnAction - -### peerSelection.churn.DecreasedEstablishedBigLedgerPeers.duration - - - -Dispatched by: -Net.PeerSelection.Selection.ChurnAction - -### peerSelection.churn.DecreasedEstablishedPeers.duration - - - -Dispatched by: -Net.PeerSelection.Selection.ChurnAction - -### peerSelection.churn.DecreasedKnownBigLedgerPeers.duration - - - -Dispatched by: -Net.PeerSelection.Selection.ChurnAction - -### peerSelection.churn.DecreasedKnownPeers.duration - - - -Dispatched by: -Net.PeerSelection.Selection.ChurnAction - -### remainingKESPeriods - - - -Dispatched by: -Forge.StateInfo - -### remainingKESPeriods - - - -Dispatched by: -Forge.Loop.ForgeStateUpdateError - -### rpc.request.QueryService.ReadParams - -> Span for the ReadParams UTXORPC method. - - -Dispatched by: -RPC.QueryService.ReadParams.Span - -### rpc.request.QueryService.ReadUtxos - -> Span for the ReadUtxos UTXORPC method. - - -Dispatched by: -RPC.QueryService.ReadUtxos.Span - -### rpc.request.SubmitService.SubmitTx - -> Span for the SubmitTx UTXORPC method. - - -Dispatched by: -RPC.SubmitService.SubmitTx.Span - -### served.block - -> This counter metric indicates how many blocks this node has served. - - -Dispatched by: -BlockFetch.Server.SendBlock - -### served.block.latest - -> This counter metric indicates how many chain tip blocks this node has served. - - -Dispatched by: -BlockFetch.Server.SendBlock - -### served.header - -> A counter triggered only on header event with falling edge - - -Dispatched by: -ChainSync.ServerHeader.Update - -### served.header - -> A counter triggered only on header event with falling edge - - -Dispatched by: -ChainSync.ServerBlock.Update - -### slotInEpoch - -> Relative slot number of the tip of the current chain within the epoch.. - - -Dispatched by: -ChainDB.AddBlockEvent.AddedToCurrentChain -ChainDB.AddBlockEvent.SwitchedToAFork - -### slotNum - -> Number of slots in this chain fragment. - - -Dispatched by: -ChainDB.AddBlockEvent.AddedToCurrentChain -ChainDB.AddBlockEvent.SwitchedToAFork - -### slotsMissed - -> How many slots did this node miss? - - -Dispatched by: -Forge.ThreadStats.ForgingStats - -### submissions.accepted - - - -Dispatched by: -TxSubmission.TxInbound.Processed - -### submissions.rejected - - - -Dispatched by: -TxSubmission.TxInbound.Processed - -### submissions.submitted - - - -Dispatched by: -TxSubmission.TxInbound.Collected - -### systemStartTime - -> The UTC time this node was started. - - -Dispatched by: -Startup.Common - -### tipBlock - -> Values for hash, parent hash and issuer verification key hash - - -Dispatched by: -ChainDB.AddBlockEvent.AddedToCurrentChain -ChainDB.AddBlockEvent.SwitchedToAFork - -### txsInMempool - -> Transactions in mempool - - -Dispatched by: -Mempool.AddedTx -Mempool.ManuallyRemovedTxs -Mempool.RejectedTx -Mempool.RemoveTxs - -### txsMempoolTimeoutHard - -> Transactions that hard timed out in mempool - - -Dispatched by: -Net.Mux.Remote.ExceptionExit - -### txsMempoolTimeoutHard - -> Transactions that hard timed out in mempool - - -Dispatched by: -Net.Mux.Local.ExceptionExit - -### txsMempoolTimeoutSoft - -> Transactions that soft timed out in mempool - - -Dispatched by: -Mempool.RejectedTx - -### txsProcessedNum - - - -Dispatched by: -Mempool.ManuallyRemovedTxs - -### txsSyncDuration - -> Time to sync the mempool in ms after block adoption - - -Dispatched by: -Mempool.Synced - -### utxoSize - -> UTxO set size - - -Dispatched by: -LedgerMetrics -## Datapoints - -### NodeInfo - - -> Basic information about this node collected at startup -> -> _niName_: Name of the node. -> _niProtocol_: Protocol which this nodes uses. -> _niVersion_: Software version which this node is using. -> _niStartTime_: Start time of this node. -> _niSystemStartTime_: How long did the start of the node took. - - -### NodeStartupInfo - - -> Startup information about this node, required for RTView -> -> _suiEra_: Name of the current era. -> _suiSlotLength_: Slot length, in seconds. -> _suiEpochLength_: Epoch length, in slots. -> _suiSlotsPerKESPeriod_: KES period length, in slots. - -## Configuration: -``` -{ - "AppicationName": null, - "Forwarder": { - "maxReconnectDelay": 30, - "queueSize": 128, - "verbosity": "Minimum" - }, - "MetricsPrefix": "cardano.node.metrics.", - "Options": { - "": { - "backends": [ - "EKGBackend", - "Forwarder", - "PrometheusSimple 127.0.0.1 12798", - "Stdout HumanFormatColoured" - ], - "detail": "DNormal", - "severity": "Notice" - }, - "BlockFetch.Client.CompletedBlockFetch": { - "maxFrequency": 2 - }, - "BlockFetch.Decision": { - "severity": "Info" - }, - "ChainDB": { - "severity": "Info" - }, - "ChainDB.AddBlockEvent.AddBlockValidation": { - "severity": "Silence" - }, - "ChainDB.AddBlockEvent.AddBlockValidation.ValidCandidate": { - "maxFrequency": 2 - }, - "ChainDB.AddBlockEvent.AddedBlockToQueue": { - "maxFrequency": 2 - }, - "ChainDB.AddBlockEvent.AddedBlockToVolatileDB": { - "maxFrequency": 2 - }, - "ChainDB.CopyToImmutableDBEvent.CopiedBlockToImmutableDB": { - "maxFrequency": 2 - }, - "ChainDB.LedgerEvent.Forker": { - "severity": "Silence" - }, - "ChainSync.Client": { - "severity": "Warning" - }, - "Forge.Loop": { - "severity": "Info" - }, - "Forge.StateInfo": { - "severity": "Info" - }, - "Mempool": { - "severity": "Silence" - }, - "Mempool.AttemptAdd": { - "severity": "Silence" - }, - "Mempool.SyncNotNeeded": { - "severity": "Silence" - }, - "Net.ConnectionManager.Remote": { - "severity": "Info" - }, - "Net.InboundGovernor": { - "severity": "Warning" - }, - "Net.InboundGovernor.Remote": { - "severity": "Info" - }, - "Net.Mux.Remote": { - "severity": "Info" - }, - "Net.PeerSelection": { - "severity": "Info" - }, - "Resources": { - "severity": "Silence" - }, - "Startup.DiffusionInit": { - "severity": "Info" - } - }, - "PrometheusSimpleRun": null -} -``` -663 log messages, -159 metrics, -2 datapoints. - -ⓣ- This is the root of a tracer - -ⓢ- This is the root of a tracer that is silent because of the current configuration - -ⓜ- This is the root of a tracer, that provides metrics - -Generated at 2026-04-13 12:16:53.097436005 CEST, git commit hash f28b2ab394330fc5ac35893f1337230d1262b712, node version 10.7.1 diff --git a/bench/trace-schemas/trace-schemas-presentation.odp b/bench/trace-schemas/trace-schemas-presentation.odp deleted file mode 100644 index 0ae3414376029ac977538a997c5028542ec155b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46829 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 diff --git a/bench/trace-schemas/trace-schemas-presentation.pptx b/bench/trace-schemas/trace-schemas-presentation.pptx deleted file mode 100644 index d99683ba0dd3fa55e605ea231a3af597a34c2a58..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35056 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 z 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 9.12) proto-lens-tests proto-lens -source-repository-package - type: git - location: https://github.com/IntersectMBO/hermod-tracing - tag: e5d49217cc3cd1bc084c4a2b453f06f93bcb2006 - --sha256: sha256-eO7604L/xw+52K3jHLU2HbNz7kjCNUvL/DJmeOlP2lI= - subdir: - trace-dispatcher + diff --git a/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs b/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs deleted file mode 100644 index 840076510db..00000000000 --- a/cardano-node/src/Cardano/Node/Tracing/Tracers/Diffusion.hs +++ /dev/null @@ -1,993 +0,0 @@ -{-# LANGUAGE AllowAmbiguousTypes #-} -{-# LANGUAGE CPP #-} -{-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE FlexibleInstances #-} -{-# LANGUAGE GADTs #-} -{-# LANGUAGE LambdaCase #-} -{-# LANGUAGE NamedFieldPuns #-} -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} -{-# LANGUAGE TypeApplications #-} - - - -{-# OPTIONS_GHC -Wno-orphans #-} - -module Cardano.Node.Tracing.Tracers.Diffusion - ( txsMempoolTimeoutHardCounterName - , impliesMempoolTimeoutHard - ) where - - -import Cardano.Logging -import Cardano.Node.Configuration.TopologyP2P () -import Control.Exception (fromException) -import Ouroboros.Consensus.Mempool.API (ExnMempoolTimeout) -import qualified Ouroboros.Network.Diffusion.Types as Diff -import Ouroboros.Network.PeerSelection.LedgerPeers (NumberOfPeers (..), PoolStake (..), - TraceLedgerPeers (..)) -import qualified Ouroboros.Network.Protocol.Handshake.Type as HS - -import Data.Aeson (Value (String), (.=)) -import qualified Data.List as List -import Data.Text (Text, pack) -import Data.Typeable -import Formatting - -import qualified Network.Mux as Mux -#ifdef linux_HOST_OS -import Network.Mux.TCPInfo (StructTCPInfo (..)) -#endif -import Network.Mux.Types (SDUHeader (..), unRemoteClockModel) -import Network.TypedProtocol.Codec (AnyMessage (..)) - --------------------------------------------------------------------------------- --- Mux Tracer --------------------------------------------------------------------------------- - -instance (LogFormatting peer, LogFormatting tr, Typeable tr) => - LogFormatting (Mux.WithBearer peer tr) where - forMachine dtal (Mux.WithBearer b ev) = - mconcat [ "kind" .= (show . typeOf $ ev) - , "bearer" .= forMachine dtal b - , "event" .= forMachine dtal ev ] - forHuman (Mux.WithBearer b ev) = "With mux bearer " <> forHuman b - <> ". " <> forHuman ev - -instance MetaTrace tr => MetaTrace (Mux.WithBearer peer tr) where - namespaceFor (Mux.WithBearer _peer obj) = (nsCast . namespaceFor) obj - severityFor ns Nothing = severityFor (nsCast ns :: Namespace tr) Nothing - severityFor ns (Just (Mux.WithBearer _peer obj)) = - severityFor (nsCast ns) (Just obj) - privacyFor ns Nothing = privacyFor (nsCast ns :: Namespace tr) Nothing - privacyFor ns (Just (Mux.WithBearer _peer obj)) = - privacyFor (nsCast ns) (Just obj) - detailsFor ns Nothing = detailsFor (nsCast ns :: Namespace tr) Nothing - detailsFor ns (Just (Mux.WithBearer _peer obj)) = - detailsFor (nsCast ns) (Just obj) - documentFor ns = documentFor (nsCast ns :: Namespace tr) - metricsDocFor ns = metricsDocFor (nsCast ns :: Namespace tr) - allNamespaces = map nsCast (allNamespaces :: [Namespace tr]) - -instance LogFormatting Mux.BearerTrace where - forMachine _dtal Mux.TraceRecvHeaderStart = mconcat - [ "kind" .= String "Mux.TraceRecvHeaderStart" - , "msg" .= String "Bearer Receive Header Start" - ] - forMachine _dtal (Mux.TraceRecvHeaderEnd SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = mconcat - [ "kind" .= String "Mux.TraceRecvHeaderStart" - , "msg" .= String "Bearer Receive Header End" - , "timestamp" .= String (showTHex (unRemoteClockModel mhTimestamp)) - , "miniProtocolNum" .= String (showT mhNum) - , "miniProtocolDir" .= String (showT mhDir) - , "length" .= String (showT mhLength) - ] - forMachine _dtal (Mux.TraceRecvDeltaQObservation SDUHeader { mhTimestamp, mhLength } ts) = mconcat - [ "kind" .= String "Mux.TraceRecvDeltaQObservation" - , "msg" .= String "Bearer DeltaQ observation" - , "timeRemote" .= String (showT ts) - , "timeLocal" .= String (showTHex (unRemoteClockModel mhTimestamp)) - , "length" .= String (showT mhLength) - ] - forMachine _dtal (Mux.TraceRecvDeltaQSample d sp so dqs dqvm dqvs estR sdud) = mconcat - [ "kind" .= String "Mux.TraceRecvDeltaQSample" - , "msg" .= String "Bearer DeltaQ Sample" - , "duration" .= String (showT d) - , "packets" .= String (showT sp) - , "sumBytes" .= String (showT so) - , "DeltaQ_S" .= String (showT dqs) - , "DeltaQ_VMean" .= String (showT dqvm) - , "DeltaQ_VVar" .= String (showT dqvs) - , "DeltaQ_estR" .= String (showT estR) - , "sizeDist" .= String (showT sdud) - ] - forMachine _dtal (Mux.TraceRecvStart len) = mconcat - [ "kind" .= String "Mux.TraceRecvStart" - , "msg" .= String "Bearer Receive Start" - , "length" .= String (showT len) - ] - forMachine _dtal (Mux.TraceRecvRaw len) = mconcat - [ "kind" .= String "Mux.TraceRecvRaw" - , "msg" .= String "Bearer Receive Raw" - , "length" .= String (showT len) - ] - forMachine _dtal (Mux.TraceRecvEnd len) = mconcat - [ "kind" .= String "Mux.TraceRecvEnd" - , "msg" .= String "Bearer Receive End" - , "length" .= String (showT len) - ] - forMachine _dtal (Mux.TraceSendStart SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = mconcat - [ "kind" .= String "Mux.TraceSendStart" - , "msg" .= String "Bearer Send Start" - , "timestamp" .= String (showTHex (unRemoteClockModel mhTimestamp)) - , "miniProtocolNum" .= String (showT mhNum) - , "miniProtocolDir" .= String (showT mhDir) - , "length" .= String (showT mhLength) - ] - forMachine _dtal Mux.TraceSendEnd = mconcat - [ "kind" .= String "Mux.TraceSendEnd" - , "msg" .= String "Bearer Send End" - ] - forMachine _dtal Mux.TraceSDUReadTimeoutException = mconcat - [ "kind" .= String "Mux.TraceSDUReadTimeoutException" - , "msg" .= String "Timed out reading SDU" - ] - forMachine _dtal Mux.TraceSDUWriteTimeoutException = mconcat - [ "kind" .= String "Mux.TraceSDUWriteTimeoutException" - , "msg" .= String "Timed out writing SDU" - ] - forMachine _dtal Mux.TraceEmitDeltaQ = mempty -#ifdef linux_HOST_OS - forMachine _dtal (Mux.TraceTCPInfo StructTCPInfo - { tcpi_snd_mss, tcpi_rcv_mss, tcpi_lost, tcpi_retrans - , tcpi_rtt, tcpi_rttvar, tcpi_snd_cwnd } - len) = mconcat - [ "kind" .= String "Mux.TraceTCPInfo" - , "msg" .= String "TCPInfo" - , "rtt" .= (fromIntegral tcpi_rtt :: Word) - , "rttvar" .= (fromIntegral tcpi_rttvar :: Word) - , "snd_cwnd" .= (fromIntegral tcpi_snd_cwnd :: Word) - , "snd_mss" .= (fromIntegral tcpi_snd_mss :: Word) - , "rcv_mss" .= (fromIntegral tcpi_rcv_mss :: Word) - , "lost" .= (fromIntegral tcpi_lost :: Word) - , "retrans" .= (fromIntegral tcpi_retrans :: Word) - , "length" .= len - ] -#else - forMachine _dtal (Mux.TraceTCPInfo _ len) = mconcat - [ "kind" .= String "Mux.TraceTCPInfo" - , "msg" .= String "TCPInfo" - , "len" .= String (showT len) - ] -#endif - - forHuman Mux.TraceRecvHeaderStart = - "Bearer Receive Header Start" - forHuman (Mux.TraceRecvHeaderEnd SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = - sformat ("Bearer Receive Header End: ts:" % prefixHex % "(" % shown % ") " % shown % " len " % int) - (unRemoteClockModel mhTimestamp) mhNum mhDir mhLength - forHuman (Mux.TraceRecvDeltaQObservation SDUHeader { mhTimestamp, mhLength } ts) = - sformat ("Bearer DeltaQ observation: remote ts" % int % " local ts " % shown % " length " % int) - (unRemoteClockModel mhTimestamp) ts mhLength - forHuman (Mux.TraceRecvDeltaQSample d sp so dqs dqvm dqvs estR sdud) = - sformat ("Bearer DeltaQ Sample: duration " % fixed 3 % " packets " % int % " sumBytes " - % int % " DeltaQ_S " % fixed 3 % " DeltaQ_VMean " % fixed 3 % "DeltaQ_VVar " % fixed 3 - % " DeltaQ_estR " % fixed 3 % " sizeDist " % string) - d sp so dqs dqvm dqvs estR sdud - forHuman (Mux.TraceRecvStart len) = - sformat ("Bearer Receive Start: length " % int) len - forHuman (Mux.TraceRecvRaw len) = - sformat ("Bearer Receive Raw: length " % int) len - forHuman (Mux.TraceRecvEnd len) = - sformat ("Bearer Receive End: length " % int) len - forHuman (Mux.TraceSendStart SDUHeader { mhTimestamp, mhNum, mhDir, mhLength }) = - sformat ("Bearer Send Start: ts: " % prefixHex % " (" % shown % ") " % shown % " length " % int) - (unRemoteClockModel mhTimestamp) mhNum mhDir mhLength - forHuman Mux.TraceSendEnd = - "Bearer Send End" - forHuman Mux.TraceSDUReadTimeoutException = - "Timed out reading SDU" - forHuman Mux.TraceSDUWriteTimeoutException = - "Timed out writing SDU" - forHuman Mux.TraceEmitDeltaQ = mempty -#ifdef linux_HOST_OS - forHuman (Mux.TraceTCPInfo StructTCPInfo - { tcpi_snd_mss, tcpi_rcv_mss, tcpi_lost, tcpi_retrans - , tcpi_rtt, tcpi_rttvar, tcpi_snd_cwnd } - len) = - sformat ("TCPInfo rtt " % int % " rttvar " % int % " snd_cwnd " % int % - " snd_mss " % int % " rcv_mss " % int % " lost " % int % - " retrans " % int % " len " % int) - (fromIntegral tcpi_rtt :: Word) - (fromIntegral tcpi_rttvar :: Word) - (fromIntegral tcpi_snd_cwnd :: Word) - (fromIntegral tcpi_snd_mss :: Word) - (fromIntegral tcpi_rcv_mss :: Word) - (fromIntegral tcpi_lost :: Word) - (fromIntegral tcpi_retrans :: Word) - len -#else - forHuman (Mux.TraceTCPInfo _ len) = sformat ("TCPInfo len " % int) len -#endif - -instance MetaTrace Mux.BearerTrace where - namespaceFor Mux.TraceRecvHeaderStart {} = - Namespace [] ["RecvHeaderStart"] - namespaceFor Mux.TraceRecvHeaderEnd {} = - Namespace [] ["RecvHeaderEnd"] - namespaceFor Mux.TraceRecvStart {} = - Namespace [] ["RecvStart"] - namespaceFor Mux.TraceRecvRaw {} = - Namespace [] ["RecvRaw"] - namespaceFor Mux.TraceRecvEnd {} = - Namespace [] ["RecvEnd"] - namespaceFor Mux.TraceSendStart {} = - Namespace [] ["SendStart"] - namespaceFor Mux.TraceSendEnd = - Namespace [] ["SendEnd"] - namespaceFor Mux.TraceRecvDeltaQObservation {} = - Namespace [] ["RecvDeltaQObservation"] - namespaceFor Mux.TraceRecvDeltaQSample {} = - Namespace [] ["RecvDeltaQSample"] - namespaceFor Mux.TraceSDUReadTimeoutException = - Namespace [] ["SDUReadTimeoutException"] - namespaceFor Mux.TraceSDUWriteTimeoutException = - Namespace [] ["SDUWriteTimeoutException"] - namespaceFor Mux.TraceEmitDeltaQ = - Namespace [] ["TraceEmitDeltaQ"] - namespaceFor Mux.TraceTCPInfo {} = - Namespace [] ["TCPInfo"] - - severityFor (Namespace _ ["RecvHeaderStart"]) _ = Just Debug - severityFor (Namespace _ ["RecvRaw"]) _ = Just Debug - severityFor (Namespace _ ["RecvHeaderEnd"]) _ = Just Debug - severityFor (Namespace _ ["RecvStart"]) _ = Just Debug - severityFor (Namespace _ ["RecvEnd"]) _ = Just Debug - severityFor (Namespace _ ["SendStart"]) _ = Just Debug - severityFor (Namespace _ ["SendEnd"]) _ = Just Debug - severityFor (Namespace _ ["RecvDeltaQObservation"]) _ = Just Debug - severityFor (Namespace _ ["RecvDeltaQSample"]) _ = Just Debug - severityFor (Namespace _ ["SDUReadTimeoutException"]) _ = Just Notice - severityFor (Namespace _ ["SDUWriteTimeoutException"]) _ = Just Notice - severityFor (Namespace _ ["TCPInfo"]) _ = Just Debug - severityFor (Namespace _ ["TraceEmitDeltaQ"]) _ = Nothing - severityFor _ _ = Nothing - - documentFor (Namespace _ ["RecvHeaderStart"]) = Just - "Bearer receive header start." - documentFor (Namespace _ ["RecvRaw"]) = Just - "Bearer receive raw." - documentFor (Namespace _ ["RecvHeaderEnd"]) = Just - "Bearer receive header end." - documentFor (Namespace _ ["RecvStart"]) = Just - "Bearer receive start." - documentFor (Namespace _ ["RecvEnd"]) = Just - "Bearer receive end." - documentFor (Namespace _ ["SendStart"]) = Just - "Bearer send start." - documentFor (Namespace _ ["SendEnd"]) = Just - "Bearer send end." - documentFor (Namespace _ ["RecvDeltaQObservation"]) = Just - "Bearer DeltaQ observation." - documentFor (Namespace _ ["RecvDeltaQSample"]) = Just - "Bearer DeltaQ sample." - documentFor (Namespace _ ["SDUReadTimeoutException"]) = Just - "Timed out reading SDU." - documentFor (Namespace _ ["SDUWriteTimeoutException"]) = Just - "Timed out writing SDU." - documentFor (Namespace _ ["TraceEmitDeltaQ"]) = Nothing - documentFor (Namespace _ ["TCPInfo"]) = Just - "TCPInfo." - documentFor _ = Nothing - - allNamespaces = [ - Namespace [] ["RecvHeaderStart"] - , Namespace [] ["RecvRaw"] - , Namespace [] ["RecvHeaderEnd"] - , Namespace [] ["RecvStart"] - , Namespace [] ["RecvEnd"] - , Namespace [] ["SendStart"] - , Namespace [] ["SendEnd"] - , Namespace [] ["RecvDeltaQObservation"] - , Namespace [] ["RecvDeltaQSample"] - , Namespace [] ["SDUReadTimeoutException"] - , Namespace [] ["SDUWriteTimeoutException"] - , Namespace [] ["TraceEmitDeltaQ"] - , Namespace [] ["TCPInfo"] - ] - -instance LogFormatting Mux.ChannelTrace where - forMachine _dtal (Mux.TraceChannelRecvStart mid) = mconcat - [ "kind" .= String "Mux.TraceChannelRecvStart" - , "msg" .= String "Channel Receive Start" - , "miniProtocolNum" .= String (showT mid) - ] - forMachine _dtal (Mux.TraceChannelRecvEnd mid len) = mconcat - [ "kind" .= String "Mux.TraceChannelRecvEnd" - , "msg" .= String "Channel Receive End" - , "miniProtocolNum" .= String (showT mid) - , "length" .= String (showT len) - ] - forMachine _dtal (Mux.TraceChannelSendStart mid len) = mconcat - [ "kind" .= String "Mux.TraceChannelSendStart" - , "msg" .= String "Channel Send Start" - , "miniProtocolNum" .= String (showT mid) - , "length" .= String (showT len) - ] - forMachine _dtal (Mux.TraceChannelSendEnd mid) = mconcat - [ "kind" .= String "Mux.TraceChannelSendEnd" - , "msg" .= String "Channel Send End" - , "miniProtocolNum" .= String (showT mid) - ] - - forHuman (Mux.TraceChannelRecvStart mid) = - sformat ("Channel Receive Start on " % shown) mid - forHuman (Mux.TraceChannelRecvEnd mid len) = - sformat ("Channel Receive End on (" % shown % ") " % int) mid len - forHuman (Mux.TraceChannelSendStart mid len) = - sformat ("Channel Send Start on (" % shown % ") " % int) mid len - forHuman (Mux.TraceChannelSendEnd mid) = - sformat ("Channel Send End on " % shown) mid - -instance MetaTrace Mux.ChannelTrace where - namespaceFor Mux.TraceChannelRecvStart {} = - Namespace [] ["ChannelRecvStart"] - namespaceFor Mux.TraceChannelRecvEnd {} = - Namespace [] ["ChannelRecvEnd"] - namespaceFor Mux.TraceChannelSendStart {} = - Namespace [] ["ChannelSendStart"] - namespaceFor Mux.TraceChannelSendEnd {} = - Namespace [] ["ChannelSendEnd"] - - severityFor (Namespace _ ["ChannelRecvStart"]) _ = Just Debug - severityFor (Namespace _ ["ChannelRecvEnd"]) _ = Just Debug - severityFor (Namespace _ ["ChannelSendStart"]) _ = Just Debug - severityFor (Namespace _ ["ChannelSendEnd"]) _ = Just Debug - severityFor _ _ = Nothing - - documentFor (Namespace _ ["ChannelRecvStart"]) = Just - "Channel receive start." - documentFor (Namespace _ ["ChannelRecvEnd"]) = Just - "Channel receive end." - documentFor (Namespace _ ["ChannelSendStart"]) = Just - "Channel send start." - documentFor (Namespace _ ["ChannelSendEnd"]) = Just - "Channel send end." - documentFor _ = Nothing - - allNamespaces = [ - Namespace [] ["ChannelRecvStart"] - , Namespace [] ["ChannelRecvEnd"] - , Namespace [] ["ChannelSendStart"] - , Namespace [] ["ChannelSendEnd"] - ] - -txsMempoolTimeoutHardCounterName :: Text -txsMempoolTimeoutHardCounterName = "txsMempoolTimeoutHard" - -impliesMempoolTimeoutHard :: Mux.Trace -> Bool -impliesMempoolTimeoutHard = \case - Mux.TraceExceptionExit _mid _dir e - | Just _ <- fromException @ExnMempoolTimeout e - -> True - _ -> False - -instance LogFormatting Mux.Trace where - forMachine _dtal (Mux.TraceState new) = mconcat - [ "kind" .= String "Mux.TraceState" - , "msg" .= String "MuxState" - , "state" .= String (showT new) - ] - forMachine _dtal (Mux.TraceCleanExit mid dir) = mconcat - [ "kind" .= String "Mux.TraceCleanExit" - , "msg" .= String "Miniprotocol terminated cleanly" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - ] - forMachine _dtal (Mux.TraceExceptionExit mid dir exc) = mconcat - [ "kind" .= String "Mux.TraceExceptionExit" - , "msg" .= String "Miniprotocol terminated with exception" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - , "exception" .= String (showT exc) - ] - forMachine _dtal (Mux.TraceStartEagerly mid dir) = mconcat - [ "kind" .= String "Mux.TraceStartEagerly" - , "msg" .= String "Eagerly started" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - ] - forMachine _dtal (Mux.TraceStartOnDemand mid dir) = mconcat - [ "kind" .= String "Mux.TraceStartOnDemand" - , "msg" .= String "Preparing to start" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - ] - forMachine _dtal (Mux.TraceStartOnDemandAny mid dir) = mconcat - [ "kind" .= String "Mux.TraceStartOnDemandAny" - , "msg" .= String "Preparing to start" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - ] - forMachine _dtal (Mux.TraceStartedOnDemand mid dir) = mconcat - [ "kind" .= String "Mux.TraceStartedOnDemand" - , "msg" .= String "Started on demand" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - ] - forMachine _dtal (Mux.TraceTerminating mid dir) = mconcat - [ "kind" .= String "Mux.TraceTerminating" - , "msg" .= String "Terminating" - , "miniProtocolNum" .= String (showT mid) - , "miniProtocolDir" .= String (showT dir) - ] - forMachine _dtal Mux.TraceStopping = mconcat - [ "kind" .= String "Mux.TraceStopping" - , "msg" .= String "Mux stopping" - ] - forMachine _dtal Mux.TraceStopped = mconcat - [ "kind" .= String "Mux.TraceStopped" - , "msg" .= String "Mux stoppped" - ] - - forHuman (Mux.TraceState new) = - sformat ("State: " % shown) new - forHuman (Mux.TraceCleanExit mid dir) = - sformat ("Miniprotocol (" % shown % ") " % shown % " terminated cleanly") - mid dir - forHuman (Mux.TraceExceptionExit mid dir e) = - sformat ("Miniprotocol (" % shown % ") " % shown % - " terminated with exception " % shown) mid dir e - forHuman (Mux.TraceStartEagerly mid dir) = - sformat ("Eagerly started (" % shown % ") in " % shown) mid dir - forHuman (Mux.TraceStartOnDemand mid dir) = - sformat ("Preparing to start (" % shown % ") in " % shown) mid dir - forHuman (Mux.TraceStartOnDemandAny mid dir) = - sformat ("Preparing to start (" % shown % ") in " % shown) mid dir - forHuman (Mux.TraceStartedOnDemand mid dir) = - sformat ("Started on demand (" % shown % ") in " % shown) mid dir - forHuman (Mux.TraceTerminating mid dir) = - sformat ("Terminating (" % shown % ") in " % shown) mid dir - forHuman Mux.TraceStopping = "Mux stopping" - forHuman Mux.TraceStopped = "Mux stoppped" - - asMetrics = \case - Mux.TraceState{} -> [] - Mux.TraceCleanExit{} -> [] - ev@Mux.TraceExceptionExit{} -> - -- Somewhat awkward to "catch" this Consensus exception here, but - -- Diffusion Layer is indeed the ultimate manager of the per-peer - -- threads. - [ CounterM txsMempoolTimeoutHardCounterName Nothing - | impliesMempoolTimeoutHard ev - ] - Mux.TraceStartEagerly{} -> [] - Mux.TraceStartOnDemand{} -> [] - Mux.TraceStartOnDemandAny{} -> [] - Mux.TraceStartedOnDemand{} -> [] - Mux.TraceTerminating{} -> [] - Mux.TraceStopping{} -> [] - Mux.TraceStopped{} -> [] - -instance MetaTrace Mux.Trace where - namespaceFor Mux.TraceState {} = - Namespace [] ["State"] - namespaceFor Mux.TraceCleanExit {} = - Namespace [] ["CleanExit"] - namespaceFor Mux.TraceExceptionExit {} = - Namespace [] ["ExceptionExit"] - namespaceFor Mux.TraceStartEagerly {} = - Namespace [] ["StartEagerly"] - namespaceFor Mux.TraceStartOnDemand {} = - Namespace [] ["StartOnDemand"] - namespaceFor Mux.TraceStartOnDemandAny {} = - Namespace [] ["StartOnDemandAny"] - namespaceFor Mux.TraceStartedOnDemand {} = - Namespace [] ["StartedOnDemand"] - namespaceFor Mux.TraceTerminating {} = - Namespace [] ["Terminating"] - namespaceFor Mux.TraceStopping = - Namespace [] ["Stopping"] - namespaceFor Mux.TraceStopped = - Namespace [] ["Stopped"] - - severityFor (Namespace _ ["State"]) _ = Just Info - severityFor (Namespace _ ["CleanExit"]) _ = Just Notice - severityFor (Namespace _ ["ExceptionExit"]) _ = Just Notice - severityFor (Namespace _ ["StartEagerly"]) _ = Just Debug - severityFor (Namespace _ ["StartOnDemand"]) _ = Just Debug - severityFor (Namespace _ ["StartOnDemandAny"]) _ = Just Debug - severityFor (Namespace _ ["StartedOnDemand"]) _ = Just Debug - severityFor (Namespace _ ["Terminating"]) _ = Just Debug - severityFor (Namespace _ ["Stopping"]) _ = Just Debug - severityFor (Namespace _ ["Stopped"]) _ = Just Debug - severityFor _ _ = Nothing - - documentFor (Namespace _ ["State"]) = Just - "State." - documentFor (Namespace _ ["CleanExit"]) = Just - "Miniprotocol terminated cleanly." - documentFor (Namespace _ ["ExceptionExit"]) = Just - "Miniprotocol terminated with exception." - documentFor (Namespace _ ["StartEagerly"]) = Just - "Eagerly started." - documentFor (Namespace _ ["StartOnDemand"]) = Just - "Preparing to start." - documentFor (Namespace _ ["StartedOnDemand"]) = Just - "Started on demand." - documentFor (Namespace _ ["StartOnDemandAny"]) = Just - "Start whenever any other protocol has started." - documentFor (Namespace _ ["Terminating"]) = Just - "Terminating." - documentFor (Namespace _ ["Stopping"]) = Just - "Mux shutdown." - documentFor (Namespace _ ["Stopped"]) = Just - "Mux shutdown." - documentFor _ = Nothing - - metricsDocFor (Namespace _ ["State"]) = [] - metricsDocFor (Namespace _ ["CleanExit"]) = [] - metricsDocFor (Namespace _ ["ExceptionExit"]) = - [ (txsMempoolTimeoutHardCounterName, "Transactions that hard timed out in mempool") - ] - metricsDocFor (Namespace _ ["StartEagerly"]) = [] - metricsDocFor (Namespace _ ["StartOnDemand"]) = [] - metricsDocFor (Namespace _ ["StartedOnDemand"]) = [] - metricsDocFor (Namespace _ ["StartOnDemandAny"]) = [] - metricsDocFor (Namespace _ ["Terminating"]) = [] - metricsDocFor (Namespace _ ["Stopping"]) = [] - metricsDocFor (Namespace _ ["Stopped"]) = [] - metricsDocFor _ = [] - - allNamespaces = [ - Namespace [] ["State"] - , Namespace [] ["CleanExit"] - , Namespace [] ["ExceptionExit"] - , Namespace [] ["StartEagerly"] - , Namespace [] ["StartOnDemand"] - , Namespace [] ["StartOnDemandAny"] - , Namespace [] ["StartedOnDemand"] - , Namespace [] ["Terminating"] - , Namespace [] ["Stopping"] - , Namespace [] ["Stopped"] - ] - - --------------------------------------------------------------------------------- --- Handshake Tracer --------------------------------------------------------------------------------- - -instance (Show term, Show ntcVersion) => - LogFormatting (AnyMessage (HS.Handshake ntcVersion term)) where - forMachine _dtal (AnyMessageAndAgency stok msg) = - mconcat [ "kind" .= String kind - , "msg" .= (String . showT $ msg) - , "agency" .= String (pack $ show stok) - ] - where - kind = case msg of - HS.MsgProposeVersions {} -> "ProposeVersions" - HS.MsgReplyVersions {} -> "ReplyVersions" - HS.MsgQueryReply {} -> "QueryReply" - HS.MsgAcceptVersion {} -> "AcceptVersion" - HS.MsgRefuse {} -> "Refuse" - - forHuman (AnyMessageAndAgency stok msg) = - "Handshake (agency, message) = " <> "(" <> showT stok <> "," <> showT msg <> ")" - -instance MetaTrace (AnyMessage (HS.Handshake a b)) where - namespaceFor (AnyMessage msg) = Namespace [] $ case msg of - HS.MsgProposeVersions {} -> ["ProposeVersions"] - HS.MsgReplyVersions {} -> ["ReplyVersions"] - HS.MsgQueryReply {} -> ["QueryReply"] - HS.MsgAcceptVersion {} -> ["AcceptVersion"] - HS.MsgRefuse {} -> ["Refuse"] - - severityFor (Namespace _ [sym]) _ = case sym of - "ProposeVersions" -> Just Debug - "ReplyVersions" -> Just Debug - "QueryReply" -> Just Debug - "AcceptVersion" -> Just Debug - "Refuse" -> Just Debug - _otherwise -> Nothing - severityFor _ _ = Nothing - - documentFor (Namespace _ sym) = wrap . mconcat $ case sym of - ["ProposeVersions"] -> - [ "Propose versions together with version parameters. It must be" - , " encoded to a sorted list.." - ] - ["ReplyVersions"] -> - [ "`MsgReplyVersions` received as a response to 'MsgProposeVersions'. It" - , " is not supported to explicitly send this message. It can only be" - , " received as a copy of 'MsgProposeVersions' in a simultaneous open" - , " scenario." - ] - ["QueryReply"] -> - [ "`MsgQueryReply` received as a response to a handshake query in " - , " 'MsgProposeVersions' and lists the supported versions." - ] - ["AcceptVersion"] -> - [ "The remote end decides which version to use and sends chosen version." - , "The server is allowed to modify version parameters." - ] - ["Refuse"] -> ["It refuses to run any version."] - _otherwise -> [] :: [Text] - where - wrap it = case it of - "" -> Nothing - it' -> Just it' - - allNamespaces = [ - Namespace [] ["ProposeVersions"] - , Namespace [] ["ReplyVersions"] - , Namespace [] ["QueryReply"] - , Namespace [] ["AcceptVersion"] - , Namespace [] ["Refuse"] - ] - - --------------------------------------------------------------------------------- --- DiffusionInit Tracer --------------------------------------------------------------------------------- - -instance (Show ntnAddr, Show ntcAddr) => - LogFormatting (Diff.DiffusionTracer ntnAddr ntcAddr) where - forMachine _dtal (Diff.RunServer sockAddr) = mconcat - [ "kind" .= String "RunServer" - , "socketAddress" .= String (pack (show sockAddr)) - ] - - forMachine _dtal (Diff.RunLocalServer localAddress) = mconcat - [ "kind" .= String "RunLocalServer" - , "localAddress" .= String (pack (show localAddress)) - ] - forMachine _dtal (Diff.UsingSystemdSocket localAddress) = mconcat - [ "kind" .= String "UsingSystemdSocket" - , "path" .= String (pack . show $ localAddress) - ] - - forMachine _dtal (Diff.CreateSystemdSocketForSnocketPath localAddress) = mconcat - [ "kind" .= String "CreateSystemdSocketForSnocketPath" - , "path" .= String (pack . show $ localAddress) - ] - forMachine _dtal (Diff.CreatedLocalSocket localAddress) = mconcat - [ "kind" .= String "CreatedLocalSocket" - , "path" .= String (pack . show $ localAddress) - ] - forMachine _dtal (Diff.ConfiguringLocalSocket localAddress socket) = mconcat - [ "kind" .= String "ConfiguringLocalSocket" - , "path" .= String (pack . show $ localAddress) - , "socket" .= String (pack (show socket)) - ] - forMachine _dtal (Diff.ListeningLocalSocket localAddress socket) = mconcat - [ "kind" .= String "ListeningLocalSocket" - , "path" .= String (pack . show $ localAddress) - , "socket" .= String (pack (show socket)) - ] - forMachine _dtal (Diff.LocalSocketUp localAddress fd) = mconcat - [ "kind" .= String "LocalSocketUp" - , "path" .= String (pack . show $ localAddress) - , "socket" .= String (pack (show fd)) - ] - forMachine _dtal (Diff.CreatingServerSocket socket) = mconcat - [ "kind" .= String "CreatingServerSocket" - , "socket" .= String (pack (show socket)) - ] - forMachine _dtal (Diff.ListeningServerSocket socket) = mconcat - [ "kind" .= String "ListeningServerSocket" - , "socket" .= String (pack (show socket)) - ] - forMachine _dtal (Diff.ServerSocketUp socket) = mconcat - [ "kind" .= String "ServerSocketUp" - , "socket" .= String (pack (show socket)) - ] - forMachine _dtal (Diff.ConfiguringServerSocket socket) = mconcat - [ "kind" .= String "ConfiguringServerSocket" - , "socket" .= String (pack (show socket)) - ] - forMachine _dtal (Diff.UnsupportedLocalSystemdSocket path) = mconcat - [ "kind" .= String "UnsupportedLocalSystemdSocket" - , "path" .= String (pack (show path)) - ] - forMachine _dtal Diff.UnsupportedReadySocketCase = mconcat - [ "kind" .= String "UnsupportedReadySocketCase" - ] - forMachine _dtal (Diff.DiffusionErrored exception) = mconcat - [ "kind" .= String "DiffusionErrored" - , "error" .= String (pack (show exception)) - ] - forMachine _dtal (Diff.SystemdSocketConfiguration config) = mconcat - [ "kind" .= String "SystemdSocketConfiguration" - , "path" .= String (pack (show config)) - ] - -instance MetaTrace (Diff.DiffusionTracer ntnAddr ntcAddr) where - namespaceFor Diff.RunServer {} = - Namespace [] ["RunServer"] - namespaceFor Diff.RunLocalServer {} = - Namespace [] ["RunLocalServer"] - namespaceFor Diff.UsingSystemdSocket {} = - Namespace [] ["UsingSystemdSocket"] - namespaceFor Diff.CreateSystemdSocketForSnocketPath {} = - Namespace [] ["CreateSystemdSocketForSnocketPath"] - namespaceFor Diff.CreatedLocalSocket {} = - Namespace [] ["CreatedLocalSocket"] - namespaceFor Diff.ConfiguringLocalSocket {} = - Namespace [] ["ConfiguringLocalSocket"] - namespaceFor Diff.ListeningLocalSocket {} = - Namespace [] ["ListeningLocalSocket"] - namespaceFor Diff.LocalSocketUp {} = - Namespace [] ["LocalSocketUp"] - namespaceFor Diff.CreatingServerSocket {} = - Namespace [] ["CreatingServerSocket"] - namespaceFor Diff.ListeningServerSocket {} = - Namespace [] ["ListeningServerSocket"] - namespaceFor Diff.ServerSocketUp {} = - Namespace [] ["ServerSocketUp"] - namespaceFor Diff.ConfiguringServerSocket {} = - Namespace [] ["ConfiguringServerSocket"] - namespaceFor Diff.UnsupportedLocalSystemdSocket {} = - Namespace [] ["UnsupportedLocalSystemdSocket"] - namespaceFor Diff.UnsupportedReadySocketCase {} = - Namespace [] ["UnsupportedReadySocketCase"] - namespaceFor Diff.DiffusionErrored {} = - Namespace [] ["DiffusionErrored"] - namespaceFor Diff.SystemdSocketConfiguration {} = - Namespace [] ["SystemdSocketConfiguration"] - - severityFor (Namespace _ ["RunServer"]) _ = Just Info - severityFor (Namespace _ ["RunLocalServer"]) _ = Just Info - severityFor (Namespace _ ["UsingSystemdSocket"]) _ = Just Info - severityFor (Namespace _ ["CreateSystemdSocketForSnocketPath"]) _ = Just Info - severityFor (Namespace _ ["CreatedLocalSocket"]) _ = Just Info - severityFor (Namespace _ ["ConfiguringLocalSocket"]) _ = Just Info - severityFor (Namespace _ ["ListeningLocalSocket"]) _ = Just Info - severityFor (Namespace _ ["LocalSocketUp"]) _ = Just Info - severityFor (Namespace _ ["CreatingServerSocket"]) _ = Just Info - severityFor (Namespace _ ["ListeningServerSocket"]) _ = Just Info - severityFor (Namespace _ ["ServerSocketUp"]) _ = Just Info - severityFor (Namespace _ ["ConfiguringServerSocket"]) _ = Just Info - severityFor (Namespace _ ["UnsupportedLocalSystemdSocket"]) _ = Just Warning - severityFor (Namespace _ ["UnsupportedReadySocketCase"]) _ = Just Info - severityFor (Namespace _ ["DiffusionErrored"]) _ = Just Critical - severityFor (Namespace _ ["SystemdSocketConfiguration"]) _ = Just Warning - severityFor _ _ = Nothing - - documentFor (Namespace _ ["RunServer"]) = Just - "RunServer" - documentFor (Namespace _ ["RunLocalServer"]) = Just - "RunLocalServer" - documentFor (Namespace _ ["UsingSystemdSocket"]) = Just - "UsingSystemdSocket" - documentFor (Namespace _ ["CreateSystemdSocketForSnocketPath"]) = Just - "CreateSystemdSocketForSnocketPath" - documentFor (Namespace _ ["CreatedLocalSocket"]) = Just - "CreatedLocalSocket" - documentFor (Namespace _ ["ConfiguringLocalSocket"]) = Just - "ConfiguringLocalSocket" - documentFor (Namespace _ ["ListeningLocalSocket"]) = Just - "ListeningLocalSocket" - documentFor (Namespace _ ["LocalSocketUp"]) = Just - "LocalSocketUp" - documentFor (Namespace _ ["CreatingServerSocket"]) = Just - "CreatingServerSocket" - documentFor (Namespace _ ["ListeningServerSocket"]) = Just - "ListeningServerSocket" - documentFor (Namespace _ ["ServerSocketUp"]) = Just - "ServerSocketUp" - documentFor (Namespace _ ["ConfiguringServerSocket"]) = Just - "ConfiguringServerSocket" - documentFor (Namespace _ ["UnsupportedLocalSystemdSocket"]) = Just - "UnsupportedLocalSystemdSocket" - documentFor (Namespace _ ["UnsupportedReadySocketCase"]) = Just - "UnsupportedReadySocketCase" - documentFor (Namespace _ ["DiffusionErrored"]) = Just - "DiffusionErrored" - documentFor (Namespace _ ["SystemdSocketConfiguration"]) = Just - "SystemdSocketConfiguration" - documentFor _ = Nothing - - allNamespaces = [ - Namespace [] ["RunServer"] - , Namespace [] ["RunLocalServer"] - , Namespace [] ["UsingSystemdSocket"] - , Namespace [] ["CreateSystemdSocketForSnocketPath"] - , Namespace [] ["CreatedLocalSocket"] - , Namespace [] ["ConfiguringLocalSocket"] - , Namespace [] ["ListeningLocalSocket"] - , Namespace [] ["LocalSocketUp"] - , Namespace [] ["CreatingServerSocket"] - , Namespace [] ["ListeningServerSocket"] - , Namespace [] ["ServerSocketUp"] - , Namespace [] ["ConfiguringServerSocket"] - , Namespace [] ["UnsupportedLocalSystemdSocket"] - , Namespace [] ["UnsupportedReadySocketCase"] - , Namespace [] ["DiffusionErrored"] - , Namespace [] ["SystemdSocketConfiguration"] - ] - --------------------------------------------------------------------------------- --- LedgerPeers Tracer --------------------------------------------------------------------------------- - -instance LogFormatting TraceLedgerPeers where - forMachine _dtal (PickedLedgerPeer addr _ackStake stake) = - mconcat - [ "kind" .= String "PickedLedgerPeer" - , "address" .= show addr - , "relativeStake" .= (realToFrac (unPoolStake stake) :: Double) - ] - forMachine _dtal (PickedLedgerPeers (NumberOfPeers n) addrs) = - mconcat - [ "kind" .= String "PickedLedgerPeers" - , "desiredCount" .= n - , "count" .= List.length addrs - , "addresses" .= show addrs - ] - forMachine _dtal (PickedBigLedgerPeer addr _ackStake stake) = - mconcat - [ "kind" .= String "PickedBigLedgerPeer" - , "address" .= show addr - , "relativeStake" .= (realToFrac (unPoolStake stake) :: Double) - ] - forMachine _dtal (PickedBigLedgerPeers (NumberOfPeers n) addrs) = - mconcat - [ "kind" .= String "PickedBigLedgerPeers" - , "desiredCount" .= n - , "count" .= List.length addrs - , "addresses" .= show addrs - ] - forMachine _dtal (FetchingNewLedgerState cnt bigCnt) = - mconcat - [ "kind" .= String "FetchingNewLedgerState" - , "numberOfLedgerPeers" .= cnt - , "numberOfBigLedgerPeers" .= bigCnt - ] - forMachine _dtal DisabledLedgerPeers = - mconcat - [ "kind" .= String "DisabledLedgerPeers" - ] - forMachine _dtal (TraceUseLedgerPeers ulp) = - mconcat - [ "kind" .= String "UseLedgerPeers" - , "useLedgerPeers" .= ulp - ] - forMachine _dtal WaitingOnRequest = - mconcat - [ "kind" .= String "WaitingOnRequest" - ] - forMachine _dtal (RequestForPeers (NumberOfPeers np)) = - mconcat - [ "kind" .= String "RequestForPeers" - , "numberOfPeers" .= np - ] - forMachine _dtal (ReusingLedgerState cnt age) = - mconcat - [ "kind" .= String "ReusingLedgerState" - , "numberOfPools" .= cnt - , "ledgerStateAge" .= age - ] - forMachine _dtal FallingBackToPublicRootPeers = - mconcat - [ "kind" .= String "FallingBackToPublicRootPeers" - ] - forMachine _dtal (NotEnoughLedgerPeers (NumberOfPeers target) numOfLedgerPeers) = - mconcat - [ "kind" .= String "NotEnoughLedgerPeers" - , "target" .= target - , "numOfLedgerPeers" .= numOfLedgerPeers - ] - forMachine _dtal (NotEnoughBigLedgerPeers (NumberOfPeers target) numOfBigLedgerPeers) = - mconcat - [ "kind" .= String "NotEnoughBigLedgerPeers" - , "target" .= target - , "numOfBigLedgerPeers" .= numOfBigLedgerPeers - ] - forMachine _dtal (TraceLedgerPeersDomains daps) = - mconcat - [ "kind" .= String "TraceLedgerPeersDomains" - , "domainAccessPoints" .= daps - ] - forMachine _dtal UsingBigLedgerPeerSnapshot = - mconcat - [ "kind" .= String "UsingBigLedgerPeerSnapshot" - ] - -instance MetaTrace TraceLedgerPeers where - namespaceFor PickedLedgerPeer {} = - Namespace [] ["PickedLedgerPeer"] - namespaceFor PickedLedgerPeers {} = - Namespace [] ["PickedLedgerPeers"] - namespaceFor PickedBigLedgerPeer {} = - Namespace [] ["PickedBigLedgerPeer"] - namespaceFor PickedBigLedgerPeers {} = - Namespace [] ["PickedBigLedgerPeers"] - namespaceFor FetchingNewLedgerState {} = - Namespace [] ["FetchingNewLedgerState"] - namespaceFor DisabledLedgerPeers {} = - Namespace [] ["DisabledLedgerPeers"] - namespaceFor TraceUseLedgerPeers {} = - Namespace [] ["TraceUseLedgerPeers"] - namespaceFor WaitingOnRequest {} = - Namespace [] ["WaitingOnRequest"] - namespaceFor RequestForPeers {} = - Namespace [] ["RequestForPeers"] - namespaceFor ReusingLedgerState {} = - Namespace [] ["ReusingLedgerState"] - namespaceFor FallingBackToPublicRootPeers {} = - Namespace [] ["FallingBackToPublicRootPeers"] - namespaceFor NotEnoughLedgerPeers {} = - Namespace [] ["NotEnoughLedgerPeers"] - namespaceFor NotEnoughBigLedgerPeers {} = - Namespace [] ["NotEnoughBigLedgerPeers"] - namespaceFor TraceLedgerPeersDomains {} = - Namespace [] ["TraceLedgerPeersDomains"] - namespaceFor UsingBigLedgerPeerSnapshot {} = - Namespace [] ["UsingBigLedgerPeerSnapshot"] - - severityFor (Namespace _ ["PickedLedgerPeer"]) _ = Just Debug - severityFor (Namespace _ ["PickedLedgerPeers"]) _ = Just Info - severityFor (Namespace _ ["PickedBigLedgerPeer"]) _ = Just Debug - severityFor (Namespace _ ["PickedBigLedgerPeers"]) _ = Just Info - severityFor (Namespace _ ["FetchingNewLedgerState"]) _ = Just Info - severityFor (Namespace _ ["DisabledLedgerPeers"]) _ = Just Info - severityFor (Namespace _ ["TraceUseLedgerAfter"]) _ = Just Info - severityFor (Namespace _ ["WaitingOnRequest"]) _ = Just Debug - severityFor (Namespace _ ["RequestForPeers"]) _ = Just Debug - severityFor (Namespace _ ["ReusingLedgerState"]) _ = Just Debug - severityFor (Namespace _ ["FallingBackToPublicRootPeers"]) _ = Just Info - severityFor (Namespace _ ["NotEnoughLedgerPeers"]) _ = Just Warning - severityFor (Namespace _ ["NotEnoughBigLedgerPeers"]) _ = Just Warning - severityFor (Namespace _ ["TraceLedgerPeersDomains"]) _ = Just Debug - severityFor (Namespace _ ["UsingBigLedgerPeerSnapshot"]) _ = Just Debug - severityFor _ _ = Nothing - - documentFor (Namespace _ ["PickedLedgerPeer"]) = Just - "Trace for a peer picked with accumulated and relative stake of its pool." - documentFor (Namespace _ ["PickedLedgerPeers"]) = Just - "Trace for the number of peers we wanted to pick and the list of peers picked." - documentFor (Namespace _ ["PickedBigLedgerPeer"]) = Just - "Trace for a big ledger peer picked with accumulated and relative stake of its pool." - documentFor (Namespace _ ["PickedBigLedgerPeers"]) = Just - "Trace for the number of big ledger peers we wanted to pick and the list of peers picked." - documentFor (Namespace _ ["FetchingNewLedgerState"]) = Just $ mconcat - [ "Trace for fetching a new list of peers from the ledger. Int is the number of peers" - , " returned." - ] - documentFor (Namespace _ ["DisabledLedgerPeers"]) = Just - "Trace for when getting peers from the ledger is disabled, that is DontUseLedger." - documentFor (Namespace _ ["TraceUseLedgerAfter"]) = Just - "Trace UseLedgerAfter value." - documentFor (Namespace _ ["WaitingOnRequest"]) = Just - "" - documentFor (Namespace _ ["RequestForPeers"]) = Just - "RequestForPeers (NumberOfPeers 1)" - documentFor (Namespace _ ["ReusingLedgerState"]) = Just - "" - documentFor (Namespace _ ["FallingBackToPublicRootPeers"]) = Just - "" - documentFor (Namespace _ ["TraceLedgerPeersDomains"]) = Just - "" - documentFor (Namespace _ ["UsingBigLedgerPeerSnapshot"]) = Just $ mconcat - [ "Trace for when a request for big ledger peers is fulfilled from the snapshot file" - , " specified in the topology file."] - documentFor _ = Nothing - - allNamespaces = [ - Namespace [] ["PickedLedgerPeer"] - , Namespace [] ["PickedLedgerPeers"] - , Namespace [] ["PickedBigLedgerPeer"] - , Namespace [] ["PickedBigLedgerPeers"] - , Namespace [] ["FetchingNewLedgerState"] - , Namespace [] ["DisabledLedgerPeers"] - , Namespace [] ["TraceUseLedgerAfter"] - , Namespace [] ["WaitingOnRequest"] - , Namespace [] ["RequestForPeers"] - , Namespace [] ["ReusingLedgerState"] - , Namespace [] ["FallingBackToPublicRootPeers"] - , Namespace [] ["NotEnoughLedgerPeers"] - , Namespace [] ["NotEnoughBigLedgerPeers"] - , Namespace [] ["TraceLedgerPeersDomains"] - , Namespace [] ["UsingBigLedgerPeerSnapshot"] - ] diff --git a/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs b/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs deleted file mode 100644 index e7d6f1b49c1..00000000000 --- a/trace-dispatcher/src/Cardano/Logging/DocuGenerator.hs +++ /dev/null @@ -1,610 +0,0 @@ -{-# LANGUAGE DerivingVia #-} -{-# LANGUAGE RecordWildCards #-} -{-# LANGUAGE ScopedTypeVariables #-} - -{- HLINT ignore "Use map" -} -{- HLINT ignore "Use map with tuple-section" -} - -module Cardano.Logging.DocuGenerator ( - -- First call documentTracer for every tracer and then - -- docuResultToText on all results - documentTracer - , documentTracer' - , docuResultsToText - , docuResultsToNamespaces - , docuResultsToMetricsHelptext - -- Callbacks - , docTracer - , docTracerDatapoint - , docIt - , addFiltered - , addLimiter - , addSilent - , addDocumentedNamespace - , DocuResult - , DocTracer(..) -) where - -import Cardano.Logging.ConfigurationParser () -import Cardano.Logging.DocuGenerator.Tree -import Cardano.Logging.DocuGenerator.Result (DocuResult (..)) -import qualified Cardano.Logging.DocuGenerator.Result as DocuResult -import Cardano.Logging.Types - -import Prelude hiding (lines, unlines) - -import Control.Monad (mfilter) -import Control.Monad.IO.Class (MonadIO, liftIO) -import qualified Control.Tracer as TR -import Data.Aeson (ToJSON) -import qualified Data.Aeson.Encode.Pretty as AE -import Data.IORef (modifyIORef, newIORef, readIORef) -import Data.List (find, group, groupBy, intersperse, isPrefixOf, nub, sort, sortBy) -import qualified Data.Map.Strict as Map -import Data.Maybe (fromJust, fromMaybe, mapMaybe) -import Data.Text (split) -import Data.Text as T (Text, empty, intercalate, lines, pack, stripPrefix, toLower, - unlines) -import Data.Text.Internal.Builder (toLazyText) -import Data.Text.Lazy (toStrict) -import Data.Text.Lazy.Builder (Builder, fromString, fromText, singleton) - -type InconsistencyWarning = Text - -utf16CircledT :: Text -utf16CircledT = "\x24E3" - -utf16CircledS :: Text -utf16CircledS = "\x24E2" - -utf16CircledM :: Text -utf16CircledM = "\x24DC" - --- | Convenience function for adding a namespace prefix to a documented -addDocumentedNamespace :: [Text] -> Documented a -> Documented a -addDocumentedNamespace out (Documented list) = - Documented $ map - (\ dm@DocMsg {} -> dm {dmNamespace = nsReplacePrefix out (dmNamespace dm)}) - list - -data DocTracer = DocTracer { - dtTracerNames :: [[Text]] - , dtSilent :: [[Text]] - , dtNoMetrics :: [[Text]] - , dtBuilderList :: [([Text], DocuResult)] - , dtWarnings :: [InconsistencyWarning] -} deriving (Show) - -instance Semigroup DocTracer where - dtl <> dtr = DocTracer - (dtTracerNames dtl <> dtTracerNames dtr) - (dtSilent dtl <> dtSilent dtr) - (dtNoMetrics dtl <> dtNoMetrics dtr) - (dtBuilderList dtl <> dtBuilderList dtr) - (dtWarnings dtl <> dtWarnings dtr) - -documentTracer' :: forall a a1. - MetaTrace a - => (Trace IO a1 -> IO (Trace IO a)) - -> Trace IO a1 - -> IO DocTracer -documentTracer' hook tracer = do - tr' <- hook tracer - documentTracer tr' - --- This function calls document tracers and returns a DocTracer result -documentTracer :: forall a. - MetaTrace a - => Trace IO a - -> IO DocTracer -documentTracer tracer = do - DocCollector docRef <- documentTracersRun [tracer] - items <- fmap Map.toList (liftIO (readIORef docRef)) - let sortedItems = sortBy - (\ (_,l) (_,r) -> compare (ldNamespace l) (ldNamespace r)) - items - let messageDocs = map (\(i, ld) -> case ldNamespace ld of - (prn,pon) : _ -> (prn ++ pon, documentItem (i, ld)) - [] -> (["No ns"], documentItem (i, ld))) sortedItems - metricsItems = map snd $ filter (not . Map.null . ldMetricsDoc . snd) sortedItems - metricsDocs = documentMetrics metricsItems - tracerName = case sortedItems of - ((_i, ld) : _) -> case ldNamespace ld of - (prn, _pon) : _ -> prn - [] -> [] - [] -> [] - silent = case sortedItems of - ((_i, ld) : _) -> ldSilent ld - [] -> False - hasNoMetrics = null metricsItems - warnings = concatMap (\(i, ld) -> case ldNamespace ld of - (_,_): _ -> warningItem (i, ld) - [] -> (pack "No ns for " <> ldDoc ld) : - warningItem (i, ld)) sortedItems - pure $ DocTracer - [tracerName] - [tracerName | silent] - [tracerName | hasNoMetrics] - (messageDocs ++ metricsDocs) - warnings - - where - documentItem :: (Int, LogDoc) -> DocuResult - documentItem (_idx, ld@LogDoc {..}) = - case ldBackends of - [DatapointBackend] -> DocuDatapoint $ - mconcat $ intersperse (fromText "\n\n") - [ namespacesBuilder (nub ldNamespace) - , accentuated ldDoc - ] - _ -> DocuTracer $ - mconcat $ intersperse (fromText "\n\n") - [ namespacesBuilder (nub ldNamespace) - , accentuated ldDoc - , propertiesBuilder ld - , configBuilder ld - ] - - warningItem :: (Int, LogDoc) -> [InconsistencyWarning] - warningItem (_idx, ld@LogDoc {..}) = - case ldBackends of - [DatapointBackend] -> namespacesWarning (nub ldNamespace) ld - _ -> namespacesWarning (nub ldNamespace) ld - ++ propertiesWarning ld - - documentMetrics :: [LogDoc] -> [([Text],DocuResult)] - documentMetrics logDocs = - let nameCommentNamespaceList = - concatMap (\ld -> zip (Map.toList (ldMetricsDoc ld)) (repeat (ldNamespace ld))) logDocs - sortedNameCommentNamespaceList = - sortBy (\a b -> compare ((fst . fst) a) ((fst . fst) b)) nameCommentNamespaceList - groupedNameCommentNamespaceList = - groupBy (\a b -> (fst . fst) a == (fst . fst) b) sortedNameCommentNamespaceList - in mapMaybe documentMetrics' groupedNameCommentNamespaceList - - documentMetrics' :: [( (Text, Text) , [([Text],[Text])] )] -> Maybe ([Text], DocuResult) - documentMetrics' ncns@(((name, comment), _) : _tail) = - Just ([name], DocuMetric - $ mconcat $ intersperse (fromText "\n\n") - [ metricToBuilder (name,comment) - , namespacesMetricsBuilder (nub (concatMap snd ncns)) - ]) - documentMetrics' [] = Nothing - - namespacesBuilder :: [([Text], [Text])] -> Builder - namespacesBuilder [ns] = namespaceBuilder ns - namespacesBuilder [] = fromText "__Warning__: namespace missing" - namespacesBuilder nsl = - mconcat (intersperse (singleton '\n') (map namespaceBuilder nsl)) - - namespaceBuilder :: ([Text], [Text]) -> Builder - namespaceBuilder (nsPr, nsPo) = fromText "### " <> - mconcat (intersperse (singleton '.') (map fromText (nsPr ++ nsPo))) - - namespacesMetricsBuilder :: [ ([Text], [Text])] -> Builder - namespacesMetricsBuilder [ns] = fromText "Dispatched by: \n" <> namespaceMetricsBuilder ns - namespacesMetricsBuilder [] = mempty - namespacesMetricsBuilder nsl = fromText "Dispatched by: \n" <> - mconcat (intersperse (singleton '\n') (map namespaceMetricsBuilder nsl)) - - namespaceMetricsBuilder :: ([Text], [Text]) -> Builder - namespaceMetricsBuilder (nsPr, nsPo) = mconcat (intersperse (singleton '.') - (map fromText (nsPr ++ nsPo))) - - namespacesWarning :: [([Text], [Text])] -> LogDoc -> [InconsistencyWarning] - namespacesWarning [] ld = ["Namespace missing " <> ldDoc ld] - namespacesWarning _ _ = [] - - propertiesBuilder :: LogDoc -> Builder - propertiesBuilder LogDoc {..} = - case ldSeverityCoded of - Just s -> fromText "Severity: " <> asCode (fromString (show s)) <> "\n" - Nothing -> fromText "Severity missing: " <> "\n" - <> - case ldPrivacyCoded of - Just p -> fromText "Privacy: " <> asCode (fromString (show p)) <> "\n" - Nothing -> fromText "Privacy missing: " <> "\n" - <> - case ldDetailsCoded of - Just d -> fromText "Details: " <> asCode (fromString (show d)) <> "\n" - Nothing -> fromText "Details missing: " <> "\n" - - propertiesWarning :: LogDoc ->[InconsistencyWarning] - propertiesWarning LogDoc {..} = - case ldSeverityCoded of - Just _s -> [] - Nothing -> map (\ns -> pack "Severity missing: " <> nsRawToText ns) ldNamespace - <> - case ldPrivacyCoded of - Just _p -> [] - Nothing -> map (\ns -> pack "Privacy missing: " <> nsRawToText ns) ldNamespace - <> - case ldDetailsCoded of - Just _d -> [] - Nothing -> map (\ns -> pack "Details missing: " <> nsRawToText ns) ldNamespace - - configBuilder :: LogDoc -> Builder - configBuilder LogDoc {..} = - fromText "From current configuration:\n" - <> case nub ldDetails of - [] -> mempty - [d] -> if Just d /= ldDetailsCoded - then fromText "Details: " - <> asCode (fromString (show d)) - else mempty - l -> fromText "Details: " - <> mconcat (intersperse (fromText ",\n ") - (map (asCode . fromString . show) l)) - <> fromText "\n" - <> backendsBuilder (nub ldBackends) - <> fromText "\n" - <> filteredBuilder (nub ldFiltered) ldSeverityCoded - <> limiterBuilder (nub ldLimiter) - - backendsBuilder :: [BackendConfig] -> Builder - backendsBuilder [] = fromText "No backends found" - backendsBuilder l = fromText "Backends:\n " - <> mconcat (intersperse (fromText ",\n ") - (map backendFormatToText l)) - - backendFormatToText :: BackendConfig -> Builder - backendFormatToText be = asCode (fromString (show be)) - - filteredBuilder :: [SeverityF] -> Maybe SeverityS -> Builder - filteredBuilder [] _ = mempty - filteredBuilder _ Nothing = mempty - filteredBuilder l (Just r) = - fromText "Filtered " - <> case l of - [SeverityF (Just lh)] -> - if fromEnum r >= fromEnum lh - then (asCode . fromString) "Visible" - else (asCode . fromString) "Invisible" - [SeverityF Nothing] -> "Invisible" - _ -> mempty - <> fromText " by config value: " - <> mconcat (intersperse (fromText ", ") - (map (asCode . fromString . show) l)) - - limiterBuilder :: - [(Text, Double)] - -> Builder - limiterBuilder [] = mempty - limiterBuilder l = - mconcat (intersperse (fromText ", ") - (map (\ (n, d) -> fromText "\nLimiter " - <> (asCode . fromText) n - <> fromText " with frequency " - <> (asCode . fromString. show) d) - l)) - - metricToBuilder :: (Text, Text) -> Builder - metricToBuilder (name, text) = - fromText "### " - <> fromText name - <> fromText "\n" - <> accentuated text - - - --- | Calls the tracers in a documentation control mode, --- and returns a DocCollector, from which the documentation gets generated -documentTracersRun :: forall a. MetaTrace a => [Trace IO a] -> IO DocCollector -documentTracersRun tracers = do - let nss = allNamespaces :: [Namespace a] - nsIdx = zip nss [0..] - coll <- fmap DocCollector (liftIO $ newIORef (Map.empty :: Map.Map Int LogDoc)) - mapM_ (docTrace nsIdx coll) tracers - pure coll - where - docTrace nsIdx dc@(DocCollector docRef) (Trace tr) = - mapM_ - (\ (ns, idx) -> do - let condDoc = documentFor ns - doc = fromMaybe mempty condDoc - - modifyIORef docRef - (Map.insert - idx - ((emptyLogDoc - doc - (metricsDocFor ns)) - { ldSeverityCoded = severityFor ns Nothing - , ldPrivacyCoded = privacyFor ns Nothing - , ldDetailsCoded = detailsFor ns Nothing - })) - TR.traceWith tr (emptyLoggingContext {lcNSInner = nsInner ns}, - Left (TCDocument idx dc))) - nsIdx - --------------------- Callbacks --------------------------- - -docTracer :: MonadIO m => - BackendConfig - -> Trace m FormattedMessage -docTracer backendConfig = Trace $ TR.arrow $ TR.emit output - where - output p@(_, Left TCDocument {}) = - docIt backendConfig p - output (_, _) = pure () - -docTracerDatapoint :: MonadIO m => - BackendConfig - -> Trace m a -docTracerDatapoint backendConfig = Trace $ TR.arrow $ TR.emit output - where - output p@(_, Left TCDocument {}) = - docItDatapoint backendConfig p - output (_, _) = pure () - - --- | Callback for doc collection -addFiltered :: MonadIO m => TraceControl -> Maybe SeverityF -> m () -addFiltered (TCDocument idx (DocCollector docRef)) (Just sev) = do - liftIO $ modifyIORef docRef (\ docMap -> - Map.insert - idx - ((\e -> e { ldFiltered = seq sev (sev : ldFiltered e)}) - (case Map.lookup idx docMap of - Just e -> e - Nothing -> error "DocuGenerator>>missing log doc")) - docMap) -addFiltered _ _ = pure () - --- | Callback for doc collection -addLimiter :: MonadIO m => TraceControl -> (Text, Double) -> m () -addLimiter (TCDocument idx (DocCollector docRef)) (ln, lf) = do - liftIO $ modifyIORef docRef (\ docMap -> - Map.insert - idx - ((\e -> e { ldLimiter = seq ln (seq lf ((ln, lf) : ldLimiter e))}) - (case Map.lookup idx docMap of - Just e -> e - Nothing -> error "DocuGenerator>>missing log doc")) - docMap) -addLimiter _ _ = pure () - -addSilent :: MonadIO m => TraceControl -> Maybe Bool -> m () -addSilent (TCDocument idx (DocCollector docRef)) (Just silent) = do - liftIO $ modifyIORef docRef (\ docMap -> - Map.insert - idx - ((\e -> e { ldSilent = silent}) - (case Map.lookup idx docMap of - Just e -> e - Nothing -> error "DocuGenerator>>missing log doc")) - docMap) -addSilent _ _ = pure () - --- | Callback for doc collection -docIt :: MonadIO m - => BackendConfig - -> (LoggingContext, Either TraceControl a) - -> m () -docIt EKGBackend (LoggingContext{}, - Left (TCDocument idx (DocCollector docRef))) = do - liftIO $ modifyIORef docRef (\ docMap -> - Map.insert - idx - ((\e -> e { ldBackends = EKGBackend : ldBackends e - }) - (case Map.lookup idx docMap of - Just e -> e - Nothing -> error "DocuGenerator>>missing log doc")) - docMap) -docIt backend (LoggingContext {..}, - Left (TCDocument idx (DocCollector docRef))) = do - liftIO $ modifyIORef docRef (\ docMap -> - Map.insert - idx - ((\e -> e { ldBackends = backend : ldBackends e - , ldNamespace = nub ((lcNSPrefix,lcNSInner) : ldNamespace e) - , ldDetails = case lcDetails of - Nothing -> ldDetails e - Just d -> d : ldDetails e - }) - (case Map.lookup idx docMap of - Just e -> e - Nothing -> error "DocuGenerator>>missing log doc")) - docMap) -docIt _ (_, _) = pure () - --- | Callback for doc collection -docItDatapoint :: MonadIO m => - BackendConfig - -> (LoggingContext, Either TraceControl a) - -> m () -docItDatapoint _backend (LoggingContext {..}, - Left (TCDocument idx (DocCollector docRef))) = do - liftIO $ modifyIORef docRef (\ docMap -> - Map.insert - idx - ((\e -> e { ldNamespace = nub ((lcNSPrefix, lcNSInner) : ldNamespace e) - , ldBackends = [DatapointBackend] - }) - (case Map.lookup idx docMap of - Just e -> e - Nothing -> error "DocuGenerator>>missing log doc")) - docMap) -docItDatapoint _backend (LoggingContext {}, _) = pure () - - --- Finally generate a text from all the builders -docuResultsToText :: DocTracer -> TraceConfig -> Text -docuResultsToText dt@DocTracer {..} configuration = - let traceBuilders = sortBy (\ (l,_) (r,_) -> compare l r) - (filter (DocuResult.isTracer . snd) dtBuilderList) - metricsBuilders = sortBy (\ (l,_) (r,_) -> compare l r) - (filter (DocuResult.isMetric .snd) dtBuilderList) - datapointBuilders = sortBy (\ (l,_) (r,_) -> compare l r) - (filter (DocuResult.isDatapoint . snd) dtBuilderList) - header = fromText "# Cardano Trace Documentation\n\n" - header1 = fromText "## Table Of Contents\n\n" - toc = generateTOC dt - (map fst traceBuilders) - (map fst metricsBuilders) - (map fst datapointBuilders) - - header2 = fromText "\n## Trace Messages\n\n" - contentT = mconcat $ intersperse (fromText "\n\n") - (map (DocuResult.unpackDocu . snd) traceBuilders) - header3 = fromText "\n## Metrics\n\n" - contentM = mconcat $ intersperse (fromText "\n\n") - (map (DocuResult.unpackDocu . snd) metricsBuilders) - header4 = fromText "\n## Datapoints\n\n" - contentD = mconcat $ intersperse (fromText "\n\n") - (map (DocuResult.unpackDocu . snd) datapointBuilders) - config = fromText "\n## Configuration: \n```\n" - <> AE.encodePrettyToTextBuilder configuration - <> fromText "\n```\n" - numbers = fromString $ show (length traceBuilders) <> " log messages, " <> "\n" <> - show (length metricsBuilders) <> " metrics," <> "\n" <> - show (length datapointBuilders) <> " datapoints." <> "\n\n" - - legend = fromText $ utf16CircledT <> "- This is the root of a tracer\n\n" <> - utf16CircledS <> "- This is the root of a tracer that is silent because of the current configuration\n\n" <> - utf16CircledM <> "- This is the root of a tracer, that provides metrics\n\n" in - toStrict $ toLazyText $ - header - <> header1 - <> toc - <> header2 - <> contentT - <> header3 - <> contentM - <> header4 - <> contentD - <> config - <> numbers - <> legend - -generateTOC :: DocTracer -> [[Text]] -> [[Text]] -> [[Text]] -> Builder -generateTOC DocTracer {..} traces metrics datapoints = - generateTOCTraces - <> generateTOCMetrics - <> generateTOCDatapoints - <> generateTOCRest - where - tracesTree = mapMaybe (trim []) (toForest traces) - metricsTree = toForest (fmap splitToNS metrics) - datapointsTree = toForest datapoints - - generateTOCTraces = - fromText "### [Trace Messages](#trace-messages)\n\n" - <> mconcat (map (namespaceToToc traces False []) tracesTree) - <> fromText "\n" - generateTOCMetrics = - fromText "### [Metrics](#metrics)\n\n" - <> mconcat (map (namespaceToToc (fmap splitToNS metrics) True []) metricsTree) - <> fromText "\n" - generateTOCDatapoints = - fromText "### [Datapoints](#datapoints)\n\n" - <> mconcat (map (namespaceToToc datapoints True []) datapointsTree) - <> fromText "\n" - generateTOCRest = - fromText "### [Configuration](#configuration)\n\n" - <> fromText "\n" - - splitToNS :: [Text] -> [Text] - splitToNS [sym] = split (== '.') sym - splitToNS other = other - - isTracerSymbol :: [Text] -> Bool - isTracerSymbol tracer = tracer `elem` dtTracerNames - - -- Modify the given tracer tree so that the result is a tree where entries which - -- are not tracers are removed. In case the whole tree doesn't contain a tracer, return Nothing. - trim :: [Text] {- accumulated namespace in reverse -} -> Tree Text -> Maybe (Tree Text) - trim ns (Node x nested) = - let that = reverse (x : ns) - -- List of all nested tracers that we shall render - nestedTrimmed = mapMaybe (trim (x : ns)) nested in - mfilter (\_ -> not (null nestedTrimmed) || isTracerSymbol that) (Just (Node x nestedTrimmed)) - - namespaceToToc :: - [[Text]] - -> Bool - -> [Text] {- Accumulated namespace in reverse -} - -> Tree Text - -> Builder - namespaceToToc allTracers skipSymbols accns (Node x nested) = text - where - ns = reverse (x : accns) - - inner = mconcat (map (namespaceToToc allTracers skipSymbols (x : accns)) nested) - - indent lvl txt = mconcat (replicate lvl "\t") <> txt - - text :: Builder - text = - indent (length accns) - ( - "1. " - <> "[" <> fromText x <> fromText symbolsText <> "]" - <> "(#" <> link <> ")\n" - ) <> inner - - symbolsText :: Text - symbolsText = if skipSymbols then "" else - let isTracer = elem ns dtTracerNames - isSilent = elem ns dtSilent - isMetric = notElem ns dtNoMetrics - in - (if isTracer then utf16CircledT else "") - <> (if isSilent then utf16CircledS else "") - <> (if isMetric then utf16CircledM else "") - - -- The link to the description of the first tracer in that namespace - link :: Builder - link = mconcat (map (fromText . toLower) firstTracer) - - -- The first tracer in the list of tracers that has that namespace prefix - firstTracer :: [Text] - firstTracer = fromJust $ find (ns `isPrefixOf`) allTracers - - -asCode :: Builder -> Builder -asCode b = singleton '`' <> b <> singleton '`' - -accentuated :: Text -> Builder -accentuated t = if t == "" - then fromText "\n" - else fromText "\n" - <> fromText (unlines $ map addAccent (lines t)) - where - addAccent :: Text -> Text - addAccent t' = if t' == "" - then ">" - else "> " <> t' - --- this reflects the type cardano-tracer expects the metrics help texts to be serialized from: --- simple key-value map -newtype MetricsHelp = MH (Map.Map Text Text) - deriving ToJSON via (Map.Map Text Text) - -docuResultsToMetricsHelptext :: DocTracer -> Text -docuResultsToMetricsHelptext DocTracer{dtBuilderList} = - toStrict $ toLazyText $ - AE.encodePrettyToTextBuilder' conf mh - where - conf = AE.defConfig { AE.confCompare = compare, AE.confTrailingNewline = True } - mh = MH $ Map.fromList - [(intercalate "." ns, fromMaybe T.empty x) - | (ns, DocuMetric helpDescr) <- dtBuilderList - - -- for now, just extract the helptext (if any) from the markdown paragraph: - -- it's the line that starts with "> " - , let xs = T.lines $ toStrict $ toLazyText helpDescr - , let x = mconcat $ map (stripPrefix "> ") xs - ] - -docuResultsToNamespaces :: DocTracer -> Text -docuResultsToNamespaces DocTracer{dtBuilderList} = - T.unlines uniqueSorted - where - namespaces = - [ intercalate "." ns - | (ns, doc) <- dtBuilderList - , DocuResult.isTracer doc || DocuResult.isDatapoint doc - ] - uniqueSorted = map head $ group $ sort namespaces From 1e620b4940dc7406e636cb58a9a0204c2f3bffd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Thu, 23 Apr 2026 17:35:03 +0200 Subject: [PATCH 06/11] Review changes 2 --- .../scripts/schema-gen/GhciSchemaGen.hs | 205 +++++++++--------- 1 file changed, 99 insertions(+), 106 deletions(-) diff --git a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs index d3108c9d39b..907602d6d02 100644 --- a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs +++ b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs @@ -12,7 +12,7 @@ import qualified Data.Aeson.KeyMap as KM import qualified Data.Aeson.Key as K import qualified Data.Vector as V import Data.Char (isAlphaNum, isLower, isUpper, isSpace, toLower) -import Data.List (elemIndex, isPrefixOf, isSuffixOf, sortOn) +import Data.List (elemIndex, foldl', isInfixOf, isPrefixOf, isSuffixOf, sortOn, stripPrefix) import Data.Maybe (catMaybes, fromMaybe, listToMaybe, mapMaybe) import Data.Ord (Down (..)) import System.Directory @@ -23,12 +23,11 @@ import System.Exit import System.IO import Data.IORef import Control.Exception (catch, IOException, bracket) -import System.IO.Unsafe (unsafePerformIO) import qualified Data.Aeson as A import qualified Data.Aeson.Encode.Pretty as AP import qualified Data.ByteString.Lazy as BL import qualified Data.ByteString.Lazy.Char8 as BL8 -import Control.Monad (forM, guard, unless, when) +import Control.Monad (filterM, forM, guard, unless, when) -------------------------------------------------------------------------------- -- Entry point / high-level flow @@ -98,7 +97,7 @@ main = do config <- parseArgs =<< getArgs let nsFile = "bench/trace-schemas/newNamespaces.txt" putStrLn $ "Reading namespaces from " <> nsFile - namespaces <- filter (not . null) . map T.unpack . T.lines <$> T.readFile nsFile + namespaces <- filter (not . null) . lines <$> readFile' nsFile putStrLn $ "Loaded " <> show (length namespaces) <> " namespace(s)" validatedRootDirs <- validateSourceDirs emitWarning rootDirs @@ -108,8 +107,10 @@ main = do -- Build constructor -> namespace map from namespaceFor clauses putStrLn "Building namespace map..." - let sources = map (\fp -> (fp, readFileSafe fp)) hsFiles - let nsMap = foldlStrict mergeNs Map.empty [ normalizeNamespaceMap fp (parseNamespaceMap src) | (fp, src) <- sources ] + sources <- forM hsFiles $ \fp -> do + src <- readFileSafe fp + pure (fp, src) + let nsMap = foldl' mergeNs Map.empty [ normalizeNamespaceMap fp (parseNamespaceMap src) | (fp, src) <- sources ] -- Parse forMachine clauses and map their field bindings to variables putStrLn "Parsing forMachine clauses..." let helperFieldMaps = map (parseObjectHelperMap . snd) sources @@ -119,7 +120,7 @@ main = do ] let fieldVarMap = - foldlStrict + foldl' (Map.unionWith (Map.unionWith Map.union)) Map.empty [ normalizeFieldVarMap fp (parseFieldVarMap helpers clauses) @@ -133,7 +134,7 @@ main = do "[ghci " <> show idx <> "/" <> show (length clausesByFile) <> "] " <> fp normalizeVarTypesMap fp <$> ghciTypesForFile fp clauses - let varTypes = foldlStrict (Map.unionWith Map.union) Map.empty varTypesMaps + let varTypes = foldl' (Map.unionWith Map.union) Map.empty varTypesMaps let msgOutDir = "bench/trace-schemas/messages" let typeOutDir = "bench/trace-schemas/types" @@ -183,9 +184,6 @@ printHelp = -- Utilities -foldlStrict :: (b -> a -> b) -> b -> [a] -> b -foldlStrict f = go where go acc [] = acc; go acc (y:ys) = let acc' = f acc y in acc' `seq` go acc' ys - validateSourceDirs :: (String -> IO ()) -> [FilePath] -> IO [FilePath] validateSourceDirs emitWarning dirs = do dirPresence <- forM dirs $ \dir -> do @@ -200,17 +198,17 @@ validateSourceDirs emitWarning dirs = do pure existingDirs -- Read file for quick text parsing; tolerate missing files. -readFileSafe :: FilePath -> String -readFileSafe fp = unsafePerformIO (readFile fp `catch` (\(_e :: IOException) -> pure "")) +readFileSafe :: FilePath -> IO String +readFileSafe fp = readFile fp `catch` (\(_e :: IOException) -> pure "") collectTargets :: [FilePath] -> IO [FilePath] collectTargets roots = do files <- concat <$> mapM listHsFiles roots - catMaybes <$> mapM (\fp -> do + filterM (\fp -> do content <- T.readFile fp if "forMachine" `T.isInfixOf` content || "namespaceFor" `T.isInfixOf` content - then pure (Just fp) - else pure Nothing) files + then pure True + else pure False) files listHsFiles :: FilePath -> IO [FilePath] listHsFiles root = do @@ -254,12 +252,12 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty header = unwords headerLines bodyAfterLambda = dropLeadingLambdaCase bodyLines acc' - | "\\case" `isInfix` header || isLambdaCaseBody bodyLines = - foldlStrict insertNamespaceClause acc (parseNamespaceLambdaClauses bodyAfterLambda) + | "\\case" `isInfixOf` header || isLambdaCaseBody bodyLines = + foldl' insertNamespaceClause acc (parseNamespaceLambdaClauses bodyAfterLambda) | hasBranchArrows bodyLines = case ctorsAfter "namespaceFor" (takeWhile (/= '=') (unwords headerLines)) of [] -> acc - ctors -> foldlStrict insertNamespaceClause acc (parseNamespaceCaseBranches ctors bodyLines) + ctors -> foldl' insertNamespaceClause acc (parseNamespaceCaseBranches ctors bodyLines) | otherwise = case extractNamespaceClause currentType typeConstructors (unwords clauseLines) of Just clauseInfo -> insertNamespaceClause acc clauseInfo @@ -269,7 +267,7 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty spanUntilHeaderEnd acc [] = (reverse acc, []) spanUntilHeaderEnd acc (x:xs) - | any ("=" `isInfix`) acc = (reverse acc, x:xs) + | any ("=" `isInfixOf`) acc = (reverse acc, x:xs) | otherwise = spanUntilHeaderEnd (x:acc) xs spanNamespaceBody [] = ([], []) @@ -306,7 +304,7 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty startsMetaTraceInstance line = let t = trim line - in "instance" `isPrefixOf` t && "MetaTrace" `isInfix` t + in "instance" `isPrefixOf` t && "MetaTrace" `isInfixOf` t spanMetaTraceInstanceHeader :: [String] -> ([String], [String], Maybe TypeName) spanMetaTraceInstanceHeader [] = ([], [], Nothing) @@ -316,13 +314,13 @@ parseNamespaceMap src = go Nothing (lines src) Map.empty let hdr = reverse acc in (hdr, [], parseMetaTraceInstanceType (unwords hdr)) finish acc rest@(y:ys) - | any ("where" `isInfix`) acc = + | any ("where" `isInfixOf`) acc = let hdr = reverse acc in (hdr, rest, parseMetaTraceInstanceType (unwords hdr)) | otherwise = finish (y:acc) ys extractNamespaceClause currentType ctorMap clause = do - guard ("namespaceFor" `isInfix` clause) + guard ("namespaceFor" `isInfixOf` clause) let lhs = takeWhile (/= '=') clause parts <- extractNamespaceParts clause let ctors = ctorsAfter "namespaceFor" lhs @@ -393,7 +391,7 @@ parseTypeConstructors src = go (lines src) Map.empty | otherwise = step (y:acc) ys hasDeclBody line = - "=" `isInfix` line || " where" `isInfix` line + "=" `isInfixOf` line || " where" `isInfixOf` line startsNextTopLevel line = let t = trim line @@ -456,26 +454,26 @@ insertNamespaceClause :: Map.Map ConstructorName [NamespaceParts] -> ([ConstructorName], NamespaceParts) -> Map.Map ConstructorName [NamespaceParts] insertNamespaceClause acc (ctors, parts) = - foldlStrict (\m ctor -> Map.insertWith (++) ctor [parts] m) acc ctors + foldl' (\m ctor -> Map.insertWith (++) ctor [parts] m) acc ctors isLambdaCaseBody :: [String] -> Bool -isLambdaCaseBody (l:_) = "\\case" `isInfix` trim l +isLambdaCaseBody (l:_) = "\\case" `isInfixOf` trim l isLambdaCaseBody _ = False dropLeadingLambdaCase :: [String] -> [String] dropLeadingLambdaCase (l:ls) - | "\\case" `isInfix` trim l = ls + | "\\case" `isInfixOf` trim l = ls dropLeadingLambdaCase ls = ls hasBranchArrows :: [String] -> Bool -hasBranchArrows = any ("->" `isInfix`) +hasBranchArrows = any ("->" `isInfixOf`) parseNamespaceLambdaClauses :: [String] -> [([ConstructorName], NamespaceParts)] parseNamespaceLambdaClauses = mapMaybe parseBranch . go where go [] = [] go (l:ls) - | "->" `isInfix` l = + | "->" `isInfixOf` l = let (pat0, rhs0) = case breakSub "->" l of Just (a, b) -> (trim a, trim b) Nothing -> ("", "") @@ -491,7 +489,7 @@ parseNamespaceLambdaClauses = mapMaybe parseBranch . go | isBranchStart x = (reverse acc, allLines) | otherwise = step (x:acc) xs - isBranchStart l = "->" `isInfix` l && startsIndented l + isBranchStart l = "->" `isInfixOf` l && startsIndented l parseBranch (pat, body) = do let parts = quotedStrings body @@ -503,7 +501,7 @@ parseNamespaceCaseBranches ctors = mapMaybe parseBranch . go where go [] = [] go (l:ls) - | "->" `isInfix` l = + | "->" `isInfixOf` l = let (_pat0, rhs0) = case breakSub "->" l of Just (a, b) -> (trim a, trim b) Nothing -> ("", "") @@ -519,7 +517,7 @@ parseNamespaceCaseBranches ctors = mapMaybe parseBranch . go | isBranchStart x = (reverse acc, allLines) | otherwise = step (x:acc) xs - isBranchStart l = "->" `isInfix` l && startsIndented l + isBranchStart l = "->" `isInfixOf` l && startsIndented l parseBranch body = do let parts = quotedStrings body @@ -570,15 +568,15 @@ parseObjectHelperMap src = Set.fromList [ trim (takeWhile (\c -> isAlphaNum c || c == '_') l) | l <- lines src - , "::" `isInfix` l - , "Aeson.Object" `isInfix` l + , "::" `isInfixOf` l + , "Aeson.Object" `isInfixOf` l ] helperBodies [] = [] helperBodies (l:ls) | Just name <- helperDefName l , name `Set.member` helperNames - , "= \\case" `isInfix` l = + , "= \\case" `isInfixOf` l = let (body, rest) = spanIndented ls in (name, body) : helperBodies rest | otherwise = helperBodies ls @@ -601,11 +599,11 @@ parseObjectHelperMap src = && not ("--" `isPrefixOf` trim l) parseHelperFields body = - foldlStrict (Map.unionWith preferSpecific) Map.empty (mapMaybe parseBranch (helperBranches body)) + foldl' (Map.unionWith preferSpecific) Map.empty (mapMaybe parseBranch (helperBranches body)) helperBranches [] = [] helperBranches (l:ls) - | "->" `isInfix` l = + | "->" `isInfixOf` l = let (pat0, rhs0) = case breakSub "->" l of Just (a, b) -> (trim a, trim b) Nothing -> ("", "") @@ -622,7 +620,7 @@ parseObjectHelperMap src = | isTopLevelDecl x = (reverse acc, allLines) | otherwise = go (x:acc) xs - isBranchStart l = "->" `isInfix` l && startsIndented l + isBranchStart l = "->" `isInfixOf` l && startsIndented l parseBranch cl = let vars = Set.fromList (extractVars (clausePattern cl)) @@ -642,7 +640,7 @@ parseForMachineClauses src = go Nothing (lines src) startsHeader line = let t = trim line in "forMachine" `isPrefixOf` t || "forMachineGov" `isPrefixOf` t - hasEquals line = "=" `isInfix` line + hasEquals line = "=" `isInfixOf` line go _ [] = [] go currentType allLines@(l:ls) | startsLogFormattingInstance l = @@ -656,7 +654,7 @@ parseForMachineClauses src = go Nothing (lines src) (lvlTok, pat) = parseHeader header (body, rest) = break startsHeader afterHeader bodyAfterLambda = dropLeadingLambdaCase body - in if "\\case" `isInfix` header || isLambdaCaseBody body + in if "\\case" `isInfixOf` header || isLambdaCaseBody body then parseLambdaCaseClauses lvlTok currentType typeConstructors bodyAfterLambda ++ go currentType rest else expandNestedCaseClauses lvlTok currentType typeConstructors pat body ++ go currentType rest | otherwise = go currentType ls @@ -668,7 +666,7 @@ parseForMachineClauses src = go Nothing (lines src) startsLogFormattingInstance line = let t = trim line - in "instance" `isPrefixOf` t && "LogFormatting" `isInfix` t + in "instance" `isPrefixOf` t && "LogFormatting" `isInfixOf` t startsTopLevelDeclForMachine line = let t = trim line @@ -688,7 +686,7 @@ parseLambdaCaseClauses lvl currentType typeConstructors = go where go [] = [] go (l:ls) - | "->" `isInfix` l = + | "->" `isInfixOf` l = let (pat0, rhs0) = case breakSub "->" l of Just (a, b) -> (trim a, trim b) Nothing -> ("", "") @@ -704,7 +702,7 @@ parseLambdaCaseClauses lvl currentType typeConstructors = go | isBranchStart x = (reverse acc, allLines) | otherwise = step (x:acc) xs - isBranchStart l = "->" `isInfix` l && startsIndented l + isBranchStart l = "->" `isInfixOf` l && startsIndented l expandNestedCaseClauses :: String -> Maybe TypeName -> Map.Map TypeName [ConstructorName] -> String -> [String] -> [Clause] expandNestedCaseClauses lvl currentType typeConstructors pat body = @@ -741,7 +739,7 @@ parseHeader :: String -> (String, String) parseHeader line = let ws = words line keyword = case () of - _ | "forMachineGov" `isInfix` line -> "forMachineGov" + _ | "forMachineGov" `isInfixOf` line -> "forMachineGov" | otherwise -> "forMachine" lvl = case dropWhile (/= keyword) ws of (_:l:_) -> l @@ -762,7 +760,7 @@ spanInstanceHeader className (x:xs) = finish [x] xs let hdr = reverse acc in (hdr, [], parseInstanceTypeForClass className (unwords hdr)) finish acc rest@(y:ys) - | any ("where" `isInfix`) acc = + | any ("where" `isInfixOf`) acc = let hdr = reverse acc in (hdr, rest, parseInstanceTypeForClass className (unwords hdr)) | otherwise = finish (y:acc) ys @@ -873,7 +871,7 @@ isVariableOnlyPattern pat = -- Map JSON field keys to the pattern variable they come from. parseFieldVarMap :: HelperFieldMap -> [Clause] -> Map.Map ConstructorName (Map.Map DetailLevel (Map.Map String String)) -parseFieldVarMap helperMap = foldlStrict step Map.empty +parseFieldVarMap helperMap = foldl' step Map.empty where step acc cl = case clauseCtor cl of @@ -890,8 +888,8 @@ parseFieldVarMap helperMap = foldlStrict step Map.empty directPairs = mapMaybe (parseFieldLine vars) (collectFieldEntries sanitizedBody) helperPairs = concatMap helperPairsForLine sanitizedBody pairs = Map.toList (Map.fromListWith preferSpecific (directPairs ++ helperPairs)) - addOne m (k,v) = foldlStrict (\mm lvl -> Map.insertWith Map.union lvl (Map.singleton k v) mm) m lvls - in Map.insertWith (Map.unionWith Map.union) ctor (foldlStrict addOne Map.empty pairs) acc + addOne m (k,v) = foldl' (\mm lvl -> Map.insertWith Map.union lvl (Map.singleton k v) mm) m lvls + in Map.insertWith (Map.unionWith Map.union) ctor (foldl' addOne Map.empty pairs) acc helperPairsForLine line = concatMap helperPairsForName (tokenize line) @@ -905,22 +903,22 @@ parseFieldVarMap helperMap = foldlStrict step Map.empty | otherwise = old collectFieldEntries :: [String] -> [String] -collectFieldEntries = finalize . foldlStrict step [] +collectFieldEntries = finalize . foldl' step [] where step :: [String] -> String -> [String] step [] line - | ".=" `isInfix` line = [line] + | ".=" `isInfixOf` line = [line] | otherwise = [] step acc@(cur:rest) line | fieldEntryNeedsContinuation cur = (cur <> " " <> trim line) : rest - | ".=" `isInfix` line = line : acc + | ".=" `isInfixOf` line = line : acc | otherwise = acc - finalize = concatMap splitFieldFragments . reverse . filter (".=" `isInfix`) + finalize = concatMap splitFieldFragments . reverse . filter (".=" `isInfixOf`) splitFieldFragments :: String -> [String] splitFieldFragments = - filter (".=" `isInfix`) . map trim . splitTopLevelCommasGeneral . stripOuterList . trim + filter (".=" `isInfixOf`) . map trim . splitTopLevelCommasGeneral . stripOuterList . trim stripOuterList s | headMay s == Just '[' && lastMay s == Just ']' = dropOuterDelims s @@ -971,7 +969,7 @@ fieldEntryNeedsContinuation = hasOpenBalance . trim | otherwise = go paren bracketDepth brace cs stripCommentBlocks :: [String] -> [String] -stripCommentBlocks = snd . foldlStrict step (0 :: Int, []) +stripCommentBlocks = snd . foldl' step (0 :: Int, []) where step (depth, acc) line = let (depth', cleaned) = stripLine depth line @@ -1086,48 +1084,48 @@ stringArrayExprVar = "__string_array_expr__" -- Heuristic detection for String-literal RHS. isStringLiteral :: String -> Bool isStringLiteral s = - "String \"" `isInfix` s || "String '" `isInfix` s + "String \"" `isInfixOf` s || "String '" `isInfixOf` s inferRhsMarker :: String -> Maybe String inferRhsMarker rhs | isStringLiteral rhs = Just literalStringVar - | "Number (fromIntegral" `isInfix` rhs = Just integerExprVar - | "Number (fromRational" `isInfix` rhs = Just numberExprVar + | "Number (fromIntegral" `isInfixOf` rhs = Just integerExprVar + | "Number (fromRational" `isInfixOf` rhs = Just numberExprVar | "Number " `isPrefixOf` trim rhs = Just numberExprVar | "String " `isPrefixOf` trim rhs = Just renderedStringVar - | "forMachine " `isInfix` rhs = Just objectExprVar - | "toObject " `isInfix` rhs = Just objectExprVar - | "Aeson.object" `isInfix` rhs = Just objectExprVar - | "object [" `isInfix` rhs = Just objectExprVar - | "mconcat [" `isInfix` rhs = Just objectExprVar - | "toJSON [" `isInfix` rhs = Just arrayExprVar - | "toJSONList (map show" `isInfix` rhs = Just stringArrayExprVar - | "toJSONList (map showT" `isInfix` rhs = Just stringArrayExprVar - | "toJSONList (map textShow" `isInfix` rhs = Just stringArrayExprVar - | "toJSONList (map (show" `isInfix` rhs = Just stringArrayExprVar - | "toJSONList " `isInfix` rhs = Just arrayExprVar - | "toJSON (map show" `isInfix` rhs = Just stringArrayExprVar - | "toJSON (map showT" `isInfix` rhs = Just stringArrayExprVar - | "toJSON (map textShow" `isInfix` rhs = Just stringArrayExprVar - | "toJSON (map (show" `isInfix` rhs = Just stringArrayExprVar - | "toJSON (map (" `isInfix` rhs = Just arrayExprVar - | "toJSON (Set.toList" `isInfix` rhs = Just arrayExprVar - | "toJSON (Map.keys" `isInfix` rhs = Just arrayExprVar - | "toJSON (Map.elems" `isInfix` rhs = Just arrayExprVar - | "toJSON True" `isInfix` rhs = Just booleanExprVar - | "toJSON False" `isInfix` rhs = Just booleanExprVar - | "toJSON (" `isInfix` rhs && any (`isInfix` rhs) [" is", "==", "/=", "&&", "||", " not "] = Just booleanExprVar - | "String (" `isInfix` rhs = Just renderedStringVar - | "textShow" `isInfix` rhs = Just renderedStringVar - | "showT" `isInfix` rhs = Just renderedStringVar - | "renderHeaderHash" `isInfix` rhs = Just renderedStringVar - | "renderChainHash" `isInfix` rhs = Just renderedStringVar - | "renderPoint" `isInfix` rhs = Just renderedStringVar - | "toJSON (unBlockNo" `isInfix` rhs = Just integerExprVar - | "toJSON (unSlotNo" `isInfix` rhs = Just integerExprVar - | "toJSON (fromIntegral" `isInfix` rhs = Just integerExprVar - | "toJSON (" `isInfix` rhs && any (`isInfix` rhs) ["Word", "Int", "SlotNo", "BlockNo", "EpochNo", "length ", "length(", "fragmentLength"] = Just integerExprVar - | "toJSON (" `isInfix` rhs && any (`isInfix` rhs) ["Double", "Float", "NominalDiffTime", "DiffTime"] = Just numberExprVar + | "forMachine " `isInfixOf` rhs = Just objectExprVar + | "toObject " `isInfixOf` rhs = Just objectExprVar + | "Aeson.object" `isInfixOf` rhs = Just objectExprVar + | "object [" `isInfixOf` rhs = Just objectExprVar + | "mconcat [" `isInfixOf` rhs = Just objectExprVar + | "toJSON [" `isInfixOf` rhs = Just arrayExprVar + | "toJSONList (map show" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSONList (map showT" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSONList (map textShow" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSONList (map (show" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSONList " `isInfixOf` rhs = Just arrayExprVar + | "toJSON (map show" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSON (map showT" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSON (map textShow" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSON (map (show" `isInfixOf` rhs = Just stringArrayExprVar + | "toJSON (map (" `isInfixOf` rhs = Just arrayExprVar + | "toJSON (Set.toList" `isInfixOf` rhs = Just arrayExprVar + | "toJSON (Map.keys" `isInfixOf` rhs = Just arrayExprVar + | "toJSON (Map.elems" `isInfixOf` rhs = Just arrayExprVar + | "toJSON True" `isInfixOf` rhs = Just booleanExprVar + | "toJSON False" `isInfixOf` rhs = Just booleanExprVar + | "toJSON (" `isInfixOf` rhs && any (`isInfixOf` rhs) [" is", "==", "/=", "&&", "||", " not "] = Just booleanExprVar + | "String (" `isInfixOf` rhs = Just renderedStringVar + | "textShow" `isInfixOf` rhs = Just renderedStringVar + | "showT" `isInfixOf` rhs = Just renderedStringVar + | "renderHeaderHash" `isInfixOf` rhs = Just renderedStringVar + | "renderChainHash" `isInfixOf` rhs = Just renderedStringVar + | "renderPoint" `isInfixOf` rhs = Just renderedStringVar + | "toJSON (unBlockNo" `isInfixOf` rhs = Just integerExprVar + | "toJSON (unSlotNo" `isInfixOf` rhs = Just integerExprVar + | "toJSON (fromIntegral" `isInfixOf` rhs = Just integerExprVar + | "toJSON (" `isInfixOf` rhs && any (`isInfixOf` rhs) ["Word", "Int", "SlotNo", "BlockNo", "EpochNo", "length ", "length(", "fragmentLength"] = Just integerExprVar + | "toJSON (" `isInfixOf` rhs && any (`isInfixOf` rhs) ["Double", "Float", "NominalDiffTime", "DiffTime"] = Just numberExprVar | otherwise = Nothing parseQuotedKey :: String -> Maybe String @@ -1158,15 +1156,16 @@ type VarTypes = Map.Map ConstructorName (Map.Map String String) -- For each file, ask GHCi for the types of variables extracted from forMachine clauses. ghciTypesForFile :: FilePath -> [Clause] -> IO VarTypes ghciTypesForFile fp clauses = do - let src = readFileSafe fp + src <- readFileSafe fp + let moduleName = extractModuleName src imports = extractImports src - let queries = mapMaybe buildQuery clauses + queries = mapMaybe buildQuery clauses if null queries then pure Map.empty else do out <- runGhci moduleName imports (map (fst . snd) queries) let outputs = splitOutputs out (length queries) let pairs = zip queries outputs - pure $ foldlStrict mergeVarTypes Map.empty (map parseQueryResult pairs) + pure $ foldl' mergeVarTypes Map.empty (map parseQueryResult pairs) where mergeVarTypes = Map.unionWith Map.union @@ -1273,7 +1272,7 @@ splitOutputs out n = map snd (take n (splitMarkers out)) parseQueryResult :: ((ConstructorName, (String, [String])), String) -> VarTypes parseQueryResult ((ctor, (_cmd, vars)), out) = - let isErr = "error:" `isInfix` out + let isErr = "error:" `isInfixOf` out varTypes = if isErr then parseBindings out else parseSignature out vars @@ -1290,7 +1289,7 @@ parseSignature out vars = do findSigBlock :: String -> Maybe String findSigBlock out = - case break (isInfix "::") (lines out) of + case break (isInfixOf "::") (lines out) of (_, []) -> Nothing (_, sigStart:rest) -> let sigLines = sigStart : takeWhile isSigContinuation rest @@ -1338,7 +1337,7 @@ parseBindings :: String -> Maybe (Map.Map String String) parseBindings out = let constraints = parseConstraints out bindings = mapMaybe parseBindingLine (lines out) - applyConstraints ty = foldlStrict (\t (v, rep) -> replaceToken v rep t) ty constraints + applyConstraints ty = foldl' (\t (v, rep) -> replaceToken v rep t) ty constraints fixed = [ (name, applyConstraints ty) | (name, ty) <- bindings ] in if null fixed then Nothing else Just (Map.fromList fixed) @@ -1409,9 +1408,6 @@ headWord s = case words s of [] -> "" (x:_) -> x -isInfix :: String -> String -> Bool -isInfix needle hay = T.isInfixOf (T.pack needle) (T.pack hay) - -- Schema update type FieldVarMap = Map.Map ConstructorName (Map.Map DetailLevel (Map.Map String String)) @@ -1560,8 +1556,8 @@ mergeHistDataIfEmpty histOut v@(A.Object o) = do if not histExists then pure v else do - bs <- BL.readFile histOut - case A.decode bs of + histValue <- A.decodeFileStrict' histOut + case histValue of Just (A.Object ho) -> case KM.lookup (K.fromString "data") ho of Just d -> pure (A.Object (KM.insert (K.fromString "data") d o)) @@ -1878,9 +1874,6 @@ baseTypeName s = (x:_) -> x [] -> s'' -stripPrefix :: String -> String -> Maybe String -stripPrefix pre s = if pre `isPrefixOf` s then Just (drop (length pre) s) else Nothing - ensureTypeSchema :: FilePath -> String -> FieldVarMap -> VarTypes -> Set.Set String -> IO () ensureTypeSchema out name fieldVarMap varTypes seen = do createDirectoryIfMissing True (takeDirectory out) @@ -1943,7 +1936,7 @@ mergedPropsForType -> IO A.Object mergedPropsForType fieldVarMap varTypes seen ctor byLevel = do let fieldVars = - foldlStrict (Map.unionWith (++)) Map.empty + foldl' (Map.unionWith (++)) Map.empty [ Map.map (:[]) lvlMap | lvlMap <- Map.elems byLevel ] @@ -2017,7 +2010,7 @@ mergeSchemas xs = in fromMaybe (A.object ["anyOf" A..= unique]) (singleElement unique) dedupeValues :: [A.Value] -> [A.Value] -dedupeValues = reverse . foldlStrict step [] +dedupeValues = reverse . foldl' step [] where step acc v = let key = BL8.unpack (A.encode v) From a59523856f98c611ecc66d19f4e4cc7b235f6fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Thu, 23 Apr 2026 17:35:51 +0200 Subject: [PATCH 07/11] Add testcases with cabal test --- .../schema-gen/ApplySchemaOverrides.hs | 249 +----------------- .../schema-gen/CheckOverrideCoverage.hs | 104 +------- .../schema-gen/ValidateTraceSchemas.hs | 122 +-------- .../TraceSchemaGen/ApplySchemaOverrides.hs | 249 ++++++++++++++++++ .../TraceSchemaGen/CheckOverrideCoverage.hs | 112 ++++++++ .../TraceSchemaGen/ValidateTraceSchemas.hs | 136 ++++++++++ .../scripts/schema-gen/test/Main.hs | 131 +++++++++ .../scripts/schema-gen/trace-schema-gen.cabal | 47 +++- 8 files changed, 671 insertions(+), 479 deletions(-) create mode 100644 bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ValidateTraceSchemas.hs create mode 100644 bench/trace-schemas/scripts/schema-gen/test/Main.hs diff --git a/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs b/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs index 6db1317dff4..27957d7f5e5 100644 --- a/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs +++ b/bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs @@ -1,251 +1,6 @@ -{-# LANGUAGE OverloadedStrings #-} -{-# LANGUAGE ScopedTypeVariables #-} - module Main (main) where -import qualified Data.Aeson as A -import qualified Data.Aeson.Encode.Pretty as AP -import qualified Data.Aeson.Key as K -import qualified Data.Aeson.KeyMap as KM -import qualified Data.ByteString.Lazy as BL -import Control.Monad (forM, unless, when) -import Data.List (isSuffixOf, sort) -import Data.Maybe (fromMaybe) -import System.Directory - ( createDirectoryIfMissing - , doesDirectoryExist - , doesFileExist - , listDirectory - ) -import System.Environment (getArgs) -import System.Exit (exitFailure, exitSuccess) -import System.FilePath ((), takeDirectory, takeFileName) - -defaultRoot :: FilePath -defaultRoot = "bench/trace-schemas" - -data Config = Config - { cfgRoot :: FilePath - , cfgCheck :: Bool - , cfgVerbose :: Bool - , cfgAllowDestructive :: Bool - } - -defaultConfig :: Config -defaultConfig = - Config - { cfgRoot = defaultRoot - , cfgCheck = False - , cfgVerbose = False - , cfgAllowDestructive = False - } +import qualified TraceSchemaGen.ApplySchemaOverrides as Apply main :: IO () -main = do - config <- parseArgs defaultConfig =<< getArgs - let overridesRoot = cfgRoot config "overrides" - overridesExists <- doesDirectoryExist overridesRoot - if not overridesExists - then do - when (cfgVerbose config) $ - putStrLn $ "No overrides directory at " <> overridesRoot - exitSuccess - else do - overrideFiles <- sort <$> listOverrideFiles overridesRoot - results <- forM overrideFiles (processOverride config) - let changedTargets = [target | (target, True) <- results] - when (cfgCheck config && not (null changedTargets)) $ do - putStrLn "Schema overrides are not applied (or generated files were edited directly):" - mapM_ (\fp -> putStrLn $ " " <> fp) changedTargets - exitFailure - when (cfgVerbose config) $ do - putStrLn $ "Processed " <> show (length overrideFiles) <> " override file(s)." - putStrLn $ "Updated " <> show (length changedTargets) <> " target schema file(s)." - exitSuccess - -parseArgs :: Config -> [String] -> IO Config -parseArgs = go - where - go cfg [] = pure cfg - go cfg ("--root" : root : rest) = go cfg {cfgRoot = root} rest - go cfg ("--check" : rest) = go cfg {cfgCheck = True} rest - go cfg ("--verbose" : rest) = go cfg {cfgVerbose = True} rest - go cfg ("--allow-destructive" : rest) = go cfg {cfgAllowDestructive = True} rest - go _ ["--help"] = printHelp >> exitSuccess - go _ ["-h"] = printHelp >> exitSuccess - go _ unknown = do - putStrLn $ "Unrecognized arguments: " <> unwords unknown - printHelp - exitFailure - -printHelp :: IO () -printHelp = - putStrLn $ - unlines - [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs [options]" - , "" - , "Options:" - , " --root PATH trace-schemas root path (default: bench/trace-schemas)" - , " --check Dry-run; fail if any target file would change" - , " --verbose Print each override mapping" - , " --allow-destructive Allow overrides that delete or replace existing fields" - ] - -listOverrideFiles :: FilePath -> IO [FilePath] -listOverrideFiles root = do - entries <- listDirectory root - fmap concat $ - forM entries $ \name -> do - let path = root name - isDir <- doesDirectoryExist path - if isDir - then listOverrideFiles path - else pure [path | ".override.json" `isSuffixOf` name] - -processOverride :: Config -> FilePath -> IO (FilePath, Bool) -processOverride config overrideFile = do - let overridesRoot = cfgRoot config "overrides" - rel <- stripPrefixPath overridesRoot overrideFile - targetRel <- overrideRelToTarget rel - let targetFile = cfgRoot config targetRel - - targetExists <- doesFileExist targetFile - unless targetExists $ - failWith $ - "Override target does not exist: " <> targetFile - <> " (from " <> overrideFile <> ")" - - targetValue <- readJsonFile targetFile - overrideValue <- readJsonFile overrideFile - patchValue <- normalizePatch overrideFile overrideValue - - unless (cfgAllowDestructive config) $ do - let destructiveOps = findDestructiveOps targetValue patchValue - unless (null destructiveOps) $ - failWith $ - "Override " <> overrideFile <> " contains destructive operations:\n" - <> unlines (map (" " <>) destructiveOps) - <> "Pass --allow-destructive to permit destructive overrides." - - let mergedValue = mergePatch targetValue patchValue - let changed = mergedValue /= targetValue - - when (cfgVerbose config) $ - putStrLn $ overrideFile <> " -> " <> targetFile - - when (changed && not (cfgCheck config)) $ do - createDirectoryIfMissing True (takeDirectory targetFile) - BL.writeFile targetFile (AP.encodePretty mergedValue) - - pure (targetFile, changed) - -readJsonFile :: FilePath -> IO A.Value -readJsonFile fp = do - bs <- BL.readFile fp - case A.eitherDecode bs of - Left err -> failWith $ "Invalid JSON in " <> fp <> ": " <> err - Right v -> pure v - -normalizePatch :: FilePath -> A.Value -> IO A.Value -normalizePatch source v@(A.Object o) = - case KM.lookup (K.fromString "patch") o of - Nothing -> pure v - Just patch@(A.Object _) -> pure patch - Just _ -> - failWith $ - "Override \"patch\" must be an object in " <> source -normalizePatch source _ = - failWith $ "Override must be a JSON object: " <> source - --- | Returns human-readable descriptions of operations that would delete or --- replace existing fields when applying @patch@ to @target@. An empty list --- means the patch is non-destructive (only adds new keys or deep-merges --- objects). -findDestructiveOps :: A.Value -> A.Value -> [String] -findDestructiveOps target patch = goObj "" targetObj patchObj - where - targetObj = case target of { A.Object o -> o; _ -> KM.empty } - patchObj = case patch of { A.Object o -> o; _ -> KM.empty } - - goObj path tObj pObj = concatMap (checkKey path tObj) (KM.toList pObj) - - checkKey path tObj (k, pv) = - let kStr = K.toString k - keyPath = if null path then kStr else path <> "." <> kStr - in case (KM.lookup k tObj, pv) of - (Nothing, _) -> [] -- new key: not destructive - (Just _, A.Null) -> [keyPath <> ": field deletion"] - (Just (A.Object tv), A.Object pv') -> - goObj keyPath tv pv' -- recurse: only destructive if inner keys are - (Just _, _) -> [keyPath <> ": field replacement"] - -mergePatch :: A.Value -> A.Value -> A.Value -mergePatch _ A.Null = A.Null -mergePatch _ patch@(A.Bool _) = patch -mergePatch _ patch@(A.String _) = patch -mergePatch _ patch@(A.Number _) = patch -mergePatch _ patch@(A.Array _) = patch -mergePatch target (A.Object patchObj) = - let targetObj = - case target of - A.Object o -> o - _ -> KM.empty - in A.Object (mergeObject targetObj patchObj) - -mergeObject :: A.Object -> A.Object -> A.Object -mergeObject = KM.foldrWithKey step - where - step key value acc = - case value of - A.Null -> KM.delete key acc - A.Object _ -> - let existing = fromMaybe A.Null (KM.lookup key acc) - merged = mergePatch existing value - in KM.insert key merged acc - _ -> KM.insert key value acc - -stripPrefixPath :: FilePath -> FilePath -> IO FilePath -stripPrefixPath prefix full = - case stripPrefixList (splitPath prefix) (splitPath full) of - Just suffix -> pure (joinPath suffix) - Nothing -> - failWith $ - "Path " <> full <> " is not under " <> prefix - -overrideRelToTarget :: FilePath -> IO FilePath -overrideRelToTarget rel = do - let name = takeFileName rel - let suffix = ".override.json" :: String - unless (suffix `isSuffixOf` name) $ - failWith $ "Override must end with .override.json: " <> rel - let targetName = take (length name - length suffix) name <> ".json" - pure (replaceFileName rel targetName) - -splitPath :: FilePath -> [FilePath] -splitPath path = filter (not . null) (go path) - where - go "" = [] - go p = - case break (== '/') p of - (a, []) -> [a] - (a, _:rest) -> a : go rest - -joinPath :: [FilePath] -> FilePath -joinPath [] = "" -joinPath (x:xs) = foldl () x xs - -replaceFileName :: FilePath -> FilePath -> FilePath -replaceFileName path newName = - case reverse (splitPath path) of - [] -> newName - (_old:dirsRev) -> joinPath (reverse dirsRev <> [newName]) - -stripPrefixList :: Eq a => [a] -> [a] -> Maybe [a] -stripPrefixList [] ys = Just ys -stripPrefixList _ [] = Nothing -stripPrefixList (x:xs) (y:ys) - | x == y = stripPrefixList xs ys - | otherwise = Nothing - -failWith :: String -> IO a -failWith msg = putStrLn ("ERROR: " <> msg) >> exitFailure +main = Apply.main diff --git a/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs b/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs index cd962545822..983cbbc720c 100644 --- a/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs +++ b/bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs @@ -1,106 +1,6 @@ -{-# LANGUAGE ScopedTypeVariables #-} - module Main (main) where -import Control.Monad (unless, when) -import Data.List (isPrefixOf, isSuffixOf, sort) -import qualified Data.Set as Set -import System.Environment (getArgs) -import System.Exit (ExitCode (..), exitFailure, exitSuccess) -import System.Process (proc, readCreateProcessWithExitCode) - -generatedRoots :: [FilePath] -generatedRoots = - [ "bench/trace-schemas/messages" - , "bench/trace-schemas/types" - ] - -overridesRoot :: FilePath -overridesRoot = "bench/trace-schemas/overrides" - -newtype Config = Config - { cfgRange :: Maybe String - } - -defaultConfig :: Config -defaultConfig = Config {cfgRange = Nothing} +import qualified TraceSchemaGen.CheckOverrideCoverage as Coverage main :: IO () -main = do - config <- parseArgs defaultConfig =<< getArgs - generatedChanged <- listChangedPaths config generatedRoots - overrideChanged <- Set.fromList <$> listChangedPaths config [overridesRoot] - - let generatedChangedSet = Set.fromList (filter isGeneratedJson generatedChanged) - let requiredOverrideFiles = Set.map generatedToOverride generatedChangedSet - let missing = sort (Set.toList (Set.difference requiredOverrideFiles overrideChanged)) - - when (null generatedChangedSet) $ do - putStrLn "No generated trace-schema files changed." - exitSuccess - - unless (null missing) $ do - putStrLn "Generated schema files changed without matching override sidecar updates:" - mapM_ (\fp -> putStrLn $ " " <> fp) missing - putStrLn "" - putStrLn "Update corresponding files under bench/trace-schemas/overrides/." - exitFailure - - putStrLn "Override coverage check passed." - exitSuccess - -parseArgs :: Config -> [String] -> IO Config -parseArgs = go - where - go cfg [] = pure cfg - go cfg ("--range" : r : rest) = go cfg {cfgRange = Just r} rest - go _ ["--help"] = printHelp >> exitSuccess - go _ ["-h"] = printHelp >> exitSuccess - go _ unknown = do - putStrLn $ "Unrecognized arguments: " <> unwords unknown - printHelp - exitFailure - -printHelp :: IO () -printHelp = - putStrLn $ - unlines - [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs [options]" - , "" - , "Options:" - , " --range GIT_RANGE Diff range to inspect, e.g. origin/master...HEAD" - ] - -listChangedPaths :: Config -> [FilePath] -> IO [FilePath] -listChangedPaths config paths = do - let baseArgs = - case cfgRange config of - Just r -> ["diff", "--name-only", r, "--"] - Nothing -> ["diff", "--name-only", "--"] - args = baseArgs <> paths - (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "git" args) "" - case exitCode of - ExitSuccess -> pure (filter (not . null) (lines stdoutText)) - ExitFailure _ -> do - unless (null stdoutText) (putStr stdoutText) - unless (null stderrText) (putStr stderrText) - exitFailure - -isGeneratedJson :: FilePath -> Bool -isGeneratedJson path = - any (`isPrefixOf` path) generatedRoots - && ".schema.json" `isSuffixOf` path - -generatedToOverride :: FilePath -> FilePath -generatedToOverride generatedPath = - case stripPrefixPath "bench/trace-schemas/" generatedPath of - Just rel -> - let withoutSuffix = take (length rel - length ".json") rel - in overridesRoot <> "/" <> withoutSuffix <> ".override.json" - Nothing -> generatedPath - -stripPrefixPath :: FilePath -> FilePath -> Maybe FilePath -stripPrefixPath prefix path = - if prefix `isPrefixOf` path - then Just (drop (length prefix) path) - else Nothing +main = Coverage.main diff --git a/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs b/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs index f594193204e..7e13c3a4c4a 100644 --- a/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs +++ b/bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs @@ -1,124 +1,6 @@ -{-# LANGUAGE ScopedTypeVariables #-} - module Main (main) where -import Control.Monad (unless, when) -import Data.List (isSuffixOf) -import System.Directory - ( doesDirectoryExist - , doesFileExist - , listDirectory - ) -import System.Environment (getArgs) -import System.Exit (ExitCode (..), exitFailure, exitSuccess) -import System.FilePath (()) -import System.Process (proc, readCreateProcessWithExitCode) - -defaultMetaSchema :: FilePath -defaultMetaSchema = "bench/trace-schemas/meta.schema.json" - -defaultMessagesDir :: FilePath -defaultMessagesDir = "bench/trace-schemas/messages" - -data Config = Config - { cfgMetaSchema :: FilePath - , cfgMessagesDir :: FilePath - } - -defaultConfig :: Config -defaultConfig = - Config - { cfgMetaSchema = defaultMetaSchema - , cfgMessagesDir = defaultMessagesDir - } +import qualified TraceSchemaGen.ValidateTraceSchemas as Validate main :: IO () -main = do - config <- parseArgs defaultConfig =<< getArgs - checkInputs config - schemaFiles <- listJsonFilesRecursive (cfgMessagesDir config) - when (null schemaFiles) $ do - putStrLn $ "No schema files found under " <> cfgMessagesDir config - exitFailure - - runValidator "Validating meta schema..." (validatorArgs ["--check-metaschema", cfgMetaSchema config]) - runValidator - ("Validating " <> show (length schemaFiles) <> " trace schema files...") - (validatorArgs (["--schemafile", cfgMetaSchema config] <> schemaFiles)) - - putStrLn $ - "Validated " - <> show (length schemaFiles) - <> " trace schema file(s) against " - <> cfgMetaSchema config - exitSuccess - -parseArgs :: Config -> [String] -> IO Config -parseArgs = go - where - go cfg [] = pure cfg - go cfg ("--meta-schema" : path : rest) = go cfg {cfgMetaSchema = path} rest - go cfg ("--messages-dir" : path : rest) = go cfg {cfgMessagesDir = path} rest - go _ ["--help"] = printHelp >> exitSuccess - go _ ["-h"] = printHelp >> exitSuccess - go _ unknown = do - putStrLn $ "Unrecognized arguments: " <> unwords unknown - printHelp - exitFailure - -printHelp :: IO () -printHelp = - putStrLn $ - unlines - [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs [options]" - , "" - , "Options:" - , " --meta-schema PATH Path to the meta schema." - , " --messages-dir PATH Directory containing trace schema files." - ] - -checkInputs :: Config -> IO () -checkInputs config = do - metaExists <- doesFileExist (cfgMetaSchema config) - unless metaExists $ do - putStrLn $ "Meta schema not found: " <> cfgMetaSchema config - exitFailure - - messagesExists <- doesDirectoryExist (cfgMessagesDir config) - unless messagesExists $ do - putStrLn $ "Messages directory not found: " <> cfgMessagesDir config - exitFailure - -listJsonFilesRecursive :: FilePath -> IO [FilePath] -listJsonFilesRecursive root = do - entries <- listDirectory root - paths <- mapM descend entries - pure (concat paths) - where - descend name = do - let path = root name - isDir <- doesDirectoryExist path - if isDir - then listJsonFilesRecursive path - else pure [path | ".json" `isSuffixOf` path] - -validatorArgs :: [String] -> [String] -validatorArgs args = - [ "run" - , "nixpkgs#check-jsonschema" - , "--" - ] - <> args - -runValidator :: String -> [String] -> IO () -runValidator message args = do - putStrLn message - (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "nix" args) "" - case exitCode of - ExitSuccess -> do - unless (null stdoutText) (putStr stdoutText) - unless (null stderrText) (putStr stderrText) - ExitFailure _ -> do - unless (null stdoutText) (putStr stdoutText) - unless (null stderrText) (putStr stderrText) - exitFailure +main = Validate.main diff --git a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs new file mode 100644 index 00000000000..6c4f27f6967 --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs @@ -0,0 +1,249 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} + +module TraceSchemaGen.ApplySchemaOverrides + ( Config (..) + , defaultConfig + , defaultRoot + , findDestructiveOps + , listOverrideFiles + , main + , mergePatch + , normalizePatch + , overrideRelToTarget + , parseArgs + , processOverride + , readJsonFile + , stripPrefixPath + ) where + +import qualified Data.Aeson as A +import qualified Data.Aeson.Encode.Pretty as AP +import qualified Data.Aeson.Key as K +import qualified Data.Aeson.KeyMap as KM +import qualified Data.ByteString.Lazy as BL +import Control.Monad (forM, unless, when) +import Data.List (isSuffixOf, sort) +import Data.Maybe (fromMaybe) +import System.Directory + ( createDirectoryIfMissing + , doesDirectoryExist + , doesFileExist + , listDirectory + ) +import System.Environment (getArgs) +import System.Exit (exitFailure, exitSuccess) +import System.FilePath + ( () + , joinPath + , replaceFileName + , splitDirectories + , takeDirectory + , takeFileName + ) + +defaultRoot :: FilePath +defaultRoot = "bench/trace-schemas" + +data Config = Config + { cfgRoot :: FilePath + , cfgCheck :: Bool + , cfgVerbose :: Bool + , cfgAllowDestructive :: Bool + } + deriving (Eq, Show) + +defaultConfig :: Config +defaultConfig = + Config + { cfgRoot = defaultRoot + , cfgCheck = False + , cfgVerbose = False + , cfgAllowDestructive = False + } + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + let overridesRoot = cfgRoot config "overrides" + overridesExists <- doesDirectoryExist overridesRoot + if not overridesExists + then do + when (cfgVerbose config) $ + putStrLn $ "No overrides directory at " <> overridesRoot + exitSuccess + else do + overrideFiles <- sort <$> listOverrideFiles overridesRoot + results <- forM overrideFiles (processOverride config) + let changedTargets = [target | (target, True) <- results] + when (cfgCheck config && not (null changedTargets)) $ do + putStrLn "Schema overrides are not applied (or generated files were edited directly):" + mapM_ (\fp -> putStrLn $ " " <> fp) changedTargets + exitFailure + when (cfgVerbose config) $ do + putStrLn $ "Processed " <> show (length overrideFiles) <> " override file(s)." + putStrLn $ "Updated " <> show (length changedTargets) <> " target schema file(s)." + exitSuccess + +parseArgs :: Config -> [String] -> IO Config +parseArgs = go + where + go cfg [] = pure cfg + go cfg ("--root" : root : rest) = go cfg {cfgRoot = root} rest + go cfg ("--check" : rest) = go cfg {cfgCheck = True} rest + go cfg ("--verbose" : rest) = go cfg {cfgVerbose = True} rest + go cfg ("--allow-destructive" : rest) = go cfg {cfgAllowDestructive = True} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs [options]" + , "" + , "Options:" + , " --root PATH trace-schemas root path (default: bench/trace-schemas)" + , " --check Dry-run; fail if any target file would change" + , " --verbose Print each override mapping" + , " --allow-destructive Allow overrides that delete or replace existing fields" + ] + +listOverrideFiles :: FilePath -> IO [FilePath] +listOverrideFiles root = do + entries <- listDirectory root + fmap concat $ + forM entries $ \name -> do + let path = root name + isDir <- doesDirectoryExist path + if isDir + then listOverrideFiles path + else pure [path | ".override.json" `isSuffixOf` name] + +processOverride :: Config -> FilePath -> IO (FilePath, Bool) +processOverride config overrideFile = do + let overridesRoot = cfgRoot config "overrides" + rel <- stripPrefixPath overridesRoot overrideFile + targetRel <- overrideRelToTarget rel + let targetFile = cfgRoot config targetRel + + targetExists <- doesFileExist targetFile + unless targetExists $ + failWith $ + "Override target does not exist: " <> targetFile + <> " (from " <> overrideFile <> ")" + + targetValue <- readJsonFile targetFile + overrideValue <- readJsonFile overrideFile + patchValue <- normalizePatch overrideFile overrideValue + + unless (cfgAllowDestructive config) $ do + let destructiveOps = findDestructiveOps targetValue patchValue + unless (null destructiveOps) $ + failWith $ + "Override " <> overrideFile <> " contains destructive operations:\n" + <> unlines (map (" " <>) destructiveOps) + <> "Pass --allow-destructive to permit destructive overrides." + + let mergedValue = mergePatch targetValue patchValue + let changed = mergedValue /= targetValue + + when (cfgVerbose config) $ + putStrLn $ overrideFile <> " -> " <> targetFile + + when (changed && not (cfgCheck config)) $ do + createDirectoryIfMissing True (takeDirectory targetFile) + BL.writeFile targetFile (AP.encodePretty mergedValue) + + pure (targetFile, changed) + +readJsonFile :: FilePath -> IO A.Value +readJsonFile fp = do + result <- A.eitherDecodeFileStrict' fp + case result of + Left err -> failWith $ "Invalid JSON in " <> fp <> ": " <> err + Right v -> pure v + +normalizePatch :: FilePath -> A.Value -> IO A.Value +normalizePatch source v@(A.Object o) = + case KM.lookup (K.fromString "patch") o of + Nothing -> pure v + Just patch@(A.Object _) -> pure patch + Just _ -> + failWith $ + "Override \"patch\" must be an object in " <> source +normalizePatch source _ = + failWith $ "Override must be a JSON object: " <> source + +findDestructiveOps :: A.Value -> A.Value -> [String] +findDestructiveOps target patch = goObj "" targetObj patchObj + where + targetObj = case target of { A.Object o -> o; _ -> KM.empty } + patchObj = case patch of { A.Object o -> o; _ -> KM.empty } + + goObj path tObj pObj = concatMap (checkKey path tObj) (KM.toList pObj) + + checkKey path tObj (k, pv) = + let kStr = K.toString k + keyPath = if null path then kStr else path <> "." <> kStr + in case (KM.lookup k tObj, pv) of + (Nothing, _) -> [] + (Just _, A.Null) -> [keyPath <> ": field deletion"] + (Just (A.Object tv), A.Object pv') -> goObj keyPath tv pv' + (Just _, _) -> [keyPath <> ": field replacement"] + +mergePatch :: A.Value -> A.Value -> A.Value +mergePatch _ A.Null = A.Null +mergePatch _ patch@(A.Bool _) = patch +mergePatch _ patch@(A.String _) = patch +mergePatch _ patch@(A.Number _) = patch +mergePatch _ patch@(A.Array _) = patch +mergePatch target (A.Object patchObj) = + let targetObj = + case target of + A.Object o -> o + _ -> KM.empty + in A.Object (mergeObject targetObj patchObj) + +mergeObject :: A.Object -> A.Object -> A.Object +mergeObject = KM.foldrWithKey step + where + step key value acc = + case value of + A.Null -> KM.delete key acc + A.Object _ -> + let existing = fromMaybe A.Null (KM.lookup key acc) + merged = mergePatch existing value + in KM.insert key merged acc + _ -> KM.insert key value acc + +stripPrefixPath :: FilePath -> FilePath -> IO FilePath +stripPrefixPath prefix full = + case stripPrefixList (splitDirectories prefix) (splitDirectories full) of + Just suffix -> pure (joinPath suffix) + Nothing -> + failWith $ + "Path " <> full <> " is not under " <> prefix + +overrideRelToTarget :: FilePath -> IO FilePath +overrideRelToTarget rel = do + let name = takeFileName rel + let suffix = ".override.json" :: String + unless (suffix `isSuffixOf` name) $ + failWith $ "Override must end with .override.json: " <> rel + let targetName = take (length name - length suffix) name <> ".json" + pure (replaceFileName rel targetName) + +stripPrefixList :: Eq a => [a] -> [a] -> Maybe [a] +stripPrefixList [] ys = Just ys +stripPrefixList _ [] = Nothing +stripPrefixList (x : xs) (y : ys) + | x == y = stripPrefixList xs ys + | otherwise = Nothing + +failWith :: String -> IO a +failWith msg = putStrLn ("ERROR: " <> msg) >> exitFailure diff --git a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs new file mode 100644 index 00000000000..e60affceaeb --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs @@ -0,0 +1,112 @@ +{-# LANGUAGE ScopedTypeVariables #-} + +module TraceSchemaGen.CheckOverrideCoverage + ( Config (..) + , defaultConfig + , generatedRoots + , generatedToOverride + , isGeneratedJson + , listChangedPaths + , main + , overridesRoot + , parseArgs + ) where + +import Control.Monad (unless, when) +import Data.List (isPrefixOf, isSuffixOf, sort, stripPrefix) +import qualified Data.Set as Set +import System.Environment (getArgs) +import System.Exit (ExitCode (..), exitFailure, exitSuccess) +import System.FilePath (dropExtension) +import System.Process (proc, readCreateProcessWithExitCode) + +generatedRoots :: [FilePath] +generatedRoots = + [ "bench/trace-schemas/messages" + , "bench/trace-schemas/types" + ] + +overridesRoot :: FilePath +overridesRoot = "bench/trace-schemas/overrides" + +newtype Config = Config + { cfgRange :: Maybe String + } + deriving (Eq, Show) + +defaultConfig :: Config +defaultConfig = Config {cfgRange = Nothing} + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + generatedChanged <- listChangedPaths config generatedRoots + overrideChanged <- Set.fromList <$> listChangedPaths config [overridesRoot] + + let generatedChangedSet = Set.fromList (filter isGeneratedJson generatedChanged) + let requiredOverrideFiles = Set.map generatedToOverride generatedChangedSet + let missing = sort (Set.toList (Set.difference requiredOverrideFiles overrideChanged)) + + when (null generatedChangedSet) $ do + putStrLn "No generated trace-schema files changed." + exitSuccess + + unless (null missing) $ do + putStrLn "Generated schema files changed without matching override sidecar updates:" + mapM_ (\fp -> putStrLn $ " " <> fp) missing + putStrLn "" + putStrLn "Update corresponding files under bench/trace-schemas/overrides/." + exitFailure + + putStrLn "Override coverage check passed." + exitSuccess + +parseArgs :: Config -> [String] -> IO Config +parseArgs = go + where + go cfg [] = pure cfg + go cfg ("--range" : r : rest) = go cfg {cfgRange = Just r} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs [options]" + , "" + , "Options:" + , " --range GIT_RANGE Diff range to inspect, e.g. origin/master...HEAD" + ] + +listChangedPaths :: Config -> [FilePath] -> IO [FilePath] +listChangedPaths config paths = do + let baseArgs = + case cfgRange config of + Just r -> ["diff", "--name-only", r, "--"] + Nothing -> ["diff", "--name-only", "--"] + args = baseArgs <> paths + (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "git" args) "" + case exitCode of + ExitSuccess -> pure (filter (not . null) (lines stdoutText)) + ExitFailure _ -> do + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + exitFailure + +isGeneratedJson :: FilePath -> Bool +isGeneratedJson path = + any (`isPrefixOf` path) generatedRoots + && ".schema.json" `isSuffixOf` path + +generatedToOverride :: FilePath -> FilePath +generatedToOverride generatedPath = + case stripPrefix "bench/trace-schemas/" generatedPath of + Just rel -> + let withoutSuffix = dropExtension rel + in overridesRoot <> "/" <> withoutSuffix <> ".override.json" + Nothing -> generatedPath diff --git a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ValidateTraceSchemas.hs b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ValidateTraceSchemas.hs new file mode 100644 index 00000000000..720c8e097d8 --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ValidateTraceSchemas.hs @@ -0,0 +1,136 @@ +{-# LANGUAGE ScopedTypeVariables #-} + +module TraceSchemaGen.ValidateTraceSchemas + ( Config (..) + , checkInputs + , defaultConfig + , defaultMessagesDir + , defaultMetaSchema + , listJsonFilesRecursive + , main + , parseArgs + , runValidator + , validatorArgs + ) where + +import Control.Monad (unless, when) +import Data.List (isSuffixOf) +import System.Directory + ( doesDirectoryExist + , doesFileExist + , listDirectory + ) +import System.Environment (getArgs) +import System.Exit (ExitCode (..), exitFailure, exitSuccess) +import System.FilePath (()) +import System.Process (proc, readCreateProcessWithExitCode) + +defaultMetaSchema :: FilePath +defaultMetaSchema = "bench/trace-schemas/meta.schema.json" + +defaultMessagesDir :: FilePath +defaultMessagesDir = "bench/trace-schemas/messages" + +data Config = Config + { cfgMetaSchema :: FilePath + , cfgMessagesDir :: FilePath + } + deriving (Eq, Show) + +defaultConfig :: Config +defaultConfig = + Config + { cfgMetaSchema = defaultMetaSchema + , cfgMessagesDir = defaultMessagesDir + } + +main :: IO () +main = do + config <- parseArgs defaultConfig =<< getArgs + checkInputs config + schemaFiles <- listJsonFilesRecursive (cfgMessagesDir config) + when (null schemaFiles) $ do + putStrLn $ "No schema files found under " <> cfgMessagesDir config + exitFailure + + runValidator "Validating meta schema..." (validatorArgs ["--check-metaschema", cfgMetaSchema config]) + runValidator + ("Validating " <> show (length schemaFiles) <> " trace schema files...") + (validatorArgs (["--schemafile", cfgMetaSchema config] <> schemaFiles)) + + putStrLn $ + "Validated " + <> show (length schemaFiles) + <> " trace schema file(s) against " + <> cfgMetaSchema config + exitSuccess + +parseArgs :: Config -> [String] -> IO Config +parseArgs = go + where + go cfg [] = pure cfg + go cfg ("--meta-schema" : path : rest) = go cfg {cfgMetaSchema = path} rest + go cfg ("--messages-dir" : path : rest) = go cfg {cfgMessagesDir = path} rest + go _ ["--help"] = printHelp >> exitSuccess + go _ ["-h"] = printHelp >> exitSuccess + go _ unknown = do + putStrLn $ "Unrecognized arguments: " <> unwords unknown + printHelp + exitFailure + +printHelp :: IO () +printHelp = + putStrLn $ + unlines + [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs [options]" + , "" + , "Options:" + , " --meta-schema PATH Path to the meta schema." + , " --messages-dir PATH Directory containing trace schema files." + ] + +checkInputs :: Config -> IO () +checkInputs config = do + metaExists <- doesFileExist (cfgMetaSchema config) + unless metaExists $ do + putStrLn $ "Meta schema not found: " <> cfgMetaSchema config + exitFailure + + messagesExists <- doesDirectoryExist (cfgMessagesDir config) + unless messagesExists $ do + putStrLn $ "Messages directory not found: " <> cfgMessagesDir config + exitFailure + +listJsonFilesRecursive :: FilePath -> IO [FilePath] +listJsonFilesRecursive root = do + entries <- listDirectory root + paths <- mapM descend entries + pure (concat paths) + where + descend name = do + let path = root name + isDir <- doesDirectoryExist path + if isDir + then listJsonFilesRecursive path + else pure [path | ".json" `isSuffixOf` path] + +validatorArgs :: [String] -> [String] +validatorArgs args = + [ "run" + , "nixpkgs#check-jsonschema" + , "--" + ] + <> args + +runValidator :: String -> [String] -> IO () +runValidator message args = do + putStrLn message + (exitCode, stdoutText, stderrText) <- readCreateProcessWithExitCode (proc "nix" args) "" + case exitCode of + ExitSuccess -> do + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + ExitFailure _ -> do + unless (null stdoutText) (putStr stdoutText) + unless (null stderrText) (putStr stderrText) + exitFailure diff --git a/bench/trace-schemas/scripts/schema-gen/test/Main.hs b/bench/trace-schemas/scripts/schema-gen/test/Main.hs new file mode 100644 index 00000000000..ac705798803 --- /dev/null +++ b/bench/trace-schemas/scripts/schema-gen/test/Main.hs @@ -0,0 +1,131 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main (main) where + +import qualified Data.Aeson as A +import qualified Data.ByteString.Lazy as BL +import qualified TraceSchemaGen.ApplySchemaOverrides as Apply +import qualified TraceSchemaGen.CheckOverrideCoverage as Coverage +import qualified TraceSchemaGen.ValidateTraceSchemas as Validate +import Control.Exception (catch) +import Data.List (sort) +import System.Directory (createDirectoryIfMissing) +import System.Exit (ExitCode (..)) +import System.FilePath (()) +import System.IO.Temp (withSystemTempDirectory) +import Test.Tasty (TestTree, defaultMain, testGroup) +import Test.Tasty.HUnit + +main :: IO () +main = defaultMain tests + +tests :: TestTree +tests = + testGroup "trace-schema-gen" + [ applySchemaOverridesTests + , checkOverrideCoverageTests + , validateTraceSchemasTests + ] + +applySchemaOverridesTests :: TestTree +applySchemaOverridesTests = + testGroup "ApplySchemaOverrides" + [ testCase "overrideRelToTarget maps nested override file" $ do + actual <- Apply.overrideRelToTarget "messages/Foo/Bar.schema.override.json" + actual @?= "messages/Foo/Bar.schema.json" + , testCase "findDestructiveOps reports replacement and deletion" $ do + let target = A.object ["keep" A..= ("x" :: String), "nested" A..= A.object ["gone" A..= (1 :: Int)]] + let patch = A.object ["keep" A..= (2 :: Int), "nested" A..= A.object ["gone" A..= A.Null]] + Apply.findDestructiveOps target patch + @?= ["keep: field replacement", "nested.gone: field deletion"] + , testCase "processOverride applies additive patch in temp tree" $ + withSystemTempDirectory "trace-schema-gen" $ \root -> do + let target = root "messages" "Example.schema.json" + let override = root "overrides" "messages" "Example.schema.override.json" + createDirectoryIfMissing True (root "messages") + createDirectoryIfMissing True (root "overrides" "messages") + BL.writeFile target (A.encode (A.object ["existing" A..= ("value" :: String)])) + BL.writeFile override (A.encode (A.object ["patch" A..= A.object ["added" A..= (1 :: Int)]])) + + let cfg = Apply.defaultConfig {Apply.cfgRoot = root} + (writtenTarget, changed) <- Apply.processOverride cfg override + + writtenTarget @?= target + assertBool "expected target to change" changed + + decoded <- A.eitherDecodeFileStrict' target + decoded @?= Right (A.object ["existing" A..= ("value" :: String), "added" A..= (1 :: Int)]) + , testCase "processOverride rejects destructive patch by default" $ + withSystemTempDirectory "trace-schema-gen" $ \root -> do + let target = root "messages" "Example.schema.json" + let override = root "overrides" "messages" "Example.schema.override.json" + createDirectoryIfMissing True (root "messages") + createDirectoryIfMissing True (root "overrides" "messages") + BL.writeFile target (A.encode (A.object ["existing" A..= ("value" :: String)])) + BL.writeFile override (A.encode (A.object ["patch" A..= A.object ["existing" A..= (1 :: Int)]])) + + let cfg = Apply.defaultConfig {Apply.cfgRoot = root} + result <- catch (Apply.processOverride cfg override >> pure Nothing) exitCodeToMaybe + assertBool "expected processOverride to exit with failure" $ + case result of + Just (ExitFailure _) -> True + _ -> False + ] + +checkOverrideCoverageTests :: TestTree +checkOverrideCoverageTests = + testGroup "CheckOverrideCoverage" + [ testCase "isGeneratedJson matches schema outputs only" $ do + assertBool "messages schema should match" $ + Coverage.isGeneratedJson "bench/trace-schemas/messages/Foo.schema.json" + assertBool "types schema should match" $ + Coverage.isGeneratedJson "bench/trace-schemas/types/Foo.schema.json" + assertBool "override file should not match" $ + not (Coverage.isGeneratedJson "bench/trace-schemas/overrides/messages/Foo.schema.override.json") + , testCase "generatedToOverride maps generated schema path" $ do + Coverage.generatedToOverride "bench/trace-schemas/messages/Foo.schema.json" + @?= "bench/trace-schemas/overrides/messages/Foo.schema.override.json" + ] + +validateTraceSchemasTests :: TestTree +validateTraceSchemasTests = + testGroup "ValidateTraceSchemas" + [ testCase "listJsonFilesRecursive finds nested json files only" $ + withSystemTempDirectory "trace-schema-gen" $ \root -> do + let nested = root "nested" + createDirectoryIfMissing True nested + writeFile (root "one.json") "{}" + writeFile (nested "two.json") "{}" + writeFile (nested "skip.txt") "nope" + + files <- sort <$> Validate.listJsonFilesRecursive root + files @?= sort [root "one.json", nested "two.json"] + , testCase "validatorArgs prepend nix check-jsonschema invocation" $ do + Validate.validatorArgs ["--schemafile", "meta.schema.json", "msg.schema.json"] + @?= ["run", "nixpkgs#check-jsonschema", "--", "--schemafile", "meta.schema.json", "msg.schema.json"] + , testCase "checkInputs accepts existing files and directories" $ + withSystemTempDirectory "trace-schema-gen" $ \root -> do + let meta = root "meta.schema.json" + let messages = root "messages" + writeFile meta "{}" + createDirectoryIfMissing True messages + Validate.checkInputs Validate.defaultConfig + { Validate.cfgMetaSchema = meta + , Validate.cfgMessagesDir = messages + } + , testCase "checkInputs fails on missing inputs" $ + withSystemTempDirectory "trace-schema-gen" $ \root -> do + let cfg = + Validate.defaultConfig + { Validate.cfgMetaSchema = root "missing.schema.json" + , Validate.cfgMessagesDir = root "missing-dir" + } + result <- catch (Validate.checkInputs cfg >> pure Nothing) exitCodeToMaybe + assertBool "expected checkInputs to exit with failure" $ + case result of + Just (ExitFailure _) -> True + _ -> False + ] + +exitCodeToMaybe :: ExitCode -> IO (Maybe ExitCode) +exitCodeToMaybe code = pure (Just code) diff --git a/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal b/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal index 78a9738b3aa..7b0124ddbc4 100644 --- a/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal +++ b/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal @@ -21,10 +21,13 @@ common common build-depends: base >= 4.14 && < 5, -executable schema-gen +library import: common - main-is: GhciSchemaGen.hs - hs-source-dirs: . + hs-source-dirs: src + exposed-modules: + TraceSchemaGen.ApplySchemaOverrides + TraceSchemaGen.CheckOverrideCoverage + TraceSchemaGen.ValidateTraceSchemas build-depends: aeson, aeson-pretty, @@ -36,25 +39,34 @@ executable schema-gen text, vector, -executable apply-schema-overrides +executable schema-gen import: common - main-is: ApplySchemaOverrides.hs + main-is: GhciSchemaGen.hs hs-source-dirs: . build-depends: aeson, aeson-pretty, bytestring, + containers, directory, filepath, + process, + text, + vector, + +executable apply-schema-overrides + import: common + main-is: ApplySchemaOverrides.hs + hs-source-dirs: . + build-depends: + trace-schema-gen, executable validate-trace-schemas import: common main-is: ValidateTraceSchemas.hs hs-source-dirs: . build-depends: - directory, - filepath, - process, + trace-schema-gen, executable validate-trace-log import: common @@ -74,5 +86,20 @@ executable check-override-coverage main-is: CheckOverrideCoverage.hs hs-source-dirs: . build-depends: - containers, - process, + trace-schema-gen, + +test-suite trace-schema-gen-test + import: common + type: exitcode-stdio-1.0 + hs-source-dirs: test + main-is: Main.hs + build-depends: + aeson, + bytestring, + directory, + filepath, + tasty, + tasty-hunit, + temporary, + text, + trace-schema-gen, From 1e15488bb204d98fcb9dd067c1ba86c9a9d985da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Thu, 23 Apr 2026 17:47:07 +0200 Subject: [PATCH 08/11] Use optparse-applicative for CL parsing --- .../TraceSchemaGen/ApplySchemaOverrides.hs | 88 ++++++++++++------- .../TraceSchemaGen/CheckOverrideCoverage.hs | 58 +++++++----- .../scripts/schema-gen/trace-schema-gen.cabal | 1 + 3 files changed, 89 insertions(+), 58 deletions(-) diff --git a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs index 6c4f27f6967..8988e69c68b 100644 --- a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs +++ b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/ApplySchemaOverrides.hs @@ -11,7 +11,6 @@ module TraceSchemaGen.ApplySchemaOverrides , mergePatch , normalizePatch , overrideRelToTarget - , parseArgs , processOverride , readJsonFile , stripPrefixPath @@ -25,13 +24,30 @@ import qualified Data.ByteString.Lazy as BL import Control.Monad (forM, unless, when) import Data.List (isSuffixOf, sort) import Data.Maybe (fromMaybe) +import Options.Applicative + ( Parser + , ParserInfo + , execParser + , fullDesc + , header + , help + , helper + , info + , long + , metavar + , progDesc + , showDefault + , strOption + , switch + , value + , (<**>) + ) import System.Directory ( createDirectoryIfMissing , doesDirectoryExist , doesFileExist , listDirectory ) -import System.Environment (getArgs) import System.Exit (exitFailure, exitSuccess) import System.FilePath ( () @@ -64,7 +80,7 @@ defaultConfig = main :: IO () main = do - config <- parseArgs defaultConfig =<< getArgs + config <- execParser parserInfo let overridesRoot = cfgRoot config "overrides" overridesExists <- doesDirectoryExist overridesRoot if not overridesExists @@ -85,33 +101,37 @@ main = do putStrLn $ "Updated " <> show (length changedTargets) <> " target schema file(s)." exitSuccess -parseArgs :: Config -> [String] -> IO Config -parseArgs = go - where - go cfg [] = pure cfg - go cfg ("--root" : root : rest) = go cfg {cfgRoot = root} rest - go cfg ("--check" : rest) = go cfg {cfgCheck = True} rest - go cfg ("--verbose" : rest) = go cfg {cfgVerbose = True} rest - go cfg ("--allow-destructive" : rest) = go cfg {cfgAllowDestructive = True} rest - go _ ["--help"] = printHelp >> exitSuccess - go _ ["-h"] = printHelp >> exitSuccess - go _ unknown = do - putStrLn $ "Unrecognized arguments: " <> unwords unknown - printHelp - exitFailure - -printHelp :: IO () -printHelp = - putStrLn $ - unlines - [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs [options]" - , "" - , "Options:" - , " --root PATH trace-schemas root path (default: bench/trace-schemas)" - , " --check Dry-run; fail if any target file would change" - , " --verbose Print each override mapping" - , " --allow-destructive Allow overrides that delete or replace existing fields" - ] +configParser :: Parser Config +configParser = + Config + <$> strOption + ( long "root" + <> metavar "PATH" + <> value defaultRoot + <> showDefault + <> help "trace-schemas root path" + ) + <*> switch + ( long "check" + <> help "Dry-run; fail if any target file would change" + ) + <*> switch + ( long "verbose" + <> help "Print each override mapping" + ) + <*> switch + ( long "allow-destructive" + <> help "Allow overrides that delete or replace existing fields" + ) + +parserInfo :: ParserInfo Config +parserInfo = + info + (configParser <**> helper) + ( fullDesc + <> progDesc "Apply schema override sidecars to generated trace schemas" + <> header "apply-schema-overrides" + ) listOverrideFiles :: FilePath -> IO [FilePath] listOverrideFiles root = do @@ -212,14 +232,14 @@ mergePatch target (A.Object patchObj) = mergeObject :: A.Object -> A.Object -> A.Object mergeObject = KM.foldrWithKey step where - step key value acc = - case value of + step key patchValue acc = + case patchValue of A.Null -> KM.delete key acc A.Object _ -> let existing = fromMaybe A.Null (KM.lookup key acc) - merged = mergePatch existing value + merged = mergePatch existing patchValue in KM.insert key merged acc - _ -> KM.insert key value acc + _ -> KM.insert key patchValue acc stripPrefixPath :: FilePath -> FilePath -> IO FilePath stripPrefixPath prefix full = diff --git a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs index e60affceaeb..1c380a54338 100644 --- a/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs +++ b/bench/trace-schemas/scripts/schema-gen/src/TraceSchemaGen/CheckOverrideCoverage.hs @@ -9,13 +9,26 @@ module TraceSchemaGen.CheckOverrideCoverage , listChangedPaths , main , overridesRoot - , parseArgs ) where import Control.Monad (unless, when) import Data.List (isPrefixOf, isSuffixOf, sort, stripPrefix) +import Options.Applicative + ( Parser + , ParserInfo + , execParser + , fullDesc + , help + , helper + , info + , long + , metavar + , optional + , progDesc + , strOption + , (<**>) + ) import qualified Data.Set as Set -import System.Environment (getArgs) import System.Exit (ExitCode (..), exitFailure, exitSuccess) import System.FilePath (dropExtension) import System.Process (proc, readCreateProcessWithExitCode) @@ -39,7 +52,7 @@ defaultConfig = Config {cfgRange = Nothing} main :: IO () main = do - config <- parseArgs defaultConfig =<< getArgs + config <- execParser parserInfo generatedChanged <- listChangedPaths config generatedRoots overrideChanged <- Set.fromList <$> listChangedPaths config [overridesRoot] @@ -61,27 +74,24 @@ main = do putStrLn "Override coverage check passed." exitSuccess -parseArgs :: Config -> [String] -> IO Config -parseArgs = go - where - go cfg [] = pure cfg - go cfg ("--range" : r : rest) = go cfg {cfgRange = Just r} rest - go _ ["--help"] = printHelp >> exitSuccess - go _ ["-h"] = printHelp >> exitSuccess - go _ unknown = do - putStrLn $ "Unrecognized arguments: " <> unwords unknown - printHelp - exitFailure - -printHelp :: IO () -printHelp = - putStrLn $ - unlines - [ "Usage: runghc bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs [options]" - , "" - , "Options:" - , " --range GIT_RANGE Diff range to inspect, e.g. origin/master...HEAD" - ] +configParser :: Parser Config +configParser = + Config + <$> optional + ( strOption + ( long "range" + <> metavar "GIT_RANGE" + <> help "Diff range to inspect, e.g. origin/master...HEAD" + ) + ) + +parserInfo :: ParserInfo Config +parserInfo = + info + (configParser <**> helper) + ( fullDesc + <> progDesc "Check that changed generated schemas have matching override updates" + ) listChangedPaths :: Config -> [FilePath] -> IO [FilePath] listChangedPaths config paths = do diff --git a/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal b/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal index 7b0124ddbc4..f10f32355d3 100644 --- a/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal +++ b/bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal @@ -35,6 +35,7 @@ library containers, directory, filepath, + optparse-applicative, process, text, vector, From 75417797a4597b049dac83df85b4c686eed318e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Fri, 24 Apr 2026 10:00:01 +0200 Subject: [PATCH 09/11] Fix --- bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs index 907602d6d02..63ba981a475 100644 --- a/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs +++ b/bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs @@ -13,7 +13,7 @@ import qualified Data.Aeson.Key as K import qualified Data.Vector as V import Data.Char (isAlphaNum, isLower, isUpper, isSpace, toLower) import Data.List (elemIndex, foldl', isInfixOf, isPrefixOf, isSuffixOf, sortOn, stripPrefix) -import Data.Maybe (catMaybes, fromMaybe, listToMaybe, mapMaybe) +import Data.Maybe (fromMaybe, listToMaybe, mapMaybe) import Data.Ord (Down (..)) import System.Directory import System.Environment (getArgs) From 23034d94c41f221b218571bf265da5397e645d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Fri, 24 Apr 2026 10:16:26 +0200 Subject: [PATCH 10/11] trace-schemas: run schema tools via flake executables --- Makefile | 6 ++-- .../scripts/schema-gen/README.md | 30 ++++++++++++++----- .../schema-gen/RegenerateTraceSchemas.sh | 9 ++---- 3 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 7c469228364..50df92b1333 100644 --- a/Makefile +++ b/Makefile @@ -42,13 +42,13 @@ trace-schemas-regenerate: ## Regenerate trace schemas, apply overrides, validate bash bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh trace-schemas-overrides-check: ## Check whether all schema overrides are applied - nix develop -c bash -lc "GHC_ENVIRONMENT=- runghc -package-env - bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --check --verbose" + nix run .#apply-schema-overrides -- --check --verbose trace-schemas-overrides-coverage: ## Fail when generated schema files change without matching override sidecars (use RANGE=origin/master...HEAD in CI) - nix develop -c bash -lc "GHC_ENVIRONMENT=- runghc -package-env - bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs ${if ${RANGE},--range ${RANGE}}" + nix run .#check-override-coverage -- ${if ${RANGE},--range ${RANGE}} trace-schemas-validate: ## Validate trace message schemas against meta.schema.json - nix develop -c bash -lc "GHC_ENVIRONMENT=- runghc -package-env - bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs" + nix run .#validate-trace-schemas ### ### Workbench diff --git a/bench/trace-schemas/scripts/schema-gen/README.md b/bench/trace-schemas/scripts/schema-gen/README.md index fa8948c3e9f..1e20cd28655 100644 --- a/bench/trace-schemas/scripts/schema-gen/README.md +++ b/bench/trace-schemas/scripts/schema-gen/README.md @@ -6,13 +6,21 @@ or the step-by-step commands: `GHC_ENVIRONMENT=- nix develop -c cabal run cardano-node -- trace-documentation --config configuration/cardano/mainnet-config.yaml --output-namespace-list bench/trace-schemas/newNamespaces.txt --output-file bench/trace-schemas/trace-documentation.md` -`nix develop -c bash -c 'runghc bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs'` +`nix run .#schema-gen` -`nix develop -c bash -c "runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --verbose"` +`nix run .#apply-schema-overrides -- --verbose` -`nix develop -c bash -c "runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs"` +`nix run .#validate-trace-schemas` -`nix develop -c bash -c "runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceLog.hs --log-file run/.../stdout"` +`nix run .#validate-trace-log -- --log-file run/.../stdout` + +Additional checks: + +`make trace-schemas-overrides-check` + +`make trace-schemas-overrides-coverage RANGE=origin/master...HEAD` + +`make trace-schemas-validate` ## What it does @@ -23,7 +31,7 @@ or the step-by-step commands: ## High-level flow 1. **Find relevant Haskell files** - - Scans `cardano-node/src`, `cardano-submit-api/src`, `cardano-tracer/src`, `trace-dispatcher/src`, `trace-forward/src`, `trace-resources/src`. + - Scans `cardano-node/src`, `cardano-submit-api/src`, `cardano-tracer/src`, `trace-forward/src`, `trace-resources/src`, and several tracing-related directories in `ouroboros-network`, `ouroboros-consensus`, and `hermod-tracing`. - Warns when any configured source directory is missing, instead of silently ignoring it. - Keeps only `.hs` files that contain `forMachine` or `namespaceFor`. @@ -39,7 +47,7 @@ or the step-by-step commands: - Literal string RHS like `"kind" .= String "X"` are treated as string fields. 4. **Ask GHCi for types** - - For each file, it runs `cabal repl cardano-node` and issues `:t` queries for patterns. + - For each file, it runs GHCi and issues `:t` queries for patterns. - Extracts variable types from the returned type signatures or error output. - This becomes a map `constructor -> variable -> type`. @@ -69,14 +77,20 @@ or the step-by-step commands: - `ValidateTraceSchemas.hs` checks `meta.schema.json` with `check-jsonschema`, then validates every file in `bench/trace-schemas/messages` against that meta-schema. - The Haskell script controls discovery and execution; the actual JSON Schema validation is delegated to `check-jsonschema` via `nix run nixpkgs#check-jsonschema`. -- Run it with `runghc -package-env - ...` so the standalone script does not inherit the repo's package environment. +- Run it via the packaged flake executable: `nix run .#validate-trace-schemas`. - `ValidateTraceLog.hs` validates a real cardano-node log file: it skips the non-JSON preamble, validates the common envelope against `TraceMessage.schema.json`, validates known namespaces against the matching schema in `bench/trace-schemas/messages`, and reports namespaces that do not have a corresponding message schema. +## Packaging and tests + +- The scripts are packaged in `bench/trace-schemas/scripts/schema-gen/trace-schema-gen.cabal` as executables, which is why they can be invoked with `nix run .#...`. +- The smaller helper scripts also have a package test suite: + - `nix develop -c cabal test trace-schema-gen-test` + ## Human changes that survive regeneration - Treat `bench/trace-schemas/messages` and `bench/trace-schemas/types` as generated outputs. - Put manual edits in sidecar override patches under `bench/trace-schemas/overrides`. -- Apply overrides with `ApplySchemaOverrides.hs` after every generation. +- Apply overrides with `nix run .#apply-schema-overrides -- --verbose` after every generation. - Enforce in CI with: - `make trace-schemas-regenerate` - `make trace-schemas-overrides-check` diff --git a/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh b/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh index 77fd65a9659..c23b28493f6 100644 --- a/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh +++ b/bench/trace-schemas/scripts/schema-gen/RegenerateTraceSchemas.sh @@ -13,15 +13,12 @@ GHC_ENVIRONMENT=- nix develop -c cabal run cardano-node -- \ --output-file bench/trace-schemas/trace-documentation.md echo "[trace-schemas] Generating schemas..." -nix develop -c bash -c \ - 'runghc bench/trace-schemas/scripts/schema-gen/GhciSchemaGen.hs' +nix run .#schema-gen echo "[trace-schemas] Applying human overrides..." -nix develop -c bash -c \ - "runghc bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --verbose" +nix run .#apply-schema-overrides -- --verbose echo "[trace-schemas] Validating generated schemas..." -nix develop -c bash -c \ - "runghc bench/trace-schemas/scripts/schema-gen/ValidateTraceSchemas.hs" +nix run .#validate-trace-schemas echo "[trace-schemas] Done." From 3d2061f942b81e7b385c3241704d0fbfddeeb7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Nicklisch-Franken?= Date: Fri, 24 Apr 2026 10:28:39 +0200 Subject: [PATCH 11/11] Docu fix --- bench/trace-schemas/overrides/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bench/trace-schemas/overrides/README.md b/bench/trace-schemas/overrides/README.md index 593a5443126..34522f0c41a 100644 --- a/bench/trace-schemas/overrides/README.md +++ b/bench/trace-schemas/overrides/README.md @@ -170,12 +170,12 @@ Concrete example files are also available in: Apply overrides: -`nix develop -c bash -lc "runghc -package-env - bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --verbose"` +`nix run .#apply-schema-overrides -- --verbose` Check that overrides are already applied: -`nix develop -c bash -lc "runghc -package-env - bench/trace-schemas/scripts/schema-gen/ApplySchemaOverrides.hs --check --verbose"` +`nix run .#apply-schema-overrides -- --check --verbose` Fail when generated schema files changed without matching override file updates: -`nix develop -c bash -lc "runghc -package-env - bench/trace-schemas/scripts/schema-gen/CheckOverrideCoverage.hs --range origin/master...HEAD"` +`nix run .#check-override-coverage -- --range origin/master...HEAD`