Skip to content

Commit f464032

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

File tree

3 files changed

+46
-34
lines changed

3 files changed

+46
-34
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 `TxLevel` argument to `Tx` and `TxBody`
78
* Add `HasEraTxLevel` instances for `Tx` and `TxBody`

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

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,6 @@ conwayDelegTransition = do
227227
%~ registerConwayAccount stakeCred ppKeyDepositCompact Nothing
228228
ConwayUnRegCert stakeCred sMayRefund -> do
229229
let (mAccountState, newAccounts) = unregisterConwayAccount stakeCred accounts
230-
mCurDelegatee = mAccountState >>= accountStateDelegatee
231230
checkInvalidRefund = do
232231
SJust suppliedRefund <- Just sMayRefund
233232
-- we don't want to report invalid refund when stake credential is not registered:
@@ -259,7 +258,7 @@ conwayDelegTransition = do
259258
pure $
260259
certState
261260
& certDStateL . accountsL .~ newAccounts
262-
& certVStateL %~ unDelegDRep stakeCred mCurDelegatee
261+
& certVStateL %~ unDelegReDelegDRep stakeCred accountState Nothing
263262
& certPStateL %~ unDelegReDelegStakePool stakeCred accountState Nothing
264263
ConwayDelegCert stakeCred delegatee -> do
265264
let mAccountState = lookupAccountState stakeCred accounts
@@ -312,7 +311,6 @@ processDelegationInternal preserveIncorrectDelegation stakeCred mAccountState ne
312311
DelegVote dRep -> delegVote dRep
313312
DelegStakeVote sPool dRep -> delegVote dRep . delegStake sPool
314313
where
315-
mCurDelegatee = mAccountState >>= accountStateDelegatee
316314
delegStake stakePool cState =
317315
cState
318316
& certDStateL . accountsL
@@ -322,33 +320,13 @@ processDelegationInternal preserveIncorrectDelegation stakeCred mAccountState ne
322320
(\accountState -> certPStateL %~ unDelegReDelegStakePool stakeCred accountState (Just stakePool))
323321
mAccountState
324322
delegVote dRep cState =
325-
let cState' =
326-
cState
327-
& certDStateL . accountsL
328-
%~ adjustAccountState (dRepDelegationAccountStateL ?~ dRep) stakeCred
329-
& certVStateL %~ unDelegDRep stakeCred mCurDelegatee
330-
dReps
331-
| preserveIncorrectDelegation = cState ^. certVStateL . vsDRepsL
332-
| otherwise = cState' ^. certVStateL . vsDRepsL
333-
in case dRep of
334-
DRepCredential targetDRep
335-
| Just dRepState <- Map.lookup targetDRep dReps ->
336-
let dRepState' = dRepState {drepDelegs = Set.insert stakeCred (drepDelegs dRepState)}
337-
in cState' & certVStateL . vsDRepsL .~ Map.insert targetDRep dRepState' dReps
338-
_ -> cState'
339-
340-
unDelegDRep ::
341-
Credential 'Staking ->
342-
Maybe Delegatee ->
343-
VState era ->
344-
VState era
345-
unDelegDRep stakeCred mCurDelegatee =
346-
maybe
347-
id
348-
(\dRepCred -> vsDRepsL %~ Map.adjust (drepDelegsL %~ Set.delete stakeCred) dRepCred)
349-
(mCurDelegatee >>= drepToUndeleg)
350-
where
351-
drepToUndeleg = \case
352-
DelegVote (DRepCredential dRepCred) -> Just dRepCred
353-
DelegStakeVote _ (DRepCredential dRepCred) -> Just dRepCred
354-
_ -> Nothing
323+
cState
324+
& certDStateL . accountsL %~ adjustAccountState (dRepDelegationAccountStateL ?~ dRep) stakeCred
325+
& maybe
326+
(certVStateL %~ insertDRepDeleg dRep)
327+
(\accountState -> certVStateL %~ unDelegReDelegDRep stakeCred accountState (Just dRep))
328+
(guard (not preserveIncorrectDelegation) >> mAccountState)
329+
insertDRepDeleg dRep = case dRep of
330+
DRepCredential dRepCred ->
331+
vsDRepsL %~ Map.adjust (drepDelegsL %~ Set.insert stakeCred) dRepCred
332+
_ -> 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)