Fixed64 to an interface (#1906)

* Fixed64 to an interface

* Cleanups, re-use creation

* Fix Int export from codec

* Fix Int export
This commit is contained in:
Jaco Greeff
2020-02-20 13:03:29 +01:00
committed by GitHub
parent 09ab373b54
commit 543b4846f9
16 changed files with 75 additions and 50 deletions
+8 -3
View File
@@ -66,6 +66,12 @@ function tsEnum (definitions: object, { name: enumName, sub }: TypeDef, imports:
return exportInterface(enumName, 'Enum', keys.join(''));
}
function tsInt (definitions: object, def: TypeDef, imports: TypeImports, type: 'Int' | 'UInt' = 'Int'): string {
setImports(definitions, imports, [type]);
return exportInterface(def.name, type);
}
/** @internal */
function tsResultGetter (definitions: object, resultName = '', getter: 'Ok' | 'Error', def: TypeDef, imports: TypeImports): string {
const { info, type } = def;
@@ -124,9 +130,7 @@ function tsStruct (definitions: object, { name: structName, sub }: TypeDef, impo
/** @internal */
function tsUInt (definitions: object, def: TypeDef, imports: TypeImports): string {
setImports(definitions, imports, ['UInt']);
return exportInterface(def.name, 'UInt');
return tsInt(definitions, def, imports, 'UInt');
}
/** @internal */
@@ -154,6 +158,7 @@ function generateInterfaces (definitions: object, { types }: { types: Record<str
[TypeDefInfo.BTreeSet]: tsBTreeSet,
[TypeDefInfo.Compact]: tsCompact,
[TypeDefInfo.Enum]: tsEnum,
[TypeDefInfo.Int]: tsInt,
[TypeDefInfo.Linkage]: errorUnhandled,
[TypeDefInfo.Null]: errorUnhandled,
[TypeDefInfo.Option]: tsOption,
+12 -5
View File
@@ -29,15 +29,15 @@ export default abstract class AbstractInt extends BN implements Codec {
private _isHexJson: boolean;
private _isNegative: boolean;
private _isSigned: boolean;
protected constructor (registry: Registry, isNegative: boolean, value: AnyNumber = 0, bitLength: UIntBitLength = DEFAULT_UINT_BITS, isHexJson = true) {
super(AbstractInt.decodeAbstracInt(value, bitLength, isNegative));
protected constructor (registry: Registry, isSigned: boolean, value: AnyNumber = 0, bitLength: UIntBitLength = DEFAULT_UINT_BITS, isHexJson = true) {
super(AbstractInt.decodeAbstracInt(value, bitLength, isSigned));
this.registry = registry;
this._bitLength = bitLength;
this._isHexJson = isHexJson;
this._isNegative = isNegative;
this._isSigned = isSigned;
assert(super.bitLength() <= bitLength, `${this.toRawType()}: Input too large. Found input with ${super.bitLength()} bits, expected ${bitLength}`);
}
@@ -93,6 +93,13 @@ export default abstract class AbstractInt extends BN implements Codec {
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
*/
@@ -109,7 +116,7 @@ export default abstract class AbstractInt extends BN implements Codec {
// number and BN inputs (no `.eqn` needed) - numbers will be converted
return super.eq(
isHex(other)
? hexToBn(other.toString(), { isLe: false, isNegative: this._isNegative })
? hexToBn(other.toString(), { isLe: false, isNegative: this._isSigned })
: bnToBn(other)
);
}
+1
View File
@@ -22,6 +22,7 @@ export { default as Tuple } from './Tuple';
export { default as Vec } from './Vec';
// Convenience base classes, used as "anything of this type" bases
export { default as Int } from './Int';
export { default as Raw } from './Raw';
export { default as UInt } from './UInt';
export { default as U8aFixed } from './U8aFixed';
@@ -103,12 +103,12 @@ function encodeTuple (typeDef: Pick<TypeDef, any>): string {
})`;
}
function encodeUInt (typeDef: Pick<TypeDef, any>): string {
function encodeUInt (typeDef: Pick<TypeDef, any>, type: 'Int' | 'UInt'): string {
assert(typeDef.ext, 'Unable to encode VecFixed type');
const { length } = typeDef.ext as TypeDefExtUInt;
return `UInt<${length}>`;
return `${type}<${length}>`;
}
function encodeVecFixed (typeDef: Pick<TypeDef, any>): string {
@@ -126,6 +126,7 @@ const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
[TypeDefInfo.BTreeSet]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'BTreeSet'),
[TypeDefInfo.Compact]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Compact'),
[TypeDefInfo.Enum]: (typeDef: TypeDef): string => encodeEnum(typeDef),
[TypeDefInfo.Int]: (typeDef: TypeDef): string => encodeUInt(typeDef, 'Int'),
[TypeDefInfo.Linkage]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Linkage'),
// eslint-disable-next-line @typescript-eslint/no-unused-vars
[TypeDefInfo.Null]: (typeDef: TypeDef): string => 'Null',
@@ -135,7 +136,7 @@ const encoders: Record<TypeDefInfo, (typeDef: TypeDef) => string> = {
[TypeDefInfo.Set]: (typeDef: TypeDef): string => typeDef.type,
[TypeDefInfo.Struct]: (typeDef: TypeDef): string => encodeStruct(typeDef),
[TypeDefInfo.Tuple]: (typeDef: TypeDef): string => encodeTuple(typeDef),
[TypeDefInfo.UInt]: (typeDef: TypeDef): string => encodeUInt(typeDef),
[TypeDefInfo.UInt]: (typeDef: TypeDef): string => encodeUInt(typeDef, 'UInt'),
[TypeDefInfo.Vec]: (typeDef: TypeDef): string => encodeWithParams(typeDef, 'Vec'),
[TypeDefInfo.VecFixed]: (typeDef: TypeDef): string => encodeVecFixed(typeDef)
};
+12 -7
View File
@@ -11,6 +11,7 @@ import BTreeMap from '../codec/BTreeMap';
import BTreeSet from '../codec/BTreeSet';
import Compact from '../codec/Compact';
import Enum from '../codec/Enum';
import Int from '../codec/Int';
import Option from '../codec/Option';
import Result from '../codec/Result';
import CodecSet from '../codec/Set';
@@ -76,6 +77,14 @@ function getTypeClassArray (value: TypeDef): (InterfaceTypes)[] {
);
}
function createInt (value: TypeDef, Clazz: typeof Int | typeof UInt): Constructor {
assert(value.ext, `Expected bitLength information for ${Clazz.constructor.name}<bitLength>`);
const ext = value.ext as TypeDefExtUInt;
return Clazz.with(ext.length, ext.typeName);
}
const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => Constructor> = {
[TypeDefInfo.BTreeMap]: (registry: Registry, value: TypeDef): Constructor => {
const [keyType, valueType] = getTypeClassArray(value);
@@ -90,6 +99,8 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
[TypeDefInfo.Enum]: (registry: Registry, value: TypeDef): Constructor => Enum.with(getTypeClassMap(value)),
[TypeDefInfo.Int]: (registry: Registry, value: TypeDef): Constructor => createInt(value, Int),
// We have circular deps between Linkage & Struct
[TypeDefInfo.Linkage]: (registry: Registry, value: TypeDef): Constructor => {
const type = `Option<${getSubType(value)}>`;
@@ -133,13 +144,7 @@ const infoMapping: Record<TypeDefInfo, (registry: Registry, value: TypeDef) => C
[TypeDefInfo.Tuple]: (registry: Registry, value: TypeDef): Constructor => Tuple.with(getTypeClassArray(value)),
[TypeDefInfo.UInt]: (registry: Registry, value: TypeDef): Constructor => {
assert(value.ext, 'Expected bitLength information for UInt<bitLength>');
const ext = value.ext as TypeDefExtUInt;
return UInt.with(ext.length, ext.typeName);
},
[TypeDefInfo.UInt]: (registry: Registry, value: TypeDef): Constructor => createInt(value, UInt),
[TypeDefInfo.Vec]: (registry: Registry, value: TypeDef): Constructor => {
const subType = getSubType(value);
+12 -2
View File
@@ -2,6 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Int from '../codec/Int';
import CodecSet from '../codec/Set';
import { createClass, createType, createTypeUnsafe, ClassOf, TypeRegistry } from '.';
@@ -10,13 +11,22 @@ describe('createType', (): void => {
it('allows creation of a H256 (with proper toRawType)', (): void => {
expect(
createTypeUnsafe(registry, 'H256').toRawType()
createType(registry, 'H256').toRawType()
).toEqual('H256');
expect(
createTypeUnsafe(registry, 'Hash').toRawType()
createType(registry, 'Hash').toRawType()
).toEqual('H256');
});
it('allows creation of a Fixed64 (with proper toRawType & instance)', (): void => {
const f64 = createType(registry, 'Fixed64');
expect(f64.toRawType()).toEqual('Fixed64');
expect(f64.bitLength()).toEqual(64);
expect(f64.isUnsigned).toBe(false);
expect(f64 instanceof Int).toBe(true);
});
it('allows creation of a Struct', (): void => {
const raw = '{"balance":"Balance","index":"u32"}';
const struct = createTypeUnsafe(registry, raw, [{
+11 -6
View File
@@ -90,20 +90,24 @@ function _decodeTuple (value: TypeDef, _: string, subType: string): TypeDef {
return value;
}
// decode a fixed vector, e.g. [u8;32]
// decode a Int/UInt<bitLength[, name]>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function _decodeUInt (value: TypeDef, type: string, _: string): TypeDef {
const _bitLength = type.substr(5, type.length - 6);
const length = parseInt(_bitLength.trim(), 10);
function _decodeInt (value: TypeDef, type: string, _: string, clazz: 'Int' | 'UInt' = 'Int'): TypeDef {
const [strLength, typeName] = type.substr(clazz.length + 1, type.length - clazz.length - 1 - 1).split(',');
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 UInt<bitLength>, where length <= 8192 and a power of 8`);
assert(length <= 8192 && (length % 8) === 0, `${type}: Only support for ${clazz}<bitLength>, where length <= 8192 and a power of 8, found ${length}`);
value.ext = { length } as TypeDefExtUInt;
value.ext = { length, typeName } as TypeDefExtUInt;
return value;
}
function _decodeUInt (value: TypeDef, type: string, subType: string): TypeDef {
return _decodeInt(value, type, subType, 'UInt');
}
function hasWrapper (type: string, [start, end]: [string, string, TypeDefInfo, any?]): boolean {
if (type.substr(0, start.length) !== start) {
return false;
@@ -120,6 +124,7 @@ const nestedExtraction: [string, string, TypeDefInfo, (value: TypeDef, type: str
['(', ')', TypeDefInfo.Tuple, _decodeTuple],
// the inner for these are the same as tuple, multiple values
['BTreeMap<', '>', TypeDefInfo.BTreeMap, _decodeTuple],
['Int<', '>', TypeDefInfo.Int, _decodeInt],
['Result<', '>', TypeDefInfo.Result, _decodeTuple],
['UInt<', '>', TypeDefInfo.UInt, _decodeUInt]
];
+1 -1
View File
@@ -5,7 +5,7 @@
type Mapper = (value: string) => string;
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'Linkage', 'Result', 'Option', 'UInt', 'Vec'];
const ALLOWED_BOXES = ['BTreeMap', 'BTreeSet', 'Compact', 'Int', 'Linkage', 'Result', 'Option', 'UInt', 'Vec'];
const BOX_PRECEDING = ['<', '(', '[', '"', ',', ' ']; // start of vec, tuple, fixed array, part of struct def or in tuple
const mappings: Mapper[] = [
+1
View File
@@ -26,6 +26,7 @@ export enum TypeDefInfo {
Tuple,
Vec,
VecFixed,
Int,
UInt,
// anything not fully supported (keep this as the last entry)
Null
+5 -5
View File
@@ -2,8 +2,8 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import { Compact, Option, Raw, Vec } from '@polkadot/types/codec';
import { BitVec, Bytes, Data, Fixed64, IdentityFields, Null, StorageData, StorageKey, Text, Type, U256, Unconstructable, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, ChangesTrieConfiguration, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, DispatchInfoTo190, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicSignatureV1, ExtrinsicSignatureV2, ExtrinsicSignatureV3, ExtrinsicSignatureV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, H160, H256, H512, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, LookupSource, LookupTarget, Moment, MortalEra, MultiSignature, Origin, Perbill, Percent, Permill, Perquintill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { BitVec, Bytes, Data, IdentityFields, Null, StorageData, StorageKey, Text, Type, U256, Unconstructable, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types/primitive';
import { AccountId, AccountIdOf, AccountIndex, Address, AssetId, Balance, BalanceOf, Block, BlockNumber, Call, ChangesTrieConfiguration, Consensus, ConsensusEngineId, Digest, DigestItem, DispatchClass, DispatchInfo, DispatchInfoTo190, EcdsaSignature, Ed25519Signature, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV1, ExtrinsicPayloadV2, ExtrinsicPayloadV3, ExtrinsicPayloadV4, ExtrinsicSignatureV1, ExtrinsicSignatureV2, ExtrinsicSignatureV3, ExtrinsicSignatureV4, ExtrinsicUnknown, ExtrinsicV1, ExtrinsicV2, ExtrinsicV3, ExtrinsicV4, Fixed64, H160, H256, H512, Hash, Header, ImmortalEra, Index, Justification, KeyTypeId, KeyValue, LockIdentifier, LookupSource, LookupTarget, Moment, MortalEra, MultiSignature, Origin, Perbill, Percent, Permill, Perquintill, Phantom, PhantomData, PreRuntime, Seal, SealV0, Signature, SignedBlock, SignerPayload, Sr25519Signature, ValidatorId, Weight, WeightMultiplier } from '@polkadot/types/interfaces/runtime';
import { InclusionHeight, Uncle, UncleEntryItem } from '@polkadot/types/interfaces/authorship';
import { RawAuraPreDigest } from '@polkadot/types/interfaces/aura';
import { BabeAuthorityWeight, BabeBlockWeight, BabeWeight, MaybeVrf, RawBabePreDigest, RawBabePreDigestCompat, RawBabePreDigestPrimary, RawBabePreDigestPrimaryTo159, RawBabePreDigestSecondary, RawBabePreDigestSecondaryTo159, RawBabePreDigestTo159, SlotNumber, VrfData, VrfProof } from '@polkadot/types/interfaces/babe';
@@ -64,9 +64,6 @@ export interface InterfaceRegistry {
i64: i64;
'Option<i64>': Option<i64>;
'Vec<i64>': Vec<i64>;
Fixed64: Fixed64;
'Option<Fixed64>': Option<Fixed64>;
'Vec<Fixed64>': Vec<Fixed64>;
i128: i128;
'Option<i128>': Option<i128>;
'Vec<i128>': Vec<i128>;
@@ -231,6 +228,9 @@ export interface InterfaceRegistry {
DispatchInfoTo190: DispatchInfoTo190;
'Option<DispatchInfoTo190>': Option<DispatchInfoTo190>;
'Vec<DispatchInfoTo190>': Vec<DispatchInfoTo190>;
Fixed64: Fixed64;
'Option<Fixed64>': Option<Fixed64>;
'Vec<Fixed64>': Vec<Fixed64>;
H160: H160;
'Option<H160>': Option<H160>;
'Vec<H160>': Vec<H160>;
@@ -65,6 +65,7 @@ export default {
weight: 'Weight',
class: 'DispatchClass'
},
Fixed64: 'Int<64, Fixed64>',
H160: '[u8; 20; H160]',
H256: '[u8; 32; H256]',
H512: '[u8; 64; H512]',
@@ -2,10 +2,10 @@
/* eslint-disable @typescript-eslint/no-empty-interface */
import { ITuple } from '@polkadot/types/types';
import { Compact, Enum, Struct, U8aFixed, Vec } from '@polkadot/types/codec';
import { Compact, Enum, Int, Struct, U8aFixed, Vec } from '@polkadot/types/codec';
import { GenericExtrinsic, GenericExtrinsicEra, GenericExtrinsicPayload, GenericExtrinsicPayloadUnknown, GenericExtrinsicPayloadV1, GenericExtrinsicPayloadV2, GenericExtrinsicPayloadV3, GenericExtrinsicPayloadV4, GenericExtrinsicSignatureV1, GenericExtrinsicSignatureV2, GenericExtrinsicSignatureV3, GenericExtrinsicSignatureV4, GenericExtrinsicUnknown, GenericExtrinsicV1, GenericExtrinsicV2, GenericExtrinsicV3, GenericExtrinsicV4, GenericImmortalEra, GenericMortalEra, GenericSignerPayload } from '@polkadot/types/extrinsic';
import { GenericAccountId, GenericAccountIndex, GenericAddress, GenericBlock, GenericCall, GenericConsensusEngineId, GenericDigest, GenericOrigin } from '@polkadot/types/generic';
import { Bytes, Fixed64, Null, StorageData, StorageKey, bool, u128, u32, u64, u8 } from '@polkadot/types/primitive';
import { Bytes, Null, StorageData, StorageKey, bool, u128, u32, u64, u8 } from '@polkadot/types/primitive';
import { AuthorityId } from '@polkadot/types/interfaces/consensus';
/** @name AccountId */
@@ -147,6 +147,9 @@ export interface ExtrinsicV3 extends GenericExtrinsicV3 {}
/** @name ExtrinsicV4 */
export interface ExtrinsicV4 extends GenericExtrinsicV4 {}
/** @name Fixed64 */
export interface Fixed64 extends Int {}
/** @name H160 */
export interface H160 extends U8aFixed {}
@@ -1,7 +1,7 @@
// Auto-generated via `yarn polkadot-types-from-defs`, do not edit
/* eslint-disable @typescript-eslint/no-empty-interface */
import { Fixed64 } from '@polkadot/types/primitive';
import { Fixed64 } from '@polkadot/types/interfaces/runtime';
/** @name Multiplier */
export interface Multiplier extends Fixed64 {}
-13
View File
@@ -1,13 +0,0 @@
// Copyright 2017-2020 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import I64 from './I64';
/**
* @name I64Fixed
* @description
* A 64-bit signed integer (Fixed64 in Rust)
*/
export default class I64Fixed extends I64 {
}
-1
View File
@@ -17,7 +17,6 @@ export { default as i8 } from './I8';
export { default as i16 } from './I16';
export { default as i32 } from './I32';
export { default as i64 } from './I64';
export { default as Fixed64 } from './I64Fixed';
export { default as i128 } from './I128';
export { default as i256 } from './I256';
export { default as Null } from './Null';