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