diff --git a/CHANGELOG.md b/CHANGELOG.md index 4b8585d4db..694fa61ac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Changes: - Use Promise resolve/reject to track state in typegen on-chain metadata retrievals - Basic support for markdown generation for different chains (only Kusama & Polkadot currently added) +- Add not-to-be-used `ISize` type support (same as `USize`, throwing on use - added for completeness) +- Expand tests around `toU8a()` where the `isBare` flag is is being used ## 10.1.4 Mar 19, 2023 diff --git a/packages/types-augment/src/registry/interfaces.ts b/packages/types-augment/src/registry/interfaces.ts index 5ce509bfd6..1bdc0db13a 100644 --- a/packages/types-augment/src/registry/interfaces.ts +++ b/packages/types-augment/src/registry/interfaces.ts @@ -6,7 +6,7 @@ import '@polkadot/types/types/registry'; import type { Data, StorageKey } from '@polkadot/types'; -import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; +import type { BitVec, Bool, Bytes, F32, F64, I128, I16, I256, I32, I64, I8, ISize, Json, Null, OptionBool, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, f32, f64, i128, i16, i256, i32, i64, i8, isize, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec'; import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets'; import type { BlockAttestations, IncludedBlocks, MoreAttestations } from '@polkadot/types/interfaces/attestations'; import type { RawAuraPreDigest } from '@polkadot/types/interfaces/aura'; @@ -549,6 +549,8 @@ declare module '@polkadot/types/types/registry' { I64: I64; i8: i8; I8: I8; + isize: isize; + ISize: ISize; IdentificationTuple: IdentificationTuple; IdentityFields: IdentityFields; IdentityInfo: IdentityInfo; diff --git a/packages/types-codec/src/abstract/Array.ts b/packages/types-codec/src/abstract/Array.ts index d6f507521d..f6d3e79553 100644 --- a/packages/types-codec/src/abstract/Array.ts +++ b/packages/types-codec/src/abstract/Array.ts @@ -90,6 +90,10 @@ export abstract class AbstractArray extends Array implements }; } + /** + * @internal + * @description Internal per-item inspection of internal values + */ public inspectInner (): Inspect[] { const inner = new Array(this.length); @@ -185,6 +189,11 @@ export abstract class AbstractArray extends Array implements : u8aConcatStrict([compactToU8a(this.length), ...encoded]); } + /** + * @internal + * @description Internal per-item SCALE encoding of contained values + * @param isBare true when the value has none of the type-specific prefixes (internal) + */ public toU8aInner (isBare?: boolean): Uint8Array[] { const encoded = new Array(this.length); diff --git a/packages/types-codec/src/abstract/Int.ts b/packages/types-codec/src/abstract/Int.ts index 152ec10df6..c832b4c184 100644 --- a/packages/types-codec/src/abstract/Int.ts +++ b/packages/types-codec/src/abstract/Int.ts @@ -260,7 +260,6 @@ export abstract class AbstractInt extends BN implements INumber { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return bnToU8a(this, { diff --git a/packages/types-codec/src/base/Compact.ts b/packages/types-codec/src/base/Compact.ts index 11c75e0113..d5523bc580 100644 --- a/packages/types-codec/src/base/Compact.ts +++ b/packages/types-codec/src/base/Compact.ts @@ -193,7 +193,6 @@ export class Compact implements ICompact { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return compactToU8a(this.#raw.toBn()); diff --git a/packages/types-codec/src/base/DoNotConstruct.ts b/packages/types-codec/src/base/DoNotConstruct.ts index 5f2304e342..018d3a0510 100644 --- a/packages/types-codec/src/base/DoNotConstruct.ts +++ b/packages/types-codec/src/base/DoNotConstruct.ts @@ -53,38 +53,65 @@ export class DoNotConstruct implements Codec { throw this.#neverError; } + /** + * @description Unimplemented + */ eq (): boolean { throw this.#neverError; } + /** + * @description Unimplemented + */ public inspect (): Inspect { throw this.#neverError; } + /** + * @description Unimplemented + */ toHex (): HexString { throw this.#neverError; } + /** + * @description Unimplemented + */ toHuman (): AnyJson { throw this.#neverError; } + /** + * @description Unimplemented + */ toJSON (): AnyJson { throw this.#neverError; } + /** + * @description Unimplemented + */ toPrimitive (): AnyJson { throw this.#neverError; } + /** + * @description Unimplemented + */ toRawType (): string { throw this.#neverError; } + /** + * @description Unimplemented + */ toString (): string { throw this.#neverError; } + /** + * @description Unimplemented + */ toU8a (): Uint8Array { throw this.#neverError; } diff --git a/packages/types-codec/src/base/Enum.spec.ts b/packages/types-codec/src/base/Enum.spec.ts index 2ade5699b6..d80104d8f0 100644 --- a/packages/types-codec/src/base/Enum.spec.ts +++ b/packages/types-codec/src/base/Enum.spec.ts @@ -460,5 +460,28 @@ describe('Enum', (): void => { }); }); + describe('toU8a', (): void => { + const Test = Enum.with({ + A: Text, + B: U32 + }); + + it('has a correct toU8a() output', (): void => { + expect( + new Test(registry, { B: 69 }).toU8a() + ).toEqual( + new Uint8Array([1, 69, 0, 0, 0]) + ); + }); + + it('has a correct toU8a(true) output', (): void => { + expect( + new Test(registry, { B: 69 }).toU8a(true) + ).toEqual( + new Uint8Array([69, 0, 0, 0]) + ); + }); + }); + perf('Enum', 20_000, [[new Uint8Array([0, 31, 32, 33, 34])]], (v: Uint8Array) => new PEnum(registry, v)); }); diff --git a/packages/types-codec/src/base/Null.ts b/packages/types-codec/src/base/Null.ts index 659ec846ff..ab20c90076 100644 --- a/packages/types-codec/src/base/Null.ts +++ b/packages/types-codec/src/base/Null.ts @@ -89,7 +89,6 @@ export class Null implements Codec { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return new Uint8Array(); diff --git a/packages/types-codec/src/base/Option.spec.ts b/packages/types-codec/src/base/Option.spec.ts index 692ae81b2c..880431c4a7 100644 --- a/packages/types-codec/src/base/Option.spec.ts +++ b/packages/types-codec/src/base/Option.spec.ts @@ -147,6 +147,12 @@ describe('Option', (): void => { ).toEqual(new Uint8Array([1, 4 << 2, 49, 50, 51, 52])); }); + it('allows bare specifiers on toU8a', (): void => { + expect( + new Option(registry, Text, '1234').toU8a(true) + ).toEqual(new Uint8Array([49, 50, 51, 52])); + }); + it('converts toU8a() without', (): void => { expect( new Option(registry, Text).toU8a() diff --git a/packages/types-codec/src/base/Vec.spec.ts b/packages/types-codec/src/base/Vec.spec.ts index 21c842825e..f9feead8f7 100644 --- a/packages/types-codec/src/base/Vec.spec.ts +++ b/packages/types-codec/src/base/Vec.spec.ts @@ -86,7 +86,7 @@ describe('Vec', (): void => { expect(vector.toString()).toEqual('[1, 23, 345, 4567, 56789]'); }); - it('encodes with length prefix', (): void => { + it('encodes with length prefix on toU8a()', (): void => { expect(vector.toU8a()).toEqual(new Uint8Array([ 5 << 2, 1 << 2, 49, @@ -97,6 +97,16 @@ describe('Vec', (): void => { ])); }); + it('encodes without length prefix on toU8a(true)', (): void => { + expect(vector.toU8a(true)).toEqual(new Uint8Array([ + 1 << 2, 49, + 2 << 2, 50, 51, + 3 << 2, 51, 52, 53, + 4 << 2, 52, 53, 54, 55, + 5 << 2, 53, 54, 55, 56, 57 + ])); + }); + it('exposes the type', (): void => { expect(vector.Type).toEqual('Text'); }); diff --git a/packages/types-codec/src/extended/BitVec.ts b/packages/types-codec/src/extended/BitVec.ts index 8912ed9fdc..e2d0c42ec4 100644 --- a/packages/types-codec/src/extended/BitVec.ts +++ b/packages/types-codec/src/extended/BitVec.ts @@ -73,6 +73,9 @@ export class BitVec extends Raw { }; } + /** + * @description Converts the Object to to a human-friendly JSON, with additional fields, expansion and formatting of information + */ public override toHuman (): string { return `0b${ [...this.toU8a(true)] @@ -94,7 +97,7 @@ export class BitVec extends Raw { * @param isBare true when the value has none of the type-specific prefixes (internal) */ public override toU8a (isBare?: boolean): Uint8Array { - const bitVec = super.toU8a(); + const bitVec = super.toU8a(isBare); return isBare ? bitVec diff --git a/packages/types-codec/src/extended/Linkage.ts b/packages/types-codec/src/extended/Linkage.ts index 9bd1b11069..00d1a308b3 100644 --- a/packages/types-codec/src/extended/Linkage.ts +++ b/packages/types-codec/src/extended/Linkage.ts @@ -34,10 +34,16 @@ export class Linkage extends Struct { }; } + /** + * @description Returns the next item the Linkage is pointing to + */ public get previous (): Option { return this.get('previous') as Option; } + /** + * @description Returns the previous item the Linkage is pointing to + */ public get next (): Option { return this.get('next') as Option; } @@ -52,12 +58,12 @@ export class Linkage extends Struct { /** * @description Custom toU8a which with bare mode does not return the linkage if empty */ - public override toU8a (): Uint8Array { + public override toU8a (isBare?: boolean): Uint8Array { // As part of a storage query (where these appear), in the case of empty, the values // are NOT populated by the node - follow the same logic, leaving it empty return this.isEmpty ? EMPTY - : super.toU8a(); + : super.toU8a(isBare); } } diff --git a/packages/types-codec/src/native/Bool.ts b/packages/types-codec/src/native/Bool.ts index ee75db4a02..b569ded687 100644 --- a/packages/types-codec/src/native/Bool.ts +++ b/packages/types-codec/src/native/Bool.ts @@ -130,7 +130,6 @@ export class bool extends Boolean implements Codec { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return new Uint8Array([this.valueOf() ? 1 : 0]); diff --git a/packages/types-codec/src/native/Date.ts b/packages/types-codec/src/native/Date.ts index 33b11ea76b..d724f133fa 100644 --- a/packages/types-codec/src/native/Date.ts +++ b/packages/types-codec/src/native/Date.ts @@ -162,7 +162,6 @@ export class CodecDate extends Date implements INumber { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return bnToU8a(this.toNumber(), U8A_OPTS); diff --git a/packages/types-codec/src/native/Float.ts b/packages/types-codec/src/native/Float.ts index 66e79ef0f9..7c52ac3981 100644 --- a/packages/types-codec/src/native/Float.ts +++ b/packages/types-codec/src/native/Float.ts @@ -128,7 +128,9 @@ export class Float extends Number implements IFloat { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications */ - public toU8a (): Uint8Array { - return floatToU8a(this, { bitLength: this.#bitLength }); + public toU8a (_isBare?: boolean): Uint8Array { + return floatToU8a(this, { + bitLength: this.#bitLength + }); } } diff --git a/packages/types-codec/src/native/Raw.ts b/packages/types-codec/src/native/Raw.ts index 910da6fdeb..c1233b5073 100644 --- a/packages/types-codec/src/native/Raw.ts +++ b/packages/types-codec/src/native/Raw.ts @@ -153,7 +153,6 @@ export class Raw extends Uint8Array implements IU8a { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return Uint8Array.from(this); diff --git a/packages/types-codec/src/native/Set.ts b/packages/types-codec/src/native/Set.ts index dd4e036f9e..ffec8091c6 100644 --- a/packages/types-codec/src/native/Set.ts +++ b/packages/types-codec/src/native/Set.ts @@ -257,7 +257,6 @@ export class CodecSet extends Set implements ISet { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) */ public toU8a (_isBare?: boolean): Uint8Array { return bnToU8a(this.valueEncoded, { diff --git a/packages/types-codec/src/primitive/ISize.ts b/packages/types-codec/src/primitive/ISize.ts new file mode 100644 index 0000000000..2963f5a022 --- /dev/null +++ b/packages/types-codec/src/primitive/ISize.ts @@ -0,0 +1,21 @@ +// Copyright 2017-2023 @polkadot/types-codec authors & contributors +// SPDX-License-Identifier: Apache-2.0 + +import type { Registry } from '../types/index.js'; + +import { i32 } from './I32.js'; + +/** + * @name ISize + * @description + * A System default signed number, typically used in RPC to report non-consensus + * data. It is a wrapper for [[I32]] as a WASM default (as generated by Rust bindings). + * It is not to be used, since it creates consensus mismatches. + */ +export class isize extends i32 { + constructor (registry: Registry, value?: unknown) { + super(registry, value); + + throw new Error('The `osize` type should not be used. Since it is platform-specific, it creates incompatibilities between native (generally i64) and WASM (always i32) code. Use one of the `i32` or `i64` types explicitly.'); + } +} diff --git a/packages/types-codec/src/primitive/index.ts b/packages/types-codec/src/primitive/index.ts index 397eeb4273..ac876d2545 100644 --- a/packages/types-codec/src/primitive/index.ts +++ b/packages/types-codec/src/primitive/index.ts @@ -9,6 +9,7 @@ export { i32, i32 as I32 } from './I32.js'; export { i64, i64 as I64 } from './I64.js'; export { i128, i128 as I128 } from './I128.js'; export { i256, i256 as I256 } from './I256.js'; +export { isize, isize as ISize } from './ISize.js'; export { u8, u8 as U8 } from './U8.js'; export { u16, u16 as U16 } from './U16.js'; export { u32, u32 as U32 } from './U32.js'; diff --git a/packages/types-codec/src/types/codec.ts b/packages/types-codec/src/types/codec.ts index fe30e20ad9..6c0b406d49 100644 --- a/packages/types-codec/src/types/codec.ts +++ b/packages/types-codec/src/types/codec.ts @@ -111,7 +111,8 @@ export interface Codec { /** * @description Encodes the value as a Uint8Array as per the SCALE specifications - * @param isBare true when the value has none of the type-specific prefixes (internal) + * @param isBare true when the value has none of the type-specific prefixes (internal use, only available on + * some Codec types, specifically those that add encodings such as length of indexes) */ toU8a (isBare?: BareOpts): Uint8Array; } diff --git a/packages/types/src/primitive/index.ts b/packages/types/src/primitive/index.ts index 48546a6f96..80d4377009 100644 --- a/packages/types/src/primitive/index.ts +++ b/packages/types/src/primitive/index.ts @@ -4,7 +4,7 @@ /** * @summary Type definitions that are used in the system */ -export { BitVec, bool, Bool, Bytes, f32, F32, f64, F64, i8, I8, i16, I16, i32, I32, i64, I64, i128, I128, i256, I256, Null, OptionBool, Text, Type, u8, U8, u16, U16, u32, U32, u64, U64, u128, U128, u256, U256, usize, USize } from '@polkadot/types-codec'; +export { BitVec, bool, Bool, Bytes, f32, F32, f64, F64, i8, I8, i16, I16, i32, I32, i64, I64, i128, I128, i256, I256, isize, ISize, Null, OptionBool, Text, Type, u8, U8, u16, U16, u32, U32, u64, U64, u128, U128, u256, U256, usize, USize } from '@polkadot/types-codec'; export { Data } from './Data.js'; export { StorageKey } from './StorageKey.js'; diff --git a/packages/types/src/types/registry.ts b/packages/types/src/types/registry.ts index 6266bed8cf..770d7da697 100644 --- a/packages/types/src/types/registry.ts +++ b/packages/types/src/types/registry.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { Observable } from 'rxjs'; -import type { BitVec, Bool, bool, Bytes, F32, f32, F64, f64, I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, I256, i256, Json, Null, OptionBool, Raw, Text, Type, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128, U256, u256, USize, usize } from '@polkadot/types-codec'; +import type { BitVec, Bool, bool, Bytes, F32, f32, F64, f64, I8, i8, I16, i16, I32, i32, I64, i64, I128, i128, I256, i256, ISize, isize, Json, Null, OptionBool, Raw, Text, Type, U8, u8, U16, u16, U32, u32, U64, u64, U128, u128, U256, u256, USize, usize } from '@polkadot/types-codec'; import type { RegistryTypes } from '@polkadot/types-codec/types'; import type { BN } from '@polkadot/util'; import type { HexString } from '@polkadot/util/types'; @@ -21,9 +21,9 @@ export interface InterfaceTypes { // base codec BitVec: BitVec, Bytes: Bytes, Json: Json, Null: Null, OptionBool: OptionBool, Raw: Raw, Text: Text, Type: Type, // base codec - upper variants - Bool: Bool, F32: F32, F64: F64, I128: I128, I16: I16, I256: I256, I32: I32, I64: I64, I8: I8, U128: U128, U16: U16, U256: U256, U32: U32, U64: U64, U8: U8, USize: USize, + Bool: Bool, F32: F32, F64: F64, I128: I128, I16: I16, I256: I256, I32: I32, I64: I64, I8: I8, ISize: ISize, U128: U128, U16: U16, U256: U256, U32: U32, U64: U64, U8: U8, USize: USize, // base codec - lower variants - bool: bool, f32: f32, f64: f64, i128: i128, i16: i16, i256: i256, i32: i32, i64: i64, i8: i8, u128: u128, u16: u16, u256: u256, u32: u32, u64: u64, u8: u8, usize: usize, + bool: bool, f32: f32, f64: f64, i128: i128, i16: i16, i256: i256, i32: i32, i64: i64, i8: i8, isize: isize, u128: u128, u16: u16, u256: u256, u32: u32, u64: u64, u8: u8, usize: usize, // extrinsic Extrinsic: GenericExtrinsic, ExtrinsicEra: GenericExtrinsicEra, ExtrinsicPayload: GenericExtrinsicPayload, SignerPayload: GenericSignerPayload, // generic