diff --git a/CHANGELOG.md b/CHANGELOG.md index 27367c7051..205e1df8a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## 1.33.0-beta.x + +Changes: + +- Optimize derive `receivedHeartbeats` to not re-create the full object + + ## 1.32.1 Sep 7, 2020 Upgrade priority: Low. Recommended when manually using provider connect/disconnect or using multiple instances in a single process. diff --git a/packages/api-derive/src/imOnline/receivedHeartbeats.ts b/packages/api-derive/src/imOnline/receivedHeartbeats.ts index 8d18672d78..6998e46e51 100644 --- a/packages/api-derive/src/imOnline/receivedHeartbeats.ts +++ b/packages/api-derive/src/imOnline/receivedHeartbeats.ts @@ -13,6 +13,25 @@ import { BN_ZERO } from '@polkadot/util'; import { memo } from '../util'; +function mapResult ([result, validators, heartbeats, numBlocks]: [DeriveHeartbeats, AccountId[], Option[], u32[]]): DeriveHeartbeats { + validators.forEach((validator, index): void => { + const validatorId = validator.toString(); + const blockCount = numBlocks[index]; + const hasMessage = !heartbeats[index].isEmpty; + const prev = result[validatorId]; + + if (!prev || prev.hasMessage !== hasMessage || !prev.blockCount.eq(blockCount)) { + result[validatorId] = { + blockCount, + hasMessage, + isOnline: hasMessage || blockCount.gt(BN_ZERO) + }; + } + }); + + return result; +} + /** * @description Return a boolean array indicating whether the passed accounts had received heartbeats in the current session */ @@ -20,8 +39,9 @@ export function receivedHeartbeats (instanceId: string, api: ApiInterfaceRx): () return memo(instanceId, (): Observable => api.query.imOnline?.receivedHeartbeats ? api.derive.staking.overview().pipe( - switchMap(({ currentIndex, validators }): Observable<[AccountId[], Option[], u32[]]> => + switchMap(({ currentIndex, validators }): Observable<[DeriveHeartbeats, AccountId[], Option[], u32[]]> => combineLatest([ + of({}), of(validators), api.query.imOnline.receivedHeartbeats.multi>( validators.map((_address, index) => [currentIndex, index])), @@ -29,16 +49,8 @@ export function receivedHeartbeats (instanceId: string, api: ApiInterfaceRx): () validators.map((address) => [currentIndex, address])) ]) ), - map(([validators, heartbeats, numBlocks]): DeriveHeartbeats => - validators.reduce((result: DeriveHeartbeats, validator, index): DeriveHeartbeats => ({ - ...result, - [validator.toString()]: { - blockCount: numBlocks[index], - hasMessage: !heartbeats[index].isEmpty, - isOnline: !heartbeats[index].isEmpty || numBlocks[index].gt(BN_ZERO) - } - }), {}) - ) + map(mapResult) ) - : of({})); + : of({}) + ); }