From 22a7567d78fcf05953d294110ff5a8478a321b54 Mon Sep 17 00:00:00 2001 From: drsk Date: Thu, 16 Oct 2025 16:26:56 +0200 Subject: [PATCH 1/6] COR-2001: P10 boilerplate code --- CHANGELOG.md | 1 + .../src/Concordium/GlobalState/BakerInfo.hs | 1 + .../src/Concordium/GlobalState/Block.hs | 1 + .../GlobalState/Persistent/Account.hs | 2 + .../Persistent/Account/StructureV1.hs | 2 + .../GlobalState/Persistent/Bakers.hs | 7 ++ .../GlobalState/Persistent/BlockState.hs | 9 ++ .../Persistent/BlockState/Modules.hs | 1 + .../Persistent/BlockState/Updates.hs | 17 +++ .../GlobalState/Persistent/Genesis.hs | 4 + .../GlobalState/Persistent/ReleaseSchedule.hs | 3 + .../src/Concordium/KonsensusV1/TestMonad.hs | 4 +- .../src/Concordium/ProtocolUpdate/P10.hs | 61 ++++++++++ .../Concordium/ProtocolUpdate/P10/Reboot.hs | 111 ++++++++++++++++++ .../Concordium/ProtocolUpdate/P9/Reboot.hs | 2 +- .../src/Concordium/ProtocolUpdate/V1.hs | 8 +- .../src/Concordium/Scheduler.hs | 1 + .../Scheduler/TreeStateEnvironment.hs | 1 + .../src/Concordium/Startup.hs | 7 ++ 19 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs create mode 100644 concordium-consensus/src/Concordium/ProtocolUpdate/P10/Reboot.hs diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac990d90..e32a5b24a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ the token module state. They are still required by the current token module implementation, and initialization without the parameters set will be rejected, so there are no observable changes to PLT behaviour. - Fixed the `build_catchup_url` in the Ubuntu build release pipeline. +- Added boilerplate code for the upcoming P10. ## 9.0.7 diff --git a/concordium-consensus/src/Concordium/GlobalState/BakerInfo.hs b/concordium-consensus/src/Concordium/GlobalState/BakerInfo.hs index 1f292c8f4..40eed9e2f 100644 --- a/concordium-consensus/src/Concordium/GlobalState/BakerInfo.hs +++ b/concordium-consensus/src/Concordium/GlobalState/BakerInfo.hs @@ -377,6 +377,7 @@ genesisBakerInfoEx spv cp GenesisBaker{..} = case spv of SP7 -> binfoV1 SP8 -> binfoV1 SP9 -> binfoV1 + SP10 -> binfoV1 where bkrInfo = BakerInfo diff --git a/concordium-consensus/src/Concordium/GlobalState/Block.hs b/concordium-consensus/src/Concordium/GlobalState/Block.hs index d25b3ca7c..3ef3f70c4 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Block.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Block.hs @@ -144,6 +144,7 @@ blockVersion SP6 = 3 blockVersion SP7 = 3 blockVersion SP8 = 3 blockVersion SP9 = 3 +blockVersion SP10 = 3 {-# INLINE blockVersion #-} -- | Type class that supports serialization of a block. diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/Account.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/Account.hs index d8922488d..cabac3c92 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/Account.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/Account.hs @@ -865,6 +865,7 @@ migratePersistentAccount m@StateMigrationParametersP5ToP6{} (PAV2 acc) = PAV2 <$ migratePersistentAccount m@StateMigrationParametersP6ToP7{} (PAV2 acc) = PAV3 <$> V1.migratePersistentAccount m acc migratePersistentAccount m@StateMigrationParametersP7ToP8{} (PAV3 acc) = PAV4 <$> V1.migratePersistentAccount m acc migratePersistentAccount m@StateMigrationParametersP8ToP9{} (PAV4 acc) = PAV5 <$> V1.migratePersistentAccount m acc +migratePersistentAccount m@StateMigrationParametersP9ToP10{} (PAV5 acc) = PAV5 <$> V1.migratePersistentAccount m acc -- | Migrate a 'PersistentBakerInfoRef' between protocol versions according to a state migration. migratePersistentBakerInfoRef :: @@ -887,6 +888,7 @@ migratePersistentBakerInfoRef m@StateMigrationParametersP5ToP6{} (PBIRV2 bir) = migratePersistentBakerInfoRef m@StateMigrationParametersP6ToP7{} (PBIRV2 bir) = PBIRV3 <$> V1.migratePersistentBakerInfoEx m bir migratePersistentBakerInfoRef m@StateMigrationParametersP7ToP8{} (PBIRV3 bir) = PBIRV4 <$> V1.migratePersistentBakerInfoEx m bir migratePersistentBakerInfoRef m@StateMigrationParametersP8ToP9{} (PBIRV4 bir) = PBIRV5 <$> V1.migratePersistentBakerInfoEx m bir +migratePersistentBakerInfoRef m@StateMigrationParametersP9ToP10{} (PBIRV5 bir) = PBIRV5 <$> V1.migratePersistentBakerInfoEx m bir -- * Conversion diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/Account/StructureV1.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/Account/StructureV1.hs index ceefb9d73..dc51bd7d2 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/Account/StructureV1.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/Account/StructureV1.hs @@ -134,6 +134,7 @@ migratePersistentBakerInfoEx StateMigrationParametersP7ToP8{} = migrateReference m' (BakerInfoEx av2) migrateBakerInfoExV1 BakerInfoExV1{..} = return BakerInfoExV1{_bieIsSuspended = CTrue False, ..} migratePersistentBakerInfoEx StateMigrationParametersP8ToP9{} = migrateReference (return . coerceBakerInfoExV1) +migratePersistentBakerInfoEx StateMigrationParametersP9ToP10{} = migrateReference (return . coerceBakerInfoExV1) -- | Migrate a 'V0.PersistentBakerInfoEx' to a 'PersistentBakerInfoEx'. -- See documentation of @migratePersistentBlockState@. @@ -2472,6 +2473,7 @@ migratePersistentAccount StateMigrationParametersP5ToP6{} acc = migrateV2ToV2 ac migratePersistentAccount StateMigrationParametersP6ToP7{} acc = migrateV2ToV3 acc migratePersistentAccount StateMigrationParametersP7ToP8{} acc = migrateV3ToV4 acc migratePersistentAccount StateMigrationParametersP8ToP9{} acc = migrateV4ToV5 acc +migratePersistentAccount StateMigrationParametersP9ToP10{} acc = migrateV5ToV5 acc -- | Migration for 'PersistentAccount' from 'V0.PersistentAccount'. This supports migration from -- 'P4' to 'P5'. diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/Bakers.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/Bakers.hs index 8358efa7f..94ef038e5 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/Bakers.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/Bakers.hs @@ -159,6 +159,8 @@ migratePersistentEpochBakers migration PersistentEpochBakers{..} = do SomeParam $ unOParam _bakerFinalizationCommitteeParameters StateMigrationParametersP8ToP9{} -> SomeParam $ unOParam _bakerFinalizationCommitteeParameters + StateMigrationParametersP9ToP10{} -> + SomeParam $ unOParam _bakerFinalizationCommitteeParameters return PersistentEpochBakers { _bakerInfos = newBakerInfos, @@ -336,6 +338,10 @@ migratePersistentActiveDelegators StateMigrationParametersP8ToP9{} = \case PersistentActiveDelegatorsV1{..} -> do newDelegators <- Trie.migrateTrieN True return adDelegators return PersistentActiveDelegatorsV1{adDelegators = newDelegators, ..} +migratePersistentActiveDelegators StateMigrationParametersP9ToP10{} = \case + PersistentActiveDelegatorsV1{..} -> do + newDelegators <- Trie.migrateTrieN True return adDelegators + return PersistentActiveDelegatorsV1{adDelegators = newDelegators, ..} emptyPersistentActiveDelegators :: forall av. (IsAccountVersion av) => PersistentActiveDelegators av emptyPersistentActiveDelegators = @@ -387,6 +393,7 @@ migrateTotalActiveCapital StateMigrationParametersP5ToP6{} _ (TotalActiveCapital migrateTotalActiveCapital StateMigrationParametersP6ToP7{} _ (TotalActiveCapitalV1 bts) = TotalActiveCapitalV1 bts migrateTotalActiveCapital StateMigrationParametersP7ToP8{} _ (TotalActiveCapitalV1 bts) = TotalActiveCapitalV1 bts migrateTotalActiveCapital StateMigrationParametersP8ToP9{} _ (TotalActiveCapitalV1 bts) = TotalActiveCapitalV1 bts +migrateTotalActiveCapital StateMigrationParametersP9ToP10{} _ (TotalActiveCapitalV1 bts) = TotalActiveCapitalV1 bts instance (IsAccountVersion av) => Serialize (TotalActiveCapital av) where put TotalActiveCapitalV0 = return () diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState.hs index 4b1d58a06..3737c7b3a 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState.hs @@ -187,6 +187,7 @@ migrateSeedState (StateMigrationParametersP5ToP6 (P6.StateMigrationData _ time)) migrateSeedState StateMigrationParametersP6ToP7{} ss = migrateSeedStateV1Trivial ss migrateSeedState StateMigrationParametersP7ToP8{} ss = migrateSeedStateV1Trivial ss migrateSeedState StateMigrationParametersP8ToP9{} ss = migrateSeedStateV1Trivial ss +migrateSeedState StateMigrationParametersP9ToP10{} ss = migrateSeedStateV1Trivial ss -- | Trivial migration of a 'SeedStateV1' between protocol versions. migrateSeedStateV1Trivial :: SeedState 'SeedStateVersion1 -> SeedState 'SeedStateVersion1 @@ -642,6 +643,10 @@ migrateBlockRewardDetails StateMigrationParametersP8ToP9{} _ _ (SomeParam TimePa (BlockRewardDetailsV1 hbr) -> BlockRewardDetailsV1 <$> migrateHashedBufferedRef (migratePoolRewardsP6 oldEpoch _tpRewardPeriodLength) hbr +migrateBlockRewardDetails StateMigrationParametersP9ToP10{} _ _ (SomeParam TimeParametersV1{..}) oldEpoch = \case + (BlockRewardDetailsV1 hbr) -> + BlockRewardDetailsV1 + <$> migrateHashedBufferedRef (migratePoolRewardsP6 oldEpoch _tpRewardPeriodLength) hbr instance (MonadBlobStore m, IsBlockHashVersion bhv, IsAccountVersion av) => @@ -2848,6 +2853,7 @@ doGetRewardStatus pbs = do SP7 -> rewardsV1 SP8 -> rewardsV1 SP9 -> rewardsV1 + SP10 -> rewardsV1 doRewardFoundationAccount :: (SupportsPersistentState pv m) => PersistentBlockState pv -> Amount -> m (PersistentBlockState pv) doRewardFoundationAccount pbs reward = do @@ -2976,6 +2982,7 @@ doModifyAccount pbs aUpd@AccountUpdate{..} = do SP7 -> return _auIndex SP8 -> return _auIndex SP9 -> return _auIndex + SP10 -> return _auIndex !oldRel <- accountNextReleaseTimestamp acc !newRel <- accountNextReleaseTimestamp acc' return (acctRef :: RSAccountRef pv, oldRel, newRel) @@ -3679,6 +3686,7 @@ doProcessReleaseSchedule pbs ts = do SP7 -> processAccountP5 SP8 -> processAccountP5 SP9 -> processAccountP5 + SP10 -> processAccountP5 (newAccs, newRS) <- foldM processAccount (bspAccounts bsp, remRS) affectedAccounts storePBS pbs (bsp{bspAccounts = newAccs, bspReleaseSchedule = newRS}) @@ -4874,6 +4882,7 @@ migrateBlockPointers migration BlockStatePointers{..} = do StateMigrationParametersP6ToP7{} -> RSMNewToNew StateMigrationParametersP7ToP8{} -> RSMNewToNew StateMigrationParametersP8ToP9{} -> RSMNewToNew + StateMigrationParametersP9ToP10{} -> RSMNewToNew logEvent GlobalState LLTrace "Migrating release schedule" newReleaseSchedule <- migrateReleaseSchedule rsMigration bspReleaseSchedule pab <- lift . refLoad $ bspBirkParameters ^. birkActiveBakers diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Modules.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Modules.hs index a6bd08a0e..bea304ccd 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Modules.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Modules.hs @@ -577,6 +577,7 @@ migrateModules migration mods = do StateMigrationParametersP6ToP7{} -> migrateToP7 @v wasmMod -- always recompile to lower transaction costs. StateMigrationParametersP7ToP8{} -> return $! moduleVInterface{GSWasm.miModule = PIMVMem artifact} StateMigrationParametersP8ToP9{} -> return $! moduleVInterface{GSWasm.miModule = PIMVMem artifact} + StateMigrationParametersP9ToP10{} -> return $! moduleVInterface{GSWasm.miModule = PIMVMem artifact} -- store the module into the new state, and remove it from memory makeFlushedHashedCachedRef $! diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Updates.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Updates.hs index a9ee18a79..bb1b1e0f0 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Updates.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/BlockState/Updates.hs @@ -317,6 +317,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa NoParam -> return NoParam StateMigrationParametersP8ToP9{} -> case pElectionDifficultyQueue of NoParam -> return NoParam + StateMigrationParametersP9ToP10{} -> case pElectionDifficultyQueue of + NoParam -> return NoParam newTimeParameters <- case migration of StateMigrationParametersTrivial -> case pTimeParametersQueue of NoParam -> return NoParam @@ -338,6 +340,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr StateMigrationParametersP8ToP9{} -> case pTimeParametersQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pTimeParametersQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr newCooldownParameters <- case migration of StateMigrationParametersTrivial -> case pCooldownParametersQueue of NoParam -> return NoParam @@ -360,6 +364,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr StateMigrationParametersP8ToP9{} -> case pCooldownParametersQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pCooldownParametersQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr newTimeoutParameters <- case migration of StateMigrationParametersTrivial -> case pTimeoutParametersQueue of NoParam -> return NoParam @@ -381,6 +387,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr StateMigrationParametersP8ToP9{} -> case pTimeoutParametersQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pTimeoutParametersQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr newMinBlockTimeQueue <- case migration of StateMigrationParametersTrivial -> case pMinBlockTimeQueue of NoParam -> return NoParam @@ -402,6 +410,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr StateMigrationParametersP8ToP9{} -> case pMinBlockTimeQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pMinBlockTimeQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr newBlockEnergyLimitQueue <- case migration of StateMigrationParametersTrivial -> case pBlockEnergyLimitQueue of NoParam -> return NoParam @@ -423,6 +433,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr StateMigrationParametersP8ToP9{} -> case pBlockEnergyLimitQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pBlockEnergyLimitQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr newFinalizationCommitteeParametersQueue <- case migration of StateMigrationParametersTrivial -> case pFinalizationCommitteeParametersQueue of NoParam -> return NoParam @@ -444,6 +456,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr StateMigrationParametersP8ToP9{} -> case pFinalizationCommitteeParametersQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pFinalizationCommitteeParametersQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr newValidatorScoreParametersQueue <- case migration of StateMigrationParametersTrivial -> case pValidatorScoreParametersQueue of NoParam -> return NoParam @@ -465,6 +479,8 @@ migratePendingUpdates migration PendingUpdates{..} = withCPVConstraints (chainPa return (SomeParam hbr) StateMigrationParametersP8ToP9{} -> case pValidatorScoreParametersQueue of SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr + StateMigrationParametersP9ToP10{} -> case pValidatorScoreParametersQueue of + SomeParam hbr -> SomeParam <$> migrateHashedBufferedRef (migrateUpdateQueue id) hbr return $! PendingUpdates { pRootKeysUpdateQueue = newRootKeys, @@ -812,6 +828,7 @@ migrateUpdates migration Updates{..} = do StateMigrationParametersP6ToP7 -> CFalse StateMigrationParametersP7ToP8 _ -> CFalse StateMigrationParametersP8ToP9 _ -> CTrue minUpdateSequenceNumber + StateMigrationParametersP9ToP10 _ -> CTrue minUpdateSequenceNumber return Updates { currentKeyCollection = newKeyCollection, diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/Genesis.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/Genesis.hs index bbd0107f4..4987c2d50 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/Genesis.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/Genesis.hs @@ -12,6 +12,7 @@ module Concordium.GlobalState.Persistent.Genesis (genesisState) where import qualified Concordium.Genesis.Data as GenesisData import qualified Concordium.Genesis.Data.BaseV1 as GDBaseV1 import qualified Concordium.Genesis.Data.P1 as P1 +import qualified Concordium.Genesis.Data.P10 as P10 import qualified Concordium.Genesis.Data.P2 as P2 import qualified Concordium.Genesis.Data.P3 as P3 import qualified Concordium.Genesis.Data.P4 as P4 @@ -90,6 +91,9 @@ genesisState gd = MTL.runExceptT $ case Types.protocolVersion @pv of Types.SP9 -> case gd of GenesisData.GDP9 P9.GDP9Initial{..} -> buildGenesisBlockState (CGPV1 genesisCore) genesisInitialState + Types.SP10 -> case gd of + GenesisData.GDP10 P10.GDP10Initial{..} -> + buildGenesisBlockState (CGPV1 genesisCore) genesisInitialState -------- Types ----------- diff --git a/concordium-consensus/src/Concordium/GlobalState/Persistent/ReleaseSchedule.hs b/concordium-consensus/src/Concordium/GlobalState/Persistent/ReleaseSchedule.hs index 1dd66af4c..5f9f8bbe3 100644 --- a/concordium-consensus/src/Concordium/GlobalState/Persistent/ReleaseSchedule.hs +++ b/concordium-consensus/src/Concordium/GlobalState/Persistent/ReleaseSchedule.hs @@ -310,6 +310,7 @@ instance (MonadBlobStore m, IsProtocolVersion pv) => BlobStorable m (ReleaseSche SP7 -> fmap ReleaseScheduleP5 <$> load SP8 -> fmap ReleaseScheduleP5 <$> load SP9 -> fmap ReleaseScheduleP5 <$> load + SP10 -> fmap ReleaseScheduleP5 <$> load instance (MonadBlobStore m) => Cacheable m (ReleaseSchedule pv) where cache (ReleaseScheduleP0 rs) = ReleaseScheduleP0 <$> cache rs @@ -342,6 +343,7 @@ emptyReleaseSchedule = case protocolVersion @pv of SP7 -> rsP1 SP8 -> rsP1 SP9 -> rsP1 + SP10 -> rsP1 where rsP0 :: (RSAccountRef pv ~ AccountAddress) => m (ReleaseSchedule pv) rsP0 = do @@ -391,6 +393,7 @@ trivialReleaseScheduleMigration = case protocolVersion @pv of SP7 -> RSMNewToNew SP8 -> RSMNewToNew SP9 -> RSMNewToNew + SP10 -> RSMNewToNew -- | Migrate a release schedule from one protocol version to another, given by a -- 'ReleaseScheduleMigration'. diff --git a/concordium-consensus/src/Concordium/KonsensusV1/TestMonad.hs b/concordium-consensus/src/Concordium/KonsensusV1/TestMonad.hs index 51575d6ad..1ea905ac5 100644 --- a/concordium-consensus/src/Concordium/KonsensusV1/TestMonad.hs +++ b/concordium-consensus/src/Concordium/KonsensusV1/TestMonad.hs @@ -25,6 +25,7 @@ import Concordium.TimeMonad import Concordium.Types import qualified Concordium.Genesis.Data.BaseV1 as BaseV1 +import qualified Concordium.Genesis.Data.P10 as P10 import qualified Concordium.Genesis.Data.P6 as P6 import qualified Concordium.Genesis.Data.P7 as P7 import qualified Concordium.Genesis.Data.P8 as P8 @@ -33,7 +34,7 @@ import qualified Concordium.GlobalState.AccountMap.LMDB as LMDBAccountMap import Concordium.GlobalState.BlockState import qualified Concordium.GlobalState.ContractStateV1 as StateV1 import Concordium.GlobalState.Parameters ( - GenesisData (GDP6, GDP7, GDP8, GDP9), + GenesisData (GDP10, GDP6, GDP7, GDP8, GDP9), defaultRuntimeParameters, genesisBlockHash, ) @@ -153,6 +154,7 @@ genesisCore = case protocolVersion @pv of SP7 -> \(GDP7 P7.GDP7Initial{genesisCore = core}) -> core SP8 -> \(GDP8 P8.GDP8Initial{genesisCore = core}) -> core SP9 -> \(GDP9 P9.GDP9Initial{genesisCore = core}) -> core + SP10 -> \(GDP10 P10.GDP10Initial{genesisCore = core}) -> core -- | Run an operation in the 'TestMonad' with the given baker, time and genesis data. -- This sets up a temporary blob store for the block state that is deleted after use. diff --git a/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs b/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs new file mode 100644 index 000000000..3f633068b --- /dev/null +++ b/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs @@ -0,0 +1,61 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE TypeFamilies #-} + +module Concordium.ProtocolUpdate.P10 ( + Update (..), + checkUpdate, + updateRegenesis, + updateNextProtocolVersion, +) where + +import Control.Monad.State +import qualified Data.HashMap.Strict as HM +import Data.Serialize + +import qualified Concordium.Crypto.SHA256 as SHA256 +import Concordium.Types +import Concordium.Types.Updates + +import Concordium.GlobalState.BlockState +import qualified Concordium.GlobalState.Persistent.BlockState as PBS +import Concordium.GlobalState.Types +import qualified Concordium.GlobalState.Types as GSTypes +import Concordium.KonsensusV1.TreeState.Implementation +import Concordium.KonsensusV1.TreeState.Types +import qualified Concordium.ProtocolUpdate.P10.Reboot as Reboot + +-- | Updates that are supported from protocol version P9. +data Update = Reboot + deriving (Show) + +-- | Hash map for resolving updates from their specification hash. +updates :: HM.HashMap SHA256.Hash (Get Update) +updates = HM.fromList [(Reboot.updateHash, return Reboot)] + +-- | Determine if a 'ProtocolUpdate' corresponds to a supported update type. +checkUpdate :: ProtocolUpdate -> Either String Update +checkUpdate ProtocolUpdate{..} = case HM.lookup puSpecificationHash updates of + Nothing -> Left "Specification hash does not correspond to a known protocol update." + Just updateGet -> case runGet updateGet puSpecificationAuxiliaryData of + Left err -> Left $! "Could not deserialize auxiliary data: " ++ err + Right update -> return update + +-- | Construct the genesis data for a P10 update. +updateRegenesis :: + ( MPV m ~ 'P10, + BlockStateStorage m, + MonadState (SkovData (MPV m)) m, + GSTypes.BlockState m ~ PBS.HashedPersistentBlockState (MPV m) + ) => + -- | The update taking effect. + Update -> + -- | The terminal block of the old chain. + BlockPointer (MPV m) -> + m (PVInit m) +updateRegenesis Reboot = Reboot.updateRegenesis + +-- | Determine the protocol version the update will update to. +updateNextProtocolVersion :: + Update -> + SomeProtocolVersion +updateNextProtocolVersion Reboot{} = SomeProtocolVersion SP10 diff --git a/concordium-consensus/src/Concordium/ProtocolUpdate/P10/Reboot.hs b/concordium-consensus/src/Concordium/ProtocolUpdate/P10/Reboot.hs new file mode 100644 index 000000000..63a0140d3 --- /dev/null +++ b/concordium-consensus/src/Concordium/ProtocolUpdate/P10/Reboot.hs @@ -0,0 +1,111 @@ +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE TypeFamilies #-} + +-- | This module implements the P10.Reboot protocol update. +-- This protocol update is valid at protocol version P10, and updates +-- to protocol version P10. +-- This produces a new 'RegenesisDataP10 using the 'GDP10Regenesis' constructor, +-- as follows: +-- +-- * 'genesisCore': +-- +-- * 'genesisTime' is the timestamp of the last finalized block of the previous chain. +-- * 'genesisEpochDuration' is taken from the previous genesis. +-- * 'genesisSignatureThreshold' is taken from the previous genesis. +-- +-- * 'genesisFirstGenesis' is either: +-- +-- * the hash of the genesis block of the previous chain, if it is a 'GDP10Initial'; or +-- * the 'genesisFirstGenesis' value of the genesis block of the previous chain, if it +-- is a 'GDP10Regenesis'. +-- +-- * 'genesisPreviousGenesis' is the hash of the previous genesis block. +-- +-- * 'genesisTerminalBlock' is the hash of the last finalized block of the previous chain. +-- +-- * 'genesisStateHash' is the state hash of the last finalized block of the previous chain. +-- +-- The block state is taken from the last finalized block of the previous chain. It is updated +-- as part of the state migration, which makes the following changes: +-- +-- * The seed state is migrated as follows: +-- +-- * The current epoch is reset to zero. +-- * The current and updated leadership election nonce are set to the hash of +-- @"Regenesis" <> encode oldUpdatedNonce@. +-- * The trigger block time is kept the same, meaning that the epoch will transition as soon +-- as possible. +-- * The epoch transition triggered flag is set. +-- * The shutdown triggered flag is cleared. +-- +-- * The old current epoch is subtracted from the next payday epoch. +-- +-- * The protocol update queue is emptied during the migration. +-- +-- Note that, the initial epoch of the new chain is not considered +-- a new epoch for the purposes of block rewards and baker/finalization committee determination. +-- In particular, the timing of the next payday will be the same as if the protocol update +-- had not happened. (For instance, if it would have happened at the start of the next epoch +-- prior to the protocol update, after the update it will happen at the start of epoch 1. +-- The trigger block time in epoch 0 of the new consensus is the same as the trigger block +-- time in the final epoch of the old consensus.) +-- Furthermore, the bakers from the final epoch of the previous chain are also the bakers for the +-- initial epoch of the new chain. +module Concordium.ProtocolUpdate.P10.Reboot where + +import Control.Monad.State +import Lens.Micro.Platform + +import qualified Concordium.Crypto.SHA256 as SHA256 +import qualified Concordium.Genesis.Data as GenesisData +import qualified Concordium.Genesis.Data.BaseV1 as BaseV1 +import qualified Concordium.Genesis.Data.P10 as P10 +import Concordium.GlobalState.BlockState +import qualified Concordium.GlobalState.Persistent.BlockState as PBS +import Concordium.GlobalState.Types +import qualified Concordium.GlobalState.Types as GSTypes +import Concordium.KonsensusV1.TreeState.Implementation +import Concordium.KonsensusV1.TreeState.Types +import Concordium.KonsensusV1.Types +import Concordium.Types.HashableTo (getHash) +import Concordium.Types.ProtocolVersion + +-- | The hash that identifies the P10.Reboot update: +-- e135d02624bcf91d8184c6746f6b2fc2e869df0b2716693e47e5ece8ec4d9704 +updateHash :: SHA256.Hash +updateHash = SHA256.hash "P10.Reboot" + +-- | Construct the genesis data for a P10.Reboot update. +-- This takes the terminal block of the old chain which is used as the basis for constructing +-- the new genesis block. +updateRegenesis :: + ( MPV m ~ 'P10, + BlockStateStorage m, + MonadState (SkovData (MPV m)) m, + GSTypes.BlockState m ~ PBS.HashedPersistentBlockState (MPV m) + ) => + -- | The terminal block of the old chain. + BlockPointer 'P10 -> + m (PVInit m) +updateRegenesis terminal = do + -- Genesis time is the timestamp of the terminal block + let regenesisTime = blockTimestamp terminal + -- Core parameters are derived from the old genesis, apart from genesis time which is set for + -- the time of the terminal block. + gMetadata <- use genesisMetadata + BaseV1.CoreGenesisParametersV1{..} <- gmParameters <$> use genesisMetadata + let core = + BaseV1.CoreGenesisParametersV1 + { BaseV1.genesisTime = regenesisTime, + .. + } + -- genesisFirstGenesis is the block hash of the previous genesis, if it is initial, + -- or the genesisFirstGenesis of the previous genesis otherwise. + let genesisFirstGenesis = gmFirstGenesisHash gMetadata + genesisPreviousGenesis = gmCurrentGenesisHash gMetadata + genesisTerminalBlock = getHash terminal + let regenesisBlockState = bpState terminal + genesisStateHash <- getStateHash regenesisBlockState + let newGenesis = GenesisData.RGDP10 $ P10.GDP10Regenesis{genesisRegenesis = BaseV1.RegenesisDataV1{genesisCore = core, ..}} + return (PVInit newGenesis GenesisData.StateMigrationParametersTrivial (bmHeight $ bpInfo terminal)) diff --git a/concordium-consensus/src/Concordium/ProtocolUpdate/P9/Reboot.hs b/concordium-consensus/src/Concordium/ProtocolUpdate/P9/Reboot.hs index 3f5f34e61..baad9187c 100644 --- a/concordium-consensus/src/Concordium/ProtocolUpdate/P9/Reboot.hs +++ b/concordium-consensus/src/Concordium/ProtocolUpdate/P9/Reboot.hs @@ -76,7 +76,7 @@ import Concordium.Types.ProtocolVersion updateHash :: SHA256.Hash updateHash = SHA256.hash "P9.Reboot" --- | Construct the genesis data for a P8.Reboot update. +-- | Construct the genesis data for a P9.Reboot update. -- This takes the terminal block of the old chain which is used as the basis for constructing -- the new genesis block. updateRegenesis :: diff --git a/concordium-consensus/src/Concordium/ProtocolUpdate/V1.hs b/concordium-consensus/src/Concordium/ProtocolUpdate/V1.hs index 3f04fcc4d..5a1c07015 100644 --- a/concordium-consensus/src/Concordium/ProtocolUpdate/V1.hs +++ b/concordium-consensus/src/Concordium/ProtocolUpdate/V1.hs @@ -17,6 +17,7 @@ import Concordium.GlobalState.Types (PVInit) import qualified Concordium.GlobalState.Types as GSTypes import Concordium.KonsensusV1.TreeState.Implementation import Concordium.KonsensusV1.TreeState.Types +import qualified Concordium.ProtocolUpdate.P10 as P10 import qualified Concordium.ProtocolUpdate.P6 as P6 import qualified Concordium.ProtocolUpdate.P7 as P7 import qualified Concordium.ProtocolUpdate.P8 as P8 @@ -28,12 +29,14 @@ data Update (pv :: ProtocolVersion) where UpdateP7 :: P7.Update -> Update 'P7 UpdateP8 :: P8.Update -> Update 'P8 UpdateP9 :: P9.Update -> Update 'P9 + UpdateP10 :: P10.Update -> Update 'P10 instance Show (Update pv) where show (UpdateP6 u) = "P6." ++ show u show (UpdateP7 u) = "P7." ++ show u show (UpdateP8 u) = "P8." ++ show u - show (UpdateP9 u) = "P8." ++ show u + show (UpdateP9 u) = "P9." ++ show u + show (UpdateP10 u) = "P10." ++ show u -- | Determine if a 'ProtocolUpdate' corresponds to a supported update type. checkUpdate :: forall pv. (IsProtocolVersion pv) => ProtocolUpdate -> Either String (Update pv) @@ -49,6 +52,7 @@ checkUpdate = case protocolVersion @pv of SP7 -> fmap UpdateP7 . P7.checkUpdate SP8 -> fmap UpdateP8 . P8.checkUpdate SP9 -> fmap UpdateP9 . P9.checkUpdate + SP10 -> fmap UpdateP10 . P10.checkUpdate -- | Construct the genesis data for a P1 update. updateRegenesis :: @@ -65,6 +69,7 @@ updateRegenesis (UpdateP6 u) = P6.updateRegenesis u updateRegenesis (UpdateP7 u) = P7.updateRegenesis u updateRegenesis (UpdateP8 u) = P8.updateRegenesis u updateRegenesis (UpdateP9 u) = P9.updateRegenesis u +updateRegenesis (UpdateP10 u) = P10.updateRegenesis u -- | Determine the next protocol version for the given update. Although the same -- information can be retrieved from 'updateRegenesis', this is more efficient @@ -76,3 +81,4 @@ updateNextProtocolVersion (UpdateP6 u) = P6.updateNextProtocolVersion u updateNextProtocolVersion (UpdateP7 u) = P7.updateNextProtocolVersion u updateNextProtocolVersion (UpdateP8 u) = P8.updateNextProtocolVersion u updateNextProtocolVersion (UpdateP9 u) = P9.updateNextProtocolVersion u +updateNextProtocolVersion (UpdateP10 u) = P10.updateNextProtocolVersion u diff --git a/concordium-consensus/src/Concordium/Scheduler.hs b/concordium-consensus/src/Concordium/Scheduler.hs index d32271d33..f83c324ca 100644 --- a/concordium-consensus/src/Concordium/Scheduler.hs +++ b/concordium-consensus/src/Concordium/Scheduler.hs @@ -1283,6 +1283,7 @@ handleContractUpdateV1 depth originAddr istance checkAndGetSender transferAmount P7 -> resumeEvent False : interruptEvent : events P8 -> resumeEvent False : interruptEvent : events P9 -> resumeEvent False : interruptEvent : events + P10 -> resumeEvent False : interruptEvent : events go newEvents =<< runInterpreter (return . WasmV1.resumeReceiveFun rrdInterruptedConfig rrdCurrentState False entryBalance (WasmV1.Error (WasmV1.EnvFailure (WasmV1.MissingContract imcTo))) Nothing) Just (InstanceInfoV0 targetInstance) -> do -- we are invoking a V0 instance. diff --git a/concordium-consensus/src/Concordium/Scheduler/TreeStateEnvironment.hs b/concordium-consensus/src/Concordium/Scheduler/TreeStateEnvironment.hs index 69f73f838..b6888edd2 100644 --- a/concordium-consensus/src/Concordium/Scheduler/TreeStateEnvironment.hs +++ b/concordium-consensus/src/Concordium/Scheduler/TreeStateEnvironment.hs @@ -1183,6 +1183,7 @@ putBakerCommissionsInRange ranges bs (BakerId ai) = case protocolVersion @(MPV m SP7 -> bsoConstrainBakerCommission bs ai ranges SP8 -> bsoConstrainBakerCommission bs ai ranges SP9 -> bsoConstrainBakerCommission bs ai ranges + SP10 -> bsoConstrainBakerCommission bs ai ranges -- | The result of executing the block prologue. data PrologueResult m = PrologueResult diff --git a/concordium-consensus/src/Concordium/Startup.hs b/concordium-consensus/src/Concordium/Startup.hs index b6dcfa8c8..e914e809b 100644 --- a/concordium-consensus/src/Concordium/Startup.hs +++ b/concordium-consensus/src/Concordium/Startup.hs @@ -32,6 +32,7 @@ import Concordium.Crypto.DummyData ( import qualified Concordium.Genesis.Data as GenesisData import qualified Concordium.Genesis.Data.BaseV1 as GDBaseV1 import qualified Concordium.Genesis.Data.P1 as P1 +import qualified Concordium.Genesis.Data.P10 as P10 import qualified Concordium.Genesis.Data.P2 as P2 import qualified Concordium.Genesis.Data.P3 as P3 import qualified Concordium.Genesis.Data.P4 as P4 @@ -278,3 +279,9 @@ makeGenesisDataV1 { genesisCore = GDBaseV1.CoreGenesisParametersV1{..}, genesisInitialState = GenesisData.GenesisState{genesisAccounts = Vec.fromList genesisAccounts, ..} } + SP10 -> + GDP10 + P10.GDP10Initial + { genesisCore = GDBaseV1.CoreGenesisParametersV1{..}, + genesisInitialState = GenesisData.GenesisState{genesisAccounts = Vec.fromList genesisAccounts, ..} + } From 17c52fc78babaa4313a481679a99024f028e47f4 Mon Sep 17 00:00:00 2001 From: drsk Date: Mon, 20 Oct 2025 14:33:32 +0200 Subject: [PATCH 2/6] concordium-base: update submodule --- concordium-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concordium-base b/concordium-base index 73e1dad0e..b20e9c9be 160000 --- a/concordium-base +++ b/concordium-base @@ -1 +1 @@ -Subproject commit 73e1dad0e423a6830d704d15adf732191a5f73df +Subproject commit b20e9c9be5e03faf63bc215ae69f1e6756f7cc1a From 26277ec94a8aaa03d7d3e4778fe03fa90bebecaa Mon Sep 17 00:00:00 2001 From: drsk Date: Mon, 20 Oct 2025 15:24:20 +0200 Subject: [PATCH 3/6] update tests --- .../ConcordiumTests/KonsensusV1/Consensus/Blocks.hs | 2 ++ .../KonsensusV1/TransactionProcessingTest.hs | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/Consensus/Blocks.hs b/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/Consensus/Blocks.hs index c9dc238f6..dd581dd92 100644 --- a/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/Consensus/Blocks.hs +++ b/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/Consensus/Blocks.hs @@ -38,6 +38,7 @@ import qualified Concordium.Types.TransactionOutcomes as TransactionOutcomes import Concordium.Types.Transactions import qualified Concordium.Types.Transactions as Transactions +import qualified Concordium.Genesis.Data.P10 as P10 import qualified Concordium.Genesis.Data.P6 as P6 import qualified Concordium.Genesis.Data.P7 as P7 import qualified Concordium.Genesis.Data.P8 as P8 @@ -128,6 +129,7 @@ genesisLEN sProtocolVersion = case sProtocolVersion of SP7 -> genesisLeadershipElectionNonce $ P7.genesisInitialState $ unGDP7 $ genesisData sProtocolVersion SP8 -> genesisLeadershipElectionNonce $ P8.genesisInitialState $ unGDP8 $ genesisData sProtocolVersion SP9 -> genesisLeadershipElectionNonce $ P9.genesisInitialState $ unGDP9 $ genesisData sProtocolVersion + SP10 -> genesisLeadershipElectionNonce $ P10.genesisInitialState $ unGDP10 $ genesisData sProtocolVersion -- | Full bakers at genesis genesisFullBakers :: forall pv. (IsConsensusV1 pv, IsProtocolVersion pv) => SProtocolVersion pv -> FullBakers diff --git a/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/TransactionProcessingTest.hs b/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/TransactionProcessingTest.hs index 0baa4a31f..bc887718b 100644 --- a/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/TransactionProcessingTest.hs +++ b/concordium-consensus/tests/consensus/ConcordiumTests/KonsensusV1/TransactionProcessingTest.hs @@ -46,6 +46,7 @@ import qualified Concordium.Crypto.VRF as VRF import Concordium.Genesis.Data hiding (GenesisConfiguration) import qualified Concordium.Genesis.Data.Base as Base import Concordium.Genesis.Data.BaseV1 +import Concordium.Genesis.Data.P10 import Concordium.Genesis.Data.P6 import Concordium.Genesis.Data.P7 import Concordium.Genesis.Data.P8 @@ -278,6 +279,12 @@ makeTestingGenesisData idps = { genesisCore = coreGenesisParams, genesisInitialState = Base.GenesisState{..} } + SP10 -> + GDP10 + GDP10Initial + { genesisCore = coreGenesisParams, + genesisInitialState = Base.GenesisState{..} + } -- | Utility function for parrsing identity providers. readIps :: BSL.ByteString -> Maybe IdentityProviders From 73e903fa1d7f0fbcfedebba2b23ff9a798b2bee4 Mon Sep 17 00:00:00 2001 From: drsk <827698+drsk0@users.noreply.github.com> Date: Tue, 28 Oct 2025 14:59:31 +0100 Subject: [PATCH 4/6] Update concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs Co-authored-by: Thomas Dinsdale-Young --- concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs b/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs index 3f633068b..cd3f70ef6 100644 --- a/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs +++ b/concordium-consensus/src/Concordium/ProtocolUpdate/P10.hs @@ -24,7 +24,7 @@ import Concordium.KonsensusV1.TreeState.Implementation import Concordium.KonsensusV1.TreeState.Types import qualified Concordium.ProtocolUpdate.P10.Reboot as Reboot --- | Updates that are supported from protocol version P9. +-- | Updates that are supported from protocol version P10. data Update = Reboot deriving (Show) From fda92f199a19d87162c71d28beafac38254a5d30 Mon Sep 17 00:00:00 2001 From: drsk Date: Tue, 28 Oct 2025 15:49:52 +0100 Subject: [PATCH 5/6] update Cargo.lock --- concordium-node/Cargo.lock | 4 ++-- plt-deployment-unit/Cargo.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/concordium-node/Cargo.lock b/concordium-node/Cargo.lock index 7a9d4002a..8537e6e36 100644 --- a/concordium-node/Cargo.lock +++ b/concordium-node/Cargo.lock @@ -757,7 +757,7 @@ dependencies = [ [[package]] name = "concordium_base" -version = "8.0.0" +version = "8.0.0-alpha.3" dependencies = [ "aes", "anyhow", @@ -805,7 +805,7 @@ dependencies = [ [[package]] name = "concordium_base_derive" -version = "1.1.0" +version = "1.1.0-alpha.3" dependencies = [ "convert_case 0.8.0", "darling", diff --git a/plt-deployment-unit/Cargo.lock b/plt-deployment-unit/Cargo.lock index d4ac1289e..989f338b8 100644 --- a/plt-deployment-unit/Cargo.lock +++ b/plt-deployment-unit/Cargo.lock @@ -365,7 +365,7 @@ dependencies = [ [[package]] name = "concordium_base" -version = "8.0.0" +version = "8.0.0-alpha.3" dependencies = [ "anyhow", "ark-bls12-381", @@ -408,7 +408,7 @@ dependencies = [ [[package]] name = "concordium_base_derive" -version = "1.1.0" +version = "1.1.0-alpha.3" dependencies = [ "convert_case 0.8.0", "darling 0.20.11", From e13019761b56c3b867ef1e40648d60b2493b2c66 Mon Sep 17 00:00:00 2001 From: drsk Date: Tue, 28 Oct 2025 17:39:27 +0100 Subject: [PATCH 6/6] concordium-base: update submodule --- concordium-base | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/concordium-base b/concordium-base index b20e9c9be..3b735e101 160000 --- a/concordium-base +++ b/concordium-base @@ -1 +1 @@ -Subproject commit b20e9c9be5e03faf63bc215ae69f1e6756f7cc1a +Subproject commit 3b735e1012411208ec20d7bb2b2d224239a21150