Add .range([from, to?], ...args) on storage queries (#1979)

* Add .between(from, to) ot storage queries

* between -> range

* CHANGELOG

* checkTypes.manual

* Tested as working
This commit is contained in:
Jaco Greeff
2020-03-01 09:12:17 +01:00
committed by GitHub
parent 96700eef5d
commit f59cb12ec7
18 changed files with 124 additions and 90 deletions
+1 -1
View File
@@ -30,7 +30,7 @@
"@polkadot/api": "1.5.0-beta.20",
"@polkadot/rpc-core": "1.5.0-beta.20",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util": "^2.6.1",
"bn.js": "^5.1.1",
"rxjs": "^6.5.4"
}
+3 -3
View File
@@ -32,13 +32,13 @@
"@polkadot/rpc-core": "1.5.0-beta.20",
"@polkadot/rpc-provider": "1.5.0-beta.20",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"bn.js": "^5.1.1",
"memoizee": "^0.4.14",
"rxjs": "^6.5.4"
},
"devDependencies": {
"@polkadot/keyring": "^2.5.1"
"@polkadot/keyring": "^2.6.1"
}
}
+4 -4
View File
@@ -28,18 +28,18 @@
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/api-derive": "1.5.0-beta.20",
"@polkadot/keyring": "^2.5.1",
"@polkadot/keyring": "^2.6.1",
"@polkadot/metadata": "1.5.0-beta.20",
"@polkadot/rpc-core": "1.5.0-beta.20",
"@polkadot/rpc-provider": "1.5.0-beta.20",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"bn.js": "^5.1.1",
"eventemitter3": "^4.0.0",
"rxjs": "^6.5.4"
},
"devDependencies": {
"@polkadot/keyring": "^2.5.1"
"@polkadot/keyring": "^2.6.1"
}
}
+20 -2
View File
@@ -4,7 +4,7 @@
import { Constants, Storage } from '@polkadot/metadata/Decorated/types';
import { RpcInterface } from '@polkadot/rpc-core/types';
import { Call, Hash, RuntimeVersion } from '@polkadot/types/interfaces';
import { Call, Hash, RuntimeVersion, StorageChangeSet } from '@polkadot/types/interfaces';
import { AnyFunction, CallFunction, Codec, CodecArg as Arg, ITuple, InterfaceTypes, ModulesWithCalls, Registry, RegistryTypes } from '@polkadot/types/types';
import { SubmittableExtrinsic } from '../submittable/types';
import { ApiInterfaceRx, ApiOptions, ApiTypes, DecorateMethod, DecoratedRpc, DecoratedRpcSection, QueryableModuleStorage, QueryableStorage, QueryableStorageEntry, QueryableStorageMulti, QueryableStorageMultiArg, SubmittableExtrinsicFunction, SubmittableExtrinsics, SubmittableModuleExtrinsics } from '../types';
@@ -20,7 +20,7 @@ import { WsProvider } from '@polkadot/rpc-provider';
import { Metadata, Null, Option, Text, TypeRegistry, u64, Vec } from '@polkadot/types';
import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage';
import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/extrinsic/constants';
import StorageKey, { StorageEntry } from '@polkadot/types/primitive/StorageKey';
import StorageKey, { StorageEntry, unwrapStorageType } from '@polkadot/types/primitive/StorageKey';
import { assert, compactStripLength, isNull, isUndefined, u8aConcat, u8aToHex } from '@polkadot/util';
import { createSubmittable } from '../submittable';
@@ -332,12 +332,30 @@ export default abstract class Decorate<ApiType extends ApiTypes> extends Events
args.map((arg: Arg[] | Arg): [StorageEntry, Arg | Arg[]] => [creator, arg])));
}
decorated.range = decorateMethod((range: [Hash, Hash?], arg1?: Arg, arg2?: Arg): Observable<[Hash, Codec][]> =>
this.decorateStorageRange(decorated, [arg1, arg2], range));
decorated.size = decorateMethod((arg1?: Arg, arg2?: Arg): Observable<u64> =>
this._rpcCore.state.getStorageSize(getArgs(arg1, arg2)));
return this.decorateFunctionMeta(creator, decorated) as unknown as QueryableStorageEntry<ApiType>;
}
private decorateStorageRange<ApiType extends ApiTypes> (decorated: QueryableStorageEntry<ApiType>, args: [Arg?, Arg?], range: [Hash, Hash?]): Observable<[Hash, Codec][]> {
const outputType = unwrapStorageType(decorated.creator.meta.type);
return this._rpcCore.state
.queryStorage([decorated.key(...args)], ...range)
.pipe(map((result: StorageChangeSet[]): [Hash, Codec][] =>
result
.filter((change): change is StorageChangeSet => !!change.changes.length)
.map(({ block, changes: [[, value]] }): [Hash, Codec] => [
block,
this.createType(outputType, value.unwrapOrDefault())
])
));
}
private decorateStorageLinked<ApiType extends ApiTypes> (creator: StorageEntry, decorateMethod: DecorateMethod<ApiType>): ReturnType<DecorateMethod<ApiType>> {
const result: Map<Codec, ITuple<[Codec, Linkage<Codec>]> | null> = new Map();
let subject: BehaviorSubject<LinkageResult>;
+4
View File
@@ -72,6 +72,10 @@ async function query (api: ApiPromise, keyring: TestKeyringMap): Promise<void> {
// check entries()
await api.query.system.account.entries(); // should not take a param
await api.query.staking.nominatorSlashInEra.entries(123); // should take a param
// check range
await api.query.balances.freeBalance.range<Balance>(['0x1234'], keyring.bob.address);
await api.query.system.events.range(['0x12345', '0x7890']);
}
async function rpc (api: ApiPromise): Promise<void> {
+4 -3
View File
@@ -26,18 +26,19 @@ export type QueryableStorageEntry<ApiType extends ApiTypes> =
: AugmentedQuery<'promise', GenericStorageEntryFunction> & StorageEntryPromiseOverloads;
export interface StorageEntryBase<ApiType extends ApiTypes, F extends AnyFunction> {
at: (hash: Hash | Uint8Array | string, ...args: Parameters<F>) => PromiseOrObs<ApiType, ObsInnerType<ReturnType<F>>>;
at: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(hash: Hash | Uint8Array | string, ...args: Parameters<F>) => PromiseOrObs<ApiType, T>;
creator: StorageEntry;
entries: (arg?: any) => PromiseOrObs<ApiType, [StorageKey, ObsInnerType<ReturnType<F>>][]>;
entries: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(arg?: any) => PromiseOrObs<ApiType, [StorageKey, T][]>;
hash: (...args: Parameters<F>) => PromiseOrObs<ApiType, Hash>;
key: (...args: Parameters<F>) => string;
keyPrefix: () => string;
range: <T extends Codec | any = ObsInnerType<ReturnType<F>>>([from, to]: [Hash | Uint8Array | string, Hash | Uint8Array | string | undefined] | [Hash | Uint8Array | string], ...args: Parameters<F>) => PromiseOrObs<ApiType, [Hash, T][]>;
size: (...args: Parameters<F>) => PromiseOrObs<ApiType, u64>;
multi: ApiType extends 'rxjs' ? StorageEntryObservableMulti : StorageEntryPromiseMulti;
}
export interface StorageEntryDoubleMap<ApiType extends ApiTypes, F extends AnyFunction> extends StorageEntryBase<ApiType, F> {
entries: (arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, ObsInnerType<ReturnType<F>>][]>;
entries: <T extends Codec | any = ObsInnerType<ReturnType<F>>>(arg?: Parameters<F>[0]) => PromiseOrObs<ApiType, [StorageKey, T][]>;
}
interface StorageEntryObservableMulti {
+1 -1
View File
@@ -28,6 +28,6 @@
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1"
"@polkadot/util": "^2.6.1"
}
}
+3 -3
View File
@@ -28,11 +28,11 @@
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"bn.js": "^5.1.1"
},
"devDependencies": {
"@polkadot/keyring": "^2.5.1"
"@polkadot/keyring": "^2.6.1"
}
}
@@ -5,7 +5,6 @@
import { Codec, Registry } from '@polkadot/types/types';
import { MetadataInterface } from '../types';
import { createTypeUnsafe } from '@polkadot/types/create';
import { unwrapStorageType } from '@polkadot/types/primitive/StorageKey';
import getUniqTypes from './getUniqTypes';
@@ -55,7 +54,7 @@ export function defaultValues (registry: Registry, rpcData: string, withThrow =
it(`creates default types for ${location}`, (): void => {
expect((): void => {
try {
createTypeUnsafe(registry, inner, [fallback]);
registry.createType(inner, fallback);
} catch (error) {
const message = `${location}:: ${error.message}`;
+2 -2
View File
@@ -31,11 +31,11 @@
"@polkadot/metadata": "1.5.0-beta.20",
"@polkadot/rpc-provider": "1.5.0-beta.20",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util": "^2.6.1",
"memoizee": "^0.4.14",
"rxjs": "^6.5.4"
},
"devDependencies": {
"@polkadot/keyring": "^2.5.1"
"@polkadot/keyring": "^2.6.1"
}
}
+3 -3
View File
@@ -30,15 +30,15 @@
"@polkadot/jsonrpc": "1.5.0-beta.20",
"@polkadot/metadata": "1.5.0-beta.20",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"bn.js": "^5.1.1",
"eventemitter3": "^4.0.0",
"isomorphic-fetch": "^2.2.1",
"websocket": "^1.0.31"
},
"devDependencies": {
"@polkadot/keyring": "^2.5.1",
"@polkadot/keyring": "^2.6.1",
"mock-socket": "^9.0.3",
"nock": "^12.0.1"
}
+1 -1
View File
@@ -41,7 +41,7 @@
"@polkadot/metadata": "1.5.0-beta.20",
"@polkadot/rpc-provider": "1.5.0-beta.20",
"@polkadot/types": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util": "^2.6.1",
"websocket": "^1.0.31",
"yargs": "^15.1.0"
},
+2 -1
View File
@@ -3,6 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { MetadataLatest } from '@polkadot/types/interfaces/metadata';
import { InterfaceTypes } from '@polkadot/types/types';
import fs from 'fs';
import interfaces from '@polkadot/jsonrpc';
@@ -176,7 +177,7 @@ function addStorage (metadata: MetadataLatest): string {
let result = unwrapStorageType(func.type);
if (func.modifier.isOptional) {
result = `Option<${result}>`;
result = `Option<${result}>` as keyof InterfaceTypes;
}
return {
+3 -3
View File
@@ -28,15 +28,15 @@
"dependencies": {
"@babel/runtime": "^7.8.4",
"@polkadot/metadata": "1.5.0-beta.20",
"@polkadot/util": "^2.5.1",
"@polkadot/util-crypto": "^2.5.1",
"@polkadot/util": "^2.6.1",
"@polkadot/util-crypto": "^2.6.1",
"@types/bn.js": "^4.11.6",
"bn.js": "^5.1.1",
"memoizee": "^0.4.14",
"rxjs": "^6.5.4"
},
"devDependencies": {
"@polkadot/keyring": "^2.5.1",
"@polkadot/keyring": "^2.6.1",
"@types/memoizee": "^0.4.3"
}
}
+6 -6
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { StorageEntryMetadataLatest, StorageEntryTypeLatest } from '../interfaces/metadata';
import { AnyU8a, Codec, Registry } from '../types';
import { AnyU8a, Codec, InterfaceTypes, Registry } from '../types';
import { assert, isFunction, isString, isU8a } from '@polkadot/util';
@@ -33,20 +33,20 @@ interface StorageKeyExtra {
// we unwrap the type here, turning into an output usable for createType
/** @internal */
export function unwrapStorageType (type: StorageEntryTypeLatest): string {
export function unwrapStorageType (type: StorageEntryTypeLatest): keyof InterfaceTypes {
if (type.isPlain) {
return type.asPlain.toString();
return type.asPlain.toString() as keyof InterfaceTypes;
} else if (type.isDoubleMap) {
return type.asDoubleMap.value.toString();
return type.asDoubleMap.value.toString() as keyof InterfaceTypes;
}
const map = type.asMap;
if (map.linked.isTrue) {
return `(${map.value.toString()}, Linkage<${map.key.toString()}>)`;
return `(${map.value.toString()}, Linkage<${map.key.toString()}>)` as keyof InterfaceTypes;
}
return map.value.toString();
return map.value.toString() as keyof InterfaceTypes;
}
/**