Skip to content

Commit 9982786

Browse files
Merge pull request #63 from LimeChain/fix/u128
Fix UInt128
2 parents 3c7f3e4 + 2a24443 commit 9982786

File tree

6 files changed

+155
-186
lines changed

6 files changed

+155
-186
lines changed

assembly/Arrays/UInt128Array.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export class UInt128Array extends AbstractArray<UInt128, u128> {
2525
/**
2626
* @description BoolArray elements decryption implementation
2727
*/
28-
public decodeElement (value: u8[]): DecodedData<u128> {
29-
const u128Instance = UInt128.fromU8a(value);
28+
public decodeElement(value: u8[]): DecodedData<u128> {
29+
const u128Instance = UInt128.fromU8a(value.slice(0, BIT_LENGTH.INT_128));
3030

3131
return new DecodedData<u128>(
3232
u128Instance.unwrap(),
@@ -43,7 +43,7 @@ export class UInt128Array extends AbstractArray<UInt128, u128> {
4343
const bytesReader = new BytesReader(bytes.slice(index));
4444
const data = bytesReader.readInto<CompactInt>();
4545
for(let i: i32 = 0; i < data.unwrap(); i++){
46-
const element: UInt128 = bytesReader.readInto<UInt128>();
46+
const element: UInt128 = BytesReader.decodeInto<UInt128>(bytesReader.readBytes(BIT_LENGTH.INT_128));
4747
this.values.push(element.unwrap());
4848
}
4949
}

assembly/UInt/UInt128.ts

Lines changed: 10 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@
1414

1515
import { u128 } from "as-bignum";
1616
import { UnwrappableCodec } from "../interfaces/UnwrappableCodec";
17-
import { BIT_LENGTH, Bytes } from "../utils/Bytes";
17+
import { ArrayUtils } from "../utils/Arrays";
18+
import { BIT_LENGTH } from "../utils/Bytes";
1819

1920
/** Representation for a UInt128 value in the system. */
2021
export class UInt128 implements UnwrappableCodec<u128> {
2122

2223
private _value: u128;
23-
protected bitLength: i32;
2424

2525
constructor (value: u128 = u128.Zero) {
2626
this._value = value;
27-
this.bitLength = UInt128._computeBitLength(value);
2827
}
2928

3029
/**
@@ -34,30 +33,13 @@ export class UInt128 implements UnwrappableCodec<u128> {
3433
return this._value;
3534
}
3635

37-
/** Encodes the value as u8[] as per the SCALE codec specification */
36+
/**
37+
* @description Encodes the value as u8[] as per the SCALE codec specification
38+
* */
3839
toU8a (): u8[] {
39-
const bytes = new Array<u8>();
40-
if (this._value < u128.fromU32(1 << 6)) { // if value < 1 << 6
41-
Bytes.appendUint<u8>(bytes, u8(this._value.as<u8>()) << 2, BIT_LENGTH.INT_8); // 1 byte
42-
} else if (this._value < u128.fromU32(1 << 14)) { // if value < 1 << 14
43-
Bytes.appendUint<u16>(bytes, u16(this._value.as<u16>() << 2) + 1, BIT_LENGTH.INT_16); // 2 bytes
44-
} else if (this._value < u128.fromU64(1 << 30)) { // if value < 1 << 30
45-
Bytes.appendUint<u32>(bytes, u32(this._value.as<u32>() << 2) + 2, BIT_LENGTH.INT_32); // 4 bytes
46-
} else {
47-
const valueInBytes = this._value.toBytes();
48-
Bytes.trimEmptyBytes(valueInBytes);
49-
50-
const topSixBits: u8 = u8(valueInBytes.length - 4);
51-
const lengthByte: u8 = (topSixBits << 2) + 3;
52-
53-
// Encode Mode and Bytes length
54-
bytes.push(lengthByte);
55-
// copy the u128 bytes
56-
Bytes.copy(valueInBytes, bytes, 1);
57-
}
58-
return bytes;
40+
return ArrayUtils.toU8Array(this._value.toUint8Array(false));
5941
}
60-
42+
6143
toString(): string {
6244
return this._value.toString();
6345
}
@@ -68,54 +50,19 @@ export class UInt128 implements UnwrappableCodec<u128> {
6850
*/
6951
populateFromBytes(bytes: u8[], index: i32 = 0): void{
7052
assert(bytes.length - index > 0, 'Invalid input: Byte array should not be empty');
71-
const value = UInt128._computeValue(bytes, index);
72-
this._value = value;
73-
this.bitLength = UInt128._computeBitLength(this._value);
53+
this._value = u128.fromBytesLE(bytes.slice(index));
7454
}
7555
/**
7656
* @description The length of Int when the value is encoded
7757
*/
7858
public encodedLength (): i32 {
79-
return this.bitLength;
80-
}
81-
82-
/**
83-
* Internal static private function to compute value of the UInt128
84-
* @param bytes
85-
* @param index
86-
*/
87-
static _computeValue(bytes: u8[], index: i32 = 0): u128{
88-
const mode = bytes[index] & 0x03;
89-
if (i32(mode) <= 2) {
90-
return new u128(u64(Bytes.decodeSmallInt(bytes, mode, index).value), 0);
91-
}
92-
const topSixBits = bytes[index] >> 2;
93-
const byteLength = topSixBits + 4;
94-
95-
const value = bytes.slice(index + 1, byteLength + index + 1);
96-
Bytes.appendZeroBytes(value, BIT_LENGTH.INT_128);
97-
return u128.fromBytesLE(value)
98-
}
99-
100-
/**
101-
* Internal private function to compute bit length of the value
102-
* @param value
103-
*/
104-
static _computeBitLength(value: u128): i32 {
105-
if (value < u128.fromU32(1 << 6)) return BIT_LENGTH.INT_8;
106-
else if (value < u128.fromU32(1 << 14)) return BIT_LENGTH.INT_16;
107-
else if (value < u128.fromU32(1 << 30)) return BIT_LENGTH.INT_32;
108-
else {
109-
const valueInBytes = value.toBytes();
110-
Bytes.trimEmptyBytes(valueInBytes);
111-
return 1 + valueInBytes.length;
112-
}
59+
return BIT_LENGTH.INT_128;
11360
}
11461

11562
/** Instantiates new UInt128 from u8[] SCALE encoded bytes */
11663
static fromU8a(input: u8[], index: i32 = 0): UInt128 {
11764
assert(input.length - index != 0, 'Invalid input: Byte array should not be empty');
118-
return new UInt128(UInt128._computeValue(input, index));
65+
return new UInt128(u128.fromBytesLE(input.slice(index)));
11966
}
12067

12168
eq(other: UInt128): bool {

assembly/__tests__/Arrays/UInt128Array.spec.ts

Lines changed: 62 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,35 @@
1-
import { UInt128Array } from "../../Arrays/UInt128Array";
21
import { u128 } from "as-bignum";
3-
import {UInt128} from "../../UInt/UInt128";
2+
import { UInt128Array } from "../../Arrays/UInt128Array";
43

54
describe("UInt128Array", () => {
65

76
it("should encode uint128 array", () => {
87
const dataInput: Array<Array<u128>> = [
9-
[u128.One], // Expected output: [0x04, 0x04]
10-
[u128.fromU32(1), u128.fromU32(2), u128.fromU32(3), u128.fromU32(4)], // Expected output: [0x10, 0x04, 0x08, 0x0c, 0x10]
11-
[u128.fromU32(16384), u128.fromU32(2), u128.fromU32(3), u128.fromU32(4)], // Expected output: [0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10]
12-
[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)],
13-
[u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615)],
8+
[u128.One],
9+
[u128.fromString('54321')],
10+
[u128.fromU32(20001), u128.fromU32(123456)],
11+
[
12+
u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'),
13+
u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345')
14+
],
15+
[u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max],
1416
[u128.Max - u128.fromU64(u64.MAX_VALUE)]
1517
];
1618

1719
const expectedOutput: Array<Array<u8>> = [
18-
[0x04, 0x04],
19-
[0x10, 0x04, 0x08, 0x0c, 0x10],
20-
[0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10],
21-
[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],
22-
[0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
23-
[0x04, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
20+
[4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1]
21+
[4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321
22+
[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]
23+
[
24+
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,
25+
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,
26+
121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0
27+
],
28+
[
29+
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,
30+
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
31+
],
32+
[4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255]
2433
];
2534

2635
for (let i = 0; i < dataInput.length; i++) {
@@ -31,20 +40,30 @@ describe("UInt128Array", () => {
3140

3241
it("should decode uint128 array", () => {
3342
const dataInput: Array<Array<u8>> = [
34-
[0x04, 0x04], // Expected output: [1]
35-
[0x10, 0x04, 0x08, 0x0c, 0x10], // Expected output: [1, 2, 3, 4]
36-
[0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], // Expected output: [16384, 2, 3, 4]
37-
[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],
38-
[0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
39-
[0x04, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
43+
[4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1]
44+
[4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321
45+
[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]
46+
[
47+
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,
48+
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,
49+
121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0
50+
],
51+
[
52+
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,
53+
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
54+
],
55+
[4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255]
4056
];
4157

4258
const expectedOutput: Array<Array<u128>> = [
4359
[u128.One],
44-
[u128.One, u128.fromU64(2), u128.fromU64(3), u128.fromU64(4)],
45-
[u128.fromU64(16384), u128.fromU64(2), u128.fromU64(3), u128.fromU64(4)],
46-
[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)],
47-
[u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615)],
60+
[u128.fromString('54321')],
61+
[u128.fromU32(20001), u128.fromU32(123456)],
62+
[
63+
u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'),
64+
u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345')
65+
],
66+
[u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max],
4867
[u128.Max - u128.fromU64(u64.MAX_VALUE)]
4968
];
5069

@@ -56,19 +75,29 @@ describe("UInt128Array", () => {
5675

5776
it("should decode uint128 array with populate method", () => {
5877
const dataInput: Array<Array<u8>> = [
59-
[0x04, 0x04], // Expected output: [1]
60-
[0x10, 0x04, 0x0c, 0x0c, 0x10], // Expected output: [1, 3, 3, 4]
61-
[0x10, 0x02, 0x00, 0x01, 0x00, 0x08, 0x0c, 0x10], // Expected output: [16384, 2, 3, 4]
62-
[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],
63-
[0x08, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x13, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
64-
[0x04, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]
78+
[4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: [1]
79+
[4, 49, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // Expected output: 54321
80+
[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]
81+
[
82+
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,
83+
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,
84+
121, 223, 226, 61, 68, 166, 54, 15, 110, 5, 1, 0, 0, 0, 0, 0
85+
],
86+
[
87+
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,
88+
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
89+
],
90+
[4, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255]
6591
];
6692
const expectedOutput: Array<Array<u128>> = [
6793
[u128.One],
68-
[u128.One, u128.fromU64(3), u128.fromU64(3), u128.fromU64(4)],
69-
[u128.fromU64(16384), u128.fromU64(2), u128.fromU64(3), u128.fromU64(4)],
70-
[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)],
71-
[u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615)],
94+
[u128.fromString('54321')],
95+
[u128.fromU32(20001), u128.fromU32(123456)],
96+
[
97+
u128.fromU32(1), u128.fromU64(123456789), u128.fromString('123456789012345'),
98+
u128.fromString('12345678901234567890'), u128.fromString('1234567890123456789012345')
99+
],
100+
[u128.fromU64(18446744073709551615), u128.fromU64(18446744073709551615), u128.Max],
72101
[u128.Max - u128.fromU64(u64.MAX_VALUE)]
73102
];
74103

assembly/__tests__/ScaleMap.spec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,15 @@ describe("String", () => {
4646

4747
const map2U8a: u8[] = [
4848
8,
49-
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,
50-
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
49+
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,
50+
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51+
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,
52+
64, 226, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
5153
];
5254
const decodedMap2 = BytesReader.decodeInto<ScaleMap<Hash, UInt128>>(map2U8a);
5355
const scaleMap2 = new ScaleMap<Hash, UInt128>();
54-
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")));
55-
scaleMap2.set(new Hash([0xff, 0x00, 0xab]), new UInt128(u128.fromString("18446744073709551615")));
56+
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)));
57+
scaleMap2.set(new Hash([0xff, 0x00, 0xab]), new UInt128(u128.fromU32(123456)));
5658
expect<bool>(decodedMap2.eq(scaleMap2)).toStrictEqual(true);
5759
})
5860
})

0 commit comments

Comments
 (0)