@typeberry/jam 0.4.0-203a18d → 0.4.0-248b604
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/README.md +5 -0
- package/bootstrap-generator.mjs +8 -4
- package/bootstrap-generator.mjs.map +1 -1
- package/bootstrap-importer.mjs +189 -112
- package/bootstrap-importer.mjs.map +1 -1
- package/bootstrap-network.mjs +8 -7
- package/bootstrap-network.mjs.map +1 -1
- package/index.js +189 -112
- package/index.js.map +1 -1
- package/package.json +1 -1
package/bootstrap-importer.mjs
CHANGED
|
@@ -3550,7 +3550,11 @@ var TestSuite;
|
|
|
3550
3550
|
})(TestSuite || (TestSuite = {}));
|
|
3551
3551
|
const ALL_VERSIONS_IN_ORDER = [compatibility_GpVersion.V0_6_7, compatibility_GpVersion.V0_7_0, compatibility_GpVersion.V0_7_1, compatibility_GpVersion.V0_7_2];
|
|
3552
3552
|
const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
|
|
3553
|
-
|
|
3553
|
+
/**
|
|
3554
|
+
* Current version is set to track the jam-conformance testing.
|
|
3555
|
+
* Since we are currently at 0.7.1 not 0.7.2, we set our default version accordingly.
|
|
3556
|
+
*/
|
|
3557
|
+
const DEFAULT_VERSION = compatibility_GpVersion.V0_7_1;
|
|
3554
3558
|
const env = typeof process === "undefined" ? {} : process.env;
|
|
3555
3559
|
let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
|
|
3556
3560
|
let CURRENT_SUITE = parseCurrentSuite(env.TEST_SUITE) ?? DEFAULT_SUITE;
|
|
@@ -3609,8 +3613,8 @@ class compatibility_Compatibility {
|
|
|
3609
3613
|
/**
|
|
3610
3614
|
* Allows selecting different values for different Gray Paper versions from one record.
|
|
3611
3615
|
*
|
|
3612
|
-
*
|
|
3613
|
-
*
|
|
3616
|
+
* fallback The default value to return if no value is found for the current.
|
|
3617
|
+
* versions A record mapping versions to values, checking if the version is greater or equal to the current version.
|
|
3614
3618
|
* @returns The value for the current version, or the default value.
|
|
3615
3619
|
*/
|
|
3616
3620
|
static selectIfGreaterOrEqual({ fallback, versions, }) {
|
|
@@ -3773,7 +3777,7 @@ const workspacePathFix = dev_env.NODE_ENV === "development"
|
|
|
3773
3777
|
|
|
3774
3778
|
;// CONCATENATED MODULE: ./packages/core/utils/opaque.ts
|
|
3775
3779
|
/**
|
|
3776
|
-
*
|
|
3780
|
+
* `Opaque<Type, Token>` constructs a unique type which is a subset of Type with a
|
|
3777
3781
|
* specified unique token Token. It means that base type cannot be assigned to unique type by accident.
|
|
3778
3782
|
* Good examples of opaque types include:
|
|
3779
3783
|
* - JWTs or other tokens - these are special kinds of string used for authorization purposes.
|
|
@@ -13210,7 +13214,6 @@ class LeafNode {
|
|
|
13210
13214
|
/**
|
|
13211
13215
|
* Get the byte length of embedded value.
|
|
13212
13216
|
*
|
|
13213
|
-
* @remark
|
|
13214
13217
|
* Note in case this node only contains hash this is going to be 0.
|
|
13215
13218
|
*/
|
|
13216
13219
|
getValueLength() {
|
|
@@ -13221,7 +13224,6 @@ class LeafNode {
|
|
|
13221
13224
|
/**
|
|
13222
13225
|
* Returns the embedded value.
|
|
13223
13226
|
*
|
|
13224
|
-
* @remark
|
|
13225
13227
|
* Note that this is going to be empty for a regular leaf node (i.e. containing a hash).
|
|
13226
13228
|
*/
|
|
13227
13229
|
getValue() {
|
|
@@ -13231,7 +13233,6 @@ class LeafNode {
|
|
|
13231
13233
|
/**
|
|
13232
13234
|
* Returns contained value hash.
|
|
13233
13235
|
*
|
|
13234
|
-
* @remark
|
|
13235
13236
|
* Note that for embedded value this is going to be full 0-padded 32 bytes.
|
|
13236
13237
|
*/
|
|
13237
13238
|
getValueHash() {
|
|
@@ -14387,7 +14388,7 @@ const gas_tryAsSmallGas = (v) => opaque_asOpaqueType(numbers_tryAsU32(v));
|
|
|
14387
14388
|
/** Attempt to convert given number into U64 gas representation. */
|
|
14388
14389
|
const tryAsBigGas = (v) => opaque_asOpaqueType(numbers_tryAsU64(v));
|
|
14389
14390
|
/** Attempt to convert given number into gas. */
|
|
14390
|
-
const
|
|
14391
|
+
const gas_tryAsGas = (v) => typeof v === "number" && v < 2 ** 32 ? gas_tryAsSmallGas(v) : tryAsBigGas(v);
|
|
14391
14392
|
|
|
14392
14393
|
;// CONCATENATED MODULE: ./packages/core/pvm-interface/memory.ts
|
|
14393
14394
|
|
|
@@ -14670,7 +14671,7 @@ const tryAsRegisterIndex = (index) => {
|
|
|
14670
14671
|
debug_check `${index >= 0 && index < registers_NO_OF_REGISTERS} Incorrect register index: ${index}!`;
|
|
14671
14672
|
return opaque_asOpaqueType(index);
|
|
14672
14673
|
};
|
|
14673
|
-
class
|
|
14674
|
+
class registers_Registers {
|
|
14674
14675
|
bytes;
|
|
14675
14676
|
asSigned;
|
|
14676
14677
|
asUnsigned;
|
|
@@ -14689,7 +14690,7 @@ class Registers {
|
|
|
14689
14690
|
}
|
|
14690
14691
|
static fromBytes(bytes) {
|
|
14691
14692
|
debug_check `${bytes.length === registers_NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14692
|
-
return new
|
|
14693
|
+
return new registers_Registers(bytes);
|
|
14693
14694
|
}
|
|
14694
14695
|
getBytesAsLittleEndian(index, len) {
|
|
14695
14696
|
const offset = index << REGISTER_SIZE_SHIFT;
|
|
@@ -15003,49 +15004,10 @@ class NoopMissing {
|
|
|
15003
15004
|
}
|
|
15004
15005
|
}
|
|
15005
15006
|
|
|
15006
|
-
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/gas.ts
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
/** Create a new gas counter instance depending on the gas value. */
|
|
15010
|
-
function gasCounter(gas) {
|
|
15011
|
-
return new GasCounterU64(numbers_tryAsU64(gas));
|
|
15012
|
-
}
|
|
15013
|
-
class GasCounterU64 {
|
|
15014
|
-
gas;
|
|
15015
|
-
initialGas;
|
|
15016
|
-
constructor(gas) {
|
|
15017
|
-
this.gas = gas;
|
|
15018
|
-
this.initialGas = tryAsGas(gas);
|
|
15019
|
-
}
|
|
15020
|
-
set(g) {
|
|
15021
|
-
this.gas = numbers_tryAsU64(g);
|
|
15022
|
-
}
|
|
15023
|
-
get() {
|
|
15024
|
-
return tryAsGas(this.gas);
|
|
15025
|
-
}
|
|
15026
|
-
sub(g) {
|
|
15027
|
-
const result = this.gas - numbers_tryAsU64(g);
|
|
15028
|
-
if (result >= 0n) {
|
|
15029
|
-
this.gas = numbers_tryAsU64(result);
|
|
15030
|
-
return false;
|
|
15031
|
-
}
|
|
15032
|
-
this.gas = numbers_tryAsU64(0n);
|
|
15033
|
-
return true;
|
|
15034
|
-
}
|
|
15035
|
-
used() {
|
|
15036
|
-
const gasConsumed = numbers_tryAsU64(this.initialGas) - this.gas;
|
|
15037
|
-
// In we have less than zero left we assume that all gas has been consumed.
|
|
15038
|
-
if (gasConsumed < 0) {
|
|
15039
|
-
return this.initialGas;
|
|
15040
|
-
}
|
|
15041
|
-
return tryAsGas(gasConsumed);
|
|
15042
|
-
}
|
|
15043
|
-
}
|
|
15044
|
-
|
|
15045
15007
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/memory-index.ts
|
|
15046
15008
|
|
|
15047
15009
|
|
|
15048
|
-
const
|
|
15010
|
+
const memory_index_tryAsMemoryIndex = (index) => {
|
|
15049
15011
|
debug_check `${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15050
15012
|
return opaque_asOpaqueType(index);
|
|
15051
15013
|
};
|
|
@@ -15059,25 +15021,25 @@ const tryAsSbrkIndex = (index) => {
|
|
|
15059
15021
|
|
|
15060
15022
|
const memory_consts_PAGE_SIZE_SHIFT = 12;
|
|
15061
15023
|
// PAGE_SIZE has to be a power of 2
|
|
15062
|
-
const
|
|
15024
|
+
const memory_consts_PAGE_SIZE = 1 << memory_consts_PAGE_SIZE_SHIFT;
|
|
15063
15025
|
const MIN_ALLOCATION_SHIFT = (() => {
|
|
15064
15026
|
const MIN_ALLOCATION_SHIFT = 7;
|
|
15065
15027
|
debug_check `${MIN_ALLOCATION_SHIFT >= 0 && MIN_ALLOCATION_SHIFT < memory_consts_PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
15066
15028
|
return MIN_ALLOCATION_SHIFT;
|
|
15067
15029
|
})();
|
|
15068
|
-
const MIN_ALLOCATION_LENGTH =
|
|
15069
|
-
const LAST_PAGE_NUMBER = (MEMORY_SIZE -
|
|
15030
|
+
const MIN_ALLOCATION_LENGTH = memory_consts_PAGE_SIZE >> MIN_ALLOCATION_SHIFT;
|
|
15031
|
+
const LAST_PAGE_NUMBER = (MEMORY_SIZE - memory_consts_PAGE_SIZE) / memory_consts_PAGE_SIZE;
|
|
15070
15032
|
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
15071
15033
|
const RESERVED_NUMBER_OF_PAGES = 16;
|
|
15072
15034
|
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
15073
|
-
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE /
|
|
15035
|
+
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE / memory_consts_PAGE_SIZE;
|
|
15074
15036
|
|
|
15075
15037
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/pages/page-utils.ts
|
|
15076
15038
|
|
|
15077
15039
|
|
|
15078
15040
|
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
15079
15041
|
const tryAsPageIndex = (index) => {
|
|
15080
|
-
debug_check `${index >= 0 && index <
|
|
15042
|
+
debug_check `${index >= 0 && index < memory_consts_PAGE_SIZE}, Incorect page index: ${index}!`;
|
|
15081
15043
|
return opaque_asOpaqueType(index);
|
|
15082
15044
|
};
|
|
15083
15045
|
/** Ensure that given `index` represents an index of one of the pages. */
|
|
@@ -15105,17 +15067,17 @@ function getNextPageNumber(pageNumber) {
|
|
|
15105
15067
|
|
|
15106
15068
|
|
|
15107
15069
|
function alignToPageSize(length) {
|
|
15108
|
-
return
|
|
15070
|
+
return memory_consts_PAGE_SIZE * Math.ceil(length / memory_consts_PAGE_SIZE);
|
|
15109
15071
|
}
|
|
15110
15072
|
function getPageNumber(address) {
|
|
15111
15073
|
return tryAsPageNumber(address >>> memory_consts_PAGE_SIZE_SHIFT);
|
|
15112
15074
|
}
|
|
15113
15075
|
function getStartPageIndex(address) {
|
|
15114
|
-
return
|
|
15076
|
+
return memory_index_tryAsMemoryIndex((address >>> memory_consts_PAGE_SIZE_SHIFT) << memory_consts_PAGE_SIZE_SHIFT);
|
|
15115
15077
|
}
|
|
15116
15078
|
function getStartPageIndexFromPageNumber(pageNumber) {
|
|
15117
15079
|
// >>> 0 is needed to avoid changing sign of the number
|
|
15118
|
-
return
|
|
15080
|
+
return memory_index_tryAsMemoryIndex((pageNumber << memory_consts_PAGE_SIZE_SHIFT) >>> 0);
|
|
15119
15081
|
}
|
|
15120
15082
|
|
|
15121
15083
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/errors.ts
|
|
@@ -15137,7 +15099,7 @@ class PageFault {
|
|
|
15137
15099
|
return new PageFault(numbers_tryAsU32(startPageIndex), isAccessFault);
|
|
15138
15100
|
}
|
|
15139
15101
|
static fromMemoryIndex(maybeMemoryIndex, isAccessFault = false) {
|
|
15140
|
-
const memoryIndex =
|
|
15102
|
+
const memoryIndex = memory_index_tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
15141
15103
|
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
15142
15104
|
return new PageFault(numbers_tryAsU32(startPageIndex), isAccessFault);
|
|
15143
15105
|
}
|
|
@@ -15216,9 +15178,9 @@ class MemoryRange {
|
|
|
15216
15178
|
constructor(start, length) {
|
|
15217
15179
|
this.start = start;
|
|
15218
15180
|
this.length = length;
|
|
15219
|
-
this.end =
|
|
15181
|
+
this.end = memory_index_tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
15220
15182
|
if (length > 0) {
|
|
15221
|
-
this.lastIndex =
|
|
15183
|
+
this.lastIndex = memory_index_tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
15222
15184
|
}
|
|
15223
15185
|
}
|
|
15224
15186
|
/** Creates a memory range from given starting point and length */
|
|
@@ -15261,7 +15223,7 @@ class MemoryRange {
|
|
|
15261
15223
|
*
|
|
15262
15224
|
* it should be in `memory-consts` but it cannot be there because of circular dependency
|
|
15263
15225
|
*/
|
|
15264
|
-
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(
|
|
15226
|
+
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(memory_index_tryAsMemoryIndex(0), RESERVED_NUMBER_OF_PAGES * memory_consts_PAGE_SIZE);
|
|
15265
15227
|
|
|
15266
15228
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/page-range.ts
|
|
15267
15229
|
|
|
@@ -15299,7 +15261,7 @@ class PageRange {
|
|
|
15299
15261
|
// lastIndex is not null because we just ensured that the range is not empty
|
|
15300
15262
|
const pageWithLastIndex = getPageNumber(range.lastIndex ?? range.end);
|
|
15301
15263
|
const endPage = getNextPageNumber(pageWithLastIndex);
|
|
15302
|
-
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length >
|
|
15264
|
+
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length > memory_consts_PAGE_SIZE) {
|
|
15303
15265
|
// full range
|
|
15304
15266
|
return new PageRange(startPage, MAX_NUMBER_OF_PAGES);
|
|
15305
15267
|
}
|
|
@@ -15363,8 +15325,8 @@ class ReadablePage extends MemoryPage {
|
|
|
15363
15325
|
}
|
|
15364
15326
|
loadInto(result, startIndex, length) {
|
|
15365
15327
|
const endIndex = startIndex + length;
|
|
15366
|
-
if (endIndex >
|
|
15367
|
-
return Result.error(PageFault.fromMemoryIndex(this.start +
|
|
15328
|
+
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
15329
|
+
return Result.error(PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
15368
15330
|
}
|
|
15369
15331
|
const bytes = this.data.subarray(startIndex, endIndex);
|
|
15370
15332
|
// we zero the bytes, since data might not yet be initialized at `endIndex`.
|
|
@@ -15397,8 +15359,8 @@ class WriteablePage extends MemoryPage {
|
|
|
15397
15359
|
constructor(pageNumber, initialData) {
|
|
15398
15360
|
super(pageNumber);
|
|
15399
15361
|
const dataLength = initialData?.length ?? 0;
|
|
15400
|
-
const initialPageLength = Math.min(
|
|
15401
|
-
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength:
|
|
15362
|
+
const initialPageLength = Math.min(memory_consts_PAGE_SIZE, Math.max(dataLength, MIN_ALLOCATION_LENGTH));
|
|
15363
|
+
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength: memory_consts_PAGE_SIZE });
|
|
15402
15364
|
this.view = new Uint8Array(this.buffer);
|
|
15403
15365
|
if (initialData !== undefined) {
|
|
15404
15366
|
this.view.set(initialData);
|
|
@@ -15406,8 +15368,8 @@ class WriteablePage extends MemoryPage {
|
|
|
15406
15368
|
}
|
|
15407
15369
|
loadInto(result, startIndex, length) {
|
|
15408
15370
|
const endIndex = startIndex + length;
|
|
15409
|
-
if (endIndex >
|
|
15410
|
-
return Result.error(PageFault.fromMemoryIndex(this.start +
|
|
15371
|
+
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
15372
|
+
return Result.error(PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
15411
15373
|
}
|
|
15412
15374
|
const bytes = this.view.subarray(startIndex, endIndex);
|
|
15413
15375
|
// we zero the bytes, since the view might not yet be initialized at `endIndex`.
|
|
@@ -15416,16 +15378,16 @@ class WriteablePage extends MemoryPage {
|
|
|
15416
15378
|
return Result.ok(OK);
|
|
15417
15379
|
}
|
|
15418
15380
|
storeFrom(startIndex, bytes) {
|
|
15419
|
-
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength <
|
|
15420
|
-
const newLength = Math.min(
|
|
15381
|
+
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength < memory_consts_PAGE_SIZE) {
|
|
15382
|
+
const newLength = Math.min(memory_consts_PAGE_SIZE, Math.max(MIN_ALLOCATION_LENGTH, startIndex + bytes.length));
|
|
15421
15383
|
this.buffer.resize(newLength);
|
|
15422
15384
|
}
|
|
15423
15385
|
this.view.set(bytes, startIndex);
|
|
15424
15386
|
return Result.ok(OK);
|
|
15425
15387
|
}
|
|
15426
15388
|
setData(pageIndex, data) {
|
|
15427
|
-
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength <
|
|
15428
|
-
const newLength = Math.min(
|
|
15389
|
+
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength < memory_consts_PAGE_SIZE) {
|
|
15390
|
+
const newLength = Math.min(memory_consts_PAGE_SIZE, Math.max(MIN_ALLOCATION_LENGTH, pageIndex + data.length));
|
|
15429
15391
|
this.buffer.resize(newLength);
|
|
15430
15392
|
}
|
|
15431
15393
|
this.view.set(data, pageIndex);
|
|
@@ -15476,10 +15438,10 @@ class Memory {
|
|
|
15476
15438
|
this.memory = memory;
|
|
15477
15439
|
}
|
|
15478
15440
|
store(address, bytes) {
|
|
15479
|
-
return this.storeFrom(
|
|
15441
|
+
return this.storeFrom(memory_index_tryAsMemoryIndex(address), bytes);
|
|
15480
15442
|
}
|
|
15481
15443
|
read(address, output) {
|
|
15482
|
-
return this.loadInto(output,
|
|
15444
|
+
return this.loadInto(output, memory_index_tryAsMemoryIndex(address));
|
|
15483
15445
|
}
|
|
15484
15446
|
reset() {
|
|
15485
15447
|
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
@@ -15506,8 +15468,8 @@ class Memory {
|
|
|
15506
15468
|
let currentPosition = address;
|
|
15507
15469
|
let bytesLeft = bytes.length;
|
|
15508
15470
|
for (const page of pages) {
|
|
15509
|
-
const pageStartIndex = tryAsPageIndex(currentPosition %
|
|
15510
|
-
const bytesToWrite = Math.min(
|
|
15471
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % memory_consts_PAGE_SIZE);
|
|
15472
|
+
const bytesToWrite = Math.min(memory_consts_PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15511
15473
|
const sourceStartIndex = currentPosition - address;
|
|
15512
15474
|
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
15513
15475
|
page.storeFrom(pageStartIndex, source);
|
|
@@ -15556,8 +15518,8 @@ class Memory {
|
|
|
15556
15518
|
let currentPosition = startAddress;
|
|
15557
15519
|
let bytesLeft = result.length;
|
|
15558
15520
|
for (const page of pages) {
|
|
15559
|
-
const pageStartIndex = tryAsPageIndex(currentPosition %
|
|
15560
|
-
const bytesToRead = Math.min(
|
|
15521
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % memory_consts_PAGE_SIZE);
|
|
15522
|
+
const bytesToRead = Math.min(memory_consts_PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15561
15523
|
const destinationStartIndex = currentPosition - startAddress;
|
|
15562
15524
|
const destination = result.subarray(destinationStartIndex);
|
|
15563
15525
|
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
@@ -15584,7 +15546,7 @@ class Memory {
|
|
|
15584
15546
|
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize(newVirtualSbrkIndex));
|
|
15585
15547
|
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15586
15548
|
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15587
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) /
|
|
15549
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / memory_consts_PAGE_SIZE;
|
|
15588
15550
|
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15589
15551
|
for (const pageNumber of rangeToAllocate) {
|
|
15590
15552
|
const page = new WriteablePage(pageNumber);
|
|
@@ -15639,8 +15601,8 @@ class MemoryBuilder {
|
|
|
15639
15601
|
setReadablePages(start, end, data = new Uint8Array()) {
|
|
15640
15602
|
this.ensureNotFinalized();
|
|
15641
15603
|
debug_check `${start < end} end has to be bigger than start`;
|
|
15642
|
-
debug_check `${start %
|
|
15643
|
-
debug_check `${end %
|
|
15604
|
+
debug_check `${start % memory_consts_PAGE_SIZE === 0} start needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15605
|
+
debug_check `${end % memory_consts_PAGE_SIZE === 0} end needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15644
15606
|
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15645
15607
|
const length = end - start;
|
|
15646
15608
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15649,7 +15611,7 @@ class MemoryBuilder {
|
|
|
15649
15611
|
const noOfPages = pages.length;
|
|
15650
15612
|
for (let i = 0; i < noOfPages; i++) {
|
|
15651
15613
|
const pageNumber = pages[i];
|
|
15652
|
-
const dataChunk = data.subarray(i *
|
|
15614
|
+
const dataChunk = data.subarray(i * memory_consts_PAGE_SIZE, (i + 1) * memory_consts_PAGE_SIZE);
|
|
15653
15615
|
const page = new ReadablePage(pageNumber, dataChunk);
|
|
15654
15616
|
this.initialMemory.set(pageNumber, page);
|
|
15655
15617
|
}
|
|
@@ -15667,8 +15629,8 @@ class MemoryBuilder {
|
|
|
15667
15629
|
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
15668
15630
|
this.ensureNotFinalized();
|
|
15669
15631
|
debug_check `${start < end} end has to be bigger than start`;
|
|
15670
|
-
debug_check `${start %
|
|
15671
|
-
debug_check `${end %
|
|
15632
|
+
debug_check `${start % memory_consts_PAGE_SIZE === 0} start needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15633
|
+
debug_check `${end % memory_consts_PAGE_SIZE === 0} end needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15672
15634
|
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15673
15635
|
const length = end - start;
|
|
15674
15636
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15677,7 +15639,7 @@ class MemoryBuilder {
|
|
|
15677
15639
|
const noOfPages = pages.length;
|
|
15678
15640
|
for (let i = 0; i < noOfPages; i++) {
|
|
15679
15641
|
const pageNumber = pages[i];
|
|
15680
|
-
const dataChunk = data.subarray(i *
|
|
15642
|
+
const dataChunk = data.subarray(i * memory_consts_PAGE_SIZE, (i + 1) * memory_consts_PAGE_SIZE);
|
|
15681
15643
|
const page = new WriteablePage(pageNumber, dataChunk);
|
|
15682
15644
|
this.initialMemory.set(pageNumber, page);
|
|
15683
15645
|
}
|
|
@@ -15689,8 +15651,8 @@ class MemoryBuilder {
|
|
|
15689
15651
|
*/
|
|
15690
15652
|
setData(start, data) {
|
|
15691
15653
|
this.ensureNotFinalized();
|
|
15692
|
-
const pageOffset = start %
|
|
15693
|
-
const remainingSpaceOnPage =
|
|
15654
|
+
const pageOffset = start % memory_consts_PAGE_SIZE;
|
|
15655
|
+
const remainingSpaceOnPage = memory_consts_PAGE_SIZE - pageOffset;
|
|
15694
15656
|
debug_check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15695
15657
|
const length = data.length;
|
|
15696
15658
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15881,27 +15843,27 @@ class Program {
|
|
|
15881
15843
|
static fromSpi(blob, args, hasMetadata) {
|
|
15882
15844
|
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15883
15845
|
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
15884
|
-
const regs = new
|
|
15846
|
+
const regs = new registers_Registers();
|
|
15885
15847
|
regs.copyFrom(registers);
|
|
15886
15848
|
const memoryBuilder = new MemoryBuilder();
|
|
15887
15849
|
for (const { start, end, data } of rawMemory.readable) {
|
|
15888
|
-
const startIndex =
|
|
15889
|
-
const endIndex =
|
|
15850
|
+
const startIndex = memory_index_tryAsMemoryIndex(start);
|
|
15851
|
+
const endIndex = memory_index_tryAsMemoryIndex(end);
|
|
15890
15852
|
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15891
15853
|
}
|
|
15892
15854
|
for (const { start, end, data } of rawMemory.writeable) {
|
|
15893
|
-
const startIndex =
|
|
15894
|
-
const endIndex =
|
|
15855
|
+
const startIndex = memory_index_tryAsMemoryIndex(start);
|
|
15856
|
+
const endIndex = memory_index_tryAsMemoryIndex(end);
|
|
15895
15857
|
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15896
15858
|
}
|
|
15897
|
-
const heapStart =
|
|
15859
|
+
const heapStart = memory_index_tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
15898
15860
|
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
15899
15861
|
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
15900
15862
|
return new Program(code, regs, memory, metadata);
|
|
15901
15863
|
}
|
|
15902
15864
|
static fromGeneric(blob, hasMetadata) {
|
|
15903
15865
|
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15904
|
-
const regs = new
|
|
15866
|
+
const regs = new registers_Registers();
|
|
15905
15867
|
const memory = new Memory();
|
|
15906
15868
|
return new Program(code, regs, memory, metadata);
|
|
15907
15869
|
}
|
|
@@ -16916,6 +16878,45 @@ class BasicBlocks {
|
|
|
16916
16878
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/basic-blocks/index.ts
|
|
16917
16879
|
|
|
16918
16880
|
|
|
16881
|
+
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/gas.ts
|
|
16882
|
+
|
|
16883
|
+
|
|
16884
|
+
/** Create a new gas counter instance depending on the gas value. */
|
|
16885
|
+
function gasCounter(gas) {
|
|
16886
|
+
return new GasCounterU64(numbers_tryAsU64(gas));
|
|
16887
|
+
}
|
|
16888
|
+
class GasCounterU64 {
|
|
16889
|
+
gas;
|
|
16890
|
+
initialGas;
|
|
16891
|
+
constructor(gas) {
|
|
16892
|
+
this.gas = gas;
|
|
16893
|
+
this.initialGas = gas_tryAsGas(gas);
|
|
16894
|
+
}
|
|
16895
|
+
set(g) {
|
|
16896
|
+
this.gas = numbers_tryAsU64(g);
|
|
16897
|
+
}
|
|
16898
|
+
get() {
|
|
16899
|
+
return gas_tryAsGas(this.gas);
|
|
16900
|
+
}
|
|
16901
|
+
sub(g) {
|
|
16902
|
+
const result = this.gas - numbers_tryAsU64(g);
|
|
16903
|
+
if (result >= 0n) {
|
|
16904
|
+
this.gas = numbers_tryAsU64(result);
|
|
16905
|
+
return false;
|
|
16906
|
+
}
|
|
16907
|
+
this.gas = numbers_tryAsU64(0n);
|
|
16908
|
+
return true;
|
|
16909
|
+
}
|
|
16910
|
+
used() {
|
|
16911
|
+
const gasConsumed = numbers_tryAsU64(this.initialGas) - this.gas;
|
|
16912
|
+
// In we have less than zero left we assume that all gas has been consumed.
|
|
16913
|
+
if (gasConsumed < 0) {
|
|
16914
|
+
return this.initialGas;
|
|
16915
|
+
}
|
|
16916
|
+
return gas_tryAsGas(gasConsumed);
|
|
16917
|
+
}
|
|
16918
|
+
}
|
|
16919
|
+
|
|
16919
16920
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/instruction-gas-map.ts
|
|
16920
16921
|
|
|
16921
16922
|
|
|
@@ -17492,7 +17493,7 @@ class LoadOps {
|
|
|
17492
17493
|
}
|
|
17493
17494
|
loadNumber(address, registerIndex, numberLength) {
|
|
17494
17495
|
const registerBytes = this.regs.getBytesAsLittleEndian(registerIndex, REG_SIZE_BYTES);
|
|
17495
|
-
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength),
|
|
17496
|
+
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength), memory_index_tryAsMemoryIndex(address));
|
|
17496
17497
|
if (loadResult.isError) {
|
|
17497
17498
|
if (loadResult.error.isAccessFault) {
|
|
17498
17499
|
this.instructionResult.status = result_Result.FAULT_ACCESS;
|
|
@@ -17508,7 +17509,7 @@ class LoadOps {
|
|
|
17508
17509
|
loadSignedNumber(address, registerIndex, numberLength) {
|
|
17509
17510
|
// load all bytes from register to correctly handle the sign.
|
|
17510
17511
|
const registerBytes = this.regs.getBytesAsLittleEndian(registerIndex, REG_SIZE_BYTES);
|
|
17511
|
-
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength),
|
|
17512
|
+
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength), memory_index_tryAsMemoryIndex(address));
|
|
17512
17513
|
if (loadResult.isError) {
|
|
17513
17514
|
if (loadResult.error.isAccessFault) {
|
|
17514
17515
|
this.instructionResult.status = result_Result.FAULT_ACCESS;
|
|
@@ -17930,7 +17931,7 @@ class StoreOps {
|
|
|
17930
17931
|
this.store(address, secondImmediateDecoder.getExtendedBytesAsLittleEndian());
|
|
17931
17932
|
}
|
|
17932
17933
|
store(address, bytes) {
|
|
17933
|
-
const storeResult = this.memory.storeFrom(
|
|
17934
|
+
const storeResult = this.memory.storeFrom(memory_index_tryAsMemoryIndex(address), bytes);
|
|
17934
17935
|
if (storeResult.isOk) {
|
|
17935
17936
|
return;
|
|
17936
17937
|
}
|
|
@@ -17939,7 +17940,7 @@ class StoreOps {
|
|
|
17939
17940
|
}
|
|
17940
17941
|
else {
|
|
17941
17942
|
this.instructionResult.status = result_Result.FAULT;
|
|
17942
|
-
this.instructionResult.exitParam = getStartPageIndex(
|
|
17943
|
+
this.instructionResult.exitParam = getStartPageIndex(memory_index_tryAsMemoryIndex(storeResult.error.address));
|
|
17943
17944
|
}
|
|
17944
17945
|
}
|
|
17945
17946
|
}
|
|
@@ -18738,11 +18739,11 @@ class ProgramDecoder {
|
|
|
18738
18739
|
|
|
18739
18740
|
|
|
18740
18741
|
const interpreter_logger = Logger.new(import.meta.filename, "pvm");
|
|
18741
|
-
class
|
|
18742
|
+
class interpreter_Interpreter {
|
|
18742
18743
|
useSbrkGas;
|
|
18743
|
-
registers = new
|
|
18744
|
+
registers = new registers_Registers();
|
|
18744
18745
|
memory = new Memory();
|
|
18745
|
-
gas = gasCounter(
|
|
18746
|
+
gas = gasCounter(gas_tryAsGas(0));
|
|
18746
18747
|
code = new Uint8Array();
|
|
18747
18748
|
mask = Mask.empty();
|
|
18748
18749
|
pc = 0;
|
|
@@ -18876,8 +18877,8 @@ class Interpreter {
|
|
|
18876
18877
|
break;
|
|
18877
18878
|
case ArgumentType.TWO_REGISTERS:
|
|
18878
18879
|
if (this.useSbrkGas && currentInstruction === Instruction.SBRK) {
|
|
18879
|
-
const calculateSbrkCost = (length) => (alignToPageSize(length) /
|
|
18880
|
-
const underflow = this.gas.sub(
|
|
18880
|
+
const calculateSbrkCost = (length) => (alignToPageSize(length) / memory_consts_PAGE_SIZE) * 16;
|
|
18881
|
+
const underflow = this.gas.sub(gas_tryAsGas(calculateSbrkCost(this.registers.getLowerU32(argsResult.firstRegisterIndex))));
|
|
18881
18882
|
if (underflow) {
|
|
18882
18883
|
this.status = status_Status.OOG;
|
|
18883
18884
|
return this.status;
|
|
@@ -18972,12 +18973,88 @@ class Interpreter {
|
|
|
18972
18973
|
}
|
|
18973
18974
|
}
|
|
18974
18975
|
|
|
18976
|
+
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/debugger-adapter.ts
|
|
18977
|
+
|
|
18978
|
+
|
|
18979
|
+
|
|
18980
|
+
|
|
18981
|
+
|
|
18982
|
+
|
|
18983
|
+
class DebuggerAdapter {
|
|
18984
|
+
pvm;
|
|
18985
|
+
constructor(useSbrkGas = false) {
|
|
18986
|
+
this.pvm = new Interpreter({ useSbrkGas });
|
|
18987
|
+
}
|
|
18988
|
+
resetGeneric(rawProgram, flatRegisters, initialGas) {
|
|
18989
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
18990
|
+
}
|
|
18991
|
+
reset(rawProgram, pc, gas, maybeRegisters, maybeMemory) {
|
|
18992
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
18993
|
+
}
|
|
18994
|
+
getPageDump(pageNumber) {
|
|
18995
|
+
const page = this.pvm.getMemoryPage(pageNumber);
|
|
18996
|
+
if (page === null) {
|
|
18997
|
+
// page wasn't allocated so we return an empty page
|
|
18998
|
+
return safeAllocUint8Array(PAGE_SIZE);
|
|
18999
|
+
}
|
|
19000
|
+
if (page.length === PAGE_SIZE) {
|
|
19001
|
+
// page was allocated and has a proper size so we can simply return it
|
|
19002
|
+
return page;
|
|
19003
|
+
}
|
|
19004
|
+
// page was allocated but it is shorter than PAGE_SIZE so we have to extend it
|
|
19005
|
+
const fullPage = safeAllocUint8Array(PAGE_SIZE);
|
|
19006
|
+
fullPage.set(page);
|
|
19007
|
+
return fullPage;
|
|
19008
|
+
}
|
|
19009
|
+
setMemory(address, value) {
|
|
19010
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
19011
|
+
}
|
|
19012
|
+
getExitArg() {
|
|
19013
|
+
return this.pvm.getExitParam() ?? 0;
|
|
19014
|
+
}
|
|
19015
|
+
getStatus() {
|
|
19016
|
+
return this.pvm.getStatus();
|
|
19017
|
+
}
|
|
19018
|
+
nextStep() {
|
|
19019
|
+
return this.pvm.nextStep() === Status.OK;
|
|
19020
|
+
}
|
|
19021
|
+
nSteps(steps) {
|
|
19022
|
+
check `${steps >>> 0 > 0} Expected a positive integer got ${steps}`;
|
|
19023
|
+
for (let i = 0; i < steps; i++) {
|
|
19024
|
+
const isOk = this.nextStep();
|
|
19025
|
+
if (!isOk) {
|
|
19026
|
+
return false;
|
|
19027
|
+
}
|
|
19028
|
+
}
|
|
19029
|
+
return true;
|
|
19030
|
+
}
|
|
19031
|
+
getRegisters() {
|
|
19032
|
+
return this.pvm.registers.getAllU64();
|
|
19033
|
+
}
|
|
19034
|
+
setRegisters(registers) {
|
|
19035
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
19036
|
+
}
|
|
19037
|
+
getProgramCounter() {
|
|
19038
|
+
return this.pvm.getPC();
|
|
19039
|
+
}
|
|
19040
|
+
setNextProgramCounter(nextPc) {
|
|
19041
|
+
this.pvm.setNextPC(nextPc);
|
|
19042
|
+
}
|
|
19043
|
+
getGasLeft() {
|
|
19044
|
+
return BigInt(this.pvm.gas.get());
|
|
19045
|
+
}
|
|
19046
|
+
setGasLeft(gas) {
|
|
19047
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
19048
|
+
}
|
|
19049
|
+
}
|
|
19050
|
+
|
|
18975
19051
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/index.ts
|
|
18976
19052
|
|
|
18977
19053
|
|
|
18978
19054
|
|
|
18979
19055
|
|
|
18980
19056
|
|
|
19057
|
+
|
|
18981
19058
|
;// CONCATENATED MODULE: ./node_modules/@fluffylabs/anan-as/build/debug-raw.js
|
|
18982
19059
|
async function instantiate(module, imports = {}) {
|
|
18983
19060
|
const adaptedImports = {
|
|
@@ -19431,12 +19508,12 @@ class AnanasMemory {
|
|
|
19431
19508
|
}
|
|
19432
19509
|
class AnanasGasCounter {
|
|
19433
19510
|
instance;
|
|
19434
|
-
initialGas =
|
|
19511
|
+
initialGas = gas_tryAsGas(0n);
|
|
19435
19512
|
constructor(instance) {
|
|
19436
19513
|
this.instance = instance;
|
|
19437
19514
|
}
|
|
19438
19515
|
get() {
|
|
19439
|
-
return
|
|
19516
|
+
return gas_tryAsGas(this.instance.getGasLeft());
|
|
19440
19517
|
}
|
|
19441
19518
|
set(g) {
|
|
19442
19519
|
this.instance.setGasLeft(BigInt(g));
|
|
@@ -19541,7 +19618,7 @@ class InterpreterInstanceManager {
|
|
|
19541
19618
|
const instances = [];
|
|
19542
19619
|
switch (interpreter) {
|
|
19543
19620
|
case PvmBackend.BuiltIn:
|
|
19544
|
-
instances.push(new
|
|
19621
|
+
instances.push(new interpreter_Interpreter({
|
|
19545
19622
|
useSbrkGas: false,
|
|
19546
19623
|
}));
|
|
19547
19624
|
break;
|
|
@@ -21997,7 +22074,7 @@ class Transfer {
|
|
|
21997
22074
|
*/
|
|
21998
22075
|
basicGasCost = compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2)
|
|
21999
22076
|
? gas_tryAsSmallGas(10)
|
|
22000
|
-
: (regs) =>
|
|
22077
|
+
: (regs) => gas_tryAsGas(10n + regs.get(TRANSFER_GAS_FEE_REG));
|
|
22001
22078
|
tracedRegisters = traceRegisters(transfer_IN_OUT_REG, AMOUNT_REG, TRANSFER_GAS_FEE_REG, MEMO_START_REG);
|
|
22002
22079
|
constructor(currentServiceId, partialState) {
|
|
22003
22080
|
this.currentServiceId = currentServiceId;
|
|
@@ -22025,7 +22102,7 @@ class Transfer {
|
|
|
22025
22102
|
if (transferResult.isOk) {
|
|
22026
22103
|
if (compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2)) {
|
|
22027
22104
|
// substracting value `t`
|
|
22028
|
-
const underflow = gas.sub(
|
|
22105
|
+
const underflow = gas.sub(gas_tryAsGas(transferGasFee));
|
|
22029
22106
|
if (underflow) {
|
|
22030
22107
|
return PvmExecution.OOG;
|
|
22031
22108
|
}
|
|
@@ -22770,7 +22847,7 @@ class Accumulate {
|
|
|
22770
22847
|
serviceId,
|
|
22771
22848
|
argsLength: numbers_tryAsU32(transfers.length + operands.length),
|
|
22772
22849
|
});
|
|
22773
|
-
const result = await executor.run(invocationArgs,
|
|
22850
|
+
const result = await executor.run(invocationArgs, gas_tryAsGas(gas));
|
|
22774
22851
|
const [newState, checkpoint] = partialState.getStateUpdates();
|
|
22775
22852
|
/**
|
|
22776
22853
|
* PVM invocation returned and error so we return the checkpoint
|
|
@@ -23174,7 +23251,7 @@ class DeferredTransfers {
|
|
|
23174
23251
|
partiallyUpdatedState.updateServiceInfo(serviceId, newInfo);
|
|
23175
23252
|
const partialState = new AccumulateExternalities(this.chainSpec, this.blake2b, partiallyUpdatedState, serviceId, serviceId, timeslot);
|
|
23176
23253
|
const fetchExternalities = FetchExternalities.createForOnTransfer({ entropy, transfers }, this.chainSpec);
|
|
23177
|
-
let consumedGas =
|
|
23254
|
+
let consumedGas = gas_tryAsGas(0);
|
|
23178
23255
|
const hasTransfers = transfers.length > 0;
|
|
23179
23256
|
const isCodeCorrect = code !== null && code.length <= W_C;
|
|
23180
23257
|
if (!hasTransfers || !isCodeCorrect) {
|
|
@@ -23192,7 +23269,7 @@ class DeferredTransfers {
|
|
|
23192
23269
|
const executor = await PvmExecutor.createOnTransferExecutor(serviceId, code, { partialState, fetchExternalities }, this.pvm);
|
|
23193
23270
|
const args = encoder_Encoder.encodeObject(deferred_transfers_ARGS_CODEC, { timeslot, serviceId, transfersLength: numbers_tryAsU32(transfers.length) }, this.chainSpec);
|
|
23194
23271
|
const gas = transfers.reduce((acc, item) => acc + item.gas, 0n);
|
|
23195
|
-
consumedGas = (await executor.run(args,
|
|
23272
|
+
consumedGas = (await executor.run(args, gas_tryAsGas(gas))).consumedGas;
|
|
23196
23273
|
}
|
|
23197
23274
|
transferStatistics.set(serviceId, { count: numbers_tryAsU32(transfers.length), gasUsed: tryAsServiceGas(consumedGas) });
|
|
23198
23275
|
const [updatedState] = partialState.getStateUpdates();
|