Add inspect(...args) to storage (#4545)

This commit is contained in:
Jaco
2022-02-08 12:34:01 +02:00
committed by GitHub
parent 0754bc45d3
commit f13462f7cf
8 changed files with 79 additions and 21 deletions
+1 -1
View File
@@ -183,7 +183,7 @@ const formatters: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef, def
},
[TypeDefInfo.Si]: (registry: Registry, typeDef: TypeDef, definitions: Record<string, ModuleTypes>, imports: TypeImports, withShortcut: boolean) => {
return formatType(registry, definitions, (registry).lookup.getTypeDef(typeDef.type), imports, withShortcut);
return formatType(registry, definitions, registry.lookup.getTypeDef(typeDef.type), imports, withShortcut);
},
[TypeDefInfo.Struct]: (registry: Registry, typeDef: TypeDef, definitions: Record<string, ModuleTypes>, imports: TypeImports, withShortcut: boolean) => {
+6
View File
@@ -8,6 +8,12 @@ import type { Registry } from './registry';
export type BareOpts = boolean | Record<string, boolean>;
export interface Inspect {
inner: Inspect[];
name?: string;
value?: Uint8Array;
}
/**
* @name Codec
* @description
+1 -1
View File
@@ -127,7 +127,7 @@ export class GenericCall<A extends AnyTuple = AnyTuple> extends Struct implement
let method = 'unknown.unknown';
try {
const c = (registry).findMetaCall(decoded.callIndex);
const c = registry.findMetaCall(decoded.callIndex);
method = `${c.section}.${c.method}`;
} catch (error) {
+1 -1
View File
@@ -57,7 +57,7 @@ export class GenericEventData extends Tuple implements IEventData {
this.#meta = meta;
this.#method = method;
this.#section = section;
this.#typeDef = fields.map(({ type }) => (registry).lookup.getTypeDef(type));
this.#typeDef = fields.map(({ type }) => registry.lookup.getTypeDef(type));
}
/**
@@ -1,7 +1,7 @@
// Copyright 2017-2022 @polkadot/types authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ICompact, INumber } from '@polkadot/types-codec/types';
import type { ICompact, Inspect, INumber } from '@polkadot/types-codec/types';
import type { StorageEntryMetadataLatest, StorageHasher } from '../../../interfaces/metadata';
import type { StorageEntry, StorageEntryIterator } from '../../../primitive/types';
import type { Registry } from '../../../types';
@@ -46,7 +46,14 @@ export const NO_RAW_ARGS: RawArgs = {
};
/** @internal */
export function createKeyRaw (registry: Registry, itemFn: CreateItemBase, { args, hashers, keys }: RawArgs): Uint8Array {
function assertArgs ({ method, section }: CreateItemFn, { args, keys }: RawArgs): void {
assert(Array.isArray(args), () => `Call to ${stringCamelCase(section || 'unknown')}.${stringCamelCase(method || 'unknown')} needs ${keys.length} arguments`);
assert(args.filter(filterDefined).length === keys.length, () => `Call to ${stringCamelCase(section || 'unknown')}.${stringCamelCase(method || 'unknown')} needs ${keys.length} arguments, found [${args.join(', ')}]`);
}
/** @internal */
export function createKeyRawParts (registry: Registry, itemFn: CreateItemBase, { args, hashers, keys }: RawArgs): [Uint8Array[], Uint8Array[]] {
const extra = new Array<Uint8Array>(keys.length);
for (let i = 0; i < keys.length; i++) {
@@ -55,9 +62,36 @@ export function createKeyRaw (registry: Registry, itemFn: CreateItemBase, { args
);
}
return [
[
xxhashAsU8a(itemFn.prefix, 128),
xxhashAsU8a(itemFn.method, 128)
],
extra
];
}
/** @internal */
export function createKeyInspect (registry: Registry, itemFn: CreateItemFn, args: RawArgs): Inspect {
assertArgs(itemFn, args);
const [prefix, extra] = createKeyRawParts(registry, itemFn, args);
const names = ['module', 'method'].concat(...args.args.map((_, i) => `arg${i}`));
return {
inner: prefix
.concat(...extra)
.map((value, i) => ({ inner: [], name: names[i], value })),
value: new Uint8Array()
};
}
/** @internal */
export function createKeyRaw (registry: Registry, itemFn: CreateItemBase, args: RawArgs): Uint8Array {
const [prefix, extra] = createKeyRawParts(registry, itemFn, args);
return u8aConcat(
xxhashAsU8a(itemFn.prefix, 128),
xxhashAsU8a(itemFn.method, 128),
...prefix,
...extra
);
}
@@ -68,20 +102,36 @@ function filterDefined (a: unknown): boolean {
}
/** @internal */
function createKey (registry: Registry, itemFn: CreateItemFn, { args, hashers, keys }: RawArgs): Uint8Array {
const { method, section } = itemFn;
function createKey (registry: Registry, itemFn: CreateItemFn, args: RawArgs): Uint8Array {
assertArgs(itemFn, args);
assert(Array.isArray(args), () => `Call to ${stringCamelCase(section || 'unknown')}.${stringCamelCase(method || 'unknown')} needs ${keys.length} arguments`);
assert(args.filter(filterDefined).length === keys.length, () => `Call to ${stringCamelCase(section || 'unknown')}.${stringCamelCase(method || 'unknown')} needs ${keys.length} arguments, found [${args.join(', ')}]`);
// as per createKey, always add the length prefix (underlying it is Bytes)
// always add the length prefix (underlying it is Bytes)
return compactAddLength(
createKeyRaw(registry, itemFn, { args, hashers, keys })
createKeyRaw(registry, itemFn, args)
);
}
/** @internal */
function createWStorageFn (registry: Registry, itemFn: CreateItemFn, options: CreateItemOptions): (...args: unknown[]) => Uint8Array {
function createStorageInspect (registry: Registry, itemFn: CreateItemFn, options: CreateItemOptions): (...args: unknown[]) => Inspect {
const { meta: { type } } = itemFn;
return (...args: unknown[]) => {
if (type.isPlain) {
return options.skipHashing
? { inner: [], name: 'encoded', value: u8aToU8a(options.key) }
: createKeyInspect(registry, itemFn, NO_RAW_ARGS);
}
const { hashers, key } = type.asMap;
return hashers.length === 1
? createKeyInspect(registry, itemFn, { args, hashers, keys: [key] })
: createKeyInspect(registry, itemFn, { args, hashers, keys: registry.lookup.getSiType(key).def.asTuple });
};
}
/** @internal */
function createStorageFn (registry: Registry, itemFn: CreateItemFn, options: CreateItemOptions): (...args: unknown[]) => Uint8Array {
const { meta: { type } } = itemFn;
let cacheKey: Uint8Array | null = null;
@@ -104,15 +154,16 @@ function createWStorageFn (registry: Registry, itemFn: CreateItemFn, options: Cr
return hashers.length === 1
? createKey(registry, itemFn, { args, hashers, keys: [key] })
: createKey(registry, itemFn, { args, hashers, keys: (registry).lookup.getSiType(key).def.asTuple });
: createKey(registry, itemFn, { args, hashers, keys: registry.lookup.getSiType(key).def.asTuple });
};
}
/** @internal */
function createWithMeta (registry: Registry, itemFn: CreateItemFn, options: CreateItemOptions): StorageEntry {
const { meta, method, prefix, section } = itemFn;
const storageFn = createWStorageFn(registry, itemFn, options) as StorageEntry;
const storageFn = createStorageFn(registry, itemFn, options) as StorageEntry;
storageFn.inspect = createStorageInspect(registry, itemFn, options);
storageFn.meta = meta;
storageFn.method = stringCamelCase(method);
storageFn.prefix = prefix;
@@ -165,7 +216,7 @@ function extendPrefixedMap (registry: Registry, itemFn: CreateItemFn, storageFn:
const { hashers, key } = type.asMap;
const keysVec = hashers.length === 1
? [key]
: (registry).lookup.getSiType(key).def.asTuple;
: registry.lookup.getSiType(key).def.asTuple;
return new Raw(registry, createKeyRaw(registry, itemFn, { args, hashers: hashers.slice(0, args.length), keys: keysVec.slice(0, args.length) }));
}
+1 -1
View File
@@ -118,7 +118,7 @@ function decodeArgsFromMeta <A extends AnyTuple> (registry: Registry, value: Uin
const { hashers, key } = meta.type.asMap;
const keys = hashers.length === 1
? [key]
: (registry).lookup.getSiType(key).def.asTuple;
: registry.lookup.getSiType(key).def.asTuple;
return decodeHashers(registry, value, hashers.map((h, i) => [h, keys[i]]));
}
+2 -1
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
import type { StorageEntryMetadataLatest } from '../interfaces/metadata';
import type { Codec } from '../types';
import type { Codec, Inspect } from '../types';
export interface StorageEntryIterator {
(...args: unknown[]): Uint8Array & Codec;
@@ -12,6 +12,7 @@ export interface StorageEntryIterator {
export interface StorageEntry {
(...args: unknown[]): Uint8Array;
iterKey?: StorageEntryIterator;
inspect: (...args: unknown[]) => Inspect;
keyPrefix: (...args: unknown[]) => Uint8Array;
meta: StorageEntryMetadataLatest;
method: string;
+1 -1
View File
@@ -3,7 +3,7 @@
import type { Codec } from '@polkadot/types-codec/types';
export type { AnyJson, AnyFunction, AnyNumber, AnyString, AnyTuple, AnyU8a, ArgsDef, BareOpts, Codec, CodecClass, CodecClass as Constructor, CodecTo } from '@polkadot/types-codec/types';
export type { AnyJson, AnyFunction, AnyNumber, AnyString, AnyTuple, AnyU8a, ArgsDef, BareOpts, Codec, CodecClass, CodecClass as Constructor, CodecTo, Inspect } from '@polkadot/types-codec/types';
// helper to extract keys from an array
export type ArrayElementType<T extends ReadonlyArray<unknown>> = T extends ReadonlyArray<infer ElementType>