envio 3.3.0-alpha.4 → 3.3.0-alpha.6

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 (55) hide show
  1. package/evm.schema.json +10 -0
  2. package/package.json +7 -7
  3. package/src/Batch.res.mjs +1 -1
  4. package/src/BatchProcessing.res +5 -0
  5. package/src/BatchProcessing.res.mjs +6 -0
  6. package/src/ChainState.res +41 -7
  7. package/src/ChainState.res.mjs +22 -18
  8. package/src/ChainState.resi +3 -1
  9. package/src/Config.res +3 -0
  10. package/src/Config.res.mjs +3 -1
  11. package/src/Core.res +0 -3
  12. package/src/ExitOnCaughtUp.res +10 -2
  13. package/src/ExitOnCaughtUp.res.mjs +10 -1
  14. package/src/FetchState.res +63 -133
  15. package/src/FetchState.res.mjs +107 -166
  16. package/src/IndexerState.res +4 -0
  17. package/src/IndexerState.res.mjs +8 -1
  18. package/src/IndexerState.resi +1 -0
  19. package/src/IndexingAddresses.res +105 -0
  20. package/src/IndexingAddresses.res.mjs +100 -0
  21. package/src/IndexingAddresses.resi +32 -0
  22. package/src/Main.res +4 -15
  23. package/src/Main.res.mjs +6 -14
  24. package/src/Metrics.res +33 -0
  25. package/src/Metrics.res.mjs +39 -0
  26. package/src/Prometheus.res +2 -20
  27. package/src/Prometheus.res.mjs +83 -95
  28. package/src/SimulateDeadInputTracker.res +85 -0
  29. package/src/SimulateDeadInputTracker.res.mjs +73 -0
  30. package/src/SimulateDeadInputTracker.resi +12 -0
  31. package/src/SimulateItems.res +23 -42
  32. package/src/SimulateItems.res.mjs +12 -30
  33. package/src/TestIndexer.res +3 -27
  34. package/src/TestIndexer.res.mjs +2 -9
  35. package/src/bindings/Viem.res +0 -41
  36. package/src/bindings/Viem.res.mjs +1 -43
  37. package/src/sources/Evm.res +7 -36
  38. package/src/sources/Evm.res.mjs +4 -36
  39. package/src/sources/EvmChain.res +4 -2
  40. package/src/sources/EvmChain.res.mjs +3 -2
  41. package/src/sources/EvmRpcClient.res +36 -5
  42. package/src/sources/EvmRpcClient.res.mjs +7 -4
  43. package/src/sources/HyperSyncClient.res +0 -35
  44. package/src/sources/HyperSyncClient.res.mjs +1 -8
  45. package/src/sources/Rpc.res +15 -47
  46. package/src/sources/Rpc.res.mjs +25 -56
  47. package/src/sources/RpcSource.res +289 -204
  48. package/src/sources/RpcSource.res.mjs +293 -303
  49. package/src/sources/SimulateSource.res +1 -0
  50. package/src/sources/SimulateSource.res.mjs +2 -1
  51. package/src/sources/Source.res +4 -0
  52. package/src/sources/Svm.res +7 -15
  53. package/src/sources/Svm.res.mjs +4 -15
  54. package/src/sources/TransactionStore.res +14 -2
  55. package/src/sources/TransactionStore.res.mjs +10 -2
@@ -1,11 +1,5 @@
1
- type contractConfig = {startBlock: option<int>}
2
-
3
1
  type indexingAddress = Internal.indexingContract
4
2
 
5
- let deriveEffectiveStartBlock = (~registrationBlock: int, ~contractStartBlock: option<int>) => {
6
- Pervasives.max(Pervasives.max(registrationBlock, 0), contractStartBlock->Option.getOr(0))
7
- }
8
-
9
3
  type blockNumberAndTimestamp = {
10
4
  blockNumber: int,
11
5
  blockTimestamp: int,
@@ -536,10 +530,8 @@ type t = {
536
530
  startBlock: int,
537
531
  endBlock: option<int>,
538
532
  normalSelection: selection,
539
- // By address
540
- indexingAddresses: dict<indexingAddress>,
541
533
  // By contract name
542
- contractConfigs: dict<contractConfig>,
534
+ contractConfigs: dict<IndexingAddresses.contractConfig>,
543
535
  // Not used for logic - only metadata
544
536
  chainId: int,
545
537
  // The block number of the latest block which was added to the queue
@@ -592,6 +584,25 @@ let bufferBlock = ({optimizedPartitions, latestOnBlockBlockNumber}: t) => {
592
584
  }
593
585
  }
594
586
 
587
+ // Number of buffered items at or below the ready frontier (processable now,
588
+ // i.e. not stuck behind a gap from a lagging partition or out-of-order chunk).
589
+ // The buffer is kept sorted, so binary-search the frontier in O(log n).
590
+ let bufferReadyCount = (fetchState: t) => {
591
+ let frontier = fetchState->bufferBlockNumber
592
+ let buffer = fetchState.buffer
593
+ let lo = ref(0)
594
+ let hi = ref(buffer->Array.length)
595
+ while lo.contents < hi.contents {
596
+ let mid = (lo.contents + hi.contents) / 2
597
+ if buffer->Array.getUnsafe(mid)->Internal.getItemBlockNumber <= frontier {
598
+ lo := mid + 1
599
+ } else {
600
+ hi := mid
601
+ }
602
+ }
603
+ lo.contents
604
+ }
605
+
595
606
  /*
596
607
  Comparitor for two events from the same chain. No need for chain id or timestamp
597
608
  */
@@ -607,8 +618,6 @@ let compareBufferItem = (a: Internal.item, b: Internal.item) => {
607
618
  // Some big number which should be bigger than any log index
608
619
  let blockItemLogIndex = 16777216
609
620
 
610
- let numAddresses = fetchState => fetchState.indexingAddresses->Utils.Dict.size
611
-
612
621
  // Appends Block items produced by the onBlock handlers for every block in
613
622
  // (fromBlock, maxBlockNumber] into mutItems and returns the new
614
623
  // latestOnBlockBlockNumber pointer. maxOnBlockBufferSize bounds how many items
@@ -673,7 +682,6 @@ Runs partition optimization when partitions change.
673
682
  let updateInternal = (
674
683
  fetchState: t,
675
684
  ~optimizedPartitions=fetchState.optimizedPartitions,
676
- ~indexingAddresses=fetchState.indexingAddresses,
677
685
  ~mutItems=?,
678
686
  ~blockLag=fetchState.blockLag,
679
687
  ~knownHeight=fetchState.knownHeight,
@@ -729,7 +737,6 @@ let updateInternal = (
729
737
  maxOnBlockBufferSize: fetchState.maxOnBlockBufferSize,
730
738
  optimizedPartitions,
731
739
  latestOnBlockBlockNumber,
732
- indexingAddresses,
733
740
  blockLag,
734
741
  knownHeight,
735
742
  buffer: switch mutItemsRef.contents {
@@ -757,12 +764,6 @@ let updateInternal = (
757
764
  ~blockNumber=updatedFetchState->bufferBlockNumber,
758
765
  ~chainId=fetchState.chainId,
759
766
  )
760
- if indexingAddresses !== fetchState.indexingAddresses {
761
- Prometheus.IndexingAddresses.set(
762
- ~addressesCount=updatedFetchState->numAddresses,
763
- ~chainId=fetchState.chainId,
764
- )
765
- }
766
767
 
767
768
  updatedFetchState
768
769
  }
@@ -993,6 +994,7 @@ OptimizedPartitions.t => {
993
994
 
994
995
  let registerDynamicContracts = (
995
996
  fetchState: t,
997
+ ~indexingAddresses: IndexingAddresses.t,
996
998
  // These are raw items which might have dynamic contracts received from contractRegister call.
997
999
  // Might contain duplicates which we should filter out
998
1000
  items: array<Internal.item>,
@@ -1004,11 +1006,10 @@ let registerDynamicContracts = (
1004
1006
  )
1005
1007
  }
1006
1008
 
1007
- let indexingAddresses = fetchState.indexingAddresses
1008
1009
  let registeringContractsByContract: dict<dict<indexingAddress>> = Dict.make()
1009
1010
  let earliestRegisteringEventBlockNumber = ref(%raw(`Infinity`))
1010
1011
  // Addresses registered for contracts without matching events. These are not
1011
- // added to partitions, but they are tracked on fetchState.indexingAddresses
1012
+ // added to partitions, but they are tracked on indexingAddresses
1012
1013
  // so that later conflicting registrations are detected, and are persisted
1013
1014
  // to envio_addresses so they can be picked up on restart with updated config.
1014
1015
  let noEventsAddresses: dict<indexingAddress> = Dict.make()
@@ -1034,15 +1035,13 @@ let registerDynamicContracts = (
1034
1035
  address: dc.address,
1035
1036
  contractName: dc.contractName,
1036
1037
  registrationBlock: dc.registrationBlock,
1037
- effectiveStartBlock: deriveEffectiveStartBlock(
1038
+ effectiveStartBlock: IndexingAddresses.deriveEffectiveStartBlock(
1038
1039
  ~registrationBlock=dc.registrationBlock,
1039
1040
  ~contractStartBlock,
1040
1041
  ),
1041
1042
  }
1042
1043
  // Prevent registering already indexing contracts
1043
- switch indexingAddresses->Utils.Dict.dangerouslyGetNonOption(
1044
- dc.address->Address.toString,
1045
- ) {
1044
+ switch indexingAddresses->IndexingAddresses.get(dc.address->Address.toString) {
1046
1045
  | Some(existingContract) =>
1047
1046
  // FIXME: Instead of filtering out duplicates,
1048
1047
  // we should check the block number first.
@@ -1097,7 +1096,7 @@ let registerDynamicContracts = (
1097
1096
  address: dc.address,
1098
1097
  contractName: dc.contractName,
1099
1098
  registrationBlock: dc.registrationBlock,
1100
- effectiveStartBlock: deriveEffectiveStartBlock(
1099
+ effectiveStartBlock: IndexingAddresses.deriveEffectiveStartBlock(
1101
1100
  ~registrationBlock=dc.registrationBlock,
1102
1101
  ~contractStartBlock=None,
1103
1102
  ),
@@ -1105,9 +1104,7 @@ let registerDynamicContracts = (
1105
1104
  // Prevent duplicate logging/persistence when the same address is
1106
1105
  // already tracked on fetchState, either from the db on startup or
1107
1106
  // from an earlier registration in this batch.
1108
- switch indexingAddresses->Utils.Dict.dangerouslyGetNonOption(
1109
- dc.address->Address.toString,
1110
- ) {
1107
+ switch indexingAddresses->IndexingAddresses.get(dc.address->Address.toString) {
1111
1108
  | Some(existingContract) =>
1112
1109
  if existingContract.contractName != dc.contractName {
1113
1110
  fetchState->warnDifferentContractType(~existingContract, ~dc=dcAsIndexingAddress)
@@ -1161,12 +1158,10 @@ let registerDynamicContracts = (
1161
1158
  // Only dcs for contracts without events. Track them on
1162
1159
  // indexingAddresses so subsequent registrations see them, but don't touch
1163
1160
  // partitions since there's nothing to fetch for them.
1164
- let newIndexingContracts = indexingAddresses->Utils.Dict.shallowCopy
1165
- let _ = Utils.Dict.mergeInPlace(newIndexingContracts, noEventsAddresses)
1166
- fetchState->updateInternal(~indexingAddresses=newIndexingContracts)
1161
+ indexingAddresses->IndexingAddresses.register(noEventsAddresses)
1162
+ fetchState
1167
1163
  | (_, _) => {
1168
1164
  let newPartitions = []
1169
- let newIndexingAddresses = indexingAddresses->Utils.Dict.shallowCopy
1170
1165
  let dynamicContractsRef = ref(fetchState.optimizedPartitions.dynamicContracts)
1171
1166
  let mutExistingPartitions = fetchState.optimizedPartitions.entities->Dict.valuesToArray
1172
1167
 
@@ -1248,10 +1243,10 @@ let registerDynamicContracts = (
1248
1243
  }
1249
1244
 
1250
1245
  let registeringContracts = registeringContractsByContract->Dict.getUnsafe(contractName)
1251
- let _ = Utils.Dict.mergeInPlace(newIndexingAddresses, registeringContracts)
1246
+ indexingAddresses->IndexingAddresses.register(registeringContracts)
1252
1247
  }
1253
1248
  // Include no-events dcs so later batches detect conflicts against them.
1254
- let _ = Utils.Dict.mergeInPlace(newIndexingAddresses, noEventsAddresses)
1249
+ indexingAddresses->IndexingAddresses.register(noEventsAddresses)
1255
1250
 
1256
1251
  let optimizedPartitions = createPartitionsFromIndexingAddresses(
1257
1252
  ~registeringContractsByContract,
@@ -1264,7 +1259,7 @@ let registerDynamicContracts = (
1264
1259
  ~progressBlockNumber=0,
1265
1260
  )
1266
1261
 
1267
- fetchState->updateInternal(~optimizedPartitions, ~indexingAddresses=newIndexingAddresses)
1262
+ fetchState->updateInternal(~optimizedPartitions)
1268
1263
  }
1269
1264
  }
1270
1265
  }
@@ -1277,6 +1272,7 @@ newItems are ordered earliest to latest (as they are returned from the worker)
1277
1272
  */
1278
1273
  let handleQueryResult = (
1279
1274
  fetchState: t,
1275
+ ~indexingAddresses: IndexingAddresses.t,
1280
1276
  ~query: query,
1281
1277
  ~latestFetchedBlock: blockNumberAndTimestamp,
1282
1278
  ~newItems,
@@ -1289,7 +1285,8 @@ let handleQueryResult = (
1289
1285
  switch item {
1290
1286
  | Internal.Event({eventConfig, payload, blockNumber}) =>
1291
1287
  switch eventConfig.clientAddressFilter {
1292
- | Some(filter) => filter(payload, blockNumber, fetchState.indexingAddresses)
1288
+ | Some(filter) =>
1289
+ filter(payload, blockNumber, indexingAddresses->IndexingAddresses.rawForFilter)
1293
1290
  | None => true
1294
1291
  }
1295
1292
  | _ => true
@@ -1462,11 +1459,16 @@ let getNextQuery = (
1462
1459
  !isOnBlockBehindTheHead,
1463
1460
  )
1464
1461
 
1465
- // Limit how far ahead we fetch to budget items (plus what's already in
1466
- // flight) so processing always has buffer without ballooning memory. A
1467
- // partition that fetched further is skipped until the buffer drains.
1462
+ // Fetch at most `budget` items past the ready frontier (plus what's already
1463
+ // in flight) so processing always has buffer without ballooning memory.
1464
+ // budget already excludes items at/below the frontier (they're in the shared
1465
+ // totalReadyCount), so offset the index by bufferReadyCount — otherwise the
1466
+ // ready prefix is subtracted twice and the buffer caps at a fraction of its
1467
+ // target. A partition that fetched further is skipped until the buffer drains.
1468
1468
  let maxQueryBlockNumber = {
1469
- switch buffer->Array.get(budget + chainPendingBudget->Float.toInt - 1) {
1469
+ switch buffer->Array.get(
1470
+ fetchState->bufferReadyCount + budget + chainPendingBudget->Float.toInt - 1,
1471
+ ) {
1470
1472
  | Some(item) =>
1471
1473
  // Just in case check that we don't query beyond the current block
1472
1474
  Pervasives.min(item->Internal.getItemBlockNumber, knownHeight)
@@ -1625,6 +1627,7 @@ let make = (
1625
1627
  ~startBlock,
1626
1628
  ~endBlock,
1627
1629
  ~eventConfigs: array<Internal.eventConfig>,
1630
+ ~contractConfigs: dict<IndexingAddresses.contractConfig>,
1628
1631
  ~addresses: array<Internal.indexingAddress>,
1629
1632
  ~maxAddrInPartition,
1630
1633
  ~chainId,
@@ -1643,31 +1646,8 @@ let make = (
1643
1646
  let notDependingOnAddresses = []
1644
1647
  let normalEventConfigs = []
1645
1648
  let contractNamesWithNormalEvents = Utils.Set.make()
1646
- let indexingAddresses = Dict.make()
1647
- let contractConfigs: dict<contractConfig> = Dict.make()
1648
1649
 
1649
1650
  eventConfigs->Array.forEach(ec => {
1650
- switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(ec.contractName) {
1651
- | Some({startBlock}) =>
1652
- contractConfigs->Dict.set(
1653
- ec.contractName,
1654
- {
1655
- startBlock: switch (startBlock, ec.startBlock) {
1656
- | (Some(a), Some(b)) => Some(Pervasives.min(a, b))
1657
- | (Some(_) as s, None) | (None, Some(_) as s) => s
1658
- | (None, None) => None
1659
- },
1660
- },
1661
- )
1662
- | None =>
1663
- contractConfigs->Dict.set(
1664
- ec.contractName,
1665
- {
1666
- startBlock: ec.startBlock,
1667
- },
1668
- )
1669
- }
1670
-
1671
1651
  if ec.dependsOnAddresses {
1672
1652
  normalEventConfigs->Array.push(ec)
1673
1653
  contractNamesWithNormalEvents->Utils.Set.add(ec.contractName)->ignore
@@ -1707,32 +1687,16 @@ let make = (
1707
1687
 
1708
1688
  addresses->Array.forEach(contract => {
1709
1689
  let contractName = contract.contractName
1710
- let contractStartBlock = switch contractConfigs->Utils.Dict.dangerouslyGetNonOption(
1711
- contractName,
1712
- ) {
1713
- | Some({startBlock}) => startBlock
1714
- | None => None
1715
- }
1716
- let ia: indexingAddress = {
1717
- address: contract.address,
1718
- contractName: contract.contractName,
1719
- registrationBlock: contract.registrationBlock,
1720
- effectiveStartBlock: deriveEffectiveStartBlock(
1721
- ~registrationBlock=contract.registrationBlock,
1722
- ~contractStartBlock,
1723
- ),
1724
- }
1725
- // Track the address on fetchState regardless of whether it currently has
1726
- // matching events. This way, if the config is updated later to add events
1727
- // for this contract, the address is already known.
1728
- indexingAddresses->Dict.set(contract.address->Address.toString, ia)
1729
1690
 
1730
1691
  // Only addresses whose contract has events that depend on addresses get
1731
1692
  // registered for active fetching via partitions.
1732
1693
  if contractNamesWithNormalEvents->Utils.Set.has(contractName) {
1733
- let registeringContracts =
1734
- registeringContractsByContract->Utils.Dict.getOrInsertEmptyDict(contractName)
1735
- registeringContracts->Dict.set(contract.address->Address.toString, ia)
1694
+ registeringContractsByContract
1695
+ ->Utils.Dict.getOrInsertEmptyDict(contractName)
1696
+ ->Dict.set(
1697
+ contract.address->Address.toString,
1698
+ IndexingAddresses.makeIndexingAddress(~contract, ~contractConfigs),
1699
+ )
1736
1700
 
1737
1701
  // Detect dynamic contracts by registrationBlock
1738
1702
  if contract.registrationBlock !== -1 {
@@ -1792,7 +1756,6 @@ let make = (
1792
1756
  endBlock,
1793
1757
  latestOnBlockBlockNumber,
1794
1758
  normalSelection,
1795
- indexingAddresses,
1796
1759
  blockLag,
1797
1760
  onBlockConfigs,
1798
1761
  maxOnBlockBufferSize,
@@ -1801,8 +1764,6 @@ let make = (
1801
1764
  firstEventBlock,
1802
1765
  }
1803
1766
 
1804
- let numAddresses = indexingAddresses->Utils.Dict.size
1805
- Prometheus.IndexingAddresses.set(~addressesCount=numAddresses, ~chainId)
1806
1767
  Prometheus.IndexingPartitions.set(
1807
1768
  ~partitionsCount=optimizedPartitions->OptimizedPartitions.count,
1808
1769
  ~chainId,
@@ -1819,25 +1780,6 @@ let make = (
1819
1780
 
1820
1781
  let bufferSize = ({buffer}: t) => buffer->Array.length
1821
1782
 
1822
- // Number of buffered items at or below the ready frontier (processable now,
1823
- // i.e. not stuck behind a gap from a lagging partition or out-of-order chunk).
1824
- // The buffer is kept sorted, so binary-search the frontier in O(log n).
1825
- let bufferReadyCount = (fetchState: t) => {
1826
- let frontier = fetchState->bufferBlockNumber
1827
- let buffer = fetchState.buffer
1828
- let lo = ref(0)
1829
- let hi = ref(buffer->Array.length)
1830
- while lo.contents < hi.contents {
1831
- let mid = (lo.contents + hi.contents) / 2
1832
- if buffer->Array.getUnsafe(mid)->Internal.getItemBlockNumber <= frontier {
1833
- lo := mid + 1
1834
- } else {
1835
- hi := mid
1836
- }
1837
- }
1838
- lo.contents
1839
- }
1840
-
1841
1783
  let rollbackPendingQueries = (mutPendingQueries: array<pendingQuery>, ~targetBlockNumber) => {
1842
1784
  // - Remove queries where fromBlock > target
1843
1785
  // - Cap fetchedBlock at target where fetchedBlock > target
@@ -1869,18 +1811,11 @@ Always recreates optimized partitions to avoid duplicate addresses:
1869
1811
  - Non-wildcard with lfb <= target: keep, adjust pending queries and mergeBlock
1870
1812
  - Non-wildcard with lfb > target: delete, track addresses for recreation
1871
1813
  */
1872
- let rollback = (fetchState: t, ~targetBlockNumber) => {
1873
- // Step 1: Build addressesToRemove and surviving indexingAddresses
1874
- let addressesToRemove = Utils.Set.make()
1875
- let indexingAddresses = Dict.make()
1876
-
1877
- fetchState.indexingAddresses->Utils.Dict.forEachWithKey((indexingContract, address) => {
1878
- if indexingContract.registrationBlock > targetBlockNumber {
1879
- let _ = addressesToRemove->Utils.Set.add(address->Address.unsafeFromString)
1880
- } else {
1881
- indexingAddresses->Dict.set(address, indexingContract)
1882
- }
1883
- })
1814
+ let rollback = (fetchState: t, ~indexingAddresses: IndexingAddresses.t, ~targetBlockNumber) => {
1815
+ // Step 1: Prune addresses registered after the target block. The pruned index is
1816
+ // then the source of truth for partition cleanup below — an address survives iff
1817
+ // it's still in the index.
1818
+ indexingAddresses->IndexingAddresses.rollbackInPlace(~targetBlockNumber)
1884
1819
 
1885
1820
  // Step 2: Categorize partitions
1886
1821
  let keptPartitions = []
@@ -1910,18 +1845,12 @@ let rollback = (fetchState: t, ~targetBlockNumber) => {
1910
1845
  | _ if p.latestFetchedBlock.blockNumber > targetBlockNumber =>
1911
1846
  p.addressesByContractName->Utils.Dict.forEachWithKey((addresses, contractName) => {
1912
1847
  addresses->Array.forEach(address => {
1913
- if (
1914
- !(addressesToRemove->Utils.Set.has(address)) &&
1915
- indexingAddresses
1916
- ->Utils.Dict.dangerouslyGetNonOption(address->Address.toString)
1917
- ->Option.isSome
1918
- ) {
1848
+ switch indexingAddresses->IndexingAddresses.get(address->Address.toString) {
1849
+ | Some(indexingContract) =>
1919
1850
  let registeringContracts =
1920
1851
  registeringContractsByContract->Utils.Dict.getOrInsertEmptyDict(contractName)
1921
- registeringContracts->Dict.set(
1922
- address->Address.toString,
1923
- indexingAddresses->Dict.getUnsafe(address->Address.toString),
1924
- )
1852
+ registeringContracts->Dict.set(address->Address.toString, indexingContract)
1853
+ | None => ()
1925
1854
  }
1926
1855
  })
1927
1856
  })
@@ -1934,11 +1863,13 @@ let rollback = (fetchState: t, ~targetBlockNumber) => {
1934
1863
  | other => other
1935
1864
  }
1936
1865
 
1937
- // Remove addresses that should be removed
1866
+ // Drop addresses pruned from the index
1938
1867
  let rollbackedAddressesByContractName = Dict.make()
1939
1868
  addressesByContractName->Utils.Dict.forEachWithKey((addresses, contractName) => {
1940
1869
  let keptAddresses =
1941
- addresses->Array.filter(address => !(addressesToRemove->Utils.Set.has(address)))
1870
+ addresses->Array.filter(address =>
1871
+ indexingAddresses->IndexingAddresses.get(address->Address.toString)->Option.isSome
1872
+ )
1942
1873
  if keptAddresses->Array.length > 0 {
1943
1874
  rollbackedAddressesByContractName->Dict.set(contractName, keptAddresses)
1944
1875
  }
@@ -1982,7 +1913,6 @@ let rollback = (fetchState: t, ~targetBlockNumber) => {
1982
1913
  ),
1983
1914
  }->updateInternal(
1984
1915
  ~optimizedPartitions,
1985
- ~indexingAddresses,
1986
1916
  ~mutItems=fetchState.buffer->Array.filter(item =>
1987
1917
  switch item {
1988
1918
  | Event({blockNumber})