@typeberry/jam 0.2.0-74f246e → 0.2.0-8017bfd

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
@@ -32026,6 +32026,7 @@ function accumulationOutputComparator(a, b) {
32026
32026
 
32027
32027
  ;// CONCATENATED MODULE: ./packages/jam/block/gp-constants.ts
32028
32028
 
32029
+
32029
32030
  /**
32030
32031
  * This file lists all of the constants defined in the GrayPaper appendix.
32031
32032
  *
@@ -32036,7 +32037,7 @@ function accumulationOutputComparator(a, b) {
32036
32037
  * here are only temporarily for convenience. When we figure out better names
32037
32038
  * and places for these this file will be eradicated.
32038
32039
  *
32039
- * https://graypaper.fluffylabs.dev/#/579bd12/413000413000
32040
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/442300442300?v=0.7.2
32040
32041
  */
32041
32042
  /** `G_I`: The gas allocated to invoke a work-package’s Is-Authorized logic. */
32042
32043
  const G_I = 50_000_000;
@@ -32052,8 +32053,8 @@ const S = 1024;
32052
32053
  const T = 128;
32053
32054
  /** `W_A`: The maximum size of is-authorized code in octets. */
32054
32055
  const W_A = 64_000;
32055
- /** `W_B`: The maximum size of an encoded work-package with extrinsic data and imports. */
32056
- const W_B = 13_794_305;
32056
+ /** `W_B`: The maximum size of the concatenated variable-size blobs, extrinsics and imported segments of a work-package, in octets */
32057
+ const W_B = Compatibility.isGreaterOrEqual(GpVersion.V0_7_2) ? 13_791_360 : 13_794_305;
32057
32058
  /** `W_C`: The maximum size of service code in octets. */
32058
32059
  const W_C = 4_000_000;
32059
32060
  /** `W_M`: The maximum number of imports in a work-package. */
@@ -33152,31 +33153,29 @@ var UpdatePreimageKind;
33152
33153
  * 3. Update `LookupHistory` with given value.
33153
33154
  */
33154
33155
  class UpdatePreimage {
33155
- serviceId;
33156
33156
  action;
33157
- constructor(serviceId, action) {
33158
- this.serviceId = serviceId;
33157
+ constructor(action) {
33159
33158
  this.action = action;
33160
33159
  }
33161
33160
  /** A preimage is provided. We should update the lookuphistory and add the preimage to db. */
33162
- static provide({ serviceId, preimage, slot, }) {
33163
- return new UpdatePreimage(serviceId, {
33161
+ static provide({ preimage, slot }) {
33162
+ return new UpdatePreimage({
33164
33163
  kind: UpdatePreimageKind.Provide,
33165
33164
  preimage,
33166
33165
  slot,
33167
33166
  });
33168
33167
  }
33169
33168
  /** The preimage should be removed completely from the database. */
33170
- static remove({ serviceId, hash, length }) {
33171
- return new UpdatePreimage(serviceId, {
33169
+ static remove({ hash, length }) {
33170
+ return new UpdatePreimage({
33172
33171
  kind: UpdatePreimageKind.Remove,
33173
33172
  hash,
33174
33173
  length,
33175
33174
  });
33176
33175
  }
33177
33176
  /** Update the lookup history of some preimage or add a new one (request). */
33178
- static updateOrAdd({ serviceId, lookupHistory }) {
33179
- return new UpdatePreimage(serviceId, {
33177
+ static updateOrAdd({ lookupHistory }) {
33178
+ return new UpdatePreimage({
33180
33179
  kind: UpdatePreimageKind.UpdateOrAdd,
33181
33180
  item: lookupHistory,
33182
33181
  });
@@ -33213,23 +33212,21 @@ var UpdateServiceKind;
33213
33212
  UpdateServiceKind[UpdateServiceKind["Create"] = 1] = "Create";
33214
33213
  })(UpdateServiceKind || (UpdateServiceKind = {}));
33215
33214
  /**
33216
- * Update service info of a particular `ServiceId` or create a new one.
33215
+ * Update service info or create a new one.
33217
33216
  */
33218
33217
  class UpdateService {
33219
- serviceId;
33220
33218
  action;
33221
- constructor(serviceId, action) {
33222
- this.serviceId = serviceId;
33219
+ constructor(action) {
33223
33220
  this.action = action;
33224
33221
  }
33225
- static update({ serviceId, serviceInfo }) {
33226
- return new UpdateService(serviceId, {
33222
+ static update({ serviceInfo }) {
33223
+ return new UpdateService({
33227
33224
  kind: UpdateServiceKind.Update,
33228
33225
  account: serviceInfo,
33229
33226
  });
33230
33227
  }
33231
- static create({ serviceId, serviceInfo, lookupHistory, }) {
33232
- return new UpdateService(serviceId, {
33228
+ static create({ serviceInfo, lookupHistory, }) {
33229
+ return new UpdateService({
33233
33230
  kind: UpdateServiceKind.Create,
33234
33231
  account: serviceInfo,
33235
33232
  lookupHistory,
@@ -33250,17 +33247,15 @@ var UpdateStorageKind;
33250
33247
  * Can either create/modify an entry or remove it.
33251
33248
  */
33252
33249
  class UpdateStorage {
33253
- serviceId;
33254
33250
  action;
33255
- constructor(serviceId, action) {
33256
- this.serviceId = serviceId;
33251
+ constructor(action) {
33257
33252
  this.action = action;
33258
33253
  }
33259
- static set({ serviceId, storage }) {
33260
- return new UpdateStorage(serviceId, { kind: UpdateStorageKind.Set, storage });
33254
+ static set({ storage }) {
33255
+ return new UpdateStorage({ kind: UpdateStorageKind.Set, storage });
33261
33256
  }
33262
- static remove({ serviceId, key }) {
33263
- return new UpdateStorage(serviceId, { kind: UpdateStorageKind.Remove, key });
33257
+ static remove({ key }) {
33258
+ return new UpdateStorage({ kind: UpdateStorageKind.Remove, key });
33264
33259
  }
33265
33260
  get key() {
33266
33261
  if (this.action.kind === UpdateStorageKind.Remove) {
@@ -33469,12 +33464,12 @@ class in_memory_state_InMemoryState extends WithDebug {
33469
33464
  * Modify the state and apply a single state update.
33470
33465
  */
33471
33466
  applyUpdate(update) {
33472
- const { servicesRemoved, servicesUpdates, preimages, storage, ...rest } = update;
33467
+ const { removed, created: _, updated, preimages, storage, ...rest } = update;
33473
33468
  // just assign all other variables
33474
33469
  Object.assign(this, rest);
33475
33470
  // and update the services state
33476
33471
  let result;
33477
- result = this.updateServices(servicesUpdates);
33472
+ result = this.updateServices(updated);
33478
33473
  if (result.isError) {
33479
33474
  return result;
33480
33475
  }
@@ -33486,7 +33481,7 @@ class in_memory_state_InMemoryState extends WithDebug {
33486
33481
  if (result.isError) {
33487
33482
  return result;
33488
33483
  }
33489
- this.removeServices(servicesRemoved);
33484
+ this.removeServices(removed);
33490
33485
  return result_Result.ok(result_OK);
33491
33486
  }
33492
33487
  removeServices(servicesRemoved) {
@@ -33495,87 +33490,100 @@ class in_memory_state_InMemoryState extends WithDebug {
33495
33490
  this.services.delete(serviceId);
33496
33491
  }
33497
33492
  }
33498
- updateStorage(storage) {
33499
- for (const { serviceId, action } of storage ?? []) {
33500
- const { kind } = action;
33501
- const service = this.services.get(serviceId);
33502
- if (service === undefined) {
33503
- return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update storage of non-existing service: ${serviceId}`);
33504
- }
33505
- if (kind === UpdateStorageKind.Set) {
33506
- const { key, value } = action.storage;
33507
- service.data.storage.set(key.toString(), StorageItem.create({ key, value }));
33508
- }
33509
- else if (kind === UpdateStorageKind.Remove) {
33510
- const { key } = action;
33511
- debug_check `
33493
+ updateStorage(storageUpdates) {
33494
+ if (storageUpdates === undefined) {
33495
+ return result_Result.ok(result_OK);
33496
+ }
33497
+ for (const [serviceId, updates] of storageUpdates.entries()) {
33498
+ for (const update of updates) {
33499
+ const { kind } = update.action;
33500
+ const service = this.services.get(serviceId);
33501
+ if (service === undefined) {
33502
+ return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update storage of non-existing service: ${serviceId}`);
33503
+ }
33504
+ if (kind === UpdateStorageKind.Set) {
33505
+ const { key, value } = update.action.storage;
33506
+ service.data.storage.set(key.toString(), StorageItem.create({ key, value }));
33507
+ }
33508
+ else if (kind === UpdateStorageKind.Remove) {
33509
+ const { key } = update.action;
33510
+ debug_check `
33512
33511
  ${service.data.storage.has(key.toString())}
33513
- Attempting to remove non-existing storage item at ${serviceId}: ${action.key}
33512
+ Attempting to remove non-existing storage item at ${serviceId}: ${update.action.key}
33514
33513
  `;
33515
- service.data.storage.delete(key.toString());
33516
- }
33517
- else {
33518
- debug_assertNever(kind);
33514
+ service.data.storage.delete(key.toString());
33515
+ }
33516
+ else {
33517
+ debug_assertNever(kind);
33518
+ }
33519
33519
  }
33520
33520
  }
33521
33521
  return result_Result.ok(result_OK);
33522
33522
  }
33523
- updatePreimages(preimages) {
33524
- for (const { serviceId, action } of preimages ?? []) {
33523
+ updatePreimages(preimagesUpdates) {
33524
+ if (preimagesUpdates === undefined) {
33525
+ return result_Result.ok(result_OK);
33526
+ }
33527
+ for (const [serviceId, updates] of preimagesUpdates.entries()) {
33525
33528
  const service = this.services.get(serviceId);
33526
33529
  if (service === undefined) {
33527
33530
  return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update preimage of non-existing service: ${serviceId}`);
33528
33531
  }
33529
- const { kind } = action;
33530
- if (kind === UpdatePreimageKind.Provide) {
33531
- const { preimage, slot } = action;
33532
- if (service.data.preimages.has(preimage.hash)) {
33533
- return result_Result.error(in_memory_state_UpdateError.PreimageExists, `Overwriting existing preimage at ${serviceId}: ${preimage}`);
33534
- }
33535
- service.data.preimages.set(preimage.hash, preimage);
33536
- if (slot !== null) {
33537
- const lookupHistory = service.data.lookupHistory.get(preimage.hash);
33538
- const length = numbers_tryAsU32(preimage.blob.length);
33539
- const lookup = new LookupHistoryItem(preimage.hash, length, tryAsLookupHistorySlots([slot]));
33540
- if (lookupHistory === undefined) {
33541
- // no lookup history for that preimage at all (edge case, should be requested)
33542
- service.data.lookupHistory.set(preimage.hash, [lookup]);
33532
+ for (const update of updates) {
33533
+ const { kind } = update.action;
33534
+ if (kind === UpdatePreimageKind.Provide) {
33535
+ const { preimage, slot } = update.action;
33536
+ if (service.data.preimages.has(preimage.hash)) {
33537
+ return result_Result.error(in_memory_state_UpdateError.PreimageExists, `Overwriting existing preimage at ${serviceId}: ${preimage}`);
33543
33538
  }
33544
- else {
33545
- // insert or replace exiting entry
33546
- const index = lookupHistory.map((x) => x.length).indexOf(length);
33547
- lookupHistory.splice(index, index === -1 ? 0 : 1, lookup);
33539
+ service.data.preimages.set(preimage.hash, preimage);
33540
+ if (slot !== null) {
33541
+ const lookupHistory = service.data.lookupHistory.get(preimage.hash);
33542
+ const length = numbers_tryAsU32(preimage.blob.length);
33543
+ const lookup = new LookupHistoryItem(preimage.hash, length, tryAsLookupHistorySlots([slot]));
33544
+ if (lookupHistory === undefined) {
33545
+ // no lookup history for that preimage at all (edge case, should be requested)
33546
+ service.data.lookupHistory.set(preimage.hash, [lookup]);
33547
+ }
33548
+ else {
33549
+ // insert or replace exiting entry
33550
+ const index = lookupHistory.map((x) => x.length).indexOf(length);
33551
+ lookupHistory.splice(index, index === -1 ? 0 : 1, lookup);
33552
+ }
33548
33553
  }
33549
33554
  }
33550
- }
33551
- else if (kind === UpdatePreimageKind.Remove) {
33552
- const { hash, length } = action;
33553
- service.data.preimages.delete(hash);
33554
- const history = service.data.lookupHistory.get(hash) ?? [];
33555
- const idx = history.map((x) => x.length).indexOf(length);
33556
- if (idx !== -1) {
33557
- history.splice(idx, 1);
33555
+ else if (kind === UpdatePreimageKind.Remove) {
33556
+ const { hash, length } = update.action;
33557
+ service.data.preimages.delete(hash);
33558
+ const history = service.data.lookupHistory.get(hash) ?? [];
33559
+ const idx = history.map((x) => x.length).indexOf(length);
33560
+ if (idx !== -1) {
33561
+ history.splice(idx, 1);
33562
+ }
33563
+ }
33564
+ else if (kind === UpdatePreimageKind.UpdateOrAdd) {
33565
+ const { item } = update.action;
33566
+ const history = service.data.lookupHistory.get(item.hash) ?? [];
33567
+ const existingIdx = history.map((x) => x.length).indexOf(item.length);
33568
+ const removeCount = existingIdx === -1 ? 0 : 1;
33569
+ history.splice(existingIdx, removeCount, item);
33570
+ service.data.lookupHistory.set(item.hash, history);
33571
+ }
33572
+ else {
33573
+ debug_assertNever(kind);
33558
33574
  }
33559
- }
33560
- else if (kind === UpdatePreimageKind.UpdateOrAdd) {
33561
- const { item } = action;
33562
- const history = service.data.lookupHistory.get(item.hash) ?? [];
33563
- const existingIdx = history.map((x) => x.length).indexOf(item.length);
33564
- const removeCount = existingIdx === -1 ? 0 : 1;
33565
- history.splice(existingIdx, removeCount, item);
33566
- service.data.lookupHistory.set(item.hash, history);
33567
- }
33568
- else {
33569
- debug_assertNever(kind);
33570
33575
  }
33571
33576
  }
33572
33577
  return result_Result.ok(result_OK);
33573
33578
  }
33574
33579
  updateServices(servicesUpdates) {
33575
- for (const { serviceId, action } of servicesUpdates ?? []) {
33576
- const { kind, account } = action;
33580
+ if (servicesUpdates === undefined) {
33581
+ return result_Result.ok(result_OK);
33582
+ }
33583
+ for (const [serviceId, update] of servicesUpdates.entries()) {
33584
+ const { kind, account } = update.action;
33577
33585
  if (kind === UpdateServiceKind.Create) {
33578
- const { lookupHistory } = action;
33586
+ const { lookupHistory } = update.action;
33579
33587
  if (this.services.has(serviceId)) {
33580
33588
  return result_Result.error(in_memory_state_UpdateError.DuplicateService, `${serviceId} already exists!`);
33581
33589
  }
@@ -34836,7 +34844,6 @@ function getKeccakTrieHasher(hasher) {
34836
34844
 
34837
34845
 
34838
34846
 
34839
-
34840
34847
  /** What should be done with that key? */
34841
34848
  var StateEntryUpdateAction;
34842
34849
  (function (StateEntryUpdateAction) {
@@ -34852,76 +34859,88 @@ function* serializeStateUpdate(spec, blake2b, update) {
34852
34859
  yield* serializeBasicKeys(spec, update);
34853
34860
  const encode = (codec, val) => encoder_Encoder.encodeObject(codec, val, spec);
34854
34861
  // then let's proceed with service updates
34855
- yield* serializeServiceUpdates(update.servicesUpdates, encode, blake2b);
34862
+ yield* serializeServiceUpdates(update.updated, encode, blake2b);
34856
34863
  yield* serializePreimages(update.preimages, encode, blake2b);
34857
34864
  yield* serializeStorage(update.storage, blake2b);
34858
- yield* serializeRemovedServices(update.servicesRemoved);
34865
+ yield* serializeRemovedServices(update.removed);
34859
34866
  }
34860
34867
  function* serializeRemovedServices(servicesRemoved) {
34861
- for (const serviceId of servicesRemoved ?? []) {
34868
+ if (servicesRemoved === undefined) {
34869
+ return;
34870
+ }
34871
+ for (const serviceId of servicesRemoved) {
34862
34872
  // TODO [ToDr] what about all data associated with a service?
34863
34873
  const codec = serialize_serialize.serviceData(serviceId);
34864
34874
  yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
34865
34875
  }
34866
34876
  }
34867
- function* serializeStorage(storage, blake2b) {
34868
- for (const { action, serviceId } of storage ?? []) {
34869
- switch (action.kind) {
34870
- case UpdateStorageKind.Set: {
34871
- const key = action.storage.key;
34872
- const codec = serialize_serialize.serviceStorage(blake2b, serviceId, key);
34873
- yield [StateEntryUpdateAction.Insert, codec.key, action.storage.value];
34874
- break;
34875
- }
34876
- case UpdateStorageKind.Remove: {
34877
- const key = action.key;
34878
- const codec = serialize_serialize.serviceStorage(blake2b, serviceId, key);
34879
- yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
34880
- break;
34877
+ function* serializeStorage(storageUpdates, blake2b) {
34878
+ if (storageUpdates === undefined) {
34879
+ return;
34880
+ }
34881
+ for (const [serviceId, updates] of storageUpdates.entries()) {
34882
+ for (const { action } of updates) {
34883
+ switch (action.kind) {
34884
+ case UpdateStorageKind.Set: {
34885
+ const key = action.storage.key;
34886
+ const codec = serialize_serialize.serviceStorage(blake2b, serviceId, key);
34887
+ yield [StateEntryUpdateAction.Insert, codec.key, action.storage.value];
34888
+ break;
34889
+ }
34890
+ case UpdateStorageKind.Remove: {
34891
+ const key = action.key;
34892
+ const codec = serialize_serialize.serviceStorage(blake2b, serviceId, key);
34893
+ yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
34894
+ break;
34895
+ }
34881
34896
  }
34882
- default:
34883
- debug_assertNever(action);
34884
34897
  }
34885
34898
  }
34886
34899
  }
34887
- function* serializePreimages(preimages, encode, blake2b) {
34888
- for (const { action, serviceId } of preimages ?? []) {
34889
- switch (action.kind) {
34890
- case UpdatePreimageKind.Provide: {
34891
- const { hash, blob } = action.preimage;
34892
- const codec = serialize_serialize.servicePreimages(blake2b, serviceId, hash);
34893
- yield [StateEntryUpdateAction.Insert, codec.key, blob];
34894
- if (action.slot !== null) {
34895
- const codec2 = serialize_serialize.serviceLookupHistory(blake2b, serviceId, hash, numbers_tryAsU32(blob.length));
34896
- yield [
34897
- StateEntryUpdateAction.Insert,
34898
- codec2.key,
34899
- encode(codec2.Codec, tryAsLookupHistorySlots([action.slot])),
34900
- ];
34900
+ function* serializePreimages(preimagesUpdates, encode, blake2b) {
34901
+ if (preimagesUpdates === undefined) {
34902
+ return;
34903
+ }
34904
+ for (const [serviceId, updates] of preimagesUpdates.entries()) {
34905
+ for (const { action } of updates) {
34906
+ switch (action.kind) {
34907
+ case UpdatePreimageKind.Provide: {
34908
+ const { hash, blob } = action.preimage;
34909
+ const codec = serialize_serialize.servicePreimages(blake2b, serviceId, hash);
34910
+ yield [StateEntryUpdateAction.Insert, codec.key, blob];
34911
+ if (action.slot !== null) {
34912
+ const codec2 = serialize_serialize.serviceLookupHistory(blake2b, serviceId, hash, numbers_tryAsU32(blob.length));
34913
+ yield [
34914
+ StateEntryUpdateAction.Insert,
34915
+ codec2.key,
34916
+ encode(codec2.Codec, tryAsLookupHistorySlots([action.slot])),
34917
+ ];
34918
+ }
34919
+ break;
34920
+ }
34921
+ case UpdatePreimageKind.UpdateOrAdd: {
34922
+ const { hash, length, slots } = action.item;
34923
+ const codec = serialize_serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
34924
+ yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, slots)];
34925
+ break;
34926
+ }
34927
+ case UpdatePreimageKind.Remove: {
34928
+ const { hash, length } = action;
34929
+ const codec = serialize_serialize.servicePreimages(blake2b, serviceId, hash);
34930
+ yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
34931
+ const codec2 = serialize_serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
34932
+ yield [StateEntryUpdateAction.Remove, codec2.key, EMPTY_BLOB];
34933
+ break;
34901
34934
  }
34902
- break;
34903
- }
34904
- case UpdatePreimageKind.UpdateOrAdd: {
34905
- const { hash, length, slots } = action.item;
34906
- const codec = serialize_serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
34907
- yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, slots)];
34908
- break;
34909
- }
34910
- case UpdatePreimageKind.Remove: {
34911
- const { hash, length } = action;
34912
- const codec = serialize_serialize.servicePreimages(blake2b, serviceId, hash);
34913
- yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
34914
- const codec2 = serialize_serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
34915
- yield [StateEntryUpdateAction.Remove, codec2.key, EMPTY_BLOB];
34916
- break;
34917
34935
  }
34918
- default:
34919
- debug_assertNever(action);
34920
34936
  }
34921
34937
  }
34922
34938
  }
34923
34939
  function* serializeServiceUpdates(servicesUpdates, encode, blake2b) {
34924
- for (const { action, serviceId } of servicesUpdates ?? []) {
34940
+ if (servicesUpdates === undefined) {
34941
+ return;
34942
+ }
34943
+ for (const [serviceId, { action }] of servicesUpdates.entries()) {
34925
34944
  // new service being created or updated
34926
34945
  const codec = serialize_serialize.serviceData(serviceId);
34927
34946
  yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, action.account)];
@@ -36990,7 +37009,7 @@ class Preimages {
36990
37009
  }
36991
37010
  }
36992
37011
  const { preimages, slot } = input;
36993
- const pendingChanges = [];
37012
+ const pendingChanges = new Map();
36994
37013
  // select preimages for integration
36995
37014
  for (const preimage of preimages) {
36996
37015
  const { requester, blob } = preimage;
@@ -37007,11 +37026,12 @@ class Preimages {
37007
37026
  return result_Result.error(PreimagesErrorCode.PreimageUnneeded);
37008
37027
  }
37009
37028
  // https://graypaper.fluffylabs.dev/#/5f542d7/18c00018f300
37010
- pendingChanges.push(UpdatePreimage.provide({
37011
- serviceId: requester,
37029
+ const updates = pendingChanges.get(requester) ?? [];
37030
+ updates.push(UpdatePreimage.provide({
37012
37031
  preimage: PreimageItem.create({ hash, blob }),
37013
37032
  slot,
37014
37033
  }));
37034
+ pendingChanges.set(requester, updates);
37015
37035
  }
37016
37036
  return result_Result.ok({
37017
37037
  preimages: pendingChanges,
@@ -42126,6 +42146,14 @@ async function getRootHash(yieldedRoots) {
42126
42146
 
42127
42147
 
42128
42148
  const InsufficientFundsError = "insufficient funds";
42149
+ /** Deep clone of a map with array. */
42150
+ function deepCloneMapWithArray(map) {
42151
+ const cloned = [];
42152
+ for (const [k, v] of map.entries()) {
42153
+ cloned.push([k, v.slice()]);
42154
+ }
42155
+ return new Map(cloned);
42156
+ }
42129
42157
  /**
42130
42158
  * State updates that currently accumulating service produced.
42131
42159
  *
@@ -42155,10 +42183,11 @@ class AccumulationStateUpdate {
42155
42183
  /** Create new empty state update. */
42156
42184
  static empty() {
42157
42185
  return new AccumulationStateUpdate({
42158
- servicesUpdates: [],
42159
- servicesRemoved: [],
42160
- preimages: [],
42161
- storage: [],
42186
+ created: [],
42187
+ updated: new Map(),
42188
+ removed: [],
42189
+ preimages: new Map(),
42190
+ storage: new Map(),
42162
42191
  }, []);
42163
42192
  }
42164
42193
  /** Create a state update with some existing, yet uncommited services updates. */
@@ -42170,10 +42199,13 @@ class AccumulationStateUpdate {
42170
42199
  /** Create a copy of another `StateUpdate`. Used by checkpoints. */
42171
42200
  static copyFrom(from) {
42172
42201
  const serviceUpdates = {
42173
- servicesUpdates: [...from.services.servicesUpdates],
42174
- servicesRemoved: [...from.services.servicesRemoved],
42175
- preimages: [...from.services.preimages],
42176
- storage: [...from.services.storage],
42202
+ // shallow copy
42203
+ created: [...from.services.created],
42204
+ updated: new Map(from.services.updated),
42205
+ removed: [...from.services.removed],
42206
+ // deep copy
42207
+ preimages: deepCloneMapWithArray(from.services.preimages),
42208
+ storage: deepCloneMapWithArray(from.services.storage),
42177
42209
  };
42178
42210
  const transfers = [...from.transfers];
42179
42211
  const update = new AccumulationStateUpdate(serviceUpdates, transfers, new Map(from.yieldedRoots));
@@ -42221,9 +42253,9 @@ class PartiallyUpdatedState {
42221
42253
  if (destination === null) {
42222
42254
  return null;
42223
42255
  }
42224
- const maybeNewService = this.stateUpdate.services.servicesUpdates.find((update) => update.serviceId === destination);
42225
- if (maybeNewService !== undefined) {
42226
- return maybeNewService.action.account;
42256
+ const maybeUpdatedServiceInfo = this.stateUpdate.services.updated.get(destination);
42257
+ if (maybeUpdatedServiceInfo !== undefined) {
42258
+ return maybeUpdatedServiceInfo.action.account;
42227
42259
  }
42228
42260
  const maybeService = this.state.getService(destination);
42229
42261
  if (maybeService === null) {
@@ -42232,7 +42264,8 @@ class PartiallyUpdatedState {
42232
42264
  return maybeService.getInfo();
42233
42265
  }
42234
42266
  getStorage(serviceId, rawKey) {
42235
- const item = this.stateUpdate.services.storage.find((x) => x.serviceId === serviceId && x.key.isEqualTo(rawKey));
42267
+ const storages = this.stateUpdate.services.storage.get(serviceId) ?? [];
42268
+ const item = storages.find((x) => x.key.isEqualTo(rawKey));
42236
42269
  if (item !== undefined) {
42237
42270
  return item.value;
42238
42271
  }
@@ -42247,10 +42280,11 @@ class PartiallyUpdatedState {
42247
42280
  * the existence in `preimages` map.
42248
42281
  */
42249
42282
  hasPreimage(serviceId, hash) {
42250
- const providedPreimage = this.stateUpdate.services.preimages.find(
42283
+ const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
42284
+ const providedPreimage = preimages.find(
42251
42285
  // we ignore the action here, since if there is <any> update on that
42252
42286
  // hash it means it has to exist, right?
42253
- (p) => p.serviceId === serviceId && p.hash.isEqualTo(hash));
42287
+ (p) => p.hash.isEqualTo(hash));
42254
42288
  if (providedPreimage !== undefined) {
42255
42289
  return true;
42256
42290
  }
@@ -42263,7 +42297,8 @@ class PartiallyUpdatedState {
42263
42297
  }
42264
42298
  getPreimage(serviceId, hash) {
42265
42299
  // TODO [ToDr] Should we verify availability here?
42266
- const freshlyProvided = this.stateUpdate.services.preimages.find((x) => x.serviceId === serviceId && x.hash.isEqualTo(hash));
42300
+ const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
42301
+ const freshlyProvided = preimages.find((x) => x.hash.isEqualTo(hash));
42267
42302
  if (freshlyProvided !== undefined && freshlyProvided.action.kind === UpdatePreimageKind.Provide) {
42268
42303
  return freshlyProvided.action.preimage.blob;
42269
42304
  }
@@ -42272,10 +42307,11 @@ class PartiallyUpdatedState {
42272
42307
  }
42273
42308
  /** Get status of a preimage of current service taking into account any updates. */
42274
42309
  getLookupHistory(currentTimeslot, serviceId, hash, length) {
42310
+ const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
42275
42311
  // TODO [ToDr] This is most likely wrong. We may have `provide` and `remove` within
42276
42312
  // the same state update. We should however switch to proper "updated state"
42277
42313
  // representation soon.
42278
- const updatedPreimage = this.stateUpdate.services.preimages.findLast((update) => update.serviceId === serviceId && update.hash.isEqualTo(hash) && BigInt(update.length) === length);
42314
+ const updatedPreimage = preimages.findLast((update) => update.hash.isEqualTo(hash) && BigInt(update.length) === length);
42279
42315
  const stateFallback = () => {
42280
42316
  // fallback to state lookup
42281
42317
  const service = this.state.getService(serviceId);
@@ -42312,14 +42348,15 @@ class PartiallyUpdatedState {
42312
42348
  /* State update functions. */
42313
42349
  updateStorage(serviceId, key, value) {
42314
42350
  const update = value === null
42315
- ? UpdateStorage.remove({ serviceId, key })
42351
+ ? UpdateStorage.remove({ key })
42316
42352
  : UpdateStorage.set({
42317
- serviceId,
42318
42353
  storage: StorageItem.create({ key, value }),
42319
42354
  });
42320
- const index = this.stateUpdate.services.storage.findIndex((x) => x.serviceId === update.serviceId && x.key.isEqualTo(key));
42355
+ const storages = this.stateUpdate.services.storage.get(serviceId) ?? [];
42356
+ const index = storages.findIndex((x) => x.key.isEqualTo(key));
42321
42357
  const count = index === -1 ? 0 : 1;
42322
- this.stateUpdate.services.storage.splice(index, count, update);
42358
+ storages.splice(index, count, update);
42359
+ this.stateUpdate.services.storage.set(serviceId, storages);
42323
42360
  }
42324
42361
  /**
42325
42362
  * Update a preimage.
@@ -42327,8 +42364,10 @@ class PartiallyUpdatedState {
42327
42364
  * Note we store all previous entries as well, since there might be a sequence of:
42328
42365
  * `provide` -> `remove` and both should update the end state somehow.
42329
42366
  */
42330
- updatePreimage(newUpdate) {
42331
- this.stateUpdate.services.preimages.push(newUpdate);
42367
+ updatePreimage(serviceId, newUpdate) {
42368
+ const updatePreimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
42369
+ updatePreimages.push(newUpdate);
42370
+ this.stateUpdate.services.preimages.set(serviceId, updatePreimages);
42332
42371
  }
42333
42372
  updateServiceStorageUtilisation(serviceId, items, bytes, serviceInfo) {
42334
42373
  debug_check `${items >= 0} storageUtilisationCount has to be a positive number, got: ${items}`;
@@ -42352,22 +42391,25 @@ class PartiallyUpdatedState {
42352
42391
  return result_Result.ok(result_OK);
42353
42392
  }
42354
42393
  updateServiceInfo(serviceId, newInfo) {
42355
- const idx = this.stateUpdate.services.servicesUpdates.findIndex((x) => x.serviceId === serviceId);
42356
- const toRemove = idx === -1 ? 0 : 1;
42357
- const existingItem = this.stateUpdate.services.servicesUpdates[idx];
42358
- if (existingItem?.action.kind === UpdateServiceKind.Create) {
42359
- this.stateUpdate.services.servicesUpdates.splice(idx, toRemove, UpdateService.create({
42360
- serviceId,
42394
+ const existingUpdate = this.stateUpdate.services.updated.get(serviceId);
42395
+ if (existingUpdate?.action.kind === UpdateServiceKind.Create) {
42396
+ this.stateUpdate.services.updated.set(serviceId, UpdateService.create({
42361
42397
  serviceInfo: newInfo,
42362
- lookupHistory: existingItem.action.lookupHistory,
42398
+ lookupHistory: existingUpdate.action.lookupHistory,
42363
42399
  }));
42364
42400
  return;
42365
42401
  }
42366
- this.stateUpdate.services.servicesUpdates.splice(idx, toRemove, UpdateService.update({
42367
- serviceId,
42402
+ this.stateUpdate.services.updated.set(serviceId, UpdateService.update({
42368
42403
  serviceInfo: newInfo,
42369
42404
  }));
42370
42405
  }
42406
+ createService(serviceId, newInfo, newLookupHistory) {
42407
+ this.stateUpdate.services.created.push(serviceId);
42408
+ this.stateUpdate.services.updated.set(serviceId, UpdateService.create({
42409
+ serviceInfo: newInfo,
42410
+ lookupHistory: newLookupHistory,
42411
+ }));
42412
+ }
42371
42413
  getPrivilegedServices() {
42372
42414
  if (this.stateUpdate.privilegedServices !== null) {
42373
42415
  return this.stateUpdate.privilegedServices;
@@ -46730,15 +46772,13 @@ class AccumulateExternalities {
46730
46772
  const clampedLength = clampU64ToU32(length);
46731
46773
  if (existingPreimage === null) {
46732
46774
  // https://graypaper.fluffylabs.dev/#/9a08063/38a60038a600?v=0.6.6
46733
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
46734
- serviceId: this.currentServiceId,
46775
+ this.updatedState.updatePreimage(this.currentServiceId, UpdatePreimage.updateOrAdd({
46735
46776
  lookupHistory: new LookupHistoryItem(hash, clampedLength, tryAsLookupHistorySlots([])),
46736
46777
  }));
46737
46778
  }
46738
46779
  else {
46739
46780
  /** https://graypaper.fluffylabs.dev/#/9a08063/38ca0038ca00?v=0.6.6 */
46740
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
46741
- serviceId: this.currentServiceId,
46781
+ this.updatedState.updatePreimage(this.currentServiceId, UpdatePreimage.updateOrAdd({
46742
46782
  lookupHistory: new LookupHistoryItem(hash, clampedLength, tryAsLookupHistorySlots([...existingPreimage.slots, this.currentTimeslot])),
46743
46783
  }));
46744
46784
  }
@@ -46763,8 +46803,7 @@ class AccumulateExternalities {
46763
46803
  if (res.isError) {
46764
46804
  return result_Result.error(ForgetPreimageError.StorageUtilisationError);
46765
46805
  }
46766
- this.updatedState.updatePreimage(UpdatePreimage.remove({
46767
- serviceId,
46806
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.remove({
46768
46807
  hash: status.hash,
46769
46808
  length: status.length,
46770
46809
  }));
@@ -46779,8 +46818,7 @@ class AccumulateExternalities {
46779
46818
  if (res.isError) {
46780
46819
  return result_Result.error(ForgetPreimageError.StorageUtilisationError);
46781
46820
  }
46782
- this.updatedState.updatePreimage(UpdatePreimage.remove({
46783
- serviceId,
46821
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.remove({
46784
46822
  hash: status.hash,
46785
46823
  length: status.length,
46786
46824
  }));
@@ -46790,8 +46828,7 @@ class AccumulateExternalities {
46790
46828
  }
46791
46829
  // https://graypaper.fluffylabs.dev/#/9a08063/38c80138c801?v=0.6.6
46792
46830
  if (s.status === PreimageStatusKind.Available) {
46793
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
46794
- serviceId,
46831
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.updateOrAdd({
46795
46832
  lookupHistory: new LookupHistoryItem(status.hash, status.length, tryAsLookupHistorySlots([s.data[0], t])),
46796
46833
  }));
46797
46834
  return result_Result.ok(result_OK);
@@ -46800,8 +46837,7 @@ class AccumulateExternalities {
46800
46837
  if (s.status === PreimageStatusKind.Reavailable) {
46801
46838
  const y = s.data[1];
46802
46839
  if (y < t - this.chainSpec.preimageExpungePeriod) {
46803
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
46804
- serviceId,
46840
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.updateOrAdd({
46805
46841
  lookupHistory: new LookupHistoryItem(status.hash, status.length, tryAsLookupHistorySlots([s.data[2], t])),
46806
46842
  }));
46807
46843
  return result_Result.ok(result_OK);
@@ -46892,11 +46928,7 @@ class AccumulateExternalities {
46892
46928
  }
46893
46929
  // add the new service with selected ID
46894
46930
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/36be0336c003?v=0.7.2
46895
- this.updatedState.stateUpdate.services.servicesUpdates.push(UpdateService.create({
46896
- serviceId: newServiceId,
46897
- serviceInfo: newAccount,
46898
- lookupHistory: newLookupItem,
46899
- }));
46931
+ this.updatedState.createService(newServiceId, newAccount, newLookupItem);
46900
46932
  // update the balance of current service
46901
46933
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/36c20336c403?v=0.7.2
46902
46934
  this.updatedState.updateServiceInfo(this.currentServiceId, updatedCurrentAccount);
@@ -46907,12 +46939,8 @@ class AccumulateExternalities {
46907
46939
  }
46908
46940
  const newServiceId = this.nextNewServiceId;
46909
46941
  // add the new service
46910
- // https://graypaper.fluffylabs.dev/#/ab2cdbd/36e70336e903?v=0.7.2
46911
- this.updatedState.stateUpdate.services.servicesUpdates.push(UpdateService.create({
46912
- serviceId: newServiceId,
46913
- serviceInfo: newAccount,
46914
- lookupHistory: newLookupItem,
46915
- }));
46942
+ // https://graypaper.fluffylabs.dev/#/7e6ff6a/36cb0236cb02?v=0.6.7
46943
+ this.updatedState.createService(newServiceId, newAccount, newLookupItem);
46916
46944
  // update the balance of current service
46917
46945
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/36ec0336ee03?v=0.7.2
46918
46946
  this.updatedState.updateServiceInfo(this.currentServiceId, updatedCurrentAccount);
@@ -47059,8 +47087,7 @@ class AccumulateExternalities {
47059
47087
  return result_Result.error(ProvidePreimageError.AlreadyProvided);
47060
47088
  }
47061
47089
  // setting up the new preimage
47062
- this.updatedState.updatePreimage(UpdatePreimage.provide({
47063
- serviceId,
47090
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.provide({
47064
47091
  preimage: PreimageItem.create({
47065
47092
  hash: preimageHash,
47066
47093
  blob: preimage,
@@ -47104,11 +47131,13 @@ class AccumulateExternalities {
47104
47131
  balance: newBalance.value,
47105
47132
  }));
47106
47133
  // and finally add an ejected service.
47107
- this.updatedState.stateUpdate.services.servicesRemoved.push(destination);
47134
+ this.updatedState.stateUpdate.services.removed.push(destination);
47108
47135
  // take care of the code preimage and its lookup history
47109
47136
  // Safe, because we know the preimage is valid, and it's the code of the service, which is bounded by maximal service code size anyway (much smaller than 2**32 bytes).
47110
47137
  const preimageLength = numbers_tryAsU32(Number(l));
47111
- this.updatedState.stateUpdate.services.preimages.push(UpdatePreimage.remove({ serviceId: destination, hash: previousCodeHash, length: preimageLength }));
47138
+ const preimages = this.updatedState.stateUpdate.services.preimages.get(destination) ?? [];
47139
+ preimages.push(UpdatePreimage.remove({ hash: previousCodeHash, length: preimageLength }));
47140
+ this.updatedState.stateUpdate.services.preimages.set(destination, preimages);
47112
47141
  return result_Result.ok(result_OK);
47113
47142
  }
47114
47143
  read(serviceId, rawKey) {
@@ -47997,9 +48026,6 @@ class HostCallMemory {
47997
48026
  }
47998
48027
  return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
47999
48028
  }
48000
- getMemory() {
48001
- return this.memory;
48002
- }
48003
48029
  }
48004
48030
 
48005
48031
  ;// CONCATENATED MODULE: ./packages/core/pvm-host-calls/host-call-registers.ts
@@ -50205,19 +50231,16 @@ class Accumulate {
50205
50231
  const gasLimit = tryAsServiceGas(this.chainSpec.maxBlockGas > calculatedGasLimit ? this.chainSpec.maxBlockGas : calculatedGasLimit);
50206
50232
  return tryAsServiceGas(gasLimit);
50207
50233
  }
50208
- hasDuplicatedServicesCreated(updateServices) {
50209
- const createdServiceIds = new Set();
50210
- for (const update of updateServices) {
50211
- if (update.action.kind === UpdateServiceKind.Create) {
50212
- const serviceId = update.serviceId;
50213
- if (createdServiceIds.has(serviceId)) {
50214
- accumulate_logger.log `Duplicated Service creation detected ${serviceId}. Block is invalid.`;
50215
- return true;
50216
- }
50217
- createdServiceIds.add(serviceId);
50218
- }
50219
- }
50220
- return false;
50234
+ /**
50235
+ * Detects the very unlikely situation where multiple services are created with the same ID.
50236
+ *
50237
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/30f20330f403?v=0.7.2
50238
+ *
50239
+ * NOTE: This is public only for testing purposes and should not be used outside of accumulation.
50240
+ */
50241
+ hasDuplicatedServiceIdCreated(createdIds) {
50242
+ const uniqueIds = new Set(createdIds);
50243
+ return uniqueIds.size !== createdIds.length;
50221
50244
  }
50222
50245
  async transition({ reports, slot, entropy }) {
50223
50246
  const statistics = new Map();
@@ -50239,7 +50262,8 @@ class Accumulate {
50239
50262
  const accumulated = accumulatableReports.subview(0, accumulatedReports);
50240
50263
  const { services, yieldedRoots, transfers, validatorsData, privilegedServices, authorizationQueues, ...stateUpdateRest } = state;
50241
50264
  assertEmpty(stateUpdateRest);
50242
- if (this.hasDuplicatedServicesCreated(services.servicesUpdates)) {
50265
+ if (this.hasDuplicatedServiceIdCreated(services.created)) {
50266
+ accumulate_logger.trace `Duplicated Service creation detected. Block is invalid.`;
50243
50267
  return result_Result.error(ACCUMULATION_ERROR);
50244
50268
  }
50245
50269
  const accStateUpdate = this.getAccumulationStateUpdate(accumulated.toArray(), toAccumulateLater, slot, Array.from(statistics.keys()), services);
@@ -51929,6 +51953,16 @@ class OnChain {
51929
51953
  });
51930
51954
  const { statistics, ...statisticsRest } = statisticsUpdate;
51931
51955
  assertEmpty(statisticsRest);
51956
+ // Concat accumulatePreimages updates with preimages
51957
+ for (const [serviceId, accPreimageUpdates] of accumulatePreimages.entries()) {
51958
+ const preimagesUpdates = preimages.get(serviceId);
51959
+ if (preimagesUpdates === undefined) {
51960
+ preimages.set(serviceId, accPreimageUpdates);
51961
+ }
51962
+ else {
51963
+ preimages.set(serviceId, preimagesUpdates.concat(accPreimageUpdates));
51964
+ }
51965
+ }
51932
51966
  return result_Result.ok({
51933
51967
  ...(maybeAuthorizationQueues !== undefined ? { authQueues: maybeAuthorizationQueues } : {}),
51934
51968
  ...(maybeDesignatedValidatorData !== undefined ? { designatedValidatorData: maybeDesignatedValidatorData } : {}),
@@ -51950,7 +51984,7 @@ class OnChain {
51950
51984
  recentlyAccumulated,
51951
51985
  accumulationOutputLog,
51952
51986
  ...servicesUpdate,
51953
- preimages: preimages.concat(accumulatePreimages),
51987
+ preimages,
51954
51988
  });
51955
51989
  }
51956
51990
  getUsedAuthorizerHashes(guarantees) {