@typeberry/convert 0.2.0-5746fdc → 0.2.0-79dc2d4

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 CHANGED
@@ -4245,44 +4245,40 @@ var compatibility_GpVersion;
4245
4245
  GpVersion["V0_6_7"] = "0.6.7";
4246
4246
  GpVersion["V0_7_0"] = "0.7.0";
4247
4247
  GpVersion["V0_7_1"] = "0.7.1";
4248
- GpVersion["V0_7_2"] = "0.7.2-preview";
4248
+ GpVersion["V0_7_2"] = "0.7.2";
4249
4249
  })(compatibility_GpVersion || (compatibility_GpVersion = {}));
4250
- var TestSuite;
4250
+ var compatibility_TestSuite;
4251
4251
  (function (TestSuite) {
4252
4252
  TestSuite["W3F_DAVXY"] = "w3f-davxy";
4253
4253
  TestSuite["JAMDUNA"] = "jamduna";
4254
- })(TestSuite || (TestSuite = {}));
4255
- const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
4256
- const DEFAULT_VERSION = compatibility_GpVersion.V0_7_1;
4254
+ })(compatibility_TestSuite || (compatibility_TestSuite = {}));
4255
+ const ALL_VERSIONS_IN_ORDER = [compatibility_GpVersion.V0_6_7, compatibility_GpVersion.V0_7_0, compatibility_GpVersion.V0_7_1, compatibility_GpVersion.V0_7_2];
4256
+ const DEFAULT_SUITE = compatibility_TestSuite.W3F_DAVXY;
4257
+ const DEFAULT_VERSION = compatibility_GpVersion.V0_7_2;
4257
4258
  const env = typeof process === "undefined" ? {} : process.env;
4258
4259
  let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
4259
4260
  let CURRENT_SUITE = parseCurrentSuite(env.TEST_SUITE) ?? DEFAULT_SUITE;
4260
- const ALL_VERSIONS_IN_ORDER = [compatibility_GpVersion.V0_6_7, compatibility_GpVersion.V0_7_0, compatibility_GpVersion.V0_7_1, compatibility_GpVersion.V0_7_2];
4261
4261
  function parseCurrentVersion(env) {
4262
4262
  if (env === undefined) {
4263
4263
  return undefined;
4264
4264
  }
4265
- switch (env) {
4266
- case compatibility_GpVersion.V0_6_7:
4267
- case compatibility_GpVersion.V0_7_0:
4268
- case compatibility_GpVersion.V0_7_1:
4269
- case compatibility_GpVersion.V0_7_2:
4270
- return env;
4271
- default:
4272
- throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
4265
+ for (const v of Object.values(compatibility_GpVersion)) {
4266
+ if (env === v) {
4267
+ return v;
4268
+ }
4273
4269
  }
4270
+ throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
4274
4271
  }
4275
4272
  function parseCurrentSuite(env) {
4276
4273
  if (env === undefined) {
4277
4274
  return undefined;
4278
4275
  }
4279
- switch (env) {
4280
- case TestSuite.W3F_DAVXY:
4281
- case TestSuite.JAMDUNA:
4282
- return env;
4283
- default:
4284
- throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`);
4276
+ for (const s of Object.values(compatibility_TestSuite)) {
4277
+ if (env === s) {
4278
+ return s;
4279
+ }
4285
4280
  }
4281
+ throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(compatibility_TestSuite)}`);
4286
4282
  }
4287
4283
  class compatibility_Compatibility {
4288
4284
  static override(version) {
@@ -4443,6 +4439,13 @@ class WithDebug {
4443
4439
  return debug_inspect(this);
4444
4440
  }
4445
4441
  }
4442
+ function lazyInspect(obj) {
4443
+ return {
4444
+ toString() {
4445
+ return debug_inspect(obj);
4446
+ },
4447
+ };
4448
+ }
4446
4449
 
4447
4450
  ;// CONCATENATED MODULE: ./packages/core/utils/dev.ts
4448
4451
  const dev_env = typeof process === "undefined" ? {} : process.env;
@@ -5227,7 +5230,7 @@ const asTypedNumber = (v) => v;
5227
5230
  const MAX_VALUE_U8 = 0xff;
5228
5231
  const MAX_VALUE_U16 = 0xffff;
5229
5232
  const MAX_VALUE_U32 = 0xffff_ffff;
5230
- const MAX_VALUE_U64 = 0xffffffffffffffffn;
5233
+ const numbers_MAX_VALUE_U64 = 0xffffffffffffffffn;
5231
5234
  /** Attempt to cast an input number into U8. */
5232
5235
  const tryAsU8 = (v) => {
5233
5236
  debug_check `${isU8(v)} input must have one-byte representation, got ${v}`;
@@ -5256,7 +5259,7 @@ const numbers_tryAsU64 = (x) => {
5256
5259
  return asTypedNumber(v);
5257
5260
  };
5258
5261
  /** Check if given number is a valid U64 number. */
5259
- const numbers_isU64 = (v) => (v & MAX_VALUE_U64) === v;
5262
+ const numbers_isU64 = (v) => (v & numbers_MAX_VALUE_U64) === v;
5260
5263
  /** Collate two U32 parts into one U64. */
5261
5264
  const u64FromParts = ({ lower, upper }) => {
5262
5265
  const val = (BigInt(upper) << 32n) + BigInt(lower);
@@ -10785,7 +10788,7 @@ const DEV_CONFIG = "dev";
10785
10788
  const DEFAULT_CONFIG = "default";
10786
10789
  const NODE_DEFAULTS = {
10787
10790
  name: isBrowser() ? "browser" : external_node_os_default().hostname(),
10788
- config: DEFAULT_CONFIG,
10791
+ config: [DEFAULT_CONFIG],
10789
10792
  pvm: pvm_backend_PvmBackend.BuiltIn,
10790
10793
  };
10791
10794
  /** Chain spec chooser. */
@@ -10838,25 +10841,137 @@ class NodeConfiguration {
10838
10841
  this.authorship = authorship;
10839
10842
  }
10840
10843
  }
10841
- function loadConfig(configPath) {
10842
- if (configPath === DEFAULT_CONFIG) {
10843
- node_config_logger.log `🔧 Loading DEFAULT config`;
10844
- return parseFromJson(configs.default, NodeConfiguration.fromJson);
10845
- }
10846
- if (configPath === DEV_CONFIG) {
10847
- node_config_logger.log `🔧 Loading DEV config`;
10848
- return parseFromJson(configs.dev, NodeConfiguration.fromJson);
10844
+ function loadConfig(config, withRelPath) {
10845
+ node_config_logger.log `🔧 Loading config`;
10846
+ let mergedJson = {};
10847
+ for (const entry of config) {
10848
+ node_config_logger.log `🔧 Applying '${entry}'`;
10849
+ if (entry === DEV_CONFIG) {
10850
+ mergedJson = structuredClone(configs.dev); // clone to avoid mutating the original config. not doing a merge since dev and default should theoretically replace all properties.
10851
+ continue;
10852
+ }
10853
+ if (entry === DEFAULT_CONFIG) {
10854
+ mergedJson = structuredClone(configs.default);
10855
+ continue;
10856
+ }
10857
+ // try to parse as JSON
10858
+ try {
10859
+ const parsed = JSON.parse(entry);
10860
+ deepMerge(mergedJson, parsed);
10861
+ continue;
10862
+ }
10863
+ catch { }
10864
+ // if not, try to load as file
10865
+ if (entry.indexOf("=") === -1 && entry.endsWith(".json")) {
10866
+ try {
10867
+ const configFile = fs.readFileSync(withRelPath(entry), "utf8");
10868
+ const parsed = JSON.parse(configFile);
10869
+ deepMerge(mergedJson, parsed);
10870
+ }
10871
+ catch (e) {
10872
+ throw new Error(`Unable to load config from ${entry}: ${e}`);
10873
+ }
10874
+ }
10875
+ else {
10876
+ // finally try to process as a pseudo-jq query
10877
+ try {
10878
+ processQuery(mergedJson, entry, withRelPath);
10879
+ }
10880
+ catch (e) {
10881
+ throw new Error(`Error while processing '${entry}': ${e}`);
10882
+ }
10883
+ }
10849
10884
  }
10850
10885
  try {
10851
- node_config_logger.log `🔧 Loading config from ${configPath}`;
10852
- const configFile = fs.readFileSync(configPath, "utf8");
10853
- const parsed = JSON.parse(configFile);
10854
- return parseFromJson(parsed, NodeConfiguration.fromJson);
10886
+ const parsed = parseFromJson(mergedJson, NodeConfiguration.fromJson);
10887
+ node_config_logger.log `🔧 Config ready`;
10888
+ return parsed;
10855
10889
  }
10856
10890
  catch (e) {
10857
- throw new Error(`Unable to load config file from ${configPath}: ${e}`);
10891
+ throw new Error(`Unable to parse config: ${e}`);
10858
10892
  }
10859
10893
  }
10894
+ function deepMerge(target, source) {
10895
+ if (!isJsonObject(source)) {
10896
+ throw new Error(`Expected object, got ${source}`);
10897
+ }
10898
+ for (const key in source) {
10899
+ if (isJsonObject(source[key])) {
10900
+ if (!isJsonObject(target[key])) {
10901
+ target[key] = {};
10902
+ }
10903
+ deepMerge(target[key], source[key]);
10904
+ }
10905
+ else {
10906
+ target[key] = source[key];
10907
+ }
10908
+ }
10909
+ }
10910
+ /**
10911
+ * Caution: updates input directly.
10912
+ * Processes a pseudo-jq query. Syntax:
10913
+ * .path.to.value = { ... } - updates value with the specified object by replacement
10914
+ * .path.to.value += { ... } - updates value with the specified object by merging
10915
+ * .path.to.value = file.json - updates value with the contents of file.json
10916
+ * .path.to.value += file.json - merges the contents of file.json onto value
10917
+ */
10918
+ function processQuery(input, query, withRelPath) {
10919
+ const queryParts = query.split("=");
10920
+ if (queryParts.length === 2) {
10921
+ let [path, value] = queryParts.map((part) => part.trim());
10922
+ let merge = false;
10923
+ // detect += syntax
10924
+ if (path.endsWith("+")) {
10925
+ merge = true;
10926
+ path = path.slice(0, -1);
10927
+ }
10928
+ let parsedValue;
10929
+ if (value.endsWith(".json")) {
10930
+ try {
10931
+ const configFile = fs.readFileSync(withRelPath(value), "utf8");
10932
+ const parsed = JSON.parse(configFile);
10933
+ parsedValue = parsed;
10934
+ }
10935
+ catch (e) {
10936
+ throw new Error(`Unable to load config from ${value}: ${e}`);
10937
+ }
10938
+ }
10939
+ else {
10940
+ try {
10941
+ parsedValue = JSON.parse(value);
10942
+ }
10943
+ catch (e) {
10944
+ throw new Error(`Unrecognized syntax '${value}': ${e}`);
10945
+ }
10946
+ }
10947
+ let pathParts = path.split(".");
10948
+ // allow leading dot in path
10949
+ if (pathParts[0] === "") {
10950
+ pathParts = pathParts.slice(1);
10951
+ }
10952
+ let target = input;
10953
+ for (let i = 0; i < pathParts.length; i++) {
10954
+ const part = pathParts[i];
10955
+ if (!isJsonObject(target[part])) {
10956
+ target[part] = {};
10957
+ }
10958
+ if (i === pathParts.length - 1) {
10959
+ if (merge) {
10960
+ deepMerge(target[part], parsedValue);
10961
+ }
10962
+ else {
10963
+ target[part] = parsedValue;
10964
+ }
10965
+ return;
10966
+ }
10967
+ target = target[part];
10968
+ }
10969
+ }
10970
+ throw new Error("Unrecognized syntax.");
10971
+ }
10972
+ function isJsonObject(value) {
10973
+ return typeof value === "object" && value !== null && !Array.isArray(value);
10974
+ }
10860
10975
 
10861
10976
  ;// CONCATENATED MODULE: ./packages/jam/config-node/index.ts
10862
10977
 
@@ -12144,7 +12259,7 @@ class service_LookupHistoryItem {
12144
12259
 
12145
12260
 
12146
12261
 
12147
- const codecServiceId = compatibility_Compatibility.isSuite(TestSuite.W3F_DAVXY) || compatibility_Compatibility.isSuite(TestSuite.JAMDUNA, compatibility_GpVersion.V0_6_7)
12262
+ const codecServiceId = compatibility_Compatibility.isSuite(compatibility_TestSuite.W3F_DAVXY) || compatibility_Compatibility.isSuite(compatibility_TestSuite.JAMDUNA, compatibility_GpVersion.V0_6_7)
12148
12263
  ? descriptors_codec.u32.asOpaque()
12149
12264
  : descriptors_codec.varU32.convert((s) => numbers_tryAsU32(s), (i) => common_tryAsServiceId(i));
12150
12265
  /**
@@ -12483,26 +12598,6 @@ class InMemoryStateView {
12483
12598
 
12484
12599
 
12485
12600
 
12486
- /** Dictionary entry of services that auto-accumulate every block. */
12487
- class privileged_services_AutoAccumulate {
12488
- service;
12489
- gasLimit;
12490
- static Codec = descriptors_codec.Class(privileged_services_AutoAccumulate, {
12491
- service: descriptors_codec.u32.asOpaque(),
12492
- gasLimit: descriptors_codec.u64.asOpaque(),
12493
- });
12494
- static create({ service, gasLimit }) {
12495
- return new privileged_services_AutoAccumulate(service, gasLimit);
12496
- }
12497
- constructor(
12498
- /** Service id that auto-accumulates. */
12499
- service,
12500
- /** Gas limit for auto-accumulation. */
12501
- gasLimit) {
12502
- this.service = service;
12503
- this.gasLimit = gasLimit;
12504
- }
12505
- }
12506
12601
  /**
12507
12602
  * https://graypaper.fluffylabs.dev/#/ab2cdbd/114402114402?v=0.7.2
12508
12603
  */
@@ -12520,7 +12615,9 @@ class privileged_services_PrivilegedServices {
12520
12615
  registrar: compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_1)
12521
12616
  ? descriptors_codec.u32.asOpaque()
12522
12617
  : ignoreValueWithDefault(common_tryAsServiceId(2 ** 32 - 1)),
12523
- autoAccumulateServices: readonlyArray(descriptors_codec.sequenceVarLen(privileged_services_AutoAccumulate.Codec)),
12618
+ autoAccumulateServices: descriptors_codec.dictionary(descriptors_codec.u32.asOpaque(), descriptors_codec.u64.asOpaque(), {
12619
+ sortKeys: (a, b) => a - b,
12620
+ }),
12524
12621
  });
12525
12622
  static create(a) {
12526
12623
  return new privileged_services_PrivilegedServices(a.manager, a.delegator, a.registrar, a.assigners, a.autoAccumulateServices);
@@ -13153,7 +13250,7 @@ class in_memory_state_InMemoryState extends WithDebug {
13153
13250
  assigners: common_tryAsPerCore(new Array(spec.coresCount).fill(common_tryAsServiceId(0)), spec),
13154
13251
  delegator: common_tryAsServiceId(0),
13155
13252
  registrar: common_tryAsServiceId(math_consts_MAX_VALUE),
13156
- autoAccumulateServices: [],
13253
+ autoAccumulateServices: new Map(),
13157
13254
  }),
13158
13255
  accumulationOutputLog: sorted_array_SortedArray.fromArray(accumulation_output_accumulationOutputComparator, []),
13159
13256
  services: new Map(),
@@ -13625,10 +13722,7 @@ const fullStateDumpFromJson = (spec) => json.object({
13625
13722
  chi_a: json.array("number"),
13626
13723
  chi_v: "number",
13627
13724
  chi_r: json.optional("number"),
13628
- chi_g: json.nullable(json.array({
13629
- service: "number",
13630
- gasLimit: json.fromNumber((v) => common_tryAsServiceGas(v)),
13631
- })),
13725
+ chi_g: json.nullable(json.map("number", json.fromNumber((v) => common_tryAsServiceGas(v)))),
13632
13726
  },
13633
13727
  pi: JsonStatisticsData.fromJson,
13634
13728
  omega: json.array(json.array(notYetAccumulatedFromJson)),
@@ -13669,7 +13763,7 @@ const fullStateDumpFromJson = (spec) => json.object({
13669
13763
  assigners: chi.chi_a,
13670
13764
  delegator: chi.chi_v,
13671
13765
  registrar: chi.chi_r ?? common_tryAsServiceId(2 ** 32 - 1),
13672
- autoAccumulateServices: chi.chi_g ?? [],
13766
+ autoAccumulateServices: chi.chi_g ?? new Map(),
13673
13767
  }),
13674
13768
  statistics: JsonStatisticsData.toStatisticsData(spec, pi),
13675
13769
  accumulationQueue: omega,
@@ -17700,7 +17794,7 @@ class accumulate_externalities_AccumulateExternalities {
17700
17794
  updatedState;
17701
17795
  currentServiceId;
17702
17796
  currentTimeslot;
17703
- checkpointedState = null;
17797
+ checkpointedState;
17704
17798
  /** `x_i`: next service id we are going to create. */
17705
17799
  nextNewServiceId;
17706
17800
  constructor(chainSpec, blake2b, updatedState,
@@ -17711,13 +17805,14 @@ class accumulate_externalities_AccumulateExternalities {
17711
17805
  this.updatedState = updatedState;
17712
17806
  this.currentServiceId = currentServiceId;
17713
17807
  this.currentTimeslot = currentTimeslot;
17808
+ this.checkpointedState = AccumulationStateUpdate.copyFrom(updatedState.stateUpdate);
17714
17809
  this.nextNewServiceId = this.getNextAvailableServiceId(nextNewServiceIdCandidate);
17715
17810
  const service = this.updatedState.getServiceInfo(this.currentServiceId);
17716
17811
  if (service === null) {
17717
17812
  throw new Error(`Invalid state initialization. Service info missing for ${this.currentServiceId}.`);
17718
17813
  }
17719
17814
  }
17720
- /** Return the underlying state update and checkpointed state (if any). */
17815
+ /** Return the underlying state update and checkpointed state. */
17721
17816
  getStateUpdates() {
17722
17817
  return [this.updatedState.stateUpdate, this.checkpointedState];
17723
17818
  }
@@ -18084,7 +18179,7 @@ class accumulate_externalities_AccumulateExternalities {
18084
18179
  assigners: authorizers,
18085
18180
  delegator: delegator,
18086
18181
  registrar: registrar ?? tryAsServiceId(0),
18087
- autoAccumulateServices: autoAccumulate.map(([service, gasLimit]) => AutoAccumulate.create({ service, gasLimit })),
18182
+ autoAccumulateServices: autoAccumulate,
18088
18183
  });
18089
18184
  return Result.ok(OK);
18090
18185
  }
@@ -18108,9 +18203,7 @@ class accumulate_externalities_AccumulateExternalities {
18108
18203
  isAlreadyChanged: currentAssigner !== original.assigners[index],
18109
18204
  }));
18110
18205
  const newManager = isManager ? manager : current.manager;
18111
- const newAutoAccumulateServices = isManager
18112
- ? autoAccumulate.map(([service, gasLimit]) => AutoAccumulate.create({ service, gasLimit }))
18113
- : current.autoAccumulateServices;
18206
+ const newAutoAccumulateServices = isManager ? autoAccumulate : current.autoAccumulateServices;
18114
18207
  // finally update the privileges
18115
18208
  this.updatedState.stateUpdate.privilegedServices = PrivilegedServices.create({
18116
18209
  manager: newManager,
@@ -18254,7 +18347,7 @@ function bumpServiceId(serviceId) {
18254
18347
  */
18255
18348
  class operand_Operand extends WithDebug {
18256
18349
  // JamDuna uses a different order of operands.
18257
- static Codec = descriptors_codec.Class(operand_Operand, compatibility_Compatibility.isSuite(TestSuite.JAMDUNA)
18350
+ static Codec = descriptors_codec.Class(operand_Operand, compatibility_Compatibility.isSuite(compatibility_TestSuite.JAMDUNA)
18258
18351
  ? {
18259
18352
  hash: descriptors_codec.bytes(hash_HASH_SIZE).asOpaque(),
18260
18353
  exportsRoot: descriptors_codec.bytes(hash_HASH_SIZE).asOpaque(),
@@ -18738,17 +18831,16 @@ class fetch_externalities_FetchExternalities {
18738
18831
 
18739
18832
 
18740
18833
 
18834
+
18741
18835
  class AccumulateDataItem {
18742
18836
  operands;
18743
18837
  reportsLength;
18744
- gasCost;
18745
- constructor(operands, reportsLength, gasCost) {
18838
+ constructor(operands, reportsLength) {
18746
18839
  this.operands = operands;
18747
18840
  this.reportsLength = reportsLength;
18748
- this.gasCost = gasCost;
18749
18841
  }
18750
18842
  static empty() {
18751
- return new AccumulateDataItem([], tryAsU32(0), tryAsServiceGas(0n));
18843
+ return new AccumulateDataItem([], tryAsU32(0));
18752
18844
  }
18753
18845
  }
18754
18846
  /**
@@ -18758,23 +18850,43 @@ class AccumulateDataItem {
18758
18850
  * - gas cost and reports length for each service (statistics)
18759
18851
  */
18760
18852
  class accumulate_data_AccumulateData {
18853
+ autoAccumulateServicesByServiceId;
18761
18854
  reportsDataByServiceId;
18762
18855
  transfersByServiceId;
18763
- autoAccumulateServicesByServiceId;
18764
18856
  serviceIds;
18765
- constructor(reports, transfers, autoAccumulateServices) {
18766
- const { autoAccumulateServicesByServiceId, serviceIds: serviceIdsFromAutoAccumulate } = this.transformAutoAccumulateServices(autoAccumulateServices);
18857
+ gasLimitByServiceId;
18858
+ constructor(reports, transfers, autoAccumulateServicesByServiceId) {
18767
18859
  this.autoAccumulateServicesByServiceId = autoAccumulateServicesByServiceId;
18768
- const { reportsDataByServiceId, serviceIds: serviceIdsFromReports } = this.transformReports(reports);
18860
+ const serviceIdsFromAutoAccumulate = new Set(autoAccumulateServicesByServiceId.keys());
18861
+ const { reportsDataByServiceId, serviceIds: serviceIdsFromReports, gasLimitByServiceId: reportsGasLimitByServiceId, } = this.transformReports(reports);
18769
18862
  this.reportsDataByServiceId = reportsDataByServiceId;
18770
- const { transfersByServiceId, serviceIds: serviceIdsFromTransfers } = this.transformTransfers(transfers);
18863
+ const { transfersByServiceId, serviceIds: serviceIdsFromTransfers, gasLimitByServiceId: transfersGasLimitByServiceId, } = this.transformTransfers(transfers);
18771
18864
  this.transfersByServiceId = transfersByServiceId;
18772
18865
  /**
18773
18866
  * Merge service ids from reports, auto-accumulate services and transfers.
18774
18867
  *
18775
- * https://graypaper.fluffylabs.dev/#/68eaa1f/175f01175f01?v=0.6.4
18868
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/173803174b03?v=0.7.2
18776
18869
  */
18777
18870
  this.serviceIds = this.mergeServiceIds(serviceIdsFromReports, serviceIdsFromAutoAccumulate, serviceIdsFromTransfers);
18871
+ /**
18872
+ * Merge gas limits from reports, auto-accumulate services and transfers.
18873
+ *
18874
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/182001183701?v=0.7.2
18875
+ */
18876
+ this.gasLimitByServiceId = this.mergeGasLimitByServiceId(this.serviceIds, autoAccumulateServicesByServiceId, reportsGasLimitByServiceId, transfersGasLimitByServiceId);
18877
+ }
18878
+ /**
18879
+ * Calculate the gas limit implied by the selected deferred-transfers, work-reports and gas-privileges.
18880
+ *
18881
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/182001183701?v=0.7.2
18882
+ */
18883
+ mergeGasLimitByServiceId(serviceIds, ...gasLimitByServiceIdMaps) {
18884
+ const gasByServiceId = new Map();
18885
+ for (const serviceId of serviceIds) {
18886
+ const { overflow, value } = sumU64(...gasLimitByServiceIdMaps.map((map) => map.get(serviceId) ?? tryAsServiceGas(0)));
18887
+ gasByServiceId.set(serviceId, tryAsServiceGas(overflow ? MAX_VALUE_U64 : value));
18888
+ }
18889
+ return gasByServiceId;
18778
18890
  }
18779
18891
  /** Merge two sets of service ids */
18780
18892
  mergeServiceIds(...sources) {
@@ -18786,50 +18898,60 @@ class accumulate_data_AccumulateData {
18786
18898
  }
18787
18899
  return Array.from(merged);
18788
18900
  }
18901
+ /**
18902
+ * Transform the list of pending transfers into:
18903
+ * - map: transfers by service id
18904
+ * - map: gas limit by service id
18905
+ * - set: service ids
18906
+ */
18789
18907
  transformTransfers(transfersToTransform) {
18790
18908
  const transfersByServiceId = new Map();
18791
18909
  const serviceIds = new Set();
18910
+ const gasLimitByServiceId = new Map();
18792
18911
  for (const transfer of transfersToTransform) {
18793
18912
  const serviceId = transfer.destination;
18794
18913
  const transfers = transfersByServiceId.get(serviceId) ?? [];
18914
+ const gas = gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
18915
+ const { value, overflow } = sumU64(gas, transfer.gas);
18916
+ gasLimitByServiceId.set(serviceId, tryAsServiceGas(overflow ? MAX_VALUE_U64 : value));
18795
18917
  transfers.push(transfer);
18796
18918
  transfersByServiceId.set(serviceId, transfers);
18797
18919
  serviceIds.add(serviceId);
18798
18920
  }
18799
- return { transfersByServiceId, serviceIds };
18800
- }
18801
- /** Transform the list of auto-accumulate services into a map by service id. */
18802
- transformAutoAccumulateServices(autoAccumulateServices) {
18803
- const serviceIds = new Set();
18804
- const autoAccumulateServicesByServiceId = new Map();
18805
- for (const autoAccumulate of autoAccumulateServices) {
18806
- autoAccumulateServicesByServiceId.set(autoAccumulate.service, autoAccumulate);
18807
- serviceIds.add(autoAccumulate.service);
18808
- }
18809
- return { autoAccumulateServicesByServiceId, serviceIds };
18921
+ return { transfersByServiceId, serviceIds, gasLimitByServiceId };
18810
18922
  }
18811
18923
  /**
18812
18924
  * A function that transform reports into a list of operands and data needed for statistics (gas cost and reports length).
18813
18925
  */
18926
+ /**
18927
+ * Transform the list of reports into:
18928
+ * - map: AccumulateDataItem by service id
18929
+ * - map: gas limit by service id
18930
+ * - set: service ids
18931
+ */
18814
18932
  transformReports(reports) {
18815
18933
  const reportsDataByServiceId = new Map();
18934
+ const gasLimitByServiceId = new Map();
18816
18935
  const serviceIds = new Set();
18817
18936
  for (const report of reports) {
18818
18937
  for (const result of report.results) {
18819
18938
  const serviceId = result.serviceId;
18820
18939
  serviceIds.add(serviceId);
18821
18940
  const item = reportsDataByServiceId.get(serviceId) ?? AccumulateDataItem.empty();
18941
+ const gas = gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
18942
+ const { value, overflow } = sumU64(gas, result.gas);
18943
+ const newGas = tryAsServiceGas(overflow ? MAX_VALUE_U64 : value);
18944
+ gasLimitByServiceId.set(serviceId, newGas);
18822
18945
  /**
18823
18946
  * We count the report results and gas cost for each service to update service statistics.
18824
18947
  *
18825
- * https://graypaper.fluffylabs.dev/#/68eaa1f/171e04174a04?v=0.6.4
18948
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/180504182604?v=0.7.2
18826
18949
  */
18827
18950
  item.reportsLength = tryAsU32(item.reportsLength + 1);
18828
- item.gasCost = tryAsServiceGas(item.gasCost + result.gas);
18829
18951
  /**
18830
18952
  * Transform report into an operand
18831
18953
  *
18832
- * https://graypaper.fluffylabs.dev/#/68eaa1f/17bf02176f03?v=0.6.4
18954
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/185901181402?v=0.7.2
18833
18955
  */
18834
18956
  item.operands.push(Operand.new({
18835
18957
  gas: result.gas, // g
@@ -18843,19 +18965,7 @@ class accumulate_data_AccumulateData {
18843
18965
  reportsDataByServiceId.set(serviceId, item);
18844
18966
  }
18845
18967
  }
18846
- /**
18847
- * Add initial gas cost - it is `U(f_s, 0)` from this formula:
18848
- *
18849
- * https://graypaper.fluffylabs.dev/#/68eaa1f/17b00217b002?v=0.6.4
18850
- */
18851
- for (const serviceId of serviceIds) {
18852
- const item = reportsDataByServiceId.get(serviceId) ?? null;
18853
- const autoAccumulateService = this.autoAccumulateServicesByServiceId.get(serviceId) ?? null;
18854
- if (item !== null && autoAccumulateService !== null) {
18855
- item.gasCost = tryAsServiceGas(item.gasCost + autoAccumulateService.gasLimit);
18856
- }
18857
- }
18858
- return { reportsDataByServiceId, serviceIds };
18968
+ return { reportsDataByServiceId, serviceIds, gasLimitByServiceId };
18859
18969
  }
18860
18970
  /** Returns the list of operands for a given service id */
18861
18971
  getOperands(serviceId) {
@@ -18869,14 +18979,14 @@ class accumulate_data_AccumulateData {
18869
18979
  getReportsLength(serviceId) {
18870
18980
  return this.reportsDataByServiceId.get(serviceId)?.reportsLength ?? tryAsU32(0);
18871
18981
  }
18872
- /** Returns the gas cost for a given service id */
18873
- getGasCost(serviceId) {
18874
- return this.reportsDataByServiceId.get(serviceId)?.gasCost ?? tryAsServiceGas(0n);
18982
+ /** Returns the gas limit for a given service id */
18983
+ getGasLimit(serviceId) {
18984
+ return this.gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
18875
18985
  }
18876
18986
  /**
18877
18987
  * Returns a list of service ids that should be accumulated.
18878
18988
  *
18879
- * https://graypaper.fluffylabs.dev/#/68eaa1f/175f01175f01?v=0.6.4
18989
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/173803174a03?v=0.7.2
18880
18990
  */
18881
18991
  getServiceIds() {
18882
18992
  return this.serviceIds;
@@ -23252,7 +23362,7 @@ class Bless {
23252
23362
  * `z`: array of key-value pairs serviceId -> gas that auto-accumulate every block
23253
23363
  * https://graypaper.fluffylabs.dev/#/7e6ff6a/368100368100?v=0.6.7
23254
23364
  */
23255
- const autoAccumulateEntries = [];
23365
+ const autoAccumulate = new Map();
23256
23366
  const result = safe_alloc_uint8array_safeAllocUint8Array(tryAsExactBytes(serviceIdAndGasCodec.sizeHint));
23257
23367
  const decoder = decoder_Decoder.fromBlob(result);
23258
23368
  let memIndex = sourceStart;
@@ -23265,7 +23375,7 @@ class Bless {
23265
23375
  return host_call_handler_PvmExecution.Panic;
23266
23376
  }
23267
23377
  const { serviceId, gas } = decoder.object(serviceIdAndGasCodec);
23268
- autoAccumulateEntries.push([serviceId, gas]);
23378
+ autoAccumulate.set(serviceId, gas);
23269
23379
  // we allow the index to go beyond `MEMORY_SIZE` (i.e. 2**32) and have the next `loadInto` fail with page fault.
23270
23380
  memIndex = numbers_tryAsU64(memIndex + numbers_tryAsU64(decoder.bytesRead()));
23271
23381
  }
@@ -23274,26 +23384,26 @@ class Bless {
23274
23384
  const authorizersDecoder = decoder_Decoder.fromBlob(res);
23275
23385
  const memoryReadResult = memory.loadInto(res, authorization);
23276
23386
  if (memoryReadResult.isError) {
23277
- logger_logger.trace `BLESS(${manager}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- PANIC`;
23387
+ logger_logger.trace `BLESS(${manager}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- PANIC`;
23278
23388
  return host_call_handler_PvmExecution.Panic;
23279
23389
  }
23280
23390
  // `a`
23281
23391
  const authorizers = common_tryAsPerCore(authorizersDecoder.sequenceFixLen(descriptors_codec.u32.asOpaque(), this.chainSpec.coresCount), this.chainSpec);
23282
- const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar, autoAccumulateEntries);
23392
+ const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar, autoAccumulate);
23283
23393
  if (updateResult.isOk) {
23284
- logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- OK`;
23394
+ logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- OK`;
23285
23395
  regs.set(bless_IN_OUT_REG, results_HostCallResult.OK);
23286
23396
  return;
23287
23397
  }
23288
23398
  const e = updateResult.error;
23289
23399
  // NOTE: `UpdatePrivilegesError.UnprivilegedService` won't happen in 0.7.1+
23290
23400
  if (e === partial_state_UpdatePrivilegesError.UnprivilegedService) {
23291
- logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- HUH`;
23401
+ logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- HUH`;
23292
23402
  regs.set(bless_IN_OUT_REG, results_HostCallResult.HUH);
23293
23403
  return;
23294
23404
  }
23295
23405
  if (e === partial_state_UpdatePrivilegesError.InvalidServiceId) {
23296
- logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- WHO`;
23406
+ logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- WHO`;
23297
23407
  regs.set(bless_IN_OUT_REG, results_HostCallResult.WHO);
23298
23408
  return;
23299
23409
  }
@@ -24117,8 +24227,8 @@ var FetchKind;
24117
24227
 
24118
24228
 
24119
24229
  const info_IN_OUT_REG = 7;
24120
- const OFFSET_REG = compatibility_Compatibility.isSuite(TestSuite.W3F_DAVXY) || compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 9 : 11;
24121
- const LEN_REG = compatibility_Compatibility.isSuite(TestSuite.W3F_DAVXY) || compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 10 : 12;
24230
+ const OFFSET_REG = compatibility_Compatibility.isSuite(compatibility_TestSuite.W3F_DAVXY) || compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 9 : 11;
24231
+ const LEN_REG = compatibility_Compatibility.isSuite(compatibility_TestSuite.W3F_DAVXY) || compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 10 : 12;
24122
24232
  /**
24123
24233
  * Return info about some account.
24124
24234
  *
@@ -24593,6 +24703,7 @@ class pvm_executor_PvmExecutor {
24593
24703
 
24594
24704
 
24595
24705
 
24706
+
24596
24707
  const ACCUMULATION_ERROR = "duplicate service created";
24597
24708
  var PvmInvocationError;
24598
24709
  (function (PvmInvocationError) {
@@ -24761,7 +24872,7 @@ class accumulate_Accumulate {
24761
24872
  const { gasCost, state: stateAfterParallelAcc, ...rest } = await this.accumulateInParallel(accumulateData, slot, entropy, statistics, stateUpdate);
24762
24873
  assertEmpty(rest);
24763
24874
  // NOTE [ToDr] recursive invocation
24764
- const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentiallyLegacy(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, slot, entropy, statistics, stateAfterParallelAcc, []);
24875
+ const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentiallyLegacy(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, slot, entropy, statistics, stateAfterParallelAcc, new Map());
24765
24876
  assertEmpty(seqRest);
24766
24877
  return {
24767
24878
  accumulatedReports: tryAsU32(i + accumulatedReports),
@@ -24793,8 +24904,15 @@ class accumulate_Accumulate {
24793
24904
  const { gasCost, state: stateAfterParallelAcc, ...rest } = await this.accumulateInParallel(accumulateData, slot, entropy, statistics, stateUpdate);
24794
24905
  const newTransfers = stateAfterParallelAcc.takeTransfers();
24795
24906
  assertEmpty(rest);
24907
+ /**
24908
+ * Gas limit from transfers is added to the next round of accumulation
24909
+ *
24910
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/172b02172b02?v=0.7.2
24911
+ */
24912
+ const transfersGas = transfers.map((t) => t.gas);
24913
+ const { value: newGasLimit, overflow } = sumU64(tryAsServiceGas(gasLimit - gasCost), ...transfersGas);
24796
24914
  // NOTE [ToDr] recursive invocation
24797
- const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentially(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, newTransfers, slot, entropy, statistics, stateAfterParallelAcc, []);
24915
+ const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentially(tryAsServiceGas(overflow ? MAX_VALUE_U64 : newGasLimit), reportsToAccumulateSequentially, newTransfers, slot, entropy, statistics, stateAfterParallelAcc, new Map());
24798
24916
  assertEmpty(seqRest);
24799
24917
  return {
24800
24918
  accumulatedReports: tryAsU32(i + accumulatedReports),
@@ -24820,14 +24938,16 @@ class accumulate_Accumulate {
24820
24938
  for (const serviceId of serviceIds) {
24821
24939
  const checkpoint = AccumulationStateUpdate.copyFrom(currentState);
24822
24940
  const operands = accumulateData.getOperands(serviceId);
24823
- const { consumedGas, stateUpdate } = await this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), operands, accumulateData.getGasCost(serviceId), slot, entropy, currentState);
24941
+ const { consumedGas, stateUpdate } = await this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), operands, accumulateData.getGasLimit(serviceId), slot, entropy, currentState);
24824
24942
  gasCost = tryAsServiceGas(gasCost + consumedGas);
24825
24943
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/193b05193b05?v=0.7.2
24826
24944
  const serviceStatistics = statistics.get(serviceId) ?? { count: tryAsU32(0), gasUsed: tryAsServiceGas(0) };
24827
24945
  const count = accumulateData.getReportsLength(serviceId);
24828
24946
  // [0.7.1]: do not update statistics, if the service only had incoming transfers
24829
24947
  if ((Compatibility.isLessThan(GpVersion.V0_7_2) && count > 0) ||
24830
- (Compatibility.isGreaterOrEqual(GpVersion.V0_7_2) && (count > 0 || consumedGas > 0n))) {
24948
+ ((Compatibility.isGreaterOrEqual(GpVersion.V0_7_2) ||
24949
+ (Compatibility.isSuite(TestSuite.W3F_DAVXY) && Compatibility.is(GpVersion.V0_7_1))) &&
24950
+ (count > 0 || consumedGas > 0n))) {
24831
24951
  serviceStatistics.count = tryAsU32(serviceStatistics.count + count);
24832
24952
  serviceStatistics.gasUsed = tryAsServiceGas(serviceStatistics.gasUsed + consumedGas);
24833
24953
  statistics.set(serviceId, serviceStatistics);
@@ -24840,7 +24960,7 @@ class accumulate_Accumulate {
24840
24960
  // Since serviceIds already contains newV, this service gets accumulated twice.
24841
24961
  // To avoid double-counting, we skip stats and gas cost tracking here.
24842
24962
  // We need this accumulation to get the correct `delegator`
24843
- const { stateUpdate } = await this.accumulateSingleService(newV, [], accumulateData.getOperands(newV), accumulateData.getGasCost(newV), slot, entropy, checkpoint);
24963
+ const { stateUpdate } = await this.accumulateSingleService(newV, [], accumulateData.getOperands(newV), accumulateData.getGasLimit(newV), slot, entropy, checkpoint);
24844
24964
  const correctV = stateUpdate?.privilegedServices?.delegator ?? this.state.privilegedServices.delegator;
24845
24965
  currentState.privilegedServices = PrivilegedServices.create({
24846
24966
  ...currentState.privilegedServices,
@@ -24906,7 +25026,7 @@ class accumulate_Accumulate {
24906
25026
  */
24907
25027
  getGasLimit() {
24908
25028
  const calculatedGasLimit = GAS_TO_INVOKE_WORK_REPORT * BigInt(this.chainSpec.coresCount) +
24909
- this.state.privilegedServices.autoAccumulateServices.reduce((acc, { gasLimit }) => acc + gasLimit, 0n);
25029
+ Array.from(this.state.privilegedServices.autoAccumulateServices.values()).reduce((acc, gasLimit) => acc + gasLimit, 0n);
24910
25030
  const gasLimit = tryAsServiceGas(this.chainSpec.maxBlockGas > calculatedGasLimit ? this.chainSpec.maxBlockGas : calculatedGasLimit);
24911
25031
  return tryAsServiceGas(gasLimit);
24912
25032
  }
@@ -25059,9 +25179,8 @@ class deferred_transfers_DeferredTransfers {
25059
25179
  consumedGas = (await executor.run(args, tryAsGas(gas))).consumedGas;
25060
25180
  }
25061
25181
  transferStatistics.set(serviceId, { count: tryAsU32(transfers.length), gasUsed: tryAsServiceGas(consumedGas) });
25062
- const [updatedState, checkpointedState] = partialState.getStateUpdates();
25182
+ const [updatedState] = partialState.getStateUpdates();
25063
25183
  currentStateUpdate = updatedState;
25064
- check `${checkpointedState === null} On transfer cannot invoke checkpoint.`;
25065
25184
  }
25066
25185
  return Result.ok({
25067
25186
  // NOTE: we return only services, since it's impossible to update
@@ -26378,7 +26497,6 @@ class statistics_Statistics {
26378
26497
 
26379
26498
 
26380
26499
 
26381
-
26382
26500
  class DbHeaderChain {
26383
26501
  blocks;
26384
26502
  constructor(blocks) {
@@ -26449,7 +26567,7 @@ class chain_stf_OnChain {
26449
26567
  // chapter 13: https://graypaper.fluffylabs.dev/#/68eaa1f/18b60118b601?v=0.6.4
26450
26568
  statistics;
26451
26569
  isReadyForNextEpoch = Promise.resolve(false);
26452
- constructor(chainSpec, state, blocks, hasher, pvm = PvmBackend.BuiltIn) {
26570
+ constructor(chainSpec, state, blocks, hasher, pvm) {
26453
26571
  this.chainSpec = chainSpec;
26454
26572
  this.state = state;
26455
26573
  this.hasher = hasher;
@@ -26743,7 +26861,6 @@ function state_loader_loadState(spec, blake2b, keyvals) {
26743
26861
 
26744
26862
 
26745
26863
 
26746
-
26747
26864
  class StateTransitionGenesis {
26748
26865
  static fromJson = {
26749
26866
  header: headerFromJson,
@@ -26773,7 +26890,7 @@ class StateTransition {
26773
26890
  }
26774
26891
  const keccakHasher = keccak_KeccakHasher.create();
26775
26892
  const cachedBlocks = new Map();
26776
- function loadBlocks(testPath) {
26893
+ function loadBlocks(testPath, spec) {
26777
26894
  const dir = path.dirname(testPath);
26778
26895
  const fromCache = cachedBlocks.get(dir);
26779
26896
  if (fromCache !== undefined) {
@@ -26781,20 +26898,19 @@ function loadBlocks(testPath) {
26781
26898
  }
26782
26899
  const blocks = [];
26783
26900
  for (const file of fs.readdirSync(dir)) {
26784
- if (!file.endsWith(".json")) {
26901
+ if (!file.endsWith(".bin")) {
26785
26902
  continue;
26786
26903
  }
26787
- const data = fs.readFileSync(path.join(dir, file), "utf8");
26788
- const parsed = JSON.parse(data);
26904
+ const data = fs.readFileSync(path.join(dir, file));
26789
26905
  try {
26790
- if (file.endsWith("genesis.json")) {
26791
- const content = parseFromJson(parsed, StateTransitionGenesis.fromJson);
26792
- const genesisBlock = Block.create({ header: content.header, extrinsic: emptyBlock().extrinsic });
26906
+ if (file.endsWith("genesis.bin")) {
26907
+ const genesis = Decoder.decodeObject(StateTransitionGenesis.Codec, data, spec);
26908
+ const genesisBlock = Block.create({ header: genesis.header, extrinsic: emptyBlock().extrinsic });
26793
26909
  blocks.push(genesisBlock);
26794
26910
  }
26795
26911
  else {
26796
- const content = parseFromJson(parsed, StateTransition.fromJson);
26797
- blocks.push(content.block);
26912
+ const test = Decoder.decodeObject(StateTransition.Codec, data, spec);
26913
+ blocks.push(test.block);
26798
26914
  }
26799
26915
  }
26800
26916
  catch {
@@ -26816,20 +26932,20 @@ const jamConformance070V0Spec = new ChainSpec({
26816
26932
  ...chain_spec_tinyChainSpec,
26817
26933
  maxLookupAnchorAge: numbers_tryAsU32(14_400),
26818
26934
  });
26819
- async function runStateTransition(testContent, testPath, t) {
26935
+ async function runStateTransition(testContent, testPath, t, chainSpec) {
26820
26936
  const blake2b = await Blake2b.createHasher();
26821
26937
  // a bit of a hack, but the new value for `maxLookupAnchorAge` was proposed with V1
26822
26938
  // version of the fuzzer, yet these tests were still depending on the older value.
26823
26939
  // To simplify the chain spec, we just special case this one vector here.
26824
26940
  const spec = testPath.includes("fuzz-reports/0.7.0/traces/1756548916/00000082.json")
26825
26941
  ? jamConformance070V0Spec
26826
- : tinyChainSpec;
26942
+ : chainSpec;
26827
26943
  const preState = loadState(spec, blake2b, testContent.pre_state.keyvals);
26828
26944
  const postState = loadState(spec, blake2b, testContent.post_state.keyvals);
26829
26945
  const preStateRoot = preState.backend.getRootHash(blake2b);
26830
26946
  const postStateRoot = postState.backend.getRootHash(blake2b);
26831
26947
  const blockView = blockAsView(spec, testContent.block);
26832
- const allBlocks = loadBlocks(testPath);
26948
+ const allBlocks = loadBlocks(testPath, spec);
26833
26949
  const myBlockIndex = allBlocks.findIndex(({ header }) => header.timeSlotIndex === testContent.block.header.timeSlotIndex);
26834
26950
  const previousBlocks = allBlocks.slice(0, myBlockIndex);
26835
26951
  const hasher = new TransitionHasher(spec, await keccakHasher, blake2b);
@@ -26838,7 +26954,7 @@ async function runStateTransition(testContent, testPath, t) {
26838
26954
  const headerHash = hasher.header(blockView.header.view());
26839
26955
  return new WithHash(headerHash.hash, blockView);
26840
26956
  }));
26841
- const stf = new OnChain(spec, preState, blocksDb, hasher);
26957
+ const stf = new OnChain(spec, preState, blocksDb, hasher, PvmBackend.BuiltIn);
26842
26958
  // verify that we compute the state root exactly the same.
26843
26959
  assert.deepStrictEqual(testContent.pre_state.state_root.toString(), preStateRoot.toString());
26844
26960
  assert.deepStrictEqual(testContent.post_state.state_root.toString(), postStateRoot.toString());