Struct decoding error messaging (#3425)
* Struct decoding error messaging * Error adjust * Tests * Bump common, use stringify * Linting * Adjust * Bumps * Rebump * Assert cleanups * Don't modify original value on encoding * util bump, fixe compact encoding
This commit is contained in:
@@ -7,7 +7,7 @@ import type { UIntBitLength } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
import { assert, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, BN_ZERO, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isHex, isString, isU8a, u8aToBn } from '@polkadot/util';
|
||||
import { assert, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, BN_ZERO, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isHex, isString, isU8a, stringify, u8aToBn } from '@polkadot/util';
|
||||
|
||||
export const DEFAULT_UINT_BITS = 64;
|
||||
|
||||
@@ -37,7 +37,7 @@ function decodeAbstracIntU8a (value: Uint8Array, bitLength: UIntBitLength, isNeg
|
||||
// NOTE When passing u8a in (typically from decoded data), it is always Little Endian
|
||||
return u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative }).toString();
|
||||
} catch (error) {
|
||||
throw new Error(`AbstractInt: failed on ${JSON.stringify(value)}:: ${(error as Error).message}`);
|
||||
throw new Error(`AbstractInt: failed on ${stringify(value)}:: ${(error as Error).message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,8 +83,8 @@ export abstract class AbstractInt extends BN implements Codec {
|
||||
const isPositive = this.gte(BN_ZERO);
|
||||
const maxBits = bitLength - (isSigned && isPositive ? 1 : 0);
|
||||
|
||||
assert(isSigned || isPositive, `${this.toRawType()}: Negative number passed to unsigned type`);
|
||||
assert(super.bitLength() <= maxBits, `${this.toRawType()}: Input too large. Found input with ${super.bitLength()} bits, expected ${maxBits}`);
|
||||
assert(isSigned || isPositive, () => `${this.toRawType()}: Negative number passed to unsigned type`);
|
||||
assert(super.bitLength() <= maxBits, () => `${this.toRawType()}: Input too large. Found input with ${super.bitLength()} bits, expected ${maxBits}`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { CodecHash, Hash } from '../interfaces/runtime';
|
||||
import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types';
|
||||
|
||||
import { compactFromU8a, compactToU8a, isHex, isU8a, logger, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { compactFromU8a, compactToU8a, isHex, isU8a, logger, stringify, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { compareSet, decodeU8a, typeToConstructor } from './utils';
|
||||
|
||||
@@ -176,7 +176,7 @@ export class BTreeSet<V extends Codec = Codec> extends Set<V> implements Codec {
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return JSON.stringify(this.toJSON());
|
||||
return stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import type { CodecHash, Hash } from '../interfaces';
|
||||
import type { AnyJson, AnyNumber, Constructor, ICompact, InterfaceTypes, Registry } from '../types';
|
||||
import type { CompactEncodable, UIntBitLength } from './types';
|
||||
import type { CompactEncodable } from './types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
@@ -50,9 +50,7 @@ export class Compact<T extends CompactEncodable> implements ICompact<T> {
|
||||
return new Type(registry, value);
|
||||
}
|
||||
|
||||
const [, _value] = compactFromU8a(value, new Type(registry, 0).bitLength() as UIntBitLength);
|
||||
|
||||
return new Type(registry, _value);
|
||||
return new Type(registry, compactFromU8a(value)[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { CodecHash, Hash } from '../interfaces';
|
||||
import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types';
|
||||
|
||||
import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefined, stringCamelCase, stringUpperFirst, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefined, stringCamelCase, stringify, stringUpperFirst, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { Null } from '../primitive/Null';
|
||||
import { Struct } from './Struct';
|
||||
@@ -88,7 +88,7 @@ function extractDef (registry: Registry, _def: Record<string, keyof InterfaceTyp
|
||||
function createFromValue (registry: Registry, def: TypesDef, index = 0, value?: any): Decoded {
|
||||
const entry = Object.values(def).find((e) => e.index === index);
|
||||
|
||||
assert(!isUndefined(entry), `Unable to create Enum via index ${index}, in ${Object.keys(def).join(', ')}`);
|
||||
assert(!isUndefined(entry), () => `Unable to create Enum via index ${index}, in ${Object.keys(def).join(', ')}`);
|
||||
|
||||
return {
|
||||
index,
|
||||
@@ -105,7 +105,7 @@ function decodeFromJSON (registry: Registry, def: TypesDef, key: string, value?:
|
||||
const keyLower = key.toLowerCase();
|
||||
const index = keys.indexOf(keyLower);
|
||||
|
||||
assert(index !== -1, `Cannot map Enum JSON, unable to find '${key}' in ${keys.join(', ')}`);
|
||||
assert(index !== -1, () => `Cannot map Enum JSON, unable to find '${key}' in ${keys.join(', ')}`);
|
||||
|
||||
try {
|
||||
return createFromValue(registry, def, Object.values(def)[index].index, value);
|
||||
@@ -213,7 +213,7 @@ export class Enum implements Codec {
|
||||
Object.defineProperty(this, askey, {
|
||||
enumerable: true,
|
||||
get: (): Codec => {
|
||||
assert(this[iskey as keyof this], `Cannot convert '${this.type}' via ${askey}`);
|
||||
assert(this[iskey as keyof this], () => `Cannot convert '${this.type}' via ${askey}`);
|
||||
|
||||
return this.value;
|
||||
}
|
||||
@@ -384,7 +384,7 @@ export class Enum implements Codec {
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public toRawType (): string {
|
||||
return JSON.stringify({ _enum: this._toRawStruct() });
|
||||
return stringify({ _enum: this._toRawStruct() });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,7 +393,7 @@ export class Enum implements Codec {
|
||||
public toString (): string {
|
||||
return this.isNull
|
||||
? this.type
|
||||
: JSON.stringify(this.toJSON());
|
||||
: stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { CodecHash, Hash } from '../interfaces/runtime';
|
||||
import type { AnyJson, Codec, Registry } from '../types';
|
||||
|
||||
import { isFunction, isUndefined } from '@polkadot/util';
|
||||
import { isFunction, isUndefined, stringify } from '@polkadot/util';
|
||||
|
||||
import { compareMap } from './utils';
|
||||
|
||||
@@ -112,7 +112,7 @@ export class Json extends Map<string, any> implements Codec {
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return JSON.stringify(this.toJSON());
|
||||
return stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { CodecHash, Hash } from '../interfaces/runtime';
|
||||
import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types';
|
||||
|
||||
import { compactFromU8a, compactToU8a, isHex, isObject, isU8a, logger, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { compactFromU8a, compactToU8a, isHex, isObject, isU8a, logger, stringify, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { compareMap, decodeU8a, typeToConstructor } from './utils';
|
||||
|
||||
@@ -183,7 +183,7 @@ export class CodecMap<K extends Codec = Codec, V extends Codec = Codec> extends
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return JSON.stringify(this.toJSON());
|
||||
return stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Codec, Constructor, Registry } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
|
||||
import { assert, bnToBn, bnToU8a, isBn, isNumber, isString, isU8a, isUndefined, stringCamelCase, stringUpperFirst, u8aToBn, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
import { assert, bnToBn, bnToU8a, isBn, isNumber, isString, isU8a, isUndefined, stringCamelCase, stringify, stringUpperFirst, u8aToBn, u8aToHex, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { compareArray } from './utils';
|
||||
|
||||
@@ -21,7 +21,7 @@ function encodeSet (setValues: SetValues, value: string[]): BN {
|
||||
/** @internal */
|
||||
function decodeSetArray (setValues: SetValues, value: string[]): string[] {
|
||||
return value.reduce((result, key): string[] => {
|
||||
assert(!isUndefined(setValues[key]), `Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`);
|
||||
assert(!isUndefined(setValues[key]), () => `Set: Invalid key '${key}' passed to Set, allowed ${Object.keys(setValues).join(', ')}`);
|
||||
|
||||
result.push(key);
|
||||
|
||||
@@ -42,14 +42,14 @@ function decodeSetNumber (setValues: SetValues, _value: BN | number): string[] {
|
||||
|
||||
const computed = encodeSet(setValues, result);
|
||||
|
||||
assert(bn.eq(computed), `Set: Mismatch decoding '${bn.toString()}', computed as '${computed.toString()}' with ${result.join(', ')}`);
|
||||
assert(bn.eq(computed), () => `Set: Mismatch decoding '${bn.toString()}', computed as '${computed.toString()}' with ${result.join(', ')}`);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
function decodeSet (setValues: SetValues, value: string[] | Set<string> | Uint8Array | BN | number | string = 0, bitLength: number): string[] {
|
||||
assert(bitLength % 8 === 0, `Expected valid bitLength, power of 8, found ${bitLength}`);
|
||||
assert(bitLength % 8 === 0, () => `Expected valid bitLength, power of 8, found ${bitLength}`);
|
||||
|
||||
const byteLength = bitLength / 8;
|
||||
|
||||
@@ -155,7 +155,7 @@ export class CodecSet extends Set<string> implements Codec {
|
||||
// ^^^ add = () property done to assign this instance's this, otherwise Set.add creates "some" chaos
|
||||
// we have the isUndefined(this._setValues) in here as well, add is used internally
|
||||
// in the Set constructor (so it is undefined at this point, and should allow)
|
||||
assert(isUndefined(this.#allowed) || !isUndefined(this.#allowed[key]), `Set: Invalid key '${key}' on add`);
|
||||
assert(isUndefined(this.#allowed) || !isUndefined(this.#allowed[key]), () => `Set: Invalid key '${key}' on add`);
|
||||
|
||||
super.add(key);
|
||||
|
||||
@@ -210,7 +210,7 @@ export class CodecSet extends Set<string> implements Codec {
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public toRawType (): string {
|
||||
return JSON.stringify({ _set: this.#allowed });
|
||||
return stringify({ _set: this.#allowed });
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -119,6 +119,14 @@ describe('Struct', (): void => {
|
||||
).toThrowError(/Cannot decode value/);
|
||||
});
|
||||
|
||||
it('throws a sensical error on incorrect array values passed to structs', (): void => {
|
||||
expect(
|
||||
() => new Struct(registry, {
|
||||
_: 'Vec<u32>'
|
||||
}, [123, 456])
|
||||
).toThrow(/array to object with known keys/);
|
||||
});
|
||||
|
||||
it('provides a clean toString()', (): void => {
|
||||
expect(
|
||||
new (
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import type { CodecHash, Hash } from '../interfaces/runtime';
|
||||
import type { AnyJson, BareOpts, Codec, Constructor, ConstructorDef, InterfaceTypes, Registry } from '../types';
|
||||
|
||||
import { hexToU8a, isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, stringCamelCase, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
import { assert, hexToU8a, isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, stringCamelCase, stringify, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { compareMap, decodeU8a, mapToTypeMap } from './utils';
|
||||
|
||||
@@ -13,8 +13,11 @@ type TypesDef<T = Codec> = Record<string, keyof InterfaceTypes | Constructor<T>>
|
||||
/** @internal */
|
||||
function decodeStructFromObject <T> (registry: Registry, Types: ConstructorDef, value: any, jsonMap: Map<any, string>): T {
|
||||
let jsonObj: Record<string, any> | undefined;
|
||||
const inputKeys = Object.keys(Types);
|
||||
|
||||
return Object.keys(Types).reduce((raw, key, index): T => {
|
||||
assert(!Array.isArray(value) || value.length === inputKeys.length, () => `Struct: Unable to map ${stringify(value)} array to object with known keys ${inputKeys.join(', ')}`);
|
||||
|
||||
return inputKeys.reduce((raw, key, index): T => {
|
||||
// The key in the JSON can be snake_case (or other cases), but in our
|
||||
// Types, result or any other maps, it's camelCase
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
@@ -60,7 +63,7 @@ function decodeStructFromObject <T> (registry: Registry, Types: ConstructorDef,
|
||||
? assign
|
||||
: new Types[key](registry, assign);
|
||||
} else {
|
||||
throw new Error(`Cannot decode value ${JSON.stringify(value)}`);
|
||||
throw new Error(`Cannot decode value ${stringify(value)} (typeof ${typeof value}), expected an input object with known keys`);
|
||||
}
|
||||
} catch (error) {
|
||||
let type = Types[key].name;
|
||||
@@ -297,7 +300,7 @@ export class Struct<
|
||||
* @description Returns the base runtime type name for this instance
|
||||
*/
|
||||
public toRawType (): string {
|
||||
return JSON.stringify(
|
||||
return stringify(
|
||||
Struct.typesToMap(this.registry, this.#Types)
|
||||
);
|
||||
}
|
||||
@@ -306,7 +309,7 @@ export class Struct<
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return JSON.stringify(this.toJSON());
|
||||
return stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import type { AnyNumber, AnyString, AnyU8a, Codec, Constructor, InterfaceTypes, Registry } from '../types';
|
||||
|
||||
import { isHex, isU8a, u8aConcat, u8aToU8a } from '@polkadot/util';
|
||||
import { isHex, isU8a, stringify, u8aConcat, u8aToU8a } from '@polkadot/util';
|
||||
|
||||
import { AbstractArray } from './AbstractArray';
|
||||
import { decodeU8a, mapToTypeMap, typeToConstructor } from './utils';
|
||||
@@ -110,7 +110,7 @@ export class Tuple extends AbstractArray<Codec> {
|
||||
*/
|
||||
public toString (): string {
|
||||
// Overwrite the default toString representation of Array.
|
||||
return JSON.stringify(this.toJSON());
|
||||
return stringify(this.toJSON());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,7 +50,7 @@ export class Vec<T extends Codec> extends AbstractArray<T> {
|
||||
const u8a = u8aToU8a(value);
|
||||
const [offset, length] = compactFromU8a(u8a);
|
||||
|
||||
assert(length.lten(MAX_LENGTH), `Vec length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
assert(length.lten(MAX_LENGTH), () => `Vec length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
|
||||
return decodeU8a(registry, u8a.subarray(offset), new Array(length.toNumber()).fill(Type)) as T[];
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export class VecFixed<T extends Codec> extends AbstractArray<T> {
|
||||
values.push(new Type(registry));
|
||||
}
|
||||
|
||||
assert(values.length === allocLength, `Expected a length of exactly ${allocLength} entries`);
|
||||
assert(values.length === allocLength, () => `Expected a length of exactly ${allocLength} entries`);
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { U8aBitLength, UIntBitLength } from '../codec/types';
|
||||
import type { Codec, Constructor, InterfaceTypes, Registry } from '../types';
|
||||
import type { FromReg, TypeDef } from './types';
|
||||
|
||||
import { assert, isNumber, isUndefined } from '@polkadot/util';
|
||||
import { assert, isNumber, isUndefined, stringify } from '@polkadot/util';
|
||||
|
||||
import { BTreeMap, BTreeSet, CodecSet, Compact, Enum, HashMap, Int, Option, Result, Struct, Tuple, U8aFixed, UInt, Vec, VecFixed } from '../codec';
|
||||
import { DoNotConstruct } from '../primitive';
|
||||
@@ -33,13 +33,13 @@ export function ClassOf<K extends keyof InterfaceTypes> (registry: Registry, nam
|
||||
}
|
||||
|
||||
function getSubDefArray (value: TypeDef): TypeDef[] {
|
||||
assert(value.sub && Array.isArray(value.sub), `Expected subtype as TypeDef[] in ${JSON.stringify(value)}`);
|
||||
assert(value.sub && Array.isArray(value.sub), () => `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 ${JSON.stringify(value)}`);
|
||||
assert(value.sub && !Array.isArray(value.sub), () => `Expected subtype as TypeDef in ${stringify(value)}`);
|
||||
|
||||
return value.sub;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ function getTypeClassArray (value: TypeDef): (keyof InterfaceTypes)[] {
|
||||
}
|
||||
|
||||
function createInt ({ displayName, length }: TypeDef, Clazz: typeof Int | typeof UInt): Constructor {
|
||||
assert(isNumber(length), `Expected bitLength information for ${displayName || Clazz.constructor.name}<bitLength>`);
|
||||
assert(isNumber(length), () => `Expected bitLength information for ${displayName || Clazz.constructor.name}<bitLength>`);
|
||||
|
||||
return Clazz.with(length as UIntBitLength, displayName);
|
||||
}
|
||||
@@ -185,7 +185,7 @@ export function getTypeClass<T extends Codec = Codec> (registry: Registry, value
|
||||
|
||||
const getFn = infoMapping[value.info];
|
||||
|
||||
assert(getFn, `Unable to construct class from ${JSON.stringify(value)}`);
|
||||
assert(getFn, () => `Unable to construct class from ${stringify(value)}`);
|
||||
|
||||
return getFn(registry, value) as Constructor<T>;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import type { TypeDef } from './types';
|
||||
|
||||
import { assert, isNumber, isUndefined } from '@polkadot/util';
|
||||
import { assert, isNumber, isUndefined, stringify } from '@polkadot/util';
|
||||
|
||||
import { TypeDefInfo } from './types';
|
||||
|
||||
@@ -34,7 +34,7 @@ function encodeWithParams (typeDef: TypeDef, outer: string): string {
|
||||
return paramsNotation(outer, sub, (param) => encodeTypeDef(param));
|
||||
}
|
||||
|
||||
throw new Error(`Unable to encode ${JSON.stringify(typeDef)} with params`);
|
||||
throw new Error(`Unable to encode ${stringify(typeDef)} with params`);
|
||||
}
|
||||
|
||||
function encodeDoNotConstruct ({ displayName }: TypeDef): string {
|
||||
@@ -44,14 +44,14 @@ function encodeDoNotConstruct ({ displayName }: TypeDef): string {
|
||||
function encodeSubTypes (sub: TypeDef[], asEnum?: boolean): string {
|
||||
const names = sub.map(({ name }) => name);
|
||||
|
||||
assert(names.every((n) => !!n), `Subtypes does not have consistent names, ${names.join(', ')}`);
|
||||
assert(names.every((n) => !!n), () => `Subtypes does not have consistent names, ${names.join(', ')}`);
|
||||
|
||||
const inner = sub.reduce((result: Record<string, string>, type): Record<string, string> => ({
|
||||
...result,
|
||||
[type.name as string]: encodeTypeDef(type)
|
||||
}), {});
|
||||
|
||||
return JSON.stringify(
|
||||
return stringify(
|
||||
asEnum
|
||||
? { _enum: inner }
|
||||
: inner
|
||||
@@ -66,7 +66,7 @@ function encodeEnum (typeDef: TypeDef): string {
|
||||
// c-like enums have all Null entries
|
||||
// TODO We need to take the disciminant into account and auto-add empty entries
|
||||
return sub.every(({ type }) => type === 'Null')
|
||||
? JSON.stringify({ _enum: sub.map(({ name }, index) => `${name || `Empty${index}`}`) })
|
||||
? stringify({ _enum: sub.map(({ name }, index) => `${name || `Empty${index}`}`) })
|
||||
: encodeSubTypes(sub, true);
|
||||
}
|
||||
|
||||
@@ -121,13 +121,13 @@ const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
|
||||
function encodeType (typeDef: TypeDef): string {
|
||||
const encoder = encoders[typeDef.info];
|
||||
|
||||
assert(encoder, `Cannot encode type: ${JSON.stringify(typeDef)}`);
|
||||
assert(encoder, () => `Cannot encode type: ${stringify(typeDef)}`);
|
||||
|
||||
return encoder(typeDef);
|
||||
}
|
||||
|
||||
export function encodeTypeDef (typeDef: TypeDef): string {
|
||||
assert(!isUndefined(typeDef.info), `Invalid type definition with no instance info, ${JSON.stringify(typeDef)}`);
|
||||
assert(!isUndefined(typeDef.info), () => `Invalid type definition with no instance info, ${stringify(typeDef)}`);
|
||||
|
||||
// In the case of contracts we do have the unfortunate situation where the displayName would
|
||||
// refer to "Option" when it is an option. For these, string it out, only using when actually
|
||||
|
||||
@@ -110,7 +110,7 @@ function _decodeFixedVec (value: TypeDef, type: string, _: string, count: number
|
||||
const length = parseInt(strLength.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(length <= 256, `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
assert(length <= 256, () => `${type}: Only support for [Type; <length>], where length <= 256`);
|
||||
|
||||
value.displayName = displayName;
|
||||
value.length = length;
|
||||
@@ -137,7 +137,7 @@ function _decodeAnyInt (value: TypeDef, type: string, _: string, clazz: 'Int' |
|
||||
const length = parseInt(strLength.trim(), 10);
|
||||
|
||||
// as a first round, only u8 via u8aFixed, we can add more support
|
||||
assert(length <= 8192 && (length % 8) === 0, `${type}: Only support for ${clazz}<bitLength>, where length <= 8192 and a power of 8, found ${length}`);
|
||||
assert(length <= 8192 && (length % 8) === 0, () => `${type}: Only support for ${clazz}<bitLength>, where length <= 8192 and a power of 8, found ${length}`);
|
||||
|
||||
value.displayName = displayName;
|
||||
value.length = length;
|
||||
|
||||
@@ -10,7 +10,7 @@ import type { CallFunction, Codec, CodecHasher, Constructor, InterfaceTypes, Reg
|
||||
// we are attempting to avoid circular refs, hence the Metadata path import
|
||||
import { decorateConstants, decorateExtrinsics } from '@polkadot/metadata/decorate';
|
||||
import { Metadata } from '@polkadot/metadata/Metadata';
|
||||
import { assert, assertReturn, BN_ZERO, formatBalance, isFunction, isString, isU8a, logger, stringCamelCase, u8aToHex } from '@polkadot/util';
|
||||
import { assert, assertReturn, BN_ZERO, formatBalance, isFunction, isString, isU8a, logger, stringCamelCase, stringify, u8aToHex } from '@polkadot/util';
|
||||
import { blake2AsU8a } from '@polkadot/util-crypto';
|
||||
|
||||
import { Json } from '../codec/Json';
|
||||
@@ -340,8 +340,8 @@ export class TypeRegistry implements Registry {
|
||||
if (isFunction(arg1)) {
|
||||
this.#classes.set(arg1.name, arg1);
|
||||
} else if (isString(arg1)) {
|
||||
assert(isFunction(arg2), `Expected class definition passed to '${arg1}' registration`);
|
||||
assert(arg1 !== arg2.toString(), `Unable to register circular ${arg1} === ${arg1}`);
|
||||
assert(isFunction(arg2), () => `Expected class definition passed to '${arg1}' registration`);
|
||||
assert(arg1 !== arg2.toString(), () => `Unable to register circular ${arg1} === ${arg1}`);
|
||||
|
||||
this.#classes.set(arg1, arg2);
|
||||
} else {
|
||||
@@ -357,9 +357,9 @@ export class TypeRegistry implements Registry {
|
||||
} else {
|
||||
const def = isString(type)
|
||||
? type
|
||||
: JSON.stringify(type);
|
||||
: stringify(type);
|
||||
|
||||
assert(name !== def, `Unable to register circular ${name} === ${def}`);
|
||||
assert(name !== def, () => `Unable to register circular ${name} === ${def}`);
|
||||
|
||||
// we already have this type, remove the classes registered for it
|
||||
if (this.#classes.has(name)) {
|
||||
|
||||
@@ -42,7 +42,7 @@ export function typeSplit (type: string): string[] {
|
||||
}
|
||||
}
|
||||
|
||||
assert(isNotNested(cDepth, fDepth, sDepth, tDepth), `Invalid definition (missing terminators) found in ${type}`);
|
||||
assert(isNotNested(cDepth, fDepth, sDepth, tDepth), () => `Invalid definition (missing terminators) found in ${type}`);
|
||||
|
||||
// the final leg of the journey
|
||||
result.push(type.substr(start, type.length - start).trim());
|
||||
|
||||
@@ -206,7 +206,7 @@ export class GenericExtrinsic<A extends AnyTuple = AnyTuple> extends ExtrinsicBa
|
||||
const [offset, length] = compactFromU8a(value);
|
||||
const total = offset + length.toNumber();
|
||||
|
||||
assert(total <= value.length, `Extrinsic: length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
assert(total <= value.length, () => `Extrinsic: length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
const data = value.subarray(offset, total);
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ export class GenericExtrinsicEra extends Enum implements IExtrinsicEra {
|
||||
* @description Returns the item as a [[ImmortalEra]]
|
||||
*/
|
||||
public get asImmortalEra (): ImmortalEra {
|
||||
assert(this.isImmortalEra, `Cannot convert '${this.type}' via asImmortalEra`);
|
||||
assert(this.isImmortalEra, () => `Cannot convert '${this.type}' via asImmortalEra`);
|
||||
|
||||
return this.value as ImmortalEra;
|
||||
}
|
||||
@@ -255,7 +255,7 @@ export class GenericExtrinsicEra extends Enum implements IExtrinsicEra {
|
||||
* @description Returns the item as a [[MortalEra]]
|
||||
*/
|
||||
public get asMortalEra (): MortalEra {
|
||||
assert(this.isMortalEra, `Cannot convert '${this.type}' via asMortalEra`);
|
||||
assert(this.isMortalEra, () => `Cannot convert '${this.type}' via asMortalEra`);
|
||||
|
||||
return this.value as MortalEra;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Address, Balance, Call, Index } from '../../interfaces/runtime';
|
||||
import type { ExtrinsicPayloadValue, IExtrinsicSignature, IKeyringPair, Registry, SignatureOptions } from '../../types';
|
||||
import type { ExtrinsicSignatureOptions } from '../types';
|
||||
|
||||
import { assert, isU8a, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
import { assert, isU8a, stringify, u8aConcat, u8aToHex } from '@polkadot/util';
|
||||
|
||||
import { Compact } from '../../codec/Compact';
|
||||
import { Enum } from '../../codec/Enum';
|
||||
@@ -155,7 +155,7 @@ export class GenericExtrinsicSignatureV4 extends Struct implements IExtrinsicSig
|
||||
* @description Generate a payload and applies the signature from a keypair
|
||||
*/
|
||||
public sign (method: Call, account: IKeyringPair, options: SignatureOptions): IExtrinsicSignature {
|
||||
assert(account && account.addressRaw, `Expected a valid keypair for signing, found ${JSON.stringify(account)}`);
|
||||
assert(account && account.addressRaw, () => `Expected a valid keypair for signing, found ${stringify(account)}`);
|
||||
|
||||
const signer = toAddress(this.registry, account.addressRaw);
|
||||
const payload = this.createPayload(method, options);
|
||||
@@ -168,7 +168,7 @@ export class GenericExtrinsicSignatureV4 extends Struct implements IExtrinsicSig
|
||||
* @description Generate a payload and applies a fake signature
|
||||
*/
|
||||
public signFake (method: Call, address: Address | Uint8Array | string, options: SignatureOptions): IExtrinsicSignature {
|
||||
assert(address, `Expected a valid address for signing, found ${JSON.stringify(address)}`);
|
||||
assert(address, () => `Expected a valid address for signing, found ${stringify(address)}`);
|
||||
|
||||
const signer = toAddress(this.registry, address);
|
||||
const payload = this.createPayload(method, options);
|
||||
|
||||
@@ -35,15 +35,11 @@ export class GenericAccountId extends U8aFixed {
|
||||
const decoded = decodeAccountId(value);
|
||||
|
||||
// Part of stream containing >= 32 bytes or a all empty (defaults)
|
||||
assert(decoded.length >= 32 || !decoded.some((b) => b), `Invalid AccountId provided, expected 32 bytes, found ${decoded.length}`);
|
||||
assert(decoded.length >= 32 || !decoded.some((b) => b), () => `Invalid AccountId provided, expected 32 bytes, found ${decoded.length}`);
|
||||
|
||||
super(registry, decoded, 256);
|
||||
}
|
||||
|
||||
public static encode (value: Uint8Array, ss58Format?: number): string {
|
||||
return encodeAddress(value, ss58Format);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Compares the value of the input to see if there is a match
|
||||
*/
|
||||
@@ -69,7 +65,7 @@ export class GenericAccountId extends U8aFixed {
|
||||
* @description Returns the string representation of the value
|
||||
*/
|
||||
public toString (): string {
|
||||
return GenericAccountId.encode(this, this.registry.chainSS58);
|
||||
return encodeAddress(this, this.registry.chainSS58);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,7 @@ describe('Call', (): void => {
|
||||
it('handles decoding correctly (bare)', (): void => {
|
||||
expect(
|
||||
new Call(registry, {
|
||||
args: [],
|
||||
args: ['0x0000000000000000000000000000000000000000000000000000000000000000', 0, 0],
|
||||
callIndex: [6, 1] // balances.setBalance
|
||||
}).toU8a()
|
||||
).toEqual(
|
||||
|
||||
@@ -17,7 +17,7 @@ function decodeBitVecU8a (value?: Uint8Array): Uint8Array {
|
||||
const [offset, length] = compactFromU8a(value);
|
||||
const total = offset + Math.ceil(length.toNumber() / 8);
|
||||
|
||||
assert(total <= value.length, `BitVec: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
assert(total <= value.length, () => `BitVec: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return value.subarray(offset, total);
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ function decodeBytesU8a (value: Uint8Array): Uint8Array {
|
||||
const [offset, length] = compactFromU8a(value);
|
||||
const total = offset + length.toNumber();
|
||||
|
||||
assert(length.lten(MAX_LENGTH), `Bytes length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
assert(total <= value.length, `Bytes: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
assert(length.lten(MAX_LENGTH), () => `Bytes length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
assert(total <= value.length, () => `Bytes: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return value.subarray(offset, total);
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ function decodeText (value?: null | Text | string | AnyU8a | { toString: () => s
|
||||
const [offset, length] = compactFromU8a(value);
|
||||
const total = offset + length.toNumber();
|
||||
|
||||
assert(length.lten(MAX_LENGTH), `Text length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
assert(total <= value.length, `Text: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
assert(length.lten(MAX_LENGTH), () => `Text length ${length.toString()} exceeds ${MAX_LENGTH}`);
|
||||
assert(total <= value.length, () => `Text: required length less than remainder, expected at least ${total}, found ${value.length}`);
|
||||
|
||||
return u8aToString(value.subarray(offset, total));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user