@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/importer/index.js
CHANGED
|
@@ -4224,10 +4224,17 @@ async function initAll() {
|
|
|
4224
4224
|
await init.ed25519();
|
|
4225
4225
|
await init.reedSolomon();
|
|
4226
4226
|
}
|
|
4227
|
+
function initOnce(doInit) {
|
|
4228
|
+
let ready = null;
|
|
4229
|
+
return async () => {
|
|
4230
|
+
if (ready === null) ready = doInit();
|
|
4231
|
+
return await ready;
|
|
4232
|
+
};
|
|
4233
|
+
}
|
|
4227
4234
|
const init = {
|
|
4228
|
-
bandersnatch: async () => await bandersnatch_default({ module_or_path: await bandersnatch_bg_default() }),
|
|
4229
|
-
ed25519: async () => await ed25519_wasm_default({ module_or_path: await ed25519_wasm_bg_default() }),
|
|
4230
|
-
reedSolomon: async () => await reed_solomon_wasm_default({ module_or_path: await reed_solomon_wasm_bg_default() })
|
|
4235
|
+
bandersnatch: initOnce(async () => await bandersnatch_default({ module_or_path: await bandersnatch_bg_default() })),
|
|
4236
|
+
ed25519: initOnce(async () => await ed25519_wasm_default({ module_or_path: await ed25519_wasm_bg_default() })),
|
|
4237
|
+
reedSolomon: initOnce(async () => await reed_solomon_wasm_default({ module_or_path: await reed_solomon_wasm_bg_default() }))
|
|
4231
4238
|
};
|
|
4232
4239
|
|
|
4233
4240
|
//#endregion
|
|
@@ -4327,29 +4334,17 @@ function isBrowser() {
|
|
|
4327
4334
|
* We avoid using `node:assert` to keep compatibility with a browser environment.
|
|
4328
4335
|
* Note the checks should not have any side effects, since we might decide
|
|
4329
4336
|
* to remove all of them in a post-processing step.
|
|
4330
|
-
*/
|
|
4331
|
-
function debug_check(condition, message) {
|
|
4332
|
-
if (!condition) {
|
|
4333
|
-
throw new Error(`Assertion failure: ${message ?? ""}`);
|
|
4334
|
-
}
|
|
4335
|
-
}
|
|
4336
|
-
function cast(_a, condition) {
|
|
4337
|
-
return condition;
|
|
4338
|
-
}
|
|
4339
|
-
/**
|
|
4340
|
-
* Yet another function to perform runtime assertions.
|
|
4341
|
-
* 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.
|
|
4342
4337
|
*
|
|
4343
|
-
*
|
|
4344
|
-
*
|
|
4345
|
-
* should be replaced with:
|
|
4346
|
-
* const x = y as CheckedNumber;
|
|
4338
|
+
* NOTE the function is intended to be used as tagged template string for the performance
|
|
4339
|
+
* reasons.
|
|
4347
4340
|
*/
|
|
4348
|
-
function
|
|
4349
|
-
if (
|
|
4350
|
-
|
|
4341
|
+
function debug_check(strings, condition, ...data) {
|
|
4342
|
+
if (!condition) {
|
|
4343
|
+
// add an empty value so that `data.length === strings.length`
|
|
4344
|
+
data.unshift("");
|
|
4345
|
+
const message = strings.map((v, index) => `${v}${data[index] ?? ""}`);
|
|
4346
|
+
throw new Error(`Assertion failure:${message.join("")}`);
|
|
4351
4347
|
}
|
|
4352
|
-
throw new Error(`Assertion failure: ${message ?? ""}`);
|
|
4353
4348
|
}
|
|
4354
4349
|
/**
|
|
4355
4350
|
* The function can be used to make sure that a particular type is `never`
|
|
@@ -4519,7 +4514,7 @@ function resultToString(res) {
|
|
|
4519
4514
|
const result_Result = {
|
|
4520
4515
|
/** Create new [`Result`] with `Ok` status. */
|
|
4521
4516
|
ok: (ok) => {
|
|
4522
|
-
debug_check
|
|
4517
|
+
debug_check `${ok !== undefined} 'ok' type cannot be undefined.`;
|
|
4523
4518
|
return {
|
|
4524
4519
|
isOk: true,
|
|
4525
4520
|
isError: false,
|
|
@@ -4528,7 +4523,7 @@ const result_Result = {
|
|
|
4528
4523
|
},
|
|
4529
4524
|
/** Create new [`Result`] with `Error` status. */
|
|
4530
4525
|
error: (error, details = "") => {
|
|
4531
|
-
debug_check
|
|
4526
|
+
debug_check `${error !== undefined} 'Error' type cannot be undefined.`;
|
|
4532
4527
|
return {
|
|
4533
4528
|
isOk: false,
|
|
4534
4529
|
isError: true,
|
|
@@ -4812,7 +4807,10 @@ class BitVec {
|
|
|
4812
4807
|
constructor(data, bitLength) {
|
|
4813
4808
|
this.data = data;
|
|
4814
4809
|
this.bitLength = bitLength;
|
|
4815
|
-
debug_check
|
|
4810
|
+
debug_check `
|
|
4811
|
+
${data.length * 8 >= bitLength}
|
|
4812
|
+
Not enough bytes in the data array. Need ${data.length * 8} has ${bitLength}.
|
|
4813
|
+
`;
|
|
4816
4814
|
this.byteLength = Math.ceil(bitLength / 8);
|
|
4817
4815
|
}
|
|
4818
4816
|
/** Return a raw in-memory representation of this [`BitVec`]. */
|
|
@@ -4821,7 +4819,10 @@ class BitVec {
|
|
|
4821
4819
|
}
|
|
4822
4820
|
/** Perform OR operation on all bits in place. */
|
|
4823
4821
|
sumWith(other) {
|
|
4824
|
-
debug_check
|
|
4822
|
+
debug_check `
|
|
4823
|
+
${other.bitLength === this.bitLength}
|
|
4824
|
+
Invalid bit length for sumWith: ${other.bitLength} vs ${this.bitLength}
|
|
4825
|
+
`;
|
|
4825
4826
|
const otherRaw = other.raw;
|
|
4826
4827
|
for (let i = 0; i < this.byteLength; i++) {
|
|
4827
4828
|
this.data[i] |= otherRaw[i];
|
|
@@ -4831,7 +4832,7 @@ class BitVec {
|
|
|
4831
4832
|
* Set the bit at index `idx` to value `val`.
|
|
4832
4833
|
*/
|
|
4833
4834
|
setBit(idx, val) {
|
|
4834
|
-
debug_check
|
|
4835
|
+
debug_check `${idx >= 0 && idx < this.bitLength} Index out of bounds. Need ${idx} has ${this.bitLength}.`;
|
|
4835
4836
|
const byteIndex = Math.floor(idx / 8);
|
|
4836
4837
|
const bitIndexInByte = idx % 8;
|
|
4837
4838
|
const mask = 1 << bitIndexInByte;
|
|
@@ -4846,7 +4847,7 @@ class BitVec {
|
|
|
4846
4847
|
* Return `true` if the bit at index `idx` is set.
|
|
4847
4848
|
*/
|
|
4848
4849
|
isSet(idx) {
|
|
4849
|
-
debug_check
|
|
4850
|
+
debug_check `${idx >= 0 && idx < this.bitLength} Index out of bounds. Need ${idx} has ${this.bitLength}.`;
|
|
4850
4851
|
const byteIndex = Math.floor(idx / 8);
|
|
4851
4852
|
const bitIndexInByte = idx % 8;
|
|
4852
4853
|
const mask = 1 << bitIndexInByte;
|
|
@@ -5013,7 +5014,7 @@ class bytes_BytesBlob {
|
|
|
5013
5014
|
}
|
|
5014
5015
|
/** Create a new [`BytesBlob`] from an array of bytes. */
|
|
5015
5016
|
static blobFromNumbers(v) {
|
|
5016
|
-
debug_check
|
|
5017
|
+
debug_check `${v.find((x) => (x & 0xff) !== x) === undefined} BytesBlob.blobFromNumbers used with non-byte number array.`;
|
|
5017
5018
|
const arr = new Uint8Array(v);
|
|
5018
5019
|
return new bytes_BytesBlob(arr);
|
|
5019
5020
|
}
|
|
@@ -5057,7 +5058,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
5057
5058
|
length;
|
|
5058
5059
|
constructor(raw, len) {
|
|
5059
5060
|
super(raw);
|
|
5060
|
-
debug_check
|
|
5061
|
+
debug_check `${raw.byteLength === len} Given buffer has incorrect size ${raw.byteLength} vs expected ${len}`;
|
|
5061
5062
|
this.length = len;
|
|
5062
5063
|
}
|
|
5063
5064
|
/** Create new [`Bytes<X>`] given a backing buffer and it's length. */
|
|
@@ -5066,7 +5067,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
5066
5067
|
}
|
|
5067
5068
|
/** Create new [`Bytes<X>`] given an array of bytes and it's length. */
|
|
5068
5069
|
static fromNumbers(v, len) {
|
|
5069
|
-
debug_check
|
|
5070
|
+
debug_check `${v.find((x) => (x & 0xff) !== x) === undefined} Bytes.fromNumbers used with non-byte number array.`;
|
|
5070
5071
|
const x = new Uint8Array(v);
|
|
5071
5072
|
return new bytes_Bytes(x, len);
|
|
5072
5073
|
}
|
|
@@ -5077,7 +5078,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
5077
5078
|
// TODO [ToDr] `fill` should have the argments swapped to align with the rest.
|
|
5078
5079
|
/** Create a [`Bytes<X>`] with all bytes filled with given input number. */
|
|
5079
5080
|
static fill(len, input) {
|
|
5080
|
-
debug_check(
|
|
5081
|
+
debug_check `${(input & 0xff) === input} Input has to be a byte.`;
|
|
5081
5082
|
const bytes = bytes_Bytes.zero(len);
|
|
5082
5083
|
bytes.raw.fill(input, 0, len);
|
|
5083
5084
|
return bytes;
|
|
@@ -5100,7 +5101,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
5100
5101
|
}
|
|
5101
5102
|
/** Compare the sequence to another one. */
|
|
5102
5103
|
isEqualTo(other) {
|
|
5103
|
-
debug_check
|
|
5104
|
+
debug_check `${this.length === other.length} Comparing incorrectly typed bytes!`;
|
|
5104
5105
|
return u8ArraySameLengthEqual(this.raw, other.raw);
|
|
5105
5106
|
}
|
|
5106
5107
|
/** Converts current type into some opaque extension. */
|
|
@@ -5109,7 +5110,7 @@ class bytes_Bytes extends bytes_BytesBlob {
|
|
|
5109
5110
|
}
|
|
5110
5111
|
}
|
|
5111
5112
|
function byteFromString(s) {
|
|
5112
|
-
debug_check
|
|
5113
|
+
debug_check `${s.length === 2} Two-character string expected`;
|
|
5113
5114
|
const a = numberFromCharCode(s.charCodeAt(0));
|
|
5114
5115
|
const b = numberFromCharCode(s.charCodeAt(1));
|
|
5115
5116
|
return (a << 4) | b;
|
|
@@ -5178,7 +5179,7 @@ const BLS_KEY_BYTES = 144;
|
|
|
5178
5179
|
/** Derive a Bandersnatch public key from a seed. */
|
|
5179
5180
|
function bandersnatch_publicKey(seed) {
|
|
5180
5181
|
const key = bandersnatch.derive_public_key(seed);
|
|
5181
|
-
check
|
|
5182
|
+
check `${key[0] === 0} Invalid Bandersnatch public key derived from seed`;
|
|
5182
5183
|
return Bytes.fromBlob(key.subarray(1), BANDERSNATCH_KEY_BYTES).asOpaque();
|
|
5183
5184
|
}
|
|
5184
5185
|
|
|
@@ -5666,7 +5667,7 @@ async function ed25519_verify(input) {
|
|
|
5666
5667
|
data.set(signature.raw, offset);
|
|
5667
5668
|
offset += ED25519_SIGNATURE_BYTES;
|
|
5668
5669
|
const messageLength = message.length;
|
|
5669
|
-
debug_check
|
|
5670
|
+
debug_check `${messageLength < 256} Message needs to be shorter than 256 bytes. Got: ${messageLength}`;
|
|
5670
5671
|
data[offset] = messageLength;
|
|
5671
5672
|
offset += 1;
|
|
5672
5673
|
data.set(message.raw, offset);
|
|
@@ -5750,7 +5751,7 @@ class PageAllocator {
|
|
|
5750
5751
|
// TODO [ToDr] Benchmark the performance!
|
|
5751
5752
|
constructor(hashesPerPage) {
|
|
5752
5753
|
this.hashesPerPage = hashesPerPage;
|
|
5753
|
-
check
|
|
5754
|
+
check `${hashesPerPage > 0 && hashesPerPage >>> 0 === hashesPerPage} Expected a non-zero integer.`;
|
|
5754
5755
|
this.resetPage();
|
|
5755
5756
|
}
|
|
5756
5757
|
resetPage() {
|
|
@@ -5844,42 +5845,53 @@ function keccak_hashBlobs(hasher, blobs) {
|
|
|
5844
5845
|
|
|
5845
5846
|
;// CONCATENATED MODULE: ./packages/core/numbers/index.ts
|
|
5846
5847
|
|
|
5847
|
-
const
|
|
5848
|
+
const asTypedNumber = (v) => v;
|
|
5848
5849
|
const MAX_VALUE_U8 = 0xff;
|
|
5849
5850
|
const MAX_VALUE_U16 = 0xffff;
|
|
5850
5851
|
const MAX_VALUE_U32 = 0xffff_ffff;
|
|
5851
5852
|
const MAX_VALUE_U64 = 0xffffffffffffffffn;
|
|
5852
5853
|
/** Attempt to cast an input number into U8. */
|
|
5853
|
-
const numbers_tryAsU8 = (v) =>
|
|
5854
|
+
const numbers_tryAsU8 = (v) => {
|
|
5855
|
+
debug_check `${isU8(v)} input must have one-byte representation, got ${v}`;
|
|
5856
|
+
return asTypedNumber(v);
|
|
5857
|
+
};
|
|
5854
5858
|
/** Check if given number is a valid U8 number. */
|
|
5855
5859
|
const isU8 = (v) => (v & MAX_VALUE_U8) === v;
|
|
5856
5860
|
/** Attempt to cast an input number into U16. */
|
|
5857
|
-
const numbers_tryAsU16 = (v) =>
|
|
5861
|
+
const numbers_tryAsU16 = (v) => {
|
|
5862
|
+
debug_check `${isU16(v)} input must have two-byte representation, got ${v}`;
|
|
5863
|
+
return asTypedNumber(v);
|
|
5864
|
+
};
|
|
5858
5865
|
/** Check if given number is a valid U16 number. */
|
|
5859
5866
|
const isU16 = (v) => (v & MAX_VALUE_U16) === v;
|
|
5860
5867
|
/** Attempt to cast an input number into U32. */
|
|
5861
|
-
const numbers_tryAsU32 = (v) =>
|
|
5868
|
+
const numbers_tryAsU32 = (v) => {
|
|
5869
|
+
debug_check `${isU32(v)} input must have four-byte representation, got ${v}`;
|
|
5870
|
+
return asTypedNumber(v);
|
|
5871
|
+
};
|
|
5862
5872
|
/** Check if given number is a valid U32 number. */
|
|
5863
5873
|
const isU32 = (v) => (v & MAX_VALUE_U32) >>> 0 === v;
|
|
5864
5874
|
/** Attempt to cast an input number into U64. */
|
|
5865
5875
|
const numbers_tryAsU64 = (x) => {
|
|
5866
5876
|
const v = BigInt(x);
|
|
5867
|
-
|
|
5877
|
+
debug_check `${isU64(v)} input must have eight-byte representation, got ${x}`;
|
|
5878
|
+
return asTypedNumber(v);
|
|
5868
5879
|
};
|
|
5869
5880
|
/** Check if given number is a valid U64 number. */
|
|
5870
5881
|
const isU64 = (v) => (v & MAX_VALUE_U64) === v;
|
|
5871
5882
|
/** Collate two U32 parts into one U64. */
|
|
5872
5883
|
const u64FromParts = ({ lower, upper }) => {
|
|
5873
5884
|
const val = (BigInt(upper) << 32n) + BigInt(lower);
|
|
5874
|
-
return
|
|
5885
|
+
return asTypedNumber(val);
|
|
5875
5886
|
};
|
|
5876
5887
|
/** Split U64 into lower & upper parts. */
|
|
5877
5888
|
const u64IntoParts = (v) => {
|
|
5878
|
-
|
|
5879
|
-
const
|
|
5889
|
+
// Number(...) safe: both parts are <= 0xffffffff
|
|
5890
|
+
const lower = Number(v & (2n ** 32n - 1n));
|
|
5891
|
+
const upper = Number(v >> 32n);
|
|
5880
5892
|
return {
|
|
5881
|
-
lower:
|
|
5882
|
-
upper:
|
|
5893
|
+
lower: asTypedNumber(lower),
|
|
5894
|
+
upper: asTypedNumber(upper),
|
|
5883
5895
|
};
|
|
5884
5896
|
};
|
|
5885
5897
|
/**
|
|
@@ -5919,8 +5931,8 @@ function numbers_u32AsLeBytes(value) {
|
|
|
5919
5931
|
* Interpret 4-byte `Uint8Array` as U32 written as little endian.
|
|
5920
5932
|
*/
|
|
5921
5933
|
function leBytesAsU32(uint8Array) {
|
|
5922
|
-
debug_check
|
|
5923
|
-
return
|
|
5934
|
+
debug_check `${uint8Array.length === 4} Input must be a Uint8Array of length 4`;
|
|
5935
|
+
return asTypedNumber(uint8Array[0] | (uint8Array[1] << 8) | (uint8Array[2] << 16) | (uint8Array[3] << 24));
|
|
5924
5936
|
}
|
|
5925
5937
|
/** Get the smallest value between U64 a and values given as input parameters. */
|
|
5926
5938
|
const minU64 = (a, ...values) => values.reduce((min, value) => (value > min ? min : value), a);
|
|
@@ -6268,7 +6280,7 @@ class decoder_Decoder {
|
|
|
6268
6280
|
this.skip(newOffset - this.offset);
|
|
6269
6281
|
}
|
|
6270
6282
|
else {
|
|
6271
|
-
debug_check
|
|
6283
|
+
debug_check `${newOffset >= 0} The offset has to be positive`;
|
|
6272
6284
|
this.offset = newOffset;
|
|
6273
6285
|
}
|
|
6274
6286
|
}
|
|
@@ -6296,7 +6308,7 @@ class decoder_Decoder {
|
|
|
6296
6308
|
return num;
|
|
6297
6309
|
}
|
|
6298
6310
|
ensureHasBytes(bytes) {
|
|
6299
|
-
debug_check
|
|
6311
|
+
debug_check `${bytes >= 0} Negative number of bytes given.`;
|
|
6300
6312
|
if (this.offset + bytes > this.source.length) {
|
|
6301
6313
|
throw new Error(`Attempting to decode more data than there is left. Need ${bytes}, left: ${this.source.length - this.offset}.`);
|
|
6302
6314
|
}
|
|
@@ -6304,7 +6316,7 @@ class decoder_Decoder {
|
|
|
6304
6316
|
}
|
|
6305
6317
|
const MASKS = [0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80];
|
|
6306
6318
|
function decodeVariableLengthExtraBytes(firstByte) {
|
|
6307
|
-
debug_check
|
|
6319
|
+
debug_check `${firstByte >= 0 && firstByte < 256} Incorrect byte value: ${firstByte}`;
|
|
6308
6320
|
for (let i = 0; i < MASKS.length; i++) {
|
|
6309
6321
|
if (firstByte >= MASKS[i]) {
|
|
6310
6322
|
return 8 - i;
|
|
@@ -6459,7 +6471,7 @@ class descriptor_Descriptor {
|
|
|
6459
6471
|
|
|
6460
6472
|
|
|
6461
6473
|
function tryAsExactBytes(a) {
|
|
6462
|
-
debug_check
|
|
6474
|
+
debug_check `${a.isExact} The value is not exact size estimation!`;
|
|
6463
6475
|
return a.bytes;
|
|
6464
6476
|
}
|
|
6465
6477
|
function addSizeHints(a, b) {
|
|
@@ -6566,8 +6578,8 @@ class encoder_Encoder {
|
|
|
6566
6578
|
// we still allow positive numbers from `[maxNum / 2, maxNum)`.
|
|
6567
6579
|
// So it does not matter if the argument is a negative value,
|
|
6568
6580
|
// OR if someone just gave us two-complement already.
|
|
6569
|
-
debug_check
|
|
6570
|
-
debug_check
|
|
6581
|
+
debug_check `${num < maxNum} Only for numbers up to 2**64 - 1`;
|
|
6582
|
+
debug_check `${-num <= maxNum / 2n} Only for numbers down to -2**63`;
|
|
6571
6583
|
this.ensureBigEnough(8);
|
|
6572
6584
|
this.dataView.setBigInt64(this.offset, num, true);
|
|
6573
6585
|
this.offset += 8;
|
|
@@ -6631,8 +6643,8 @@ class encoder_Encoder {
|
|
|
6631
6643
|
// we still allow positive numbers from `[maxNum / 2, maxNum)`.
|
|
6632
6644
|
// So it does not matter if the argument is a negative value,
|
|
6633
6645
|
// OR if someone just gave us two-complement already.
|
|
6634
|
-
debug_check
|
|
6635
|
-
debug_check
|
|
6646
|
+
debug_check `${num < maxNum} Only for numbers up to 2**${BITS * bytesToEncode} - 1`;
|
|
6647
|
+
debug_check `${-num <= maxNum / 2} Only for numbers down to -2**${BITS * bytesToEncode - 1}`;
|
|
6636
6648
|
this.ensureBigEnough(bytesToEncode);
|
|
6637
6649
|
}
|
|
6638
6650
|
/**
|
|
@@ -6643,8 +6655,8 @@ class encoder_Encoder {
|
|
|
6643
6655
|
* https://graypaper.fluffylabs.dev/#/579bd12/365202365202
|
|
6644
6656
|
*/
|
|
6645
6657
|
varU32(num) {
|
|
6646
|
-
debug_check
|
|
6647
|
-
debug_check
|
|
6658
|
+
debug_check `${num >= 0} Only for natural numbers.`;
|
|
6659
|
+
debug_check `${num < 2 ** 32} Only for numbers up to 2**32`;
|
|
6648
6660
|
this.varU64(BigInt(num));
|
|
6649
6661
|
}
|
|
6650
6662
|
/**
|
|
@@ -6795,7 +6807,7 @@ class encoder_Encoder {
|
|
|
6795
6807
|
* https://graypaper.fluffylabs.dev/#/579bd12/374400374400
|
|
6796
6808
|
*/
|
|
6797
6809
|
sequenceVarLen(encode, elements) {
|
|
6798
|
-
debug_check
|
|
6810
|
+
debug_check `${elements.length <= 2 ** 32} Wow, that's a nice long sequence you've got here.`;
|
|
6799
6811
|
this.varU32(numbers_tryAsU32(elements.length));
|
|
6800
6812
|
this.sequenceFixLen(encode, elements);
|
|
6801
6813
|
}
|
|
@@ -6816,7 +6828,7 @@ class encoder_Encoder {
|
|
|
6816
6828
|
* anyway, so if we really should throw we will.
|
|
6817
6829
|
*/
|
|
6818
6830
|
ensureBigEnough(length, options = { silent: false }) {
|
|
6819
|
-
debug_check
|
|
6831
|
+
debug_check `${length >= 0} Negative length given`;
|
|
6820
6832
|
const newLength = this.offset + length;
|
|
6821
6833
|
if (newLength > MAX_LENGTH) {
|
|
6822
6834
|
if (options.silent) {
|
|
@@ -6952,10 +6964,12 @@ class ObjectView {
|
|
|
6952
6964
|
decodeUpTo(field) {
|
|
6953
6965
|
const index = this.descriptorsKeys.indexOf(field);
|
|
6954
6966
|
const lastField = this.descriptorsKeys[this.lastDecodedFieldIdx];
|
|
6955
|
-
debug_check
|
|
6967
|
+
debug_check `
|
|
6968
|
+
${this.lastDecodedFieldIdx < index}
|
|
6969
|
+
Unjustified call to 'decodeUpTo' -
|
|
6956
6970
|
the index ($Blobindex}, ${String(field)})
|
|
6957
6971
|
is already decoded (${this.lastDecodedFieldIdx}, ${String(lastField)}).
|
|
6958
|
-
|
|
6972
|
+
`;
|
|
6959
6973
|
let lastItem = this.cache.get(lastField);
|
|
6960
6974
|
const skipper = new Skipper(this.decoder);
|
|
6961
6975
|
// now skip all of the fields and further populate the cache.
|
|
@@ -6971,8 +6985,10 @@ class ObjectView {
|
|
|
6971
6985
|
this.cache.set(field, lastItem);
|
|
6972
6986
|
this.lastDecodedFieldIdx = i;
|
|
6973
6987
|
}
|
|
6974
|
-
|
|
6975
|
-
|
|
6988
|
+
if (lastItem === undefined) {
|
|
6989
|
+
throw new Error("Last item must be set, since the loop turns at least once.");
|
|
6990
|
+
}
|
|
6991
|
+
return lastItem;
|
|
6976
6992
|
}
|
|
6977
6993
|
}
|
|
6978
6994
|
/**
|
|
@@ -7005,8 +7021,10 @@ class SequenceView {
|
|
|
7005
7021
|
*[Symbol.iterator]() {
|
|
7006
7022
|
for (let i = 0; i < this.length; i++) {
|
|
7007
7023
|
const val = this.get(i);
|
|
7008
|
-
|
|
7009
|
-
|
|
7024
|
+
if (val === undefined) {
|
|
7025
|
+
throw new Error("We are within 0..this.length so all items are defined.");
|
|
7026
|
+
}
|
|
7027
|
+
yield val;
|
|
7010
7028
|
}
|
|
7011
7029
|
}
|
|
7012
7030
|
/** Create an array of all views mapped to some particular value. */
|
|
@@ -7049,7 +7067,10 @@ class SequenceView {
|
|
|
7049
7067
|
return bytes_BytesBlob.blobFrom(this.decoder.source.subarray(this.initialDecoderOffset, this.decoder.bytesRead()));
|
|
7050
7068
|
}
|
|
7051
7069
|
decodeUpTo(index) {
|
|
7052
|
-
debug_check
|
|
7070
|
+
debug_check `
|
|
7071
|
+
${this.lastDecodedIdx < index}
|
|
7072
|
+
Unjustified call to 'decodeUpTo' - the index (${index}) is already decoded (${this.lastDecodedIdx}).
|
|
7073
|
+
`;
|
|
7053
7074
|
let lastItem = this.cache.get(this.lastDecodedIdx);
|
|
7054
7075
|
const skipper = new Skipper(this.decoder);
|
|
7055
7076
|
// now skip all of the fields and further populate the cache.
|
|
@@ -7064,8 +7085,10 @@ class SequenceView {
|
|
|
7064
7085
|
this.cache.set(i, lastItem);
|
|
7065
7086
|
this.lastDecodedIdx = i;
|
|
7066
7087
|
}
|
|
7067
|
-
|
|
7068
|
-
|
|
7088
|
+
if (lastItem === undefined) {
|
|
7089
|
+
throw new Error("Last item must be set, since the loop turns at least once.");
|
|
7090
|
+
}
|
|
7091
|
+
return lastItem;
|
|
7069
7092
|
}
|
|
7070
7093
|
}
|
|
7071
7094
|
|
|
@@ -7098,7 +7121,10 @@ const TYPICAL_DICTIONARY_LENGTH = 32;
|
|
|
7098
7121
|
*/
|
|
7099
7122
|
function readonlyArray(desc) {
|
|
7100
7123
|
return desc.convert((x) => {
|
|
7101
|
-
debug_check
|
|
7124
|
+
debug_check `
|
|
7125
|
+
${Array.isArray(x)}
|
|
7126
|
+
Non-arrays are not supported as 'readonly': got ${typeof x}, ${x}
|
|
7127
|
+
`;
|
|
7102
7128
|
// NOTE [ToDr] This assumption is incorrect in general, but it's documented
|
|
7103
7129
|
// in the general note. We avoid `.slice()` the array for performance reasons.
|
|
7104
7130
|
return x;
|
|
@@ -7546,8 +7572,8 @@ class MultiMap {
|
|
|
7546
7572
|
* if needed.
|
|
7547
7573
|
*/
|
|
7548
7574
|
constructor(keysLength, keyMappers) {
|
|
7549
|
-
check
|
|
7550
|
-
check
|
|
7575
|
+
check `${keysLength > 0} Keys cannot be empty.`;
|
|
7576
|
+
check `${keyMappers === undefined || keyMappers.length === keysLength} Incorrect number of key mappers given!`;
|
|
7551
7577
|
this.data = new Map();
|
|
7552
7578
|
this.keyMappers = keyMappers === undefined ? Array(keysLength).fill(null) : keyMappers;
|
|
7553
7579
|
}
|
|
@@ -7648,7 +7674,7 @@ class sized_array_FixedSizeArray extends Array {
|
|
|
7648
7674
|
this.fixedLength = this.length;
|
|
7649
7675
|
}
|
|
7650
7676
|
static new(data, len) {
|
|
7651
|
-
debug_check
|
|
7677
|
+
debug_check `${data.length === len} Expected an array of size: ${len}, got: ${data.length}`;
|
|
7652
7678
|
const arr = new sized_array_FixedSizeArray(len);
|
|
7653
7679
|
for (let i = 0; i < len; i++) {
|
|
7654
7680
|
arr[i] = data[i];
|
|
@@ -7782,7 +7808,7 @@ class SortedArray {
|
|
|
7782
7808
|
}
|
|
7783
7809
|
/** Create a new SortedSet from two sorted collections. */
|
|
7784
7810
|
static fromTwoSortedCollections(first, second) {
|
|
7785
|
-
debug_check
|
|
7811
|
+
debug_check `${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
7786
7812
|
const comparator = first.comparator;
|
|
7787
7813
|
const arr1 = first.array;
|
|
7788
7814
|
const arr1Length = arr1.length;
|
|
@@ -7902,7 +7928,7 @@ class SortedSet extends SortedArray {
|
|
|
7902
7928
|
}
|
|
7903
7929
|
/** Create a new SortedSet from two sorted collections. */
|
|
7904
7930
|
static fromTwoSortedCollections(first, second) {
|
|
7905
|
-
debug_check
|
|
7931
|
+
debug_check `${first.comparator === second.comparator} Cannot merge arrays if they do not use the same comparator`;
|
|
7906
7932
|
const comparator = first.comparator;
|
|
7907
7933
|
if (first.length === 0) {
|
|
7908
7934
|
return SortedSet.fromSortedArray(comparator, second.array);
|
|
@@ -8540,7 +8566,10 @@ const common_tryAsCoreIndex = (v) => opaque_asOpaqueType(numbers_tryAsU16(v));
|
|
|
8540
8566
|
/** Attempt to convert a number into `Epoch`. */
|
|
8541
8567
|
const tryAsEpoch = (v) => asOpaqueType(tryAsU32(v));
|
|
8542
8568
|
function tryAsPerValidator(array, spec) {
|
|
8543
|
-
debug_check
|
|
8569
|
+
debug_check `
|
|
8570
|
+
${array.length === spec.validatorsCount}
|
|
8571
|
+
Invalid per-validator array length. Expected ${spec.validatorsCount}, got: ${array.length}
|
|
8572
|
+
`;
|
|
8544
8573
|
return sized_array_asKnownSize(array);
|
|
8545
8574
|
}
|
|
8546
8575
|
const codecPerValidator = (val) => codecWithContext((context) => {
|
|
@@ -8549,7 +8578,10 @@ const codecPerValidator = (val) => codecWithContext((context) => {
|
|
|
8549
8578
|
});
|
|
8550
8579
|
});
|
|
8551
8580
|
function tryAsPerEpochBlock(array, spec) {
|
|
8552
|
-
debug_check
|
|
8581
|
+
debug_check `
|
|
8582
|
+
${array.length === spec.epochLength}
|
|
8583
|
+
Invalid per-epoch-block array length. Expected ${spec.epochLength}, got: ${array.length}
|
|
8584
|
+
`;
|
|
8553
8585
|
return sized_array_asKnownSize(array);
|
|
8554
8586
|
}
|
|
8555
8587
|
const codecPerEpochBlock = (val) => codecWithContext((context) => {
|
|
@@ -8820,9 +8852,14 @@ class WorkItem extends WithDebug {
|
|
|
8820
8852
|
|
|
8821
8853
|
|
|
8822
8854
|
|
|
8855
|
+
|
|
8823
8856
|
/** Verify the value is within the `WorkItemsCount` bounds. */
|
|
8824
8857
|
function work_package_tryAsWorkItemsCount(len) {
|
|
8825
|
-
|
|
8858
|
+
debug_check `
|
|
8859
|
+
${len >= MIN_NUMBER_OF_WORK_ITEMS && len <= work_package_MAX_NUMBER_OF_WORK_ITEMS}
|
|
8860
|
+
WorkItemsCount: Expected '${MIN_NUMBER_OF_WORK_ITEMS} <= count <= ${work_package_MAX_NUMBER_OF_WORK_ITEMS}' got ${len}
|
|
8861
|
+
`;
|
|
8862
|
+
return numbers_tryAsU8(len);
|
|
8826
8863
|
}
|
|
8827
8864
|
/** Minimal number of work items in the work package or results in work report. */
|
|
8828
8865
|
const MIN_NUMBER_OF_WORK_ITEMS = 1;
|
|
@@ -10065,7 +10102,10 @@ class AvailabilityAssignment extends WithDebug {
|
|
|
10065
10102
|
|
|
10066
10103
|
/** Check if given array has correct length before casting to the opaque type. */
|
|
10067
10104
|
function tryAsPerCore(array, spec) {
|
|
10068
|
-
debug_check
|
|
10105
|
+
debug_check `
|
|
10106
|
+
${array.length === spec.coresCount}
|
|
10107
|
+
Invalid per-core array length. Expected ${spec.coresCount}, got: ${array.length}
|
|
10108
|
+
`;
|
|
10069
10109
|
return opaque_asOpaqueType(array);
|
|
10070
10110
|
}
|
|
10071
10111
|
const codecPerCore = (val) => codecWithContext((context) => {
|
|
@@ -11316,7 +11356,7 @@ class InMemoryState extends WithDebug {
|
|
|
11316
11356
|
}
|
|
11317
11357
|
removeServices(servicesRemoved) {
|
|
11318
11358
|
for (const serviceId of servicesRemoved ?? []) {
|
|
11319
|
-
debug_check
|
|
11359
|
+
debug_check `${this.services.has(serviceId)} Attempting to remove non-existing service: ${serviceId}`;
|
|
11320
11360
|
this.services.delete(serviceId);
|
|
11321
11361
|
}
|
|
11322
11362
|
}
|
|
@@ -11333,7 +11373,10 @@ class InMemoryState extends WithDebug {
|
|
|
11333
11373
|
}
|
|
11334
11374
|
else if (kind === UpdateStorageKind.Remove) {
|
|
11335
11375
|
const { key } = action;
|
|
11336
|
-
debug_check
|
|
11376
|
+
debug_check `
|
|
11377
|
+
${service.data.storage.has(key.toString())}
|
|
11378
|
+
Attempting to remove non-existing storage item at ${serviceId}: ${action.key}
|
|
11379
|
+
`;
|
|
11337
11380
|
service.data.storage.delete(key.toString());
|
|
11338
11381
|
}
|
|
11339
11382
|
else {
|
|
@@ -12016,12 +12059,12 @@ class TrieNode {
|
|
|
12016
12059
|
}
|
|
12017
12060
|
/** View this node as a branch node */
|
|
12018
12061
|
asBranchNode() {
|
|
12019
|
-
debug_check
|
|
12062
|
+
debug_check `${this.getNodeType() === NodeType.Branch} not a branch!`;
|
|
12020
12063
|
return new BranchNode(this);
|
|
12021
12064
|
}
|
|
12022
12065
|
/** View this node as a leaf node */
|
|
12023
12066
|
asLeafNode() {
|
|
12024
|
-
debug_check
|
|
12067
|
+
debug_check `${this.getNodeType() !== NodeType.Branch} not a leaf!`;
|
|
12025
12068
|
return new LeafNode(this);
|
|
12026
12069
|
}
|
|
12027
12070
|
toString() {
|
|
@@ -12509,7 +12552,7 @@ function createSubtreeForBothLeaves(traversedPath, nodes, leafToReplace, leaf) {
|
|
|
12509
12552
|
* Return a single bit from `key` located at `bitIndex`.
|
|
12510
12553
|
*/
|
|
12511
12554
|
function getBit(key, bitIndex) {
|
|
12512
|
-
debug_check
|
|
12555
|
+
debug_check `${bitIndex < TRUNCATED_KEY_BITS} invalid bit index passed ${bitIndex}`;
|
|
12513
12556
|
const byte = bitIndex >>> 3;
|
|
12514
12557
|
const bit = bitIndex - (byte << 3);
|
|
12515
12558
|
const mask = 0b10_00_00_00 >>> bit;
|
|
@@ -13834,7 +13877,7 @@ class TypedPort {
|
|
|
13834
13877
|
* Send a response given the worker that has previously requested something.
|
|
13835
13878
|
*/
|
|
13836
13879
|
respond(localState, request, data, transferList) {
|
|
13837
|
-
debug_check
|
|
13880
|
+
debug_check `${request.kind === "request"}`;
|
|
13838
13881
|
this.postMessage({
|
|
13839
13882
|
kind: "response",
|
|
13840
13883
|
id: request.id,
|
|
@@ -13865,10 +13908,11 @@ class TypedPort {
|
|
|
13865
13908
|
throw new Error(`Invalid message: ${JSON.stringify(msg)}.`);
|
|
13866
13909
|
}
|
|
13867
13910
|
switch (msg.kind) {
|
|
13868
|
-
case "response":
|
|
13869
|
-
debug_check
|
|
13911
|
+
case "response": {
|
|
13912
|
+
debug_check `${this.responseListeners.eventNames().indexOf(reqEvent(msg.id)) !== -1}`;
|
|
13870
13913
|
this.responseListeners.emit(reqEvent(msg.id), null, msg.data, msg.name, msg.localState, msg);
|
|
13871
13914
|
break;
|
|
13915
|
+
}
|
|
13872
13916
|
case "signal":
|
|
13873
13917
|
this.listeners.emit("signal", msg.name, msg.data, msg.localState, msg);
|
|
13874
13918
|
break;
|
|
@@ -14083,9 +14127,9 @@ class channel_MessageChannelStateMachine {
|
|
|
14083
14127
|
const promise = new Promise((resolve, reject) => {
|
|
14084
14128
|
parentPort.once("message", (value) => {
|
|
14085
14129
|
try {
|
|
14086
|
-
debug_check
|
|
14087
|
-
debug_check
|
|
14088
|
-
debug_check
|
|
14130
|
+
debug_check `${value.kind === "request"} The initial message should be a request with channel.`;
|
|
14131
|
+
debug_check `${value.name === CHANNEL_MESSAGE}`;
|
|
14132
|
+
debug_check `${value.data instanceof external_node_worker_threads_namespaceObject.MessagePort}`;
|
|
14089
14133
|
const port = new TypedPort(value.data);
|
|
14090
14134
|
port.respond(machine.currentState().stateName, value, Ok);
|
|
14091
14135
|
resolve(port);
|
|
@@ -14165,7 +14209,7 @@ class machine_StateMachine {
|
|
|
14165
14209
|
/** Get state object by name. */
|
|
14166
14210
|
getState(name) {
|
|
14167
14211
|
const state = this.allStates.get(name);
|
|
14168
|
-
debug_check
|
|
14212
|
+
debug_check `${state !== undefined} Unable to retrieve state object for ${name}.`;
|
|
14169
14213
|
return state;
|
|
14170
14214
|
}
|
|
14171
14215
|
/** Get the currently active state object. */
|
|
@@ -14430,19 +14474,22 @@ class Preimages {
|
|
|
14430
14474
|
|
|
14431
14475
|
const NO_OF_REGISTERS = 13;
|
|
14432
14476
|
const REGISTER_SIZE_SHIFT = 3;
|
|
14433
|
-
const tryAsRegisterIndex = (index) =>
|
|
14477
|
+
const tryAsRegisterIndex = (index) => {
|
|
14478
|
+
debug_check `${index >= 0 && index < NO_OF_REGISTERS} Incorrect register index: ${index}!`;
|
|
14479
|
+
return opaque_asOpaqueType(index);
|
|
14480
|
+
};
|
|
14434
14481
|
class Registers {
|
|
14435
14482
|
bytes;
|
|
14436
14483
|
asSigned;
|
|
14437
14484
|
asUnsigned;
|
|
14438
14485
|
constructor(bytes = new Uint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
|
|
14439
14486
|
this.bytes = bytes;
|
|
14440
|
-
debug_check
|
|
14487
|
+
debug_check `${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14441
14488
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
14442
14489
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
14443
14490
|
}
|
|
14444
14491
|
static fromBytes(bytes) {
|
|
14445
|
-
debug_check
|
|
14492
|
+
debug_check `${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14446
14493
|
return new Registers(bytes);
|
|
14447
14494
|
}
|
|
14448
14495
|
getBytesAsLittleEndian(index, len) {
|
|
@@ -14588,7 +14635,7 @@ class Mask {
|
|
|
14588
14635
|
return this.lookupTableForward[index] === 0;
|
|
14589
14636
|
}
|
|
14590
14637
|
getNoOfBytesToNextInstruction(index) {
|
|
14591
|
-
debug_check
|
|
14638
|
+
debug_check `${index >= 0} index (${index}) cannot be a negative number`;
|
|
14592
14639
|
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
14593
14640
|
}
|
|
14594
14641
|
buildLookupTableForward(mask) {
|
|
@@ -15588,7 +15635,7 @@ const PAGE_SIZE_SHIFT = 12;
|
|
|
15588
15635
|
const PAGE_SIZE = 1 << PAGE_SIZE_SHIFT;
|
|
15589
15636
|
const MIN_ALLOCATION_SHIFT = (() => {
|
|
15590
15637
|
const MIN_ALLOCATION_SHIFT = 7;
|
|
15591
|
-
debug_check
|
|
15638
|
+
debug_check `${MIN_ALLOCATION_SHIFT >= 0 && MIN_ALLOCATION_SHIFT < PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
15592
15639
|
return MIN_ALLOCATION_SHIFT;
|
|
15593
15640
|
})();
|
|
15594
15641
|
const MIN_ALLOCATION_LENGTH = PAGE_SIZE >> MIN_ALLOCATION_SHIFT;
|
|
@@ -15601,16 +15648,28 @@ const MAX_NUMBER_OF_PAGES = MEMORY_SIZE / PAGE_SIZE;
|
|
|
15601
15648
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/memory-index.ts
|
|
15602
15649
|
|
|
15603
15650
|
|
|
15604
|
-
const tryAsMemoryIndex = (index) =>
|
|
15605
|
-
|
|
15651
|
+
const tryAsMemoryIndex = (index) => {
|
|
15652
|
+
debug_check `${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15653
|
+
return opaque_asOpaqueType(index);
|
|
15654
|
+
};
|
|
15655
|
+
const tryAsSbrkIndex = (index) => {
|
|
15656
|
+
debug_check `${index >= 0 && index <= MAX_MEMORY_INDEX + 1} Incorrect sbrk index: ${index}!`;
|
|
15657
|
+
return opaque_asOpaqueType(index);
|
|
15658
|
+
};
|
|
15606
15659
|
|
|
15607
15660
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/pages/page-utils.ts
|
|
15608
15661
|
|
|
15609
15662
|
|
|
15610
15663
|
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
15611
|
-
const tryAsPageIndex = (index) =>
|
|
15664
|
+
const tryAsPageIndex = (index) => {
|
|
15665
|
+
debug_check `${index >= 0 && index < PAGE_SIZE}, Incorect page index: ${index}!`;
|
|
15666
|
+
return opaque_asOpaqueType(index);
|
|
15667
|
+
};
|
|
15612
15668
|
/** Ensure that given `index` represents an index of one of the pages. */
|
|
15613
|
-
const tryAsPageNumber = (index) =>
|
|
15669
|
+
const tryAsPageNumber = (index) => {
|
|
15670
|
+
debug_check `${index >= 0 && index <= LAST_PAGE_NUMBER}, Incorect page number: ${index}!`;
|
|
15671
|
+
return opaque_asOpaqueType(index);
|
|
15672
|
+
};
|
|
15614
15673
|
/**
|
|
15615
15674
|
* Get the next page number and wrap the result if it is bigger than LAST_PAGE_NUMBER
|
|
15616
15675
|
*
|
|
@@ -16142,10 +16201,10 @@ class MemoryBuilder {
|
|
|
16142
16201
|
*/
|
|
16143
16202
|
setReadablePages(start, end, data = new Uint8Array()) {
|
|
16144
16203
|
this.ensureNotFinalized();
|
|
16145
|
-
debug_check
|
|
16146
|
-
debug_check
|
|
16147
|
-
debug_check
|
|
16148
|
-
debug_check
|
|
16204
|
+
debug_check `${start < end} end has to be bigger than start`;
|
|
16205
|
+
debug_check `${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
16206
|
+
debug_check `${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
16207
|
+
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
16149
16208
|
const length = end - start;
|
|
16150
16209
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
16151
16210
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -16170,10 +16229,10 @@ class MemoryBuilder {
|
|
|
16170
16229
|
*/
|
|
16171
16230
|
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
16172
16231
|
this.ensureNotFinalized();
|
|
16173
|
-
debug_check
|
|
16174
|
-
debug_check
|
|
16175
|
-
debug_check
|
|
16176
|
-
debug_check
|
|
16232
|
+
debug_check `${start < end} end has to be bigger than start`;
|
|
16233
|
+
debug_check `${start % PAGE_SIZE === 0} start needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
16234
|
+
debug_check `${end % PAGE_SIZE === 0} end needs to be a multiple of page size (${PAGE_SIZE})`;
|
|
16235
|
+
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
16177
16236
|
const length = end - start;
|
|
16178
16237
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
16179
16238
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -16195,7 +16254,7 @@ class MemoryBuilder {
|
|
|
16195
16254
|
this.ensureNotFinalized();
|
|
16196
16255
|
const pageOffset = start % PAGE_SIZE;
|
|
16197
16256
|
const remainingSpaceOnPage = PAGE_SIZE - pageOffset;
|
|
16198
|
-
debug_check
|
|
16257
|
+
debug_check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
16199
16258
|
const length = data.length;
|
|
16200
16259
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
16201
16260
|
this.ensureNoReservedMemoryUsage(range);
|
|
@@ -16209,7 +16268,10 @@ class MemoryBuilder {
|
|
|
16209
16268
|
return this;
|
|
16210
16269
|
}
|
|
16211
16270
|
finalize(startHeapIndex, endHeapIndex) {
|
|
16212
|
-
debug_check
|
|
16271
|
+
debug_check `
|
|
16272
|
+
${startHeapIndex <= endHeapIndex}
|
|
16273
|
+
startHeapIndex (${startHeapIndex}) has to be less than or equal to endHeapIndex (${endHeapIndex})
|
|
16274
|
+
`;
|
|
16213
16275
|
this.ensureNotFinalized();
|
|
16214
16276
|
const range = MemoryRange.fromStartAndLength(startHeapIndex, endHeapIndex - startHeapIndex);
|
|
16215
16277
|
const pages = PageRange.fromMemoryRange(range);
|
|
@@ -16447,7 +16509,7 @@ function mulU64(a, b) {
|
|
|
16447
16509
|
*
|
|
16448
16510
|
* The result of multiplication is a 64-bits number and we are only interested in the part that lands in the upper 32-bits.
|
|
16449
16511
|
* For example if we multiply `0xffffffff * 0xffffffff`, we get:
|
|
16450
|
-
|
|
16512
|
+
|
|
16451
16513
|
* | 64-bits | 64-bits |
|
|
16452
16514
|
* +--------------------+--------------------+
|
|
16453
16515
|
* | upper | lower |
|
|
@@ -16483,7 +16545,7 @@ function mulUpperSS(a, b) {
|
|
|
16483
16545
|
return interpretAsSigned(resultLimitedTo64Bits);
|
|
16484
16546
|
}
|
|
16485
16547
|
function unsignedRightShiftBigInt(value, shift) {
|
|
16486
|
-
debug_check
|
|
16548
|
+
debug_check `${shift >= 0} Shift count must be non-negative`;
|
|
16487
16549
|
const fillBit = value < 0 ? "1" : "0";
|
|
16488
16550
|
// Convert the BigInt to its binary representation
|
|
16489
16551
|
const binaryRepresentation = value.toString(2).padStart(64, fillBit);
|
|
@@ -17899,7 +17961,10 @@ class TwoRegsTwoImmsDispatcher {
|
|
|
17899
17961
|
class JumpTable {
|
|
17900
17962
|
indices;
|
|
17901
17963
|
constructor(itemByteLength, bytes) {
|
|
17902
|
-
debug_check
|
|
17964
|
+
debug_check `
|
|
17965
|
+
${itemByteLength === 0 || bytes.length % itemByteLength === 0}
|
|
17966
|
+
Length of jump table (${bytes.length}) should be a multiple of item lenght (${itemByteLength})!
|
|
17967
|
+
`;
|
|
17903
17968
|
const length = itemByteLength === 0 ? 0 : bytes.length / itemByteLength;
|
|
17904
17969
|
this.indices = new Uint32Array(length);
|
|
17905
17970
|
for (let i = 0; i < length; i++) {
|
|
@@ -18343,7 +18408,10 @@ class ReturnValue {
|
|
|
18343
18408
|
this.consumedGas = consumedGas;
|
|
18344
18409
|
this.status = status;
|
|
18345
18410
|
this.memorySlice = memorySlice;
|
|
18346
|
-
debug_check
|
|
18411
|
+
debug_check `
|
|
18412
|
+
${(status === null && memorySlice !== null) || (status !== null && memorySlice === null)}
|
|
18413
|
+
'status' and 'memorySlice' must not both be null or both be non-null — exactly one must be provided
|
|
18414
|
+
`;
|
|
18347
18415
|
}
|
|
18348
18416
|
static fromStatus(consumedGas, status) {
|
|
18349
18417
|
return new ReturnValue(consumedGas, status, null);
|
|
@@ -18392,7 +18460,10 @@ class HostCalls {
|
|
|
18392
18460
|
if (status !== status_Status.HOST) {
|
|
18393
18461
|
return this.getReturnValue(status, pvmInstance);
|
|
18394
18462
|
}
|
|
18395
|
-
debug_check
|
|
18463
|
+
debug_check `
|
|
18464
|
+
${pvmInstance.getExitParam() !== null}
|
|
18465
|
+
"We know that the exit param is not null, because the status is 'Status.HOST'
|
|
18466
|
+
`;
|
|
18396
18467
|
const hostCallIndex = pvmInstance.getExitParam() ?? -1;
|
|
18397
18468
|
const gas = pvmInstance.getGasCounter();
|
|
18398
18469
|
const regs = new HostCallRegisters(pvmInstance.getRegisters());
|
|
@@ -18452,7 +18523,7 @@ class host_calls_manager_HostCallsManager {
|
|
|
18452
18523
|
constructor({ missing, handlers = [], }) {
|
|
18453
18524
|
this.missing = missing;
|
|
18454
18525
|
for (const handler of handlers) {
|
|
18455
|
-
debug_check
|
|
18526
|
+
debug_check `${this.hostCalls.get(handler.index) === undefined} Overwriting host call handler at index ${handler.index}`;
|
|
18456
18527
|
this.hostCalls.set(handler.index, handler);
|
|
18457
18528
|
}
|
|
18458
18529
|
}
|
|
@@ -18575,7 +18646,7 @@ function getServiceId(serviceId) {
|
|
|
18575
18646
|
return null;
|
|
18576
18647
|
}
|
|
18577
18648
|
function writeServiceIdAsLeBytes(serviceId, destination) {
|
|
18578
|
-
debug_check
|
|
18649
|
+
debug_check `${destination.length >= SERVICE_ID_BYTES} Not enough space in the destination.`;
|
|
18579
18650
|
destination.set(numbers_u32AsLeBytes(serviceId));
|
|
18580
18651
|
}
|
|
18581
18652
|
/** Clamp a U64 to the maximum value of a 32-bit unsigned integer. */
|
|
@@ -18664,13 +18735,27 @@ class SpiProgram extends WithDebug {
|
|
|
18664
18735
|
this.registers = registers;
|
|
18665
18736
|
}
|
|
18666
18737
|
}
|
|
18738
|
+
/**
|
|
18739
|
+
* program = E_3(|o|) ++ E_3(|w|) ++ E_2(z) ++ E_3(s) ++ o ++ w ++ E_4(|c|) ++ c
|
|
18740
|
+
*
|
|
18741
|
+
* E_n - little endian encoding, n - length
|
|
18742
|
+
* o - initial read only data
|
|
18743
|
+
* w - initial heap
|
|
18744
|
+
* z - heap pages filled with zeros
|
|
18745
|
+
* s - stack size
|
|
18746
|
+
* c - program code
|
|
18747
|
+
*
|
|
18748
|
+
* https://graypaper.fluffylabs.dev/#/579bd12/2b92022b9202
|
|
18749
|
+
*/
|
|
18667
18750
|
function decodeStandardProgram(program, args) {
|
|
18668
18751
|
const decoder = decoder_Decoder.fromBlob(program);
|
|
18669
18752
|
const oLength = decoder.u24();
|
|
18670
18753
|
const wLength = decoder.u24();
|
|
18671
|
-
|
|
18672
|
-
|
|
18673
|
-
const
|
|
18754
|
+
debug_check `${args.length <= DATA_LEGNTH} Incorrect arguments length`;
|
|
18755
|
+
debug_check `${oLength <= DATA_LEGNTH} Incorrect readonly segment length`;
|
|
18756
|
+
const readOnlyLength = oLength;
|
|
18757
|
+
debug_check `${wLength <= DATA_LEGNTH} Incorrect heap segment length`;
|
|
18758
|
+
const heapLength = wLength;
|
|
18674
18759
|
const noOfHeapZerosPages = decoder.u16();
|
|
18675
18760
|
const stackSize = decoder.u24();
|
|
18676
18761
|
const readOnlyMemory = decoder.bytes(readOnlyLength).raw;
|
|
@@ -18686,14 +18771,14 @@ function decodeStandardProgram(program, args) {
|
|
|
18686
18771
|
const stackStart = STACK_SEGMENT - memory_utils_alignToPageSize(stackSize);
|
|
18687
18772
|
const stackEnd = STACK_SEGMENT;
|
|
18688
18773
|
const argsStart = ARGS_SEGMENT;
|
|
18689
|
-
const argsEnd = argsStart + memory_utils_alignToPageSize(
|
|
18690
|
-
const argsZerosEnd = argsEnd + memory_utils_alignToPageSize(
|
|
18774
|
+
const argsEnd = argsStart + memory_utils_alignToPageSize(args.length);
|
|
18775
|
+
const argsZerosEnd = argsEnd + memory_utils_alignToPageSize(args.length);
|
|
18691
18776
|
function nonEmpty(s) {
|
|
18692
18777
|
return s !== false;
|
|
18693
18778
|
}
|
|
18694
18779
|
const readableMemory = [
|
|
18695
18780
|
readOnlyLength > 0 && getMemorySegment(readonlyDataStart, readonlyDataEnd, readOnlyMemory),
|
|
18696
|
-
|
|
18781
|
+
args.length > 0 && getMemorySegment(argsStart, argsEnd, args),
|
|
18697
18782
|
argsEnd < argsZerosEnd && getMemorySegment(argsEnd, argsZerosEnd),
|
|
18698
18783
|
].filter(nonEmpty);
|
|
18699
18784
|
const writeableMemory = [
|
|
@@ -20216,8 +20301,8 @@ class PartiallyUpdatedState {
|
|
|
20216
20301
|
this.stateUpdate.services.preimages.push(newUpdate);
|
|
20217
20302
|
}
|
|
20218
20303
|
updateServiceStorageUtilisation(serviceId, items, bytes, serviceInfo) {
|
|
20219
|
-
debug_check
|
|
20220
|
-
debug_check
|
|
20304
|
+
debug_check `${items >= 0} storageUtilisationCount has to be a positive number, got: ${items}`;
|
|
20305
|
+
debug_check `${bytes >= 0} storageUtilisationBytes has to be a positive number, got: ${bytes}`;
|
|
20221
20306
|
const overflowItems = !isU32(items);
|
|
20222
20307
|
const overflowBytes = !isU64(bytes);
|
|
20223
20308
|
// TODO [ToDr] this is not specified in GP, but it seems sensible.
|
|
@@ -20642,7 +20727,7 @@ class AccumulateExternalities {
|
|
|
20642
20727
|
}
|
|
20643
20728
|
// TODO [ToDr] Not sure if we should update the service info in that case,
|
|
20644
20729
|
// but for now we let that case fall-through.
|
|
20645
|
-
debug_check
|
|
20730
|
+
debug_check `${len === PreimageStatusKind.Unavailable} preimage is not unavailable`;
|
|
20646
20731
|
}
|
|
20647
20732
|
// make sure we have enough balance for this update
|
|
20648
20733
|
// https://graypaper.fluffylabs.dev/#/9a08063/381201381601?v=0.6.6
|
|
@@ -21138,7 +21223,7 @@ class Assurances {
|
|
|
21138
21223
|
return result_Result.error(AssurancesError.InvalidOrder, `order: expected: ${prevValidatorIndex + 1}, got: ${validatorIndex}`);
|
|
21139
21224
|
}
|
|
21140
21225
|
prevValidatorIndex = assurance.validatorIndex;
|
|
21141
|
-
debug_check
|
|
21226
|
+
debug_check `${bitfield.bitLength === coresCount} Invalid bitfield length of ${bitfield.bitLength}`;
|
|
21142
21227
|
const setBits = bitfield.indicesOfSetBits();
|
|
21143
21228
|
for (const idx of setBits) {
|
|
21144
21229
|
perCoreAssurances[idx] += 1;
|
|
@@ -23462,7 +23547,7 @@ class DeferredTransfers {
|
|
|
23462
23547
|
transferStatistics.set(serviceId, { count: numbers_tryAsU32(transfers.length), gasUsed: common_tryAsServiceGas(consumedGas) });
|
|
23463
23548
|
const [updatedState, checkpointedState] = partialState.getStateUpdates();
|
|
23464
23549
|
currentStateUpdate = updatedState;
|
|
23465
|
-
debug_check
|
|
23550
|
+
debug_check `${checkpointedState === null} On transfer cannot invoke checkpoint.`;
|
|
23466
23551
|
}
|
|
23467
23552
|
return result_Result.ok({
|
|
23468
23553
|
// NOTE: we return only services, since it's impossible to update
|
|
@@ -23800,7 +23885,7 @@ const ENTROPY_BYTES = 32;
|
|
|
23800
23885
|
* https://graypaper.fluffylabs.dev/#/579bd12/3b9a013b9a01
|
|
23801
23886
|
*/
|
|
23802
23887
|
function fisherYatesShuffle(arr, entropy) {
|
|
23803
|
-
debug_check
|
|
23888
|
+
debug_check `${entropy.length === ENTROPY_BYTES} Expected entropy of length ${ENTROPY_BYTES}, got ${entropy.length}`;
|
|
23804
23889
|
const n = arr.length;
|
|
23805
23890
|
const randomNumbers = hashToNumberSequence(entropy, arr.length);
|
|
23806
23891
|
const result = new Array(n);
|
|
@@ -24647,7 +24732,7 @@ class Statistics {
|
|
|
24647
24732
|
/** get statistics for the current epoch */
|
|
24648
24733
|
const statistics = this.getStatistics(slot);
|
|
24649
24734
|
const { current, cores, services } = statistics;
|
|
24650
|
-
debug_check
|
|
24735
|
+
debug_check `${current[authorIndex] !== undefined} authorIndex is out of bounds`;
|
|
24651
24736
|
/** One validator can produce maximal one block per timeslot */
|
|
24652
24737
|
const newBlocksCount = current[authorIndex].blocks + 1;
|
|
24653
24738
|
current[authorIndex].blocks = numbers_tryAsU32(newBlocksCount);
|