@typeberry/lib 0.5.0-70ae055 → 0.5.0-793dce7

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.
Files changed (4) hide show
  1. package/index.cjs +177 -166
  2. package/index.d.ts +30 -17
  3. package/index.js +177 -166
  4. package/package.json +1 -1
package/index.cjs CHANGED
@@ -1584,7 +1584,7 @@ function addSizeHints(a, b) {
1584
1584
  };
1585
1585
  }
1586
1586
  const DEFAULT_START_LENGTH = 512; // 512B
1587
- const MAX_LENGTH$1 = 10 * 1024 * 1024; // 10MB
1587
+ const MAX_LENGTH$1 = 20 * 1024 * 1024; // 20MB
1588
1588
  /**
1589
1589
  * JAM encoder.
1590
1590
  */
@@ -1937,7 +1937,7 @@ class Encoder {
1937
1937
  if (options.silent) {
1938
1938
  return;
1939
1939
  }
1940
- throw new Error(`The encoded size would reach the maximum of ${MAX_LENGTH$1}.`);
1940
+ throw new Error(`The encoded size (${newLength}) would reach the maximum of ${MAX_LENGTH$1}.`);
1941
1941
  }
1942
1942
  if (newLength > this.destination.length) {
1943
1943
  // we can try to resize the underlying buffer
@@ -6778,7 +6778,7 @@ class Credential extends WithDebug {
6778
6778
  /**
6779
6779
  * Tuple of work-report, a credential and it's corresponding timeslot.
6780
6780
  *
6781
- * https://graypaper.fluffylabs.dev/#/579bd12/147102149102
6781
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15df00150301?v=0.7.2
6782
6782
  */
6783
6783
  class ReportGuarantee extends WithDebug {
6784
6784
  report;
@@ -6806,7 +6806,7 @@ class ReportGuarantee extends WithDebug {
6806
6806
  * validator index and a signature.
6807
6807
  * Credentials must be ordered by their validator index.
6808
6808
  *
6809
- * https://graypaper.fluffylabs.dev/#/579bd12/14b90214bb02
6809
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/152b01152d01?v=0.7.2
6810
6810
  */
6811
6811
  credentials) {
6812
6812
  super();
@@ -7583,7 +7583,7 @@ const workExecResultFromJson = json.object({
7583
7583
  code_oversize: json.optional(json.fromAny(() => null)),
7584
7584
  output_oversize: json.optional(json.fromAny(() => null)),
7585
7585
  }, (val) => {
7586
- const { ok, out_of_gas, panic, bad_code, code_oversize } = val;
7586
+ const { ok, out_of_gas, panic, bad_code, code_oversize, output_oversize } = val;
7587
7587
  if (ok !== undefined) {
7588
7588
  return new WorkExecResult(tryAsU32(WorkExecResultKind.ok), ok);
7589
7589
  }
@@ -7599,7 +7599,7 @@ const workExecResultFromJson = json.object({
7599
7599
  if (code_oversize === null) {
7600
7600
  return new WorkExecResult(tryAsU32(WorkExecResultKind.codeOversize));
7601
7601
  }
7602
- if (val.output_oversize === null) {
7602
+ if (output_oversize === null) {
7603
7603
  return new WorkExecResult(tryAsU32(WorkExecResultKind.digestTooBig));
7604
7604
  }
7605
7605
  throw new Error("Invalid WorkExecResult");
@@ -8711,8 +8711,6 @@ const W_B = Compatibility.isGreaterOrEqual(GpVersion.V0_7_2) ? 13_791_360 : 13_7
8711
8711
  const W_C = 4_000_000;
8712
8712
  /** `W_M`: The maximum number of imports in a work-package. */
8713
8713
  const W_M = 3_072;
8714
- /** `W_R`: The maximum total size of all output blobs in a work-report, in octets. */
8715
- const W_R = 49_152;
8716
8714
  /** `W_T`: The size of a transfer memo in octets. */
8717
8715
  const W_T = 128;
8718
8716
  /** `W_M`: The maximum number of exports in a work-package. */
@@ -20478,6 +20476,103 @@ function signingPayload$1(blake2b, anchor, blob) {
20478
20476
  return BytesBlob.blobFromParts(JAM_AVAILABLE, blake2b.hashBytes(BytesBlob.blobFromParts(anchor.raw, blob.raw)).raw);
20479
20477
  }
20480
20478
 
20479
+ /** Error that may happen during reports processing. */
20480
+ var ReportsError;
20481
+ (function (ReportsError) {
20482
+ /** Core index is greater than the number of available cores. */
20483
+ ReportsError[ReportsError["BadCoreIndex"] = 0] = "BadCoreIndex";
20484
+ /** The report slot is greater than the current block slot. */
20485
+ ReportsError[ReportsError["FutureReportSlot"] = 1] = "FutureReportSlot";
20486
+ /** Report is too old to be considered. */
20487
+ ReportsError[ReportsError["ReportEpochBeforeLast"] = 2] = "ReportEpochBeforeLast";
20488
+ /** Not enough credentials for the guarantee. */
20489
+ ReportsError[ReportsError["InsufficientGuarantees"] = 3] = "InsufficientGuarantees";
20490
+ /** Guarantees are not ordered by the core index. */
20491
+ ReportsError[ReportsError["OutOfOrderGuarantee"] = 4] = "OutOfOrderGuarantee";
20492
+ /** Credentials of guarantors are not sorted or unique. */
20493
+ ReportsError[ReportsError["NotSortedOrUniqueGuarantors"] = 5] = "NotSortedOrUniqueGuarantors";
20494
+ /** Validator in credentials is assigned to a different core. */
20495
+ ReportsError[ReportsError["WrongAssignment"] = 6] = "WrongAssignment";
20496
+ /** There is a report pending availability on that core already. */
20497
+ ReportsError[ReportsError["CoreEngaged"] = 7] = "CoreEngaged";
20498
+ /** Anchor block is not found in recent blocks. */
20499
+ ReportsError[ReportsError["AnchorNotRecent"] = 8] = "AnchorNotRecent";
20500
+ /** Service not foubd. */
20501
+ ReportsError[ReportsError["BadServiceId"] = 9] = "BadServiceId";
20502
+ /** Service code hash does not match the current one. */
20503
+ ReportsError[ReportsError["BadCodeHash"] = 10] = "BadCodeHash";
20504
+ /** Pre-requisite work package is missing in either recent blocks or lookup extrinsic. */
20505
+ ReportsError[ReportsError["DependencyMissing"] = 11] = "DependencyMissing";
20506
+ /** Results for the same package are in more than one report. */
20507
+ ReportsError[ReportsError["DuplicatePackage"] = 12] = "DuplicatePackage";
20508
+ /** Anchor block declared state root does not match the one we have in recent blocks. */
20509
+ ReportsError[ReportsError["BadStateRoot"] = 13] = "BadStateRoot";
20510
+ /** BEEFY super hash mmr mismatch. */
20511
+ ReportsError[ReportsError["BadBeefyMmrRoot"] = 14] = "BadBeefyMmrRoot";
20512
+ /** The authorization hash is not found in the authorization pool. */
20513
+ ReportsError[ReportsError["CoreUnauthorized"] = 15] = "CoreUnauthorized";
20514
+ /** Validator index is greater than the number of validators. */
20515
+ ReportsError[ReportsError["BadValidatorIndex"] = 16] = "BadValidatorIndex";
20516
+ /** Total gas of work report is too high. */
20517
+ ReportsError[ReportsError["WorkReportGasTooHigh"] = 17] = "WorkReportGasTooHigh";
20518
+ /** Work item has is smaller than required minimal accumulation gas of a service. */
20519
+ ReportsError[ReportsError["ServiceItemGasTooLow"] = 18] = "ServiceItemGasTooLow";
20520
+ /** The report has too many dependencies (prerequisites and/or segment-root lookups). */
20521
+ ReportsError[ReportsError["TooManyDependencies"] = 19] = "TooManyDependencies";
20522
+ /** Segment root lookup block has invalid time slot or is not found in the header chain. */
20523
+ ReportsError[ReportsError["SegmentRootLookupInvalid"] = 20] = "SegmentRootLookupInvalid";
20524
+ /** Signature in credentials is invalid. */
20525
+ ReportsError[ReportsError["BadSignature"] = 21] = "BadSignature";
20526
+ /** Size of authorizer output and all work-item successful output blobs is too big. */
20527
+ ReportsError[ReportsError["WorkReportTooBig"] = 22] = "WorkReportTooBig";
20528
+ /** Contains guarantee from validator that is proven to be an offender. */
20529
+ ReportsError[ReportsError["BannedValidator"] = 23] = "BannedValidator";
20530
+ })(ReportsError || (ReportsError = {}));
20531
+
20532
+ /**
20533
+ * `W_R = 48 * 2**10`: The maximum total size of all output blobs in a work-report, in octets.
20534
+ *
20535
+ * https://graypaper.fluffylabs.dev/#/5f542d7/41a60041aa00?v=0.6.2
20536
+ */
20537
+ const MAX_WORK_REPORT_SIZE_BYTES = 48 * 2 ** 10;
20538
+ function verifyReportsBasic(input) {
20539
+ for (const guarantee of input) {
20540
+ const reportView = guarantee.view().report.view();
20541
+ /**
20542
+ * We limit the sum of the number of items in the
20543
+ * segment-root lookup dictionary and the number of
20544
+ * prerequisites to J = 8:
20545
+ *
20546
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/13fd0113ff01?v=0.7.2
20547
+ */
20548
+ const noOfPrerequisites = reportView.context.view().prerequisites.view().length;
20549
+ const noOfSegmentRootLookups = reportView.segmentRootLookup.view().length;
20550
+ if (noOfPrerequisites + noOfSegmentRootLookups > MAX_REPORT_DEPENDENCIES) {
20551
+ return Result$1.error(ReportsError.TooManyDependencies, () => `Report at ${reportView.coreIndex.materialize()} has too many dependencies. Got ${noOfPrerequisites} + ${noOfSegmentRootLookups}, max: ${MAX_REPORT_DEPENDENCIES}`);
20552
+ }
20553
+ /**
20554
+ * In order to ensure fair use of a block’s extrinsic space,
20555
+ * work-reports are limited in the maximum total size of the
20556
+ * successful output blobs together with the authorizer output
20557
+ * blob, effectively limiting their overall size:
20558
+ *
20559
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/14a80014ab00?v=0.7.2
20560
+ */
20561
+ // adding is safe here, since the total-encoded size of the report
20562
+ // is limited as well. Even though we just have a view, the size
20563
+ // should have been verified earlier.
20564
+ const authOutputSize = reportView.authorizationOutput.view().length;
20565
+ let totalOutputsSize = 0;
20566
+ for (const item of reportView.results.view()) {
20567
+ totalOutputsSize += item.view().result.view().okBlob?.raw.length ?? 0;
20568
+ }
20569
+ if (authOutputSize + totalOutputsSize > MAX_WORK_REPORT_SIZE_BYTES) {
20570
+ return Result$1.error(ReportsError.WorkReportTooBig, () => `Work report at ${reportView.coreIndex.materialize()} too big. Got ${authOutputSize} + ${totalOutputsSize}, max: ${MAX_WORK_REPORT_SIZE_BYTES}`);
20571
+ }
20572
+ }
20573
+ return Result$1.ok(OK);
20574
+ }
20575
+
20481
20576
  var TransferOperandKind;
20482
20577
  (function (TransferOperandKind) {
20483
20578
  TransferOperandKind[TransferOperandKind["OPERAND"] = 0] = "OPERAND";
@@ -20589,7 +20684,7 @@ function getEncodedConstants(chainSpec) {
20589
20684
  W_E: tryAsU32(chainSpec.erasureCodedPieceSize),
20590
20685
  W_M: tryAsU32(W_M),
20591
20686
  W_P: tryAsU32(chainSpec.numberECPiecesPerSegment),
20592
- W_R: tryAsU32(W_R),
20687
+ W_R: tryAsU32(MAX_WORK_REPORT_SIZE_BYTES),
20593
20688
  W_T: tryAsU32(W_T),
20594
20689
  W_X: tryAsU32(W_X),
20595
20690
  Y: tryAsU32(chainSpec.contestLength),
@@ -21326,12 +21421,15 @@ class Accumulate {
21326
21421
  chainSpec;
21327
21422
  blake2b;
21328
21423
  state;
21329
- pvm;
21330
- constructor(chainSpec, blake2b, state, pvm) {
21424
+ options;
21425
+ constructor(chainSpec, blake2b, state, options) {
21331
21426
  this.chainSpec = chainSpec;
21332
21427
  this.blake2b = blake2b;
21333
21428
  this.state = state;
21334
- this.pvm = pvm;
21429
+ this.options = options;
21430
+ if (options.accumulateSequentially === true) {
21431
+ logger$5.warn `⚠️ Parallel accumulation is disabled. Running in sequential mode.`;
21432
+ }
21335
21433
  }
21336
21434
  /**
21337
21435
  * Returns an index that determines how many WorkReports can be processed before exceeding a given gasLimit.
@@ -21383,7 +21481,7 @@ class Accumulate {
21383
21481
  serviceExternalities: partialState,
21384
21482
  fetchExternalities,
21385
21483
  };
21386
- const executor = await PvmExecutor.createAccumulateExecutor(serviceId, code, externalities, this.chainSpec, this.pvm);
21484
+ const executor = await PvmExecutor.createAccumulateExecutor(serviceId, code, externalities, this.chainSpec, this.options.pvm);
21387
21485
  const invocationArgs = Encoder.encodeObject(ARGS_CODEC$1, {
21388
21486
  slot,
21389
21487
  serviceId,
@@ -21600,6 +21698,9 @@ class Accumulate {
21600
21698
  ];
21601
21699
  return resultEntry;
21602
21700
  });
21701
+ if (this.options.accumulateSequentially === true) {
21702
+ await promise;
21703
+ }
21603
21704
  resultPromises[serviceIndex] = promise;
21604
21705
  }
21605
21706
  return Promise.all(resultPromises).then((results) => new Map(results));
@@ -21908,7 +22009,7 @@ class BlockVerifier {
21908
22009
  }
21909
22010
  }
21910
22011
  // Check if extrinsic is valid.
21911
- // https://graypaper.fluffylabs.dev/#/cc517d7/0cba000cba00?v=0.6.5
22012
+ // https://graypaper.fluffylabs.dev/#/ab2cdbd/0cba000cba00?v=0.7.2
21912
22013
  const extrinsicHash = headerView.extrinsicHash.materialize();
21913
22014
  const extrinsicMerkleCommitment = this.hasher.extrinsic(block.extrinsic.view());
21914
22015
  if (!extrinsicHash.isEqualTo(extrinsicMerkleCommitment.hash)) {
@@ -23234,59 +23335,6 @@ class RecentHistory {
23234
23335
  }
23235
23336
  }
23236
23337
 
23237
- /** Error that may happen during reports processing. */
23238
- var ReportsError;
23239
- (function (ReportsError) {
23240
- /** Core index is greater than the number of available cores. */
23241
- ReportsError[ReportsError["BadCoreIndex"] = 0] = "BadCoreIndex";
23242
- /** The report slot is greater than the current block slot. */
23243
- ReportsError[ReportsError["FutureReportSlot"] = 1] = "FutureReportSlot";
23244
- /** Report is too old to be considered. */
23245
- ReportsError[ReportsError["ReportEpochBeforeLast"] = 2] = "ReportEpochBeforeLast";
23246
- /** Not enough credentials for the guarantee. */
23247
- ReportsError[ReportsError["InsufficientGuarantees"] = 3] = "InsufficientGuarantees";
23248
- /** Guarantees are not ordered by the core index. */
23249
- ReportsError[ReportsError["OutOfOrderGuarantee"] = 4] = "OutOfOrderGuarantee";
23250
- /** Credentials of guarantors are not sorted or unique. */
23251
- ReportsError[ReportsError["NotSortedOrUniqueGuarantors"] = 5] = "NotSortedOrUniqueGuarantors";
23252
- /** Validator in credentials is assigned to a different core. */
23253
- ReportsError[ReportsError["WrongAssignment"] = 6] = "WrongAssignment";
23254
- /** There is a report pending availability on that core already. */
23255
- ReportsError[ReportsError["CoreEngaged"] = 7] = "CoreEngaged";
23256
- /** Anchor block is not found in recent blocks. */
23257
- ReportsError[ReportsError["AnchorNotRecent"] = 8] = "AnchorNotRecent";
23258
- /** Service not foubd. */
23259
- ReportsError[ReportsError["BadServiceId"] = 9] = "BadServiceId";
23260
- /** Service code hash does not match the current one. */
23261
- ReportsError[ReportsError["BadCodeHash"] = 10] = "BadCodeHash";
23262
- /** Pre-requisite work package is missing in either recent blocks or lookup extrinsic. */
23263
- ReportsError[ReportsError["DependencyMissing"] = 11] = "DependencyMissing";
23264
- /** Results for the same package are in more than one report. */
23265
- ReportsError[ReportsError["DuplicatePackage"] = 12] = "DuplicatePackage";
23266
- /** Anchor block declared state root does not match the one we have in recent blocks. */
23267
- ReportsError[ReportsError["BadStateRoot"] = 13] = "BadStateRoot";
23268
- /** BEEFY super hash mmr mismatch. */
23269
- ReportsError[ReportsError["BadBeefyMmrRoot"] = 14] = "BadBeefyMmrRoot";
23270
- /** The authorization hash is not found in the authorization pool. */
23271
- ReportsError[ReportsError["CoreUnauthorized"] = 15] = "CoreUnauthorized";
23272
- /** Validator index is greater than the number of validators. */
23273
- ReportsError[ReportsError["BadValidatorIndex"] = 16] = "BadValidatorIndex";
23274
- /** Total gas of work report is too high. */
23275
- ReportsError[ReportsError["WorkReportGasTooHigh"] = 17] = "WorkReportGasTooHigh";
23276
- /** Work item has is smaller than required minimal accumulation gas of a service. */
23277
- ReportsError[ReportsError["ServiceItemGasTooLow"] = 18] = "ServiceItemGasTooLow";
23278
- /** The report has too many dependencies (prerequisites and/or segment-root lookups). */
23279
- ReportsError[ReportsError["TooManyDependencies"] = 19] = "TooManyDependencies";
23280
- /** Segment root lookup block has invalid time slot or is not found in the header chain. */
23281
- ReportsError[ReportsError["SegmentRootLookupInvalid"] = 20] = "SegmentRootLookupInvalid";
23282
- /** Signature in credentials is invalid. */
23283
- ReportsError[ReportsError["BadSignature"] = 21] = "BadSignature";
23284
- /** Size of authorizer output and all work-item successful output blobs is too big. */
23285
- ReportsError[ReportsError["WorkReportTooBig"] = 22] = "WorkReportTooBig";
23286
- /** Contains guarantee from validator that is proven to be an offender. */
23287
- ReportsError[ReportsError["BannedValidator"] = 23] = "BannedValidator";
23288
- })(ReportsError || (ReportsError = {}));
23289
-
23290
23338
  const ENTROPY_BYTES = 32;
23291
23339
  /**
23292
23340
  * Deterministic variant of the Fisher–Yates shuffle function
@@ -23335,17 +23383,17 @@ var index$5 = /*#__PURE__*/Object.freeze({
23335
23383
  * reports for it. This is borne out with V= 1023 validators
23336
23384
  * and C = 341 cores, since V/C = 3. The core index assigned to
23337
23385
  * each of the validators, as well as the validators’ Ed25519
23338
- * keys are denoted by G.
23386
+ * keys are denoted by M.
23339
23387
  *
23340
- * https://graypaper.fluffylabs.dev/#/5f542d7/147601147e01
23388
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/144c02145402?v=0.7.2
23341
23389
  */
23342
23390
  /**
23343
23391
  * Returns core assignments for each validator index.
23344
23392
  *
23345
- * https://graypaper.fluffylabs.dev/#/5f542d7/14fd0114fd01
23393
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/155300155d00?v=0.7.2
23346
23394
  */
23347
23395
  function generateCoreAssignment(spec, blake2b,
23348
- /** https://graypaper.fluffylabs.dev/#/5f542d7/149601149601 */
23396
+ /** https://graypaper.fluffylabs.dev/#/ab2cdbd/147102147102?v=0.7.2 */
23349
23397
  eta2entropy,
23350
23398
  /** timeslot */
23351
23399
  slot) {
@@ -23355,7 +23403,7 @@ slot) {
23355
23403
  function rotationIndex(slot, rotationPeriod) {
23356
23404
  return asOpaqueType(Math.floor(slot / rotationPeriod));
23357
23405
  }
23358
- /** https://graypaper.fluffylabs.dev/#/5f542d7/14c00114c001 */
23406
+ /** https://graypaper.fluffylabs.dev/#/ab2cdbd/151900151900?v=0.7.2 */
23359
23407
  function permute(blake2b, entropy, slot, spec) {
23360
23408
  const shift = rotationIndex(tryAsTimeSlot(slot % spec.epochLength), spec.rotationPeriod);
23361
23409
  const initialAssignment = Array(spec.validatorsCount)
@@ -23370,58 +23418,14 @@ function permute(blake2b, entropy, slot, spec) {
23370
23418
  // we are sure this is PerValidator, since that's the array we create earlier.
23371
23419
  return asKnownSize(coreAssignment);
23372
23420
  }
23373
- /** https://graypaper.fluffylabs.dev/#/5f542d7/14a50114a501 */
23421
+ /** https://graypaper.fluffylabs.dev/#/ab2cdbd/148002148002?v=0.7.2 */
23374
23422
  function rotate(cores, n, noOfCores) {
23375
23423
  // modulo `noOfCores` guarantees that we're within `CoreIndex` range.
23376
23424
  return cores.map((x) => asOpaqueType((x + n) % noOfCores));
23377
23425
  }
23378
23426
 
23379
- /**
23380
- * `W_R = 48 * 2**10`: The maximum total size of all output blobs in a work-report, in octets.
23381
- *
23382
- * https://graypaper.fluffylabs.dev/#/5f542d7/41a60041aa00?v=0.6.2
23383
- */
23384
- const MAX_WORK_REPORT_SIZE_BYTES = 48 * 2 ** 10;
23385
- function verifyReportsBasic(input) {
23386
- for (const guarantee of input) {
23387
- const reportView = guarantee.view().report.view();
23388
- /**
23389
- * We limit the sum of the number of items in the
23390
- * segment-root lookup dictionary and the number of
23391
- * prerequisites to J = 8:
23392
- *
23393
- * https://graypaper.fluffylabs.dev/#/5f542d7/13ab0013ad00?v=0.6.2
23394
- */
23395
- const noOfPrerequisites = reportView.context.view().prerequisites.view().length;
23396
- const noOfSegmentRootLookups = reportView.segmentRootLookup.view().length;
23397
- if (noOfPrerequisites + noOfSegmentRootLookups > MAX_REPORT_DEPENDENCIES) {
23398
- return Result$1.error(ReportsError.TooManyDependencies, () => `Report at ${reportView.coreIndex.materialize()} has too many dependencies. Got ${noOfPrerequisites} + ${noOfSegmentRootLookups}, max: ${MAX_REPORT_DEPENDENCIES}`);
23399
- }
23400
- /**
23401
- * In order to ensure fair use of a block’s extrinsic space,
23402
- * work-reports are limited in the maximum total size of the
23403
- * successful output blobs together with the authorizer output
23404
- * blob, effectively limiting their overall size:
23405
- *
23406
- * https://graypaper.fluffylabs.dev/#/5f542d7/141d00142000?v=0.6.2
23407
- */
23408
- // adding is safe here, since the total-encoded size of the report
23409
- // is limited as well. Even though we just have a view, the size
23410
- // should have been verified earlier.
23411
- const authOutputSize = reportView.authorizationOutput.view().length;
23412
- let totalOutputsSize = 0;
23413
- for (const item of reportView.results.view()) {
23414
- totalOutputsSize += item.view().result.view().okBlob?.raw.length ?? 0;
23415
- }
23416
- if (authOutputSize + totalOutputsSize > MAX_WORK_REPORT_SIZE_BYTES) {
23417
- return Result$1.error(ReportsError.WorkReportTooBig, () => `Work report at ${reportView.coreIndex.materialize()} too big. Got ${authOutputSize} + ${totalOutputsSize}, max: ${MAX_WORK_REPORT_SIZE_BYTES}`);
23418
- }
23419
- }
23420
- return Result$1.ok(OK);
23421
- }
23422
-
23423
23427
  const logger$3 = Logger.new(undefined, "stf:reports");
23424
- /** https://graypaper.fluffylabs.dev/#/7e6ff6a/15eb0115eb01?v=0.6.7 */
23428
+ /** https://graypaper.fluffylabs.dev/#/ab2cdbd/158202158202?v=0.7.2 */
23425
23429
  function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge) {
23426
23430
  const contexts = [];
23427
23431
  // hashes of work packages reported in this extrinsic
@@ -23443,8 +23447,11 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
23443
23447
  if (service === null) {
23444
23448
  return Result$1.error(ReportsError.BadServiceId, () => `No service with id: ${result.serviceId}`);
23445
23449
  }
23446
- // check service code hash
23447
- // https://graypaper.fluffylabs.dev/#/5f542d7/154b02154b02
23450
+ /**
23451
+ * Check service code hash
23452
+ *
23453
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/150804150804?v=0.7.2
23454
+ */
23448
23455
  if (!result.codeHash.isEqualTo(service.getInfo().codeHash)) {
23449
23456
  return Result$1.error(ReportsError.BadCodeHash, () => `Service (${result.serviceId}) code hash mismatch. Got: ${result.codeHash}, expected: ${service.getInfo().codeHash}`);
23450
23457
  }
@@ -23454,7 +23461,7 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
23454
23461
  * There must be no duplicate work-package hashes (i.e.
23455
23462
  * two work-reports of the same package).
23456
23463
  *
23457
- * https://graypaper.fluffylabs.dev/#/5f542d7/151f01152101
23464
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/159c02159e02?v=0.7.2
23458
23465
  */
23459
23466
  if (currentWorkPackages.size !== input.guarantees.length) {
23460
23467
  return Result$1.error(ReportsError.DuplicatePackage, () => "Duplicate work package detected.");
@@ -23508,7 +23515,7 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
23508
23515
  }
23509
23516
  return Result$1.ok(currentWorkPackages);
23510
23517
  }
23511
- /** https://graypaper.fluffylabs.dev/#/7e6ff6a/152502152502?v=0.6.7 */
23518
+ /** https://graypaper.fluffylabs.dev/#/ab2cdbd/15cd0215cd02?v=0.7.2 */
23512
23519
  function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate, headerChain) {
23513
23520
  // TODO [ToDr] [opti] This could be cached and updated efficiently between runs.
23514
23521
  const recentBlocks = HashDictionary.new();
@@ -23519,9 +23526,9 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
23519
23526
  /**
23520
23527
  * We require that the anchor block be within the last H
23521
23528
  * blocks and that its details be correct by ensuring that it
23522
- * appears within our most recent blocks β †:
23529
+ * appears within our most recent blocks β†:
23523
23530
  *
23524
- * https://graypaper.fluffylabs.dev/#/5f542d7/152801152b01
23531
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15ad0215af02?v=0.7.2
23525
23532
  */
23526
23533
  const recentBlock = recentBlocks.get(context.anchor);
23527
23534
  if (recentBlock === undefined) {
@@ -23540,7 +23547,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
23540
23547
  * We require that each lookup-anchor block be within the
23541
23548
  * last L timeslots.
23542
23549
  *
23543
- * https://graypaper.fluffylabs.dev/#/5f542d7/154601154701
23550
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15ce0215cf02?v=0.7.2
23544
23551
  */
23545
23552
  if (context.lookupAnchorSlot < minLookupSlot) {
23546
23553
  return Result$1.error(ReportsError.SegmentRootLookupInvalid, () => `Lookup anchor slot's too old. Got: ${context.lookupAnchorSlot}, minimal: ${minLookupSlot}`);
@@ -23551,7 +23558,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
23551
23558
  * on-chain state and must be checked by virtue of retaini
23552
23559
  * ing the series of the last L headers as the ancestor set A.
23553
23560
  *
23554
- * https://graypaper.fluffylabs.dev/#/5f542d7/155c01155f01
23561
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15e40215e702?v=0.7.2
23555
23562
  */
23556
23563
  const isInChain = recentBlocks.has(context.lookupAnchor) ||
23557
23564
  headerChain.isAncestor(context.lookupAnchorSlot, context.lookupAnchor, context.anchor);
@@ -23574,7 +23581,7 @@ function verifyDependencies({ currentWorkPackages, recentlyReported, prerequisit
23574
23581
  * segment-root lookup, be either in the extrinsic or in our
23575
23582
  * recent history.
23576
23583
  *
23577
- * https://graypaper.fluffylabs.dev/#/5f542d7/15ca0115cd01
23584
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/156b03156e03?v=0.7.2
23578
23585
  */
23579
23586
  for (const preReqHash of dependencies) {
23580
23587
  if (currentWorkPackages.has(preReqHash)) {
@@ -23603,7 +23610,7 @@ function verifyWorkPackagesUniqueness(workPackageHashes, state) {
23603
23610
  /**
23604
23611
  * Make sure that the package does not appear anywhere in the pipeline.
23605
23612
  *
23606
- * https://graypaper.fluffylabs.dev/#/5f542d7/159101159101
23613
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/152803152803?v=0.7.2
23607
23614
  */
23608
23615
  // TODO [ToDr] [opti] this most likely should be cached and either
23609
23616
  // re-computed on invalidity or we could maintain additional
@@ -23644,9 +23651,9 @@ function verifyCredentials(guarantees,
23644
23651
  workReportHashes, slot, getGuarantorAssignment) {
23645
23652
  /**
23646
23653
  * Collect signatures payload for later verification
23647
- * and construct the `reporters set R` from that data.
23654
+ * and construct the `reporters set G` from that data.
23648
23655
  *
23649
- * https://graypaper.fluffylabs.dev/#/5f542d7/15cf0015cf00
23656
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/153002153002?v=0.7.2
23650
23657
  */
23651
23658
  const signaturesToVerify = [];
23652
23659
  const headerTimeSlot = slot;
@@ -23660,7 +23667,7 @@ workReportHashes, slot, getGuarantorAssignment) {
23660
23667
  * The credential is a sequence of two or three tuples of a
23661
23668
  * unique validator index and a signature.
23662
23669
  *
23663
- * https://graypaper.fluffylabs.dev/#/5f542d7/14b90214bb02
23670
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/152b01152d01?v=0.7.2
23664
23671
  */
23665
23672
  const credentialsView = guaranteeView.credentials.view();
23666
23673
  if (credentialsView.length < REQUIRED_CREDENTIALS_RANGE[0] ||
@@ -23690,7 +23697,8 @@ workReportHashes, slot, getGuarantorAssignment) {
23690
23697
  }
23691
23698
  /**
23692
23699
  * Verify core assignment.
23693
- * https://graypaper.fluffylabs.dev/#/5f542d7/14e40214e602
23700
+ *
23701
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/155201155401?v=0.7.2
23694
23702
  */
23695
23703
  if (guarantorData.core !== coreIndex) {
23696
23704
  return Result$1.error(ReportsError.WrongAssignment, () => `Invalid core assignment for validator ${validatorIndex}. Expected: ${guarantorData.core}, got: ${coreIndex}`);
@@ -23709,7 +23717,7 @@ const JAM_GUARANTEE = BytesBlob.blobFromString("jam_guarantee").raw;
23709
23717
  * The signature [...] whose message is the serialization of the hash
23710
23718
  * of the work-report.
23711
23719
  *
23712
- * https://graypaper.fluffylabs.dev/#/5f542d7/155200155200
23720
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15a20115a201?v=0.7.2
23713
23721
  */
23714
23722
  function signingPayload(hash) {
23715
23723
  return BytesBlob.blobFromParts(JAM_GUARANTEE, hash.raw);
@@ -23720,7 +23728,7 @@ function verifyReportsOrder(input, chainSpec) {
23720
23728
  * The core index of each guarantee must be unique and
23721
23729
  * guarantees must be in ascending order of this.
23722
23730
  *
23723
- * https://graypaper.fluffylabs.dev/#/5f542d7/146902146a02
23731
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15d60015d700?v=0.7.2
23724
23732
  */
23725
23733
  const noOfCores = chainSpec.coresCount;
23726
23734
  let lastCoreIndex = -1;
@@ -23749,7 +23757,7 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
23749
23757
  * No reports may be placed on cores with a report pending
23750
23758
  * availability on it.
23751
23759
  *
23752
- * https://graypaper.fluffylabs.dev/#/5f542d7/15ea0015ea00
23760
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/155002155002?v=0.7.2
23753
23761
  */
23754
23762
  if (availabilityAssignment[coreIndex] !== null) {
23755
23763
  return Result$1.error(ReportsError.CoreEngaged, () => `Report pending availability at core: ${coreIndex}`);
@@ -23759,7 +23767,7 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
23759
23767
  * in the authorizer pool of the core on which the work is
23760
23768
  * reported.
23761
23769
  *
23762
- * https://graypaper.fluffylabs.dev/#/5f542d7/15eb0015ed00
23770
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/155102155302?v=0.7.2
23763
23771
  */
23764
23772
  const authorizerHash = report.authorizerHash;
23765
23773
  const authorizerPool = authPools.get(coreIndex);
@@ -23769,10 +23777,10 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
23769
23777
  }
23770
23778
  /**
23771
23779
  * We require that the gas allotted for accumulation of each
23772
- * work item in each work-report respects its service’s
23780
+ * work-digest in each work-report respects its service’s
23773
23781
  * minimum gas requirements.
23774
23782
  *
23775
- * https://graypaper.fluffylabs.dev/#/5f542d7/15f80015fa00
23783
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/156602156802?v=0.7.2
23776
23784
  */
23777
23785
  for (const result of report.results) {
23778
23786
  const service = services(result.serviceId);
@@ -23844,10 +23852,11 @@ class Reports {
23844
23852
  /**
23845
23853
  * ρ′ - equivalent to ρ‡, except where the extrinsic replaced
23846
23854
  * an entry. In the case an entry is replaced, the new value
23847
- * includes the present time τ allowing for the value to be
23855
+ * includes the present time τ' allowing for the value to be
23848
23856
  * replaced without respect to its availability once sufficient
23849
23857
  * time has elapsed.
23850
- * https://graypaper.fluffylabs.dev/#/1c979cb/161e00165900?v=0.7.1
23858
+ *
23859
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/161e00165900?v=0.7.2
23851
23860
  */
23852
23861
  const availabilityAssignment = input.assurancesAvailAssignment.slice();
23853
23862
  for (const guarantee of input.guarantees) {
@@ -23905,7 +23914,7 @@ class Reports {
23905
23914
  * Get the guarantor assignment (both core and validator data)
23906
23915
  * depending on the rotation.
23907
23916
  *
23908
- * https://graypaper.fluffylabs.dev/#/5f542d7/158200158200
23917
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/15df0115df01?v=0.7.2
23909
23918
  */
23910
23919
  getGuarantorAssignment(headerTimeSlot, guaranteeTimeSlot, newEntropy) {
23911
23920
  const epochLength = this.chainSpec.epochLength;
@@ -23913,7 +23922,7 @@ class Reports {
23913
23922
  const headerRotation = rotationIndex(headerTimeSlot, rotationPeriod);
23914
23923
  const guaranteeRotation = rotationIndex(guaranteeTimeSlot, rotationPeriod);
23915
23924
  const minTimeSlot = Math.max(0, headerRotation - 1) * rotationPeriod;
23916
- // https://graypaper.fluffylabs.dev/#/5f542d7/155e00156900
23925
+ // https://graypaper.fluffylabs.dev/#/ab2cdbd/15980115be01?v=0.7.2
23917
23926
  if (guaranteeTimeSlot > headerTimeSlot) {
23918
23927
  return Result$1.error(ReportsError.FutureReportSlot, () => `Report slot is in future. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
23919
23928
  }
@@ -23921,7 +23930,7 @@ class Reports {
23921
23930
  return Result$1.error(ReportsError.ReportEpochBeforeLast, () => `Report slot is too old. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
23922
23931
  }
23923
23932
  // TODO [ToDr] [opti] below code needs cache.
23924
- // The `G` and `G*` sets should only be computed once per rotation.
23933
+ // The `M` and `M*` sets should only be computed once per rotation.
23925
23934
  // Default data for the current rotation
23926
23935
  let entropy = newEntropy[2];
23927
23936
  let validatorData = this.state.currentValidatorData;
@@ -23938,7 +23947,7 @@ class Reports {
23938
23947
  }
23939
23948
  }
23940
23949
  // we know which entropy, timeSlot and validatorData should be used,
23941
- // so we can compute `G` or `G*` here.
23950
+ // so we can compute `M` or `M*` here.
23942
23951
  const coreAssignment = generateCoreAssignment(this.chainSpec, this.blake2b, entropy, timeSlot);
23943
23952
  return Result$1.ok(zip(coreAssignment, validatorData, (core, validator) => ({
23944
23953
  core,
@@ -24106,22 +24115,23 @@ class Statistics {
24106
24115
  const newPreImagesSize = current[authorIndex].preImagesSize + preImagesSize;
24107
24116
  current[authorIndex].preImagesSize = tryAsU32(newPreImagesSize);
24108
24117
  /**
24109
- * * NOTE [MaSi] Please note I don't use Kappa' here. If I understand correctly we don't need it.
24110
- * Kappa' is not needed because we can use validator indexes directly from guarantees extrinsic.
24111
- * I asked a question to ensure it is true but I didn't get any response yet:
24112
- * https://github.com/w3f/jamtestvectors/pull/28#discussion_r190723700
24118
+ * Update guarantees
24113
24119
  *
24114
- * https://graypaper.fluffylabs.dev/#/1c979cb/19a00119a801?v=0.7.1
24120
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/19ea0119f201?v=0.7.2
24115
24121
  */
24116
- const incrementedGuarantors = new Set();
24117
- for (const guarantee of extrinsic.guarantees) {
24118
- for (const { validatorIndex } of guarantee.credentials) {
24119
- if (!incrementedGuarantors.has(validatorIndex)) {
24120
- const newGuaranteesCount = current[validatorIndex].guarantees + 1;
24121
- current[validatorIndex].guarantees = tryAsU32(newGuaranteesCount);
24122
- incrementedGuarantors.add(validatorIndex);
24123
- }
24122
+ const validatorKeys = input.currentValidatorData.map((v) => v.ed25519);
24123
+ for (const reporter of input.reporters) {
24124
+ const index = validatorKeys.findIndex((x) => x.isEqualTo(reporter));
24125
+ if (index === -1) {
24126
+ /**
24127
+ * it should never happen because:
24128
+ * 1. the extrinsic is verified in reports transition
24129
+ * 2. we use current validators set from safrole
24130
+ */
24131
+ continue;
24124
24132
  }
24133
+ const newGuaranteesCount = current[index].guarantees + 1;
24134
+ current[index].guarantees = tryAsU32(newGuaranteesCount);
24125
24135
  }
24126
24136
  for (const { validatorIndex } of extrinsic.assurances) {
24127
24137
  const newAssurancesCount = current[validatorIndex].assurances + 1;
@@ -24276,7 +24286,7 @@ class OnChain {
24276
24286
  // chapter 13: https://graypaper.fluffylabs.dev/#/68eaa1f/18b60118b601?v=0.6.4
24277
24287
  statistics;
24278
24288
  isReadyForNextEpoch = Promise.resolve(false);
24279
- constructor(chainSpec, state, hasher, pvm, headerChain) {
24289
+ constructor(chainSpec, state, hasher, options, headerChain) {
24280
24290
  this.chainSpec = chainSpec;
24281
24291
  this.state = state;
24282
24292
  this.hasher = hasher;
@@ -24288,9 +24298,9 @@ class OnChain {
24288
24298
  this.disputes = new Disputes(chainSpec, hasher.blake2b, state);
24289
24299
  this.reports = new Reports(chainSpec, hasher.blake2b, state, headerChain);
24290
24300
  this.assurances = new Assurances(chainSpec, state, hasher.blake2b);
24291
- this.accumulate = new Accumulate(chainSpec, hasher.blake2b, state, pvm);
24301
+ this.accumulate = new Accumulate(chainSpec, hasher.blake2b, state, options);
24292
24302
  this.accumulateOutput = new AccumulateOutput();
24293
- this.deferredTransfers = new DeferredTransfers(chainSpec, hasher.blake2b, state, pvm);
24303
+ this.deferredTransfers = new DeferredTransfers(chainSpec, hasher.blake2b, state, options.pvm);
24294
24304
  this.preimages = new Preimages(state, hasher.blake2b);
24295
24305
  this.authorization = new Authorization(chainSpec, state);
24296
24306
  }
@@ -24378,8 +24388,7 @@ class OnChain {
24378
24388
  if (reportsResult.isError) {
24379
24389
  return stfError(StfErrorKind.Reports, reportsResult);
24380
24390
  }
24381
- // NOTE `reporters` are unused
24382
- const { reported: workPackages, reporters: _, stateUpdate: reportsUpdate, ...reportsRest } = reportsResult.ok;
24391
+ const { reported: workPackages, reporters, stateUpdate: reportsUpdate, ...reportsRest } = reportsResult.ok;
24383
24392
  assertEmpty(reportsRest);
24384
24393
  const { availabilityAssignment: reportsAvailAssignment, ...reportsUpdateRest } = reportsUpdate;
24385
24394
  assertEmpty(reportsUpdateRest);
@@ -24393,7 +24402,7 @@ class OnChain {
24393
24402
  }
24394
24403
  const { preimages, ...preimagesRest } = preimagesResult.ok;
24395
24404
  assertEmpty(preimagesRest);
24396
- const timerAccumulate = measure(`import:accumulate (${PvmBackend[this.accumulate.pvm]})`);
24405
+ const timerAccumulate = measure(`import:accumulate (${PvmBackend[this.accumulate.options.pvm]})`);
24397
24406
  // accumulate
24398
24407
  const accumulateResult = await this.accumulate.transition({
24399
24408
  slot: timeSlot,
@@ -24453,6 +24462,8 @@ class OnChain {
24453
24462
  availableReports,
24454
24463
  accumulationStatistics,
24455
24464
  transferStatistics,
24465
+ reporters: reporters,
24466
+ currentValidatorData,
24456
24467
  });
24457
24468
  const { statistics, ...statisticsRest } = statisticsUpdate;
24458
24469
  assertEmpty(statisticsRest);
@@ -25495,7 +25506,7 @@ class Importer {
25495
25506
  throw new Error(`Unable to load best state from header hash: ${currentBestHeaderHash}.`);
25496
25507
  }
25497
25508
  this.verifier = new BlockVerifier(hasher, blocks);
25498
- this.stf = new OnChain(spec, state, hasher, pvm, DbHeaderChain.new(blocks));
25509
+ this.stf = new OnChain(spec, state, hasher, { pvm, accumulateSequentially: false }, DbHeaderChain.new(blocks));
25499
25510
  this.state = state;
25500
25511
  this.currentHash = currentBestHeaderHash;
25501
25512
  this.prepareForNextEpoch();
@@ -25641,11 +25652,11 @@ const blake2b = Blake2b.createHasher();
25641
25652
  async function createImporter(config) {
25642
25653
  const chainSpec = config.chainSpec;
25643
25654
  const db = config.openDatabase({ readonly: false });
25644
- const interpreter = config.workerParams.pvm;
25655
+ const pvm = config.workerParams.pvm;
25645
25656
  const blocks = db.getBlocksDb();
25646
25657
  const states = db.getStatesDb();
25647
25658
  const hasher = new TransitionHasher(await keccakHasher, await blake2b);
25648
- const importer = new Importer(chainSpec, interpreter, hasher, logger$1, blocks, states);
25659
+ const importer = new Importer(chainSpec, pvm, hasher, logger$1, blocks, states);
25649
25660
  return {
25650
25661
  importer,
25651
25662
  db,