From 8675aafcf3b62d40708073dd5653a0320b1ac72a Mon Sep 17 00:00:00 2001 From: Dastan Date: Fri, 5 Mar 2021 03:00:23 +0200 Subject: [PATCH 1/2] Fix UInt128 --- assembly/Arrays/UInt128Array.ts | 6 +- assembly/UInt/UInt128.ts | 73 ++------- .../__tests__/Arrays/UInt128Array.spec.ts | 95 ++++++++---- assembly/__tests__/ScaleMap.spec.ts | 10 +- assembly/__tests__/UInt.spec.ts | 145 ++++++++---------- assembly/utils/Arrays.ts | 12 ++ 6 files changed, 155 insertions(+), 186 deletions(-) diff --git a/assembly/Arrays/UInt128Array.ts b/assembly/Arrays/UInt128Array.ts index cc34316..f02e0f1 100644 --- a/assembly/Arrays/UInt128Array.ts +++ b/assembly/Arrays/UInt128Array.ts @@ -25,8 +25,8 @@ export class UInt128Array extends AbstractArray { /** * @description BoolArray elements decryption implementation */ - public decodeElement (value: u8[]): DecodedData { - const u128Instance = UInt128.fromU8a(value); + public decodeElement(value: u8[]): DecodedData { + const u128Instance = UInt128.fromU8a(value.slice(0, BIT_LENGTH.INT_128)); return new DecodedData( u128Instance.unwrap(), @@ -43,7 +43,7 @@ export class UInt128Array extends AbstractArray { const bytesReader = new BytesReader(bytes.slice(index)); const data = bytesReader.readInto(); for(let i: i32 = 0; i < data.unwrap(); i++){ - const element: UInt128 = bytesReader.readInto(); + const element: UInt128 = BytesReader.decodeInto(bytesReader.readBytes(BIT_LENGTH.INT_128)); this.values.push(element.unwrap()); } } diff --git a/assembly/UInt/UInt128.ts b/assembly/UInt/UInt128.ts index 093792e..8283690 100644 --- a/assembly/UInt/UInt128.ts +++ b/assembly/UInt/UInt128.ts @@ -14,17 +14,16 @@ import { u128 } from "as-bignum"; import { UnwrappableCodec } from "../interfaces/UnwrappableCodec"; -import { BIT_LENGTH, Bytes } from "../utils/Bytes"; +import { ArrayUtils } from "../utils/Arrays"; +import { BIT_LENGTH } from "../utils/Bytes"; /** Representation for a UInt128 value in the system. */ export class UInt128 implements UnwrappableCodec { private _value: u128; - protected bitLength: i32; constructor (value: u128 = u128.Zero) { this._value = value; - this.bitLength = UInt128._computeBitLength(value); } /** @@ -34,30 +33,13 @@ export class UInt128 implements UnwrappableCodec { return this._value; } - /** Encodes the value as u8[] as per the SCALE codec specification */ + /** + * @description Encodes the value as u8[] as per the SCALE codec specification + * */ toU8a (): u8[] { - const bytes = new Array(); - if (this._value < u128.fromU32(1 << 6)) { // if value < 1 << 6 - Bytes.appendUint(bytes, u8(this._value.as()) << 2, BIT_LENGTH.INT_8); // 1 byte - } else if (this._value < u128.fromU32(1 << 14)) { // if value < 1 << 14 - Bytes.appendUint(bytes, u16(this._value.as() << 2) + 1, BIT_LENGTH.INT_16); // 2 bytes - } else if (this._value < u128.fromU64(1 << 30)) { // if value < 1 << 30 - Bytes.appendUint(bytes, u32(this._value.as() << 2) + 2, BIT_LENGTH.INT_32); // 4 bytes - } else { - const valueInBytes = this._value.toBytes(); - Bytes.trimEmptyBytes(valueInBytes); - - const topSixBits: u8 = u8(valueInBytes.length - 4); - const lengthByte: u8 = (topSixBits << 2) + 3; - - // Encode Mode and Bytes length - bytes.push(lengthByte); - // copy the u128 bytes - Bytes.copy(valueInBytes, bytes, 1); - } - return bytes; + return ArrayUtils.toU8Array(this._value.toUint8Array(false)); } - + toString(): string { return this._value.toString(); } @@ -68,54 +50,19 @@ export class UInt128 implements UnwrappableCodec { */ populateFromBytes(bytes: u8[], index: i32 = 0): void{ assert(bytes.length - index > 0, 'Invalid input: Byte array should not be empty'); - const value = UInt128._computeValue(bytes, index); - this._value = value; - this.bitLength = UInt128._computeBitLength(this._value); + this._value = u128.fromBytesLE(bytes.slice(index)); } /** * @description The length of Int when the value is encoded */ public encodedLength (): i32 { - return this.bitLength; - } - - /** - * Internal static private function to compute value of the UInt128 - * @param bytes - * @param index - */ - static _computeValue(bytes: u8[], index: i32 = 0): u128{ - const mode = bytes[index] & 0x03; - if (i32(mode) <= 2) { - return new u128(u64(Bytes.decodeSmallInt(bytes, mode, index).value), 0); - } - const topSixBits = bytes[index] >> 2; - const byteLength = topSixBits + 4; - - const value = bytes.slice(index + 1, byteLength + index + 1); - Bytes.appendZeroBytes(value, BIT_LENGTH.INT_128); - return u128.fromBytesLE(value) - } - - /** - * Internal private function to compute bit length of the value - * @param value - */ - static _computeBitLength(value: u128): i32 { - if (value < u128.fromU32(1 << 6)) return BIT_LENGTH.INT_8; - else if (value < u128.fromU32(1 << 14)) return BIT_LENGTH.INT_16; - else if (value < u128.fromU32(1 << 30)) return BIT_LENGTH.INT_32; - else { - const valueInBytes = value.toBytes(); - Bytes.trimEmptyBytes(valueInBytes); - return 1 + valueInBytes.length; - } + return BIT_LENGTH.INT_128; } /** Instantiates new UInt128 from u8[] SCALE encoded bytes */ static fromU8a(input: u8[], index: i32 = 0): UInt128 { assert(input.length - index != 0, 'Invalid input: Byte array should not be empty'); - return new UInt128(UInt128._computeValue(input, index)); + return new UInt128(u128.fromBytesLE(input.slice(index))); } eq(other: UInt128): bool { diff --git a/assembly/__tests__/Arrays/UInt128Array.spec.ts b/assembly/__tests__/Arrays/UInt128Array.spec.ts index bfeda25..0f5e3c3 100644 --- a/assembly/__tests__/Arrays/UInt128Array.spec.ts +++ b/assembly/__tests__/Arrays/UInt128Array.spec.ts @@ -1,26 +1,35 @@ -import { UInt128Array } from "../../Arrays/UInt128Array"; import { u128 } from "as-bignum"; -import {UInt128} from "../../UInt/UInt128"; +import { UInt128Array } from "../../Arrays/UInt128Array"; describe("UInt128Array", () => { it("should encode uint128 array", () => { const dataInput: Array> = [ - [u128.One], // Expected output: [0x04, 0x04] - [u128.fromU32(1), u128.fromU32(2), u128.fromU32(3), u128.fromU32(4)], // Expected output: [0x10, 0x04, 0x08, 0x0c, 0x10] - [u128.fromU32(16384), u128.fromU32(2), u128.fromU32(3), u128.fromU32(4)], // Expected output: [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10] - [u128.fromU64(97222587), u128.fromU64(260918714), u128.fromU64(432884242), u128.fromU64(497178323), u128.fromU64(524283510), u128.fromU64(530431722), u128.fromU64(619955096), u128.fromU64(629855926), u128.fromU64(884757710), u128.fromU64(947465305)], - [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615)], + [u128.One], + [u128.fromString('54321')], + [u128.fromU32(20001), u128.fromU32(123456)], + [ + u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'), + u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345') + ], + [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max], [u128.Max - u128.fromU64(u64.MAX_VALUE)] ]; const expectedOutput: Array> = [ - [0x04, 0x04], - [0x10, 0x04, 0x08, 0x0c, 0x10], - [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], - [0x28, 0xee, 0xfe, 0x2d, 0x17, 0xea, 0x36, 0x35, 0x3e, 0x4a, 0x28, 0x35, 0x67, 0x4e, 0x5b, 0x89, 0x76, 0xda, 0xb9, 0xff, 0x7c, 0xaa, 0xfb, 0x76, 0x7e, 0x62, 0x0e, 0xcf, 0x93, 0xda, 0x5a, 0x2b, 0x96, 0x3a, 0x53, 0xf1, 0xd2, 0x66, 0xb1, 0xe4, 0xe1], - [0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - [0x04, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + [4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1] + [4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321 + [8, 33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [20001, 123456] + [ + 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0 + ], + [ + 12, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ], + [4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255] ]; for (let i = 0; i < dataInput.length; i++) { @@ -31,20 +40,30 @@ describe("UInt128Array", () => { it("should decode uint128 array", () => { const dataInput: Array> = [ - [0x04, 0x04], // Expected output: [1] - [0x10, 0x04, 0x08, 0x0c, 0x10], // Expected output: [1, 2, 3, 4] - [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], // Expected output: [16384, 2, 3, 4] - [0x28, 0xee, 0xfe, 0x2d, 0x17, 0xea, 0x36, 0x35, 0x3e, 0x4a, 0x28, 0x35, 0x67, 0x4e, 0x5b, 0x89, 0x76, 0xda, 0xb9, 0xff, 0x7c, 0xaa, 0xfb, 0x76, 0x7e, 0x62, 0x0e, 0xcf, 0x93, 0xda, 0x5a, 0x2b, 0x96, 0x3a, 0x53, 0xf1, 0xd2, 0x66, 0xb1, 0xe4, 0xe1], - [0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - [0x04, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + [4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1] + [4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321 + [8, 33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [20001, 123456] + [ + 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0 + ], + [ + 12, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ], + [4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255] ]; const expectedOutput: Array> = [ [u128.One], - [u128.One, u128.fromU64(2), u128.fromU64(3), u128.fromU64(4)], - [u128.fromU64(16384), u128.fromU64(2), u128.fromU64(3), u128.fromU64(4)], - [u128.fromU64(97222587), u128.fromU64(260918714), u128.fromU64(432884242), u128.fromU64(497178323), u128.fromU64(524283510), u128.fromU64(530431722), u128.fromU64(619955096), u128.fromU64(629855926), u128.fromU64(884757710), u128.fromU64(947465305)], - [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615)], + [u128.fromString('54321')], + [u128.fromU32(20001), u128.fromU32(123456)], + [ + u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'), + u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345') + ], + [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max], [u128.Max - u128.fromU64(u64.MAX_VALUE)] ]; @@ -56,19 +75,29 @@ describe("UInt128Array", () => { it("should decode uint128 array with populate method", () => { const dataInput: Array> = [ - [0x04, 0x04], // Expected output: [1] - [0x10, 0x04, 0x0c, 0x0c, 0x10], // Expected output: [1, 3, 3, 4] - [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], // Expected output: [16384, 2, 3, 4] - [0x28, 0xee, 0xfe, 0x2d, 0x17, 0xea, 0x36, 0x35, 0x3e, 0x4a, 0x28, 0x35, 0x67, 0x4e, 0x5b, 0x89, 0x76, 0xda, 0xb9, 0xff, 0x7c, 0xaa, 0xfb, 0x76, 0x7e, 0x62, 0x0e, 0xcf, 0x93, 0xda, 0x5a, 0x2b, 0x96, 0x3a, 0x53, 0xf1, 0xd2, 0x66, 0xb1, 0xe4, 0xe1], - [0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - [0x04, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff] + [4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1] + [4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321 + [8, 33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [20001, 123456] + [ + 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0, + 121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0 + ], + [ + 12, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 + ], + [4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255] ]; const expectedOutput: Array> = [ [u128.One], - [u128.One, u128.fromU64(3), u128.fromU64(3), u128.fromU64(4)], - [u128.fromU64(16384), u128.fromU64(2), u128.fromU64(3), u128.fromU64(4)], - [u128.fromU64(97222587), u128.fromU64(260918714), u128.fromU64(432884242), u128.fromU64(497178323), u128.fromU64(524283510), u128.fromU64(530431722), u128.fromU64(619955096), u128.fromU64(629855926), u128.fromU64(884757710), u128.fromU64(947465305)], - [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615)], + [u128.fromString('54321')], + [u128.fromU32(20001), u128.fromU32(123456)], + [ + u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'), + u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345') + ], + [u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max], [u128.Max - u128.fromU64(u64.MAX_VALUE)] ]; diff --git a/assembly/__tests__/ScaleMap.spec.ts b/assembly/__tests__/ScaleMap.spec.ts index 8116e38..51d799a 100644 --- a/assembly/__tests__/ScaleMap.spec.ts +++ b/assembly/__tests__/ScaleMap.spec.ts @@ -46,13 +46,15 @@ describe("String", () => { const map2U8a: u8[] = [ 8, - 1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, - 0xff, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + 1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0xff, 0x00, 0xab, 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, + 64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; const decodedMap2 = BytesReader.decodeInto>(map2U8a); const scaleMap2 = new ScaleMap(); - scaleMap2.set(new Hash([1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121]), new UInt128(u128.fromString("549755813888"))); - scaleMap2.set(new Hash([0xff, 0x00, 0xab]), new UInt128(u128.fromString("18446744073709551615"))); + scaleMap2.set(new Hash([1, 12, 12, 12, 1, 1, 1, 0, 0, 0, 1, 12, 123, 123, 11, 123, 33, 121]), new UInt128(u128.fromU32(1))); + scaleMap2.set(new Hash([0xff, 0x00, 0xab]), new UInt128(u128.fromU32(123456))); expect(decodedMap2.eq(scaleMap2)).toStrictEqual(true); }) }) \ No newline at end of file diff --git a/assembly/__tests__/UInt.spec.ts b/assembly/__tests__/UInt.spec.ts index 7b5631b..a6670d6 100644 --- a/assembly/__tests__/UInt.spec.ts +++ b/assembly/__tests__/UInt.spec.ts @@ -11,13 +11,12 @@ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. - -import { UInt8 } from "../UInt/UInt8"; +import { u128 } from "as-bignum"; +import { UInt128 } from "../UInt/UInt128"; import { UInt16 } from "../UInt/UInt16"; import { UInt32 } from "../UInt/UInt32"; import { UInt64 } from "../UInt/UInt64"; -import {UInt128} from "../UInt/UInt128"; -import { u128 } from "as-bignum"; +import { UInt8 } from "../UInt/UInt8"; describe("UInt8", () => { @@ -297,115 +296,95 @@ describe("UInt128", () => { it("should encode uint128", () => { const v0 = new UInt128(u128.fromU32(1)); - expect(v0.toU8a()).toStrictEqual([0x04]); - - const v1 = new UInt128(u128.fromU32(64)); - expect(v1.toU8a()).toStrictEqual([0x01, 0x01]); + expect(v0.toU8a()).toStrictEqual([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - const v2 = new UInt128(u128.fromU32(16383)); - expect(v2.toU8a()).toStrictEqual([0xfd, 0xff]); + const v1 = new UInt128(u128.fromU32(20001)); + expect(v1.toU8a()).toStrictEqual([33, 78, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - const v3 = new UInt128(u128.fromU32(16384)); - expect(v3.toU8a()).toStrictEqual([0x02, 0x00, 0x01, 0x00]); + const v2 = new UInt128(u128.fromU32(123456)); + expect(v2.toU8a()).toStrictEqual([64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - const v4 = new UInt128(u128.fromU32(1073741823)); - expect(v4.toU8a()).toStrictEqual([0xfe, 0xff, 0xff, 0xff]); + const v3 = new UInt128(u128.fromU64(123456789)); + expect(v3.toU8a()).toStrictEqual([21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - const v5 = new UInt128(u128.fromU32(1073741824)); - expect(v5.toU8a()).toStrictEqual([0x03, 0x00, 0x00, 0x00, 0x40]); + const v4 = new UInt128(u128.fromString('123456789012345')); + expect(v4.toU8a()).toStrictEqual([121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - const v6 = new UInt128(u128.fromU32(1073745328)); - expect(v6.toU8a()).toStrictEqual([0x03, 0xb0, 0x0d, 0x00, 0x40]); + const v5 = new UInt128(u128.fromString('12345678901234567890')); + expect(v5.toU8a()).toStrictEqual([210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0]); - const v7 = new UInt128(u128.fromU64(549755813888)); - expect(v7.toU8a()).toStrictEqual([0x07, 0x00, 0x00, 0x00, 0x00, 0x80]); - - const v8 = new UInt128(u128.fromU32(4294967295)); - expect(v8.toU8a()).toStrictEqual([0x03, 0xff, 0xff, 0xff, 0xff]); - - const v9 = new UInt128(u128.fromU32(2180)); - expect(v9.toU8a()).toStrictEqual([0x11, 0x22]); - - const v10 = new UInt128(u128.fromU64(3091694112222222222)); - expect(v10.toU8a()).toStrictEqual([0x13, 0x8e, 0x17, 0x2c, 0x21, 0x6a, 0xe7, 0xe7, 0x2a]); - - const v11 = new UInt128(u128.fromU64(18446744073709551615)); - expect(v11.toU8a()).toStrictEqual([0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); - - const v12 = new UInt128(u128.Max - u128.fromU64(u64.MAX_VALUE)); // 340282366920938463444927863358058659840 - expect(v12.toU8a()).toStrictEqual([0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); + const v6 = new UInt128(u128.fromString('1234567890123456789012345')); + expect(v6.toU8a()).toStrictEqual([121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0]); + + const v7 = new UInt128(u128.fromU64(u64.MAX_VALUE)); + expect(v7.toU8a()).toStrictEqual([255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); + const v8 = new UInt128(u128.Max); + expect(v8.toU8a()).toStrictEqual([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); + + //@ts-ignore + const v9 = new UInt128(u128.Max - u128.fromU64(u64.MAX_VALUE)); + expect(v9.toU8a()).toStrictEqual([0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255]); }); it("should decode uint128", () => { - const v0 = UInt128.fromU8a([0x00]); - expect(v0.toString()).toStrictEqual("0"); - - const v1 = UInt128.fromU8a([0x04]); - expect(v1.toString()).toStrictEqual("1"); - - const v2 = UInt128.fromU8a([0xfc]); - expect(v2.toString()).toStrictEqual("63"); + const v0 = UInt128.fromU8a([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v0.toString()).toStrictEqual("1"); - const v3 = UInt128.fromU8a([0xfd, 0xff]); - expect(v3.toString()).toStrictEqual("16383"); + const v1 = UInt128.fromU8a([49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v1.toString()).toStrictEqual("54321"); - const v4 = UInt128.fromU8a([0x02, 0x00, 0x01, 0x00]); - expect(v4.toString()).toStrictEqual("16384"); + const v2 = UInt128.fromU8a([21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v2.toString()).toStrictEqual("123456789"); - const v5 = UInt128.fromU8a([0xfe, 0xff, 0xff, 0xff]); - expect(v5.toString()).toStrictEqual("1073741823"); + const v3 = UInt128.fromU8a([121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v3.toString()).toStrictEqual("123456789012345"); - const v6 = UInt128.fromU8a([0x03, 0x00, 0x00, 0x00, 0x40]); - expect(v6.toString()).toStrictEqual("1073741824"); + const v4 = UInt128.fromU8a([210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v4.toString()).toStrictEqual("12345678901234567890"); - const v7 = UInt128.fromU8a([0x03, 0xb0, 0x0d, 0x00, 0x40]); - expect(v7.toString()).toStrictEqual("1073745328"); + const v5 = UInt128.fromU8a([121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0]); + expect(v5.toString()).toStrictEqual("1234567890123456789012345"); - const v8 = UInt128.fromU8a([0x03, 0xff, 0xff, 0xff, 0xff]); - expect(v8.toString()).toStrictEqual("4294967295"); - - const v9 = UInt128.fromU8a([ 0x13, 0x8e, 0x17, 0x2c, 0x21, 0x6a, 0xe7, 0xe7, 0x2a]); - expect(v9.toString()).toStrictEqual("3091694112222222222"); - - // Reads only the upper 6 bits and the following byte - const v13 = UInt128.fromU8a([ 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x12]); - expect(v13.toString()).toStrictEqual("2180"); - - const v10 = UInt128.fromU8a([0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); - expect(v10.toString()).toStrictEqual("340282366920938463444927863358058659840"); + const v6 = UInt128.fromU8a([255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v6.toString()).toStrictEqual(u64.MAX_VALUE.toString()); - const v11 = UInt128.fromU8a([0x2b, 0x00, 0x01, 0xfa, 0xcb, 0xaa, 0x15, 0x10, 0x05, 0x04, 0x11]); - expect(v11.toString()).toStrictEqual("80354382000471934632192"); - - const v12 = UInt128.fromU8a([0x43, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); - expect(v12.toString()).toStrictEqual("1329227995784915872903807060280344575"); + const v7 = UInt128.fromU8a([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); + expect(v7.toString()).toStrictEqual(u128.Max.toString()); }); it("should decode uint128 with populate method", () => { + const v0 = new UInt128(); + v0.populateFromBytes([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v0.toString()).toStrictEqual("1"); + const v1 = new UInt128(); - v1.populateFromBytes([0x07, 0x00, 0x00, 0x00, 0x00, 0x80]); - expect(v1.toString()).toStrictEqual("549755813888"); + v1.populateFromBytes([49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v1.toString()).toStrictEqual("54321"); const v2 = new UInt128(); - v2.populateFromBytes([ 0x11, 0x22]); - expect(v2.toString()).toStrictEqual("2180"); + v2.populateFromBytes([21, 205, 91, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v2.toString()).toStrictEqual("123456789"); const v3 = new UInt128(); - v3.populateFromBytes([0x01, 0x01]); - expect(v3.toString()).toStrictEqual("64"); + v3.populateFromBytes([121, 223, 13, 134, 72, 112, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v3.toString()).toStrictEqual("123456789012345"); const v4 = new UInt128(); - v4.populateFromBytes([0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); - expect(v4.toString()).toStrictEqual("18446744073709551615"); - + v4.populateFromBytes([210, 10, 31, 235, 140, 169, 84, 171, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v4.toString()).toStrictEqual("12345678901234567890"); + const v5 = new UInt128(); - v5.populateFromBytes([0x2b, 0x00, 0x01, 0xfa, 0xcb, 0xaa, 0x15, 0x10, 0x05, 0x04, 0x11]); - expect(v5.toString()).toStrictEqual("80354382000471934632192"); + v5.populateFromBytes([121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0]); + expect(v5.toString()).toStrictEqual("1234567890123456789012345"); const v6 = new UInt128(); - v6.populateFromBytes([0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]); - expect(v6.toString()).toStrictEqual("18446744073709551615"); + v6.populateFromBytes([255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0]); + expect(v6.toString()).toStrictEqual(u64.MAX_VALUE.toString()); + + const v7 = new UInt128(); + v7.populateFromBytes([255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); + expect(v7.toString()).toStrictEqual(u128.Max.toString()); }); itThrows('should throw when decoding empty array', () => { diff --git a/assembly/utils/Arrays.ts b/assembly/utils/Arrays.ts index 3853efe..3f46268 100644 --- a/assembly/utils/Arrays.ts +++ b/assembly/utils/Arrays.ts @@ -19,4 +19,16 @@ export namespace ArrayUtils { } return true; } + + /** + * Returns new Array from Uint8 Typed array + * @param typedArr + */ + export function toU8Array(typedArr: Uint8Array): u8[] { + let res = new Array(2); + for (let i = 0; i < typedArr.length; i++) { + res[i] = typedArr[i]; + } + return res; + } } \ No newline at end of file From 2a244438d31ce157442e8be6b2f7d9dbbdb74804 Mon Sep 17 00:00:00 2001 From: Dastan Date: Fri, 5 Mar 2021 10:24:52 +0200 Subject: [PATCH 2/2] Fix array util --- assembly/utils/Arrays.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assembly/utils/Arrays.ts b/assembly/utils/Arrays.ts index 3f46268..9201af5 100644 --- a/assembly/utils/Arrays.ts +++ b/assembly/utils/Arrays.ts @@ -25,9 +25,9 @@ export namespace ArrayUtils { * @param typedArr */ export function toU8Array(typedArr: Uint8Array): u8[] { - let res = new Array(2); + let res: u8[] = []; for (let i = 0; i < typedArr.length; i++) { - res[i] = typedArr[i]; + res.push(typedArr[i]); } return res; }