@typeberry/convert 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.
Files changed (3) hide show
  1. package/index.js +256 -222
  2. package/index.js.map +1 -1
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -11465,6 +11465,7 @@ function accumulation_output_accumulationOutputComparator(a, b) {
11465
11465
 
11466
11466
  ;// CONCATENATED MODULE: ./packages/jam/block/gp-constants.ts
11467
11467
 
11468
+
11468
11469
  /**
11469
11470
  * This file lists all of the constants defined in the GrayPaper appendix.
11470
11471
  *
@@ -11475,7 +11476,7 @@ function accumulation_output_accumulationOutputComparator(a, b) {
11475
11476
  * here are only temporarily for convenience. When we figure out better names
11476
11477
  * and places for these this file will be eradicated.
11477
11478
  *
11478
- * https://graypaper.fluffylabs.dev/#/579bd12/413000413000
11479
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/442300442300?v=0.7.2
11479
11480
  */
11480
11481
  /** `G_I`: The gas allocated to invoke a work-package’s Is-Authorized logic. */
11481
11482
  const gp_constants_G_I = 50_000_000;
@@ -11491,8 +11492,8 @@ const S = 1024;
11491
11492
  const gp_constants_T = 128;
11492
11493
  /** `W_A`: The maximum size of is-authorized code in octets. */
11493
11494
  const gp_constants_W_A = 64_000;
11494
- /** `W_B`: The maximum size of an encoded work-package with extrinsic data and imports. */
11495
- const gp_constants_W_B = 13_794_305;
11495
+ /** `W_B`: The maximum size of the concatenated variable-size blobs, extrinsics and imported segments of a work-package, in octets */
11496
+ const gp_constants_W_B = compatibility_Compatibility.isGreaterOrEqual(compatibility_GpVersion.V0_7_2) ? 13_791_360 : 13_794_305;
11496
11497
  /** `W_C`: The maximum size of service code in octets. */
11497
11498
  const gp_constants_W_C = 4_000_000;
11498
11499
  /** `W_M`: The maximum number of imports in a work-package. */
@@ -12591,31 +12592,29 @@ var state_update_UpdatePreimageKind;
12591
12592
  * 3. Update `LookupHistory` with given value.
12592
12593
  */
12593
12594
  class state_update_UpdatePreimage {
12594
- serviceId;
12595
12595
  action;
12596
- constructor(serviceId, action) {
12597
- this.serviceId = serviceId;
12596
+ constructor(action) {
12598
12597
  this.action = action;
12599
12598
  }
12600
12599
  /** A preimage is provided. We should update the lookuphistory and add the preimage to db. */
12601
- static provide({ serviceId, preimage, slot, }) {
12602
- return new state_update_UpdatePreimage(serviceId, {
12600
+ static provide({ preimage, slot }) {
12601
+ return new state_update_UpdatePreimage({
12603
12602
  kind: state_update_UpdatePreimageKind.Provide,
12604
12603
  preimage,
12605
12604
  slot,
12606
12605
  });
12607
12606
  }
12608
12607
  /** The preimage should be removed completely from the database. */
12609
- static remove({ serviceId, hash, length }) {
12610
- return new state_update_UpdatePreimage(serviceId, {
12608
+ static remove({ hash, length }) {
12609
+ return new state_update_UpdatePreimage({
12611
12610
  kind: state_update_UpdatePreimageKind.Remove,
12612
12611
  hash,
12613
12612
  length,
12614
12613
  });
12615
12614
  }
12616
12615
  /** Update the lookup history of some preimage or add a new one (request). */
12617
- static updateOrAdd({ serviceId, lookupHistory }) {
12618
- return new state_update_UpdatePreimage(serviceId, {
12616
+ static updateOrAdd({ lookupHistory }) {
12617
+ return new state_update_UpdatePreimage({
12619
12618
  kind: state_update_UpdatePreimageKind.UpdateOrAdd,
12620
12619
  item: lookupHistory,
12621
12620
  });
@@ -12652,23 +12651,21 @@ var state_update_UpdateServiceKind;
12652
12651
  UpdateServiceKind[UpdateServiceKind["Create"] = 1] = "Create";
12653
12652
  })(state_update_UpdateServiceKind || (state_update_UpdateServiceKind = {}));
12654
12653
  /**
12655
- * Update service info of a particular `ServiceId` or create a new one.
12654
+ * Update service info or create a new one.
12656
12655
  */
12657
12656
  class state_update_UpdateService {
12658
- serviceId;
12659
12657
  action;
12660
- constructor(serviceId, action) {
12661
- this.serviceId = serviceId;
12658
+ constructor(action) {
12662
12659
  this.action = action;
12663
12660
  }
12664
- static update({ serviceId, serviceInfo }) {
12665
- return new state_update_UpdateService(serviceId, {
12661
+ static update({ serviceInfo }) {
12662
+ return new state_update_UpdateService({
12666
12663
  kind: state_update_UpdateServiceKind.Update,
12667
12664
  account: serviceInfo,
12668
12665
  });
12669
12666
  }
12670
- static create({ serviceId, serviceInfo, lookupHistory, }) {
12671
- return new state_update_UpdateService(serviceId, {
12667
+ static create({ serviceInfo, lookupHistory, }) {
12668
+ return new state_update_UpdateService({
12672
12669
  kind: state_update_UpdateServiceKind.Create,
12673
12670
  account: serviceInfo,
12674
12671
  lookupHistory,
@@ -12689,17 +12686,15 @@ var state_update_UpdateStorageKind;
12689
12686
  * Can either create/modify an entry or remove it.
12690
12687
  */
12691
12688
  class state_update_UpdateStorage {
12692
- serviceId;
12693
12689
  action;
12694
- constructor(serviceId, action) {
12695
- this.serviceId = serviceId;
12690
+ constructor(action) {
12696
12691
  this.action = action;
12697
12692
  }
12698
- static set({ serviceId, storage }) {
12699
- return new state_update_UpdateStorage(serviceId, { kind: state_update_UpdateStorageKind.Set, storage });
12693
+ static set({ storage }) {
12694
+ return new state_update_UpdateStorage({ kind: state_update_UpdateStorageKind.Set, storage });
12700
12695
  }
12701
- static remove({ serviceId, key }) {
12702
- return new state_update_UpdateStorage(serviceId, { kind: state_update_UpdateStorageKind.Remove, key });
12696
+ static remove({ key }) {
12697
+ return new state_update_UpdateStorage({ kind: state_update_UpdateStorageKind.Remove, key });
12703
12698
  }
12704
12699
  get key() {
12705
12700
  if (this.action.kind === state_update_UpdateStorageKind.Remove) {
@@ -12908,12 +12903,12 @@ class InMemoryState extends WithDebug {
12908
12903
  * Modify the state and apply a single state update.
12909
12904
  */
12910
12905
  applyUpdate(update) {
12911
- const { servicesRemoved, servicesUpdates, preimages, storage, ...rest } = update;
12906
+ const { removed, created: _, updated, preimages, storage, ...rest } = update;
12912
12907
  // just assign all other variables
12913
12908
  Object.assign(this, rest);
12914
12909
  // and update the services state
12915
12910
  let result;
12916
- result = this.updateServices(servicesUpdates);
12911
+ result = this.updateServices(updated);
12917
12912
  if (result.isError) {
12918
12913
  return result;
12919
12914
  }
@@ -12925,7 +12920,7 @@ class InMemoryState extends WithDebug {
12925
12920
  if (result.isError) {
12926
12921
  return result;
12927
12922
  }
12928
- this.removeServices(servicesRemoved);
12923
+ this.removeServices(removed);
12929
12924
  return result_Result.ok(result_OK);
12930
12925
  }
12931
12926
  removeServices(servicesRemoved) {
@@ -12934,87 +12929,100 @@ class InMemoryState extends WithDebug {
12934
12929
  this.services.delete(serviceId);
12935
12930
  }
12936
12931
  }
12937
- updateStorage(storage) {
12938
- for (const { serviceId, action } of storage ?? []) {
12939
- const { kind } = action;
12940
- const service = this.services.get(serviceId);
12941
- if (service === undefined) {
12942
- return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update storage of non-existing service: ${serviceId}`);
12943
- }
12944
- if (kind === state_update_UpdateStorageKind.Set) {
12945
- const { key, value } = action.storage;
12946
- service.data.storage.set(key.toString(), service_StorageItem.create({ key, value }));
12947
- }
12948
- else if (kind === state_update_UpdateStorageKind.Remove) {
12949
- const { key } = action;
12950
- debug_check `
12932
+ updateStorage(storageUpdates) {
12933
+ if (storageUpdates === undefined) {
12934
+ return result_Result.ok(result_OK);
12935
+ }
12936
+ for (const [serviceId, updates] of storageUpdates.entries()) {
12937
+ for (const update of updates) {
12938
+ const { kind } = update.action;
12939
+ const service = this.services.get(serviceId);
12940
+ if (service === undefined) {
12941
+ return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update storage of non-existing service: ${serviceId}`);
12942
+ }
12943
+ if (kind === state_update_UpdateStorageKind.Set) {
12944
+ const { key, value } = update.action.storage;
12945
+ service.data.storage.set(key.toString(), service_StorageItem.create({ key, value }));
12946
+ }
12947
+ else if (kind === state_update_UpdateStorageKind.Remove) {
12948
+ const { key } = update.action;
12949
+ debug_check `
12951
12950
  ${service.data.storage.has(key.toString())}
12952
- Attempting to remove non-existing storage item at ${serviceId}: ${action.key}
12951
+ Attempting to remove non-existing storage item at ${serviceId}: ${update.action.key}
12953
12952
  `;
12954
- service.data.storage.delete(key.toString());
12955
- }
12956
- else {
12957
- debug_assertNever(kind);
12953
+ service.data.storage.delete(key.toString());
12954
+ }
12955
+ else {
12956
+ debug_assertNever(kind);
12957
+ }
12958
12958
  }
12959
12959
  }
12960
12960
  return result_Result.ok(result_OK);
12961
12961
  }
12962
- updatePreimages(preimages) {
12963
- for (const { serviceId, action } of preimages ?? []) {
12962
+ updatePreimages(preimagesUpdates) {
12963
+ if (preimagesUpdates === undefined) {
12964
+ return result_Result.ok(result_OK);
12965
+ }
12966
+ for (const [serviceId, updates] of preimagesUpdates.entries()) {
12964
12967
  const service = this.services.get(serviceId);
12965
12968
  if (service === undefined) {
12966
12969
  return result_Result.error(in_memory_state_UpdateError.NoService, `Attempting to update preimage of non-existing service: ${serviceId}`);
12967
12970
  }
12968
- const { kind } = action;
12969
- if (kind === state_update_UpdatePreimageKind.Provide) {
12970
- const { preimage, slot } = action;
12971
- if (service.data.preimages.has(preimage.hash)) {
12972
- return result_Result.error(in_memory_state_UpdateError.PreimageExists, `Overwriting existing preimage at ${serviceId}: ${preimage}`);
12973
- }
12974
- service.data.preimages.set(preimage.hash, preimage);
12975
- if (slot !== null) {
12976
- const lookupHistory = service.data.lookupHistory.get(preimage.hash);
12977
- const length = numbers_tryAsU32(preimage.blob.length);
12978
- const lookup = new service_LookupHistoryItem(preimage.hash, length, service_tryAsLookupHistorySlots([slot]));
12979
- if (lookupHistory === undefined) {
12980
- // no lookup history for that preimage at all (edge case, should be requested)
12981
- service.data.lookupHistory.set(preimage.hash, [lookup]);
12971
+ for (const update of updates) {
12972
+ const { kind } = update.action;
12973
+ if (kind === state_update_UpdatePreimageKind.Provide) {
12974
+ const { preimage, slot } = update.action;
12975
+ if (service.data.preimages.has(preimage.hash)) {
12976
+ return result_Result.error(in_memory_state_UpdateError.PreimageExists, `Overwriting existing preimage at ${serviceId}: ${preimage}`);
12977
+ }
12978
+ service.data.preimages.set(preimage.hash, preimage);
12979
+ if (slot !== null) {
12980
+ const lookupHistory = service.data.lookupHistory.get(preimage.hash);
12981
+ const length = numbers_tryAsU32(preimage.blob.length);
12982
+ const lookup = new service_LookupHistoryItem(preimage.hash, length, service_tryAsLookupHistorySlots([slot]));
12983
+ if (lookupHistory === undefined) {
12984
+ // no lookup history for that preimage at all (edge case, should be requested)
12985
+ service.data.lookupHistory.set(preimage.hash, [lookup]);
12986
+ }
12987
+ else {
12988
+ // insert or replace exiting entry
12989
+ const index = lookupHistory.map((x) => x.length).indexOf(length);
12990
+ lookupHistory.splice(index, index === -1 ? 0 : 1, lookup);
12991
+ }
12982
12992
  }
12983
- else {
12984
- // insert or replace exiting entry
12985
- const index = lookupHistory.map((x) => x.length).indexOf(length);
12986
- lookupHistory.splice(index, index === -1 ? 0 : 1, lookup);
12993
+ }
12994
+ else if (kind === state_update_UpdatePreimageKind.Remove) {
12995
+ const { hash, length } = update.action;
12996
+ service.data.preimages.delete(hash);
12997
+ const history = service.data.lookupHistory.get(hash) ?? [];
12998
+ const idx = history.map((x) => x.length).indexOf(length);
12999
+ if (idx !== -1) {
13000
+ history.splice(idx, 1);
12987
13001
  }
12988
13002
  }
12989
- }
12990
- else if (kind === state_update_UpdatePreimageKind.Remove) {
12991
- const { hash, length } = action;
12992
- service.data.preimages.delete(hash);
12993
- const history = service.data.lookupHistory.get(hash) ?? [];
12994
- const idx = history.map((x) => x.length).indexOf(length);
12995
- if (idx !== -1) {
12996
- history.splice(idx, 1);
13003
+ else if (kind === state_update_UpdatePreimageKind.UpdateOrAdd) {
13004
+ const { item } = update.action;
13005
+ const history = service.data.lookupHistory.get(item.hash) ?? [];
13006
+ const existingIdx = history.map((x) => x.length).indexOf(item.length);
13007
+ const removeCount = existingIdx === -1 ? 0 : 1;
13008
+ history.splice(existingIdx, removeCount, item);
13009
+ service.data.lookupHistory.set(item.hash, history);
13010
+ }
13011
+ else {
13012
+ debug_assertNever(kind);
12997
13013
  }
12998
- }
12999
- else if (kind === state_update_UpdatePreimageKind.UpdateOrAdd) {
13000
- const { item } = action;
13001
- const history = service.data.lookupHistory.get(item.hash) ?? [];
13002
- const existingIdx = history.map((x) => x.length).indexOf(item.length);
13003
- const removeCount = existingIdx === -1 ? 0 : 1;
13004
- history.splice(existingIdx, removeCount, item);
13005
- service.data.lookupHistory.set(item.hash, history);
13006
- }
13007
- else {
13008
- debug_assertNever(kind);
13009
13014
  }
13010
13015
  }
13011
13016
  return result_Result.ok(result_OK);
13012
13017
  }
13013
13018
  updateServices(servicesUpdates) {
13014
- for (const { serviceId, action } of servicesUpdates ?? []) {
13015
- const { kind, account } = action;
13019
+ if (servicesUpdates === undefined) {
13020
+ return result_Result.ok(result_OK);
13021
+ }
13022
+ for (const [serviceId, update] of servicesUpdates.entries()) {
13023
+ const { kind, account } = update.action;
13016
13024
  if (kind === state_update_UpdateServiceKind.Create) {
13017
- const { lookupHistory } = action;
13025
+ const { lookupHistory } = update.action;
13018
13026
  if (this.services.has(serviceId)) {
13019
13027
  return result_Result.error(in_memory_state_UpdateError.DuplicateService, `${serviceId} already exists!`);
13020
13028
  }
@@ -14938,7 +14946,6 @@ function hasher_getKeccakTrieHasher(hasher) {
14938
14946
 
14939
14947
 
14940
14948
 
14941
-
14942
14949
  /** What should be done with that key? */
14943
14950
  var StateEntryUpdateAction;
14944
14951
  (function (StateEntryUpdateAction) {
@@ -14954,76 +14961,88 @@ function* serialize_state_update_serializeStateUpdate(spec, blake2b, update) {
14954
14961
  yield* serializeBasicKeys(spec, update);
14955
14962
  const encode = (codec, val) => Encoder.encodeObject(codec, val, spec);
14956
14963
  // then let's proceed with service updates
14957
- yield* serializeServiceUpdates(update.servicesUpdates, encode, blake2b);
14964
+ yield* serializeServiceUpdates(update.updated, encode, blake2b);
14958
14965
  yield* serializePreimages(update.preimages, encode, blake2b);
14959
14966
  yield* serializeStorage(update.storage, blake2b);
14960
- yield* serializeRemovedServices(update.servicesRemoved);
14967
+ yield* serializeRemovedServices(update.removed);
14961
14968
  }
14962
14969
  function* serializeRemovedServices(servicesRemoved) {
14963
- for (const serviceId of servicesRemoved ?? []) {
14970
+ if (servicesRemoved === undefined) {
14971
+ return;
14972
+ }
14973
+ for (const serviceId of servicesRemoved) {
14964
14974
  // TODO [ToDr] what about all data associated with a service?
14965
14975
  const codec = serialize.serviceData(serviceId);
14966
14976
  yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
14967
14977
  }
14968
14978
  }
14969
- function* serializeStorage(storage, blake2b) {
14970
- for (const { action, serviceId } of storage ?? []) {
14971
- switch (action.kind) {
14972
- case UpdateStorageKind.Set: {
14973
- const key = action.storage.key;
14974
- const codec = serialize.serviceStorage(blake2b, serviceId, key);
14975
- yield [StateEntryUpdateAction.Insert, codec.key, action.storage.value];
14976
- break;
14977
- }
14978
- case UpdateStorageKind.Remove: {
14979
- const key = action.key;
14980
- const codec = serialize.serviceStorage(blake2b, serviceId, key);
14981
- yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
14982
- break;
14979
+ function* serializeStorage(storageUpdates, blake2b) {
14980
+ if (storageUpdates === undefined) {
14981
+ return;
14982
+ }
14983
+ for (const [serviceId, updates] of storageUpdates.entries()) {
14984
+ for (const { action } of updates) {
14985
+ switch (action.kind) {
14986
+ case UpdateStorageKind.Set: {
14987
+ const key = action.storage.key;
14988
+ const codec = serialize.serviceStorage(blake2b, serviceId, key);
14989
+ yield [StateEntryUpdateAction.Insert, codec.key, action.storage.value];
14990
+ break;
14991
+ }
14992
+ case UpdateStorageKind.Remove: {
14993
+ const key = action.key;
14994
+ const codec = serialize.serviceStorage(blake2b, serviceId, key);
14995
+ yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
14996
+ break;
14997
+ }
14983
14998
  }
14984
- default:
14985
- assertNever(action);
14986
14999
  }
14987
15000
  }
14988
15001
  }
14989
- function* serializePreimages(preimages, encode, blake2b) {
14990
- for (const { action, serviceId } of preimages ?? []) {
14991
- switch (action.kind) {
14992
- case UpdatePreimageKind.Provide: {
14993
- const { hash, blob } = action.preimage;
14994
- const codec = serialize.servicePreimages(blake2b, serviceId, hash);
14995
- yield [StateEntryUpdateAction.Insert, codec.key, blob];
14996
- if (action.slot !== null) {
14997
- const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, tryAsU32(blob.length));
14998
- yield [
14999
- StateEntryUpdateAction.Insert,
15000
- codec2.key,
15001
- encode(codec2.Codec, tryAsLookupHistorySlots([action.slot])),
15002
- ];
15002
+ function* serializePreimages(preimagesUpdates, encode, blake2b) {
15003
+ if (preimagesUpdates === undefined) {
15004
+ return;
15005
+ }
15006
+ for (const [serviceId, updates] of preimagesUpdates.entries()) {
15007
+ for (const { action } of updates) {
15008
+ switch (action.kind) {
15009
+ case UpdatePreimageKind.Provide: {
15010
+ const { hash, blob } = action.preimage;
15011
+ const codec = serialize.servicePreimages(blake2b, serviceId, hash);
15012
+ yield [StateEntryUpdateAction.Insert, codec.key, blob];
15013
+ if (action.slot !== null) {
15014
+ const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, tryAsU32(blob.length));
15015
+ yield [
15016
+ StateEntryUpdateAction.Insert,
15017
+ codec2.key,
15018
+ encode(codec2.Codec, tryAsLookupHistorySlots([action.slot])),
15019
+ ];
15020
+ }
15021
+ break;
15022
+ }
15023
+ case UpdatePreimageKind.UpdateOrAdd: {
15024
+ const { hash, length, slots } = action.item;
15025
+ const codec = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
15026
+ yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, slots)];
15027
+ break;
15028
+ }
15029
+ case UpdatePreimageKind.Remove: {
15030
+ const { hash, length } = action;
15031
+ const codec = serialize.servicePreimages(blake2b, serviceId, hash);
15032
+ yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
15033
+ const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
15034
+ yield [StateEntryUpdateAction.Remove, codec2.key, EMPTY_BLOB];
15035
+ break;
15003
15036
  }
15004
- break;
15005
- }
15006
- case UpdatePreimageKind.UpdateOrAdd: {
15007
- const { hash, length, slots } = action.item;
15008
- const codec = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
15009
- yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, slots)];
15010
- break;
15011
- }
15012
- case UpdatePreimageKind.Remove: {
15013
- const { hash, length } = action;
15014
- const codec = serialize.servicePreimages(blake2b, serviceId, hash);
15015
- yield [StateEntryUpdateAction.Remove, codec.key, EMPTY_BLOB];
15016
- const codec2 = serialize.serviceLookupHistory(blake2b, serviceId, hash, length);
15017
- yield [StateEntryUpdateAction.Remove, codec2.key, EMPTY_BLOB];
15018
- break;
15019
15037
  }
15020
- default:
15021
- assertNever(action);
15022
15038
  }
15023
15039
  }
15024
15040
  }
15025
15041
  function* serializeServiceUpdates(servicesUpdates, encode, blake2b) {
15026
- for (const { action, serviceId } of servicesUpdates ?? []) {
15042
+ if (servicesUpdates === undefined) {
15043
+ return;
15044
+ }
15045
+ for (const [serviceId, { action }] of servicesUpdates.entries()) {
15027
15046
  // new service being created or updated
15028
15047
  const codec = serialize.serviceData(serviceId);
15029
15048
  yield [StateEntryUpdateAction.Insert, codec.key, encode(codec.Codec, action.account)];
@@ -15746,7 +15765,7 @@ class preimages_Preimages {
15746
15765
  }
15747
15766
  }
15748
15767
  const { preimages, slot } = input;
15749
- const pendingChanges = [];
15768
+ const pendingChanges = new Map();
15750
15769
  // select preimages for integration
15751
15770
  for (const preimage of preimages) {
15752
15771
  const { requester, blob } = preimage;
@@ -15763,11 +15782,12 @@ class preimages_Preimages {
15763
15782
  return Result.error(PreimagesErrorCode.PreimageUnneeded);
15764
15783
  }
15765
15784
  // https://graypaper.fluffylabs.dev/#/5f542d7/18c00018f300
15766
- pendingChanges.push(UpdatePreimage.provide({
15767
- serviceId: requester,
15785
+ const updates = pendingChanges.get(requester) ?? [];
15786
+ updates.push(UpdatePreimage.provide({
15768
15787
  preimage: PreimageItem.create({ hash, blob }),
15769
15788
  slot,
15770
15789
  }));
15790
+ pendingChanges.set(requester, updates);
15771
15791
  }
15772
15792
  return Result.ok({
15773
15793
  preimages: pendingChanges,
@@ -16901,6 +16921,14 @@ async function getRootHash(yieldedRoots) {
16901
16921
 
16902
16922
 
16903
16923
  const InsufficientFundsError = "insufficient funds";
16924
+ /** Deep clone of a map with array. */
16925
+ function deepCloneMapWithArray(map) {
16926
+ const cloned = [];
16927
+ for (const [k, v] of map.entries()) {
16928
+ cloned.push([k, v.slice()]);
16929
+ }
16930
+ return new Map(cloned);
16931
+ }
16904
16932
  /**
16905
16933
  * State updates that currently accumulating service produced.
16906
16934
  *
@@ -16930,10 +16958,11 @@ class state_update_AccumulationStateUpdate {
16930
16958
  /** Create new empty state update. */
16931
16959
  static empty() {
16932
16960
  return new state_update_AccumulationStateUpdate({
16933
- servicesUpdates: [],
16934
- servicesRemoved: [],
16935
- preimages: [],
16936
- storage: [],
16961
+ created: [],
16962
+ updated: new Map(),
16963
+ removed: [],
16964
+ preimages: new Map(),
16965
+ storage: new Map(),
16937
16966
  }, []);
16938
16967
  }
16939
16968
  /** Create a state update with some existing, yet uncommited services updates. */
@@ -16945,10 +16974,13 @@ class state_update_AccumulationStateUpdate {
16945
16974
  /** Create a copy of another `StateUpdate`. Used by checkpoints. */
16946
16975
  static copyFrom(from) {
16947
16976
  const serviceUpdates = {
16948
- servicesUpdates: [...from.services.servicesUpdates],
16949
- servicesRemoved: [...from.services.servicesRemoved],
16950
- preimages: [...from.services.preimages],
16951
- storage: [...from.services.storage],
16977
+ // shallow copy
16978
+ created: [...from.services.created],
16979
+ updated: new Map(from.services.updated),
16980
+ removed: [...from.services.removed],
16981
+ // deep copy
16982
+ preimages: deepCloneMapWithArray(from.services.preimages),
16983
+ storage: deepCloneMapWithArray(from.services.storage),
16952
16984
  };
16953
16985
  const transfers = [...from.transfers];
16954
16986
  const update = new state_update_AccumulationStateUpdate(serviceUpdates, transfers, new Map(from.yieldedRoots));
@@ -16996,9 +17028,9 @@ class state_update_PartiallyUpdatedState {
16996
17028
  if (destination === null) {
16997
17029
  return null;
16998
17030
  }
16999
- const maybeNewService = this.stateUpdate.services.servicesUpdates.find((update) => update.serviceId === destination);
17000
- if (maybeNewService !== undefined) {
17001
- return maybeNewService.action.account;
17031
+ const maybeUpdatedServiceInfo = this.stateUpdate.services.updated.get(destination);
17032
+ if (maybeUpdatedServiceInfo !== undefined) {
17033
+ return maybeUpdatedServiceInfo.action.account;
17002
17034
  }
17003
17035
  const maybeService = this.state.getService(destination);
17004
17036
  if (maybeService === null) {
@@ -17007,7 +17039,8 @@ class state_update_PartiallyUpdatedState {
17007
17039
  return maybeService.getInfo();
17008
17040
  }
17009
17041
  getStorage(serviceId, rawKey) {
17010
- const item = this.stateUpdate.services.storage.find((x) => x.serviceId === serviceId && x.key.isEqualTo(rawKey));
17042
+ const storages = this.stateUpdate.services.storage.get(serviceId) ?? [];
17043
+ const item = storages.find((x) => x.key.isEqualTo(rawKey));
17011
17044
  if (item !== undefined) {
17012
17045
  return item.value;
17013
17046
  }
@@ -17022,10 +17055,11 @@ class state_update_PartiallyUpdatedState {
17022
17055
  * the existence in `preimages` map.
17023
17056
  */
17024
17057
  hasPreimage(serviceId, hash) {
17025
- const providedPreimage = this.stateUpdate.services.preimages.find(
17058
+ const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
17059
+ const providedPreimage = preimages.find(
17026
17060
  // we ignore the action here, since if there is <any> update on that
17027
17061
  // hash it means it has to exist, right?
17028
- (p) => p.serviceId === serviceId && p.hash.isEqualTo(hash));
17062
+ (p) => p.hash.isEqualTo(hash));
17029
17063
  if (providedPreimage !== undefined) {
17030
17064
  return true;
17031
17065
  }
@@ -17038,7 +17072,8 @@ class state_update_PartiallyUpdatedState {
17038
17072
  }
17039
17073
  getPreimage(serviceId, hash) {
17040
17074
  // TODO [ToDr] Should we verify availability here?
17041
- const freshlyProvided = this.stateUpdate.services.preimages.find((x) => x.serviceId === serviceId && x.hash.isEqualTo(hash));
17075
+ const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
17076
+ const freshlyProvided = preimages.find((x) => x.hash.isEqualTo(hash));
17042
17077
  if (freshlyProvided !== undefined && freshlyProvided.action.kind === UpdatePreimageKind.Provide) {
17043
17078
  return freshlyProvided.action.preimage.blob;
17044
17079
  }
@@ -17047,10 +17082,11 @@ class state_update_PartiallyUpdatedState {
17047
17082
  }
17048
17083
  /** Get status of a preimage of current service taking into account any updates. */
17049
17084
  getLookupHistory(currentTimeslot, serviceId, hash, length) {
17085
+ const preimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
17050
17086
  // TODO [ToDr] This is most likely wrong. We may have `provide` and `remove` within
17051
17087
  // the same state update. We should however switch to proper "updated state"
17052
17088
  // representation soon.
17053
- const updatedPreimage = this.stateUpdate.services.preimages.findLast((update) => update.serviceId === serviceId && update.hash.isEqualTo(hash) && BigInt(update.length) === length);
17089
+ const updatedPreimage = preimages.findLast((update) => update.hash.isEqualTo(hash) && BigInt(update.length) === length);
17054
17090
  const stateFallback = () => {
17055
17091
  // fallback to state lookup
17056
17092
  const service = this.state.getService(serviceId);
@@ -17087,14 +17123,15 @@ class state_update_PartiallyUpdatedState {
17087
17123
  /* State update functions. */
17088
17124
  updateStorage(serviceId, key, value) {
17089
17125
  const update = value === null
17090
- ? UpdateStorage.remove({ serviceId, key })
17126
+ ? UpdateStorage.remove({ key })
17091
17127
  : UpdateStorage.set({
17092
- serviceId,
17093
17128
  storage: StorageItem.create({ key, value }),
17094
17129
  });
17095
- const index = this.stateUpdate.services.storage.findIndex((x) => x.serviceId === update.serviceId && x.key.isEqualTo(key));
17130
+ const storages = this.stateUpdate.services.storage.get(serviceId) ?? [];
17131
+ const index = storages.findIndex((x) => x.key.isEqualTo(key));
17096
17132
  const count = index === -1 ? 0 : 1;
17097
- this.stateUpdate.services.storage.splice(index, count, update);
17133
+ storages.splice(index, count, update);
17134
+ this.stateUpdate.services.storage.set(serviceId, storages);
17098
17135
  }
17099
17136
  /**
17100
17137
  * Update a preimage.
@@ -17102,8 +17139,10 @@ class state_update_PartiallyUpdatedState {
17102
17139
  * Note we store all previous entries as well, since there might be a sequence of:
17103
17140
  * `provide` -> `remove` and both should update the end state somehow.
17104
17141
  */
17105
- updatePreimage(newUpdate) {
17106
- this.stateUpdate.services.preimages.push(newUpdate);
17142
+ updatePreimage(serviceId, newUpdate) {
17143
+ const updatePreimages = this.stateUpdate.services.preimages.get(serviceId) ?? [];
17144
+ updatePreimages.push(newUpdate);
17145
+ this.stateUpdate.services.preimages.set(serviceId, updatePreimages);
17107
17146
  }
17108
17147
  updateServiceStorageUtilisation(serviceId, items, bytes, serviceInfo) {
17109
17148
  check `${items >= 0} storageUtilisationCount has to be a positive number, got: ${items}`;
@@ -17127,22 +17166,25 @@ class state_update_PartiallyUpdatedState {
17127
17166
  return Result.ok(OK);
17128
17167
  }
17129
17168
  updateServiceInfo(serviceId, newInfo) {
17130
- const idx = this.stateUpdate.services.servicesUpdates.findIndex((x) => x.serviceId === serviceId);
17131
- const toRemove = idx === -1 ? 0 : 1;
17132
- const existingItem = this.stateUpdate.services.servicesUpdates[idx];
17133
- if (existingItem?.action.kind === UpdateServiceKind.Create) {
17134
- this.stateUpdate.services.servicesUpdates.splice(idx, toRemove, UpdateService.create({
17135
- serviceId,
17169
+ const existingUpdate = this.stateUpdate.services.updated.get(serviceId);
17170
+ if (existingUpdate?.action.kind === UpdateServiceKind.Create) {
17171
+ this.stateUpdate.services.updated.set(serviceId, UpdateService.create({
17136
17172
  serviceInfo: newInfo,
17137
- lookupHistory: existingItem.action.lookupHistory,
17173
+ lookupHistory: existingUpdate.action.lookupHistory,
17138
17174
  }));
17139
17175
  return;
17140
17176
  }
17141
- this.stateUpdate.services.servicesUpdates.splice(idx, toRemove, UpdateService.update({
17142
- serviceId,
17177
+ this.stateUpdate.services.updated.set(serviceId, UpdateService.update({
17143
17178
  serviceInfo: newInfo,
17144
17179
  }));
17145
17180
  }
17181
+ createService(serviceId, newInfo, newLookupHistory) {
17182
+ this.stateUpdate.services.created.push(serviceId);
17183
+ this.stateUpdate.services.updated.set(serviceId, UpdateService.create({
17184
+ serviceInfo: newInfo,
17185
+ lookupHistory: newLookupHistory,
17186
+ }));
17187
+ }
17146
17188
  getPrivilegedServices() {
17147
17189
  if (this.stateUpdate.privilegedServices !== null) {
17148
17190
  return this.stateUpdate.privilegedServices;
@@ -21205,15 +21247,13 @@ class accumulate_externalities_AccumulateExternalities {
21205
21247
  const clampedLength = clampU64ToU32(length);
21206
21248
  if (existingPreimage === null) {
21207
21249
  // https://graypaper.fluffylabs.dev/#/9a08063/38a60038a600?v=0.6.6
21208
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
21209
- serviceId: this.currentServiceId,
21250
+ this.updatedState.updatePreimage(this.currentServiceId, UpdatePreimage.updateOrAdd({
21210
21251
  lookupHistory: new LookupHistoryItem(hash, clampedLength, tryAsLookupHistorySlots([])),
21211
21252
  }));
21212
21253
  }
21213
21254
  else {
21214
21255
  /** https://graypaper.fluffylabs.dev/#/9a08063/38ca0038ca00?v=0.6.6 */
21215
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
21216
- serviceId: this.currentServiceId,
21256
+ this.updatedState.updatePreimage(this.currentServiceId, UpdatePreimage.updateOrAdd({
21217
21257
  lookupHistory: new LookupHistoryItem(hash, clampedLength, tryAsLookupHistorySlots([...existingPreimage.slots, this.currentTimeslot])),
21218
21258
  }));
21219
21259
  }
@@ -21238,8 +21278,7 @@ class accumulate_externalities_AccumulateExternalities {
21238
21278
  if (res.isError) {
21239
21279
  return Result.error(ForgetPreimageError.StorageUtilisationError);
21240
21280
  }
21241
- this.updatedState.updatePreimage(UpdatePreimage.remove({
21242
- serviceId,
21281
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.remove({
21243
21282
  hash: status.hash,
21244
21283
  length: status.length,
21245
21284
  }));
@@ -21254,8 +21293,7 @@ class accumulate_externalities_AccumulateExternalities {
21254
21293
  if (res.isError) {
21255
21294
  return Result.error(ForgetPreimageError.StorageUtilisationError);
21256
21295
  }
21257
- this.updatedState.updatePreimage(UpdatePreimage.remove({
21258
- serviceId,
21296
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.remove({
21259
21297
  hash: status.hash,
21260
21298
  length: status.length,
21261
21299
  }));
@@ -21265,8 +21303,7 @@ class accumulate_externalities_AccumulateExternalities {
21265
21303
  }
21266
21304
  // https://graypaper.fluffylabs.dev/#/9a08063/38c80138c801?v=0.6.6
21267
21305
  if (s.status === PreimageStatusKind.Available) {
21268
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
21269
- serviceId,
21306
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.updateOrAdd({
21270
21307
  lookupHistory: new LookupHistoryItem(status.hash, status.length, tryAsLookupHistorySlots([s.data[0], t])),
21271
21308
  }));
21272
21309
  return Result.ok(OK);
@@ -21275,8 +21312,7 @@ class accumulate_externalities_AccumulateExternalities {
21275
21312
  if (s.status === PreimageStatusKind.Reavailable) {
21276
21313
  const y = s.data[1];
21277
21314
  if (y < t - this.chainSpec.preimageExpungePeriod) {
21278
- this.updatedState.updatePreimage(UpdatePreimage.updateOrAdd({
21279
- serviceId,
21315
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.updateOrAdd({
21280
21316
  lookupHistory: new LookupHistoryItem(status.hash, status.length, tryAsLookupHistorySlots([s.data[2], t])),
21281
21317
  }));
21282
21318
  return Result.ok(OK);
@@ -21367,11 +21403,7 @@ class accumulate_externalities_AccumulateExternalities {
21367
21403
  }
21368
21404
  // add the new service with selected ID
21369
21405
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/36be0336c003?v=0.7.2
21370
- this.updatedState.stateUpdate.services.servicesUpdates.push(UpdateService.create({
21371
- serviceId: newServiceId,
21372
- serviceInfo: newAccount,
21373
- lookupHistory: newLookupItem,
21374
- }));
21406
+ this.updatedState.createService(newServiceId, newAccount, newLookupItem);
21375
21407
  // update the balance of current service
21376
21408
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/36c20336c403?v=0.7.2
21377
21409
  this.updatedState.updateServiceInfo(this.currentServiceId, updatedCurrentAccount);
@@ -21382,12 +21414,8 @@ class accumulate_externalities_AccumulateExternalities {
21382
21414
  }
21383
21415
  const newServiceId = this.nextNewServiceId;
21384
21416
  // add the new service
21385
- // https://graypaper.fluffylabs.dev/#/ab2cdbd/36e70336e903?v=0.7.2
21386
- this.updatedState.stateUpdate.services.servicesUpdates.push(UpdateService.create({
21387
- serviceId: newServiceId,
21388
- serviceInfo: newAccount,
21389
- lookupHistory: newLookupItem,
21390
- }));
21417
+ // https://graypaper.fluffylabs.dev/#/7e6ff6a/36cb0236cb02?v=0.6.7
21418
+ this.updatedState.createService(newServiceId, newAccount, newLookupItem);
21391
21419
  // update the balance of current service
21392
21420
  // https://graypaper.fluffylabs.dev/#/ab2cdbd/36ec0336ee03?v=0.7.2
21393
21421
  this.updatedState.updateServiceInfo(this.currentServiceId, updatedCurrentAccount);
@@ -21534,8 +21562,7 @@ class accumulate_externalities_AccumulateExternalities {
21534
21562
  return Result.error(ProvidePreimageError.AlreadyProvided);
21535
21563
  }
21536
21564
  // setting up the new preimage
21537
- this.updatedState.updatePreimage(UpdatePreimage.provide({
21538
- serviceId,
21565
+ this.updatedState.updatePreimage(serviceId, UpdatePreimage.provide({
21539
21566
  preimage: PreimageItem.create({
21540
21567
  hash: preimageHash,
21541
21568
  blob: preimage,
@@ -21579,11 +21606,13 @@ class accumulate_externalities_AccumulateExternalities {
21579
21606
  balance: newBalance.value,
21580
21607
  }));
21581
21608
  // and finally add an ejected service.
21582
- this.updatedState.stateUpdate.services.servicesRemoved.push(destination);
21609
+ this.updatedState.stateUpdate.services.removed.push(destination);
21583
21610
  // take care of the code preimage and its lookup history
21584
21611
  // 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).
21585
21612
  const preimageLength = tryAsU32(Number(l));
21586
- this.updatedState.stateUpdate.services.preimages.push(UpdatePreimage.remove({ serviceId: destination, hash: previousCodeHash, length: preimageLength }));
21613
+ const preimages = this.updatedState.stateUpdate.services.preimages.get(destination) ?? [];
21614
+ preimages.push(UpdatePreimage.remove({ hash: previousCodeHash, length: preimageLength }));
21615
+ this.updatedState.stateUpdate.services.preimages.set(destination, preimages);
21587
21616
  return Result.ok(OK);
21588
21617
  }
21589
21618
  read(serviceId, rawKey) {
@@ -22468,9 +22497,6 @@ class host_call_memory_HostCallMemory {
22468
22497
  }
22469
22498
  return this.memory.loadInto(result, tryAsMemoryIndex(Number(startAddress)));
22470
22499
  }
22471
- getMemory() {
22472
- return this.memory;
22473
- }
22474
22500
  }
22475
22501
 
22476
22502
  ;// CONCATENATED MODULE: ./packages/core/pvm-host-calls/host-call-registers.ts
@@ -24542,19 +24568,16 @@ class accumulate_Accumulate {
24542
24568
  const gasLimit = tryAsServiceGas(this.chainSpec.maxBlockGas > calculatedGasLimit ? this.chainSpec.maxBlockGas : calculatedGasLimit);
24543
24569
  return tryAsServiceGas(gasLimit);
24544
24570
  }
24545
- hasDuplicatedServicesCreated(updateServices) {
24546
- const createdServiceIds = new Set();
24547
- for (const update of updateServices) {
24548
- if (update.action.kind === UpdateServiceKind.Create) {
24549
- const serviceId = update.serviceId;
24550
- if (createdServiceIds.has(serviceId)) {
24551
- accumulate_logger.log `Duplicated Service creation detected ${serviceId}. Block is invalid.`;
24552
- return true;
24553
- }
24554
- createdServiceIds.add(serviceId);
24555
- }
24556
- }
24557
- return false;
24571
+ /**
24572
+ * Detects the very unlikely situation where multiple services are created with the same ID.
24573
+ *
24574
+ * https://graypaper.fluffylabs.dev/#/ab2cdbd/30f20330f403?v=0.7.2
24575
+ *
24576
+ * NOTE: This is public only for testing purposes and should not be used outside of accumulation.
24577
+ */
24578
+ hasDuplicatedServiceIdCreated(createdIds) {
24579
+ const uniqueIds = new Set(createdIds);
24580
+ return uniqueIds.size !== createdIds.length;
24558
24581
  }
24559
24582
  async transition({ reports, slot, entropy }) {
24560
24583
  const statistics = new Map();
@@ -24576,7 +24599,8 @@ class accumulate_Accumulate {
24576
24599
  const accumulated = accumulatableReports.subview(0, accumulatedReports);
24577
24600
  const { services, yieldedRoots, transfers, validatorsData, privilegedServices, authorizationQueues, ...stateUpdateRest } = state;
24578
24601
  assertEmpty(stateUpdateRest);
24579
- if (this.hasDuplicatedServicesCreated(services.servicesUpdates)) {
24602
+ if (this.hasDuplicatedServiceIdCreated(services.created)) {
24603
+ accumulate_logger.trace `Duplicated Service creation detected. Block is invalid.`;
24580
24604
  return Result.error(ACCUMULATION_ERROR);
24581
24605
  }
24582
24606
  const accStateUpdate = this.getAccumulationStateUpdate(accumulated.toArray(), toAccumulateLater, slot, Array.from(statistics.keys()), services);
@@ -26266,6 +26290,16 @@ class chain_stf_OnChain {
26266
26290
  });
26267
26291
  const { statistics, ...statisticsRest } = statisticsUpdate;
26268
26292
  assertEmpty(statisticsRest);
26293
+ // Concat accumulatePreimages updates with preimages
26294
+ for (const [serviceId, accPreimageUpdates] of accumulatePreimages.entries()) {
26295
+ const preimagesUpdates = preimages.get(serviceId);
26296
+ if (preimagesUpdates === undefined) {
26297
+ preimages.set(serviceId, accPreimageUpdates);
26298
+ }
26299
+ else {
26300
+ preimages.set(serviceId, preimagesUpdates.concat(accPreimageUpdates));
26301
+ }
26302
+ }
26269
26303
  return Result.ok({
26270
26304
  ...(maybeAuthorizationQueues !== undefined ? { authQueues: maybeAuthorizationQueues } : {}),
26271
26305
  ...(maybeDesignatedValidatorData !== undefined ? { designatedValidatorData: maybeDesignatedValidatorData } : {}),
@@ -26287,7 +26321,7 @@ class chain_stf_OnChain {
26287
26321
  recentlyAccumulated,
26288
26322
  accumulationOutputLog,
26289
26323
  ...servicesUpdate,
26290
- preimages: preimages.concat(accumulatePreimages),
26324
+ preimages,
26291
26325
  });
26292
26326
  }
26293
26327
  getUsedAuthorizerHashes(guarantees) {