Improve voter derive calls (#1181)
* voterPositions * cleanup * rename var * changes * export VoterPosition
This commit is contained in:
@@ -6,4 +6,4 @@ export * from './approvalsOf';
|
||||
export * from './approvalsOfAt';
|
||||
export * from './info';
|
||||
export * from './voters';
|
||||
export * from './voterSets';
|
||||
export * from './voterPositions';
|
||||
|
||||
@@ -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()
|
||||
);
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user