Skip to content

Commit

Permalink
suspend new bids at snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
drsk committed Dec 2, 2024
1 parent f70cdcb commit 69ff933
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
50 changes: 29 additions & 21 deletions concordium-consensus/src/Concordium/KonsensusV1/Scheduler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ module Concordium.KonsensusV1.Scheduler where
import Control.Monad
import Data.Bool.Singletons
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Time
import Data.Word
import Lens.Micro.Platform

import Concordium.Logger
import Concordium.TimeMonad
import Concordium.Types
import Concordium.Types.Accounts (bakerIdentity)
import Concordium.Types.Conditionally
import Concordium.Types.SeedState

Expand Down Expand Up @@ -121,7 +123,8 @@ data PrologueResult m av = PrologueResult
prologuePaydayParameters :: Maybe (PaydayParameters av),
-- | If the block triggered an epoch transition and the new epoch is a
-- snapshot, this flag is true.
prologueIsSnapshot :: Bool
prologueIsSnapshot :: Bool,
prologueSuspendedBids :: Set.Set BakerId
}

-- * Block prologue
Expand Down Expand Up @@ -190,8 +193,8 @@ doEpochTransition ::
Duration ->
-- | State to update
UpdatableBlockState m ->
m (Maybe (PaydayParameters (AccountVersionFor (MPV m))), Bool, UpdatableBlockState m)
doEpochTransition False _ theState = return (Nothing, False, theState)
m (Maybe (PaydayParameters (AccountVersionFor (MPV m))), Bool, Set.Set BakerId, UpdatableBlockState m)
doEpochTransition False _ theState = return (Nothing, False, Set.empty, theState)
doEpochTransition True epochDuration theState0 = do
chainParams <- bsoGetChainParameters theState0
oldSeedState <- bsoGetSeedState theState0
Expand Down Expand Up @@ -230,9 +233,15 @@ doEpochTransition True epochDuration theState0 = do
let newSeedState = updateSeedStateForEpoch newBakers epochDuration oldSeedState
theState7 <- bsoSetSeedState theState6 newSeedState
let isSnapshot = newEpoch + 1 == newNextPayday
theState9 <- do
(suspendedBids, theState8) <- do
if isSnapshot
then do
snapshotPoolRewards <- bsoGetBakerPoolRewardDetails theState7
-- account indexes that will be suspended
let suspendedBids =
Set.fromList
[ bid | (bid, rd) <- Map.toList snapshotPoolRewards, primedForSuspension $ fromCondDef (suspensionInfo rd) emptySuspensionInfo
]
-- This is the start of the last epoch of a payday, so take a baker snapshot.
let epochEnd = newSeedState ^. triggerBlockTime
let av = accountVersionFor (demoteProtocolVersion (protocolVersion @(MPV m)))
Expand All @@ -244,6 +253,7 @@ doEpochTransition True epochDuration theState0 = do
(chainParams ^. cpPoolParameters)
activeBakers
passiveDelegators
suspendedBids
theState8 <-
bsoSetNextEpochBakers
theState7
Expand All @@ -253,10 +263,10 @@ doEpochTransition True epochDuration theState0 = do
-- From P7 onwards, we transition pre-pre-cooldowns into pre-cooldowns, so that
-- at the next payday they will enter cooldown.
case sSupportsFlexibleCooldown (sAccountVersionFor (protocolVersion @(MPV m))) of
STrue -> bsoProcessPrePreCooldowns theState9
SFalse -> return theState9
else return theState7
return (mPaydayParams, isSnapshot, theState9)
STrue -> (suspendedBids,) <$> bsoProcessPrePreCooldowns theState9
SFalse -> return (suspendedBids, theState9)
else return (Set.empty, theState7)
return (mPaydayParams, isSnapshot, suspendedBids, theState8)

-- | Update the seed state to account for a block.
-- See 'updateSeedStateForBlock' for details of what this entails.
Expand Down Expand Up @@ -308,14 +318,15 @@ executeBlockPrologue BlockExecutionData{..} = do
-- unlock the scheduled releases that have expired
theState3 <- bsoProcessReleaseSchedule theState2 bedTimestamp
-- transition the epoch if necessary
(mPaydayParms, isSnapshot, theState4) <- doEpochTransition bedIsNewEpoch bedEpochDuration theState3
(mPaydayParms, isSnapshot, snapshotSuspendedBids, theState4) <- doEpochTransition bedIsNewEpoch bedEpochDuration theState3
-- update the seed state using the block time and block nonce
theState5 <- doUpdateSeedStateForBlock bedTimestamp bedBlockNonce theState4
return
PrologueResult
{ prologueBlockState = theState5,
prologuePaydayParameters = mPaydayParms,
prologueIsSnapshot = isSnapshot
prologueIsSnapshot = isSnapshot,
prologueSuspendedBids = snapshotSuspendedBids
}

-- * Block epilogue
Expand Down Expand Up @@ -379,7 +390,6 @@ processPaydayRewards (Just PaydayParameters{..}) theState0 = do
case _cpValidatorScoreParameters cps of
NoParam -> return theState1
SomeParam (ValidatorScoreParameters{..}) -> do
(bids, theState3) <- bsoPrimeForSuspension theState2 _vspMaxMissedRounds (Map.keys paydayPoolRewards)
(bids, theState3) <- bsoPrimeForSuspension theState2 _vspMaxMissedRounds (bakerInfoExs paydayBakers ^.. each . bakerIdentity)
foldM bsoAddSpecialTransactionOutcome theState3 (ValidatorPrimedForSuspension <$> bids)
where
Expand Down Expand Up @@ -428,18 +438,13 @@ processSuspensions ::
forall pv m.
( pv ~ MPV m,
BlockStateStorage m,
IsConsensusV1 pv,
PVSupportsValidatorSuspension pv
) =>
Set.Set BakerId ->
UpdatableBlockState m ->
m (UpdatableBlockState m)
processSuspensions bs0 = do
bprd <- bsoGetBakerPoolRewardDetails bs0
-- account indexes that will be suspended
let ais =
[ ai | (BakerId ai, rd) <- Map.toList bprd, primedForSuspension $ fromCondDef (suspensionInfo rd) emptySuspensionInfo
]
(ais', bs1) <- bsoSuspendValidators bs0 ais
processSuspensions snapshotSuspendedBids bs0 = do
(ais', bs1) <- bsoSuspendValidators bs0 [ai | BakerId ai <- Set.toList snapshotSuspendedBids]
foldM bsoAddSpecialTransactionOutcome bs1 (ValidatorSuspended . BakerId <$> ais')

-- | Execute the block epilogue. This mints and distributes the rewards for a payday if the block is
Expand All @@ -458,14 +463,15 @@ executeBlockEpilogue ::
TransactionRewardParameters ->
Map.Map BakerId Word64 ->
Bool ->
Set.Set BakerId ->
UpdatableBlockState m ->
m (PBS.HashedPersistentBlockState pv)
executeBlockEpilogue participants paydayParams transactionRewardParams missedRounds isSnapshot theState0 = do
executeBlockEpilogue participants paydayParams transactionRewardParams missedRounds isSnapshot snapshotSuspendedBids theState0 = do
theState1 <- processPaydayRewards paydayParams theState0
theState2 <- processBlockRewards participants transactionRewardParams missedRounds theState1
theState3 <- case hasValidatorSuspension of
STrue
| isSnapshot -> processSuspensions theState2
| isSnapshot -> processSuspensions snapshotSuspendedBids theState2
| otherwise -> return theState2
SFalse -> return theState2
freezeBlockState theState3
Expand Down Expand Up @@ -642,6 +648,7 @@ executeBlockState execData@BlockExecutionData{..} transactions = do
terTransactionRewardParameters
bedMissedRounds
prologueIsSnapshot
prologueSuspendedBids
terBlockState
return (endState, terEnergyUsed)

Expand Down Expand Up @@ -698,6 +705,7 @@ constructBlockState runtimeParams transactionTable pendingTable execData@BlockEx
terTransactionRewardParameters
bedMissedRounds
prologueIsSnapshot
prologueSuspendedBids
terBlockState
endTime <- currentTime
logEvent Scheduler LLInfo $ "Constructed a block in " ++ show (diffUTCTime endTime startTime)
Expand Down
12 changes: 8 additions & 4 deletions concordium-consensus/src/Concordium/Kontrol/Bakers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ module Concordium.Kontrol.Bakers where

import Data.Maybe
import Data.Monoid
import qualified Data.Set as Set
import qualified Data.Vector as Vec
import Lens.Micro.Platform

Expand Down Expand Up @@ -178,8 +179,9 @@ computeBakerStakesAndCapital ::
PoolParameters' 'PoolParametersVersion1 ->
[ActiveBakerInfo' bakerInfoRef] ->
[ActiveDelegatorInfo] ->
Set.Set BakerId ->
BakerStakesAndCapital bakerInfoRef
computeBakerStakesAndCapital poolParams activeBakers passiveDelegators = BakerStakesAndCapital{..}
computeBakerStakesAndCapital poolParams activeBakers passiveDelegators snapshotSuspendedBids = BakerStakesAndCapital{..}
where
leverage = poolParams ^. ppLeverageBound
capitalBound = poolParams ^. ppCapitalBound
Expand All @@ -195,7 +197,7 @@ computeBakerStakesAndCapital poolParams activeBakers passiveDelegators = BakerSt
capLimit
]
)
filteredActiveBakers = [abi | abi@ActiveBakerInfo{..} <- activeBakers, not activeBakerIsSuspended]
filteredActiveBakers = [abi | abi@ActiveBakerInfo{..} <- activeBakers, not (activeBakerIsSuspended || activeBakerId `Set.member` snapshotSuspendedBids)]
filteredPoolCapitals = poolCapital <$> filteredActiveBakers
bakerStakes = zipWith makeBakerStake filteredActiveBakers filteredPoolCapitals
delegatorCapital ActiveDelegatorInfo{..} = DelegatorCapital activeDelegatorId activeDelegatorStake
Expand All @@ -219,9 +221,10 @@ generateNextBakers ::
) =>
-- | The payday epoch
Epoch ->
Set.Set BakerId ->
UpdatableBlockState m ->
m (UpdatableBlockState m)
generateNextBakers paydayEpoch bs0 = do
generateNextBakers paydayEpoch suspendedBids bs0 = do
isEffective <- effectiveTest paydayEpoch
-- Determine the bakers and delegators for the next reward period, accounting for any
-- stake reductions that are currently pending on active bakers with effective time at
Expand All @@ -241,6 +244,7 @@ generateNextBakers paydayEpoch bs0 = do
(cps ^. cpPoolParameters)
activeBakers
passiveDelegators
suspendedBids
bs1 <- bsoSetNextEpochBakers bs0 bakerStakes NoParam
bsoSetNextCapitalDistribution bs1 capitalDistribution

Expand Down Expand Up @@ -389,7 +393,7 @@ getSlotBakersP4 genData bs slot =
ePoolParams pp' updates
ePoolParams pp _ = pp
effectivePoolParameters = ePoolParams (chainParams ^. cpPoolParameters) pendingPoolParams
bsc = computeBakerStakesAndCapital effectivePoolParameters activeBakers passiveDelegators
bsc = computeBakerStakesAndCapital effectivePoolParameters activeBakers passiveDelegators Set.empty
let mkFullBaker (biRef, _bakerStake) = do
_theBakerInfo <- derefBakerInfo biRef
return FullBakerInfo{..}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import qualified Data.Map as Map
import Data.Maybe
import Data.Ratio
import qualified Data.Sequence as Seq
import qualified Data.Set as Set
import Data.Time
import qualified Data.Vector as Vec
import Data.Word
Expand Down Expand Up @@ -1110,7 +1111,7 @@ updateBirkParameters newSeedState bs0 oldChainParameters updates = case protocol
processPaydays pd mrps0 bspp0 = do
bspp1 <-
if oldSeedState ^. epoch < pd - 1 && pd - 1 <= newSeedState ^. epoch
then generateNextBakers pd bspp0
then generateNextBakers pd Set.empty bspp0
else return bspp0
if pd <= newSeedState ^. epoch
then do
Expand Down

0 comments on commit 69ff933

Please sign in to comment.