@typeberry/jam 0.1.0-3c30204 → 0.1.0-b2d0b72
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/block-generator/index.js +210 -125
- package/block-generator/index.js.map +1 -1
- package/importer/index.js +217 -132
- package/importer/index.js.map +1 -1
- package/index.js +217 -132
- package/index.js.map +1 -1
- package/jam-network/index.js +137 -93
- package/jam-network/index.js.map +1 -1
- package/package.json +1 -1
package/block-generator/index.js
CHANGED
|
@@ -3664,29 +3664,17 @@ function isBrowser() {
|
|
|
3664
3664
|
* We avoid using `node:assert` to keep compatibility with a browser environment.
|
|
3665
3665
|
* Note the checks should not have any side effects, since we might decide
|
|
3666
3666
|
* to remove all of them in a post-processing step.
|
|
3667
|
-
*/
|
|
3668
|
-
function debug_check(condition, message) {
|
|
3669
|
-
if (!condition) {
|
|
3670
|
-
throw new Error(`Assertion failure: ${message ?? ""}`);
|
|
3671
|
-
}
|
|
3672
|
-
}
|
|
3673
|
-
function cast(_a, condition) {
|
|
3674
|
-
return condition;
|
|
3675
|
-
}
|
|
3676
|
-
/**
|
|
3677
|
-
* Yet another function to perform runtime assertions.
|
|
3678
|
-
* This function returns a new type to mark in the code that this value was checked and you don't have to do it again.
|
|
3679
3667
|
*
|
|
3680
|
-
*
|
|
3681
|
-
*
|
|
3682
|
-
* should be replaced with:
|
|
3683
|
-
* const x = y as CheckedNumber;
|
|
3668
|
+
* NOTE the function is intended to be used as tagged template string for the performance
|
|
3669
|
+
* reasons.
|
|
3684
3670
|
*/
|
|
3685
|
-
function
|
|
3686
|
-
if (
|
|
3687
|
-
|
|
3671
|
+
function debug_check(strings, condition, ...data) {
|
|
3672
|
+
if (!condition) {
|
|
3673
|
+
// add an empty value so that `data.length === strings.length`
|
|
3674
|
+
data.unshift("");
|
|
3675
|
+
const message = strings.map((v, index) => `${v}${data[index] ?? ""}`);
|
|
3676
|
+
throw new Error(`Assertion failure:${message.join("")}`);
|
|
3688
3677
|
}
|
|
3689
|
-
throw new Error(`Assertion failure: ${message ?? ""}`);
|
|
3690
3678
|
}
|
|
3691
3679
|
/**
|
|
3692
3680
|
* The function can be used to make sure that a particular type is `never`
|
|
@@ -3856,7 +3844,7 @@ function resultToString(res) {
|
|
|
3856
3844
|
const result_Result = {
|
|
3857
3845
|
/** Create new [`Result`] with `Ok` status. */
|
|
3858
3846
|
ok: (ok) => {
|
|
3859
|
-
debug_check
|
|
3847
|
+
debug_check `${ok !== undefined} 'ok' type cannot be undefined.`;
|
|
3860
3848
|
return {
|
|
3861
3849
|
isOk: true,
|
|
3862
3850
|
isError: false,
|
|
@@ -3865,7 +3853,7 @@ const result_Result = {
|
|
|
3865
3853
|
},
|
|
3866
3854
|
/** Create new [`Result`] with `Error` status. */
|
|
3867
3855
|
error: (error, details = "") => {
|
|
3868
|
-
debug_check
|
|
3856
|
+
debug_check `${error !== undefined} 'Error' type cannot be undefined.`;
|
|
3869
3857
|
return {
|
|
3870
3858
|
isOk: false,
|
|
3871
3859
|
isError: true,
|
|
@@ -4149,7 +4137,10 @@ class bitvec_BitVec {
|
|
|
4149
4137
|
constructor(data, bitLength) {
|
|
4150
4138
|
this.data = data;
|
|
4151
4139
|
this.bitLength = bitLength;
|
|
4152
|
-
debug_check
|
|
4140
|
+
debug_check `
|
|
4141
|
+
${data.length * 8 >= bitLength}
|
|
4142
|
+
Not enough bytes in the data array. Need ${data.length * 8} has ${bitLength}.
|
|
4143
|
+
`;
|
|
4153
4144
|
this.byteLength = Math.ceil(bitLength / 8);
|
|
4154
4145
|
}
|
|
4155
4146
|
/** Return a raw in-memory representation of this [`BitVec`]. */
|
|
@@ -4158,7 +4149,10 @@ class bitvec_BitVec {
|
|
|
4158
4149
|
}
|
|
4159
4150
|
/** Perform OR operation on all bits in place. */
|
|
4160
4151
|
sumWith(other) {
|
|
4161
|
-
debug_check
|
|
4152
|
+
debug_check `
|
|
4153
|
+
${other.bitLength === this.bitLength}
|
|
4154
|
+
Invalid bit length for sumWith: ${other.bitLength} vs ${this.bitLength}
|
|
4155
|
+
`;
|
|
4162
4156
|
const otherRaw = other.raw;
|
|
4163
4157
|
for (let i = 0; i < this.byteLength; i++) {
|
|
4164
4158
|
this.data[i] |= otherRaw[i];
|
|
@@ -4168,7 +4162,7 @@ class bitvec_BitVec {
|
|
|
4168
4162
|
* Set the bit at index `idx` to value `val`.
|
|
4169
4163
|
*/
|
|
4170
4164
|
setBit(idx, val) {
|
|
4171
|
-
debug_check
|
|
4165
|
+
debug_check `${idx >= 0 && idx < this.bitLength} Index out of bounds. Need ${idx} has ${this.bitLength}.`;
|
|
4172
4166
|
const byteIndex = Math.floor(idx / 8);
|
|
4173
4167
|
const bitIndexInByte = idx % 8;
|
|
4174
4168
|
const mask = 1 << bitIndexInByte;
|
|
@@ -4183,7 +4177,7 @@ class bitvec_BitVec {
|
|
|
4183
4177
|
* Return `true` if the bit at index `idx` is set.
|
|
4184
4178
|
*/
|
|
4185
4179
|
isSet(idx) {
|
|
4186
|
-
debug_check
|
|
4180
|
+
debug_check `${idx >= 0 && idx < this.bitLength} Index out of bounds. Need ${idx} has ${this.bitLength}.`;
|
|
4187
4181
|
const byteIndex = Math.floor(idx / 8);
|
|
4188
4182
|
const bitIndexInByte = idx % 8;
|
|
4189
4183
|
const mask = 1 << bitIndexInByte;
|
|
@@ -4350,7 +4344,7 @@ class bytes_BytesBlob {
|
|
|
4350
4344
|
}
|
|
4351
4345
|
/** Create a new [`BytesBlob`] from an array of bytes. */
|
|
4352
4346
|
static blobFromNumbers(v) {
|
|
4353
|
-
debug_check
|
|
4347
|
+
debug_check `${v.find((x) => (x & 0xff) !== x) === undefined} BytesBlob.blobFromNumbers used with non-byte number array.`;
|
|
4354
4348
|
const arr = new Uint8Array(v);
|
|
4355
4349
|
return new bytes_BytesBlob(arr);
|
|
4356
4350
|
}
|
|
@@ -4394,7 +4388,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
4394
4388
|
length;
|
|
4395
4389
|
constructor(raw, len) {
|
|
4396
4390
|
super(raw);
|
|
4397
|
-
debug_check
|
|
4391
|
+
debug_check `${raw.byteLength === len} Given buffer has incorrect size ${raw.byteLength} vs expected ${len}`;
|
|
4398
4392
|
this.length = len;
|
|
4399
4393
|
}
|
|
4400
4394
|
/** Create new [`Bytes<X>`] given a backing buffer and it's length. */
|
|
@@ -4403,7 +4397,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
4403
4397
|
}
|
|
4404
4398
|
/** Create new [`Bytes<X>`] given an array of bytes and it's length. */
|
|
4405
4399
|
static fromNumbers(v, len) {
|
|
4406
|
-
debug_check
|
|
4400
|
+
debug_check `${v.find((x) => (x & 0xff) !== x) === undefined} Bytes.fromNumbers used with non-byte number array.`;
|
|
4407
4401
|
const x = new Uint8Array(v);
|
|
4408
4402
|
return new bytes_Bytes(x, len);
|
|
4409
4403
|
}
|
|
@@ -4414,7 +4408,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
4414
4408
|
// TODO [ToDr] `fill` should have the argments swapped to align with the rest.
|
|
4415
4409
|
/** Create a [`Bytes<X>`] with all bytes filled with given input number. */
|
|
4416
4410
|
static fill(len, input) {
|
|
4417
|
-
debug_check(
|
|
4411
|
+
debug_check `${(input & 0xff) === input} Input has to be a byte.`;
|
|
4418
4412
|
const bytes = bytes_Bytes.zero(len);
|
|
4419
4413
|
bytes.raw.fill(input, 0, len);
|
|
4420
4414
|
return bytes;
|
|
@@ -4437,7 +4431,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
4437
4431
|
}
|
|
4438
4432
|
/** Compare the sequence to another one. */
|
|
4439
4433
|
isEqualTo(other) {
|
|
4440
|
-
debug_check
|
|
4434
|
+
debug_check `${this.length === other.length} Comparing incorrectly typed bytes!`;
|
|
4441
4435
|
return u8ArraySameLengthEqual(this.raw, other.raw);
|
|
4442
4436
|
}
|
|
4443
4437
|
/** Converts current type into some opaque extension. */
|
|
@@ -4446,7 +4440,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
4446
4440
|
}
|
|
4447
4441
|
}
|
|
4448
4442
|
function byteFromString(s) {
|
|
4449
|
-
debug_check
|
|
4443
|
+
debug_check `${s.length === 2} Two-character string expected`;
|
|
4450
4444
|
const a = numberFromCharCode(s.charCodeAt(0));
|
|
4451
4445
|
const b = numberFromCharCode(s.charCodeAt(1));
|
|
4452
4446
|
return (a << 4) | b;
|
|
@@ -4500,42 +4494,53 @@ const bytesBlobComparator = (a, b) => a.compare(b);
|
|
|
4500
4494
|
|
|
4501
4495
|
;// CONCATENATED MODULE: ./packages/core/numbers/index.ts
|
|
4502
4496
|
|
|
4503
|
-
const
|
|
4497
|
+
const asTypedNumber = (v) => v;
|
|
4504
4498
|
const MAX_VALUE_U8 = 0xff;
|
|
4505
4499
|
const MAX_VALUE_U16 = 0xffff;
|
|
4506
4500
|
const MAX_VALUE_U32 = 0xffff_ffff;
|
|
4507
4501
|
const MAX_VALUE_U64 = 0xffffffffffffffffn;
|
|
4508
4502
|
/** Attempt to cast an input number into U8. */
|
|
4509
|
-
const numbers_tryAsU8 = (v) =>
|
|
4503
|
+
const numbers_tryAsU8 = (v) => {
|
|
4504
|
+
debug_check `${isU8(v)} input must have one-byte representation, got ${v}`;
|
|
4505
|
+
return asTypedNumber(v);
|
|
4506
|
+
};
|
|
4510
4507
|
/** Check if given number is a valid U8 number. */
|
|
4511
4508
|
const isU8 = (v) => (v & MAX_VALUE_U8) === v;
|
|
4512
4509
|
/** Attempt to cast an input number into U16. */
|
|
4513
|
-
const numbers_tryAsU16 = (v) =>
|
|
4510
|
+
const numbers_tryAsU16 = (v) => {
|
|
4511
|
+
debug_check `${isU16(v)} input must have two-byte representation, got ${v}`;
|
|
4512
|
+
return asTypedNumber(v);
|
|
4513
|
+
};
|
|
4514
4514
|
/** Check if given number is a valid U16 number. */
|
|
4515
4515
|
const isU16 = (v) => (v & MAX_VALUE_U16) === v;
|
|
4516
4516
|
/** Attempt to cast an input number into U32. */
|
|
4517
|
-
const numbers_tryAsU32 = (v) =>
|
|
4517
|
+
const numbers_tryAsU32 = (v) => {
|
|
4518
|
+
debug_check `${isU32(v)} input must have four-byte representation, got ${v}`;
|
|
4519
|
+
return asTypedNumber(v);
|
|
4520
|
+
};
|
|
4518
4521
|
/** Check if given number is a valid U32 number. */
|
|
4519
4522
|
const isU32 = (v) => (v & MAX_VALUE_U32) >>> 0 === v;
|
|
4520
4523
|
/** Attempt to cast an input number into U64. */
|
|
4521
4524
|
const numbers_tryAsU64 = (x) => {
|
|
4522
4525
|
const v = BigInt(x);
|
|
4523
|
-
|
|
4526
|
+
debug_check `${isU64(v)} input must have eight-byte representation, got ${x}`;
|
|
4527
|
+
return asTypedNumber(v);
|
|
4524
4528
|
};
|
|
4525
4529
|
/** Check if given number is a valid U64 number. */
|
|
4526
4530
|
const isU64 = (v) => (v & MAX_VALUE_U64) === v;
|
|
4527
4531
|
/** Collate two U32 parts into one U64. */
|
|
4528
4532
|
const u64FromParts = ({ lower, upper }) => {
|
|
4529
4533
|
const val = (BigInt(upper) << 32n) + BigInt(lower);
|
|
4530
|
-
return
|
|
4534
|
+
return asTypedNumber(val);
|
|
4531
4535
|
};
|
|
4532
4536
|
/** Split U64 into lower & upper parts. */
|
|
4533
4537
|
const numbers_u64IntoParts = (v) => {
|
|
4534
|
-
|
|
4535
|
-
const
|
|
4538
|
+
// Number(...) safe: both parts are <= 0xffffffff
|
|
4539
|
+
const lower = Number(v & (2n ** 32n - 1n));
|
|
4540
|
+
const upper = Number(v >> 32n);
|
|
4536
4541
|
return {
|
|
4537
|
-
lower:
|
|
4538
|
-
upper:
|
|
4542
|
+
lower: asTypedNumber(lower),
|
|
4543
|
+
upper: asTypedNumber(upper),
|
|
4539
4544
|
};
|
|
4540
4545
|
};
|
|
4541
4546
|
/**
|
|
@@ -4575,8 +4580,8 @@ function numbers_u32AsLeBytes(value) {
|
|
|
4575
4580
|
* Interpret 4-byte `Uint8Array` as U32 written as little endian.
|
|
4576
4581
|
*/
|
|
4577
4582
|
function leBytesAsU32(uint8Array) {
|
|
4578
|
-
check
|
|
4579
|
-
return
|
|
4583
|
+
check `${uint8Array.length === 4} Input must be a Uint8Array of length 4`;
|
|
4584
|
+
return asTypedNumber(uint8Array[0] | (uint8Array[1] << 8) | (uint8Array[2] << 16) | (uint8Array[3] << 24));
|
|
4580
4585
|
}
|
|
4581
4586
|
/** Get the smallest value between U64 a and values given as input parameters. */
|
|
4582
4587
|
const minU64 = (a, ...values) => values.reduce((min, value) => (value > min ? min : value), a);
|
|
@@ -4867,7 +4872,7 @@ class decoder_Decoder {
|
|
|
4867
4872
|
this.skip(newOffset - this.offset);
|
|
4868
4873
|
}
|
|
4869
4874
|
else {
|
|
4870
|
-
debug_check
|
|
4875
|
+
debug_check `${newOffset >= 0} The offset has to be positive`;
|
|
4871
4876
|
this.offset = newOffset;
|
|
4872
4877
|
}
|
|
4873
4878
|
}
|
|
@@ -4895,7 +4900,7 @@ class decoder_Decoder {
|
|
|
4895
4900
|
return num;
|
|
4896
4901
|
}
|
|
4897
4902
|
ensureHasBytes(bytes) {
|
|
4898
|
-
debug_check
|
|
4903
|
+
debug_check `${bytes >= 0} Negative number of bytes given.`;
|
|
4899
4904
|
if (this.offset + bytes > this.source.length) {
|
|
4900
4905
|
throw new Error(`Attempting to decode more data than there is left. Need ${bytes}, left: ${this.source.length - this.offset}.`);
|
|
4901
4906
|
}
|
|
@@ -4903,7 +4908,7 @@ class decoder_Decoder {
|
|
|
4903
4908
|
}
|
|
4904
4909
|
const MASKS = [0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80];
|
|
4905
4910
|
function decodeVariableLengthExtraBytes(firstByte) {
|
|
4906
|
-
debug_check
|
|
4911
|
+
debug_check `${firstByte >= 0 && firstByte < 256} Incorrect byte value: ${firstByte}`;
|
|
4907
4912
|
for (let i = 0; i < MASKS.length; i++) {
|
|
4908
4913
|
if (firstByte >= MASKS[i]) {
|
|
4909
4914
|
return 8 - i;
|
|
@@ -5058,7 +5063,7 @@ class descriptor_Descriptor {
|
|
|
5058
5063
|
|
|
5059
5064
|
|
|
5060
5065
|
function tryAsExactBytes(a) {
|
|
5061
|
-
check
|
|
5066
|
+
check `${a.isExact} The value is not exact size estimation!`;
|
|
5062
5067
|
return a.bytes;
|
|
5063
5068
|
}
|
|
5064
5069
|
function addSizeHints(a, b) {
|
|
@@ -5165,8 +5170,8 @@ class encoder_Encoder {
|
|
|
5165
5170
|
// we still allow positive numbers from `[maxNum / 2, maxNum)`.
|
|
5166
5171
|
// So it does not matter if the argument is a negative value,
|
|
5167
5172
|
// OR if someone just gave us two-complement already.
|
|
5168
|
-
debug_check
|
|
5169
|
-
debug_check
|
|
5173
|
+
debug_check `${num < maxNum} Only for numbers up to 2**64 - 1`;
|
|
5174
|
+
debug_check `${-num <= maxNum / 2n} Only for numbers down to -2**63`;
|
|
5170
5175
|
this.ensureBigEnough(8);
|
|
5171
5176
|
this.dataView.setBigInt64(this.offset, num, true);
|
|
5172
5177
|
this.offset += 8;
|
|
@@ -5230,8 +5235,8 @@ class encoder_Encoder {
|
|
|
5230
5235
|
// we still allow positive numbers from `[maxNum / 2, maxNum)`.
|
|
5231
5236
|
// So it does not matter if the argument is a negative value,
|
|
5232
5237
|
// OR if someone just gave us two-complement already.
|
|
5233
|
-
debug_check
|
|
5234
|
-
debug_check
|
|
5238
|
+
debug_check `${num < maxNum} Only for numbers up to 2**${BITS * bytesToEncode} - 1`;
|
|
5239
|
+
debug_check `${-num <= maxNum / 2} Only for numbers down to -2**${BITS * bytesToEncode - 1}`;
|
|
5235
5240
|
this.ensureBigEnough(bytesToEncode);
|
|
5236
5241
|
}
|
|
5237
5242
|
/**
|
|
@@ -5242,8 +5247,8 @@ class encoder_Encoder {
|
|
|
5242
5247
|
* https://graypaper.fluffylabs.dev/#/579bd12/365202365202
|
|
5243
5248
|
*/
|
|
5244
5249
|
varU32(num) {
|
|
5245
|
-
debug_check
|
|
5246
|
-
debug_check
|
|
5250
|
+
debug_check `${num >= 0} Only for natural numbers.`;
|
|
5251
|
+
debug_check `${num < 2 ** 32} Only for numbers up to 2**32`;
|
|
5247
5252
|
this.varU64(BigInt(num));
|
|
5248
5253
|
}
|
|
5249
5254
|
/**
|
|
@@ -5394,7 +5399,7 @@ class encoder_Encoder {
|
|
|
5394
5399
|
* https://graypaper.fluffylabs.dev/#/579bd12/374400374400
|
|
5395
5400
|
*/
|
|
5396
5401
|
sequenceVarLen(encode, elements) {
|
|
5397
|
-
debug_check
|
|
5402
|
+
debug_check `${elements.length <= 2 ** 32} Wow, that's a nice long sequence you've got here.`;
|
|
5398
5403
|
this.varU32(numbers_tryAsU32(elements.length));
|
|
5399
5404
|
this.sequenceFixLen(encode, elements);
|
|
5400
5405
|
}
|
|
@@ -5415,7 +5420,7 @@ class encoder_Encoder {
|
|
|
5415
5420
|
* anyway, so if we really should throw we will.
|
|
5416
5421
|
*/
|
|
5417
5422
|
ensureBigEnough(length, options = { silent: false }) {
|
|
5418
|
-
debug_check
|
|
5423
|
+
debug_check `${length >= 0} Negative length given`;
|
|
5419
5424
|
const newLength = this.offset + length;
|
|
5420
5425
|
if (newLength > MAX_LENGTH) {
|
|
5421
5426
|
if (options.silent) {
|
|
@@ -5551,10 +5556,12 @@ class ObjectView {
|
|
|
5551
5556
|
decodeUpTo(field) {
|
|
5552
5557
|
const index = this.descriptorsKeys.indexOf(field);
|
|
5553
5558
|
const lastField = this.descriptorsKeys[this.lastDecodedFieldIdx];
|
|
5554
|
-
debug_check
|
|
5559
|
+
debug_check `
|
|
5560
|
+
${this.lastDecodedFieldIdx < index}
|
|
5561
|
+
Unjustified call to 'decodeUpTo' -
|
|
5555
5562
|
the index ($Blobindex}, ${String(field)})
|
|
5556
5563
|
is already decoded (${this.lastDecodedFieldIdx}, ${String(lastField)}).
|
|
5557
|
-
|
|
5564
|
+
`;
|
|
5558
5565
|
let lastItem = this.cache.get(lastField);
|
|
5559
5566
|
const skipper = new Skipper(this.decoder);
|
|
5560
5567
|
// now skip all of the fields and further populate the cache.
|
|
@@ -5570,8 +5577,10 @@ class ObjectView {
|
|
|
5570
5577
|
this.cache.set(field, lastItem);
|
|
5571
5578
|
this.lastDecodedFieldIdx = i;
|
|
5572
5579
|
}
|
|
5573
|
-
|
|
5574
|
-
|
|
5580
|
+
if (lastItem === undefined) {
|
|
5581
|
+
throw new Error("Last item must be set, since the loop turns at least once.");
|
|
5582
|
+
}
|
|
5583
|
+
return lastItem;
|
|
5575
5584
|
}
|
|
5576
5585
|
}
|
|
5577
5586
|
/**
|
|
@@ -5604,8 +5613,10 @@ class SequenceView {
|
|
|
5604
5613
|
*[Symbol.iterator]() {
|
|
5605
5614
|
for (let i = 0; i < this.length; i++) {
|
|
5606
5615
|
const val = this.get(i);
|
|
5607
|
-
|
|
5608
|
-
|
|
5616
|
+
if (val === undefined) {
|
|
5617
|
+
throw new Error("We are within 0..this.length so all items are defined.");
|
|
5618
|
+
}
|
|
5619
|
+
yield val;
|
|
5609
5620
|
}
|
|
5610
5621
|
}
|
|
5611
5622
|
/** Create an array of all views mapped to some particular value. */
|
|
@@ -5648,7 +5659,10 @@ class SequenceView {
|
|
|
5648
5659
|
return bytes_BytesBlob.blobFrom(this.decoder.source.subarray(this.initialDecoderOffset, this.decoder.bytesRead()));
|
|
5649
5660
|
}
|
|
5650
5661
|
decodeUpTo(index) {
|
|
5651
|
-
debug_check
|
|
5662
|
+
debug_check `
|
|
5663
|
+
${this.lastDecodedIdx < index}
|
|
5664
|
+
Unjustified call to 'decodeUpTo' - the index (${index}) is already decoded (${this.lastDecodedIdx}).
|
|
5665
|
+
`;
|
|
5652
5666
|
let lastItem = this.cache.get(this.lastDecodedIdx);
|
|
5653
5667
|
const skipper = new Skipper(this.decoder);
|
|
5654
5668
|
// now skip all of the fields and further populate the cache.
|
|
@@ -5663,8 +5677,10 @@ class SequenceView {
|
|
|
5663
5677
|
this.cache.set(i, lastItem);
|
|
5664
5678
|
this.lastDecodedIdx = i;
|
|
5665
5679
|
}
|
|
5666
|
-
|
|
5667
|
-
|
|
5680
|
+
if (lastItem === undefined) {
|
|
5681
|
+
throw new Error("Last item must be set, since the loop turns at least once.");
|
|
5682
|
+
}
|
|
5683
|
+
return lastItem;
|
|
5668
5684
|
}
|
|
5669
5685
|
}
|
|
5670
5686
|
|
|
@@ -5697,7 +5713,10 @@ const TYPICAL_DICTIONARY_LENGTH = 32;
|
|
|
5697
5713
|
*/
|
|
5698
5714
|
function readonlyArray(desc) {
|
|
5699
5715
|
return desc.convert((x) => {
|
|
5700
|
-
debug_check
|
|
5716
|
+
debug_check `
|
|
5717
|
+
${Array.isArray(x)}
|
|
5718
|
+
Non-arrays are not supported as 'readonly': got ${typeof x}, ${x}
|
|
5719
|
+
`;
|
|
5701
5720
|
// NOTE [ToDr] This assumption is incorrect in general, but it's documented
|
|
5702
5721
|
// in the general note. We avoid `.slice()` the array for performance reasons.
|
|
5703
5722
|
return x;
|
|
@@ -6652,10 +6671,17 @@ async function initAll() {
|
|
|
6652
6671
|
await init.ed25519();
|
|
6653
6672
|
await init.reedSolomon();
|
|
6654
6673
|
}
|
|
6674
|
+
function initOnce(doInit) {
|
|
6675
|
+
let ready = null;
|
|
6676
|
+
return async () => {
|
|
6677
|
+
if (ready === null) ready = doInit();
|
|
6678
|
+
return await ready;
|
|
6679
|
+
};
|
|
6680
|
+
}
|
|
6655
6681
|
const init = {
|
|
6656
|
-
bandersnatch: async () => await bandersnatch_default({ module_or_path: await bandersnatch_bg_default() }),
|
|
6657
|
-
ed25519: async () => await ed25519_wasm_default({ module_or_path: await ed25519_wasm_bg_default() }),
|
|
6658
|
-
reedSolomon: async () => await reed_solomon_wasm_default({ module_or_path: await reed_solomon_wasm_bg_default() })
|
|
6682
|
+
bandersnatch: initOnce(async () => await bandersnatch_default({ module_or_path: await bandersnatch_bg_default() })),
|
|
6683
|
+
ed25519: initOnce(async () => await ed25519_wasm_default({ module_or_path: await ed25519_wasm_bg_default() })),
|
|
6684
|
+
reedSolomon: initOnce(async () => await reed_solomon_wasm_default({ module_or_path: await reed_solomon_wasm_bg_default() }))
|
|
6659
6685
|
};
|
|
6660
6686
|
|
|
6661
6687
|
//#endregion
|
|
@@ -6677,7 +6703,7 @@ const BLS_KEY_BYTES = 144;
|
|
|
6677
6703
|
/** Derive a Bandersnatch public key from a seed. */
|
|
6678
6704
|
function bandersnatch_publicKey(seed) {
|
|
6679
6705
|
const key = bandersnatch.derive_public_key(seed);
|
|
6680
|
-
check
|
|
6706
|
+
check `${key[0] === 0} Invalid Bandersnatch public key derived from seed`;
|
|
6681
6707
|
return Bytes.fromBlob(key.subarray(1), BANDERSNATCH_KEY_BYTES).asOpaque();
|
|
6682
6708
|
}
|
|
6683
6709
|
|
|
@@ -6737,7 +6763,7 @@ async function verify(input) {
|
|
|
6737
6763
|
data.set(signature.raw, offset);
|
|
6738
6764
|
offset += ED25519_SIGNATURE_BYTES;
|
|
6739
6765
|
const messageLength = message.length;
|
|
6740
|
-
check
|
|
6766
|
+
check `${messageLength < 256} Message needs to be shorter than 256 bytes. Got: ${messageLength}`;
|
|
6741
6767
|
data[offset] = messageLength;
|
|
6742
6768
|
offset += 1;
|
|
6743
6769
|
data.set(message.raw, offset);
|
|
@@ -6821,7 +6847,7 @@ class PageAllocator {
|
|
|
6821
6847
|
// TODO [ToDr] Benchmark the performance!
|
|
6822
6848
|
constructor(hashesPerPage) {
|
|
6823
6849
|
this.hashesPerPage = hashesPerPage;
|
|
6824
|
-
check
|
|
6850
|
+
check `${hashesPerPage > 0 && hashesPerPage >>> 0 === hashesPerPage} Expected a non-zero integer.`;
|
|
6825
6851
|
this.resetPage();
|
|
6826
6852
|
}
|
|
6827
6853
|
resetPage() {
|
|
@@ -7120,8 +7146,8 @@ class MultiMap {
|
|
|
7120
7146
|
* if needed.
|
|
7121
7147
|
*/
|
|
7122
7148
|
constructor(keysLength, keyMappers) {
|
|
7123
|
-
check
|
|
7124
|
-
check
|
|
7149
|
+
check `${keysLength > 0} Keys cannot be empty.`;
|
|
7150
|
+
check `${keyMappers === undefined || keyMappers.length === keysLength} Incorrect number of key mappers given!`;
|
|
7125
7151
|
this.data = new Map();
|
|
7126
7152
|
this.keyMappers = keyMappers === undefined ? Array(keysLength).fill(null) : keyMappers;
|
|
7127
7153
|
}
|
|
@@ -7222,7 +7248,7 @@ class sized_array_FixedSizeArray extends Array {
|
|
|
7222
7248
|
this.fixedLength = this.length;
|
|
7223
7249
|
}
|
|
7224
7250
|
static new(data, len) {
|
|
7225
|
-
debug_check
|
|
7251
|
+
debug_check `${data.length === len} Expected an array of size: ${len}, got: ${data.length}`;
|
|
7226
7252
|
const arr = new sized_array_FixedSizeArray(len);
|
|
7227
7253
|
for (let i = 0; i < len; i++) {
|
|
7228
7254
|
arr[i] = data[i];
|
|
@@ -7356,7 +7382,7 @@ class SortedArray {
|
|
|
7356
7382
|
}
|
|
7357
7383
|
/** Create a new SortedSet from two sorted collections. */
|
|
7358
7384
|
static fromTwoSortedCollections(first, second) {
|
|
7359
|
-
debug_check
|
|
7385
|
+
debug_check `${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
7360
7386
|
const comparator = first.comparator;
|
|
7361
7387
|
const arr1 = first.array;
|
|
7362
7388
|
const arr1Length = arr1.length;
|
|
@@ -7476,7 +7502,7 @@ class SortedSet extends SortedArray {
|
|
|
7476
7502
|
}
|
|
7477
7503
|
/** Create a new SortedSet from two sorted collections. */
|
|
7478
7504
|
static fromTwoSortedCollections(first, second) {
|
|
7479
|
-
debug_check
|
|
7505
|
+
debug_check `${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
7480
7506
|
const comparator = first.comparator;
|
|
7481
7507
|
if (first.length === 0) {
|
|
7482
7508
|
return SortedSet.fromSortedArray(comparator, second.array);
|
|
@@ -8114,7 +8140,10 @@ const common_tryAsCoreIndex = (v) => opaque_asOpaqueType(numbers_tryAsU16(v));
|
|
|
8114
8140
|
/** Attempt to convert a number into `Epoch`. */
|
|
8115
8141
|
const tryAsEpoch = (v) => asOpaqueType(tryAsU32(v));
|
|
8116
8142
|
function tryAsPerValidator(array, spec) {
|
|
8117
|
-
debug_check
|
|
8143
|
+
debug_check `
|
|
8144
|
+
${array.length === spec.validatorsCount}
|
|
8145
|
+
Invalid per-validator array length. Expected ${spec.validatorsCount}, got: ${array.length}
|
|
8146
|
+
`;
|
|
8118
8147
|
return sized_array_asKnownSize(array);
|
|
8119
8148
|
}
|
|
8120
8149
|
const codecPerValidator = (val) => codecWithContext((context) => {
|
|
@@ -8123,7 +8152,10 @@ const codecPerValidator = (val) => codecWithContext((context) => {
|
|
|
8123
8152
|
});
|
|
8124
8153
|
});
|
|
8125
8154
|
function tryAsPerEpochBlock(array, spec) {
|
|
8126
|
-
debug_check
|
|
8155
|
+
debug_check `
|
|
8156
|
+
${array.length === spec.epochLength}
|
|
8157
|
+
Invalid per-epoch-block array length. Expected ${spec.epochLength}, got: ${array.length}
|
|
8158
|
+
`;
|
|
8127
8159
|
return sized_array_asKnownSize(array);
|
|
8128
8160
|
}
|
|
8129
8161
|
const codecPerEpochBlock = (val) => codecWithContext((context) => {
|
|
@@ -8394,9 +8426,14 @@ class WorkItem extends WithDebug {
|
|
|
8394
8426
|
|
|
8395
8427
|
|
|
8396
8428
|
|
|
8429
|
+
|
|
8397
8430
|
/** Verify the value is within the `WorkItemsCount` bounds. */
|
|
8398
8431
|
function work_package_tryAsWorkItemsCount(len) {
|
|
8399
|
-
|
|
8432
|
+
debug_check `
|
|
8433
|
+
${len >= MIN_NUMBER_OF_WORK_ITEMS && len <= work_package_MAX_NUMBER_OF_WORK_ITEMS}
|
|
8434
|
+
WorkItemsCount: Expected '${MIN_NUMBER_OF_WORK_ITEMS} <= count <= ${work_package_MAX_NUMBER_OF_WORK_ITEMS}' got ${len}
|
|
8435
|
+
`;
|
|
8436
|
+
return numbers_tryAsU8(len);
|
|
8400
8437
|
}
|
|
8401
8438
|
/** Minimal number of work items in the work package or results in work report. */
|
|
8402
8439
|
const MIN_NUMBER_OF_WORK_ITEMS = 1;
|
|
@@ -9639,7 +9676,10 @@ class AvailabilityAssignment extends WithDebug {
|
|
|
9639
9676
|
|
|
9640
9677
|
/** Check if given array has correct length before casting to the opaque type. */
|
|
9641
9678
|
function tryAsPerCore(array, spec) {
|
|
9642
|
-
debug_check
|
|
9679
|
+
debug_check `
|
|
9680
|
+
${array.length === spec.coresCount}
|
|
9681
|
+
Invalid per-core array length. Expected ${spec.coresCount}, got: ${array.length}
|
|
9682
|
+
`;
|
|
9643
9683
|
return opaque_asOpaqueType(array);
|
|
9644
9684
|
}
|
|
9645
9685
|
const codecPerCore = (val) => codecWithContext((context) => {
|
|
@@ -10890,7 +10930,7 @@ class InMemoryState extends WithDebug {
|
|
|
10890
10930
|
}
|
|
10891
10931
|
removeServices(servicesRemoved) {
|
|
10892
10932
|
for (const serviceId of servicesRemoved ?? []) {
|
|
10893
|
-
debug_check
|
|
10933
|
+
debug_check `${this.services.has(serviceId)} Attempting to remove non-existing service: ${serviceId}`;
|
|
10894
10934
|
this.services.delete(serviceId);
|
|
10895
10935
|
}
|
|
10896
10936
|
}
|
|
@@ -10907,7 +10947,10 @@ class InMemoryState extends WithDebug {
|
|
|
10907
10947
|
}
|
|
10908
10948
|
else if (kind === UpdateStorageKind.Remove) {
|
|
10909
10949
|
const { key } = action;
|
|
10910
|
-
debug_check
|
|
10950
|
+
debug_check `
|
|
10951
|
+
${service.data.storage.has(key.toString())}
|
|
10952
|
+
Attempting to remove non-existing storage item at ${serviceId}: ${action.key}
|
|
10953
|
+
`;
|
|
10911
10954
|
service.data.storage.delete(key.toString());
|
|
10912
10955
|
}
|
|
10913
10956
|
else {
|
|
@@ -11590,12 +11633,12 @@ class TrieNode {
|
|
|
11590
11633
|
}
|
|
11591
11634
|
/** View this node as a branch node */
|
|
11592
11635
|
asBranchNode() {
|
|
11593
|
-
debug_check
|
|
11636
|
+
debug_check `${this.getNodeType() === NodeType.Branch} not a branch!`;
|
|
11594
11637
|
return new BranchNode(this);
|
|
11595
11638
|
}
|
|
11596
11639
|
/** View this node as a leaf node */
|
|
11597
11640
|
asLeafNode() {
|
|
11598
|
-
debug_check
|
|
11641
|
+
debug_check `${this.getNodeType() !== NodeType.Branch} not a leaf!`;
|
|
11599
11642
|
return new LeafNode(this);
|
|
11600
11643
|
}
|
|
11601
11644
|
toString() {
|
|
@@ -12083,7 +12126,7 @@ function createSubtreeForBothLeaves(traversedPath, nodes, leafToReplace, leaf) {
|
|
|
12083
12126
|
* Return a single bit from `key` located at `bitIndex`.
|
|
12084
12127
|
*/
|
|
12085
12128
|
function getBit(key, bitIndex) {
|
|
12086
|
-
debug_check
|
|
12129
|
+
debug_check `${bitIndex < TRUNCATED_KEY_BITS} invalid bit index passed ${bitIndex}`;
|
|
12087
12130
|
const byte = bitIndex >>> 3;
|
|
12088
12131
|
const bit = bitIndex - (byte << 3);
|
|
12089
12132
|
const mask = 0b10_00_00_00 >>> bit;
|
|
@@ -13408,7 +13451,7 @@ class TypedPort {
|
|
|
13408
13451
|
* Send a response given the worker that has previously requested something.
|
|
13409
13452
|
*/
|
|
13410
13453
|
respond(localState, request, data, transferList) {
|
|
13411
|
-
debug_check
|
|
13454
|
+
debug_check `${request.kind === "request"}`;
|
|
13412
13455
|
this.postMessage({
|
|
13413
13456
|
kind: "response",
|
|
13414
13457
|
id: request.id,
|
|
@@ -13439,10 +13482,11 @@ class TypedPort {
|
|
|
13439
13482
|
throw new Error(`Invalid message: ${JSON.stringify(msg)}.`);
|
|
13440
13483
|
}
|
|
13441
13484
|
switch (msg.kind) {
|
|
13442
|
-
case "response":
|
|
13443
|
-
debug_check
|
|
13485
|
+
case "response": {
|
|
13486
|
+
debug_check `${this.responseListeners.eventNames().indexOf(reqEvent(msg.id)) !== -1}`;
|
|
13444
13487
|
this.responseListeners.emit(reqEvent(msg.id), null, msg.data, msg.name, msg.localState, msg);
|
|
13445
13488
|
break;
|
|
13489
|
+
}
|
|
13446
13490
|
case "signal":
|
|
13447
13491
|
this.listeners.emit("signal", msg.name, msg.data, msg.localState, msg);
|
|
13448
13492
|
break;
|
|
@@ -13657,9 +13701,9 @@ class MessageChannelStateMachine {
|
|
|
13657
13701
|
const promise = new Promise((resolve, reject) => {
|
|
13658
13702
|
parentPort.once("message", (value) => {
|
|
13659
13703
|
try {
|
|
13660
|
-
debug_check
|
|
13661
|
-
debug_check
|
|
13662
|
-
debug_check
|
|
13704
|
+
debug_check `${value.kind === "request"} The initial message should be a request with channel.`;
|
|
13705
|
+
debug_check `${value.name === CHANNEL_MESSAGE}`;
|
|
13706
|
+
debug_check `${value.data instanceof external_node_worker_threads_namespaceObject.MessagePort}`;
|
|
13663
13707
|
const port = new TypedPort(value.data);
|
|
13664
13708
|
port.respond(machine.currentState().stateName, value, Ok);
|
|
13665
13709
|
resolve(port);
|
|
@@ -13739,7 +13783,7 @@ class StateMachine {
|
|
|
13739
13783
|
/** Get state object by name. */
|
|
13740
13784
|
getState(name) {
|
|
13741
13785
|
const state = this.allStates.get(name);
|
|
13742
|
-
debug_check
|
|
13786
|
+
debug_check `${state !== undefined} Unable to retrieve state object for ${name}.`;
|
|
13743
13787
|
return state;
|
|
13744
13788
|
}
|
|
13745
13789
|
/** Get the currently active state object. */
|
|
@@ -14083,19 +14127,22 @@ class Preimages {
|
|
|
14083
14127
|
|
|
14084
14128
|
const NO_OF_REGISTERS = 13;
|
|
14085
14129
|
const REGISTER_SIZE_SHIFT = 3;
|
|
14086
|
-
const registers_tryAsRegisterIndex = (index) =>
|
|
14130
|
+
const registers_tryAsRegisterIndex = (index) => {
|
|
14131
|
+
check `${index >= 0 && index < NO_OF_REGISTERS} Incorrect register index: ${index}!`;
|
|
14132
|
+
return asOpaqueType(index);
|
|
14133
|
+
};
|
|
14087
14134
|
class registers_Registers {
|
|
14088
14135
|
bytes;
|
|
14089
14136
|
asSigned;
|
|
14090
14137
|
asUnsigned;
|
|
14091
14138
|
constructor(bytes = new Uint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
|
|
14092
14139
|
this.bytes = bytes;
|
|
14093
|
-
check
|
|
14140
|
+
check `${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14094
14141
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
14095
14142
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14096
14143
|
}
|
|
14097
14144
|
static fromBytes(bytes) {
|
|
14098
|
-
check
|
|
14145
|
+
check `${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14099
14146
|
return new registers_Registers(bytes);
|
|
14100
14147
|
}
|
|
14101
14148
|
getBytesAsLittleEndian(index, len) {
|
|
@@ -14241,7 +14288,7 @@ class mask_Mask {
|
|
|
14241
14288
|
return this.lookupTableForward[index] === 0;
|
|
14242
14289
|
}
|
|
14243
14290
|
getNoOfBytesToNextInstruction(index) {
|
|
14244
|
-
check
|
|
14291
|
+
check `${index >= 0} index (${index}) cannot be a negative number`;
|
|
14245
14292
|
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
14246
14293
|
}
|
|
14247
14294
|
buildLookupTableForward(mask) {
|
|
@@ -15127,7 +15174,7 @@ const PAGE_SIZE_SHIFT = 12;
|
|
|
15127
15174
|
const memory_consts_PAGE_SIZE = 1 << PAGE_SIZE_SHIFT;
|
|
15128
15175
|
const MIN_ALLOCATION_SHIFT = (() => {
|
|
15129
15176
|
const MIN_ALLOCATION_SHIFT = 7;
|
|
15130
|
-
debug_check
|
|
15177
|
+
debug_check `${MIN_ALLOCATION_SHIFT >= 0 && MIN_ALLOCATION_SHIFT < PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
15131
15178
|
return MIN_ALLOCATION_SHIFT;
|
|
15132
15179
|
})();
|
|
15133
15180
|
const MIN_ALLOCATION_LENGTH = memory_consts_PAGE_SIZE >> MIN_ALLOCATION_SHIFT;
|
|
@@ -15140,16 +15187,28 @@ const MAX_NUMBER_OF_PAGES = memory_consts_MEMORY_SIZE / memory_consts_PAGE_SIZE;
|
|
|
15140
15187
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/memory-index.ts
|
|
15141
15188
|
|
|
15142
15189
|
|
|
15143
|
-
const memory_index_tryAsMemoryIndex = (index) =>
|
|
15144
|
-
|
|
15190
|
+
const memory_index_tryAsMemoryIndex = (index) => {
|
|
15191
|
+
debug_check `${index >= 0 && index <= memory_consts_MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15192
|
+
return opaque_asOpaqueType(index);
|
|
15193
|
+
};
|
|
15194
|
+
const memory_index_tryAsSbrkIndex = (index) => {
|
|
15195
|
+
check `${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
15196
|
+
return asOpaqueType(index);
|
|
15197
|
+
};
|
|
15145
15198
|
|
|
15146
15199
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/pages/page-utils.ts
|
|
15147
15200
|
|
|
15148
15201
|
|
|
15149
15202
|
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
15150
|
-
const page_utils_tryAsPageIndex = (index) =>
|
|
15203
|
+
const page_utils_tryAsPageIndex = (index) => {
|
|
15204
|
+
check `${index >= 0 && index < PAGE_SIZE}, Incorect page index: ${index}!`;
|
|
15205
|
+
return asOpaqueType(index);
|
|
15206
|
+
};
|
|
15151
15207
|
/** Ensure that given `index` represents an index of one of the pages. */
|
|
15152
|
-
const page_utils_tryAsPageNumber = (index) =>
|
|
15208
|
+
const page_utils_tryAsPageNumber = (index) => {
|
|
15209
|
+
debug_check `${index >= 0 && index <= LAST_PAGE_NUMBER}, Incorect page number: ${index}!`;
|
|
15210
|
+
return opaque_asOpaqueType(index);
|
|
15211
|
+
};
|
|
15153
15212
|
/**
|
|
15154
15213
|
* Get the next page number and wrap the result if it is bigger than LAST_PAGE_NUMBER
|
|
15155
15214
|
*
|
|
@@ -15681,10 +15740,10 @@ class memory_builder_MemoryBuilder {
|
|
|
15681
15740
|
*/
|
|
15682
15741
|
setReadablePages(start, end, data = new Uint8Array()) {
|
|
15683
15742
|
this.ensureNotFinalized();
|
|
15684
|
-
check
|
|
15685
|
-
check
|
|
15686
|
-
check
|
|
15687
|
-
check
|
|
15743
|
+
check `${start < end} end has to be bigger than start`;
|
|
15744
|
+
check `${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15745
|
+
check `${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15746
|
+
check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15688
15747
|
const length = end - start;
|
|
15689
15748
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15690
15749
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -15709,10 +15768,10 @@ class memory_builder_MemoryBuilder {
|
|
|
15709
15768
|
*/
|
|
15710
15769
|
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
15711
15770
|
this.ensureNotFinalized();
|
|
15712
|
-
check
|
|
15713
|
-
check
|
|
15714
|
-
check
|
|
15715
|
-
check
|
|
15771
|
+
check `${start < end} end has to be bigger than start`;
|
|
15772
|
+
check `${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15773
|
+
check `${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
15774
|
+
check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15716
15775
|
const length = end - start;
|
|
15717
15776
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15718
15777
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -15734,7 +15793,7 @@ class memory_builder_MemoryBuilder {
|
|
|
15734
15793
|
this.ensureNotFinalized();
|
|
15735
15794
|
const pageOffset = start % PAGE_SIZE;
|
|
15736
15795
|
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15737
|
-
check
|
|
15796
|
+
check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15738
15797
|
const length = data.length;
|
|
15739
15798
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15740
15799
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -15748,7 +15807,10 @@ class memory_builder_MemoryBuilder {
|
|
|
15748
15807
|
return this;
|
|
15749
15808
|
}
|
|
15750
15809
|
finalize(startHeapIndex, endHeapIndex) {
|
|
15751
|
-
check
|
|
15810
|
+
check `
|
|
15811
|
+
${startHeapIndex <= endHeapIndex}
|
|
15812
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
15813
|
+
`;
|
|
15752
15814
|
this.ensureNotFinalized();
|
|
15753
15815
|
const range = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
15754
15816
|
const pages = PageRange.fromMemoryRange(range);
|
|
@@ -15850,7 +15912,7 @@ function math_utils_mulU64(a, b) {
|
|
|
15850
15912
|
*
|
|
15851
15913
|
* The result of multiplication is a 64-bits number and we are only interested in the part that lands in the upper 32-bits.
|
|
15852
15914
|
* For example if we multiply `0xffffffff * 0xffffffff`, we get:
|
|
15853
|
-
|
|
15915
|
+
|
|
15854
15916
|
* | 64-bits | 64-bits |
|
|
15855
15917
|
* +--------------------+--------------------+
|
|
15856
15918
|
* | upper | lower |
|
|
@@ -15886,7 +15948,7 @@ function math_utils_mulUpperSS(a, b) {
|
|
|
15886
15948
|
return interpretAsSigned(resultLimitedTo64Bits);
|
|
15887
15949
|
}
|
|
15888
15950
|
function math_utils_unsignedRightShiftBigInt(value, shift) {
|
|
15889
|
-
check
|
|
15951
|
+
check `${shift >= 0} Shift count must be non-negative`;
|
|
15890
15952
|
const fillBit = value < 0 ? "1" : "0";
|
|
15891
15953
|
// Convert the BigInt to its binary representation
|
|
15892
15954
|
const binaryRepresentation = value.toString(2).padStart(64, fillBit);
|
|
@@ -17245,7 +17307,10 @@ class two_regs_two_imms_dispatcher_TwoRegsTwoImmsDispatcher {
|
|
|
17245
17307
|
class jump_table_JumpTable {
|
|
17246
17308
|
indices;
|
|
17247
17309
|
constructor(itemByteLength, bytes) {
|
|
17248
|
-
check
|
|
17310
|
+
check `
|
|
17311
|
+
${itemByteLength === 0 || bytes.length % itemByteLength === 0}
|
|
17312
|
+
Length of jump table (${bytes.length}) should be a multiple of item lenght (${itemByteLength})!
|
|
17313
|
+
`;
|
|
17249
17314
|
const length = itemByteLength === 0 ? 0 : bytes.length / itemByteLength;
|
|
17250
17315
|
this.indices = new Uint32Array(length);
|
|
17251
17316
|
for (let i = 0; i < length; i++) {
|
|
@@ -17689,7 +17754,10 @@ class ReturnValue {
|
|
|
17689
17754
|
this.consumedGas = consumedGas;
|
|
17690
17755
|
this.status = status;
|
|
17691
17756
|
this.memorySlice = memorySlice;
|
|
17692
|
-
check
|
|
17757
|
+
check `
|
|
17758
|
+
${(status === null && memorySlice !== null) || (status !== null && memorySlice === null)}
|
|
17759
|
+
'status' and 'memorySlice' must not both be null or both be non-null — exactly one must be provided
|
|
17760
|
+
`;
|
|
17693
17761
|
}
|
|
17694
17762
|
static fromStatus(consumedGas, status) {
|
|
17695
17763
|
return new ReturnValue(consumedGas, status, null);
|
|
@@ -17738,7 +17806,10 @@ class HostCalls {
|
|
|
17738
17806
|
if (status !== Status.HOST) {
|
|
17739
17807
|
return this.getReturnValue(status, pvmInstance);
|
|
17740
17808
|
}
|
|
17741
|
-
check
|
|
17809
|
+
check `
|
|
17810
|
+
${pvmInstance.getExitParam() !== null}
|
|
17811
|
+
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
17812
|
+
`;
|
|
17742
17813
|
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
17743
17814
|
const gas = pvmInstance.getGasCounter();
|
|
17744
17815
|
const regs = new HostCallRegisters(pvmInstance.getRegisters());
|
|
@@ -17798,7 +17869,7 @@ class host_calls_manager_HostCallsManager {
|
|
|
17798
17869
|
constructor({ missing, handlers = [], }) {
|
|
17799
17870
|
this.missing = missing;
|
|
17800
17871
|
for (const handler of handlers) {
|
|
17801
|
-
check
|
|
17872
|
+
check `${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
17802
17873
|
this.hostCalls.set(handler.index, handler);
|
|
17803
17874
|
}
|
|
17804
17875
|
}
|
|
@@ -17921,7 +17992,7 @@ function getServiceId(serviceId) {
|
|
|
17921
17992
|
return null;
|
|
17922
17993
|
}
|
|
17923
17994
|
function writeServiceIdAsLeBytes(serviceId, destination) {
|
|
17924
|
-
check
|
|
17995
|
+
check `${destination.length >= SERVICE_ID_BYTES} Not enough space in the destination.`;
|
|
17925
17996
|
destination.set(u32AsLeBytes(serviceId));
|
|
17926
17997
|
}
|
|
17927
17998
|
/** Clamp a U64 to the maximum value of a 32-bit unsigned integer. */
|
|
@@ -17989,13 +18060,27 @@ class SpiProgram extends WithDebug {
|
|
|
17989
18060
|
this.registers = registers;
|
|
17990
18061
|
}
|
|
17991
18062
|
}
|
|
18063
|
+
/**
|
|
18064
|
+
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
18065
|
+
*
|
|
18066
|
+
* E_n - little endian encoding, n - length
|
|
18067
|
+
* o - initial read only data
|
|
18068
|
+
* w - initial heap
|
|
18069
|
+
* z - heap pages filled with zeros
|
|
18070
|
+
* s - stack size
|
|
18071
|
+
* c - program code
|
|
18072
|
+
*
|
|
18073
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
18074
|
+
*/
|
|
17992
18075
|
function decode_standard_program_decodeStandardProgram(program, args) {
|
|
17993
18076
|
const decoder = Decoder.fromBlob(program);
|
|
17994
18077
|
const oLength = decoder.u24();
|
|
17995
18078
|
const wLength = decoder.u24();
|
|
17996
|
-
|
|
17997
|
-
|
|
17998
|
-
const
|
|
18079
|
+
check `${args.length <= DATA_LENGTH} Incorrect arguments length`;
|
|
18080
|
+
check `${oLength <= DATA_LENGTH} Incorrect readonly segment length`;
|
|
18081
|
+
const readOnlyLength = oLength;
|
|
18082
|
+
check `${wLength <= DATA_LENGTH} Incorrect heap segment length`;
|
|
18083
|
+
const heapLength = wLength;
|
|
17999
18084
|
const noOfHeapZerosPages = decoder.u16();
|
|
18000
18085
|
const stackSize = decoder.u24();
|
|
18001
18086
|
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
@@ -18011,14 +18096,14 @@ function decode_standard_program_decodeStandardProgram(program, args) {
|
|
|
18011
18096
|
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
18012
18097
|
const stackEnd = STACK_SEGMENT;
|
|
18013
18098
|
const argsStart = ARGS_SEGMENT;
|
|
18014
|
-
const argsEnd = argsStart + alignToPageSize(
|
|
18015
|
-
const argsZerosEnd = argsEnd + alignToPageSize(
|
|
18099
|
+
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
18100
|
+
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
18016
18101
|
function nonEmpty(s) {
|
|
18017
18102
|
return s !== false;
|
|
18018
18103
|
}
|
|
18019
18104
|
const readableMemory = [
|
|
18020
18105
|
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
18021
|
-
|
|
18106
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
18022
18107
|
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
18023
18108
|
].filter(nonEmpty);
|
|
18024
18109
|
const writeableMemory = [
|