diff --git a/packages/type-params/src/decode/value/index.ts b/packages/type-params/src/decode/value/index.ts index afff3eed25..c37b29d1ee 100644 --- a/packages/type-params/src/decode/value/index.ts +++ b/packages/type-params/src/decode/value/index.ts @@ -5,11 +5,12 @@ import { EncodingVersions, Param$Decoded, Param$Type } from '../../types'; import { Decoder } from '../types'; -import sizes from '@polkadot/primitives/sizes'; +import defaultSizes from '@polkadot/primitives/sizes'; import toU8a from '@polkadot/util/u8a/toU8a'; import isNull from '@polkadot/util/is/null'; import isUndefined from '@polkadot/util/is/undefined'; +import sizes from '../../sizes'; import accountId from './accountId'; import bool from './bool'; import bn from './bn'; @@ -37,8 +38,11 @@ export default function decodeValue (decode: Decoder, type: Param$Type, _input: case 'AccountId': return accountId(input, version, isStorage); + case 'AccountIndex': + return bn(input, sizes.AccountIndex.get(version) || defaultSizes.AccountIndex); + case 'Balance': - return bn(input, sizes.Balance); + return bn(input, sizes.Balance.get(version) || defaultSizes.Balance); case 'BlockNumber': case 'Gas': @@ -72,9 +76,6 @@ export default function decodeValue (decode: Decoder, type: Param$Type, _input: case 'Hash': return u8a(input, 256, 0); - case 'AccountIndex': - return bn(input, sizes.AccountIndex); - case 'KeyValue': case 'StorageKeyValue': return keyValue(input); diff --git a/packages/type-params/src/types.d.ts b/packages/type-params/src/types.d.ts index a5a2355254..475934f464 100644 --- a/packages/type-params/src/types.d.ts +++ b/packages/type-params/src/types.d.ts @@ -27,7 +27,7 @@ export type ExtrinsicDecoded = { export type BlockExtrinsicDecoded = { address: string, - nonce: BN, + accountIndex: BN, extrinsic: SectionItem, params: Array, signature: Uint8Array diff --git a/packages/type-primitives/src/json/block/decode.spec.js b/packages/type-primitives/src/json/block/decode.spec.js new file mode 100644 index 0000000000..47fff23148 --- /dev/null +++ b/packages/type-primitives/src/json/block/decode.spec.js @@ -0,0 +1,42 @@ +// Copyright 2017-2018 @polkadot/primitives authors & contributors +// This software may be modified and distributed under the terms +// of the ISC license. See the LICENSE file for details. + +import decode from './decode'; + +const blockPoc1 = { + block: { + extrinsics: [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 36, 241, 242, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ], + header: { + digest: { + logs: [] + }, + extrinsicsRoot: '0xcfc906dc1496e190742daefd8ec378a0a901c134d176178f6bbbaeea407b3649', + number: 1, + parentHash: '0x6c5a31dc701c2a01a3f985da4da5faae19dc205ea212a5b1e4271e3e358271cc', + stateRoot: '0x71abf5a507b6cf7a94d5cbfd8b4a1a809167a0044994acb420f891ff18f296d8' + } + }, + justification: { + hash: '0xa04cab547ca4ef9ff13c1c489a8620994968035a7f07ef9d507226530c8dd81d', + round_number: 1, + signatures: [ + ['0x82c39b31a2b79a90f8e66e7a77fdb85a4ed5517f2ae39f6a80565e8ecae85cf5', '0xa681bd611800ede4637f2500315a850ffa8b9202640f0bed06125eb5fb10216c7f8bc4a4a0057a53807242144f2411c26bf84df91e7d62373a8cb7453973010e'], + ['0x063d7787ebca768b7445dfebe7d62cbb1625ff4dba288ea34488da266dd6dca5', '0x5710dfbbbb17e1661d7cc0bcf879e8da9ba9255fae15603b35b8079a30f20547f882eaab8ff959ed85cb410718fda102c010420281b5cbef64e5d4e3147c3b0f'], + ['0x4de37a07567ebcbf8c64568428a835269a566723687058e017b6d69db00a77e7', '0x95a6fd0eca0f36c560d27fc437433a1bfe3787c98f59515922394c8c51c500f13976cac28c79af22488cb0f9b123d933e4eb0eaf563d3b9672f6ae281e581708'] + ] + } +}; + +describe('blockDecode', () => { + it('decodes poc-1 blocks properly', () => { + expect( + decode(blockPoc1).extrinsics[0].extrinsic + ).toMatchObject({ + name: 'set', + section: 'timestamp' + }); + }); +}); diff --git a/packages/type-primitives/src/json/extrinsic/decode.spec.js b/packages/type-primitives/src/json/extrinsic/decode.spec.js index 018b536ad7..11136d0547 100644 --- a/packages/type-primitives/src/json/extrinsic/decode.spec.js +++ b/packages/type-primitives/src/json/extrinsic/decode.spec.js @@ -16,6 +16,10 @@ const extrinsics = [ ]) ]; +const poc1 = new Uint8Array([ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 36, 241, 242, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +]); + describe('extrinsic', () => { extrinsics.forEach((extrinsic, index) => { it(`decodes the extrinsic - ${index}`, () => { @@ -24,4 +28,22 @@ describe('extrinsic', () => { expect(decoded).toBeDefined(); }); }); + + it('decodes poc-1 extrinsic', () => { + expect( + decode(poc1).extrinsic + ).toMatchObject({ + name: 'set', + section: 'timestamp' + }); + }); + + it('decodes poc-2/latest extrinsic', () => { + expect( + decode(extrinsics[1]).extrinsic + ).toMatchObject({ + name: 'setHeads', + section: 'parachains' + }); + }); }); diff --git a/packages/type-primitives/src/json/extrinsic/decode.ts b/packages/type-primitives/src/json/extrinsic/decode.ts index 4a29170ef8..52b28b42c8 100644 --- a/packages/type-primitives/src/json/extrinsic/decode.ts +++ b/packages/type-primitives/src/json/extrinsic/decode.ts @@ -2,21 +2,32 @@ // This software may be modified and distributed under the terms // of the ISC license. See the LICENSE file for details. -import { BlockExtrinsicDecoded, ExtrinsicDecoded } from '@polkadot/params/types'; +import { BlockExtrinsicDecoded, ExtrinsicDecoded, EncodingVersions } from '@polkadot/params/types'; import BN from 'bn.js'; import decoder from '@polkadot/params/decode'; +import ExtError from '@polkadot/util/ext/error'; +import u8aToHex from '@polkadot/util/u8a/toHex'; + +const VERSIONS: Array = ['latest', 'poc-1']; export default function extrinsicDecode (extrinsic: Uint8Array): BlockExtrinsicDecoded { - const addressDecoded = decoder('AccountId', extrinsic, 'latest'); - const nonceDecoded = decoder('AccountIndex', extrinsic.subarray(addressDecoded.length), 'latest'); - const extrinsicDecoded = decoder('Call', extrinsic.subarray(addressDecoded.length + nonceDecoded.length), 'latest'); - const signature = extrinsic.subarray(addressDecoded.length + nonceDecoded.length + extrinsicDecoded.length); + for (let version of VERSIONS) { + const addressDecoded = decoder('AccountId', extrinsic, version); + const nonceDecoded = decoder('AccountIndex', extrinsic.subarray(addressDecoded.length), version); + const extrinsicDecoded = decoder('Call', extrinsic.subarray(addressDecoded.length + nonceDecoded.length), version); + const signature = extrinsic.subarray(addressDecoded.length + nonceDecoded.length + extrinsicDecoded.length); + const totalLength = addressDecoded.length + nonceDecoded.length + extrinsicDecoded.length + signature.length; - return { - ...(extrinsicDecoded.value as ExtrinsicDecoded), - address: addressDecoded.value as string, - nonce: nonceDecoded.value as BN, - signature - }; + if (totalLength === extrinsic.length) { + return { + ...(extrinsicDecoded.value as ExtrinsicDecoded), + address: addressDecoded.value as string, + accountIndex: nonceDecoded.value as BN, + signature + }; + } + } + + throw new ExtError(`Unable to decode extrinsic: ${u8aToHex(extrinsic)}`); }