Skip to content

Commit 693218d

Browse files
authored
Merge pull request #5176 from rrruko/rrruko/add-query-drep-delegation-state
add `queryDRepDelegationState` state query
2 parents 38c7814 + e262c58 commit 693218d

File tree

5 files changed

+83
-1
lines changed

5 files changed

+83
-1
lines changed

libs/cardano-ledger-api/CHANGELOG.md

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

33
## 1.12.0.0
44

5+
* Add `queryDRepDelegations` state query
56
* Remove `filterStakePoolDelegsAndRewards` as unnecessary. Use `queryStakePoolDelegsAndRewards` instead
67
* Expose `binaryUpgradeTx`, `binaryUpgradeTxBody`, `binaryUpgradeTxWits`, `binaryUpgradeTxAuxData`, `upgradeTx`, `upgradeTxBody`, `upgradeTxWits`, `upgradeTxAuxData`
78
* Add `EraApi` class

libs/cardano-ledger-api/src/Cardano/Ledger/Api/State/Query.hs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE DataKinds #-}
22
{-# LANGUAGE GADTs #-}
3+
{-# LANGUAGE OverloadedStrings #-}
34
{-# LANGUAGE RecordWildCards #-}
45
{-# LANGUAGE ScopedTypeVariables #-}
56

@@ -19,6 +20,9 @@ module Cardano.Ledger.Api.State.Query (
1920
-- * @GetDRepState@
2021
queryDRepState,
2122

23+
-- * @GetDRepDelegations@
24+
queryDRepDelegations,
25+
2226
-- * @GetDRepStakeDistr@
2327
queryDRepStakeDistr,
2428

@@ -96,7 +100,8 @@ import Cardano.Ledger.Conway.Governance (
96100
import Cardano.Ledger.Conway.Rules (updateDormantDRepExpiry)
97101
import Cardano.Ledger.Conway.State
98102
import Cardano.Ledger.Core
99-
import Cardano.Ledger.Credential (Credential)
103+
import Cardano.Ledger.Credential (Credential (..))
104+
import Cardano.Ledger.DRep (credToDRep, dRepToCred)
100105
import Cardano.Ledger.Shelley.LedgerState
101106
import Control.Monad (guard)
102107
import Data.Foldable (foldMap')
@@ -156,6 +161,45 @@ queryDRepState nes creds
156161
vState = nes ^. nesEsL . esLStateL . lsCertStateL . certVStateL
157162
updateDormantDRepExpiry' = updateDormantDRepExpiry (nes ^. nesELL)
158163

164+
-- | Query the delegators delegated to each DRep, including
165+
-- @AlwaysAbstain@ and @NoConfidence@.
166+
queryDRepDelegations ::
167+
forall era.
168+
ConwayEraCertState era =>
169+
NewEpochState era ->
170+
-- | Specify a set of DReps whose state should be returned. When this set is
171+
-- empty, states for all of the DReps will be returned.
172+
Set DRep ->
173+
Map DRep (Set (Credential 'Staking))
174+
queryDRepDelegations nes dreps =
175+
case getDRepCreds dreps of
176+
Just creds ->
177+
Map.map drepDelegs $
178+
Map.mapKeys credToDRep ((vState ^. vsDRepsL) `Map.restrictKeys` creds)
179+
Nothing ->
180+
-- Whenever predefined `AlwaysAbstain` or `AlwaysNoConfidence` are
181+
-- requested we are forced to iterate over all accounts and find those
182+
-- delegations.
183+
Map.foldlWithKey'
184+
( \m cred cas ->
185+
case cas ^. dRepDelegationAccountStateL of
186+
Just drep
187+
| Set.null dreps || drep `Set.member` dreps ->
188+
Map.insertWith (<>) drep (Set.singleton cred) m
189+
_ ->
190+
m
191+
)
192+
Map.empty
193+
(dState ^. accountsL . accountsMapL)
194+
where
195+
dState = nes ^. nesEsL . esLStateL . lsCertStateL . certDStateL
196+
vState = nes ^. nesEsL . esLStateL . lsCertStateL . certVStateL
197+
-- Find all credentials for requested DReps, but only when we don't care
198+
-- about predefined DReps
199+
getDRepCreds ds = do
200+
guard $ not $ Set.null ds
201+
Set.fromList <$> traverse dRepToCred (Set.elems ds)
202+
159203
-- | Query DRep stake distribution. Note that this can be an expensive query because there
160204
-- is a chance that current distribution has not been fully computed yet.
161205
queryDRepStakeDistr ::

libs/cardano-ledger-api/test/Test/Cardano/Ledger/Api/State/Imp/QuerySpec.hs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Cardano.Ledger.Api.State.Query (
1414
MemberStatus (..),
1515
NextEpochChange (..),
1616
queryCommitteeMembersState,
17+
queryDRepDelegations,
1718
queryDRepState,
1819
)
1920
import Cardano.Ledger.BaseTypes
@@ -198,6 +199,39 @@ spec = do
198199
expectQueryResult (Set.singleton c1) mempty mempty $
199200
[(c1, CommitteeMemberState (MemberAuthorized hk1) Active (Just c1Expiry) NoChangeExpected)]
200201

202+
it "queryDRepDelegationState" $ do
203+
(credDrep, delegator, _) <- setupSingleDRep 1_000_000
204+
205+
kh <- freshKeyHash
206+
let cred = KeyHashObj kh
207+
_ <- registerStakeCredential cred
208+
_ <- delegateToDRep cred (Coin 2_000_000) DRepAlwaysAbstain
209+
210+
kh2 <- freshKeyHash
211+
let cred2 = KeyHashObj kh2
212+
_ <- registerStakeCredential cred2
213+
_ <- delegateToDRep cred2 (Coin 3_000_000) DRepAlwaysNoConfidence
214+
215+
let realDRepCred = DRepCredential credDrep
216+
217+
nes <- getsNES id
218+
let abstainDelegations =
219+
Map.singleton DRepAlwaysAbstain (Set.fromList [cred])
220+
noConfidenceDelegations =
221+
Map.singleton DRepAlwaysNoConfidence (Set.fromList [cred2])
222+
realDRepDelegations = Map.singleton realDRepCred (Set.fromList [delegator])
223+
expectedAllDelegations =
224+
realDRepDelegations
225+
<> abstainDelegations
226+
<> noConfidenceDelegations
227+
queryDRepDelegations nes mempty `shouldBe` expectedAllDelegations
228+
queryDRepDelegations nes (Set.singleton DRepAlwaysAbstain)
229+
`shouldBe` abstainDelegations
230+
queryDRepDelegations nes (Set.singleton DRepAlwaysNoConfidence)
231+
`shouldBe` noConfidenceDelegations
232+
queryDRepDelegations nes (Set.singleton realDRepCred)
233+
`shouldBe` realDRepDelegations
234+
201235
it "Committee queries" $ whenPostBootstrap $ do
202236
(drep, _, _) <- setupSingleDRep 1_000_000
203237
(spoC, _, _) <- setupPoolWithStake $ Coin 42_000_000

libs/cardano-ledger-core/CHANGELOG.md

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

33
## 1.18.0.0
44

5+
* Export `credToDRep` and `dRepToCred`
56
* Deprecate `PoolParams` in favor of `StakePoolState`. #5196
67
* Move the `PoolParams` module to `Cardano.Ledger.State.StakePool` and export from there.
78
* Add the `StakePoolState` data type to the new module.

libs/cardano-ledger-core/src/Cardano/Ledger/DRep.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
module Cardano.Ledger.DRep (
1212
DRep (DRepCredential, DRepKeyHash, DRepScriptHash, DRepAlwaysAbstain, DRepAlwaysNoConfidence),
1313
DRepState (..),
14+
credToDRep,
15+
dRepToCred,
1416
drepExpiryL,
1517
drepAnchorL,
1618
drepDepositL,

0 commit comments

Comments
 (0)