Skip to content

Commit 06465a9

Browse files
committed
Adapt the HFC time translation layer for Peras
- Add `PerasRoundLength` - HFC: translate between Peras rounds and slots
1 parent c971d39 commit 06465a9

File tree

18 files changed

+352
-37
lines changed

18 files changed

+352
-37
lines changed

ouroboros-consensus-cardano/src/byron/Ouroboros/Consensus/Byron/Ledger/Ledger.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ import qualified Cardano.Chain.Update as Update
5656
import qualified Cardano.Chain.Update.Validation.Endorsement as UPE
5757
import qualified Cardano.Chain.Update.Validation.Interface as UPI
5858
import qualified Cardano.Chain.ValidationMode as CC
59-
import Cardano.Ledger.BaseTypes (unNonZero)
59+
import Cardano.Ledger.BaseTypes (StrictMaybe (..), unNonZero)
6060
import Cardano.Ledger.Binary (fromByronCBOR, toByronCBOR)
6161
import Cardano.Ledger.Binary.Plain (encodeListLen, enforceSize)
6262
import Codec.CBOR.Decoding (Decoder)
@@ -333,6 +333,7 @@ byronEraParams genesis =
333333
, eraSlotLength = fromByronSlotLength $ genesisSlotLength genesis
334334
, eraSafeZone = HardFork.StandardSafeZone (2 * k)
335335
, eraGenesisWin = GenesisWindow (2 * k)
336+
, eraPerasRoundLength = SNothing -- Byron is not Peras-enabled
336337
}
337338
where
338339
k = unNonZero $ maxRollbacks $ genesisSecurityParam genesis
@@ -345,6 +346,7 @@ byronEraParamsNeverHardForks genesis =
345346
, eraSlotLength = fromByronSlotLength $ genesisSlotLength genesis
346347
, eraSafeZone = HardFork.UnsafeIndefiniteSafeZone
347348
, eraGenesisWin = GenesisWindow (2 * Gen.unBlockCount (Gen.configK genesis))
349+
, eraPerasRoundLength = SNothing -- Byron is not Peras-enabled
348350
}
349351

350352
instance HasHardForkHistory ByronBlock where

ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Ledger.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ module Ouroboros.Consensus.Shelley.Ledger.Ledger
5757
) where
5858

5959
import qualified Cardano.Ledger.BHeaderView as SL (BHeaderView)
60+
import Cardano.Ledger.BaseTypes (StrictMaybe (..))
6061
import qualified Cardano.Ledger.BaseTypes as SL (epochInfoPure)
6162
import Cardano.Ledger.BaseTypes.NonZero (unNonZero)
6263
import Cardano.Ledger.Binary.Decoding
@@ -113,6 +114,7 @@ import Ouroboros.Consensus.Config
113114
import Ouroboros.Consensus.HardFork.Abstract
114115
import Ouroboros.Consensus.HardFork.Combinator.PartialConfig
115116
import qualified Ouroboros.Consensus.HardFork.History as HardFork
117+
import Ouroboros.Consensus.HardFork.History.EraParams (EraParams (..))
116118
import Ouroboros.Consensus.HardFork.History.Util
117119
import Ouroboros.Consensus.HardFork.Simple
118120
import Ouroboros.Consensus.HeaderValidation
@@ -168,6 +170,7 @@ shelleyEraParams genesis =
168170
, eraSlotLength = mkSlotLength $ SL.fromNominalDiffTimeMicro $ SL.sgSlotLength genesis
169171
, eraSafeZone = HardFork.StandardSafeZone stabilityWindow
170172
, eraGenesisWin = GenesisWindow stabilityWindow
173+
, eraPerasRoundLength = SNothing -- Shelley is not Peras-enabled
171174
}
172175
where
173176
stabilityWindow =
@@ -183,6 +186,7 @@ shelleyEraParamsNeverHardForks genesis =
183186
, eraSlotLength = mkSlotLength $ SL.fromNominalDiffTimeMicro $ SL.sgSlotLength genesis
184187
, eraSafeZone = HardFork.UnsafeIndefiniteSafeZone
185188
, eraGenesisWin = GenesisWindow stabilityWindow
189+
, eraPerasRoundLength = SNothing -- Shelley is not Peras-enabled
186190
}
187191
where
188192
stabilityWindow =

ouroboros-consensus-cardano/src/unstable-cardano-testlib/Test/Consensus/Cardano/Generators.hs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ instance
137137
aux ::
138138
forall blk.
139139
SingleEraBlock blk =>
140-
WrapHeaderHash blk -> K (OneEraHash (CardanoEras c)) blk
140+
WrapHeaderHash blk ->
141+
K (OneEraHash (CardanoEras c)) blk
141142
aux = K . OneEraHash . toShortRawHash (Proxy @blk) . unwrapHeaderHash
142143

143144
instance
@@ -993,11 +994,11 @@ instance Arbitrary History.EraEnd where
993994
]
994995

995996
instance Arbitrary History.EraSummary where
996-
arbitrary =
997-
History.EraSummary
998-
<$> arbitrary
999-
<*> arbitrary
1000-
<*> arbitrary
997+
-- Note: this generator may produce EraSummary with nonsensical bounds,
998+
-- i.e. with existing PerasRoundNo at era start and Nothing for it at the end.
999+
-- However, this does not create problems, and we thus choose to keep the generator
1000+
-- unconstrained.
1001+
arbitrary = History.EraSummary <$> arbitrary <*> arbitrary <*> arbitrary
10011002

10021003
instance (Arbitrary a, SListI xs) => Arbitrary (NonEmpty xs a) where
10031004
arbitrary = do

ouroboros-consensus-diffusion/test/consensus-test/Test/Consensus/HardFork/Combinator.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
module Test.Consensus.HardFork.Combinator (tests) where
2020

21-
import Cardano.Ledger.BaseTypes (nonZero, unNonZero)
21+
import Cardano.Ledger.BaseTypes (StrictMaybe (..), nonZero, unNonZero)
2222
import qualified Data.Map.Strict as Map
2323
import Data.MemPack
2424
import Data.SOP.BasicFunctors
@@ -164,6 +164,7 @@ prop_simple_hfc_convergence testSetup@TestSetup{..} =
164164
(History.StandardSafeZone (safeFromTipA k))
165165
(safeZoneB k)
166166
<*> pure (GenesisWindow ((unNonZero $ maxRollbacks k) * 2))
167+
<*> pure (SJust defaultPerasRoundLength)
167168

168169
shape :: History.Shape '[BlockA, BlockB]
169170
shape = History.Shape $ exactlyTwo eraParamsA eraParamsB

ouroboros-consensus-diffusion/test/mock-test/Test/ThreadNet/BFT.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ prop_simple_bft_convergence
103103
, version = newestVersion (Proxy @MockBftBlock)
104104
}
105105

106+
testOutput :: TestOutput MockBftBlock
106107
testOutput =
107108
runTestNetwork
108109
testConfig

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Block/Abstract.hs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ module Ouroboros.Consensus.Block.Abstract
4141
-- * Ouroboros Genesis window
4242
, GenesisWindow (..)
4343

44+
-- * Ouroboros Peras round length
45+
, PerasRoundLength (..)
46+
, defaultPerasRoundLength
47+
4448
-- * Re-export basic definitions from @ouroboros-network@
4549
, ChainHash (..)
4650
, HasHeader (..)
@@ -300,3 +304,16 @@ succWithOrigin = withOrigin minBound succ
300304
newtype GenesisWindow = GenesisWindow {unGenesisWindow :: Word64}
301305
deriving stock (Show, Eq, Ord)
302306
deriving newtype (NoThunks, Num)
307+
308+
{-------------------------------------------------------------------------------
309+
Ouroboros Peras round length
310+
-------------------------------------------------------------------------------}
311+
312+
newtype PerasRoundLength = PerasRoundLength {unPerasRoundLength :: Word64}
313+
deriving stock (Show, Eq, Ord)
314+
deriving newtype (NoThunks, Num)
315+
316+
-- | See the Protocol parameters section of the Peras design report:
317+
-- https://tweag.github.io/cardano-peras/peras-design.pdf#section.2.1
318+
defaultPerasRoundLength :: PerasRoundLength
319+
defaultPerasRoundLength = 90

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/Block/SupportsPeras.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010

1111
module Ouroboros.Consensus.Block.SupportsPeras
1212
( PerasRoundNo (..)
13+
, defaultPerasRoundNo
1314
, PerasWeight (..)
1415
, boostPerCert
1516
, BlockSupportsPeras (..)
1617
, PerasCert (..)
1718
) where
1819

20+
import Codec.Serialise.Class
1921
import Data.Monoid (Sum (..))
2022
import Data.Word (Word64)
2123
import GHC.Generics (Generic)
@@ -27,7 +29,10 @@ import Quiet (Quiet (..))
2729
newtype PerasRoundNo = PerasRoundNo {unPerasRoundNo :: Word64}
2830
deriving Show via Quiet PerasRoundNo
2931
deriving stock Generic
30-
deriving newtype (Eq, Ord, NoThunks)
32+
deriving newtype (Enum, Eq, Ord, NoThunks, Serialise)
33+
34+
defaultPerasRoundNo :: PerasRoundNo
35+
defaultPerasRoundNo = PerasRoundNo 0
3136

3237
instance Condense PerasRoundNo where
3338
condense = show . unPerasRoundNo

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Abstract.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,6 @@ neverForksHardForkSummary ::
6767
LedgerState blk mk ->
6868
HardFork.Summary '[blk]
6969
neverForksHardForkSummary getParams cfg _st =
70-
HardFork.neverForksSummary eraEpochSize eraSlotLength eraGenesisWin
70+
HardFork.neverForksSummary eraEpochSize eraSlotLength eraGenesisWin eraPerasRoundLength
7171
where
7272
HardFork.EraParams{..} = getParams cfg

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/Combinator/Serialisation/SerialiseNodeToClient.hs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,9 @@ encodeQueryIfCurrentResult (_ :* _) (EraNodeToClientDisabled :* _) (QZ qry) =
539539
qryDisabledEra ::
540540
forall blk fp result.
541541
SingleEraBlock blk =>
542-
BlockQuery blk fp result -> result -> Encoding
542+
BlockQuery blk fp result ->
543+
result ->
544+
Encoding
543545
qryDisabledEra _ _ = throw $ disabledEraException (Proxy @blk)
544546
encodeQueryIfCurrentResult (_ :* cs) (_ :* vs) (QS qry) =
545547
encodeQueryIfCurrentResult cs vs qry
@@ -560,7 +562,9 @@ decodeQueryIfCurrentResult (_ :* _) (EraNodeToClientDisabled :* _) (QZ qry) =
560562
qryDisabledEra ::
561563
forall blk fp result.
562564
SingleEraBlock blk =>
563-
BlockQuery blk fp result -> forall s. Decoder s result
565+
BlockQuery blk fp result ->
566+
forall s.
567+
Decoder s result
564568
qryDisabledEra _ = fail . show $ disabledEraException (Proxy @blk)
565569
decodeQueryIfCurrentResult (_ :* cs) (_ :* vs) (QS qry) =
566570
decodeQueryIfCurrentResult cs vs qry

ouroboros-consensus/src/ouroboros-consensus/Ouroboros/Consensus/HardFork/History/EraParams.hs

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
{-# LANGUAGE DerivingStrategies #-}
44
{-# LANGUAGE FlexibleContexts #-}
55
{-# LANGUAGE LambdaCase #-}
6+
{-# LANGUAGE MultiWayIf #-}
67
{-# LANGUAGE OverloadedStrings #-}
78
{-# LANGUAGE RecordWildCards #-}
89
{-# LANGUAGE TypeApplications #-}
@@ -17,8 +18,8 @@ module Ouroboros.Consensus.HardFork.History.EraParams
1718
, defaultEraParams
1819
) where
1920

20-
import Cardano.Binary (enforceSize)
21-
import Cardano.Ledger.BaseTypes (unNonZero)
21+
import Cardano.Binary (DecoderError (DecoderErrorCustom), cborError)
22+
import Cardano.Ledger.BaseTypes (StrictMaybe (..), unNonZero)
2223
import Codec.CBOR.Decoding (Decoder, decodeListLen, decodeWord8)
2324
import Codec.CBOR.Encoding (Encoding, encodeListLen, encodeWord8)
2425
import Codec.Serialise (Serialise (..))
@@ -136,6 +137,8 @@ data EraParams = EraParams
136137
, eraSlotLength :: !SlotLength
137138
, eraSafeZone :: !SafeZone
138139
, eraGenesisWin :: !GenesisWindow
140+
, eraPerasRoundLength :: !(StrictMaybe PerasRoundLength)
141+
-- ^ Optional, as not every era will be Peras-enabled
139142
}
140143
deriving stock (Show, Eq, Generic)
141144
deriving anyclass NoThunks
@@ -147,16 +150,21 @@ data EraParams = EraParams
147150
-- * epoch size to @10k@ slots
148151
-- * the safe zone to @2k@ slots
149152
-- * the upper bound to 'NoLowerBound'
153+
-- * the Peras Round Length is unset
150154
--
151155
-- This is primarily useful for tests.
152156
defaultEraParams :: SecurityParam -> SlotLength -> EraParams
153157
defaultEraParams (SecurityParam k) slotLength =
154158
EraParams
155-
{ eraEpochSize = EpochSize (unNonZero k * 10)
159+
{ eraEpochSize = EpochSize epochSize
156160
, eraSlotLength = slotLength
157161
, eraSafeZone = StandardSafeZone (unNonZero k * 2)
158162
, eraGenesisWin = GenesisWindow (unNonZero k * 2)
163+
, -- Peras is disabled by default
164+
eraPerasRoundLength = SNothing
159165
}
166+
where
167+
epochSize = unNonZero k * 10
160168

161169
-- | Zone in which it is guaranteed that no hard fork can take place
162170
data SafeZone
@@ -235,17 +243,28 @@ decodeSafeBeforeEpoch = do
235243
instance Serialise EraParams where
236244
encode EraParams{..} =
237245
mconcat $
238-
[ encodeListLen 4
246+
[ encodeListLen $ case eraPerasRoundLength of
247+
SNothing -> 4
248+
SJust{} -> 5
239249
, encode (unEpochSize eraEpochSize)
240250
, encode eraSlotLength
241251
, encode eraSafeZone
242252
, encode (unGenesisWindow eraGenesisWin)
243253
]
254+
<> case eraPerasRoundLength of
255+
SNothing -> []
256+
SJust rl -> [encode (unPerasRoundLength rl)]
244257

245258
decode = do
246-
enforceSize "EraParams" 4
259+
len <- decodeListLen
260+
-- TODO(geo2a): use 'enforceSize "EraParams" 5' when Peras is on mainnet and we know the list size statically
247261
eraEpochSize <- EpochSize <$> decode
248262
eraSlotLength <- decode
249263
eraSafeZone <- decode
250264
eraGenesisWin <- GenesisWindow <$> decode
265+
eraPerasRoundLength <-
266+
if
267+
| len == 4 -> pure SNothing
268+
| len == 5 -> SJust . PerasRoundLength <$> decode
269+
| otherwise -> cborError (DecoderErrorCustom "EraParams" "unexpected list length")
251270
return EraParams{..}

0 commit comments

Comments
 (0)