@typeberry/lib 0.1.3-707962d → 0.1.3-d3752d8
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/index.cjs +64 -22
- package/index.d.ts +77 -27
- package/index.js +64 -22
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -332,6 +332,19 @@ const Result$1 = {
|
|
|
332
332
|
},
|
|
333
333
|
};
|
|
334
334
|
|
|
335
|
+
// about 2GB, the maximum ArrayBuffer length on Chrome confirmed by several sources:
|
|
336
|
+
// - https://issues.chromium.org/issues/40055619
|
|
337
|
+
// - https://stackoverflow.com/a/72124984
|
|
338
|
+
// - https://onnxruntime.ai/docs/tutorials/web/large-models.html#maximum-size-of-arraybuffer
|
|
339
|
+
const MAX_LENGTH$2 = 2145386496;
|
|
340
|
+
function safeAllocUint8Array(length) {
|
|
341
|
+
if (length > MAX_LENGTH$2) {
|
|
342
|
+
// biome-ignore lint/suspicious/noConsole: can't have a dependency on logger here
|
|
343
|
+
console.warn(`Trying to allocate ${length} bytes, which is greater than the maximum of ${MAX_LENGTH$2}.`);
|
|
344
|
+
}
|
|
345
|
+
return new Uint8Array(Math.min(MAX_LENGTH$2, length));
|
|
346
|
+
}
|
|
347
|
+
|
|
335
348
|
/**
|
|
336
349
|
* Utilities for tests.
|
|
337
350
|
*/
|
|
@@ -572,6 +585,7 @@ var index$u = /*#__PURE__*/Object.freeze({
|
|
|
572
585
|
DEFAULT_VERSION: DEFAULT_VERSION,
|
|
573
586
|
ErrorsCollector: ErrorsCollector,
|
|
574
587
|
get GpVersion () { return GpVersion; },
|
|
588
|
+
MAX_LENGTH: MAX_LENGTH$2,
|
|
575
589
|
OK: OK,
|
|
576
590
|
Result: Result$1,
|
|
577
591
|
TEST_COMPARE_USING: TEST_COMPARE_USING,
|
|
@@ -586,6 +600,7 @@ var index$u = /*#__PURE__*/Object.freeze({
|
|
|
586
600
|
isBrowser: isBrowser,
|
|
587
601
|
measure: measure,
|
|
588
602
|
resultToString: resultToString,
|
|
603
|
+
safeAllocUint8Array: safeAllocUint8Array,
|
|
589
604
|
seeThrough: seeThrough,
|
|
590
605
|
workspacePathFix: workspacePathFix
|
|
591
606
|
});
|
|
@@ -609,7 +624,7 @@ class BitVec {
|
|
|
609
624
|
* Create new [`BitVec`] with all values set to `false`.
|
|
610
625
|
*/
|
|
611
626
|
static empty(bitLength) {
|
|
612
|
-
const data =
|
|
627
|
+
const data = safeAllocUint8Array(Math.ceil(bitLength / 8));
|
|
613
628
|
return new BitVec(data, bitLength);
|
|
614
629
|
}
|
|
615
630
|
byteLength;
|
|
@@ -810,7 +825,7 @@ class BytesBlob {
|
|
|
810
825
|
static blobFromParts(v, ...rest) {
|
|
811
826
|
const vArr = v instanceof Uint8Array ? [v] : v;
|
|
812
827
|
const totalLength = vArr.reduce((a, v) => a + v.length, 0) + rest.reduce((a, v) => a + v.length, 0);
|
|
813
|
-
const buffer =
|
|
828
|
+
const buffer = safeAllocUint8Array(totalLength);
|
|
814
829
|
let offset = 0;
|
|
815
830
|
for (const r of vArr) {
|
|
816
831
|
buffer.set(r, offset);
|
|
@@ -883,7 +898,7 @@ class Bytes extends BytesBlob {
|
|
|
883
898
|
}
|
|
884
899
|
/** Create an empty [`Bytes<X>`] of given length. */
|
|
885
900
|
static zero(len) {
|
|
886
|
-
return new Bytes(
|
|
901
|
+
return new Bytes(safeAllocUint8Array(len), len);
|
|
887
902
|
}
|
|
888
903
|
// TODO [ToDr] `fill` should have the argments swapped to align with the rest.
|
|
889
904
|
/** Create a [`Bytes<X>`] with all bytes filled with given input number. */
|
|
@@ -3592,7 +3607,7 @@ async function verify(input) {
|
|
|
3592
3607
|
return Promise.resolve([]);
|
|
3593
3608
|
}
|
|
3594
3609
|
const dataLength = input.reduce((acc, { message, key, signature }) => acc + key.length + signature.length + message.length + 1, 0);
|
|
3595
|
-
const data =
|
|
3610
|
+
const data = safeAllocUint8Array(dataLength);
|
|
3596
3611
|
let offset = 0;
|
|
3597
3612
|
for (const { key, message, signature } of input) {
|
|
3598
3613
|
data.set(key.raw, offset);
|
|
@@ -3684,7 +3699,7 @@ class SimpleAllocator {
|
|
|
3684
3699
|
/** An allocator that works by allocating larger (continuous) pages of memory. */
|
|
3685
3700
|
class PageAllocator {
|
|
3686
3701
|
hashesPerPage;
|
|
3687
|
-
page =
|
|
3702
|
+
page = safeAllocUint8Array(0);
|
|
3688
3703
|
currentHash = 0;
|
|
3689
3704
|
// TODO [ToDr] Benchmark the performance!
|
|
3690
3705
|
constructor(hashesPerPage) {
|
|
@@ -3695,7 +3710,7 @@ class PageAllocator {
|
|
|
3695
3710
|
resetPage() {
|
|
3696
3711
|
const pageSizeBytes = this.hashesPerPage * HASH_SIZE;
|
|
3697
3712
|
this.currentHash = 0;
|
|
3698
|
-
this.page =
|
|
3713
|
+
this.page = safeAllocUint8Array(pageSizeBytes);
|
|
3699
3714
|
}
|
|
3700
3715
|
emptyHash() {
|
|
3701
3716
|
const startIdx = this.currentHash * HASH_SIZE;
|
|
@@ -8731,6 +8746,10 @@ class DisputesRecords {
|
|
|
8731
8746
|
static create({ goodSet, badSet, wonkySet, punishSet }) {
|
|
8732
8747
|
return new DisputesRecords(goodSet, badSet, wonkySet, punishSet);
|
|
8733
8748
|
}
|
|
8749
|
+
goodSetDict;
|
|
8750
|
+
badSetDict;
|
|
8751
|
+
wonkySetDict;
|
|
8752
|
+
punishSetDict;
|
|
8734
8753
|
constructor(
|
|
8735
8754
|
/** `goodSet`: all work-reports hashes which were judged to be correct */
|
|
8736
8755
|
goodSet,
|
|
@@ -8744,6 +8763,18 @@ class DisputesRecords {
|
|
|
8744
8763
|
this.badSet = badSet;
|
|
8745
8764
|
this.wonkySet = wonkySet;
|
|
8746
8765
|
this.punishSet = punishSet;
|
|
8766
|
+
this.goodSetDict = HashSet.from(goodSet.array);
|
|
8767
|
+
this.badSetDict = HashSet.from(badSet.array);
|
|
8768
|
+
this.wonkySetDict = HashSet.from(wonkySet.array);
|
|
8769
|
+
this.punishSetDict = HashSet.from(punishSet.array);
|
|
8770
|
+
}
|
|
8771
|
+
asDictionaries() {
|
|
8772
|
+
return {
|
|
8773
|
+
goodSet: this.goodSetDict,
|
|
8774
|
+
badSet: this.badSetDict,
|
|
8775
|
+
wonkySet: this.wonkySetDict,
|
|
8776
|
+
punishSet: this.punishSetDict,
|
|
8777
|
+
};
|
|
8747
8778
|
}
|
|
8748
8779
|
static fromSortedArrays({ goodSet, badSet, wonkySet, punishSet, }) {
|
|
8749
8780
|
return new DisputesRecords(SortedSet.fromSortedArray(hashComparator, goodSet), SortedSet.fromSortedArray(hashComparator, badSet), SortedSet.fromSortedArray(hashComparator, wonkySet), SortedSet.fromSortedArray(hashComparator, punishSet));
|
|
@@ -10447,7 +10478,7 @@ class SerializedService {
|
|
|
10447
10478
|
getStorage(rawKey) {
|
|
10448
10479
|
if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
|
|
10449
10480
|
const SERVICE_ID_BYTES = 4;
|
|
10450
|
-
const serviceIdAndKey =
|
|
10481
|
+
const serviceIdAndKey = safeAllocUint8Array(SERVICE_ID_BYTES + rawKey.length);
|
|
10451
10482
|
serviceIdAndKey.set(u32AsLeBytes(this.serviceId));
|
|
10452
10483
|
serviceIdAndKey.set(rawKey.raw, SERVICE_ID_BYTES);
|
|
10453
10484
|
const key = asOpaqueType(BytesBlob.blobFrom(hashBytes(serviceIdAndKey).raw));
|
|
@@ -10532,7 +10563,7 @@ class TrieNode {
|
|
|
10532
10563
|
raw;
|
|
10533
10564
|
constructor(
|
|
10534
10565
|
/** Exactly 512 bits / 64 bytes */
|
|
10535
|
-
raw =
|
|
10566
|
+
raw = safeAllocUint8Array(TRIE_NODE_BYTES)) {
|
|
10536
10567
|
this.raw = raw;
|
|
10537
10568
|
}
|
|
10538
10569
|
/** Returns the type of the node */
|
|
@@ -11783,7 +11814,7 @@ function padAndEncodeData(input) {
|
|
|
11783
11814
|
const paddedLength = Math.ceil(input.length / PIECE_SIZE) * PIECE_SIZE;
|
|
11784
11815
|
let padded = input;
|
|
11785
11816
|
if (input.length !== paddedLength) {
|
|
11786
|
-
padded = BytesBlob.blobFrom(
|
|
11817
|
+
padded = BytesBlob.blobFrom(safeAllocUint8Array(paddedLength));
|
|
11787
11818
|
padded.raw.set(input.raw, 0);
|
|
11788
11819
|
}
|
|
11789
11820
|
return chunkingFunction(padded);
|
|
@@ -11829,7 +11860,7 @@ function decodeData(input) {
|
|
|
11829
11860
|
*/
|
|
11830
11861
|
function encodePoints(input) {
|
|
11831
11862
|
const result = [];
|
|
11832
|
-
const data =
|
|
11863
|
+
const data = safeAllocUint8Array(POINT_ALIGNMENT * N_CHUNKS_REQUIRED);
|
|
11833
11864
|
// add original shards to the result
|
|
11834
11865
|
for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
|
|
11835
11866
|
const pointStart = POINT_LENGTH * i;
|
|
@@ -11845,7 +11876,7 @@ function encodePoints(input) {
|
|
|
11845
11876
|
const encodedData = encodedResult.take_data();
|
|
11846
11877
|
for (let i = 0; i < N_CHUNKS_REDUNDANCY; i++) {
|
|
11847
11878
|
const pointIndex = i * POINT_ALIGNMENT;
|
|
11848
|
-
const redundancyPoint =
|
|
11879
|
+
const redundancyPoint = safeAllocUint8Array(POINT_LENGTH);
|
|
11849
11880
|
for (let j = 0; j < POINT_LENGTH; j++) {
|
|
11850
11881
|
redundancyPoint[j] = encodedData[pointIndex + j * HALF_POINT_SIZE];
|
|
11851
11882
|
}
|
|
@@ -11860,7 +11891,7 @@ function encodePoints(input) {
|
|
|
11860
11891
|
*/
|
|
11861
11892
|
function decodePiece(input) {
|
|
11862
11893
|
const result = Bytes.zero(PIECE_SIZE);
|
|
11863
|
-
const data =
|
|
11894
|
+
const data = safeAllocUint8Array(N_CHUNKS_REQUIRED * POINT_ALIGNMENT);
|
|
11864
11895
|
const indices = new Uint16Array(input.length);
|
|
11865
11896
|
for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
|
|
11866
11897
|
const [index, points] = input[i];
|
|
@@ -11976,7 +12007,7 @@ function lace(input) {
|
|
|
11976
12007
|
return BytesBlob.empty();
|
|
11977
12008
|
}
|
|
11978
12009
|
const n = input[0].length;
|
|
11979
|
-
const result = BytesBlob.blobFrom(
|
|
12010
|
+
const result = BytesBlob.blobFrom(safeAllocUint8Array(k * n));
|
|
11980
12011
|
for (let i = 0; i < k; i++) {
|
|
11981
12012
|
const entry = input[i].raw;
|
|
11982
12013
|
for (let j = 0; j < n; j++) {
|
|
@@ -13255,7 +13286,7 @@ class Registers {
|
|
|
13255
13286
|
bytes;
|
|
13256
13287
|
asSigned;
|
|
13257
13288
|
asUnsigned;
|
|
13258
|
-
constructor(bytes =
|
|
13289
|
+
constructor(bytes = safeAllocUint8Array(NO_OF_REGISTERS$1 << REGISTER_SIZE_SHIFT)) {
|
|
13259
13290
|
this.bytes = bytes;
|
|
13260
13291
|
check `${bytes.length === NO_OF_REGISTERS$1 << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
13261
13292
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
@@ -13327,10 +13358,16 @@ function signExtend32To64(value) {
|
|
|
13327
13358
|
|
|
13328
13359
|
/** Attempt to convert a number into `HostCallIndex`. */
|
|
13329
13360
|
const tryAsHostCallIndex = (v) => asOpaqueType(tryAsU32(v));
|
|
13361
|
+
/**
|
|
13362
|
+
* Host-call exit reason.
|
|
13363
|
+
*
|
|
13364
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
13365
|
+
*/
|
|
13330
13366
|
var PvmExecution;
|
|
13331
13367
|
(function (PvmExecution) {
|
|
13332
13368
|
PvmExecution[PvmExecution["Halt"] = 0] = "Halt";
|
|
13333
13369
|
PvmExecution[PvmExecution["Panic"] = 1] = "Panic";
|
|
13370
|
+
PvmExecution[PvmExecution["OOG"] = 2] = "OOG";
|
|
13334
13371
|
})(PvmExecution || (PvmExecution = {}));
|
|
13335
13372
|
/** A utility function to easily trace a bunch of registers. */
|
|
13336
13373
|
function traceRegisters(...regs) {
|
|
@@ -13402,7 +13439,7 @@ class Mask {
|
|
|
13402
13439
|
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
13403
13440
|
}
|
|
13404
13441
|
buildLookupTableForward(mask) {
|
|
13405
|
-
const table =
|
|
13442
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
13406
13443
|
let lastInstructionOffset = 0;
|
|
13407
13444
|
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
13408
13445
|
if (mask.isSet(i)) {
|
|
@@ -16937,7 +16974,7 @@ class HostCalls {
|
|
|
16937
16974
|
const regs = pvmInstance.getRegisters();
|
|
16938
16975
|
const maybeAddress = regs.getLowerU32(7);
|
|
16939
16976
|
const maybeLength = regs.getLowerU32(8);
|
|
16940
|
-
const result =
|
|
16977
|
+
const result = safeAllocUint8Array(maybeLength);
|
|
16941
16978
|
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
16942
16979
|
const loadResult = memory.loadInto(result, startAddress);
|
|
16943
16980
|
if (loadResult.isError) {
|
|
@@ -16965,8 +17002,9 @@ class HostCalls {
|
|
|
16965
17002
|
const index = tryAsHostCallIndex(hostCallIndex);
|
|
16966
17003
|
const hostCall = this.hostCalls.get(index);
|
|
16967
17004
|
const gasBefore = gas.get();
|
|
16968
|
-
|
|
16969
|
-
const
|
|
17005
|
+
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
17006
|
+
const basicGasCost = typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
17007
|
+
const underflow = gas.sub(basicGasCost);
|
|
16970
17008
|
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
16971
17009
|
if (underflow) {
|
|
16972
17010
|
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
@@ -16983,6 +17021,10 @@ class HostCalls {
|
|
|
16983
17021
|
status = Status.PANIC;
|
|
16984
17022
|
return this.getReturnValue(status, pvmInstance);
|
|
16985
17023
|
}
|
|
17024
|
+
if (result === PvmExecution.OOG) {
|
|
17025
|
+
status = Status.OOG;
|
|
17026
|
+
return this.getReturnValue(status, pvmInstance);
|
|
17027
|
+
}
|
|
16986
17028
|
if (result === undefined) {
|
|
16987
17029
|
pvmInstance.runProgram();
|
|
16988
17030
|
status = pvmInstance.getStatus();
|
|
@@ -17281,14 +17323,14 @@ class DebuggerAdapter {
|
|
|
17281
17323
|
const page = this.pvm.getMemoryPage(pageNumber);
|
|
17282
17324
|
if (page === null) {
|
|
17283
17325
|
// page wasn't allocated so we return an empty page
|
|
17284
|
-
return
|
|
17326
|
+
return safeAllocUint8Array(PAGE_SIZE$1);
|
|
17285
17327
|
}
|
|
17286
17328
|
if (page.length === PAGE_SIZE$1) {
|
|
17287
17329
|
// page was allocated and has a proper size so we can simply return it
|
|
17288
17330
|
return page;
|
|
17289
17331
|
}
|
|
17290
17332
|
// page was allocated but it is shorter than PAGE_SIZE so we have to extend it
|
|
17291
|
-
const fullPage =
|
|
17333
|
+
const fullPage = safeAllocUint8Array(PAGE_SIZE$1);
|
|
17292
17334
|
fullPage.set(page);
|
|
17293
17335
|
return fullPage;
|
|
17294
17336
|
}
|
|
@@ -17432,7 +17474,7 @@ function fisherYatesShuffle(arr, entropy) {
|
|
|
17432
17474
|
}
|
|
17433
17475
|
function hashToNumberSequence(entropy, length) {
|
|
17434
17476
|
const result = new Array(length);
|
|
17435
|
-
const randomBytes =
|
|
17477
|
+
const randomBytes = safeAllocUint8Array(ENTROPY_BYTES + 4);
|
|
17436
17478
|
randomBytes.set(entropy.raw);
|
|
17437
17479
|
for (let i = 0; i < length; i++) {
|
|
17438
17480
|
randomBytes.set(u32AsLeBytes(tryAsU32(Math.floor(i / 8))), ENTROPY_BYTES);
|
|
@@ -17972,7 +18014,7 @@ class Preimages {
|
|
|
17972
18014
|
|
|
17973
18015
|
class Missing {
|
|
17974
18016
|
index = tryAsHostCallIndex(2 ** 32 - 1);
|
|
17975
|
-
|
|
18017
|
+
basicGasCost = tryAsSmallGas(10);
|
|
17976
18018
|
currentServiceId = CURRENT_SERVICE_ID;
|
|
17977
18019
|
tracedRegisters = traceRegisters(7);
|
|
17978
18020
|
execute(_gas, regs, _memory) {
|
package/index.d.ts
CHANGED
|
@@ -420,6 +420,20 @@ declare const Result$2 = {
|
|
|
420
420
|
},
|
|
421
421
|
};
|
|
422
422
|
|
|
423
|
+
// about 2GB, the maximum ArrayBuffer length on Chrome confirmed by several sources:
|
|
424
|
+
// - https://issues.chromium.org/issues/40055619
|
|
425
|
+
// - https://stackoverflow.com/a/72124984
|
|
426
|
+
// - https://onnxruntime.ai/docs/tutorials/web/large-models.html#maximum-size-of-arraybuffer
|
|
427
|
+
declare const MAX_LENGTH$1 = 2145386496;
|
|
428
|
+
|
|
429
|
+
declare function safeAllocUint8Array(length: number) {
|
|
430
|
+
if (length > MAX_LENGTH) {
|
|
431
|
+
// biome-ignore lint/suspicious/noConsole: can't have a dependency on logger here
|
|
432
|
+
console.warn(`Trying to allocate ${length} bytes, which is greater than the maximum of ${MAX_LENGTH}.`);
|
|
433
|
+
}
|
|
434
|
+
return new Uint8Array(Math.min(MAX_LENGTH, length));
|
|
435
|
+
}
|
|
436
|
+
|
|
423
437
|
/**
|
|
424
438
|
* Utilities for tests.
|
|
425
439
|
*/
|
|
@@ -755,11 +769,12 @@ declare const index$u_oomWarningPrinted: typeof oomWarningPrinted;
|
|
|
755
769
|
declare const index$u_parseCurrentSuite: typeof parseCurrentSuite;
|
|
756
770
|
declare const index$u_parseCurrentVersion: typeof parseCurrentVersion;
|
|
757
771
|
declare const index$u_resultToString: typeof resultToString;
|
|
772
|
+
declare const index$u_safeAllocUint8Array: typeof safeAllocUint8Array;
|
|
758
773
|
declare const index$u_seeThrough: typeof seeThrough;
|
|
759
774
|
declare const index$u_trimStack: typeof trimStack;
|
|
760
775
|
declare const index$u_workspacePathFix: typeof workspacePathFix;
|
|
761
776
|
declare namespace index$u {
|
|
762
|
-
export { index$u_ALL_VERSIONS_IN_ORDER as ALL_VERSIONS_IN_ORDER, index$u_CURRENT_SUITE as CURRENT_SUITE, index$u_CURRENT_VERSION as CURRENT_VERSION, index$u_Compatibility as Compatibility, index$u_DEFAULT_SUITE as DEFAULT_SUITE, index$u_DEFAULT_VERSION as DEFAULT_VERSION, index$u_ErrorsCollector as ErrorsCollector, index$u_GpVersion as GpVersion, Result$2 as Result, index$u_RichTaggedError as RichTaggedError, index$u_TEST_COMPARE_USING as TEST_COMPARE_USING, index$u_TestSuite as TestSuite, index$u_WithDebug as WithDebug, index$u___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$u_asOpaqueType as asOpaqueType, index$u_assertEmpty as assertEmpty, index$u_assertNever as assertNever, index$u_callCompareFunction as callCompareFunction, index$u_check as check, index$u_deepEqual as deepEqual, index$u_getAllKeysSorted as getAllKeysSorted, index$u_inspect as inspect, index$u_isBrowser as isBrowser, index$u_isResult as isResult, index$u_isTaggedError as isTaggedError, index$u_maybeTaggedErrorToString as maybeTaggedErrorToString, index$u_measure as measure, index$u_oomWarningPrinted as oomWarningPrinted, index$u_parseCurrentSuite as parseCurrentSuite, index$u_parseCurrentVersion as parseCurrentVersion, index$u_resultToString as resultToString, index$u_seeThrough as seeThrough, index$u_trimStack as trimStack, index$u_workspacePathFix as workspacePathFix };
|
|
777
|
+
export { index$u_ALL_VERSIONS_IN_ORDER as ALL_VERSIONS_IN_ORDER, index$u_CURRENT_SUITE as CURRENT_SUITE, index$u_CURRENT_VERSION as CURRENT_VERSION, index$u_Compatibility as Compatibility, index$u_DEFAULT_SUITE as DEFAULT_SUITE, index$u_DEFAULT_VERSION as DEFAULT_VERSION, index$u_ErrorsCollector as ErrorsCollector, index$u_GpVersion as GpVersion, MAX_LENGTH$1 as MAX_LENGTH, Result$2 as Result, index$u_RichTaggedError as RichTaggedError, index$u_TEST_COMPARE_USING as TEST_COMPARE_USING, index$u_TestSuite as TestSuite, index$u_WithDebug as WithDebug, index$u___OPAQUE_TYPE__ as __OPAQUE_TYPE__, index$u_asOpaqueType as asOpaqueType, index$u_assertEmpty as assertEmpty, index$u_assertNever as assertNever, index$u_callCompareFunction as callCompareFunction, index$u_check as check, index$u_deepEqual as deepEqual, index$u_getAllKeysSorted as getAllKeysSorted, index$u_inspect as inspect, index$u_isBrowser as isBrowser, index$u_isResult as isResult, index$u_isTaggedError as isTaggedError, index$u_maybeTaggedErrorToString as maybeTaggedErrorToString, index$u_measure as measure, index$u_oomWarningPrinted as oomWarningPrinted, index$u_parseCurrentSuite as parseCurrentSuite, index$u_parseCurrentVersion as parseCurrentVersion, index$u_resultToString as resultToString, index$u_safeAllocUint8Array as safeAllocUint8Array, index$u_seeThrough as seeThrough, index$u_trimStack as trimStack, index$u_workspacePathFix as workspacePathFix };
|
|
763
778
|
export type { index$u_DeepEqualOptions as DeepEqualOptions, index$u_EnumMapping as EnumMapping, index$u_ErrorResult as ErrorResult, index$u_OK as OK, index$u_OkResult as OkResult, index$u_Opaque as Opaque, index$u_StringLiteral as StringLiteral, index$u_TaggedError as TaggedError, index$u_TokenOf as TokenOf, index$u_Uninstantiable as Uninstantiable, index$u_WithOpaque as WithOpaque };
|
|
764
779
|
}
|
|
765
780
|
|
|
@@ -929,7 +944,7 @@ declare class BytesBlob {
|
|
|
929
944
|
static blobFromParts(v: Uint8Array | Uint8Array[], ...rest: Uint8Array[]) {
|
|
930
945
|
const vArr = v instanceof Uint8Array ? [v] : v;
|
|
931
946
|
const totalLength = vArr.reduce((a, v) => a + v.length, 0) + rest.reduce((a, v) => a + v.length, 0);
|
|
932
|
-
const buffer =
|
|
947
|
+
const buffer = safeAllocUint8Array(totalLength);
|
|
933
948
|
let offset = 0;
|
|
934
949
|
for (const r of vArr) {
|
|
935
950
|
buffer.set(r, offset);
|
|
@@ -1012,7 +1027,7 @@ declare class Bytes<T extends number> extends BytesBlob {
|
|
|
1012
1027
|
|
|
1013
1028
|
/** Create an empty [`Bytes<X>`] of given length. */
|
|
1014
1029
|
static zero<X extends number>(len: X): Bytes<X> {
|
|
1015
|
-
return new Bytes(
|
|
1030
|
+
return new Bytes(safeAllocUint8Array(len), len);
|
|
1016
1031
|
}
|
|
1017
1032
|
|
|
1018
1033
|
// TODO [ToDr] `fill` should have the argments swapped to align with the rest.
|
|
@@ -1133,7 +1148,7 @@ declare class BitVec {
|
|
|
1133
1148
|
* Create new [`BitVec`] with all values set to `false`.
|
|
1134
1149
|
*/
|
|
1135
1150
|
static empty(bitLength: number) {
|
|
1136
|
-
const data =
|
|
1151
|
+
const data = safeAllocUint8Array(Math.ceil(bitLength / 8));
|
|
1137
1152
|
return new BitVec(data, bitLength);
|
|
1138
1153
|
}
|
|
1139
1154
|
|
|
@@ -3531,7 +3546,7 @@ declare class SimpleAllocator implements HashAllocator {
|
|
|
3531
3546
|
|
|
3532
3547
|
/** An allocator that works by allocating larger (continuous) pages of memory. */
|
|
3533
3548
|
declare class PageAllocator implements HashAllocator {
|
|
3534
|
-
private page: Uint8Array =
|
|
3549
|
+
private page: Uint8Array = safeAllocUint8Array(0);
|
|
3535
3550
|
private currentHash = 0;
|
|
3536
3551
|
|
|
3537
3552
|
// TODO [ToDr] Benchmark the performance!
|
|
@@ -3543,7 +3558,7 @@ declare class PageAllocator implements HashAllocator {
|
|
|
3543
3558
|
private resetPage() {
|
|
3544
3559
|
const pageSizeBytes = this.hashesPerPage * HASH_SIZE;
|
|
3545
3560
|
this.currentHash = 0;
|
|
3546
|
-
this.page =
|
|
3561
|
+
this.page = safeAllocUint8Array(pageSizeBytes);
|
|
3547
3562
|
}
|
|
3548
3563
|
|
|
3549
3564
|
emptyHash(): OpaqueHash {
|
|
@@ -4735,7 +4750,7 @@ declare async function verify<T extends BytesBlob>(input: Input<T>[]): Promise<b
|
|
|
4735
4750
|
(acc, { message, key, signature }) => acc + key.length + signature.length + message.length + 1,
|
|
4736
4751
|
0,
|
|
4737
4752
|
);
|
|
4738
|
-
const data =
|
|
4753
|
+
const data = safeAllocUint8Array(dataLength);
|
|
4739
4754
|
|
|
4740
4755
|
let offset = 0;
|
|
4741
4756
|
|
|
@@ -8373,7 +8388,7 @@ declare enum NodeType {
|
|
|
8373
8388
|
declare class TrieNode {
|
|
8374
8389
|
constructor(
|
|
8375
8390
|
/** Exactly 512 bits / 64 bytes */
|
|
8376
|
-
public readonly raw: Uint8Array =
|
|
8391
|
+
public readonly raw: Uint8Array = safeAllocUint8Array(TRIE_NODE_BYTES),
|
|
8377
8392
|
) {}
|
|
8378
8393
|
|
|
8379
8394
|
/** Returns the type of the node */
|
|
@@ -9196,6 +9211,11 @@ declare class DisputesRecords {
|
|
|
9196
9211
|
return new DisputesRecords(goodSet, badSet, wonkySet, punishSet);
|
|
9197
9212
|
}
|
|
9198
9213
|
|
|
9214
|
+
private readonly goodSetDict: ImmutableHashSet<WorkReportHash>;
|
|
9215
|
+
private readonly badSetDict: ImmutableHashSet<WorkReportHash>;
|
|
9216
|
+
private readonly wonkySetDict: ImmutableHashSet<WorkReportHash>;
|
|
9217
|
+
private readonly punishSetDict: ImmutableHashSet<Ed25519Key>;
|
|
9218
|
+
|
|
9199
9219
|
private constructor(
|
|
9200
9220
|
/** `goodSet`: all work-reports hashes which were judged to be correct */
|
|
9201
9221
|
public readonly goodSet: ImmutableSortedSet<WorkReportHash>,
|
|
@@ -9205,7 +9225,21 @@ declare class DisputesRecords {
|
|
|
9205
9225
|
public readonly wonkySet: ImmutableSortedSet<WorkReportHash>,
|
|
9206
9226
|
/** `punishSet`: set of Ed25519 keys representing validators which were found to have misjudged a work-report */
|
|
9207
9227
|
public readonly punishSet: ImmutableSortedSet<Ed25519Key>,
|
|
9208
|
-
) {
|
|
9228
|
+
) {
|
|
9229
|
+
this.goodSetDict = HashSet.from(goodSet.array);
|
|
9230
|
+
this.badSetDict = HashSet.from(badSet.array);
|
|
9231
|
+
this.wonkySetDict = HashSet.from(wonkySet.array);
|
|
9232
|
+
this.punishSetDict = HashSet.from(punishSet.array);
|
|
9233
|
+
}
|
|
9234
|
+
|
|
9235
|
+
public asDictionaries() {
|
|
9236
|
+
return {
|
|
9237
|
+
goodSet: this.goodSetDict,
|
|
9238
|
+
badSet: this.badSetDict,
|
|
9239
|
+
wonkySet: this.wonkySetDict,
|
|
9240
|
+
punishSet: this.punishSetDict,
|
|
9241
|
+
};
|
|
9242
|
+
}
|
|
9209
9243
|
|
|
9210
9244
|
static fromSortedArrays({
|
|
9211
9245
|
goodSet,
|
|
@@ -12153,7 +12187,7 @@ declare class SerializedService implements Service {
|
|
|
12153
12187
|
getStorage(rawKey: StorageKey): BytesBlob | null {
|
|
12154
12188
|
if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
|
|
12155
12189
|
const SERVICE_ID_BYTES = 4;
|
|
12156
|
-
const serviceIdAndKey =
|
|
12190
|
+
const serviceIdAndKey = safeAllocUint8Array(SERVICE_ID_BYTES + rawKey.length);
|
|
12157
12191
|
serviceIdAndKey.set(u32AsLeBytes(this.serviceId));
|
|
12158
12192
|
serviceIdAndKey.set(rawKey.raw, SERVICE_ID_BYTES);
|
|
12159
12193
|
const key: StorageKey = asOpaqueType(BytesBlob.blobFrom(blake2b.hashBytes(serviceIdAndKey).raw));
|
|
@@ -12554,7 +12588,7 @@ declare function padAndEncodeData(input: BytesBlob) {
|
|
|
12554
12588
|
const paddedLength = Math.ceil(input.length / PIECE_SIZE) * PIECE_SIZE;
|
|
12555
12589
|
let padded = input;
|
|
12556
12590
|
if (input.length !== paddedLength) {
|
|
12557
|
-
padded = BytesBlob.blobFrom(
|
|
12591
|
+
padded = BytesBlob.blobFrom(safeAllocUint8Array(paddedLength));
|
|
12558
12592
|
padded.raw.set(input.raw, 0);
|
|
12559
12593
|
}
|
|
12560
12594
|
return chunkingFunction(padded);
|
|
@@ -12610,7 +12644,7 @@ declare function decodeData(input: FixedSizeArray<[number, BytesBlob], N_CHUNKS_
|
|
|
12610
12644
|
*/
|
|
12611
12645
|
declare function encodePoints(input: Bytes<PIECE_SIZE>): FixedSizeArray<Bytes<POINT_LENGTH>, N_CHUNKS_TOTAL> {
|
|
12612
12646
|
const result: Bytes<POINT_LENGTH>[] = [];
|
|
12613
|
-
const data =
|
|
12647
|
+
const data = safeAllocUint8Array(POINT_ALIGNMENT * N_CHUNKS_REQUIRED);
|
|
12614
12648
|
|
|
12615
12649
|
// add original shards to the result
|
|
12616
12650
|
for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
|
|
@@ -12630,7 +12664,7 @@ declare function encodePoints(input: Bytes<PIECE_SIZE>): FixedSizeArray<Bytes<PO
|
|
|
12630
12664
|
for (let i = 0; i < N_CHUNKS_REDUNDANCY; i++) {
|
|
12631
12665
|
const pointIndex = i * POINT_ALIGNMENT;
|
|
12632
12666
|
|
|
12633
|
-
const redundancyPoint =
|
|
12667
|
+
const redundancyPoint = safeAllocUint8Array(POINT_LENGTH);
|
|
12634
12668
|
for (let j = 0; j < POINT_LENGTH; j++) {
|
|
12635
12669
|
redundancyPoint[j] = encodedData[pointIndex + j * HALF_POINT_SIZE];
|
|
12636
12670
|
}
|
|
@@ -12650,7 +12684,7 @@ declare function decodePiece(
|
|
|
12650
12684
|
): Bytes<PIECE_SIZE> {
|
|
12651
12685
|
const result = Bytes.zero(PIECE_SIZE);
|
|
12652
12686
|
|
|
12653
|
-
const data =
|
|
12687
|
+
const data = safeAllocUint8Array(N_CHUNKS_REQUIRED * POINT_ALIGNMENT);
|
|
12654
12688
|
const indices = new Uint16Array(input.length);
|
|
12655
12689
|
|
|
12656
12690
|
for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
|
|
@@ -12777,7 +12811,7 @@ declare function lace<N extends number, K extends number>(input: FixedSizeArray<
|
|
|
12777
12811
|
return BytesBlob.empty();
|
|
12778
12812
|
}
|
|
12779
12813
|
const n = input[0].length;
|
|
12780
|
-
const result = BytesBlob.blobFrom(
|
|
12814
|
+
const result = BytesBlob.blobFrom(safeAllocUint8Array(k * n));
|
|
12781
12815
|
for (let i = 0; i < k; i++) {
|
|
12782
12816
|
const entry = input[i].raw;
|
|
12783
12817
|
for (let j = 0; j < n; j++) {
|
|
@@ -13675,13 +13709,12 @@ interface PartialState {
|
|
|
13675
13709
|
|
|
13676
13710
|
/**
|
|
13677
13711
|
* Transfer given `amount` of funds to the `destination`,
|
|
13678
|
-
* passing `
|
|
13679
|
-
* and given `memo`.
|
|
13712
|
+
* passing `gas` fee for transfer and given `memo`.
|
|
13680
13713
|
*/
|
|
13681
13714
|
transfer(
|
|
13682
13715
|
destination: ServiceId | null,
|
|
13683
13716
|
amount: U64,
|
|
13684
|
-
|
|
13717
|
+
gas: ServiceGas,
|
|
13685
13718
|
memo: Bytes<TRANSFER_MEMO_BYTES>,
|
|
13686
13719
|
): Result$2<OK, TransferError>;
|
|
13687
13720
|
|
|
@@ -13850,7 +13883,7 @@ declare class Mask {
|
|
|
13850
13883
|
}
|
|
13851
13884
|
|
|
13852
13885
|
private buildLookupTableForward(mask: BitVec) {
|
|
13853
|
-
const table =
|
|
13886
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
13854
13887
|
let lastInstructionOffset = 0;
|
|
13855
13888
|
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
13856
13889
|
if (mask.isSet(i)) {
|
|
@@ -13994,7 +14027,7 @@ declare class Registers {
|
|
|
13994
14027
|
private asSigned: BigInt64Array;
|
|
13995
14028
|
private asUnsigned: BigUint64Array;
|
|
13996
14029
|
|
|
13997
|
-
constructor(private readonly bytes =
|
|
14030
|
+
constructor(private readonly bytes = safeAllocUint8Array(NO_OF_REGISTERS << REGISTER_SIZE_SHIFT)) {
|
|
13998
14031
|
check`${bytes.length === NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
13999
14032
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
14000
14033
|
this.asUnsigned = new BigUint64Array(bytes.buffer, bytes.byteOffset);
|
|
@@ -18052,9 +18085,15 @@ type HostCallIndex = Opaque<U32, "HostCallIndex[U32]">;
|
|
|
18052
18085
|
/** Attempt to convert a number into `HostCallIndex`. */
|
|
18053
18086
|
declare const tryAsHostCallIndex = (v: number): HostCallIndex => asOpaqueType(tryAsU32(v));
|
|
18054
18087
|
|
|
18088
|
+
/**
|
|
18089
|
+
* Host-call exit reason.
|
|
18090
|
+
*
|
|
18091
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
18092
|
+
*/
|
|
18055
18093
|
declare enum PvmExecution {
|
|
18056
18094
|
Halt = 0,
|
|
18057
18095
|
Panic = 1,
|
|
18096
|
+
OOG = 2, // out-of-gas
|
|
18058
18097
|
}
|
|
18059
18098
|
|
|
18060
18099
|
/** A utility function to easily trace a bunch of registers. */
|
|
@@ -18067,8 +18106,12 @@ interface HostCallHandler {
|
|
|
18067
18106
|
/** Index of that host call (i.e. what PVM invokes via `ecalli`) */
|
|
18068
18107
|
readonly index: HostCallIndex;
|
|
18069
18108
|
|
|
18070
|
-
/**
|
|
18071
|
-
|
|
18109
|
+
/**
|
|
18110
|
+
* The gas cost of invocation of that host call.
|
|
18111
|
+
*
|
|
18112
|
+
* NOTE: `((reg: IHostCallRegisters) => Gas)` function is for compatibility reasons: pre GP 0.7.2
|
|
18113
|
+
*/
|
|
18114
|
+
readonly basicGasCost: SmallGas | ((reg: IHostCallRegisters) => Gas);
|
|
18072
18115
|
|
|
18073
18116
|
/** Currently executing service id. */
|
|
18074
18117
|
readonly currentServiceId: U32;
|
|
@@ -18211,7 +18254,7 @@ declare class HostCalls {
|
|
|
18211
18254
|
const maybeAddress = regs.getLowerU32(7);
|
|
18212
18255
|
const maybeLength = regs.getLowerU32(8);
|
|
18213
18256
|
|
|
18214
|
-
const result =
|
|
18257
|
+
const result = safeAllocUint8Array(maybeLength);
|
|
18215
18258
|
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
18216
18259
|
const loadResult = memory.loadInto(result, startAddress);
|
|
18217
18260
|
|
|
@@ -18244,8 +18287,10 @@ declare class HostCalls {
|
|
|
18244
18287
|
|
|
18245
18288
|
const hostCall = this.hostCalls.get(index);
|
|
18246
18289
|
const gasBefore = gas.get();
|
|
18247
|
-
|
|
18248
|
-
const
|
|
18290
|
+
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
18291
|
+
const basicGasCost =
|
|
18292
|
+
typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
18293
|
+
const underflow = gas.sub(basicGasCost);
|
|
18249
18294
|
|
|
18250
18295
|
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
18251
18296
|
if (underflow) {
|
|
@@ -18272,6 +18317,11 @@ declare class HostCalls {
|
|
|
18272
18317
|
return this.getReturnValue(status, pvmInstance);
|
|
18273
18318
|
}
|
|
18274
18319
|
|
|
18320
|
+
if (result === PvmExecution.OOG) {
|
|
18321
|
+
status = Status.OOG;
|
|
18322
|
+
return this.getReturnValue(status, pvmInstance);
|
|
18323
|
+
}
|
|
18324
|
+
|
|
18275
18325
|
if (result === undefined) {
|
|
18276
18326
|
pvmInstance.runProgram();
|
|
18277
18327
|
status = pvmInstance.getStatus();
|
|
@@ -18643,7 +18693,7 @@ declare class DebuggerAdapter {
|
|
|
18643
18693
|
|
|
18644
18694
|
if (page === null) {
|
|
18645
18695
|
// page wasn't allocated so we return an empty page
|
|
18646
|
-
return
|
|
18696
|
+
return safeAllocUint8Array(PAGE_SIZE);
|
|
18647
18697
|
}
|
|
18648
18698
|
|
|
18649
18699
|
if (page.length === PAGE_SIZE) {
|
|
@@ -18652,7 +18702,7 @@ declare class DebuggerAdapter {
|
|
|
18652
18702
|
}
|
|
18653
18703
|
|
|
18654
18704
|
// page was allocated but it is shorter than PAGE_SIZE so we have to extend it
|
|
18655
|
-
const fullPage =
|
|
18705
|
+
const fullPage = safeAllocUint8Array(PAGE_SIZE);
|
|
18656
18706
|
fullPage.set(page);
|
|
18657
18707
|
return fullPage;
|
|
18658
18708
|
}
|
package/index.js
CHANGED
|
@@ -329,6 +329,19 @@ const Result$1 = {
|
|
|
329
329
|
},
|
|
330
330
|
};
|
|
331
331
|
|
|
332
|
+
// about 2GB, the maximum ArrayBuffer length on Chrome confirmed by several sources:
|
|
333
|
+
// - https://issues.chromium.org/issues/40055619
|
|
334
|
+
// - https://stackoverflow.com/a/72124984
|
|
335
|
+
// - https://onnxruntime.ai/docs/tutorials/web/large-models.html#maximum-size-of-arraybuffer
|
|
336
|
+
const MAX_LENGTH$2 = 2145386496;
|
|
337
|
+
function safeAllocUint8Array(length) {
|
|
338
|
+
if (length > MAX_LENGTH$2) {
|
|
339
|
+
// biome-ignore lint/suspicious/noConsole: can't have a dependency on logger here
|
|
340
|
+
console.warn(`Trying to allocate ${length} bytes, which is greater than the maximum of ${MAX_LENGTH$2}.`);
|
|
341
|
+
}
|
|
342
|
+
return new Uint8Array(Math.min(MAX_LENGTH$2, length));
|
|
343
|
+
}
|
|
344
|
+
|
|
332
345
|
/**
|
|
333
346
|
* Utilities for tests.
|
|
334
347
|
*/
|
|
@@ -569,6 +582,7 @@ var index$u = /*#__PURE__*/Object.freeze({
|
|
|
569
582
|
DEFAULT_VERSION: DEFAULT_VERSION,
|
|
570
583
|
ErrorsCollector: ErrorsCollector,
|
|
571
584
|
get GpVersion () { return GpVersion; },
|
|
585
|
+
MAX_LENGTH: MAX_LENGTH$2,
|
|
572
586
|
OK: OK,
|
|
573
587
|
Result: Result$1,
|
|
574
588
|
TEST_COMPARE_USING: TEST_COMPARE_USING,
|
|
@@ -583,6 +597,7 @@ var index$u = /*#__PURE__*/Object.freeze({
|
|
|
583
597
|
isBrowser: isBrowser,
|
|
584
598
|
measure: measure,
|
|
585
599
|
resultToString: resultToString,
|
|
600
|
+
safeAllocUint8Array: safeAllocUint8Array,
|
|
586
601
|
seeThrough: seeThrough,
|
|
587
602
|
workspacePathFix: workspacePathFix
|
|
588
603
|
});
|
|
@@ -606,7 +621,7 @@ class BitVec {
|
|
|
606
621
|
* Create new [`BitVec`] with all values set to `false`.
|
|
607
622
|
*/
|
|
608
623
|
static empty(bitLength) {
|
|
609
|
-
const data =
|
|
624
|
+
const data = safeAllocUint8Array(Math.ceil(bitLength / 8));
|
|
610
625
|
return new BitVec(data, bitLength);
|
|
611
626
|
}
|
|
612
627
|
byteLength;
|
|
@@ -807,7 +822,7 @@ class BytesBlob {
|
|
|
807
822
|
static blobFromParts(v, ...rest) {
|
|
808
823
|
const vArr = v instanceof Uint8Array ? [v] : v;
|
|
809
824
|
const totalLength = vArr.reduce((a, v) => a + v.length, 0) + rest.reduce((a, v) => a + v.length, 0);
|
|
810
|
-
const buffer =
|
|
825
|
+
const buffer = safeAllocUint8Array(totalLength);
|
|
811
826
|
let offset = 0;
|
|
812
827
|
for (const r of vArr) {
|
|
813
828
|
buffer.set(r, offset);
|
|
@@ -880,7 +895,7 @@ class Bytes extends BytesBlob {
|
|
|
880
895
|
}
|
|
881
896
|
/** Create an empty [`Bytes<X>`] of given length. */
|
|
882
897
|
static zero(len) {
|
|
883
|
-
return new Bytes(
|
|
898
|
+
return new Bytes(safeAllocUint8Array(len), len);
|
|
884
899
|
}
|
|
885
900
|
// TODO [ToDr] `fill` should have the argments swapped to align with the rest.
|
|
886
901
|
/** Create a [`Bytes<X>`] with all bytes filled with given input number. */
|
|
@@ -3589,7 +3604,7 @@ async function verify(input) {
|
|
|
3589
3604
|
return Promise.resolve([]);
|
|
3590
3605
|
}
|
|
3591
3606
|
const dataLength = input.reduce((acc, { message, key, signature }) => acc + key.length + signature.length + message.length + 1, 0);
|
|
3592
|
-
const data =
|
|
3607
|
+
const data = safeAllocUint8Array(dataLength);
|
|
3593
3608
|
let offset = 0;
|
|
3594
3609
|
for (const { key, message, signature } of input) {
|
|
3595
3610
|
data.set(key.raw, offset);
|
|
@@ -3681,7 +3696,7 @@ class SimpleAllocator {
|
|
|
3681
3696
|
/** An allocator that works by allocating larger (continuous) pages of memory. */
|
|
3682
3697
|
class PageAllocator {
|
|
3683
3698
|
hashesPerPage;
|
|
3684
|
-
page =
|
|
3699
|
+
page = safeAllocUint8Array(0);
|
|
3685
3700
|
currentHash = 0;
|
|
3686
3701
|
// TODO [ToDr] Benchmark the performance!
|
|
3687
3702
|
constructor(hashesPerPage) {
|
|
@@ -3692,7 +3707,7 @@ class PageAllocator {
|
|
|
3692
3707
|
resetPage() {
|
|
3693
3708
|
const pageSizeBytes = this.hashesPerPage * HASH_SIZE;
|
|
3694
3709
|
this.currentHash = 0;
|
|
3695
|
-
this.page =
|
|
3710
|
+
this.page = safeAllocUint8Array(pageSizeBytes);
|
|
3696
3711
|
}
|
|
3697
3712
|
emptyHash() {
|
|
3698
3713
|
const startIdx = this.currentHash * HASH_SIZE;
|
|
@@ -8728,6 +8743,10 @@ class DisputesRecords {
|
|
|
8728
8743
|
static create({ goodSet, badSet, wonkySet, punishSet }) {
|
|
8729
8744
|
return new DisputesRecords(goodSet, badSet, wonkySet, punishSet);
|
|
8730
8745
|
}
|
|
8746
|
+
goodSetDict;
|
|
8747
|
+
badSetDict;
|
|
8748
|
+
wonkySetDict;
|
|
8749
|
+
punishSetDict;
|
|
8731
8750
|
constructor(
|
|
8732
8751
|
/** `goodSet`: all work-reports hashes which were judged to be correct */
|
|
8733
8752
|
goodSet,
|
|
@@ -8741,6 +8760,18 @@ class DisputesRecords {
|
|
|
8741
8760
|
this.badSet = badSet;
|
|
8742
8761
|
this.wonkySet = wonkySet;
|
|
8743
8762
|
this.punishSet = punishSet;
|
|
8763
|
+
this.goodSetDict = HashSet.from(goodSet.array);
|
|
8764
|
+
this.badSetDict = HashSet.from(badSet.array);
|
|
8765
|
+
this.wonkySetDict = HashSet.from(wonkySet.array);
|
|
8766
|
+
this.punishSetDict = HashSet.from(punishSet.array);
|
|
8767
|
+
}
|
|
8768
|
+
asDictionaries() {
|
|
8769
|
+
return {
|
|
8770
|
+
goodSet: this.goodSetDict,
|
|
8771
|
+
badSet: this.badSetDict,
|
|
8772
|
+
wonkySet: this.wonkySetDict,
|
|
8773
|
+
punishSet: this.punishSetDict,
|
|
8774
|
+
};
|
|
8744
8775
|
}
|
|
8745
8776
|
static fromSortedArrays({ goodSet, badSet, wonkySet, punishSet, }) {
|
|
8746
8777
|
return new DisputesRecords(SortedSet.fromSortedArray(hashComparator, goodSet), SortedSet.fromSortedArray(hashComparator, badSet), SortedSet.fromSortedArray(hashComparator, wonkySet), SortedSet.fromSortedArray(hashComparator, punishSet));
|
|
@@ -10444,7 +10475,7 @@ class SerializedService {
|
|
|
10444
10475
|
getStorage(rawKey) {
|
|
10445
10476
|
if (Compatibility.isLessThan(GpVersion.V0_6_7)) {
|
|
10446
10477
|
const SERVICE_ID_BYTES = 4;
|
|
10447
|
-
const serviceIdAndKey =
|
|
10478
|
+
const serviceIdAndKey = safeAllocUint8Array(SERVICE_ID_BYTES + rawKey.length);
|
|
10448
10479
|
serviceIdAndKey.set(u32AsLeBytes(this.serviceId));
|
|
10449
10480
|
serviceIdAndKey.set(rawKey.raw, SERVICE_ID_BYTES);
|
|
10450
10481
|
const key = asOpaqueType(BytesBlob.blobFrom(hashBytes(serviceIdAndKey).raw));
|
|
@@ -10529,7 +10560,7 @@ class TrieNode {
|
|
|
10529
10560
|
raw;
|
|
10530
10561
|
constructor(
|
|
10531
10562
|
/** Exactly 512 bits / 64 bytes */
|
|
10532
|
-
raw =
|
|
10563
|
+
raw = safeAllocUint8Array(TRIE_NODE_BYTES)) {
|
|
10533
10564
|
this.raw = raw;
|
|
10534
10565
|
}
|
|
10535
10566
|
/** Returns the type of the node */
|
|
@@ -11780,7 +11811,7 @@ function padAndEncodeData(input) {
|
|
|
11780
11811
|
const paddedLength = Math.ceil(input.length / PIECE_SIZE) * PIECE_SIZE;
|
|
11781
11812
|
let padded = input;
|
|
11782
11813
|
if (input.length !== paddedLength) {
|
|
11783
|
-
padded = BytesBlob.blobFrom(
|
|
11814
|
+
padded = BytesBlob.blobFrom(safeAllocUint8Array(paddedLength));
|
|
11784
11815
|
padded.raw.set(input.raw, 0);
|
|
11785
11816
|
}
|
|
11786
11817
|
return chunkingFunction(padded);
|
|
@@ -11826,7 +11857,7 @@ function decodeData(input) {
|
|
|
11826
11857
|
*/
|
|
11827
11858
|
function encodePoints(input) {
|
|
11828
11859
|
const result = [];
|
|
11829
|
-
const data =
|
|
11860
|
+
const data = safeAllocUint8Array(POINT_ALIGNMENT * N_CHUNKS_REQUIRED);
|
|
11830
11861
|
// add original shards to the result
|
|
11831
11862
|
for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
|
|
11832
11863
|
const pointStart = POINT_LENGTH * i;
|
|
@@ -11842,7 +11873,7 @@ function encodePoints(input) {
|
|
|
11842
11873
|
const encodedData = encodedResult.take_data();
|
|
11843
11874
|
for (let i = 0; i < N_CHUNKS_REDUNDANCY; i++) {
|
|
11844
11875
|
const pointIndex = i * POINT_ALIGNMENT;
|
|
11845
|
-
const redundancyPoint =
|
|
11876
|
+
const redundancyPoint = safeAllocUint8Array(POINT_LENGTH);
|
|
11846
11877
|
for (let j = 0; j < POINT_LENGTH; j++) {
|
|
11847
11878
|
redundancyPoint[j] = encodedData[pointIndex + j * HALF_POINT_SIZE];
|
|
11848
11879
|
}
|
|
@@ -11857,7 +11888,7 @@ function encodePoints(input) {
|
|
|
11857
11888
|
*/
|
|
11858
11889
|
function decodePiece(input) {
|
|
11859
11890
|
const result = Bytes.zero(PIECE_SIZE);
|
|
11860
|
-
const data =
|
|
11891
|
+
const data = safeAllocUint8Array(N_CHUNKS_REQUIRED * POINT_ALIGNMENT);
|
|
11861
11892
|
const indices = new Uint16Array(input.length);
|
|
11862
11893
|
for (let i = 0; i < N_CHUNKS_REQUIRED; i++) {
|
|
11863
11894
|
const [index, points] = input[i];
|
|
@@ -11973,7 +12004,7 @@ function lace(input) {
|
|
|
11973
12004
|
return BytesBlob.empty();
|
|
11974
12005
|
}
|
|
11975
12006
|
const n = input[0].length;
|
|
11976
|
-
const result = BytesBlob.blobFrom(
|
|
12007
|
+
const result = BytesBlob.blobFrom(safeAllocUint8Array(k * n));
|
|
11977
12008
|
for (let i = 0; i < k; i++) {
|
|
11978
12009
|
const entry = input[i].raw;
|
|
11979
12010
|
for (let j = 0; j < n; j++) {
|
|
@@ -13252,7 +13283,7 @@ class Registers {
|
|
|
13252
13283
|
bytes;
|
|
13253
13284
|
asSigned;
|
|
13254
13285
|
asUnsigned;
|
|
13255
|
-
constructor(bytes =
|
|
13286
|
+
constructor(bytes = safeAllocUint8Array(NO_OF_REGISTERS$1 << REGISTER_SIZE_SHIFT)) {
|
|
13256
13287
|
this.bytes = bytes;
|
|
13257
13288
|
check `${bytes.length === NO_OF_REGISTERS$1 << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
13258
13289
|
this.asSigned = new BigInt64Array(bytes.buffer, bytes.byteOffset);
|
|
@@ -13324,10 +13355,16 @@ function signExtend32To64(value) {
|
|
|
13324
13355
|
|
|
13325
13356
|
/** Attempt to convert a number into `HostCallIndex`. */
|
|
13326
13357
|
const tryAsHostCallIndex = (v) => asOpaqueType(tryAsU32(v));
|
|
13358
|
+
/**
|
|
13359
|
+
* Host-call exit reason.
|
|
13360
|
+
*
|
|
13361
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/24a30124a501?v=0.7.2
|
|
13362
|
+
*/
|
|
13327
13363
|
var PvmExecution;
|
|
13328
13364
|
(function (PvmExecution) {
|
|
13329
13365
|
PvmExecution[PvmExecution["Halt"] = 0] = "Halt";
|
|
13330
13366
|
PvmExecution[PvmExecution["Panic"] = 1] = "Panic";
|
|
13367
|
+
PvmExecution[PvmExecution["OOG"] = 2] = "OOG";
|
|
13331
13368
|
})(PvmExecution || (PvmExecution = {}));
|
|
13332
13369
|
/** A utility function to easily trace a bunch of registers. */
|
|
13333
13370
|
function traceRegisters(...regs) {
|
|
@@ -13399,7 +13436,7 @@ class Mask {
|
|
|
13399
13436
|
return Math.min(this.lookupTableForward[index] ?? 0, MAX_INSTRUCTION_DISTANCE);
|
|
13400
13437
|
}
|
|
13401
13438
|
buildLookupTableForward(mask) {
|
|
13402
|
-
const table =
|
|
13439
|
+
const table = safeAllocUint8Array(mask.bitLength);
|
|
13403
13440
|
let lastInstructionOffset = 0;
|
|
13404
13441
|
for (let i = mask.bitLength - 1; i >= 0; i--) {
|
|
13405
13442
|
if (mask.isSet(i)) {
|
|
@@ -16934,7 +16971,7 @@ class HostCalls {
|
|
|
16934
16971
|
const regs = pvmInstance.getRegisters();
|
|
16935
16972
|
const maybeAddress = regs.getLowerU32(7);
|
|
16936
16973
|
const maybeLength = regs.getLowerU32(8);
|
|
16937
|
-
const result =
|
|
16974
|
+
const result = safeAllocUint8Array(maybeLength);
|
|
16938
16975
|
const startAddress = tryAsMemoryIndex(maybeAddress);
|
|
16939
16976
|
const loadResult = memory.loadInto(result, startAddress);
|
|
16940
16977
|
if (loadResult.isError) {
|
|
@@ -16962,8 +16999,9 @@ class HostCalls {
|
|
|
16962
16999
|
const index = tryAsHostCallIndex(hostCallIndex);
|
|
16963
17000
|
const hostCall = this.hostCalls.get(index);
|
|
16964
17001
|
const gasBefore = gas.get();
|
|
16965
|
-
|
|
16966
|
-
const
|
|
17002
|
+
// NOTE: `basicGasCost(regs)` function is for compatibility reasons: pre GP 0.7.2
|
|
17003
|
+
const basicGasCost = typeof hostCall.basicGasCost === "number" ? hostCall.basicGasCost : hostCall.basicGasCost(regs);
|
|
17004
|
+
const underflow = gas.sub(basicGasCost);
|
|
16967
17005
|
const pcLog = `[PC: ${pvmInstance.getPC()}]`;
|
|
16968
17006
|
if (underflow) {
|
|
16969
17007
|
this.hostCalls.traceHostCall(`${pcLog} OOG`, index, hostCall, regs, gas.get());
|
|
@@ -16980,6 +17018,10 @@ class HostCalls {
|
|
|
16980
17018
|
status = Status.PANIC;
|
|
16981
17019
|
return this.getReturnValue(status, pvmInstance);
|
|
16982
17020
|
}
|
|
17021
|
+
if (result === PvmExecution.OOG) {
|
|
17022
|
+
status = Status.OOG;
|
|
17023
|
+
return this.getReturnValue(status, pvmInstance);
|
|
17024
|
+
}
|
|
16983
17025
|
if (result === undefined) {
|
|
16984
17026
|
pvmInstance.runProgram();
|
|
16985
17027
|
status = pvmInstance.getStatus();
|
|
@@ -17278,14 +17320,14 @@ class DebuggerAdapter {
|
|
|
17278
17320
|
const page = this.pvm.getMemoryPage(pageNumber);
|
|
17279
17321
|
if (page === null) {
|
|
17280
17322
|
// page wasn't allocated so we return an empty page
|
|
17281
|
-
return
|
|
17323
|
+
return safeAllocUint8Array(PAGE_SIZE$1);
|
|
17282
17324
|
}
|
|
17283
17325
|
if (page.length === PAGE_SIZE$1) {
|
|
17284
17326
|
// page was allocated and has a proper size so we can simply return it
|
|
17285
17327
|
return page;
|
|
17286
17328
|
}
|
|
17287
17329
|
// page was allocated but it is shorter than PAGE_SIZE so we have to extend it
|
|
17288
|
-
const fullPage =
|
|
17330
|
+
const fullPage = safeAllocUint8Array(PAGE_SIZE$1);
|
|
17289
17331
|
fullPage.set(page);
|
|
17290
17332
|
return fullPage;
|
|
17291
17333
|
}
|
|
@@ -17429,7 +17471,7 @@ function fisherYatesShuffle(arr, entropy) {
|
|
|
17429
17471
|
}
|
|
17430
17472
|
function hashToNumberSequence(entropy, length) {
|
|
17431
17473
|
const result = new Array(length);
|
|
17432
|
-
const randomBytes =
|
|
17474
|
+
const randomBytes = safeAllocUint8Array(ENTROPY_BYTES + 4);
|
|
17433
17475
|
randomBytes.set(entropy.raw);
|
|
17434
17476
|
for (let i = 0; i < length; i++) {
|
|
17435
17477
|
randomBytes.set(u32AsLeBytes(tryAsU32(Math.floor(i / 8))), ENTROPY_BYTES);
|
|
@@ -17969,7 +18011,7 @@ class Preimages {
|
|
|
17969
18011
|
|
|
17970
18012
|
class Missing {
|
|
17971
18013
|
index = tryAsHostCallIndex(2 ** 32 - 1);
|
|
17972
|
-
|
|
18014
|
+
basicGasCost = tryAsSmallGas(10);
|
|
17973
18015
|
currentServiceId = CURRENT_SERVICE_ID;
|
|
17974
18016
|
tracedRegisters = traceRegisters(7);
|
|
17975
18017
|
execute(_gas, regs, _memory) {
|