envio 3.5.0-alpha.2 → 3.5.0-rc.0

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 (129) hide show
  1. package/package.json +6 -6
  2. package/src/Batch.res +8 -8
  3. package/src/Batch.res.mjs +4 -3
  4. package/src/BatchProcessing.res +24 -0
  5. package/src/BatchProcessing.res.mjs +12 -0
  6. package/src/ChainFetching.res +20 -19
  7. package/src/ChainFetching.res.mjs +14 -14
  8. package/src/ChainId.res +58 -0
  9. package/src/ChainId.res.mjs +49 -0
  10. package/src/ChainId.resi +27 -0
  11. package/src/ChainMap.res +12 -26
  12. package/src/ChainMap.res.mjs +5 -41
  13. package/src/ChainMap.resi +5 -20
  14. package/src/ChainMetadata.res +1 -1
  15. package/src/ChainMetadata.res.mjs +3 -2
  16. package/src/ChainState.res +45 -24
  17. package/src/ChainState.res.mjs +40 -16
  18. package/src/ChainState.resi +3 -1
  19. package/src/Config.res +43 -26
  20. package/src/Config.res.mjs +19 -16
  21. package/src/ContractRegisterContext.res +1 -1
  22. package/src/ContractRegisterContext.res.mjs +1 -1
  23. package/src/Core.res +1 -0
  24. package/src/CrossChainState.res +90 -22
  25. package/src/CrossChainState.res.mjs +55 -16
  26. package/src/CrossChainState.resi +5 -1
  27. package/src/Env.res +0 -3
  28. package/src/Env.res.mjs +0 -3
  29. package/src/EventConfigBuilder.res +1 -1
  30. package/src/EventProcessing.res +4 -4
  31. package/src/EventProcessing.res.mjs +5 -5
  32. package/src/FetchState.res +489 -153
  33. package/src/FetchState.res.mjs +399 -129
  34. package/src/FinalizeBackfill.res +61 -0
  35. package/src/FinalizeBackfill.res.mjs +44 -0
  36. package/src/HandlerRegister.res +8 -8
  37. package/src/HandlerRegister.res.mjs +5 -4
  38. package/src/HandlerRegister.resi +1 -1
  39. package/src/InMemoryStore.res +4 -0
  40. package/src/InMemoryStore.res.mjs +1 -1
  41. package/src/InMemoryTable.res +15 -15
  42. package/src/InMemoryTable.res.mjs +14 -14
  43. package/src/IndexerLoop.res +9 -2
  44. package/src/IndexerLoop.res.mjs +8 -1
  45. package/src/IndexerState.res +52 -23
  46. package/src/IndexerState.res.mjs +52 -14
  47. package/src/IndexerState.resi +11 -6
  48. package/src/Internal.res +19 -17
  49. package/src/Internal.res.mjs +18 -9
  50. package/src/LoadLayer.res +10 -2
  51. package/src/LoadLayer.res.mjs +3 -1
  52. package/src/LogSelection.res +2 -2
  53. package/src/Main.res +7 -11
  54. package/src/Main.res.mjs +4 -6
  55. package/src/Metrics.res +6 -6
  56. package/src/Metrics.res.mjs +4 -3
  57. package/src/Persistence.res +23 -4
  58. package/src/PgStorage.res +447 -100
  59. package/src/PgStorage.res.mjs +285 -99
  60. package/src/RawEvent.res +1 -2
  61. package/src/RawEvent.res.mjs +1 -1
  62. package/src/Rollback.res +18 -20
  63. package/src/Rollback.res.mjs +9 -9
  64. package/src/RollbackCommit.res +2 -2
  65. package/src/RollbackCommit.res.mjs +3 -3
  66. package/src/SafeCheckpointTracking.res +2 -2
  67. package/src/SimulateDeadInputTracker.res +17 -21
  68. package/src/SimulateDeadInputTracker.res.mjs +9 -8
  69. package/src/SimulateItems.res +8 -10
  70. package/src/SimulateItems.res.mjs +9 -10
  71. package/src/Sink.res +2 -2
  72. package/src/Sink.res.mjs +3 -2
  73. package/src/TestIndexer.res +14 -14
  74. package/src/TestIndexer.res.mjs +16 -10
  75. package/src/UserContext.res +2 -2
  76. package/src/UserContext.res.mjs +2 -1
  77. package/src/Utils.res +0 -4
  78. package/src/Utils.res.mjs +1 -6
  79. package/src/bindings/ClickHouse.res +20 -2
  80. package/src/bindings/ClickHouse.res.mjs +25 -14
  81. package/src/db/EntityFilter.res +0 -4
  82. package/src/db/EntityFilter.res.mjs +1 -8
  83. package/src/db/EntityHistory.res +1 -1
  84. package/src/db/IndexCatalog.res +248 -0
  85. package/src/db/IndexCatalog.res.mjs +222 -0
  86. package/src/db/IndexDefinition.res +131 -0
  87. package/src/db/IndexDefinition.res.mjs +138 -0
  88. package/src/db/IndexManager.res +145 -0
  89. package/src/db/IndexManager.res.mjs +130 -0
  90. package/src/db/InternalTable.res +54 -23
  91. package/src/db/InternalTable.res.mjs +38 -23
  92. package/src/db/Table.res +24 -14
  93. package/src/db/Table.res.mjs +21 -16
  94. package/src/sources/AddressSet.res +5 -4
  95. package/src/sources/AddressStore.res +25 -14
  96. package/src/sources/AddressStore.res.mjs +10 -12
  97. package/src/sources/Evm.res +2 -2
  98. package/src/sources/Evm.res.mjs +1 -1
  99. package/src/sources/EvmChain.res +3 -3
  100. package/src/sources/EvmChain.res.mjs +3 -3
  101. package/src/sources/EvmHyperSyncSource.res +7 -7
  102. package/src/sources/EvmHyperSyncSource.res.mjs +6 -6
  103. package/src/sources/Fuel.res +2 -2
  104. package/src/sources/Fuel.res.mjs +1 -1
  105. package/src/sources/FuelHyperSyncClient.res +3 -0
  106. package/src/sources/FuelHyperSyncClient.res.mjs +1 -0
  107. package/src/sources/FuelHyperSyncSource.res +5 -7
  108. package/src/sources/FuelHyperSyncSource.res.mjs +5 -5
  109. package/src/sources/HyperSync.resi +2 -2
  110. package/src/sources/HyperSyncClient.res +5 -0
  111. package/src/sources/HyperSyncClient.res.mjs +1 -0
  112. package/src/sources/RpcSource.res +13 -14
  113. package/src/sources/RpcSource.res.mjs +13 -12
  114. package/src/sources/SimulateSource.res +42 -15
  115. package/src/sources/SimulateSource.res.mjs +27 -9
  116. package/src/sources/Source.res +1 -5
  117. package/src/sources/SourceManager.res +12 -12
  118. package/src/sources/SourceManager.res.mjs +11 -10
  119. package/src/sources/SourceManager.resi +2 -2
  120. package/src/sources/Svm.res +4 -5
  121. package/src/sources/Svm.res.mjs +5 -4
  122. package/src/sources/SvmHyperSyncClient.res +3 -0
  123. package/src/sources/SvmHyperSyncClient.res.mjs +1 -0
  124. package/src/sources/SvmHyperSyncSource.res +4 -4
  125. package/src/sources/SvmHyperSyncSource.res.mjs +3 -3
  126. package/src/tui/Tui.res +1 -1
  127. package/src/tui/Tui.res.mjs +2 -1
  128. package/src/tui/components/CustomHooks.res +5 -4
  129. package/src/tui/components/CustomHooks.res.mjs +4 -2
@@ -2,6 +2,7 @@
2
2
 
3
3
  import * as Env from "./Env.res.mjs";
4
4
  import * as Utils from "./Utils.res.mjs";
5
+ import * as ChainId from "./ChainId.res.mjs";
5
6
  import * as Js_math from "@rescript/runtime/lib/es6/Js_math.js";
6
7
  import * as Logging from "./Logging.res.mjs";
7
8
  import * as AddressSet from "./sources/AddressSet.res.mjs";
@@ -14,6 +15,38 @@ import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
14
15
  import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
15
16
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
16
17
 
18
+ function deriveSelectionStartBlock(onEventRegistrations) {
19
+ let earliest;
20
+ let idx = 0;
21
+ let unrestricted = Utils.$$Array.isEmpty(onEventRegistrations);
22
+ while (!unrestricted && idx < onEventRegistrations.length) {
23
+ let startBlock = onEventRegistrations[idx].startBlock;
24
+ if (startBlock !== undefined) {
25
+ let current = earliest;
26
+ if (!(current !== undefined && current <= startBlock)) {
27
+ earliest = startBlock;
28
+ }
29
+ } else {
30
+ unrestricted = true;
31
+ }
32
+ idx = idx + 1 | 0;
33
+ };
34
+ if (unrestricted) {
35
+ return;
36
+ } else {
37
+ return earliest;
38
+ }
39
+ }
40
+
41
+ function makeSelection(onEventRegistrations, dependsOnAddresses, clientFilteredContracts) {
42
+ return {
43
+ onEventRegistrations: onEventRegistrations,
44
+ dependsOnAddresses: dependsOnAddresses,
45
+ clientFilteredContracts: clientFilteredContracts,
46
+ startBlock: deriveSelectionStartBlock(onEventRegistrations)
47
+ };
48
+ }
49
+
17
50
  function withAddresses(p, addresses) {
18
51
  return {
19
52
  id: p.id,
@@ -30,6 +63,26 @@ function withAddresses(p, addresses) {
30
63
  };
31
64
  }
32
65
 
66
+ function narrowSelectionToRange(selection, toBlock) {
67
+ if (toBlock === undefined) {
68
+ return selection;
69
+ }
70
+ let inRange = selection.onEventRegistrations.filter(reg => {
71
+ let startBlock = reg.startBlock;
72
+ if (startBlock !== undefined) {
73
+ return startBlock <= toBlock;
74
+ } else {
75
+ return true;
76
+ }
77
+ });
78
+ let length = inRange.length;
79
+ if (length !== 0 && length !== selection.onEventRegistrations.length) {
80
+ return makeSelection(inRange, selection.dependsOnAddresses, selection.clientFilteredContracts);
81
+ } else {
82
+ return selection;
83
+ }
84
+ }
85
+
33
86
  function densityItemsTarget(density, fromBlock, toBlock, chainTargetBlock) {
34
87
  return Primitive_int.max(1, Math.ceil(((Stdlib_Option.getOr(toBlock, chainTargetBlock) - fromBlock | 0) + 1 | 0) * density) | 0);
35
88
  }
@@ -46,6 +99,10 @@ function getTrustedDensity(p) {
46
99
  return p.eventDensity;
47
100
  }
48
101
 
102
+ function isFetching(p) {
103
+ return p.mutPendingQueries.some(pq => pq.fetchedBlock === undefined);
104
+ }
105
+
49
106
  function getMinQueryRange(partitions) {
50
107
  let min = 0;
51
108
  for (let i = 0, i_finish = partitions.length; i < i_finish; ++i) {
@@ -200,16 +257,92 @@ function ascSortFn(a, b) {
200
257
  return Primitive_int.compare(a.latestFetchedBlock.blockNumber, b.latestFetchedBlock.blockNumber);
201
258
  }
202
259
 
260
+ function anchoredContracts(partitions) {
261
+ let set = new Set();
262
+ partitions.forEach(p => {
263
+ let match = p.mergeBlock;
264
+ let match$1 = p.selection.clientFilteredContracts;
265
+ if (match !== undefined || match$1 === undefined) {
266
+ return;
267
+ } else {
268
+ match$1.forEach(name => {
269
+ set.add(name);
270
+ });
271
+ return;
272
+ }
273
+ });
274
+ return set;
275
+ }
276
+
277
+ function getAnchorSafeBlock(p) {
278
+ let safeRef = {
279
+ contents: p.latestFetchedBlock.blockNumber
280
+ };
281
+ p.mutPendingQueries.forEach(pq => {
282
+ let match = safeRef.contents;
283
+ if (match === undefined) {
284
+ return;
285
+ }
286
+ let toBlock = pq.toBlock;
287
+ let match$1 = pq.fetchedBlock;
288
+ if (match$1 === undefined) {
289
+ if (toBlock !== undefined) {
290
+ if (toBlock > match) {
291
+ safeRef.contents = toBlock;
292
+ return;
293
+ } else {
294
+ return;
295
+ }
296
+ } else {
297
+ safeRef.contents = undefined;
298
+ return;
299
+ }
300
+ }
301
+ let blockNumber = match$1.blockNumber;
302
+ if (blockNumber > match) {
303
+ safeRef.contents = blockNumber;
304
+ return;
305
+ }
306
+ });
307
+ return safeRef.contents;
308
+ }
309
+
203
310
  function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContracts, clientFilteredContracts) {
204
311
  let newPartitions = [];
205
312
  let mergingPartitions = {};
206
313
  let nextPartitionIndexRef = {
207
314
  contents: nextPartitionIndex
208
315
  };
316
+ let anchorSafeBlocks = {};
317
+ let anchoredContractsSet = new Set();
318
+ if (clientFilteredContracts.size > 0) {
319
+ partitions.forEach(p => {
320
+ let match = p.mergeBlock;
321
+ let match$1 = p.selection.clientFilteredContracts;
322
+ if (match !== undefined) {
323
+ return;
324
+ }
325
+ if (match$1 === undefined) {
326
+ return;
327
+ }
328
+ let safeBlock = getAnchorSafeBlock(p);
329
+ match$1.forEach(name => {
330
+ anchoredContractsSet.add(name);
331
+ if (safeBlock !== undefined) {
332
+ anchorSafeBlocks[name] = safeBlock;
333
+ return;
334
+ }
335
+ });
336
+ });
337
+ }
209
338
  for (let idx = 0, idx_finish = partitions.length; idx < idx_finish; ++idx) {
210
339
  let p = partitions[idx];
211
- let exit = 0;
212
- if (p.dynamicContract !== undefined && p.mergeBlock === undefined && p.selection.dependsOnAddresses) {
340
+ let mergeBlock = p.mergeBlock;
341
+ if (mergeBlock !== undefined) {
342
+ if (p.latestFetchedBlock.blockNumber < mergeBlock || isFetching(p)) {
343
+ newPartitions.push(p);
344
+ }
345
+ } else if (p.dynamicContract !== undefined && p.selection.dependsOnAddresses) {
213
346
  let contractName = p.dynamicContract;
214
347
  let pAddressesCount = p.addresses.countFor(contractName);
215
348
  let match = Utils.$$Array.last(p.mutPendingQueries);
@@ -236,9 +369,6 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
236
369
  newPartitions.push(p);
237
370
  }
238
371
  } else {
239
- exit = 1;
240
- }
241
- if (exit === 1) {
242
372
  newPartitions.push(p);
243
373
  }
244
374
  }
@@ -276,12 +406,72 @@ function make(partitions, maxAddrInPartition, nextPartitionIndex, dynamicContrac
276
406
  };
277
407
  newPartitions.push(currentPRef);
278
408
  }
279
- newPartitions.sort(ascSortFn);
280
- let partitionsCount = newPartitions.length;
409
+ let finalPartitions;
410
+ if (anchoredContractsSet.size === 0) {
411
+ finalPartitions = newPartitions;
412
+ } else {
413
+ let anchored = [];
414
+ newPartitions.forEach(p => {
415
+ if (p.mergeBlock !== undefined) {
416
+ anchored.push(p);
417
+ return;
418
+ }
419
+ let contractName = p.dynamicContract;
420
+ if (contractName !== undefined) {
421
+ if (anchoredContractsSet.has(contractName)) {
422
+ let anchorSafeBlock = anchorSafeBlocks[contractName];
423
+ if (anchorSafeBlock !== undefined) {
424
+ if (p.latestFetchedBlock.blockNumber < anchorSafeBlock) {
425
+ anchored.push({
426
+ id: p.id,
427
+ latestFetchedBlock: p.latestFetchedBlock,
428
+ selection: p.selection,
429
+ addresses: p.addresses,
430
+ mergeBlock: anchorSafeBlock,
431
+ dynamicContract: p.dynamicContract,
432
+ mutPendingQueries: p.mutPendingQueries,
433
+ sourceRangeCapacity: p.sourceRangeCapacity,
434
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
435
+ eventDensity: p.eventDensity,
436
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
437
+ });
438
+ return;
439
+ } else if (isFetching(p)) {
440
+ anchored.push({
441
+ id: p.id,
442
+ latestFetchedBlock: p.latestFetchedBlock,
443
+ selection: p.selection,
444
+ addresses: p.addresses,
445
+ mergeBlock: p.latestFetchedBlock.blockNumber,
446
+ dynamicContract: p.dynamicContract,
447
+ mutPendingQueries: p.mutPendingQueries,
448
+ sourceRangeCapacity: p.sourceRangeCapacity,
449
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
450
+ eventDensity: p.eventDensity,
451
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
452
+ });
453
+ return;
454
+ } else {
455
+ return;
456
+ }
457
+ } else {
458
+ anchored.push(p);
459
+ return;
460
+ }
461
+ }
462
+ anchored.push(p);
463
+ return;
464
+ }
465
+ anchored.push(p);
466
+ });
467
+ finalPartitions = anchored;
468
+ }
469
+ finalPartitions.sort(ascSortFn);
470
+ let partitionsCount = finalPartitions.length;
281
471
  let idsInAscOrder = Array(partitionsCount);
282
472
  let entities = {};
283
473
  for (let idx$2 = 0; idx$2 < partitionsCount; ++idx$2) {
284
- let p$1 = newPartitions[idx$2];
474
+ let p$1 = finalPartitions[idx$2];
285
475
  idsInAscOrder[idx$2] = p$1.id;
286
476
  entities[p$1.id] = p$1;
287
477
  }
@@ -387,7 +577,9 @@ function handleQueryResponseForPartition(optimizedPartitions, p, query, knownHei
387
577
  }
388
578
  let updatedLatestFetchedBlock = latestFetchedBlock$1;
389
579
  let mergeBlock = p.mergeBlock;
390
- let partitionReachedMergeBlock = mergeBlock !== undefined ? updatedLatestFetchedBlock.blockNumber >= mergeBlock : false;
580
+ let partitionReachedMergeBlock = (
581
+ mergeBlock !== undefined ? updatedLatestFetchedBlock.blockNumber >= mergeBlock : false
582
+ ) && !isFetching(p);
391
583
  if (partitionReachedMergeBlock) {
392
584
  Utils.Dict.deleteInPlace(mutEntities, p.id);
393
585
  return make(Object.values(mutEntities), optimizedPartitions.maxAddrInPartition, optimizedPartitions.nextPartitionIndex, optimizedPartitions.dynamicContracts, optimizedPartitions.clientFilteredContracts);
@@ -454,12 +646,9 @@ function handleQueryResponseForPartition(optimizedPartitions, p, query, knownHei
454
646
  }
455
647
 
456
648
  function handleQueryResponse(optimizedPartitions, query, knownHeight, itemsCount, latestFetchedBlock) {
457
- let p = optimizedPartitions.entities[query.partitionId];
458
- if (p !== undefined) {
459
- return handleQueryResponseForPartition(optimizedPartitions, p, query, knownHeight, itemsCount, latestFetchedBlock);
460
- } else {
461
- return optimizedPartitions;
462
- }
649
+ let partitionId = query.partitionId;
650
+ let p = optimizedPartitions.entities[partitionId];
651
+ return handleQueryResponseForPartition(optimizedPartitions, p !== undefined ? p : Stdlib_JsError.throwWithMessage(`Unexpected case: Couldn't find partition ` + partitionId), query, knownHeight, itemsCount, latestFetchedBlock);
463
652
  }
464
653
 
465
654
  function getLatestFullyFetchedBlock(optimizedPartitions) {
@@ -475,6 +664,8 @@ let OptimizedPartitions = {
475
664
  mergePartitionsAtBlock: mergePartitionsAtBlock,
476
665
  tooFarBlockRange: 20000,
477
666
  ascSortFn: ascSortFn,
667
+ anchoredContracts: anchoredContracts,
668
+ getAnchorSafeBlock: getAnchorSafeBlock,
478
669
  make: make,
479
670
  consumeFetchedQueries: consumeFetchedQueries,
480
671
  getPendingQueryOrThrow: getPendingQueryOrThrow,
@@ -683,14 +874,17 @@ function updateInternal(fetchState, optimizedPartitionsOpt, mutItems, mutItemsSo
683
874
  };
684
875
  }
685
876
 
686
- function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold) {
877
+ function addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, threshold, shouldLogOpt) {
878
+ let shouldLog = shouldLogOpt !== undefined ? shouldLogOpt : true;
687
879
  clientFilteredContracts.add(contractName);
688
- Logging.childTrace(Logging.createChild({
689
- chainId: chainId,
690
- contractName: contractName,
691
- addressCount: addressCount,
692
- threshold: threshold
693
- }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
880
+ if (shouldLog) {
881
+ return Logging.childTrace(Logging.createChild({
882
+ chainId: chainId,
883
+ contractName: contractName,
884
+ addressCount: addressCount,
885
+ threshold: threshold
886
+ }), "Switching contract to client-side address filtering: registered address count crossed the server-side threshold.");
887
+ }
694
888
  }
695
889
 
696
890
  function claimedFetchedBlock(p, knownHeight) {
@@ -700,7 +894,8 @@ function claimedFetchedBlock(p, knownHeight) {
700
894
  });
701
895
  }
702
896
 
703
- function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, knownHeight) {
897
+ function collapseClientFilteredContracts(partitions, clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, clientFilteredFrontiersOpt, knownHeight) {
898
+ let clientFilteredFrontiers = clientFilteredFrontiersOpt !== undefined ? clientFilteredFrontiersOpt : [];
704
899
  if (clientFilteredContracts.size === 0) {
705
900
  return partitions;
706
901
  }
@@ -711,31 +906,65 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
711
906
  let backfills = [];
712
907
  let absorbedPartitions = [];
713
908
  let strippedFrontiers = [];
909
+ let anchoredContracts$1 = anchoredContracts(partitions);
910
+ let retire = p => ({
911
+ id: p.id,
912
+ latestFetchedBlock: p.latestFetchedBlock,
913
+ selection: p.selection,
914
+ addresses: p.addresses,
915
+ mergeBlock: p.latestFetchedBlock.blockNumber,
916
+ dynamicContract: p.dynamicContract,
917
+ mutPendingQueries: p.mutPendingQueries,
918
+ sourceRangeCapacity: p.sourceRangeCapacity,
919
+ prevSourceRangeCapacity: p.prevSourceRangeCapacity,
920
+ eventDensity: p.eventDensity,
921
+ latestSourceRangeCapacityUpdateBlock: p.latestSourceRangeCapacityUpdateBlock
922
+ });
923
+ let absorb = p => {
924
+ absorbedPartitions.push(p);
925
+ if (isFetching(p)) {
926
+ kept.push(retire(p));
927
+ return;
928
+ }
929
+ };
714
930
  partitions.forEach(p => {
715
931
  if (!p.selection.dependsOnAddresses) {
716
932
  if (p.mergeBlock !== undefined) {
717
933
  backfills.push(p);
934
+ if (isFetching(p)) {
935
+ kept.push(retire(p));
936
+ return;
937
+ } else {
938
+ return;
939
+ }
718
940
  } else if (Stdlib_Option.isNone(standingRef.contents)) {
719
941
  standingRef.contents = p;
942
+ return;
720
943
  } else {
721
- absorbedPartitions.push(p);
944
+ return absorb(p);
722
945
  }
723
- return;
724
946
  }
725
947
  let contractNames = p.addresses.contractNames();
726
948
  let serverSideNames = contractNames.filter(c => !clientFilteredContracts.has(c));
727
949
  if (serverSideNames.length === contractNames.length) {
728
950
  kept.push(p);
951
+ return;
952
+ }
953
+ let contractName = p.dynamicContract;
954
+ if (contractName !== undefined ? anchoredContracts$1.has(contractName) : false) {
955
+ kept.push(p);
956
+ return;
729
957
  } else if (Utils.$$Array.isEmpty(serverSideNames)) {
730
- absorbedPartitions.push(p);
958
+ return absorb(p);
731
959
  } else {
732
960
  strippedFrontiers.push(p.latestFetchedBlock);
733
961
  kept.push(withAddresses(p, p.addresses.filterByContracts(serverSideNames)));
962
+ return;
734
963
  }
735
964
  });
736
965
  let standing = standingRef.contents;
737
966
  let selectionChanged = standing !== undefined ? Stdlib_Option.mapOr(standing.selection.clientFilteredContracts, 0, prim => prim.length) !== clientFilteredContracts.size : true;
738
- if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && !selectionChanged) {
967
+ if (Utils.$$Array.isEmpty(absorbedPartitions) && Utils.$$Array.isEmpty(strippedFrontiers) && Utils.$$Array.isEmpty(clientFilteredFrontiers) && !selectionChanged) {
739
968
  return partitions;
740
969
  }
741
970
  let minFrontierRef = {
@@ -753,6 +982,7 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
753
982
  absorbedPartitions.forEach(p => considerFrontier(p.latestFetchedBlock));
754
983
  backfills.forEach(p => considerFrontier(p.latestFetchedBlock));
755
984
  strippedFrontiers.forEach(considerFrontier);
985
+ clientFilteredFrontiers.forEach(considerFrontier);
756
986
  let regByIndex = {};
757
987
  let addRegs = regs => {
758
988
  regs.forEach(reg => {
@@ -769,19 +999,16 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
769
999
  }
770
1000
  });
771
1001
  addRegs(normalSelection.onEventRegistrations.filter(reg => clientFilteredContracts.has(reg.eventConfig.contractName)));
772
- let newSelection_onEventRegistrations = Object.values(regByIndex);
773
- let newSelection_clientFilteredContracts = Array.from(clientFilteredContracts);
774
- let newSelection = {
775
- onEventRegistrations: newSelection_onEventRegistrations,
776
- dependsOnAddresses: false,
777
- clientFilteredContracts: newSelection_clientFilteredContracts
778
- };
1002
+ let newSelection = makeSelection(Object.values(regByIndex), false, Array.from(clientFilteredContracts));
779
1003
  let standing$2 = standingRef.contents;
780
1004
  if (standing$2 !== undefined) {
781
1005
  let standingOut;
782
1006
  if (selectionChanged) {
783
1007
  let id = nextPartitionIndexRef.contents.toString();
784
1008
  nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
1009
+ if (isFetching(standing$2)) {
1010
+ kept.push(retire(standing$2));
1011
+ }
785
1012
  standingOut = {
786
1013
  id: id,
787
1014
  latestFetchedBlock: standing$2.latestFetchedBlock,
@@ -843,65 +1070,115 @@ function collapseClientFilteredContracts(partitions, clientFilteredContracts, no
843
1070
  return kept;
844
1071
  }
845
1072
 
1073
+ function warnAddressRegistration(chainId, contractAddress, params, message) {
1074
+ Logging.childWarn(Logging.createChild({
1075
+ chainId: chainId,
1076
+ contractAddress: contractAddress,
1077
+ details: params
1078
+ }), message);
1079
+ }
1080
+
1081
+ function warnRejectedRegistration(verdict, chainId, contractAddress, contractName) {
1082
+ if (typeof verdict !== "object") {
1083
+ return warnAddressRegistration(chainId, contractAddress, {
1084
+ contractName: contractName
1085
+ }, `Skipping contract registration: Not a valid address for this chain's ecosystem.`);
1086
+ }
1087
+ switch (verdict.TAG) {
1088
+ case "Added" :
1089
+ case "NoEvents" :
1090
+ return;
1091
+ case "Duplicate" :
1092
+ let existingEffectiveStartBlock = verdict.existingEffectiveStartBlock;
1093
+ let effectiveStartBlock = verdict.effectiveStartBlock;
1094
+ if (existingEffectiveStartBlock > effectiveStartBlock) {
1095
+ return warnAddressRegistration(chainId, contractAddress, {
1096
+ existingBlockNumber: existingEffectiveStartBlock,
1097
+ newBlockNumber: effectiveStartBlock
1098
+ }, `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.`);
1099
+ } else {
1100
+ return;
1101
+ }
1102
+ case "Conflict" :
1103
+ return warnAddressRegistration(chainId, contractAddress, {
1104
+ existingContractType: verdict.existingContractName,
1105
+ newContractType: contractName
1106
+ }, `Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.`);
1107
+ }
1108
+ }
1109
+
846
1110
  function createPartitions(registeringSetsByContract, addressStore, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, nextPartitionIndex, existingPartitions, progressBlockNumber, knownHeight) {
847
1111
  let nextPartitionIndexRef = {
848
1112
  contents: nextPartitionIndex
849
1113
  };
850
1114
  let dynamicPartitions = [];
851
1115
  let nonDynamicPartitions = [];
1116
+ let clientFilteredFrontiers = [];
1117
+ let anchoredContracts$1 = anchoredContracts(existingPartitions);
852
1118
  let contractNames = Object.keys(registeringSetsByContract);
853
1119
  for (let cIdx = 0, cIdx_finish = contractNames.length; cIdx < cIdx_finish; ++cIdx) {
854
1120
  let contractName = contractNames[cIdx];
855
1121
  let contractSet = registeringSetsByContract[contractName];
856
- let isDynamic = dynamicContracts.has(contractName);
1122
+ let isAnchored = anchoredContracts$1.has(contractName);
1123
+ let isDynamic = dynamicContracts.has(contractName) || isAnchored;
857
1124
  let partitions = isDynamic ? dynamicPartitions : nonDynamicPartitions;
858
1125
  let groups = contractSet.startBlockGroups();
859
- let offsetRef = 0;
860
- let groupIdx = 0;
861
- while (groupIdx < groups.length) {
862
- let startBlock = groups[groupIdx].startBlock;
863
- let countRef = 0;
864
- let nextIdx = groupIdx;
865
- let joining = true;
866
- while (joining && nextIdx < groups.length) {
867
- let group = groups[nextIdx];
868
- if ((group.startBlock - startBlock | 0) < 20000) {
869
- countRef = countRef + group.count | 0;
870
- nextIdx = nextIdx + 1 | 0;
871
- } else {
872
- joining = false;
873
- }
874
- };
875
- let latestFetchedBlock_blockNumber = Primitive_int.max(startBlock - 1 | 0, progressBlockNumber);
876
- let latestFetchedBlock = {
877
- blockNumber: latestFetchedBlock_blockNumber,
878
- blockTimestamp: 0
879
- };
880
- let remainingRef = countRef;
881
- let chunkOffsetRef = offsetRef;
882
- while (remainingRef > 0) {
883
- let take = Primitive_int.min(remainingRef, maxAddrInPartition);
884
- let pAddresses = contractSet.slice(chunkOffsetRef, take);
885
- partitions.push({
886
- id: nextPartitionIndexRef.contents.toString(),
887
- latestFetchedBlock: latestFetchedBlock,
888
- selection: normalSelection,
889
- addresses: pAddresses,
890
- mergeBlock: undefined,
891
- dynamicContract: isDynamic ? contractName : undefined,
892
- mutPendingQueries: [],
893
- sourceRangeCapacity: 0,
894
- prevSourceRangeCapacity: 0,
895
- eventDensity: undefined,
896
- latestSourceRangeCapacityUpdateBlock: 0
1126
+ if (clientFilteredContracts.has(contractName) && !isAnchored) {
1127
+ let match = groups[0];
1128
+ if (match !== undefined) {
1129
+ clientFilteredFrontiers.push({
1130
+ blockNumber: Primitive_int.max(match.startBlock - 1 | 0, progressBlockNumber),
1131
+ blockTimestamp: 0
897
1132
  });
898
- nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
899
- chunkOffsetRef = chunkOffsetRef + take | 0;
900
- remainingRef = remainingRef - take | 0;
1133
+ }
1134
+ } else {
1135
+ let offsetRef = 0;
1136
+ let groupIdx = 0;
1137
+ while (groupIdx < groups.length) {
1138
+ let startBlock = groups[groupIdx].startBlock;
1139
+ let countRef = 0;
1140
+ let nextIdx = groupIdx;
1141
+ let joining = true;
1142
+ while (joining && nextIdx < groups.length) {
1143
+ let group = groups[nextIdx];
1144
+ if ((group.startBlock - startBlock | 0) < 20000) {
1145
+ countRef = countRef + group.count | 0;
1146
+ nextIdx = nextIdx + 1 | 0;
1147
+ } else {
1148
+ joining = false;
1149
+ }
1150
+ };
1151
+ let latestFetchedBlock_blockNumber = Primitive_int.max(startBlock - 1 | 0, progressBlockNumber);
1152
+ let latestFetchedBlock = {
1153
+ blockNumber: latestFetchedBlock_blockNumber,
1154
+ blockTimestamp: 0
1155
+ };
1156
+ let remainingRef = countRef;
1157
+ let chunkOffsetRef = offsetRef;
1158
+ while (remainingRef > 0) {
1159
+ let take = Primitive_int.min(remainingRef, maxAddrInPartition);
1160
+ let pAddresses = contractSet.slice(chunkOffsetRef, take);
1161
+ partitions.push({
1162
+ id: nextPartitionIndexRef.contents.toString(),
1163
+ latestFetchedBlock: latestFetchedBlock,
1164
+ selection: normalSelection,
1165
+ addresses: pAddresses,
1166
+ mergeBlock: undefined,
1167
+ dynamicContract: isDynamic ? contractName : undefined,
1168
+ mutPendingQueries: [],
1169
+ sourceRangeCapacity: 0,
1170
+ prevSourceRangeCapacity: 0,
1171
+ eventDensity: undefined,
1172
+ latestSourceRangeCapacityUpdateBlock: 0
1173
+ });
1174
+ nextPartitionIndexRef.contents = nextPartitionIndexRef.contents + 1 | 0;
1175
+ chunkOffsetRef = chunkOffsetRef + take | 0;
1176
+ remainingRef = remainingRef - take | 0;
1177
+ };
1178
+ offsetRef = offsetRef + countRef | 0;
1179
+ groupIdx = nextIdx;
901
1180
  };
902
- offsetRef = offsetRef + countRef | 0;
903
- groupIdx = nextIdx;
904
- };
1181
+ }
905
1182
  }
906
1183
  let mergedNonDynamic = [];
907
1184
  if (nonDynamicPartitions.length !== 0) {
@@ -944,7 +1221,7 @@ function createPartitions(registeringSetsByContract, addressStore, dynamicContra
944
1221
  mergedNonDynamic.push(currentPRef);
945
1222
  }
946
1223
  let mergedPartitions = mergedNonDynamic.concat(dynamicPartitions);
947
- let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, knownHeight);
1224
+ let allPartitions = collapseClientFilteredContracts(existingPartitions.concat(mergedPartitions), clientFilteredContracts, normalSelection, nextPartitionIndexRef, addressStore, clientFilteredFrontiers, knownHeight);
948
1225
  return make(allPartitions, maxAddrInPartition, nextPartitionIndexRef.contents, dynamicContracts, clientFilteredContracts);
949
1226
  }
950
1227
 
@@ -973,25 +1250,17 @@ function registerDynamicContracts(fetchState, addressStore, claimCeilingOpt, ite
973
1250
  }
974
1251
  let idCursor = addressStore.nextId();
975
1252
  let verdicts = AddressStore.registerBatch(addressStore, registrations);
976
- let warn = (contractAddress, params, message) => Logging.childWarn(Logging.createChild({
977
- chainId: fetchState.chainId,
978
- contractAddress: contractAddress,
979
- details: params
980
- }), message);
981
1253
  let registeringContractNames = [];
982
1254
  let hasNoEventsUpdatesRef = false;
983
1255
  for (let idx = 0, idx_finish = verdicts.length; idx < idx_finish; ++idx) {
984
1256
  let registration = registrations[idx];
985
- let contractAddress = registration.address;
986
- let match = verdicts[idx];
1257
+ let verdict = verdicts[idx];
987
1258
  let keep;
988
- if (typeof match !== "object") {
989
- warn(contractAddress, {
990
- contractName: registration.contractName
991
- }, `Skipping contract registration: Not a valid address for this chain's ecosystem.`);
992
- keep = false;
1259
+ let exit = 0;
1260
+ if (typeof verdict !== "object") {
1261
+ exit = 1;
993
1262
  } else {
994
- switch (match.TAG) {
1263
+ switch (verdict.TAG) {
995
1264
  case "Added" :
996
1265
  if (!registeringContractNames.includes(registration.contractName)) {
997
1266
  registeringContractNames.push(registration.contractName);
@@ -1000,31 +1269,19 @@ function registerDynamicContracts(fetchState, addressStore, claimCeilingOpt, ite
1000
1269
  break;
1001
1270
  case "NoEvents" :
1002
1271
  hasNoEventsUpdatesRef = true;
1003
- warn(contractAddress, {
1272
+ warnAddressRegistration(fetchState.chainId, registration.address, {
1004
1273
  contractName: registration.contractName
1005
1274
  }, `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.`);
1006
1275
  keep = true;
1007
1276
  break;
1008
- case "Duplicate" :
1009
- let existingEffectiveStartBlock = match.existingEffectiveStartBlock;
1010
- let effectiveStartBlock = match.effectiveStartBlock;
1011
- if (existingEffectiveStartBlock > effectiveStartBlock) {
1012
- warn(contractAddress, {
1013
- existingBlockNumber: existingEffectiveStartBlock,
1014
- newBlockNumber: effectiveStartBlock
1015
- }, `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.`);
1016
- }
1017
- keep = false;
1018
- break;
1019
- case "Conflict" :
1020
- warn(contractAddress, {
1021
- existingContractType: match.existingContractName,
1022
- newContractType: registration.contractName
1023
- }, `Skipping contract registration: Contract address is already registered for one contract and cannot be registered for another contract.`);
1024
- keep = false;
1025
- break;
1277
+ default:
1278
+ exit = 1;
1026
1279
  }
1027
1280
  }
1281
+ if (exit === 1) {
1282
+ warnRejectedRegistration(verdict, fetchState.chainId, registration.address, registration.contractName);
1283
+ keep = false;
1284
+ }
1028
1285
  if (!keep) {
1029
1286
  sourceIndexes[idx] = -1 - sourceIndexes[idx] | 0;
1030
1287
  }
@@ -1047,8 +1304,8 @@ function registerDynamicContracts(fetchState, addressStore, claimCeilingOpt, ite
1047
1304
  dynamicContractsRef = Utils.$$Set.immutableAdd(dynamicContractsRef, contractName);
1048
1305
  for (let idx$3 = 0, idx_finish$2 = mutExistingPartitions.length; idx$3 < idx_finish$2; ++idx$3) {
1049
1306
  let p = mutExistingPartitions[idx$3];
1050
- let match$1 = p.addresses.countFor(contractName);
1051
- if (match$1 !== 0 && p.selection.dependsOnAddresses && p.mergeBlock === undefined) {
1307
+ let match = p.addresses.countFor(contractName);
1308
+ if (match !== 0 && p.selection.dependsOnAddresses && p.mergeBlock === undefined) {
1052
1309
  let allPartitionContractNames = p.addresses.contractNames();
1053
1310
  if (allPartitionContractNames.length !== 1) {
1054
1311
  let isFetching = p.mutPendingQueries.length !== 0;
@@ -1097,7 +1354,7 @@ function registerDynamicContracts(fetchState, addressStore, claimCeilingOpt, ite
1097
1354
  Array.from(dynamicContractsRef).forEach(contractName => {
1098
1355
  let addressCount = addressStore.contractCount(contractName);
1099
1356
  if (!clientFilteredContracts$1.has(contractName) && addressCount > threshold) {
1100
- return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold);
1357
+ return addClientFilteredContract(clientFilteredContracts$1, contractName, fetchState.chainId, addressCount, threshold, undefined);
1101
1358
  }
1102
1359
  });
1103
1360
  clientFilteredContracts = clientFilteredContracts$1;
@@ -1245,11 +1502,19 @@ function walkPartitionPending(p, partitionId, inFlightCount, candidates, headBlo
1245
1502
  }
1246
1503
  pqIdx = pqIdx + 1 | 0;
1247
1504
  };
1505
+ let startBlock = p.selection.startBlock;
1506
+ let cursor$1;
1507
+ if (startBlock !== undefined && startBlock > cursor) {
1508
+ let reachable = Utils.$$Math.minOptInt(headBlockNumber, queryEndBlock);
1509
+ cursor$1 = reachable !== undefined && startBlock <= reachable ? startBlock : cursor;
1510
+ } else {
1511
+ cursor$1 = cursor;
1512
+ }
1248
1513
  if (canContinue) {
1249
1514
  return {
1250
1515
  partitionId: partitionId,
1251
1516
  p: p,
1252
- cursor: cursor,
1517
+ cursor: cursor$1,
1253
1518
  chunksUsedThisCall: chunksUsedThisCall,
1254
1519
  inFlightCount: inFlightCount,
1255
1520
  queryEndBlock: queryEndBlock,
@@ -1482,12 +1747,13 @@ function getReadyItemsCount(fetchState, targetSize, fromItem) {
1482
1747
  return acc;
1483
1748
  }
1484
1749
 
1485
- function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt) {
1750
+ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addresses, maxAddrInPartition, chainId, maxOnBlockBufferSize, knownHeight, progressBlockNumberOpt, onBlockRegistrationsOpt, blockLagOpt, firstEventBlockOpt, clientFilterAddressThresholdOpt, isResumedOpt) {
1486
1751
  let progressBlockNumber = progressBlockNumberOpt !== undefined ? progressBlockNumberOpt : startBlock - 1 | 0;
1487
1752
  let onBlockRegistrations = onBlockRegistrationsOpt !== undefined ? onBlockRegistrationsOpt : [];
1488
1753
  let blockLag = blockLagOpt !== undefined ? blockLagOpt : 0;
1489
1754
  let firstEventBlock = firstEventBlockOpt !== undefined ? Primitive_option.valFromOption(firstEventBlockOpt) : undefined;
1490
1755
  let clientFilterAddressThreshold = clientFilterAddressThresholdOpt !== undefined ? Primitive_option.valFromOption(clientFilterAddressThresholdOpt) : undefined;
1756
+ let isResumed = isResumedOpt !== undefined ? isResumedOpt : false;
1491
1757
  let latestFetchedBlock = {
1492
1758
  blockNumber: progressBlockNumber,
1493
1759
  blockTimestamp: 0
@@ -1508,10 +1774,7 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
1508
1774
  partitions.push({
1509
1775
  id: partitions.length.toString(),
1510
1776
  latestFetchedBlock: latestFetchedBlock,
1511
- selection: {
1512
- onEventRegistrations: notDependingOnAddresses,
1513
- dependsOnAddresses: false
1514
- },
1777
+ selection: makeSelection(notDependingOnAddresses, false, undefined),
1515
1778
  addresses: addressStore.emptySet(),
1516
1779
  mergeBlock: undefined,
1517
1780
  dynamicContract: undefined,
@@ -1522,15 +1785,15 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
1522
1785
  latestSourceRangeCapacityUpdateBlock: 0
1523
1786
  });
1524
1787
  }
1525
- let normalSelection = {
1526
- onEventRegistrations: normalRegistrations,
1527
- dependsOnAddresses: true
1528
- };
1788
+ let normalSelection = makeSelection(normalRegistrations, true, undefined);
1529
1789
  AddressStore.registerBatch(addressStore, addresses.map(contract => ({
1530
1790
  address: contract.address,
1531
1791
  contractName: contract.contractName,
1532
1792
  registrationBlock: contract.registrationBlock
1533
- })));
1793
+ }))).forEach((verdict, idx) => {
1794
+ let contract = addresses[idx];
1795
+ warnRejectedRegistration(verdict, chainId, contract.address, contract.contractName);
1796
+ });
1534
1797
  let dynamicContracts = new Set();
1535
1798
  let clientFilteredContracts = new Set();
1536
1799
  let registeringSetsByContract = {};
@@ -1552,13 +1815,13 @@ function make$1(startBlock, endBlock, onEventRegistrations, addressStore, addres
1552
1815
  Utils.Dict.forEachWithKey(registeringSetsByContract, (set, contractName) => {
1553
1816
  let addressCount = set.size();
1554
1817
  if (addressCount > clientFilterAddressThreshold) {
1555
- return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold);
1818
+ return addClientFilteredContract(clientFilteredContracts, contractName, chainId, addressCount, clientFilterAddressThreshold, !isResumed);
1556
1819
  }
1557
1820
  });
1558
1821
  }
1559
1822
  let optimizedPartitions = createPartitions(registeringSetsByContract, addressStore, dynamicContracts, clientFilteredContracts, normalSelection, maxAddrInPartition, partitions.length, partitions, progressBlockNumber, knownHeight);
1560
1823
  if (optimizedPartitions.idsInAscOrder.length === 0 && Utils.$$Array.isEmpty(onBlockRegistrations)) {
1561
- 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.`);
1824
+ Stdlib_JsError.throwWithMessage(`Invalid configuration: Nothing to fetch on chain ` + ChainId.toString(chainId) + `. ` + (`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.`);
1562
1825
  }
1563
1826
  let buffer = [];
1564
1827
  let latestOnBlockBlockNumber;
@@ -1669,6 +1932,7 @@ function rollback(fetchState, addressStore, targetBlockNumber) {
1669
1932
  } else {
1670
1933
  let id$1 = nextKeptIdRef.toString();
1671
1934
  nextKeptIdRef = nextKeptIdRef + 1 | 0;
1935
+ let mergeBlock$2 = p.mergeBlock;
1672
1936
  keptPartitions.push({
1673
1937
  id: id$1,
1674
1938
  latestFetchedBlock: p.latestFetchedBlock.blockNumber > targetBlockNumber ? ({
@@ -1677,7 +1941,7 @@ function rollback(fetchState, addressStore, targetBlockNumber) {
1677
1941
  }) : p.latestFetchedBlock,
1678
1942
  selection: p.selection,
1679
1943
  addresses: p.addresses,
1680
- mergeBlock: p.mergeBlock,
1944
+ mergeBlock: mergeBlock$2 !== undefined && mergeBlock$2 > targetBlockNumber ? targetBlockNumber : mergeBlock$2,
1681
1945
  dynamicContract: p.dynamicContract,
1682
1946
  mutPendingQueries: rollbackPendingQueries(p.mutPendingQueries, targetBlockNumber),
1683
1947
  sourceRangeCapacity: p.sourceRangeCapacity,
@@ -1874,10 +2138,14 @@ let maxChainConcurrency = Env.maxChainConcurrency;
1874
2138
  let chunkRangeGrowthFactor = 1.8;
1875
2139
 
1876
2140
  export {
2141
+ deriveSelectionStartBlock,
2142
+ makeSelection,
1877
2143
  withAddresses,
2144
+ narrowSelectionToRange,
1878
2145
  densityItemsTarget,
1879
2146
  getMinHistoryRange,
1880
2147
  getTrustedDensity,
2148
+ isFetching,
1881
2149
  getMinQueryRange,
1882
2150
  OptimizedPartitions,
1883
2151
  bufferBlockNumber,
@@ -1892,6 +2160,8 @@ export {
1892
2160
  addClientFilteredContract,
1893
2161
  claimedFetchedBlock,
1894
2162
  collapseClientFilteredContracts,
2163
+ warnAddressRegistration,
2164
+ warnRejectedRegistration,
1895
2165
  createPartitions,
1896
2166
  registerDynamicContracts,
1897
2167
  handleQueryResult,