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