Adjust type asserts (#4952)

This commit is contained in:
Jaco
2022-06-18 13:45:04 +03:00
committed by GitHub
parent 0d2e938674
commit b42669f864
34 changed files with 320 additions and 113 deletions
+22 -8
View File
@@ -5,7 +5,7 @@ import type { Codec, CodecClass, Registry, U8aBitLength, UIntBitLength } from '@
import type { TypeDef } from '../types';
import { BTreeMap, BTreeSet, Bytes, CodecSet, Compact, DoNotConstruct, Enum, HashMap, Int, Null, Option, Range, RangeInclusive, Result, Struct, Tuple, U8aFixed, UInt, Vec, VecFixed, WrapperKeepOpaque, WrapperOpaque } from '@polkadot/types-codec';
import { assert, isNumber, stringify } from '@polkadot/util';
import { isNumber, stringify } from '@polkadot/util';
import { TypeDefInfo } from '../types';
import { getTypeDef } from '../util/getTypeDef';
@@ -15,13 +15,17 @@ function getTypeDefType ({ lookupName, type }: TypeDef): string {
}
function getSubDefArray (value: TypeDef): TypeDef[] {
assert(value.sub && Array.isArray(value.sub), () => `Expected subtype as TypeDef[] in ${stringify(value)}`);
if (!Array.isArray(value.sub)) {
throw new Error(`Expected subtype as TypeDef[] in ${stringify(value)}`);
}
return value.sub;
}
function getSubDef (value: TypeDef): TypeDef {
assert(value.sub && !Array.isArray(value.sub), () => `Expected subtype as TypeDef in ${stringify(value)}`);
if (!value.sub || Array.isArray(value.sub)) {
throw new Error(`Expected subtype as TypeDef in ${stringify(value)}`);
}
return value.sub;
}
@@ -48,7 +52,9 @@ function getTypeClassArray (value: TypeDef): string[] {
}
function createInt (Clazz: typeof Int | typeof UInt, { displayName, length }: TypeDef): CodecClass<Codec> {
assert(isNumber(length), () => `Expected bitLength information for ${displayName || Clazz.constructor.name}<bitLength>`);
if (!isNumber(length)) {
throw new Error(`Expected bitLength information for ${displayName || Clazz.constructor.name}<bitLength>`);
}
return Clazz.with(length as UIntBitLength, displayName);
}
@@ -116,7 +122,9 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
Null,
[TypeDefInfo.Option]: (registry: Registry, value: TypeDef): CodecClass<Codec> => {
assert(value.sub && !Array.isArray(value.sub), 'Expected type information for Option');
if (!value.sub || Array.isArray(value.sub)) {
throw new Error('Expected type information for Option');
}
// NOTE This is opt-in (unhandled), not by default
// if (value.sub.type === 'bool') {
@@ -165,7 +173,9 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
createInt(UInt, value),
[TypeDefInfo.Vec]: (registry: Registry, { sub }: TypeDef): CodecClass<Codec> => {
assert(sub && !Array.isArray(sub), 'Expected type information for vector');
if (!sub || Array.isArray(sub)) {
throw new Error('Expected type information for vector');
}
return (
sub.type === 'u8'
@@ -175,7 +185,9 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
},
[TypeDefInfo.VecFixed]: (registry: Registry, { displayName, length, sub }: TypeDef): CodecClass<Codec> => {
assert(sub && isNumber(length) && !Array.isArray(sub), 'Expected length & type information for fixed vector');
if (!isNumber(length) || !sub || Array.isArray(sub)) {
throw new Error('Expected length & type information for fixed vector');
}
return (
sub.type === 'u8'
@@ -195,7 +207,9 @@ export function constructTypeClass<T extends Codec = Codec> (registry: Registry,
try {
const Type = infoMapping[typeDef.info](registry, typeDef);
assert(Type, 'No class created');
if (!Type) {
throw new Error('No class created');
}
// don't clobber any existing
if (!Type.__fallbackType && typeDef.fallbackType) {
+4 -2
View File
@@ -5,7 +5,7 @@ import type { Codec, CodecClass, IU8a, Registry } from '@polkadot/types-codec/ty
import type { CreateOptions } from '../types';
import { Bytes, Option } from '@polkadot/types-codec';
import { assert, isHex, isU8a, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
import { isHex, isU8a, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util';
import { createClassUnsafe } from './class';
@@ -29,7 +29,9 @@ function checkInstance (created: Codec, matcher: Uint8Array): void {
)
);
assert(isOk, () => `${rawType}:: Decoded input doesn't match input, received ${u8aToHex(matcher, 512)} (${matcher.length} bytes), created ${u8aToHex(u8a, 512)} (${u8a.length} bytes)`);
if (!isOk) {
throw new Error(`${rawType}:: Decoded input doesn't match input, received ${u8aToHex(matcher, 512)} (${matcher.length} bytes), created ${u8aToHex(u8a, 512)} (${u8a.length} bytes)`);
}
}
function checkPedantic (created: Codec, [value]: unknown[]): void {
+19 -7
View File
@@ -4,7 +4,7 @@
import type { Registry } from '@polkadot/types-codec/types';
import type { TypeDef } from '@polkadot/types-create/types';
import { assert, isNumber, isUndefined, objectSpread, stringify } from '@polkadot/util';
import { isNumber, isUndefined, objectSpread, stringify } from '@polkadot/util';
import { TypeDefInfo } from '../types';
@@ -45,7 +45,9 @@ function encodeWithParams (registry: Registry, typeDef: TypeDef, outer: string):
function encodeSubTypes (registry: Registry, sub: TypeDef[], asEnum?: boolean, extra?: Record<string, unknown>): string {
const names = sub.map(({ name }) => name);
assert(names.every((n) => !!n), () => `Subtypes does not have consistent names, ${names.join(', ')}`);
if (!names.every((n) => !!n)) {
throw new Error(`Subtypes does not have consistent names, ${names.join(', ')}`);
}
const inner: Record<string, string> = objectSpread({}, extra);
@@ -78,7 +80,9 @@ const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef) => st
`DoNotConstruct<${lookupName || displayName || (isUndefined(lookupIndex) ? 'Unknown' : registry.createLookupType(lookupIndex))}>`,
[TypeDefInfo.Enum]: (registry: Registry, { sub }: TypeDef): string => {
assert(sub && Array.isArray(sub), 'Unable to encode Enum type');
if (!Array.isArray(sub)) {
throw new Error('Unable to encode Enum type');
}
// c-like enums have all Null entries
// TODO We need to take the disciminant into account and auto-add empty entries
@@ -118,7 +122,9 @@ const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef) => st
// eslint-disable-next-line @typescript-eslint/no-unused-vars
[TypeDefInfo.Set]: (registry: Registry, { length = 8, sub }: TypeDef): string => {
assert(sub && Array.isArray(sub), 'Unable to encode Set type');
if (!Array.isArray(sub)) {
throw new Error('Unable to encode Set type');
}
return stringify({
_set: sub.reduce((all, { index, name }, count) =>
@@ -132,7 +138,9 @@ const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef) => st
lookupName || type,
[TypeDefInfo.Struct]: (registry: Registry, { alias, sub }: TypeDef): string => {
assert(sub && Array.isArray(sub), 'Unable to encode Struct type');
if (!Array.isArray(sub)) {
throw new Error('Unable to encode Struct type');
}
return encodeSubTypes(registry, sub, false,
alias
@@ -146,7 +154,9 @@ const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef) => st
},
[TypeDefInfo.Tuple]: (registry: Registry, { sub }: TypeDef): string => {
assert(sub && Array.isArray(sub), 'Unable to encode Tuple type');
if (!Array.isArray(sub)) {
throw new Error('Unable to encode Tuple type');
}
return `(${sub.map((type) => encodeTypeDef(registry, type)).join(',')})`;
},
@@ -158,7 +168,9 @@ const encoders: Record<TypeDefInfo, (registry: Registry, typeDef: TypeDef) => st
encodeWithParams(registry, typeDef, 'Vec'),
[TypeDefInfo.VecFixed]: (registry: Registry, { length, sub }: TypeDef): string => {
assert(isNumber(length) && !isUndefined(sub) && !Array.isArray(sub), 'Unable to encode VecFixed type');
if (!isNumber(length) || !sub || Array.isArray(sub)) {
throw new Error('Unable to encode VecFixed type');
}
return `[${sub.type};${length}]`;
},
+16 -9
View File
@@ -5,7 +5,7 @@ import type { AnyString } from '@polkadot/types-codec/types';
import type { TypeDef } from '@polkadot/types-create/types';
import { sanitize } from '@polkadot/types-codec';
import { assert, isNumber, isString, objectSpread } from '@polkadot/util';
import { isNumber, isString, objectSpread } from '@polkadot/util';
import { TypeDefInfo } from '../types';
import { typeSplit } from './typeSplit';
@@ -15,9 +15,6 @@ interface TypeDefOptions {
displayName?: string;
}
const MAX_NESTED = 64;
const MAX_FIX_LEN = 2048;
const MAX_BIT_LEN = 8192;
const KNOWN_INTERNALS = ['_alias', '_fallback'];
function getTypeString (typeOrObj: any): string {
@@ -30,7 +27,9 @@ function isRustEnum (details: Record<string, string> | Record<string, number>):
const values = Object.values(details);
if (values.some((v) => isNumber(v))) {
assert(values.every((v) => isNumber(v) && v >= 0 && v <= 255), 'Invalid number-indexed enum definition');
if (!values.every((v) => isNumber(v) && v >= 0 && v <= 255)) {
throw new Error('Invalid number-indexed enum definition');
}
return false;
}
@@ -145,13 +144,17 @@ function _decodeFixedVec (value: TypeDef, type: string, _: string, count: number
}
}
assert(index !== -1, () => `${type}: Unable to extract location of ';'`);
if (index === -1) {
throw new Error(`${type}: Unable to extract location of ';'`);
}
const vecType = type.substring(1, index);
const [strLength, displayName] = type.substring(index + 1, max).split(';');
const length = parseInt(strLength.trim(), 10);
assert(length <= MAX_FIX_LEN, () => `${type}: Only support for [Type; <length>], where length <= ${MAX_FIX_LEN}`);
if (length > 2048) {
throw new Error(`${type}: Only support for [Type; <length>], where length <= 2048`);
}
value.displayName = displayName;
value.length = length;
@@ -175,7 +178,9 @@ function _decodeAnyInt (value: TypeDef, type: string, _: string, clazz: 'Int' |
const [strLength, displayName] = type.substring(clazz.length + 1, type.length - 1).split(',');
const length = parseInt(strLength.trim(), 10);
assert(length <= MAX_BIT_LEN && (length % 8) === 0, () => `${type}: Only support for ${clazz}<bitLength>, where length <= ${MAX_BIT_LEN} and a power of 8, found ${length}`);
if ((length > 8192) || (length % 8)) {
throw new Error(`${type}: Only support for ${clazz}<bitLength>, where length <= 8192 and a power of 8, found ${length}`);
}
value.displayName = displayName;
value.length = length;
@@ -238,7 +243,9 @@ export function getTypeDef (_type: AnyString, { displayName, name }: TypeDefOpti
const type = sanitize(_type);
const value: TypeDef = { displayName, info: TypeDefInfo.Plain, name, type };
assert(++count !== MAX_NESTED, 'getTypeDef: Maximum nested limit reached');
if (++count > 64) {
throw new Error('getTypeDef: Maximum nested limit reached');
}
const nested = nestedExtraction.find((nested) => hasWrapper(type, nested));
+3 -3
View File
@@ -1,8 +1,6 @@
// Copyright 2017-2022 @polkadot/types-create authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { assert } from '@polkadot/util';
// safely split a string on ', ' while taking care of any nested occurences
export function typeSplit (type: string): string[] {
const result: string[] = [];
@@ -47,7 +45,9 @@ export function typeSplit (type: string): string[] {
}
// ensure we have all the terminators taken care of
assert(!(c || f || s || t), () => `Invalid definition (missing terminators) found in ${type}`);
if (c || f || s || t) {
throw new Error(`Invalid definition (missing terminators) found in ${type}`);
}
// the final leg of the journey
result.push(type.substring(start, type.length).trim());