Retrieve heartbeats for all validators (#1527)
* Retrieve heartbeats for all validators * Tested, confirmed working
This commit is contained in:
@@ -27,12 +27,11 @@ import { drr } from '../util/drr';
|
||||
*/
|
||||
export function idToIndex (api: ApiInterfaceRx): (accountId: AccountId | string) => Observable<AccountIndex | undefined> {
|
||||
return (accountId: AccountId | string): Observable<AccountIndex | undefined> =>
|
||||
indexes(api)()
|
||||
.pipe(
|
||||
startWith({}),
|
||||
map((indexes: AccountIndexes): AccountIndex | undefined =>
|
||||
(indexes || {})[accountId.toString()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
indexes(api)().pipe(
|
||||
startWith({}),
|
||||
map((indexes: AccountIndexes): AccountIndex | undefined =>
|
||||
(indexes || {})[accountId.toString()]
|
||||
),
|
||||
drr()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,8 @@ export function indexToId (api: ApiInterfaceRx): (accountIndex: AccountIndex | s
|
||||
? _accountIndex
|
||||
: createType('AccountIndex', _accountIndex);
|
||||
|
||||
return (querySection.enumSet<Vec<AccountId>>(accountIndex.div(ENUMSET_SIZE)))
|
||||
return querySection
|
||||
.enumSet<Vec<AccountId>>(accountIndex.div(ENUMSET_SIZE))
|
||||
.pipe(
|
||||
startWith([]),
|
||||
map((accounts): AccountId | undefined =>
|
||||
|
||||
@@ -33,7 +33,8 @@ const enumsetSize = ENUMSET_SIZE.toNumber();
|
||||
*/
|
||||
export function indexes (api: ApiInterfaceRx): () => Observable<AccountIndexes> {
|
||||
return (): Observable<AccountIndexes> => {
|
||||
return (api.query.indices.nextEnumSet<AccountIndex>())
|
||||
return api.query.indices
|
||||
.nextEnumSet<AccountIndex>()
|
||||
.pipe(
|
||||
// use the nextEnumSet (which is a counter of the number of sets) to construct
|
||||
// a range of values to query [0, 1, 2, ...]. Retrieve the full enum set for the
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { AccountId, SessionIndex } from '@polkadot/types/interfaces';
|
||||
import { DerivedHeartbeats } from '../types';
|
||||
|
||||
import { of, Observable } from 'rxjs';
|
||||
import { of, Observable, combineLatest } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Bytes, Vec } from '@polkadot/types';
|
||||
@@ -14,25 +15,29 @@ import { drr } from '../util/drr';
|
||||
/**
|
||||
* @description Return a boolean array indicating whether the passed accounts had received heartbeats in the current session
|
||||
*/
|
||||
export function receivedHeartbeats (api: ApiInterfaceRx): (addresses: (AccountId | string)[]) => Observable<boolean[]> {
|
||||
return (addresses: (AccountId | string)[]): Observable<boolean[]> => {
|
||||
export function receivedHeartbeats (api: ApiInterfaceRx): () => Observable<DerivedHeartbeats> {
|
||||
return (): Observable<DerivedHeartbeats> => {
|
||||
return api.query.imOnline && api.query.imOnline.receivedHeartbeats
|
||||
? api.queryMulti<[SessionIndex, Vec<AccountId>]>([
|
||||
api.query.session.currentIndex,
|
||||
api.query.imOnline.keys
|
||||
? api.queryMulti<[Vec<AccountId>, SessionIndex]>([
|
||||
api.query.imOnline.keys,
|
||||
api.query.session.currentIndex
|
||||
]).pipe(
|
||||
switchMap(([currentIndex, keys]): Observable<Bytes[]> =>
|
||||
api.query.imOnline.receivedHeartbeats.multi(
|
||||
addresses.map((address): [SessionIndex, number] =>
|
||||
[currentIndex, keys.indexOf(address)]
|
||||
switchMap(([keys, currentIndex]): Observable<[AccountId[], Bytes[]]> =>
|
||||
combineLatest([
|
||||
of(keys),
|
||||
api.query.imOnline.receivedHeartbeats.multi<Bytes>(
|
||||
keys.map((_address, index): [SessionIndex, number] => [currentIndex, index])
|
||||
)
|
||||
)
|
||||
])
|
||||
),
|
||||
map((heartbeats): boolean[] =>
|
||||
heartbeats.map((heartbeat): boolean => !heartbeat.isEmpty)
|
||||
map(([keys, heartbeats]): DerivedHeartbeats =>
|
||||
keys.reduce((result: DerivedHeartbeats, key, index): DerivedHeartbeats => ({
|
||||
...result,
|
||||
[key.toString()]: !!heartbeats[index] && !heartbeats[index].isEmpty
|
||||
}), {})
|
||||
),
|
||||
drr()
|
||||
)
|
||||
: of([...new Array(addresses.length).keys()].map((): boolean => false));
|
||||
: of({});
|
||||
};
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ export interface DerivedFees {
|
||||
transferFee: Balance;
|
||||
}
|
||||
|
||||
export type DerivedHeartbeats = Record<string, boolean>;
|
||||
|
||||
export interface RecentlyOffline {
|
||||
blockNumber: BlockNumber;
|
||||
count: BN;
|
||||
|
||||
Reference in New Issue
Block a user