Skip to content

[BUG] - BlockFetch.Decision documents namespaces that can never fire, and BlockFetch.Client.ClientMetrics is unknown to the config check #6667

Description

@jasagredo

Two tracers have namespaces that disagree between what is emitted, what is documented, and what a trace configuration is allowed to name. Both come from the same root cause: a tracer's type is written out by hand in Documentation.hs and Consistency.hs, and neither is type-checked against the tracer actually wired in Tracers.hs, so the three can drift apart silently.

Verified on 39d586694 against released ouroboros-consensus-4.1.0.0.

1. BlockFetch.Decision — three phantom namespaces, two missing ones

Consensus.Tracers.blockFetchDecisionTracer has carried TraceDecisionEvent since ouroboros-consensus-4.1.0.0:

-- ouroboros-consensus-4.1.0.0, Ouroboros/Consensus/Node/Tracers.hs:73
, blockFetchDecisionTracer :: f (TraceDecisionEvent remotePeer (Header blk))

Tracers.hs wires that field, so what the node emits under BlockFetch.Decision is TraceDecisionEvent, whose namespaces are PeersFetch and PeerStarvedUs (Tracers/Consensus.hs:671).

But both declaration sites still name the pre-TraceDecisionEvent type:

-- Tracing/Documentation.hs:322
blockFetchDecisionTrDoc <- documentTracer (blockFetchDecisionTr ::
   Logging.Trace IO [BlockFetch.TraceLabelPeer remotePeer
                                  (FetchDecision [Point (Header blk)])])

-- Tracing/Consistency.hs:174
blockFetchDecisionNS = map (nsGetTuple . nsReplacePrefix ["BlockFetch", "Decision"])
                (allNamespaces :: [Namespace [BlockFetch.TraceLabelPeer remotePeer
                                              (FetchDecision [Point (Header blk)])]])

whose namespaces are EmptyPeersFetch, Accept and Decline.

Effect

  • bench/trace-schemas/newNamespaces.txt:10-12 lists BlockFetch.Decision.Accept, .Decline and .EmptyPeersFetch. None of them can ever be emitted.
  • BlockFetch.Decision.PeersFetch and .PeerStarvedUs are emitted but appear in no documentation, and checkTraceConfiguration rejects them as unknown namespaces — so the two real messages cannot be re-levelled or silenced from a config file.

2. BlockFetch.Client.ClientMetrics — documented and emitted, but rejected by the config check

ClientMetrics is folded from blockfetch events and composed onto the blockfetch client tracer in Tracers.hs, and documented at the ["BlockFetch","Client"] prefix:

-- Tracing/Documentation.hs:341
blockFetchClientMetricsDoc <- documentTracer (blockFetchClientMetricsTr ::
    Logging.Trace IO ClientMetrics)

so BlockFetch.Client.ClientMetrics is in newNamespaces.txt:3. But Consistency.hs has no ClientMetrics entry — getAllNamespaces never mentions it.

Effect

The namespace is emitted and documented, yet naming it in a trace configuration produces a Config namespace error from checkTraceConfiguration.

Suggested fix

  1. In Documentation.hs and Consistency.hs, annotate the blockfetch decision tracer as TraceDecisionEvent remotePeer (Header blk), matching the record field.
  2. Add a ClientMetrics entry to getAllNamespaces at prefix ["BlockFetch","Client"], alongside the existing blockFetchClientNS.
  3. Regenerate bench/trace-schemas/newNamespaces.txt and the trace schemas.

Worth confirming whether the now-unused MetaTrace/LogFormatting instances for FetchDecision [Point header] and [TraceLabelPeer peer (FetchDecision [Point header])] still have a consumer; if not, they can go with (1).

Root cause, and preventing recurrence

Each tracer's type is stated three times — once by the Consensus.Tracers field, once in Documentation.hs, once in Consistency.hs — and only the first is checked by the compiler. The other two build their own tracer values purely to enumerate namespaces, so a wrong annotation there compiles cleanly and surfaces only as a wrong name in the generated docs or a rejected config entry.

Anything that derives all three from one place would close this off. Failing that, a test asserting that the namespace set from getAllNamespaces matches the set docTracersFirstPhase produces would have caught both of these, since they disagree in opposite directions.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions