Parameterize DoNotConstruct (#2165)

* Parameterize DoNotConstruct

* Update DoNotConstruct list

* typo fix
This commit is contained in:
Jaco Greeff
2020-04-14 12:37:30 +02:00
committed by GitHub
parent 70a160cca0
commit c8f91fcf7a
21 changed files with 70 additions and 64 deletions
+4 -4
View File
@@ -2,7 +2,7 @@
/* eslint-disable */
import { Compact, Option, Raw, Vec } from '@polkadot/types/codec';
import { BitVec, Bytes, Data, Null, StorageKey, Text, Type, U256, Unconstructable, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { BitVec, Bytes, Data, DoNotConstruct, Null, StorageKey, Text, Type, U256, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { BlockAttestations, IncludedBlocks, MoreAttestations } from '@polkadot/types/interfaces/attestations';
import { RawAuraPreDigest } from '@polkadot/types/interfaces/aura';
import { ExtrinsicOrHash, ExtrinsicStatus } from '@polkadot/types/interfaces/author';
@@ -57,6 +57,9 @@ declare module '@polkadot/types/types/registry' {
Data: Data;
'Option<Data>': Option<Data>;
'Vec<Data>': Vec<Data>;
DoNotConstruct: DoNotConstruct;
'Option<DoNotConstruct>': Option<DoNotConstruct>;
'Vec<DoNotConstruct>': Vec<DoNotConstruct>;
i8: i8;
'Option<i8>': Option<i8>;
'Vec<i8>': Vec<i8>;
@@ -115,9 +118,6 @@ declare module '@polkadot/types/types/registry' {
'Compact<U256>': Compact<U256>;
'Option<U256>': Option<U256>;
'Vec<U256>': Vec<U256>;
Unconstructable: Unconstructable;
'Option<Unconstructable>': Option<Unconstructable>;
'Vec<Unconstructable>': Vec<Unconstructable>;
usize: usize;
'Compact<usize>': Compact<usize>;
'Option<usize>': Option<usize>;
@@ -43,6 +43,10 @@ function encodeWithParams (typeDef: Pick<TypeDef, any>, outer = typeDef.displayN
}
}
function encodeDoNotConstruct ({ displayName }: TypeDef): string {
return `DoNotEncode<${displayName}>`;
}
function encodeSubTypes (sub: TypeDef[], asEnum?: boolean): string {
const inner = sub.reduce(
(result: Record<string, string>, type: TypeDef): Record<string, string> => {
@@ -122,6 +126,7 @@ const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
[TypeDefInfo.BTreeMap]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeMap'),
[TypeDefInfo.BTreeSet]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeSet'),
[TypeDefInfo.Compact]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Compact'),
[TypeDefInfo.DoNotConstruct]: (typeDef: TypeDef): string => encodeDoNotConstruct(typeDef),
[TypeDefInfo.Enum]: (typeDef: TypeDef): string => encodeEnum(typeDef),
[TypeDefInfo.HashMap]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'HashMap'),
[TypeDefInfo.Int]: (typeDef: TypeDef): string => encodeUInt(typeDef, 'Int'),
@@ -33,6 +33,6 @@ describe('getTypeClass', (): void => {
getTypeClass(registry, typeDef);
expect(spy).toHaveBeenCalledWith('Unable to resolve type ABC, it will fail on constrution');
expect(spy).toHaveBeenCalledWith('Unable to resolve type ABC, it will fail on construction');
});
});
+4
View File
@@ -23,6 +23,8 @@ import U8aFixed, { BitLength as U8aFixedBitLength } from '../codec/U8aFixed';
import UInt from '../codec/UInt';
import Vec from '../codec/Vec';
import VecFixed from '../codec/VecFixed';
import DoNotConstruct from '../primitive/DoNotConstruct';
import { getTypeDef } from './getTypeDef';
export function createClass<T extends Codec = Codec, K extends string = string> (registry: Registry, type: K): Constructor<FromReg<T, K>> {
@@ -97,6 +99,8 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
[TypeDefInfo.Compact]: (registry: Registry, value: TypeDef): Constructor => Compact.with(getSubType(value)),
[TypeDefInfo.DoNotConstruct]: (registry: Registry, value: TypeDef): Constructor => DoNotConstruct.with(value.displayName),
[TypeDefInfo.Enum]: (registry: Registry, value: TypeDef): Constructor => Enum.with(getTypeClassMap(value)),
[TypeDefInfo.HashMap]: (registry: Registry, value: TypeDef): Constructor => createHashMap(value, HashMap),
@@ -95,6 +95,14 @@ describe('createType', (): void => {
).toThrow('UInt<20>: Only support for UInt<bitLength>, where length <= 8192 and a power of 8');
});
it('fails on creation of DoNotConstruct', (): void => {
const Clazz = createClass(registry, 'DoNotConstruct<UnknownSomething>');
expect(
() => new Clazz(registry)
).toThrow('Cannot construct unknown type UnknownSomething');
});
it('allows creation of a [u8; 8]', (): void => {
expect(
createTypeUnsafe(registry, '[u8; 8]', [[0x12, 0x00, 0x23, 0x00, 0x45, 0x00, 0x67, 0x00]]).toHex()
+3 -3
View File
@@ -54,13 +54,13 @@ function initType<T extends Codec = Codec, K extends string = string> (registry:
}
// An unsafe version of the `createType` below. It's unsafe because the `type`
// argument here can be any string, which, if not parseable, will yield a
// argument here can be any string, which, when it cannot parse, will yield a
// runtime error.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export function createTypeUnsafe<T extends Codec = Codec, K extends string = string> (registry: Registry, type: K, params: any[] = [], isPedantic?: boolean): T {
try {
// Circle back to isPedenatic when it handles all cases 100% - as of now,
// it provides false wraning which is more hinderance than help
// Circle back to isPedantic when it handles all cases 100% - as of now,
// it provides false warning which is more hinderance than help
return initType(registry, createClass<T, K>(registry, type), params); // , isPedantic);
} catch (error) {
throw new Error(`createType(${type}):: ${error.message}`);
+11 -1
View File
@@ -119,6 +119,15 @@ function _decodeUInt (value: TypeDef, type: string, subType: string): TypeDef {
return _decodeInt(value, type, subType, 'UInt');
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _decodeDoNotConstruct (value: TypeDef, type: string, _: string): TypeDef {
const NAME_LENGTH = 'DoNotConstruct'.length;
value.displayName = type.substr(NAME_LENGTH + 1, type.length - NAME_LENGTH - 1 - 1);
return value;
}
function hasWrapper (type: string, [start, end]: [string, string, TypeDefInfo, any?]): boolean {
if (type.substr(0, start.length) !== start) {
return false;
@@ -138,7 +147,8 @@ const nestedExtraction: [string, string, TypeDefInfo, (value: TypeDef, type: str
['HashMap<', '>', TypeDefInfo.HashMap, _decodeTuple],
['Int<', '>', TypeDefInfo.Int, _decodeInt],
['Result<', '>', TypeDefInfo.Result, _decodeTuple],
['UInt<', '>', TypeDefInfo.UInt, _decodeUInt]
['UInt<', '>', TypeDefInfo.UInt, _decodeUInt],
['DoNotConstruct<', '>', TypeDefInfo.DoNotConstruct, _decodeDoNotConstruct]
];
const wrappedExtraction: [string, string, TypeDefInfo][] = [
+2 -2
View File
@@ -7,9 +7,9 @@ import { Codec, Constructor } from '../types';
import { isChildClass } from '@polkadot/util';
import Struct from '../codec/Struct';
import DoNotConstruct from '../primitive/DoNotConstruct';
import Text from '../primitive/Text';
import U32 from '../primitive/U32';
import Unconstructable from '../primitive/Unconstructable';
import { TypeRegistry } from './registry';
describe('TypeRegistry', (): void => {
@@ -29,7 +29,7 @@ describe('TypeRegistry', (): void => {
expect(Type).toBeDefined();
// eslint-disable-next-line no-prototype-builtins
expect(isChildClass(Unconstructable, Type));
expect(isChildClass(DoNotConstruct, Type));
});
it('can register single type', (): void => {
+3 -3
View File
@@ -13,7 +13,7 @@ import { assert, formatBalance, isFunction, isString, isU8a, isUndefined, string
import Raw from '../codec/Raw';
import { defaultExtensions, expandExtensionTypes, findUnknownExtensions } from '../extrinsic/signedExtensions';
import { EventData } from '../generic/Event';
import Unconstructable from '../primitive/Unconstructable';
import DoNotConstruct from '../primitive/DoNotConstruct';
import { createClass, getTypeClass } from './createClass';
import { createType } from './createType';
import { getTypeDef } from './getTypeDef';
@@ -194,10 +194,10 @@ export class TypeRegistry implements Registry {
if (definition) {
BaseType = createClass(this, definition);
} else if (withUnknown) {
console.warn(`Unable to resolve type ${name}, it will fail on constrution`);
console.warn(`Unable to resolve type ${name}, it will fail on construction`);
this.#unknownTypes.set(name, true);
BaseType = Unconstructable.with(name);
BaseType = DoNotConstruct.with(name);
}
if (BaseType) {
+1 -1
View File
@@ -9,7 +9,7 @@ interface SanitizeOptions {
allowNamespaces?: boolean;
}
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'HashMap', 'Int', 'Linkage', 'Result', 'Option', 'UInt', 'Vec'];
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'DoNotConstruct', 'HashMap', 'Int', 'Linkage', 'Result', 'Option', 'UInt', 'Vec'];
const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fixed array, part of struct def or in tuple
const mappings: Mapper[] = [
+1
View File
@@ -26,6 +26,7 @@ export enum TypeDefInfo {
HashMap,
Int,
UInt,
DoNotConstruct,
// anything not fully supported (keep this as the last entry)
Null
}
-16
View File
@@ -1,16 +0,0 @@
// Copyright 2017-2020 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { TypeRegistry } from '../create';
import Origin from './Origin';
describe('Origin', (): void => {
const registry = new TypeRegistry();
it('does not allow construction', (): void => {
expect(
(): Origin => new Origin(registry)
).toThrow(/placeholder/);
});
});
-21
View File
@@ -1,21 +0,0 @@
// Copyright 2017-2020 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Registry } from '../types';
import Null from '../primitive/Null';
/**
* @name Origin
* @description
* Where Origin occurs, it should be ignored as an internal-only value, so it should
* never actually be constructed
*/
export default class Origin extends Null {
constructor (registry: Registry) {
super(registry);
throw new Error('Origin should not be constructed, it is only a placeholder for compatibility');
}
}
-1
View File
@@ -9,5 +9,4 @@ export { default as GenericBlock } from './Block';
export { default as GenericCall } from './Call';
export { default as GenericConsensusEngineId } from './ConsensusEngineId';
export { default as GenericEvent } from './Event';
export { default as GenericOrigin } from './Origin';
export { default as GenericVote } from './Vote';
+2 -2
View File
@@ -17,8 +17,8 @@ import * as definitions from './interfaces/definitions';
const UNCONSTRUCTABLE = [
'ExtrinsicPayloadUnknown', 'GenericExtrinsicPayloadUnknown',
'ExtrinsicUnknown', 'GenericExtrinsicUnknown',
'GenericOrigin', 'Origin',
'Unconstructable',
'DoNotConstruct',
'Origin',
'usize'
].map((v): string => v.toLowerCase());
@@ -71,7 +71,7 @@ export default {
LookupSource: 'Address',
LookupTarget: 'AccountId',
Moment: 'u64',
Origin: 'GenericOrigin',
Origin: 'DoNotConstruct<Origin>',
Perbill: 'u32',
Percent: 'u8',
Permill: 'u32',
@@ -3,8 +3,8 @@
import { ITuple } from '@polkadot/types/types';
import { Compact, Enum, Int, Struct, U8aFixed, Vec } from '@polkadot/types/codec';
import { GenericAccountId, GenericAccountIndex, GenericAddress, GenericBlock, GenericCall, GenericConsensusEngineId, GenericOrigin } from '@polkadot/types/generic';
import { Bytes, Null, StorageKey, bool, u128, u32, u64, u8 } from '@polkadot/types/primitive';
import { GenericAccountId, GenericAccountIndex, GenericAddress, GenericBlock, GenericCall, GenericConsensusEngineId } from '@polkadot/types/generic';
import { Bytes, DoNotConstruct, Null, StorageKey, bool, u128, u32, u64, u8 } from '@polkadot/types/primitive';
import { AuthorityId } from '@polkadot/types/interfaces/consensus';
import { Signature } from '@polkadot/types/interfaces/extrinsics';
@@ -142,7 +142,7 @@ export interface LookupTarget extends AccountId {}
export interface Moment extends u64 {}
/** @name Origin */
export interface Origin extends GenericOrigin {}
export interface Origin extends DoNotConstruct {}
/** @name Perbill */
export interface Perbill extends u32 {}
@@ -7,19 +7,19 @@ import { Constructor, Registry } from '../types';
import Null from './Null';
/**
* @name Unconstructable
* @name DoNotConstruct
* @description
* An unknown type that fails on construction with the type info
*/
export default class Unconstructable extends Null {
export default class DoNotConstruct extends Null {
constructor (registry: Registry, typeName: string) {
super(registry);
throw new Error(`Cannot construct unknown type ${typeName}`);
}
public static with (typeName: string): Constructor {
return class extends Unconstructable {
public static with (typeName = 'DoNotConstruct'): Constructor {
return class extends DoNotConstruct {
constructor (registry: Registry) {
super(registry, typeName);
}
+1 -1
View File
@@ -12,6 +12,7 @@ export { default as BitVec } from './BitVec';
export { default as bool } from './Bool';
export { default as Bytes } from './Bytes';
export { default as Data } from './Data';
export { default as DoNotConstruct } from './DoNotConstruct';
export { default as i8 } from './I8';
export { default as i16 } from './I16';
export { default as i32 } from './I32';
@@ -28,5 +29,4 @@ export { default as u32 } from './U32';
export { default as u64 } from './U64';
export { default as u128 } from './U128';
export { default as u256, default as U256 } from './U256';
export { default as Unconstructable } from './Unconstructable';
export { default as usize } from './USize';