Skip to content

Commit a70f0f3

Browse files
authored
Minimal workaround for updating protocol params on Babbage→Conway (#366)
Closes IntersectMBO/cardano-ledger#3491 in an ad-hoc but minimal fashion. Primary motivation is to fix this bug on Sanchonet without having to wait for the full HFC refactoring (see #345) that we will probably end up with.
2 parents 2a30527 + 173f1ad commit a70f0f3

File tree

1 file changed

+71
-4
lines changed
  • ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano

1 file changed

+71
-4
lines changed

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

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,27 @@ import qualified Cardano.Chain.Genesis as CC.Genesis
2929
import qualified Cardano.Chain.Update as CC.Update
3030
import Cardano.Crypto.DSIGN (Ed25519DSIGN)
3131
import Cardano.Crypto.Hash.Blake2b (Blake2b_224, Blake2b_256)
32+
import qualified Cardano.Ledger.BaseTypes as SL
33+
import qualified Cardano.Ledger.Core as Core
3234
import Cardano.Ledger.Crypto (ADDRHASH, Crypto, DSIGN, HASH)
3335
import qualified Cardano.Ledger.Era as SL
3436
import Cardano.Ledger.Hashes (EraIndependentTxBody)
3537
import Cardano.Ledger.Keys (DSignable, Hash)
3638
import qualified Cardano.Ledger.Shelley.API as SL
39+
import qualified Cardano.Ledger.Shelley.Governance as SL
40+
import qualified Cardano.Ledger.Shelley.LedgerState as SL
3741
import Cardano.Ledger.Shelley.Translation
3842
(toFromByronTranslationContext)
3943
import qualified Cardano.Protocol.TPraos.API as SL
4044
import qualified Cardano.Protocol.TPraos.Rules.Prtcl as SL
4145
import qualified Cardano.Protocol.TPraos.Rules.Tickn as SL
46+
import Cardano.Slotting.EpochInfo (epochInfoFirst)
4247
import Control.Monad
4348
import Control.Monad.Except (runExcept, throwError)
49+
import qualified Control.State.Transition as STS
4450
import Data.Coerce (coerce)
51+
import Data.Function ((&))
52+
import Data.Functor.Identity
4553
import qualified Data.Map.Strict as Map
4654
import Data.Maybe (listToMaybe, mapMaybe)
4755
import Data.Proxy
@@ -50,8 +58,11 @@ import Data.SOP.InPairs (RequiringBoth (..), ignoringBoth)
5058
import Data.SOP.Strict (hpure)
5159
import Data.SOP.Tails (Tails (..))
5260
import qualified Data.SOP.Tails as Tails
61+
import Data.Void
5362
import Data.Word
5463
import GHC.Generics (Generic)
64+
import Lens.Micro (Lens', (.~))
65+
import Lens.Micro.Extras (view)
5566
import NoThunks.Class (NoThunks)
5667
import Ouroboros.Consensus.Block
5768
import Ouroboros.Consensus.Byron.Ledger
@@ -677,16 +688,72 @@ translateValidatedTxAlonzoToBabbageWrapper ctxt = InjectValidatedTx $
677688
-------------------------------------------------------------------------------}
678689

679690
translateLedgerStateBabbageToConwayWrapper ::
680-
(Praos.PraosCrypto c)
691+
forall c. (Praos.PraosCrypto c)
681692
=> RequiringBoth
682693
WrapLedgerConfig
683694
(Translate LedgerState)
684695
(ShelleyBlock (Praos c) (BabbageEra c))
685696
(ShelleyBlock (Praos c) (ConwayEra c))
686697
translateLedgerStateBabbageToConwayWrapper =
687-
RequireBoth $ \_cfgBabbage cfgConway ->
688-
Translate $ \_epochNo ->
689-
unComp . SL.translateEra' (getConwayTranslationContext cfgConway) . Comp
698+
RequireBoth $ \cfgBabbage cfgConway ->
699+
Translate $ \epochNo ->
700+
let -- It would be cleaner to just pass in the entire 'Bound' instead of
701+
-- just the 'EpochNo'.
702+
firstSlotNewEra = runIdentity $ epochInfoFirst ei epochNo
703+
where
704+
ei =
705+
SL.epochInfoPure
706+
$ shelleyLedgerGlobals
707+
$ unwrapLedgerConfig cfgConway
708+
709+
-- HACK to make sure protocol parameters get properly updated on the
710+
-- era transition from Babbage to Conway. This will be replaced by a
711+
-- more principled refactoring in the future.
712+
--
713+
-- Pre-Conway, protocol parameters (like the ledger protocol
714+
-- version) were updated by the UPEC rule, which is executed while
715+
-- ticking across an epoch boundary. If sufficiently many Genesis
716+
-- keys submitted the same update proposal, it will update the
717+
-- governance state accordingly.
718+
--
719+
-- Conway has a completely different governance scheme (CIP-1694),
720+
-- and thus has no representation for pre-Conway update proposals,
721+
-- which are hence discarded by 'SL.translateEra'' below. Therefore,
722+
-- we monkey-patch the governance state by ticking across the
723+
-- era/epoch boundary using Babbage logic, and set the governance
724+
-- state to the updated one /before/ translating.
725+
patchGovState ::
726+
LedgerState (ShelleyBlock proto (BabbageEra c))
727+
-> LedgerState (ShelleyBlock proto (BabbageEra c))
728+
patchGovState st =
729+
st { shelleyLedgerState = shelleyLedgerState st
730+
& newEpochStateGovStateL .~ newGovState
731+
}
732+
where
733+
-- next ledger release already provides this
734+
newEpochStateGovStateL ::
735+
Lens' (SL.NewEpochState era) (SL.GovState era)
736+
newEpochStateGovStateL =
737+
SL.nesEsL . SL.esLStateL . SL.lsUTxOStateL . SL.utxosGovStateL
738+
739+
newGovState =
740+
view newEpochStateGovStateL
741+
. tickedShelleyLedgerState
742+
. applyChainTick
743+
(unwrapLedgerConfig cfgBabbage)
744+
firstSlotNewEra
745+
$ st
746+
747+
-- The UPEC rule emits no ledger events, hence this hack is not
748+
-- swallowing anything.
749+
_upecNoLedgerEvents ::
750+
STS.Event (Core.EraRule "UPEC" (BabbageEra c)) :~: Void
751+
_upecNoLedgerEvents = Refl
752+
753+
in unComp
754+
. SL.translateEra' (getConwayTranslationContext cfgConway)
755+
. Comp
756+
. patchGovState
690757

691758
getConwayTranslationContext ::
692759
WrapLedgerConfig (ShelleyBlock (Praos c) (ConwayEra c))

0 commit comments

Comments
 (0)