diff --git a/packages/app-staking/src/useSessionRewards.tsx b/packages/app-staking/src/useSessionRewards.tsx index dccaa8e92539..41221c1cb55d 100644 --- a/packages/app-staking/src/useSessionRewards.tsx +++ b/packages/app-staking/src/useSessionRewards.tsx @@ -2,7 +2,7 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { Balance, BlockNumber, EventRecord, Hash, Header } from '@polkadot/types/interfaces'; +import { Balance, EventRecord, Hash, Header, StorageChangeSet } from '@polkadot/types/interfaces'; import { Slash, SessionRewards } from '@polkadot/react-hooks/types'; import BN from 'bn.js'; @@ -66,7 +66,10 @@ function mergeResults (sessions: SessionRewards[], newSessions: SessionRewards[] } async function loadSome (api: ApiPromise, fromHash: Hash, toHash: Hash): Promise { - const results = await api.rpc.state.queryStorage([api.query.session.currentIndex.key()], fromHash, toHash); + // query a range of blocks - on non-archive nodes this will fail, so return an empty set + const results = await api.rpc.state + .queryStorage([api.query.session.currentIndex.key()], fromHash, toHash) + .catch((): StorageChangeSet[] => []); const headers = await Promise.all( results.map(({ block }): Promise
=> api.rpc.chain.getHeader(block)) ); @@ -93,16 +96,20 @@ async function loadSome (api: ApiPromise, fromHash: Hash, toHash: Hash): Promise return rewards[0]?.event?.data[0] as Balance; }); - return results.map(({ changes: [[, value]] }, index): SessionRewards => ({ - blockHash: headers[index].hash, - blockNumber: headers[index].number.unwrap(), - isEventsEmpty: events[index].length === 0, - reward: rewards[index] || createType('Balance'), - sessionIndex: createType('SessionIndex', u8aToU8a( - value.isSome ? value.unwrap() : new Uint8Array([]) - )), - slashes: slashes[index] - })); + // For old v1, the query results have empty spots (subsequently fixed in v2), + // filter these before trying to extract the results + return results + .filter(({ changes }): boolean => !!(changes && changes.length)) + .map(({ changes: [[, value]] }, index): SessionRewards => ({ + blockHash: headers[index].hash, + blockNumber: headers[index].number.unwrap(), + isEventsEmpty: events[index].length === 0, + reward: rewards[index] || createType('Balance'), + sessionIndex: createType('SessionIndex', u8aToU8a( + value.isSome ? value.unwrap() : new Uint8Array([]) + )), + slashes: slashes[index] + })); } export default function useSessionRewards (maxSessions: number): SessionRewards[] { @@ -116,7 +123,7 @@ export default function useSessionRewards (maxSessions: number): SessionRewards[ setImmediate((): void => { api.isReady.then(async (): Promise => { const maxSessionsStore = maxSessions + 1; // assuming first is a bust - const sessionLength = (api.consts.babe?.epochDuration as BlockNumber || new BN(500)); + const sessionLength = api.consts.babe?.epochDuration || new BN(500); const count = Math.min(sessionLength.muln(maxSessionsStore).divn(10).toNumber(), 10000); const bestHeader = await api.rpc.chain.getHeader(); let toHash = bestHeader.hash;