diff --git a/packages/api-derive/src/balances/fees.ts b/packages/api-derive/src/balances/fees.ts index 2b866a3208..d4db94905d 100644 --- a/packages/api-derive/src/balances/fees.ts +++ b/packages/api-derive/src/balances/fees.ts @@ -11,6 +11,31 @@ import { map } from 'rxjs/operators'; import { drr } from '../util/drr'; +type Result = [BN, BN, BN, BN, BN]; + +function querySubtrateV2 (api: ApiInterfaceRx): Observable { + return of([ + // get values from api.const for substrate versions post spec_version: 101 + // https://github.com/paritytech/substrate/pull/2883/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R131 + api.consts.balances.creationFee, + api.consts.balances.existentialDeposit, + api.consts.balances.transactionBaseFee, + api.consts.balances.transactionByteFee, + api.consts.balances.transferFee + ]) as any as Observable; +} + +function querySubtrateV1 (api: ApiInterfaceRx): Observable { + return api.queryMulti([ + // Support older versions and get values from storage + api.query.balances.creationFee, + api.query.balances.existentialDeposit, + api.query.balances.transactionBaseFee, + api.query.balances.transactionByteFee, + api.query.balances.transferFee + ]) as any as Observable; +} + /** * @name fees * @returns An object containing the combined results of the storage queries for @@ -28,23 +53,8 @@ export function fees (api: ApiInterfaceRx): () => Observable { return (): Observable => { return ( api.consts.balances - ? of([ - // get values from api.const for substrate versions post spec_version: 101 - // https://github.com/paritytech/substrate/pull/2883/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R131 - api.consts.balances.creationFee, - api.consts.balances.existentialDeposit, - api.consts.balances.transactionBaseFee, - api.consts.balances.transactionByteFee, - api.consts.balances.transferFee - ]) as any as Observable<[BN, BN, BN, BN, BN]> - : api.queryMulti([ - // Support older versions and get values from storage - api.query.balances.creationFee, - api.query.balances.existentialDeposit, - api.query.balances.transactionBaseFee, - api.query.balances.transactionByteFee, - api.query.balances.transferFee - ]) as any as Observable<[BN, BN, BN, BN, BN]> + ? querySubtrateV2(api) + : querySubtrateV1(api) ).pipe( map(([creationFee, existentialDeposit, transactionBaseFee, transactionByteFee, transferFee]): DerivedFees => ({ creationFee, diff --git a/packages/api-derive/src/session/info.ts b/packages/api-derive/src/session/info.ts index 6322841241..42c1a84c4c 100644 --- a/packages/api-derive/src/session/info.ts +++ b/packages/api-derive/src/session/info.ts @@ -21,7 +21,6 @@ const ZERO = new BN(0); // internal helper to just split the logic - take all inputs, do the calculations and combine function createDerived0to94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result0to94): DerivedSessionInfo { - const eraLength = sessionLength.mul(sessionsPerEra); const lastLengthChange = _lastLengthChange ? _lastLengthChange.unwrapOr(ZERO) : ZERO; @@ -32,15 +31,14 @@ function createDerived0to94 ([bestNumber, [currentIndex, _lastLengthChange, sess const currentEra = (currentIndex) .sub(lastEraLengthChange) .mod(sessionsPerEra); - const eraProgress = currentEra - .mul(sessionLength) - .add(sessionProgress); return { currentEra, currentIndex, - eraLength, - eraProgress, + eraLength: sessionLength.mul(sessionsPerEra), + eraProgress: currentEra + .mul(sessionLength) + .add(sessionProgress), isEpoch: false, lastEraLengthChange, lastLengthChange, @@ -52,15 +50,17 @@ function createDerived0to94 ([bestNumber, [currentIndex, _lastLengthChange, sess function createDerived ([[epochDuration, sessionsPerEra], [currentSlot, epochIndex, epochStartSlot, currentIndex, currentEra]]: Result): DerivedSessionInfo { const sessionProgress = currentSlot.sub(epochStartSlot); - const eraLength = sessionsPerEra.mul(epochDuration); - const eraProgress = epochIndex.mod(sessionsPerEra).mul(epochDuration).add(sessionProgress); + const eraProgress = epochIndex + .mod(sessionsPerEra) + .mul(epochDuration) + .add(sessionProgress); // FIXME This alwasy assumes Babe, as per the substrate defaults - at least for // aura the `isEpoch` should be false return { currentEra, currentIndex, - eraLength, + eraLength: sessionsPerEra.mul(epochDuration), eraProgress, isEpoch: true, lastEraLengthChange: ZERO, diff --git a/packages/api-derive/src/type/HeaderExtended.ts b/packages/api-derive/src/type/HeaderExtended.ts index 1f12c6ed68..34cf9a4f12 100644 --- a/packages/api-derive/src/type/HeaderExtended.ts +++ b/packages/api-derive/src/type/HeaderExtended.ts @@ -50,9 +50,7 @@ export default class HeaderExtended extends _Header { // extract author from the seal (pre substrate 1.0, backwards compat) if (sitem) { - this._author = sessionValidators[ - sitem.asSealV0[0].modn(sessionValidators.length) - ]; + this._author = sessionValidators[sitem.asSealV0[0].modn(sessionValidators.length)]; } } } diff --git a/packages/types/src/codec/createType.ts b/packages/types/src/codec/createType.ts index 27c896c909..f2f480bfb9 100644 --- a/packages/types/src/codec/createType.ts +++ b/packages/types/src/codec/createType.ts @@ -54,12 +54,9 @@ export function typeSplit (type: string): string[] { case '{': sDepth++; break; case '}': sDepth--; break; - // adjusttuple depth + // adjust tuple depth case '(': tDepth++; break; case ')': tDepth--; break; - - // normal character - default: break; } } diff --git a/packages/types/src/primitive/Extrinsic/ExtrinsicEra.ts b/packages/types/src/primitive/Extrinsic/ExtrinsicEra.ts index 2994645953..0e6ca7ef3c 100644 --- a/packages/types/src/primitive/Extrinsic/ExtrinsicEra.ts +++ b/packages/types/src/primitive/Extrinsic/ExtrinsicEra.ts @@ -57,24 +57,11 @@ export class MortalEra extends Tuple { private static decodeMortalEra (value?: MortalMethod | Uint8Array | number[] | string): MortalEraValue { if (isHex(value)) { - return MortalEra.decodeMortalEra(hexToU8a(value)); + return MortalEra.decodeMortalU8a(hexToU8a(value)); } else if (Array.isArray(value)) { - return MortalEra.decodeMortalEra(new Uint8Array(value)); + return MortalEra.decodeMortalU8a(new Uint8Array(value)); } else if (isU8a(value)) { - if (value.length === 0) { - return [new U64(), new U64()]; - } - - const first = u8aToBn(value.subarray(0, 1)).toNumber(); - const second = u8aToBn(value.subarray(1, 2)).toNumber(); - const encoded: number = first + (second << 8); - const period = 2 << (encoded % (1 << 4)); - const quantizeFactor = Math.max(period >> 12, 1); - const phase = (encoded >> 4) * quantizeFactor; - - assert(period >= 4 && phase < period, 'Invalid data passed to Mortal era'); - - return [new U64(period), new U64(phase)]; + return MortalEra.decodeMortalU8a(value); } else if (isObject(value)) { const { current, period } = value; let calPeriod = Math.pow(2, Math.ceil(Math.log2(period))); @@ -91,6 +78,23 @@ export class MortalEra extends Tuple { throw new Error('Invalid data passed to Mortal era'); } + private static decodeMortalU8a (value: Uint8Array): MortalEraValue { + if (value.length === 0) { + return [new U64(), new U64()]; + } + + const first = u8aToBn(value.subarray(0, 1)).toNumber(); + const second = u8aToBn(value.subarray(1, 2)).toNumber(); + const encoded: number = first + (second << 8); + const period = 2 << (encoded % (1 << 4)); + const quantizeFactor = Math.max(period >> 12, 1); + const phase = (encoded >> 4) * quantizeFactor; + + assert(period >= 4 && phase < period, 'Invalid data passed to Mortal era'); + + return [new U64(period), new U64(phase)]; + } + /** * @description Encoded length for mortals occupy 2 bytes, different from the actual Tuple since it is encoded. This is a shortcut fro `toU8a().length` */ @@ -199,11 +203,9 @@ export default class ExtrinsicEra extends Enum implements IExtrinsicEra { } else if (isHex(value)) { return ExtrinsicEra.decodeExtrinsicEra(hexToU8a(value)); } else if (isU8a(value)) { - if (!value.length || value[0] === 0) { - return new Uint8Array([0]); - } else { - return new Uint8Array([1, value[0], value[1]]); - } + return (!value.length || value[0] === 0) + ? new Uint8Array([0]) + : new Uint8Array([1, value[0], value[1]]); } else if (isObject(value)) { // this is to de-serialize from JSON if ((value as MortalEnumDef).MortalEra) { diff --git a/packages/types/src/primitive/Generic/Address.ts b/packages/types/src/primitive/Generic/Address.ts index 713c474ddf..a36da26d2c 100644 --- a/packages/types/src/primitive/Generic/Address.ts +++ b/packages/types/src/primitive/Generic/Address.ts @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import BN from 'bn.js'; -import { hexToU8a, isBn, isHex, isNumber, isU8a, u8aConcat, u8aToHex, u8aToU8a, u8aToBn } from '@polkadot/util'; +import { isBn, isHex, isNumber, isU8a, u8aConcat, u8aToHex, u8aToU8a, u8aToBn } from '@polkadot/util'; import { decodeAddress } from '@polkadot/util-crypto'; import createType from '../../codec/createType'; @@ -37,22 +37,8 @@ export default class Address extends Base { return createType('AccountIndex', value); } else if (value instanceof Address) { return value.raw; - } else if (Array.isArray(value)) { - return Address.decodeAddress(u8aToU8a(value)); - } else if (isU8a(value)) { - // This allows us to instantiate an address with a raw publicKey. Do this first before - // we checking the first byte, otherwise we may split an already-existent valid address - if (value.length === 32) { - return createType('AccountId', value); - } else if (value[0] === 0xff) { - return createType('AccountId', value.subarray(1)); - } - - const [offset, length] = AccountIndex.readLength(value); - - return createType('AccountIndex', u8aToBn(value.subarray(offset, offset + length), true)); - } else if (isHex(value)) { - return Address.decodeAddress(hexToU8a(value)); + } else if (Array.isArray(value) || isHex(value) || isU8a(value)) { + return Address.decodeU8a(u8aToU8a(value)); } const decoded = decodeAddress(value); @@ -62,6 +48,20 @@ export default class Address extends Base { : createType('AccountIndex', u8aToBn(decoded, true)); } + private static decodeU8a (value: Uint8Array): AccountId | AccountIndex { + // This allows us to instantiate an address with a raw publicKey. Do this first before + // we checking the first byte, otherwise we may split an already-existent valid address + if (value.length === 32) { + return createType('AccountId', value); + } else if (value[0] === 0xff) { + return createType('AccountId', value.subarray(1)); + } + + const [offset, length] = AccountIndex.readLength(value); + + return createType('AccountIndex', u8aToBn(value.subarray(offset, offset + length), true)); + } + /** * @description The length of the value when encoded as a Uint8Array */ diff --git a/packages/types/src/primitive/StorageKey.ts b/packages/types/src/primitive/StorageKey.ts index 656a65eb89..42ae4a64a2 100644 --- a/packages/types/src/primitive/StorageKey.ts +++ b/packages/types/src/primitive/StorageKey.ts @@ -64,9 +64,7 @@ export default class StorageKey extends Bytes { }; } else if (!value || isString(value) || isU8a(value)) { // let Bytes handle these inputs - return { - key: value - }; + return { key: value }; } else if (isFunction(value)) { return { key: value(),