Skip to content

Commit a75026f

Browse files
committed
Set delegators of updated pools in PoolReap rule
in order not to lose the delegations that happened after the update, before the end of the epoch
1 parent 3d357bd commit a75026f

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ poolDelegationTransition = do
277277
Nothing -> Map.insert ppVrf (knownNonZeroBounded @1)
278278
Just futureStakePoolState
279279
| futureStakePoolState ^. spsVrfL /= ppVrf ->
280-
(Map.insert ppVrf (knownNonZeroBounded @1))
280+
Map.insert ppVrf (knownNonZeroBounded @1)
281281
. Map.delete (futureStakePoolState ^. spsVrfL)
282282
| otherwise -> id
283283
| otherwise = id
@@ -297,7 +297,9 @@ poolDelegationTransition = do
297297
let futureStakePoolState =
298298
mkStakePoolState
299299
(stakePoolState ^. spsDepositL)
300-
(stakePoolState ^. spsDelegatorsL)
300+
-- delegators are set in PoolReap,
301+
-- in order to capture delegations that happened after re-registration but before the end of the epoch
302+
mempty
301303
poolParams
302304
pure $
303305
ps

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ poolReapTransition = do
152152
-- activate future stakePools
153153
ps =
154154
ps0
155-
{ psStakePools = Map.union (ps0 ^. psFutureStakePoolsL) (ps0 ^. psStakePoolsL)
155+
{ psStakePools =
156+
Map.unionWith
157+
(\newPoolState oldPoolState -> newPoolState {spsDelegators = spsDelegators oldPoolState})
158+
(ps0 ^. psFutureStakePoolsL)
159+
(ps0 ^. psStakePoolsL)
156160
, psFutureStakePools = Map.empty
157161
}
158162
cs = cs0 & certPStateL .~ ps
@@ -226,7 +230,6 @@ poolReapTransition = do
226230
removeVRFKeyHashOccurrence =
227231
-- Removes the key from the map if the value drops to 0
228232
Map.update (mapNonZero (\n -> n - 1))
229-
230233
delegsToClear cState pools =
231234
foldMap spsDelegators $
232235
Map.restrictKeys (cState ^. certPStateL . psStakePoolsL) pools

eras/shelley/impl/testlib/Test/Cardano/Ledger/Shelley/Imp/PoolSpec.hs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import Cardano.Ledger.Credential (Credential (..))
1616
import Cardano.Ledger.Shelley.LedgerState
1717
import Cardano.Ledger.Shelley.Rules (ShelleyPoolPredFailure (..))
1818
import Cardano.Ledger.State
19-
import qualified Data.Map.Strict as Map
19+
import Data.Map.Strict as Map
2020
import Data.Proxy
2121
import Lens.Micro
2222
import Test.Cardano.Ledger.Binary.Arbitrary (genByteString)
@@ -52,6 +52,7 @@ spec = describe "POOL" $ do
5252
submitTx_ tx
5353
else
5454
submitFailingTx tx [injectFailure $ WrongNetworkPOOL (Mismatch Mainnet Testnet) kh]
55+
5556
it "register a pool with too big metadata" $ do
5657
pv <- getsPParams ppProtocolVersionL
5758
let maxMetadataSize = sizeHash (Proxy :: Proxy HASH)
@@ -82,6 +83,39 @@ spec = describe "POOL" $ do
8283
expectPool khNew Nothing
8384
expectPool kh (Just vrf)
8485

86+
it "re-register a pool and change its delegations in the same epoch" $ do
87+
(poolKh, _) <- registerNewPool
88+
(poolKh2, _) <- registerNewPool
89+
stakeCred <- KeyHashObj <$> freshKeyHash
90+
_ <- registerStakeCredential stakeCred
91+
stakeCred2 <- KeyHashObj <$> freshKeyHash
92+
_ <- registerStakeCredential stakeCred2
93+
delegateStake stakeCred poolKh
94+
vrf1 <- freshKeyHashVRF
95+
registerPoolTx <$> poolParams poolKh vrf1 >>= \tx -> do
96+
submitTx_ tx
97+
expectPoolDelegs poolKh (Just [stakeCred])
98+
delegateStake stakeCred2 poolKh
99+
expectPoolDelegs poolKh (Just [stakeCred, stakeCred2])
100+
passEpoch
101+
expectPoolDelegs poolKh (Just [stakeCred, stakeCred2])
102+
103+
vrf2 <- freshKeyHashVRF
104+
registerPoolTx <$> poolParams poolKh vrf2 >>= \tx -> do
105+
submitTx_ tx
106+
expectPoolDelegs poolKh (Just [stakeCred, stakeCred2])
107+
108+
unRegTxCert <- genUnRegTxCert stakeCred2
109+
submitTx_ $
110+
mkBasicTx mkBasicTxBody
111+
& bodyTxL . certsTxBodyL
112+
.~ [unRegTxCert]
113+
expectPoolDelegs poolKh (Just [stakeCred])
114+
delegateStake stakeCred poolKh2
115+
expectPoolDelegs poolKh (Just [])
116+
passEpoch
117+
expectPoolDelegs poolKh (Just [])
118+
85119
it "re-register a pool with an already registered VRF" $ do
86120
pv <- getsPParams ppProtocolVersionL
87121
(kh1, vrf1) <- registerNewPool
@@ -287,6 +321,27 @@ spec = describe "POOL" $ do
287321
expectRetiring False khNew
288322
expectPool kh Nothing
289323

324+
it "retiring a pool clears its delegations" $ do
325+
(poolKh, _) <- registerNewPool
326+
let retirement = 1
327+
stakeCred1 <- do
328+
cred <- KeyHashObj <$> freshKeyHash
329+
_ <- registerStakeCredential cred
330+
delegateStake cred poolKh
331+
pure cred
332+
333+
retirePoolTx poolKh (EpochInterval retirement) >>= submitTx_
334+
expectPoolDelegs poolKh (Just [stakeCred1])
335+
stakeCred2 <- do
336+
cred <- KeyHashObj <$> freshKeyHash
337+
_ <- registerStakeCredential cred
338+
delegateStake cred poolKh
339+
pure cred
340+
expectPoolDelegs poolKh (Just [stakeCred1, stakeCred2])
341+
342+
passNEpochs (fromIntegral retirement)
343+
expectPoolDelegs poolKh Nothing
344+
290345
describe "Retired pools" $ do
291346
it "re-register a pool with the same keyhash and VRF " $ do
292347
(kh, vrf) <- registerNewPool
@@ -331,6 +386,9 @@ spec = describe "POOL" $ do
331386
expectFuturePool poolKh mbVrf = do
332387
fps <- psFutureStakePools <$> getPState
333388
spsVrf <$> Map.lookup poolKh fps `shouldBe` mbVrf
389+
expectPoolDelegs poolKh delegs = do
390+
pps <- psStakePools <$> getPState
391+
spsDelegators <$> Map.lookup poolKh pps `shouldBe` delegs
334392
expectRetiring isRetiring poolKh = do
335393
retiring <- psRetiring <$> getPState
336394
assertBool

0 commit comments

Comments
 (0)