Dedupe internal Codec property access (#4941)

* Dedupe internal Codec property access

* Remove getter override

* OptionBool fixes

* Adjust isBasic

* Remove isBasic check

* Re-add isBasic

* Remove static decodeCompact
This commit is contained in:
Jaco
2022-06-17 09:46:57 +03:00
committed by GitHub
parent d0c55a31b8
commit 530909d773
33 changed files with 165 additions and 199 deletions
@@ -10,6 +10,7 @@ import type { DeriveApi, DeriveDispatch, DeriveProposalImage } from '../types';
import { catchError, combineLatest, map, of, switchMap } from 'rxjs';
import { Enum } from '@polkadot/types';
import { isFunction, stringToHex } from '@polkadot/util';
import { memo } from '../util';
@@ -24,7 +25,7 @@ interface SchedulerInfo {
function isMaybeHashed (call: FrameSupportScheduleMaybeHashed | Call): call is FrameSupportScheduleMaybeHashed {
// check for enum
return (call as FrameSupportScheduleMaybeHashed).isBasic === false;
return call instanceof Enum;
}
function queryQueue (api: DeriveApi): Observable<DeriveDispatch[]> {
@@ -73,14 +73,14 @@ export abstract class AbstractArray<T extends Codec> extends Array<T> implements
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
inner: this.inspectInner(),
outer: [compactToU8a(this.length)]
};
}
inspectInner (): Inspect[] {
public inspectInner (): Inspect[] {
const inner = new Array<Inspect>(this.length);
for (let i = 0; i < this.length; i++) {
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyNumber, Inspect, INumber, IU8a, Registry, UIntBitLength } from '../types';
import { assert, BN, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, BN_ZERO, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isBn, isHex, isNumber, isString, isU8a, u8aToBn } from '@polkadot/util';
import { assert, BN, BN_BILLION, BN_HUNDRED, BN_MILLION, BN_QUINTILL, BN_ZERO, bnToBn, bnToHex, bnToU8a, formatBalance, formatNumber, hexToBn, isBn, isHex, isNumber, isString, isU8a, u8aToBn, u8aToNumber } from '@polkadot/util';
export const DEFAULT_UINT_BITS = 64;
@@ -55,27 +55,29 @@ export abstract class AbstractInt extends BN implements INumber {
public createdAtHash?: IU8a;
readonly encodedLength: number;
public readonly encodedLength: number;
public readonly isUnsigned: boolean;
readonly #bitLength: UIntBitLength;
readonly #isSigned: boolean;
constructor (registry: Registry, value: AnyNumber = 0, bitLength: UIntBitLength = DEFAULT_UINT_BITS, isSigned = false) {
// Construct via a string, which will be passed in the BN constructor.
// Construct via a string/number, which will be passed in the BN constructor.
// It would be ideal to actually return a BN, but there is an issue:
// https://github.com/indutny/bn.js/issues/206
super(
// shortcut isU8a as used in SCALE decoding
isU8a(value)
? u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative: isSigned }).toString()
? bitLength <= 48
? u8aToNumber(value.subarray(0, bitLength / 8), { isNegative: isSigned })
: u8aToBn(value.subarray(0, bitLength / 8), { isLe: true, isNegative: isSigned }).toString()
: decodeAbstractInt(value, isSigned)
);
this.registry = registry;
this.#bitLength = bitLength;
this.encodedLength = this.#bitLength / 8;
this.#isSigned = isSigned;
this.isUnsigned = !isSigned;
const isPositive = this.gte(BN_ZERO);
const maxBits = bitLength - (isSigned && isPositive ? 1 : 0);
@@ -98,13 +100,6 @@ export abstract class AbstractInt extends BN implements INumber {
return this.isZero();
}
/**
* @description Checks if the value is an unsigned type
*/
public get isUnsigned (): boolean {
return !this.#isSigned;
}
/**
* @description Returns the number of bits in the value
*/
@@ -121,7 +116,7 @@ export abstract class AbstractInt extends BN implements INumber {
// number and BN inputs (no `.eqn` needed) - numbers will be converted
return super.eq(
isHex(other)
? hexToBn(other.toString(), { isLe: false, isNegative: this.#isSigned })
? hexToBn(other.toString(), { isLe: false, isNegative: !this.isUnsigned })
: bnToBn(other as string)
);
}
@@ -129,7 +124,7 @@ export abstract class AbstractInt extends BN implements INumber {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
outer: [this.toU8a()]
};
+5 -9
View File
@@ -9,18 +9,18 @@ import type { AnyJson, BareOpts, Codec, Inspect, IU8a, Registry } from '../types
* @description A type extends the Base class, when it holds a value
*/
export abstract class Base<T extends Codec> implements Codec {
readonly #registry: Registry;
public createdAtHash?: IU8a;
readonly initialU8aLength?: number;
public readonly initialU8aLength?: number;
public readonly registry: Registry;
readonly #raw: T;
protected constructor (registry: Registry, value: T, initialU8aLength?: number) {
this.#registry = registry;
this.#raw = value;
this.initialU8aLength = initialU8aLength;
this.registry = registry;
}
/**
@@ -48,10 +48,6 @@ export abstract class Base<T extends Codec> implements Codec {
return this.#raw.isEmpty;
}
public get registry (): Registry {
return this.#registry;
}
/**
* @description Compares the value of the input to see if there is a match
*/
@@ -62,7 +58,7 @@ export abstract class Base<T extends Codec> implements Codec {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return this.#raw.inspect();
}
+22 -21
View File
@@ -18,6 +18,26 @@ function noopSetDefinition <T> (d: CodecClass<T>): CodecClass<T> {
return d;
}
function decodeCompact<T extends INumber> (registry: Registry, Type: CodecClass<T>, value: Compact<T> | AnyNumber): [T, number] {
if (isU8a(value)) {
const [decodedLength, bn] = (value[0] & 0b11) < 0b11
? compactFromU8aLim(value)
: compactFromU8a(value);
return [new Type(registry, bn), decodedLength];
} else if (value instanceof Compact) {
const raw = value.unwrap();
return raw instanceof Type
? [raw, 0]
: [new Type(registry, raw), 0];
} else if (value instanceof Type) {
return [value, 0];
}
return [new Type(registry, value), 0];
}
/**
* @name Compact
* @description
@@ -41,7 +61,7 @@ export class Compact<T extends INumber> implements ICompact<T> {
this.registry = registry;
this.#Type = definition || setDefinition(typeToConstructor(registry, Type));
const [raw, decodedLength] = Compact.decodeCompact<T>(registry, this.#Type, value);
const [raw, decodedLength] = decodeCompact<T>(registry, this.#Type, value);
this.initialU8aLength = decodedLength;
this.#raw = raw;
@@ -61,25 +81,6 @@ export class Compact<T extends INumber> implements ICompact<T> {
};
}
/** @internal */
public static decodeCompact<T extends INumber> (registry: Registry, Type: CodecClass<T>, value: Compact<T> | AnyNumber): [T, number] {
if (isU8a(value)) {
const [decodedLength, bn] = (value[0] & 0b11) < 0b11
? compactFromU8aLim(value)
: compactFromU8a(value);
return [new Type(registry, bn), decodedLength];
} else if (value instanceof Compact) {
return value.#raw instanceof Type
? [value.#raw, 0]
: [new Type(registry, value.#raw), 0];
} else if (value instanceof Type) {
return [value, 0];
}
return [new Type(registry, value), 0];
}
/**
* @description The length of the value when encoded as a Uint8Array
*/
@@ -122,7 +123,7 @@ export class Compact<T extends INumber> implements ICompact<T> {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
outer: [this.toU8a()]
};
@@ -56,7 +56,7 @@ export class DoNotConstruct implements Codec {
throw this.#neverError;
}
inspect (): Inspect {
public inspect (): Inspect {
throw this.#neverError;
}
+7 -7
View File
@@ -4,7 +4,7 @@
import type { HexString } from '@polkadot/util/types';
import type { AnyJson, Codec, CodecClass, IEnum, Inspect, IU8a, Registry } from '../types';
import { assert, isCodec, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { assert, isHex, isNumber, isObject, isString, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, stringPascalCase, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { mapToTypeMap, typesToMap } from '../utils';
import { Null } from './Null';
@@ -101,7 +101,7 @@ function createFromValue (registry: Registry, def: TypesDef, index = 0, value?:
return {
index,
value: isCodec(value) && value instanceof entry.Type
value: value instanceof entry.Type
? value
: new entry.Type(registry, value)
};
@@ -189,7 +189,7 @@ export class Enum implements IEnum {
this.#isBasic = isBasic;
this.#isIndexed = isIndexed;
this.#indexes = Object.values(def).map(({ index }) => index);
this.#entryIndex = this.#indexes.indexOf(decoded.index) || 0;
this.#entryIndex = this.#indexes.indexOf(decoded.index);
this.#raw = decoded.value;
if (this.#raw.initialU8aLength) {
@@ -205,7 +205,7 @@ export class Enum implements IEnum {
const isKeys = new Array<string>(keys.length);
for (let i = 0; i < keys.length; i++) {
const name = stringPascalCase(keys[i].replace(' ', '_'));
const name = stringPascalCase(keys[i]);
asKeys[i] = `as${name}`;
isKeys[i] = `is${name}`;
@@ -329,7 +329,7 @@ export class Enum implements IEnum {
return this.type === other;
} else if (isHex(other)) {
return this.toHex() === other;
} else if (isCodec(other) && other instanceof Enum) {
} else if (other instanceof Enum) {
return this.index === other.index && this.value.eq(other.value);
} else if (isObject(other)) {
return this.value.eq(other[this.type]);
@@ -342,8 +342,8 @@ export class Enum implements IEnum {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
if (this.isBasic) {
public inspect (): Inspect {
if (this.#isBasic) {
return { outer: [new Uint8Array([this.index])] };
}
+5 -15
View File
@@ -12,6 +12,10 @@ import { isNull } from '@polkadot/util';
* Implements a type that does not contain anything (apart from `null`)
*/
export class Null implements Codec {
public readonly encodedLength = 0;
public readonly isEmpty = true;
public readonly registry: Registry;
public createdAtHash?: IU8a;
@@ -23,13 +27,6 @@ export class Null implements Codec {
this.registry = registry;
}
/**
* @description The length of the value when encoded as a Uint8Array
*/
public get encodedLength (): number {
return 0;
}
/**
* @description returns a hash of the contents
*/
@@ -37,13 +34,6 @@ export class Null implements Codec {
throw new Error('.hash is not implemented on Null');
}
/**
* @description Checks if the value is an empty value (always true)
*/
public get isEmpty (): boolean {
return true;
}
/**
* @description Compares the value of the input to see if there is a match
*/
@@ -54,7 +44,7 @@ export class Null implements Codec {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {};
}
+4 -11
View File
@@ -70,9 +70,9 @@ export class Option<T extends Codec> implements IOption<T> {
public createdAtHash?: IU8a;
readonly #Type: CodecClass<T>;
public initialU8aLength?: number;
readonly #initialU8aLength?: number;
readonly #Type: CodecClass<T>;
readonly #raw: T;
@@ -89,7 +89,7 @@ export class Option<T extends Codec> implements IOption<T> {
this.#raw = decoded as T;
if (decoded && decoded.initialU8aLength) {
this.#initialU8aLength = 1 + decoded.initialU8aLength;
this.initialU8aLength = 1 + decoded.initialU8aLength;
}
}
@@ -117,13 +117,6 @@ export class Option<T extends Codec> implements IOption<T> {
return 1 + this.#raw.encodedLength;
}
/**
* @description The length of the initial encoded value (Only available when constructed from a Uint8Array)
*/
public get initialU8aLength (): number | undefined {
return this.#initialU8aLength;
}
/**
* @description returns a hash of the contents
*/
@@ -173,7 +166,7 @@ export class Option<T extends Codec> implements IOption<T> {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
if (this.isNone) {
return { outer: [new Uint8Array([0])] };
}
+7 -7
View File
@@ -26,7 +26,7 @@ function noopSetDefinition (d: Definition): Definition {
}
/** @internal */
function decodeTuple (registry: Registry, result: Codec[], Classes: Definition, value?: Exclude<AnyTupleValue, Uint8Array>): [Codec[], number] {
function decodeTuple (registry: Registry, result: Codec[], value: Exclude<AnyTupleValue, Uint8Array> | undefined, Classes: Definition): [Codec[], number] {
if (isU8a(value) || isHex(value)) {
return decodeU8a(registry, result, u8aToU8a(value), Classes);
}
@@ -70,11 +70,11 @@ export class Tuple extends AbstractArray<Codec> implements ITuple<Codec[]> {
super(registry, Classes[0].length);
const [, decodedLength] = isU8a(value)
? decodeU8a(registry, this, value, Classes, false)
: decodeTuple(registry, this, Classes, value);
this.initialU8aLength = decodedLength;
this.initialU8aLength = (
isU8a(value)
? decodeU8a(registry, this, value, Classes)
: decodeTuple(registry, this, value, Classes)
)[1];
this.#Types = Classes;
}
@@ -117,7 +117,7 @@ export class Tuple extends AbstractArray<Codec> implements ITuple<Codec[]> {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
override inspect (): Inspect {
public override inspect (): Inspect {
return {
inner: this.inspectInner()
};
+5 -5
View File
@@ -78,11 +78,11 @@ export class Vec<T extends Codec> extends AbstractArray<T> {
this.#Type = definition || setDefinition(typeToConstructor<T>(registry, Type));
const [decodedLength] = isU8a(decodeFrom)
? decodeU8aVec(registry, this, decodeFrom, startAt, this.#Type)
: decodeVec(registry, this, decodeFrom, startAt, this.#Type);
this.initialU8aLength = decodedLength;
this.initialU8aLength = (
isU8a(decodeFrom)
? decodeU8aVec(registry, this, decodeFrom, startAt, this.#Type)
: decodeVec(registry, this, decodeFrom, startAt, this.#Type)
)[0];
}
public static with<O extends Codec> (Type: CodecClass<O> | string): CodecClass<Vec<O>> {
+6 -6
View File
@@ -34,11 +34,11 @@ export class VecFixed<T extends Codec> extends AbstractArray<T> {
this.#Type = definition || setDefinition(typeToConstructor<T>(registry, Type));
const [, decodedLengthNoOffset] = isU8a(value)
? decodeU8aVec(registry, this, value, 0, this.#Type)
: decodeVec(registry, this, value, 0, this.#Type);
this.initialU8aLength = decodedLengthNoOffset;
this.initialU8aLength = (
isU8a(value)
? decodeU8aVec(registry, this, value, 0, this.#Type)
: decodeVec(registry, this, value, 0, this.#Type)
)[1];
}
public static with<O extends Codec> (Type: CodecClass<O> | string, length: number): CodecClass<VecFixed<O>> {
@@ -78,7 +78,7 @@ export class VecFixed<T extends Codec> extends AbstractArray<T> {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
override inspect (): Inspect {
public override inspect (): Inspect {
return {
inner: this.inspectInner()
};
@@ -140,7 +140,7 @@ export class BTreeSet<V extends Codec = Codec> extends Set<V> implements ISet<V>
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
const inner = new Array<Inspect>();
for (const v of this.values()) {
+1 -1
View File
@@ -65,7 +65,7 @@ export class BitVec extends Raw {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
override inspect (): Inspect {
public override inspect (): Inspect {
return {
outer: [compactToU8a(this.#decodedLength), super.toU8a()]
};
+3 -3
View File
@@ -3,7 +3,7 @@
import type { AnyU8a, Inspect, Registry } from '../types';
import { assert, compactAddLength, compactFromU8aLim, compactToU8a, isCodec, isString, isU8a, u8aToU8a } from '@polkadot/util';
import { assert, compactAddLength, compactFromU8aLim, compactToU8a, isString, isU8a, u8aToU8a } from '@polkadot/util';
import { Raw } from '../native/Raw';
@@ -35,7 +35,7 @@ function decodeBytesU8a (value: Uint8Array): [Uint8Array, number] {
*/
export class Bytes extends Raw {
constructor (registry: Registry, value?: AnyU8a) {
const [u8a, decodedLength] = isU8a(value) && !(isCodec(value) && value instanceof Raw)
const [u8a, decodedLength] = isU8a(value) && !(value instanceof Raw)
? decodeBytesU8a(value)
: Array.isArray(value) || isString(value)
? [u8aToU8a(value), 0]
@@ -54,7 +54,7 @@ export class Bytes extends Raw {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
override inspect (isBare?: boolean): Inspect {
public override inspect (isBare?: boolean): Inspect {
const clength = compactToU8a(this.length);
return {
+1 -1
View File
@@ -154,7 +154,7 @@ export class CodecMap<K extends Codec = Codec, V extends Codec = Codec> extends
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
const inner = new Array<Inspect>();
for (const [k, v] of this.entries()) {
@@ -32,6 +32,8 @@ export class OptionBool extends Option<Bool> {
? decodeU8a(registry, u8aToU8a(value))
: value
);
this.initialU8aLength = 1;
}
/**
@@ -41,13 +43,6 @@ export class OptionBool extends Option<Bool> {
return 1;
}
/**
* @description The length of the initial encoded value (Only available when constructed from a Uint8Array)
*/
public override get initialU8aLength (): number {
return 1;
}
/**
* @description Checks if the value is an empty value (always false)
*/
@@ -69,7 +64,7 @@ export class OptionBool extends Option<Bool> {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
override inspect (): Inspect {
public override inspect (): Inspect {
return { outer: [this.toU8a()] };
}
@@ -70,7 +70,7 @@ export class WrapperKeepOpaque<T extends Codec> extends Bytes {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
override inspect (): Inspect {
public override inspect (): Inspect {
return this.#decoded
? {
inner: [this.#decoded.inspect()],
+1 -1
View File
@@ -78,7 +78,7 @@ export class bool extends Boolean implements Codec {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
outer: [this.toU8a()]
};
+1 -1
View File
@@ -81,7 +81,7 @@ export class CodecDate extends Date implements INumber {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
outer: [this.toU8a()]
};
+4 -4
View File
@@ -16,11 +16,11 @@ import { assert, isAscii, isUndefined, isUtf8, u8aToHex, u8aToString, u8aToU8a }
* @noInheritDoc
*/
export class Raw extends Uint8Array implements IU8a {
readonly registry: Registry;
public createdAtHash?: IU8a;
readonly initialU8aLength?: number;
public readonly initialU8aLength?: number;
public readonly registry: Registry;
constructor (registry: Registry, value?: AnyU8a, initialU8aLength?: number) {
super(u8aToU8a(value));
@@ -94,7 +94,7 @@ export class Raw extends Uint8Array implements IU8a {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
outer: [this.toU8a()]
};
+1 -1
View File
@@ -187,7 +187,7 @@ export class CodecSet extends Set<string> implements ISet<string> {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
return {
outer: [this.toU8a()]
};
+7 -11
View File
@@ -6,7 +6,7 @@ import type { AnyJson, BareOpts, Codec, CodecClass, Inspect, IStruct, IU8a, Regi
import { assert, isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, objectProperties, stringCamelCase, stringify, u8aConcatStrict, u8aToHex, u8aToU8a } from '@polkadot/util';
import { compareMap, decodeU8a, mapToTypeMap, typesToMap } from '../utils';
import { compareMap, decodeU8aStruct, mapToTypeMap, typesToMap } from '../utils';
type TypesDef<T = Codec> = Record<string, string | CodecClass<T>>;
@@ -100,11 +100,11 @@ export class Struct<
V extends { [K in keyof S]: any } = { [K in keyof S]: any },
// type names, mapped by key, name of Class in S
E extends { [K in keyof S]: string } = { [K in keyof S]: string }> extends Map<keyof S, Codec> implements IStruct<keyof S> {
#registry: Registry;
public createdAtHash?: IU8a;
readonly initialU8aLength?: number;
public readonly initialU8aLength?: number;
public readonly registry: Registry;
readonly #jsonMap: Map<keyof S, string>;
@@ -113,15 +113,15 @@ export class Struct<
constructor (registry: Registry, Types: S, value?: V | Map<unknown, unknown> | unknown[] | HexString | null, jsonMap = new Map<string, string>(), { definition, setDefinition = noopSetDefinition }: Options = {}) {
const typeMap = definition || setDefinition(mapToTypeMap(registry, Types));
const [decoded, decodedLength] = isU8a(value) || isHex(value)
? decodeU8a<Codec, [string, Codec]>(registry, new Array(typeMap[0].length), u8aToU8a(value), typeMap, true)
? decodeU8aStruct(registry, new Array<[string, Codec]>(typeMap[0].length), u8aToU8a(value), typeMap)
: value instanceof Struct
? [value as Iterable<[string, Codec]>, 0]
: decodeStructFromObject(registry, typeMap, value || {}, jsonMap);
super(decoded);
this.#registry = registry;
this.initialU8aLength = decodedLength;
this.registry = registry;
this.#jsonMap = jsonMap;
this.#Types = typeMap;
}
@@ -202,10 +202,6 @@ export class Struct<
return this.registry.hash(this.toU8a());
}
public get registry (): Registry {
return this.#registry;
}
/**
* @description Compares the value of the input to see if there is a match
*/
@@ -231,7 +227,7 @@ export class Struct<
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (isBare?: BareOpts): Inspect {
public inspect (isBare?: BareOpts): Inspect {
const inner = new Array<Inspect>();
for (const [k, v] of this.entries()) {
+5 -12
View File
@@ -46,11 +46,11 @@ function decodeText (value?: null | AnyString | AnyU8a | { toString: () => strin
* @noInheritDoc
*/
export class Text extends String implements IText {
public readonly registry: Registry;
public createdAtHash?: IU8a;
readonly #initialU8aLength?: number;
public readonly initialU8aLength?: number;
public readonly registry: Registry;
#override: string | null = null;
@@ -60,7 +60,7 @@ export class Text extends String implements IText {
super(str);
this.registry = registry;
this.#initialU8aLength = decodedLength;
this.initialU8aLength = decodedLength;
}
/**
@@ -70,13 +70,6 @@ export class Text extends String implements IText {
return this.toU8a().length;
}
/**
* @description The length of the initial encoded value (Only available when constructed from a Uint8Array)
*/
public get initialU8aLength (): number | undefined {
return this.#initialU8aLength;
}
/**
* @description returns a hash of the contents
*/
@@ -111,7 +104,7 @@ export class Text extends String implements IText {
/**
* @description Returns a breakdown of the hex encoding for this Codec
*/
inspect (): Inspect {
public inspect (): Inspect {
const value = stringToU8a(super.toString());
return {
+1 -1
View File
@@ -17,7 +17,7 @@ export interface IEnum extends Codec {
readonly defIndexes: number[];
readonly defKeys: string[];
readonly index: number;
readonly isBasic: boolean
readonly isBasic: boolean;
readonly type: string;
readonly value: Codec;
+56 -30
View File
@@ -5,19 +5,22 @@ import type { Codec, CodecClass, Registry } from '../types';
import { u8aToHex } from '@polkadot/util';
function formatFailure (error: Error, type: string | null, u8a: Uint8Array, key?: string): string {
return `decodeU8a: failed at ${u8aToHex(u8a)}…${key ? ` on ${key}` : ''}${type ? `: ${type}` : ''}:: ${error.message}`;
}
/** @internal */
function formatFailure (registry: Registry, { message }: Error, u8a: Uint8Array, i: number, count: number, Type: CodecClass, key?: string): string {
let type = '';
function getRawType (registry: Registry, Type: CodecClass): string | null {
try {
return new Type(registry).toRawType();
type = `: ${new Type(registry).toRawType()}`;
} catch {
return null;
// ignore
}
return `decodeU8a: failed at ${u8aToHex(u8a.subarray(0, 16))}…${key ? ` on ${key}` : ''} (index ${i}/${count})${type}:: ${message}`;
}
/**
* @internal
*
* Given an u8a, and an array of Type constructors, decode the u8a against the
* types, and return an array of decoded values.
*
@@ -25,50 +28,73 @@ function getRawType (registry: Registry, Type: CodecClass): string | null {
* @param result - The result array (will be returned with values pushed)
* @param types - The array of CodecClass to decode the U8a against.
*/
export function decodeU8a <T extends Codec = Codec, E = T> (registry: Registry, result: unknown[], u8a: Uint8Array, [Types, keys]: [CodecClass[], string[]], withZip?: boolean): [E[], number] {
export function decodeU8a <T extends Codec = Codec> (registry: Registry, result: T[], u8a: Uint8Array, [Types, keys]: [CodecClass<T>[], string[]]): [T[], number] {
const count = result.length;
let offset = 0;
let i = 0;
for (let i = 0; i < count; i++) {
try {
try {
while (i < count) {
const value = new Types[i](registry, u8a.subarray(offset));
offset += value.initialU8aLength || value.encodedLength;
result[i] = withZip
? [keys[i], value]
: value;
} catch (error) {
throw new Error(formatFailure(
error as Error,
getRawType(registry, Types[i]),
u8a.subarray(offset, offset + 16),
keys[i]
));
result[i] = value;
i++;
}
} catch (error) {
throw new Error(formatFailure(registry, error as Error, u8a.subarray(offset), i, count, Types[i], keys[i]));
}
return [result as E[], offset];
return [result, offset];
}
// Split from decodeU8a since this is specialized to 1 instance ... yes duplication, but
// since we have to do less checks (and these are intensive anyway), much faster
/**
* @internal
*
* Split from decodeU8a since this is specialized to zip returns ... while we duplicate, this
* is all on the hot-path, so it is not great, however there is (some) method behind the madness
*/
export function decodeU8aStruct (registry: Registry, result: [string, Codec][], u8a: Uint8Array, [Types, keys]: [CodecClass[], string[]]): [[string, Codec][], number] {
const count = result.length;
let offset = 0;
let i = 0;
try {
while (i < count) {
const value = new Types[i](registry, u8a.subarray(offset));
offset += value.initialU8aLength || value.encodedLength;
result[i] = [keys[i], value];
i++;
}
} catch (error) {
throw new Error(formatFailure(registry, error as Error, u8a.subarray(offset), i, count, Types[i], keys[i]));
}
return [result, offset];
}
/**
* @internal
*
* Split from decodeU8a since this is specialized to 1 instance ... while we duplicate, this
* is all on the hot-path, so it is not great, however there is (some) method behind the madness
*/
export function decodeU8aVec <T extends Codec = Codec> (registry: Registry, result: unknown[], u8a: Uint8Array, startAt: number, Type: CodecClass<T>): [number, number] {
const count = result.length;
let offset = startAt;
let i = 0;
for (let i = 0; i < count; i++) {
try {
try {
while (i < count) {
const value = new Type(registry, u8a.subarray(offset));
offset += value.initialU8aLength || value.encodedLength;
result[i] = value;
} catch (error) {
throw new Error(formatFailure(
error as Error,
getRawType(registry, Type),
u8a.subarray(offset, offset + 16)
));
i++;
}
} catch (error) {
throw new Error(formatFailure(registry, error as Error, u8a.subarray(offset), i, count, Type));
}
return [offset, offset - startAt];
+1 -1
View File
@@ -4,7 +4,7 @@
export { compareArray } from './compareArray';
export { compareMap } from './compareMap';
export { compareSet } from './compareSet';
export { decodeU8a, decodeU8aVec } from './decodeU8a';
export { decodeU8a, decodeU8aStruct, decodeU8aVec } from './decodeU8a';
export { mapToTypeMap } from './mapToTypeMap';
export { typeToConstructor } from './typeToConstructor';
export { sanitize } from './sanitize';
@@ -13,7 +13,7 @@ export function mapToTypeMap (registry: Registry, input: Record<string, string |
const count = entries.length;
const output: [CodecClass[], string[]] = [new Array<CodecClass>(count), new Array<string>(count)];
for (let i = 0; i < entries.length; i++) {
for (let i = 0; i < count; i++) {
output[1][i] = entries[i][0];
output[0][i] = typeToConstructor(registry, entries[i][1]);
}
@@ -167,10 +167,6 @@ abstract class ExtrinsicBase<A extends AnyTuple> extends Base<ExtrinsicVx | Extr
return this.inner.signature.nonce;
}
public override get registry (): Registry {
return super.registry;
}
/**
* @description The actual [[EcdsaSignature]], [[Ed25519Signature]] or [[Sr25519Signature]]
*/
@@ -65,10 +65,6 @@ export class GenericExtrinsicV4 extends Struct implements IExtrinsicImpl {
return this.getT('method');
}
public override get registry (): Registry {
return super.registry;
}
/**
* @description The [[ExtrinsicSignatureV4]]
*/
@@ -89,10 +89,6 @@ export class GenericExtrinsicSignatureV4 extends Struct implements IExtrinsicSig
return this.getT('nonce');
}
public override get registry (): Registry {
return super.registry;
}
/**
* @description The actual [[EcdsaSignature]], [[Ed25519Signature]] or [[Sr25519Signature]]
*/
-4
View File
@@ -189,10 +189,6 @@ export class GenericCall<A extends AnyTuple = AnyTuple> extends Struct implement
return this.registry.findMetaCall(this.callIndex).method;
}
public override get registry (): Registry {
return super.registry;
}
/**
* @description Returns the module containing the method
*/
@@ -73,10 +73,6 @@ export class MetadataVersioned extends Struct {
return this.getT('metadata');
};
public override get registry (): Registry {
return super.registry;
}
/**
* @description Returns the wrapped metadata as a limited calls-only (latest) version
*/