@typeberry/jam 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.
@@ -3541,44 +3541,40 @@ var compatibility_GpVersion;
3541
3541
  GpVersion["V0_6_7"] = "0.6.7";
3542
3542
  GpVersion["V0_7_0"] = "0.7.0";
3543
3543
  GpVersion["V0_7_1"] = "0.7.1";
3544
- GpVersion["V0_7_2"] = "0.7.2-preview";
3544
+ GpVersion["V0_7_2"] = "0.7.2";
3545
3545
  })(compatibility_GpVersion || (compatibility_GpVersion = {}));
3546
3546
  var TestSuite;
3547
3547
  (function (TestSuite) {
3548
3548
  TestSuite["W3F_DAVXY"] = "w3f-davxy";
3549
3549
  TestSuite["JAMDUNA"] = "jamduna";
3550
3550
  })(TestSuite || (TestSuite = {}));
3551
+ 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];
3551
3552
  const DEFAULT_SUITE = TestSuite.W3F_DAVXY;
3552
- const DEFAULT_VERSION = compatibility_GpVersion.V0_7_1;
3553
+ const DEFAULT_VERSION = compatibility_GpVersion.V0_7_2;
3553
3554
  const env = typeof process === "undefined" ? {} : process.env;
3554
3555
  let CURRENT_VERSION = parseCurrentVersion(env.GP_VERSION) ?? DEFAULT_VERSION;
3555
3556
  let CURRENT_SUITE = parseCurrentSuite(env.TEST_SUITE) ?? DEFAULT_SUITE;
3556
- 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];
3557
3557
  function parseCurrentVersion(env) {
3558
3558
  if (env === undefined) {
3559
3559
  return undefined;
3560
3560
  }
3561
- switch (env) {
3562
- case compatibility_GpVersion.V0_6_7:
3563
- case compatibility_GpVersion.V0_7_0:
3564
- case compatibility_GpVersion.V0_7_1:
3565
- case compatibility_GpVersion.V0_7_2:
3566
- return env;
3567
- default:
3568
- throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
3561
+ for (const v of Object.values(compatibility_GpVersion)) {
3562
+ if (env === v) {
3563
+ return v;
3564
+ }
3569
3565
  }
3566
+ throw new Error(`Configured environment variable GP_VERSION is unknown: '${env}'. Use one of: ${ALL_VERSIONS_IN_ORDER}`);
3570
3567
  }
3571
3568
  function parseCurrentSuite(env) {
3572
3569
  if (env === undefined) {
3573
3570
  return undefined;
3574
3571
  }
3575
- switch (env) {
3576
- case TestSuite.W3F_DAVXY:
3577
- case TestSuite.JAMDUNA:
3578
- return env;
3579
- default:
3580
- throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`);
3572
+ for (const s of Object.values(TestSuite)) {
3573
+ if (env === s) {
3574
+ return s;
3575
+ }
3581
3576
  }
3577
+ throw new Error(`Configured environment variable TEST_SUITE is unknown: '${env}'. Use one of: ${Object.values(TestSuite)}`);
3582
3578
  }
3583
3579
  class compatibility_Compatibility {
3584
3580
  static override(version) {
@@ -3739,6 +3735,13 @@ class WithDebug {
3739
3735
  return debug_inspect(this);
3740
3736
  }
3741
3737
  }
3738
+ function lazyInspect(obj) {
3739
+ return {
3740
+ toString() {
3741
+ return debug_inspect(obj);
3742
+ },
3743
+ };
3744
+ }
3742
3745
 
3743
3746
  ;// CONCATENATED MODULE: ./packages/core/utils/dev.ts
3744
3747
  const dev_env = typeof process === "undefined" ? {} : process.env;
@@ -9774,7 +9777,7 @@ function hashComparator(a, b) {
9774
9777
 
9775
9778
  ;// CONCATENATED MODULE: ./packages/core/pvm-interpreter/ops/math-consts.ts
9776
9779
  const MAX_VALUE = 4294967295;
9777
- const math_consts_MAX_VALUE_U64 = (/* unused pure expression or super */ null && (2n ** 63n));
9780
+ const math_consts_MAX_VALUE_U64 = 2n ** 63n;
9778
9781
  const MIN_VALUE = -(2 ** 31);
9779
9782
  const MAX_SHIFT_U32 = 32;
9780
9783
  const MAX_SHIFT_U64 = 64n;
@@ -10559,26 +10562,6 @@ class InMemoryStateView {
10559
10562
 
10560
10563
 
10561
10564
 
10562
- /** Dictionary entry of services that auto-accumulate every block. */
10563
- class AutoAccumulate {
10564
- service;
10565
- gasLimit;
10566
- static Codec = descriptors_codec.Class(AutoAccumulate, {
10567
- service: descriptors_codec.u32.asOpaque(),
10568
- gasLimit: descriptors_codec.u64.asOpaque(),
10569
- });
10570
- static create({ service, gasLimit }) {
10571
- return new AutoAccumulate(service, gasLimit);
10572
- }
10573
- constructor(
10574
- /** Service id that auto-accumulates. */
10575
- service,
10576
- /** Gas limit for auto-accumulation. */
10577
- gasLimit) {
10578
- this.service = service;
10579
- this.gasLimit = gasLimit;
10580
- }
10581
- }
10582
10565
  /**
10583
10566
  * https://graypaper.fluffylabs.dev/#/ab2cdbd/114402114402?v=0.7.2
10584
10567
  */
@@ -10596,7 +10579,9 @@ class PrivilegedServices {
10596
10579
  registrar: compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_1)
10597
10580
  ? descriptors_codec.u32.asOpaque()
10598
10581
  : ignoreValueWithDefault(tryAsServiceId(2 ** 32 - 1)),
10599
- autoAccumulateServices: readonlyArray(descriptors_codec.sequenceVarLen(AutoAccumulate.Codec)),
10582
+ autoAccumulateServices: descriptors_codec.dictionary(descriptors_codec.u32.asOpaque(), descriptors_codec.u64.asOpaque(), {
10583
+ sortKeys: (a, b) => a - b,
10584
+ }),
10600
10585
  });
10601
10586
  static create(a) {
10602
10587
  return new PrivilegedServices(a.manager, a.delegator, a.registrar, a.assigners, a.autoAccumulateServices);
@@ -11229,7 +11214,7 @@ class InMemoryState extends WithDebug {
11229
11214
  assigners: tryAsPerCore(new Array(spec.coresCount).fill(tryAsServiceId(0)), spec),
11230
11215
  delegator: tryAsServiceId(0),
11231
11216
  registrar: tryAsServiceId(MAX_VALUE),
11232
- autoAccumulateServices: [],
11217
+ autoAccumulateServices: new Map(),
11233
11218
  }),
11234
11219
  accumulationOutputLog: SortedArray.fromArray(accumulationOutputComparator, []),
11235
11220
  services: new Map(),
@@ -14768,7 +14753,7 @@ class AccumulateExternalities {
14768
14753
  updatedState;
14769
14754
  currentServiceId;
14770
14755
  currentTimeslot;
14771
- checkpointedState = null;
14756
+ checkpointedState;
14772
14757
  /** `x_i`: next service id we are going to create. */
14773
14758
  nextNewServiceId;
14774
14759
  constructor(chainSpec, blake2b, updatedState,
@@ -14779,13 +14764,14 @@ class AccumulateExternalities {
14779
14764
  this.updatedState = updatedState;
14780
14765
  this.currentServiceId = currentServiceId;
14781
14766
  this.currentTimeslot = currentTimeslot;
14767
+ this.checkpointedState = AccumulationStateUpdate.copyFrom(updatedState.stateUpdate);
14782
14768
  this.nextNewServiceId = this.getNextAvailableServiceId(nextNewServiceIdCandidate);
14783
14769
  const service = this.updatedState.getServiceInfo(this.currentServiceId);
14784
14770
  if (service === null) {
14785
14771
  throw new Error(`Invalid state initialization. Service info missing for ${this.currentServiceId}.`);
14786
14772
  }
14787
14773
  }
14788
- /** Return the underlying state update and checkpointed state (if any). */
14774
+ /** Return the underlying state update and checkpointed state. */
14789
14775
  getStateUpdates() {
14790
14776
  return [this.updatedState.stateUpdate, this.checkpointedState];
14791
14777
  }
@@ -15152,7 +15138,7 @@ class AccumulateExternalities {
15152
15138
  assigners: authorizers,
15153
15139
  delegator: delegator,
15154
15140
  registrar: registrar ?? tryAsServiceId(0),
15155
- autoAccumulateServices: autoAccumulate.map(([service, gasLimit]) => AutoAccumulate.create({ service, gasLimit })),
15141
+ autoAccumulateServices: autoAccumulate,
15156
15142
  });
15157
15143
  return Result.ok(OK);
15158
15144
  }
@@ -15176,9 +15162,7 @@ class AccumulateExternalities {
15176
15162
  isAlreadyChanged: currentAssigner !== original.assigners[index],
15177
15163
  }));
15178
15164
  const newManager = isManager ? manager : current.manager;
15179
- const newAutoAccumulateServices = isManager
15180
- ? autoAccumulate.map(([service, gasLimit]) => AutoAccumulate.create({ service, gasLimit }))
15181
- : current.autoAccumulateServices;
15165
+ const newAutoAccumulateServices = isManager ? autoAccumulate : current.autoAccumulateServices;
15182
15166
  // finally update the privileges
15183
15167
  this.updatedState.stateUpdate.privilegedServices = PrivilegedServices.create({
15184
15168
  manager: newManager,
@@ -15810,17 +15794,16 @@ class FetchExternalities {
15810
15794
 
15811
15795
 
15812
15796
 
15797
+
15813
15798
  class AccumulateDataItem {
15814
15799
  operands;
15815
15800
  reportsLength;
15816
- gasCost;
15817
- constructor(operands, reportsLength, gasCost) {
15801
+ constructor(operands, reportsLength) {
15818
15802
  this.operands = operands;
15819
15803
  this.reportsLength = reportsLength;
15820
- this.gasCost = gasCost;
15821
15804
  }
15822
15805
  static empty() {
15823
- return new AccumulateDataItem([], numbers_tryAsU32(0), tryAsServiceGas(0n));
15806
+ return new AccumulateDataItem([], numbers_tryAsU32(0));
15824
15807
  }
15825
15808
  }
15826
15809
  /**
@@ -15830,23 +15813,43 @@ class AccumulateDataItem {
15830
15813
  * - gas cost and reports length for each service (statistics)
15831
15814
  */
15832
15815
  class AccumulateData {
15816
+ autoAccumulateServicesByServiceId;
15833
15817
  reportsDataByServiceId;
15834
15818
  transfersByServiceId;
15835
- autoAccumulateServicesByServiceId;
15836
15819
  serviceIds;
15837
- constructor(reports, transfers, autoAccumulateServices) {
15838
- const { autoAccumulateServicesByServiceId, serviceIds: serviceIdsFromAutoAccumulate } = this.transformAutoAccumulateServices(autoAccumulateServices);
15820
+ gasLimitByServiceId;
15821
+ constructor(reports, transfers, autoAccumulateServicesByServiceId) {
15839
15822
  this.autoAccumulateServicesByServiceId = autoAccumulateServicesByServiceId;
15840
- const { reportsDataByServiceId, serviceIds: serviceIdsFromReports } = this.transformReports(reports);
15823
+ const serviceIdsFromAutoAccumulate = new Set(autoAccumulateServicesByServiceId.keys());
15824
+ const { reportsDataByServiceId, serviceIds: serviceIdsFromReports, gasLimitByServiceId: reportsGasLimitByServiceId, } = this.transformReports(reports);
15841
15825
  this.reportsDataByServiceId = reportsDataByServiceId;
15842
- const { transfersByServiceId, serviceIds: serviceIdsFromTransfers } = this.transformTransfers(transfers);
15826
+ const { transfersByServiceId, serviceIds: serviceIdsFromTransfers, gasLimitByServiceId: transfersGasLimitByServiceId, } = this.transformTransfers(transfers);
15843
15827
  this.transfersByServiceId = transfersByServiceId;
15844
15828
  /**
15845
15829
  * Merge service ids from reports, auto-accumulate services and transfers.
15846
15830
  *
15847
- * https://graypaper.fluffylabs.dev/#/68eaa1f/175f01175f01?v=0.6.4
15831
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/173803174b03?v=0.7.2
15848
15832
  */
15849
15833
  this.serviceIds = this.mergeServiceIds(serviceIdsFromReports, serviceIdsFromAutoAccumulate, serviceIdsFromTransfers);
15834
+ /**
15835
+ * Merge gas limits from reports, auto-accumulate services and transfers.
15836
+ *
15837
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/182001183701?v=0.7.2
15838
+ */
15839
+ this.gasLimitByServiceId = this.mergeGasLimitByServiceId(this.serviceIds, autoAccumulateServicesByServiceId, reportsGasLimitByServiceId, transfersGasLimitByServiceId);
15840
+ }
15841
+ /**
15842
+ * Calculate the gas limit implied by the selected deferred-transfers, work-reports and gas-privileges.
15843
+ *
15844
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/182001183701?v=0.7.2
15845
+ */
15846
+ mergeGasLimitByServiceId(serviceIds, ...gasLimitByServiceIdMaps) {
15847
+ const gasByServiceId = new Map();
15848
+ for (const serviceId of serviceIds) {
15849
+ const { overflow, value } = sumU64(...gasLimitByServiceIdMaps.map((map) => map.get(serviceId) ?? tryAsServiceGas(0)));
15850
+ gasByServiceId.set(serviceId, tryAsServiceGas(overflow ? math_consts_MAX_VALUE_U64 : value));
15851
+ }
15852
+ return gasByServiceId;
15850
15853
  }
15851
15854
  /** Merge two sets of service ids */
15852
15855
  mergeServiceIds(...sources) {
@@ -15858,50 +15861,60 @@ class AccumulateData {
15858
15861
  }
15859
15862
  return Array.from(merged);
15860
15863
  }
15864
+ /**
15865
+ * Transform the list of pending transfers into:
15866
+ * - map: transfers by service id
15867
+ * - map: gas limit by service id
15868
+ * - set: service ids
15869
+ */
15861
15870
  transformTransfers(transfersToTransform) {
15862
15871
  const transfersByServiceId = new Map();
15863
15872
  const serviceIds = new Set();
15873
+ const gasLimitByServiceId = new Map();
15864
15874
  for (const transfer of transfersToTransform) {
15865
15875
  const serviceId = transfer.destination;
15866
15876
  const transfers = transfersByServiceId.get(serviceId) ?? [];
15877
+ const gas = gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
15878
+ const { value, overflow } = sumU64(gas, transfer.gas);
15879
+ gasLimitByServiceId.set(serviceId, tryAsServiceGas(overflow ? math_consts_MAX_VALUE_U64 : value));
15867
15880
  transfers.push(transfer);
15868
15881
  transfersByServiceId.set(serviceId, transfers);
15869
15882
  serviceIds.add(serviceId);
15870
15883
  }
15871
- return { transfersByServiceId, serviceIds };
15872
- }
15873
- /** Transform the list of auto-accumulate services into a map by service id. */
15874
- transformAutoAccumulateServices(autoAccumulateServices) {
15875
- const serviceIds = new Set();
15876
- const autoAccumulateServicesByServiceId = new Map();
15877
- for (const autoAccumulate of autoAccumulateServices) {
15878
- autoAccumulateServicesByServiceId.set(autoAccumulate.service, autoAccumulate);
15879
- serviceIds.add(autoAccumulate.service);
15880
- }
15881
- return { autoAccumulateServicesByServiceId, serviceIds };
15884
+ return { transfersByServiceId, serviceIds, gasLimitByServiceId };
15882
15885
  }
15883
15886
  /**
15884
15887
  * A function that transform reports into a list of operands and data needed for statistics (gas cost and reports length).
15885
15888
  */
15889
+ /**
15890
+ * Transform the list of reports into:
15891
+ * - map: AccumulateDataItem by service id
15892
+ * - map: gas limit by service id
15893
+ * - set: service ids
15894
+ */
15886
15895
  transformReports(reports) {
15887
15896
  const reportsDataByServiceId = new Map();
15897
+ const gasLimitByServiceId = new Map();
15888
15898
  const serviceIds = new Set();
15889
15899
  for (const report of reports) {
15890
15900
  for (const result of report.results) {
15891
15901
  const serviceId = result.serviceId;
15892
15902
  serviceIds.add(serviceId);
15893
15903
  const item = reportsDataByServiceId.get(serviceId) ?? AccumulateDataItem.empty();
15904
+ const gas = gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
15905
+ const { value, overflow } = sumU64(gas, result.gas);
15906
+ const newGas = tryAsServiceGas(overflow ? math_consts_MAX_VALUE_U64 : value);
15907
+ gasLimitByServiceId.set(serviceId, newGas);
15894
15908
  /**
15895
15909
  * We count the report results and gas cost for each service to update service statistics.
15896
15910
  *
15897
- * https://graypaper.fluffylabs.dev/#/68eaa1f/171e04174a04?v=0.6.4
15911
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/180504182604?v=0.7.2
15898
15912
  */
15899
15913
  item.reportsLength = numbers_tryAsU32(item.reportsLength + 1);
15900
- item.gasCost = tryAsServiceGas(item.gasCost + result.gas);
15901
15914
  /**
15902
15915
  * Transform report into an operand
15903
15916
  *
15904
- * https://graypaper.fluffylabs.dev/#/68eaa1f/17bf02176f03?v=0.6.4
15917
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/185901181402?v=0.7.2
15905
15918
  */
15906
15919
  item.operands.push(Operand.new({
15907
15920
  gas: result.gas, // g
@@ -15915,19 +15928,7 @@ class AccumulateData {
15915
15928
  reportsDataByServiceId.set(serviceId, item);
15916
15929
  }
15917
15930
  }
15918
- /**
15919
- * Add initial gas cost - it is `U(f_s, 0)` from this formula:
15920
- *
15921
- * https://graypaper.fluffylabs.dev/#/68eaa1f/17b00217b002?v=0.6.4
15922
- */
15923
- for (const serviceId of serviceIds) {
15924
- const item = reportsDataByServiceId.get(serviceId) ?? null;
15925
- const autoAccumulateService = this.autoAccumulateServicesByServiceId.get(serviceId) ?? null;
15926
- if (item !== null && autoAccumulateService !== null) {
15927
- item.gasCost = tryAsServiceGas(item.gasCost + autoAccumulateService.gasLimit);
15928
- }
15929
- }
15930
- return { reportsDataByServiceId, serviceIds };
15931
+ return { reportsDataByServiceId, serviceIds, gasLimitByServiceId };
15931
15932
  }
15932
15933
  /** Returns the list of operands for a given service id */
15933
15934
  getOperands(serviceId) {
@@ -15941,14 +15942,14 @@ class AccumulateData {
15941
15942
  getReportsLength(serviceId) {
15942
15943
  return this.reportsDataByServiceId.get(serviceId)?.reportsLength ?? numbers_tryAsU32(0);
15943
15944
  }
15944
- /** Returns the gas cost for a given service id */
15945
- getGasCost(serviceId) {
15946
- return this.reportsDataByServiceId.get(serviceId)?.gasCost ?? tryAsServiceGas(0n);
15945
+ /** Returns the gas limit for a given service id */
15946
+ getGasLimit(serviceId) {
15947
+ return this.gasLimitByServiceId.get(serviceId) ?? tryAsServiceGas(0n);
15947
15948
  }
15948
15949
  /**
15949
15950
  * Returns a list of service ids that should be accumulated.
15950
15951
  *
15951
- * https://graypaper.fluffylabs.dev/#/68eaa1f/175f01175f01?v=0.6.4
15952
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/173803174a03?v=0.7.2
15952
15953
  */
15953
15954
  getServiceIds() {
15954
15955
  return this.serviceIds;
@@ -21138,7 +21139,7 @@ class Bless {
21138
21139
  * `z`: array of key-value pairs serviceId -> gas that auto-accumulate every block
21139
21140
  * https://graypaper.fluffylabs.dev/#/7e6ff6a/368100368100?v=0.6.7
21140
21141
  */
21141
- const autoAccumulateEntries = [];
21142
+ const autoAccumulate = new Map();
21142
21143
  const result = safe_alloc_uint8array_safeAllocUint8Array(tryAsExactBytes(serviceIdAndGasCodec.sizeHint));
21143
21144
  const decoder = decoder_Decoder.fromBlob(result);
21144
21145
  let memIndex = sourceStart;
@@ -21151,7 +21152,7 @@ class Bless {
21151
21152
  return PvmExecution.Panic;
21152
21153
  }
21153
21154
  const { serviceId, gas } = decoder.object(serviceIdAndGasCodec);
21154
- autoAccumulateEntries.push([serviceId, gas]);
21155
+ autoAccumulate.set(serviceId, gas);
21155
21156
  // we allow the index to go beyond `MEMORY_SIZE` (i.e. 2**32) and have the next `loadInto` fail with page fault.
21156
21157
  memIndex = numbers_tryAsU64(memIndex + numbers_tryAsU64(decoder.bytesRead()));
21157
21158
  }
@@ -21160,26 +21161,26 @@ class Bless {
21160
21161
  const authorizersDecoder = decoder_Decoder.fromBlob(res);
21161
21162
  const memoryReadResult = memory.loadInto(res, authorization);
21162
21163
  if (memoryReadResult.isError) {
21163
- logger_logger.trace `BLESS(${manager}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- PANIC`;
21164
+ logger_logger.trace `BLESS(${manager}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- PANIC`;
21164
21165
  return PvmExecution.Panic;
21165
21166
  }
21166
21167
  // `a`
21167
21168
  const authorizers = tryAsPerCore(authorizersDecoder.sequenceFixLen(descriptors_codec.u32.asOpaque(), this.chainSpec.coresCount), this.chainSpec);
21168
- const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar, autoAccumulateEntries);
21169
+ const updateResult = this.partialState.updatePrivilegedServices(manager, authorizers, delegator, registrar, autoAccumulate);
21169
21170
  if (updateResult.isOk) {
21170
- logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- OK`;
21171
+ logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- OK`;
21171
21172
  regs.set(bless_IN_OUT_REG, HostCallResult.OK);
21172
21173
  return;
21173
21174
  }
21174
21175
  const e = updateResult.error;
21175
21176
  // NOTE: `UpdatePrivilegesError.UnprivilegedService` won't happen in 0.7.1+
21176
21177
  if (e === UpdatePrivilegesError.UnprivilegedService) {
21177
- logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- HUH`;
21178
+ logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- HUH`;
21178
21179
  regs.set(bless_IN_OUT_REG, HostCallResult.HUH);
21179
21180
  return;
21180
21181
  }
21181
21182
  if (e === UpdatePrivilegesError.InvalidServiceId) {
21182
- logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${autoAccumulateEntries}) <- WHO`;
21183
+ logger_logger.trace `BLESS(${manager}, ${authorizers}, ${delegator}, ${registrar}, ${lazyInspect(autoAccumulate)}) <- WHO`;
21183
21184
  regs.set(bless_IN_OUT_REG, HostCallResult.WHO);
21184
21185
  return;
21185
21186
  }
@@ -22479,6 +22480,7 @@ class PvmExecutor {
22479
22480
 
22480
22481
 
22481
22482
 
22483
+
22482
22484
  const ACCUMULATION_ERROR = "duplicate service created";
22483
22485
  var PvmInvocationError;
22484
22486
  (function (PvmInvocationError) {
@@ -22647,7 +22649,7 @@ class Accumulate {
22647
22649
  const { gasCost, state: stateAfterParallelAcc, ...rest } = await this.accumulateInParallel(accumulateData, slot, entropy, statistics, stateUpdate);
22648
22650
  assertEmpty(rest);
22649
22651
  // NOTE [ToDr] recursive invocation
22650
- const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentiallyLegacy(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, slot, entropy, statistics, stateAfterParallelAcc, []);
22652
+ const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentiallyLegacy(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, slot, entropy, statistics, stateAfterParallelAcc, new Map());
22651
22653
  assertEmpty(seqRest);
22652
22654
  return {
22653
22655
  accumulatedReports: numbers_tryAsU32(i + accumulatedReports),
@@ -22679,8 +22681,15 @@ class Accumulate {
22679
22681
  const { gasCost, state: stateAfterParallelAcc, ...rest } = await this.accumulateInParallel(accumulateData, slot, entropy, statistics, stateUpdate);
22680
22682
  const newTransfers = stateAfterParallelAcc.takeTransfers();
22681
22683
  assertEmpty(rest);
22684
+ /**
22685
+ * Gas limit from transfers is added to the next round of accumulation
22686
+ *
22687
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/172b02172b02?v=0.7.2
22688
+ */
22689
+ const transfersGas = transfers.map((t) => t.gas);
22690
+ const { value: newGasLimit, overflow } = sumU64(tryAsServiceGas(gasLimit - gasCost), ...transfersGas);
22682
22691
  // NOTE [ToDr] recursive invocation
22683
- const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentially(tryAsServiceGas(gasLimit - gasCost), reportsToAccumulateSequentially, newTransfers, slot, entropy, statistics, stateAfterParallelAcc, []);
22692
+ const { accumulatedReports, gasCost: seqGasCost, state, ...seqRest } = await this.accumulateSequentially(tryAsServiceGas(overflow ? math_consts_MAX_VALUE_U64 : newGasLimit), reportsToAccumulateSequentially, newTransfers, slot, entropy, statistics, stateAfterParallelAcc, new Map());
22684
22693
  assertEmpty(seqRest);
22685
22694
  return {
22686
22695
  accumulatedReports: numbers_tryAsU32(i + accumulatedReports),
@@ -22706,14 +22715,16 @@ class Accumulate {
22706
22715
  for (const serviceId of serviceIds) {
22707
22716
  const checkpoint = AccumulationStateUpdate.copyFrom(currentState);
22708
22717
  const operands = accumulateData.getOperands(serviceId);
22709
- const { consumedGas, stateUpdate } = await this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), operands, accumulateData.getGasCost(serviceId), slot, entropy, currentState);
22718
+ const { consumedGas, stateUpdate } = await this.accumulateSingleService(serviceId, accumulateData.getTransfers(serviceId), operands, accumulateData.getGasLimit(serviceId), slot, entropy, currentState);
22710
22719
  gasCost = tryAsServiceGas(gasCost + consumedGas);
22711
22720
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/193b05193b05?v=0.7.2
22712
22721
  const serviceStatistics = statistics.get(serviceId) ?? { count: numbers_tryAsU32(0), gasUsed: tryAsServiceGas(0) };
22713
22722
  const count = accumulateData.getReportsLength(serviceId);
22714
22723
  // [0.7.1]: do not update statistics, if the service only had incoming transfers
22715
22724
  if ((compatibility_Compatibility.isLessThan(compatibility_GpVersion.V0_7_2) && count > 0) ||
22716
- (compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) && (count > 0 || consumedGas > 0n))) {
22725
+ ((compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ||
22726
+ (compatibility_Compatibility.isSuite(TestSuite.W3F_DAVXY) && compatibility_Compatibility.is(compatibility_GpVersion.V0_7_1))) &&
22727
+ (count > 0 || consumedGas > 0n))) {
22717
22728
  serviceStatistics.count = numbers_tryAsU32(serviceStatistics.count + count);
22718
22729
  serviceStatistics.gasUsed = tryAsServiceGas(serviceStatistics.gasUsed + consumedGas);
22719
22730
  statistics.set(serviceId, serviceStatistics);
@@ -22726,7 +22737,7 @@ class Accumulate {
22726
22737
  // Since serviceIds already contains newV, this service gets accumulated twice.
22727
22738
  // To avoid double-counting, we skip stats and gas cost tracking here.
22728
22739
  // We need this accumulation to get the correct `delegator`
22729
- const { stateUpdate } = await this.accumulateSingleService(newV, [], accumulateData.getOperands(newV), accumulateData.getGasCost(newV), slot, entropy, checkpoint);
22740
+ const { stateUpdate } = await this.accumulateSingleService(newV, [], accumulateData.getOperands(newV), accumulateData.getGasLimit(newV), slot, entropy, checkpoint);
22730
22741
  const correctV = stateUpdate?.privilegedServices?.delegator ?? this.state.privilegedServices.delegator;
22731
22742
  currentState.privilegedServices = PrivilegedServices.create({
22732
22743
  ...currentState.privilegedServices,
@@ -22792,7 +22803,7 @@ class Accumulate {
22792
22803
  */
22793
22804
  getGasLimit() {
22794
22805
  const calculatedGasLimit = GAS_TO_INVOKE_WORK_REPORT * BigInt(this.chainSpec.coresCount) +
22795
- this.state.privilegedServices.autoAccumulateServices.reduce((acc, { gasLimit }) => acc + gasLimit, 0n);
22806
+ Array.from(this.state.privilegedServices.autoAccumulateServices.values()).reduce((acc, gasLimit) => acc + gasLimit, 0n);
22796
22807
  const gasLimit = tryAsServiceGas(this.chainSpec.maxBlockGas > calculatedGasLimit ? this.chainSpec.maxBlockGas : calculatedGasLimit);
22797
22808
  return tryAsServiceGas(gasLimit);
22798
22809
  }
@@ -22945,9 +22956,8 @@ class DeferredTransfers {
22945
22956
  consumedGas = (await executor.run(args, tryAsGas(gas))).consumedGas;
22946
22957
  }
22947
22958
  transferStatistics.set(serviceId, { count: numbers_tryAsU32(transfers.length), gasUsed: tryAsServiceGas(consumedGas) });
22948
- const [updatedState, checkpointedState] = partialState.getStateUpdates();
22959
+ const [updatedState] = partialState.getStateUpdates();
22949
22960
  currentStateUpdate = updatedState;
22950
- debug_check `${checkpointedState === null} On transfer cannot invoke checkpoint.`;
22951
22961
  }
22952
22962
  return Result.ok({
22953
22963
  // NOTE: we return only services, since it's impossible to update
@@ -24264,7 +24274,6 @@ class Statistics {
24264
24274
 
24265
24275
 
24266
24276
 
24267
-
24268
24277
  class DbHeaderChain {
24269
24278
  blocks;
24270
24279
  constructor(blocks) {
@@ -24335,7 +24344,7 @@ class OnChain {
24335
24344
  // chapter 13: https://graypaper.fluffylabs.dev/#/68eaa1f/18b60118b601?v=0.6.4
24336
24345
  statistics;
24337
24346
  isReadyForNextEpoch = Promise.resolve(false);
24338
- constructor(chainSpec, state, blocks, hasher, pvm = PvmBackend.BuiltIn) {
24347
+ constructor(chainSpec, state, blocks, hasher, pvm) {
24339
24348
  this.chainSpec = chainSpec;
24340
24349
  this.state = state;
24341
24350
  this.hasher = hasher;