@typeberry/jam 0.1.0 → 0.1.1-135f62f
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 +212 -125
- package/block-generator/index.js.map +1 -1
- package/importer/index.js +287 -594
- package/importer/index.js.map +1 -1
- package/index.js +289 -593
- package/index.js.map +1 -1
- package/jam-network/index.js +139 -93
- package/jam-network/index.js.map +1 -1
- package/package.json +1 -1
- package/bandersnatch/6b655f8772c01b768329.js +0 -1
- package/bandersnatch/ccf8ada94096a8f232f5.js +0 -1
- package/bandersnatch/e2fdc1b646378dd96eda.js +0 -1
- package/bandersnatch/index.js +0 -3037
- package/bandersnatch/index.js.map +0 -1
- package/bandersnatch/package.json +0 -3
- package/bandersnatch/sourcemap-register.cjs +0 -1
- package/bootstrap-bandersnatch.mjs +0 -162
- package/bootstrap-bandersnatch.mjs.map +0 -1
- package/importer/bootstrap-bandersnatch.mjs.map +0 -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);
|
|
@@ -6766,6 +6792,7 @@ async function verifyBatch(input) {
|
|
|
6766
6792
|
|
|
6767
6793
|
;// CONCATENATED MODULE: ./packages/core/hash/hash.ts
|
|
6768
6794
|
|
|
6795
|
+
|
|
6769
6796
|
/**
|
|
6770
6797
|
* Size of the output of the hash functions.
|
|
6771
6798
|
*
|
|
@@ -6775,6 +6802,7 @@ async function verifyBatch(input) {
|
|
|
6775
6802
|
const hash_HASH_SIZE = 32;
|
|
6776
6803
|
/** A hash without last byte (useful for trie representation). */
|
|
6777
6804
|
const TRUNCATED_HASH_SIZE = 31;
|
|
6805
|
+
const ZERO_HASH = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
6778
6806
|
/**
|
|
6779
6807
|
* Container for some object with a hash that is related to this object.
|
|
6780
6808
|
*
|
|
@@ -6819,7 +6847,7 @@ class PageAllocator {
|
|
|
6819
6847
|
// TODO [ToDr] Benchmark the performance!
|
|
6820
6848
|
constructor(hashesPerPage) {
|
|
6821
6849
|
this.hashesPerPage = hashesPerPage;
|
|
6822
|
-
check
|
|
6850
|
+
check `${hashesPerPage > 0 && hashesPerPage >>> 0 === hashesPerPage} Expected a non-zero integer.`;
|
|
6823
6851
|
this.resetPage();
|
|
6824
6852
|
}
|
|
6825
6853
|
resetPage() {
|
|
@@ -7118,8 +7146,8 @@ class MultiMap {
|
|
|
7118
7146
|
* if needed.
|
|
7119
7147
|
*/
|
|
7120
7148
|
constructor(keysLength, keyMappers) {
|
|
7121
|
-
check
|
|
7122
|
-
check
|
|
7149
|
+
check `${keysLength > 0} Keys cannot be empty.`;
|
|
7150
|
+
check `${keyMappers === undefined || keyMappers.length === keysLength} Incorrect number of key mappers given!`;
|
|
7123
7151
|
this.data = new Map();
|
|
7124
7152
|
this.keyMappers = keyMappers === undefined ? Array(keysLength).fill(null) : keyMappers;
|
|
7125
7153
|
}
|
|
@@ -7220,7 +7248,7 @@ class sized_array_FixedSizeArray extends Array {
|
|
|
7220
7248
|
this.fixedLength = this.length;
|
|
7221
7249
|
}
|
|
7222
7250
|
static new(data, len) {
|
|
7223
|
-
debug_check
|
|
7251
|
+
debug_check `${data.length === len} Expected an array of size: ${len}, got: ${data.length}`;
|
|
7224
7252
|
const arr = new sized_array_FixedSizeArray(len);
|
|
7225
7253
|
for (let i = 0; i < len; i++) {
|
|
7226
7254
|
arr[i] = data[i];
|
|
@@ -7354,7 +7382,7 @@ class SortedArray {
|
|
|
7354
7382
|
}
|
|
7355
7383
|
/** Create a new SortedSet from two sorted collections. */
|
|
7356
7384
|
static fromTwoSortedCollections(first, second) {
|
|
7357
|
-
debug_check
|
|
7385
|
+
debug_check `${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
7358
7386
|
const comparator = first.comparator;
|
|
7359
7387
|
const arr1 = first.array;
|
|
7360
7388
|
const arr1Length = arr1.length;
|
|
@@ -7474,7 +7502,7 @@ class SortedSet extends SortedArray {
|
|
|
7474
7502
|
}
|
|
7475
7503
|
/** Create a new SortedSet from two sorted collections. */
|
|
7476
7504
|
static fromTwoSortedCollections(first, second) {
|
|
7477
|
-
debug_check
|
|
7505
|
+
debug_check `${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
7478
7506
|
const comparator = first.comparator;
|
|
7479
7507
|
if (first.length === 0) {
|
|
7480
7508
|
return SortedSet.fromSortedArray(comparator, second.array);
|
|
@@ -8112,7 +8140,10 @@ const common_tryAsCoreIndex = (v) => opaque_asOpaqueType(numbers_tryAsU16(v));
|
|
|
8112
8140
|
/** Attempt to convert a number into `Epoch`. */
|
|
8113
8141
|
const tryAsEpoch = (v) => asOpaqueType(tryAsU32(v));
|
|
8114
8142
|
function tryAsPerValidator(array, spec) {
|
|
8115
|
-
debug_check
|
|
8143
|
+
debug_check `
|
|
8144
|
+
${array.length === spec.validatorsCount}
|
|
8145
|
+
Invalid per-validator array length. Expected ${spec.validatorsCount}, got: ${array.length}
|
|
8146
|
+
`;
|
|
8116
8147
|
return sized_array_asKnownSize(array);
|
|
8117
8148
|
}
|
|
8118
8149
|
const codecPerValidator = (val) => codecWithContext((context) => {
|
|
@@ -8121,7 +8152,10 @@ const codecPerValidator = (val) => codecWithContext((context) => {
|
|
|
8121
8152
|
});
|
|
8122
8153
|
});
|
|
8123
8154
|
function tryAsPerEpochBlock(array, spec) {
|
|
8124
|
-
debug_check
|
|
8155
|
+
debug_check `
|
|
8156
|
+
${array.length === spec.epochLength}
|
|
8157
|
+
Invalid per-epoch-block array length. Expected ${spec.epochLength}, got: ${array.length}
|
|
8158
|
+
`;
|
|
8125
8159
|
return sized_array_asKnownSize(array);
|
|
8126
8160
|
}
|
|
8127
8161
|
const codecPerEpochBlock = (val) => codecWithContext((context) => {
|
|
@@ -8392,9 +8426,14 @@ class WorkItem extends WithDebug {
|
|
|
8392
8426
|
|
|
8393
8427
|
|
|
8394
8428
|
|
|
8429
|
+
|
|
8395
8430
|
/** Verify the value is within the `WorkItemsCount` bounds. */
|
|
8396
8431
|
function work_package_tryAsWorkItemsCount(len) {
|
|
8397
|
-
|
|
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);
|
|
8398
8437
|
}
|
|
8399
8438
|
/** Minimal number of work items in the work package or results in work report. */
|
|
8400
8439
|
const MIN_NUMBER_OF_WORK_ITEMS = 1;
|
|
@@ -9637,7 +9676,10 @@ class AvailabilityAssignment extends WithDebug {
|
|
|
9637
9676
|
|
|
9638
9677
|
/** Check if given array has correct length before casting to the opaque type. */
|
|
9639
9678
|
function tryAsPerCore(array, spec) {
|
|
9640
|
-
debug_check
|
|
9679
|
+
debug_check `
|
|
9680
|
+
${array.length === spec.coresCount}
|
|
9681
|
+
Invalid per-core array length. Expected ${spec.coresCount}, got: ${array.length}
|
|
9682
|
+
`;
|
|
9641
9683
|
return opaque_asOpaqueType(array);
|
|
9642
9684
|
}
|
|
9643
9685
|
const codecPerCore = (val) => codecWithContext((context) => {
|
|
@@ -10888,7 +10930,7 @@ class InMemoryState extends WithDebug {
|
|
|
10888
10930
|
}
|
|
10889
10931
|
removeServices(servicesRemoved) {
|
|
10890
10932
|
for (const serviceId of servicesRemoved ?? []) {
|
|
10891
|
-
debug_check
|
|
10933
|
+
debug_check `${this.services.has(serviceId)} Attempting to remove non-existing service: ${serviceId}`;
|
|
10892
10934
|
this.services.delete(serviceId);
|
|
10893
10935
|
}
|
|
10894
10936
|
}
|
|
@@ -10905,7 +10947,10 @@ class InMemoryState extends WithDebug {
|
|
|
10905
10947
|
}
|
|
10906
10948
|
else if (kind === UpdateStorageKind.Remove) {
|
|
10907
10949
|
const { key } = action;
|
|
10908
|
-
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
|
+
`;
|
|
10909
10954
|
service.data.storage.delete(key.toString());
|
|
10910
10955
|
}
|
|
10911
10956
|
else {
|
|
@@ -11588,12 +11633,12 @@ class TrieNode {
|
|
|
11588
11633
|
}
|
|
11589
11634
|
/** View this node as a branch node */
|
|
11590
11635
|
asBranchNode() {
|
|
11591
|
-
debug_check
|
|
11636
|
+
debug_check `${this.getNodeType() === NodeType.Branch} not a branch!`;
|
|
11592
11637
|
return new BranchNode(this);
|
|
11593
11638
|
}
|
|
11594
11639
|
/** View this node as a leaf node */
|
|
11595
11640
|
asLeafNode() {
|
|
11596
|
-
debug_check
|
|
11641
|
+
debug_check `${this.getNodeType() !== NodeType.Branch} not a leaf!`;
|
|
11597
11642
|
return new LeafNode(this);
|
|
11598
11643
|
}
|
|
11599
11644
|
toString() {
|
|
@@ -12081,7 +12126,7 @@ function createSubtreeForBothLeaves(traversedPath, nodes, leafToReplace, leaf) {
|
|
|
12081
12126
|
* Return a single bit from `key` located at `bitIndex`.
|
|
12082
12127
|
*/
|
|
12083
12128
|
function getBit(key, bitIndex) {
|
|
12084
|
-
debug_check
|
|
12129
|
+
debug_check `${bitIndex < TRUNCATED_KEY_BITS} invalid bit index passed ${bitIndex}`;
|
|
12085
12130
|
const byte = bitIndex >>> 3;
|
|
12086
12131
|
const bit = bitIndex - (byte << 3);
|
|
12087
12132
|
const mask = 0b10_00_00_00 >>> bit;
|
|
@@ -13406,7 +13451,7 @@ class TypedPort {
|
|
|
13406
13451
|
* Send a response given the worker that has previously requested something.
|
|
13407
13452
|
*/
|
|
13408
13453
|
respond(localState, request, data, transferList) {
|
|
13409
|
-
debug_check
|
|
13454
|
+
debug_check `${request.kind === "request"}`;
|
|
13410
13455
|
this.postMessage({
|
|
13411
13456
|
kind: "response",
|
|
13412
13457
|
id: request.id,
|
|
@@ -13437,10 +13482,11 @@ class TypedPort {
|
|
|
13437
13482
|
throw new Error(`Invalid message: ${JSON.stringify(msg)}.`);
|
|
13438
13483
|
}
|
|
13439
13484
|
switch (msg.kind) {
|
|
13440
|
-
case "response":
|
|
13441
|
-
debug_check
|
|
13485
|
+
case "response": {
|
|
13486
|
+
debug_check `${this.responseListeners.eventNames().indexOf(reqEvent(msg.id)) !== -1}`;
|
|
13442
13487
|
this.responseListeners.emit(reqEvent(msg.id), null, msg.data, msg.name, msg.localState, msg);
|
|
13443
13488
|
break;
|
|
13489
|
+
}
|
|
13444
13490
|
case "signal":
|
|
13445
13491
|
this.listeners.emit("signal", msg.name, msg.data, msg.localState, msg);
|
|
13446
13492
|
break;
|
|
@@ -13655,9 +13701,9 @@ class MessageChannelStateMachine {
|
|
|
13655
13701
|
const promise = new Promise((resolve, reject) => {
|
|
13656
13702
|
parentPort.once("message", (value) => {
|
|
13657
13703
|
try {
|
|
13658
|
-
debug_check
|
|
13659
|
-
debug_check
|
|
13660
|
-
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}`;
|
|
13661
13707
|
const port = new TypedPort(value.data);
|
|
13662
13708
|
port.respond(machine.currentState().stateName, value, Ok);
|
|
13663
13709
|
resolve(port);
|
|
@@ -13737,7 +13783,7 @@ class StateMachine {
|
|
|
13737
13783
|
/** Get state object by name. */
|
|
13738
13784
|
getState(name) {
|
|
13739
13785
|
const state = this.allStates.get(name);
|
|
13740
|
-
debug_check
|
|
13786
|
+
debug_check `${state !== undefined} Unable to retrieve state object for ${name}.`;
|
|
13741
13787
|
return state;
|
|
13742
13788
|
}
|
|
13743
13789
|
/** Get the currently active state object. */
|
|
@@ -14081,19 +14127,22 @@ class Preimages {
|
|
|
14081
14127
|
|
|
14082
14128
|
const NO_OF_REGISTERS = 13;
|
|
14083
14129
|
const REGISTER_SIZE_SHIFT = 3;
|
|
14084
|
-
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
|
+
};
|
|
14085
14134
|
class registers_Registers {
|
|
14086
14135
|
bytes;
|
|
14087
14136
|
asSigned;
|
|
14088
14137
|
asUnsigned;
|
|
14089
14138
|
constructor(bytes = new Uint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
|
|
14090
14139
|
this.bytes = bytes;
|
|
14091
|
-
check
|
|
14140
|
+
check `${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14092
14141
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
14093
14142
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14094
14143
|
}
|
|
14095
14144
|
static fromBytes(bytes) {
|
|
14096
|
-
check
|
|
14145
|
+
check `${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14097
14146
|
return new registers_Registers(bytes);
|
|
14098
14147
|
}
|
|
14099
14148
|
getBytesAsLittleEndian(index, len) {
|
|
@@ -14239,7 +14288,7 @@ class mask_Mask {
|
|
|
14239
14288
|
return this.lookupTableForward[index] === 0;
|
|
14240
14289
|
}
|
|
14241
14290
|
getNoOfBytesToNextInstruction(index) {
|
|
14242
|
-
check
|
|
14291
|
+
check `${index >= 0} index (${index}) cannot be a negative number`;
|
|
14243
14292
|
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
14244
14293
|
}
|
|
14245
14294
|
buildLookupTableForward(mask) {
|
|
@@ -15125,7 +15174,7 @@ const PAGE_SIZE_SHIFT = 12;
|
|
|
15125
15174
|
const memory_consts_PAGE_SIZE = 1 << PAGE_SIZE_SHIFT;
|
|
15126
15175
|
const MIN_ALLOCATION_SHIFT = (() => {
|
|
15127
15176
|
const MIN_ALLOCATION_SHIFT = 7;
|
|
15128
|
-
debug_check
|
|
15177
|
+
debug_check `${MIN_ALLOCATION_SHIFT >= 0 && MIN_ALLOCATION_SHIFT < PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
15129
15178
|
return MIN_ALLOCATION_SHIFT;
|
|
15130
15179
|
})();
|
|
15131
15180
|
const MIN_ALLOCATION_LENGTH = memory_consts_PAGE_SIZE >> MIN_ALLOCATION_SHIFT;
|
|
@@ -15138,16 +15187,28 @@ const MAX_NUMBER_OF_PAGES = memory_consts_MEMORY_SIZE / memory_consts_PAGE_SIZE;
|
|
|
15138
15187
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/memory-index.ts
|
|
15139
15188
|
|
|
15140
15189
|
|
|
15141
|
-
const memory_index_tryAsMemoryIndex = (index) =>
|
|
15142
|
-
|
|
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
|
+
};
|
|
15143
15198
|
|
|
15144
15199
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/pages/page-utils.ts
|
|
15145
15200
|
|
|
15146
15201
|
|
|
15147
15202
|
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
15148
|
-
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
|
+
};
|
|
15149
15207
|
/** Ensure that given `index` represents an index of one of the pages. */
|
|
15150
|
-
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
|
+
};
|
|
15151
15212
|
/**
|
|
15152
15213
|
* Get the next page number and wrap the result if it is bigger than LAST_PAGE_NUMBER
|
|
15153
15214
|
*
|
|
@@ -15679,10 +15740,10 @@ class memory_builder_MemoryBuilder {
|
|
|
15679
15740
|
*/
|
|
15680
15741
|
setReadablePages(start, end, data = new Uint8Array()) {
|
|
15681
15742
|
this.ensureNotFinalized();
|
|
15682
|
-
check
|
|
15683
|
-
check
|
|
15684
|
-
check
|
|
15685
|
-
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`;
|
|
15686
15747
|
const length = end - start;
|
|
15687
15748
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15688
15749
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -15707,10 +15768,10 @@ class memory_builder_MemoryBuilder {
|
|
|
15707
15768
|
*/
|
|
15708
15769
|
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
15709
15770
|
this.ensureNotFinalized();
|
|
15710
|
-
check
|
|
15711
|
-
check
|
|
15712
|
-
check
|
|
15713
|
-
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`;
|
|
15714
15775
|
const length = end - start;
|
|
15715
15776
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15716
15777
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -15732,7 +15793,7 @@ class memory_builder_MemoryBuilder {
|
|
|
15732
15793
|
this.ensureNotFinalized();
|
|
15733
15794
|
const pageOffset = start % PAGE_SIZE;
|
|
15734
15795
|
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
15735
|
-
check
|
|
15796
|
+
check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15736
15797
|
const length = data.length;
|
|
15737
15798
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
15738
15799
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -15746,7 +15807,10 @@ class memory_builder_MemoryBuilder {
|
|
|
15746
15807
|
return this;
|
|
15747
15808
|
}
|
|
15748
15809
|
finalize(startHeapIndex, endHeapIndex) {
|
|
15749
|
-
check
|
|
15810
|
+
check `
|
|
15811
|
+
${startHeapIndex <= endHeapIndex}
|
|
15812
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
15813
|
+
`;
|
|
15750
15814
|
this.ensureNotFinalized();
|
|
15751
15815
|
const range = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
15752
15816
|
const pages = PageRange.fromMemoryRange(range);
|
|
@@ -15848,7 +15912,7 @@ function math_utils_mulU64(a, b) {
|
|
|
15848
15912
|
*
|
|
15849
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.
|
|
15850
15914
|
* For example if we multiply `0xffffffff * 0xffffffff`, we get:
|
|
15851
|
-
|
|
15915
|
+
|
|
15852
15916
|
* | 64-bits | 64-bits |
|
|
15853
15917
|
* +--------------------+--------------------+
|
|
15854
15918
|
* | upper | lower |
|
|
@@ -15884,7 +15948,7 @@ function math_utils_mulUpperSS(a, b) {
|
|
|
15884
15948
|
return interpretAsSigned(resultLimitedTo64Bits);
|
|
15885
15949
|
}
|
|
15886
15950
|
function math_utils_unsignedRightShiftBigInt(value, shift) {
|
|
15887
|
-
check
|
|
15951
|
+
check `${shift >= 0} Shift count must be non-negative`;
|
|
15888
15952
|
const fillBit = value < 0 ? "1" : "0";
|
|
15889
15953
|
// Convert the BigInt to its binary representation
|
|
15890
15954
|
const binaryRepresentation = value.toString(2).padStart(64, fillBit);
|
|
@@ -17243,7 +17307,10 @@ class two_regs_two_imms_dispatcher_TwoRegsTwoImmsDispatcher {
|
|
|
17243
17307
|
class jump_table_JumpTable {
|
|
17244
17308
|
indices;
|
|
17245
17309
|
constructor(itemByteLength, bytes) {
|
|
17246
|
-
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
|
+
`;
|
|
17247
17314
|
const length = itemByteLength === 0 ? 0 : bytes.length / itemByteLength;
|
|
17248
17315
|
this.indices = new Uint32Array(length);
|
|
17249
17316
|
for (let i = 0; i < length; i++) {
|
|
@@ -17687,7 +17754,10 @@ class ReturnValue {
|
|
|
17687
17754
|
this.consumedGas = consumedGas;
|
|
17688
17755
|
this.status = status;
|
|
17689
17756
|
this.memorySlice = memorySlice;
|
|
17690
|
-
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
|
+
`;
|
|
17691
17761
|
}
|
|
17692
17762
|
static fromStatus(consumedGas, status) {
|
|
17693
17763
|
return new ReturnValue(consumedGas, status, null);
|
|
@@ -17736,7 +17806,10 @@ class HostCalls {
|
|
|
17736
17806
|
if (status !== Status.HOST) {
|
|
17737
17807
|
return this.getReturnValue(status, pvmInstance);
|
|
17738
17808
|
}
|
|
17739
|
-
check
|
|
17809
|
+
check `
|
|
17810
|
+
${pvmInstance.getExitParam() !== null}
|
|
17811
|
+
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
17812
|
+
`;
|
|
17740
17813
|
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
17741
17814
|
const gas = pvmInstance.getGasCounter();
|
|
17742
17815
|
const regs = new HostCallRegisters(pvmInstance.getRegisters());
|
|
@@ -17796,7 +17869,7 @@ class host_calls_manager_HostCallsManager {
|
|
|
17796
17869
|
constructor({ missing, handlers = [], }) {
|
|
17797
17870
|
this.missing = missing;
|
|
17798
17871
|
for (const handler of handlers) {
|
|
17799
|
-
check
|
|
17872
|
+
check `${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
17800
17873
|
this.hostCalls.set(handler.index, handler);
|
|
17801
17874
|
}
|
|
17802
17875
|
}
|
|
@@ -17919,7 +17992,7 @@ function getServiceId(serviceId) {
|
|
|
17919
17992
|
return null;
|
|
17920
17993
|
}
|
|
17921
17994
|
function writeServiceIdAsLeBytes(serviceId, destination) {
|
|
17922
|
-
check
|
|
17995
|
+
check `${destination.length >= SERVICE_ID_BYTES} Not enough space in the destination.`;
|
|
17923
17996
|
destination.set(u32AsLeBytes(serviceId));
|
|
17924
17997
|
}
|
|
17925
17998
|
/** Clamp a U64 to the maximum value of a 32-bit unsigned integer. */
|
|
@@ -17987,13 +18060,27 @@ class SpiProgram extends WithDebug {
|
|
|
17987
18060
|
this.registers = registers;
|
|
17988
18061
|
}
|
|
17989
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
|
+
*/
|
|
17990
18075
|
function decode_standard_program_decodeStandardProgram(program, args) {
|
|
17991
18076
|
const decoder = Decoder.fromBlob(program);
|
|
17992
18077
|
const oLength = decoder.u24();
|
|
17993
18078
|
const wLength = decoder.u24();
|
|
17994
|
-
|
|
17995
|
-
|
|
17996
|
-
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;
|
|
17997
18084
|
const noOfHeapZerosPages = decoder.u16();
|
|
17998
18085
|
const stackSize = decoder.u24();
|
|
17999
18086
|
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
@@ -18009,14 +18096,14 @@ function decode_standard_program_decodeStandardProgram(program, args) {
|
|
|
18009
18096
|
const stackStart = STACK_SEGMENT - alignToPageSize(stackSize);
|
|
18010
18097
|
const stackEnd = STACK_SEGMENT;
|
|
18011
18098
|
const argsStart = ARGS_SEGMENT;
|
|
18012
|
-
const argsEnd = argsStart + alignToPageSize(
|
|
18013
|
-
const argsZerosEnd = argsEnd + alignToPageSize(
|
|
18099
|
+
const argsEnd = argsStart + alignToPageSize(args.length);
|
|
18100
|
+
const argsZerosEnd = argsEnd + alignToPageSize(args.length);
|
|
18014
18101
|
function nonEmpty(s) {
|
|
18015
18102
|
return s !== false;
|
|
18016
18103
|
}
|
|
18017
18104
|
const readableMemory = [
|
|
18018
18105
|
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
18019
|
-
|
|
18106
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
18020
18107
|
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
18021
18108
|
].filter(nonEmpty);
|
|
18022
18109
|
const writeableMemory = [
|