Allow switching on/off of isPedantic checks (#5620)

* Allow switching on/off of isPedantic checks

* CHANGELOG

* typos
This commit is contained in:
Jaco
2023-04-28 10:37:27 +03:00
committed by GitHub
parent ac46305d15
commit 1ba4c0c277
8 changed files with 42 additions and 23 deletions
+9 -6
View File
@@ -139,19 +139,22 @@ export abstract class Decorate<ApiType extends ApiTypes> extends Events {
this._rx.queryAt = (blockHash: Uint8Array | string, knownVersion?: RuntimeVersion) =>
from(this.at(blockHash, knownVersion)).pipe(map((a) => a.rx.query));
this._rx.registry = this.#registry;
this._decorateMethod = decorateMethod;
this._options = options;
this._type = type;
const thisProvider = options.source
const provider = options.source
? options.source._rpcCore.provider.isClonable
? options.source._rpcCore.provider.clone()
: options.source._rpcCore.provider
: (options.provider || new WsProvider());
this._decorateMethod = decorateMethod;
this._options = options;
this._type = type;
// The RPC interface decorates the known interfaces on init
this._rpcCore = new RpcCore(this.#instanceId, this.#registry, thisProvider, this._options.rpc) as (RpcCore & RpcInterface);
this._rpcCore = new RpcCore(this.#instanceId, this.#registry, {
isPedantic: this._options.isPedantic,
provider,
userRpc: this._options.rpc
}) as (RpcCore & RpcInterface);
this._isConnected = new BehaviorSubject(this._rpcCore.provider.isConnected);
this._rx.hasSubscriptions = this._rpcCore.provider.hasSubscriptions;
}
+4
View File
@@ -47,6 +47,10 @@ export interface ApiOptions extends RegisteredTypes {
* @description Control the initialization of the wasm libraries. When not specified, it defaults to `true`, initializing the wasm libraries, set to `false` to not initialize wasm. (No sr25519 support)
*/
initWasm?: boolean;
/**
* @description Controls the checking of storage values once they have been contructed. When not specified this defaults to `true`. Set to `false` to forgo any checking on storage results.
*/
isPedantic?: boolean;
/**
* @description pre-bundles is a map of 'genesis hash and runtime spec version' as key to a metadata hex string
* if genesis hash and runtime spec version matches, then use metadata, else fetch it from chain
+14 -7
View File
@@ -29,6 +29,12 @@ type MemoizedRpcInterfaceMethod = Memoized<RpcInterfaceMethod> & {
meta: DefinitionRpc;
}
interface Options {
isPedantic?: boolean;
provider: ProviderInterface;
userRpc?: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>>;
}
const l = logger('rpc-core');
const EMPTY_META = {
@@ -84,14 +90,14 @@ function isTreatAsHex (key: StorageKey): boolean {
* ```
*/
export class RpcCore {
#instanceId: string;
#registryDefault: Registry;
readonly #instanceId: string;
readonly #isPedantic: boolean;
readonly #registryDefault: Registry;
readonly #storageCache = new Map<string, Codec>();
#getBlockRegistry?: (blockHash: Uint8Array) => Promise<{ registry: Registry }>;
#getBlockHash?: (blockNumber: AnyNumber) => Promise<Uint8Array>;
readonly #storageCache = new Map<string, Codec>();
readonly mapping = new Map<string, DefinitionRpcExt>();
readonly provider: ProviderInterface;
readonly sections: string[] = [];
@@ -101,13 +107,14 @@ export class RpcCore {
* Default constructor for the core RPC handler
* @param {ProviderInterface} provider An API provider using any of the supported providers (HTTP, SC or WebSocket)
*/
constructor (instanceId: string, registry: Registry, provider: ProviderInterface, userRpc: Record<string, Record<string, DefinitionRpc | DefinitionRpcSub>> = {}) {
constructor (instanceId: string, registry: Registry, { isPedantic = true, provider, userRpc = {} }: Options) {
// eslint-disable-next-line @typescript-eslint/unbound-method
if (!provider || !isFunction(provider.send)) {
throw new Error('Expected Provider to API create');
}
this.#instanceId = instanceId;
this.#isPedantic = isPedantic;
this.#registryDefault = registry;
this.provider = provider;
@@ -484,9 +491,9 @@ export class RpcCore {
: hexToU8a(meta.fallback.toHex())
: undefined
: meta.modifier.isOptional
? registry.createTypeUnsafe(type, [input], { blockHash, isPedantic: true })
? registry.createTypeUnsafe(type, [input], { blockHash, isPedantic: this.#isPedantic })
: input
], { blockHash, isFallback: isEmpty && !!meta.fallback, isOptional: meta.modifier.isOptional, isPedantic: !meta.modifier.isOptional });
], { blockHash, isFallback: isEmpty && !!meta.fallback, isOptional: meta.modifier.isOptional, isPedantic: this.#isPedantic && !meta.modifier.isOptional });
} catch (error) {
throw new Error(`Unable to decode storage ${key.section || 'unknown'}.${key.method || 'unknown'}:${entryNum}: ${(error as Error).message}`);
}
+1 -1
View File
@@ -19,7 +19,7 @@ describe('Cached Observables', (): void => {
beforeEach((): void => {
provider = new MockProvider(registry);
rpc = new RpcCore('123', registry, provider) as (RpcCore & RpcInterface);
rpc = new RpcCore('123', registry, { provider }) as (RpcCore & RpcInterface);
});
afterEach(async () => {
+10 -7
View File
@@ -16,18 +16,21 @@ describe('Api', (): void => {
it('requires a provider with a send method', (): void => {
expect(
() => new RpcCore('234', registry, {} as unknown as ProviderInterface)
() => new RpcCore('234', registry, { provider: {} as unknown as ProviderInterface })
).toThrow(/Expected Provider/);
});
it('allows for the definition of user RPCs', async () => {
const provider = new MockProvider(registry);
const rpc = new RpcCore('567', registry, provider, {
testing: {
foo: {
description: 'foo',
params: [{ name: 'bar', type: 'u32' }],
type: 'Balance'
const rpc = new RpcCore('567', registry, {
provider,
userRpc: {
testing: {
foo: {
description: 'foo',
params: [{ name: 'bar', type: 'u32' }],
type: 'Balance'
}
}
}
});
+1 -1
View File
@@ -38,7 +38,7 @@ describe('methodSend', (): void => {
)
} as unknown as ProviderInterface;
rpc = new RpcCore('987', registry, provider);
rpc = new RpcCore('987', registry, { provider });
});
it('checks for mismatched parameters', async (): Promise<void> => {
+1 -1
View File
@@ -17,7 +17,7 @@ describe('replay', (): void => {
beforeEach((): void => {
provider = new MockProvider(registry);
rpc = new RpcCore('653', registry, provider) as (RpcCore & RpcInterface);
rpc = new RpcCore('653', registry, { provider }) as (RpcCore & RpcInterface);
});
afterEach(async () => {