diff --git a/packages/types/src/Bytes.spec.ts b/packages/types/src/Bytes.spec.ts index e171b7bafa..0e7ee0dc3a 100644 --- a/packages/types/src/Bytes.spec.ts +++ b/packages/types/src/Bytes.spec.ts @@ -3,15 +3,32 @@ // of the Apache-2.0 license. See the LICENSE file for details. import Bytes from './Bytes'; +import StorageData from './StorageData'; describe('Bytes', () => { - describe('hex decoding', () => { - const CODE = new Uint8Array([0x14, 0x3a, 0x63, 0x6f, 0x64, 0x65]); + const CODE = new Uint8Array([0x14, 0x3a, 0x63, 0x6f, 0x64, 0x65]); + describe('construction', () => { it('decodes when hex is not length prefixed', () => { expect( new Bytes('0x3a636f6465').toU8a() ).toEqual(CODE); }); + + it('creates via storagedata (no prefix)', () => { + expect( + new Bytes( + new StorageData('0x3a636f6465') + ).toU8a() + ).toEqual(CODE); + }); + + it('creates via storagedata (with length prefix)', () => { + expect( + new Bytes( + new StorageData('0x143a636f6465') + ).toU8a() + ).toEqual(CODE); + }); }); }); diff --git a/packages/types/src/Bytes.ts b/packages/types/src/Bytes.ts index 1429744416..317f926a6b 100644 --- a/packages/types/src/Bytes.ts +++ b/packages/types/src/Bytes.ts @@ -17,6 +17,11 @@ export default class Bytes extends U8a { } private static decodeBytes (value: AnyU8a): Uint8Array { + // FIXME Cyclic dependency, however needed for the StoreageData check below. In a perfect + // world, we should probably be checking Bytes - however as a first step, check against + // StorageData to cater for the _specific_ problematic case + const StorageData = require('./StorageData').default; + if (isHex(value)) { // FIXME We manually add the length prefix for hex for now // https://github.com/paritytech/substrate/issues/889 @@ -25,8 +30,17 @@ export default class Bytes extends U8a { return Bytes.decodeBytes( Compact.addLengthPrefix(u8a) ); + } else if (value instanceof StorageData) { + // Here we cater for the actual StorageData that _could_ have a length prefix. In the + // case of `:code` it is not added, for others it is + const u8a = value as Uint8Array; + const [offset, length] = Compact.decodeU8a(u8a); + + return u8a.length === length.addn(offset).toNumber() + ? u8a.subarray(offset) + : u8a; } else if (value instanceof U8a) { - // This is required. In the case of a U8a we already have gottent rid of the length, + // This is required. In the case of a U8a we already have gotten rid of the length, // i.e. new Bytes(new Bytes(...)) will work as expected return value; } else if (isU8a(value)) { diff --git a/packages/types/src/StorageData.ts b/packages/types/src/StorageData.ts index 1a4a5ea63f..39a18b6f0b 100644 --- a/packages/types/src/StorageData.ts +++ b/packages/types/src/StorageData.ts @@ -4,5 +4,6 @@ import Bytes from './Bytes'; +// Data retrieve via Storage queries and data for KeyValue pairs export default class StorageData extends Bytes { }