Export storage prefix on StorageEntry (#1106)
This commit is contained in:
@@ -11,11 +11,12 @@ import createFunction from './createFunction';
|
||||
describe('createFunction', () => {
|
||||
it('should create timestamp.now correctly', () => {
|
||||
expect(
|
||||
createFunction(
|
||||
'Timestamp',
|
||||
'Now',
|
||||
{ type: {} } as any
|
||||
)()
|
||||
createFunction({
|
||||
prefix: 'Timestamp',
|
||||
section: 'timestamp',
|
||||
method: 'Now',
|
||||
meta: { type: {} } as any
|
||||
})()
|
||||
).toEqual(
|
||||
Uint8Array.from([64, 14, 73, 68, 207, 217, 141, 111, 76, 195, 116, 209, 111, 90, 78, 63, 156]) // Length-prefixed
|
||||
);
|
||||
@@ -24,9 +25,12 @@ describe('createFunction', () => {
|
||||
it('allows overrides on key (keeping name)', () => {
|
||||
expect(
|
||||
createFunction(
|
||||
'Substrate',
|
||||
'authorityCount',
|
||||
{ type: {} } as any,
|
||||
{
|
||||
prefix: 'Substrate',
|
||||
section: 'substrate',
|
||||
method: 'authorityCount',
|
||||
meta: { type: {} } as any
|
||||
},
|
||||
{
|
||||
key: ':auth:len',
|
||||
skipHashing: true
|
||||
@@ -40,9 +44,12 @@ describe('createFunction', () => {
|
||||
|
||||
expect(
|
||||
createFunction(
|
||||
'Substrate',
|
||||
'authorityCount',
|
||||
{ type: {} } as any,
|
||||
{
|
||||
prefix: 'Substrate',
|
||||
section: 'substrate',
|
||||
method: 'authorityCount',
|
||||
meta: { type: {} } as any
|
||||
},
|
||||
{
|
||||
key,
|
||||
skipHashing: true
|
||||
@@ -59,9 +66,11 @@ describe('createFunction', () => {
|
||||
describe('the created double map function', () => {
|
||||
let storageFn: StorageEntry;
|
||||
beforeAll(() => {
|
||||
storageFn = createFunction(
|
||||
'GenericAsset',
|
||||
'FreeBalance', {
|
||||
storageFn = createFunction({
|
||||
prefix: 'GenericAsset',
|
||||
section: 'genericAsset',
|
||||
method: 'FreeBalance',
|
||||
meta: {
|
||||
name: 'metaName',
|
||||
type: {
|
||||
isDoubleMap: true,
|
||||
@@ -74,7 +83,7 @@ describe('createFunction', () => {
|
||||
}
|
||||
}
|
||||
} as any
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return correct key', () => {
|
||||
@@ -90,22 +99,24 @@ describe('createFunction', () => {
|
||||
});
|
||||
|
||||
it('allows creates double map function with a Null type key', () => {
|
||||
const storageFn = createFunction(
|
||||
'System',
|
||||
'EventTopics',
|
||||
{
|
||||
type: {
|
||||
isDoubleMap: true,
|
||||
asDoubleMap: {
|
||||
hasher: new StorageHasher('Blake2_256'),
|
||||
key1: new Text('Null'),
|
||||
key2: new Text('Hash'),
|
||||
value: new Text('Vec<(BlockNumber,EventIndex)>'),
|
||||
key2Hasher: new Text('blake2_256')
|
||||
}
|
||||
const storageFn = createFunction({
|
||||
prefix: 'System',
|
||||
section: 'system',
|
||||
method: 'EventTopics',
|
||||
meta: {
|
||||
type: {
|
||||
isDoubleMap: true,
|
||||
asDoubleMap: {
|
||||
hasher: new StorageHasher('Blake2_256'),
|
||||
key1: new Text('Null'),
|
||||
key2: new Text('Hash'),
|
||||
value: new Text('Vec<(BlockNumber,EventIndex)>'),
|
||||
key2Hasher: new Text('blake2_256')
|
||||
}
|
||||
} as any
|
||||
);
|
||||
}
|
||||
} as any
|
||||
});
|
||||
|
||||
// the value of the Null type key does not effect the result
|
||||
expect(u8aToHex(storageFn(['any', [1, 2, 3]]))).toEqual(u8aToHex(storageFn([[1, 2, 3], [1, 2, 3]])));
|
||||
// the value of the not Null type key does effect the result
|
||||
|
||||
@@ -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 { createType, Bytes, Compact, StorageKey, Text, U8a } from '@polkadot/types';
|
||||
import { createType, Bytes, Compact, StorageKey, U8a } from '@polkadot/types';
|
||||
import { PlainType, StorageEntryMetadata, StorageEntryModifier, StorageEntryType } from '@polkadot/types/Metadata/v6/Storage';
|
||||
import { StorageEntry } from '@polkadot/types/primitive/StorageKey';
|
||||
import { assert, isNull, isUndefined, stringLowerFirst, stringToU8a, u8aConcat } from '@polkadot/util';
|
||||
@@ -14,6 +14,13 @@ export interface CreateItemOptions {
|
||||
skipHashing?: boolean; // We don't hash the keys defined in ./substrate.ts
|
||||
}
|
||||
|
||||
export interface CreateItemFn {
|
||||
meta: StorageEntryMetadata;
|
||||
method: string;
|
||||
prefix: string;
|
||||
section: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* From the schema of a function in the module's storage, generate the function
|
||||
* that will return the correct storage key.
|
||||
@@ -24,10 +31,10 @@ export interface CreateItemOptions {
|
||||
* are not known at runtime (from state_getMetadata), they need to be supplied
|
||||
* by us manually at compile time.
|
||||
*/
|
||||
export default function createFunction (section: Text | string, method: Text | string, meta: StorageEntryMetadata, options: CreateItemOptions = {}): StorageEntry {
|
||||
export default function createFunction ({ meta, method, prefix, section }: CreateItemFn, options: CreateItemOptions = {}): StorageEntry {
|
||||
const stringKey = options.key
|
||||
? options.key
|
||||
: `${section.toString()} ${method.toString()}`;
|
||||
: `${prefix} ${method}`;
|
||||
const rawKey = stringToU8a(stringKey);
|
||||
|
||||
// Get the hashing function
|
||||
@@ -46,7 +53,7 @@ export default function createFunction (section: Text | string, method: Text | s
|
||||
// Can only have zero or one argument:
|
||||
// - storage.balances.freeBalance(address)
|
||||
// - storage.timestamp.blockPeriod()
|
||||
const storageFn = (arg?: any): Uint8Array => {
|
||||
const _storageFn = (arg?: any): Uint8Array => {
|
||||
let key = rawKey;
|
||||
|
||||
if (meta.type.isDoubleMap) {
|
||||
@@ -78,6 +85,8 @@ export default function createFunction (section: Text | string, method: Text | s
|
||||
);
|
||||
};
|
||||
|
||||
const storageFn = _storageFn as StorageEntry;
|
||||
|
||||
if (meta.type.isMap && meta.type.asMap.isLinked) {
|
||||
const keyHash = new U8a(hasher(`head of ${stringKey}`));
|
||||
const keyFn: any = () => keyHash;
|
||||
@@ -92,9 +101,10 @@ export default function createFunction (section: Text | string, method: Text | s
|
||||
}
|
||||
|
||||
storageFn.meta = meta;
|
||||
storageFn.method = stringLowerFirst(method.toString());
|
||||
storageFn.section = stringLowerFirst(section.toString());
|
||||
storageFn.method = stringLowerFirst(method);
|
||||
storageFn.prefix = prefix;
|
||||
storageFn.section = section;
|
||||
storageFn.toJSON = (): any => meta.toJSON();
|
||||
|
||||
return storageFn as StorageEntry;
|
||||
return storageFn;
|
||||
}
|
||||
|
||||
@@ -22,10 +22,18 @@ export default function fromMetadata (metadata: Metadata): Storage {
|
||||
}
|
||||
|
||||
const { name, prefix } = moduleMetadata;
|
||||
const section = stringCamelCase(name.toString());
|
||||
|
||||
// For access, we change the index names, i.e. Balances.FreeBalance -> balances.freeBalance
|
||||
result[stringCamelCase(name.toString())] = moduleMetadata.storage.unwrap().reduce((newModule, storageFnMeta) => {
|
||||
newModule[stringLowerFirst(storageFnMeta.name.toString())] = createFunction(prefix, storageFnMeta.name, storageFnMeta);
|
||||
result[section] = moduleMetadata.storage.unwrap().reduce((newModule, meta) => {
|
||||
const method = meta.name.toString();
|
||||
|
||||
newModule[stringLowerFirst(method)] = createFunction({
|
||||
meta,
|
||||
method,
|
||||
prefix: prefix.toString(),
|
||||
section
|
||||
});
|
||||
|
||||
return newModule;
|
||||
}, {} as ModuleStorage);
|
||||
|
||||
@@ -16,14 +16,17 @@ interface SubstrateMetadata {
|
||||
// Small helper function to factorize code on this page.
|
||||
const createRuntimeFunction = (method: string, key: string, { documentation, type }: SubstrateMetadata): StorageEntry =>
|
||||
createFunction(
|
||||
new Text('Substrate'),
|
||||
new Text(method),
|
||||
{
|
||||
documentation: new Vector(Text, [documentation]),
|
||||
modifier: new StorageEntryModifier(1), // default
|
||||
type: new StorageEntryType(type, 0),
|
||||
toJSON: (): any => key
|
||||
} as StorageEntryMetadata,
|
||||
meta: {
|
||||
documentation: new Vector(Text, [documentation]),
|
||||
modifier: new StorageEntryModifier(1), // default
|
||||
type: new StorageEntryType(type, 0),
|
||||
toJSON: (): any => key
|
||||
} as StorageEntryMetadata,
|
||||
method,
|
||||
prefix: 'Substrate',
|
||||
section: 'substrate'
|
||||
},
|
||||
{
|
||||
key,
|
||||
skipHashing: true
|
||||
|
||||
@@ -13,15 +13,16 @@ export interface StorageEntry {
|
||||
headKey?: Uint8Array;
|
||||
meta: MetaV6;
|
||||
method: string;
|
||||
prefix: string;
|
||||
section: string;
|
||||
toJSON: () => any;
|
||||
}
|
||||
|
||||
type Decoded = {
|
||||
interface Decoded {
|
||||
key?: Uint8Array | string;
|
||||
method?: string;
|
||||
section?: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @name StorageKey
|
||||
|
||||
Reference in New Issue
Block a user