envio 3.2.1 → 3.3.0-alpha.1

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 (106) 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 +373 -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 +643 -0
  11. package/src/ChainState.res.mjs +476 -0
  12. package/src/ChainState.resi +87 -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 +294 -0
  19. package/src/CrossChainState.res.mjs +221 -0
  20. package/src/CrossChainState.resi +39 -0
  21. package/src/Ecosystem.res +58 -0
  22. package/src/Ecosystem.res.mjs +43 -1
  23. package/src/Env.res +0 -2
  24. package/src/Env.res.mjs +0 -3
  25. package/src/EventConfigBuilder.res +2 -2
  26. package/src/EventProcessing.res +60 -46
  27. package/src/EventProcessing.res.mjs +33 -32
  28. package/src/EventUtils.res +0 -4
  29. package/src/EventUtils.res.mjs +0 -4
  30. package/src/ExitOnCaughtUp.res +10 -0
  31. package/src/ExitOnCaughtUp.res.mjs +22 -0
  32. package/src/FetchState.res +205 -73
  33. package/src/FetchState.res.mjs +242 -103
  34. package/src/InMemoryStore.res +36 -451
  35. package/src/InMemoryStore.res.mjs +20 -369
  36. package/src/IndexerLoop.res +43 -0
  37. package/src/IndexerLoop.res.mjs +46 -0
  38. package/src/IndexerState.res +536 -0
  39. package/src/IndexerState.res.mjs +543 -0
  40. package/src/IndexerState.resi +128 -0
  41. package/src/Internal.res +29 -8
  42. package/src/LoadLayer.res +20 -18
  43. package/src/LoadLayer.res.mjs +14 -12
  44. package/src/LoadLayer.resi +6 -3
  45. package/src/Logging.res +11 -44
  46. package/src/Logging.res.mjs +10 -42
  47. package/src/Main.res +54 -79
  48. package/src/Main.res.mjs +44 -56
  49. package/src/PgStorage.res +8 -71
  50. package/src/PgStorage.res.mjs +3 -47
  51. package/src/Prometheus.res +1 -13
  52. package/src/Prometheus.res.mjs +84 -96
  53. package/src/PruneStaleHistory.res +45 -0
  54. package/src/PruneStaleHistory.res.mjs +46 -0
  55. package/src/RawEvent.res +73 -0
  56. package/src/RawEvent.res.mjs +51 -0
  57. package/src/Rollback.res +204 -0
  58. package/src/Rollback.res.mjs +118 -0
  59. package/src/SimulateItems.res +12 -10
  60. package/src/SimulateItems.res.mjs +1 -1
  61. package/src/UserContext.res +26 -114
  62. package/src/UserContext.res.mjs +15 -78
  63. package/src/Writing.res +242 -0
  64. package/src/Writing.res.mjs +215 -0
  65. package/src/db/InternalTable.res +14 -27
  66. package/src/sources/Evm.res +40 -1
  67. package/src/sources/Evm.res.mjs +94 -84
  68. package/src/sources/Fuel.res +40 -1
  69. package/src/sources/Fuel.res.mjs +36 -26
  70. package/src/sources/HyperFuel.res +41 -120
  71. package/src/sources/HyperFuel.res.mjs +42 -80
  72. package/src/sources/HyperFuel.resi +1 -24
  73. package/src/sources/HyperFuelClient.res +16 -297
  74. package/src/sources/HyperFuelClient.res.mjs +5 -4
  75. package/src/sources/HyperFuelSource.res +33 -8
  76. package/src/sources/HyperFuelSource.res.mjs +56 -10
  77. package/src/sources/HyperSyncSource.res +5 -3
  78. package/src/sources/HyperSyncSource.res.mjs +1 -1
  79. package/src/sources/RpcSource.res +2 -2
  80. package/src/sources/RpcSource.res.mjs +1 -1
  81. package/src/sources/SourceManager.res +14 -23
  82. package/src/sources/SourceManager.res.mjs +27 -29
  83. package/src/sources/SourceManager.resi +4 -2
  84. package/src/sources/Svm.res +18 -1
  85. package/src/sources/Svm.res.mjs +30 -22
  86. package/src/sources/SvmHyperSyncSource.res +1 -1
  87. package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
  88. package/src/tui/Tui.res +38 -36
  89. package/src/tui/Tui.res.mjs +51 -51
  90. package/src/ChainFetcher.res +0 -519
  91. package/src/ChainFetcher.res.mjs +0 -314
  92. package/src/ChainManager.res +0 -358
  93. package/src/ChainManager.res.mjs +0 -291
  94. package/src/Ctx.res +0 -6
  95. package/src/Ctx.res.mjs +0 -2
  96. package/src/GlobalState.res +0 -1056
  97. package/src/GlobalState.res.mjs +0 -1086
  98. package/src/GlobalStateManager.res +0 -57
  99. package/src/GlobalStateManager.res.mjs +0 -68
  100. package/src/GlobalStateManager.resi +0 -7
  101. package/src/Ports.res +0 -5
  102. package/src/Ports.res.mjs +0 -9
  103. package/src/adapters/MarkBatchProcessedAdapter.res +0 -5
  104. package/src/adapters/MarkBatchProcessedAdapter.res.mjs +0 -14
  105. package/src/sources/EnvioApiClient.res +0 -15
  106. package/src/sources/EnvioApiClient.res.mjs +0 -24
@@ -0,0 +1,221 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Env from "./Env.res.mjs";
4
+ import * as Batch from "./Batch.res.mjs";
5
+ import * as Utils from "./Utils.res.mjs";
6
+ import * as Logging from "./Logging.res.mjs";
7
+ import * as ChainMap from "./ChainMap.res.mjs";
8
+ import * as ChainState from "./ChainState.res.mjs";
9
+ import * as FetchState from "./FetchState.res.mjs";
10
+ import * as Prometheus from "./Prometheus.res.mjs";
11
+ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
12
+ import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
13
+ import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
14
+ import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
15
+ import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
16
+
17
+ function calculateTargetBufferSize() {
18
+ if (Env.targetBufferSize !== undefined) {
19
+ return Env.targetBufferSize;
20
+ } else {
21
+ return 100000;
22
+ }
23
+ }
24
+
25
+ function make(chainStates, isInReorgThreshold, isRealtime, targetBufferSizeOpt) {
26
+ let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : (
27
+ Env.targetBufferSize !== undefined ? Env.targetBufferSize : 100000
28
+ );
29
+ let crossChainState = {
30
+ chainStates: chainStates,
31
+ chainIds: Object.values(chainStates).map(cs => ChainState.chainConfig(cs).id),
32
+ isRealtime: isRealtime,
33
+ isInReorgThreshold: isInReorgThreshold,
34
+ targetBufferSize: targetBufferSize
35
+ };
36
+ Prometheus.IndexingTargetBufferSize.set(targetBufferSize);
37
+ return crossChainState;
38
+ }
39
+
40
+ function chainStates(crossChainState) {
41
+ return crossChainState.chainStates;
42
+ }
43
+
44
+ function isRealtime(crossChainState) {
45
+ return crossChainState.isRealtime;
46
+ }
47
+
48
+ function isInReorgThreshold(crossChainState) {
49
+ return crossChainState.isInReorgThreshold;
50
+ }
51
+
52
+ function totalReadyCount(crossChainState) {
53
+ let total = 0;
54
+ for (let i = 0, i_finish = crossChainState.chainIds.length; i < i_finish; ++i) {
55
+ let cs = crossChainState.chainStates[crossChainState.chainIds[i]];
56
+ total = total + FetchState.bufferReadyCount(ChainState.fetchState(cs)) | 0;
57
+ }
58
+ return total;
59
+ }
60
+
61
+ function nextItemIsNone(crossChainState) {
62
+ return !Batch.hasReadyItem(Object.values(crossChainState.chainStates).map(ChainState.fetchState));
63
+ }
64
+
65
+ function getSafeCheckpointId(crossChainState) {
66
+ let result;
67
+ for (let i = 0, i_finish = crossChainState.chainIds.length; i < i_finish; ++i) {
68
+ let cs = crossChainState.chainStates[crossChainState.chainIds[i]];
69
+ let safeCheckpointTracking = ChainState.safeCheckpointTracking(cs);
70
+ if (safeCheckpointTracking !== undefined) {
71
+ let safeCheckpointId = SafeCheckpointTracking.getSafeCheckpointId(safeCheckpointTracking, ChainState.fetchState(cs).knownHeight);
72
+ let current = result;
73
+ if (!(current !== undefined && safeCheckpointId >= current)) {
74
+ result = safeCheckpointId;
75
+ }
76
+ }
77
+ }
78
+ let id = result;
79
+ if (id !== undefined && id > 0n) {
80
+ return id;
81
+ }
82
+ }
83
+
84
+ function createBatch(crossChainState, processedCheckpointId, batchSizeTarget, isRollback) {
85
+ return Batch.make(processedCheckpointId + (
86
+ isRollback ? 1n : 0n
87
+ ), Utils.Dict.mapValues(crossChainState.chainStates, cs => ({
88
+ fetchState: ChainState.fetchState(cs),
89
+ reorgDetection: ChainState.reorgDetection(cs),
90
+ progressBlockNumber: ChainState.committedProgressBlockNumber(cs),
91
+ sourceBlockNumber: ChainState.fetchState(cs).knownHeight,
92
+ totalEventsProcessed: ChainState.numEventsProcessed(cs),
93
+ chainConfig: ChainState.chainConfig(cs)
94
+ })), batchSizeTarget, crossChainState.isInReorgThreshold);
95
+ }
96
+
97
+ function enterReorgThreshold(crossChainState) {
98
+ Logging.info("Reorg threshold reached");
99
+ Prometheus.ReorgThreshold.set(true);
100
+ for (let i = 0, i_finish = crossChainState.chainIds.length; i < i_finish; ++i) {
101
+ ChainState.enterReorgThreshold(crossChainState.chainStates[crossChainState.chainIds[i]]);
102
+ }
103
+ crossChainState.isInReorgThreshold = true;
104
+ }
105
+
106
+ function applyBatchProgress(crossChainState, batch) {
107
+ let chainIds = crossChainState.chainIds;
108
+ let everyChainCaughtUp = true;
109
+ for (let i = 0, i_finish = chainIds.length; i < i_finish; ++i) {
110
+ let cs = crossChainState.chainStates[chainIds[i]];
111
+ ChainState.applyBatchProgress(cs, batch);
112
+ if (!(ChainState.hasProcessedToEndblock(cs) || ChainState.isProgressAtHead(cs))) {
113
+ everyChainCaughtUp = false;
114
+ }
115
+ }
116
+ let indexerCaughtUp = nextItemIsNone(crossChainState) && everyChainCaughtUp;
117
+ let allChainsReady = true;
118
+ for (let i$1 = 0, i_finish$1 = chainIds.length; i$1 < i_finish$1; ++i$1) {
119
+ let cs$1 = crossChainState.chainStates[chainIds[i$1]];
120
+ if (indexerCaughtUp) {
121
+ ChainState.markReady(cs$1);
122
+ }
123
+ if (!ChainState.isReady(cs$1)) {
124
+ allChainsReady = false;
125
+ }
126
+ }
127
+ if (allChainsReady) {
128
+ Prometheus.ProgressReady.setAllReady();
129
+ }
130
+ crossChainState.isRealtime = crossChainState.isRealtime || allChainsReady;
131
+ }
132
+
133
+ function priorityOrder(crossChainState) {
134
+ return Object.values(crossChainState.chainStates).toSorted((a, b) => Primitive_float.compare(FetchState.getProgressPercentage(ChainState.fetchState(a)), FetchState.getProgressPercentage(ChainState.fetchState(b))));
135
+ }
136
+
137
+ function totalReservedSize(crossChainState) {
138
+ let total = 0;
139
+ for (let i = 0, i_finish = crossChainState.chainIds.length; i < i_finish; ++i) {
140
+ let cs = crossChainState.chainStates[crossChainState.chainIds[i]];
141
+ total = total + ChainState.pendingBudget(cs);
142
+ }
143
+ return total;
144
+ }
145
+
146
+ function compareByProgress(a, b) {
147
+ return Primitive_float.compare(a.progress, b.progress);
148
+ }
149
+
150
+ async function checkAndFetch(crossChainState, dispatchChain) {
151
+ let remaining = Primitive_int.max(0, (crossChainState.targetBufferSize - totalReadyCount(crossChainState) | 0) - (totalReservedSize(crossChainState) | 0) | 0);
152
+ let chainIds = crossChainState.chainIds;
153
+ let actionByChain = {};
154
+ let candidates = [];
155
+ for (let i = 0, i_finish = chainIds.length; i < i_finish; ++i) {
156
+ let chainId = chainIds[i];
157
+ let cs = crossChainState.chainStates[chainId];
158
+ let fetchState = ChainState.fetchState(cs);
159
+ let action = FetchState.getNextQuery(fetchState, remaining, ChainState.pendingBudget(cs));
160
+ if (typeof action !== "object") {
161
+ actionByChain[chainId] = action;
162
+ } else {
163
+ actionByChain[chainId] = "NothingToQuery";
164
+ action._0.forEach(query => {
165
+ query.chainId = chainId;
166
+ query.progress = FetchState.getProgressPercentageAt(fetchState, query.fromBlock);
167
+ candidates.push(query);
168
+ });
169
+ }
170
+ }
171
+ candidates.sort(compareByProgress);
172
+ let admittedByChain = {};
173
+ let running = 0;
174
+ let idx = 0;
175
+ while (running < remaining && idx < candidates.length) {
176
+ let query = candidates[idx];
177
+ Utils.Dict.push(admittedByChain, query.chainId.toString(), query);
178
+ running = running + query.estResponseSize;
179
+ idx = idx + 1 | 0;
180
+ };
181
+ Stdlib_Dict.forEachWithKey(admittedByChain, (queries, chainId) => {
182
+ actionByChain[chainId] = {
183
+ TAG: "Ready",
184
+ _0: queries
185
+ };
186
+ let chainId$1 = Stdlib_Int.fromString(chainId, undefined);
187
+ ChainState.startFetchingQueries(crossChainState.chainStates[chainId$1], queries);
188
+ });
189
+ let promises = [];
190
+ for (let i$1 = 0, i_finish$1 = chainIds.length; i$1 < i_finish$1; ++i$1) {
191
+ let chainId$1 = chainIds[i$1];
192
+ let action$1 = actionByChain[chainId$1];
193
+ if (action$1 !== undefined) {
194
+ let exit = 0;
195
+ if (typeof action$1 === "object" || action$1 === "WaitingForNewBlock") {
196
+ exit = 1;
197
+ }
198
+ if (exit === 1) {
199
+ let chain = ChainMap.Chain.makeUnsafe(chainId$1);
200
+ promises.push(dispatchChain(chain, action$1));
201
+ }
202
+ }
203
+ }
204
+ await Promise.all(promises);
205
+ }
206
+
207
+ export {
208
+ calculateTargetBufferSize,
209
+ make,
210
+ chainStates,
211
+ isRealtime,
212
+ isInReorgThreshold,
213
+ nextItemIsNone,
214
+ getSafeCheckpointId,
215
+ createBatch,
216
+ enterReorgThreshold,
217
+ applyBatchProgress,
218
+ priorityOrder,
219
+ checkAndFetch,
220
+ }
221
+ /* Env Not a pure module */
@@ -0,0 +1,39 @@
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
+ ~targetBufferSize: int=?,
13
+ ) => t
14
+
15
+ // Accessors.
16
+ let chainStates: t => dict<ChainState.t>
17
+ let isRealtime: t => bool
18
+ let isInReorgThreshold: t => bool
19
+
20
+ // Derived (pure).
21
+ let nextItemIsNone: t => bool
22
+ let getSafeCheckpointId: t => option<Internal.checkpointId>
23
+
24
+ // Cross-chain transitions.
25
+ let createBatch: (
26
+ t,
27
+ ~processedCheckpointId: Internal.checkpointId,
28
+ ~batchSizeTarget: int,
29
+ ~isRollback: bool,
30
+ ) => Batch.t
31
+ let enterReorgThreshold: t => unit
32
+ let applyBatchProgress: (t, ~batch: Batch.t) => unit
33
+
34
+ // Fetch control.
35
+ let priorityOrder: t => array<ChainState.t>
36
+ let checkAndFetch: (
37
+ t,
38
+ ~dispatchChain: (~chain: ChainMap.Chain.t, ~action: FetchState.nextQuery) => promise<unit>,
39
+ ) => 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,6 @@ 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)
13
11
 
14
12
  // Target number of in-memory objects (uncommitted entity/effect changes plus
15
13
  // unwritten batch items) the store holds before processing waits for the write
package/src/Env.res.mjs CHANGED
@@ -19,8 +19,6 @@ 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);
23
-
24
22
  let inMemoryObjectsTarget = EnvSafe.get(envSafe, "ENVIO_IN_MEMORY_OBJECTS_TARGET", S$RescriptSchema.int, undefined, 100000, undefined, undefined);
25
23
 
26
24
  let serverPort = EnvSafe.get(envSafe, "ENVIO_INDEXER_PORT", S$RescriptSchema.port(S$RescriptSchema.int, undefined), undefined, EnvSafe.get(envSafe, "METRICS_PORT", S$RescriptSchema.port(S$RescriptSchema.int, undefined), undefined, 9898, undefined, undefined), undefined, undefined);
@@ -222,7 +220,6 @@ export {
222
220
  updateSyncTimeOnRestart,
223
221
  targetBufferSize,
224
222
  maxAddrInPartition,
225
- maxPartitionConcurrency,
226
223
  inMemoryObjectsTarget,
227
224
  serverPort,
228
225
  tuiEnvVar,
@@ -312,7 +312,7 @@ let resolveFieldSelection = (
312
312
  // ============== Client-side address filter ==============
313
313
 
314
314
  let compileAddressFilter: string => (
315
- Internal.event,
315
+ Internal.eventPayload,
316
316
  int,
317
317
  dict<Internal.indexingContract>,
318
318
  ) => bool = %raw(`function (body) {
@@ -339,7 +339,7 @@ let buildAddressFilterBody = (groups: array<array<string>>): option<string> => {
339
339
  }
340
340
 
341
341
  let buildAddressFilter = (groups: array<array<string>>): option<
342
- (Internal.event, int, dict<Internal.indexingContract>) => bool,
342
+ (Internal.eventPayload, int, dict<Internal.indexingContract>) => bool,
343
343
  > => buildAddressFilterBody(groups)->Option.map(compileAddressFilter)
344
344
 
345
345
  // ============== Build complete EVM event config ==============
@@ -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
  }