Skip to content

Commit 1be9add

Browse files
committed
Move pool deposits into StakePoolState
1 parent d157bd5 commit 1be9add

File tree

11 files changed

+131
-71
lines changed

11 files changed

+131
-71
lines changed

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

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

4444
-- * DelegationState
45-
payPoolDeposit,
46-
refundPoolDeposit,
45+
46+
-- payPoolDeposit,
47+
-- refundPoolDeposit,
4748
totalObligation,
4849
allObligations,
4950

@@ -102,7 +103,7 @@ module Cardano.Ledger.Shelley.LedgerState (
102103
utxosDonationL,
103104
epochStateGovStateL,
104105
epochStateStakeDistrL,
105-
epochStatePoolParamsL,
106+
epochStatePoolParamsG,
106107
epochStateStakePoolsL,
107108
epochStateDonationL,
108109
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/Epoch.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ epochTransition = do
212212
ss' <-
213213
trans @(EraRule "SNAP" era) $ TRC (SnapEnv ls pp, ss, ())
214214

215-
let PState stakePools futureStakePools _ _ = pstate
215+
let PState stakePools futureStakePools _ = pstate
216216
ppp = eval (stakePools futureStakePools)
217217
pstate' =
218218
pstate

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

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,15 @@ import Cardano.Ledger.Shelley.Era (
5050
ShelleyPOOL,
5151
hardforkAlonzoValidatePoolRewardAccountNetID,
5252
)
53-
import Cardano.Ledger.Shelley.LedgerState (PState (..), payPoolDeposit)
5453
import qualified Cardano.Ledger.Shelley.SoftForks as SoftForks
55-
import Cardano.Ledger.State (PoolMetadata (..), PoolParams (..), mkStakePoolState)
54+
import Cardano.Ledger.State (
55+
PState (..),
56+
PoolMetadata (..),
57+
PoolParams (..),
58+
StakePoolState (..),
59+
mkStakePoolState,
60+
psStakePoolsL,
61+
)
5662
import Control.DeepSeq
5763
import Control.Monad (forM_, when)
5864
import Control.Monad.Trans.Reader (asks)
@@ -68,9 +74,10 @@ import Control.State.Transition (
6874
)
6975
import qualified Data.ByteString as BS
7076
import Data.Kind (Type)
77+
import Data.Map.Strict ((!))
7178
import Data.Word (Word8)
7279
import GHC.Generics (Generic)
73-
import Lens.Micro ((^.))
80+
import Lens.Micro ((%~), (&), (^.))
7481
import NoThunks.Class (NoThunks (..))
7582

7683
data PoolEnv era
@@ -239,8 +246,9 @@ poolDelegationTransition = do
239246
-- register new, Pool-Reg
240247
tellEvent $ RegisterPool ppId
241248
pure $
242-
payPoolDeposit ppId pp $
243-
ps {psStakePools = eval (psStakePools singleton ppId (mkStakePoolState poolParams))}
249+
ps
250+
& psStakePoolsL %~ \stakePools ->
251+
eval (stakePools singleton ppId (mkStakePoolState (pp ^. ppPoolDepositCompactL) poolParams))
244252
else do
245253
tellEvent $ ReregisterPool ppId
246254
-- hk is already registered, so we want to reregister it. That means adding it
@@ -251,11 +259,12 @@ poolDelegationTransition = do
251259
-- (i.e. it's deposit has been refunded, and it has been removed from the
252260
-- registered pools). does it need to pay a new deposit (at the current deposit
253261
-- amount). But of course, if that has happened, we cannot be in this branch of
254-
-- the if statement.
262+
-- the if statement. And so the use of (!) is also justified here.
263+
let existingDeposit = spsDeposit $ psStakePools ! ppId
255264
pure $
256265
ps
257266
{ psFutureStakePools =
258-
eval (psFutureStakePools singleton ppId (mkStakePoolState poolParams))
267+
eval (psFutureStakePools singleton ppId (mkStakePoolState existingDeposit poolParams))
259268
, psRetiring = eval (setSingleton ppId psRetiring)
260269
}
261270
RetirePool hk e -> do

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

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

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

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

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

400412
-- | Register all staking credentials and apply delegations. Make sure StakePools that are bing
401413
-- 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)