Skip to content

Conversation

@agustinmista
Copy link
Contributor

@agustinmista agustinmista commented Nov 28, 2025

This PR introduces some general changes and QoL improvements in anticipation to the introduction of the Peras voting rules. These are separated into hopefully digestible atomic commits:

  1. Introduce Ouroboros.Consensus.Peras.Params module to keep track of Peras protocol parameters in a single place,
  2. Add small helper function onPerasRoundNo,
  3. Tweak HasPerasCertX field projection typeclasses,
  4. Introduce WithArrivalTime combinator to wrap values with a RelativeTime,
  5. Wrap validated Peras certs with their arrival time (and adapt tests).
  6. Store latest certificate seen in the PerasCertDB and add a getLatestCertSeen method to retrieve it.

Please refer to the corresponding commit messages for more information.

@agustinmista agustinmista force-pushed the peras/main-pr/new-defs-and-plumbing branch 4 times, most recently from 8d5c8a4 to 84a8f29 Compare December 1, 2025 11:15
agustinmista and others added 2 commits December 1, 2025 12:24
This commits introduces the module:

Ouroboros.Consensus.Peras.Params

To consolidate all the protocol parameters related to Peras in one
place.

Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
This commit adds a small helper to compute over Peras round numbers.
Will be needed later on to implement the Peras voting rules.

Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
@agustinmista agustinmista force-pushed the peras/main-pr/new-defs-and-plumbing branch from 84a8f29 to 14229b9 Compare December 1, 2025 11:48
agustinmista and others added 4 commits December 1, 2025 12:49
This commit simplifies the interface of the HasPerasCertX typeclasses,
removing the StandardHash superclass constraint, and splitting them into
several smaller typeclasses.

Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
This commit defines a generic WithArrivalTime combinator to wrap a value
with its arrival time (as a Relative time). This is needed by Peras in
several places, e.g., to evaluate the voting rules.

Notably, we store a raw Relative time instead of a (arguably more apt)
SlotNo or PerasRoundNo to defer as much as possible having to deal with
the case where making this translation (timestamp -> slot/round) is not
possible due to the HFC time translation horizon. Instead, the client
will need to perform this translation in a context where such a failure
cannot occur or can be more easily dealt with.

Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
This commit wraps the existing ValidatedPerasCerts stored in the
PerasCertDB with their corresponding arrival time. In addition, it
adapts tests to use either a randomly generated arrival time, or (when
appropriate) one generated by a monotonically increasing SystemTime.

Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
This commit adds a method to the PerasCertDB API to retrieve the latest
certificate seen. This is certificate needed to implement the Peras voting
and must be kept around even after garbage collection. Because of this,
we extend the internal state of the PerasCertDB to store this special
certificate on the side, and (potentially) update it after new
certificates are added to the database.

Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
@agustinmista agustinmista force-pushed the peras/main-pr/new-defs-and-plumbing branch from 14229b9 to 85e4b39 Compare December 1, 2025 11:49
Co-authored-by: Agustin Mista <agustin.mista@moduscreate.com>
Co-authored-by: Alexander Esgen <alexander.esgen@iohk.io>
Co-authored-by: Georgy Lukyanov <georgy.lukyanov@iohk.io>
Co-authored-by: Thomas BAGREL <thomas.bagrel@tweag.io>
Co-authored-by: Nicolas BACQUEY <nicolas.bacquey@tweag.io>
Copy link
Contributor

@tbagrel1 tbagrel1 left a comment

Choose a reason for hiding this comment

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

LGTM!

I think we may change the title of the PR though (and maybe part of its description) to better reflect that most changes are related to adding timestamps on certs and propagate the necessary stuff to make it work.

deriving stock Generic
deriving newtype (Enum, Eq, Ord, NoThunks)

-- | Maximum number of slots to after the start of a round to consider a
Copy link
Contributor

Choose a reason for hiding this comment

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

Slight typo here: "Maximum number of slots to after"

deriving stock Generic
deriving newtype (Enum, Eq, Ord, NoThunks)

-- | Minimum age (in slots) of a block to be voted on at the beginning of a
Copy link
Contributor

Choose a reason for hiding this comment

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

This description is not entierely clear to me

Copy link
Contributor

@nbacquey nbacquey left a comment

Choose a reason for hiding this comment

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

Besides my comments, it seems ok to undraft

Copy link
Contributor

Choose a reason for hiding this comment

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

There are other parameters that could have their place here, for instance:

  • Weight boost
  • Round length
  • Quorum size

Do we plan to put those here at a later date?

Copy link
Contributor

Choose a reason for hiding this comment

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

Now that I'm thinking about it, we have PerasCfg blk as part of SupportPeras.hs / BlockSupportsPeras typeclass. Do we have a clear line on what should be part of this PerasCfg vs what should be part of PerasParams?

-- the db since it has been opened. This certificate is not affected by garbage
-- collection, but it's forgotten when the db is closed.
--
-- NOTE: having seen a certificate is a precondition to start voting in every
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this ought to be a TODO or even a FIXME, lest we forget about it and render Peras unusable for lack of bootstrapping

instance WithId (PerasCert blk) PerasRoundNo where
getId = pcCertRound

mockSystemTime :: IOLike m => m (SystemTime m)
Copy link
Contributor

Choose a reason for hiding this comment

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

IOLike is MonadTime, I'm not sure this mocking is necessary

genSystemTime :: Gen (SystemTime Gen)
genSystemTime = do
current <- RelativeTime . fromIntegral <$> arbitrary @Word64
pure $ SystemTime{systemTimeCurrent = return current, systemTimeWait = pure ()}
Copy link
Contributor

Choose a reason for hiding this comment

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

This may cause problems: maybe we rely on the fact that successive calls to systemTimeCurrent return strictly increasing values

]
| otherwise = pure $ Some OpenDB
where
genSystemTime :: Gen (SystemTime Gen)
Copy link
Contributor

Choose a reason for hiding this comment

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

Sane remark. Also, maybe we could share that piece of code somewhere, since it's used twice?

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants