Decode poc-2 & poc-1 extrinsics from JSON (#138)

This commit is contained in:
Jaco Greeff
2018-08-17 10:11:33 +02:00
committed by GitHub
parent 809ea04796
commit e891d4ec2b
5 changed files with 93 additions and 17 deletions
@@ -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);
+1 -1
View File
@@ -27,7 +27,7 @@ export type ExtrinsicDecoded = {
export type BlockExtrinsicDecoded = {
address: string,
nonce: BN,
accountIndex: BN,
extrinsic: SectionItem<Extrinsics>,
params: Array<any>,
signature: Uint8Array
@@ -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'
});
});
});
@@ -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'
});
});
});
@@ -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<EncodingVersions> = ['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)}`);
}