@typeberry/jam 0.4.0 → 0.4.1-0a3acb2
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 +505 -42
- package/bootstrap-generator.mjs.map +1 -1
- package/bootstrap-importer.mjs +785 -244
- package/bootstrap-importer.mjs.map +1 -1
- package/bootstrap-network.mjs +479 -38
- package/bootstrap-network.mjs.map +1 -1
- package/index.js +789 -248
- 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.
|
|
@@ -7100,11 +7104,9 @@ function sequenceViewFixLen(type, { fixedLength }) {
|
|
|
7100
7104
|
|
|
7101
7105
|
/** Helper function to create most used hashes in the block */
|
|
7102
7106
|
class TransitionHasher {
|
|
7103
|
-
context;
|
|
7104
7107
|
keccakHasher;
|
|
7105
7108
|
blake2b;
|
|
7106
|
-
constructor(
|
|
7107
|
-
this.context = context;
|
|
7109
|
+
constructor(keccakHasher, blake2b) {
|
|
7108
7110
|
this.keccakHasher = keccakHasher;
|
|
7109
7111
|
this.blake2b = blake2b;
|
|
7110
7112
|
}
|
|
@@ -7226,9 +7228,438 @@ class ArrayView {
|
|
|
7226
7228
|
}
|
|
7227
7229
|
}
|
|
7228
7230
|
|
|
7231
|
+
;// CONCATENATED MODULE: ./packages/core/collections/blob-dictionary.ts
|
|
7232
|
+
|
|
7233
|
+
|
|
7234
|
+
/** A map which uses byte blobs as keys */
|
|
7235
|
+
class BlobDictionary extends WithDebug {
|
|
7236
|
+
mapNodeThreshold;
|
|
7237
|
+
/**
|
|
7238
|
+
* The root node of the dictionary.
|
|
7239
|
+
*
|
|
7240
|
+
* This is the main internal data structure that organizes entries
|
|
7241
|
+
* in a tree-like fashion (array-based nodes up to `mapNodeThreshold`,
|
|
7242
|
+
* map-based nodes beyond it). All insertions, updates, and deletions
|
|
7243
|
+
* operate through this structure.
|
|
7244
|
+
*/
|
|
7245
|
+
root = Node.withList();
|
|
7246
|
+
/**
|
|
7247
|
+
* Auxiliary map that stores references to the original keys and their values.
|
|
7248
|
+
*
|
|
7249
|
+
* - Overriding a value in the main structure does not replace the original key reference.
|
|
7250
|
+
* - Used for efficient iteration over `keys()`, `values()`, `entries()`, and computing `size`.
|
|
7251
|
+
*/
|
|
7252
|
+
keyvals = new Map();
|
|
7253
|
+
/**
|
|
7254
|
+
* Protected constructor used internally by `BlobDictionary.new`
|
|
7255
|
+
* and `BlobDictionary.fromEntries`.
|
|
7256
|
+
*
|
|
7257
|
+
* This enforces controlled instantiation — users should create instances
|
|
7258
|
+
* through the provided static factory methods instead of calling the
|
|
7259
|
+
* constructor directly.
|
|
7260
|
+
*
|
|
7261
|
+
* @param mapNodeThreshold - The threshold that determines when the dictionary
|
|
7262
|
+
* switches from using an array-based (`ListChildren`) node to a map-based (`MapChildren`) node for storing entries.
|
|
7263
|
+
*/
|
|
7264
|
+
constructor(mapNodeThreshold) {
|
|
7265
|
+
super();
|
|
7266
|
+
this.mapNodeThreshold = mapNodeThreshold;
|
|
7267
|
+
}
|
|
7268
|
+
/**
|
|
7269
|
+
* Returns the number of entries in the dictionary.
|
|
7270
|
+
*
|
|
7271
|
+
* The count is derived from the auxiliary `keyvals` map, which stores
|
|
7272
|
+
* all original key references and their associated values. This ensures
|
|
7273
|
+
* that the `size` reflects the actual number of entries, independent of
|
|
7274
|
+
* internal overrides in the main `root` structure.
|
|
7275
|
+
*
|
|
7276
|
+
* @returns The total number of entries in the dictionary.
|
|
7277
|
+
*/
|
|
7278
|
+
get size() {
|
|
7279
|
+
return this.keyvals.size;
|
|
7280
|
+
}
|
|
7281
|
+
[TEST_COMPARE_USING]() {
|
|
7282
|
+
const vals = Array.from(this);
|
|
7283
|
+
vals.sort((a, b) => a[0].compare(b[0]).value);
|
|
7284
|
+
return vals;
|
|
7285
|
+
}
|
|
7286
|
+
/**
|
|
7287
|
+
* Creates an empty `BlobDictionary`.
|
|
7288
|
+
*
|
|
7289
|
+
* @param mapNodeThreshold - The threshold that determines when the dictionary
|
|
7290
|
+
* switches from using an array-based (`ListChildren`) node to a map-based (`MapChildren`) node for storing entries.
|
|
7291
|
+
* Defaults to `0`.
|
|
7292
|
+
*
|
|
7293
|
+
* @returns A new, empty `BlobDictionary` instance.
|
|
7294
|
+
*/
|
|
7295
|
+
static new(mapNodeThreshold = 0) {
|
|
7296
|
+
return new BlobDictionary(mapNodeThreshold);
|
|
7297
|
+
}
|
|
7298
|
+
/**
|
|
7299
|
+
* Creates a new `BlobDictionary` initialized with the given entries.
|
|
7300
|
+
*
|
|
7301
|
+
* @param entries - An array of `[key, value]` pairs used to populate the dictionary.
|
|
7302
|
+
* @param mapNodeThreshold - The threshold that determines when the dictionary
|
|
7303
|
+
* switches from using an array-based (`ListChildren`) node to a map-based (`MapChildren`) node for storing entries.
|
|
7304
|
+
* Defaults to `0`.
|
|
7305
|
+
*
|
|
7306
|
+
* @returns A new `BlobDictionary` containing the provided entries.
|
|
7307
|
+
*/
|
|
7308
|
+
static fromEntries(entries, mapNodeThreshold) {
|
|
7309
|
+
const dict = BlobDictionary.new(mapNodeThreshold);
|
|
7310
|
+
for (const [key, value] of entries) {
|
|
7311
|
+
dict.set(key, value);
|
|
7312
|
+
}
|
|
7313
|
+
return dict;
|
|
7314
|
+
}
|
|
7315
|
+
/**
|
|
7316
|
+
* Internal helper that inserts, updates or deletes an entry in the dictionary.
|
|
7317
|
+
*
|
|
7318
|
+
* Behaviour details:
|
|
7319
|
+
* - Passing `undefined` as `value` indicates a deletion. (E.g. `delete` uses `internalSet(key, undefined)`.)
|
|
7320
|
+
* - When an add (new entry) or a delete actually changes the structure, the method returns the affected leaf node.
|
|
7321
|
+
* - When the call only overrides an existing value (no structural add/delete), the method returns `null`.
|
|
7322
|
+
*
|
|
7323
|
+
* This method is intended for internal use by the dictionary implementation and allows `undefined` as a
|
|
7324
|
+
* sentinel value to signal removals.
|
|
7325
|
+
*
|
|
7326
|
+
* @param key - The key to insert, update or remove.
|
|
7327
|
+
* @param value - The value to associate with the key, or `undefined` to remove the key.
|
|
7328
|
+
* @returns The leaf node created or removed on add/delete, or `null` if the operation only overwrote an existing value.
|
|
7329
|
+
*/
|
|
7330
|
+
internalSet(key, value) {
|
|
7331
|
+
let node = this.root;
|
|
7332
|
+
const keyChunkGenerator = key.chunks(CHUNK_SIZE);
|
|
7333
|
+
let depth = 0;
|
|
7334
|
+
for (;;) {
|
|
7335
|
+
const maybeKeyChunk = keyChunkGenerator.next().value;
|
|
7336
|
+
if (maybeKeyChunk === undefined) {
|
|
7337
|
+
if (value === undefined) {
|
|
7338
|
+
return node.remove(key);
|
|
7339
|
+
}
|
|
7340
|
+
return node.set(key, value);
|
|
7341
|
+
}
|
|
7342
|
+
const keyChunk = opaque_asOpaqueType(maybeKeyChunk);
|
|
7343
|
+
if (node.children instanceof ListChildren) {
|
|
7344
|
+
const subkey = bytes_BytesBlob.blobFrom(key.raw.subarray(CHUNK_SIZE * depth));
|
|
7345
|
+
const leaf = value !== undefined ? node.children.insert(subkey, { key, value }) : node.children.remove(subkey);
|
|
7346
|
+
if (subkey.length > CHUNK_SIZE && node.children.children.length > this.mapNodeThreshold) {
|
|
7347
|
+
node.convertListChildrenToMap();
|
|
7348
|
+
}
|
|
7349
|
+
return leaf;
|
|
7350
|
+
}
|
|
7351
|
+
depth += 1;
|
|
7352
|
+
const children = node.children;
|
|
7353
|
+
if (children instanceof ListChildren) {
|
|
7354
|
+
throw new Error("We handle list node earlier. If we fall through, we know it's for the `Map` case.");
|
|
7355
|
+
}
|
|
7356
|
+
if (children instanceof MapChildren) {
|
|
7357
|
+
const maybeNode = children.getChild(keyChunk);
|
|
7358
|
+
if (maybeNode !== undefined) {
|
|
7359
|
+
// simply go one level deeper
|
|
7360
|
+
node = maybeNode;
|
|
7361
|
+
}
|
|
7362
|
+
else {
|
|
7363
|
+
// we are trying to remove an item, but it does not exist
|
|
7364
|
+
if (value === undefined) {
|
|
7365
|
+
return null;
|
|
7366
|
+
}
|
|
7367
|
+
// no more child nodes, we insert a new one.
|
|
7368
|
+
const newNode = Node.withList();
|
|
7369
|
+
children.setChild(keyChunk, newNode);
|
|
7370
|
+
node = newNode;
|
|
7371
|
+
}
|
|
7372
|
+
continue;
|
|
7373
|
+
}
|
|
7374
|
+
assertNever(children);
|
|
7375
|
+
}
|
|
7376
|
+
}
|
|
7377
|
+
/**
|
|
7378
|
+
* Adds a new entry to the dictionary or updates the value of an existing key.
|
|
7379
|
+
*
|
|
7380
|
+
* If an entry with the given key already exists, its value is replaced
|
|
7381
|
+
* with the new one.
|
|
7382
|
+
*
|
|
7383
|
+
* @param key - The key to add or update in the dictionary.
|
|
7384
|
+
* @param value - The value to associate with the specified key.
|
|
7385
|
+
* @returns Nothing (`void`).
|
|
7386
|
+
*/
|
|
7387
|
+
set(key, value) {
|
|
7388
|
+
const leaf = this.internalSet(key, value);
|
|
7389
|
+
if (leaf !== null) {
|
|
7390
|
+
this.keyvals.set(leaf.key, leaf);
|
|
7391
|
+
}
|
|
7392
|
+
}
|
|
7393
|
+
/**
|
|
7394
|
+
* Retrieves the value associated with the given key from the dictionary.
|
|
7395
|
+
*
|
|
7396
|
+
* If the key does not exist, this method returns `undefined`.
|
|
7397
|
+
*
|
|
7398
|
+
* @param key - The key whose associated value should be retrieved.
|
|
7399
|
+
* @returns The value associated with the specified key, or `undefined` if the key is not present.
|
|
7400
|
+
*/
|
|
7401
|
+
get(key) {
|
|
7402
|
+
let node = this.root;
|
|
7403
|
+
const pathChunksGenerator = key.chunks(CHUNK_SIZE);
|
|
7404
|
+
let depth = 0;
|
|
7405
|
+
while (node !== undefined) {
|
|
7406
|
+
const maybePathChunk = pathChunksGenerator.next().value;
|
|
7407
|
+
if (node.children instanceof ListChildren) {
|
|
7408
|
+
const subkey = bytes_BytesBlob.blobFrom(key.raw.subarray(depth * CHUNK_SIZE));
|
|
7409
|
+
const child = node.children.find(subkey);
|
|
7410
|
+
if (child !== null) {
|
|
7411
|
+
return child.value;
|
|
7412
|
+
}
|
|
7413
|
+
}
|
|
7414
|
+
if (maybePathChunk === undefined) {
|
|
7415
|
+
return node.getLeaf()?.value;
|
|
7416
|
+
}
|
|
7417
|
+
if (node.children instanceof MapChildren) {
|
|
7418
|
+
const pathChunk = opaque_asOpaqueType(maybePathChunk);
|
|
7419
|
+
node = node.children.getChild(pathChunk);
|
|
7420
|
+
depth += 1;
|
|
7421
|
+
}
|
|
7422
|
+
}
|
|
7423
|
+
return undefined;
|
|
7424
|
+
}
|
|
7425
|
+
/**
|
|
7426
|
+
* Checks whether the dictionary contains an entry for the given key.
|
|
7427
|
+
*
|
|
7428
|
+
* ⚠️ **Note:** Avoid using `has(...)` together with `get(...)` in a pattern like this:
|
|
7429
|
+
*
|
|
7430
|
+
* ```ts
|
|
7431
|
+
* if (dict.has(key)) {
|
|
7432
|
+
* const value = dict.get(key);
|
|
7433
|
+
* ...
|
|
7434
|
+
* }
|
|
7435
|
+
* ```
|
|
7436
|
+
*
|
|
7437
|
+
* This approach performs two lookups for the same key.
|
|
7438
|
+
*
|
|
7439
|
+
* Instead, prefer the following pattern, which retrieves the value once:
|
|
7440
|
+
*
|
|
7441
|
+
* ```ts
|
|
7442
|
+
* const value = dict.get(key);
|
|
7443
|
+
* if (value !== undefined) {
|
|
7444
|
+
* ...
|
|
7445
|
+
* }
|
|
7446
|
+
* ```
|
|
7447
|
+
*
|
|
7448
|
+
* @param key - The key to check for.
|
|
7449
|
+
* @returns `true` if the dictionary contains an entry for the given key, otherwise `false`.
|
|
7450
|
+
*/
|
|
7451
|
+
has(key) {
|
|
7452
|
+
return this.get(key) !== undefined;
|
|
7453
|
+
}
|
|
7454
|
+
/**
|
|
7455
|
+
* Removes an entry with the specified key from the dictionary.
|
|
7456
|
+
*
|
|
7457
|
+
* Internally, this calls {@link internalSet} with `undefined` to mark the entry as deleted.
|
|
7458
|
+
*
|
|
7459
|
+
* @param key - The key of the entry to remove.
|
|
7460
|
+
* @returns `true` if an entry was removed (i.e. the key existed), otherwise `false`.
|
|
7461
|
+
*/
|
|
7462
|
+
delete(key) {
|
|
7463
|
+
const leaf = this.internalSet(key, undefined);
|
|
7464
|
+
if (leaf !== null) {
|
|
7465
|
+
this.keyvals.delete(leaf.key);
|
|
7466
|
+
return true;
|
|
7467
|
+
}
|
|
7468
|
+
return false;
|
|
7469
|
+
}
|
|
7470
|
+
/**
|
|
7471
|
+
* Returns an iterator over the keys in the dictionary.
|
|
7472
|
+
*
|
|
7473
|
+
* The iterator yields each key in insertion order.
|
|
7474
|
+
*
|
|
7475
|
+
* @returns An iterator over all keys in the dictionary.
|
|
7476
|
+
*/
|
|
7477
|
+
keys() {
|
|
7478
|
+
return this.keyvals.keys();
|
|
7479
|
+
}
|
|
7480
|
+
/**
|
|
7481
|
+
* Returns an iterator over the values in the dictionary.
|
|
7482
|
+
*
|
|
7483
|
+
* The iterator yields each value in insertion order.
|
|
7484
|
+
*
|
|
7485
|
+
* @returns An iterator over all values in the dictionary.
|
|
7486
|
+
*/
|
|
7487
|
+
*values() {
|
|
7488
|
+
for (const leaf of this.keyvals.values()) {
|
|
7489
|
+
yield leaf.value;
|
|
7490
|
+
}
|
|
7491
|
+
}
|
|
7492
|
+
/**
|
|
7493
|
+
* Returns an iterator over the `[key, value]` pairs in the dictionary.
|
|
7494
|
+
*
|
|
7495
|
+
* The iterator yields entries in insertion order.
|
|
7496
|
+
*
|
|
7497
|
+
* @returns An iterator over `[key, value]` tuples for each entry in the dictionary.
|
|
7498
|
+
*/
|
|
7499
|
+
*entries() {
|
|
7500
|
+
for (const leaf of this.keyvals.values()) {
|
|
7501
|
+
yield [leaf.key, leaf.value];
|
|
7502
|
+
}
|
|
7503
|
+
}
|
|
7504
|
+
/**
|
|
7505
|
+
* Default iterator for the dictionary.
|
|
7506
|
+
*
|
|
7507
|
+
* Equivalent to calling {@link entries}.
|
|
7508
|
+
* Enables iteration with `for...of`:
|
|
7509
|
+
*
|
|
7510
|
+
* ```ts
|
|
7511
|
+
* for (const [key, value] of dict) {
|
|
7512
|
+
* ...
|
|
7513
|
+
* }
|
|
7514
|
+
* ```
|
|
7515
|
+
*
|
|
7516
|
+
* @returns An iterator over `[key, value]` pairs.
|
|
7517
|
+
*/
|
|
7518
|
+
[Symbol.iterator]() {
|
|
7519
|
+
return this.entries();
|
|
7520
|
+
}
|
|
7521
|
+
/**
|
|
7522
|
+
* Creates a new sorted array of values, ordered by their corresponding keys.
|
|
7523
|
+
*
|
|
7524
|
+
* Iterates over all entries in the dictionary and sorts them according
|
|
7525
|
+
* to the provided comparator function applied to the keys.
|
|
7526
|
+
*
|
|
7527
|
+
* @param comparator - A comparator function that can compare two keys.
|
|
7528
|
+
*
|
|
7529
|
+
* @returns A new array containing all values from the dictionary,
|
|
7530
|
+
* sorted according to their keys.
|
|
7531
|
+
*/
|
|
7532
|
+
toSortedArray(comparator) {
|
|
7533
|
+
const vals = Array.from(this);
|
|
7534
|
+
vals.sort((a, b) => comparator(a[0], b[0]).value);
|
|
7535
|
+
return vals.map((x) => x[1]);
|
|
7536
|
+
}
|
|
7537
|
+
}
|
|
7538
|
+
const CHUNK_SIZE = 6;
|
|
7539
|
+
/**
|
|
7540
|
+
* A function to transform a bytes chunk (up to 6 bytes into U48 number)
|
|
7541
|
+
*
|
|
7542
|
+
* Note that it uses 3 additional bits to store length(`value * 8 + len;`),
|
|
7543
|
+
* It is needed to distinguish shorter chunks that have 0s at the end, for example: [1, 2] and [1, 2, 0]
|
|
7544
|
+
* */
|
|
7545
|
+
function bytesAsU48(bytes) {
|
|
7546
|
+
const len = bytes.length;
|
|
7547
|
+
debug_check `${len <= CHUNK_SIZE} Length has to be <= ${CHUNK_SIZE}, got: ${len}`;
|
|
7548
|
+
let value = bytes[3] | (bytes[2] << 8) | (bytes[1] << 16) | (bytes[0] << 24);
|
|
7549
|
+
for (let i = 4; i < bytes.length; i++) {
|
|
7550
|
+
value = value * 256 + bytes[i];
|
|
7551
|
+
}
|
|
7552
|
+
return value * 8 + len;
|
|
7553
|
+
}
|
|
7554
|
+
class Node {
|
|
7555
|
+
leaf;
|
|
7556
|
+
children;
|
|
7557
|
+
convertListChildrenToMap() {
|
|
7558
|
+
if (!(this.children instanceof ListChildren)) {
|
|
7559
|
+
return;
|
|
7560
|
+
}
|
|
7561
|
+
this.children = MapChildren.fromListNode(this.children);
|
|
7562
|
+
}
|
|
7563
|
+
static withList() {
|
|
7564
|
+
return new Node(undefined, ListChildren.new());
|
|
7565
|
+
}
|
|
7566
|
+
static withMap() {
|
|
7567
|
+
return new Node(undefined, MapChildren.new());
|
|
7568
|
+
}
|
|
7569
|
+
constructor(leaf, children) {
|
|
7570
|
+
this.leaf = leaf;
|
|
7571
|
+
this.children = children;
|
|
7572
|
+
}
|
|
7573
|
+
getLeaf() {
|
|
7574
|
+
return this.leaf;
|
|
7575
|
+
}
|
|
7576
|
+
remove(_key) {
|
|
7577
|
+
if (this.leaf === undefined) {
|
|
7578
|
+
return null;
|
|
7579
|
+
}
|
|
7580
|
+
const removedLeaf = this.leaf;
|
|
7581
|
+
this.leaf = undefined;
|
|
7582
|
+
return removedLeaf;
|
|
7583
|
+
}
|
|
7584
|
+
set(key, value) {
|
|
7585
|
+
if (this.leaf === undefined) {
|
|
7586
|
+
this.leaf = { key, value };
|
|
7587
|
+
return this.leaf;
|
|
7588
|
+
}
|
|
7589
|
+
this.leaf.value = value;
|
|
7590
|
+
return null;
|
|
7591
|
+
}
|
|
7592
|
+
}
|
|
7593
|
+
class ListChildren {
|
|
7594
|
+
children = [];
|
|
7595
|
+
constructor() { }
|
|
7596
|
+
find(key) {
|
|
7597
|
+
const result = this.children.find((item) => item[0].isEqualTo(key));
|
|
7598
|
+
if (result !== undefined) {
|
|
7599
|
+
return result[1];
|
|
7600
|
+
}
|
|
7601
|
+
return null;
|
|
7602
|
+
}
|
|
7603
|
+
remove(key) {
|
|
7604
|
+
const existingIndex = this.children.findIndex((item) => item[0].isEqualTo(key));
|
|
7605
|
+
if (existingIndex >= 0) {
|
|
7606
|
+
const ret = this.children.splice(existingIndex, 1);
|
|
7607
|
+
return ret[0][1];
|
|
7608
|
+
}
|
|
7609
|
+
return null;
|
|
7610
|
+
}
|
|
7611
|
+
insert(key, leaf) {
|
|
7612
|
+
const existingIndex = this.children.findIndex((item) => item[0].isEqualTo(key));
|
|
7613
|
+
if (existingIndex >= 0) {
|
|
7614
|
+
const existing = this.children[existingIndex];
|
|
7615
|
+
existing[1].value = leaf.value;
|
|
7616
|
+
return null;
|
|
7617
|
+
}
|
|
7618
|
+
this.children.push([key, leaf]);
|
|
7619
|
+
return leaf;
|
|
7620
|
+
}
|
|
7621
|
+
static new() {
|
|
7622
|
+
return new ListChildren();
|
|
7623
|
+
}
|
|
7624
|
+
}
|
|
7625
|
+
class MapChildren {
|
|
7626
|
+
children = new Map();
|
|
7627
|
+
constructor() { }
|
|
7628
|
+
static new() {
|
|
7629
|
+
return new MapChildren();
|
|
7630
|
+
}
|
|
7631
|
+
static fromListNode(node) {
|
|
7632
|
+
const mapNode = new MapChildren();
|
|
7633
|
+
for (const [key, leaf] of node.children) {
|
|
7634
|
+
const currentKeyChunk = opaque_asOpaqueType(bytes_BytesBlob.blobFrom(key.raw.subarray(0, CHUNK_SIZE)));
|
|
7635
|
+
const subKey = bytes_BytesBlob.blobFrom(key.raw.subarray(CHUNK_SIZE));
|
|
7636
|
+
let child = mapNode.getChild(currentKeyChunk);
|
|
7637
|
+
if (child === undefined) {
|
|
7638
|
+
child = Node.withList();
|
|
7639
|
+
mapNode.setChild(currentKeyChunk, child);
|
|
7640
|
+
}
|
|
7641
|
+
const children = child.children;
|
|
7642
|
+
children.insert(subKey, leaf);
|
|
7643
|
+
}
|
|
7644
|
+
return mapNode;
|
|
7645
|
+
}
|
|
7646
|
+
getChild(keyChunk) {
|
|
7647
|
+
const chunkAsNumber = bytesAsU48(keyChunk.raw);
|
|
7648
|
+
return this.children.get(chunkAsNumber);
|
|
7649
|
+
}
|
|
7650
|
+
setChild(keyChunk, node) {
|
|
7651
|
+
const chunkAsNumber = bytesAsU48(keyChunk.raw);
|
|
7652
|
+
this.children.set(chunkAsNumber, node);
|
|
7653
|
+
}
|
|
7654
|
+
}
|
|
7655
|
+
|
|
7229
7656
|
;// CONCATENATED MODULE: ./packages/core/collections/hash-dictionary.ts
|
|
7230
|
-
/**
|
|
7231
|
-
|
|
7657
|
+
/**
|
|
7658
|
+
* A map which uses hashes as keys.
|
|
7659
|
+
*
|
|
7660
|
+
* @deprecated
|
|
7661
|
+
* */
|
|
7662
|
+
class StringHashDictionary {
|
|
7232
7663
|
// TODO [ToDr] [crit] We can't use `TrieHash` directly in the map,
|
|
7233
7664
|
// because of the way it's being compared. Hence having `string` here.
|
|
7234
7665
|
// This has to be benchmarked and re-written to a custom map most likely.
|
|
@@ -7294,6 +7725,17 @@ class hash_dictionary_HashDictionary {
|
|
|
7294
7725
|
}
|
|
7295
7726
|
}
|
|
7296
7727
|
|
|
7728
|
+
/**
|
|
7729
|
+
* A value that indicates when `BlobDictionary` transforms Array nodes into Map nodes.
|
|
7730
|
+
* In practice, it doesn't matter much because, in real life, arrays in this structure usually have a length close to 1.
|
|
7731
|
+
*/
|
|
7732
|
+
const BLOB_DICTIONARY_THRESHOLD = 5;
|
|
7733
|
+
class hash_dictionary_HashDictionary extends BlobDictionary {
|
|
7734
|
+
constructor() {
|
|
7735
|
+
super(BLOB_DICTIONARY_THRESHOLD);
|
|
7736
|
+
}
|
|
7737
|
+
}
|
|
7738
|
+
|
|
7297
7739
|
;// CONCATENATED MODULE: ./packages/core/collections/hash-set.ts
|
|
7298
7740
|
|
|
7299
7741
|
/** A set specialized for storing hashes. */
|
|
@@ -7758,6 +8200,18 @@ class SortedSet extends SortedArray {
|
|
|
7758
8200
|
|
|
7759
8201
|
|
|
7760
8202
|
|
|
8203
|
+
function getTruncatedKey(key) {
|
|
8204
|
+
// Always return exactly TRUNCATED_HASH_SIZE bytes.
|
|
8205
|
+
if (key.length === TRUNCATED_HASH_SIZE) {
|
|
8206
|
+
return key;
|
|
8207
|
+
}
|
|
8208
|
+
return bytes_Bytes.fromBlob(key.raw.subarray(0, TRUNCATED_HASH_SIZE), TRUNCATED_HASH_SIZE);
|
|
8209
|
+
}
|
|
8210
|
+
/**
|
|
8211
|
+
* A value that indicates when `BlobDictionary` transforms Array nodes into Map nodes.
|
|
8212
|
+
* In practice, it doesn't matter much because, in real life, arrays in this structure usually have a length close to 1.
|
|
8213
|
+
*/
|
|
8214
|
+
const truncated_hash_dictionary_BLOB_DICTIONARY_THRESHOLD = 5;
|
|
7761
8215
|
/**
|
|
7762
8216
|
* A collection of hash-based keys (likely `StateKey`s) which ignores
|
|
7763
8217
|
* differences on the last byte.
|
|
@@ -7770,48 +8224,37 @@ class TruncatedHashDictionary {
|
|
|
7770
8224
|
* Each key will be copied and have the last byte replace with a 0.
|
|
7771
8225
|
*/
|
|
7772
8226
|
static fromEntries(entries) {
|
|
7773
|
-
|
|
7774
|
-
const mapped = Array.from(entries).map(([key, value]) => {
|
|
7775
|
-
const newKey = bytes_Bytes.zero(hash_HASH_SIZE).asOpaque();
|
|
7776
|
-
newKey.raw.set(key.raw.subarray(0, TRUNCATED_HASH_SIZE));
|
|
7777
|
-
return [newKey, value];
|
|
7778
|
-
});
|
|
7779
|
-
return new TruncatedHashDictionary(hash_dictionary_HashDictionary.fromEntries(mapped));
|
|
8227
|
+
return new TruncatedHashDictionary(BlobDictionary.fromEntries(Array.from(entries).map(([key, value]) => [getTruncatedKey(key), value]), truncated_hash_dictionary_BLOB_DICTIONARY_THRESHOLD));
|
|
7780
8228
|
}
|
|
7781
|
-
/** A truncated key which we re-use to query the dictionary. */
|
|
7782
|
-
truncatedKey = bytes_Bytes.zero(hash_HASH_SIZE).asOpaque();
|
|
7783
8229
|
constructor(dict) {
|
|
7784
8230
|
this.dict = dict;
|
|
7785
8231
|
}
|
|
7786
8232
|
[TEST_COMPARE_USING]() {
|
|
7787
|
-
return this.dict;
|
|
8233
|
+
return Array.from(this.dict);
|
|
7788
8234
|
}
|
|
7789
8235
|
/** Return number of items in the dictionary. */
|
|
7790
8236
|
get size() {
|
|
7791
8237
|
return this.dict.size;
|
|
7792
8238
|
}
|
|
7793
8239
|
/** Retrieve a value that matches the key on `TRUNCATED_HASH_SIZE`. */
|
|
7794
|
-
get(
|
|
7795
|
-
|
|
7796
|
-
return this.dict.get(
|
|
8240
|
+
get(key) {
|
|
8241
|
+
const truncatedKey = getTruncatedKey(key);
|
|
8242
|
+
return this.dict.get(truncatedKey);
|
|
7797
8243
|
}
|
|
7798
8244
|
/** Return true if the key is present in the dictionary */
|
|
7799
|
-
has(
|
|
7800
|
-
|
|
7801
|
-
return this.dict.has(
|
|
8245
|
+
has(key) {
|
|
8246
|
+
const truncatedKey = getTruncatedKey(key);
|
|
8247
|
+
return this.dict.has(truncatedKey);
|
|
7802
8248
|
}
|
|
7803
8249
|
/** Set or update a value that matches the key on `TRUNCATED_HASH_SIZE`. */
|
|
7804
|
-
set(
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
const key = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
7808
|
-
key.raw.set(fullKey.raw.subarray(0, TRUNCATED_HASH_SIZE));
|
|
7809
|
-
this.dict.set(key.asOpaque(), value);
|
|
8250
|
+
set(key, value) {
|
|
8251
|
+
const truncatedKey = getTruncatedKey(key);
|
|
8252
|
+
this.dict.set(truncatedKey, value);
|
|
7810
8253
|
}
|
|
7811
8254
|
/** Remove a value that matches the key on `TRUNCATED_HASH_SIZE`. */
|
|
7812
|
-
delete(
|
|
7813
|
-
|
|
7814
|
-
this.dict.delete(
|
|
8255
|
+
delete(key) {
|
|
8256
|
+
const truncatedKey = getTruncatedKey(key);
|
|
8257
|
+
this.dict.delete(truncatedKey);
|
|
7815
8258
|
}
|
|
7816
8259
|
/** Iterator over values of the dictionary. */
|
|
7817
8260
|
values() {
|
|
@@ -7819,9 +8262,7 @@ class TruncatedHashDictionary {
|
|
|
7819
8262
|
}
|
|
7820
8263
|
/** Iterator over entries of the dictionary (with truncated keys) */
|
|
7821
8264
|
*entries() {
|
|
7822
|
-
|
|
7823
|
-
yield [bytes_Bytes.fromBlob(key.raw.subarray(0, TRUNCATED_HASH_SIZE), TRUNCATED_HASH_SIZE).asOpaque(), value];
|
|
7824
|
-
}
|
|
8265
|
+
yield* this.dict.entries();
|
|
7825
8266
|
}
|
|
7826
8267
|
[Symbol.iterator]() {
|
|
7827
8268
|
return this.entries();
|
|
@@ -7838,6 +8279,7 @@ class TruncatedHashDictionary {
|
|
|
7838
8279
|
|
|
7839
8280
|
|
|
7840
8281
|
|
|
8282
|
+
|
|
7841
8283
|
;// CONCATENATED MODULE: ./packages/jam/config/chain-spec.ts
|
|
7842
8284
|
|
|
7843
8285
|
|
|
@@ -10630,11 +11072,32 @@ const ENTROPY_ENTRIES = 4;
|
|
|
10630
11072
|
|
|
10631
11073
|
var state_update_UpdatePreimageKind;
|
|
10632
11074
|
(function (UpdatePreimageKind) {
|
|
10633
|
-
/**
|
|
11075
|
+
/**
|
|
11076
|
+
* Insert new preimage and optionally update it's lookup history.
|
|
11077
|
+
*
|
|
11078
|
+
* Used in: `provide`
|
|
11079
|
+
*
|
|
11080
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/383904383904?v=0.7.2
|
|
11081
|
+
*/
|
|
10634
11082
|
UpdatePreimageKind[UpdatePreimageKind["Provide"] = 0] = "Provide";
|
|
10635
|
-
/**
|
|
11083
|
+
/**
|
|
11084
|
+
* Remove a preimage and it's lookup history.
|
|
11085
|
+
*
|
|
11086
|
+
* Used in: `forget` and `eject`
|
|
11087
|
+
*
|
|
11088
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/38c701380202?v=0.7.2
|
|
11089
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/379102379302?v=0.7.2
|
|
11090
|
+
*/
|
|
10636
11091
|
UpdatePreimageKind[UpdatePreimageKind["Remove"] = 1] = "Remove";
|
|
10637
|
-
/**
|
|
11092
|
+
/**
|
|
11093
|
+
* Update or add lookup history for preimage hash/len to given value.
|
|
11094
|
+
*
|
|
11095
|
+
* Used in: `solicit` and `forget`
|
|
11096
|
+
*
|
|
11097
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/382802382802?v=0.7.2
|
|
11098
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/384002384b02?v=0.7.2
|
|
11099
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/38c60038ea00?v=0.7.2
|
|
11100
|
+
*/
|
|
10638
11101
|
UpdatePreimageKind[UpdatePreimageKind["UpdateOrAdd"] = 2] = "UpdateOrAdd";
|
|
10639
11102
|
})(state_update_UpdatePreimageKind || (state_update_UpdatePreimageKind = {}));
|
|
10640
11103
|
/**
|
|
@@ -10642,7 +11105,7 @@ var state_update_UpdatePreimageKind;
|
|
|
10642
11105
|
*
|
|
10643
11106
|
* Can be one of the following cases:
|
|
10644
11107
|
* 1. Provide a new preimage blob and set the lookup history to available at `slot`.
|
|
10645
|
-
* 2. Remove (
|
|
11108
|
+
* 2. Remove (forget) a preimage and it's lookup history.
|
|
10646
11109
|
* 3. Update `LookupHistory` with given value.
|
|
10647
11110
|
*/
|
|
10648
11111
|
class UpdatePreimage {
|
|
@@ -13212,7 +13675,6 @@ class LeafNode {
|
|
|
13212
13675
|
/**
|
|
13213
13676
|
* Get the byte length of embedded value.
|
|
13214
13677
|
*
|
|
13215
|
-
* @remark
|
|
13216
13678
|
* Note in case this node only contains hash this is going to be 0.
|
|
13217
13679
|
*/
|
|
13218
13680
|
getValueLength() {
|
|
@@ -13223,7 +13685,6 @@ class LeafNode {
|
|
|
13223
13685
|
/**
|
|
13224
13686
|
* Returns the embedded value.
|
|
13225
13687
|
*
|
|
13226
|
-
* @remark
|
|
13227
13688
|
* Note that this is going to be empty for a regular leaf node (i.e. containing a hash).
|
|
13228
13689
|
*/
|
|
13229
13690
|
getValue() {
|
|
@@ -13233,7 +13694,6 @@ class LeafNode {
|
|
|
13233
13694
|
/**
|
|
13234
13695
|
* Returns contained value hash.
|
|
13235
13696
|
*
|
|
13236
|
-
* @remark
|
|
13237
13697
|
* Note that for embedded value this is going to be full 0-padded 32 bytes.
|
|
13238
13698
|
*/
|
|
13239
13699
|
getValueHash() {
|
|
@@ -14254,7 +14714,11 @@ class PartiallyUpdatedState {
|
|
|
14254
14714
|
const service = this.state.getService(serviceId);
|
|
14255
14715
|
return service?.getPreimage(hash) ?? null;
|
|
14256
14716
|
}
|
|
14257
|
-
/**
|
|
14717
|
+
/**
|
|
14718
|
+
* Get status of a preimage of current service taking into account any updates.
|
|
14719
|
+
*
|
|
14720
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/110201110201?v=0.7.2
|
|
14721
|
+
*/
|
|
14258
14722
|
getLookupHistory(currentTimeslot, serviceId, hash, length) {
|
|
14259
14723
|
const updatedService = this.stateUpdate.services.updated.get(serviceId);
|
|
14260
14724
|
/** Return lookup history item for newly created service */
|
|
@@ -14291,12 +14755,7 @@ class PartiallyUpdatedState {
|
|
|
14291
14755
|
return new LookupHistoryItem(hash, updatedPreimage.length, service_tryAsLookupHistorySlots([currentTimeslot]));
|
|
14292
14756
|
}
|
|
14293
14757
|
case state_update_UpdatePreimageKind.Remove: {
|
|
14294
|
-
|
|
14295
|
-
// kinda impossible, since we know it's there because it's removed.
|
|
14296
|
-
if (state === null) {
|
|
14297
|
-
return null;
|
|
14298
|
-
}
|
|
14299
|
-
return new LookupHistoryItem(hash, state.length, service_tryAsLookupHistorySlots([...state.slots, currentTimeslot]));
|
|
14758
|
+
return null;
|
|
14300
14759
|
}
|
|
14301
14760
|
case state_update_UpdatePreimageKind.UpdateOrAdd: {
|
|
14302
14761
|
return action.item;
|
|
@@ -14389,7 +14848,7 @@ const gas_tryAsSmallGas = (v) => opaque_asOpaqueType(numbers_tryAsU32(v));
|
|
|
14389
14848
|
/** Attempt to convert given number into U64 gas representation. */
|
|
14390
14849
|
const tryAsBigGas = (v) => opaque_asOpaqueType(numbers_tryAsU64(v));
|
|
14391
14850
|
/** Attempt to convert given number into gas. */
|
|
14392
|
-
const
|
|
14851
|
+
const gas_tryAsGas = (v) => typeof v === "number" && v < 2 ** 32 ? gas_tryAsSmallGas(v) : tryAsBigGas(v);
|
|
14393
14852
|
|
|
14394
14853
|
;// CONCATENATED MODULE: ./packages/core/pvm-interface/memory.ts
|
|
14395
14854
|
|
|
@@ -14672,7 +15131,7 @@ const tryAsRegisterIndex = (index) => {
|
|
|
14672
15131
|
debug_check `${index >= 0 && index < registers_NO_OF_REGISTERS} Incorrect register index: ${index}!`;
|
|
14673
15132
|
return opaque_asOpaqueType(index);
|
|
14674
15133
|
};
|
|
14675
|
-
class
|
|
15134
|
+
class registers_Registers {
|
|
14676
15135
|
bytes;
|
|
14677
15136
|
asSigned;
|
|
14678
15137
|
asUnsigned;
|
|
@@ -14691,7 +15150,7 @@ class Registers {
|
|
|
14691
15150
|
}
|
|
14692
15151
|
static fromBytes(bytes) {
|
|
14693
15152
|
debug_check `${bytes.length === registers_NO_OF_REGISTERS << REGISTER_SIZE_SHIFT} Invalid size of registers array.`;
|
|
14694
|
-
return new
|
|
15153
|
+
return new registers_Registers(bytes);
|
|
14695
15154
|
}
|
|
14696
15155
|
getBytesAsLittleEndian(index, len) {
|
|
14697
15156
|
const offset = index << REGISTER_SIZE_SHIFT;
|
|
@@ -15005,49 +15464,10 @@ class NoopMissing {
|
|
|
15005
15464
|
}
|
|
15006
15465
|
}
|
|
15007
15466
|
|
|
15008
|
-
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/gas.ts
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
/** Create a new gas counter instance depending on the gas value. */
|
|
15012
|
-
function gasCounter(gas) {
|
|
15013
|
-
return new GasCounterU64(numbers_tryAsU64(gas));
|
|
15014
|
-
}
|
|
15015
|
-
class GasCounterU64 {
|
|
15016
|
-
gas;
|
|
15017
|
-
initialGas;
|
|
15018
|
-
constructor(gas) {
|
|
15019
|
-
this.gas = gas;
|
|
15020
|
-
this.initialGas = tryAsGas(gas);
|
|
15021
|
-
}
|
|
15022
|
-
set(g) {
|
|
15023
|
-
this.gas = numbers_tryAsU64(g);
|
|
15024
|
-
}
|
|
15025
|
-
get() {
|
|
15026
|
-
return tryAsGas(this.gas);
|
|
15027
|
-
}
|
|
15028
|
-
sub(g) {
|
|
15029
|
-
const result = this.gas - numbers_tryAsU64(g);
|
|
15030
|
-
if (result >= 0n) {
|
|
15031
|
-
this.gas = numbers_tryAsU64(result);
|
|
15032
|
-
return false;
|
|
15033
|
-
}
|
|
15034
|
-
this.gas = numbers_tryAsU64(0n);
|
|
15035
|
-
return true;
|
|
15036
|
-
}
|
|
15037
|
-
used() {
|
|
15038
|
-
const gasConsumed = numbers_tryAsU64(this.initialGas) - this.gas;
|
|
15039
|
-
// In we have less than zero left we assume that all gas has been consumed.
|
|
15040
|
-
if (gasConsumed < 0) {
|
|
15041
|
-
return this.initialGas;
|
|
15042
|
-
}
|
|
15043
|
-
return tryAsGas(gasConsumed);
|
|
15044
|
-
}
|
|
15045
|
-
}
|
|
15046
|
-
|
|
15047
15467
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/memory-index.ts
|
|
15048
15468
|
|
|
15049
15469
|
|
|
15050
|
-
const
|
|
15470
|
+
const memory_index_tryAsMemoryIndex = (index) => {
|
|
15051
15471
|
debug_check `${index >= 0 && index <= MAX_MEMORY_INDEX} Incorrect memory index: ${index}!`;
|
|
15052
15472
|
return opaque_asOpaqueType(index);
|
|
15053
15473
|
};
|
|
@@ -15061,25 +15481,25 @@ const tryAsSbrkIndex = (index) => {
|
|
|
15061
15481
|
|
|
15062
15482
|
const memory_consts_PAGE_SIZE_SHIFT = 12;
|
|
15063
15483
|
// PAGE_SIZE has to be a power of 2
|
|
15064
|
-
const
|
|
15484
|
+
const memory_consts_PAGE_SIZE = 1 << memory_consts_PAGE_SIZE_SHIFT;
|
|
15065
15485
|
const MIN_ALLOCATION_SHIFT = (() => {
|
|
15066
15486
|
const MIN_ALLOCATION_SHIFT = 7;
|
|
15067
15487
|
debug_check `${MIN_ALLOCATION_SHIFT >= 0 && MIN_ALLOCATION_SHIFT < memory_consts_PAGE_SIZE_SHIFT} incorrect minimal allocation shift`;
|
|
15068
15488
|
return MIN_ALLOCATION_SHIFT;
|
|
15069
15489
|
})();
|
|
15070
|
-
const MIN_ALLOCATION_LENGTH =
|
|
15071
|
-
const LAST_PAGE_NUMBER = (MEMORY_SIZE -
|
|
15490
|
+
const MIN_ALLOCATION_LENGTH = memory_consts_PAGE_SIZE >> MIN_ALLOCATION_SHIFT;
|
|
15491
|
+
const LAST_PAGE_NUMBER = (MEMORY_SIZE - memory_consts_PAGE_SIZE) / memory_consts_PAGE_SIZE;
|
|
15072
15492
|
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
15073
15493
|
const RESERVED_NUMBER_OF_PAGES = 16;
|
|
15074
15494
|
/** https://graypaper.fluffylabs.dev/#/68eaa1f/35a60235a602?v=0.6.4 */
|
|
15075
|
-
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE /
|
|
15495
|
+
const MAX_NUMBER_OF_PAGES = MEMORY_SIZE / memory_consts_PAGE_SIZE;
|
|
15076
15496
|
|
|
15077
15497
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/pages/page-utils.ts
|
|
15078
15498
|
|
|
15079
15499
|
|
|
15080
15500
|
/** Ensure that given memory `index` is within `[0...PAGE_SIZE)` and can be used to index a page */
|
|
15081
15501
|
const tryAsPageIndex = (index) => {
|
|
15082
|
-
debug_check `${index >= 0 && index <
|
|
15502
|
+
debug_check `${index >= 0 && index < memory_consts_PAGE_SIZE}, Incorect page index: ${index}!`;
|
|
15083
15503
|
return opaque_asOpaqueType(index);
|
|
15084
15504
|
};
|
|
15085
15505
|
/** Ensure that given `index` represents an index of one of the pages. */
|
|
@@ -15107,17 +15527,17 @@ function getNextPageNumber(pageNumber) {
|
|
|
15107
15527
|
|
|
15108
15528
|
|
|
15109
15529
|
function alignToPageSize(length) {
|
|
15110
|
-
return
|
|
15530
|
+
return memory_consts_PAGE_SIZE * Math.ceil(length / memory_consts_PAGE_SIZE);
|
|
15111
15531
|
}
|
|
15112
15532
|
function getPageNumber(address) {
|
|
15113
15533
|
return tryAsPageNumber(address >>> memory_consts_PAGE_SIZE_SHIFT);
|
|
15114
15534
|
}
|
|
15115
15535
|
function getStartPageIndex(address) {
|
|
15116
|
-
return
|
|
15536
|
+
return memory_index_tryAsMemoryIndex((address >>> memory_consts_PAGE_SIZE_SHIFT) << memory_consts_PAGE_SIZE_SHIFT);
|
|
15117
15537
|
}
|
|
15118
15538
|
function getStartPageIndexFromPageNumber(pageNumber) {
|
|
15119
15539
|
// >>> 0 is needed to avoid changing sign of the number
|
|
15120
|
-
return
|
|
15540
|
+
return memory_index_tryAsMemoryIndex((pageNumber << memory_consts_PAGE_SIZE_SHIFT) >>> 0);
|
|
15121
15541
|
}
|
|
15122
15542
|
|
|
15123
15543
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/errors.ts
|
|
@@ -15139,7 +15559,7 @@ class PageFault {
|
|
|
15139
15559
|
return new PageFault(numbers_tryAsU32(startPageIndex), isAccessFault);
|
|
15140
15560
|
}
|
|
15141
15561
|
static fromMemoryIndex(maybeMemoryIndex, isAccessFault = false) {
|
|
15142
|
-
const memoryIndex =
|
|
15562
|
+
const memoryIndex = memory_index_tryAsMemoryIndex(maybeMemoryIndex % MEMORY_SIZE);
|
|
15143
15563
|
const startPageIndex = getStartPageIndex(memoryIndex);
|
|
15144
15564
|
return new PageFault(numbers_tryAsU32(startPageIndex), isAccessFault);
|
|
15145
15565
|
}
|
|
@@ -15218,9 +15638,9 @@ class MemoryRange {
|
|
|
15218
15638
|
constructor(start, length) {
|
|
15219
15639
|
this.start = start;
|
|
15220
15640
|
this.length = length;
|
|
15221
|
-
this.end =
|
|
15641
|
+
this.end = memory_index_tryAsMemoryIndex((this.start + this.length) % MEMORY_SIZE);
|
|
15222
15642
|
if (length > 0) {
|
|
15223
|
-
this.lastIndex =
|
|
15643
|
+
this.lastIndex = memory_index_tryAsMemoryIndex((this.end - 1 + MEMORY_SIZE) % MEMORY_SIZE);
|
|
15224
15644
|
}
|
|
15225
15645
|
}
|
|
15226
15646
|
/** Creates a memory range from given starting point and length */
|
|
@@ -15263,7 +15683,7 @@ class MemoryRange {
|
|
|
15263
15683
|
*
|
|
15264
15684
|
* it should be in `memory-consts` but it cannot be there because of circular dependency
|
|
15265
15685
|
*/
|
|
15266
|
-
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(
|
|
15686
|
+
const RESERVED_MEMORY_RANGE = MemoryRange.fromStartAndLength(memory_index_tryAsMemoryIndex(0), RESERVED_NUMBER_OF_PAGES * memory_consts_PAGE_SIZE);
|
|
15267
15687
|
|
|
15268
15688
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/memory/page-range.ts
|
|
15269
15689
|
|
|
@@ -15301,7 +15721,7 @@ class PageRange {
|
|
|
15301
15721
|
// lastIndex is not null because we just ensured that the range is not empty
|
|
15302
15722
|
const pageWithLastIndex = getPageNumber(range.lastIndex ?? range.end);
|
|
15303
15723
|
const endPage = getNextPageNumber(pageWithLastIndex);
|
|
15304
|
-
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length >
|
|
15724
|
+
if ((startPage === endPage || startPage === pageWithLastIndex) && range.length > memory_consts_PAGE_SIZE) {
|
|
15305
15725
|
// full range
|
|
15306
15726
|
return new PageRange(startPage, MAX_NUMBER_OF_PAGES);
|
|
15307
15727
|
}
|
|
@@ -15365,8 +15785,8 @@ class ReadablePage extends MemoryPage {
|
|
|
15365
15785
|
}
|
|
15366
15786
|
loadInto(result, startIndex, length) {
|
|
15367
15787
|
const endIndex = startIndex + length;
|
|
15368
|
-
if (endIndex >
|
|
15369
|
-
return Result.error(PageFault.fromMemoryIndex(this.start +
|
|
15788
|
+
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
15789
|
+
return Result.error(PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
15370
15790
|
}
|
|
15371
15791
|
const bytes = this.data.subarray(startIndex, endIndex);
|
|
15372
15792
|
// we zero the bytes, since data might not yet be initialized at `endIndex`.
|
|
@@ -15399,8 +15819,8 @@ class WriteablePage extends MemoryPage {
|
|
|
15399
15819
|
constructor(pageNumber, initialData) {
|
|
15400
15820
|
super(pageNumber);
|
|
15401
15821
|
const dataLength = initialData?.length ?? 0;
|
|
15402
|
-
const initialPageLength = Math.min(
|
|
15403
|
-
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength:
|
|
15822
|
+
const initialPageLength = Math.min(memory_consts_PAGE_SIZE, Math.max(dataLength, MIN_ALLOCATION_LENGTH));
|
|
15823
|
+
this.buffer = new ArrayBuffer(initialPageLength, { maxByteLength: memory_consts_PAGE_SIZE });
|
|
15404
15824
|
this.view = new Uint8Array(this.buffer);
|
|
15405
15825
|
if (initialData !== undefined) {
|
|
15406
15826
|
this.view.set(initialData);
|
|
@@ -15408,8 +15828,8 @@ class WriteablePage extends MemoryPage {
|
|
|
15408
15828
|
}
|
|
15409
15829
|
loadInto(result, startIndex, length) {
|
|
15410
15830
|
const endIndex = startIndex + length;
|
|
15411
|
-
if (endIndex >
|
|
15412
|
-
return Result.error(PageFault.fromMemoryIndex(this.start +
|
|
15831
|
+
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
15832
|
+
return Result.error(PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
15413
15833
|
}
|
|
15414
15834
|
const bytes = this.view.subarray(startIndex, endIndex);
|
|
15415
15835
|
// we zero the bytes, since the view might not yet be initialized at `endIndex`.
|
|
@@ -15418,16 +15838,16 @@ class WriteablePage extends MemoryPage {
|
|
|
15418
15838
|
return Result.ok(OK);
|
|
15419
15839
|
}
|
|
15420
15840
|
storeFrom(startIndex, bytes) {
|
|
15421
|
-
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength <
|
|
15422
|
-
const newLength = Math.min(
|
|
15841
|
+
if (this.buffer.byteLength < startIndex + bytes.length && this.buffer.byteLength < memory_consts_PAGE_SIZE) {
|
|
15842
|
+
const newLength = Math.min(memory_consts_PAGE_SIZE, Math.max(MIN_ALLOCATION_LENGTH, startIndex + bytes.length));
|
|
15423
15843
|
this.buffer.resize(newLength);
|
|
15424
15844
|
}
|
|
15425
15845
|
this.view.set(bytes, startIndex);
|
|
15426
15846
|
return Result.ok(OK);
|
|
15427
15847
|
}
|
|
15428
15848
|
setData(pageIndex, data) {
|
|
15429
|
-
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength <
|
|
15430
|
-
const newLength = Math.min(
|
|
15849
|
+
if (this.buffer.byteLength < pageIndex + data.length && this.buffer.byteLength < memory_consts_PAGE_SIZE) {
|
|
15850
|
+
const newLength = Math.min(memory_consts_PAGE_SIZE, Math.max(MIN_ALLOCATION_LENGTH, pageIndex + data.length));
|
|
15431
15851
|
this.buffer.resize(newLength);
|
|
15432
15852
|
}
|
|
15433
15853
|
this.view.set(data, pageIndex);
|
|
@@ -15478,10 +15898,10 @@ class Memory {
|
|
|
15478
15898
|
this.memory = memory;
|
|
15479
15899
|
}
|
|
15480
15900
|
store(address, bytes) {
|
|
15481
|
-
return this.storeFrom(
|
|
15901
|
+
return this.storeFrom(memory_index_tryAsMemoryIndex(address), bytes);
|
|
15482
15902
|
}
|
|
15483
15903
|
read(address, output) {
|
|
15484
|
-
return this.loadInto(output,
|
|
15904
|
+
return this.loadInto(output, memory_index_tryAsMemoryIndex(address));
|
|
15485
15905
|
}
|
|
15486
15906
|
reset() {
|
|
15487
15907
|
this.sbrkIndex = tryAsSbrkIndex(RESERVED_MEMORY_RANGE.end);
|
|
@@ -15508,8 +15928,8 @@ class Memory {
|
|
|
15508
15928
|
let currentPosition = address;
|
|
15509
15929
|
let bytesLeft = bytes.length;
|
|
15510
15930
|
for (const page of pages) {
|
|
15511
|
-
const pageStartIndex = tryAsPageIndex(currentPosition %
|
|
15512
|
-
const bytesToWrite = Math.min(
|
|
15931
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % memory_consts_PAGE_SIZE);
|
|
15932
|
+
const bytesToWrite = Math.min(memory_consts_PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15513
15933
|
const sourceStartIndex = currentPosition - address;
|
|
15514
15934
|
const source = bytes.subarray(sourceStartIndex, sourceStartIndex + bytesToWrite);
|
|
15515
15935
|
page.storeFrom(pageStartIndex, source);
|
|
@@ -15558,8 +15978,8 @@ class Memory {
|
|
|
15558
15978
|
let currentPosition = startAddress;
|
|
15559
15979
|
let bytesLeft = result.length;
|
|
15560
15980
|
for (const page of pages) {
|
|
15561
|
-
const pageStartIndex = tryAsPageIndex(currentPosition %
|
|
15562
|
-
const bytesToRead = Math.min(
|
|
15981
|
+
const pageStartIndex = tryAsPageIndex(currentPosition % memory_consts_PAGE_SIZE);
|
|
15982
|
+
const bytesToRead = Math.min(memory_consts_PAGE_SIZE - pageStartIndex, bytesLeft);
|
|
15563
15983
|
const destinationStartIndex = currentPosition - startAddress;
|
|
15564
15984
|
const destination = result.subarray(destinationStartIndex);
|
|
15565
15985
|
page.loadInto(destination, pageStartIndex, bytesToRead);
|
|
@@ -15586,7 +16006,7 @@ class Memory {
|
|
|
15586
16006
|
const newSbrkIndex = tryAsSbrkIndex(alignToPageSize(newVirtualSbrkIndex));
|
|
15587
16007
|
// TODO [MaSi]: `getPageNumber` works incorrectly for SbrkIndex. Sbrk index should be changed to MemoryIndex
|
|
15588
16008
|
const firstPageNumber = getPageNumber(currentSbrkIndex);
|
|
15589
|
-
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) /
|
|
16009
|
+
const pagesToAllocate = (newSbrkIndex - currentSbrkIndex) / memory_consts_PAGE_SIZE;
|
|
15590
16010
|
const rangeToAllocate = PageRange.fromStartAndLength(firstPageNumber, pagesToAllocate);
|
|
15591
16011
|
for (const pageNumber of rangeToAllocate) {
|
|
15592
16012
|
const page = new WriteablePage(pageNumber);
|
|
@@ -15641,8 +16061,8 @@ class MemoryBuilder {
|
|
|
15641
16061
|
setReadablePages(start, end, data = new Uint8Array()) {
|
|
15642
16062
|
this.ensureNotFinalized();
|
|
15643
16063
|
debug_check `${start < end} end has to be bigger than start`;
|
|
15644
|
-
debug_check `${start %
|
|
15645
|
-
debug_check `${end %
|
|
16064
|
+
debug_check `${start % memory_consts_PAGE_SIZE === 0} start needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
16065
|
+
debug_check `${end % memory_consts_PAGE_SIZE === 0} end needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15646
16066
|
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15647
16067
|
const length = end - start;
|
|
15648
16068
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15651,7 +16071,7 @@ class MemoryBuilder {
|
|
|
15651
16071
|
const noOfPages = pages.length;
|
|
15652
16072
|
for (let i = 0; i < noOfPages; i++) {
|
|
15653
16073
|
const pageNumber = pages[i];
|
|
15654
|
-
const dataChunk = data.subarray(i *
|
|
16074
|
+
const dataChunk = data.subarray(i * memory_consts_PAGE_SIZE, (i + 1) * memory_consts_PAGE_SIZE);
|
|
15655
16075
|
const page = new ReadablePage(pageNumber, dataChunk);
|
|
15656
16076
|
this.initialMemory.set(pageNumber, page);
|
|
15657
16077
|
}
|
|
@@ -15669,8 +16089,8 @@ class MemoryBuilder {
|
|
|
15669
16089
|
setWriteablePages(start, end, data = new Uint8Array()) {
|
|
15670
16090
|
this.ensureNotFinalized();
|
|
15671
16091
|
debug_check `${start < end} end has to be bigger than start`;
|
|
15672
|
-
debug_check `${start %
|
|
15673
|
-
debug_check `${end %
|
|
16092
|
+
debug_check `${start % memory_consts_PAGE_SIZE === 0} start needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
16093
|
+
debug_check `${end % memory_consts_PAGE_SIZE === 0} end needs to be a multiple of page size (${memory_consts_PAGE_SIZE})`;
|
|
15674
16094
|
debug_check `${data.length <= end - start} the initial data is longer than address range`;
|
|
15675
16095
|
const length = end - start;
|
|
15676
16096
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15679,7 +16099,7 @@ class MemoryBuilder {
|
|
|
15679
16099
|
const noOfPages = pages.length;
|
|
15680
16100
|
for (let i = 0; i < noOfPages; i++) {
|
|
15681
16101
|
const pageNumber = pages[i];
|
|
15682
|
-
const dataChunk = data.subarray(i *
|
|
16102
|
+
const dataChunk = data.subarray(i * memory_consts_PAGE_SIZE, (i + 1) * memory_consts_PAGE_SIZE);
|
|
15683
16103
|
const page = new WriteablePage(pageNumber, dataChunk);
|
|
15684
16104
|
this.initialMemory.set(pageNumber, page);
|
|
15685
16105
|
}
|
|
@@ -15691,8 +16111,8 @@ class MemoryBuilder {
|
|
|
15691
16111
|
*/
|
|
15692
16112
|
setData(start, data) {
|
|
15693
16113
|
this.ensureNotFinalized();
|
|
15694
|
-
const pageOffset = start %
|
|
15695
|
-
const remainingSpaceOnPage =
|
|
16114
|
+
const pageOffset = start % memory_consts_PAGE_SIZE;
|
|
16115
|
+
const remainingSpaceOnPage = memory_consts_PAGE_SIZE - pageOffset;
|
|
15696
16116
|
debug_check `${data.length <= remainingSpaceOnPage} The data has to fit into a single page.`;
|
|
15697
16117
|
const length = data.length;
|
|
15698
16118
|
const range = MemoryRange.fromStartAndLength(start, length);
|
|
@@ -15883,27 +16303,27 @@ class Program {
|
|
|
15883
16303
|
static fromSpi(blob, args, hasMetadata) {
|
|
15884
16304
|
const { code: spiCode, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15885
16305
|
const { code, memory: rawMemory, registers } = decodeStandardProgram(spiCode, args);
|
|
15886
|
-
const regs = new
|
|
16306
|
+
const regs = new registers_Registers();
|
|
15887
16307
|
regs.copyFrom(registers);
|
|
15888
16308
|
const memoryBuilder = new MemoryBuilder();
|
|
15889
16309
|
for (const { start, end, data } of rawMemory.readable) {
|
|
15890
|
-
const startIndex =
|
|
15891
|
-
const endIndex =
|
|
16310
|
+
const startIndex = memory_index_tryAsMemoryIndex(start);
|
|
16311
|
+
const endIndex = memory_index_tryAsMemoryIndex(end);
|
|
15892
16312
|
memoryBuilder.setReadablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15893
16313
|
}
|
|
15894
16314
|
for (const { start, end, data } of rawMemory.writeable) {
|
|
15895
|
-
const startIndex =
|
|
15896
|
-
const endIndex =
|
|
16315
|
+
const startIndex = memory_index_tryAsMemoryIndex(start);
|
|
16316
|
+
const endIndex = memory_index_tryAsMemoryIndex(end);
|
|
15897
16317
|
memoryBuilder.setWriteablePages(startIndex, endIndex, data ?? new Uint8Array());
|
|
15898
16318
|
}
|
|
15899
|
-
const heapStart =
|
|
16319
|
+
const heapStart = memory_index_tryAsMemoryIndex(rawMemory.sbrkIndex);
|
|
15900
16320
|
const heapEnd = tryAsSbrkIndex(rawMemory.heapEnd);
|
|
15901
16321
|
const memory = memoryBuilder.finalize(heapStart, heapEnd);
|
|
15902
16322
|
return new Program(code, regs, memory, metadata);
|
|
15903
16323
|
}
|
|
15904
16324
|
static fromGeneric(blob, hasMetadata) {
|
|
15905
16325
|
const { code, metadata } = hasMetadata ? extractCodeAndMetadata(blob) : { code: blob };
|
|
15906
|
-
const regs = new
|
|
16326
|
+
const regs = new registers_Registers();
|
|
15907
16327
|
const memory = new Memory();
|
|
15908
16328
|
return new Program(code, regs, memory, metadata);
|
|
15909
16329
|
}
|
|
@@ -16918,6 +17338,45 @@ class BasicBlocks {
|
|
|
16918
17338
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/basic-blocks/index.ts
|
|
16919
17339
|
|
|
16920
17340
|
|
|
17341
|
+
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/gas.ts
|
|
17342
|
+
|
|
17343
|
+
|
|
17344
|
+
/** Create a new gas counter instance depending on the gas value. */
|
|
17345
|
+
function gasCounter(gas) {
|
|
17346
|
+
return new GasCounterU64(numbers_tryAsU64(gas));
|
|
17347
|
+
}
|
|
17348
|
+
class GasCounterU64 {
|
|
17349
|
+
gas;
|
|
17350
|
+
initialGas;
|
|
17351
|
+
constructor(gas) {
|
|
17352
|
+
this.gas = gas;
|
|
17353
|
+
this.initialGas = gas_tryAsGas(gas);
|
|
17354
|
+
}
|
|
17355
|
+
set(g) {
|
|
17356
|
+
this.gas = numbers_tryAsU64(g);
|
|
17357
|
+
}
|
|
17358
|
+
get() {
|
|
17359
|
+
return gas_tryAsGas(this.gas);
|
|
17360
|
+
}
|
|
17361
|
+
sub(g) {
|
|
17362
|
+
const result = this.gas - numbers_tryAsU64(g);
|
|
17363
|
+
if (result >= 0n) {
|
|
17364
|
+
this.gas = numbers_tryAsU64(result);
|
|
17365
|
+
return false;
|
|
17366
|
+
}
|
|
17367
|
+
this.gas = numbers_tryAsU64(0n);
|
|
17368
|
+
return true;
|
|
17369
|
+
}
|
|
17370
|
+
used() {
|
|
17371
|
+
const gasConsumed = numbers_tryAsU64(this.initialGas) - this.gas;
|
|
17372
|
+
// In we have less than zero left we assume that all gas has been consumed.
|
|
17373
|
+
if (gasConsumed < 0) {
|
|
17374
|
+
return this.initialGas;
|
|
17375
|
+
}
|
|
17376
|
+
return gas_tryAsGas(gasConsumed);
|
|
17377
|
+
}
|
|
17378
|
+
}
|
|
17379
|
+
|
|
16921
17380
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/instruction-gas-map.ts
|
|
16922
17381
|
|
|
16923
17382
|
|
|
@@ -17494,7 +17953,7 @@ class LoadOps {
|
|
|
17494
17953
|
}
|
|
17495
17954
|
loadNumber(address, registerIndex, numberLength) {
|
|
17496
17955
|
const registerBytes = this.regs.getBytesAsLittleEndian(registerIndex, REG_SIZE_BYTES);
|
|
17497
|
-
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength),
|
|
17956
|
+
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength), memory_index_tryAsMemoryIndex(address));
|
|
17498
17957
|
if (loadResult.isError) {
|
|
17499
17958
|
if (loadResult.error.isAccessFault) {
|
|
17500
17959
|
this.instructionResult.status = result_Result.FAULT_ACCESS;
|
|
@@ -17510,7 +17969,7 @@ class LoadOps {
|
|
|
17510
17969
|
loadSignedNumber(address, registerIndex, numberLength) {
|
|
17511
17970
|
// load all bytes from register to correctly handle the sign.
|
|
17512
17971
|
const registerBytes = this.regs.getBytesAsLittleEndian(registerIndex, REG_SIZE_BYTES);
|
|
17513
|
-
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength),
|
|
17972
|
+
const loadResult = this.memory.loadInto(registerBytes.subarray(0, numberLength), memory_index_tryAsMemoryIndex(address));
|
|
17514
17973
|
if (loadResult.isError) {
|
|
17515
17974
|
if (loadResult.error.isAccessFault) {
|
|
17516
17975
|
this.instructionResult.status = result_Result.FAULT_ACCESS;
|
|
@@ -17932,7 +18391,7 @@ class StoreOps {
|
|
|
17932
18391
|
this.store(address, secondImmediateDecoder.getExtendedBytesAsLittleEndian());
|
|
17933
18392
|
}
|
|
17934
18393
|
store(address, bytes) {
|
|
17935
|
-
const storeResult = this.memory.storeFrom(
|
|
18394
|
+
const storeResult = this.memory.storeFrom(memory_index_tryAsMemoryIndex(address), bytes);
|
|
17936
18395
|
if (storeResult.isOk) {
|
|
17937
18396
|
return;
|
|
17938
18397
|
}
|
|
@@ -17941,7 +18400,7 @@ class StoreOps {
|
|
|
17941
18400
|
}
|
|
17942
18401
|
else {
|
|
17943
18402
|
this.instructionResult.status = result_Result.FAULT;
|
|
17944
|
-
this.instructionResult.exitParam = getStartPageIndex(
|
|
18403
|
+
this.instructionResult.exitParam = getStartPageIndex(memory_index_tryAsMemoryIndex(storeResult.error.address));
|
|
17945
18404
|
}
|
|
17946
18405
|
}
|
|
17947
18406
|
}
|
|
@@ -18740,11 +19199,11 @@ class ProgramDecoder {
|
|
|
18740
19199
|
|
|
18741
19200
|
|
|
18742
19201
|
const interpreter_logger = Logger.new(import.meta.filename, "pvm");
|
|
18743
|
-
class
|
|
19202
|
+
class interpreter_Interpreter {
|
|
18744
19203
|
useSbrkGas;
|
|
18745
|
-
registers = new
|
|
19204
|
+
registers = new registers_Registers();
|
|
18746
19205
|
memory = new Memory();
|
|
18747
|
-
gas = gasCounter(
|
|
19206
|
+
gas = gasCounter(gas_tryAsGas(0));
|
|
18748
19207
|
code = new Uint8Array();
|
|
18749
19208
|
mask = Mask.empty();
|
|
18750
19209
|
pc = 0;
|
|
@@ -18878,8 +19337,8 @@ class Interpreter {
|
|
|
18878
19337
|
break;
|
|
18879
19338
|
case ArgumentType.TWO_REGISTERS:
|
|
18880
19339
|
if (this.useSbrkGas && currentInstruction === Instruction.SBRK) {
|
|
18881
|
-
const calculateSbrkCost = (length) => (alignToPageSize(length) /
|
|
18882
|
-
const underflow = this.gas.sub(
|
|
19340
|
+
const calculateSbrkCost = (length) => (alignToPageSize(length) / memory_consts_PAGE_SIZE) * 16;
|
|
19341
|
+
const underflow = this.gas.sub(gas_tryAsGas(calculateSbrkCost(this.registers.getLowerU32(argsResult.firstRegisterIndex))));
|
|
18883
19342
|
if (underflow) {
|
|
18884
19343
|
this.status = status_Status.OOG;
|
|
18885
19344
|
return this.status;
|
|
@@ -18974,12 +19433,88 @@ class Interpreter {
|
|
|
18974
19433
|
}
|
|
18975
19434
|
}
|
|
18976
19435
|
|
|
19436
|
+
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/debugger-adapter.ts
|
|
19437
|
+
|
|
19438
|
+
|
|
19439
|
+
|
|
19440
|
+
|
|
19441
|
+
|
|
19442
|
+
|
|
19443
|
+
class DebuggerAdapter {
|
|
19444
|
+
pvm;
|
|
19445
|
+
constructor(useSbrkGas = false) {
|
|
19446
|
+
this.pvm = new Interpreter({ useSbrkGas });
|
|
19447
|
+
}
|
|
19448
|
+
resetGeneric(rawProgram, flatRegisters, initialGas) {
|
|
19449
|
+
this.pvm.resetGeneric(rawProgram, 0, tryAsGas(initialGas), new Registers(flatRegisters));
|
|
19450
|
+
}
|
|
19451
|
+
reset(rawProgram, pc, gas, maybeRegisters, maybeMemory) {
|
|
19452
|
+
this.pvm.resetGeneric(rawProgram, pc, tryAsGas(gas), maybeRegisters, maybeMemory);
|
|
19453
|
+
}
|
|
19454
|
+
getPageDump(pageNumber) {
|
|
19455
|
+
const page = this.pvm.getMemoryPage(pageNumber);
|
|
19456
|
+
if (page === null) {
|
|
19457
|
+
// page wasn't allocated so we return an empty page
|
|
19458
|
+
return safeAllocUint8Array(PAGE_SIZE);
|
|
19459
|
+
}
|
|
19460
|
+
if (page.length === PAGE_SIZE) {
|
|
19461
|
+
// page was allocated and has a proper size so we can simply return it
|
|
19462
|
+
return page;
|
|
19463
|
+
}
|
|
19464
|
+
// page was allocated but it is shorter than PAGE_SIZE so we have to extend it
|
|
19465
|
+
const fullPage = safeAllocUint8Array(PAGE_SIZE);
|
|
19466
|
+
fullPage.set(page);
|
|
19467
|
+
return fullPage;
|
|
19468
|
+
}
|
|
19469
|
+
setMemory(address, value) {
|
|
19470
|
+
this.pvm.memory.storeFrom(tryAsMemoryIndex(address), value);
|
|
19471
|
+
}
|
|
19472
|
+
getExitArg() {
|
|
19473
|
+
return this.pvm.getExitParam() ?? 0;
|
|
19474
|
+
}
|
|
19475
|
+
getStatus() {
|
|
19476
|
+
return this.pvm.getStatus();
|
|
19477
|
+
}
|
|
19478
|
+
nextStep() {
|
|
19479
|
+
return this.pvm.nextStep() === Status.OK;
|
|
19480
|
+
}
|
|
19481
|
+
nSteps(steps) {
|
|
19482
|
+
check `${steps >>> 0 > 0} Expected a positive integer got ${steps}`;
|
|
19483
|
+
for (let i = 0; i < steps; i++) {
|
|
19484
|
+
const isOk = this.nextStep();
|
|
19485
|
+
if (!isOk) {
|
|
19486
|
+
return false;
|
|
19487
|
+
}
|
|
19488
|
+
}
|
|
19489
|
+
return true;
|
|
19490
|
+
}
|
|
19491
|
+
getRegisters() {
|
|
19492
|
+
return this.pvm.registers.getAllU64();
|
|
19493
|
+
}
|
|
19494
|
+
setRegisters(registers) {
|
|
19495
|
+
this.pvm.registers.copyFrom(new Registers(registers));
|
|
19496
|
+
}
|
|
19497
|
+
getProgramCounter() {
|
|
19498
|
+
return this.pvm.getPC();
|
|
19499
|
+
}
|
|
19500
|
+
setNextProgramCounter(nextPc) {
|
|
19501
|
+
this.pvm.setNextPC(nextPc);
|
|
19502
|
+
}
|
|
19503
|
+
getGasLeft() {
|
|
19504
|
+
return BigInt(this.pvm.gas.get());
|
|
19505
|
+
}
|
|
19506
|
+
setGasLeft(gas) {
|
|
19507
|
+
this.pvm.gas.set(tryAsGas(gas));
|
|
19508
|
+
}
|
|
19509
|
+
}
|
|
19510
|
+
|
|
18977
19511
|
;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/index.ts
|
|
18978
19512
|
|
|
18979
19513
|
|
|
18980
19514
|
|
|
18981
19515
|
|
|
18982
19516
|
|
|
19517
|
+
|
|
18983
19518
|
;// CONCATENATED MODULE: ./node_modules/@fluffylabs/anan-as/build/debug-raw.js
|
|
18984
19519
|
async function instantiate(module, imports = {}) {
|
|
18985
19520
|
const adaptedImports = {
|
|
@@ -19433,12 +19968,12 @@ class AnanasMemory {
|
|
|
19433
19968
|
}
|
|
19434
19969
|
class AnanasGasCounter {
|
|
19435
19970
|
instance;
|
|
19436
|
-
initialGas =
|
|
19971
|
+
initialGas = gas_tryAsGas(0n);
|
|
19437
19972
|
constructor(instance) {
|
|
19438
19973
|
this.instance = instance;
|
|
19439
19974
|
}
|
|
19440
19975
|
get() {
|
|
19441
|
-
return
|
|
19976
|
+
return gas_tryAsGas(this.instance.getGasLeft());
|
|
19442
19977
|
}
|
|
19443
19978
|
set(g) {
|
|
19444
19979
|
this.instance.setGasLeft(BigInt(g));
|
|
@@ -19543,7 +20078,7 @@ class InterpreterInstanceManager {
|
|
|
19543
20078
|
const instances = [];
|
|
19544
20079
|
switch (interpreter) {
|
|
19545
20080
|
case PvmBackend.BuiltIn:
|
|
19546
|
-
instances.push(new
|
|
20081
|
+
instances.push(new interpreter_Interpreter({
|
|
19547
20082
|
useSbrkGas: false,
|
|
19548
20083
|
}));
|
|
19549
20084
|
break;
|
|
@@ -19717,10 +20252,10 @@ class Info {
|
|
|
19717
20252
|
const chunk = encodedInfo.raw.subarray(Number(offset), Number(offset + length));
|
|
19718
20253
|
const writeResult = memory.storeFrom(outputStart, chunk);
|
|
19719
20254
|
if (writeResult.isError) {
|
|
19720
|
-
logger_logger.trace `INFO(${serviceId}, off: ${offset}, len: ${length}) <- PANIC`;
|
|
20255
|
+
logger_logger.trace `[${this.currentServiceId}] INFO(${serviceId}, off: ${offset}, len: ${length}) <- PANIC`;
|
|
19721
20256
|
return PvmExecution.Panic;
|
|
19722
20257
|
}
|
|
19723
|
-
logger_logger.trace `INFO(${serviceId}, off: ${offset}, len: ${length}) <- ${bytes_BytesBlob.blobFrom(chunk)}`;
|
|
20258
|
+
logger_logger.trace `[${this.currentServiceId}] INFO(${serviceId}, off: ${offset}, len: ${length}) <- ${bytes_BytesBlob.blobFrom(chunk)}`;
|
|
19724
20259
|
if (accountInfo === null) {
|
|
19725
20260
|
regs.set(IN_OUT_REG, HostCallResult.NONE);
|
|
19726
20261
|
return;
|
|
@@ -19944,7 +20479,7 @@ class AccumulateExternalities {
|
|
|
19944
20479
|
const bytes = serviceInfo.storageUtilisationBytes - length - LOOKUP_HISTORY_ENTRY_BYTES;
|
|
19945
20480
|
return this.updatedState.updateServiceStorageUtilisation(this.currentServiceId, items, bytes, serviceInfo);
|
|
19946
20481
|
};
|
|
19947
|
-
// https://graypaper.fluffylabs.dev/#/
|
|
20482
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/380802380802?v=0.7.2
|
|
19948
20483
|
if (s.status === PreimageStatusKind.Requested) {
|
|
19949
20484
|
const res = updateStorageUtilisation();
|
|
19950
20485
|
if (res.isError) {
|
|
@@ -19957,7 +20492,7 @@ class AccumulateExternalities {
|
|
|
19957
20492
|
return Result.ok(OK);
|
|
19958
20493
|
}
|
|
19959
20494
|
const t = this.currentTimeslot;
|
|
19960
|
-
// https://graypaper.fluffylabs.dev/#/
|
|
20495
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/380802380802?v=0.7.2
|
|
19961
20496
|
if (s.status === PreimageStatusKind.Unavailable) {
|
|
19962
20497
|
const y = s.data[1];
|
|
19963
20498
|
if (y < t - this.chainSpec.preimageExpungePeriod) {
|
|
@@ -19973,14 +20508,14 @@ class AccumulateExternalities {
|
|
|
19973
20508
|
}
|
|
19974
20509
|
return Result.error(ForgetPreimageError.NotExpired, () => `Preimage not expired: y=${y}, timeslot=${t}, period=${this.chainSpec.preimageExpungePeriod}`);
|
|
19975
20510
|
}
|
|
19976
|
-
// https://graypaper.fluffylabs.dev/#/
|
|
20511
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/382802383302?v=0.7.2
|
|
19977
20512
|
if (s.status === PreimageStatusKind.Available) {
|
|
19978
20513
|
this.updatedState.updatePreimage(serviceId, UpdatePreimage.updateOrAdd({
|
|
19979
20514
|
lookupHistory: new LookupHistoryItem(status.hash, status.length, service_tryAsLookupHistorySlots([s.data[0], t])),
|
|
19980
20515
|
}));
|
|
19981
20516
|
return Result.ok(OK);
|
|
19982
20517
|
}
|
|
19983
|
-
// https://graypaper.fluffylabs.dev/#/
|
|
20518
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/384002384c02?v=0.7.2
|
|
19984
20519
|
if (s.status === PreimageStatusKind.Reavailable) {
|
|
19985
20520
|
const y = s.data[1];
|
|
19986
20521
|
if (y < t - this.chainSpec.preimageExpungePeriod) {
|
|
@@ -20816,13 +21351,11 @@ class AccumulateDataItem {
|
|
|
20816
21351
|
* - gas cost and reports length for each service (statistics)
|
|
20817
21352
|
*/
|
|
20818
21353
|
class AccumulateData {
|
|
20819
|
-
autoAccumulateServicesByServiceId;
|
|
20820
21354
|
reportsDataByServiceId;
|
|
20821
21355
|
transfersByServiceId;
|
|
20822
21356
|
serviceIds;
|
|
20823
21357
|
gasLimitByServiceId;
|
|
20824
21358
|
constructor(reports, transfers, autoAccumulateServicesByServiceId) {
|
|
20825
|
-
this.autoAccumulateServicesByServiceId = autoAccumulateServicesByServiceId;
|
|
20826
21359
|
const serviceIdsFromAutoAccumulate = new Set(autoAccumulateServicesByServiceId.keys());
|
|
20827
21360
|
const { reportsDataByServiceId, serviceIds: serviceIdsFromReports, gasLimitByServiceId: reportsGasLimitByServiceId, } = this.transformReports(reports);
|
|
20828
21361
|
this.reportsDataByServiceId = reportsDataByServiceId;
|
|
@@ -21142,12 +21675,12 @@ function createMergeContext(chainSpec, state, inputState, results) {
|
|
|
21142
21675
|
}
|
|
21143
21676
|
function updatePrivilegedService(currentServiceId, serviceIdUpdatedByManager, selfUpdatedServiceId) {
|
|
21144
21677
|
if (currentServiceId === serviceIdUpdatedByManager) {
|
|
21145
|
-
return
|
|
21678
|
+
return selfUpdatedServiceId;
|
|
21146
21679
|
}
|
|
21147
|
-
return
|
|
21680
|
+
return serviceIdUpdatedByManager;
|
|
21148
21681
|
}
|
|
21149
21682
|
function mergePrivilegedServices(mergeContext, [serviceId, { stateUpdate }]) {
|
|
21150
|
-
const { outputState, currentPrivilegedServices, chainSpec } = mergeContext;
|
|
21683
|
+
const { outputState, currentPrivilegedServices, chainSpec, privilegedServicesUpdatedByManager } = mergeContext;
|
|
21151
21684
|
const currentManager = currentPrivilegedServices.manager;
|
|
21152
21685
|
const currentRegistrar = currentPrivilegedServices.registrar;
|
|
21153
21686
|
const currentDelegator = currentPrivilegedServices.delegator;
|
|
@@ -21165,28 +21698,35 @@ function mergePrivilegedServices(mergeContext, [serviceId, { stateUpdate }]) {
|
|
|
21165
21698
|
});
|
|
21166
21699
|
}
|
|
21167
21700
|
if (serviceId === currentRegistrar) {
|
|
21168
|
-
const newRegistrar = updatePrivilegedService(currentPrivilegedServices.registrar,
|
|
21701
|
+
const newRegistrar = updatePrivilegedService(currentPrivilegedServices.registrar, privilegedServicesUpdatedByManager.registrar, privilegedServices.registrar);
|
|
21169
21702
|
outputState.privilegedServices = PrivilegedServices.create({
|
|
21170
21703
|
...outputState.privilegedServices,
|
|
21171
21704
|
registrar: newRegistrar,
|
|
21172
21705
|
});
|
|
21173
21706
|
}
|
|
21174
21707
|
if (serviceId === currentDelegator) {
|
|
21175
|
-
const newDelegator = updatePrivilegedService(currentPrivilegedServices.delegator,
|
|
21708
|
+
const newDelegator = updatePrivilegedService(currentPrivilegedServices.delegator, privilegedServicesUpdatedByManager.delegator, privilegedServices.delegator);
|
|
21176
21709
|
outputState.privilegedServices = PrivilegedServices.create({
|
|
21177
21710
|
...outputState.privilegedServices,
|
|
21178
21711
|
delegator: newDelegator,
|
|
21179
21712
|
});
|
|
21180
21713
|
}
|
|
21181
|
-
|
|
21182
|
-
const newAssigners = currentAssigners.map((currentAssigner, coreIndex) =>
|
|
21183
|
-
|
|
21184
|
-
|
|
21185
|
-
|
|
21186
|
-
|
|
21187
|
-
|
|
21188
|
-
|
|
21714
|
+
let shouldUpdateAssigners = false;
|
|
21715
|
+
const newAssigners = currentAssigners.map((currentAssigner, coreIndex) => {
|
|
21716
|
+
if (serviceId === currentAssigner) {
|
|
21717
|
+
const newAssigner = updatePrivilegedService(currentPrivilegedServices.assigners[coreIndex], privilegedServicesUpdatedByManager.assigners[coreIndex], privilegedServices.assigners[coreIndex]);
|
|
21718
|
+
shouldUpdateAssigners = shouldUpdateAssigners || newAssigner !== currentAssigner;
|
|
21719
|
+
return newAssigner;
|
|
21720
|
+
}
|
|
21721
|
+
return currentAssigner;
|
|
21189
21722
|
});
|
|
21723
|
+
if (shouldUpdateAssigners) {
|
|
21724
|
+
const newAssignersPerCore = tryAsPerCore(newAssigners, chainSpec);
|
|
21725
|
+
outputState.privilegedServices = PrivilegedServices.create({
|
|
21726
|
+
...outputState.privilegedServices,
|
|
21727
|
+
assigners: newAssignersPerCore,
|
|
21728
|
+
});
|
|
21729
|
+
}
|
|
21190
21730
|
}
|
|
21191
21731
|
}
|
|
21192
21732
|
function mergeValidatorsData(mergeContext, [serviceId, { stateUpdate }]) {
|
|
@@ -21331,7 +21871,7 @@ class Assign {
|
|
|
21331
21871
|
const memoryReadResult = memory.loadInto(res, authorizationQueueStart);
|
|
21332
21872
|
// error while reading the memory.
|
|
21333
21873
|
if (memoryReadResult.isError) {
|
|
21334
|
-
logger_logger.trace `ASSIGN() <- PANIC`;
|
|
21874
|
+
logger_logger.trace `[${this.currentServiceId}] ASSIGN() <- PANIC`;
|
|
21335
21875
|
return PvmExecution.Panic;
|
|
21336
21876
|
}
|
|
21337
21877
|
if (maybeCoreIndex >= this.chainSpec.coresCount) {
|
|
@@ -21346,18 +21886,18 @@ class Assign {
|
|
|
21346
21886
|
const result = this.partialState.updateAuthorizationQueue(coreIndex, fixedSizeAuthQueue, assigners);
|
|
21347
21887
|
if (result.isOk) {
|
|
21348
21888
|
regs.set(assign_IN_OUT_REG, HostCallResult.OK);
|
|
21349
|
-
logger_logger.trace `ASSIGN(${coreIndex}, ${fixedSizeAuthQueue}) <- OK`;
|
|
21889
|
+
logger_logger.trace `[${this.currentServiceId}] ASSIGN(${coreIndex}, ${fixedSizeAuthQueue}) <- OK`;
|
|
21350
21890
|
return;
|
|
21351
21891
|
}
|
|
21352
21892
|
const e = result.error;
|
|
21353
21893
|
if (e === UpdatePrivilegesError.UnprivilegedService) {
|
|
21354
21894
|
regs.set(assign_IN_OUT_REG, HostCallResult.HUH);
|
|
21355
|
-
logger_logger.trace `ASSIGN(${coreIndex}, ${fixedSizeAuthQueue}) <- HUH`;
|
|
21895
|
+
logger_logger.trace `[${this.currentServiceId}] ASSIGN(${coreIndex}, ${fixedSizeAuthQueue}) <- HUH`;
|
|
21356
21896
|
return;
|
|
21357
21897
|
}
|
|
21358
21898
|
if (e === UpdatePrivilegesError.InvalidServiceId) {
|
|
21359
21899
|
regs.set(assign_IN_OUT_REG, HostCallResult.WHO);
|
|
21360
|
-
logger_logger.trace `ASSIGN(${coreIndex}, ${fixedSizeAuthQueue}) <- HUH`;
|
|
21900
|
+
logger_logger.trace `[${this.currentServiceId}] ASSIGN(${coreIndex}, ${fixedSizeAuthQueue}) <- HUH`;
|
|
21361
21901
|
return;
|
|
21362
21902
|
}
|
|
21363
21903
|
assertNever(e);
|
|
@@ -21428,7 +21968,7 @@ class Bless {
|
|
|
21428
21968
|
decoder.resetTo(0);
|
|
21429
21969
|
const memoryReadResult = memory.loadInto(result, memIndex);
|
|
21430
21970
|
if (memoryReadResult.isError) {
|
|
21431
|
-
logger_logger.trace `BLESS(m: ${manager}, v: ${delegator}, r: ${registrar}) <- PANIC`;
|
|
21971
|
+
logger_logger.trace `[${this.currentServiceId}] BLESS(m: ${manager}, v: ${delegator}, r: ${registrar}) <- PANIC`;
|
|
21432
21972
|
return PvmExecution.Panic;
|
|
21433
21973
|
}
|
|
21434
21974
|
const { serviceId, gas } = decoder.object(serviceIdAndGasCodec);
|
|
@@ -21441,26 +21981,26 @@ class Bless {
|
|
|
21441
21981
|
const authorizersDecoder = decoder_Decoder.fromBlob(res);
|
|
21442
21982
|
const memoryReadResult = memory.loadInto(res, authorization);
|
|
21443
21983
|
if (memoryReadResult.isError) {
|
|
21444
|
-
logger_logger.trace `BLESS(m: ${manager}, v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- PANIC`;
|
|
21984
|
+
logger_logger.trace `[${this.currentServiceId}] BLESS(m: ${manager}, v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- PANIC`;
|
|
21445
21985
|
return PvmExecution.Panic;
|
|
21446
21986
|
}
|
|
21447
21987
|
// `a`
|
|
21448
21988
|
const authorizers = tryAsPerCore(authorizersDecoder.sequenceFixLen(descriptors_codec.u32.asOpaque(), this.chainSpec.coresCount), this.chainSpec);
|
|
21449
21989
|
const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar, autoAccumulate);
|
|
21450
21990
|
if (updateResult.isOk) {
|
|
21451
|
-
logger_logger.trace `BLESS(m: ${manager}, a: [${authorizers}], v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- OK`;
|
|
21991
|
+
logger_logger.trace `[${this.currentServiceId}] BLESS(m: ${manager}, a: [${authorizers}], v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- OK`;
|
|
21452
21992
|
regs.set(bless_IN_OUT_REG, HostCallResult.OK);
|
|
21453
21993
|
return;
|
|
21454
21994
|
}
|
|
21455
21995
|
const e = updateResult.error;
|
|
21456
21996
|
// NOTE: `UpdatePrivilegesError.UnprivilegedService` won't happen in 0.7.1+
|
|
21457
21997
|
if (e === UpdatePrivilegesError.UnprivilegedService) {
|
|
21458
|
-
logger_logger.trace `BLESS(m: ${manager}, a: [${authorizers}], v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- HUH`;
|
|
21998
|
+
logger_logger.trace `[${this.currentServiceId}] BLESS(m: ${manager}, a: [${authorizers}], v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- HUH`;
|
|
21459
21999
|
regs.set(bless_IN_OUT_REG, HostCallResult.HUH);
|
|
21460
22000
|
return;
|
|
21461
22001
|
}
|
|
21462
22002
|
if (e === UpdatePrivilegesError.InvalidServiceId) {
|
|
21463
|
-
logger_logger.trace `BLESS(m: ${manager}, a: [${authorizers}], v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- WHO`;
|
|
22003
|
+
logger_logger.trace `[${this.currentServiceId}] BLESS(m: ${manager}, a: [${authorizers}], v: ${delegator}, r: ${registrar}, ${lazyInspect(autoAccumulate)}) <- WHO`;
|
|
21464
22004
|
regs.set(bless_IN_OUT_REG, HostCallResult.WHO);
|
|
21465
22005
|
return;
|
|
21466
22006
|
}
|
|
@@ -21490,7 +22030,7 @@ class GasHostCall {
|
|
|
21490
22030
|
}
|
|
21491
22031
|
execute(gas, regs) {
|
|
21492
22032
|
const gasValue = gas.get();
|
|
21493
|
-
logger_logger.trace `GAS <- ${gasValue}`;
|
|
22033
|
+
logger_logger.trace `[${this.currentServiceId}] GAS <- ${gasValue}`;
|
|
21494
22034
|
regs.set(7, numbers_tryAsU64(gasValue));
|
|
21495
22035
|
return Promise.resolve(undefined);
|
|
21496
22036
|
}
|
|
@@ -21522,7 +22062,7 @@ class Checkpoint {
|
|
|
21522
22062
|
async execute(gas, regs) {
|
|
21523
22063
|
await this.gasHostCall.execute(gas, regs);
|
|
21524
22064
|
this.partialState.checkpoint();
|
|
21525
|
-
logger_logger.trace `CHECKPOINT()`;
|
|
22065
|
+
logger_logger.trace `[${this.currentServiceId}] CHECKPOINT()`;
|
|
21526
22066
|
return;
|
|
21527
22067
|
}
|
|
21528
22068
|
}
|
|
@@ -21562,18 +22102,18 @@ class Designate {
|
|
|
21562
22102
|
const memoryReadResult = memory.loadInto(res, validatorsStart);
|
|
21563
22103
|
// error while reading the memory.
|
|
21564
22104
|
if (memoryReadResult.isError) {
|
|
21565
|
-
logger_logger.trace `DESIGNATE() <- PANIC`;
|
|
22105
|
+
logger_logger.trace `[${this.currentServiceId}] DESIGNATE() <- PANIC`;
|
|
21566
22106
|
return PvmExecution.Panic;
|
|
21567
22107
|
}
|
|
21568
22108
|
const decoder = decoder_Decoder.fromBlob(res);
|
|
21569
22109
|
const validatorsData = decoder.sequenceFixLen(ValidatorData.Codec, this.chainSpec.validatorsCount);
|
|
21570
22110
|
const result = this.partialState.updateValidatorsData(tryAsPerValidator(validatorsData, this.chainSpec));
|
|
21571
22111
|
if (result.isError) {
|
|
21572
|
-
logger_logger.trace `DESIGNATE([${validatorsData[0]}, ${validatorsData[1]}, ...]) <- HUH`;
|
|
22112
|
+
logger_logger.trace `[${this.currentServiceId}] DESIGNATE([${validatorsData[0]}, ${validatorsData[1]}, ...]) <- HUH`;
|
|
21573
22113
|
regs.set(designate_IN_OUT_REG, HostCallResult.HUH);
|
|
21574
22114
|
}
|
|
21575
22115
|
else {
|
|
21576
|
-
logger_logger.trace `DESIGNATE([${validatorsData[0]}, ${validatorsData[1]}, ...]) <- OK`;
|
|
22116
|
+
logger_logger.trace `[${this.currentServiceId}] DESIGNATE([${validatorsData[0]}, ${validatorsData[1]}, ...]) <- OK`;
|
|
21577
22117
|
regs.set(designate_IN_OUT_REG, HostCallResult.OK);
|
|
21578
22118
|
}
|
|
21579
22119
|
}
|
|
@@ -21614,29 +22154,29 @@ class Eject {
|
|
|
21614
22154
|
const previousCodeHash = bytes_Bytes.zero(hash_HASH_SIZE).asOpaque();
|
|
21615
22155
|
const memoryReadResult = memory.loadInto(previousCodeHash.raw, preimageHashStart);
|
|
21616
22156
|
if (memoryReadResult.isError) {
|
|
21617
|
-
logger_logger.trace `EJECT(${serviceId}) <- PANIC`;
|
|
22157
|
+
logger_logger.trace `[${this.currentServiceId}] EJECT(${serviceId}) <- PANIC`;
|
|
21618
22158
|
return PvmExecution.Panic;
|
|
21619
22159
|
}
|
|
21620
22160
|
// cannot eject self
|
|
21621
22161
|
if (serviceId === this.currentServiceId) {
|
|
21622
22162
|
regs.set(eject_IN_OUT_REG, HostCallResult.WHO);
|
|
21623
|
-
logger_logger.trace `EJECT(${serviceId}, ${previousCodeHash}) <- WHO`;
|
|
22163
|
+
logger_logger.trace `[${this.currentServiceId}] EJECT(${serviceId}, ${previousCodeHash}) <- WHO`;
|
|
21624
22164
|
return;
|
|
21625
22165
|
}
|
|
21626
22166
|
const result = this.partialState.eject(serviceId, previousCodeHash);
|
|
21627
22167
|
// All good!
|
|
21628
22168
|
if (result.isOk) {
|
|
21629
|
-
logger_logger.trace `EJECT(${serviceId}, ${previousCodeHash}) <- OK`;
|
|
22169
|
+
logger_logger.trace `[${this.currentServiceId}] EJECT(${serviceId}, ${previousCodeHash}) <- OK`;
|
|
21630
22170
|
regs.set(eject_IN_OUT_REG, HostCallResult.OK);
|
|
21631
22171
|
return;
|
|
21632
22172
|
}
|
|
21633
22173
|
const e = result.error;
|
|
21634
22174
|
if (e === EjectError.InvalidService) {
|
|
21635
|
-
logger_logger.trace `EJECT(${serviceId}, ${previousCodeHash}) <- WHO ${resultToString(result)}`;
|
|
22175
|
+
logger_logger.trace `[${this.currentServiceId}] EJECT(${serviceId}, ${previousCodeHash}) <- WHO ${resultToString(result)}`;
|
|
21636
22176
|
regs.set(eject_IN_OUT_REG, HostCallResult.WHO);
|
|
21637
22177
|
}
|
|
21638
22178
|
else if (e === EjectError.InvalidPreimage) {
|
|
21639
|
-
logger_logger.trace `EJECT(${serviceId}, ${previousCodeHash}) <- HUH ${resultToString(result)}`;
|
|
22179
|
+
logger_logger.trace `[${this.currentServiceId}] EJECT(${serviceId}, ${previousCodeHash}) <- HUH ${resultToString(result)}`;
|
|
21640
22180
|
regs.set(eject_IN_OUT_REG, HostCallResult.HUH);
|
|
21641
22181
|
}
|
|
21642
22182
|
else {
|
|
@@ -21655,9 +22195,9 @@ class Eject {
|
|
|
21655
22195
|
|
|
21656
22196
|
const forget_IN_OUT_REG = 7;
|
|
21657
22197
|
/**
|
|
21658
|
-
*
|
|
22198
|
+
* Delete preimage hash or mark as unavailable if it was available.
|
|
21659
22199
|
*
|
|
21660
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
22200
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/385d01385d01?v=0.7.2
|
|
21661
22201
|
*/
|
|
21662
22202
|
class Forget {
|
|
21663
22203
|
currentServiceId;
|
|
@@ -21678,11 +22218,11 @@ class Forget {
|
|
|
21678
22218
|
const memoryReadResult = memory.loadInto(hash.raw, hashStart);
|
|
21679
22219
|
// error while reading the memory.
|
|
21680
22220
|
if (memoryReadResult.isError) {
|
|
21681
|
-
logger_logger.trace `FORGET(${hash}, ${length}) <- PANIC`;
|
|
22221
|
+
logger_logger.trace `[${this.currentServiceId}] FORGET(${hash}, ${length}) <- PANIC`;
|
|
21682
22222
|
return PvmExecution.Panic;
|
|
21683
22223
|
}
|
|
21684
22224
|
const result = this.partialState.forgetPreimage(hash.asOpaque(), length);
|
|
21685
|
-
logger_logger.trace `FORGET(${hash}, ${length}) <- ${resultToString(result)}`;
|
|
22225
|
+
logger_logger.trace `[${this.currentServiceId}] FORGET(${hash}, ${length}) <- ${resultToString(result)}`;
|
|
21686
22226
|
if (result.isOk) {
|
|
21687
22227
|
regs.set(forget_IN_OUT_REG, HostCallResult.OK);
|
|
21688
22228
|
}
|
|
@@ -21739,11 +22279,11 @@ class New {
|
|
|
21739
22279
|
const memoryReadResult = memory.loadInto(codeHash.raw, codeHashStart);
|
|
21740
22280
|
// error while reading the memory.
|
|
21741
22281
|
if (memoryReadResult.isError) {
|
|
21742
|
-
logger_logger.trace `NEW(${codeHash}, ${codeLength}, ${gas}, ${allowance}, ${gratisStorage}, ${requestedServiceId}) <- PANIC`;
|
|
22282
|
+
logger_logger.trace `[${this.currentServiceId}] NEW(${codeHash}, ${codeLength}, ${gas}, ${allowance}, ${gratisStorage}, ${requestedServiceId}) <- PANIC`;
|
|
21743
22283
|
return PvmExecution.Panic;
|
|
21744
22284
|
}
|
|
21745
22285
|
const assignedId = this.partialState.newService(codeHash.asOpaque(), codeLength, gas, allowance, gratisStorage, requestedServiceId);
|
|
21746
|
-
logger_logger.trace `NEW(${codeHash}, ${codeLength}, ${gas}, ${allowance}, ${gratisStorage}, ${requestedServiceId}) <- ${resultToString(assignedId)}`;
|
|
22286
|
+
logger_logger.trace `[${this.currentServiceId}] NEW(${codeHash}, ${codeLength}, ${gas}, ${allowance}, ${gratisStorage}, ${requestedServiceId}) <- ${resultToString(assignedId)}`;
|
|
21747
22287
|
if (assignedId.isOk) {
|
|
21748
22288
|
regs.set(new_IN_OUT_REG, numbers_tryAsU64(assignedId.ok));
|
|
21749
22289
|
return;
|
|
@@ -21803,11 +22343,11 @@ class Provide {
|
|
|
21803
22343
|
const preimage = bytes_BytesBlob.blobFrom(safe_alloc_uint8array_safeAllocUint8Array(length));
|
|
21804
22344
|
const memoryReadResult = memory.loadInto(preimage.raw, preimageStart);
|
|
21805
22345
|
if (memoryReadResult.isError) {
|
|
21806
|
-
logger_logger.trace `PROVIDE(${serviceId}, ${preimage.toStringTruncated()}) <- PANIC`;
|
|
22346
|
+
logger_logger.trace `[${this.currentServiceId}] PROVIDE(${serviceId}, ${preimage.toStringTruncated()}) <- PANIC`;
|
|
21807
22347
|
return PvmExecution.Panic;
|
|
21808
22348
|
}
|
|
21809
22349
|
const result = this.partialState.providePreimage(serviceId, preimage);
|
|
21810
|
-
logger_logger.trace `PROVIDE(${serviceId}, ${preimage.toStringTruncated()}) <- ${resultToString(result)}`;
|
|
22350
|
+
logger_logger.trace `[${this.currentServiceId}] PROVIDE(${serviceId}, ${preimage.toStringTruncated()}) <- ${resultToString(result)}`;
|
|
21811
22351
|
if (result.isOk) {
|
|
21812
22352
|
regs.set(provide_IN_OUT_REG, HostCallResult.OK);
|
|
21813
22353
|
return;
|
|
@@ -21863,35 +22403,35 @@ class Query {
|
|
|
21863
22403
|
const memoryReadResult = memory.loadInto(hash.raw, hashStart);
|
|
21864
22404
|
// error while reading the memory.
|
|
21865
22405
|
if (memoryReadResult.isError) {
|
|
21866
|
-
logger_logger.trace `QUERY(${hash}, ${length}) <- PANIC`;
|
|
22406
|
+
logger_logger.trace `[${this.currentServiceId}] QUERY(${hash}, ${length}) <- PANIC`;
|
|
21867
22407
|
return PvmExecution.Panic;
|
|
21868
22408
|
}
|
|
21869
22409
|
const result = this.partialState.checkPreimageStatus(hash.asOpaque(), length);
|
|
21870
22410
|
const zero = numbers_tryAsU64(0n);
|
|
21871
22411
|
if (result === null) {
|
|
21872
|
-
logger_logger.trace `QUERY(${hash}, ${length}) <- NONE`;
|
|
22412
|
+
logger_logger.trace `[${this.currentServiceId}] QUERY(${hash}, ${length}) <- NONE`;
|
|
21873
22413
|
regs.set(IN_OUT_REG_1, HostCallResult.NONE);
|
|
21874
22414
|
regs.set(IN_OUT_REG_2, zero);
|
|
21875
22415
|
return;
|
|
21876
22416
|
}
|
|
21877
22417
|
switch (result.status) {
|
|
21878
22418
|
case PreimageStatusKind.Requested:
|
|
21879
|
-
logger_logger.trace `QUERY(${hash}, ${length}) <- REQUESTED`;
|
|
22419
|
+
logger_logger.trace `[${this.currentServiceId}] QUERY(${hash}, ${length}) <- REQUESTED`;
|
|
21880
22420
|
regs.set(IN_OUT_REG_1, zero);
|
|
21881
22421
|
regs.set(IN_OUT_REG_2, zero);
|
|
21882
22422
|
return;
|
|
21883
22423
|
case PreimageStatusKind.Available:
|
|
21884
|
-
logger_logger.trace `QUERY(${hash}, ${length}) <- AVAILABLE [${result.data}]`;
|
|
22424
|
+
logger_logger.trace `[${this.currentServiceId}] QUERY(${hash}, ${length}) <- AVAILABLE [${result.data}]`;
|
|
21885
22425
|
regs.set(IN_OUT_REG_1, numbers_tryAsU64((BigInt(result.data[0]) << UPPER_BITS_SHIFT) + 1n));
|
|
21886
22426
|
regs.set(IN_OUT_REG_2, zero);
|
|
21887
22427
|
return;
|
|
21888
22428
|
case PreimageStatusKind.Unavailable:
|
|
21889
|
-
logger_logger.trace `QUERY(${hash}, ${length}) <- UNAVAILABLE [${result.data.join(", ")}]`;
|
|
22429
|
+
logger_logger.trace `[${this.currentServiceId}] QUERY(${hash}, ${length}) <- UNAVAILABLE [${result.data.join(", ")}]`;
|
|
21890
22430
|
regs.set(IN_OUT_REG_1, numbers_tryAsU64((BigInt(result.data[0]) << UPPER_BITS_SHIFT) + 2n));
|
|
21891
22431
|
regs.set(IN_OUT_REG_2, numbers_tryAsU64(result.data[1]));
|
|
21892
22432
|
return;
|
|
21893
22433
|
case PreimageStatusKind.Reavailable:
|
|
21894
|
-
logger_logger.trace `QUERY(${hash}, ${length}) <- REAVAILABLE [${result.data.join(", ")}]`;
|
|
22434
|
+
logger_logger.trace `[${this.currentServiceId}] QUERY(${hash}, ${length}) <- REAVAILABLE [${result.data.join(", ")}]`;
|
|
21895
22435
|
regs.set(IN_OUT_REG_1, numbers_tryAsU64((BigInt(result.data[0]) << UPPER_BITS_SHIFT) + 3n));
|
|
21896
22436
|
regs.set(IN_OUT_REG_2, numbers_tryAsU64((BigInt(result.data[2]) << UPPER_BITS_SHIFT) + BigInt(result.data[1])));
|
|
21897
22437
|
return;
|
|
@@ -21932,11 +22472,11 @@ class Solicit {
|
|
|
21932
22472
|
const hash = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
21933
22473
|
const memoryReadResult = memory.loadInto(hash.raw, hashStart);
|
|
21934
22474
|
if (memoryReadResult.isError) {
|
|
21935
|
-
logger_logger.trace `SOLICIT(${hash}, ${length}) <- PANIC`;
|
|
22475
|
+
logger_logger.trace `[${this.currentServiceId}] SOLICIT(${hash}, ${length}) <- PANIC`;
|
|
21936
22476
|
return PvmExecution.Panic;
|
|
21937
22477
|
}
|
|
21938
22478
|
const result = this.partialState.requestPreimage(hash.asOpaque(), length);
|
|
21939
|
-
logger_logger.trace `SOLICIT(${hash}, ${length}) <- ${resultToString(result)}`;
|
|
22479
|
+
logger_logger.trace `[${this.currentServiceId}] SOLICIT(${hash}, ${length}) <- ${resultToString(result)}`;
|
|
21940
22480
|
if (result.isOk) {
|
|
21941
22481
|
regs.set(solicit_IN_OUT_REG, HostCallResult.OK);
|
|
21942
22482
|
return;
|
|
@@ -21994,7 +22534,7 @@ class Transfer {
|
|
|
21994
22534
|
*/
|
|
21995
22535
|
basicGasCost = compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2)
|
|
21996
22536
|
? gas_tryAsSmallGas(10)
|
|
21997
|
-
: (regs) =>
|
|
22537
|
+
: (regs) => gas_tryAsGas(10n + regs.get(TRANSFER_GAS_FEE_REG));
|
|
21998
22538
|
tracedRegisters = traceRegisters(transfer_IN_OUT_REG, AMOUNT_REG, TRANSFER_GAS_FEE_REG, MEMO_START_REG);
|
|
21999
22539
|
constructor(currentServiceId, partialState) {
|
|
22000
22540
|
this.currentServiceId = currentServiceId;
|
|
@@ -22013,16 +22553,16 @@ class Transfer {
|
|
|
22013
22553
|
const memoryReadResult = memory.loadInto(memo.raw, memoStart);
|
|
22014
22554
|
// page fault while reading the memory.
|
|
22015
22555
|
if (memoryReadResult.isError) {
|
|
22016
|
-
logger_logger.trace `TRANSFER(${destination}, ${amount}, ${transferGasFee}, ${memo}) <- PANIC`;
|
|
22556
|
+
logger_logger.trace `[${this.currentServiceId}] TRANSFER(${destination}, ${amount}, ${transferGasFee}, ${memo}) <- PANIC`;
|
|
22017
22557
|
return PvmExecution.Panic;
|
|
22018
22558
|
}
|
|
22019
22559
|
const transferResult = this.partialState.transfer(destination, amount, transferGasFee, memo);
|
|
22020
|
-
logger_logger.trace `TRANSFER(${destination}, ${amount}, ${transferGasFee}, ${memo}) <- ${resultToString(transferResult)}`;
|
|
22560
|
+
logger_logger.trace `[${this.currentServiceId}] TRANSFER(${destination}, ${amount}, ${transferGasFee}, ${memo}) <- ${resultToString(transferResult)}`;
|
|
22021
22561
|
// All good!
|
|
22022
22562
|
if (transferResult.isOk) {
|
|
22023
22563
|
if (compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2)) {
|
|
22024
22564
|
// substracting value `t`
|
|
22025
|
-
const underflow = gas.sub(
|
|
22565
|
+
const underflow = gas.sub(gas_tryAsGas(transferGasFee));
|
|
22026
22566
|
if (underflow) {
|
|
22027
22567
|
return PvmExecution.OOG;
|
|
22028
22568
|
}
|
|
@@ -22083,11 +22623,11 @@ class Upgrade {
|
|
|
22083
22623
|
const codeHash = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
22084
22624
|
const memoryReadResult = memory.loadInto(codeHash.raw, codeHashStart);
|
|
22085
22625
|
if (memoryReadResult.isError) {
|
|
22086
|
-
logger_logger.trace `UPGRADE(${codeHash}, ${gas}, ${allowance}) <- PANIC`;
|
|
22626
|
+
logger_logger.trace `[${this.currentServiceId}] UPGRADE(${codeHash}, ${gas}, ${allowance}) <- PANIC`;
|
|
22087
22627
|
return PvmExecution.Panic;
|
|
22088
22628
|
}
|
|
22089
22629
|
this.partialState.upgradeService(codeHash.asOpaque(), gas, allowance);
|
|
22090
|
-
logger_logger.trace `UPGRADE(${codeHash}, ${gas}, ${allowance})`;
|
|
22630
|
+
logger_logger.trace `[${this.currentServiceId}] UPGRADE(${codeHash}, ${gas}, ${allowance})`;
|
|
22091
22631
|
regs.set(upgrade_IN_OUT_REG, HostCallResult.OK);
|
|
22092
22632
|
}
|
|
22093
22633
|
}
|
|
@@ -22121,11 +22661,11 @@ class Yield {
|
|
|
22121
22661
|
const hash = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
22122
22662
|
const memoryReadResult = memory.loadInto(hash.raw, hashStart);
|
|
22123
22663
|
if (memoryReadResult.isError) {
|
|
22124
|
-
logger_logger.trace `YIELD() <- PANIC`;
|
|
22664
|
+
logger_logger.trace `[${this.currentServiceId}] YIELD() <- PANIC`;
|
|
22125
22665
|
return PvmExecution.Panic;
|
|
22126
22666
|
}
|
|
22127
22667
|
this.partialState.yield(hash);
|
|
22128
|
-
logger_logger.trace `YIELD(${hash})`;
|
|
22668
|
+
logger_logger.trace `[${this.currentServiceId}] YIELD(${hash})`;
|
|
22129
22669
|
regs.set(yield_IN_OUT_REG, HostCallResult.OK);
|
|
22130
22670
|
}
|
|
22131
22671
|
}
|
|
@@ -22168,10 +22708,10 @@ class Fetch {
|
|
|
22168
22708
|
const chunk = value === null ? new Uint8Array() : value.raw.subarray(Number(offset), Number(offset + length));
|
|
22169
22709
|
const storeResult = memory.storeFrom(output, chunk);
|
|
22170
22710
|
if (storeResult.isError) {
|
|
22171
|
-
logger_logger.trace `FETCH(${kind}) <- PANIC`;
|
|
22711
|
+
logger_logger.trace `[${this.currentServiceId}] FETCH(${kind}) <- PANIC`;
|
|
22172
22712
|
return PvmExecution.Panic;
|
|
22173
22713
|
}
|
|
22174
|
-
logger_logger.trace `FETCH(${kind}) <- ${value?.toStringTruncated()}`;
|
|
22714
|
+
logger_logger.trace `[${this.currentServiceId}] FETCH(${kind}) <- ${value?.toStringTruncated()}`;
|
|
22175
22715
|
// write result
|
|
22176
22716
|
regs.set(fetch_IN_OUT_REG, value === null ? HostCallResult.NONE : valueLength);
|
|
22177
22717
|
}
|
|
@@ -22321,7 +22861,7 @@ class LogHostCall {
|
|
|
22321
22861
|
}
|
|
22322
22862
|
memory.loadInto(message, msgStart);
|
|
22323
22863
|
const level = clampU64ToU32(lvl);
|
|
22324
|
-
logger_logger.trace `LOG(${this.currentServiceId}, ${level < Levels.UNKNOWN ? Levels[level] : Levels[Levels.UNKNOWN]}(${lvl}), ${decoder.decode(target)}, ${decoder.decode(message)})`;
|
|
22864
|
+
logger_logger.trace `[${this.currentServiceId}] LOG(${this.currentServiceId}, ${level < Levels.UNKNOWN ? Levels[level] : Levels[Levels.UNKNOWN]}(${lvl}), ${decoder.decode(target)}, ${decoder.decode(message)})`;
|
|
22325
22865
|
return Promise.resolve(undefined);
|
|
22326
22866
|
}
|
|
22327
22867
|
}
|
|
@@ -22362,12 +22902,12 @@ class Lookup {
|
|
|
22362
22902
|
const preImageHash = bytes_Bytes.zero(hash_HASH_SIZE);
|
|
22363
22903
|
const memoryReadResult = memory.loadInto(preImageHash.raw, hashAddress);
|
|
22364
22904
|
if (memoryReadResult.isError) {
|
|
22365
|
-
logger_logger.trace `LOOKUP(${serviceId}, ${preImageHash}) <- PANIC`;
|
|
22905
|
+
logger_logger.trace `[${this.currentServiceId}] LOOKUP(${serviceId}, ${preImageHash}) <- PANIC`;
|
|
22366
22906
|
return PvmExecution.Panic;
|
|
22367
22907
|
}
|
|
22368
22908
|
// v
|
|
22369
22909
|
const preImage = this.account.lookup(serviceId, preImageHash);
|
|
22370
|
-
logger_logger.trace `LOOKUP(${serviceId}, ${preImageHash}) <- ${preImage?.toStringTruncated() ?? "<missing>"}...`;
|
|
22910
|
+
logger_logger.trace `[${this.currentServiceId}] LOOKUP(${serviceId}, ${preImageHash}) <- ${preImage?.toStringTruncated() ?? "<missing>"}...`;
|
|
22371
22911
|
const preImageLength = preImage === null ? numbers_tryAsU64(0) : numbers_tryAsU64(preImage.raw.length);
|
|
22372
22912
|
const preimageBlobOffset = regs.get(10);
|
|
22373
22913
|
const lengthToWrite = regs.get(11);
|
|
@@ -22464,20 +23004,20 @@ class Read {
|
|
|
22464
23004
|
const chunk = value === null ? safe_alloc_uint8array_safeAllocUint8Array(0) : value.raw.subarray(Number(offset), Number(offset + blobLength));
|
|
22465
23005
|
const memoryWriteResult = memory.storeFrom(destinationAddress, chunk);
|
|
22466
23006
|
if (memoryWriteResult.isError) {
|
|
22467
|
-
logger_logger.trace `READ(${serviceId}, ${rawKey}) <- PANIC`;
|
|
23007
|
+
logger_logger.trace `[${this.currentServiceId}] READ(${serviceId}, ${rawKey}) <- PANIC`;
|
|
22468
23008
|
return PvmExecution.Panic;
|
|
22469
23009
|
}
|
|
22470
23010
|
if (value === null) {
|
|
22471
|
-
logger_logger.trace `READ(${serviceId}, ${rawKey}) <- NONE`;
|
|
23011
|
+
logger_logger.trace `[${this.currentServiceId}] READ(${serviceId}, ${rawKey}) <- NONE`;
|
|
22472
23012
|
regs.set(read_IN_OUT_REG, HostCallResult.NONE);
|
|
22473
23013
|
return;
|
|
22474
23014
|
}
|
|
22475
23015
|
if (chunk.length > 0) {
|
|
22476
|
-
logger_logger.trace `READ(${serviceId}, ${rawKey}) <- ${bytes_BytesBlob.blobFrom(chunk).toStringTruncated()}`;
|
|
23016
|
+
logger_logger.trace `[${this.currentServiceId}] READ(${serviceId}, ${rawKey}) <- ${bytes_BytesBlob.blobFrom(chunk).toStringTruncated()}`;
|
|
22477
23017
|
}
|
|
22478
23018
|
else {
|
|
22479
23019
|
// just a query for length of stored data
|
|
22480
|
-
logger_logger.trace `READ(${serviceId}, ${rawKey}) <- (${valueLength} ${valueLength === 1n ? "byte" : "bytes"})`;
|
|
23020
|
+
logger_logger.trace `[${this.currentServiceId}] READ(${serviceId}, ${rawKey}) <- (${valueLength} ${valueLength === 1n ? "byte" : "bytes"})`;
|
|
22481
23021
|
}
|
|
22482
23022
|
regs.set(read_IN_OUT_REG, valueLength);
|
|
22483
23023
|
}
|
|
@@ -22521,7 +23061,7 @@ class Write {
|
|
|
22521
23061
|
const rawStorageKey = safe_alloc_uint8array_safeAllocUint8Array(storageKeyLengthClamped);
|
|
22522
23062
|
const keyLoadingResult = memory.loadInto(rawStorageKey, storageKeyStartAddress);
|
|
22523
23063
|
if (keyLoadingResult.isError) {
|
|
22524
|
-
logger_logger.trace `WRITE() <- PANIC`;
|
|
23064
|
+
logger_logger.trace `[${this.currentServiceId}] WRITE() <- PANIC`;
|
|
22525
23065
|
return PvmExecution.Panic;
|
|
22526
23066
|
}
|
|
22527
23067
|
// k
|
|
@@ -22531,14 +23071,14 @@ class Write {
|
|
|
22531
23071
|
const valueLoadingResult = memory.loadInto(value, valueStart);
|
|
22532
23072
|
// Note [MaSo] this is ok to return bcs if valueLength is 0, then this panic won't happen
|
|
22533
23073
|
if (valueLoadingResult.isError) {
|
|
22534
|
-
logger_logger.trace `WRITE(${storageKey}) <- PANIC`;
|
|
23074
|
+
logger_logger.trace `[${this.currentServiceId}] WRITE(${storageKey}) <- PANIC`;
|
|
22535
23075
|
return PvmExecution.Panic;
|
|
22536
23076
|
}
|
|
22537
23077
|
/** https://graypaper.fluffylabs.dev/#/9a08063/33af0133b201?v=0.6.6 */
|
|
22538
23078
|
const maybeValue = valueLength === 0n ? null : bytes_BytesBlob.blobFrom(value);
|
|
22539
23079
|
// a
|
|
22540
23080
|
const result = this.account.write(storageKey, maybeValue);
|
|
22541
|
-
logger_logger.trace `WRITE(${storageKey}, ${maybeValue?.toStringTruncated() ?? "remove"}) <- ${resultToString(result)}`;
|
|
23081
|
+
logger_logger.trace `[${this.currentServiceId}] WRITE(${storageKey}, ${maybeValue?.toStringTruncated() ?? "remove"}) <- ${resultToString(result)}`;
|
|
22542
23082
|
if (result.isError) {
|
|
22543
23083
|
regs.set(write_IN_OUT_REG, HostCallResult.FULL);
|
|
22544
23084
|
return;
|
|
@@ -22767,7 +23307,7 @@ class Accumulate {
|
|
|
22767
23307
|
serviceId,
|
|
22768
23308
|
argsLength: numbers_tryAsU32(transfers.length + operands.length),
|
|
22769
23309
|
});
|
|
22770
|
-
const result = await executor.run(invocationArgs,
|
|
23310
|
+
const result = await executor.run(invocationArgs, gas_tryAsGas(gas));
|
|
22771
23311
|
const [newState, checkpoint] = partialState.getStateUpdates();
|
|
22772
23312
|
/**
|
|
22773
23313
|
* PVM invocation returned and error so we return the checkpoint
|
|
@@ -22968,19 +23508,19 @@ class Accumulate {
|
|
|
22968
23508
|
for (let serviceIndex = 0; serviceIndex < serviceIdsLength; serviceIndex += 1) {
|
|
22969
23509
|
const serviceId = serviceIds[serviceIndex];
|
|
22970
23510
|
const checkpoint = AccumulationStateUpdate.copyFrom(inputStateUpdate);
|
|
22971
|
-
const promise = this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), accumulateData.getOperands(serviceId), accumulateData.getGasLimit(serviceId), slot, entropy, AccumulationStateUpdate.copyFrom(inputStateUpdate)).then(({ consumedGas, stateUpdate }) =>
|
|
22972
|
-
|
|
22973
|
-
|
|
22974
|
-
|
|
23511
|
+
const promise = this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), accumulateData.getOperands(serviceId), accumulateData.getGasLimit(serviceId), slot, entropy, AccumulationStateUpdate.copyFrom(inputStateUpdate)).then(({ consumedGas, stateUpdate }) => {
|
|
23512
|
+
const resultEntry = [
|
|
23513
|
+
serviceId,
|
|
23514
|
+
{
|
|
23515
|
+
consumedGas,
|
|
23516
|
+
stateUpdate: stateUpdate === null ? checkpoint : stateUpdate,
|
|
23517
|
+
},
|
|
23518
|
+
];
|
|
23519
|
+
return resultEntry;
|
|
23520
|
+
});
|
|
22975
23521
|
resultPromises[serviceIndex] = promise;
|
|
22976
23522
|
}
|
|
22977
|
-
return Promise.all(resultPromises).then((results) =>
|
|
22978
|
-
const map = new Map();
|
|
22979
|
-
for (let serviceIndex = 0; serviceIndex < serviceIdsLength; serviceIndex += 1) {
|
|
22980
|
-
map.set(serviceIds[serviceIndex], results[serviceIndex]);
|
|
22981
|
-
}
|
|
22982
|
-
return map;
|
|
22983
|
-
});
|
|
23523
|
+
return Promise.all(resultPromises).then((results) => new Map(results));
|
|
22984
23524
|
}
|
|
22985
23525
|
/**
|
|
22986
23526
|
* A method that updates `recentlyAccumulated`, `accumulationQueue` and `timeslot` in state
|
|
@@ -23069,9 +23609,10 @@ class Accumulate {
|
|
|
23069
23609
|
const _gasCost = gasCost;
|
|
23070
23610
|
assertEmpty(rest);
|
|
23071
23611
|
const accumulated = accumulatableReports.subview(0, accumulatedReports);
|
|
23072
|
-
const { yieldedRoot, services, transfers
|
|
23612
|
+
const { yieldedRoot, services, transfers, validatorsData, privilegedServices, authorizationQueues, ...stateUpdateRest } = state;
|
|
23073
23613
|
assertEmpty(stateUpdateRest);
|
|
23074
|
-
// yielded root
|
|
23614
|
+
// transfers and yielded root are retrieved after each pvm invocation so we can ignore it here
|
|
23615
|
+
const _transfers = transfers;
|
|
23075
23616
|
const _yieldedRoot = yieldedRoot;
|
|
23076
23617
|
if (this.hasDuplicatedServiceIdCreated(services.created)) {
|
|
23077
23618
|
accumulate_logger.trace `Duplicated Service creation detected. Block is invalid.`;
|
|
@@ -23170,7 +23711,7 @@ class DeferredTransfers {
|
|
|
23170
23711
|
partiallyUpdatedState.updateServiceInfo(serviceId, newInfo);
|
|
23171
23712
|
const partialState = new AccumulateExternalities(this.chainSpec, this.blake2b, partiallyUpdatedState, serviceId, serviceId, timeslot);
|
|
23172
23713
|
const fetchExternalities = FetchExternalities.createForOnTransfer({ entropy, transfers }, this.chainSpec);
|
|
23173
|
-
let consumedGas =
|
|
23714
|
+
let consumedGas = gas_tryAsGas(0);
|
|
23174
23715
|
const hasTransfers = transfers.length > 0;
|
|
23175
23716
|
const isCodeCorrect = code !== null && code.length <= W_C;
|
|
23176
23717
|
if (!hasTransfers || !isCodeCorrect) {
|
|
@@ -23188,7 +23729,7 @@ class DeferredTransfers {
|
|
|
23188
23729
|
const executor = await PvmExecutor.createOnTransferExecutor(serviceId, code, { partialState, fetchExternalities }, this.pvm);
|
|
23189
23730
|
const args = encoder_Encoder.encodeObject(deferred_transfers_ARGS_CODEC, { timeslot, serviceId, transfersLength: numbers_tryAsU32(transfers.length) }, this.chainSpec);
|
|
23190
23731
|
const gas = transfers.reduce((acc, item) => acc + item.gas, 0n);
|
|
23191
|
-
consumedGas = (await executor.run(args,
|
|
23732
|
+
consumedGas = (await executor.run(args, gas_tryAsGas(gas))).consumedGas;
|
|
23192
23733
|
}
|
|
23193
23734
|
transferStatistics.set(serviceId, { count: numbers_tryAsU32(transfers.length), gasUsed: tryAsServiceGas(consumedGas) });
|
|
23194
23735
|
const [updatedState] = partialState.getStateUpdates();
|
|
@@ -25002,7 +25543,7 @@ async function createImporter(config) {
|
|
|
25002
25543
|
const interpreter = config.workerParams.pvm;
|
|
25003
25544
|
const blocks = db.getBlocksDb();
|
|
25004
25545
|
const states = db.getStatesDb();
|
|
25005
|
-
const hasher = new TransitionHasher(
|
|
25546
|
+
const hasher = new TransitionHasher(await keccakHasher, await blake2b);
|
|
25006
25547
|
const importer = new Importer(chainSpec, interpreter, hasher, main_logger, blocks, states);
|
|
25007
25548
|
return {
|
|
25008
25549
|
importer,
|