envio 3.5.0-alpha.1 → 3.5.0-alpha.3

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 (99) hide show
  1. package/index.d.ts +10 -6
  2. package/package.json +6 -6
  3. package/src/BatchProcessing.res +27 -0
  4. package/src/BatchProcessing.res.mjs +12 -0
  5. package/src/ChainFetching.res +5 -5
  6. package/src/ChainFetching.res.mjs +3 -4
  7. package/src/ChainState.res +48 -25
  8. package/src/ChainState.res.mjs +23 -29
  9. package/src/ChainState.resi +2 -6
  10. package/src/Change.res +3 -3
  11. package/src/Config.res +2 -6
  12. package/src/Config.res.mjs +2 -12
  13. package/src/Core.res +3 -0
  14. package/src/CrossChainState.res +33 -10
  15. package/src/CrossChainState.res.mjs +21 -6
  16. package/src/CrossChainState.resi +3 -0
  17. package/src/EntityId.res +15 -0
  18. package/src/EntityId.res.mjs +9 -0
  19. package/src/EventConfigBuilder.res +1 -58
  20. package/src/EventConfigBuilder.res.mjs +1 -33
  21. package/src/FetchState.res +510 -460
  22. package/src/FetchState.res.mjs +413 -428
  23. package/src/FinalizeBackfill.res +34 -0
  24. package/src/FinalizeBackfill.res.mjs +26 -0
  25. package/src/HandlerRegister.res +45 -0
  26. package/src/HandlerRegister.res.mjs +43 -0
  27. package/src/InMemoryStore.res +11 -4
  28. package/src/InMemoryTable.res +26 -24
  29. package/src/InMemoryTable.res.mjs +19 -18
  30. package/src/IndexerState.res +71 -2
  31. package/src/IndexerState.res.mjs +67 -3
  32. package/src/IndexerState.resi +5 -0
  33. package/src/Internal.res +17 -8
  34. package/src/LoadLayer.res +9 -1
  35. package/src/LoadLayer.res.mjs +1 -0
  36. package/src/LogSelection.res +2 -1
  37. package/src/Metrics.res +37 -6
  38. package/src/Metrics.res.mjs +5 -1
  39. package/src/Persistence.res +12 -1
  40. package/src/PgStorage.res +411 -57
  41. package/src/PgStorage.res.mjs +262 -41
  42. package/src/SimulateItems.res +2 -2
  43. package/src/TestIndexer.res +9 -5
  44. package/src/TestIndexer.res.mjs +5 -2
  45. package/src/UserContext.res +3 -3
  46. package/src/Writing.res +12 -2
  47. package/src/Writing.res.mjs +13 -2
  48. package/src/bindings/ClickHouse.res +5 -3
  49. package/src/bindings/ClickHouse.res.mjs +2 -5
  50. package/src/bindings/Vitest.res +22 -1
  51. package/src/bindings/Vitest.res.mjs +15 -0
  52. package/src/db/EntityFilter.res +0 -4
  53. package/src/db/EntityFilter.res.mjs +1 -8
  54. package/src/db/EntityHistory.res +16 -7
  55. package/src/db/EntityHistory.res.mjs +7 -6
  56. package/src/db/IndexRegistry.res +219 -0
  57. package/src/db/IndexRegistry.res.mjs +195 -0
  58. package/src/db/InternalTable.res +7 -0
  59. package/src/db/InternalTable.res.mjs +7 -0
  60. package/src/db/Table.res +53 -22
  61. package/src/db/Table.res.mjs +56 -18
  62. package/src/sources/AddressSet.res +48 -0
  63. package/src/sources/AddressSet.res.mjs +11 -0
  64. package/src/sources/AddressStore.res +152 -0
  65. package/src/sources/AddressStore.res.mjs +97 -0
  66. package/src/sources/EvmChain.res +3 -0
  67. package/src/sources/EvmChain.res.mjs +4 -2
  68. package/src/sources/EvmHyperSyncSource.res +6 -3
  69. package/src/sources/EvmHyperSyncSource.res.mjs +3 -3
  70. package/src/sources/EvmRpcClient.res +6 -3
  71. package/src/sources/EvmRpcClient.res.mjs +3 -3
  72. package/src/sources/FuelHyperSync.res +4 -3
  73. package/src/sources/FuelHyperSync.res.mjs +3 -3
  74. package/src/sources/FuelHyperSync.resi +2 -1
  75. package/src/sources/FuelHyperSyncClient.res +12 -6
  76. package/src/sources/FuelHyperSyncClient.res.mjs +2 -2
  77. package/src/sources/FuelHyperSyncSource.res +7 -4
  78. package/src/sources/FuelHyperSyncSource.res.mjs +3 -3
  79. package/src/sources/HyperSync.res +6 -4
  80. package/src/sources/HyperSync.res.mjs +2 -3
  81. package/src/sources/HyperSync.resi +1 -1
  82. package/src/sources/HyperSyncClient.res +18 -9
  83. package/src/sources/HyperSyncClient.res.mjs +4 -4
  84. package/src/sources/RpcSource.res +15 -10
  85. package/src/sources/RpcSource.res.mjs +3 -4
  86. package/src/sources/SimulateSource.res +26 -11
  87. package/src/sources/SimulateSource.res.mjs +13 -5
  88. package/src/sources/Source.res +4 -2
  89. package/src/sources/SourceManager.res +2 -3
  90. package/src/sources/SourceManager.res.mjs +2 -3
  91. package/src/sources/Svm.res +1 -2
  92. package/src/sources/Svm.res.mjs +1 -1
  93. package/src/sources/SvmHyperSyncClient.res +12 -3
  94. package/src/sources/SvmHyperSyncClient.res.mjs +2 -2
  95. package/src/sources/SvmHyperSyncSource.res +10 -5
  96. package/src/sources/SvmHyperSyncSource.res.mjs +5 -4
  97. package/src/IndexingAddresses.res +0 -151
  98. package/src/IndexingAddresses.res.mjs +0 -130
  99. package/src/IndexingAddresses.resi +0 -39
@@ -4,24 +4,31 @@ import * as Env from "./Env.res.mjs";
4
4
  import * as Utils from "./Utils.res.mjs";
5
5
  import * as Js_math from "@rescript/runtime/lib/es6/Js_math.js";
6
6
  import * as Logging from "./Logging.res.mjs";
7
+ import * as AddressSet from "./sources/AddressSet.res.mjs";
7
8
  import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
9
+ import * as AddressStore from "./sources/AddressStore.res.mjs";
8
10
  import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
9
11
  import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
10
12
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
11
13
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
12
14
  import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
13
15
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
14
- import * as IndexingAddresses from "./IndexingAddresses.res.mjs";
15
16
 
16
- let deriveContractNameByAddress = Utils.$$WeakMap.memoize(addressesByContractName => {
17
- let result = {};
18
- Utils.Dict.forEachWithKey(addressesByContractName, (addresses, contractName) => {
19
- for (let i = 0, i_finish = addresses.length; i < i_finish; ++i) {
20
- result[addresses[i]] = contractName;
21
- }
22
- });
23
- return result;
24
- });
17
+ function withAddresses(p, addresses) {
18
+ return {
19
+ id: p.id,
20
+ latestFetchedBlock: p.latestFetchedBlock,
21
+ selection: p.selection,
22
+ addresses: addresses,
23
+ mergeBlock: p.mergeBlock,
24
+ dynamicContract: p.dynamicContract,
25
+ mutPendingQueries: p.mutPendingQueries,
26
+ sourceRangeCapacity: p.sourceRangeCapacity,
27
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
28
+ eventDensity: p.eventDensity,
29
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
30
+ };
31
+ }
25
32
 
26
33
  function densityItemsTarget(density, fromBlock, toBlock, chainTargetBlock) {
27
34
  return Primitive_int.max(1, Math.ceil(((Stdlib_Option.getOr(toBlock, chainTargetBlock) - fromBlock | 0) + 1 | 0) * density) | 0);
@@ -69,7 +76,7 @@ function getOrThrow(optimizedPartitions, partitionId) {
69
76
  }
70
77
 
71
78
  function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAddrInPartition, nextPartitionIndexRef) {
72
- let combinedAddresses = p1.addressesByContractName[contractName].concat(p2.addressesByContractName[contractName]);
79
+ let combinedAddresses = p1.addresses.merge(p2.addresses);
73
80
  let p1Below = p1.latestFetchedBlock.blockNumber < potentialMergeBlock;
74
81
  let p2Below = p2.latestFetchedBlock.blockNumber < potentialMergeBlock;
75
82
  let completed = [];
@@ -80,7 +87,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
80
87
  id: p1.id,
81
88
  latestFetchedBlock: p1.latestFetchedBlock,
82
89
  selection: p1.selection,
83
- addressesByContractName: p1.addressesByContractName,
90
+ addresses: p1.addresses,
84
91
  mergeBlock: potentialMergeBlock,
85
92
  dynamicContract: p1.dynamicContract,
86
93
  mutPendingQueries: p1.mutPendingQueries,
@@ -93,7 +100,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
93
100
  id: p2.id,
94
101
  latestFetchedBlock: p2.latestFetchedBlock,
95
102
  selection: p2.selection,
96
- addressesByContractName: p2.addressesByContractName,
103
+ addresses: p2.addresses,
97
104
  mergeBlock: potentialMergeBlock,
98
105
  dynamicContract: p2.dynamicContract,
99
106
  mutPendingQueries: p2.mutPendingQueries,
@@ -122,7 +129,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
122
129
  blockTimestamp: 0
123
130
  },
124
131
  selection: p1.selection,
125
- addressesByContractName: {},
132
+ addresses: p1.addresses,
126
133
  mergeBlock: undefined,
127
134
  dynamicContract: contractName,
128
135
  mutPendingQueries: [],
@@ -136,7 +143,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
136
143
  id: p1.id,
137
144
  latestFetchedBlock: p1.latestFetchedBlock,
138
145
  selection: p1.selection,
139
- addressesByContractName: p1.addressesByContractName,
146
+ addresses: p1.addresses,
140
147
  mergeBlock: potentialMergeBlock,
141
148
  dynamicContract: p1.dynamicContract,
142
149
  mutPendingQueries: p1.mutPendingQueries,
@@ -152,7 +159,7 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
152
159
  id: p2.id,
153
160
  latestFetchedBlock: p2.latestFetchedBlock,
154
161
  selection: p2.selection,
155
- addressesByContractName: p2.addressesByContractName,
162
+ addresses: p2.addresses,
156
163
  mergeBlock: potentialMergeBlock,
157
164
  dynamicContract: p2.dynamicContract,
158
165
  mutPendingQueries: p2.mutPendingQueries,
@@ -165,58 +172,27 @@ function mergePartitionsAtBlock(p1, p2, potentialMergeBlock, contractName, maxAd
165
172
  } else {
166
173
  continuingBase = p1;
167
174
  }
168
- if (combinedAddresses.length > maxAddrInPartition) {
169
- let addressesFull = combinedAddresses.slice(0, maxAddrInPartition);
170
- let addressesRest = combinedAddresses.slice(maxAddrInPartition);
171
- let abcFull = {};
172
- abcFull[contractName] = addressesFull;
173
- let abcRest = {};
174
- abcRest[contractName] = addressesRest;
175
- completed.push({
176
- id: continuingBase.id,
177
- latestFetchedBlock: continuingBase.latestFetchedBlock,
178
- selection: continuingBase.selection,
179
- addressesByContractName: abcFull,
180
- mergeBlock: continuingBase.mergeBlock,
181
- dynamicContract: continuingBase.dynamicContract,
182
- mutPendingQueries: continuingBase.mutPendingQueries,
183
- sourceRangeCapacity: continuingBase.sourceRangeCapacity,
184
- prevSourceRangeCapacity: continuingBase.prevSourceRangeCapacity,
185
- eventDensity: continuingBase.eventDensity,
186
- latestSourceRangeCapacityUpdateBlock: continuingBase.latestSourceRangeCapacityUpdateBlock
187
- });
175
+ if (combinedAddresses.size() > maxAddrInPartition) {
176
+ completed.push(withAddresses(continuingBase, combinedAddresses.slice(0, maxAddrInPartition)));
188
177
  let restId = nextPartitionIndexRef.contents.toString();
189
178
  nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
179
+ let init = withAddresses(continuingBase, combinedAddresses.slice(maxAddrInPartition, undefined));
190
180
  completed.push({
191
181
  id: restId,
192
- latestFetchedBlock: continuingBase.latestFetchedBlock,
193
- selection: continuingBase.selection,
194
- addressesByContractName: abcRest,
195
- mergeBlock: continuingBase.mergeBlock,
196
- dynamicContract: continuingBase.dynamicContract,
182
+ latestFetchedBlock: init.latestFetchedBlock,
183
+ selection: init.selection,
184
+ addresses: init.addresses,
185
+ mergeBlock: init.mergeBlock,
186
+ dynamicContract: init.dynamicContract,
197
187
  mutPendingQueries: [],
198
- sourceRangeCapacity: continuingBase.sourceRangeCapacity,
199
- prevSourceRangeCapacity: continuingBase.prevSourceRangeCapacity,
200
- eventDensity: continuingBase.eventDensity,
201
- latestSourceRangeCapacityUpdateBlock: continuingBase.latestSourceRangeCapacityUpdateBlock
188
+ sourceRangeCapacity: init.sourceRangeCapacity,
189
+ prevSourceRangeCapacity: init.prevSourceRangeCapacity,
190
+ eventDensity: init.eventDensity,
191
+ latestSourceRangeCapacityUpdateBlock: init.latestSourceRangeCapacityUpdateBlock
202
192
  });
203
193
  return completed;
204
194
  }
205
- let abc = {};
206
- abc[contractName] = combinedAddresses;
207
- completed.push({
208
- id: continuingBase.id,
209
- latestFetchedBlock: continuingBase.latestFetchedBlock,
210
- selection: continuingBase.selection,
211
- addressesByContractName: abc,
212
- mergeBlock: continuingBase.mergeBlock,
213
- dynamicContract: continuingBase.dynamicContract,
214
- mutPendingQueries: continuingBase.mutPendingQueries,
215
- sourceRangeCapacity: continuingBase.sourceRangeCapacity,
216
- prevSourceRangeCapacity: continuingBase.prevSourceRangeCapacity,
217
- eventDensity: continuingBase.eventDensity,
218
- latestSourceRangeCapacityUpdateBlock: continuingBase.latestSourceRangeCapacityUpdateBlock
219
- });
195
+ completed.push(withAddresses(continuingBase, combinedAddresses));
220
196
  return completed;
221
197
  }
222
198
 
@@ -224,18 +200,94 @@ function ascSortFn(a, b) {
224
200
  return Primitive_int.compare(a.latestFetchedBlock.blockNumber, b.latestFetchedBlock.blockNumber);
225
201
  }
226
202
 
203
+ function anchoredContracts(partitions) {
204
+ let set = new Set();
205
+ partitions.forEach(p => {
206
+ let match = p.mergeBlock;
207
+ let match$1 = p.selection.clientFilteredContracts;
208
+ if (match !== undefined || match$1 === undefined) {
209
+ return;
210
+ } else {
211
+ match$1.forEach(name => {
212
+ set.add(name);
213
+ });
214
+ return;
215
+ }
216
+ });
217
+ return set;
218
+ }
219
+
220
+ function getAnchorSafeBlock(p) {
221
+ let safeRef = {
222
+ contents: p.latestFetchedBlock.blockNumber
223
+ };
224
+ p.mutPendingQueries.forEach(pq => {
225
+ let match = safeRef.contents;
226
+ if (match === undefined) {
227
+ return;
228
+ }
229
+ let toBlock = pq.toBlock;
230
+ let match$1 = pq.fetchedBlock;
231
+ if (match$1 === undefined) {
232
+ if (toBlock !== undefined) {
233
+ if (toBlock > match) {
234
+ safeRef.contents = toBlock;
235
+ return;
236
+ } else {
237
+ return;
238
+ }
239
+ } else {
240
+ safeRef.contents = undefined;
241
+ return;
242
+ }
243
+ }
244
+ let blockNumber = match$1.blockNumber;
245
+ if (blockNumber > match) {
246
+ safeRef.contents = blockNumber;
247
+ return;
248
+ }
249
+ });
250
+ return safeRef.contents;
251
+ }
252
+
227
253
  function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContracts, clientFilteredContracts) {
228
254
  let newPartitions = [];
229
255
  let mergingPartitions = {};
230
256
  let nextPartitionIndexRef = {
231
257
  contents: nextPartitionIndex
232
258
  };
259
+ let anchorSafeBlocks = {};
260
+ let anchoredContractsSet = new Set();
261
+ if (clientFilteredContracts.size > 0) {
262
+ partitions.forEach(p => {
263
+ let match = p.mergeBlock;
264
+ let match$1 = p.selection.clientFilteredContracts;
265
+ if (match !== undefined) {
266
+ return;
267
+ }
268
+ if (match$1 === undefined) {
269
+ return;
270
+ }
271
+ let safeBlock = getAnchorSafeBlock(p);
272
+ match$1.forEach(name => {
273
+ anchoredContractsSet.add(name);
274
+ if (safeBlock !== undefined) {
275
+ anchorSafeBlocks[name] = safeBlock;
276
+ return;
277
+ }
278
+ });
279
+ });
280
+ }
233
281
  for (let idx = 0, idx_finish = partitions.length; idx < idx_finish; ++idx) {
234
282
  let p = partitions[idx];
235
- let exit = 0;
236
- if (p.dynamicContract !== undefined && p.mergeBlock === undefined && p.selection.dependsOnAddresses) {
283
+ let mergeBlock = p.mergeBlock;
284
+ if (mergeBlock !== undefined) {
285
+ if (p.latestFetchedBlock.blockNumber < mergeBlock) {
286
+ newPartitions.push(p);
287
+ }
288
+ } else if (p.dynamicContract !== undefined && p.selection.dependsOnAddresses) {
237
289
  let contractName = p.dynamicContract;
238
- let pAddressesCount = p.addressesByContractName[contractName].length;
290
+ let pAddressesCount = p.addresses.countFor(contractName);
239
291
  let match = Utils.$$Array.last(p.mutPendingQueries);
240
292
  let potentialMergeBlock;
241
293
  if (match !== undefined) {
@@ -260,9 +312,6 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
260
312
  newPartitions.push(p);
261
313
  }
262
314
  } else {
263
- exit = 1;
264
- }
265
- if (exit === 1) {
266
315
  newPartitions.push(p);
267
316
  }
268
317
  }
@@ -300,12 +349,57 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
300
349
  };
301
350
  newPartitions.push(currentPRef);
302
351
  }
303
- newPartitions.sort(ascSortFn);
304
- let partitionsCount = newPartitions.length;
352
+ let finalPartitions;
353
+ if (anchoredContractsSet.size === 0) {
354
+ finalPartitions = newPartitions;
355
+ } else {
356
+ let anchored = [];
357
+ newPartitions.forEach(p => {
358
+ if (p.mergeBlock !== undefined) {
359
+ anchored.push(p);
360
+ return;
361
+ }
362
+ let contractName = p.dynamicContract;
363
+ if (contractName !== undefined) {
364
+ if (anchoredContractsSet.has(contractName)) {
365
+ let anchorSafeBlock = anchorSafeBlocks[contractName];
366
+ if (anchorSafeBlock !== undefined) {
367
+ if (p.latestFetchedBlock.blockNumber < anchorSafeBlock) {
368
+ anchored.push({
369
+ id: p.id,
370
+ latestFetchedBlock: p.latestFetchedBlock,
371
+ selection: p.selection,
372
+ addresses: p.addresses,
373
+ mergeBlock: anchorSafeBlock,
374
+ dynamicContract: p.dynamicContract,
375
+ mutPendingQueries: p.mutPendingQueries,
376
+ sourceRangeCapacity: p.sourceRangeCapacity,
377
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
378
+ eventDensity: p.eventDensity,
379
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
380
+ });
381
+ return;
382
+ } else {
383
+ return;
384
+ }
385
+ } else {
386
+ anchored.push(p);
387
+ return;
388
+ }
389
+ }
390
+ anchored.push(p);
391
+ return;
392
+ }
393
+ anchored.push(p);
394
+ });
395
+ finalPartitions = anchored;
396
+ }
397
+ finalPartitions.sort(ascSortFn);
398
+ let partitionsCount = finalPartitions.length;
305
399
  let idsInAscOrder = Array(partitionsCount);
306
400
  let entities = {};
307
401
  for (let idx$2 = 0; idx$2 < partitionsCount; ++idx$2) {
308
- let p$1 = newPartitions[idx$2];
402
+ let p$1 = finalPartitions[idx$2];
309
403
  idsInAscOrder[idx$2] = p$1.id;
310
404
  entities[p$1.id] = p$1;
311
405
  }
@@ -418,7 +512,7 @@ function handleQueryResponseForPartition(optimizedPartitions, p, query, knownHei
418
512
  }
419
513
  let updatedMainPartition_id = p.id;
420
514
  let updatedMainPartition_selection = p.selection;
421
- let updatedMainPartition_addressesByContractName = p.addressesByContractName;
515
+ let updatedMainPartition_addresses = p.addresses;
422
516
  let updatedMainPartition_mergeBlock = p.mergeBlock;
423
517
  let updatedMainPartition_dynamicContract = p.dynamicContract;
424
518
  let updatedMainPartition_mutPendingQueries = p.mutPendingQueries;
@@ -427,7 +521,7 @@ function handleQueryResponseForPartition(optimizedPartitions, p, query, knownHei
427
521
  id: updatedMainPartition_id,
428
522
  latestFetchedBlock: updatedLatestFetchedBlock,
429
523
  selection: updatedMainPartition_selection,
430
- addressesByContractName: updatedMainPartition_addressesByContractName,
524
+ addresses: updatedMainPartition_addresses,
431
525
  mergeBlock: updatedMainPartition_mergeBlock,
432
526
  dynamicContract: updatedMainPartition_dynamicContract,
433
527
  mutPendingQueries: updatedMainPartition_mutPendingQueries,
@@ -499,6 +593,8 @@ let OptimizedPartitions = {
499
593
  mergePartitionsAtBlock: mergePartitionsAtBlock,
500
594
  tooFarBlockRange: 20000,
501
595
  ascSortFn: ascSortFn,
596
+ anchoredContracts: anchoredContracts,
597
+ getAnchorSafeBlock: getAnchorSafeBlock,
502
598
  make: make,
503
599
  consumeFetchedQueries: consumeFetchedQueries,
504
600
  getPendingQueryOrThrow: getPendingQueryOrThrow,
@@ -695,7 +791,6 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSo
695
791
  startBlock: fetchState.startBlock,
696
792
  endBlock: fetchState.endBlock,
697
793
  normalSelection: fetchState.normalSelection,
698
- contractConfigs: fetchState.contractConfigs,
699
794
  chainId: fetchState.chainId,
700
795
  latestOnBlockBlockNumber: latestOnBlockBlockNumber,
701
796
  blockLag: blockLag,
@@ -708,47 +803,28 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSo
708
803
  };
709
804
  }
710
805
 
711
- function warnDifferentContractType(fetchState, existingContract, dc) {
712
- let logger = Logging.createChild({
713
- chainId: fetchState.chainId,
714
- contractAddress: dc.address,
715
- existingContractType: existingContract.contractName,
716
- newContractType: dc.contractName
717
- });
718
- Logging.childWarn(logger, `Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.`);
719
- }
720
-
721
- function addressesByContractNameCount(addressesByContractName) {
722
- let numAddresses = {
723
- contents: 0
724
- };
725
- Utils.Dict.forEach(addressesByContractName, addresses => {
726
- numAddresses.contents = numAddresses.contents + addresses.length | 0;
727
- });
728
- return numAddresses.contents;
806
+ function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold, shouldLogOpt) {
807
+ let shouldLog = shouldLogOpt !== undefined ? shouldLogOpt : true;
808
+ clientFilteredContracts.add(contractName);
809
+ if (shouldLog) {
810
+ return Logging.childTrace(Logging.createChild({
811
+ chainId: chainId,
812
+ contractName: contractName,
813
+ addressCount: addressCount,
814
+ threshold: threshold
815
+ }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
816
+ }
729
817
  }
730
818
 
731
- function addressesByContractNameGetAll(addressesByContractName) {
732
- let all = [];
733
- Utils.Dict.forEach(addressesByContractName, addresses => {
734
- for (let idx = 0, idx_finish = addresses.length; idx < idx_finish; ++idx) {
735
- all.push(addresses[idx]);
736
- }
819
+ function claimedFetchedBlock(p, knownHeight) {
820
+ return Stdlib_Array.reduce(p.mutPendingQueries, p.latestFetchedBlock.blockNumber, (max, q) => {
821
+ let match = q.fetchedBlock;
822
+ return Primitive_int.max(max, match !== undefined ? match.blockNumber : Stdlib_Option.getOr(q.toBlock, knownHeight));
737
823
  });
738
- return all;
739
824
  }
740
825
 
741
- function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold) {
742
- clientFilteredContracts.add(contractName);
743
- Logging.childTrace(Logging.createChild({
744
- chainId: chainId,
745
- contractName: contractName,
746
- addressCount: addressCount,
747
- threshold: threshold
748
- }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
749
- }
750
-
751
- function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef) {
826
+ function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, clientFilteredFrontiersOpt, knownHeight) {
827
+ let clientFilteredFrontiers = clientFilteredFrontiersOpt !== undefined ? clientFilteredFrontiersOpt : [];
752
828
  if (clientFilteredContracts.size === 0) {
753
829
  return partitions;
754
830
  }
@@ -759,6 +835,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
759
835
  let backfills = [];
760
836
  let absorbedPartitions = [];
761
837
  let strippedFrontiers = [];
838
+ let anchoredContracts$1 = anchoredContracts(partitions);
762
839
  partitions.forEach(p => {
763
840
  if (!p.selection.dependsOnAddresses) {
764
841
  if (p.mergeBlock !== undefined) {
@@ -770,36 +847,25 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
770
847
  }
771
848
  return;
772
849
  }
773
- let contractNames = Object.keys(p.addressesByContractName);
774
- let clientFilteredNames = contractNames.filter(c => clientFilteredContracts.has(c));
775
- if (Utils.$$Array.isEmpty(clientFilteredNames)) {
850
+ let contractNames = p.addresses.contractNames();
851
+ let serverSideNames = contractNames.filter(c => !clientFilteredContracts.has(c));
852
+ if (serverSideNames.length === contractNames.length) {
776
853
  kept.push(p);
777
854
  return;
778
855
  }
779
- if (clientFilteredNames.length === contractNames.length) {
856
+ let contractName = p.dynamicContract;
857
+ if (contractName !== undefined ? anchoredContracts$1.has(contractName) : false) {
858
+ kept.push(p);
859
+ } else if (Utils.$$Array.isEmpty(serverSideNames)) {
780
860
  absorbedPartitions.push(p);
781
- return;
861
+ } else {
862
+ strippedFrontiers.push(p.latestFetchedBlock);
863
+ kept.push(withAddresses(p, p.addresses.filterByContracts(serverSideNames)));
782
864
  }
783
- let stripped = Utils.Dict.shallowCopy(p.addressesByContractName);
784
- clientFilteredNames.forEach(c => Utils.Dict.deleteInPlace(stripped, c));
785
- strippedFrontiers.push(p.latestFetchedBlock);
786
- kept.push({
787
- id: p.id,
788
- latestFetchedBlock: p.latestFetchedBlock,
789
- selection: p.selection,
790
- addressesByContractName: stripped,
791
- mergeBlock: p.mergeBlock,
792
- dynamicContract: p.dynamicContract,
793
- mutPendingQueries: p.mutPendingQueries,
794
- sourceRangeCapacity: p.sourceRangeCapacity,
795
- prevSourceRangeCapacity: p.prevSourceRangeCapacity,
796
- eventDensity: p.eventDensity,
797
- latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
798
- });
799
865
  });
800
866
  let standing = standingRef.contents;
801
867
  let selectionChanged = standing !== undefined ? Stdlib_Option.mapOr(standing.selection.clientFilteredContracts, 0, prim => prim.length) !== clientFilteredContracts.size : true;
802
- if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && !selectionChanged) {
868
+ if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && Utils.$$Array.isEmpty(clientFilteredFrontiers) && !selectionChanged) {
803
869
  return partitions;
804
870
  }
805
871
  let minFrontierRef = {
@@ -817,6 +883,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
817
883
  absorbedPartitions.forEach(p => considerFrontier(p.latestFetchedBlock));
818
884
  backfills.forEach(p => considerFrontier(p.latestFetchedBlock));
819
885
  strippedFrontiers.forEach(considerFrontier);
886
+ clientFilteredFrontiers.forEach(considerFrontier);
820
887
  let regByIndex = {};
821
888
  let addRegs = regs => {
822
889
  regs.forEach(reg => {
@@ -850,7 +917,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
850
917
  id: id,
851
918
  latestFetchedBlock: standing$2.latestFetchedBlock,
852
919
  selection: newSelection,
853
- addressesByContractName: standing$2.addressesByContractName,
920
+ addresses: standing$2.addresses,
854
921
  mergeBlock: standing$2.mergeBlock,
855
922
  dynamicContract: standing$2.dynamicContract,
856
923
  mutPendingQueries: [],
@@ -863,16 +930,17 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
863
930
  standingOut = standing$2;
864
931
  }
865
932
  kept.push(standingOut);
933
+ let catchUpToBlock = claimedFetchedBlock(standingOut, knownHeight);
866
934
  let minFrontier = minFrontierRef.contents;
867
- if (minFrontier !== undefined && minFrontier.blockNumber < standing$2.latestFetchedBlock.blockNumber) {
935
+ if (minFrontier !== undefined && minFrontier.blockNumber < catchUpToBlock) {
868
936
  let id$1 = nextPartitionIndexRef.contents.toString();
869
937
  nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
870
938
  kept.push({
871
939
  id: id$1,
872
940
  latestFetchedBlock: minFrontier,
873
941
  selection: newSelection,
874
- addressesByContractName: {},
875
- mergeBlock: standing$2.latestFetchedBlock.blockNumber,
942
+ addresses: addressStore.emptySet(),
943
+ mergeBlock: catchUpToBlock,
876
944
  dynamicContract: undefined,
877
945
  mutPendingQueries: [],
878
946
  sourceRangeCapacity: standing$2.sourceRangeCapacity,
@@ -894,7 +962,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
894
962
  id: id$2,
895
963
  latestFetchedBlock: minFrontier$1,
896
964
  selection: newSelection,
897
- addressesByContractName: {},
965
+ addresses: addressStore.emptySet(),
898
966
  mergeBlock: undefined,
899
967
  dynamicContract: undefined,
900
968
  mutPendingQueries: [],
@@ -906,60 +974,62 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
906
974
  return kept;
907
975
  }
908
976
 
909
- function createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, nextPartitionIndex, existingPartitions, progressBlockNumber) {
977
+ function createPartitions(registeringSetsByContract, addressStore, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, nextPartitionIndex, existingPartitions, progressBlockNumber, knownHeight) {
910
978
  let nextPartitionIndexRef = {
911
979
  contents: nextPartitionIndex
912
980
  };
913
981
  let dynamicPartitions = [];
914
982
  let nonDynamicPartitions = [];
915
- let contractNames = Object.keys(registeringContractsByContract);
983
+ let clientFilteredFrontiers = [];
984
+ let anchoredContracts$1 = anchoredContracts(existingPartitions);
985
+ let contractNames = Object.keys(registeringSetsByContract);
916
986
  for (let cIdx = 0, cIdx_finish = contractNames.length; cIdx < cIdx_finish; ++cIdx) {
917
987
  let contractName = contractNames[cIdx];
918
- let registeringContracts = registeringContractsByContract[contractName];
919
- let addresses = Object.keys(registeringContracts);
920
- let isDynamic = dynamicContracts.has(contractName);
988
+ let contractSet = registeringSetsByContract[contractName];
989
+ let isAnchored = anchoredContracts$1.has(contractName);
990
+ let isDynamic = dynamicContracts.has(contractName) || isAnchored;
921
991
  let partitions = isDynamic ? dynamicPartitions : nonDynamicPartitions;
922
- let byStartBlock = {};
923
- for (let jdx = 0, jdx_finish = addresses.length; jdx < jdx_finish; ++jdx) {
924
- let address = addresses[jdx];
925
- let indexingContract = registeringContracts[address];
926
- Utils.Dict.push(byStartBlock, indexingContract.effectiveStartBlock.toString(), address);
927
- }
928
- let ascKeys = Object.keys(byStartBlock);
929
- let initialKey = Utils.$$Array.firstUnsafe(ascKeys);
930
- let startBlockRef = Stdlib_Int.fromString(initialKey, undefined);
931
- let addressesRef = byStartBlock[initialKey];
932
- for (let idx = 0, idx_finish = ascKeys.length; idx < idx_finish; ++idx) {
933
- let maybeNextStartBlockKey = ascKeys[idx + 1 | 0];
934
- let shouldAllocateNewPartition;
935
- if (maybeNextStartBlockKey !== undefined) {
936
- let nextStartBlock = Stdlib_Int.fromString(maybeNextStartBlockKey, undefined);
937
- let shouldJoinCurrentStartBlock = (nextStartBlock - startBlockRef | 0) < 20000;
938
- if (shouldJoinCurrentStartBlock) {
939
- addressesRef = addressesRef.concat(byStartBlock[maybeNextStartBlockKey]);
940
- shouldAllocateNewPartition = false;
941
- } else {
942
- shouldAllocateNewPartition = true;
943
- }
944
- } else {
945
- shouldAllocateNewPartition = true;
992
+ let groups = contractSet.startBlockGroups();
993
+ if (clientFilteredContracts.has(contractName) && !isAnchored) {
994
+ let match = groups[0];
995
+ if (match !== undefined) {
996
+ clientFilteredFrontiers.push({
997
+ blockNumber: Primitive_int.max(match.startBlock - 1 | 0, progressBlockNumber),
998
+ blockTimestamp: 0
999
+ });
946
1000
  }
947
- if (shouldAllocateNewPartition) {
948
- let latestFetchedBlock_blockNumber = Primitive_int.max(startBlockRef - 1 | 0, progressBlockNumber);
1001
+ } else {
1002
+ let offsetRef = 0;
1003
+ let groupIdx = 0;
1004
+ while (groupIdx < groups.length) {
1005
+ let startBlock = groups[groupIdx].startBlock;
1006
+ let countRef = 0;
1007
+ let nextIdx = groupIdx;
1008
+ let joining = true;
1009
+ while (joining && nextIdx < groups.length) {
1010
+ let group = groups[nextIdx];
1011
+ if ((group.startBlock - startBlock | 0) < 20000) {
1012
+ countRef = countRef + group.count | 0;
1013
+ nextIdx = nextIdx + 1 | 0;
1014
+ } else {
1015
+ joining = false;
1016
+ }
1017
+ };
1018
+ let latestFetchedBlock_blockNumber = Primitive_int.max(startBlock - 1 | 0, progressBlockNumber);
949
1019
  let latestFetchedBlock = {
950
1020
  blockNumber: latestFetchedBlock_blockNumber,
951
1021
  blockTimestamp: 0
952
1022
  };
953
- while (addressesRef.length !== 0) {
954
- let pAddresses = addressesRef.slice(0, maxAddrInPartition);
955
- addressesRef = addressesRef.slice(maxAddrInPartition);
956
- let addressesByContractName = {};
957
- addressesByContractName[contractName] = pAddresses;
1023
+ let remainingRef = countRef;
1024
+ let chunkOffsetRef = offsetRef;
1025
+ while (remainingRef > 0) {
1026
+ let take = Primitive_int.min(remainingRef, maxAddrInPartition);
1027
+ let pAddresses = contractSet.slice(chunkOffsetRef, take);
958
1028
  partitions.push({
959
1029
  id: nextPartitionIndexRef.contents.toString(),
960
1030
  latestFetchedBlock: latestFetchedBlock,
961
1031
  selection: normalSelection,
962
- addressesByContractName: addressesByContractName,
1032
+ addresses: pAddresses,
963
1033
  mergeBlock: undefined,
964
1034
  dynamicContract: isDynamic ? contractName : undefined,
965
1035
  mutPendingQueries: [],
@@ -969,48 +1039,37 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
969
1039
  latestSourceRangeCapacityUpdateBlock: 0
970
1040
  });
971
1041
  nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
1042
+ chunkOffsetRef = chunkOffsetRef + take | 0;
1043
+ remainingRef = remainingRef - take | 0;
972
1044
  };
973
- if (maybeNextStartBlockKey !== undefined) {
974
- startBlockRef = Stdlib_Int.fromString(maybeNextStartBlockKey, undefined);
975
- addressesRef = byStartBlock[maybeNextStartBlockKey];
976
- }
977
- }
1045
+ offsetRef = offsetRef + countRef | 0;
1046
+ groupIdx = nextIdx;
1047
+ };
978
1048
  }
979
1049
  }
980
1050
  let mergedNonDynamic = [];
981
1051
  if (nonDynamicPartitions.length !== 0) {
982
1052
  nonDynamicPartitions.sort(ascSortFn);
983
1053
  let currentPRef = nonDynamicPartitions[0];
984
- let nextIdx = 1;
985
- while (nextIdx < nonDynamicPartitions.length) {
986
- let nextP = nonDynamicPartitions[nextIdx];
1054
+ let nextIdx$1 = 1;
1055
+ while (nextIdx$1 < nonDynamicPartitions.length) {
1056
+ let nextP = nonDynamicPartitions[nextIdx$1];
987
1057
  let currentP = currentPRef;
988
1058
  let currentPBlock = currentP.latestFetchedBlock.blockNumber;
989
1059
  let nextPBlock = nextP.latestFetchedBlock.blockNumber;
990
- let totalCount = addressesByContractNameCount(currentP.addressesByContractName) + addressesByContractNameCount(nextP.addressesByContractName) | 0;
1060
+ let totalCount = currentP.addresses.size() + nextP.addresses.size() | 0;
991
1061
  if (totalCount > maxAddrInPartition) {
992
1062
  mergedNonDynamic.push(currentP);
993
1063
  currentPRef = nextP;
994
1064
  } else {
995
- let mergedAddresses = Utils.Dict.shallowCopy(nextP.addressesByContractName);
996
- let currentContractNames = Object.keys(currentP.addressesByContractName);
997
- for (let jdx$1 = 0, jdx_finish$1 = currentContractNames.length; jdx$1 < jdx_finish$1; ++jdx$1) {
998
- let cn = currentContractNames[jdx$1];
999
- let currentAddrs = currentP.addressesByContractName[cn];
1000
- let existingAddrs = mergedAddresses[cn];
1001
- if (existingAddrs !== undefined) {
1002
- mergedAddresses[cn] = existingAddrs.concat(currentAddrs);
1003
- } else {
1004
- mergedAddresses[cn] = currentAddrs;
1005
- }
1006
- }
1065
+ let mergedAddresses = nextP.addresses.merge(currentP.addresses);
1007
1066
  let isTooFar = (currentPBlock + 20000 | 0) < nextPBlock;
1008
1067
  if (isTooFar) {
1009
1068
  mergedNonDynamic.push({
1010
1069
  id: currentP.id,
1011
1070
  latestFetchedBlock: currentP.latestFetchedBlock,
1012
1071
  selection: currentP.selection,
1013
- addressesByContractName: currentP.addressesByContractName,
1072
+ addresses: currentP.addresses,
1014
1073
  mergeBlock: currentPBlock < nextPBlock ? nextPBlock : undefined,
1015
1074
  dynamicContract: currentP.dynamicContract,
1016
1075
  mutPendingQueries: currentP.mutPendingQueries,
@@ -1019,191 +1078,134 @@ function createPartitionsFromIndexingAddresses(registeringContractsByContract, d
1019
1078
  eventDensity: currentP.eventDensity,
1020
1079
  latestSourceRangeCapacityUpdateBlock: currentP.latestSourceRangeCapacityUpdateBlock
1021
1080
  });
1022
- currentPRef = {
1023
- id: nextP.id,
1024
- latestFetchedBlock: nextP.latestFetchedBlock,
1025
- selection: nextP.selection,
1026
- addressesByContractName: mergedAddresses,
1027
- mergeBlock: nextP.mergeBlock,
1028
- dynamicContract: nextP.dynamicContract,
1029
- mutPendingQueries: nextP.mutPendingQueries,
1030
- sourceRangeCapacity: nextP.sourceRangeCapacity,
1031
- prevSourceRangeCapacity: nextP.prevSourceRangeCapacity,
1032
- eventDensity: nextP.eventDensity,
1033
- latestSourceRangeCapacityUpdateBlock: nextP.latestSourceRangeCapacityUpdateBlock
1034
- };
1081
+ currentPRef = withAddresses(nextP, mergedAddresses);
1035
1082
  } else {
1036
- currentPRef = {
1037
- id: currentP.id,
1038
- latestFetchedBlock: currentP.latestFetchedBlock,
1039
- selection: currentP.selection,
1040
- addressesByContractName: mergedAddresses,
1041
- mergeBlock: currentP.mergeBlock,
1042
- dynamicContract: currentP.dynamicContract,
1043
- mutPendingQueries: currentP.mutPendingQueries,
1044
- sourceRangeCapacity: currentP.sourceRangeCapacity,
1045
- prevSourceRangeCapacity: currentP.prevSourceRangeCapacity,
1046
- eventDensity: currentP.eventDensity,
1047
- latestSourceRangeCapacityUpdateBlock: currentP.latestSourceRangeCapacityUpdateBlock
1048
- };
1083
+ currentPRef = withAddresses(currentP, mergedAddresses);
1049
1084
  }
1050
1085
  }
1051
- nextIdx = nextIdx + 1 | 0;
1086
+ nextIdx$1 = nextIdx$1 + 1 | 0;
1052
1087
  };
1053
1088
  mergedNonDynamic.push(currentPRef);
1054
1089
  }
1055
1090
  let mergedPartitions = mergedNonDynamic.concat(dynamicPartitions);
1056
- let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef);
1091
+ let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, clientFilteredFrontiers, knownHeight);
1057
1092
  return make(allPartitions, maxAddrInPartition, nextPartitionIndexRef.contents, dynamicContracts, clientFilteredContracts);
1058
1093
  }
1059
1094
 
1060
- function registerDynamicContracts(fetchState, indexingAddresses, items) {
1095
+ function registerDynamicContracts(fetchState, addressStore, claimCeilingOpt, items) {
1096
+ let claimCeiling = claimCeilingOpt !== undefined ? claimCeilingOpt : fetchState.knownHeight;
1061
1097
  if (Utils.$$Array.isEmpty(fetchState.normalSelection.onEventRegistrations)) {
1062
1098
  Stdlib_JsError.throwWithMessage("Invalid configuration. No events to fetch for the dynamic contract registration.");
1063
1099
  }
1064
- let registeringContractsByContract = {};
1065
- let earliestRegisteringEventBlockNumber = Infinity;
1066
- let noEventsAddresses = {};
1067
- let registeringAddresses = {};
1100
+ let registrations = [];
1101
+ let sourceDcs = [];
1102
+ let sourceIndexes = [];
1068
1103
  for (let itemIdx = 0, itemIdx_finish = items.length; itemIdx < itemIdx_finish; ++itemIdx) {
1069
- let item = items[itemIdx];
1070
- let dcs = item.dcs;
1104
+ let dcs = items[itemIdx].dcs;
1071
1105
  if (dcs !== undefined) {
1072
- let idx = 0;
1073
- while (idx < dcs.length) {
1074
- let dc = dcs[idx];
1075
- let shouldRemove = false;
1076
- let match = fetchState.contractConfigs[dc.contractName];
1077
- if (match !== undefined) {
1078
- let dcWithStartBlock_address = dc.address;
1079
- let dcWithStartBlock_contractName = dc.contractName;
1080
- let dcWithStartBlock_registrationBlock = dc.registrationBlock;
1081
- let dcWithStartBlock_effectiveStartBlock = IndexingAddresses.deriveEffectiveStartBlock(dc.registrationBlock, match.startBlock);
1082
- let dcWithStartBlock = {
1083
- address: dcWithStartBlock_address,
1084
- contractName: dcWithStartBlock_contractName,
1085
- registrationBlock: dcWithStartBlock_registrationBlock,
1086
- effectiveStartBlock: dcWithStartBlock_effectiveStartBlock
1087
- };
1088
- let existingContract = IndexingAddresses.get(indexingAddresses, dc.address);
1089
- if (existingContract !== undefined) {
1090
- if (existingContract.contractName !== dc.contractName) {
1091
- warnDifferentContractType(fetchState, existingContract, dcWithStartBlock);
1092
- } else if (existingContract.effectiveStartBlock > dcWithStartBlock_effectiveStartBlock) {
1093
- let logger = Logging.createChild({
1094
- chainId: fetchState.chainId,
1095
- contractAddress: dc.address,
1096
- existingBlockNumber: existingContract.effectiveStartBlock,
1097
- newBlockNumber: dcWithStartBlock_effectiveStartBlock
1098
- });
1099
- Logging.childWarn(logger, `Skipping contract registration: Contract address is already registered at a later block number. Currently registration of the same contract address is not supported by Envio. Reach out to us if it's a problem for you.`);
1100
- }
1101
- shouldRemove = true;
1102
- } else {
1103
- let registeringContract = registeringAddresses[dc.address];
1104
- let shouldUpdate = registeringContract !== undefined ? (
1105
- registeringContract.contractName !== dc.contractName ? (warnDifferentContractType(fetchState, registeringContract, dcWithStartBlock), false) : false
1106
- ) : true;
1107
- if (shouldUpdate) {
1108
- earliestRegisteringEventBlockNumber = Primitive_int.min(earliestRegisteringEventBlockNumber, dcWithStartBlock_effectiveStartBlock);
1109
- Utils.Dict.getOrInsertEmptyDict(registeringContractsByContract, dc.contractName)[dc.address] = dcWithStartBlock;
1110
- registeringAddresses[dc.address] = dcWithStartBlock;
1111
- } else {
1112
- shouldRemove = true;
1113
- }
1106
+ for (let dcIdx = 0, dcIdx_finish = dcs.length; dcIdx < dcIdx_finish; ++dcIdx) {
1107
+ let dc = dcs[dcIdx];
1108
+ registrations.push({
1109
+ address: dc.address,
1110
+ contractName: dc.contractName,
1111
+ registrationBlock: dc.registrationBlock
1112
+ });
1113
+ sourceDcs.push(dcs);
1114
+ sourceIndexes.push(dcIdx);
1115
+ }
1116
+ }
1117
+ }
1118
+ let idCursor = addressStore.nextId();
1119
+ let verdicts = AddressStore.registerBatch(addressStore, registrations);
1120
+ let warn = (contractAddress, params, message) => Logging.childWarn(Logging.createChild({
1121
+ chainId: fetchState.chainId,
1122
+ contractAddress: contractAddress,
1123
+ details: params
1124
+ }), message);
1125
+ let registeringContractNames = [];
1126
+ let hasNoEventsUpdatesRef = false;
1127
+ for (let idx = 0, idx_finish = verdicts.length; idx < idx_finish; ++idx) {
1128
+ let registration = registrations[idx];
1129
+ let contractAddress = registration.address;
1130
+ let match = verdicts[idx];
1131
+ let keep;
1132
+ if (typeof match !== "object") {
1133
+ warn(contractAddress, {
1134
+ contractName: registration.contractName
1135
+ }, `Skipping contract registration: Not a valid address for this chain's ecosystem.`);
1136
+ keep = false;
1137
+ } else {
1138
+ switch (match.TAG) {
1139
+ case "Added" :
1140
+ if (!registeringContractNames.includes(registration.contractName)) {
1141
+ registeringContractNames.push(registration.contractName);
1114
1142
  }
1115
- } else {
1116
- let dcAsIndexingAddress_address = dc.address;
1117
- let dcAsIndexingAddress_contractName = dc.contractName;
1118
- let dcAsIndexingAddress_registrationBlock = dc.registrationBlock;
1119
- let dcAsIndexingAddress_effectiveStartBlock = IndexingAddresses.deriveEffectiveStartBlock(dc.registrationBlock, undefined);
1120
- let dcAsIndexingAddress = {
1121
- address: dcAsIndexingAddress_address,
1122
- contractName: dcAsIndexingAddress_contractName,
1123
- registrationBlock: dcAsIndexingAddress_registrationBlock,
1124
- effectiveStartBlock: dcAsIndexingAddress_effectiveStartBlock
1125
- };
1126
- let existingContract$1 = IndexingAddresses.get(indexingAddresses, dc.address);
1127
- if (existingContract$1 !== undefined) {
1128
- if (existingContract$1.contractName !== dc.contractName) {
1129
- warnDifferentContractType(fetchState, existingContract$1, dcAsIndexingAddress);
1130
- }
1131
- shouldRemove = true;
1132
- } else {
1133
- let existingContract$2 = registeringAddresses[dc.address];
1134
- if (existingContract$2 !== undefined) {
1135
- if (existingContract$2.contractName !== dc.contractName) {
1136
- warnDifferentContractType(fetchState, existingContract$2, dcAsIndexingAddress);
1137
- }
1138
- shouldRemove = true;
1139
- } else {
1140
- let logger$1 = Logging.createChild({
1141
- chainId: fetchState.chainId,
1142
- contractAddress: dc.address,
1143
- contractName: dc.contractName
1144
- });
1145
- Logging.childWarn(logger$1, `Persisting contract registration without fetching: Contract doesn't have any events to fetch. It'll be picked up on restart if you add events for the contract.`);
1146
- noEventsAddresses[dc.address] = dcAsIndexingAddress;
1147
- registeringAddresses[dc.address] = dcAsIndexingAddress;
1148
- }
1143
+ keep = true;
1144
+ break;
1145
+ case "NoEvents" :
1146
+ hasNoEventsUpdatesRef = true;
1147
+ warn(contractAddress, {
1148
+ contractName: registration.contractName
1149
+ }, `Persisting contract registration without fetching: Contract doesn't have any events to fetch. It'll be picked up on restart if you add events for the contract.`);
1150
+ keep = true;
1151
+ break;
1152
+ case "Duplicate" :
1153
+ let existingEffectiveStartBlock = match.existingEffectiveStartBlock;
1154
+ let effectiveStartBlock = match.effectiveStartBlock;
1155
+ if (existingEffectiveStartBlock > effectiveStartBlock) {
1156
+ warn(contractAddress, {
1157
+ existingBlockNumber: existingEffectiveStartBlock,
1158
+ newBlockNumber: effectiveStartBlock
1159
+ }, `Skipping contract registration: Contract address is already registered at a later block number. Currently registration of the same contract address is not supported by Envio. Reach out to us if it's a problem for you.`);
1149
1160
  }
1150
- }
1151
- if (shouldRemove) {
1152
- dcs.splice(idx, 1);
1153
- } else {
1154
- idx = idx + 1 | 0;
1155
- }
1156
- };
1161
+ keep = false;
1162
+ break;
1163
+ case "Conflict" :
1164
+ warn(contractAddress, {
1165
+ existingContractType: match.existingContractName,
1166
+ newContractType: registration.contractName
1167
+ }, `Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.`);
1168
+ keep = false;
1169
+ break;
1170
+ }
1171
+ }
1172
+ if (!keep) {
1173
+ sourceIndexes[idx] = -1 - sourceIndexes[idx] | 0;
1157
1174
  }
1158
1175
  }
1159
- let dcContractNamesToStore = Object.keys(registeringContractsByContract);
1160
- let hasNoEventsUpdates = !Utils.Dict.isEmpty(noEventsAddresses);
1161
- if (dcContractNamesToStore.length === 0) {
1162
- if (hasNoEventsUpdates) {
1163
- IndexingAddresses.register(indexingAddresses, noEventsAddresses);
1164
- return fetchState;
1165
- } else {
1166
- return fetchState;
1176
+ for (let idx$1 = verdicts.length - 1 | 0; idx$1 >= 0; --idx$1) {
1177
+ let marked = sourceIndexes[idx$1];
1178
+ if (marked < 0) {
1179
+ sourceDcs[idx$1].splice(-1 - marked | 0, 1);
1167
1180
  }
1168
1181
  }
1182
+ if (registeringContractNames.length === 0) {
1183
+ return fetchState;
1184
+ }
1169
1185
  let newPartitions = [];
1170
1186
  let dynamicContractsRef = fetchState.optimizedPartitions.dynamicContracts;
1171
1187
  let mutExistingPartitions = Object.values(fetchState.optimizedPartitions.entities);
1172
- for (let idx$1 = 0, idx_finish = dcContractNamesToStore.length; idx$1 < idx_finish; ++idx$1) {
1173
- let contractName = dcContractNamesToStore[idx$1];
1188
+ for (let idx$2 = 0, idx_finish$1 = registeringContractNames.length; idx$2 < idx_finish$1; ++idx$2) {
1189
+ let contractName = registeringContractNames[idx$2];
1174
1190
  if (!dynamicContractsRef.has(contractName)) {
1175
1191
  dynamicContractsRef = Utils.$$Set.immutableAdd(dynamicContractsRef, contractName);
1176
- for (let idx$2 = 0, idx_finish$1 = mutExistingPartitions.length; idx$2 < idx_finish$1; ++idx$2) {
1177
- let p = mutExistingPartitions[idx$2];
1178
- let addresses = p.addressesByContractName[contractName];
1179
- if (addresses !== undefined && p.selection.dependsOnAddresses && p.mergeBlock === undefined) {
1180
- let allPartitionContractNames = Object.keys(p.addressesByContractName);
1192
+ for (let idx$3 = 0, idx_finish$2 = mutExistingPartitions.length; idx$3 < idx_finish$2; ++idx$3) {
1193
+ let p = mutExistingPartitions[idx$3];
1194
+ let match$1 = p.addresses.countFor(contractName);
1195
+ if (match$1 !== 0 && p.selection.dependsOnAddresses && p.mergeBlock === undefined) {
1196
+ let allPartitionContractNames = p.addresses.contractNames();
1181
1197
  if (allPartitionContractNames.length !== 1) {
1182
1198
  let isFetching = p.mutPendingQueries.length !== 0;
1183
1199
  if (!isFetching) {
1184
1200
  let newPartitionId = (fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0).toString();
1185
- let restAddressesByContractName = Utils.Dict.shallowCopy(p.addressesByContractName);
1186
- Utils.Dict.deleteInPlace(restAddressesByContractName, contractName);
1187
- mutExistingPartitions[idx$2] = {
1188
- id: p.id,
1189
- latestFetchedBlock: p.latestFetchedBlock,
1190
- selection: p.selection,
1191
- addressesByContractName: restAddressesByContractName,
1192
- mergeBlock: p.mergeBlock,
1193
- dynamicContract: p.dynamicContract,
1194
- mutPendingQueries: p.mutPendingQueries,
1195
- sourceRangeCapacity: p.sourceRangeCapacity,
1196
- prevSourceRangeCapacity: p.prevSourceRangeCapacity,
1197
- eventDensity: p.eventDensity,
1198
- latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
1199
- };
1200
- let addressesByContractName = {};
1201
- addressesByContractName[contractName] = addresses;
1201
+ let restNames = allPartitionContractNames.filter(name => name !== contractName);
1202
+ mutExistingPartitions[idx$3] = withAddresses(p, p.addresses.filterByContracts(restNames));
1203
+ let splitAddresses = p.addresses.filterByContracts([contractName]);
1202
1204
  newPartitions.push({
1203
1205
  id: newPartitionId,
1204
1206
  latestFetchedBlock: p.latestFetchedBlock,
1205
1207
  selection: fetchState.normalSelection,
1206
- addressesByContractName: addressesByContractName,
1208
+ addresses: splitAddresses,
1207
1209
  mergeBlock: undefined,
1208
1210
  dynamicContract: contractName,
1209
1211
  mutPendingQueries: p.mutPendingQueries,
@@ -1214,11 +1216,11 @@ function registerDynamicContracts(fetchState, indexingAddresses, items) {
1214
1216
  });
1215
1217
  }
1216
1218
  } else {
1217
- mutExistingPartitions[idx$2] = {
1219
+ mutExistingPartitions[idx$3] = {
1218
1220
  id: p.id,
1219
1221
  latestFetchedBlock: p.latestFetchedBlock,
1220
1222
  selection: p.selection,
1221
- addressesByContractName: p.addressesByContractName,
1223
+ addresses: p.addresses,
1222
1224
  mergeBlock: p.mergeBlock,
1223
1225
  dynamicContract: contractName,
1224
1226
  mutPendingQueries: p.mutPendingQueries,
@@ -1231,41 +1233,29 @@ function registerDynamicContracts(fetchState, indexingAddresses, items) {
1231
1233
  }
1232
1234
  }
1233
1235
  }
1234
- let registeringContracts = registeringContractsByContract[contractName];
1235
- IndexingAddresses.register(indexingAddresses, registeringContracts);
1236
1236
  }
1237
- IndexingAddresses.register(indexingAddresses, noEventsAddresses);
1238
1237
  let threshold = fetchState.clientFilterAddressThreshold;
1239
1238
  let clientFilteredContracts;
1240
1239
  if (threshold !== undefined) {
1241
1240
  let clientFilteredContracts$1 = new Set(Array.from(fetchState.optimizedPartitions.clientFilteredContracts));
1242
1241
  Array.from(dynamicContractsRef).forEach(contractName => {
1243
- let addressCount = IndexingAddresses.contractCount(indexingAddresses, contractName);
1242
+ let addressCount = addressStore.contractCount(contractName);
1244
1243
  if (!clientFilteredContracts$1.has(contractName) && addressCount > threshold) {
1245
- return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold);
1244
+ return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold, undefined);
1246
1245
  }
1247
1246
  });
1248
1247
  clientFilteredContracts = clientFilteredContracts$1;
1249
1248
  } else {
1250
1249
  clientFilteredContracts = fetchState.optimizedPartitions.clientFilteredContracts;
1251
1250
  }
1252
- let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContractsRef, clientFilteredContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0, mutExistingPartitions.concat(newPartitions), 0);
1253
- return updateInternal(fetchState, optimizedPartitions, undefined, undefined, undefined, undefined);
1254
- }
1255
-
1256
- function filterByClientAddress(items, indexingAddresses) {
1257
- return items.filter(item => {
1258
- if (item.kind !== 0) {
1259
- return true;
1260
- }
1261
- let reg = item.onEventRegistration;
1262
- let filter = reg.clientAddressFilter;
1263
- if (filter !== undefined) {
1264
- return filter(item.payload, item.blockNumber, IndexingAddresses.forContract(indexingAddresses, reg.eventConfig.contractName));
1265
- } else {
1266
- return true;
1267
- }
1251
+ let registeringSetsByContract = {};
1252
+ registeringContractNames.forEach(contractName => {
1253
+ registeringSetsByContract[contractName] = AddressStore.makeSet(addressStore, contractName, {
1254
+ minId: idCursor
1255
+ });
1268
1256
  });
1257
+ let optimizedPartitions = createPartitions(registeringSetsByContract, addressStore, dynamicContractsRef, clientFilteredContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, fetchState.optimizedPartitions.nextPartitionIndex + newPartitions.length | 0, mutExistingPartitions.concat(newPartitions), 0, Primitive_int.max(claimCeiling, fetchState.knownHeight));
1258
+ return updateInternal(fetchState, optimizedPartitions, undefined, undefined, undefined, undefined);
1269
1259
  }
1270
1260
 
1271
1261
  function handleQueryResult(fetchState, query, latestFetchedBlock, newItems) {
@@ -1302,7 +1292,7 @@ function startFetchingQueries(param, queries) {
1302
1292
  }
1303
1293
  }
1304
1294
 
1305
- function pushDensityPricedQuery(queries, partitionId, fromBlock, toBlock, isChunk, density, chainTargetBlock, selection, addressesByContractName) {
1295
+ function pushDensityPricedQuery(queries, partitionId, fromBlock, toBlock, isChunk, density, chainTargetBlock, selection, addresses) {
1306
1296
  let itemsEst = densityItemsTarget(density, fromBlock, toBlock, chainTargetBlock);
1307
1297
  queries.push({
1308
1298
  partitionId: partitionId,
@@ -1312,12 +1302,12 @@ function pushDensityPricedQuery(queries, partitionId, fromBlock, toBlock, isChun
1312
1302
  itemsTarget: toBlock !== undefined ? undefined : itemsEst,
1313
1303
  itemsEst: itemsEst,
1314
1304
  selection: selection,
1315
- addressesByContractName: addressesByContractName
1305
+ addresses: addresses
1316
1306
  });
1317
1307
  return itemsEst;
1318
1308
  }
1319
1309
 
1320
- function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock, headBlockNumber, chainTargetBlock, maybeChunkRange, maxChunks, partition, partitionBudget, selection, addressesByContractName) {
1310
+ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock, headBlockNumber, chainTargetBlock, maybeChunkRange, maxChunks, partition, partitionBudget, selection, addresses) {
1321
1311
  if (!(rangeFromBlock <= Primitive_int.min(headBlockNumber, chainTargetBlock) && maxChunks > 0)) {
1322
1312
  return;
1323
1313
  }
@@ -1333,7 +1323,7 @@ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock,
1333
1323
  if (exit === 1) {
1334
1324
  let maxBlock = rangeEndBlock !== undefined ? rangeEndBlock : chainTargetBlock;
1335
1325
  let pushSingleQuery = (density, isChunk) => {
1336
- pushDensityPricedQuery(queries, partitionId, rangeFromBlock, rangeEndBlock, isChunk, density, chainTargetBlock, selection, addressesByContractName);
1326
+ pushDensityPricedQuery(queries, partitionId, rangeFromBlock, rangeEndBlock, isChunk, density, chainTargetBlock, selection, addresses);
1337
1327
  };
1338
1328
  let match = partition.eventDensity;
1339
1329
  let exit$1 = 0;
@@ -1348,7 +1338,7 @@ function pushGapFillQueries(queries, partitionId, rangeFromBlock, rangeEndBlock,
1348
1338
  let chunkIdx = 0;
1349
1339
  while (chunkIdx < maxChunks && ((chunkFromBlock + chunkSize | 0) - 1 | 0) <= maxBlock) {
1350
1340
  let chunkToBlock = (chunkFromBlock + chunkSize | 0) - 1 | 0;
1351
- pushDensityPricedQuery(queries, partitionId, chunkFromBlock, chunkToBlock, true, match, chainTargetBlock, selection, addressesByContractName);
1341
+ pushDensityPricedQuery(queries, partitionId, chunkFromBlock, chunkToBlock, true, match, chainTargetBlock, selection, addresses);
1352
1342
  chunkFromBlock = chunkToBlock + 1 | 0;
1353
1343
  chunkIdx = chunkIdx + 1 | 0;
1354
1344
  };
@@ -1382,7 +1372,7 @@ function walkPartitionPending(p, partitionId, inFlightCount, candidates, headBlo
1382
1372
  let pq = p.mutPendingQueries[pqIdx];
1383
1373
  if (pq.fromBlock > cursor) {
1384
1374
  let beforeLen = candidates.length;
1385
- pushGapFillQueries(candidates, partitionId, cursor, Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock), headBlockNumber, chainTargetBlock, maybeChunkRange, (12 - inFlightCount | 0) - chunksUsedThisCall | 0, p, partitionBudget, p.selection, p.addressesByContractName);
1375
+ pushGapFillQueries(candidates, partitionId, cursor, Utils.$$Math.minOptInt(pq.fromBlock - 1 | 0, queryEndBlock), headBlockNumber, chainTargetBlock, maybeChunkRange, (12 - inFlightCount | 0) - chunksUsedThisCall | 0, p, partitionBudget, p.selection, p.addresses);
1386
1376
  chunksUsedThisCall = chunksUsedThisCall + (candidates.length - beforeLen | 0) | 0;
1387
1377
  }
1388
1378
  let toBlock = pq.toBlock;
@@ -1438,7 +1428,7 @@ function pushForwardCandidates(candidates, inRangeStates, inRangeCount, chainTar
1438
1428
  let generatedItems = 0;
1439
1429
  while (created < maxChunksRemaining && chunkFromBlock <= chunkStartCeiling && generatedItems <= freshBudget) {
1440
1430
  let chunkToBlock = Primitive_int.min((chunkFromBlock + chunkSize | 0) - 1 | 0, maxBlock);
1441
- let itemsEst = pushDensityPricedQuery(candidates, fs.partitionId, chunkFromBlock, chunkToBlock, true, match$1, chainTargetBlock, p.selection, p.addressesByContractName);
1431
+ let itemsEst = pushDensityPricedQuery(candidates, fs.partitionId, chunkFromBlock, chunkToBlock, true, match$1, chainTargetBlock, p.selection, p.addresses);
1442
1432
  generatedItems = generatedItems + itemsEst;
1443
1433
  chunkFromBlock = chunkToBlock + 1 | 0;
1444
1434
  created = created + 1 | 0;
@@ -1454,7 +1444,7 @@ function pushForwardCandidates(candidates, inRangeStates, inRangeCount, chainTar
1454
1444
  itemsTarget: itemsEst$1,
1455
1445
  itemsEst: itemsEst$1,
1456
1446
  selection: p.selection,
1457
- addressesByContractName: p.addressesByContractName
1447
+ addresses: p.addresses
1458
1448
  });
1459
1449
  });
1460
1450
  }
@@ -1636,12 +1626,13 @@ function getReadyItemsCount(fetchState, targetSize, fromItem) {
1636
1626
  return acc;
1637
1627
  }
1638
1628
 
1639
- function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt) {
1629
+ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt, isResumedOpt) {
1640
1630
  let progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
1641
1631
  let onBlockRegistrations = onBlockRegistrationsOpt !== undefined ? onBlockRegistrationsOpt : [];
1642
1632
  let blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
1643
1633
  let firstEventBlock = firstEventBlockOpt !== undefined ? Primitive_option.valFromOption(firstEventBlockOpt) : undefined;
1644
1634
  let clientFilterAddressThreshold = clientFilterAddressThresholdOpt !== undefined ? Primitive_option.valFromOption(clientFilterAddressThresholdOpt) : undefined;
1635
+ let isResumed = isResumedOpt !== undefined ? isResumedOpt : false;
1645
1636
  let latestFetchedBlock = {
1646
1637
  blockNumber: progressBlockNumber,
1647
1638
  blockTimestamp: 0
@@ -1666,7 +1657,7 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1666
1657
  onEventRegistrations: notDependingOnAddresses,
1667
1658
  dependsOnAddresses: false
1668
1659
  },
1669
- addressesByContractName: {},
1660
+ addresses: addressStore.emptySet(),
1670
1661
  mergeBlock: undefined,
1671
1662
  dynamicContract: undefined,
1672
1663
  mutPendingQueries: [],
@@ -1680,13 +1671,20 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1680
1671
  onEventRegistrations: normalRegistrations,
1681
1672
  dependsOnAddresses: true
1682
1673
  };
1683
- let registeringContractsByContract = {};
1674
+ AddressStore.registerBatch(addressStore, addresses.map(contract => ({
1675
+ address: contract.address,
1676
+ contractName: contract.contractName,
1677
+ registrationBlock: contract.registrationBlock
1678
+ })));
1684
1679
  let dynamicContracts = new Set();
1685
1680
  let clientFilteredContracts = new Set();
1681
+ let registeringSetsByContract = {};
1686
1682
  addresses.forEach(contract => {
1687
1683
  let contractName = contract.contractName;
1688
1684
  if (contractNamesWithNormalEvents.has(contractName)) {
1689
- Utils.Dict.getOrInsertEmptyDict(registeringContractsByContract, contractName)[contract.address] = IndexingAddresses.makeIndexingAddress(contract, contractConfigs);
1685
+ if (!(contractName in registeringSetsByContract)) {
1686
+ registeringSetsByContract[contractName] = AddressStore.makeSet(addressStore, contractName, undefined);
1687
+ }
1690
1688
  if (contract.registrationBlock !== -1) {
1691
1689
  dynamicContracts.add(contractName);
1692
1690
  return;
@@ -1696,14 +1694,14 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1696
1694
  }
1697
1695
  });
1698
1696
  if (clientFilterAddressThreshold !== undefined) {
1699
- Utils.Dict.forEachWithKey(registeringContractsByContract, (addrs, contractName) => {
1700
- let addressCount = Utils.Dict.size(addrs);
1697
+ Utils.Dict.forEachWithKey(registeringSetsByContract, (set, contractName) => {
1698
+ let addressCount = set.size();
1701
1699
  if (addressCount > clientFilterAddressThreshold) {
1702
- return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold);
1700
+ return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold, !isResumed);
1703
1701
  }
1704
1702
  });
1705
1703
  }
1706
- let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber);
1704
+ let optimizedPartitions = createPartitions(registeringSetsByContract, addressStore, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber, knownHeight);
1707
1705
  if (optimizedPartitions.idsInAscOrder.length === 0 && Utils.$$Array.isEmpty(onBlockRegistrations)) {
1708
1706
  Stdlib_JsError.throwWithMessage(`Invalid configuration: Nothing to fetch on chain ` + chainId.toString() + `. ` + (`addresses=` + addresses.length.toString() + `, `) + (`onEventRegistrations=` + onEventRegistrations.length.toString() + `, `) + (`normalRegistrations=` + normalRegistrations.length.toString() + `. `) + `Make sure that you provided at least one contract address to index, or have events with Wildcard mode enabled, or have onBlock handlers.`);
1709
1707
  }
@@ -1722,7 +1720,6 @@ function make$1(startBlock, endBlock, onEventRegistrations, contractConfigs, add
1722
1720
  startBlock: startBlock,
1723
1721
  endBlock: endBlock,
1724
1722
  normalSelection: normalSelection,
1725
- contractConfigs: contractConfigs,
1726
1723
  chainId: chainId,
1727
1724
  latestOnBlockBlockNumber: latestOnBlockBlockNumber,
1728
1725
  blockLag: blockLag,
@@ -1773,58 +1770,51 @@ function rollbackPendingQueries(mutPendingQueries, targetBlockNumber) {
1773
1770
  return adjusted;
1774
1771
  }
1775
1772
 
1776
- function rollback(fetchState, indexingAddresses, targetBlockNumber) {
1777
- IndexingAddresses.rollbackInPlace(indexingAddresses, targetBlockNumber);
1773
+ function rollback(fetchState, addressStore, targetBlockNumber) {
1774
+ addressStore.rollback(targetBlockNumber);
1778
1775
  let keptPartitions = [];
1779
1776
  let nextKeptIdRef = 0;
1780
- let registeringContractsByContract = {};
1777
+ let registeringSetsByContract = {};
1778
+ let collectForRecreation = set => {
1779
+ set.contractNames().forEach(contractName => {
1780
+ let contractSet = set.filterByContracts([contractName]);
1781
+ let existing = registeringSetsByContract[contractName];
1782
+ registeringSetsByContract[contractName] = existing !== undefined ? Primitive_option.valFromOption(existing).merge(contractSet) : contractSet;
1783
+ });
1784
+ };
1781
1785
  let partitions = Object.values(fetchState.optimizedPartitions.entities);
1782
1786
  for (let idx = 0, idx_finish = partitions.length; idx < idx_finish; ++idx) {
1783
1787
  let p = partitions[idx];
1784
1788
  if (p.selection.dependsOnAddresses) {
1785
1789
  if (p.latestFetchedBlock.blockNumber > targetBlockNumber) {
1786
- Utils.Dict.forEachWithKey(p.addressesByContractName, (addresses, contractName) => {
1787
- addresses.forEach(address => {
1788
- let indexingContract = IndexingAddresses.get(indexingAddresses, address);
1789
- if (indexingContract === undefined) {
1790
- return;
1791
- }
1792
- let registeringContracts = Utils.Dict.getOrInsertEmptyDict(registeringContractsByContract, contractName);
1793
- registeringContracts[address] = indexingContract;
1794
- });
1795
- });
1790
+ collectForRecreation(p.addresses.filterByRegistrationBlock(targetBlockNumber));
1796
1791
  } else {
1797
1792
  let mergeBlock = p.mergeBlock;
1798
1793
  let mergeBlock$1 = mergeBlock !== undefined && mergeBlock > targetBlockNumber ? targetBlockNumber : mergeBlock;
1799
- let rollbackedAddressesByContractName = {};
1800
- Utils.Dict.forEachWithKey(p.addressesByContractName, (addresses, contractName) => {
1801
- let keptAddresses = addresses.filter(address => Stdlib_Option.isSome(IndexingAddresses.get(indexingAddresses, address)));
1802
- if (keptAddresses.length !== 0) {
1803
- rollbackedAddressesByContractName[contractName] = keptAddresses;
1804
- return;
1805
- }
1806
- });
1807
- if (!Utils.Dict.isEmpty(rollbackedAddressesByContractName)) {
1794
+ let rollbackedAddresses = p.addresses.filterByRegistrationBlock(targetBlockNumber);
1795
+ if (!AddressSet.isEmpty(rollbackedAddresses)) {
1808
1796
  let id = nextKeptIdRef.toString();
1809
1797
  nextKeptIdRef = nextKeptIdRef + 1 | 0;
1798
+ let init = withAddresses(p, rollbackedAddresses);
1810
1799
  keptPartitions.push({
1811
1800
  id: id,
1812
- latestFetchedBlock: p.latestFetchedBlock,
1813
- selection: p.selection,
1814
- addressesByContractName: rollbackedAddressesByContractName,
1801
+ latestFetchedBlock: init.latestFetchedBlock,
1802
+ selection: init.selection,
1803
+ addresses: init.addresses,
1815
1804
  mergeBlock: mergeBlock$1,
1816
- dynamicContract: p.dynamicContract,
1805
+ dynamicContract: init.dynamicContract,
1817
1806
  mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
1818
- sourceRangeCapacity: p.sourceRangeCapacity,
1819
- prevSourceRangeCapacity: p.prevSourceRangeCapacity,
1820
- eventDensity: p.eventDensity,
1821
- latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
1807
+ sourceRangeCapacity: init.sourceRangeCapacity,
1808
+ prevSourceRangeCapacity: init.prevSourceRangeCapacity,
1809
+ eventDensity: init.eventDensity,
1810
+ latestSourceRangeCapacityUpdateBlock: init.latestSourceRangeCapacityUpdateBlock
1822
1811
  });
1823
1812
  }
1824
1813
  }
1825
1814
  } else {
1826
1815
  let id$1 = nextKeptIdRef.toString();
1827
1816
  nextKeptIdRef = nextKeptIdRef + 1 | 0;
1817
+ let mergeBlock$2 = p.mergeBlock;
1828
1818
  keptPartitions.push({
1829
1819
  id: id$1,
1830
1820
  latestFetchedBlock: p.latestFetchedBlock.blockNumber > targetBlockNumber ? ({
@@ -1832,8 +1822,8 @@ function rollback(fetchState, indexingAddresses, targetBlockNumber) {
1832
1822
  blockTimestamp: 0
1833
1823
  }) : p.latestFetchedBlock,
1834
1824
  selection: p.selection,
1835
- addressesByContractName: p.addressesByContractName,
1836
- mergeBlock: p.mergeBlock,
1825
+ addresses: p.addresses,
1826
+ mergeBlock: mergeBlock$2 !== undefined && mergeBlock$2 > targetBlockNumber ? targetBlockNumber : mergeBlock$2,
1837
1827
  dynamicContract: p.dynamicContract,
1838
1828
  mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
1839
1829
  sourceRangeCapacity: p.sourceRangeCapacity,
@@ -1843,13 +1833,12 @@ function rollback(fetchState, indexingAddresses, targetBlockNumber) {
1843
1833
  });
1844
1834
  }
1845
1835
  }
1846
- let optimizedPartitions = createPartitionsFromIndexingAddresses(registeringContractsByContract, fetchState.optimizedPartitions.dynamicContracts, fetchState.optimizedPartitions.clientFilteredContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, nextKeptIdRef, keptPartitions, targetBlockNumber);
1836
+ let optimizedPartitions = createPartitions(registeringSetsByContract, addressStore, fetchState.optimizedPartitions.dynamicContracts, fetchState.optimizedPartitions.clientFilteredContracts, fetchState.normalSelection, fetchState.optimizedPartitions.maxAddrInPartition, nextKeptIdRef, keptPartitions, targetBlockNumber, fetchState.knownHeight);
1847
1837
  return updateInternal({
1848
1838
  optimizedPartitions: fetchState.optimizedPartitions,
1849
1839
  startBlock: fetchState.startBlock,
1850
1840
  endBlock: fetchState.endBlock,
1851
1841
  normalSelection: fetchState.normalSelection,
1852
- contractConfigs: fetchState.contractConfigs,
1853
1842
  chainId: fetchState.chainId,
1854
1843
  latestOnBlockBlockNumber: Primitive_int.min(fetchState.latestOnBlockBlockNumber, targetBlockNumber),
1855
1844
  blockLag: fetchState.blockLag,
@@ -1877,7 +1866,7 @@ function resetPendingQueries(fetchState) {
1877
1866
  id: partition.id,
1878
1867
  latestFetchedBlock: partition.latestFetchedBlock,
1879
1868
  selection: partition.selection,
1880
- addressesByContractName: partition.addressesByContractName,
1869
+ addresses: partition.addresses,
1881
1870
  mergeBlock: partition.mergeBlock,
1882
1871
  dynamicContract: partition.dynamicContract,
1883
1872
  mutPendingQueries: kept,
@@ -1901,7 +1890,6 @@ function resetPendingQueries(fetchState) {
1901
1890
  startBlock: fetchState.startBlock,
1902
1891
  endBlock: fetchState.endBlock,
1903
1892
  normalSelection: fetchState.normalSelection,
1904
- contractConfigs: fetchState.contractConfigs,
1905
1893
  chainId: fetchState.chainId,
1906
1894
  latestOnBlockBlockNumber: fetchState.latestOnBlockBlockNumber,
1907
1895
  blockLag: fetchState.blockLag,
@@ -2032,7 +2020,7 @@ let maxChainConcurrency = Env.maxChainConcurrency;
2032
2020
  let chunkRangeGrowthFactor = 1.8;
2033
2021
 
2034
2022
  export {
2035
- deriveContractNameByAddress,
2023
+ withAddresses,
2036
2024
  densityItemsTarget,
2037
2025
  getMinHistoryRange,
2038
2026
  getTrustedDensity,
@@ -2047,14 +2035,11 @@ export {
2047
2035
  blockItemLogIndex,
2048
2036
  appendOnBlockItems,
2049
2037
  updateInternal,
2050
- warnDifferentContractType,
2051
- addressesByContractNameCount,
2052
- addressesByContractNameGetAll,
2053
2038
  addClientFilteredContract,
2039
+ claimedFetchedBlock,
2054
2040
  collapseClientFilteredContracts,
2055
- createPartitionsFromIndexingAddresses,
2041
+ createPartitions,
2056
2042
  registerDynamicContracts,
2057
- filterByClientAddress,
2058
2043
  handleQueryResult,
2059
2044
  startFetchingQueries,
2060
2045
  maxInFlightChunksPerPartition,
@@ -2082,4 +2067,4 @@ export {
2082
2067
  getProgressBlockNumberAt,
2083
2068
  updateKnownHeight,
2084
2069
  }
2085
- /* deriveContractNameByAddress Not a pure module */
2070
+ /* Env Not a pure module */