Skip to content

Commit e746469

Browse files
authored
Merge pull request #6052 from IntersectMBO/jutaro/tracer_adds
Enhancements and fixes related to logging, metrics, and testing
2 parents 16c4484 + 5c4f271 commit e746469

File tree

5 files changed

+163
-46
lines changed

5 files changed

+163
-46
lines changed

cardano-node/src/Cardano/Node/Run.hs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,11 @@ handleNodeWithTracers cmdPc nc0 p networkMagic blockType runP = do
232232
startupInfo <- getStartupInfo nc p fp
233233
mapM_ (traceWith $ startupTracer tracers) startupInfo
234234
traceNodeStartupInfo (nodeStartupInfoTracer tracers) startupInfo
235-
236235
-- sends initial BlockForgingUpdate
237236
blockForging <- snd (Api.protocolInfo runP)
237+
let isNonProducing = ncStartAsNonProducingNode nc
238238
traceWith (startupTracer tracers)
239-
(BlockForgingUpdate (if null blockForging
239+
(BlockForgingUpdate (if isNonProducing || null blockForging
240240
then DisabledBlockForging
241241
else EnabledBlockForging))
242242

@@ -278,10 +278,10 @@ handleNodeWithTracers cmdPc nc0 p networkMagic blockType runP = do
278278
>>= mapM_ (traceWith $ startupTracer tracers)
279279

280280
traceWith (nodeVersionTracer tracers) getNodeVersion
281-
281+
let isNonProducing = ncStartAsNonProducingNode nc
282282
blockForging <- snd (Api.protocolInfo runP)
283283
traceWith (startupTracer tracers)
284-
(BlockForgingUpdate (if null blockForging
284+
(BlockForgingUpdate (if isNonProducing || null blockForging
285285
then DisabledBlockForging
286286
else EnabledBlockForging))
287287

@@ -724,11 +724,11 @@ updateBlockForging startupTracer blockType nodeKernel nc = do
724724
Just Refl -> do
725725
-- TODO: check if runP' has changed
726726
blockForging <- snd (Api.protocolInfo runP')
727+
let isNonProducing = ncStartAsNonProducingNode nc
727728
traceWith startupTracer
728-
(BlockForgingUpdate (bool EnabledBlockForging
729-
DisabledBlockForging
730-
(null blockForging)))
731-
729+
(BlockForgingUpdate (if isNonProducing || null blockForging
730+
then DisabledBlockForging
731+
else EnabledBlockForging))
732732
setBlockForging nodeKernel blockForging
733733
Nothing ->
734734
traceWith startupTracer

cardano-node/src/Cardano/Node/Tracing/Tracers/ChainDB.hs

Lines changed: 102 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import Cardano.Node.Tracing.Era.Shelley ()
1919
import Cardano.Node.Tracing.Formatting ()
2020
import Cardano.Node.Tracing.Render
2121
import Cardano.Prelude (maximumDef)
22+
import Cardano.Tracing.HasIssuer
2223
import Ouroboros.Consensus.Block
2324
import Ouroboros.Consensus.HeaderValidation (HeaderEnvelopeError (..), HeaderError (..),
2425
OtherHeaderEnvelopeError)
@@ -41,6 +42,7 @@ import Ouroboros.Consensus.Util.Enclose
4142
import qualified Ouroboros.Network.AnchoredFragment as AF
4243

4344
import Data.Aeson (Value (String), object, toJSON, (.=))
45+
import qualified Data.ByteString.Base16 as B16
4446
import Data.Int (Int64)
4547
import Data.Text (Text)
4648
import qualified Data.Text as Text
@@ -50,7 +52,7 @@ import Numeric (showFFloat)
5052

5153
-- {-# ANN module ("HLint: ignore Redundant bracket" :: Text) #-}
5254

53-
-- TODO implement differently so that it uses configuration
55+
-- A limiter that is not coming from configuration, because it carries a special filter
5456
withAddedToCurrentChainEmptyLimited
5557
:: Trace IO (ChainDB.TraceEvent blk)
5658
-> IO (Trace IO (ChainDB.TraceEvent blk))
@@ -79,6 +81,7 @@ instance ( LogFormatting (Header blk)
7981
, ConvertRawHash (Header blk)
8082
, LedgerSupportsProtocol blk
8183
, InspectLedger blk
84+
, HasIssuer blk
8285
) => LogFormatting (ChainDB.TraceEvent blk) where
8386
forHuman ChainDB.TraceLastShutdownUnclean =
8487
"ChainDB is not clean. Validating all immutable chunks"
@@ -394,6 +397,7 @@ instance ( LogFormatting (Header blk)
394397
, ConvertRawHash (Header blk)
395398
, LedgerSupportsProtocol blk
396399
, InspectLedger blk
400+
, HasIssuer blk
397401
) => LogFormatting (ChainDB.TraceAddBlockEvent blk) where
398402
forHuman (ChainDB.IgnoreBlockOlderThanK pt) =
399403
"Ignoring block older than K: " <> renderRealPointAsPhrase pt
@@ -480,7 +484,31 @@ instance ( LogFormatting (Header blk)
480484
forMachine dtal (ChainDB.ChangingSelection pt) =
481485
mconcat [ "kind" .= String "TraceAddBlockEvent.ChangingSelection"
482486
, "block" .= forMachine dtal pt ]
483-
forMachine dtal (ChainDB.AddedToCurrentChain events selChangedInfo base extended) =
487+
488+
forMachine DDetailed (ChainDB.AddedToCurrentChain events selChangedInfo base extended) =
489+
let ChainInformation { .. } = chainInformation selChangedInfo base extended 0
490+
tipBlockIssuerVkHashText :: Text
491+
tipBlockIssuerVkHashText =
492+
case tipBlockIssuerVerificationKeyHash of
493+
NoBlockIssuer -> "NoBlockIssuer"
494+
BlockIssuerVerificationKeyHash bs ->
495+
Text.decodeLatin1 (B16.encode bs)
496+
in mconcat $
497+
[ "kind" .= String "AddedToCurrentChain"
498+
, "newtip" .= renderPointForDetails DDetailed (AF.headPoint extended)
499+
, "newTipSelectView" .= forMachine DDetailed (ChainDB.newTipSelectView selChangedInfo)
500+
]
501+
++ [ "oldTipSelectView" .= forMachine DDetailed oldTipSelectView
502+
| Just oldTipSelectView <- [ChainDB.oldTipSelectView selChangedInfo]
503+
]
504+
++ [ "headers" .= toJSON (forMachine DDetailed `map` addedHdrsNewChain base extended)
505+
]
506+
++ [ "events" .= toJSON (map (forMachine DDetailed) events)
507+
| not (null events) ]
508+
++ [ "tipBlockHash" .= tipBlockHash
509+
, "tipBlockParentHash" .= tipBlockParentHash
510+
, "tipBlockIssuerVKeyHash" .= tipBlockIssuerVkHashText]
511+
forMachine dtal (ChainDB.AddedToCurrentChain events selChangedInfo _base extended) =
484512
mconcat $
485513
[ "kind" .= String "AddedToCurrentChain"
486514
, "newtip" .= renderPointForDetails dtal (AF.headPoint extended)
@@ -489,11 +517,33 @@ instance ( LogFormatting (Header blk)
489517
++ [ "oldTipSelectView" .= forMachine dtal oldTipSelectView
490518
| Just oldTipSelectView <- [ChainDB.oldTipSelectView selChangedInfo]
491519
]
492-
++ [ "headers" .= toJSON (forMachine dtal `map` addedHdrsNewChain base extended)
493-
| dtal == DDetailed ]
494520
++ [ "events" .= toJSON (map (forMachine dtal) events)
495521
| not (null events) ]
496-
forMachine dtal (ChainDB.SwitchedToAFork events selChangedInfo old new) =
522+
523+
forMachine DDetailed (ChainDB.SwitchedToAFork events selChangedInfo old new) =
524+
let ChainInformation { .. } = chainInformation selChangedInfo old new 0
525+
tipBlockIssuerVkHashText :: Text
526+
tipBlockIssuerVkHashText =
527+
case tipBlockIssuerVerificationKeyHash of
528+
NoBlockIssuer -> "NoBlockIssuer"
529+
BlockIssuerVerificationKeyHash bs ->
530+
Text.decodeLatin1 (B16.encode bs)
531+
in mconcat $
532+
[ "kind" .= String "TraceAddBlockEvent.SwitchedToAFork"
533+
, "newtip" .= renderPointForDetails DDetailed (AF.headPoint new)
534+
, "newTipSelectView" .= forMachine DDetailed (ChainDB.newTipSelectView selChangedInfo)
535+
]
536+
++ [ "oldTipSelectView" .= forMachine DDetailed oldTipSelectView
537+
| Just oldTipSelectView <- [ChainDB.oldTipSelectView selChangedInfo]
538+
]
539+
++ [ "headers" .= toJSON (forMachine DDetailed `map` addedHdrsNewChain old new)
540+
]
541+
++ [ "events" .= toJSON (map (forMachine DDetailed) events)
542+
| not (null events) ]
543+
++ [ "tipBlockHash" .= tipBlockHash
544+
, "tipBlockParentHash" .= tipBlockParentHash
545+
, "tipBlockIssuerVKeyHash" .= tipBlockIssuerVkHashText]
546+
forMachine dtal (ChainDB.SwitchedToAFork events selChangedInfo _old new) =
497547
mconcat $
498548
[ "kind" .= String "TraceAddBlockEvent.SwitchedToAFork"
499549
, "newtip" .= renderPointForDetails dtal (AF.headPoint new)
@@ -502,10 +552,9 @@ instance ( LogFormatting (Header blk)
502552
++ [ "oldTipSelectView" .= forMachine dtal oldTipSelectView
503553
| Just oldTipSelectView <- [ChainDB.oldTipSelectView selChangedInfo]
504554
]
505-
++ [ "headers" .= toJSON (forMachine dtal `map` addedHdrsNewChain old new)
506-
| dtal == DDetailed ]
507555
++ [ "events" .= toJSON (map (forMachine dtal) events)
508556
| not (null events) ]
557+
509558
forMachine dtal (ChainDB.AddBlockValidation ev') =
510559
forMachine dtal ev'
511560
forMachine dtal (ChainDB.AddedBlockToVolatileDB pt (BlockNo bn) _ enclosing) =
@@ -544,22 +593,38 @@ instance ( LogFormatting (Header blk)
544593
asMetrics (ChainDB.SwitchedToAFork _warnings selChangedInfo oldChain newChain) =
545594
let forkIt = not $ AF.withinFragmentBounds (AF.headPoint oldChain)
546595
newChain
547-
ChainInformation { .. } = chainInformation selChangedInfo newChain 0
596+
ChainInformation { .. } = chainInformation selChangedInfo oldChain newChain 0
597+
tipBlockIssuerVkHashText =
598+
case tipBlockIssuerVerificationKeyHash of
599+
NoBlockIssuer -> "NoBlockIssuer"
600+
BlockIssuerVerificationKeyHash bs ->
601+
Text.decodeLatin1 (B16.encode bs)
548602
in [ DoubleM "density" (fromRational density)
549603
, IntM "slotNum" (fromIntegral slots)
550604
, IntM "blockNum" (fromIntegral blocks)
551605
, IntM "slotInEpoch" (fromIntegral slotInEpoch)
552606
, IntM "epoch" (fromIntegral (unEpochNo epoch))
553607
, CounterM "forks" (Just (if forkIt then 1 else 0))
608+
, PrometheusM "tipBlock" [("hash",tipBlockHash)
609+
,("parent_hash",tipBlockParentHash)
610+
,("issuer_VKey_hash", tipBlockIssuerVkHashText)]
554611
]
555-
asMetrics (ChainDB.AddedToCurrentChain _warnings selChangedInfo _oldChain newChain) =
612+
asMetrics (ChainDB.AddedToCurrentChain _warnings selChangedInfo oldChain newChain) =
556613
let ChainInformation { .. } =
557-
chainInformation selChangedInfo newChain 0
614+
chainInformation selChangedInfo oldChain newChain 0
615+
tipBlockIssuerVkHashText =
616+
case tipBlockIssuerVerificationKeyHash of
617+
NoBlockIssuer -> "NoBlockIssuer"
618+
BlockIssuerVerificationKeyHash bs ->
619+
Text.decodeLatin1 (B16.encode bs)
558620
in [ DoubleM "density" (fromRational density)
559621
, IntM "slotNum" (fromIntegral slots)
560622
, IntM "blockNum" (fromIntegral blocks)
561623
, IntM "slotInEpoch" (fromIntegral slotInEpoch)
562624
, IntM "epoch" (fromIntegral (unEpochNo epoch))
625+
, PrometheusM "tipBlock" [("hash",tipBlockHash)
626+
,("parent hash",tipBlockParentHash)
627+
,("issuer verification key hash", tipBlockIssuerVkHashText)]
563628
]
564629
asMetrics _ = []
565630

@@ -680,7 +745,14 @@ instance MetaTrace (ChainDB.TraceAddBlockEvent blk) where
680745
, ( "epoch"
681746
, "In which epoch is the tip of the current chain."
682747
)
748+
, ( "forks"
749+
, "counter for forks"
750+
)
751+
, ( "tipBlock"
752+
, "Values for hash, parent hash and issuer verification key hash"
753+
)
683754
]
755+
684756
metricsDocFor (Namespace _ ["AddedToCurrentChain"]) =
685757
[ ( "density"
686758
, mconcat
@@ -703,6 +775,9 @@ instance MetaTrace (ChainDB.TraceAddBlockEvent blk) where
703775
, ( "epoch"
704776
, "In which epoch is the tip of the current chain."
705777
)
778+
, ( "tipBlock"
779+
, "Values for hash, parent hash and issuer verification key hash"
780+
)
706781
]
707782
metricsDocFor _ = []
708783

@@ -1488,7 +1563,6 @@ instance MetaTrace (ChainDB.UnknownRange blk) where
14881563
namespaceFor ChainDB.MissingBlock {} = Namespace [] ["MissingBlock"]
14891564
namespaceFor ChainDB.ForkTooOld {} = Namespace [] ["ForkTooOld"]
14901565

1491-
-- TODO Tracers Is this really as intended?
14921566
severityFor _ _ = Just Debug
14931567

14941568
documentFor (Namespace _ ["MissingBlock"]) = Just
@@ -2097,22 +2171,38 @@ data ChainInformation = ChainInformation
20972171
-- ^ Relative slot number of the tip of the current chain within the
20982172
-- epoch.
20992173
, blocksUncoupledDelta :: Int64
2174+
, tipBlockHash :: Text
2175+
-- ^ Hash of the last adopted block.
2176+
, tipBlockParentHash :: Text
2177+
-- ^ Hash of the parent block of the last adopted block.
2178+
, tipBlockIssuerVerificationKeyHash :: BlockIssuerVerificationKeyHash
2179+
-- ^ Hash of the last adopted block issuer's verification key.
21002180
}
21012181

2182+
21022183
chainInformation
21032184
:: forall blk. HasHeader (Header blk)
2185+
=> HasIssuer blk
2186+
=> ConvertRawHash blk
21042187
=> ChainDB.SelectionChangedInfo blk
21052188
-> AF.AnchoredFragment (Header blk)
2189+
-> AF.AnchoredFragment (Header blk) -- ^ New fragment.
21062190
-> Int64
21072191
-> ChainInformation
2108-
chainInformation selChangedInfo frag blocksUncoupledDelta = ChainInformation
2192+
chainInformation selChangedInfo oldFrag frag blocksUncoupledDelta = ChainInformation
21092193
{ slots = unSlotNo $ fromWithOrigin 0 (AF.headSlot frag)
21102194
, blocks = unBlockNo $ fromWithOrigin (BlockNo 1) (AF.headBlockNo frag)
21112195
, density = fragmentChainDensity frag
21122196
, epoch = ChainDB.newTipEpoch selChangedInfo
21132197
, slotInEpoch = ChainDB.newTipSlotInEpoch selChangedInfo
21142198
, blocksUncoupledDelta = blocksUncoupledDelta
2199+
, tipBlockHash = renderHeaderHash (Proxy @blk) $ realPointHash (ChainDB.newTipPoint selChangedInfo)
2200+
, tipBlockParentHash = renderChainHash (Text.decodeLatin1 . B16.encode . toRawHash (Proxy @blk)) $ AF.headHash oldFrag
2201+
, tipBlockIssuerVerificationKeyHash = tipIssuerVkHash
21152202
}
2203+
where
2204+
tipIssuerVkHash :: BlockIssuerVerificationKeyHash
2205+
tipIssuerVkHash = either (const NoBlockIssuer) getIssuerVerificationKeyHash (AF.head frag)
21162206

21172207
fragmentChainDensity ::
21182208
HasHeader (Header blk)
Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,67 @@
1+
{-# LANGUAGE FlexibleContexts #-}
2+
3+
14
-- | Check namespace consistencies agains configurations
25
module Test.Cardano.Tracing.NewTracing.Consistency (tests) where
36

47
import Cardano.Node.Tracing.Consistency (checkNodeTraceConfiguration)
58

6-
import Control.Monad.IO.Class (liftIO)
9+
import Control.Monad.IO.Class (MonadIO)
710
import Data.Text
11+
import qualified System.Directory as IO
12+
import System.FilePath ((</>))
813

914
import Hedgehog (Property)
1015
import qualified Hedgehog as H
11-
import qualified Hedgehog.Extras.Test.Base as H.Base
16+
import qualified Hedgehog.Extras.Test.Base as H
17+
import qualified Hedgehog.Extras.Test.Process as H
1218
import Hedgehog.Internal.Property (PropertyName (PropertyName))
1319

14-
tests :: IO Bool
15-
tests = H.checkSequential
20+
tests :: MonadIO m => m Bool
21+
tests = do
22+
H.checkSequential
1623
$ H.Group "Configuration Consistency tests"
17-
$ test
18-
<$> [ ( []
19-
, "goodConfig.yaml")
20-
, ( [ "Config namespace error: Illegal namespace ChainDB.CopyToImmutableDBEvent2.CopiedBlockToImmutableDB"
21-
, "Config namespace error: Illegal namespace SubscriptionDNS"
22-
]
23-
, "badConfig.yaml")
24-
-- TODO: add mainnet config as good
25-
]
24+
$ Prelude.map test
25+
[ ( []
26+
-- This file name should reference the current standard config with new tracing
27+
, configSubdir
28+
, "mainnet-config-new-tracing.json"
29+
)
30+
,
31+
( []
32+
, testSubdir
33+
, "goodConfig.yaml"
34+
)
35+
, ( [ "Config namespace error: Illegal namespace ChainDB.CopyToImmutableDBEvent2.CopiedBlockToImmutableDB"
36+
, "Config namespace error: Illegal namespace SubscriptionDNS"
37+
]
38+
, testSubdir
39+
, "badConfig.yaml"
40+
)
41+
]
2642
where
27-
test (actualValue, goldenBaseName) =
28-
(PropertyName goldenBaseName, goldenTestJSON actualValue goldenBaseName)
43+
test (actualValue, subDir, goldenBaseName) =
44+
(PropertyName goldenBaseName, goldenTestJSON subDir actualValue goldenBaseName)
2945

46+
goldenTestJSON :: SubdirSelection -> [Text] -> FilePath -> Property
47+
goldenTestJSON subDir expectedOutcome goldenFileBaseName =
48+
H.withTests 1 $ H.withShrinks 0 $ H.property $ do
49+
base <- resolveDir
50+
goldenFp <- H.note $ base </> goldenFileBaseName
51+
actualValue <- H.evalIO $ checkNodeTraceConfiguration goldenFp
52+
actualValue H.=== expectedOutcome
53+
where
54+
resolveDir = case subDir of
55+
ExternalSubdir d -> do
56+
base <- H.evalIO . IO.canonicalizePath =<< H.getProjectBase
57+
pure $ base </> d
58+
InternalSubdir d ->
59+
pure d
3060

31-
goldenTestJSON :: [Text] -> FilePath -> Property
32-
goldenTestJSON expectedOutcome goldenFileBaseName =
33-
H.withTests 1 $ H.withShrinks 0 $ H.property $ do
34-
goldenFp <- H.Base.note $ addPrefix goldenFileBaseName
35-
actualValue <- liftIO $ checkNodeTraceConfiguration goldenFp
36-
actualValue H.=== expectedOutcome
37-
61+
data SubdirSelection =
62+
InternalSubdir FilePath
63+
| ExternalSubdir FilePath
3864

39-
-- | NB: this function is only used in 'goldenTestJSON' but it is defined at the
40-
-- top level so that we can refer to it in the documentation of this module.
41-
addPrefix :: FilePath -> FilePath
42-
addPrefix fname = "test/Test/Cardano/Tracing/NewTracing/data/" <> fname
65+
testSubdir, configSubdir :: SubdirSelection
66+
testSubdir = InternalSubdir "test/Test/Cardano/Tracing/NewTracing/data"
67+
configSubdir = ExternalSubdir $ "configuration" </> "cardano"

configuration/cardano/update-config-files.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ copyFile "mainnet-alonzo-genesis.json"
2020
copyFile "mainnet-byron-genesis.json"
2121
copyFile "mainnet-conway-genesis.json"
2222
copyFile "mainnet-config.json"
23+
copyFile "mainnet-config-new-tracing.json"
2324
copyFile "mainnet-shelley-genesis.json"
2425
copyFile "mainnet-topology.json"
2526

nix/haskell.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ let
194194
mainnetConfigFiles = [
195195
"configuration/cardano/mainnet-config.yaml"
196196
"configuration/cardano/mainnet-config.json"
197+
"configuration/cardano/mainnet-config-new-tracing.json"
197198
"configuration/cardano/mainnet-byron-genesis.json"
198199
"configuration/cardano/mainnet-shelley-genesis.json"
199200
"configuration/cardano/mainnet-alonzo-genesis.json"

0 commit comments

Comments
 (0)