diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Abstract/SingleEraBlock.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Abstract/SingleEraBlock.hs index 4bcb69307f..d6cd17c1ab 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Abstract/SingleEraBlock.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Abstract/SingleEraBlock.hs @@ -22,12 +22,11 @@ module Ouroboros.Consensus.HardFork.Combinator.Abstract.SingleEraBlock ( ) where import Codec.Serialise -import Data.Either (isRight) +import Data.Function (on) import Data.Proxy import Data.SOP.BasicFunctors import Data.SOP.Constraint import Data.SOP.Index -import Data.SOP.Match import Data.SOP.Strict import qualified Data.Text as Text import Data.Void @@ -117,7 +116,10 @@ newtype EraIndex xs = EraIndex { } instance Eq (EraIndex xs) where - EraIndex era == EraIndex era' = isRight (matchNS era era') + (==) = (==) `on` eraIndexToInt + +instance Ord (EraIndex xs) where + compare = compare `on` eraIndexToInt instance All SingleEraBlock xs => Show (EraIndex xs) where show = hcollapse . hcmap proxySingle getEraName . getEraIndex diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Ledger.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Ledger.hs index 6f866524d2..b1614a526c 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Ledger.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Ledger.hs @@ -113,6 +113,42 @@ deriving anyclass instance CanHardFork xs => NoThunks (Ticked (LedgerState (HardForkBlock xs))) +-- | = HFC ticking +-- +-- This is the place where era transitions happen, ie when we have @st :: +-- 'LedgerState' ('HardForkBlock' xs)@ and, for a valid @slotNo@, +-- +-- @ +-- tickedSt :: 'Ticked' ('LedgerState' ('HardForkBlock' xs)) +-- tickedSt = 'applyChainTick' cfg slotNo st +-- @ +-- +-- we have the corresponding era indices +-- +-- @ +-- ixSt, ixTickedSt :: 'EraIndex' xs +-- ixSt = +-- 'eraIndexFromNS' . State.'State.tip' . 'hardForkLedgerStatePerEra' $ st +-- ixTickedState = +-- 'eraIndexFromNS' . State.'State.tip' . 'tickedHardForkLedgerStatePerEra' $ tickedSt +-- @ +-- +-- and we always have +-- +-- >>> ixSt <= ixTickedSt +-- True +-- +-- with inequality exactly if we ticked across an era boundary. +-- +-- == Ticking alone can't reveal era transitions +-- +-- Note however that if we performed an era transition (ie @ixSt < ixTickedSt@), +-- it must have already been known via 'singleEraTransition' for @st@; or more +-- concretely, @'mostRecentTransitionInfo' cfg st@ must have already returned +-- 'TransitionKnown'. This is a reflection of the fact that ticking alone +-- currently can't make a transition become known. Also see +-- for +-- future work to reconsider this fact. instance CanHardFork xs => IsLedger (LedgerState (HardForkBlock xs)) where type LedgerErr (LedgerState (HardForkBlock xs)) = HardForkLedgerError xs diff --git a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Translation.hs b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Translation.hs index 725fadf993..5cf708a888 100644 --- a/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Translation.hs +++ b/ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Translation.hs @@ -17,7 +17,25 @@ import Ouroboros.Consensus.TypeFamilyWrappers -------------------------------------------------------------------------------} data EraTranslation xs = EraTranslation { + -- | For each pair @(x, y)@ of subsequent eras, describe how to construct + -- the initial ledger state for @y@ from the ledger state resulting from the last block in @x@. + -- + -- When ticking across an era boundary, the HFC will first invoke this and + -- then tick the resulting ledger state (in @y@) to the requested slot. + -- + -- The resulting ledger state must summarize every relevant aspect of what + -- came before the new era. This is intentionally vague; for example, + -- ticking in @y@ might work rather differently than in @x@, and so certain + -- aspects of the ticking logic of @x@ might need to happen as part of + -- 'translateLedgerState'. For a concrete example in Cardano, see + -- 'translateLedgerStateBabbageToConwayWrapper'. translateLedgerState :: InPairs (RequiringBoth WrapLedgerConfig (Translate LedgerState)) xs + -- | For each pair @(x, y)@ of subsequent eras, describe how to construct + -- the initial chain-dependent state for @y@ from the chain-dep state after the last header + -- in @x@. + -- + -- When ticking across an era boundary, the HFC will first invoke this and + -- then tick the resulting chain-dep state (in @y@) to the requested slot. , translateChainDepState :: InPairs (RequiringBoth WrapConsensusConfig (Translate WrapChainDepState)) xs , crossEraForecast :: InPairs (RequiringBoth WrapLedgerConfig (CrossEraForecaster LedgerState WrapLedgerView)) xs } diff --git a/sop-extras/CHANGELOG.md b/sop-extras/CHANGELOG.md index ba0759d611..c26778a875 100644 --- a/sop-extras/CHANGELOG.md +++ b/sop-extras/CHANGELOG.md @@ -1,5 +1,8 @@ -# Revision history for sop-extras +# sop-extras Changelog -## 0.1.0.0 -- YYYY-mm-dd +# Changelog entries + + +## 0.1.0.0 — 2023-09-07 * First version. Released on an unsuspecting world. diff --git a/sop-extras/changelog.d/20231012_142650_alexander.esgen.md b/sop-extras/changelog.d/20231012_142650_alexander.esgen.md new file mode 100644 index 0000000000..eeaa38a643 --- /dev/null +++ b/sop-extras/changelog.d/20231012_142650_alexander.esgen.md @@ -0,0 +1,3 @@ +### Non-Breaking + +- Add `Ord (EraIndex xs)` instance diff --git a/sop-extras/changelog.d/scriv.ini b/sop-extras/changelog.d/scriv.ini new file mode 100644 index 0000000000..aacceaa8da --- /dev/null +++ b/sop-extras/changelog.d/scriv.ini @@ -0,0 +1,13 @@ +[scriv] +format = md +insert_marker = Changelog entries +md_header_level = 2 +version = literal: sop-extras.cabal: version +categories = Patch, Non-Breaking, Breaking +end_marker = scriv-end-here +fragment_directory = changelog.d +ghrel_template = {{body}} +main_branches = master, main, develop +new_fragment_template = file: new_fragment.${config:format}.j2 +output_file = CHANGELOG.${config:format} +skip_fragments = README.* diff --git a/strict-sop-core/CHANGELOG.md b/strict-sop-core/CHANGELOG.md index 2f13b1e71a..d0098e81e2 100644 --- a/strict-sop-core/CHANGELOG.md +++ b/strict-sop-core/CHANGELOG.md @@ -1,5 +1,8 @@ -# Revision history for strict-sop-core +# strict-sop-core Changelog -## 0.1.0.0 -- YYYY-mm-dd +# Changelog entries + + +## 0.1.0.0 — 2023-09-07 * First version. Released on an unsuspecting world. diff --git a/strict-sop-core/changelog.d/scriv.ini b/strict-sop-core/changelog.d/scriv.ini new file mode 100644 index 0000000000..e318dbaa9c --- /dev/null +++ b/strict-sop-core/changelog.d/scriv.ini @@ -0,0 +1,13 @@ +[scriv] +format = md +insert_marker = Changelog entries +md_header_level = 2 +version = literal: strict-sop-core.cabal: version +categories = Patch, Non-Breaking, Breaking +end_marker = scriv-end-here +fragment_directory = changelog.d +ghrel_template = {{body}} +main_branches = master, main, develop +new_fragment_template = file: new_fragment.${config:format}.j2 +output_file = CHANGELOG.${config:format} +skip_fragments = README.*