Skip to content

Commit a22a053

Browse files
committed
Refactor VState update logic to handle dRep undelegation/redelegation
1 parent d5e453f commit a22a053

File tree

3 files changed

+50
-30
lines changed

3 files changed

+50
-30
lines changed

eras/conway/impl/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 1.21.0.0
44

5+
* Add `unDelegReDelegDRep` to `VState` module
56
* Expose `conwayRegisterInitialAccounts`
67
* Add `shelleyToConwayLedgerPredFailure`.
78
* Move withdrawal-validation and DRep expiry updates from `CERTS` to `LEDGER` starting protocol version 11.

eras/conway/impl/src/Cardano/Ledger/Conway/Rules/Deleg.hs

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ conwayDelegTransition = do
231231
%~ registerConwayAccount stakeCred ppKeyDepositCompact Nothing
232232
ConwayUnRegCert stakeCred sMayRefund -> do
233233
let (mAccountState, newAccounts) = unregisterConwayAccount stakeCred accounts
234-
mCurDelegatee = mAccountState >>= accountStateDelegatee
235234
checkInvalidRefund = do
236235
SJust suppliedRefund <- Just sMayRefund
237236
-- we don't want to report invalid refund when stake credential is not registered:
@@ -264,7 +263,7 @@ conwayDelegTransition = do
264263
pure $
265264
certState
266265
& certDStateL . accountsL .~ newAccounts
267-
& certVStateL %~ unDelegDRep stakeCred mCurDelegatee
266+
& certVStateL %~ unDelegReDelegDRep stakeCred accountState Nothing
268267
& certPStateL %~ unDelegReDelegStakePool stakeCred accountState Nothing
269268
ConwayDelegCert stakeCred delegatee -> do
270269
mAccountState <- checkStakeKeyIsRegistered stakeCred
@@ -316,7 +315,6 @@ processDelegationInternal preserveIncorrectDelegation stakeCred mAccountState ne
316315
DelegVote dRep -> delegVote dRep
317316
DelegStakeVote sPool dRep -> delegVote dRep . delegStake sPool
318317
where
319-
mCurDelegatee = mAccountState >>= accountStateDelegatee
320318
delegStake stakePool cState =
321319
cState
322320
& certDStateL . accountsL
@@ -330,29 +328,17 @@ processDelegationInternal preserveIncorrectDelegation stakeCred mAccountState ne
330328
cState
331329
& certDStateL . accountsL
332330
%~ adjustAccountState (dRepDelegationAccountStateL ?~ dRep) stakeCred
333-
& certVStateL %~ unDelegDRep stakeCred mCurDelegatee
334-
dReps
335-
| preserveIncorrectDelegation = cState ^. certVStateL . vsDRepsL
336-
| otherwise = cState' ^. certVStateL . vsDRepsL
337-
in case dRep of
338-
DRepCredential targetDRep
339-
| Just dRepState <- Map.lookup targetDRep dReps ->
340-
let dRepState' = dRepState {drepDelegs = Set.insert stakeCred (drepDelegs dRepState)}
341-
in cState' & certVStateL . vsDRepsL .~ Map.insert targetDRep dRepState' dReps
342-
_ -> cState'
343-
344-
unDelegDRep ::
345-
Credential 'Staking ->
346-
Maybe Delegatee ->
347-
VState era ->
348-
VState era
349-
unDelegDRep stakeCred mCurDelegatee =
350-
maybe
351-
id
352-
(\dRepCred -> vsDRepsL %~ Map.adjust (drepDelegsL %~ Set.delete stakeCred) dRepCred)
353-
(mCurDelegatee >>= drepToUndeleg)
354-
where
355-
drepToUndeleg = \case
356-
DelegVote (DRepCredential dRepCred) -> Just dRepCred
357-
DelegStakeVote _ (DRepCredential dRepCred) -> Just dRepCred
358-
_ -> Nothing
331+
& maybe
332+
(certVStateL %~ insertDRepDeleg dRep)
333+
(\accountState -> certVStateL %~ unDelegReDelegDRep stakeCred accountState (Just dRep))
334+
mAccountState
335+
in if preserveIncorrectDelegation
336+
then
337+
cState
338+
& certDStateL . accountsL %~ adjustAccountState (dRepDelegationAccountStateL ?~ dRep) stakeCred
339+
& certVStateL %~ insertDRepDeleg dRep
340+
else cState'
341+
insertDRepDeleg dRep = case dRep of
342+
DRepCredential dRepCred ->
343+
vsDRepsL %~ Map.adjust (drepDelegsL %~ Set.insert stakeCred) dRepCred
344+
_ -> id

eras/conway/impl/src/Cardano/Ledger/Conway/State/VState.hs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Cardano.Ledger.Conway.State.VState (
1717
vsNumDormantEpochsL,
1818
vsActualDRepExpiry,
1919
lookupDepositVState,
20+
unDelegReDelegDRep,
2021
) where
2122

2223
import Cardano.Ledger.BaseTypes (KeyValuePairs (..), ToKeyValuePairs (..), binOpEpochNo)
@@ -33,17 +34,21 @@ import Cardano.Ledger.Binary (
3334
import Cardano.Ledger.Binary.Coders (Decode (..), Encode (..), decode, encode, (!>), (<!))
3435
import Cardano.Ledger.Coin (Coin (..))
3536
import Cardano.Ledger.Compactible (Compactible (..))
37+
import Cardano.Ledger.Conway.State.Account
3638
import Cardano.Ledger.Core
3739
import Cardano.Ledger.Credential (Credential (..))
40+
import Cardano.Ledger.DRep (drepDelegsL)
3841
import Cardano.Ledger.Shelley.State
3942
import Cardano.Ledger.Slot (EpochNo (..))
4043
import Control.DeepSeq (NFData (..))
4144
import Data.Aeson (ToJSON (..), (.=))
4245
import Data.Default (Default (def))
4346
import Data.Map.Strict (Map)
4447
import qualified Data.Map.Strict as Map
48+
import Data.Maybe (fromMaybe)
49+
import qualified Data.Set as Set
4550
import GHC.Generics (Generic)
46-
import Lens.Micro (Lens', lens, (^.))
51+
import Lens.Micro
4752
import NoThunks.Class (NoThunks (..))
4853

4954
-- | The state that tracks the voting entities (DReps and Constitutional Committee
@@ -109,6 +114,34 @@ instance ToKeyValuePairs (VState era) where
109114
, "numDormantEpochs" .= vsNumDormantEpochs
110115
]
111116

117+
-- | Reverses DRep delegation.
118+
-- To be called when a stake credential is unregistered or its delegation target changes.
119+
-- If the new delegation matches the previous one, this is a noop.
120+
unDelegReDelegDRep ::
121+
ConwayEraAccounts era =>
122+
Credential 'Staking ->
123+
-- | Account that is losing its current delegation and/or acquiring a new one
124+
AccountState era ->
125+
-- | Potential new delegation. In case when stake credential unregisters this must be `Nothing`.
126+
Maybe DRep ->
127+
VState era ->
128+
VState era
129+
unDelegReDelegDRep stakeCred accountState mNewDRep =
130+
fromMaybe (vsDRepsL %~ addNewDelegation) $ do
131+
dRep@(DRepCredential dRepCred) <- accountState ^. dRepDelegationAccountStateL
132+
pure $
133+
-- There is no need to update set of delegations if delegation is unchanged
134+
if Just dRep == mNewDRep
135+
then id
136+
else
137+
vsDRepsL %~ addNewDelegation . Map.adjust (drepDelegsL %~ Set.delete stakeCred) dRepCred
138+
where
139+
addNewDelegation =
140+
case mNewDRep of
141+
Just (DRepCredential dRepCred) ->
142+
Map.adjust (drepDelegsL %~ Set.insert stakeCred) dRepCred
143+
_ -> id
144+
112145
vsDRepsL :: Lens' (VState era) (Map (Credential 'DRepRole) DRepState)
113146
vsDRepsL = lens vsDReps (\vs u -> vs {vsDReps = u})
114147

0 commit comments

Comments
 (0)