Add missing commission to payout calculations (#2051)

* Add missing comission to payout calcs

* yarn

* Bump dev with version update fix
This commit is contained in:
Jaco Greeff
2020-03-15 09:51:52 +01:00
committed by GitHub
parent 707c93a557
commit 908d0fcf52
6 changed files with 117 additions and 53 deletions
@@ -0,0 +1,48 @@
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { EraIndex, ValidatorPrefs } from '@polkadot/types/interfaces';
import { DeriveEraPrefs, DeriveEraValPrefs } from '../types';
import BN from 'bn.js';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { StorageKey } from '@polkadot/types';
import { memo } from '../util';
type KeysAndPrefs = [StorageKey, ValidatorPrefs][];
function mapPrefs (era: EraIndex, all: KeysAndPrefs): DeriveEraPrefs {
const validators: DeriveEraValPrefs = {};
all.forEach(([key, prefs]): void => {
validators[key.args[1].toString()] = prefs;
});
return { era, validators };
}
export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraPrefs> {
return memo((era: EraIndex): Observable<DeriveEraPrefs> =>
api.query.staking.erasValidatorPrefs.entries(era).pipe(
map((prefs) => mapPrefs(era, prefs))
)
);
}
export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean | BN | number) => Observable<DeriveEraPrefs[]> {
return memo((withActive?: boolean | BN | number): Observable<DeriveEraPrefs[]> =>
api.derive.staking.erasHistoric(withActive).pipe(
switchMap((eras): Observable<DeriveEraPrefs[]> =>
eras.length
? combineLatest(
eras.map((era) => api.derive.staking.eraPrefs(era))
)
: of([])
)
)
);
}
+1
View File
@@ -6,6 +6,7 @@ export * from './account';
export * from './erasExposure';
export * from './erasHistoric';
export * from './erasPoints';
export * from './erasPrefs';
export * from './erasRewards';
export * from './controllers';
export * from './electedInfo';
@@ -4,7 +4,7 @@
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Balance } from '@polkadot/types/interfaces';
import { DeriveEraPoints, DeriveEraRewards, DeriveStakerExposure, DeriveStakerReward } from '../types';
import { DeriveEraPoints, DeriveEraPrefs, DeriveEraRewards, DeriveEraValPrefs, DeriveStakerExposure, DeriveStakerReward } from '../types';
import BN from 'bn.js';
import { Observable, combineLatest } from 'rxjs';
@@ -12,18 +12,24 @@ import { map } from 'rxjs/operators';
import { memo } from '../util';
type Result = [DeriveEraPoints[], DeriveEraRewards[], DeriveStakerExposure[]];
const ZERO = new BN(0);
type Result = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[], DeriveStakerExposure[]];
function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasRewards, exposures]: Result): DeriveStakerReward[] {
const ZERO = new BN(0);
const COMM_DIV = new BN(1_000_000_000);
function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasPrefs, erasRewards, exposures]: Result): DeriveStakerReward[] {
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: new BN(0), validators: {} };
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: new BN(0) };
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: ZERO };
const { validators: allValPrefs } = erasPrefs.find((p) => p.era.eq(era)) || { validators: {} as DeriveEraValPrefs };
const validators: Record<string, Balance> = {};
let total = ZERO;
Object.entries(eraValidators).forEach(([validatorId, exposure]): void => {
const valPoints = allValPoints[validatorId] || new BN(0);
const valPoints = allValPoints[validatorId] || ZERO;
const valComm = allValPrefs[validatorId]?.commission.unwrap() || ZERO;
const avail = eraReward.mul(valPoints).div(eraPoints);
const valCut = valComm.mul(avail).div(COMM_DIV);
const expTotal = exposure.total.unwrap();
let value: BN | undefined;
@@ -40,7 +46,7 @@ function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasR
: ZERO;
}
value = eraReward.mul(valPoints).mul(staked).div(eraPoints).div(expTotal);
value = avail.sub(valCut).mul(staked).div(expTotal).add(validatorId === stakerId ? valCut : ZERO);
total = total.add(value);
}
@@ -64,6 +70,7 @@ export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | st
return combineLatest([
api.derive.staking.erasPoints(startEra),
api.derive.staking.erasPrefs(startEra),
api.derive.staking.erasRewards(startEra),
api.derive.staking.stakerExposure(stakerId, startEra)
]).pipe(
+7
View File
@@ -7,12 +7,19 @@ import { DeriveSessionIndexes } from '../session/types';
export type DeriveEraValPoints = Record<string, RewardPoint>;
export type DeriveEraValPrefs = Record<string, ValidatorPrefs>;
export interface DeriveEraPoints {
era: EraIndex;
eraPoints: RewardPoint;
validators: DeriveEraValPoints;
}
export interface DeriveEraPrefs {
era: EraIndex;
validators: DeriveEraValPrefs;
}
export interface DeriveEraRewards {
era: EraIndex;
eraReward: Balance;