stakerRewards filters, re-org (#2292)

This commit is contained in:
Jaco Greeff
2020-05-18 10:20:09 +02:00
committed by GitHub
parent 597563d2bb
commit dac1df35de
@@ -14,14 +14,14 @@ import { isFunction } from '@polkadot/util';
import { memo } from '../util';
type Result = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[], DeriveStakerExposure[]];
type ErasResult = [{ unwrapOr: (value: BN) => BN }, DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[]];
const ZERO = new BN(0);
const MIN_ONE = new BN(-1);
const COMM_DIV = new BN(1_000_000_000);
const MAX_ERAS = new BN(1_000_000_000);
function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [erasPoints, erasPrefs, erasRewards, exposures]: Result): DeriveStakerReward[] {
function parseRewards (api: ApiInterfaceRx, stashId: AccountId, [, erasPoints, erasPrefs, erasRewards]: ErasResult, exposures: DeriveStakerExposure[]): DeriveStakerReward[] {
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: ZERO, validators: {} };
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: api.registry.createType('Balance') };
@@ -98,29 +98,29 @@ function filterEras (eras: EraIndex[], stakingLedger: StakingLedger): EraIndex[]
return eras.filter((era) => filterEra(era, stakingLedger));
}
function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], stakingLedger: StakingLedger, withActive?: boolean): Observable<DeriveStakerReward[]> {
function filterRewards (api: ApiInterfaceRx, eras: EraIndex[], migrateEra: BN, rewards: DeriveStakerReward[], stakingLedger: StakingLedger, withActive: boolean): Observable<DeriveStakerReward[]> {
if (withActive) {
return of(rewards);
}
const validators = uniqValidators(rewards);
const isNewPayouts = isFunction(api.tx.staking.payoutStakers);
return combineLatest([
isFunction(api.query.staking.migrateEra)
? api.query.staking.migrateEra<Option<EraIndex>>()
: of({ unwrapOr: () => isNewPayouts ? ZERO : MAX_ERAS }),
isNewPayouts
return (
isFunction(api.tx.staking.payoutStakers)
? api.derive.staking.queryMulti(validators)
: of([])
]).pipe(
map(([optMigrate, queryValidators]): DeriveStakerReward[] => {
const migrateEra: BN = optMigrate.unwrapOr(ZERO);
).pipe(
map((queryValidators): DeriveStakerReward[] => {
const filter = withActive
? eras
: filterEras(eras, stakingLedger);
return rewards
.filter(({ isEmpty }) => !isEmpty)
.filter((reward): boolean => {
if (reward.era.lt(migrateEra)) {
if (!filter.some((filter) => reward.era.eq(filter))) {
return false;
} else if (reward.era.lt(migrateEra)) {
// we filter again here, the actual ledger may have changed, e.g. something has been claimed
return filterEra(reward.era, stakingLedger);
}
@@ -156,28 +156,34 @@ function filterRewards (api: ApiInterfaceRx, rewards: DeriveStakerReward[], stak
);
}
export function _stakerRewardsEras (api: ApiInterfaceRx): (eras: EraIndex[]) => Observable<ErasResult> {
return memo((eras: EraIndex[]): Observable<ErasResult> =>
combineLatest([
isFunction(api.query.staking.migrateEra)
? api.query.staking.migrateEra<Option<EraIndex>>()
: of({ unwrapOr: () => isFunction(api.tx.staking.payoutStakers) ? ZERO : MAX_ERAS }),
api.derive.staking._erasPoints(eras),
api.derive.staking._erasPrefs(eras),
api.derive.staking._erasRewards(eras)
])
);
}
export function _stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | string, eras: EraIndex[], withActive?: boolean) => Observable<DeriveStakerReward[]> {
return memo((accountId: Uint8Array | string, _eras: EraIndex[], withActive?: boolean): Observable<DeriveStakerReward[]> =>
api.derive.staking.query(accountId).pipe(
switchMap(({ stakingLedger, stashId }): Observable<DeriveStakerReward[]> => {
return memo((accountId: Uint8Array | string, eras: EraIndex[], withActive = false): Observable<DeriveStakerReward[]> =>
combineLatest([
api.derive.staking.query(accountId),
api.derive.staking._stakerExposure(accountId, eras),
api.derive.staking._stakerRewardsEras(eras)
]).pipe(
switchMap(([{ stakingLedger, stashId }, exposures, erasResult]): Observable<DeriveStakerReward[]> => {
const migrateEra: BN = erasResult[0].unwrapOr(ZERO);
if (!stashId || !stakingLedger) {
return of([]);
}
const eras = withActive
? _eras
: filterEras(_eras, stakingLedger);
return combineLatest([
api.derive.staking._erasPoints(eras),
api.derive.staking._erasPrefs(eras),
api.derive.staking._erasRewards(eras),
api.derive.staking._stakerExposure(stashId, eras)
]).pipe(
switchMap((result): Observable<DeriveStakerReward[]> =>
filterRewards(api, parseRewards(api, stashId, result), stakingLedger, withActive)
)
);
return filterRewards(api, eras, migrateEra, parseRewards(api, stashId, erasResult, exposures), stakingLedger, withActive);
})
)
);