diff --git a/packages/api-derive/src/balances/all.ts b/packages/api-derive/src/balances/all.ts index 15e96d012b..66ad6043ca 100644 --- a/packages/api-derive/src/balances/all.ts +++ b/packages/api-derive/src/balances/all.ts @@ -18,11 +18,8 @@ import { drr } from '../util/drr'; type Result = [AccountId | undefined, BlockNumber | undefined, [Balance?, Balance?, BalanceLock[]?, Option?, Index?]]; -const EMPTY_ACCOUNT = createType('AccountId'); -const ZERO = createType('Balance', 0); - -function calcBalances ([accountId = EMPTY_ACCOUNT, bestNumber = ZERO, [freeBalance = ZERO, reservedBalance = ZERO, locks = [], vesting = new Option(ClassOf('VestingSchedule'), null), accountNonce = ZERO]]: Result): DerivedBalances { - let lockedBalance = ZERO; +function calcBalances ([accountId = createType('AccountId'), bestNumber = createType('Balance'), [freeBalance = createType('Balance'), reservedBalance = createType('Balance'), locks = [], vesting = new Option(ClassOf('VestingSchedule'), null), accountNonce = createType('Balance')]]: Result): DerivedBalances { + let lockedBalance = createType('Balance'); if (Array.isArray(locks)) { // only get the locks that are valid until passed the current block @@ -30,7 +27,7 @@ function calcBalances ([accountId = EMPTY_ACCOUNT, bestNumber = ZERO, [freeBalan // get the maximum of the locks according to https://github.com/paritytech/substrate/blob/master/srml/balances/src/lib.rs#L699 lockedBalance = totals[0] ? bnMax(...totals.map(({ amount }): Balance => amount)) as Balance - : ZERO; + : createType('Balance'); } // offset = balance locked at genesis, perBlock is the unlock amount @@ -45,7 +42,7 @@ function calcBalances ([accountId = EMPTY_ACCOUNT, bestNumber = ZERO, [freeBalan // The locked is > the vested and ended up with the locked > free, // i.e. related to https://github.com/paritytech/polkadot/issues/225 // (most probably due to movements from stash -> controller -> free) - const availableBalance: BN = bnMax(ZERO, vestedBalance.sub(lockedBalance)); + const availableBalance: BN = bnMax(createType('Balance'), vestedBalance.sub(lockedBalance)); return { accountId, diff --git a/packages/api-derive/src/type/HeaderExtended.ts b/packages/api-derive/src/type/HeaderExtended.ts index 894942ca3e..1f12c6ed68 100644 --- a/packages/api-derive/src/type/HeaderExtended.ts +++ b/packages/api-derive/src/type/HeaderExtended.ts @@ -5,11 +5,11 @@ import { AccountId, Header } from '@polkadot/types/interfaces'; import { AnyJsonObject, Constructor } from '@polkadot/types/types'; -import { ClassOf } from '@polkadot/types'; +import runtimeTypes from '@polkadot/types/interfaces/runtime/definitions'; +import { Struct } from '@polkadot/types'; -// This is a bit hacky, but is exactly what it resolves to when compiled - -// and as a bonus is gets the typing right -const _Header: Constructor
= ClassOf('Header'); +// @ts-ignore +const _Header: Constructor
= Struct.with(runtimeTypes.types.Header); /** * @name HeaderExtended diff --git a/packages/api-derive/src/type/ReferendumInfoExtended.ts b/packages/api-derive/src/type/ReferendumInfoExtended.ts index dbb6469174..9442f76fa5 100644 --- a/packages/api-derive/src/type/ReferendumInfoExtended.ts +++ b/packages/api-derive/src/type/ReferendumInfoExtended.ts @@ -6,11 +6,11 @@ import { ReferendumIndex, ReferendumInfo } from '@polkadot/types/interfaces/demo import { AnyJsonObject, Constructor } from '@polkadot/types/types'; import BN from 'bn.js'; -import { ClassOf, createType } from '@polkadot/types'; +import democracyTypes from '@polkadot/types/interfaces/democracy/definitions'; +import { Struct, createType } from '@polkadot/types'; -// This is a bit hacky, but is exactly what it resolves to when compiled - -// and as a bonus is gets the typing right -const _ReferendumInfo: Constructor = ClassOf('ReferendumInfo'); +// @ts-ignore +const _ReferendumInfo: Constructor = Struct.with(democracyTypes.types.ReferendumInfo); /** * @name ReferendumInfoExtended diff --git a/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts b/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts index fe6378ff30..801884cebb 100644 --- a/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts +++ b/packages/api-metadata/src/consts/fromMetadata/fromMetadata.spec.ts @@ -16,6 +16,6 @@ const consts = fromMetadata(metadata); describe('fromMetadata', (): void => { it('should return constants with the correct type and value', (): void => { expect(consts.democracy.cooloffPeriod).toBeInstanceOf(ClassOf('BlockNumber')); - expect(consts.democracy.cooloffPeriod.toHex()).toEqual('0x0000000000062700'); + expect(consts.democracy.cooloffPeriod.toHex()).toEqual('0x00062700'); }); }); diff --git a/packages/api/src/SignerPayload.spec.ts b/packages/api/src/SignerPayload.spec.ts index f121020ad2..d5caee1b73 100644 --- a/packages/api/src/SignerPayload.spec.ts +++ b/packages/api/src/SignerPayload.spec.ts @@ -11,11 +11,11 @@ describe('SignerPayload', (): void => { const TEST = { address: '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE', blockHash: '0xde8f69eeb5e065e18c6950ff708d7e551f68dc9bf59a07c52367c0280f805ec7', - blockNumber: '0x0000000000231d30', + blockNumber: '0x00231d30', era: '0x0703', genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b', method: '0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c', - nonce: '0x0000000000001234', + nonce: '0x00001234', tip: '0x00000000000000000000000000005678', version: 2 }; @@ -40,11 +40,11 @@ describe('SignerPayload', (): void => { ).toEqual({ address: '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE', blockHash: '0xde8f69eeb5e065e18c6950ff708d7e551f68dc9bf59a07c52367c0280f805ec7', - blockNumber: '0x0000000000231d30', + blockNumber: '0x00231d30', era: '0x0703', genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b', method: '0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c', - nonce: '0x0000000000001234', + nonce: '0x00001234', tip: '0x00000000000000000000000000005678', version: 2 }); diff --git a/packages/api/src/SignerPayload.ts b/packages/api/src/SignerPayload.ts index 872d6ed76c..f97dfaa2a1 100644 --- a/packages/api/src/SignerPayload.ts +++ b/packages/api/src/SignerPayload.ts @@ -5,7 +5,7 @@ import { Address, Balance, BlockNumber, Call, ExtrinsicEra, Hash, Index } from '@polkadot/types/interfaces'; import { SignerPayload, SignerPayloadRaw } from './types'; -import { createType, ClassOf, Compact, Struct, u8 } from '@polkadot/types'; +import { createType, Compact, Struct, u8 } from '@polkadot/types'; export interface SignerPayloadType { address: Address; @@ -20,14 +20,14 @@ export interface SignerPayloadType { } export default class Payload extends Struct.with({ - address: ClassOf('Address'), - blockHash: ClassOf('Hash'), - blockNumber: ClassOf('BlockNumber'), - era: ClassOf('ExtrinsicEra'), - genesisHash: ClassOf('Hash'), - method: ClassOf('Call'), - nonce: ClassOf('Compact'), - tip: ClassOf('Compact'), + address: 'Address', + blockHash: 'Hash', + blockNumber: 'BlockNumber', + era: 'ExtrinsicEra', + genesisHash: 'Hash', + method: 'Call', + nonce: 'Compact', + tip: 'Compact', version: u8 }) { /** diff --git a/packages/rpc-core/src/formatting.spec.ts b/packages/rpc-core/src/formatting.spec.ts index 8265d36ea1..98b01181a1 100644 --- a/packages/rpc-core/src/formatting.spec.ts +++ b/packages/rpc-core/src/formatting.spec.ts @@ -96,7 +96,7 @@ function formattingTests (version: string, storage: Storage, encodedValues: [str api.state .getStorage([storage.system.accountNonce, ADDR_ONE]) .subscribe((value): void => { - expect(value.toHex()).toEqual('0x0000000000000000'); + expect(value.toHex()).toEqual('0x00000000'); done(); }); }); diff --git a/packages/types/src/codec/Compact.spec.ts b/packages/types/src/codec/Compact.spec.ts index 24937534b6..ea239c8841 100644 --- a/packages/types/src/codec/Compact.spec.ts +++ b/packages/types/src/codec/Compact.spec.ts @@ -110,7 +110,7 @@ describe('Compact', (): void => { it('has the correct bitLength for constructor values (BlockNumber)', (): void => { expect( new Compact(ClassOf('BlockNumber'), 0xfffffff9).bitLength() - ).toEqual(64); + ).toEqual(32); }); it('has the correct encodedLength for constructor values (string BlockNumber)', (): void => { diff --git a/packages/types/src/codec/Struct.spec.ts b/packages/types/src/codec/Struct.spec.ts index 5139447f66..49cd9a17cb 100644 --- a/packages/types/src/codec/Struct.spec.ts +++ b/packages/types/src/codec/Struct.spec.ts @@ -194,8 +194,8 @@ describe('Struct', (): void => { expect( new Struct({ blockNumber: ClassOf('Option') - }, { blockNumber: '0x1234567890abcdef' }).toString() - ).toEqual('{"blockNumber":"0x1234567890abcdef"}'); + }, { blockNumber: '0x0000000010abcdef' }).toString() + ).toEqual('{"blockNumber":279694831}'); }); it('generates sane toRawType', (): void => { @@ -212,9 +212,9 @@ describe('Struct', (): void => { ).toEqual(JSON.stringify({ accountId: 'AccountId', balanceCompact: 'Compact', // Override in Uint - blockNumber: 'u64', - compactNumber: 'Compact', - optionNumber: 'Option', + blockNumber: 'u32', + compactNumber: 'Compact', + optionNumber: 'Option', counter: 'u32', vector: 'Vec' })); diff --git a/packages/types/src/codec/Tuple.spec.ts b/packages/types/src/codec/Tuple.spec.ts index 7b82517d7f..75a8eb0dd6 100644 --- a/packages/types/src/codec/Tuple.spec.ts +++ b/packages/types/src/codec/Tuple.spec.ts @@ -14,6 +14,7 @@ import { ClassOf } from '../codec/createType'; import Call from '../primitive/Generic/Call'; import Text from '../primitive/Text'; import U32 from '../primitive/U32'; +import U128 from '../primitive/U128'; import Tuple from './Tuple'; describe('Tuple', (): void => { @@ -111,14 +112,14 @@ describe('Tuple', (): void => { describe('toRawType', (): void => { it('generates sane value with array types', (): void => { expect( - new Tuple([U32, ClassOf('BlockNumber')]).toRawType() - ).toEqual('(u32,u64)'); + new Tuple([U128, ClassOf('BlockNumber')]).toRawType() + ).toEqual('(u128,u32)'); }); it('generates sane value with object types', (): void => { expect( - new Tuple({ number: U32, blockNumber: ClassOf('BlockNumber') }).toRawType() - ).toEqual('(u32,u64)'); + new Tuple({ number: U128, blockNumber: ClassOf('BlockNumber') }).toRawType() + ).toEqual('(u128,u32)'); }); }); }); diff --git a/packages/types/src/codec/TypeRegistry.spec.ts b/packages/types/src/codec/TypeRegistry.spec.ts index 22dbff5c6e..0df1723c7a 100644 --- a/packages/types/src/codec/TypeRegistry.spec.ts +++ b/packages/types/src/codec/TypeRegistry.spec.ts @@ -4,11 +4,21 @@ import '../injector'; +import { Constructor } from '../types'; + import { TypeRegistry } from './typeRegistry'; import Struct from '../codec/Struct'; import Text from '../primitive/Text'; import U32 from '../primitive/U32'; +// Copied from interfacesTs +function isChildClass (Parent: Constructor, Child?: Constructor): boolean { + return Child + // eslint-disable-next-line no-prototype-builtins + ? Parent === Child || Parent.isPrototypeOf(Child) + : false; +} + describe('TypeRegistry', (): void => { let registry: TypeRegistry; @@ -27,7 +37,7 @@ describe('TypeRegistry', (): void => { it('can register type with a different name', (): void => { registry.register('TextRenamed', Text); - expect(registry.get('TextRenamed')).toBe(Text); + expect(isChildClass(Text, registry.get('TextRenamed'))).toBe(true); }); describe('object registration', (): void => { @@ -36,8 +46,8 @@ describe('TypeRegistry', (): void => { Text, U32Renamed: U32 }); - expect(registry.get('Text')).toBe(Text); - expect(registry.get('U32Renamed')).toBe(U32); + expect(isChildClass(Text, registry.get('Text'))).toBe(true); + expect(isChildClass(U32, registry.get('U32Renamed'))).toBe(true); }); it('can create types from string', (): void => { diff --git a/packages/types/src/codec/createType.spec.ts b/packages/types/src/codec/createType.spec.ts index 33eadfc596..73b262d7b1 100644 --- a/packages/types/src/codec/createType.spec.ts +++ b/packages/types/src/codec/createType.spec.ts @@ -8,6 +8,7 @@ import { Codec, Constructor } from '../types'; import { TypeDef, TypeDefInfo } from './types'; import createType, { createClass, createTypeUnsafe, getTypeClass, getTypeDef, typeSplit, ClassOf } from './createType'; +import getTypeRegistry from './typeRegistry'; import CodecSet from './Set'; describe('typeSplit', (): void => { @@ -223,10 +224,10 @@ describe('createClass', (): void => { }); it('should return equivalents for Bytes & Vec', (): void => { - const a = createClass('Vec'); - const b = createClass('Bytes'); + const A = createClass('Vec'); + const B = createClass('Bytes'); - expect(a).toBe(b); + expect(new A() instanceof B).toBe(true); }); }); @@ -288,17 +289,59 @@ describe('createType', (): void => { }); it('instanceof should work (complex type)', (): void => { - const complexType = '{"balance":"Balance","account_id":"AccountId","log":"(u64, u32)","fromSrml":"Gas"}'; + getTypeRegistry().register({ + TestComplex: { + balance: 'Balance', + accountId: 'AccountId', + log: '(u64, u32)', + fromSrml: 'Gas' + } + }); - const value = createTypeUnsafe(complexType, [{ + const value = createTypeUnsafe('TestComplex', [{ balance: 123, - accountId: '', + accountId: '0x1234567812345678123456781234567812345678123456781234567812345678', log: [456, 789], fromSrml: 0 }]); - const ComplexType = createClass(complexType); - expect(value instanceof ComplexType).toBe(true); + expect(value instanceof createClass('TestComplex')).toBe(true); + }); + + it('allows for re-registration of a type', (): void => { + const balDef = createType('Balance'); + + expect(balDef instanceof ClassOf('Balance')); + expect(balDef.bitLength()).toEqual(128); + + getTypeRegistry().register({ Balance: 'u32' }); + + const balu32 = createType('Balance'); + + expect(balu32 instanceof ClassOf('Balance')); + expect(balu32.bitLength()).toEqual(32); + }); + + it('allows for re-registration of a type (affecting derives)', (): void => { + getTypeRegistry().register({ + Balance: 'u128', + TestComplex: { + balance: 'Balance', + accountId: 'AccountId', + log: '(u64, u32)', + fromSrml: 'Gas' + } + }); + + const cmpDef: any = createTypeUnsafe('TestComplex'); + + expect(cmpDef.balance.bitLength()).toEqual(128); + + getTypeRegistry().register({ Balance: 'u32' }); + + const cmpu32: any = createTypeUnsafe('TestComplex'); + + expect(cmpu32.balance.bitLength()).toEqual(32); }); }); }); diff --git a/packages/types/src/codec/createType.ts b/packages/types/src/codec/createType.ts index 6722daf23b..fb5d697d79 100644 --- a/packages/types/src/codec/createType.ts +++ b/packages/types/src/codec/createType.ts @@ -5,7 +5,6 @@ import { Codec, Constructor, InterfaceTypes } from '../types'; import { TypeDef, TypeDefInfo, TypeDefExtVecFixed } from './types'; -import memoizee from 'memoizee'; import { assert } from '@polkadot/util'; import { InterfaceRegistry } from '../interfaceRegistry'; @@ -173,18 +172,12 @@ export function getTypeDef (_type: string, name?: string): TypeDef { return value; } -// Memoized helper of the `createClass` function below -const memoizedCreateClass = memoizee(( - type: K -): Constructor> => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - return getTypeClass>(getTypeDef(type)); -}, { length: 1 }); - export function createClass ( type: K ): Constructor> { - return memoizedCreateClass(type); + // return memoizedCreateClass(type); + // eslint-disable-next-line @typescript-eslint/no-use-before-define + return getTypeClass>(getTypeDef(type)); } // An unsafe version of the `createType` below. It's unsafe because the `type` diff --git a/packages/types/src/codec/typeRegistry.ts b/packages/types/src/codec/typeRegistry.ts index 1550351098..22d3cec946 100644 --- a/packages/types/src/codec/typeRegistry.ts +++ b/packages/types/src/codec/typeRegistry.ts @@ -37,25 +37,23 @@ export class TypeRegistry { } } - private registerObject (obj: RegistryTypes, overwrite: boolean = true): void { + private registerObject (obj: RegistryTypes): void { Object.entries(obj).forEach(([name, type]): void => { - if (overwrite || !this.get(name)) { - if (isFunction(type)) { - // This _looks_ a bit funny, but `typeof Clazz === 'function' - this._classes.set(name, type); - } else { - // when registering, remove the old value - if (this._classes.has(name)) { - this._classes.delete(name); - } + if (isFunction(type)) { + // This _looks_ a bit funny, but `typeof Clazz === 'function' + this._classes.set(name, type); + } else { + const def = isString(type) + ? type + : JSON.stringify(type); - // We only create types on-demand, so just register the definition - this._definitions.set(name, ( - isString(type) - ? type - : JSON.stringify(type) - )); + if (this._classes.has(name)) { + console.warn(`The type '${name}' is already existing as a class, re-registering definition`); + + this._classes.delete(name); } + + this._definitions.set(name, def); } }); } diff --git a/packages/types/src/interfaces/runtime/definitions.ts b/packages/types/src/interfaces/runtime/definitions.ts index abbbfb7135..b649b7186f 100644 --- a/packages/types/src/interfaces/runtime/definitions.ts +++ b/packages/types/src/interfaces/runtime/definitions.ts @@ -12,7 +12,7 @@ export default { Balance: 'u128', BalanceOf: 'Balance', Block: 'GenericBlock', - BlockNumber: 'u64', + BlockNumber: 'u32', Call: 'GenericCall', ConsensusEngineId: 'GenericConsensusEngineId', Digest: 'GenericDigest', @@ -28,7 +28,7 @@ export default { extrinsicsRoot: 'Hash', digest: 'Digest' }, - Index: 'u64', + Index: 'u32', Justification: 'Bytes', KeyValue: '(StorageKey, StorageData)', KeyTypeId: 'u32', diff --git a/packages/types/src/interfaces/runtime/types.ts b/packages/types/src/interfaces/runtime/types.ts index 22d0ad194e..73ee7ff94e 100644 --- a/packages/types/src/interfaces/runtime/types.ts +++ b/packages/types/src/interfaces/runtime/types.ts @@ -29,8 +29,8 @@ export type BalanceOf = Balance; /** GenericBlock */ export type Block = GenericBlock; -/** u64 */ -export type BlockNumber = u64; +/** u32 */ +export type BlockNumber = u32; /** GenericCall */ export type Call = GenericCall; @@ -79,8 +79,8 @@ export interface Header extends Struct { /** GenericImmortalEra */ export type ImmortalEra = GenericImmortalEra; -/** u64 */ -export type Index = u64; +/** u32 */ +export type Index = u32; /** Bytes */ export type Justification = Bytes; diff --git a/packages/types/src/primitive/Generic/Block.spec.ts b/packages/types/src/primitive/Generic/Block.spec.ts index b974800ff4..e091666de4 100644 --- a/packages/types/src/primitive/Generic/Block.spec.ts +++ b/packages/types/src/primitive/Generic/Block.spec.ts @@ -23,7 +23,7 @@ describe('Block', (): void => { JSON.stringify({ header: JSON.stringify({ parentHash: 'H256', - number: 'Compact', + number: 'Compact', stateRoot: 'H256', extrinsicsRoot: 'H256', digest: JSON.stringify({