Skip to content

Commit

Permalink
Merge f920fba into cd3255a
Browse files Browse the repository at this point in the history
  • Loading branch information
jacogr committed Oct 5, 2018
2 parents cd3255a + f920fba commit 3c62422
Show file tree
Hide file tree
Showing 6 changed files with 110 additions and 33 deletions.
6 changes: 1 addition & 5 deletions packages/type-extrinsics/src/utils/createUnchecked.ts
Expand Up @@ -22,11 +22,7 @@ export default function createDescriptor (
const callIndex = new Uint8Array([index, meta.id.toNumber()]);
let extrinsicFn: any;

// If the extrinsic function has an argument of type `Origin`, we ignore it
// FIXME should be `arg.type !== Origin`, but doesn't work...
const expectedArgs = meta.arguments.filter((arg) =>
arg.type.toString() !== 'Origin'
);
const expectedArgs = Method.filterOrigin(meta);

extrinsicFn = (...args: any[]): Extrinsic => {
if (expectedArgs.length.valueOf() !== args.length) {
Expand Down
15 changes: 15 additions & 0 deletions packages/types/src/Extrinsic.spec.js
@@ -0,0 +1,15 @@
// Copyright 2017-2018 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.

import Extrinsic from './Extrinsic';

describe('Extrinsic', () => {
it('decodes a non-signed properly via fromJSON', () => {
const extrinsic = new Extrinsic().fromJSON('0x010200ea51b75b00000000');

expect(extrinsic.isSigned).toEqual(false);
expect(extrinsic.callIndex).toEqual(new Uint8Array([2, 0]));
expect(extrinsic.data).toEqual(new Uint8Array([234, 81, 183, 91, 0, 0, 0, 0]));
});
});
27 changes: 21 additions & 6 deletions packages/types/src/Extrinsic.ts
Expand Up @@ -6,6 +6,7 @@ import { KeyringPair } from '@polkadot/util-keyring/types';
import { AnyNumber, AnyU8a } from './types';

import blake2Asu8a from '@polkadot/util-crypto/blake2/asU8a';
import hexToU8a from '@polkadot/util/hex/toU8a';
import u8aConcat from '@polkadot/util/u8a/concat';
import u8aToHex from '@polkadot/util/u8a/toHex';

Expand Down Expand Up @@ -42,8 +43,13 @@ export default class Extrinsic extends Struct {
}, value);
}

get method (): Method {
return this.raw.method as Method;
// the actual [sectionIndex, methodIndex] as used
get callIndex (): Uint8Array {
return this.method.callIndex;
}

get data (): Uint8Array {
return this.method.data;
}

// convernience, encodes the extrinsic and returns the actual hash
Expand All @@ -53,6 +59,10 @@ export default class Extrinsic extends Struct {
);
}

get isSigned (): boolean {
return this.signature.isSigned;
}

get length (): number {
return this.toU8a(true).length;
}
Expand All @@ -61,9 +71,8 @@ export default class Extrinsic extends Struct {
return this.method.meta;
}

// the actual [sectionIndex, methodIndex] as used
get callIndex (): Uint8Array {
return this.method.callIndex;
get method (): Method {
return this.raw.method as Method;
}

get signature (): ExtrinsicSignature {
Expand All @@ -76,6 +85,12 @@ export default class Extrinsic extends Struct {
return length + Compact.encode(length).length;
}

fromJSON (input: any): Extrinsic {
super.fromU8a(hexToU8a(input));

return this;
}

fromU8a (input: Uint8Array): Extrinsic {
const [offset, length] = Compact.decode(input);

Expand All @@ -102,7 +117,7 @@ export default class Extrinsic extends Struct {
}

toHex (): string {
return u8aToHex(this.toU8a());
return u8aToHex(this.toU8a(true));
}

toJSON (): any {
Expand Down
9 changes: 9 additions & 0 deletions packages/types/src/ExtrinsicSignature.ts
Expand Up @@ -43,6 +43,15 @@ export default class ExtrinsicSignature extends Struct {
}, value);
}

byteLength (): number {
// version has 1 byte, signature takes the rest
return 1 + (
this.isSigned
? super.byteLength()
: 0
);
}

get isSigned (): boolean {
return this.signature.length !== 0;
}
Expand Down
70 changes: 54 additions & 16 deletions packages/types/src/Method.ts
Expand Up @@ -9,14 +9,15 @@ import u8aConcat from '@polkadot/util/u8a/concat';
import createType from './codec/createType';
import Base from './codec/Base';
import MethodIndex from './MethodIndex';
import { FunctionMetadata } from './Metadata';
import { FunctionMetadata, FunctionArgumentMetadata } from './Metadata';

/**
* Extrinsic function descriptor, as defined in
* {@link https://github.com/paritytech/wiki/blob/master/Extrinsic.md#the-extrinsic-format-for-node}.
*/
export default class Method extends MethodIndex {
protected _args: Array<Base>;
protected _data: Uint8Array;
protected _meta: FunctionMetadata;

constructor (index: Method | AnyU8a, meta: FunctionMetadata, args: Array<any>) {
Expand All @@ -29,35 +30,72 @@ export default class Method extends MethodIndex {
this._args = args;
this._meta = meta;
}

this._data = Method.encode(this._meta, this._args);
}

static decode (meta: FunctionMetadata, data: Uint8Array): Array<Base> {
let offset = 0;

return Method.filterOrigin(meta).map(({ type }) => {
const base = createType(type).fromU8a(data.subarray(offset));

offset += base.byteLength();

return base;
});
}

get args () {
static encode (meta: FunctionMetadata, args: Array<any>): Uint8Array {
const encoded = Method.filterOrigin(meta).map(({ type }, index) =>
createType(type, args[index]).toU8a()
);

return u8aConcat(...encoded);
}

// If the extrinsic function has an argument of type `Origin`, we ignore it
static filterOrigin (meta?: FunctionMetadata): Array<FunctionArgumentMetadata> {
// FIXME should be `arg.type !== Origin`, but doesn't work...
return meta
? meta.arguments.filter(({ type }) =>
type.toString() !== 'Origin'
)
: [];
}

byteLength (): number {
return super.byteLength() + this.data.length;
}

get args (): Array<any> {
return this._args;
}

get index () {
get data (): Uint8Array {
return this._data;
}

get index (): Uint8Array {
return this.raw;
}

get meta () {
get meta (): FunctionMetadata {
return this._meta;
}

toU8a (isBare?: boolean): Uint8Array {
// FIXME Even when decoded, we will need access to the meta
const args = this.meta
? this.meta.arguments
.filter((arg) =>
arg.type.toString() !== 'Origin'
)
.map((argument, index) =>
createType(argument.type, this.args[index]).toU8a(isBare)
)
: [];
fromU8a (input: Uint8Array): Method {
super.fromU8a(input);

this._data = input.subarray(super.byteLength());

return this;
}

toU8a (isBare?: boolean): Uint8Array {
return u8aConcat(
super.toU8a(isBare),
...args
this.data
);
}
}
16 changes: 10 additions & 6 deletions packages/types/src/codec/U8aFixed.ts
Expand Up @@ -18,27 +18,31 @@ export default class U8aFixed extends U8a {

this._bitLength = bitLength;

this._trimLength();
this._trim();
}

private _trimLength (): void {
this.raw = this.raw.subarray(0, this.byteLength());
private _trimLength (): number {
return this._bitLength / 8;
}

private _trim (): void {
this.raw = this.raw.subarray(0, this._trimLength());
}

byteLength (): number {
return this._bitLength / 8;
return this._trimLength();
}

fromJSON (input: any): U8aFixed {
super.fromJSON(input);

this._trimLength();
this._trim();

return this;
}

fromU8a (input: Uint8Array): U8aFixed {
super.fromU8a(input.subarray(0, this.byteLength()));
super.fromU8a(input.subarray(0, this._trimLength()));

return this;
}
Expand Down

0 comments on commit 3c62422

Please sign in to comment.