Skip to content

Commit 19b2ba8

Browse files
authored
Use a single protocol version across all eras (#1224)
While giving us flexibility, using different protocol versions for all eras increased the level of complexity and led to several errors in the past. This PR removes this flexibility by using a single protocol version, which determines the maximum protocol version Consensus supports. See #324 for more background. Closes #324. Closes #276. TODOs: - [x] Format the code. - [x] Fix ThreadNet test failure. - [x] Improve documentation. - [x] Address all the `FIXME`s.
2 parents 9351e28 + d57d4e5 commit 19b2ba8

File tree

24 files changed

+190
-388
lines changed

24 files changed

+190
-388
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
### Breaking
2+
3+
- ProtocolParams (CardanoBlock c) was monomorphized to `CardanoProtocolParams`
4+
- Remove `cardanoProtocolParamsPerEra` from `CardanoProtocolParams` in favour of a single `cardanoProtocolVersion`.
5+
This patch intentionally removes the flexibility the n-ary product of versions per-era gave us, in favour of a simpler interface, as the current one has caused a lot of confusion and led to several mistakes in the past.

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module Ouroboros.Consensus.Byron.Node (
1818
, mkByronLeaderCredentials
1919
, mkPBftCanBeLeader
2020
-- * ProtocolInfo
21-
, ProtocolParams (..)
21+
, ProtocolParamsByron (..)
2222
, defaultPBftSignatureThreshold
2323
, mkByronConfig
2424
, protocolClientInfoByron
@@ -152,7 +152,7 @@ mkPBftCanBeLeader (ByronLeaderCredentials sk cert nid _) = PBftCanBeLeader {
152152
}
153153

154154
blockForgingByron :: Monad m
155-
=> ProtocolParams ByronBlock
155+
=> ProtocolParamsByron
156156
-> [BlockForging m ByronBlock]
157157
blockForgingByron ProtocolParamsByron { byronLeaderCredentials = mLeaderCreds
158158
} =
@@ -169,15 +169,15 @@ defaultPBftSignatureThreshold :: PBftSignatureThreshold
169169
defaultPBftSignatureThreshold = PBftSignatureThreshold 0.22
170170

171171
-- | Parameters needed to run Byron
172-
data instance ProtocolParams ByronBlock = ProtocolParamsByron {
172+
data ProtocolParamsByron = ProtocolParamsByron {
173173
byronGenesis :: Genesis.Config
174174
, byronPbftSignatureThreshold :: Maybe PBftSignatureThreshold
175175
, byronProtocolVersion :: Update.ProtocolVersion
176176
, byronSoftwareVersion :: Update.SoftwareVersion
177177
, byronLeaderCredentials :: Maybe ByronLeaderCredentials
178178
}
179179

180-
protocolInfoByron :: ProtocolParams ByronBlock
180+
protocolInfoByron :: ProtocolParamsByron
181181
-> ProtocolInfo ByronBlock
182182
protocolInfoByron ProtocolParamsByron {
183183
byronGenesis = genesisConfig

ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ module Ouroboros.Consensus.Cardano (
99
, ProtocolShelley
1010
-- * Abstract over the various protocols
1111
, CardanoHardForkTriggers (..)
12-
, ProtocolParams (..)
1312
, module X
1413
) where
1514

ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano/Node.hs

Lines changed: 65 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,8 @@
3434
module Ouroboros.Consensus.Cardano.Node (
3535
CardanoHardForkConstraints
3636
, CardanoHardForkTriggers (.., CardanoHardForkTriggers', triggerHardForkShelley, triggerHardForkAllegra, triggerHardForkMary, triggerHardForkAlonzo, triggerHardForkBabbage, triggerHardForkConway)
37-
, CardanoProtocolParams
37+
, CardanoProtocolParams (..)
3838
, MaxMajorProtVer (..)
39-
, ProtocolParams (.., CardanoProtocolParams, paramsByron, paramsShelleyBased, paramsShelley, paramsAllegra, paramsMary, paramsAlonzo, paramsBabbage, paramsConway, hardForkTriggers, ledgerTransitionConfig, checkpoints)
4039
, TriggerHardFork (..)
4140
, protocolClientInfoCardano
4241
, protocolInfoCardano
@@ -77,7 +76,6 @@ import qualified Data.Map.Strict as Map
7776
import Data.SOP.BasicFunctors
7877
import Data.SOP.Counting
7978
import Data.SOP.Index (Index (..))
80-
import Data.SOP.NonEmpty
8179
import Data.SOP.OptNP (NonEmptyOptNP, OptNP (OptSkip))
8280
import qualified Data.SOP.OptNP as OptNP
8381
import Data.SOP.Strict
@@ -93,8 +91,6 @@ import Ouroboros.Consensus.Cardano.Block
9391
import Ouroboros.Consensus.Cardano.CanHardFork
9492
import Ouroboros.Consensus.Config
9593
import Ouroboros.Consensus.HardFork.Combinator
96-
import Ouroboros.Consensus.HardFork.Combinator.AcrossEras
97-
(PerEraProtocolParams (..))
9894
import Ouroboros.Consensus.HardFork.Combinator.Embed.Nary
9995
import Ouroboros.Consensus.HardFork.Combinator.Serialisation
10096
import qualified Ouroboros.Consensus.HardFork.History as History
@@ -521,61 +517,57 @@ pattern CardanoHardForkTriggers' {
521517
{-# COMPLETE CardanoHardForkTriggers' #-}
522518

523519
-- | Parameters needed to run Cardano.
524-
data instance ProtocolParams (CardanoBlock c) = ProtocolParamsCardano {
525-
cardanoProtocolParamsPerEra :: PerEraProtocolParams (CardanoEras c)
520+
--
521+
-- __On the relation between 'cardanoHardForkTriggers' and 'cardanoProtocolVersion'__:
522+
--
523+
-- The 'cardanoHardForkTriggers' can mention __ledger__ protocol
524+
-- version versions at which the hard fork will occur. In principle
525+
-- there is no relation between the versions mentioned in
526+
-- 'cardanoProtocolVerson' (if any) and 'cardanoHardForkTriggers',
527+
-- however their relationship might indicate experimental eras or
528+
-- intra-era hard forks. For instance if the last era in the
529+
-- 'CardanoHardForkTriggers' is set to @9 0@, ie:
530+
--
531+
-- > ... :* TriggerHardForkAtVersion (ProtVer (SL.natVersion @9) 0)
532+
--
533+
-- Setting 'cardanoProtocolVersion' to @ProtVer (SL.natVersion @8) 0@
534+
-- will mark that last era as experimental because the obsolete node
535+
-- checks determine that the highest version we support is @8 0@.
536+
--
537+
-- If, on the other hand, we would set 'cardanoProtocolVersion' to
538+
-- @ProtVer (SL.natVersion @10) 0@, this indicates that the node is
539+
-- ready to perform an intra-era hardfork (from version @9@ to version
540+
-- @10@).
541+
--
542+
data CardanoProtocolParams c = CardanoProtocolParams {
543+
byronProtocolParams :: ProtocolParamsByron
526544
, shelleyBasedProtocolParams :: ProtocolParamsShelleyBased c
527545
, cardanoHardForkTriggers :: CardanoHardForkTriggers
528546
, cardanoLedgerTransitionConfig :: L.TransitionConfig (L.LatestKnownEra c)
529547
, cardanoCheckpoints :: CheckpointsMap (CardanoBlock c)
548+
-- | The greatest protocol version that this node's software and config
549+
-- files declare to handle correctly.
550+
--
551+
-- This parameter has three consequences. First, the blocks minted
552+
-- will include the protocol version in their header, but
553+
-- essentially only for public signaling (eg measuring the
554+
-- percentage of adoption of software updates).
555+
--
556+
-- Second, and more importantly, it's passed to the protocol logic. In
557+
-- particular, the node's envelope check will begin rejecting all blocks
558+
-- (actually, their headers) if the chain moves to a greater protocol
559+
-- version. This should never happen in a node that is using up-to-date
560+
-- software and config files. Note that the missing software update is
561+
-- not necessarily a 'HardForkBlock' era transition: it might be an
562+
-- /intra-era hard fork/ (ie conditionals in the ledger rules).
563+
--
564+
-- Third, it's passed to the ledger rules---but that's entirely
565+
-- vestigial. See
566+
-- <https://github.com/IntersectMBO/cardano-ledger/issues/3682>.
567+
--
568+
, cardanoProtocolVersion :: ProtVer
530569
}
531570

532-
type CardanoProtocolParams c = ProtocolParams (CardanoBlock c)
533-
534-
pattern CardanoProtocolParams ::
535-
ProtocolParams ByronBlock
536-
-> ProtocolParamsShelleyBased c
537-
-> ProtocolParams (ShelleyBlock (TPraos c) (ShelleyEra c))
538-
-> ProtocolParams (ShelleyBlock (TPraos c) (AllegraEra c))
539-
-> ProtocolParams (ShelleyBlock (TPraos c) (MaryEra c))
540-
-> ProtocolParams (ShelleyBlock (TPraos c) (AlonzoEra c))
541-
-> ProtocolParams (ShelleyBlock (Praos c) (BabbageEra c))
542-
-> ProtocolParams (ShelleyBlock (Praos c) (ConwayEra c))
543-
-> CardanoHardForkTriggers
544-
-> L.TransitionConfig (L.LatestKnownEra c)
545-
-> CheckpointsMap (CardanoBlock c)
546-
-> CardanoProtocolParams c
547-
pattern CardanoProtocolParams {
548-
paramsByron
549-
, paramsShelleyBased
550-
, paramsShelley
551-
, paramsAllegra
552-
, paramsMary
553-
, paramsAlonzo
554-
, paramsBabbage
555-
, paramsConway
556-
, hardForkTriggers
557-
, ledgerTransitionConfig
558-
, checkpoints
559-
} =
560-
ProtocolParamsCardano {
561-
cardanoProtocolParamsPerEra = PerEraProtocolParams
562-
( paramsByron
563-
:* paramsShelley
564-
:* paramsAllegra
565-
:* paramsMary
566-
:* paramsAlonzo
567-
:* paramsBabbage
568-
:* paramsConway
569-
:* Nil
570-
)
571-
, shelleyBasedProtocolParams = paramsShelleyBased
572-
, cardanoHardForkTriggers = hardForkTriggers
573-
, cardanoLedgerTransitionConfig = ledgerTransitionConfig
574-
, cardanoCheckpoints = checkpoints
575-
}
576-
577-
{-# COMPLETE CardanoProtocolParams #-}
578-
579571
-- | Create a 'ProtocolInfo' for 'CardanoBlock'
580572
--
581573
-- NOTE: For testing and benchmarking purposes, the 'ShelleyGenesis' can contain
@@ -607,84 +599,44 @@ protocolInfoCardano paramsCardano
607599
)
608600
where
609601
CardanoProtocolParams {
610-
paramsByron
611-
, paramsShelleyBased
612-
, paramsShelley
613-
, paramsAllegra
614-
, paramsMary
615-
, paramsAlonzo
616-
, paramsBabbage
617-
, paramsConway
618-
, hardForkTriggers = CardanoHardForkTriggers' {
602+
byronProtocolParams
603+
, shelleyBasedProtocolParams
604+
, cardanoHardForkTriggers = CardanoHardForkTriggers' {
619605
triggerHardForkShelley
620606
, triggerHardForkAllegra
621607
, triggerHardForkMary
622608
, triggerHardForkAlonzo
623609
, triggerHardForkBabbage
624610
, triggerHardForkConway
625611
}
626-
, ledgerTransitionConfig
627-
, checkpoints
612+
, cardanoLedgerTransitionConfig
613+
, cardanoCheckpoints
614+
, cardanoProtocolVersion
628615
} = paramsCardano
629616

630-
genesisShelley = ledgerTransitionConfig ^. L.tcShelleyGenesisL
617+
genesisShelley = cardanoLedgerTransitionConfig ^. L.tcShelleyGenesisL
631618

632619
ProtocolParamsByron {
633620
byronGenesis = genesisByron
634621
, byronLeaderCredentials = mCredsByron
635-
} = paramsByron
622+
} = byronProtocolParams
636623
ProtocolParamsShelleyBased {
637624
shelleyBasedInitialNonce = initialNonceShelley
638625
, shelleyBasedLeaderCredentials = credssShelleyBased
639-
} = paramsShelleyBased
640-
ProtocolParamsShelley {
641-
shelleyProtVer = protVerShelley
642-
} = paramsShelley
643-
ProtocolParamsAllegra {
644-
allegraProtVer = protVerAllegra
645-
} = paramsAllegra
646-
ProtocolParamsMary {
647-
maryProtVer = protVerMary
648-
} = paramsMary
649-
ProtocolParamsAlonzo {
650-
alonzoProtVer = protVerAlonzo
651-
} = paramsAlonzo
652-
ProtocolParamsBabbage {
653-
babbageProtVer = protVerBabbage
654-
} = paramsBabbage
655-
ProtocolParamsConway {
656-
conwayProtVer = protVerConway
657-
} = paramsConway
626+
} = shelleyBasedProtocolParams
658627

659628
transitionConfigShelley = transitionConfigAllegra ^. L.tcPreviousEraConfigL
660629
transitionConfigAllegra = transitionConfigMary ^. L.tcPreviousEraConfigL
661630
transitionConfigMary = transitionConfigAlonzo ^. L.tcPreviousEraConfigL
662631
transitionConfigAlonzo = transitionConfigBabbage ^. L.tcPreviousEraConfigL
663632
transitionConfigBabbage = transitionConfigConway ^. L.tcPreviousEraConfigL
664-
transitionConfigConway = ledgerTransitionConfig
633+
transitionConfigConway = cardanoLedgerTransitionConfig
665634

666635
-- The major protocol version of the last era is the maximum major protocol
667636
-- version we support.
668637
--
669-
-- TODO: use index of CardanoProtocolParams NP
670638
maxMajorProtVer :: MaxMajorProtVer
671-
maxMajorProtVer =
672-
MaxMajorProtVer
673-
$ pvMajor
674-
$ nonEmptyLast
675-
$ exactlyWeakenNonEmpty
676-
$ protVers
677-
where
678-
protVers :: Exactly (CardanoShelleyEras StandardCrypto) ProtVer
679-
protVers = Exactly $
680-
-- ensure that these have the same order as 'CardanoShelleyEras'!
681-
K protVerShelley :*
682-
K protVerAllegra :*
683-
K protVerMary :*
684-
K protVerAlonzo :*
685-
K protVerBabbage :*
686-
K protVerConway :*
687-
Nil
639+
maxMajorProtVer = MaxMajorProtVer $ pvMajor cardanoProtocolVersion
688640

689641
-- Byron
690642

@@ -695,7 +647,7 @@ protocolInfoCardano paramsCardano
695647
, topLevelConfigBlock = blockConfigByron
696648
}
697649
, pInfoInitLedger = initExtLedgerStateByron
698-
} = protocolInfoByron paramsByron
650+
} = protocolInfoByron byronProtocolParams
699651

700652
partialConsensusConfigByron :: PartialConsensusConfig (BlockProtocol ByronBlock)
701653
partialConsensusConfigByron = consensusConfigByron
@@ -744,7 +696,7 @@ protocolInfoCardano paramsCardano
744696
blockConfigShelley :: BlockConfig (ShelleyBlock (TPraos c) (ShelleyEra c))
745697
blockConfigShelley =
746698
Shelley.mkShelleyBlockConfig
747-
protVerShelley
699+
cardanoProtocolVersion
748700
genesisShelley
749701
(shelleyBlockIssuerVKey <$> credssShelleyBased)
750702

@@ -767,7 +719,7 @@ protocolInfoCardano paramsCardano
767719
blockConfigAllegra :: BlockConfig (ShelleyBlock (TPraos c) (AllegraEra c))
768720
blockConfigAllegra =
769721
Shelley.mkShelleyBlockConfig
770-
protVerAllegra
722+
cardanoProtocolVersion
771723
genesisShelley
772724
(shelleyBlockIssuerVKey <$> credssShelleyBased)
773725

@@ -787,7 +739,7 @@ protocolInfoCardano paramsCardano
787739
blockConfigMary :: BlockConfig (ShelleyBlock (TPraos c) (MaryEra c))
788740
blockConfigMary =
789741
Shelley.mkShelleyBlockConfig
790-
protVerMary
742+
cardanoProtocolVersion
791743
genesisShelley
792744
(shelleyBlockIssuerVKey <$> credssShelleyBased)
793745

@@ -807,7 +759,7 @@ protocolInfoCardano paramsCardano
807759
blockConfigAlonzo :: BlockConfig (ShelleyBlock (TPraos c) (AlonzoEra c))
808760
blockConfigAlonzo =
809761
Shelley.mkShelleyBlockConfig
810-
protVerAlonzo
762+
cardanoProtocolVersion
811763
genesisShelley
812764
(shelleyBlockIssuerVKey <$> credssShelleyBased)
813765

@@ -827,7 +779,7 @@ protocolInfoCardano paramsCardano
827779
blockConfigBabbage :: BlockConfig (ShelleyBlock (Praos c) (BabbageEra c))
828780
blockConfigBabbage =
829781
Shelley.mkShelleyBlockConfig
830-
protVerBabbage
782+
cardanoProtocolVersion
831783
genesisShelley
832784
(shelleyBlockIssuerVKey <$> credssShelleyBased)
833785

@@ -857,7 +809,7 @@ protocolInfoCardano paramsCardano
857809
blockConfigConway :: BlockConfig (ShelleyBlock (Praos c) (ConwayEra c))
858810
blockConfigConway =
859811
Shelley.mkShelleyBlockConfig
860-
protVerConway
812+
cardanoProtocolVersion
861813
genesisShelley
862814
(shelleyBlockIssuerVKey <$> credssShelleyBased)
863815

@@ -944,7 +896,7 @@ protocolInfoCardano paramsCardano
944896
(Shelley.ShelleyStorageConfig tpraosSlotsPerKESPeriod k)
945897
(Shelley.ShelleyStorageConfig tpraosSlotsPerKESPeriod k)
946898
(Shelley.ShelleyStorageConfig tpraosSlotsPerKESPeriod k)
947-
, topLevelConfigCheckpoints = checkpoints
899+
, topLevelConfigCheckpoints = cardanoCheckpoints
948900
}
949901

950902
-- When the initial ledger state is not in the Byron era, register the

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
module Ouroboros.Consensus.Shelley.Node (
1616
MaxMajorProtVer (..)
17-
, ProtocolParams (..)
1817
, ProtocolParamsShelleyBased (..)
1918
, SL.Nonce (..)
2019
, SL.ProtVer (..)
@@ -44,7 +43,6 @@ import Ouroboros.Consensus.Shelley.Ledger
4443
import Ouroboros.Consensus.Shelley.Ledger.Inspect ()
4544
import Ouroboros.Consensus.Shelley.Ledger.NetworkProtocolVersion ()
4645
import Ouroboros.Consensus.Shelley.Node.DiffusionPipelining ()
47-
import Ouroboros.Consensus.Shelley.Node.Praos
4846
import Ouroboros.Consensus.Shelley.Node.Serialisation ()
4947
import Ouroboros.Consensus.Shelley.Node.TPraos
5048
import Ouroboros.Consensus.Shelley.Protocol.Abstract (pHeaderIssuer)

0 commit comments

Comments
 (0)