From e1cf002a7609a574081da204d3bfba9142f198a5 Mon Sep 17 00:00:00 2001 From: kwingram25 Date: Wed, 24 Jul 2019 19:46:05 +0100 Subject: [PATCH] Improve voter derive calls (#1181) * voterPositions * cleanup * rename var * changes * export VoterPosition --- packages/api-derive/src/elections/index.ts | 2 +- packages/api-derive/src/elections/info.ts | 6 +- .../src/elections/voterPositions.ts | 57 +++++++++++++++++++ .../api-derive/src/elections/voterSets.ts | 48 ---------------- packages/api-derive/src/elections/voters.ts | 18 +++--- packages/api-derive/src/types.ts | 9 +++ 6 files changed, 80 insertions(+), 60 deletions(-) create mode 100644 packages/api-derive/src/elections/voterPositions.ts delete mode 100644 packages/api-derive/src/elections/voterSets.ts diff --git a/packages/api-derive/src/elections/index.ts b/packages/api-derive/src/elections/index.ts index d68257b380..e1eadbf697 100644 --- a/packages/api-derive/src/elections/index.ts +++ b/packages/api-derive/src/elections/index.ts @@ -6,4 +6,4 @@ export * from './approvalsOf'; export * from './approvalsOfAt'; export * from './info'; export * from './voters'; -export * from './voterSets'; +export * from './voterPositions'; diff --git a/packages/api-derive/src/elections/info.ts b/packages/api-derive/src/elections/info.ts index 3140a6c4eb..5f52123c93 100644 --- a/packages/api-derive/src/elections/info.ts +++ b/packages/api-derive/src/elections/info.ts @@ -34,12 +34,13 @@ export function info (api: ApiInterfaceRx): () => Observable + ]) as any as Observable<[[AccountId, BlockNumber][], AccountId[], BN, BN, SetIndex, BlockNumber, VoteIndex, SetIndex]> ).pipe( - map(([members, candidates, candidateCount, desiredSeats, termDuration, voteCount, voterCount]): DerivedElectionsInfo => ({ + map(([members, candidates, candidateCount, desiredSeats, nextVoterSet, termDuration, voteCount, voterCount]): DerivedElectionsInfo => ({ members: members.reduce( (record: Record, [accountId, blockNumber]): Record => { record[accountId.toString()] = blockNumber; @@ -50,6 +51,7 @@ export function info (api: ApiInterfaceRx): () => Observable + * + * ```javascript + * api.derive.elections.voterPositions((voters) => { + * const { index, setIndex, globalIndex } = voters[ALICE]; + * console.log(`ALICE is a voter at index ${index} in voter set ${setIndex}, with global index ${globalIndex}.`); + * }); + * ``` + */ +export function voterPositions (api: ApiInterfaceRx): () => Observable { + return (): Observable => + api.query.elections.nextVoterSet().pipe( + switchMap((nextVoterSet: SetIndex): Observable<[BN, Vector>[]]> => combineLatest( + of(api.consts.elections.voterSetSize) as any as Observable, + api.query.elections.voters.multi([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i])) as any as Observable>[]> + )), + map((result: [BN, Vector>[]]): DerivedVoterPositions => { + const [setSize, voters] = result; + return voters.reduce((result: DerivedVoterPositions, vec, setIndex): DerivedVoterPositions => { + vec.forEach((e, index): void => { + // re-create the index based on position 0 is [0][0] and likewise + // 64 (0..63 in first) is [1][0] (the first index value in set 2) + const accountId: AccountId | null = e.unwrapOr(null); + + if (accountId) { + result[accountId.toString()] = { + globalIndex: setSize.muln(setIndex).addn(index), + index: new BN(index), + setIndex: createType('SetIndex', setIndex) + }; + } + }); + + return result; + }, {}); + }), + drr() + ); +} diff --git a/packages/api-derive/src/elections/voterSets.ts b/packages/api-derive/src/elections/voterSets.ts deleted file mode 100644 index 27d8a90efa..0000000000 --- a/packages/api-derive/src/elections/voterSets.ts +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2017-2019 @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 { SetIndex } from '@polkadot/types/srml/elections/types'; - -import { ApiInterfaceRx } from '@polkadot/api/types'; -import { Observable } from 'rxjs'; -import { AccountId, Vector, Option, createType } from '@polkadot/types'; -import { switchMap, map } from 'rxjs/operators'; -import { drr } from '../util/drr'; - -/** - * @name voterSets - * @returns An mapping of all current voter accounts to their voter set index. - * @example - *
- * - * ```javascript - * api.derive.elections.voterSets((voters) => { - * console.log(`ALICE is a voter in the voter set with index ${voters[ALICE].toString()}.`); - * }); - * ``` - */ -export function voterSets (api: ApiInterfaceRx): () => Observable> { - return (): Observable> => - api.query.elections.nextVoterSet().pipe( - switchMap((nextVoterSet: SetIndex): Observable>[]> => - api.query.elections.voters.multi([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i])) as any as Observable>[]> - ), - map((voters: Vector>[]): Record => - voters.reduce((result: Record, vec, setIndex): Record => { - vec.forEach((e): void => { - // re-create the index based on position 0 is [0][0] and likewise - // 64 (0..63 in first) is [1][0] (the first index value in set 2) - const accountId: AccountId | null = e.unwrapOr(null); - - if (accountId) { - result[accountId.toString()] = createType('SetIndex', setIndex); - } - }); - - return result; - }, {}) - ), - drr() - ); -} diff --git a/packages/api-derive/src/elections/voters.ts b/packages/api-derive/src/elections/voters.ts index 734777fa3b..f248dc0ab1 100644 --- a/packages/api-derive/src/elections/voters.ts +++ b/packages/api-derive/src/elections/voters.ts @@ -2,14 +2,14 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { SetIndex } from '@polkadot/types/srml/elections/types'; - import { ApiInterfaceRx } from '@polkadot/api/types'; -import { Observable } from 'rxjs'; import { AccountId, Vector } from '@polkadot/types'; +import { DerivedVoterPositions } from '../types'; + +import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { drr } from '../util/drr'; -import { voterSets } from './voterSets'; +import { voterPositions } from './voterPositions'; /** * @name voters @@ -25,14 +25,14 @@ import { voterSets } from './voterSets'; */ export function voters (api: ApiInterfaceRx): () => Observable> { return (): Observable> => - voterSets(api)().pipe( + voterPositions(api)().pipe( map( - (voterSets: Record): Vector => + (voterPositions: DerivedVoterPositions): Vector => new Vector( AccountId, - Object.keys(voterSets).map( - (address: string): AccountId => new AccountId(address) - ) + Object.entries(voterPositions) + .sort((a, b): 0 | 1 | -1 => a[1].globalIndex.cmp(b[1].globalIndex)) + .map(([accountId]): AccountId => new AccountId(accountId)) ) ), drr() diff --git a/packages/api-derive/src/types.ts b/packages/api-derive/src/types.ts index 5a121a5c4a..34f4e21050 100644 --- a/packages/api-derive/src/types.ts +++ b/packages/api-derive/src/types.ts @@ -38,6 +38,7 @@ export interface DerivedElectionsInfo { candidates: AccountId[]; candidateCount: BN; desiredSeats: BN; + nextVoterSet: SetIndex; termDuration: BlockNumber; voteCount: VoteIndex; voterCount: SetIndex; @@ -85,3 +86,11 @@ export interface DerivedStaking { } export type DerivedUnlocking = { remainingBlocks: BN; value: BN }[]; + +export interface VoterPosition { + globalIndex: BN; + index: BN; + setIndex: SetIndex; +} + +export type DerivedVoterPositions = Record;