Skip to content

Commit 51b9f80

Browse files
committed
Move pool deposits into StakePoolState
1 parent 4edd7fd commit 51b9f80

File tree

10 files changed

+130
-83
lines changed

10 files changed

+130
-83
lines changed

eras/shelley/impl/src/Cardano/Ledger/Shelley/LedgerState.hs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ module Cardano.Ledger.Shelley.LedgerState (
4242
produced,
4343

4444
-- * DelegationState
45-
payPoolDeposit,
46-
refundPoolDeposit,
4745
totalObligation,
4846
allObligations,
4947

@@ -102,7 +100,7 @@ module Cardano.Ledger.Shelley.LedgerState (
102100
utxosDonationL,
103101
epochStateGovStateL,
104102
epochStateStakeDistrL,
105-
epochStatePoolParamsL,
103+
epochStatePoolParamsG,
106104
epochStateStakePoolsL,
107105
epochStateDonationL,
108106
newEpochStateGovStateL,

eras/shelley/impl/src/Cardano/Ledger/Shelley/LedgerState/Types.hs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -698,11 +698,13 @@ epochStateStakePoolsL ::
698698
EraCertState era => Lens' (EpochState era) (Map (KeyHash 'StakePool) StakePoolState)
699699
epochStateStakePoolsL = esLStateL . lsCertStateL . certPStateL . psStakePoolsL
700700

701-
epochStatePoolParamsL ::
702-
EraCertState era => Lens' (EpochState era) (Map (KeyHash 'StakePool) PoolParams)
703-
epochStatePoolParamsL =
704-
epochStateStakePoolsL . lens (mapWithKey stakePoolStateToPoolParams) (const $ fmap mkStakePoolState)
705-
{-# DEPRECATED epochStatePoolParamsL "In favor of `epochStateStakePoolsL`" #-}
701+
-- | We cannot have a full Lens' here since we loose information that is
702+
-- unrecoverable in the opposite direction, namely the pool deposit.
703+
epochStatePoolParamsG ::
704+
EraCertState era => SimpleGetter (EpochState era) (Map (KeyHash 'StakePool) PoolParams)
705+
epochStatePoolParamsG =
706+
esLStateL . lsCertStateL . certPStateL . psStakePoolsL . to (mapWithKey stakePoolStateToPoolParams)
707+
{-# DEPRECATED epochStatePoolParamsG "In favor of `epochStateStakePoolsL`" #-}
706708

707709
epochStateStakeDistrL ::
708710
Lens' (EpochState era) (VMap VB VP (Credential 'Staking) (CompactForm Coin))

eras/shelley/impl/src/Cardano/Ledger/Shelley/Rules/Pool.hs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -233,28 +233,27 @@ poolDelegationTransition = do
233233
, mismatchExpected = minPoolCost
234234
}
235235

236-
if not (Map.member ppId psStakePools)
237-
then do
238-
-- register new, Pool-Reg
236+
case Map.lookup ppId psStakePools of
237+
Nothing -> do
239238
tellEvent $ RegisterPool ppId
240-
pure $
241-
payPoolDeposit ppId pp $
242-
ps & psStakePoolsL %~ Map.insert ppId (mkStakePoolState poolParams)
243-
else do
239+
pure $ ps & psStakePoolsL %~ Map.insert ppId (mkStakePoolState (pp ^. ppPoolDepositCompactL) poolParams)
240+
Just sps -> do
244241
tellEvent $ ReregisterPool ppId
245-
-- hk is already registered, so we want to reregister it. That means adding it
246-
-- to the Future pool params (if it is not there already), and overriding the
247-
-- range with the new 'poolParam', if it is (using ⨃ ). We must also unretire
248-
-- it, if it has been scheduled for retirement. The deposit does not
249-
-- change. One pays the deposit just once. Only if it is fully retired
250-
-- (i.e. it's deposit has been refunded, and it has been removed from the
251-
-- registered pools). does it need to pay a new deposit (at the current deposit
252-
-- amount). But of course, if that has happened, we cannot be in this branch of
253-
-- the if statement.
254-
pure $
255-
ps
256-
& psFutureStakePoolsL %~ Map.insert ppId (mkStakePoolState poolParams)
257-
& psRetiringL %~ Map.delete ppId
242+
-- NOTE: The `ppId` is already registered, so we want to reregister
243+
-- it. That means adding it to the Future Stake Pools (if it is not
244+
-- there already), and overriding its range with the new 'poolParams',
245+
-- if it is.
246+
--
247+
-- We must also unretire it, if it has been scheduled for retirement.
248+
--
249+
-- The deposit does not change. One pays the deposit just once. Only
250+
-- if it is fully retired (i.e. it's deposit has been refunded, and it
251+
-- has been removed from the registered pools). does it need to pay a
252+
-- new deposit (at the current deposit amount). But of course, if that
253+
-- has happened, we cannot be in this branch of the case statement.
254+
pure $ ps
255+
& psFutureStakePoolsL %~ Map.insert ppId (mkStakePoolState (sps ^. spsDepositL) poolParams)
256+
& psRetiringL %~ Map.delete ppId
258257
RetirePool ppId e -> do
259258
Map.member ppId psStakePools ?! StakePoolNotRegisteredOnKeyPOOL ppId
260259
let maxEpoch = pp ^. ppEMaxL

eras/shelley/impl/src/Cardano/Ledger/Shelley/Rules/PoolReap.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ poolReapTransition = do
143143
-- The Map of pools (retiring this epoch) to their deposits
144144
retiringDeposits, remainingDeposits :: Map.Map (KeyHash 'StakePool) (CompactForm Coin)
145145
(retiringDeposits, remainingDeposits) =
146-
Map.partitionWithKey (\k _ -> Set.member k retired) (psDeposits ps)
146+
Map.partitionWithKey (\k _ -> Set.member k retired) (spsDeposit <$> psStakePools ps)
147147
-- collect all accounts for stake pools that will retire
148148
retiredStakePoolAccounts :: Map.Map (KeyHash 'StakePool) RewardAccount
149149
retiredStakePoolAccounts = Map.map spsRewardAccount $ Map.restrictKeys (psStakePools ps) retired

eras/shelley/impl/src/Cardano/Ledger/Shelley/Transition.hs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,18 @@ createInitialState tc =
385385
reserves :: Coin
386386
reserves = word64ToCoin (sgMaxLovelaceSupply sg) <-> sumCoinUTxO initialUtxo
387387

388+
-- | From the haddock for `ShelleyGenesisStaking`:
389+
--
390+
-- > `ShelleyGenesisStaking` allows us to configure some initial stake pools and
391+
-- > delegation to them, in order to test Praos in a static configuration, without
392+
-- > requiring on-chain registration and delegation.
393+
--
394+
-- > For simplicity, pools defined in the genesis staking DO NOT PAY DEPOSITS FOR
395+
-- > THEIR REGISTRATION
396+
--
397+
-- Therefore, we use `mempty` in the convertion below.
398+
--
399+
-- QUESTION: @aniketd: Is the assumption that we can use mempty truly harmless?
388400
registerInitialStakePools ::
389401
forall era.
390402
EraCertState era =>
@@ -394,7 +406,7 @@ registerInitialStakePools ::
394406
registerInitialStakePools ShelleyGenesisStaking {sgsPools} nes =
395407
nes
396408
& nesEsL . esLStateL . lsCertStateL . certPStateL . psStakePoolsL
397-
.~ (mkStakePoolState <$> ListMap.toMap sgsPools)
409+
.~ (mkStakePoolState mempty <$> ListMap.toMap sgsPools)
398410

399411
-- | Register all staking credentials and apply delegations. Make sure StakePools that are bing
400412
-- delegated to are already registered, which can be done with `registerInitialStakePools`.

eras/shelley/impl/testlib/Test/Cardano/Ledger/Shelley/UnitTests/InstantStakeTest.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ instantStakeIncludesRewards = do
8585

8686
instantStake = addInstantStake utxo1 mempty
8787
poolparamMap = Map.fromList [(poolId1, pool1), (poolId2, pool2)]
88-
pState <- arbitraryLens psStakePoolsL $ mkStakePoolState <$> poolparamMap
88+
pState <- arbitraryLens psStakePoolsL $ mkStakePoolState mempty <$> poolparamMap
8989
let snapShot = snapShotFromInstantStake instantStake dState pState
9090
computedStakeDistr = VMap.toMap (unStake (ssStake snapShot))
9191

libs/cardano-ledger-core/src/Cardano/Ledger/State/CertState.hs

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,21 @@ import Cardano.Ledger.DRep (DRep (..), DRepState (..))
7878
import Cardano.Ledger.Hashes (GenDelegPair (..), GenDelegs (..))
7979
import Cardano.Ledger.Slot (EpochNo (..), SlotNo (..))
8080
import Cardano.Ledger.State.Account
81-
import Cardano.Ledger.State.StakePool (StakePoolState)
81+
import Cardano.Ledger.State.StakePool (StakePoolState (..), spsDepositL)
8282
import Control.DeepSeq (NFData (..))
8383
import Control.Monad.Trans
8484
import Data.Aeson (ToJSON (..), object, (.=))
8585
import Data.Default (Default (def))
8686
import qualified Data.Foldable as F
8787
import Data.Kind (Type)
88+
import qualified Data.Map.Merge.Strict as Map
8889
import Data.Map.Strict (Map)
8990
import qualified Data.Map.Strict as Map
9091
import qualified Data.Set as Set
9192
import GHC.Generics (Generic)
92-
import Lens.Micro (Lens', lens, (^.), _1)
93+
import Lens.Micro
9394
import NoThunks.Class (NoThunks (..))
9495

95-
-- ======================================
96-
9796
data FutureGenDeleg = FutureGenDeleg
9897
{ fGenDelegSlot :: !SlotNo
9998
, fGenDelegGenKeyHash :: !(KeyHash 'Genesis)
@@ -235,8 +234,6 @@ data PState era = PState
235234
-- of the Shelley Ledger Specification for a sequence diagram.
236235
, psRetiring :: !(Map (KeyHash 'StakePool) EpochNo)
237236
-- ^ A map of retiring stake pools to the epoch when they retire.
238-
, psDeposits :: !(Map (KeyHash 'StakePool) (CompactForm Coin))
239-
-- ^ A map of the deposits for each pool
240237
}
241238
deriving (Show, Eq, Generic)
242239
deriving (ToJSON) via KeyValuePairs (PState era)
@@ -246,17 +243,16 @@ instance NoThunks (PState era)
246243
instance NFData (PState era)
247244

248245
instance Era era => EncCBOR (PState era) where
249-
encCBOR (PState a b c d) =
250-
encodeListLen 4 <> encCBOR a <> encCBOR b <> encCBOR c <> encCBOR d
246+
encCBOR (PState a b c) =
247+
encodeListLen 3 <> encCBOR a <> encCBOR b <> encCBOR c
251248

252249
instance DecShareCBOR (PState era) where
253250
type Share (PState era) = Interns (KeyHash 'StakePool)
254251
decSharePlusCBOR = decodeRecordNamedT "PState" (const 4) $ do
255252
psStakePools <- decSharePlusLensCBOR (toMemptyLens _1 id)
256253
psFutureStakePools <- decSharePlusLensCBOR (toMemptyLens _1 id)
257254
psRetiring <- decSharePlusLensCBOR (toMemptyLens _1 id)
258-
psDeposits <- decSharePlusLensCBOR (toMemptyLens _1 id)
259-
pure PState {psStakePools, psFutureStakePools, psRetiring, psDeposits}
255+
pure PState {psStakePools, psFutureStakePools, psRetiring}
260256

261257
instance (Era era, DecShareCBOR (PState era)) => DecCBOR (PState era) where
262258
decCBOR = decNoShareCBOR
@@ -266,7 +262,6 @@ instance ToKeyValuePairs (PState era) where
266262
[ "stakePools" .= psStakePools
267263
, "futureStakePools" .= psFutureStakePools
268264
, "retiring" .= psRetiring
269-
, "deposits" .= psDeposits
270265
]
271266

272267
data CommitteeAuthorization
@@ -396,35 +391,27 @@ instance Default (Accounts era) => Default (DState era) where
396391

397392
instance Default (PState era) where
398393
def =
399-
PState Map.empty Map.empty Map.empty Map.empty
400-
401-
-- ==========================================================
402-
-- Functions that handle Deposits
403-
404-
-- | One only pays a deposit on the initial pool registration. So return the
405-
-- the Deposits unchanged if the keyhash already exists. There are legal
406-
-- situations where a pool may be registered multiple times.
407-
payPoolDeposit ::
408-
EraPParams era =>
409-
KeyHash 'StakePool ->
410-
PParams era ->
411-
PState era ->
412-
PState era
413-
payPoolDeposit keyhash pp pstate = pstate {psDeposits = newpool}
394+
PState Map.empty Map.empty Map.empty
395+
396+
-- | One only pays a deposit on the initial pool registration. So we return the
397+
-- StakePoolState unchanged if the deposit is already non-zero.
398+
--
399+
-- NOTE: There are legal situations where a pool may be registered multiple times.
400+
payPoolDeposit :: EraPParams era => KeyHash 'StakePool -> PParams era -> PState era -> PState era
401+
payPoolDeposit keyhash pp pstate = pstate & psStakePoolsL %~ Map.adjust payDeposit keyhash
414402
where
415-
pool = psDeposits pstate
416403
!deposit = pp ^. ppPoolDepositCompactL
417-
newpool
418-
| Map.notMember keyhash pool = Map.insert keyhash deposit pool
419-
| otherwise = pool
404+
payDeposit sps
405+
| sps ^. spsDepositL <= mempty = sps & spsDepositL .~ deposit
406+
| otherwise = sps
420407

421408
refundPoolDeposit :: KeyHash 'StakePool -> PState era -> (CompactForm Coin, PState era)
422-
refundPoolDeposit keyhash pstate = (coin, pstate {psDeposits = newpool})
423-
where
424-
pool = psDeposits pstate
425-
(coin, newpool) = case Map.lookup keyhash pool of
426-
Just c -> (c, Map.delete keyhash pool)
427-
Nothing -> (mempty, pool)
409+
refundPoolDeposit keyhash pstate =
410+
( -- The actual deposit or mempty
411+
maybe mempty spsDeposit $ Map.lookup keyhash $ pstate ^. psStakePoolsL
412+
, -- The PState, updated with the deposit set to mempty
413+
pstate & psStakePoolsL %~ Map.adjust (spsDepositL .~ mempty) keyhash
414+
)
428415

429416
-- | A composite of all the Deposits the system is obligated to eventually pay back.
430417
data Obligations = Obligations
@@ -462,12 +449,6 @@ instance Show Obligations where
462449
, " Proposal deposits = " ++ show (oblProposal x)
463450
]
464451

465-
-- =======================================================
466-
-- Lenses for CertState and its subsidiary types
467-
468-
-- ===================================
469-
-- DState
470-
471452
dsGenDelegsL :: Lens' (DState era) GenDelegs
472453
dsGenDelegsL = lens dsGenDelegs (\ds u -> ds {dsGenDelegs = u})
473454

@@ -478,9 +459,6 @@ dsFutureGenDelegsL ::
478459
Lens' (DState era) (Map FutureGenDeleg GenDelegPair)
479460
dsFutureGenDelegsL = lens dsFutureGenDelegs (\ds u -> ds {dsFutureGenDelegs = u})
480461

481-
-- ===================================
482-
-- PState
483-
484462
psStakePoolsL :: Lens' (PState era) (Map (KeyHash 'StakePool) StakePoolState)
485463
psStakePoolsL = lens psStakePools (\ds u -> ds {psStakePools = u})
486464

@@ -494,4 +472,15 @@ psDepositsL :: Lens' (PState era) (Map (KeyHash 'StakePool) Coin)
494472
psDepositsL = psDepositsCompactL . lens (fmap fromCompact) (\_ -> fmap compactCoinOrError)
495473

496474
psDepositsCompactL :: Lens' (PState era) (Map (KeyHash 'StakePool) (CompactForm Coin))
497-
psDepositsCompactL = lens psDeposits (\ds u -> ds {psDeposits = u})
475+
psDepositsCompactL =
476+
lens
477+
(fmap spsDeposit . psStakePools)
478+
( \pstate deposits ->
479+
pstate
480+
& psStakePoolsL
481+
%~ Map.merge
482+
Map.dropMissing
483+
Map.preserveMissing
484+
(Map.zipWithMatched (\_key deposit sps -> sps {spsDeposit = deposit}))
485+
deposits
486+
)

0 commit comments

Comments
 (0)