Allow switching on/off of isPedantic checks (#5620)
* Allow switching on/off of isPedantic checks * CHANGELOG * typos
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}`);
|
||||
}
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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> => {
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
Reference in New Issue
Block a user