@typeberry/convert 0.2.0-8017bfd → 0.2.0-adde0dd
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.js +141 -141
- package/index.js.map +1 -1
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -4544,7 +4544,7 @@ function result_resultToString(res) {
|
|
|
4544
4544
|
if (res.isOk) {
|
|
4545
4545
|
return `OK: ${typeof res.ok === "symbol" ? res.ok.toString() : res.ok}`;
|
|
4546
4546
|
}
|
|
4547
|
-
return `${res.details}\nError: ${maybeTaggedErrorToString(res.error)}`;
|
|
4547
|
+
return `${res.details()}\nError: ${maybeTaggedErrorToString(res.error)}`;
|
|
4548
4548
|
}
|
|
4549
4549
|
/** An indication of two possible outcomes returned from a function. */
|
|
4550
4550
|
const result_Result = {
|
|
@@ -4558,7 +4558,7 @@ const result_Result = {
|
|
|
4558
4558
|
};
|
|
4559
4559
|
},
|
|
4560
4560
|
/** Create new [`Result`] with `Error` status. */
|
|
4561
|
-
error: (error, details
|
|
4561
|
+
error: (error, details) => {
|
|
4562
4562
|
debug_check `${error !== undefined} 'Error' type cannot be undefined.`;
|
|
4563
4563
|
return {
|
|
4564
4564
|
isOk: false,
|
|
@@ -4677,7 +4677,7 @@ function test_deepEqual(actual, expected, { context = [], errorsCollector, ignor
|
|
|
4677
4677
|
}
|
|
4678
4678
|
if (actual.isError && expected.isError) {
|
|
4679
4679
|
test_deepEqual(actual.error, expected.error, { context: ctx.concat(["error"]), errorsCollector: errors, ignore });
|
|
4680
|
-
test_deepEqual(actual.details, expected.details, {
|
|
4680
|
+
test_deepEqual(actual.details(), expected.details(), {
|
|
4681
4681
|
context: ctx.concat(["details"]),
|
|
4682
4682
|
errorsCollector: errors,
|
|
4683
4683
|
// display details when error does not match
|
|
@@ -12938,7 +12938,7 @@ class InMemoryState extends WithDebug {
|
|
|
12938
12938
|
const { kind } = update.action;
|
|
12939
12939
|
const service = this.services.get(serviceId);
|
|
12940
12940
|
if (service === undefined) {
|
|
12941
|
-
return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update storage of non-existing service: ${serviceId}`);
|
|
12941
|
+
return result_Result.error(in_memory_state_UpdateError.NoService, () => `Attempting to update storage of non-existing service: ${serviceId}`);
|
|
12942
12942
|
}
|
|
12943
12943
|
if (kind === state_update_UpdateStorageKind.Set) {
|
|
12944
12944
|
const { key, value } = update.action.storage;
|
|
@@ -12966,14 +12966,14 @@ class InMemoryState extends WithDebug {
|
|
|
12966
12966
|
for (const [serviceId, updates] of preimagesUpdates.entries()) {
|
|
12967
12967
|
const service = this.services.get(serviceId);
|
|
12968
12968
|
if (service === undefined) {
|
|
12969
|
-
return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update preimage of non-existing service: ${serviceId}`);
|
|
12969
|
+
return result_Result.error(in_memory_state_UpdateError.NoService, () => `Attempting to update preimage of non-existing service: ${serviceId}`);
|
|
12970
12970
|
}
|
|
12971
12971
|
for (const update of updates) {
|
|
12972
12972
|
const { kind } = update.action;
|
|
12973
12973
|
if (kind === state_update_UpdatePreimageKind.Provide) {
|
|
12974
12974
|
const { preimage, slot } = update.action;
|
|
12975
12975
|
if (service.data.preimages.has(preimage.hash)) {
|
|
12976
|
-
return result_Result.error(in_memory_state_UpdateError.PreimageExists, `Overwriting existing preimage at ${serviceId}: ${preimage}`);
|
|
12976
|
+
return result_Result.error(in_memory_state_UpdateError.PreimageExists, () => `Overwriting existing preimage at ${serviceId}: ${preimage}`);
|
|
12977
12977
|
}
|
|
12978
12978
|
service.data.preimages.set(preimage.hash, preimage);
|
|
12979
12979
|
if (slot !== null) {
|
|
@@ -13024,7 +13024,7 @@ class InMemoryState extends WithDebug {
|
|
|
13024
13024
|
if (kind === state_update_UpdateServiceKind.Create) {
|
|
13025
13025
|
const { lookupHistory } = update.action;
|
|
13026
13026
|
if (this.services.has(serviceId)) {
|
|
13027
|
-
return result_Result.error(in_memory_state_UpdateError.DuplicateService, `${serviceId} already exists!`);
|
|
13027
|
+
return result_Result.error(in_memory_state_UpdateError.DuplicateService, () => `${serviceId} already exists!`);
|
|
13028
13028
|
}
|
|
13029
13029
|
this.services.set(serviceId, new InMemoryService(serviceId, {
|
|
13030
13030
|
info: account,
|
|
@@ -13036,7 +13036,7 @@ class InMemoryState extends WithDebug {
|
|
|
13036
13036
|
else if (kind === state_update_UpdateServiceKind.Update) {
|
|
13037
13037
|
const existingService = this.services.get(serviceId);
|
|
13038
13038
|
if (existingService === undefined) {
|
|
13039
|
-
return result_Result.error(in_memory_state_UpdateError.NoService, `Cannot update ${serviceId} because it does not exist.`);
|
|
13039
|
+
return result_Result.error(in_memory_state_UpdateError.NoService, () => `Cannot update ${serviceId} because it does not exist.`);
|
|
13040
13040
|
}
|
|
13041
13041
|
existingService.data.info = account;
|
|
13042
13042
|
}
|
|
@@ -15534,13 +15534,13 @@ class LeafDb {
|
|
|
15534
15534
|
*/
|
|
15535
15535
|
static fromLeavesBlob(blob, db) {
|
|
15536
15536
|
if (blob.length % TRIE_NODE_BYTES !== 0) {
|
|
15537
|
-
return Result.error(LeafDbError.InvalidLeafData, `${blob.length} is not a multiply of ${TRIE_NODE_BYTES}: ${blob}`);
|
|
15537
|
+
return Result.error(LeafDbError.InvalidLeafData, () => `${blob.length} is not a multiply of ${TRIE_NODE_BYTES}: ${blob}`);
|
|
15538
15538
|
}
|
|
15539
15539
|
const leaves = SortedSet.fromArray(leafComparator, []);
|
|
15540
15540
|
for (const nodeData of blob.chunks(TRIE_NODE_BYTES)) {
|
|
15541
15541
|
const node = new TrieNode(nodeData.raw);
|
|
15542
15542
|
if (node.getNodeType() === NodeType.Branch) {
|
|
15543
|
-
return Result.error(LeafDbError.InvalidLeafData, `Branch node detected: ${nodeData}`);
|
|
15543
|
+
return Result.error(LeafDbError.InvalidLeafData, () => `Branch node detected: ${nodeData}`);
|
|
15544
15544
|
}
|
|
15545
15545
|
leaves.insert(node.asLeafNode());
|
|
15546
15546
|
}
|
|
@@ -15761,7 +15761,7 @@ class preimages_Preimages {
|
|
|
15761
15761
|
}
|
|
15762
15762
|
if (prevPreimage.requester > currPreimage.requester ||
|
|
15763
15763
|
currPreimage.blob.compare(prevPreimage.blob).isLessOrEqual()) {
|
|
15764
|
-
return Result.error(PreimagesErrorCode.PreimagesNotSortedUnique);
|
|
15764
|
+
return Result.error(PreimagesErrorCode.PreimagesNotSortedUnique, () => `Preimages not sorted/unique at index ${i}`);
|
|
15765
15765
|
}
|
|
15766
15766
|
}
|
|
15767
15767
|
const { preimages, slot } = input;
|
|
@@ -15772,14 +15772,14 @@ class preimages_Preimages {
|
|
|
15772
15772
|
const hash = this.blake2b.hashBytes(blob).asOpaque();
|
|
15773
15773
|
const service = this.state.getService(requester);
|
|
15774
15774
|
if (service === null) {
|
|
15775
|
-
return Result.error(PreimagesErrorCode.AccountNotFound);
|
|
15775
|
+
return Result.error(PreimagesErrorCode.AccountNotFound, () => `Service not found: ${requester}`);
|
|
15776
15776
|
}
|
|
15777
15777
|
const hasPreimage = service.hasPreimage(hash);
|
|
15778
15778
|
const slots = service.getLookupHistory(hash, tryAsU32(blob.length));
|
|
15779
15779
|
// https://graypaper.fluffylabs.dev/#/5f542d7/181800181900
|
|
15780
15780
|
// https://graypaper.fluffylabs.dev/#/5f542d7/116f0011a500
|
|
15781
15781
|
if (hasPreimage || slots === null || !LookupHistoryItem.isRequested(slots)) {
|
|
15782
|
-
return Result.error(PreimagesErrorCode.PreimageUnneeded);
|
|
15782
|
+
return Result.error(PreimagesErrorCode.PreimageUnneeded, () => `Preimage unneeded: requester=${requester}, hash=${hash}, hasPreimage=${hasPreimage}, isRequested=${slots !== null && LookupHistoryItem.isRequested(slots)}`);
|
|
15783
15783
|
}
|
|
15784
15784
|
// https://graypaper.fluffylabs.dev/#/5f542d7/18c00018f300
|
|
15785
15785
|
const updates = pendingChanges.get(requester) ?? [];
|
|
@@ -15825,7 +15825,7 @@ class block_verifier_BlockVerifier {
|
|
|
15825
15825
|
const headerHash = this.hasher.header(headerView);
|
|
15826
15826
|
// check if current block is already imported
|
|
15827
15827
|
if (this.blocks.getHeader(headerHash.hash) !== null) {
|
|
15828
|
-
return Result.error(BlockVerifierError.AlreadyImported, `Block ${headerHash.hash} is already imported.`);
|
|
15828
|
+
return Result.error(BlockVerifierError.AlreadyImported, () => `Block ${headerHash.hash} is already imported.`);
|
|
15829
15829
|
}
|
|
15830
15830
|
// Check if parent block exists.
|
|
15831
15831
|
// https://graypaper.fluffylabs.dev/#/cc517d7/0c82000c8200?v=0.6.5
|
|
@@ -15835,14 +15835,14 @@ class block_verifier_BlockVerifier {
|
|
|
15835
15835
|
if (!parentHash.isEqualTo(block_verifier_ZERO_HASH)) {
|
|
15836
15836
|
const parentBlock = this.blocks.getHeader(parentHash);
|
|
15837
15837
|
if (parentBlock === null) {
|
|
15838
|
-
return Result.error(BlockVerifierError.ParentNotFound, `Parent ${parentHash.toString()} not found`);
|
|
15838
|
+
return Result.error(BlockVerifierError.ParentNotFound, () => `Parent ${parentHash.toString()} not found`);
|
|
15839
15839
|
}
|
|
15840
15840
|
// Check if the time slot index is consecutive and not from future.
|
|
15841
15841
|
// https://graypaper.fluffylabs.dev/#/cc517d7/0c02010c0201?v=0.6.5
|
|
15842
15842
|
const timeslot = headerView.timeSlotIndex.materialize();
|
|
15843
15843
|
const parentTimeslot = parentBlock.timeSlotIndex.materialize();
|
|
15844
15844
|
if (timeslot <= parentTimeslot) {
|
|
15845
|
-
return Result.error(BlockVerifierError.InvalidTimeSlot, `Invalid time slot index: ${timeslot}, expected > ${parentTimeslot}`);
|
|
15845
|
+
return Result.error(BlockVerifierError.InvalidTimeSlot, () => `Invalid time slot index: ${timeslot}, expected > ${parentTimeslot}`);
|
|
15846
15846
|
}
|
|
15847
15847
|
}
|
|
15848
15848
|
// Check if extrinsic is valid.
|
|
@@ -15850,17 +15850,17 @@ class block_verifier_BlockVerifier {
|
|
|
15850
15850
|
const extrinsicHash = headerView.extrinsicHash.materialize();
|
|
15851
15851
|
const extrinsicMerkleCommitment = this.hasher.extrinsic(block.extrinsic.view());
|
|
15852
15852
|
if (!extrinsicHash.isEqualTo(extrinsicMerkleCommitment.hash)) {
|
|
15853
|
-
return Result.error(BlockVerifierError.InvalidExtrinsic, `Invalid extrinsic hash: ${extrinsicHash.toString()}, expected ${extrinsicMerkleCommitment.hash.toString()}`);
|
|
15853
|
+
return Result.error(BlockVerifierError.InvalidExtrinsic, () => `Invalid extrinsic hash: ${extrinsicHash.toString()}, expected ${extrinsicMerkleCommitment.hash.toString()}`);
|
|
15854
15854
|
}
|
|
15855
15855
|
// Check if the state root is valid.
|
|
15856
15856
|
// https://graypaper.fluffylabs.dev/#/cc517d7/0c18010c1801?v=0.6.5
|
|
15857
15857
|
const stateRoot = headerView.priorStateRoot.materialize();
|
|
15858
15858
|
const posteriorStateRoot = this.blocks.getPostStateRoot(parentHash);
|
|
15859
15859
|
if (posteriorStateRoot === null) {
|
|
15860
|
-
return Result.error(BlockVerifierError.StateRootNotFound, `Posterior state root ${parentHash.toString()} not found`);
|
|
15860
|
+
return Result.error(BlockVerifierError.StateRootNotFound, () => `Posterior state root ${parentHash.toString()} not found`);
|
|
15861
15861
|
}
|
|
15862
15862
|
if (!stateRoot.isEqualTo(posteriorStateRoot)) {
|
|
15863
|
-
return Result.error(BlockVerifierError.InvalidStateRoot, `Invalid prior state root: ${stateRoot.toString()}, expected ${posteriorStateRoot.toString()} (ours)`);
|
|
15863
|
+
return Result.error(BlockVerifierError.InvalidStateRoot, () => `Invalid prior state root: ${stateRoot.toString()}, expected ${posteriorStateRoot.toString()} (ours)`);
|
|
15864
15864
|
}
|
|
15865
15865
|
return Result.ok(headerHash.hash);
|
|
15866
15866
|
}
|
|
@@ -15961,7 +15961,7 @@ class disputes_Disputes {
|
|
|
15961
15961
|
// check if culprits are sorted by key
|
|
15962
15962
|
// https://graypaper.fluffylabs.dev/#/579bd12/12c50112c601
|
|
15963
15963
|
if (!isUniqueSortedBy(disputes.culprits, "key")) {
|
|
15964
|
-
return Result.error(DisputesErrorCode.CulpritsNotSortedUnique);
|
|
15964
|
+
return Result.error(DisputesErrorCode.CulpritsNotSortedUnique, () => "Culprits are not uniquely sorted by key");
|
|
15965
15965
|
}
|
|
15966
15966
|
const culpritsLength = disputes.culprits.length;
|
|
15967
15967
|
for (let i = 0; i < culpritsLength; i++) {
|
|
@@ -15970,24 +15970,24 @@ class disputes_Disputes {
|
|
|
15970
15970
|
// https://graypaper.fluffylabs.dev/#/579bd12/125501125501
|
|
15971
15971
|
const isInPunishSet = this.state.disputesRecords.asDictionaries().punishSet.has(key);
|
|
15972
15972
|
if (isInPunishSet) {
|
|
15973
|
-
return Result.error(DisputesErrorCode.OffenderAlreadyReported);
|
|
15973
|
+
return Result.error(DisputesErrorCode.OffenderAlreadyReported, () => `Offender already reported: culprit ${i}, key=${key}`);
|
|
15974
15974
|
}
|
|
15975
15975
|
// check if the guarantor key is correct
|
|
15976
15976
|
// https://graypaper.fluffylabs.dev/#/85129da/125501125501?v=0.6.3
|
|
15977
15977
|
if (!allValidatorKeys.has(key)) {
|
|
15978
|
-
return Result.error(DisputesErrorCode.BadGuarantorKey);
|
|
15978
|
+
return Result.error(DisputesErrorCode.BadGuarantorKey, () => `Bad guarantor key: culprit ${i}, key=${key}`);
|
|
15979
15979
|
}
|
|
15980
15980
|
// verify if the culprit will be in new bad set
|
|
15981
15981
|
// https://graypaper.fluffylabs.dev/#/579bd12/124601124601
|
|
15982
15982
|
const isInNewBadSet = newItems.asDictionaries().badSet.has(workReportHash);
|
|
15983
15983
|
if (!isInNewBadSet) {
|
|
15984
|
-
return Result.error(DisputesErrorCode.CulpritsVerdictNotBad);
|
|
15984
|
+
return Result.error(DisputesErrorCode.CulpritsVerdictNotBad, () => `Culprit verdict not bad: culprit ${i}, work report=${workReportHash}`);
|
|
15985
15985
|
}
|
|
15986
15986
|
// verify culprit signature
|
|
15987
15987
|
// https://graypaper.fluffylabs.dev/#/579bd12/125c01125c01
|
|
15988
15988
|
const result = verificationResult.culprits[i];
|
|
15989
15989
|
if (!result?.isValid) {
|
|
15990
|
-
return Result.error(DisputesErrorCode.BadSignature, `Invalid signature for culprit: ${i}`);
|
|
15990
|
+
return Result.error(DisputesErrorCode.BadSignature, () => `Invalid signature for culprit: ${i}`);
|
|
15991
15991
|
}
|
|
15992
15992
|
}
|
|
15993
15993
|
return Result.ok(null);
|
|
@@ -15996,7 +15996,7 @@ class disputes_Disputes {
|
|
|
15996
15996
|
// check if faults are sorted by key
|
|
15997
15997
|
// https://graypaper.fluffylabs.dev/#/579bd12/12c50112c601
|
|
15998
15998
|
if (!isUniqueSortedBy(disputes.faults, "key")) {
|
|
15999
|
-
return Result.error(DisputesErrorCode.FaultsNotSortedUnique);
|
|
15999
|
+
return Result.error(DisputesErrorCode.FaultsNotSortedUnique, () => "Faults are not uniquely sorted by key");
|
|
16000
16000
|
}
|
|
16001
16001
|
const faultsLength = disputes.faults.length;
|
|
16002
16002
|
for (let i = 0; i < faultsLength; i++) {
|
|
@@ -16005,12 +16005,12 @@ class disputes_Disputes {
|
|
|
16005
16005
|
// https://graypaper.fluffylabs.dev/#/579bd12/12a20112a201
|
|
16006
16006
|
const isInPunishSet = this.state.disputesRecords.asDictionaries().punishSet.has(key);
|
|
16007
16007
|
if (isInPunishSet) {
|
|
16008
|
-
return Result.error(DisputesErrorCode.OffenderAlreadyReported);
|
|
16008
|
+
return Result.error(DisputesErrorCode.OffenderAlreadyReported, () => `Offender already reported: fault ${i}, key=${key}`);
|
|
16009
16009
|
}
|
|
16010
16010
|
// check if the auditor key is correct
|
|
16011
16011
|
// https://graypaper.fluffylabs.dev/#/85129da/12a20112a201?v=0.6.3
|
|
16012
16012
|
if (!allValidatorKeys.has(key)) {
|
|
16013
|
-
return Result.error(DisputesErrorCode.BadAuditorKey);
|
|
16013
|
+
return Result.error(DisputesErrorCode.BadAuditorKey, () => `Bad auditor key: fault ${i}, key=${key}`);
|
|
16014
16014
|
}
|
|
16015
16015
|
// verify if the fault will be included in new good/bad set
|
|
16016
16016
|
// it may be not correct as in GP there is "iff" what means it should be rather
|
|
@@ -16022,14 +16022,14 @@ class disputes_Disputes {
|
|
|
16022
16022
|
const isInNewGoodSet = goodSet.has(workReportHash);
|
|
16023
16023
|
const isInNewBadSet = badSet.has(workReportHash);
|
|
16024
16024
|
if (isInNewGoodSet || !isInNewBadSet) {
|
|
16025
|
-
return Result.error(DisputesErrorCode.FaultVerdictWrong);
|
|
16025
|
+
return Result.error(DisputesErrorCode.FaultVerdictWrong, () => `Fault verdict wrong: fault ${i}, work report=${workReportHash}, inGood=${isInNewGoodSet}, inBad=${isInNewBadSet}`);
|
|
16026
16026
|
}
|
|
16027
16027
|
}
|
|
16028
16028
|
// verify fault signature. Verification was done earlier, here we only check the result.
|
|
16029
16029
|
// https://graypaper.fluffylabs.dev/#/579bd12/12a90112a901
|
|
16030
16030
|
const result = verificationResult.faults[i];
|
|
16031
16031
|
if (!result.isValid) {
|
|
16032
|
-
return Result.error(DisputesErrorCode.BadSignature, `Invalid signature for fault: ${i}`);
|
|
16032
|
+
return Result.error(DisputesErrorCode.BadSignature, () => `Invalid signature for fault: ${i}`);
|
|
16033
16033
|
}
|
|
16034
16034
|
}
|
|
16035
16035
|
return Result.ok(null);
|
|
@@ -16038,32 +16038,32 @@ class disputes_Disputes {
|
|
|
16038
16038
|
// check if verdicts are correctly sorted
|
|
16039
16039
|
// https://graypaper.fluffylabs.dev/#/579bd12/12c40112c401
|
|
16040
16040
|
if (!isUniqueSortedBy(disputes.verdicts, "workReportHash")) {
|
|
16041
|
-
return Result.error(DisputesErrorCode.VerdictsNotSortedUnique);
|
|
16041
|
+
return Result.error(DisputesErrorCode.VerdictsNotSortedUnique, () => "Verdicts are not uniquely sorted by work report hash");
|
|
16042
16042
|
}
|
|
16043
16043
|
// check if judgement are correctly sorted
|
|
16044
16044
|
// https://graypaper.fluffylabs.dev/#/579bd12/123702123802
|
|
16045
16045
|
if (disputes.verdicts.some((verdict) => !isUniqueSortedByIndex(verdict.votes))) {
|
|
16046
|
-
return Result.error(DisputesErrorCode.JudgementsNotSortedUnique);
|
|
16046
|
+
return Result.error(DisputesErrorCode.JudgementsNotSortedUnique, () => "Judgements are not uniquely sorted by index");
|
|
16047
16047
|
}
|
|
16048
16048
|
const currentEpoch = Math.floor(this.state.timeslot / this.chainSpec.epochLength);
|
|
16049
16049
|
let voteSignatureIndex = 0;
|
|
16050
16050
|
for (const { votesEpoch, votes } of disputes.verdicts) {
|
|
16051
16051
|
// https://graypaper.fluffylabs.dev/#/579bd12/12bb0012bc00
|
|
16052
16052
|
if (votesEpoch !== currentEpoch && votesEpoch + 1 !== currentEpoch) {
|
|
16053
|
-
return Result.error(DisputesErrorCode.BadJudgementAge);
|
|
16053
|
+
return Result.error(DisputesErrorCode.BadJudgementAge, () => `Bad judgement age: epoch=${votesEpoch}, current=${currentEpoch}`);
|
|
16054
16054
|
}
|
|
16055
16055
|
const k = votesEpoch === currentEpoch ? this.state.currentValidatorData : this.state.previousValidatorData;
|
|
16056
16056
|
for (const { index } of votes) {
|
|
16057
16057
|
const key = k[index]?.ed25519;
|
|
16058
16058
|
// no particular GP fragment but I think we don't believe in ghosts
|
|
16059
16059
|
if (key === undefined) {
|
|
16060
|
-
return Result.error(DisputesErrorCode.BadValidatorIndex);
|
|
16060
|
+
return Result.error(DisputesErrorCode.BadValidatorIndex, () => `Bad validator index: ${index} in epoch ${votesEpoch}`);
|
|
16061
16061
|
}
|
|
16062
16062
|
// verify vote signature. Verification was done earlier, here we only check the result.
|
|
16063
16063
|
// https://graypaper.fluffylabs.dev/#/579bd12/12cd0012cd00
|
|
16064
16064
|
const result = verificationResult.judgements[voteSignatureIndex];
|
|
16065
16065
|
if (!result.isValid) {
|
|
16066
|
-
return Result.error(DisputesErrorCode.BadSignature, `Invalid signature for judgement: ${voteSignatureIndex}`);
|
|
16066
|
+
return Result.error(DisputesErrorCode.BadSignature, () => `Invalid signature for judgement: ${voteSignatureIndex}`);
|
|
16067
16067
|
}
|
|
16068
16068
|
voteSignatureIndex += 1;
|
|
16069
16069
|
}
|
|
@@ -16079,7 +16079,7 @@ class disputes_Disputes {
|
|
|
16079
16079
|
const isInBadSet = badSet.has(verdict.workReportHash);
|
|
16080
16080
|
const isInWonkySet = wonkySet.has(verdict.workReportHash);
|
|
16081
16081
|
if (isInGoodSet || isInBadSet || isInWonkySet) {
|
|
16082
|
-
return Result.error(DisputesErrorCode.AlreadyJudged);
|
|
16082
|
+
return Result.error(DisputesErrorCode.AlreadyJudged, () => `Work report already judged: ${verdict.workReportHash}`);
|
|
16083
16083
|
}
|
|
16084
16084
|
}
|
|
16085
16085
|
return Result.ok(null);
|
|
@@ -16110,7 +16110,7 @@ class disputes_Disputes {
|
|
|
16110
16110
|
// https://graypaper.fluffylabs.dev/#/579bd12/12f10212fc02
|
|
16111
16111
|
const f = disputes.faults.find((x) => x.workReportHash.isEqualTo(r));
|
|
16112
16112
|
if (f === undefined) {
|
|
16113
|
-
return Result.error(DisputesErrorCode.NotEnoughFaults);
|
|
16113
|
+
return Result.error(DisputesErrorCode.NotEnoughFaults, () => `Not enough faults for work report: ${r}`);
|
|
16114
16114
|
}
|
|
16115
16115
|
}
|
|
16116
16116
|
else if (sum === 0) {
|
|
@@ -16119,13 +16119,13 @@ class disputes_Disputes {
|
|
|
16119
16119
|
const c1 = disputes.culprits.find((x) => x.workReportHash.isEqualTo(r));
|
|
16120
16120
|
const c2 = disputes.culprits.findLast((x) => x.workReportHash.isEqualTo(r));
|
|
16121
16121
|
if (c1 === c2) {
|
|
16122
|
-
return Result.error(DisputesErrorCode.NotEnoughCulprits);
|
|
16122
|
+
return Result.error(DisputesErrorCode.NotEnoughCulprits, () => `Not enough culprits for work report: ${r}`);
|
|
16123
16123
|
}
|
|
16124
16124
|
}
|
|
16125
16125
|
else if (sum !== this.chainSpec.thirdOfValidators) {
|
|
16126
16126
|
// positive votes count is not correct
|
|
16127
16127
|
// https://graypaper.fluffylabs.dev/#/579bd12/125002128102
|
|
16128
|
-
return Result.error(DisputesErrorCode.BadVoteSplit);
|
|
16128
|
+
return Result.error(DisputesErrorCode.BadVoteSplit, () => `Bad vote split: sum=${sum}, expected=${this.chainSpec.thirdOfValidators} for work report ${r}`);
|
|
16129
16129
|
}
|
|
16130
16130
|
}
|
|
16131
16131
|
return Result.ok(null);
|
|
@@ -16213,7 +16213,7 @@ class disputes_Disputes {
|
|
|
16213
16213
|
const validator = k[j.index];
|
|
16214
16214
|
// no particular GP fragment but I think we don't believe in ghosts
|
|
16215
16215
|
if (validator === undefined) {
|
|
16216
|
-
return Result.error(DisputesErrorCode.BadValidatorIndex);
|
|
16216
|
+
return Result.error(DisputesErrorCode.BadValidatorIndex, () => `Bad validator index in signature verification: ${j.index}`);
|
|
16217
16217
|
}
|
|
16218
16218
|
const key = validator.ed25519;
|
|
16219
16219
|
// verify vote signature
|
|
@@ -16321,7 +16321,7 @@ const ringCommitmentCache = [];
|
|
|
16321
16321
|
async function verifySeal(bandersnatch, authorKey, signature, payload, encodedUnsealedHeader) {
|
|
16322
16322
|
const sealResult = await bandersnatch.verifySeal(authorKey.raw, signature.raw, payload.raw, encodedUnsealedHeader.raw);
|
|
16323
16323
|
if (sealResult[RESULT_INDEX] === ResultValues.Error) {
|
|
16324
|
-
return result_Result.error(null);
|
|
16324
|
+
return result_Result.error(null, () => "Bandersnatch VRF seal verification failed");
|
|
16325
16325
|
}
|
|
16326
16326
|
return result_Result.ok(bytes_Bytes.fromBlob(sealResult.subarray(1), hash_HASH_SIZE).asOpaque());
|
|
16327
16327
|
}
|
|
@@ -16347,7 +16347,7 @@ function getRingCommitment(bandersnatch, validators) {
|
|
|
16347
16347
|
async function getRingCommitmentNoCache(bandersnatch, keys) {
|
|
16348
16348
|
const commitmentResult = await bandersnatch.getRingCommitment(keys.raw);
|
|
16349
16349
|
if (commitmentResult[RESULT_INDEX] === ResultValues.Error) {
|
|
16350
|
-
return result_Result.error(null);
|
|
16350
|
+
return result_Result.error(null, () => "Bandersnatch ring commitment calculation failed");
|
|
16351
16351
|
}
|
|
16352
16352
|
return result_Result.ok(bytes_Bytes.fromBlob(commitmentResult.subarray(1), BANDERSNATCH_RING_ROOT_BYTES).asOpaque());
|
|
16353
16353
|
}
|
|
@@ -16522,7 +16522,7 @@ class safrole_Safrole {
|
|
|
16522
16522
|
epochRoot: epochRootResult.ok,
|
|
16523
16523
|
});
|
|
16524
16524
|
}
|
|
16525
|
-
return Result.error(SafroleErrorCode.IncorrectData);
|
|
16525
|
+
return Result.error(SafroleErrorCode.IncorrectData, () => "Safrole: failed to get epoch root for validator keys");
|
|
16526
16526
|
}
|
|
16527
16527
|
/**
|
|
16528
16528
|
* Ticket sequencer that is used in standard mode
|
|
@@ -16613,10 +16613,10 @@ class safrole_Safrole {
|
|
|
16613
16613
|
for (let i = 1; i < ticketsLength; i++) {
|
|
16614
16614
|
const order = tickets[i - 1].id.compare(tickets[i].id);
|
|
16615
16615
|
if (order.isEqual()) {
|
|
16616
|
-
return Result.error(SafroleErrorCode.DuplicateTicket);
|
|
16616
|
+
return Result.error(SafroleErrorCode.DuplicateTicket, () => `Safrole: duplicate ticket found at index ${i}`);
|
|
16617
16617
|
}
|
|
16618
16618
|
if (order.isGreater()) {
|
|
16619
|
-
return Result.error(SafroleErrorCode.BadTicketOrder);
|
|
16619
|
+
return Result.error(SafroleErrorCode.BadTicketOrder, () => `Safrole: bad ticket order at index ${i}`);
|
|
16620
16620
|
}
|
|
16621
16621
|
}
|
|
16622
16622
|
return Result.ok(null);
|
|
@@ -16643,7 +16643,7 @@ class safrole_Safrole {
|
|
|
16643
16643
|
attempt: ticket.attempt,
|
|
16644
16644
|
}));
|
|
16645
16645
|
if (!verificationResult.every((x) => x.isValid)) {
|
|
16646
|
-
return Result.error(SafroleErrorCode.BadTicketProof);
|
|
16646
|
+
return Result.error(SafroleErrorCode.BadTicketProof, () => "Safrole: invalid ticket proof in extrinsic");
|
|
16647
16647
|
}
|
|
16648
16648
|
/**
|
|
16649
16649
|
* Verify if tickets are sorted and unique
|
|
@@ -16652,7 +16652,7 @@ class safrole_Safrole {
|
|
|
16652
16652
|
*/
|
|
16653
16653
|
const ticketsVerifcationResult = this.verifyTickets(tickets);
|
|
16654
16654
|
if (ticketsVerifcationResult.isError) {
|
|
16655
|
-
return Result.error(ticketsVerifcationResult.error);
|
|
16655
|
+
return Result.error(ticketsVerifcationResult.error, ticketsVerifcationResult.details);
|
|
16656
16656
|
}
|
|
16657
16657
|
if (this.isEpochChanged(timeslot)) {
|
|
16658
16658
|
return Result.ok(tickets);
|
|
@@ -16661,7 +16661,7 @@ class safrole_Safrole {
|
|
|
16661
16661
|
const ticketsFromExtrinsic = SortedSet.fromSortedArray(ticketComparator, tickets);
|
|
16662
16662
|
const mergedTickets = SortedSet.fromTwoSortedCollections(ticketsFromState, ticketsFromExtrinsic);
|
|
16663
16663
|
if (ticketsFromState.length + ticketsFromExtrinsic.length !== mergedTickets.length) {
|
|
16664
|
-
return Result.error(SafroleErrorCode.DuplicateTicket);
|
|
16664
|
+
return Result.error(SafroleErrorCode.DuplicateTicket, () => "Safrole: duplicate ticket when merging state and extrinsic tickets");
|
|
16665
16665
|
}
|
|
16666
16666
|
/**
|
|
16667
16667
|
* Remove tickets if size of accumulator exceeds E (epoch length).
|
|
@@ -16730,24 +16730,24 @@ class safrole_Safrole {
|
|
|
16730
16730
|
}
|
|
16731
16731
|
async transition(input) {
|
|
16732
16732
|
if (this.state.timeslot >= input.slot) {
|
|
16733
|
-
return Result.error(SafroleErrorCode.BadSlot);
|
|
16733
|
+
return Result.error(SafroleErrorCode.BadSlot, () => `Safrole: bad slot, state timeslot ${this.state.timeslot} >= input slot ${input.slot}`);
|
|
16734
16734
|
}
|
|
16735
16735
|
if (!this.isExtrinsicLengthValid(input.slot, input.extrinsic)) {
|
|
16736
|
-
return Result.error(SafroleErrorCode.UnexpectedTicket);
|
|
16736
|
+
return Result.error(SafroleErrorCode.UnexpectedTicket, () => `Safrole: unexpected ticket, invalid extrinsic length ${input.extrinsic.length}`);
|
|
16737
16737
|
}
|
|
16738
16738
|
if (!this.areTicketAttemptsValid(input.extrinsic)) {
|
|
16739
|
-
return Result.error(SafroleErrorCode.BadTicketAttempt);
|
|
16739
|
+
return Result.error(SafroleErrorCode.BadTicketAttempt, () => "Safrole: bad ticket attempt value in extrinsic");
|
|
16740
16740
|
}
|
|
16741
16741
|
const validatorKeysResult = await this.getValidatorKeys(input.slot, input.punishSet);
|
|
16742
16742
|
if (validatorKeysResult.isError) {
|
|
16743
|
-
return Result.error(validatorKeysResult.error);
|
|
16743
|
+
return Result.error(validatorKeysResult.error, validatorKeysResult.details);
|
|
16744
16744
|
}
|
|
16745
16745
|
const { nextValidatorData, currentValidatorData, previousValidatorData, epochRoot } = validatorKeysResult.ok;
|
|
16746
16746
|
const entropy = this.getEntropy(input.slot, input.entropy);
|
|
16747
16747
|
const sealingKeySeries = this.getSlotKeySequence(input.slot, currentValidatorData, entropy[2]);
|
|
16748
16748
|
const newTicketsAccumulatorResult = await this.getNewTicketAccumulator(input.slot, input.extrinsic, this.state.nextValidatorData, epochRoot, entropy[2]);
|
|
16749
16749
|
if (newTicketsAccumulatorResult.isError) {
|
|
16750
|
-
return Result.error(newTicketsAccumulatorResult.error);
|
|
16750
|
+
return Result.error(newTicketsAccumulatorResult.error, newTicketsAccumulatorResult.details);
|
|
16751
16751
|
}
|
|
16752
16752
|
const stateUpdate = {
|
|
16753
16753
|
nextValidatorData,
|
|
@@ -16781,14 +16781,14 @@ function compareWithEncoding(chainSpec, error, actual, expected, codec) {
|
|
|
16781
16781
|
if (actual === null || expected === null) {
|
|
16782
16782
|
// if one of them is `null`, both need to be.
|
|
16783
16783
|
if (actual !== expected) {
|
|
16784
|
-
return Result.error(error, `${SafroleErrorCode[error]} Expected: ${expected}, got: ${actual}`);
|
|
16784
|
+
return Result.error(error, () => `${SafroleErrorCode[error]} Expected: ${expected}, got: ${actual}`);
|
|
16785
16785
|
}
|
|
16786
16786
|
return Result.ok(OK);
|
|
16787
16787
|
}
|
|
16788
16788
|
// compare the literal encoding.
|
|
16789
16789
|
const encoded = Encoder.encodeObject(codec, actual, chainSpec);
|
|
16790
16790
|
if (!encoded.isEqualTo(expected.encoded())) {
|
|
16791
|
-
return Result.error(error, `${SafroleErrorCode[error]} Expected: ${expected.encoded()}, got: ${encoded}`);
|
|
16791
|
+
return Result.error(error, () => `${SafroleErrorCode[error]} Expected: ${expected.encoded()}, got: ${encoded}`);
|
|
16792
16792
|
}
|
|
16793
16793
|
return Result.ok(OK);
|
|
16794
16794
|
}
|
|
@@ -16831,7 +16831,7 @@ class safrole_seal_SafroleSeal {
|
|
|
16831
16831
|
const blockAuthorKey = state.currentValidatorData.at(blockAuthorIndex)?.bandersnatch;
|
|
16832
16832
|
const entropySourceResult = await bandersnatchVrf.verifySeal(await this.bandersnatch, blockAuthorKey ?? BANDERSNATCH_ZERO_KEY, headerView.entropySource.materialize(), payload, BytesBlob.blobFromNumbers([]));
|
|
16833
16833
|
if (entropySourceResult.isError) {
|
|
16834
|
-
return Result.error(SafroleSealError.IncorrectEntropySource);
|
|
16834
|
+
return Result.error(SafroleSealError.IncorrectEntropySource, () => "Safrole: incorrect entropy source in header seal");
|
|
16835
16835
|
}
|
|
16836
16836
|
return Result.ok(entropySourceResult.ok);
|
|
16837
16837
|
}
|
|
@@ -16840,7 +16840,7 @@ class safrole_seal_SafroleSeal {
|
|
|
16840
16840
|
const validatorIndex = headerView.bandersnatchBlockAuthorIndex.materialize();
|
|
16841
16841
|
const authorKeys = state.currentValidatorData.at(validatorIndex);
|
|
16842
16842
|
if (authorKeys === undefined) {
|
|
16843
|
-
return Result.error(SafroleSealError.InvalidValidatorIndex);
|
|
16843
|
+
return Result.error(SafroleSealError.InvalidValidatorIndex, () => `Safrole: invalid validator index ${validatorIndex}`);
|
|
16844
16844
|
}
|
|
16845
16845
|
const timeSlot = headerView.timeSlotIndex.materialize();
|
|
16846
16846
|
const sealingKeys = state.sealingKeySeries;
|
|
@@ -16859,10 +16859,10 @@ class safrole_seal_SafroleSeal {
|
|
|
16859
16859
|
const authorKey = validatorData.bandersnatch;
|
|
16860
16860
|
const result = await bandersnatchVrf.verifySeal(await this.bandersnatch, authorKey ?? BANDERSNATCH_ZERO_KEY, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView));
|
|
16861
16861
|
if (result.isError) {
|
|
16862
|
-
return Result.error(SafroleSealError.IncorrectSeal);
|
|
16862
|
+
return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: incorrect seal with ticket");
|
|
16863
16863
|
}
|
|
16864
16864
|
if (ticket === undefined || !ticket.id.isEqualTo(result.ok)) {
|
|
16865
|
-
return Result.error(SafroleSealError.InvalidTicket);
|
|
16865
|
+
return Result.error(SafroleSealError.InvalidTicket, () => `Safrole: invalid ticket, expected ${ticket?.id} got ${result.ok}`);
|
|
16866
16866
|
}
|
|
16867
16867
|
return Result.ok(result.ok);
|
|
16868
16868
|
}
|
|
@@ -16872,13 +16872,13 @@ class safrole_seal_SafroleSeal {
|
|
|
16872
16872
|
const sealingKey = keys.at(index);
|
|
16873
16873
|
const authorBandersnatchKey = authorKey.bandersnatch;
|
|
16874
16874
|
if (sealingKey === undefined || !sealingKey.isEqualTo(authorBandersnatchKey)) {
|
|
16875
|
-
return Result.error(SafroleSealError.InvalidValidator, `Invalid Validator. Expected: ${sealingKey}, got: ${authorKey.bandersnatch}`);
|
|
16875
|
+
return Result.error(SafroleSealError.InvalidValidator, () => `Invalid Validator. Expected: ${sealingKey}, got: ${authorKey.bandersnatch}`);
|
|
16876
16876
|
}
|
|
16877
16877
|
// verify seal correctness
|
|
16878
16878
|
const payload = BytesBlob.blobFromParts(JAM_FALLBACK_SEAL, entropy.raw);
|
|
16879
16879
|
const result = await bandersnatchVrf.verifySeal(await this.bandersnatch, authorBandersnatchKey, headerView.seal.materialize(), payload, encodeUnsealedHeader(headerView));
|
|
16880
16880
|
if (result.isError) {
|
|
16881
|
-
return Result.error(SafroleSealError.IncorrectSeal);
|
|
16881
|
+
return Result.error(SafroleSealError.IncorrectSeal, () => "Safrole: incorrect seal with keys");
|
|
16882
16882
|
}
|
|
16883
16883
|
return Result.ok(result.ok);
|
|
16884
16884
|
}
|
|
@@ -17151,11 +17151,11 @@ class state_update_PartiallyUpdatedState {
|
|
|
17151
17151
|
const overflowBytes = !isU64(bytes);
|
|
17152
17152
|
// TODO [ToDr] this is not specified in GP, but it seems sensible.
|
|
17153
17153
|
if (overflowItems || overflowBytes) {
|
|
17154
|
-
return Result.error(InsufficientFundsError);
|
|
17154
|
+
return Result.error(InsufficientFundsError, () => `Storage utilisation overflow: items=${overflowItems}, bytes=${overflowBytes}`);
|
|
17155
17155
|
}
|
|
17156
17156
|
const thresholdBalance = ServiceAccountInfo.calculateThresholdBalance(items, bytes, serviceInfo.gratisStorage);
|
|
17157
17157
|
if (serviceInfo.balance < thresholdBalance) {
|
|
17158
|
-
return Result.error(InsufficientFundsError);
|
|
17158
|
+
return Result.error(InsufficientFundsError, () => `Service balance (${serviceInfo.balance}) below threshold (${thresholdBalance})`);
|
|
17159
17159
|
}
|
|
17160
17160
|
// Update service info with new details.
|
|
17161
17161
|
this.updateServiceInfo(serviceId, ServiceAccountInfo.create({
|
|
@@ -18544,7 +18544,7 @@ class readable_page_ReadablePage extends MemoryPage {
|
|
|
18544
18544
|
loadInto(result, startIndex, length) {
|
|
18545
18545
|
const endIndex = startIndex + length;
|
|
18546
18546
|
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
18547
|
-
return result_Result.error(errors_PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE));
|
|
18547
|
+
return result_Result.error(errors_PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
18548
18548
|
}
|
|
18549
18549
|
const bytes = this.data.subarray(startIndex, endIndex);
|
|
18550
18550
|
// we zero the bytes, since data might not yet be initialized at `endIndex`.
|
|
@@ -18553,7 +18553,7 @@ class readable_page_ReadablePage extends MemoryPage {
|
|
|
18553
18553
|
return result_Result.ok(result_OK);
|
|
18554
18554
|
}
|
|
18555
18555
|
storeFrom(_address, _data) {
|
|
18556
|
-
return result_Result.error(errors_PageFault.fromMemoryIndex(this.start, true));
|
|
18556
|
+
return result_Result.error(errors_PageFault.fromMemoryIndex(this.start, true), () => `Page fault: attempted to write to read-only page at ${this.start}`);
|
|
18557
18557
|
}
|
|
18558
18558
|
setData(pageIndex, data) {
|
|
18559
18559
|
this.data.set(data, pageIndex);
|
|
@@ -18587,7 +18587,7 @@ class writeable_page_WriteablePage extends MemoryPage {
|
|
|
18587
18587
|
loadInto(result, startIndex, length) {
|
|
18588
18588
|
const endIndex = startIndex + length;
|
|
18589
18589
|
if (endIndex > memory_consts_PAGE_SIZE) {
|
|
18590
|
-
return result_Result.error(errors_PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE));
|
|
18590
|
+
return result_Result.error(errors_PageFault.fromMemoryIndex(this.start + memory_consts_PAGE_SIZE), () => `Page fault: read beyond page boundary at ${this.start + memory_consts_PAGE_SIZE}`);
|
|
18591
18591
|
}
|
|
18592
18592
|
const bytes = this.view.subarray(startIndex, endIndex);
|
|
18593
18593
|
// we zero the bytes, since the view might not yet be initialized at `endIndex`.
|
|
@@ -18673,7 +18673,7 @@ class memory_Memory {
|
|
|
18673
18673
|
memory_logger.insane `MEM[${address}] <- ${BytesBlob.blobFrom(bytes)}`;
|
|
18674
18674
|
const pagesResult = this.getPages(address, bytes.length, AccessType.WRITE);
|
|
18675
18675
|
if (pagesResult.isError) {
|
|
18676
|
-
return Result.error(pagesResult.error);
|
|
18676
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
18677
18677
|
}
|
|
18678
18678
|
const pages = pagesResult.ok;
|
|
18679
18679
|
let currentPosition = address;
|
|
@@ -18698,14 +18698,14 @@ class memory_Memory {
|
|
|
18698
18698
|
const pages = [];
|
|
18699
18699
|
for (const pageNumber of pageRange) {
|
|
18700
18700
|
if (pageNumber < RESERVED_NUMBER_OF_PAGES) {
|
|
18701
|
-
return Result.error(PageFault.fromPageNumber(pageNumber, true));
|
|
18701
|
+
return Result.error(PageFault.fromPageNumber(pageNumber, true), () => `Page fault: attempted to access reserved page ${pageNumber}`);
|
|
18702
18702
|
}
|
|
18703
18703
|
const page = this.memory.get(pageNumber);
|
|
18704
18704
|
if (page === undefined) {
|
|
18705
|
-
return Result.error(PageFault.fromPageNumber(pageNumber));
|
|
18705
|
+
return Result.error(PageFault.fromPageNumber(pageNumber), () => `Page fault: page ${pageNumber} not allocated`);
|
|
18706
18706
|
}
|
|
18707
18707
|
if (accessType === AccessType.WRITE && !page.isWriteable()) {
|
|
18708
|
-
return Result.error(PageFault.fromPageNumber(pageNumber, true));
|
|
18708
|
+
return Result.error(PageFault.fromPageNumber(pageNumber, true), () => `Page fault: attempted to write to read-only page ${pageNumber}`);
|
|
18709
18709
|
}
|
|
18710
18710
|
pages.push(page);
|
|
18711
18711
|
}
|
|
@@ -18723,7 +18723,7 @@ class memory_Memory {
|
|
|
18723
18723
|
}
|
|
18724
18724
|
const pagesResult = this.getPages(startAddress, result.length, AccessType.READ);
|
|
18725
18725
|
if (pagesResult.isError) {
|
|
18726
|
-
return Result.error(pagesResult.error);
|
|
18726
|
+
return Result.error(pagesResult.error, pagesResult.details);
|
|
18727
18727
|
}
|
|
18728
18728
|
const pages = pagesResult.ok;
|
|
18729
18729
|
let currentPosition = startAddress;
|
|
@@ -20476,7 +20476,7 @@ class program_decoder_ProgramDecoder {
|
|
|
20476
20476
|
}
|
|
20477
20477
|
catch (e) {
|
|
20478
20478
|
program_decoder_logger.error `Invalid program: ${e}`;
|
|
20479
|
-
return Result.error(ProgramDecoderError.InvalidProgramError);
|
|
20479
|
+
return Result.error(ProgramDecoderError.InvalidProgramError, () => `Program decoder error: ${e}`);
|
|
20480
20480
|
}
|
|
20481
20481
|
}
|
|
20482
20482
|
}
|
|
@@ -21219,10 +21219,10 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21219
21219
|
const len = existingPreimage.slots.length;
|
|
21220
21220
|
// https://graypaper.fluffylabs.dev/#/9a08063/380901380901?v=0.6.6
|
|
21221
21221
|
if (len === PreimageStatusKind.Requested) {
|
|
21222
|
-
return Result.error(RequestPreimageError.AlreadyRequested);
|
|
21222
|
+
return Result.error(RequestPreimageError.AlreadyRequested, () => `Preimage already requested: hash=${hash}`);
|
|
21223
21223
|
}
|
|
21224
21224
|
if (len === PreimageStatusKind.Available || len === PreimageStatusKind.Reavailable) {
|
|
21225
|
-
return Result.error(RequestPreimageError.AlreadyAvailable);
|
|
21225
|
+
return Result.error(RequestPreimageError.AlreadyAvailable, () => `Preimage already available: hash=${hash}`);
|
|
21226
21226
|
}
|
|
21227
21227
|
// TODO [ToDr] Not sure if we should update the service info in that case,
|
|
21228
21228
|
// but for now we let that case fall-through.
|
|
@@ -21263,7 +21263,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21263
21263
|
const serviceId = this.currentServiceId;
|
|
21264
21264
|
const status = this.updatedState.getLookupHistory(this.currentTimeslot, this.currentServiceId, hash, length);
|
|
21265
21265
|
if (status === null) {
|
|
21266
|
-
return Result.error(ForgetPreimageError.NotFound);
|
|
21266
|
+
return Result.error(ForgetPreimageError.NotFound, () => `Preimage not found: hash=${hash}, length=${length}`);
|
|
21267
21267
|
}
|
|
21268
21268
|
const s = slotsToPreimageStatus(status.slots);
|
|
21269
21269
|
const updateStorageUtilisation = () => {
|
|
@@ -21276,7 +21276,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21276
21276
|
if (s.status === PreimageStatusKind.Requested) {
|
|
21277
21277
|
const res = updateStorageUtilisation();
|
|
21278
21278
|
if (res.isError) {
|
|
21279
|
-
return Result.error(ForgetPreimageError.StorageUtilisationError);
|
|
21279
|
+
return Result.error(ForgetPreimageError.StorageUtilisationError, res.details);
|
|
21280
21280
|
}
|
|
21281
21281
|
this.updatedState.updatePreimage(serviceId, UpdatePreimage.remove({
|
|
21282
21282
|
hash: status.hash,
|
|
@@ -21291,7 +21291,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21291
21291
|
if (y < t - this.chainSpec.preimageExpungePeriod) {
|
|
21292
21292
|
const res = updateStorageUtilisation();
|
|
21293
21293
|
if (res.isError) {
|
|
21294
|
-
return Result.error(ForgetPreimageError.StorageUtilisationError);
|
|
21294
|
+
return Result.error(ForgetPreimageError.StorageUtilisationError, res.details);
|
|
21295
21295
|
}
|
|
21296
21296
|
this.updatedState.updatePreimage(serviceId, UpdatePreimage.remove({
|
|
21297
21297
|
hash: status.hash,
|
|
@@ -21299,7 +21299,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21299
21299
|
}));
|
|
21300
21300
|
return Result.ok(OK);
|
|
21301
21301
|
}
|
|
21302
|
-
return Result.error(ForgetPreimageError.NotExpired);
|
|
21302
|
+
return Result.error(ForgetPreimageError.NotExpired, () => `Preimage not expired: y=${y}, timeslot=${t}, period=${this.chainSpec.preimageExpungePeriod}`);
|
|
21303
21303
|
}
|
|
21304
21304
|
// https://graypaper.fluffylabs.dev/#/9a08063/38c80138c801?v=0.6.6
|
|
21305
21305
|
if (s.status === PreimageStatusKind.Available) {
|
|
@@ -21317,7 +21317,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21317
21317
|
}));
|
|
21318
21318
|
return Result.ok(OK);
|
|
21319
21319
|
}
|
|
21320
|
-
return Result.error(ForgetPreimageError.NotExpired);
|
|
21320
|
+
return Result.error(ForgetPreimageError.NotExpired, () => `Preimage not expired: y=${y}, timeslot=${t}, period=${this.chainSpec.preimageExpungePeriod}`);
|
|
21321
21321
|
}
|
|
21322
21322
|
assertNever(s);
|
|
21323
21323
|
}
|
|
@@ -21326,17 +21326,17 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21326
21326
|
const destination = this.getServiceInfo(destinationId);
|
|
21327
21327
|
/** https://graypaper.fluffylabs.dev/#/9a08063/370401370401?v=0.6.6 */
|
|
21328
21328
|
if (destination === null || destinationId === null) {
|
|
21329
|
-
return Result.error(TransferError.DestinationNotFound);
|
|
21329
|
+
return Result.error(TransferError.DestinationNotFound, () => `Destination service not found: ${destinationId}`);
|
|
21330
21330
|
}
|
|
21331
21331
|
/** https://graypaper.fluffylabs.dev/#/9a08063/371301371301?v=0.6.6 */
|
|
21332
21332
|
if (gas < destination.onTransferMinGas) {
|
|
21333
|
-
return Result.error(TransferError.GasTooLow);
|
|
21333
|
+
return Result.error(TransferError.GasTooLow, () => `Gas ${gas} below minimum ${destination.onTransferMinGas}`);
|
|
21334
21334
|
}
|
|
21335
21335
|
/** https://graypaper.fluffylabs.dev/#/9a08063/371b01371b01?v=0.6.6 */
|
|
21336
21336
|
const newBalance = source.balance - amount;
|
|
21337
21337
|
const thresholdBalance = ServiceAccountInfo.calculateThresholdBalance(source.storageUtilisationCount, source.storageUtilisationBytes, source.gratisStorage);
|
|
21338
21338
|
if (newBalance < thresholdBalance) {
|
|
21339
|
-
return Result.error(TransferError.BalanceBelowThreshold);
|
|
21339
|
+
return Result.error(TransferError.BalanceBelowThreshold, () => `Balance ${newBalance} below threshold ${thresholdBalance}`);
|
|
21340
21340
|
}
|
|
21341
21341
|
// outgoing transfer
|
|
21342
21342
|
this.updatedState.stateUpdate.transfers.push(PendingTransfer.create({
|
|
@@ -21363,7 +21363,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21363
21363
|
// check if we are priviledged to set gratis storage
|
|
21364
21364
|
// https://graypaper.fluffylabs.dev/#/7e6ff6a/369203369603?v=0.6.7
|
|
21365
21365
|
if (gratisStorage !== tryAsU64(0) && this.currentServiceId !== this.updatedState.getPrivilegedServices().manager) {
|
|
21366
|
-
return Result.error(NewServiceError.UnprivilegedService);
|
|
21366
|
+
return Result.error(NewServiceError.UnprivilegedService, () => `Service ${this.currentServiceId} not privileged to set gratis storage`);
|
|
21367
21367
|
}
|
|
21368
21368
|
// check if we have enough balance
|
|
21369
21369
|
// https://graypaper.fluffylabs.dev/#/7e6ff6a/369e0336a303?v=0.6.7
|
|
@@ -21372,7 +21372,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21372
21372
|
const thresholdForCurrent = ServiceAccountInfo.calculateThresholdBalance(currentService.storageUtilisationCount, currentService.storageUtilisationBytes, currentService.gratisStorage);
|
|
21373
21373
|
const balanceLeftForCurrent = currentService.balance - thresholdForNew;
|
|
21374
21374
|
if (balanceLeftForCurrent < thresholdForCurrent || bytes.overflow) {
|
|
21375
|
-
return Result.error(NewServiceError.InsufficientFunds);
|
|
21375
|
+
return Result.error(NewServiceError.InsufficientFunds, () => `Insufficient funds: balance=${currentService.balance}, required=${thresholdForNew}, overflow=${bytes.overflow}`);
|
|
21376
21376
|
}
|
|
21377
21377
|
// `a`: https://graypaper.fluffylabs.dev/#/ab2cdbd/366b02366d02?v=0.7.2
|
|
21378
21378
|
const newAccount = ServiceAccountInfo.create({
|
|
@@ -21399,7 +21399,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21399
21399
|
// NOTE: It's safe to cast to `Number` here, bcs here service ID cannot be bigger than 2**16
|
|
21400
21400
|
const newServiceId = tryAsServiceId(Number(wantedServiceId));
|
|
21401
21401
|
if (this.getServiceInfo(newServiceId) !== null) {
|
|
21402
|
-
return Result.error(NewServiceError.RegistrarServiceIdAlreadyTaken);
|
|
21402
|
+
return Result.error(NewServiceError.RegistrarServiceIdAlreadyTaken, () => `Service ID ${newServiceId} already taken`);
|
|
21403
21403
|
}
|
|
21404
21404
|
// add the new service with selected ID
|
|
21405
21405
|
// https://graypaper.fluffylabs.dev/#/ab2cdbd/36be0336c003?v=0.7.2
|
|
@@ -21439,7 +21439,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21439
21439
|
const currentDelegator = this.updatedState.getPrivilegedServices().delegator;
|
|
21440
21440
|
if (currentDelegator !== this.currentServiceId) {
|
|
21441
21441
|
accumulate_externalities_logger.trace `Current service id (${this.currentServiceId}) is not a validators manager. (expected: ${currentDelegator}) and cannot update validators data. Ignoring`;
|
|
21442
|
-
return Result.error(UnprivilegedError);
|
|
21442
|
+
return Result.error(UnprivilegedError, () => `Service ${this.currentServiceId} is not delegator (expected: ${currentDelegator})`);
|
|
21443
21443
|
}
|
|
21444
21444
|
this.updatedState.stateUpdate.validatorsData = validatorsData;
|
|
21445
21445
|
return Result.ok(OK);
|
|
@@ -21454,11 +21454,11 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21454
21454
|
const currentAssigners = this.updatedState.getPrivilegedServices().assigners[coreIndex];
|
|
21455
21455
|
if (currentAssigners !== this.currentServiceId) {
|
|
21456
21456
|
accumulate_externalities_logger.trace `Current service id (${this.currentServiceId}) is not an auth manager of core ${coreIndex} (expected: ${currentAssigners}) and cannot update authorization queue.`;
|
|
21457
|
-
return Result.error(UpdatePrivilegesError.UnprivilegedService);
|
|
21457
|
+
return Result.error(UpdatePrivilegesError.UnprivilegedService, () => `Service ${this.currentServiceId} not assigner for core ${coreIndex} (expected: ${currentAssigners})`);
|
|
21458
21458
|
}
|
|
21459
21459
|
if (assigners === null && Compatibility.isGreaterOrEqual(GpVersion.V0_7_1)) {
|
|
21460
21460
|
accumulate_externalities_logger.trace `The new auth manager is not a valid service id.`;
|
|
21461
|
-
return Result.error(UpdatePrivilegesError.InvalidServiceId);
|
|
21461
|
+
return Result.error(UpdatePrivilegesError.InvalidServiceId, () => `New auth manager is null for core ${coreIndex}`);
|
|
21462
21462
|
}
|
|
21463
21463
|
this.updatedState.stateUpdate.authorizationQueues.set(coreIndex, authQueue);
|
|
21464
21464
|
return Result.ok(OK);
|
|
@@ -21491,10 +21491,10 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21491
21491
|
const isManager = current.manager === this.currentServiceId;
|
|
21492
21492
|
if (Compatibility.isLessThan(GpVersion.V0_7_1)) {
|
|
21493
21493
|
if (!isManager) {
|
|
21494
|
-
return Result.error(UpdatePrivilegesError.UnprivilegedService);
|
|
21494
|
+
return Result.error(UpdatePrivilegesError.UnprivilegedService, () => `Service ${this.currentServiceId} is not manager`);
|
|
21495
21495
|
}
|
|
21496
21496
|
if (manager === null || delegator === null) {
|
|
21497
|
-
return Result.error(UpdatePrivilegesError.InvalidServiceId, "Either manager or delegator is not a valid service id.");
|
|
21497
|
+
return Result.error(UpdatePrivilegesError.InvalidServiceId, () => "Either manager or delegator is not a valid service id.");
|
|
21498
21498
|
}
|
|
21499
21499
|
this.updatedState.stateUpdate.privilegedServices = PrivilegedServices.create({
|
|
21500
21500
|
manager,
|
|
@@ -21507,7 +21507,7 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21507
21507
|
}
|
|
21508
21508
|
const original = this.updatedState.state.privilegedServices;
|
|
21509
21509
|
if (manager === null || delegator === null || registrar === null) {
|
|
21510
|
-
return Result.error(UpdatePrivilegesError.InvalidServiceId, "Either manager or delegator or registrar is not a valid service id.");
|
|
21510
|
+
return Result.error(UpdatePrivilegesError.InvalidServiceId, () => "Either manager or delegator or registrar is not a valid service id.");
|
|
21511
21511
|
}
|
|
21512
21512
|
const newDelegator = this.updatePrivilegedServiceId(delegator, current.delegator, {
|
|
21513
21513
|
isManager,
|
|
@@ -21547,19 +21547,19 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21547
21547
|
// TODO [ToDr] what about newly created services?
|
|
21548
21548
|
const service = serviceId === null ? null : this.updatedState.state.getService(serviceId);
|
|
21549
21549
|
if (service === null || serviceId === null) {
|
|
21550
|
-
return Result.error(ProvidePreimageError.ServiceNotFound);
|
|
21550
|
+
return Result.error(ProvidePreimageError.ServiceNotFound, () => `Service not found: ${serviceId}`);
|
|
21551
21551
|
}
|
|
21552
21552
|
// calculating the hash
|
|
21553
21553
|
const preimageHash = this.blake2b.hashBytes(preimage).asOpaque();
|
|
21554
21554
|
// checking service internal lookup
|
|
21555
21555
|
const stateLookup = this.updatedState.getLookupHistory(this.currentTimeslot, serviceId, preimageHash, tryAsU64(preimage.length));
|
|
21556
21556
|
if (stateLookup === null || !LookupHistoryItem.isRequested(stateLookup)) {
|
|
21557
|
-
return Result.error(ProvidePreimageError.WasNotRequested);
|
|
21557
|
+
return Result.error(ProvidePreimageError.WasNotRequested, () => `Preimage was not requested: hash=${preimageHash}, service=${serviceId}`);
|
|
21558
21558
|
}
|
|
21559
21559
|
// checking already provided preimages
|
|
21560
21560
|
const hasPreimage = this.updatedState.hasPreimage(serviceId, preimageHash);
|
|
21561
21561
|
if (hasPreimage) {
|
|
21562
|
-
return Result.error(ProvidePreimageError.AlreadyProvided);
|
|
21562
|
+
return Result.error(ProvidePreimageError.AlreadyProvided, () => `Preimage already provided: hash=${preimageHash}, service=${serviceId}`);
|
|
21563
21563
|
}
|
|
21564
21564
|
// setting up the new preimage
|
|
21565
21565
|
this.updatedState.updatePreimage(serviceId, UpdatePreimage.provide({
|
|
@@ -21574,31 +21574,31 @@ class accumulate_externalities_AccumulateExternalities {
|
|
|
21574
21574
|
eject(destination, previousCodeHash) {
|
|
21575
21575
|
const service = this.getServiceInfo(destination);
|
|
21576
21576
|
if (service === null || destination === null) {
|
|
21577
|
-
return Result.error(EjectError.InvalidService, "Service missing");
|
|
21577
|
+
return Result.error(EjectError.InvalidService, () => "Service missing");
|
|
21578
21578
|
}
|
|
21579
21579
|
const currentService = this.getCurrentServiceInfo();
|
|
21580
21580
|
// check if the service expects to be ejected by us:
|
|
21581
21581
|
const expectedCodeHash = Bytes.zero(HASH_SIZE).asOpaque();
|
|
21582
21582
|
writeServiceIdAsLeBytes(this.currentServiceId, expectedCodeHash.raw);
|
|
21583
21583
|
if (!service.codeHash.isEqualTo(expectedCodeHash)) {
|
|
21584
|
-
return Result.error(EjectError.InvalidService, "Invalid code hash");
|
|
21584
|
+
return Result.error(EjectError.InvalidService, () => "Invalid code hash");
|
|
21585
21585
|
}
|
|
21586
21586
|
// make sure the service only has required number of storage items?
|
|
21587
21587
|
if (service.storageUtilisationCount !== REQUIRED_NUMBER_OF_STORAGE_ITEMS_FOR_EJECT) {
|
|
21588
|
-
return Result.error(EjectError.InvalidPreimage, "Too many storage items");
|
|
21588
|
+
return Result.error(EjectError.InvalidPreimage, () => "Too many storage items");
|
|
21589
21589
|
}
|
|
21590
21590
|
// storage items length
|
|
21591
21591
|
const l = tryAsU64(maxU64(service.storageUtilisationBytes, LOOKUP_HISTORY_ENTRY_BYTES) - LOOKUP_HISTORY_ENTRY_BYTES);
|
|
21592
21592
|
// check if we have a preimage with the entire storage.
|
|
21593
21593
|
const [isPreviousCodeExpired, errorReason] = this.isPreviousCodeExpired(destination, previousCodeHash, l);
|
|
21594
21594
|
if (!isPreviousCodeExpired) {
|
|
21595
|
-
return Result.error(EjectError.InvalidPreimage, `Previous code available: ${errorReason}`);
|
|
21595
|
+
return Result.error(EjectError.InvalidPreimage, () => `Previous code available: ${errorReason}`);
|
|
21596
21596
|
}
|
|
21597
21597
|
// compute new balance of the service.
|
|
21598
21598
|
const newBalance = sumU64(currentService.balance, service.balance);
|
|
21599
21599
|
// TODO [ToDr] what to do in case of overflow?
|
|
21600
21600
|
if (newBalance.overflow) {
|
|
21601
|
-
return Result.error(EjectError.InvalidService, "Balance overflow");
|
|
21601
|
+
return Result.error(EjectError.InvalidService, () => "Balance overflow");
|
|
21602
21602
|
}
|
|
21603
21603
|
// update current service.
|
|
21604
21604
|
this.updatedState.updateServiceInfo(this.currentServiceId, ServiceAccountInfo.create({
|
|
@@ -21789,10 +21789,10 @@ class assurances_Assurances {
|
|
|
21789
21789
|
for (const assurance of assurances) {
|
|
21790
21790
|
const { anchor, validatorIndex, bitfield } = assurance;
|
|
21791
21791
|
if (!anchor.isEqualTo(input.parentHash)) {
|
|
21792
|
-
return Result.error(AssurancesError.InvalidAnchor, `anchor: expected: ${input.parentHash}, got ${anchor}`);
|
|
21792
|
+
return Result.error(AssurancesError.InvalidAnchor, () => `anchor: expected: ${input.parentHash}, got ${anchor}`);
|
|
21793
21793
|
}
|
|
21794
21794
|
if (prevValidatorIndex >= validatorIndex) {
|
|
21795
|
-
return Result.error(AssurancesError.InvalidOrder, `order: expected: ${prevValidatorIndex + 1}, got: ${validatorIndex}`);
|
|
21795
|
+
return Result.error(AssurancesError.InvalidOrder, () => `order: expected: ${prevValidatorIndex + 1}, got: ${validatorIndex}`);
|
|
21796
21796
|
}
|
|
21797
21797
|
prevValidatorIndex = assurance.validatorIndex;
|
|
21798
21798
|
check `${bitfield.bitLength === coresCount} Invalid bitfield length of ${bitfield.bitLength}`;
|
|
@@ -21815,7 +21815,7 @@ class assurances_Assurances {
|
|
|
21815
21815
|
* https://graypaper.fluffylabs.dev/#/579bd12/14e90014ea00
|
|
21816
21816
|
*/
|
|
21817
21817
|
if (noOfAssurances > 0 && !isReportPending) {
|
|
21818
|
-
return Result.error(AssurancesError.NoReportPending, `no report pending for core ${c} yet we got an assurance`);
|
|
21818
|
+
return Result.error(AssurancesError.NoReportPending, () => `no report pending for core ${c} yet we got an assurance`);
|
|
21819
21819
|
}
|
|
21820
21820
|
/**
|
|
21821
21821
|
* Remove work report if it's became available or timed out.
|
|
@@ -21861,7 +21861,7 @@ class assurances_Assurances {
|
|
|
21861
21861
|
const v = assurance.view();
|
|
21862
21862
|
const key = validatorData[v.validatorIndex.materialize()];
|
|
21863
21863
|
if (key === undefined) {
|
|
21864
|
-
return Result.error(AssurancesError.InvalidValidatorIndex);
|
|
21864
|
+
return Result.error(AssurancesError.InvalidValidatorIndex, () => `Invalid validator index: ${v.validatorIndex.materialize()}`);
|
|
21865
21865
|
}
|
|
21866
21866
|
signatures.push({
|
|
21867
21867
|
signature: v.signature.materialize(),
|
|
@@ -21873,7 +21873,7 @@ class assurances_Assurances {
|
|
|
21873
21873
|
const isAllSignaturesValid = signaturesValid.every((x) => x);
|
|
21874
21874
|
if (!isAllSignaturesValid) {
|
|
21875
21875
|
const invalidIndices = signaturesValid.reduce((acc, isValid, idx) => (isValid ? acc : acc.concat(idx)), []);
|
|
21876
|
-
return Result.error(AssurancesError.InvalidSignature, `invalid signatures at ${invalidIndices.join(", ")}`);
|
|
21876
|
+
return Result.error(AssurancesError.InvalidSignature, () => `invalid signatures at ${invalidIndices.join(", ")}`);
|
|
21877
21877
|
}
|
|
21878
21878
|
return Result.ok(OK);
|
|
21879
21879
|
}
|
|
@@ -22484,7 +22484,7 @@ class host_call_memory_HostCallMemory {
|
|
|
22484
22484
|
return Result.ok(OK);
|
|
22485
22485
|
}
|
|
22486
22486
|
if (address + tryAsU64(bytes.length) > MEMORY_SIZE) {
|
|
22487
|
-
return Result.error(new OutOfBounds());
|
|
22487
|
+
return Result.error(new OutOfBounds(), () => `Memory access out of bounds: address ${address} + length ${bytes.length} exceeds memory size`);
|
|
22488
22488
|
}
|
|
22489
22489
|
return this.memory.storeFrom(tryAsMemoryIndex(Number(address)), bytes);
|
|
22490
22490
|
}
|
|
@@ -22493,7 +22493,7 @@ class host_call_memory_HostCallMemory {
|
|
|
22493
22493
|
return Result.ok(OK);
|
|
22494
22494
|
}
|
|
22495
22495
|
if (startAddress + tryAsU64(result.length) > MEMORY_SIZE) {
|
|
22496
|
-
return Result.error(new OutOfBounds());
|
|
22496
|
+
return Result.error(new OutOfBounds(), () => `Memory access out of bounds: address ${startAddress} + length ${result.length} exceeds memory size`);
|
|
22497
22497
|
}
|
|
22498
22498
|
return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
|
|
22499
22499
|
}
|
|
@@ -24302,18 +24302,18 @@ class accumulate_Accumulate {
|
|
|
24302
24302
|
const serviceInfo = updatedState.getServiceInfo(serviceId);
|
|
24303
24303
|
if (serviceInfo === null) {
|
|
24304
24304
|
accumulate_logger.log `Service with id ${serviceId} not found.`;
|
|
24305
|
-
return Result.error(PvmInvocationError.NoService);
|
|
24305
|
+
return Result.error(PvmInvocationError.NoService, () => `Accumulate: service ${serviceId} not found`);
|
|
24306
24306
|
}
|
|
24307
24307
|
const codeHash = serviceInfo.codeHash;
|
|
24308
24308
|
// TODO [ToDr] Should we check that the preimage is still available?
|
|
24309
24309
|
const code = updatedState.getPreimage(serviceId, codeHash.asOpaque());
|
|
24310
24310
|
if (code === null) {
|
|
24311
24311
|
accumulate_logger.log `Code with hash ${codeHash} not found for service ${serviceId}.`;
|
|
24312
|
-
return Result.error(PvmInvocationError.NoPreimage);
|
|
24312
|
+
return Result.error(PvmInvocationError.NoPreimage, () => `Accumulate: code with hash ${codeHash} not found for service ${serviceId}`);
|
|
24313
24313
|
}
|
|
24314
24314
|
if (code.length > W_C) {
|
|
24315
24315
|
accumulate_logger.log `Code with hash ${codeHash} is too long for service ${serviceId}.`;
|
|
24316
|
-
return Result.error(PvmInvocationError.PreimageTooLong);
|
|
24316
|
+
return Result.error(PvmInvocationError.PreimageTooLong, () => `Accumulate: code length ${code.length} exceeds max ${W_C} for service ${serviceId}`);
|
|
24317
24317
|
}
|
|
24318
24318
|
const nextServiceId = generateNextServiceId({ serviceId, entropy, timeslot: slot }, this.chainSpec, this.blake2b);
|
|
24319
24319
|
const partialState = new AccumulateExternalities(this.chainSpec, this.blake2b, updatedState, serviceId, nextServiceId, slot);
|
|
@@ -24601,7 +24601,7 @@ class accumulate_Accumulate {
|
|
|
24601
24601
|
assertEmpty(stateUpdateRest);
|
|
24602
24602
|
if (this.hasDuplicatedServiceIdCreated(services.created)) {
|
|
24603
24603
|
accumulate_logger.trace `Duplicated Service creation detected. Block is invalid.`;
|
|
24604
|
-
return Result.error(ACCUMULATION_ERROR);
|
|
24604
|
+
return Result.error(ACCUMULATION_ERROR, () => "Accumulate: duplicate service created");
|
|
24605
24605
|
}
|
|
24606
24606
|
const accStateUpdate = this.getAccumulationStateUpdate(accumulated.toArray(), toAccumulateLater, slot, Array.from(statistics.keys()), services);
|
|
24607
24607
|
const accumulationOutputUnsorted = Array.from(yieldedRoots.entries()).map(([serviceId, root]) => {
|
|
@@ -24682,13 +24682,13 @@ class deferred_transfers_DeferredTransfers {
|
|
|
24682
24682
|
.toSorted((a, b) => a.source - b.source);
|
|
24683
24683
|
const info = partiallyUpdatedState.getServiceInfo(serviceId);
|
|
24684
24684
|
if (info === null) {
|
|
24685
|
-
return Result.error(DeferredTransfersErrorCode.ServiceInfoNotExist);
|
|
24685
|
+
return Result.error(DeferredTransfersErrorCode.ServiceInfoNotExist, () => `Deferred transfers: service info not found for ${serviceId}`);
|
|
24686
24686
|
}
|
|
24687
24687
|
const codeHash = info.codeHash;
|
|
24688
24688
|
const code = partiallyUpdatedState.getPreimage(serviceId, codeHash.asOpaque());
|
|
24689
24689
|
const newBalance = sumU64(info.balance, ...transfers.map((item) => item.amount));
|
|
24690
24690
|
if (newBalance.overflow) {
|
|
24691
|
-
return Result.error(DeferredTransfersErrorCode.ServiceBalanceOverflow);
|
|
24691
|
+
return Result.error(DeferredTransfersErrorCode.ServiceBalanceOverflow, () => `Deferred transfers: balance overflow for service ${serviceId}`);
|
|
24692
24692
|
}
|
|
24693
24693
|
const newInfo = ServiceAccountInfo.create({ ...info, balance: newBalance.value });
|
|
24694
24694
|
partiallyUpdatedState.updateServiceInfo(serviceId, newInfo);
|
|
@@ -25166,7 +25166,7 @@ function verify_basic_verifyReportsBasic(input) {
|
|
|
25166
25166
|
const noOfPrerequisites = reportView.context.view().prerequisites.view().length;
|
|
25167
25167
|
const noOfSegmentRootLookups = reportView.segmentRootLookup.view().length;
|
|
25168
25168
|
if (noOfPrerequisites + noOfSegmentRootLookups > MAX_REPORT_DEPENDENCIES) {
|
|
25169
|
-
return Result.error(ReportsError.TooManyDependencies, `Report at ${reportView.coreIndex.materialize()} has too many dependencies. Got ${noOfPrerequisites} + ${noOfSegmentRootLookups}, max: ${MAX_REPORT_DEPENDENCIES}`);
|
|
25169
|
+
return Result.error(ReportsError.TooManyDependencies, () => `Report at ${reportView.coreIndex.materialize()} has too many dependencies. Got ${noOfPrerequisites} + ${noOfSegmentRootLookups}, max: ${MAX_REPORT_DEPENDENCIES}`);
|
|
25170
25170
|
}
|
|
25171
25171
|
/**
|
|
25172
25172
|
* In order to ensure fair use of a block’s extrinsic space,
|
|
@@ -25185,7 +25185,7 @@ function verify_basic_verifyReportsBasic(input) {
|
|
|
25185
25185
|
totalOutputsSize += item.view().result.view().okBlob?.raw.length ?? 0;
|
|
25186
25186
|
}
|
|
25187
25187
|
if (authOutputSize + totalOutputsSize > MAX_WORK_REPORT_SIZE_BYTES) {
|
|
25188
|
-
return Result.error(ReportsError.WorkReportTooBig, `Work report at ${reportView.coreIndex.materialize()} too big. Got ${authOutputSize} + ${totalOutputsSize}, max: ${MAX_WORK_REPORT_SIZE_BYTES}`);
|
|
25188
|
+
return Result.error(ReportsError.WorkReportTooBig, () => `Work report at ${reportView.coreIndex.materialize()} too big. Got ${authOutputSize} + ${totalOutputsSize}, max: ${MAX_WORK_REPORT_SIZE_BYTES}`);
|
|
25189
25189
|
}
|
|
25190
25190
|
}
|
|
25191
25191
|
return Result.ok(OK);
|
|
@@ -25219,12 +25219,12 @@ function verify_contextual_verifyContextualValidity(input, state, headerChain, m
|
|
|
25219
25219
|
for (const result of guarantee.report.results) {
|
|
25220
25220
|
const service = state.getService(result.serviceId);
|
|
25221
25221
|
if (service === null) {
|
|
25222
|
-
return Result.error(ReportsError.BadServiceId, `No service with id: ${result.serviceId}`);
|
|
25222
|
+
return Result.error(ReportsError.BadServiceId, () => `No service with id: ${result.serviceId}`);
|
|
25223
25223
|
}
|
|
25224
25224
|
// check service code hash
|
|
25225
25225
|
// https://graypaper.fluffylabs.dev/#/5f542d7/154b02154b02
|
|
25226
25226
|
if (!result.codeHash.isEqualTo(service.getInfo().codeHash)) {
|
|
25227
|
-
return Result.error(ReportsError.BadCodeHash, `Service (${result.serviceId}) code hash mismatch. Got: ${result.codeHash}, expected: ${service.getInfo().codeHash}`);
|
|
25227
|
+
return Result.error(ReportsError.BadCodeHash, () => `Service (${result.serviceId}) code hash mismatch. Got: ${result.codeHash}, expected: ${service.getInfo().codeHash}`);
|
|
25228
25228
|
}
|
|
25229
25229
|
}
|
|
25230
25230
|
}
|
|
@@ -25235,7 +25235,7 @@ function verify_contextual_verifyContextualValidity(input, state, headerChain, m
|
|
|
25235
25235
|
* https://graypaper.fluffylabs.dev/#/5f542d7/151f01152101
|
|
25236
25236
|
*/
|
|
25237
25237
|
if (currentWorkPackages.size !== input.guarantees.length) {
|
|
25238
|
-
return Result.error(ReportsError.DuplicatePackage, "Duplicate work package detected.");
|
|
25238
|
+
return Result.error(ReportsError.DuplicatePackage, () => "Duplicate work package detected.");
|
|
25239
25239
|
}
|
|
25240
25240
|
const minLookupSlot = Math.max(0, input.slot - maxLookupAnchorAge);
|
|
25241
25241
|
const contextResult = verifyRefineContexts(minLookupSlot, contexts, input.recentBlocksPartialUpdate, headerChain);
|
|
@@ -25280,7 +25280,7 @@ function verify_contextual_verifyContextualValidity(input, state, headerChain, m
|
|
|
25280
25280
|
: undefined;
|
|
25281
25281
|
}
|
|
25282
25282
|
if (root === undefined || !root.segmentTreeRoot.isEqualTo(lookup.segmentTreeRoot)) {
|
|
25283
|
-
return Result.error(ReportsError.SegmentRootLookupInvalid, `Mismatching segment tree root for package ${lookup.workPackageHash}. Got: ${lookup.segmentTreeRoot}, expected: ${root?.segmentTreeRoot}`);
|
|
25283
|
+
return Result.error(ReportsError.SegmentRootLookupInvalid, () => `Mismatching segment tree root for package ${lookup.workPackageHash}. Got: ${lookup.segmentTreeRoot}, expected: ${root?.segmentTreeRoot}`);
|
|
25284
25284
|
}
|
|
25285
25285
|
}
|
|
25286
25286
|
}
|
|
@@ -25303,16 +25303,16 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
25303
25303
|
*/
|
|
25304
25304
|
const recentBlock = recentBlocks.get(context.anchor);
|
|
25305
25305
|
if (recentBlock === undefined) {
|
|
25306
|
-
return Result.error(ReportsError.AnchorNotRecent, `Anchor block ${context.anchor} not found in recent blocks.`);
|
|
25306
|
+
return Result.error(ReportsError.AnchorNotRecent, () => `Anchor block ${context.anchor} not found in recent blocks.`);
|
|
25307
25307
|
}
|
|
25308
25308
|
// check state root
|
|
25309
25309
|
if (!recentBlock.postStateRoot.isEqualTo(context.stateRoot)) {
|
|
25310
|
-
return Result.error(ReportsError.BadStateRoot, `Anchor state root mismatch. Got: ${context.stateRoot}, expected: ${recentBlock.postStateRoot}.`);
|
|
25310
|
+
return Result.error(ReportsError.BadStateRoot, () => `Anchor state root mismatch. Got: ${context.stateRoot}, expected: ${recentBlock.postStateRoot}.`);
|
|
25311
25311
|
}
|
|
25312
25312
|
// check beefy root
|
|
25313
25313
|
const beefyRoot = recentBlock.accumulationResult;
|
|
25314
25314
|
if (!beefyRoot.isEqualTo(context.beefyRoot)) {
|
|
25315
|
-
return Result.error(ReportsError.BadBeefyMmrRoot, `Invalid BEEFY super peak hash. Got: ${context.beefyRoot}, expected: ${beefyRoot}. Anchor: ${recentBlock.headerHash}`);
|
|
25315
|
+
return Result.error(ReportsError.BadBeefyMmrRoot, () => `Invalid BEEFY super peak hash. Got: ${context.beefyRoot}, expected: ${beefyRoot}. Anchor: ${recentBlock.headerHash}`);
|
|
25316
25316
|
}
|
|
25317
25317
|
/**
|
|
25318
25318
|
* We require that each lookup-anchor block be within the
|
|
@@ -25321,7 +25321,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
25321
25321
|
* https://graypaper.fluffylabs.dev/#/5f542d7/154601154701
|
|
25322
25322
|
*/
|
|
25323
25323
|
if (context.lookupAnchorSlot < minLookupSlot) {
|
|
25324
|
-
return Result.error(ReportsError.SegmentRootLookupInvalid, `Lookup anchor slot's too old. Got: ${context.lookupAnchorSlot}, minimal: ${minLookupSlot}`);
|
|
25324
|
+
return Result.error(ReportsError.SegmentRootLookupInvalid, () => `Lookup anchor slot's too old. Got: ${context.lookupAnchorSlot}, minimal: ${minLookupSlot}`);
|
|
25325
25325
|
}
|
|
25326
25326
|
/**
|
|
25327
25327
|
* We also require that we have a record of it; this is one of
|
|
@@ -25338,7 +25338,7 @@ function verifyRefineContexts(minLookupSlot, contexts, recentBlocksPartialUpdate
|
|
|
25338
25338
|
verify_contextual_logger.warn `Lookup anchor check for ${context.lookupAnchor} would fail, but override is active.`;
|
|
25339
25339
|
}
|
|
25340
25340
|
else {
|
|
25341
|
-
return Result.error(ReportsError.SegmentRootLookupInvalid, `Lookup anchor is not found in chain. Hash: ${context.lookupAnchor} (slot: ${context.lookupAnchorSlot})`);
|
|
25341
|
+
return Result.error(ReportsError.SegmentRootLookupInvalid, () => `Lookup anchor is not found in chain. Hash: ${context.lookupAnchor} (slot: ${context.lookupAnchorSlot})`);
|
|
25342
25342
|
}
|
|
25343
25343
|
}
|
|
25344
25344
|
}
|
|
@@ -25361,7 +25361,7 @@ function verifyDependencies({ currentWorkPackages, recentlyReported, prerequisit
|
|
|
25361
25361
|
if (recentlyReported.has(preReqHash)) {
|
|
25362
25362
|
continue;
|
|
25363
25363
|
}
|
|
25364
|
-
return Result.error(isSegmentRoot ? ReportsError.SegmentRootLookupInvalid : ReportsError.DependencyMissing, `Missing work package ${preReqHash} in current extrinsic or recent history.`);
|
|
25364
|
+
return Result.error(isSegmentRoot ? ReportsError.SegmentRootLookupInvalid : ReportsError.DependencyMissing, () => `Missing work package ${preReqHash} in current extrinsic or recent history.`);
|
|
25365
25365
|
}
|
|
25366
25366
|
return Result.ok(OK);
|
|
25367
25367
|
};
|
|
@@ -25409,7 +25409,7 @@ function verifyWorkPackagesUniqueness(workPackageHashes, state) {
|
|
|
25409
25409
|
// let's check if any of our packages is in the pipeline
|
|
25410
25410
|
const intersection = packagesInPipeline.intersection(workPackageHashes);
|
|
25411
25411
|
for (const packageHash of intersection) {
|
|
25412
|
-
return Result.error(ReportsError.DuplicatePackage, `The same work package hash found in the pipeline (workPackageHash: ${packageHash})`);
|
|
25412
|
+
return Result.error(ReportsError.DuplicatePackage, () => `The same work package hash found in the pipeline (workPackageHash: ${packageHash})`);
|
|
25413
25413
|
}
|
|
25414
25414
|
return Result.ok(OK);
|
|
25415
25415
|
}
|
|
@@ -25448,7 +25448,7 @@ workReportHashes, slot, getGuarantorAssignment) {
|
|
|
25448
25448
|
const credentialsView = guaranteeView.credentials.view();
|
|
25449
25449
|
if (credentialsView.length < REQUIRED_CREDENTIALS_RANGE[0] ||
|
|
25450
25450
|
credentialsView.length > REQUIRED_CREDENTIALS_RANGE[1]) {
|
|
25451
|
-
return Result.error(ReportsError.InsufficientGuarantees, `Invalid number of credentials. Expected ${REQUIRED_CREDENTIALS_RANGE}, got ${credentialsView.length}`);
|
|
25451
|
+
return Result.error(ReportsError.InsufficientGuarantees, () => `Invalid number of credentials. Expected ${REQUIRED_CREDENTIALS_RANGE}, got ${credentialsView.length}`);
|
|
25452
25452
|
}
|
|
25453
25453
|
/** Retrieve current core assignment. */
|
|
25454
25454
|
const timeSlot = guaranteeView.slot.materialize();
|
|
@@ -25463,20 +25463,20 @@ workReportHashes, slot, getGuarantorAssignment) {
|
|
|
25463
25463
|
const credentialView = credential.view();
|
|
25464
25464
|
const validatorIndex = credentialView.validatorIndex.materialize();
|
|
25465
25465
|
if (lastValidatorIndex >= validatorIndex) {
|
|
25466
|
-
return Result.error(ReportsError.NotSortedOrUniqueGuarantors, `Credentials must be sorted by validator index. Got ${validatorIndex}, expected at least ${lastValidatorIndex + 1}`);
|
|
25466
|
+
return Result.error(ReportsError.NotSortedOrUniqueGuarantors, () => `Credentials must be sorted by validator index. Got ${validatorIndex}, expected at least ${lastValidatorIndex + 1}`);
|
|
25467
25467
|
}
|
|
25468
25468
|
lastValidatorIndex = validatorIndex;
|
|
25469
25469
|
const signature = credentialView.signature.materialize();
|
|
25470
25470
|
const guarantorData = guarantorAssignments[validatorIndex];
|
|
25471
25471
|
if (guarantorData === undefined) {
|
|
25472
|
-
return Result.error(ReportsError.BadValidatorIndex, `Invalid validator index: ${validatorIndex}`);
|
|
25472
|
+
return Result.error(ReportsError.BadValidatorIndex, () => `Invalid validator index: ${validatorIndex}`);
|
|
25473
25473
|
}
|
|
25474
25474
|
/**
|
|
25475
25475
|
* Verify core assignment.
|
|
25476
25476
|
* https://graypaper.fluffylabs.dev/#/5f542d7/14e40214e602
|
|
25477
25477
|
*/
|
|
25478
25478
|
if (guarantorData.core !== coreIndex) {
|
|
25479
|
-
return Result.error(ReportsError.WrongAssignment, `Invalid core assignment for validator ${validatorIndex}. Expected: ${guarantorData.core}, got: ${coreIndex}`);
|
|
25479
|
+
return Result.error(ReportsError.WrongAssignment, () => `Invalid core assignment for validator ${validatorIndex}. Expected: ${guarantorData.core}, got: ${coreIndex}`);
|
|
25480
25480
|
}
|
|
25481
25481
|
signaturesToVerify.push({
|
|
25482
25482
|
signature,
|
|
@@ -25514,10 +25514,10 @@ function verify_order_verifyReportsOrder(input, chainSpec) {
|
|
|
25514
25514
|
const reportView = guarantee.view().report.view();
|
|
25515
25515
|
const coreIndex = reportView.coreIndex.materialize();
|
|
25516
25516
|
if (lastCoreIndex >= coreIndex) {
|
|
25517
|
-
return Result.error(ReportsError.OutOfOrderGuarantee, `Core indices of work reports are not unique or in order. Got: ${coreIndex}, expected at least: ${lastCoreIndex + 1}`);
|
|
25517
|
+
return Result.error(ReportsError.OutOfOrderGuarantee, () => `Core indices of work reports are not unique or in order. Got: ${coreIndex}, expected at least: ${lastCoreIndex + 1}`);
|
|
25518
25518
|
}
|
|
25519
25519
|
if (coreIndex >= noOfCores) {
|
|
25520
|
-
return Result.error(ReportsError.BadCoreIndex, `Invalid core index. Got: ${coreIndex}, max: ${noOfCores}`);
|
|
25520
|
+
return Result.error(ReportsError.BadCoreIndex, () => `Invalid core index. Got: ${coreIndex}, max: ${noOfCores}`);
|
|
25521
25521
|
}
|
|
25522
25522
|
lastCoreIndex = coreIndex;
|
|
25523
25523
|
}
|
|
@@ -25542,7 +25542,7 @@ function verify_post_signature_verifyPostSignatureChecks(input, availabilityAssi
|
|
|
25542
25542
|
* https://graypaper.fluffylabs.dev/#/5f542d7/15ea0015ea00
|
|
25543
25543
|
*/
|
|
25544
25544
|
if (availabilityAssignment[coreIndex] !== null) {
|
|
25545
|
-
return Result.error(ReportsError.CoreEngaged, `Report pending availability at core: ${coreIndex}`);
|
|
25545
|
+
return Result.error(ReportsError.CoreEngaged, () => `Report pending availability at core: ${coreIndex}`);
|
|
25546
25546
|
}
|
|
25547
25547
|
/**
|
|
25548
25548
|
* A report is valid only if the authorizer hash is present
|
|
@@ -25555,7 +25555,7 @@ function verify_post_signature_verifyPostSignatureChecks(input, availabilityAssi
|
|
|
25555
25555
|
const authorizerPool = authPools.get(coreIndex);
|
|
25556
25556
|
const pool = authorizerPool?.materialize() ?? [];
|
|
25557
25557
|
if (pool.find((hash) => hash.isEqualTo(authorizerHash)) === undefined) {
|
|
25558
|
-
return Result.error(ReportsError.CoreUnauthorized, `Authorizer hash not found in the pool of core ${coreIndex}: ${authorizerHash}`);
|
|
25558
|
+
return Result.error(ReportsError.CoreUnauthorized, () => `Authorizer hash not found in the pool of core ${coreIndex}: ${authorizerHash}`);
|
|
25559
25559
|
}
|
|
25560
25560
|
/**
|
|
25561
25561
|
* We require that the gas allotted for accumulation of each
|
|
@@ -25567,17 +25567,17 @@ function verify_post_signature_verifyPostSignatureChecks(input, availabilityAssi
|
|
|
25567
25567
|
for (const result of report.results) {
|
|
25568
25568
|
const service = services(result.serviceId);
|
|
25569
25569
|
if (service === null) {
|
|
25570
|
-
return Result.error(ReportsError.BadServiceId, `No service with id: ${result.serviceId}`);
|
|
25570
|
+
return Result.error(ReportsError.BadServiceId, () => `No service with id: ${result.serviceId}`);
|
|
25571
25571
|
}
|
|
25572
25572
|
const info = service.getInfo();
|
|
25573
25573
|
// check minimal accumulation gas
|
|
25574
25574
|
if (result.gas < info.accumulateMinGas) {
|
|
25575
|
-
return Result.error(ReportsError.ServiceItemGasTooLow, `Service (${result.serviceId}) gas is less than minimal. Got: ${result.gas}, expected at least: ${info.accumulateMinGas}`);
|
|
25575
|
+
return Result.error(ReportsError.ServiceItemGasTooLow, () => `Service (${result.serviceId}) gas is less than minimal. Got: ${result.gas}, expected at least: ${info.accumulateMinGas}`);
|
|
25576
25576
|
}
|
|
25577
25577
|
}
|
|
25578
25578
|
const totalGas = sumU64(...report.results.map((x) => x.gas));
|
|
25579
25579
|
if (totalGas.overflow || totalGas.value > G_A) {
|
|
25580
|
-
return Result.error(ReportsError.WorkReportGasTooHigh, `Total gas too high. Got: ${totalGas.value} (ovfl: ${totalGas.overflow}), maximal: ${G_A}`);
|
|
25580
|
+
return Result.error(ReportsError.WorkReportGasTooHigh, () => `Total gas too high. Got: ${totalGas.value} (ovfl: ${totalGas.overflow}), maximal: ${G_A}`);
|
|
25581
25581
|
}
|
|
25582
25582
|
}
|
|
25583
25583
|
return Result.ok(OK);
|
|
@@ -25663,7 +25663,7 @@ class reports_Reports {
|
|
|
25663
25663
|
}
|
|
25664
25664
|
const reporters = SortedSet.fromArray(bytesBlobComparator, signaturesToVerify.ok.map((x) => x.key)).slice();
|
|
25665
25665
|
if (hasAnyOffenders(reporters, input.offenders)) {
|
|
25666
|
-
return Result.error(ReportsError.BannedValidator);
|
|
25666
|
+
return Result.error(ReportsError.BannedValidator, () => "One or more reporters are banned validators");
|
|
25667
25667
|
}
|
|
25668
25668
|
return Result.ok({
|
|
25669
25669
|
stateUpdate: {
|
|
@@ -25703,7 +25703,7 @@ class reports_Reports {
|
|
|
25703
25703
|
return signaturesToVerify[idx].key;
|
|
25704
25704
|
})
|
|
25705
25705
|
.filter((x) => x !== null);
|
|
25706
|
-
return Result.error(ReportsError.BadSignature, `Invalid signatures for validators with keys: ${invalidKeys.join(", ")}`);
|
|
25706
|
+
return Result.error(ReportsError.BadSignature, () => `Invalid signatures for validators with keys: ${invalidKeys.join(", ")}`);
|
|
25707
25707
|
}
|
|
25708
25708
|
/**
|
|
25709
25709
|
* Get the guarantor assignment (both core and validator data)
|
|
@@ -25719,10 +25719,10 @@ class reports_Reports {
|
|
|
25719
25719
|
const minTimeSlot = Math.max(0, headerRotation - 1) * rotationPeriod;
|
|
25720
25720
|
// https://graypaper.fluffylabs.dev/#/5f542d7/155e00156900
|
|
25721
25721
|
if (guaranteeTimeSlot > headerTimeSlot) {
|
|
25722
|
-
return Result.error(ReportsError.FutureReportSlot, `Report slot is in future. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
25722
|
+
return Result.error(ReportsError.FutureReportSlot, () => `Report slot is in future. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
25723
25723
|
}
|
|
25724
25724
|
if (guaranteeTimeSlot < minTimeSlot) {
|
|
25725
|
-
return Result.error(ReportsError.ReportEpochBeforeLast, `Report slot is too old. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
25725
|
+
return Result.error(ReportsError.ReportEpochBeforeLast, () => `Report slot is too old. Block ${headerTimeSlot}, Report: ${guaranteeTimeSlot}`);
|
|
25726
25726
|
}
|
|
25727
25727
|
// TODO [ToDr] [opti] below code needs cache.
|
|
25728
25728
|
// The `G` and `G*` sets should only be computed once per rotation.
|
|
@@ -26338,11 +26338,11 @@ class chain_stf_OnChain {
|
|
|
26338
26338
|
}
|
|
26339
26339
|
function checkOffendersMatch(offendersMark, headerOffendersMark) {
|
|
26340
26340
|
if (offendersMark.size !== headerOffendersMark.length) {
|
|
26341
|
-
return Result.error(OFFENDERS_ERROR, `Length mismatch: ${offendersMark.size} vs ${headerOffendersMark.length}`);
|
|
26341
|
+
return Result.error(OFFENDERS_ERROR, () => `Length mismatch: ${offendersMark.size} vs ${headerOffendersMark.length}`);
|
|
26342
26342
|
}
|
|
26343
26343
|
for (const key of headerOffendersMark) {
|
|
26344
26344
|
if (!offendersMark.has(key)) {
|
|
26345
|
-
return Result.error(OFFENDERS_ERROR, `Missing key: ${key}`);
|
|
26345
|
+
return Result.error(OFFENDERS_ERROR, () => `Missing key: ${key}`);
|
|
26346
26346
|
}
|
|
26347
26347
|
}
|
|
26348
26348
|
return Result.ok(OK);
|