From 0187f1ff199a66ae0354780fbba3c95b80b56b54 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Thu, 28 May 2020 12:07:02 +0200 Subject: [PATCH] Extend deriveCache around ownExposure/ownSlash (#2315) --- .../api-derive/src/staking/ownExposure.ts | 66 ++++++++++++------ packages/api-derive/src/staking/ownSlashes.ts | 68 ++++++++++++++----- 2 files changed, 97 insertions(+), 37 deletions(-) diff --git a/packages/api-derive/src/staking/ownExposure.ts b/packages/api-derive/src/staking/ownExposure.ts index 0aa63a9c7e..e6b13b60a7 100644 --- a/packages/api-derive/src/staking/ownExposure.ts +++ b/packages/api-derive/src/staking/ownExposure.ts @@ -2,34 +2,62 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import { EraIndex } from '@polkadot/types/interfaces'; import { ApiInterfaceRx } from '@polkadot/api/types'; import { DeriveOwnExposure } from '../types'; import { Observable, combineLatest, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { memo } from '../util'; +import { deriveCache, memo } from '../util'; -export function ownExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { - return memo((accountId: Uint8Array | string, withActive?: boolean): Observable => { +const CACHE_KEY = 'ownExposure'; + +export function _ownExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex, withActive: boolean) => Observable { + return memo((accountId: Uint8Array | string, era: EraIndex, withActive: boolean): Observable => { + const cacheKey = `${CACHE_KEY}-${era.toString()}`; + const cached = withActive + ? undefined + : deriveCache.get(cacheKey); + + return cached + ? of(cached) + : combineLatest([ + api.query.staking.erasStakersClipped(era, accountId), + api.query.staking.erasStakers(era, accountId) + ]).pipe( + map(([clipped, exposure]): DeriveOwnExposure => { + const value = { clipped, era, exposure }; + + !withActive && deriveCache.set(cacheKey, value); + + return value; + }) + ); + }); +} + +export function ownExposure (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { + return memo((accountId: Uint8Array | string, era: EraIndex): Observable => + api.derive.staking._ownExposure(accountId, era, true) + ); +} + +export function _ownExposures (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => + eras.length + ? combineLatest( + eras.map((era) => api.derive.staking._ownExposure(accountId, era, withActive)) + ) + : of([]) + ); +} + +export function ownExposures (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { + return memo((accountId: Uint8Array | string, withActive = false): Observable => { return api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => - eras.length - ? combineLatest( - eras.map((era) => combineLatest([ - of(era), - api.query.staking.erasStakersClipped(era, accountId), - api.query.staking.erasStakers(era, accountId) - ])) - ) - : of([]) - ), - map((result): DeriveOwnExposure[] => - result.map(([era, clipped, exposure]): DeriveOwnExposure => ({ - clipped, - era, - exposure - })) + api.derive.staking._ownExposures(accountId, eras, withActive) ) ); }); diff --git a/packages/api-derive/src/staking/ownSlashes.ts b/packages/api-derive/src/staking/ownSlashes.ts index 3f6a0a1e2f..542b8eb48e 100644 --- a/packages/api-derive/src/staking/ownSlashes.ts +++ b/packages/api-derive/src/staking/ownSlashes.ts @@ -2,35 +2,67 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. +import { EraIndex } from '@polkadot/types/interfaces'; import { ApiInterfaceRx } from '@polkadot/api/types'; import { DeriveStakerSlashes } from '../types'; import { Observable, combineLatest, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; -import { memo } from '../util'; +import { deriveCache, memo } from '../util'; + +const CACHE_KEY = 'ownSlash'; + +export function _ownSlash (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex, withActive: boolean) => Observable { + return memo((accountId: Uint8Array | string, era: EraIndex, withActive: boolean): Observable => { + const cacheKey = `${CACHE_KEY}-${era.toString()}`; + const cached = withActive + ? undefined + : deriveCache.get(cacheKey); + + return cached + ? of(cached) + : combineLatest([ + api.query.staking.nominatorSlashInEra(era, accountId), + api.query.staking.validatorSlashInEra(era, accountId) + ]).pipe( + map(([optNom, optVal]): DeriveStakerSlashes => { + const value = { + era, + total: optVal.isSome + ? optVal.unwrap()[1] + : optNom.unwrapOrDefault() + }; + + !withActive && deriveCache.set(cacheKey, value); + + return value; + }) + ); + }); +} + +export function ownSlash (api: ApiInterfaceRx): (accountId: Uint8Array | string, era: EraIndex) => Observable { + return memo((accountId: Uint8Array | string, era: EraIndex): Observable => + api.derive.staking._ownSlash(accountId, era, true) + ); +} + +export function _ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean) => Observable { + return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive: boolean): Observable => + eras.length + ? combineLatest( + eras.map((era) => api.derive.staking._ownSlash(accountId, era, withActive)) + ) + : of([]) + ); +} export function ownSlashes (api: ApiInterfaceRx): (accountId: Uint8Array | string, withActive?: boolean) => Observable { return memo((accountId: Uint8Array | string, withActive = false): Observable => { return api.derive.staking.erasHistoric(withActive).pipe( switchMap((eras) => - eras.length - ? combineLatest( - eras.map((era) => combineLatest([ - of(era), - api.query.staking.nominatorSlashInEra(era, accountId), - api.query.staking.validatorSlashInEra(era, accountId) - ])) - ) - : of([]) - ), - map((result): DeriveStakerSlashes[] => - result.map(([era, optNom, optVal]): DeriveStakerSlashes => ({ - era, - total: optVal.isSome - ? optVal.unwrap()[1] - : optNom.unwrapOrDefault() - })) + api.derive.staking._ownSlashes(accountId, eras, withActive) ) ); });