envio 3.2.0 → 3.3.0-alpha.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 (113) hide show
  1. package/package.json +6 -7
  2. package/src/Batch.res +12 -15
  3. package/src/Batch.res.mjs +4 -5
  4. package/src/BatchProcessing.res +199 -0
  5. package/src/BatchProcessing.res.mjs +125 -0
  6. package/src/ChainFetching.res +375 -0
  7. package/src/ChainFetching.res.mjs +206 -0
  8. package/src/ChainMetadata.res +27 -0
  9. package/src/ChainMetadata.res.mjs +27 -0
  10. package/src/ChainState.res +618 -0
  11. package/src/ChainState.res.mjs +461 -0
  12. package/src/ChainState.resi +85 -0
  13. package/src/Config.res +13 -4
  14. package/src/Config.res.mjs +8 -3
  15. package/src/ContractRegisterContext.res +106 -0
  16. package/src/ContractRegisterContext.res.mjs +76 -0
  17. package/src/Core.res +3 -0
  18. package/src/CrossChainState.res +269 -0
  19. package/src/CrossChainState.res.mjs +197 -0
  20. package/src/CrossChainState.resi +47 -0
  21. package/src/Ecosystem.res +58 -0
  22. package/src/Ecosystem.res.mjs +43 -1
  23. package/src/Env.res +7 -2
  24. package/src/Env.res.mjs +5 -2
  25. package/src/EventConfigBuilder.res +35 -0
  26. package/src/EventConfigBuilder.res.mjs +21 -0
  27. package/src/EventProcessing.res +60 -46
  28. package/src/EventProcessing.res.mjs +33 -32
  29. package/src/EventUtils.res +0 -4
  30. package/src/EventUtils.res.mjs +0 -4
  31. package/src/ExitOnCaughtUp.res +10 -0
  32. package/src/ExitOnCaughtUp.res.mjs +22 -0
  33. package/src/FetchState.res +162 -113
  34. package/src/FetchState.res.mjs +181 -119
  35. package/src/HandlerLoader.res +6 -1
  36. package/src/HandlerLoader.res.mjs +13 -36
  37. package/src/InMemoryStore.res +36 -451
  38. package/src/InMemoryStore.res.mjs +20 -369
  39. package/src/IndexerLoop.res +44 -0
  40. package/src/IndexerLoop.res.mjs +46 -0
  41. package/src/IndexerState.res +544 -0
  42. package/src/IndexerState.res.mjs +547 -0
  43. package/src/IndexerState.resi +132 -0
  44. package/src/Internal.res +44 -7
  45. package/src/LoadLayer.res +20 -18
  46. package/src/LoadLayer.res.mjs +14 -12
  47. package/src/LoadLayer.resi +6 -3
  48. package/src/LogSelection.res +86 -17
  49. package/src/LogSelection.res.mjs +67 -14
  50. package/src/Logging.res +11 -44
  51. package/src/Logging.res.mjs +10 -42
  52. package/src/Main.res +54 -79
  53. package/src/Main.res.mjs +44 -56
  54. package/src/PgStorage.res +8 -71
  55. package/src/PgStorage.res.mjs +3 -47
  56. package/src/Prometheus.res +7 -8
  57. package/src/Prometheus.res.mjs +7 -4
  58. package/src/PruneStaleHistory.res +45 -0
  59. package/src/PruneStaleHistory.res.mjs +46 -0
  60. package/src/RawEvent.res +73 -0
  61. package/src/RawEvent.res.mjs +51 -0
  62. package/src/Rollback.res +204 -0
  63. package/src/Rollback.res.mjs +118 -0
  64. package/src/SimulateItems.res +12 -10
  65. package/src/SimulateItems.res.mjs +1 -1
  66. package/src/TestIndexer.res +34 -27
  67. package/src/TestIndexer.res.mjs +4 -1
  68. package/src/UserContext.res +26 -114
  69. package/src/UserContext.res.mjs +15 -78
  70. package/src/Writing.res +242 -0
  71. package/src/Writing.res.mjs +215 -0
  72. package/src/db/InternalTable.res +14 -27
  73. package/src/sources/Evm.res +40 -1
  74. package/src/sources/Evm.res.mjs +94 -84
  75. package/src/sources/Fuel.res +40 -1
  76. package/src/sources/Fuel.res.mjs +36 -26
  77. package/src/sources/HyperFuel.res +41 -120
  78. package/src/sources/HyperFuel.res.mjs +42 -80
  79. package/src/sources/HyperFuel.resi +1 -24
  80. package/src/sources/HyperFuelClient.res +16 -297
  81. package/src/sources/HyperFuelClient.res.mjs +5 -4
  82. package/src/sources/HyperFuelSource.res +33 -8
  83. package/src/sources/HyperFuelSource.res.mjs +56 -10
  84. package/src/sources/HyperSyncSource.res +7 -5
  85. package/src/sources/HyperSyncSource.res.mjs +3 -3
  86. package/src/sources/RpcSource.res +2 -2
  87. package/src/sources/RpcSource.res.mjs +1 -1
  88. package/src/sources/SourceManager.res +8 -18
  89. package/src/sources/SourceManager.res.mjs +8 -5
  90. package/src/sources/SourceManager.resi +4 -1
  91. package/src/sources/Svm.res +18 -1
  92. package/src/sources/Svm.res.mjs +30 -22
  93. package/src/sources/SvmHyperSyncSource.res +1 -1
  94. package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
  95. package/src/tui/Tui.res +38 -36
  96. package/src/tui/Tui.res.mjs +51 -51
  97. package/src/ChainFetcher.res +0 -519
  98. package/src/ChainFetcher.res.mjs +0 -314
  99. package/src/ChainManager.res +0 -358
  100. package/src/ChainManager.res.mjs +0 -291
  101. package/src/Ctx.res +0 -6
  102. package/src/Ctx.res.mjs +0 -2
  103. package/src/GlobalState.res +0 -1056
  104. package/src/GlobalState.res.mjs +0 -1086
  105. package/src/GlobalStateManager.res +0 -57
  106. package/src/GlobalStateManager.res.mjs +0 -68
  107. package/src/GlobalStateManager.resi +0 -7
  108. package/src/Ports.res +0 -5
  109. package/src/Ports.res.mjs +0 -9
  110. package/src/adapters/MarkBatchProcessedAdapter.res +0 -5
  111. package/src/adapters/MarkBatchProcessedAdapter.res.mjs +0 -14
  112. package/src/sources/EnvioApiClient.res +0 -15
  113. package/src/sources/EnvioApiClient.res.mjs +0 -24
@@ -0,0 +1,47 @@
1
+ // Whole-indexer view over every chain's ChainState. `t` is opaque: other modules
2
+ // read it through the accessors and change it only through the transitions here.
3
+
4
+ type t
5
+
6
+ let calculateTargetBufferSize: unit => int
7
+
8
+ let make: (
9
+ ~chainStates: dict<ChainState.t>,
10
+ ~isInReorgThreshold: bool,
11
+ ~isRealtime: bool,
12
+ ~maxBackfillConcurrency: int=?,
13
+ ~maxRealtimeConcurrency: int=?,
14
+ ~targetBufferSize: int=?,
15
+ ) => t
16
+
17
+ // Accessors.
18
+ let chainStates: t => dict<ChainState.t>
19
+ let isRealtime: t => bool
20
+ let isInReorgThreshold: t => bool
21
+ let maxConcurrency: t => int
22
+ let inFlight: t => int
23
+
24
+ // Derived (pure).
25
+ let nextItemIsNone: t => bool
26
+ let getSafeCheckpointId: t => option<Internal.checkpointId>
27
+
28
+ // Cross-chain transitions.
29
+ let createBatch: (
30
+ t,
31
+ ~processedCheckpointId: Internal.checkpointId,
32
+ ~batchSizeTarget: int,
33
+ ~isRollback: bool,
34
+ ) => Batch.t
35
+ let enterReorgThreshold: t => unit
36
+ let applyBatchProgress: (t, ~batch: Batch.t) => unit
37
+
38
+ // Fetch control.
39
+ let priorityOrder: t => array<ChainState.t>
40
+ let checkAndFetch: (
41
+ t,
42
+ ~fetchChain: (
43
+ ~chain: ChainMap.Chain.t,
44
+ ~concurrencyLimit: int,
45
+ ~bufferLimit: int,
46
+ ) => promise<unit>,
47
+ ) => promise<unit>
package/src/Ecosystem.res CHANGED
@@ -29,8 +29,66 @@ type t = {
29
29
  `LogSelection.res`. SVM does not support event handlers, so its
30
30
  schema always surfaces `None`. */
31
31
  onEventBlockFilterSchema: S.t<option<unknown>>,
32
+ /** Base logger injected at construction. Used to build per-item child
33
+ loggers (see `getItemLogger`). */
34
+ logger: Pino.t,
35
+ /** Materialise the user-facing event handed to handlers and contract
36
+ registration from an item's opaque payload. */
37
+ toEvent: Internal.eventItem => Internal.event,
38
+ /** Build the per-item child logger for an event item, with
39
+ ecosystem-specific log fields (EVM/Fuel: contract/event/address; SVM:
40
+ program/instruction/programId). Closes over the injected logger. */
41
+ toEventLogger: Internal.eventItem => Pino.t,
42
+ /** Build a raw event row for the `raw_events` table. Unsupported on SVM,
43
+ where the implementation throws. */
44
+ toRawEvent: Internal.eventItem => Internal.rawEvent,
32
45
  }
33
46
 
47
+ // The materialised event and the child logger are both memoised on the item
48
+ // object (an item is processed across preload + execution passes, and logged
49
+ // from several places). Hidden keys mirror each other.
50
+ let getItemEvent = {
51
+ let cacheKey = "_event"
52
+ (item: Internal.item, ~ecosystem: t): Internal.event => {
53
+ let cache = item->(Utils.magic: Internal.item => dict<Internal.event>)
54
+ switch cache->Utils.Dict.dangerouslyGetNonOption(cacheKey) {
55
+ | Some(event) => event
56
+ | None =>
57
+ let event = ecosystem.toEvent(item->Internal.castUnsafeEventItem)
58
+ cache->Dict.set(cacheKey, event)
59
+ event
60
+ }
61
+ }
62
+ }
63
+
64
+ let getItemLogger = {
65
+ let cacheKey = "_logger"
66
+ (item: Internal.item, ~ecosystem: t): Pino.t => {
67
+ let cache = item->(Utils.magic: Internal.item => dict<Pino.t>)
68
+ switch cache->Utils.Dict.dangerouslyGetNonOption(cacheKey) {
69
+ | Some(logger) => logger
70
+ | None =>
71
+ let logger = switch item {
72
+ | Internal.Event(_) => ecosystem.toEventLogger(item->Internal.castUnsafeEventItem)
73
+ | Block({blockNumber, onBlockConfig}) =>
74
+ Logging.createChildFrom(
75
+ ~logger=ecosystem.logger,
76
+ ~params={
77
+ "onBlock": onBlockConfig.name,
78
+ "chainId": onBlockConfig.chainId,
79
+ "block": blockNumber,
80
+ },
81
+ )
82
+ }
83
+ cache->Dict.set(cacheKey, logger)
84
+ logger
85
+ }
86
+ }
87
+ }
88
+
89
+ let getItemUserLogger = (item: Internal.item, ~ecosystem: t): Envio.logger =>
90
+ getItemLogger(item, ~ecosystem)->Logging.userLogger
91
+
34
92
  let makeOnBlockArgs = (~blockNumber: int, ~ecosystem: t, ~context): Internal.onBlockArgs => {
35
93
  switch ecosystem.name {
36
94
  | Svm => {slot: blockNumber, context}
@@ -1,7 +1,46 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
+ import * as Logging from "./Logging.res.mjs";
3
4
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
4
5
 
6
+ let cacheKey = "_event";
7
+
8
+ function getItemEvent(item, ecosystem) {
9
+ let event = item[cacheKey];
10
+ if (event !== undefined) {
11
+ return Primitive_option.valFromOption(event);
12
+ }
13
+ let event$1 = ecosystem.toEvent(item);
14
+ item[cacheKey] = event$1;
15
+ return event$1;
16
+ }
17
+
18
+ let cacheKey$1 = "_logger";
19
+
20
+ function getItemLogger(item, ecosystem) {
21
+ let logger = item[cacheKey$1];
22
+ if (logger !== undefined) {
23
+ return logger;
24
+ }
25
+ let logger$1;
26
+ if (item.kind === 0) {
27
+ logger$1 = ecosystem.toEventLogger(item);
28
+ } else {
29
+ let onBlockConfig = item.onBlockConfig;
30
+ logger$1 = Logging.createChildFrom(ecosystem.logger, {
31
+ onBlock: onBlockConfig.name,
32
+ chainId: onBlockConfig.chainId,
33
+ block: item.blockNumber
34
+ });
35
+ }
36
+ item[cacheKey$1] = logger$1;
37
+ return logger$1;
38
+ }
39
+
40
+ function getItemUserLogger(item, ecosystem) {
41
+ return Logging.userLogger(getItemLogger(item, ecosystem));
42
+ }
43
+
5
44
  function makeOnBlockArgs(blockNumber, ecosystem, context) {
6
45
  let match = ecosystem.name;
7
46
  switch (match) {
@@ -23,6 +62,9 @@ function makeOnBlockArgs(blockNumber, ecosystem, context) {
23
62
  }
24
63
 
25
64
  export {
65
+ getItemEvent,
66
+ getItemLogger,
67
+ getItemUserLogger,
26
68
  makeOnBlockArgs,
27
69
  }
28
- /* No side effect */
70
+ /* Logging Not a pure module */
package/src/Env.res CHANGED
@@ -8,8 +8,13 @@ let updateSyncTimeOnRestart =
8
8
  envSafe->EnvSafe.get("UPDATE_SYNC_TIME_ON_RESTART", S.bool, ~fallback=true)
9
9
  let targetBufferSize = envSafe->EnvSafe.get("ENVIO_INDEXING_MAX_BUFFER_SIZE", S.option(S.int))
10
10
  let maxAddrInPartition = envSafe->EnvSafe.get("MAX_PARTITION_SIZE", S.int, ~fallback=5_000)
11
- let maxPartitionConcurrency =
12
- envSafe->EnvSafe.get("ENVIO_MAX_PARTITION_CONCURRENCY", S.int, ~fallback=10)
11
+ // Global caps on concurrent data-source queries across the whole indexer (all
12
+ // chains share the budget), not per chain. Realtime allows far more since head
13
+ // queries are small and many chains follow the head at once.
14
+ let maxBackfillConcurrency =
15
+ envSafe->EnvSafe.get("ENVIO_MAX_BACKFILL_CONCURRENCY", S.int, ~fallback=30)
16
+ let maxRealtimeConcurrency =
17
+ envSafe->EnvSafe.get("ENVIO_MAX_REALTIME_CONCURRENCY", S.int, ~fallback=200)
13
18
 
14
19
  // Target number of in-memory objects (uncommitted entity/effect changes plus
15
20
  // unwritten batch items) the store holds before processing waits for the write
package/src/Env.res.mjs CHANGED
@@ -19,7 +19,9 @@ let targetBufferSize = EnvSafe.get(envSafe, "ENVIO_INDEXING_MAX_BUFFER_SIZE", S$
19
19
 
20
20
  let maxAddrInPartition = EnvSafe.get(envSafe, "MAX_PARTITION_SIZE", S$RescriptSchema.int, undefined, 5000, undefined, undefined);
21
21
 
22
- let maxPartitionConcurrency = EnvSafe.get(envSafe, "ENVIO_MAX_PARTITION_CONCURRENCY", S$RescriptSchema.int, undefined, 10, undefined, undefined);
22
+ let maxBackfillConcurrency = EnvSafe.get(envSafe, "ENVIO_MAX_BACKFILL_CONCURRENCY", S$RescriptSchema.int, undefined, 30, undefined, undefined);
23
+
24
+ let maxRealtimeConcurrency = EnvSafe.get(envSafe, "ENVIO_MAX_REALTIME_CONCURRENCY", S$RescriptSchema.int, undefined, 200, undefined, undefined);
23
25
 
24
26
  let inMemoryObjectsTarget = EnvSafe.get(envSafe, "ENVIO_IN_MEMORY_OBJECTS_TARGET", S$RescriptSchema.int, undefined, 100000, undefined, undefined);
25
27
 
@@ -222,7 +224,8 @@ export {
222
224
  updateSyncTimeOnRestart,
223
225
  targetBufferSize,
224
226
  maxAddrInPartition,
225
- maxPartitionConcurrency,
227
+ maxBackfillConcurrency,
228
+ maxRealtimeConcurrency,
226
229
  inMemoryObjectsTarget,
227
230
  serverPort,
228
231
  tuiEnvVar,
@@ -309,6 +309,39 @@ let resolveFieldSelection = (
309
309
  (selectedBlockFields, selectedTransactionFields)
310
310
  }
311
311
 
312
+ // ============== Client-side address filter ==============
313
+
314
+ let compileAddressFilter: string => (
315
+ Internal.eventPayload,
316
+ int,
317
+ dict<Internal.indexingContract>,
318
+ ) => bool = %raw(`function (body) {
319
+ return new Function("event", "blockNumber", "indexingAddresses", body);
320
+ }`)
321
+
322
+ // Body of the client-side address filter for a DNF of address-filtered param
323
+ // names (OR of AND-groups): keep the event only if some group's params are all
324
+ // registered at or before the log's block. The DNF is fixed here, so it's
325
+ // unrolled into one boolean expression — no per-event closure, loop, or array.
326
+ // `None` when there's no address-param filter. Exposed for snapshotting.
327
+ let buildAddressFilterBody = (groups: array<array<string>>): option<string> => {
328
+ switch groups {
329
+ | [] => None
330
+ | _ =>
331
+ let leaf = name =>
332
+ `(ic = indexingAddresses[p[${JSON.stringify(
333
+ JSON.String(name),
334
+ )}]]) !== undefined && ic.effectiveStartBlock <= blockNumber`
335
+ let groupExprs =
336
+ groups->Array.map(group => "(" ++ group->Array.map(leaf)->Array.join(" && ") ++ ")")
337
+ Some("var p = event.params, ic; return " ++ groupExprs->Array.join(" || ") ++ ";")
338
+ }
339
+ }
340
+
341
+ let buildAddressFilter = (groups: array<array<string>>): option<
342
+ (Internal.eventPayload, int, dict<Internal.indexingContract>) => bool,
343
+ > => buildAddressFilterBody(groups)->Option.map(compileAddressFilter)
344
+
312
345
  // ============== Build complete EVM event config ==============
313
346
 
314
347
  let buildEvmEventConfig = (
@@ -334,6 +367,7 @@ let buildEvmEventConfig = (
334
367
  let {
335
368
  getEventFiltersOrThrow,
336
369
  filterByAddresses,
370
+ addressFilterParamGroups,
337
371
  startBlock: whereStartBlock,
338
372
  } = LogSelection.parseEventFiltersOrThrow(
339
373
  ~eventFilters,
@@ -374,6 +408,7 @@ let buildEvmEventConfig = (
374
408
  simulateParamsSchema: buildSimulateParamsSchema(params),
375
409
  getEventFiltersOrThrow,
376
410
  filterByAddresses,
411
+ clientAddressFilter: ?buildAddressFilter(addressFilterParamGroups),
377
412
  dependsOnAddresses: !isWildcard || filterByAddresses,
378
413
  startBlock: resolvedStartBlock,
379
414
  selectedBlockFields,
@@ -251,6 +251,23 @@ function resolveFieldSelection(blockFields, transactionFields, globalBlockFields
251
251
  ];
252
252
  }
253
253
 
254
+ let compileAddressFilter = (function (body) {
255
+ return new Function("event", "blockNumber", "indexingAddresses", body);
256
+ });
257
+
258
+ function buildAddressFilterBody(groups) {
259
+ if (groups.length === 0) {
260
+ return;
261
+ }
262
+ let leaf = name => `(ic = indexingAddresses[p[` + JSON.stringify(name) + `]]) !== undefined && ic.effectiveStartBlock <= blockNumber`;
263
+ let groupExprs = groups.map(group => "(" + group.map(leaf).join(" && ") + ")");
264
+ return "var p = event.params, ic; return " + groupExprs.join(" || ") + ";";
265
+ }
266
+
267
+ function buildAddressFilter(groups) {
268
+ return Stdlib_Option.map(buildAddressFilterBody(groups), compileAddressFilter);
269
+ }
270
+
254
271
  function buildEvmEventConfig(contractName, eventName, sighash, params, isWildcard, handler, contractRegister, eventFilters, probeChainId, onEventBlockFilterSchema, blockFields, transactionFields, startBlock, globalBlockFieldsSetOpt, globalTransactionFieldsSetOpt) {
255
272
  let globalBlockFieldsSet = globalBlockFieldsSetOpt !== undefined ? Primitive_option.valFromOption(globalBlockFieldsSetOpt) : new Set();
256
273
  let globalTransactionFieldsSet = globalTransactionFieldsSetOpt !== undefined ? Primitive_option.valFromOption(globalTransactionFieldsSetOpt) : new Set();
@@ -274,6 +291,7 @@ function buildEvmEventConfig(contractName, eventName, sighash, params, isWildcar
274
291
  isWildcard: isWildcard,
275
292
  filterByAddresses: filterByAddresses,
276
293
  dependsOnAddresses: !isWildcard || filterByAddresses,
294
+ clientAddressFilter: Stdlib_Option.map(buildAddressFilterBody(match.addressFilterParamGroups), compileAddressFilter),
277
295
  handler: handler,
278
296
  contractRegister: contractRegister,
279
297
  paramsRawEventSchema: buildParamsSchema(params),
@@ -393,6 +411,9 @@ export {
393
411
  buildTopicGetter,
394
412
  alwaysIncludedBlockFields,
395
413
  resolveFieldSelection,
414
+ compileAddressFilter,
415
+ buildAddressFilterBody,
416
+ buildAddressFilter,
396
417
  buildEvmEventConfig,
397
418
  buildSvmInstructionEventConfig,
398
419
  buildFuelEventConfig,
@@ -1,18 +1,17 @@
1
- let allChainsEventsProcessedToEndblock = (chainFetchers: ChainMap.t<ChainFetcher.t>) => {
2
- chainFetchers
3
- ->ChainMap.values
4
- ->Array.every(cf => cf->ChainFetcher.hasProcessedToEndblock)
1
+ let allChainsEventsProcessedToEndblock = (chainStates: dict<ChainState.t>) => {
2
+ chainStates
3
+ ->Dict.valuesToArray
4
+ ->Array.every(cs => cs->ChainState.hasProcessedToEndblock)
5
5
  }
6
6
 
7
- let computeChainsState = (chainFetchers: ChainMap.t<ChainFetcher.t>): Internal.chains => {
7
+ let computeChainsState = (chainStates: dict<ChainState.t>): Internal.chains => {
8
8
  let chains = Dict.make()
9
9
 
10
- let isRealtime = chainFetchers->ChainMap.values->Array.every(cf => cf->ChainFetcher.isReady)
10
+ let values = chainStates->Dict.valuesToArray
11
+ let isRealtime = values->Array.every(cs => cs->ChainState.isReady)
11
12
 
12
- chainFetchers
13
- ->ChainMap.keys
14
- ->Array.forEach(chain => {
15
- let chainId = chain->ChainMap.Chain.toChainId
13
+ values->Array.forEach(cs => {
14
+ let chainId = (cs->ChainState.chainConfig).id
16
15
  chains->Dict.set(
17
16
  chainId->Int.toString,
18
17
  {
@@ -31,7 +30,7 @@ let runEventHandlerOrThrow = async (
31
30
  item: Internal.item,
32
31
  ~checkpointId,
33
32
  ~handler,
34
- ~inMemoryStore,
33
+ ~indexerState,
35
34
  ~loadManager,
36
35
  ~persistence,
37
36
  ~chains: Internal.chains,
@@ -46,7 +45,7 @@ let runEventHandlerOrThrow = async (
46
45
  let contextParams: UserContext.contextParams = {
47
46
  item,
48
47
  checkpointId,
49
- inMemoryStore,
48
+ indexerState,
50
49
  loadManager,
51
50
  persistence,
52
51
  isPreload: false,
@@ -57,7 +56,7 @@ let runEventHandlerOrThrow = async (
57
56
  await handler(
58
57
  (
59
58
  {
60
- event: eventItem.event,
59
+ event: item->Ecosystem.getItemEvent(~ecosystem=config.ecosystem),
61
60
  context: UserContext.getHandlerContext(contextParams),
62
61
  }: Internal.handlerArgs
63
62
  ),
@@ -84,9 +83,10 @@ let runEventHandlerOrThrow = async (
84
83
  let runHandlerOrThrow = async (
85
84
  item: Internal.item,
86
85
  ~checkpointId,
87
- ~inMemoryStore,
86
+ ~indexerState,
88
87
  ~loadManager,
89
- ~ctx: Ctx.t,
88
+ ~persistence: Persistence.t,
89
+ ~config: Config.t,
90
90
  ~chains: Internal.chains,
91
91
  ) => {
92
92
  switch item {
@@ -94,19 +94,19 @@ let runHandlerOrThrow = async (
94
94
  try {
95
95
  let contextParams: UserContext.contextParams = {
96
96
  item,
97
- inMemoryStore,
97
+ indexerState,
98
98
  loadManager,
99
- persistence: ctx.persistence,
99
+ persistence,
100
100
  checkpointId,
101
101
  isPreload: false,
102
102
  chains,
103
- config: ctx.config,
103
+ config,
104
104
  isResolved: false,
105
105
  }
106
106
  await handler(
107
107
  Ecosystem.makeOnBlockArgs(
108
108
  ~blockNumber,
109
- ~ecosystem=ctx.config.ecosystem,
109
+ ~ecosystem=config.ecosystem,
110
110
  ~context=UserContext.getHandlerContext(contextParams),
111
111
  ),
112
112
  )
@@ -121,16 +121,17 @@ let runHandlerOrThrow = async (
121
121
  }),
122
122
  )
123
123
  }
124
- | Event({eventConfig}) => switch eventConfig.handler {
124
+ | Event({eventConfig}) =>
125
+ switch eventConfig.handler {
125
126
  | Some(handler) =>
126
127
  await item->runEventHandlerOrThrow(
127
128
  ~handler,
128
129
  ~checkpointId,
129
- ~inMemoryStore,
130
+ ~indexerState,
130
131
  ~loadManager,
131
- ~persistence=ctx.persistence,
132
+ ~persistence,
132
133
  ~chains,
133
- ~config=ctx.config,
134
+ ~config,
134
135
  )
135
136
  | None => ()
136
137
  }
@@ -142,7 +143,7 @@ let preloadBatchOrThrow = async (
142
143
  ~loadManager,
143
144
  ~persistence,
144
145
  ~config: Config.t,
145
- ~inMemoryStore,
146
+ ~indexerState,
146
147
  ~chains: Internal.chains,
147
148
  ) => {
148
149
  // On the first run of loaders, we don't care about the result,
@@ -160,7 +161,7 @@ let preloadBatchOrThrow = async (
160
161
  for idx in 0 to checkpointEventsProcessed - 1 {
161
162
  let item = batch.items->Array.getUnsafe(itemIdx.contents + idx)
162
163
  switch item {
163
- | Event({eventConfig: {handler, contractName, name: eventName}, event}) =>
164
+ | Event({eventConfig: {handler, contractName, name: eventName}}) =>
164
165
  switch handler {
165
166
  | None => ()
166
167
  | Some(handler) =>
@@ -171,10 +172,10 @@ let preloadBatchOrThrow = async (
171
172
  )
172
173
  promises->Array.push(
173
174
  handler({
174
- event,
175
+ event: item->Ecosystem.getItemEvent(~ecosystem=config.ecosystem),
175
176
  context: UserContext.getHandlerContext({
176
177
  item,
177
- inMemoryStore,
178
+ indexerState,
178
179
  loadManager,
179
180
  persistence,
180
181
  checkpointId,
@@ -208,7 +209,7 @@ let preloadBatchOrThrow = async (
208
209
  ~ecosystem=config.ecosystem,
209
210
  ~context=UserContext.getHandlerContext({
210
211
  item,
211
- inMemoryStore,
212
+ indexerState,
212
213
  loadManager,
213
214
  persistence,
214
215
  checkpointId,
@@ -234,9 +235,10 @@ let preloadBatchOrThrow = async (
234
235
 
235
236
  let runBatchHandlersOrThrow = async (
236
237
  batch: Batch.t,
237
- ~inMemoryStore,
238
+ ~indexerState,
238
239
  ~loadManager,
239
- ~ctx,
240
+ ~persistence,
241
+ ~config,
240
242
  ~chains: Internal.chains,
241
243
  ) => {
242
244
  let itemIdx = ref(0)
@@ -248,7 +250,15 @@ let runBatchHandlersOrThrow = async (
248
250
  for idx in 0 to checkpointEventsProcessed - 1 {
249
251
  let item = batch.items->Array.getUnsafe(itemIdx.contents + idx)
250
252
 
251
- await runHandlerOrThrow(item, ~checkpointId, ~inMemoryStore, ~loadManager, ~ctx, ~chains)
253
+ await runHandlerOrThrow(
254
+ item,
255
+ ~checkpointId,
256
+ ~indexerState,
257
+ ~loadManager,
258
+ ~persistence,
259
+ ~config,
260
+ ~chains,
261
+ )
252
262
  }
253
263
  itemIdx := itemIdx.contents + checkpointEventsProcessed
254
264
  }
@@ -273,14 +283,15 @@ type logPartitionInfo = {
273
283
 
274
284
  let processEventBatch = async (
275
285
  ~batch: Batch.t,
276
- ~inMemoryStore: InMemoryStore.t,
286
+ ~indexerState: IndexerState.t,
277
287
  ~loadManager,
278
- ~ctx: Ctx.t,
279
- ~chainFetchers: ChainMap.t<ChainFetcher.t>,
288
+ ~persistence: Persistence.t,
289
+ ~config: Config.t,
290
+ ~chainStates: dict<ChainState.t>,
280
291
  ) => {
281
292
  let totalBatchSize = batch.totalBatchSize
282
293
  // Compute chains state for this batch
283
- let chains: Internal.chains = chainFetchers->computeChainsState
294
+ let chains: Internal.chains = chainStates->computeChainsState
284
295
 
285
296
  let logger = Logging.getLogger()
286
297
  logger->Logging.childTrace({
@@ -296,29 +307,29 @@ let processEventBatch = async (
296
307
 
297
308
  try {
298
309
  // Backpressure: keep processing within keepLatestChangesLimit of the cycle.
299
- await inMemoryStore->InMemoryStore.awaitCapacity
310
+ await indexerState->Writing.awaitCapacity
300
311
 
301
312
  let timeRef = Hrtime.makeTimer()
302
313
 
303
314
  if batch.items->Utils.Array.notEmpty {
304
- await batch->preloadBatchOrThrow(
305
- ~loadManager,
306
- ~persistence=ctx.persistence,
307
- ~inMemoryStore,
308
- ~chains,
309
- ~config=ctx.config,
310
- )
315
+ await batch->preloadBatchOrThrow(~loadManager, ~persistence, ~indexerState, ~chains, ~config)
311
316
  }
312
317
 
313
318
  let elapsedTimeAfterLoaders = timeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
314
319
 
315
320
  if batch.items->Utils.Array.notEmpty {
316
- await batch->runBatchHandlersOrThrow(~inMemoryStore, ~loadManager, ~ctx, ~chains)
321
+ await batch->runBatchHandlersOrThrow(
322
+ ~indexerState,
323
+ ~loadManager,
324
+ ~persistence,
325
+ ~config,
326
+ ~chains,
327
+ )
317
328
  }
318
329
 
319
330
  let elapsedTimeAfterProcessing = timeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
320
331
 
321
- inMemoryStore->InMemoryStore.commitBatch(~batch)
332
+ indexerState->Writing.commitBatch(~batch)
322
333
 
323
334
  let loaderDuration = elapsedTimeAfterLoaders
324
335
  let handlerDuration = elapsedTimeAfterProcessing -. loaderDuration
@@ -329,7 +340,10 @@ let processEventBatch = async (
329
340
  reason->ErrorHandling.make(~msg=message, ~logger)->Error
330
341
  | ProcessingError({message, exn, item}) =>
331
342
  exn
332
- ->ErrorHandling.make(~msg=message, ~logger=item->Logging.getItemLogger)
343
+ ->ErrorHandling.make(
344
+ ~msg=message,
345
+ ~logger=Ecosystem.getItemLogger(item, ~ecosystem=config.ecosystem),
346
+ )
333
347
  ->Error
334
348
  | exn => exn->ErrorHandling.make(~msg="Failed processing batch", ~logger)->Error
335
349
  }