Skip to content

Commit

Permalink
Add support for historical BlockNumber rpc methods (#4574)
Browse files Browse the repository at this point in the history
* Add support for historical BlockNumber rpc methods

* Update function description

* Apply suggestions from code review

Co-authored-by: Jaco <[email protected]>
  • Loading branch information
stwiname and jacogr authored Feb 20, 2022
1 parent 5080b26 commit 5da8f21
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
2 changes: 2 additions & 0 deletions packages/api/src/base/Init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ export abstract class Init<ApiType extends ApiTypes> extends Decorate<ApiType> {

this._rpcCore.setRegistrySwap((blockHash: Uint8Array) => this.getBlockRegistry(blockHash));

this._rpcCore.setResolveBlockHash((blockNumber) => firstValueFrom(this._rpcCore.chain.getBlockHash(blockNumber)));

if (this.hasSubscriptions) {
this._rpcCore.provider.on('disconnected', () => this.#onProviderDisconnect());
this._rpcCore.provider.on('error', (e: Error) => this.#onProviderError(e));
Expand Down
22 changes: 19 additions & 3 deletions packages/rpc-core/src/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { Observer } from 'rxjs';
import type { ProviderInterface, ProviderInterfaceCallback } from '@polkadot/rpc-provider/types';
import type { StorageKey, Vec } from '@polkadot/types';
import type { Hash } from '@polkadot/types/interfaces';
import type { AnyJson, Codec, DefinitionRpc, DefinitionRpcExt, DefinitionRpcSub, Registry } from '@polkadot/types/types';
import type { AnyJson, AnyNumber, Codec, DefinitionRpc, DefinitionRpcExt, DefinitionRpcSub, Registry } from '@polkadot/types/types';
import type { Memoized } from '@polkadot/util/types';
import type { RpcInterfaceMethod } from './types';

Expand Down Expand Up @@ -85,6 +85,7 @@ export class RpcCore {
#registryDefault: Registry;

#getBlockRegistry?: (blockHash: Uint8Array) => Promise<{ registry: Registry }>;
#getBlockHash?: (blockNumber: AnyNumber) => Promise<Uint8Array>;

readonly #storageCache = new Map<string, string | null>();

Expand Down Expand Up @@ -146,6 +147,15 @@ export class RpcCore {
});
}

/**
* @description Sets a function to resolve block hash from block number
*/
public setResolveBlockHash (resolveBlockHash: (blockNumber: AnyNumber) => Promise<Uint8Array>): void {
this.#getBlockHash = memoize(resolveBlockHash, {
getInstanceId: () => this.#instanceId
});
}

public addUserInterfaces (userRpc: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>): void {
// add any extra user-defined sections
this.sections.push(...Object.keys(userRpc).filter((k) => !this.sections.includes(k)));
Expand Down Expand Up @@ -202,12 +212,18 @@ export class RpcCore {

// execute the RPC call, doing a registry swap for historic as applicable
const callWithRegistry = async <T> (isScale: boolean, values: unknown[]): Promise<T> => {
const blockHash = hashIndex === -1
const blockId = hashIndex === -1
? null
: values[hashIndex] as (Uint8Array | string | null | undefined);
: values[hashIndex];

const blockHash = blockId && def.params[hashIndex].type === 'BlockNumber'
? await this.#getBlockHash?.(blockId as AnyNumber)
: blockId as (Uint8Array | string | null | undefined);

const { registry } = isScale && blockHash && this.#getBlockRegistry
? await this.#getBlockRegistry(u8aToU8a(blockHash))
: { registry: this.#registryDefault };

const params = this._formatInputs(registry, null, def, values);

// only cache .at(<blockHash>) queries, e.g. where valid blockHash was supplied
Expand Down
6 changes: 6 additions & 0 deletions packages/types/src/interfaces/eth/rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const rpc: DefinitionsRpc = objectSpread({}, netRpc, web3Rpc, {
type: 'EthCallRequest'
},
{
isHistoric: true,
isOptional: true,
name: 'number',
type: 'BlockNumber'
Expand All @@ -87,6 +88,7 @@ export const rpc: DefinitionsRpc = objectSpread({}, netRpc, web3Rpc, {
type: 'EthCallRequest'
},
{
isHistoric: true,
isOptional: true,
name: 'number',
type: 'BlockNumber'
Expand All @@ -107,6 +109,7 @@ export const rpc: DefinitionsRpc = objectSpread({}, netRpc, web3Rpc, {
type: 'H160'
},
{
isHistoric: true,
isOptional: true,
name: 'number',
type: 'BlockNumber'
Expand Down Expand Up @@ -167,6 +170,7 @@ export const rpc: DefinitionsRpc = objectSpread({}, netRpc, web3Rpc, {
type: 'H160'
},
{
isHistoric: true,
isOptional: true,
name: 'number',
type: 'BlockNumber'
Expand Down Expand Up @@ -234,6 +238,7 @@ export const rpc: DefinitionsRpc = objectSpread({}, netRpc, web3Rpc, {
type: 'U256'
},
{
isHistoric: true,
isOptional: true,
name: 'number',
type: 'BlockNumber'
Expand Down Expand Up @@ -287,6 +292,7 @@ export const rpc: DefinitionsRpc = objectSpread({}, netRpc, web3Rpc, {
type: 'H256'
},
{
isHistoric: true,
isOptional: true,
name: 'number',
type: 'BlockNumber'
Expand Down

0 comments on commit 5da8f21

Please sign in to comment.