Flatten more combineLatest into queryMulti (#1528)

This commit is contained in:
Jaco Greeff
2019-10-29 17:49:42 +01:00
committed by GitHub
parent b0e970a815
commit 41cf32c808
5 changed files with 73 additions and 66 deletions
+37 -31
View File
@@ -5,7 +5,7 @@
import { BlockNumber, EraIndex, SessionIndex } from '@polkadot/types/interfaces';
import { DerivedSessionInfo } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { Observable, combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, u64, createType } from '@polkadot/types';
@@ -17,9 +17,9 @@ type Result94Session = [SessionIndex, Option<BlockNumber>, BlockNumber, BlockNum
type Result94 = [BlockNumber, Result94Session];
type ResultIndex = [SessionIndex, EraIndex];
type ResultSlots = [u64, u64, u64];
type ResultSlots = [u64, u64, u64, SessionIndex, EraIndex];
type ResultType = [boolean, boolean, u64, SessionIndex];
type Result = [ResultType, ResultSlots, ResultIndex];
type Result = [ResultType, ResultSlots];
// internal helper to just split the logic - take all inputs, do the calculations and combine
function createDerived94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result94): DerivedSessionInfo {
@@ -49,7 +49,7 @@ function createDerived94 ([bestNumber, [currentIndex, _lastLengthChange, session
};
}
function createDerivedLatest ([[hasBabe, isGenesisSlot, epochDuration, sessionsPerEra], [currentSlot, epochIndex, epochOrGenesisStartSlot], [currentIndex, currentEra]]: Result): DerivedSessionInfo {
function createDerivedLatest ([[hasBabe, isGenesisSlot, epochDuration, sessionsPerEra], [currentSlot, epochIndex, epochOrGenesisStartSlot, currentIndex, currentEra]]: Result): DerivedSessionInfo {
const epochStartSlot = isGenesisSlot
? epochIndex
.mul(epochDuration)
@@ -91,33 +91,37 @@ function info94 (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
);
}
function infoLatest (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
const hasBabe = !!api.consts.babe;
return combineLatest([
of([
hasBabe,
hasBabe && !!api.query.babe.genesisSlot,
hasBabe
? api.consts.babe.epochDuration as u64
: createType('u64', 1),
api.consts.staking.sessionsPerEra as SessionIndex
] as ResultType),
hasBabe
? api.queryMulti<ResultSlots>([
api.query.babe.currentSlot,
api.query.babe.epochIndex,
api.query.babe.genesisSlot
? api.query.babe.genesisSlot
: api.query.babe.epochStartSlot
])
: of([createType('u64', 1), createType('u64', 1), createType('u64', 1)] as ResultSlots),
api.queryMulti<ResultIndex>([
api.query.session.currentIndex,
api.query.staking.currentEra
])
function infoLatestAura (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
return api.queryMulti<ResultIndex>([
api.query.session.currentIndex,
api.query.staking.currentEra
]).pipe(
map(createDerivedLatest),
map(([currentIndex, currentEra]): DerivedSessionInfo =>
createDerivedLatest([
[false, false, createType('u64', 1), api.consts.staking.sessionsPerEra as SessionIndex],
[createType('u64', 1), createType('u64', 1), createType('u64', 1), currentIndex, currentEra]
])
),
drr()
);
}
function infoLatestBabe (api: ApiInterfaceRx): Observable<DerivedSessionInfo> {
return api.queryMulti<ResultSlots>([
api.query.babe.currentSlot,
api.query.babe.epochIndex,
api.query.babe.genesisSlot
? api.query.babe.genesisSlot
: api.query.babe.epochStartSlot,
api.query.session.currentIndex,
api.query.staking.currentEra
]).pipe(
map((slots: ResultSlots): DerivedSessionInfo =>
createDerivedLatest([
[true, !!api.query.babe.genesisSlot, api.consts.babe.epochDuration as u64, api.consts.staking.sessionsPerEra as SessionIndex],
slots
])
),
drr()
);
}
@@ -132,6 +136,8 @@ export function info (api: ApiInterfaceRx): () => Observable<DerivedSessionInfo>
// https://github.com/paritytech/substrate/commit/dbf322620948935d2bbae214504e6c668c3073ed#diff-c29f42d6b931fa93ba038dbbbfec3055
return api.query.session.lastLengthChange
? info94(api) // 1.x
: infoLatest(api); // 2.x
: api.consts.babe
? infoLatestBabe(api) // 2.x with Babe
: infoLatestAura(api); // 2.x with Aura (not all info there)
};
}
@@ -2,7 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import { BlockNumber } from '@polkadot/types/interfaces';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
@@ -10,10 +11,10 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { drr } from '../util/drr';
import { info } from './info';
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BN> {
return (): Observable<BN> =>
export function sessionProgress (api: ApiInterfaceRx): () => Observable<BlockNumber> {
return (): Observable<BlockNumber> =>
info(api)().pipe(
map(({ sessionProgress }): BN => sessionProgress),
map(({ sessionProgress }): BlockNumber => sessionProgress),
drr()
);
}
+21 -21
View File
@@ -22,9 +22,7 @@ import { eraLength } from '../session/eraLength';
import { recentlyOffline } from './recentlyOffline';
import { drr } from '../util/drr';
type MultiResult = [Option<Keys>, [
Option<AccountId> | Vec<[AccountId, Keys] & Codec>, Option<StakingLedger>, [AccountId[]], RewardDestination, Exposure, [ValidatorPrefs]
]];
type MultiResult = [Option<AccountId> | Vec<[AccountId, Keys] & Codec>, Option<StakingLedger>, [AccountId[]], RewardDestination, Exposure, [ValidatorPrefs], Option<Keys>?];
// groups the supplied chunks by era, i.e. { [era]: BN(total of values) }
function groupByEra (list: UnlockChunk[]): Record<string, BN> {
@@ -114,23 +112,25 @@ function unwrapSessionIds (stashId: AccountId, queuedKeys: Option<AccountId> | V
}
function retrieveMulti (api: ApiInterfaceRx, stashId: AccountId, controllerId: AccountId): Observable<MultiResult> {
return combineLatest([
// TODO We really want this as part of the multi, however can only do that
// once we drop substrate 1.x support (nulti requires values for all)
api.query.session.nextKeys
? api.query.session.nextKeys<Option<Keys>>(api.consts.session.dedupKeyPrefix, stashId)
: of(createType('Option<Keys>', null)),
api.queryMulti([
api.query.session.queuedKeys
? [api.query.session.queuedKeys]
: [api.query.session.nextKeyFor, controllerId],
[api.query.staking.ledger, controllerId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId]
])
]) as Observable<MultiResult>;
// A bit horrible, since we push below to forge everything into 1 query - we do this we we end up with one
// query to retrieve everything
const queries: Array<any> = [
api.query.session.queuedKeys
? [api.query.session.queuedKeys]
: [api.query.session.nextKeyFor, controllerId],
[api.query.staking.ledger, controllerId],
[api.query.staking.nominators, stashId],
[api.query.staking.payee, stashId],
[api.query.staking.stakers, stashId],
[api.query.staking.validators, stashId]
];
//
if (api.query.session.nextKeys) {
queries.push([api.query.session.nextKeys, [api.consts.session.dedupKeyPrefix, stashId]]);
}
return api.queryMulti(queries) as Observable<MultiResult>;
}
function retrieveInfo (api: ApiInterfaceRx, accountId: AccountId, stashId: AccountId, controllerId: AccountId): Observable<DerivedStaking> {
@@ -140,7 +140,7 @@ function retrieveInfo (api: ApiInterfaceRx, accountId: AccountId, stashId: Accou
recentlyOffline(api)(),
retrieveMulti(api, stashId, controllerId)
]).pipe(
map(([eraLength, bestNumber, recentlyOffline, [nextKeys, [queuedKeys, _stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs]]]]): DerivedStaking => {
map(([eraLength, bestNumber, recentlyOffline, [queuedKeys, _stakingLedger, [nominators], rewardDestination, stakers, [validatorPrefs], nextKeys = createType('Option<Keys>', null)]]): DerivedStaking => {
const stakingLedger = _stakingLedger.unwrapOr(undefined);
return {