@typeberry/lib 0.5.0-5496f08 → 0.5.0-584584e
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs +159 -154
- package/index.d.ts +20 -13
- package/index.js +159 -154
- 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 =
|
|
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/#/
|
|
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/#/
|
|
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 (
|
|
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(
|
|
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),
|
|
@@ -23240,59 +23335,6 @@ class RecentHistory {
|
|
|
23240
23335
|
}
|
|
23241
23336
|
}
|
|
23242
23337
|
|
|
23243
|
-
/** Error that may happen during reports processing. */
|
|
23244
|
-
var ReportsError;
|
|
23245
|
-
(function (ReportsError) {
|
|
23246
|
-
/** Core index is greater than the number of available cores. */
|
|
23247
|
-
ReportsError[ReportsError["BadCoreIndex"] = 0] = "BadCoreIndex";
|
|
23248
|
-
/** The report slot is greater than the current block slot. */
|
|
23249
|
-
ReportsError[ReportsError["FutureReportSlot"] = 1] = "FutureReportSlot";
|
|
23250
|
-
/** Report is too old to be considered. */
|
|
23251
|
-
ReportsError[ReportsError["ReportEpochBeforeLast"] = 2] = "ReportEpochBeforeLast";
|
|
23252
|
-
/** Not enough credentials for the guarantee. */
|
|
23253
|
-
ReportsError[ReportsError["InsufficientGuarantees"] = 3] = "InsufficientGuarantees";
|
|
23254
|
-
/** Guarantees are not ordered by the core index. */
|
|
23255
|
-
ReportsError[ReportsError["OutOfOrderGuarantee"] = 4] = "OutOfOrderGuarantee";
|
|
23256
|
-
/** Credentials of guarantors are not sorted or unique. */
|
|
23257
|
-
ReportsError[ReportsError["NotSortedOrUniqueGuarantors"] = 5] = "NotSortedOrUniqueGuarantors";
|
|
23258
|
-
/** Validator in credentials is assigned to a different core. */
|
|
23259
|
-
ReportsError[ReportsError["WrongAssignment"] = 6] = "WrongAssignment";
|
|
23260
|
-
/** There is a report pending availability on that core already. */
|
|
23261
|
-
ReportsError[ReportsError["CoreEngaged"] = 7] = "CoreEngaged";
|
|
23262
|
-
/** Anchor block is not found in recent blocks. */
|
|
23263
|
-
ReportsError[ReportsError["AnchorNotRecent"] = 8] = "AnchorNotRecent";
|
|
23264
|
-
/** Service not foubd. */
|
|
23265
|
-
ReportsError[ReportsError["BadServiceId"] = 9] = "BadServiceId";
|
|
23266
|
-
/** Service code hash does not match the current one. */
|
|
23267
|
-
ReportsError[ReportsError["BadCodeHash"] = 10] = "BadCodeHash";
|
|
23268
|
-
/** Pre-requisite work package is missing in either recent blocks or lookup extrinsic. */
|
|
23269
|
-
ReportsError[ReportsError["DependencyMissing"] = 11] = "DependencyMissing";
|
|
23270
|
-
/** Results for the same package are in more than one report. */
|
|
23271
|
-
ReportsError[ReportsError["DuplicatePackage"] = 12] = "DuplicatePackage";
|
|
23272
|
-
/** Anchor block declared state root does not match the one we have in recent blocks. */
|
|
23273
|
-
ReportsError[ReportsError["BadStateRoot"] = 13] = "BadStateRoot";
|
|
23274
|
-
/** BEEFY super hash mmr mismatch. */
|
|
23275
|
-
ReportsError[ReportsError["BadBeefyMmrRoot"] = 14] = "BadBeefyMmrRoot";
|
|
23276
|
-
/** The authorization hash is not found in the authorization pool. */
|
|
23277
|
-
ReportsError[ReportsError["CoreUnauthorized"] = 15] = "CoreUnauthorized";
|
|
23278
|
-
/** Validator index is greater than the number of validators. */
|
|
23279
|
-
ReportsError[ReportsError["BadValidatorIndex"] = 16] = "BadValidatorIndex";
|
|
23280
|
-
/** Total gas of work report is too high. */
|
|
23281
|
-
ReportsError[ReportsError["WorkReportGasTooHigh"] = 17] = "WorkReportGasTooHigh";
|
|
23282
|
-
/** Work item has is smaller than required minimal accumulation gas of a service. */
|
|
23283
|
-
ReportsError[ReportsError["ServiceItemGasTooLow"] = 18] = "ServiceItemGasTooLow";
|
|
23284
|
-
/** The report has too many dependencies (prerequisites and/or segment-root lookups). */
|
|
23285
|
-
ReportsError[ReportsError["TooManyDependencies"] = 19] = "TooManyDependencies";
|
|
23286
|
-
/** Segment root lookup block has invalid time slot or is not found in the header chain. */
|
|
23287
|
-
ReportsError[ReportsError["SegmentRootLookupInvalid"] = 20] = "SegmentRootLookupInvalid";
|
|
23288
|
-
/** Signature in credentials is invalid. */
|
|
23289
|
-
ReportsError[ReportsError["BadSignature"] = 21] = "BadSignature";
|
|
23290
|
-
/** Size of authorizer output and all work-item successful output blobs is too big. */
|
|
23291
|
-
ReportsError[ReportsError["WorkReportTooBig"] = 22] = "WorkReportTooBig";
|
|
23292
|
-
/** Contains guarantee from validator that is proven to be an offender. */
|
|
23293
|
-
ReportsError[ReportsError["BannedValidator"] = 23] = "BannedValidator";
|
|
23294
|
-
})(ReportsError || (ReportsError = {}));
|
|
23295
|
-
|
|
23296
23338
|
const ENTROPY_BYTES = 32;
|
|
23297
23339
|
/**
|
|
23298
23340
|
* Deterministic variant of the Fisher–Yates shuffle function
|
|
@@ -23341,17 +23383,17 @@ var index$5 = /*#__PURE__*/Object.freeze({
|
|
|
23341
23383
|
* reports for it. This is borne out with V= 1023 validators
|
|
23342
23384
|
* and C = 341 cores, since V/C = 3. The core index assigned to
|
|
23343
23385
|
* each of the validators, as well as the validators’ Ed25519
|
|
23344
|
-
* keys are denoted by
|
|
23386
|
+
* keys are denoted by M.
|
|
23345
23387
|
*
|
|
23346
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23388
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/144c02145402?v=0.7.2
|
|
23347
23389
|
*/
|
|
23348
23390
|
/**
|
|
23349
23391
|
* Returns core assignments for each validator index.
|
|
23350
23392
|
*
|
|
23351
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23393
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155300155d00?v=0.7.2
|
|
23352
23394
|
*/
|
|
23353
23395
|
function generateCoreAssignment(spec, blake2b,
|
|
23354
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23396
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/147102147102?v=0.7.2 */
|
|
23355
23397
|
eta2entropy,
|
|
23356
23398
|
/** timeslot */
|
|
23357
23399
|
slot) {
|
|
@@ -23361,7 +23403,7 @@ slot) {
|
|
|
23361
23403
|
function rotationIndex(slot, rotationPeriod) {
|
|
23362
23404
|
return asOpaqueType(Math.floor(slot / rotationPeriod));
|
|
23363
23405
|
}
|
|
23364
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23406
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/151900151900?v=0.7.2 */
|
|
23365
23407
|
function permute(blake2b, entropy, slot, spec) {
|
|
23366
23408
|
const shift = rotationIndex(tryAsTimeSlot(slot % spec.epochLength), spec.rotationPeriod);
|
|
23367
23409
|
const initialAssignment = Array(spec.validatorsCount)
|
|
@@ -23376,58 +23418,14 @@ function permute(blake2b, entropy, slot, spec) {
|
|
|
23376
23418
|
// we are sure this is PerValidator, since that's the array we create earlier.
|
|
23377
23419
|
return asKnownSize(coreAssignment);
|
|
23378
23420
|
}
|
|
23379
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23421
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/148002148002?v=0.7.2 */
|
|
23380
23422
|
function rotate(cores, n, noOfCores) {
|
|
23381
23423
|
// modulo `noOfCores` guarantees that we're within `CoreIndex` range.
|
|
23382
23424
|
return cores.map((x) => asOpaqueType((x + n) % noOfCores));
|
|
23383
23425
|
}
|
|
23384
23426
|
|
|
23385
|
-
/**
|
|
23386
|
-
* `W_R = 48 * 2**10`: The maximum total size of all output blobs in a work-report, in octets.
|
|
23387
|
-
*
|
|
23388
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/41a60041aa00?v=0.6.2
|
|
23389
|
-
*/
|
|
23390
|
-
const MAX_WORK_REPORT_SIZE_BYTES = 48 * 2 ** 10;
|
|
23391
|
-
function verifyReportsBasic(input) {
|
|
23392
|
-
for (const guarantee of input) {
|
|
23393
|
-
const reportView = guarantee.view().report.view();
|
|
23394
|
-
/**
|
|
23395
|
-
* We limit the sum of the number of items in the
|
|
23396
|
-
* segment-root lookup dictionary and the number of
|
|
23397
|
-
* prerequisites to J = 8:
|
|
23398
|
-
*
|
|
23399
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/13ab0013ad00?v=0.6.2
|
|
23400
|
-
*/
|
|
23401
|
-
const noOfPrerequisites = reportView.context.view().prerequisites.view().length;
|
|
23402
|
-
const noOfSegmentRootLookups = reportView.segmentRootLookup.view().length;
|
|
23403
|
-
if (noOfPrerequisites + noOfSegmentRootLookups > MAX_REPORT_DEPENDENCIES) {
|
|
23404
|
-
return Result$1.error(ReportsError.TooManyDependencies, () => `Report at ${reportView.coreIndex.materialize()} has too many dependencies. Got ${noOfPrerequisites} + ${noOfSegmentRootLookups}, max: ${MAX_REPORT_DEPENDENCIES}`);
|
|
23405
|
-
}
|
|
23406
|
-
/**
|
|
23407
|
-
* In order to ensure fair use of a block’s extrinsic space,
|
|
23408
|
-
* work-reports are limited in the maximum total size of the
|
|
23409
|
-
* successful output blobs together with the authorizer output
|
|
23410
|
-
* blob, effectively limiting their overall size:
|
|
23411
|
-
*
|
|
23412
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/141d00142000?v=0.6.2
|
|
23413
|
-
*/
|
|
23414
|
-
// adding is safe here, since the total-encoded size of the report
|
|
23415
|
-
// is limited as well. Even though we just have a view, the size
|
|
23416
|
-
// should have been verified earlier.
|
|
23417
|
-
const authOutputSize = reportView.authorizationOutput.view().length;
|
|
23418
|
-
let totalOutputsSize = 0;
|
|
23419
|
-
for (const item of reportView.results.view()) {
|
|
23420
|
-
totalOutputsSize += item.view().result.view().okBlob?.raw.length ?? 0;
|
|
23421
|
-
}
|
|
23422
|
-
if (authOutputSize + totalOutputsSize > MAX_WORK_REPORT_SIZE_BYTES) {
|
|
23423
|
-
return Result$1.error(ReportsError.WorkReportTooBig, () => `Work report at ${reportView.coreIndex.materialize()} too big. Got ${authOutputSize} + ${totalOutputsSize}, max: ${MAX_WORK_REPORT_SIZE_BYTES}`);
|
|
23424
|
-
}
|
|
23425
|
-
}
|
|
23426
|
-
return Result$1.ok(OK);
|
|
23427
|
-
}
|
|
23428
|
-
|
|
23429
23427
|
const logger$3 = Logger.new(undefined, "stf:reports");
|
|
23430
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23428
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/158202158202?v=0.7.2 */
|
|
23431
23429
|
function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge) {
|
|
23432
23430
|
const contexts = [];
|
|
23433
23431
|
// hashes of work packages reported in this extrinsic
|
|
@@ -23449,8 +23447,11 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
|
|
|
23449
23447
|
if (service === null) {
|
|
23450
23448
|
return Result$1.error(ReportsError.BadServiceId, () => `No service with id: ${result.serviceId}`);
|
|
23451
23449
|
}
|
|
23452
|
-
|
|
23453
|
-
|
|
23450
|
+
/**
|
|
23451
|
+
* Check service code hash
|
|
23452
|
+
*
|
|
23453
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/150804150804?v=0.7.2
|
|
23454
|
+
*/
|
|
23454
23455
|
if (!result.codeHash.isEqualTo(service.getInfo().codeHash)) {
|
|
23455
23456
|
return Result$1.error(ReportsError.BadCodeHash, () => `Service (${result.serviceId}) code hash mismatch. Got: ${result.codeHash}, expected: ${service.getInfo().codeHash}`);
|
|
23456
23457
|
}
|
|
@@ -23460,7 +23461,7 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
|
|
|
23460
23461
|
* There must be no duplicate work-package hashes (i.e.
|
|
23461
23462
|
* two work-reports of the same package).
|
|
23462
23463
|
*
|
|
23463
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23464
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/159c02159e02?v=0.7.2
|
|
23464
23465
|
*/
|
|
23465
23466
|
if (currentWorkPackages.size !== input.guarantees.length) {
|
|
23466
23467
|
return Result$1.error(ReportsError.DuplicatePackage, () => "Duplicate work package detected.");
|
|
@@ -23514,7 +23515,7 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
|
|
|
23514
23515
|
}
|
|
23515
23516
|
return Result$1.ok(currentWorkPackages);
|
|
23516
23517
|
}
|
|
23517
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23518
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/15cd0215cd02?v=0.7.2 */
|
|
23518
23519
|
function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate, headerChain) {
|
|
23519
23520
|
// TODO [ToDr] [opti] This could be cached and updated efficiently between runs.
|
|
23520
23521
|
const recentBlocks = HashDictionary.new();
|
|
@@ -23525,9 +23526,9 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
23525
23526
|
/**
|
|
23526
23527
|
* We require that the anchor block be within the last H
|
|
23527
23528
|
* blocks and that its details be correct by ensuring that it
|
|
23528
|
-
* appears within our most recent blocks
|
|
23529
|
+
* appears within our most recent blocks β†:
|
|
23529
23530
|
*
|
|
23530
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23531
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15ad0215af02?v=0.7.2
|
|
23531
23532
|
*/
|
|
23532
23533
|
const recentBlock = recentBlocks.get(context.anchor);
|
|
23533
23534
|
if (recentBlock === undefined) {
|
|
@@ -23546,7 +23547,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
23546
23547
|
* We require that each lookup-anchor block be within the
|
|
23547
23548
|
* last L timeslots.
|
|
23548
23549
|
*
|
|
23549
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23550
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15ce0215cf02?v=0.7.2
|
|
23550
23551
|
*/
|
|
23551
23552
|
if (context.lookupAnchorSlot < minLookupSlot) {
|
|
23552
23553
|
return Result$1.error(ReportsError.SegmentRootLookupInvalid, () => `Lookup anchor slot's too old. Got: ${context.lookupAnchorSlot}, minimal: ${minLookupSlot}`);
|
|
@@ -23557,7 +23558,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
23557
23558
|
* on-chain state and must be checked by virtue of retaini
|
|
23558
23559
|
* ing the series of the last L headers as the ancestor set A.
|
|
23559
23560
|
*
|
|
23560
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23561
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15e40215e702?v=0.7.2
|
|
23561
23562
|
*/
|
|
23562
23563
|
const isInChain = recentBlocks.has(context.lookupAnchor) ||
|
|
23563
23564
|
headerChain.isAncestor(context.lookupAnchorSlot, context.lookupAnchor, context.anchor);
|
|
@@ -23580,7 +23581,7 @@ function verifyDependencies({ currentWorkPackages, recentlyReported, prerequisit
|
|
|
23580
23581
|
* segment-root lookup, be either in the extrinsic or in our
|
|
23581
23582
|
* recent history.
|
|
23582
23583
|
*
|
|
23583
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23584
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/156b03156e03?v=0.7.2
|
|
23584
23585
|
*/
|
|
23585
23586
|
for (const preReqHash of dependencies) {
|
|
23586
23587
|
if (currentWorkPackages.has(preReqHash)) {
|
|
@@ -23609,7 +23610,7 @@ function verifyWorkPackagesUniqueness(workPackageHashes, state) {
|
|
|
23609
23610
|
/**
|
|
23610
23611
|
* Make sure that the package does not appear anywhere in the pipeline.
|
|
23611
23612
|
*
|
|
23612
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23613
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/152803152803?v=0.7.2
|
|
23613
23614
|
*/
|
|
23614
23615
|
// TODO [ToDr] [opti] this most likely should be cached and either
|
|
23615
23616
|
// re-computed on invalidity or we could maintain additional
|
|
@@ -23650,9 +23651,9 @@ function verifyCredentials(guarantees,
|
|
|
23650
23651
|
workReportHashes, slot, getGuarantorAssignment) {
|
|
23651
23652
|
/**
|
|
23652
23653
|
* Collect signatures payload for later verification
|
|
23653
|
-
* and construct the `reporters set
|
|
23654
|
+
* and construct the `reporters set G` from that data.
|
|
23654
23655
|
*
|
|
23655
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23656
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/153002153002?v=0.7.2
|
|
23656
23657
|
*/
|
|
23657
23658
|
const signaturesToVerify = [];
|
|
23658
23659
|
const headerTimeSlot = slot;
|
|
@@ -23666,7 +23667,7 @@ workReportHashes, slot, getGuarantorAssignment) {
|
|
|
23666
23667
|
* The credential is a sequence of two or three tuples of a
|
|
23667
23668
|
* unique validator index and a signature.
|
|
23668
23669
|
*
|
|
23669
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23670
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/152b01152d01?v=0.7.2
|
|
23670
23671
|
*/
|
|
23671
23672
|
const credentialsView = guaranteeView.credentials.view();
|
|
23672
23673
|
if (credentialsView.length < REQUIRED_CREDENTIALS_RANGE[0] ||
|
|
@@ -23696,7 +23697,8 @@ workReportHashes, slot, getGuarantorAssignment) {
|
|
|
23696
23697
|
}
|
|
23697
23698
|
/**
|
|
23698
23699
|
* Verify core assignment.
|
|
23699
|
-
*
|
|
23700
|
+
*
|
|
23701
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155201155401?v=0.7.2
|
|
23700
23702
|
*/
|
|
23701
23703
|
if (guarantorData.core !== coreIndex) {
|
|
23702
23704
|
return Result$1.error(ReportsError.WrongAssignment, () => `Invalid core assignment for validator ${validatorIndex}. Expected: ${guarantorData.core}, got: ${coreIndex}`);
|
|
@@ -23715,7 +23717,7 @@ const JAM_GUARANTEE = BytesBlob.blobFromString("jam_guarantee").raw;
|
|
|
23715
23717
|
* The signature [...] whose message is the serialization of the hash
|
|
23716
23718
|
* of the work-report.
|
|
23717
23719
|
*
|
|
23718
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23720
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15a20115a201?v=0.7.2
|
|
23719
23721
|
*/
|
|
23720
23722
|
function signingPayload(hash) {
|
|
23721
23723
|
return BytesBlob.blobFromParts(JAM_GUARANTEE, hash.raw);
|
|
@@ -23726,7 +23728,7 @@ function verifyReportsOrder(input, chainSpec) {
|
|
|
23726
23728
|
* The core index of each guarantee must be unique and
|
|
23727
23729
|
* guarantees must be in ascending order of this.
|
|
23728
23730
|
*
|
|
23729
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23731
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15d60015d700?v=0.7.2
|
|
23730
23732
|
*/
|
|
23731
23733
|
const noOfCores = chainSpec.coresCount;
|
|
23732
23734
|
let lastCoreIndex = -1;
|
|
@@ -23755,7 +23757,7 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
|
|
|
23755
23757
|
* No reports may be placed on cores with a report pending
|
|
23756
23758
|
* availability on it.
|
|
23757
23759
|
*
|
|
23758
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23760
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155002155002?v=0.7.2
|
|
23759
23761
|
*/
|
|
23760
23762
|
if (availabilityAssignment[coreIndex] !== null) {
|
|
23761
23763
|
return Result$1.error(ReportsError.CoreEngaged, () => `Report pending availability at core: ${coreIndex}`);
|
|
@@ -23765,7 +23767,7 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
|
|
|
23765
23767
|
* in the authorizer pool of the core on which the work is
|
|
23766
23768
|
* reported.
|
|
23767
23769
|
*
|
|
23768
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23770
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155102155302?v=0.7.2
|
|
23769
23771
|
*/
|
|
23770
23772
|
const authorizerHash = report.authorizerHash;
|
|
23771
23773
|
const authorizerPool = authPools.get(coreIndex);
|
|
@@ -23775,10 +23777,10 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
|
|
|
23775
23777
|
}
|
|
23776
23778
|
/**
|
|
23777
23779
|
* We require that the gas allotted for accumulation of each
|
|
23778
|
-
* work
|
|
23780
|
+
* work-digest in each work-report respects its service’s
|
|
23779
23781
|
* minimum gas requirements.
|
|
23780
23782
|
*
|
|
23781
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23783
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/156602156802?v=0.7.2
|
|
23782
23784
|
*/
|
|
23783
23785
|
for (const result of report.results) {
|
|
23784
23786
|
const service = services(result.serviceId);
|
|
@@ -23850,10 +23852,11 @@ class Reports {
|
|
|
23850
23852
|
/**
|
|
23851
23853
|
* ρ′ - equivalent to ρ‡, except where the extrinsic replaced
|
|
23852
23854
|
* an entry. In the case an entry is replaced, the new value
|
|
23853
|
-
* includes the present time τ
|
|
23855
|
+
* includes the present time τ' allowing for the value to be
|
|
23854
23856
|
* replaced without respect to its availability once sufficient
|
|
23855
23857
|
* time has elapsed.
|
|
23856
|
-
*
|
|
23858
|
+
*
|
|
23859
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/161e00165900?v=0.7.2
|
|
23857
23860
|
*/
|
|
23858
23861
|
const availabilityAssignment = input.assurancesAvailAssignment.slice();
|
|
23859
23862
|
for (const guarantee of input.guarantees) {
|
|
@@ -23911,7 +23914,7 @@ class Reports {
|
|
|
23911
23914
|
* Get the guarantor assignment (both core and validator data)
|
|
23912
23915
|
* depending on the rotation.
|
|
23913
23916
|
*
|
|
23914
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23917
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15df0115df01?v=0.7.2
|
|
23915
23918
|
*/
|
|
23916
23919
|
getGuarantorAssignment(headerTimeSlot, guaranteeTimeSlot, newEntropy) {
|
|
23917
23920
|
const epochLength = this.chainSpec.epochLength;
|
|
@@ -23919,7 +23922,7 @@ class Reports {
|
|
|
23919
23922
|
const headerRotation = rotationIndex(headerTimeSlot, rotationPeriod);
|
|
23920
23923
|
const guaranteeRotation = rotationIndex(guaranteeTimeSlot, rotationPeriod);
|
|
23921
23924
|
const minTimeSlot = Math.max(0, headerRotation - 1) * rotationPeriod;
|
|
23922
|
-
// https://graypaper.fluffylabs.dev/#/
|
|
23925
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/15980115be01?v=0.7.2
|
|
23923
23926
|
if (guaranteeTimeSlot > headerTimeSlot) {
|
|
23924
23927
|
return Result$1.error(ReportsError.FutureReportSlot, () => `Report slot is in future. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
23925
23928
|
}
|
|
@@ -23927,7 +23930,7 @@ class Reports {
|
|
|
23927
23930
|
return Result$1.error(ReportsError.ReportEpochBeforeLast, () => `Report slot is too old. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
23928
23931
|
}
|
|
23929
23932
|
// TODO [ToDr] [opti] below code needs cache.
|
|
23930
|
-
// The `
|
|
23933
|
+
// The `M` and `M*` sets should only be computed once per rotation.
|
|
23931
23934
|
// Default data for the current rotation
|
|
23932
23935
|
let entropy = newEntropy[2];
|
|
23933
23936
|
let validatorData = this.state.currentValidatorData;
|
|
@@ -23944,7 +23947,7 @@ class Reports {
|
|
|
23944
23947
|
}
|
|
23945
23948
|
}
|
|
23946
23949
|
// we know which entropy, timeSlot and validatorData should be used,
|
|
23947
|
-
// so we can compute `
|
|
23950
|
+
// so we can compute `M` or `M*` here.
|
|
23948
23951
|
const coreAssignment = generateCoreAssignment(this.chainSpec, this.blake2b, entropy, timeSlot);
|
|
23949
23952
|
return Result$1.ok(zip(coreAssignment, validatorData, (core, validator) => ({
|
|
23950
23953
|
core,
|
|
@@ -24112,22 +24115,23 @@ class Statistics {
|
|
|
24112
24115
|
const newPreImagesSize = current[authorIndex].preImagesSize + preImagesSize;
|
|
24113
24116
|
current[authorIndex].preImagesSize = tryAsU32(newPreImagesSize);
|
|
24114
24117
|
/**
|
|
24115
|
-
*
|
|
24116
|
-
* Kappa' is not needed because we can use validator indexes directly from guarantees extrinsic.
|
|
24117
|
-
* I asked a question to ensure it is true but I didn't get any response yet:
|
|
24118
|
-
* https://github.com/w3f/jamtestvectors/pull/28#discussion_r190723700
|
|
24118
|
+
* Update guarantees
|
|
24119
24119
|
*
|
|
24120
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
24120
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/19ea0119f201?v=0.7.2
|
|
24121
24121
|
*/
|
|
24122
|
-
const
|
|
24123
|
-
for (const
|
|
24124
|
-
|
|
24125
|
-
|
|
24126
|
-
|
|
24127
|
-
|
|
24128
|
-
|
|
24129
|
-
|
|
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;
|
|
24130
24132
|
}
|
|
24133
|
+
const newGuaranteesCount = current[index].guarantees + 1;
|
|
24134
|
+
current[index].guarantees = tryAsU32(newGuaranteesCount);
|
|
24131
24135
|
}
|
|
24132
24136
|
for (const { validatorIndex } of extrinsic.assurances) {
|
|
24133
24137
|
const newAssurancesCount = current[validatorIndex].assurances + 1;
|
|
@@ -24384,8 +24388,7 @@ class OnChain {
|
|
|
24384
24388
|
if (reportsResult.isError) {
|
|
24385
24389
|
return stfError(StfErrorKind.Reports, reportsResult);
|
|
24386
24390
|
}
|
|
24387
|
-
|
|
24388
|
-
const { reported: workPackages, reporters: _, stateUpdate: reportsUpdate, ...reportsRest } = reportsResult.ok;
|
|
24391
|
+
const { reported: workPackages, reporters, stateUpdate: reportsUpdate, ...reportsRest } = reportsResult.ok;
|
|
24389
24392
|
assertEmpty(reportsRest);
|
|
24390
24393
|
const { availabilityAssignment: reportsAvailAssignment, ...reportsUpdateRest } = reportsUpdate;
|
|
24391
24394
|
assertEmpty(reportsUpdateRest);
|
|
@@ -24459,6 +24462,8 @@ class OnChain {
|
|
|
24459
24462
|
availableReports,
|
|
24460
24463
|
accumulationStatistics,
|
|
24461
24464
|
transferStatistics,
|
|
24465
|
+
reporters: reporters,
|
|
24466
|
+
currentValidatorData,
|
|
24462
24467
|
});
|
|
24463
24468
|
const { statistics, ...statisticsRest } = statisticsUpdate;
|
|
24464
24469
|
assertEmpty(statisticsRest);
|
package/index.d.ts
CHANGED
|
@@ -3603,7 +3603,7 @@ declare namespace workReport {
|
|
|
3603
3603
|
* Since GP defines that value explicitly as "two or three",
|
|
3604
3604
|
* we do that as well.
|
|
3605
3605
|
*
|
|
3606
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
3606
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/152b01152d01?v=0.7.2
|
|
3607
3607
|
*/
|
|
3608
3608
|
type REQUIRED_CREDENTIALS = 2 | 3;
|
|
3609
3609
|
declare const REQUIRED_CREDENTIALS_RANGE: number[];
|
|
@@ -3623,7 +3623,7 @@ declare class Credential extends WithDebug {
|
|
|
3623
3623
|
/**
|
|
3624
3624
|
* Tuple of work-report, a credential and it's corresponding timeslot.
|
|
3625
3625
|
*
|
|
3626
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
3626
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15df00150301?v=0.7.2
|
|
3627
3627
|
*/
|
|
3628
3628
|
declare class ReportGuarantee extends WithDebug {
|
|
3629
3629
|
/** The work-report being guaranteed. */
|
|
@@ -3635,7 +3635,7 @@ declare class ReportGuarantee extends WithDebug {
|
|
|
3635
3635
|
* validator index and a signature.
|
|
3636
3636
|
* Credentials must be ordered by their validator index.
|
|
3637
3637
|
*
|
|
3638
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
3638
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/152b01152d01?v=0.7.2
|
|
3639
3639
|
*/
|
|
3640
3640
|
readonly credentials: KnownSizeArray<Credential, `${REQUIRED_CREDENTIALS}`>;
|
|
3641
3641
|
static Codec: Descriptor<ReportGuarantee, ViewOf<ReportGuarantee, {
|
|
@@ -3694,7 +3694,7 @@ declare const GuaranteesExtrinsicBounds = "[0..CoresCount)";
|
|
|
3694
3694
|
* Each core index (within work-report) must be unique and guarantees
|
|
3695
3695
|
* must be in ascending order of this.
|
|
3696
3696
|
*
|
|
3697
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
3697
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15d10015d400?v=0.7.2
|
|
3698
3698
|
*/
|
|
3699
3699
|
type GuaranteesExtrinsic = KnownSizeArray<ReportGuarantee, typeof GuaranteesExtrinsicBounds>;
|
|
3700
3700
|
declare const guaranteesExtrinsicCodec: Descriptor<readonly ReportGuarantee[] & WithOpaque<"[0..CoresCount)">, SequenceView<ReportGuarantee, ViewOf<ReportGuarantee, {
|
|
@@ -9215,6 +9215,8 @@ type Input = {
|
|
|
9215
9215
|
* https://graypaper.fluffylabs.dev/#/cc517d7/18dd0018dd00?v=0.6.5
|
|
9216
9216
|
*/
|
|
9217
9217
|
transferStatistics: Map<ServiceId, CountAndGasUsed>;
|
|
9218
|
+
reporters: readonly Ed25519Key[];
|
|
9219
|
+
currentValidatorData: State["currentValidatorData"];
|
|
9218
9220
|
};
|
|
9219
9221
|
type CountAndGasUsed = {
|
|
9220
9222
|
count: U32;
|
|
@@ -9732,38 +9734,43 @@ interface HeaderChain {
|
|
|
9732
9734
|
* by validators).
|
|
9733
9735
|
*
|
|
9734
9736
|
* After enough assurances the work-report is considered available,
|
|
9735
|
-
* and the work
|
|
9737
|
+
* and the work-digests transform the state of their associated
|
|
9736
9738
|
* service by virtue of accumulation, covered in section 12.
|
|
9737
9739
|
* The report may also be timed-out, implying it may be replaced
|
|
9738
9740
|
* by another report without accumulation.
|
|
9739
9741
|
*
|
|
9740
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
9742
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/138801138d01?v=0.7.2
|
|
9741
9743
|
*/
|
|
9742
9744
|
type ReportsInput = {
|
|
9743
9745
|
/**
|
|
9744
9746
|
* A work-package, is transformed by validators acting as
|
|
9745
9747
|
* guarantors into its corresponding work-report, which
|
|
9746
|
-
* similarly comprises several work
|
|
9748
|
+
* similarly comprises several work-digests and then
|
|
9747
9749
|
* presented on-chain within the guarantees extrinsic.
|
|
9748
9750
|
*
|
|
9749
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
9751
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/138001138401?v=0.7.2
|
|
9750
9752
|
*/
|
|
9751
9753
|
guarantees: GuaranteesExtrinsicView;
|
|
9752
9754
|
/** Current time slot, excerpted from block header. */
|
|
9753
9755
|
slot: TimeSlot;
|
|
9754
9756
|
/** `eta_prime`: New entropy, after potential epoch transition. */
|
|
9755
9757
|
newEntropy: SafroleStateUpdate["entropy"];
|
|
9756
|
-
/**
|
|
9758
|
+
/**
|
|
9759
|
+
* β† - Partial update of recent blocks.
|
|
9760
|
+
*
|
|
9761
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/0f56020f6b02?v=0.7.2
|
|
9762
|
+
*/
|
|
9757
9763
|
recentBlocksPartialUpdate: RecentHistoryStateUpdate["recentBlocks"];
|
|
9758
9764
|
/**
|
|
9759
9765
|
* ρ‡ - Availability assignment resulting from assurances transition
|
|
9760
|
-
*
|
|
9766
|
+
*
|
|
9767
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/141302144402?v=0.7.2
|
|
9761
9768
|
*/
|
|
9762
9769
|
assurancesAvailAssignment: AssurancesStateUpdate["availabilityAssignment"];
|
|
9763
9770
|
/**
|
|
9764
9771
|
* ψ′O - Ed25519 keys of validators that were proven to judge incorrectly.
|
|
9765
9772
|
*
|
|
9766
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
9773
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/134201134201?v=0.7.2
|
|
9767
9774
|
*/
|
|
9768
9775
|
offenders: HashSet<Ed25519Key>;
|
|
9769
9776
|
};
|
|
@@ -9785,7 +9792,7 @@ type ReportsOutput = {
|
|
|
9785
9792
|
* This dictionary has the same number of items as in the input guarantees extrinsic.
|
|
9786
9793
|
*/
|
|
9787
9794
|
reported: HashDictionary<WorkPackageHash, WorkPackageInfo>;
|
|
9788
|
-
/** A set `
|
|
9795
|
+
/** A set `M` of work package reporters. */
|
|
9789
9796
|
reporters: KnownSizeArray<Ed25519Key, "Guarantees * Credentials (at most `cores*3`)">;
|
|
9790
9797
|
};
|
|
9791
9798
|
declare class Reports {
|
|
@@ -9804,7 +9811,7 @@ declare class Reports {
|
|
|
9804
9811
|
* Get the guarantor assignment (both core and validator data)
|
|
9805
9812
|
* depending on the rotation.
|
|
9806
9813
|
*
|
|
9807
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
9814
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15df0115df01?v=0.7.2
|
|
9808
9815
|
*/
|
|
9809
9816
|
getGuarantorAssignment(headerTimeSlot: TimeSlot, guaranteeTimeSlot: TimeSlot, newEntropy: SafroleStateUpdate["entropy"]): Result<PerValidator<GuarantorAssignment>, ReportsError>;
|
|
9810
9817
|
}
|
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 =
|
|
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/#/
|
|
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/#/
|
|
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 (
|
|
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(
|
|
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),
|
|
@@ -23237,59 +23332,6 @@ class RecentHistory {
|
|
|
23237
23332
|
}
|
|
23238
23333
|
}
|
|
23239
23334
|
|
|
23240
|
-
/** Error that may happen during reports processing. */
|
|
23241
|
-
var ReportsError;
|
|
23242
|
-
(function (ReportsError) {
|
|
23243
|
-
/** Core index is greater than the number of available cores. */
|
|
23244
|
-
ReportsError[ReportsError["BadCoreIndex"] = 0] = "BadCoreIndex";
|
|
23245
|
-
/** The report slot is greater than the current block slot. */
|
|
23246
|
-
ReportsError[ReportsError["FutureReportSlot"] = 1] = "FutureReportSlot";
|
|
23247
|
-
/** Report is too old to be considered. */
|
|
23248
|
-
ReportsError[ReportsError["ReportEpochBeforeLast"] = 2] = "ReportEpochBeforeLast";
|
|
23249
|
-
/** Not enough credentials for the guarantee. */
|
|
23250
|
-
ReportsError[ReportsError["InsufficientGuarantees"] = 3] = "InsufficientGuarantees";
|
|
23251
|
-
/** Guarantees are not ordered by the core index. */
|
|
23252
|
-
ReportsError[ReportsError["OutOfOrderGuarantee"] = 4] = "OutOfOrderGuarantee";
|
|
23253
|
-
/** Credentials of guarantors are not sorted or unique. */
|
|
23254
|
-
ReportsError[ReportsError["NotSortedOrUniqueGuarantors"] = 5] = "NotSortedOrUniqueGuarantors";
|
|
23255
|
-
/** Validator in credentials is assigned to a different core. */
|
|
23256
|
-
ReportsError[ReportsError["WrongAssignment"] = 6] = "WrongAssignment";
|
|
23257
|
-
/** There is a report pending availability on that core already. */
|
|
23258
|
-
ReportsError[ReportsError["CoreEngaged"] = 7] = "CoreEngaged";
|
|
23259
|
-
/** Anchor block is not found in recent blocks. */
|
|
23260
|
-
ReportsError[ReportsError["AnchorNotRecent"] = 8] = "AnchorNotRecent";
|
|
23261
|
-
/** Service not foubd. */
|
|
23262
|
-
ReportsError[ReportsError["BadServiceId"] = 9] = "BadServiceId";
|
|
23263
|
-
/** Service code hash does not match the current one. */
|
|
23264
|
-
ReportsError[ReportsError["BadCodeHash"] = 10] = "BadCodeHash";
|
|
23265
|
-
/** Pre-requisite work package is missing in either recent blocks or lookup extrinsic. */
|
|
23266
|
-
ReportsError[ReportsError["DependencyMissing"] = 11] = "DependencyMissing";
|
|
23267
|
-
/** Results for the same package are in more than one report. */
|
|
23268
|
-
ReportsError[ReportsError["DuplicatePackage"] = 12] = "DuplicatePackage";
|
|
23269
|
-
/** Anchor block declared state root does not match the one we have in recent blocks. */
|
|
23270
|
-
ReportsError[ReportsError["BadStateRoot"] = 13] = "BadStateRoot";
|
|
23271
|
-
/** BEEFY super hash mmr mismatch. */
|
|
23272
|
-
ReportsError[ReportsError["BadBeefyMmrRoot"] = 14] = "BadBeefyMmrRoot";
|
|
23273
|
-
/** The authorization hash is not found in the authorization pool. */
|
|
23274
|
-
ReportsError[ReportsError["CoreUnauthorized"] = 15] = "CoreUnauthorized";
|
|
23275
|
-
/** Validator index is greater than the number of validators. */
|
|
23276
|
-
ReportsError[ReportsError["BadValidatorIndex"] = 16] = "BadValidatorIndex";
|
|
23277
|
-
/** Total gas of work report is too high. */
|
|
23278
|
-
ReportsError[ReportsError["WorkReportGasTooHigh"] = 17] = "WorkReportGasTooHigh";
|
|
23279
|
-
/** Work item has is smaller than required minimal accumulation gas of a service. */
|
|
23280
|
-
ReportsError[ReportsError["ServiceItemGasTooLow"] = 18] = "ServiceItemGasTooLow";
|
|
23281
|
-
/** The report has too many dependencies (prerequisites and/or segment-root lookups). */
|
|
23282
|
-
ReportsError[ReportsError["TooManyDependencies"] = 19] = "TooManyDependencies";
|
|
23283
|
-
/** Segment root lookup block has invalid time slot or is not found in the header chain. */
|
|
23284
|
-
ReportsError[ReportsError["SegmentRootLookupInvalid"] = 20] = "SegmentRootLookupInvalid";
|
|
23285
|
-
/** Signature in credentials is invalid. */
|
|
23286
|
-
ReportsError[ReportsError["BadSignature"] = 21] = "BadSignature";
|
|
23287
|
-
/** Size of authorizer output and all work-item successful output blobs is too big. */
|
|
23288
|
-
ReportsError[ReportsError["WorkReportTooBig"] = 22] = "WorkReportTooBig";
|
|
23289
|
-
/** Contains guarantee from validator that is proven to be an offender. */
|
|
23290
|
-
ReportsError[ReportsError["BannedValidator"] = 23] = "BannedValidator";
|
|
23291
|
-
})(ReportsError || (ReportsError = {}));
|
|
23292
|
-
|
|
23293
23335
|
const ENTROPY_BYTES = 32;
|
|
23294
23336
|
/**
|
|
23295
23337
|
* Deterministic variant of the Fisher–Yates shuffle function
|
|
@@ -23338,17 +23380,17 @@ var index$5 = /*#__PURE__*/Object.freeze({
|
|
|
23338
23380
|
* reports for it. This is borne out with V= 1023 validators
|
|
23339
23381
|
* and C = 341 cores, since V/C = 3. The core index assigned to
|
|
23340
23382
|
* each of the validators, as well as the validators’ Ed25519
|
|
23341
|
-
* keys are denoted by
|
|
23383
|
+
* keys are denoted by M.
|
|
23342
23384
|
*
|
|
23343
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23385
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/144c02145402?v=0.7.2
|
|
23344
23386
|
*/
|
|
23345
23387
|
/**
|
|
23346
23388
|
* Returns core assignments for each validator index.
|
|
23347
23389
|
*
|
|
23348
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23390
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155300155d00?v=0.7.2
|
|
23349
23391
|
*/
|
|
23350
23392
|
function generateCoreAssignment(spec, blake2b,
|
|
23351
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23393
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/147102147102?v=0.7.2 */
|
|
23352
23394
|
eta2entropy,
|
|
23353
23395
|
/** timeslot */
|
|
23354
23396
|
slot) {
|
|
@@ -23358,7 +23400,7 @@ slot) {
|
|
|
23358
23400
|
function rotationIndex(slot, rotationPeriod) {
|
|
23359
23401
|
return asOpaqueType(Math.floor(slot / rotationPeriod));
|
|
23360
23402
|
}
|
|
23361
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23403
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/151900151900?v=0.7.2 */
|
|
23362
23404
|
function permute(blake2b, entropy, slot, spec) {
|
|
23363
23405
|
const shift = rotationIndex(tryAsTimeSlot(slot % spec.epochLength), spec.rotationPeriod);
|
|
23364
23406
|
const initialAssignment = Array(spec.validatorsCount)
|
|
@@ -23373,58 +23415,14 @@ function permute(blake2b, entropy, slot, spec) {
|
|
|
23373
23415
|
// we are sure this is PerValidator, since that's the array we create earlier.
|
|
23374
23416
|
return asKnownSize(coreAssignment);
|
|
23375
23417
|
}
|
|
23376
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23418
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/148002148002?v=0.7.2 */
|
|
23377
23419
|
function rotate(cores, n, noOfCores) {
|
|
23378
23420
|
// modulo `noOfCores` guarantees that we're within `CoreIndex` range.
|
|
23379
23421
|
return cores.map((x) => asOpaqueType((x + n) % noOfCores));
|
|
23380
23422
|
}
|
|
23381
23423
|
|
|
23382
|
-
/**
|
|
23383
|
-
* `W_R = 48 * 2**10`: The maximum total size of all output blobs in a work-report, in octets.
|
|
23384
|
-
*
|
|
23385
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/41a60041aa00?v=0.6.2
|
|
23386
|
-
*/
|
|
23387
|
-
const MAX_WORK_REPORT_SIZE_BYTES = 48 * 2 ** 10;
|
|
23388
|
-
function verifyReportsBasic(input) {
|
|
23389
|
-
for (const guarantee of input) {
|
|
23390
|
-
const reportView = guarantee.view().report.view();
|
|
23391
|
-
/**
|
|
23392
|
-
* We limit the sum of the number of items in the
|
|
23393
|
-
* segment-root lookup dictionary and the number of
|
|
23394
|
-
* prerequisites to J = 8:
|
|
23395
|
-
*
|
|
23396
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/13ab0013ad00?v=0.6.2
|
|
23397
|
-
*/
|
|
23398
|
-
const noOfPrerequisites = reportView.context.view().prerequisites.view().length;
|
|
23399
|
-
const noOfSegmentRootLookups = reportView.segmentRootLookup.view().length;
|
|
23400
|
-
if (noOfPrerequisites + noOfSegmentRootLookups > MAX_REPORT_DEPENDENCIES) {
|
|
23401
|
-
return Result$1.error(ReportsError.TooManyDependencies, () => `Report at ${reportView.coreIndex.materialize()} has too many dependencies. Got ${noOfPrerequisites} + ${noOfSegmentRootLookups}, max: ${MAX_REPORT_DEPENDENCIES}`);
|
|
23402
|
-
}
|
|
23403
|
-
/**
|
|
23404
|
-
* In order to ensure fair use of a block’s extrinsic space,
|
|
23405
|
-
* work-reports are limited in the maximum total size of the
|
|
23406
|
-
* successful output blobs together with the authorizer output
|
|
23407
|
-
* blob, effectively limiting their overall size:
|
|
23408
|
-
*
|
|
23409
|
-
* https://graypaper.fluffylabs.dev/#/5f542d7/141d00142000?v=0.6.2
|
|
23410
|
-
*/
|
|
23411
|
-
// adding is safe here, since the total-encoded size of the report
|
|
23412
|
-
// is limited as well. Even though we just have a view, the size
|
|
23413
|
-
// should have been verified earlier.
|
|
23414
|
-
const authOutputSize = reportView.authorizationOutput.view().length;
|
|
23415
|
-
let totalOutputsSize = 0;
|
|
23416
|
-
for (const item of reportView.results.view()) {
|
|
23417
|
-
totalOutputsSize += item.view().result.view().okBlob?.raw.length ?? 0;
|
|
23418
|
-
}
|
|
23419
|
-
if (authOutputSize + totalOutputsSize > MAX_WORK_REPORT_SIZE_BYTES) {
|
|
23420
|
-
return Result$1.error(ReportsError.WorkReportTooBig, () => `Work report at ${reportView.coreIndex.materialize()} too big. Got ${authOutputSize} + ${totalOutputsSize}, max: ${MAX_WORK_REPORT_SIZE_BYTES}`);
|
|
23421
|
-
}
|
|
23422
|
-
}
|
|
23423
|
-
return Result$1.ok(OK);
|
|
23424
|
-
}
|
|
23425
|
-
|
|
23426
23424
|
const logger$3 = Logger.new(import.meta.filename, "stf:reports");
|
|
23427
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23425
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/158202158202?v=0.7.2 */
|
|
23428
23426
|
function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge) {
|
|
23429
23427
|
const contexts = [];
|
|
23430
23428
|
// hashes of work packages reported in this extrinsic
|
|
@@ -23446,8 +23444,11 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
|
|
|
23446
23444
|
if (service === null) {
|
|
23447
23445
|
return Result$1.error(ReportsError.BadServiceId, () => `No service with id: ${result.serviceId}`);
|
|
23448
23446
|
}
|
|
23449
|
-
|
|
23450
|
-
|
|
23447
|
+
/**
|
|
23448
|
+
* Check service code hash
|
|
23449
|
+
*
|
|
23450
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/150804150804?v=0.7.2
|
|
23451
|
+
*/
|
|
23451
23452
|
if (!result.codeHash.isEqualTo(service.getInfo().codeHash)) {
|
|
23452
23453
|
return Result$1.error(ReportsError.BadCodeHash, () => `Service (${result.serviceId}) code hash mismatch. Got: ${result.codeHash}, expected: ${service.getInfo().codeHash}`);
|
|
23453
23454
|
}
|
|
@@ -23457,7 +23458,7 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
|
|
|
23457
23458
|
* There must be no duplicate work-package hashes (i.e.
|
|
23458
23459
|
* two work-reports of the same package).
|
|
23459
23460
|
*
|
|
23460
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23461
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/159c02159e02?v=0.7.2
|
|
23461
23462
|
*/
|
|
23462
23463
|
if (currentWorkPackages.size !== input.guarantees.length) {
|
|
23463
23464
|
return Result$1.error(ReportsError.DuplicatePackage, () => "Duplicate work package detected.");
|
|
@@ -23511,7 +23512,7 @@ function verifyContextualValidity(input, state, headerChain, maxLookupAnchorAge)
|
|
|
23511
23512
|
}
|
|
23512
23513
|
return Result$1.ok(currentWorkPackages);
|
|
23513
23514
|
}
|
|
23514
|
-
/** https://graypaper.fluffylabs.dev/#/
|
|
23515
|
+
/** https://graypaper.fluffylabs.dev/#/ab2cdbd/15cd0215cd02?v=0.7.2 */
|
|
23515
23516
|
function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate, headerChain) {
|
|
23516
23517
|
// TODO [ToDr] [opti] This could be cached and updated efficiently between runs.
|
|
23517
23518
|
const recentBlocks = HashDictionary.new();
|
|
@@ -23522,9 +23523,9 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
23522
23523
|
/**
|
|
23523
23524
|
* We require that the anchor block be within the last H
|
|
23524
23525
|
* blocks and that its details be correct by ensuring that it
|
|
23525
|
-
* appears within our most recent blocks
|
|
23526
|
+
* appears within our most recent blocks β†:
|
|
23526
23527
|
*
|
|
23527
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23528
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15ad0215af02?v=0.7.2
|
|
23528
23529
|
*/
|
|
23529
23530
|
const recentBlock = recentBlocks.get(context.anchor);
|
|
23530
23531
|
if (recentBlock === undefined) {
|
|
@@ -23543,7 +23544,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
23543
23544
|
* We require that each lookup-anchor block be within the
|
|
23544
23545
|
* last L timeslots.
|
|
23545
23546
|
*
|
|
23546
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23547
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15ce0215cf02?v=0.7.2
|
|
23547
23548
|
*/
|
|
23548
23549
|
if (context.lookupAnchorSlot < minLookupSlot) {
|
|
23549
23550
|
return Result$1.error(ReportsError.SegmentRootLookupInvalid, () => `Lookup anchor slot's too old. Got: ${context.lookupAnchorSlot}, minimal: ${minLookupSlot}`);
|
|
@@ -23554,7 +23555,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
23554
23555
|
* on-chain state and must be checked by virtue of retaini
|
|
23555
23556
|
* ing the series of the last L headers as the ancestor set A.
|
|
23556
23557
|
*
|
|
23557
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23558
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15e40215e702?v=0.7.2
|
|
23558
23559
|
*/
|
|
23559
23560
|
const isInChain = recentBlocks.has(context.lookupAnchor) ||
|
|
23560
23561
|
headerChain.isAncestor(context.lookupAnchorSlot, context.lookupAnchor, context.anchor);
|
|
@@ -23577,7 +23578,7 @@ function verifyDependencies({ currentWorkPackages, recentlyReported, prerequisit
|
|
|
23577
23578
|
* segment-root lookup, be either in the extrinsic or in our
|
|
23578
23579
|
* recent history.
|
|
23579
23580
|
*
|
|
23580
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23581
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/156b03156e03?v=0.7.2
|
|
23581
23582
|
*/
|
|
23582
23583
|
for (const preReqHash of dependencies) {
|
|
23583
23584
|
if (currentWorkPackages.has(preReqHash)) {
|
|
@@ -23606,7 +23607,7 @@ function verifyWorkPackagesUniqueness(workPackageHashes, state) {
|
|
|
23606
23607
|
/**
|
|
23607
23608
|
* Make sure that the package does not appear anywhere in the pipeline.
|
|
23608
23609
|
*
|
|
23609
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23610
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/152803152803?v=0.7.2
|
|
23610
23611
|
*/
|
|
23611
23612
|
// TODO [ToDr] [opti] this most likely should be cached and either
|
|
23612
23613
|
// re-computed on invalidity or we could maintain additional
|
|
@@ -23647,9 +23648,9 @@ function verifyCredentials(guarantees,
|
|
|
23647
23648
|
workReportHashes, slot, getGuarantorAssignment) {
|
|
23648
23649
|
/**
|
|
23649
23650
|
* Collect signatures payload for later verification
|
|
23650
|
-
* and construct the `reporters set
|
|
23651
|
+
* and construct the `reporters set G` from that data.
|
|
23651
23652
|
*
|
|
23652
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23653
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/153002153002?v=0.7.2
|
|
23653
23654
|
*/
|
|
23654
23655
|
const signaturesToVerify = [];
|
|
23655
23656
|
const headerTimeSlot = slot;
|
|
@@ -23663,7 +23664,7 @@ workReportHashes, slot, getGuarantorAssignment) {
|
|
|
23663
23664
|
* The credential is a sequence of two or three tuples of a
|
|
23664
23665
|
* unique validator index and a signature.
|
|
23665
23666
|
*
|
|
23666
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23667
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/152b01152d01?v=0.7.2
|
|
23667
23668
|
*/
|
|
23668
23669
|
const credentialsView = guaranteeView.credentials.view();
|
|
23669
23670
|
if (credentialsView.length < REQUIRED_CREDENTIALS_RANGE[0] ||
|
|
@@ -23693,7 +23694,8 @@ workReportHashes, slot, getGuarantorAssignment) {
|
|
|
23693
23694
|
}
|
|
23694
23695
|
/**
|
|
23695
23696
|
* Verify core assignment.
|
|
23696
|
-
*
|
|
23697
|
+
*
|
|
23698
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155201155401?v=0.7.2
|
|
23697
23699
|
*/
|
|
23698
23700
|
if (guarantorData.core !== coreIndex) {
|
|
23699
23701
|
return Result$1.error(ReportsError.WrongAssignment, () => `Invalid core assignment for validator ${validatorIndex}. Expected: ${guarantorData.core}, got: ${coreIndex}`);
|
|
@@ -23712,7 +23714,7 @@ const JAM_GUARANTEE = BytesBlob.blobFromString("jam_guarantee").raw;
|
|
|
23712
23714
|
* The signature [...] whose message is the serialization of the hash
|
|
23713
23715
|
* of the work-report.
|
|
23714
23716
|
*
|
|
23715
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23717
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15a20115a201?v=0.7.2
|
|
23716
23718
|
*/
|
|
23717
23719
|
function signingPayload(hash) {
|
|
23718
23720
|
return BytesBlob.blobFromParts(JAM_GUARANTEE, hash.raw);
|
|
@@ -23723,7 +23725,7 @@ function verifyReportsOrder(input, chainSpec) {
|
|
|
23723
23725
|
* The core index of each guarantee must be unique and
|
|
23724
23726
|
* guarantees must be in ascending order of this.
|
|
23725
23727
|
*
|
|
23726
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23728
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15d60015d700?v=0.7.2
|
|
23727
23729
|
*/
|
|
23728
23730
|
const noOfCores = chainSpec.coresCount;
|
|
23729
23731
|
let lastCoreIndex = -1;
|
|
@@ -23752,7 +23754,7 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
|
|
|
23752
23754
|
* No reports may be placed on cores with a report pending
|
|
23753
23755
|
* availability on it.
|
|
23754
23756
|
*
|
|
23755
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23757
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155002155002?v=0.7.2
|
|
23756
23758
|
*/
|
|
23757
23759
|
if (availabilityAssignment[coreIndex] !== null) {
|
|
23758
23760
|
return Result$1.error(ReportsError.CoreEngaged, () => `Report pending availability at core: ${coreIndex}`);
|
|
@@ -23762,7 +23764,7 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
|
|
|
23762
23764
|
* in the authorizer pool of the core on which the work is
|
|
23763
23765
|
* reported.
|
|
23764
23766
|
*
|
|
23765
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23767
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/155102155302?v=0.7.2
|
|
23766
23768
|
*/
|
|
23767
23769
|
const authorizerHash = report.authorizerHash;
|
|
23768
23770
|
const authorizerPool = authPools.get(coreIndex);
|
|
@@ -23772,10 +23774,10 @@ function verifyPostSignatureChecks(input, availabilityAssignment, authPools, ser
|
|
|
23772
23774
|
}
|
|
23773
23775
|
/**
|
|
23774
23776
|
* We require that the gas allotted for accumulation of each
|
|
23775
|
-
* work
|
|
23777
|
+
* work-digest in each work-report respects its service’s
|
|
23776
23778
|
* minimum gas requirements.
|
|
23777
23779
|
*
|
|
23778
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23780
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/156602156802?v=0.7.2
|
|
23779
23781
|
*/
|
|
23780
23782
|
for (const result of report.results) {
|
|
23781
23783
|
const service = services(result.serviceId);
|
|
@@ -23847,10 +23849,11 @@ class Reports {
|
|
|
23847
23849
|
/**
|
|
23848
23850
|
* ρ′ - equivalent to ρ‡, except where the extrinsic replaced
|
|
23849
23851
|
* an entry. In the case an entry is replaced, the new value
|
|
23850
|
-
* includes the present time τ
|
|
23852
|
+
* includes the present time τ' allowing for the value to be
|
|
23851
23853
|
* replaced without respect to its availability once sufficient
|
|
23852
23854
|
* time has elapsed.
|
|
23853
|
-
*
|
|
23855
|
+
*
|
|
23856
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/161e00165900?v=0.7.2
|
|
23854
23857
|
*/
|
|
23855
23858
|
const availabilityAssignment = input.assurancesAvailAssignment.slice();
|
|
23856
23859
|
for (const guarantee of input.guarantees) {
|
|
@@ -23908,7 +23911,7 @@ class Reports {
|
|
|
23908
23911
|
* Get the guarantor assignment (both core and validator data)
|
|
23909
23912
|
* depending on the rotation.
|
|
23910
23913
|
*
|
|
23911
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
23914
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/15df0115df01?v=0.7.2
|
|
23912
23915
|
*/
|
|
23913
23916
|
getGuarantorAssignment(headerTimeSlot, guaranteeTimeSlot, newEntropy) {
|
|
23914
23917
|
const epochLength = this.chainSpec.epochLength;
|
|
@@ -23916,7 +23919,7 @@ class Reports {
|
|
|
23916
23919
|
const headerRotation = rotationIndex(headerTimeSlot, rotationPeriod);
|
|
23917
23920
|
const guaranteeRotation = rotationIndex(guaranteeTimeSlot, rotationPeriod);
|
|
23918
23921
|
const minTimeSlot = Math.max(0, headerRotation - 1) * rotationPeriod;
|
|
23919
|
-
// https://graypaper.fluffylabs.dev/#/
|
|
23922
|
+
// https://graypaper.fluffylabs.dev/#/ab2cdbd/15980115be01?v=0.7.2
|
|
23920
23923
|
if (guaranteeTimeSlot > headerTimeSlot) {
|
|
23921
23924
|
return Result$1.error(ReportsError.FutureReportSlot, () => `Report slot is in future. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
23922
23925
|
}
|
|
@@ -23924,7 +23927,7 @@ class Reports {
|
|
|
23924
23927
|
return Result$1.error(ReportsError.ReportEpochBeforeLast, () => `Report slot is too old. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
23925
23928
|
}
|
|
23926
23929
|
// TODO [ToDr] [opti] below code needs cache.
|
|
23927
|
-
// The `
|
|
23930
|
+
// The `M` and `M*` sets should only be computed once per rotation.
|
|
23928
23931
|
// Default data for the current rotation
|
|
23929
23932
|
let entropy = newEntropy[2];
|
|
23930
23933
|
let validatorData = this.state.currentValidatorData;
|
|
@@ -23941,7 +23944,7 @@ class Reports {
|
|
|
23941
23944
|
}
|
|
23942
23945
|
}
|
|
23943
23946
|
// we know which entropy, timeSlot and validatorData should be used,
|
|
23944
|
-
// so we can compute `
|
|
23947
|
+
// so we can compute `M` or `M*` here.
|
|
23945
23948
|
const coreAssignment = generateCoreAssignment(this.chainSpec, this.blake2b, entropy, timeSlot);
|
|
23946
23949
|
return Result$1.ok(zip(coreAssignment, validatorData, (core, validator) => ({
|
|
23947
23950
|
core,
|
|
@@ -24109,22 +24112,23 @@ class Statistics {
|
|
|
24109
24112
|
const newPreImagesSize = current[authorIndex].preImagesSize + preImagesSize;
|
|
24110
24113
|
current[authorIndex].preImagesSize = tryAsU32(newPreImagesSize);
|
|
24111
24114
|
/**
|
|
24112
|
-
*
|
|
24113
|
-
* Kappa' is not needed because we can use validator indexes directly from guarantees extrinsic.
|
|
24114
|
-
* I asked a question to ensure it is true but I didn't get any response yet:
|
|
24115
|
-
* https://github.com/w3f/jamtestvectors/pull/28#discussion_r190723700
|
|
24115
|
+
* Update guarantees
|
|
24116
24116
|
*
|
|
24117
|
-
* https://graypaper.fluffylabs.dev/#/
|
|
24117
|
+
* https://graypaper.fluffylabs.dev/#/ab2cdbd/19ea0119f201?v=0.7.2
|
|
24118
24118
|
*/
|
|
24119
|
-
const
|
|
24120
|
-
for (const
|
|
24121
|
-
|
|
24122
|
-
|
|
24123
|
-
|
|
24124
|
-
|
|
24125
|
-
|
|
24126
|
-
|
|
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;
|
|
24127
24129
|
}
|
|
24130
|
+
const newGuaranteesCount = current[index].guarantees + 1;
|
|
24131
|
+
current[index].guarantees = tryAsU32(newGuaranteesCount);
|
|
24128
24132
|
}
|
|
24129
24133
|
for (const { validatorIndex } of extrinsic.assurances) {
|
|
24130
24134
|
const newAssurancesCount = current[validatorIndex].assurances + 1;
|
|
@@ -24381,8 +24385,7 @@ class OnChain {
|
|
|
24381
24385
|
if (reportsResult.isError) {
|
|
24382
24386
|
return stfError(StfErrorKind.Reports, reportsResult);
|
|
24383
24387
|
}
|
|
24384
|
-
|
|
24385
|
-
const { reported: workPackages, reporters: _, stateUpdate: reportsUpdate, ...reportsRest } = reportsResult.ok;
|
|
24388
|
+
const { reported: workPackages, reporters, stateUpdate: reportsUpdate, ...reportsRest } = reportsResult.ok;
|
|
24386
24389
|
assertEmpty(reportsRest);
|
|
24387
24390
|
const { availabilityAssignment: reportsAvailAssignment, ...reportsUpdateRest } = reportsUpdate;
|
|
24388
24391
|
assertEmpty(reportsUpdateRest);
|
|
@@ -24456,6 +24459,8 @@ class OnChain {
|
|
|
24456
24459
|
availableReports,
|
|
24457
24460
|
accumulationStatistics,
|
|
24458
24461
|
transferStatistics,
|
|
24462
|
+
reporters: reporters,
|
|
24463
|
+
currentValidatorData,
|
|
24459
24464
|
});
|
|
24460
24465
|
const { statistics, ...statisticsRest } = statisticsUpdate;
|
|
24461
24466
|
assertEmpty(statisticsRest);
|