Skip to content

[WIP] Peras/HFC support#1829

Draft
agustinmista wants to merge 21 commits intomainfrom
peras/hfc-supports-peras
Draft

[WIP] Peras/HFC support#1829
agustinmista wants to merge 21 commits intomainfrom
peras/hfc-supports-peras

Conversation

@agustinmista
Copy link
Copy Markdown
Contributor

Description

Please include a meaningful description of the PR and link the relevant issues
this PR might resolve.

Also note that:

  • New code should be properly tested (even if it does not add new features).
  • The fix for a regression should include a test that reproduces said regression.

agustinmista and others added 16 commits December 16, 2025 10:00
…(instance of ObjectDiffusion) (#1679)"

This reverts commit 474bfff.
This commits introduces the module:

Ouroboros.Consensus.Peras.Params

To consolidate all the protocol parameters related to Peras in one
place. Until we defined concrete BlockSupportsPeras for the different
block types + HFC, all blocks satisfy:

type PerasCfg blk = PerasParams

Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
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 <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
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 <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
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 <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
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 <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
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 <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
This commit introduces a couple of new types to represent Peras votes
and their corresponding certificate forging API. Notably, this requires
an initial representation of notions like vote targets, vote stakes and stake
distributions over multiple stake pools.

Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Alexander Esgen <[email protected]>
Co-authored-by: Georgy Lukyanov <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
This commit adds the vote aggregation routine used to turn sufficiently
many Peras votes for the same block into a Peras certificate.

Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Agustin Mista <[email protected]>
This commit defined the API and implements an initial in-memory version
of the PerasVoteDB, used to keep track of Peras votes received through
object diffusion.

Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Agustin Mista <[email protected]>
This commit defines ObjectDiffusion instances for Peras votes using the
PerasVoteDB as a storage backend.

Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Agustin Mista <[email protected]>
Co-authored-by: Nicolas BACQUEY <[email protected]>
Co-authored-by: Thomas BAGREL <[email protected]>
Co-authored-by: Agustin Mista <[email protected]>
This commit splits the PerasCert and PerasVote types defined as part of
the degenerate global BlockSupportsPeras instance into separate modules.

This is the first step of a series of changes needed to define a proper
BlockSupportsPeras instance for individual block types and the HFC.
@agustinmista agustinmista changed the base branch from main to peras/vote-db January 14, 2026 15:34
@tbagrel1 tbagrel1 force-pushed the peras/hfc-supports-peras branch 2 times, most recently from e141a8b to 57602e0 Compare January 22, 2026 16:21
@agustinmista agustinmista force-pushed the peras/vote-db branch 4 times, most recently from 77d474b to 1860284 Compare February 2, 2026 16:05
@agustinmista agustinmista force-pushed the peras/vote-db branch 4 times, most recently from 1a3a058 to 109a836 Compare February 17, 2026 09:46
@tbagrel1 tbagrel1 force-pushed the peras/hfc-supports-peras branch from 57602e0 to 86e4177 Compare February 17, 2026 14:11
@agustinmista agustinmista force-pushed the peras/vote-db branch 8 times, most recently from bc855a0 to 023456f Compare February 23, 2026 10:22
@tbagrel1 tbagrel1 force-pushed the peras/hfc-supports-peras branch from 86e4177 to d15e94b Compare February 23, 2026 17:18
Base automatically changed from peras/vote-db to main February 23, 2026 20:46
@tbagrel1 tbagrel1 force-pushed the peras/hfc-supports-peras branch from d15e94b to 15c4cf0 Compare February 24, 2026 10:28
@tbagrel1 tbagrel1 force-pushed the peras/hfc-supports-peras branch from 7fdc36b to 62ca030 Compare February 26, 2026 09:11
@tbagrel1 tbagrel1 force-pushed the peras/hfc-supports-peras branch from c679fad to 5611fa1 Compare February 26, 2026 09:21
-- Ledger state is forecast into ledger view for the target 'PerasRoundNo'.
(OneEraLedgerView nsLedgerView) <- forecastToViewAtRound hfpcLedgerConfig ledgerState roundNo
nsVoteAndLedgerView <- ensureSameEraPair (nsVote, nsLedgerView)
-- Dispatch to the per-era forgePerasVote.
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.

Suggested change
-- Dispatch to the per-era forgePerasVote.
-- Dispatch to the per-era validatePerasVote.

let summary = State.reconstructSummaryLedger ledgerConfig unwrappedLedgerState
-- Query the hard fork history to determine what is the start slot of this
-- PerasRound. Thanks to 'runQueryNS', the result is wrapped in an 'NS' which
-- \*also* gives us the era the round falls in by its position.
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.

Suggested change
-- \*also* gives us the era the round falls in by its position.
-- __also__ gives us the era the round falls in by its position.

This is the haddock markup for bold

-- Ledger state is forecast into ledger view for the target slot.
nsLedgerView <- forcastToViewAtSlot ledgerConfig slot ledgerState
-- Ensure the query era and the forecasted view era agree.
nsQueryResAndLedgerView <- ensureSameEraPair (nsQueryRes, getOneEraLedgerView nsLedgerView)
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.

Isn't this trivially true always?

Comment on lines +587 to +596
downcastHardForkPoint ::
forall blk xs.
SingleEraBlock blk =>
Point (HardForkBlock xs) ->
Point blk
downcastHardForkPoint = \case
GenesisPoint ->
GenesisPoint
BlockPoint s (OneEraHash h) ->
BlockPoint s (fromShortRawHash (Proxy @blk) h)
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.

This feels weird. I think you should be able to do castPoint directly no?

Comment on lines +598 to +610
-- | Upcast a 'Point' from a single era into a 'Point' of the hard fork block
-- by encoding the raw hash via 'toShortRawHash'. Used by accessor instances
-- to return 'Point (HardForkBlock xs)' from single-era point values.
upcastToHardForkPoint ::
forall blk xs.
SingleEraBlock blk =>
Point blk ->
Point (HardForkBlock xs)
upcastToHardForkPoint = \case
GenesisPoint ->
GenesisPoint
BlockPoint s h ->
BlockPoint s (OneEraHash (toShortRawHash (Proxy @blk) h))
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.

Same here

@qnikst qnikst linked an issue Mar 24, 2026 that may be closed by this pull request
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Interface design & HFC plumbing for Peras

3 participants