Skip to content

CDFs for EB announcements - #6639

Open
coot wants to merge 2 commits into
leios-prototypefrom
coot/leios-cdfs
Open

CDFs for EB announcements#6639
coot wants to merge 2 commits into
leios-prototypefrom
coot/leios-cdfs

Conversation

@coot

@coot coot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Description

  • CDF counters - refactorisation
  • CDFs for EB announcements

Checklist

  • Commit sequence broadly makes sense and commits have useful messages
  • New tests are added if needed and existing tests are updated. These may include:
    • golden tests
    • property tests
    • roundtrip tests
    • integration tests
      See Running tests for more details
  • Any changes are noted in the CHANGELOG.md for affected package
    • cardano-node-chairman, cardano-submit-api and cardano-testnet instead need a
      changelog fragment in <package>/.changes/, because their CHANGELOG.md is generated
      from fragments at release time. Copy _TEMPLATE.yml from that directory, or run
      nix run github:input-output-hk/cardano-dev#herald -- new
  • The version bounds in .cabal files are updated
  • CI passes. See note on CI. The following CI checks are required:
    • Code is linted with hlint. See .github/workflows/check-hlint.yml to get the hlint version
    • Code is formatted with stylish-haskell. See .github/workflows/stylish-haskell.yml to get the stylish-haskell version
    • Code builds on Linux, MacOS and Windows for ghc-9.6 and ghc-9.12
  • Self-reviewed the diff

Note on CI

If your PR is from a fork, the necessary CI jobs won't trigger automatically for security reasons.
You will need to get someone with write privileges. Please contact IOG node developers to do this
for you.

* Moved to a new module
* Provide re-usable API

This is a preparation work for re-using the CDF calculations for Leios.
@coot
coot requested a review from a team as a code owner August 5, 2026 09:51
@coot coot linked an issue Aug 5, 2026 that may be closed by this pull request
@coot coot added the leios Means that this tickets is related to the implementation of ouroboros leios. label Aug 5, 2026
@coot
coot force-pushed the coot/leios-cdfs branch from 1f7b0f3 to ee7ea74 Compare August 5, 2026 12:59

data Config = Config { numOfDataPoints :: Int }

-- | Default `Config` keeps `k/2` data points.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The proportionality to k is easier to justify for some CDFs than for others, but it's probably fine for most?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But one other option is to just force each callers to choose a number

-- ^ index, priority, value
-> State p
-> f Counter
-> (f Counter, State p, Bool)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple questions that a comment should answer:

  • What does the Bool mean?
  • Why do we need to maintain the Counter and the State as separate things?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's only two call sites to this function and they both ignore the return value when the returned Bool is False.

So return Maybe (f Counter, State p) instead?

= if Pq.size m' > numOfDataPoints
then
case Pq.minView m' of
Nothing -> (cdfs, s, False)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use nothingToDo here too?

where
nothingToDo = (cdfs, s, False)

delay_ :: Double

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just inline this as (realToFrac delay :: Double)?

| otherwise = cdf


newtype State p = State { cdfState :: IntPSQ p NominalDiffTime }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment explaining why a Cdf needs a notion of priority?

data LeiosMetrics' c = LeiosMetrics {
lmCdfState :: Cdf.State SlotNo
-- ^ internal state which collects all data points
, lmSlotMapLate :: IntPSQ SlotNo ()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this just another c?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And maybe (Maybe SlotNo, Int) would be a simpler data structure to understand?

where
size = Cdf.size lmCdfState
cdfMetric name var = DoubleM name (fromIntegral (Cdf.counter var) / fromIntegral size)
lateAnnoucementsAllMetric = [ CounterM "leios.eb.announcement.late.all" Nothing | lmDelay > 2 ]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typos:

  • lateAnnoucementsAllMetric -> lateAnnoumcementsAllMetric
  • lateAnnoucementsPerSlotMetric -> lateAnnoucementsPerSlotMetric


calculateLeiosMetrics lm _lc _ = lm

instance LogFormatting LeiosMetrics where

@nfrisby nfrisby Aug 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 matches

instance LogFormatting ClientMetrics where
forMachine _dtal _ = mempty
asMetrics ClientMetrics {cmTraceIt = False} = []
asMetrics ClientMetrics {..} =
[ DoubleM "blockfetchclient.blockdelay" cmDelay
, IntM "blockfetchclient.blocksize" (fromIntegral cmBlockSize)
]
++ lateBlockMetric
++ if cmTraceVars
then [ cdfMetric "blockfetchclient.blockdelay.cdfOne" cmCdf1sVar
, cdfMetric "blockfetchclient.blockdelay.cdfThree" cmCdf3sVar
, cdfMetric "blockfetchclient.blockdelay.cdfFive" cmCdf5sVar
]
else []
where
size = Cdf.size cmCdfState
cdfMetric name var = DoubleM name (fromIntegral (Cdf.counter var) / fromIntegral size)
lateBlockMetric = [ CounterM "blockfetchclient.lateblocks" Nothing | cmDelay > 5 ]

, ("leios.eb.announcement.delay.cdf1600ms", "probability for EB announcemement to complete within 1600ms")
, ("leios.eb.announcement.delay.cdf1800ms", "probability for EB announcemement to complete within 1800ms")
, ("leios.eb.announcement.delay.cdf2000ms", "probability for EB announcemement to complete within 2000ms")
, ("leios.e.b.announcement.late.all", "number of late EB announcements that took longer than 2s: all peers are included")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wasn't expecting "all peers are included" here. These metrics are driven by TraceLeiosAnnouncementAccepted, which is deduped---it only fires the first time some announcement arrives.

, ("leios.eb.announcement.delay.cdf1800ms", "probability for EB announcemement to complete within 1800ms")
, ("leios.eb.announcement.delay.cdf2000ms", "probability for EB announcemement to complete within 2000ms")
, ("leios.e.b.announcement.late.all", "number of late EB announcements that took longer than 2s: all peers are included")
, ("leios.e.b.announcement.late.bySlot", "number of slots for which the earliest EB announcements took longer than 2s")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks to me like lmSlotMapLate is counting announcements rather than counting slots. Am I confused?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, I'm not clear on what lmSlotMapLate is actually doing... partly because I'm not sure what IntM is, but if I recall correctly (I can't find its definition right now), it's a gauge, so it's not accumulating anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

leios Means that this tickets is related to the implementation of ouroboros leios.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Measure diffusion distributions

2 participants