Multi query adjustments (#1732)

This commit is contained in:
Jaco Greeff
2020-01-20 13:58:07 +01:00
committed by GitHub
parent f31bbdde02
commit eb5ee9860b
13 changed files with 98 additions and 140 deletions
+11 -20
View File
@@ -14,10 +14,10 @@ import { bnMax } from '@polkadot/util';
import { memo } from '../util';
type ResultBalance = [Balance, Balance, BalanceLock[], Option<VestingSchedule>];
type Result = [AccountId, BlockNumber, ResultBalance, Index];
type ResultBalance = [Balance, Balance, BalanceLock[], Option<VestingSchedule>, Index];
type Result = [AccountId, BlockNumber, ResultBalance];
function calcBalances (api: ApiInterfaceRx, [accountId, bestNumber, [freeBalance, reservedBalance, locks, vesting], accountNonce]: Result): DerivedBalances {
function calcBalances (api: ApiInterfaceRx, [accountId, bestNumber, [freeBalance, reservedBalance, locks, vesting, accountNonce]]: Result): DerivedBalances {
let lockedBalance = createType(api.registry, 'Balance');
let lockedBreakdown: BalanceLock[] = [];
@@ -64,15 +64,6 @@ function calcBalances (api: ApiInterfaceRx, [accountId, bestNumber, [freeBalance
};
}
function queryBalances (api: ApiInterfaceRx, accountId: AccountId): Observable<ResultBalance> {
return api.queryMulti<[Balance, Balance, Vec<BalanceLock>, Option<VestingSchedule>]>([
[api.query.balances.freeBalance, accountId],
[api.query.balances.reservedBalance, accountId],
[api.query.balances.locks, accountId],
[api.query.balances.vesting, accountId]
]);
}
/**
* @name all
* @param {( AccountIndex | AccountId | Address | string )} address - An accounts Id in different formats.
@@ -96,15 +87,15 @@ export function all (api: ApiInterfaceRx): (address: AccountIndex | AccountId |
? combineLatest([
of(accountId),
api.derive.chain.bestNumber(),
queryBalances(api, accountId),
// FIXME This is having issues with Kusama, only use accountNonce atm
// api.rpc.account && api.rpc.account.nextIndex
// ? api.rpc.account.nextIndex(accountId)
// // otherwise we end up with this: type 'Codec | Index' is not assignable to type 'Index'.
// : api.query.system.accountNonce<Index>(accountId)
api.query.system.accountNonce<Index>(accountId)
api.queryMulti<[Balance, Balance, Vec<BalanceLock>, Option<VestingSchedule>, Index]>([
[api.query.balances.freeBalance, accountId],
[api.query.balances.reservedBalance, accountId],
[api.query.balances.locks, accountId],
[api.query.balances.vesting, accountId],
[api.query.system.accountNonce, accountId]
])
])
: of([createType(api.registry, 'AccountId'), createType(api.registry, 'BlockNumber'), [createType(api.registry, 'Balance'), createType(api.registry, 'Balance'), createType(api.registry, 'Vec<BalanceLock>'), createType(api.registry, 'Option<VestingSchedule>', null)], createType(api.registry, 'Index')])
: of([createType(api.registry, 'AccountId'), createType(api.registry, 'BlockNumber'), [createType(api.registry, 'Balance'), createType(api.registry, 'Balance'), createType(api.registry, 'Vec<BalanceLock>'), createType(api.registry, 'Option<VestingSchedule>', null), createType(api.registry, 'Index')]])
)
),
map((result): DerivedBalances => calcBalances(api, result))
+26 -27
View File
@@ -4,41 +4,40 @@
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Hash, Proposal, Votes } from '@polkadot/types/interfaces';
import { DerivedCollectiveProposals } from '../types';
import { DerivedCollectiveProposal } from '../types';
import { combineLatest, Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { Option } from '@polkadot/types';
export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DerivedCollectiveProposals> {
return (): Observable<DerivedCollectiveProposals> =>
api.query[section]
? api.query[section].proposals()
.pipe(
switchMap((hashes: Hash[]): Observable<[Hash[], Option<Proposal>[], Option<Votes>[]]> => {
return combineLatest([
of(hashes),
combineLatest(
hashes.map((hash): Observable<Option<Proposal>> => api.query[section].proposalOf(hash))
),
api.query[section].voting.multi<Option<Votes>>(hashes)
]);
}),
map(([hashes, proposals, votes]): DerivedCollectiveProposals => {
const result: DerivedCollectiveProposals = [];
type Result = [Hash[], Option<Proposal>[], Option<Votes>[]];
proposals.forEach((proposalOpt, index): void => {
if (proposalOpt.isSome) {
result.push({
export function proposals (api: ApiInterfaceRx, section: 'council' | 'technicalCommittee'): () => Observable<DerivedCollectiveProposal[]> {
return (): Observable<DerivedCollectiveProposal[]> =>
api.query[section]
? api.query[section].proposals().pipe(
switchMap((hashes: Hash[]): Observable<Result> =>
hashes.length
? combineLatest([
of(hashes),
api.query[section].proposalOf.multi<Option<Proposal>>(hashes),
api.query[section].voting.multi<Option<Votes>>(hashes)
])
: of([[], [], []])
),
map(([hashes, proposals, votes]: Result): DerivedCollectiveProposal[] =>
proposals
.map((proposalOpt, index): DerivedCollectiveProposal | null =>
proposalOpt.isSome
? {
hash: hashes[index],
proposal: proposalOpt.unwrap(),
votes: votes[index].unwrapOr(null)
});
}
});
return result;
})
}
: null
)
.filter((proposal): boolean => !!proposal) as DerivedCollectiveProposal[]
)
: of([] as DerivedCollectiveProposals);
)
: of([] as DerivedCollectiveProposal[]);
}
+13 -13
View File
@@ -64,20 +64,20 @@ function parse (api: ApiInterfaceRx, { depositors, proposals, preimages }: Resul
export function proposals (api: ApiInterfaceRx): () => Observable<DeriveProposal[]> {
return memo((): Observable<DeriveProposal[]> =>
api.query.democracy?.publicProps
? api.query.democracy
.publicProps<Proposals>()
.pipe(
switchMap((proposals) =>
combineLatest([
of(proposals),
api.query.democracy.preimages.multi<PreImage>(proposals.map(([, hash]): Hash => hash)),
api.query.democracy.depositOf.multi<Depositors>(proposals.map(([index]): PropIndex => index))
])
),
map(([proposals, preimages, depositors]): DeriveProposal[] =>
parse(api, { depositors, proposals, preimages })
)
? api.query.democracy.publicProps<Proposals>().pipe(
switchMap((proposals) =>
combineLatest([
of(proposals),
api.query.democracy.preimages.multi<PreImage>(
proposals.map(([, hash]): Hash => hash)),
api.query.democracy.depositOf.multi<Depositors>(
proposals.map(([index]): PropIndex => index))
])
),
map(([proposals, preimages, depositors]): DeriveProposal[] =>
parse(api, { depositors, proposals, preimages })
)
)
: of([] as DeriveProposal[])
);
}
@@ -9,7 +9,7 @@ import BN from 'bn.js';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { Option, Vec } from '@polkadot/types';
import { Option } from '@polkadot/types';
import { memo } from '../util';
import { retrieveInfo } from './referendumInfo';
@@ -17,9 +17,9 @@ import { retrieveInfo } from './referendumInfo';
export function referendumInfos (api: ApiInterfaceRx): (ids?: (BN | number)[]) => Observable<DerivedReferendum[]> {
return memo((ids: (BN | number)[] = []): Observable<DerivedReferendum[]> =>
(
!ids || !ids.length
!ids?.length
? of([] as Option<ReferendumInfo>[])
: api.query.democracy.referendumInfoOf.multi(ids) as Observable<Vec<Option<ReferendumInfo>>>
: api.query.democracy.referendumInfoOf.multi<Option<ReferendumInfo>>(ids)
).pipe(
switchMap((infos): Observable<(DerivedReferendum | null)[]> =>
combineLatest(
@@ -19,7 +19,7 @@ export function referendumVotesFor (api: ApiInterfaceRx): (referendumId: BN | nu
switchMap((votersFor): Observable<[Vec<AccountId>, Vote[], DerivedBalances[]]> =>
combineLatest([
of(votersFor),
api.derive.democracy.votes(referendumId as BN, votersFor),
api.derive.democracy.votes(referendumId, votersFor),
api.derive.balances.votingBalances(votersFor)
])
),
+3 -3
View File
@@ -10,12 +10,12 @@ import { ApiInterfaceRx } from '@polkadot/api/types';
import { memo } from '../util';
export function votes (api: ApiInterfaceRx): (referendumId: BN, accountIds?: AccountId[]) => Observable<Vote[]> {
return memo((referendumId: BN, accountIds: AccountId[] = []): Observable<Vote[]> =>
export function votes (api: ApiInterfaceRx): (referendumId: BN | number, accountIds?: AccountId[]) => Observable<Vote[]> {
return memo((referendumId: BN | number, accountIds: AccountId[] = []): Observable<Vote[]> =>
!accountIds || !accountIds.length
? of([] as Vote[])
: api.query.democracy.voteOf.multi<Vote>(
accountIds.map((accountId): [BN, AccountId] =>
accountIds.map((accountId): [BN | number, AccountId] =>
[referendumId, accountId]
)
)
+14 -27
View File
@@ -5,7 +5,7 @@
import { AccountId, Balance, BlockNumber } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { Observable, combineLatest } from 'rxjs';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterfaceRx } from '@polkadot/api/types';
import { createType, Vec, u32 } from '@polkadot/types';
@@ -13,39 +13,26 @@ import { createType, Vec, u32 } from '@polkadot/types';
import { DerivedElectionsInfo } from '../types';
import { memo } from '../util';
function deriveElections (api: ApiInterfaceRx, candidates: AccountId[], members: [AccountId, Balance][], runnersUp: [AccountId, Balance][], candidacyBond: Balance, desiredSeats: u32, termDuration: BlockNumber, votingBond: Balance): DerivedElectionsInfo {
return {
candidates,
candidateCount: createType(api.registry, 'u32', candidates.length),
candidacyBond,
desiredSeats,
members: members.sort((a, b): number => b[1].cmp(a[1])),
runnersUp: runnersUp.sort((a, b): number => b[1].cmp(a[1])),
termDuration,
votingBond
};
}
function queryElections (api: ApiInterfaceRx): Observable<DerivedElectionsInfo> {
const section = api.query.electionsPhragmen ? 'electionsPhragmen' : 'elections';
// NOTE We have an issue where candidates can return `null` for an empty array, hence
// we are not using multi queries here, so empty array is empty (instead of space-filled)
return combineLatest([
api.query[section].candidates<Vec<AccountId>>(),
api.query[section].members<Vec<ITuple<[AccountId, Balance]>>>(),
api.query[section].runnersUp<Vec<ITuple<[AccountId, Balance]>>>()
return api.queryMulti<[Vec<AccountId>, Vec<ITuple<[AccountId, Balance]>>, Vec<ITuple<[AccountId, Balance]>>]>([
api.query[section].candidates,
api.query[section].members,
api.query[section].runnersUp
]).pipe(
map(([candidates, members, runnersUp]): DerivedElectionsInfo => deriveElections(
api,
map(([candidates, members, runnersUp]): DerivedElectionsInfo => ({
candidates,
members,
runnersUp,
api.consts[section].candidacyBond as Balance,
api.consts[section].desiredMembers as u32,
api.consts[section].termDuration as BlockNumber,
api.consts[section].votingBond as Balance
))
candidateCount: createType(api.registry, 'u32', candidates.length),
candidacyBond: api.consts[section].candidacyBond as Balance,
desiredSeats: api.consts[section].desiredMembers as u32,
members: members.sort((a, b): number => b[1].cmp(a[1])),
runnersUp: runnersUp.sort((a, b): number => b[1].cmp(a[1])),
termDuration: api.consts[section].termDuration as BlockNumber,
votingBond: api.consts[section].votingBond as Balance
}))
);
}
@@ -17,13 +17,15 @@ import { memo } from '../util';
*/
export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<DerivedHeartbeats> {
return memo((): Observable<DerivedHeartbeats> =>
api.query.imOnline?.receivedHeartbeats && api.query.imOnline.authoredBlocks
api.query.imOnline?.receivedHeartbeats
? api.derive.staking.overview().pipe(
switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option<Bytes>[], u32[]]> =>
combineLatest([
of(validators),
api.query.imOnline.receivedHeartbeats.multi<Option<Bytes>>(validators.map((_address, index): [SessionIndex, number] => [currentIndex, index])),
api.query.imOnline.authoredBlocks.multi<u32>(validators.map((address): [SessionIndex, AccountId] => [currentIndex, address]))
api.query.imOnline.receivedHeartbeats.multi<Option<Bytes>>(
validators.map((_address, index): [SessionIndex, number] => [currentIndex, index])),
api.query.imOnline.authoredBlocks.multi<u32>(
validators.map((address): [SessionIndex, AccountId] => [currentIndex, address]))
])
),
map(([validators, heartbeats, numBlocks]): DerivedHeartbeats =>
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { ApiInterfaceRx } from '@polkadot/api/types';
import { BalanceOf, Bid, BidKind } from '@polkadot/types/interfaces';
import { AccountId, BalanceOf, Bid, BidKind } from '@polkadot/types/interfaces';
import { ITuple } from '@polkadot/types/types';
import { DeriveSocietyCandidate } from '../types';
@@ -25,11 +25,8 @@ export function candidates (api: ApiInterfaceRx): () => Observable<DeriveSociety
switchMap((candidates: Vec<Bid>): Observable<Result> =>
combineLatest([
of(candidates),
combineLatest(
candidates.map(({ who }: Bid): Observable<ResultSuspend> =>
api.query.society.suspendedCandidates<ResultSuspend>(who)
)
)
api.query.society.suspendedCandidates.multi<ResultSuspend>(
candidates.map(({ who }): AccountId => who))
])
),
map(([candidates, suspended]: Result): DeriveSocietyCandidate[] =>
+9 -15
View File
@@ -7,33 +7,27 @@ import { AccountId, Balance, BlockNumber, StrikeCount, VouchingStatus, Vote } fr
import { ITuple } from '@polkadot/types/types';
import { DeriveSocietyMember } from '../types';
import { Observable, combineLatest } from 'rxjs';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { bool, Option, Vec } from '@polkadot/types';
import { memo } from '../util';
type ResultMulti = [Vec<ITuple<[BlockNumber, Balance]>>, StrikeCount];
type ResultSingle = [Option<Vote>, bool, Option<VouchingStatus>];
type Result = [ResultMulti, ResultSingle];
type Result = [Vec<ITuple<[BlockNumber, Balance]>>, StrikeCount, Option<Vote>, bool, Option<VouchingStatus>];
/**
* @description Get the member info for a society
*/
export function member (api: ApiInterfaceRx): (accountId: AccountId) => Observable<DeriveSocietyMember> {
return memo((accountId: AccountId): Observable<DeriveSocietyMember> =>
combineLatest([
api.queryMulti<ResultMulti>([
[api.query.society.payouts, accountId],
[api.query.society.strikes, accountId]
]),
combineLatest([
api.query.society.defenderVotes<Option<Vote>>(accountId),
api.query.society.suspendedMembers<bool>(accountId),
api.query.society.vouching<Option<VouchingStatus>>(accountId)
])
api.queryMulti<Result>([
[api.query.society.payouts, accountId],
[api.query.society.strikes, accountId],
[api.query.society.defenderVotes, accountId],
[api.query.society.suspendedMembers, accountId],
[api.query.society.vouching, accountId]
]).pipe(
map(([[payouts, strikes], [defenderVote, suspended, vouching]]: Result): DeriveSocietyMember => ({
map(([payouts, strikes, defenderVote, suspended, vouching]: Result): DeriveSocietyMember => ({
accountId,
payouts,
isSuspended: suspended.isTrue,
+1 -5
View File
@@ -8,7 +8,6 @@ import { DerivedStakingOverview } from '../types';
import { Observable, combineLatest, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { createType } from '@polkadot/types';
import { memo } from '../util';
@@ -24,10 +23,7 @@ export function overview (api: ApiInterfaceRx): () => Observable<DerivedStakingO
switchMap(([{ currentEra, currentIndex, validatorCount }, { currentElected, validators }]) =>
combineLatest([
of({ currentElected, currentEra, currentIndex, validators, validatorCount }),
// this will change on a per block basis, keep it innermost (and it needs eraIndex)
api.query.staking?.currentEraPointsEarned
? api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
: of(createType(api.registry, 'EraPoints'))
api.query.staking.currentEraPointsEarned<EraPoints>(currentEra)
])
),
map(([{ currentElected, currentEra, currentIndex, validators, validatorCount }, eraPoints]): DerivedStakingOverview => ({
@@ -62,10 +62,7 @@ function retrieveProposals (api: ApiInterfaceRx, proposalCount: ProposalIndex, a
const allIds = [...proposalIds, ...approvalIds];
return combineLatest([
// We are doing single subscriptions on all these, multi may yield old results
combineLatest(
allIds.map((id): Observable<Option<TreasuryProposal>> => api.query.treasury.proposals(id))
),
api.query.treasury.proposals.multi<Option<TreasuryProposal>>(allIds),
api.derive.council.proposals()
]).pipe(
map(([allProposals, councilProposals]: [Option<TreasuryProposal>[], DerivedCollectiveProposals]): DerivedTreasuryProposals =>