From c32bace2cda5ec955e508c264ea74ef20a93de84 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 7 Nov 2018 15:05:02 +0100 Subject: [PATCH] Handle both prefixed and non-prefixed hex Bytes (#379) --- packages/types/src/Bytes.spec.ts | 23 +++++++++++++++++++++++ packages/types/src/Bytes.ts | 13 +++++++------ packages/types/src/codec/Compact.ts | 6 ++++++ 3 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 packages/types/src/Bytes.spec.ts diff --git a/packages/types/src/Bytes.spec.ts b/packages/types/src/Bytes.spec.ts new file mode 100644 index 0000000000..5db9a53c02 --- /dev/null +++ b/packages/types/src/Bytes.spec.ts @@ -0,0 +1,23 @@ +// 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 Bytes from './Bytes'; + +describe('Bytes', () => { + describe('hex decoding', () => { + const CODE = new Uint8Array([0x14, 0x3a, 0x63, 0x6f, 0x64, 0x65]); + + it('decodes when hex is length prefixed', () => { + expect( + new Bytes('0x143a636f6465').toU8a() + ).toEqual(CODE); + }); + + it('decodes when hex is not length prefixed', () => { + expect( + new Bytes('0x3a636f6465').toU8a() + ).toEqual(CODE); + }); + }); +}); diff --git a/packages/types/src/Bytes.ts b/packages/types/src/Bytes.ts index c3c9c9be9e..59b715e145 100644 --- a/packages/types/src/Bytes.ts +++ b/packages/types/src/Bytes.ts @@ -22,15 +22,16 @@ export default class Bytes extends U8a { } else if (isHex(value)) { // FIXME We manually add the length prefix for hex for now // https://github.com/paritytech/substrate/issues/889 - // Instead of the block below, it should simply be: - // return Bytes.decodeBytes(hexToU8a(value as string)); + // HACK 7 Nov 2018 Some Bytes values are properly encoded, i.e. when + // querying storage for code, others are not (yet), i.e. extrinsics. + // Here we pull the length, check for matches and add when not const u8a = hexToU8a(value as string); + const [offset, length] = Compact.decodeU8a(u8a, DEFAULT_LENGTH_BITS); return Bytes.decodeBytes( - u8aConcat( - Compact.encodeU8a(u8a.length, DEFAULT_LENGTH_BITS), - u8a - ) + u8a.length === (offset + length.toNumber()) + ? u8a + : Compact.addLengthPrefix(u8a) ); } else if (isU8a(value)) { const [offset, length] = Compact.decodeU8a(value, DEFAULT_LENGTH_BITS); diff --git a/packages/types/src/codec/Compact.ts b/packages/types/src/codec/Compact.ts index 172ddea3e3..d2934c4edd 100644 --- a/packages/types/src/codec/Compact.ts +++ b/packages/types/src/codec/Compact.ts @@ -56,6 +56,12 @@ export default class Compact extends Base { ); } + static stripLengthPrefix (u8a: Uint8Array, bitLength: UIntBitLength = DEFAULT_LENGTH_BITS): Uint8Array { + const [offset] = Compact.decodeU8a(u8a, bitLength); + + return u8a.subarray(offset); + } + static decodeCompact (Type: Constructor, value: AnyNumber): Moment | UInt { if (isString(value)) { return new Type(