@@ -14,12 +14,12 @@ use crate::{
1414 ConfigOp ,
1515 ConfigOp :: { Noop , Set } ,
1616 } ,
17- EraRewardPoints , Exposure , IndividualExposure , RewardDestination , StakingLedger ,
18- ValidatorPrefs ,
17+ EraRewardPoints , RewardDestination , StakingLedger , ValidatorPrefs ,
1918 } ,
2019 pallet_sudo:: pallet:: Call :: sudo_as,
2120 pallets:: utility:: UtilityApi ,
2221 sp_arithmetic:: per_things:: Perbill ,
22+ sp_staking:: { Exposure , IndividualExposure } ,
2323 AccountId , Balance , BlockHash ,
2424 Call :: { Staking , Sudo } ,
2525 ConnectionApi , EraIndex , RootConnection , SignedConnectionApi , SudoCall , TxStatus ,
@@ -74,8 +74,20 @@ pub trait StakingApi {
7474 /// Returns [`minimum_validator_count`](https://paritytech.github.io/substrate/master/pallet_staking/struct.Pallet.html#method.minimum_validator_count).
7575 /// * `at` - optional hash of a block to query state from
7676 async fn get_minimum_validator_count ( & self , at : Option < BlockHash > ) -> u32 ;
77+
7778 /// Returns [`SessionsPerEra`](https://paritytech.github.io/substrate/master/pallet_staking/trait.Config.html#associatedtype.SessionsPerEra) const.
7879 async fn get_session_per_era ( & self ) -> anyhow:: Result < u32 > ;
80+
81+ /// Returns [`ClaimedRewards`](https://paritytech.github.io/polkadot-sdk/master/pallet_staking/type.ClaimedRewards.html) for a given era and validator.
82+ /// * `era` - an era index
83+ /// * `validator` - account ID of the validator
84+ /// * `at` - optional hash of a block to query state from
85+ async fn get_claimed_rewards (
86+ & self ,
87+ era : u32 ,
88+ validator : AccountId ,
89+ at : Option < BlockHash > ,
90+ ) -> Vec < u32 > ;
7991}
8092
8193/// Pallet staking api
@@ -199,7 +211,7 @@ pub trait StakingSudoApi {
199211/// Logic for retrieving raw storage keys or values from a pallet staking.
200212#[ async_trait:: async_trait]
201213pub trait StakingRawApi {
202- /// Returns all encoded [`eras_stakers `](https://paritytech.github.io/substrate/master/pallet_staking/struct.Pallet .html#method.eras_stakers ).
214+ /// Returns at most 10 encoded [`ErasStakers `](https://paritytech.github.io/substrate/master/pallet_staking/types.ErasStakers .html).
203215 /// storage keys for a given era
204216 /// * `era` - an era index
205217 /// * `at` - optional hash of a block to query state from
@@ -218,7 +230,7 @@ pub trait StakingRawApi {
218230 at : Option < BlockHash > ,
219231 ) -> anyhow:: Result < Vec < StorageKey > > ;
220232
221- /// Returns encoded [`eras_stakers `](https://paritytech.github.io/substrate/master/pallet_staking/struct.Pallet.html#method.eras_stakers ).
233+ /// Returns encoded [`ErasStakers `](https://paritytech.github.io/substrate/master/pallet_staking/types.ErasStakers ).
222234 /// storage keys for a given era and given account ids
223235 /// * `era` - an era index
224236 /// * `accounts` - list of account ids
@@ -229,6 +241,37 @@ pub trait StakingRawApi {
229241 accounts : & [ AccountId ] ,
230242 at : Option < BlockHash > ,
231243 ) -> Vec < StorageKey > ;
244+
245+ /// Returns at most 10 encoded [`ErasStakersOverview`](https://paritytech.github.io/substrate/master/pallet_staking/types.ErasStakersOverview.html).
246+ /// storage keys for a given era
247+ /// * `era` - an era index
248+ /// * `at` - optional hash of a block to query state from
249+ ///
250+ /// # Examples
251+ /// ```ignore
252+ /// let stakers = connection
253+ /// .get_stakers_overview_storage_keys(current_era, None)
254+ /// .await
255+ /// .into_iter()
256+ /// .map(|key| key.0);
257+ /// ```
258+ async fn get_stakers_overview_storage_keys (
259+ & self ,
260+ era : EraIndex ,
261+ at : Option < BlockHash > ,
262+ ) -> anyhow:: Result < Vec < StorageKey > > ;
263+
264+ /// Returns encoded [`ErasStakersOverview`](https://paritytech.github.io/substrate/master/pallet_staking/types.ErasStakersOverview.html).
265+ /// storage keys for a given era and given account ids
266+ /// * `era` - an era index
267+ /// * `accounts` - list of account ids
268+ /// * `at` - optional hash of a block to query state from
269+ async fn get_stakers_overview_storage_keys_from_accounts (
270+ & self ,
271+ era : EraIndex ,
272+ accounts : & [ AccountId ] ,
273+ at : Option < BlockHash > ,
274+ ) -> Vec < StorageKey > ;
232275}
233276
234277#[ async_trait:: async_trait]
@@ -269,11 +312,48 @@ impl<C: ConnectionApi + AsConnection> StakingApi for C {
269312 account_id : & AccountId ,
270313 at : Option < BlockHash > ,
271314 ) -> Exposure < AccountId , Balance > {
272- let addrs = api:: storage ( )
273- . staking ( )
274- . eras_stakers ( era, Static ( account_id. clone ( ) ) ) ;
315+ let overview = self
316+ . get_storage_entry_maybe (
317+ & api:: storage ( )
318+ . staking ( )
319+ . eras_stakers_overview ( era, Static ( account_id. clone ( ) ) ) ,
320+ at,
321+ )
322+ . await ;
323+
324+ let exposure = match overview {
325+ None => {
326+ self . get_storage_entry (
327+ & api:: storage ( )
328+ . staking ( )
329+ . eras_stakers ( era, Static ( account_id. clone ( ) ) ) ,
330+ at,
331+ )
332+ . await
333+ }
334+ Some ( overview) => {
335+ let mut others = Vec :: with_capacity ( overview. nominator_count as usize ) ;
336+ for page in 0 ..overview. page_count {
337+ let nominators = self
338+ . get_storage_entry_maybe (
339+ & api:: storage ( ) . staking ( ) . eras_stakers_paged (
340+ era,
341+ Static ( account_id. clone ( ) ) ,
342+ page,
343+ ) ,
344+ at,
345+ )
346+ . await ;
347+ others. append ( & mut nominators. map ( |n| n. others ) . unwrap_or_default ( ) ) ;
348+ }
349+ Exposure {
350+ total : overview. total ,
351+ own : overview. own ,
352+ others,
353+ }
354+ }
355+ } ;
275356
276- let exposure = self . get_storage_entry ( & addrs, at) . await ;
277357 Exposure {
278358 total : exposure. total ,
279359 own : exposure. own ,
@@ -321,6 +401,18 @@ impl<C: ConnectionApi + AsConnection> StakingApi for C {
321401 . at ( & addrs)
322402 . map_err ( |e| e. into ( ) )
323403 }
404+
405+ async fn get_claimed_rewards (
406+ & self ,
407+ era : u32 ,
408+ validator : AccountId ,
409+ at : Option < BlockHash > ,
410+ ) -> Vec < u32 > {
411+ let addrs = api:: storage ( )
412+ . staking ( )
413+ . claimed_rewards ( era, Static ( validator) ) ;
414+ self . get_storage_entry ( & addrs, at) . await
415+ }
324416}
325417
326418#[ async_trait:: async_trait]
@@ -467,6 +559,43 @@ impl<C: AsConnection + Sync> StakingRawApi for C {
467559 } )
468560 . collect ( )
469561 }
562+
563+ async fn get_stakers_overview_storage_keys (
564+ & self ,
565+ era : EraIndex ,
566+ at : Option < BlockHash > ,
567+ ) -> anyhow:: Result < Vec < StorageKey > > {
568+ let key_addrs = api:: storage ( ) . staking ( ) . eras_stakers_overview_root ( ) ;
569+ let mut key = key_addrs. to_root_bytes ( ) ;
570+ extend_with_twox64_concat_hash ( & mut key, era) ;
571+
572+ let storage = self . as_connection ( ) . as_client ( ) . storage ( ) ;
573+ let block = match at {
574+ Some ( block_hash) => storage. at ( block_hash) ,
575+ None => storage. at_latest ( ) . await ?,
576+ } ;
577+ block. fetch_keys ( & key, 10 , None ) . await . map_err ( |e| e. into ( ) )
578+ }
579+
580+ async fn get_stakers_overview_storage_keys_from_accounts (
581+ & self ,
582+ era : EraIndex ,
583+ accounts : & [ AccountId ] ,
584+ _: Option < BlockHash > ,
585+ ) -> Vec < StorageKey > {
586+ let key_addrs = api:: storage ( ) . staking ( ) . eras_stakers_overview_root ( ) ;
587+ let mut key = key_addrs. to_root_bytes ( ) ;
588+ extend_with_twox64_concat_hash ( & mut key, era) ;
589+ accounts
590+ . iter ( )
591+ . map ( |account| {
592+ let mut key = key. clone ( ) ;
593+ extend_with_twox64_concat_hash ( & mut key, account) ;
594+
595+ StorageKey ( key)
596+ } )
597+ . collect ( )
598+ }
470599}
471600
472601#[ async_trait:: async_trait]
0 commit comments