Improve voter derive calls (#1181)

* voterPositions

* cleanup

* rename var

* changes

* export VoterPosition
This commit is contained in:
kwingram25
2019-07-24 19:46:05 +01:00
committed by GitHub
parent 8bafdc7596
commit e1cf002a76
6 changed files with 80 additions and 60 deletions
+1 -1
View File
@@ -6,4 +6,4 @@ export * from './approvalsOf';
export * from './approvalsOfAt';
export * from './info';
export * from './voters';
export * from './voterSets';
export * from './voterPositions';
+4 -2
View File
@@ -34,12 +34,13 @@ export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInf
api.query.elections.candidates,
api.query.elections.candidateCount,
api.query.elections.desiredSeats,
api.query.elections.nextVoterSet,
api.query.elections.termDuration,
api.query.elections.voteCount,
api.query.elections.voterCount
]) as any as Observable<[[AccountId, BlockNumber][], AccountId[], BN, BN, BlockNumber, VoteIndex, SetIndex]>
]) 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<string, BlockNumber>, [accountId, blockNumber]): Record<string, BlockNumber> => {
record[accountId.toString()] = blockNumber;
@@ -50,6 +51,7 @@ export function info (api: ApiInterfaceRx): () => Observable<DerivedElectionsInf
candidates,
candidateCount,
desiredSeats,
nextVoterSet,
termDuration,
voteCount,
voterCount
@@ -0,0 +1,57 @@
// 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 { AccountId, Vector, Option, createType } from '@polkadot/types';
import { DerivedVoterPositions } from '../types';
import BN from 'bn.js';
import { of, combineLatest, Observable } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';
import { drr } from '../util/drr';
/**
* @name voterPositions
* @returns An mapping of all current voter accounts to their voter set and global index.
* @example
* <BR>
*
* ```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<DerivedVoterPositions> {
return (): Observable<DerivedVoterPositions> =>
api.query.elections.nextVoterSet<SetIndex>().pipe(
switchMap((nextVoterSet: SetIndex): Observable<[BN, Vector<Option<AccountId>>[]]> => combineLatest(
of(api.consts.elections.voterSetSize) as any as Observable<BN>,
api.query.elections.voters.multi([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i])) as any as Observable<Vector<Option<AccountId>>[]>
)),
map((result: [BN, Vector<Option<AccountId>>[]]): 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', setIndex)
};
}
});
return result;
}, {});
}),
drr()
);
}
@@ -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
* <BR>
*
* ```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<Record<string, SetIndex>> {
return (): Observable<Record<string, SetIndex>> =>
api.query.elections.nextVoterSet<SetIndex>().pipe(
switchMap((nextVoterSet: SetIndex): Observable<Vector<Option<AccountId>>[]> =>
api.query.elections.voters.multi([...Array(+nextVoterSet + 1).keys()].map((_, i): [number] => [i])) as any as Observable<Vector<Option<AccountId>>[]>
),
map((voters: Vector<Option<AccountId>>[]): Record<string, SetIndex> =>
voters.reduce((result: Record<string, SetIndex>, vec, setIndex): Record<string, SetIndex> => {
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', setIndex);
}
});
return result;
}, {})
),
drr()
);
}
+9 -9
View File
@@ -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<Vector<AccountId>> {
return (): Observable<Vector<AccountId>> =>
voterSets(api)().pipe(
voterPositions(api)().pipe(
map(
(voterSets: Record<string, SetIndex>): Vector<AccountId> =>
(voterPositions: DerivedVoterPositions): Vector<AccountId> =>
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()