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.
- package/package.json +6 -7
- package/src/Batch.res +12 -15
- package/src/Batch.res.mjs +4 -5
- package/src/BatchProcessing.res +199 -0
- package/src/BatchProcessing.res.mjs +125 -0
- package/src/ChainFetching.res +373 -0
- package/src/ChainFetching.res.mjs +206 -0
- package/src/ChainMetadata.res +27 -0
- package/src/ChainMetadata.res.mjs +27 -0
- package/src/ChainState.res +643 -0
- package/src/ChainState.res.mjs +476 -0
- package/src/ChainState.resi +87 -0
- package/src/Config.res +13 -4
- package/src/Config.res.mjs +8 -3
- package/src/ContractRegisterContext.res +106 -0
- package/src/ContractRegisterContext.res.mjs +76 -0
- package/src/Core.res +3 -0
- package/src/CrossChainState.res +294 -0
- package/src/CrossChainState.res.mjs +221 -0
- package/src/CrossChainState.resi +39 -0
- package/src/Ecosystem.res +58 -0
- package/src/Ecosystem.res.mjs +43 -1
- package/src/Env.res +0 -2
- package/src/Env.res.mjs +0 -3
- package/src/EventConfigBuilder.res +2 -2
- package/src/EventProcessing.res +60 -46
- package/src/EventProcessing.res.mjs +33 -32
- package/src/EventUtils.res +0 -4
- package/src/EventUtils.res.mjs +0 -4
- package/src/ExitOnCaughtUp.res +10 -0
- package/src/ExitOnCaughtUp.res.mjs +22 -0
- package/src/FetchState.res +205 -73
- package/src/FetchState.res.mjs +242 -103
- package/src/InMemoryStore.res +36 -451
- package/src/InMemoryStore.res.mjs +20 -369
- package/src/IndexerLoop.res +43 -0
- package/src/IndexerLoop.res.mjs +46 -0
- package/src/IndexerState.res +536 -0
- package/src/IndexerState.res.mjs +543 -0
- package/src/IndexerState.resi +128 -0
- package/src/Internal.res +29 -8
- package/src/LoadLayer.res +20 -18
- package/src/LoadLayer.res.mjs +14 -12
- package/src/LoadLayer.resi +6 -3
- package/src/Logging.res +11 -44
- package/src/Logging.res.mjs +10 -42
- package/src/Main.res +54 -79
- package/src/Main.res.mjs +44 -56
- package/src/PgStorage.res +8 -71
- package/src/PgStorage.res.mjs +3 -47
- package/src/Prometheus.res +1 -13
- package/src/Prometheus.res.mjs +84 -96
- package/src/PruneStaleHistory.res +45 -0
- package/src/PruneStaleHistory.res.mjs +46 -0
- package/src/RawEvent.res +73 -0
- package/src/RawEvent.res.mjs +51 -0
- package/src/Rollback.res +204 -0
- package/src/Rollback.res.mjs +118 -0
- package/src/SimulateItems.res +12 -10
- package/src/SimulateItems.res.mjs +1 -1
- package/src/UserContext.res +26 -114
- package/src/UserContext.res.mjs +15 -78
- package/src/Writing.res +242 -0
- package/src/Writing.res.mjs +215 -0
- package/src/db/InternalTable.res +14 -27
- package/src/sources/Evm.res +40 -1
- package/src/sources/Evm.res.mjs +94 -84
- package/src/sources/Fuel.res +40 -1
- package/src/sources/Fuel.res.mjs +36 -26
- package/src/sources/HyperFuel.res +41 -120
- package/src/sources/HyperFuel.res.mjs +42 -80
- package/src/sources/HyperFuel.resi +1 -24
- package/src/sources/HyperFuelClient.res +16 -297
- package/src/sources/HyperFuelClient.res.mjs +5 -4
- package/src/sources/HyperFuelSource.res +33 -8
- package/src/sources/HyperFuelSource.res.mjs +56 -10
- package/src/sources/HyperSyncSource.res +5 -3
- package/src/sources/HyperSyncSource.res.mjs +1 -1
- package/src/sources/RpcSource.res +2 -2
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SourceManager.res +14 -23
- package/src/sources/SourceManager.res.mjs +27 -29
- package/src/sources/SourceManager.resi +4 -2
- package/src/sources/Svm.res +18 -1
- package/src/sources/Svm.res.mjs +30 -22
- package/src/sources/SvmHyperSyncSource.res +1 -1
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
- package/src/tui/Tui.res +38 -36
- package/src/tui/Tui.res.mjs +51 -51
- package/src/ChainFetcher.res +0 -519
- package/src/ChainFetcher.res.mjs +0 -314
- package/src/ChainManager.res +0 -358
- package/src/ChainManager.res.mjs +0 -291
- package/src/Ctx.res +0 -6
- package/src/Ctx.res.mjs +0 -2
- package/src/GlobalState.res +0 -1056
- package/src/GlobalState.res.mjs +0 -1086
- package/src/GlobalStateManager.res +0 -57
- package/src/GlobalStateManager.res.mjs +0 -68
- package/src/GlobalStateManager.resi +0 -7
- package/src/Ports.res +0 -5
- package/src/Ports.res.mjs +0 -9
- package/src/adapters/MarkBatchProcessedAdapter.res +0 -5
- package/src/adapters/MarkBatchProcessedAdapter.res.mjs +0 -14
- package/src/sources/EnvioApiClient.res +0 -15
- package/src/sources/EnvioApiClient.res.mjs +0 -24
package/src/tui/Tui.res
CHANGED
|
@@ -134,11 +134,11 @@ module App = {
|
|
|
134
134
|
@react.component
|
|
135
135
|
let make = (~getState) => {
|
|
136
136
|
let stdoutColumns = Hooks.useStdoutColumns()
|
|
137
|
-
//
|
|
137
|
+
// IndexerState is mutated in place — passing the same ref to useState
|
|
138
138
|
// would bail out via Object.is and skip the re-render. Tick a counter
|
|
139
139
|
// instead and read state freshly from getState() on every render.
|
|
140
140
|
let (tick, setTick) = React.useState(() => 0)
|
|
141
|
-
let state:
|
|
141
|
+
let state: IndexerState.t = getState()
|
|
142
142
|
|
|
143
143
|
React.useEffect(() => {
|
|
144
144
|
let intervalId = setInterval(() => {
|
|
@@ -153,18 +153,22 @@ module App = {
|
|
|
153
153
|
}, [getState])
|
|
154
154
|
|
|
155
155
|
let chains =
|
|
156
|
-
state
|
|
157
|
-
->
|
|
158
|
-
->
|
|
159
|
-
|
|
156
|
+
state
|
|
157
|
+
->IndexerState.chainStates
|
|
158
|
+
->Dict.valuesToArray
|
|
159
|
+
->Array.map(cs => {
|
|
160
|
+
let numEventsProcessed = cs->ChainState.numEventsProcessed
|
|
161
|
+
let fetchState = cs->ChainState.fetchState
|
|
162
|
+
let committedProgressBlockNumber = cs->ChainState.committedProgressBlockNumber
|
|
163
|
+
let timestampCaughtUpToHeadOrEndblock = cs->ChainState.timestampCaughtUpToHeadOrEndblock
|
|
164
|
+
let sourceManager = cs->ChainState.sourceManager
|
|
160
165
|
let latestFetchedBlockNumber = Pervasives.max(fetchState->FetchState.bufferBlockNumber, 0)
|
|
161
|
-
let hasProcessedToEndblock =
|
|
162
|
-
let knownHeight =
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
: cf.fetchState.knownHeight
|
|
166
|
+
let hasProcessedToEndblock = cs->ChainState.hasProcessedToEndblock
|
|
167
|
+
let knownHeight = hasProcessedToEndblock
|
|
168
|
+
? fetchState.endBlock->Option.getOr(fetchState.knownHeight)
|
|
169
|
+
: fetchState.knownHeight
|
|
166
170
|
|
|
167
|
-
let firstEventBlock =
|
|
171
|
+
let firstEventBlock = fetchState.firstEventBlock
|
|
168
172
|
let progress: TuiData.progress = if hasProcessedToEndblock {
|
|
169
173
|
// If the endblock has been reached then set the progress to synced.
|
|
170
174
|
// if there's chains that have no events in the block range start->end,
|
|
@@ -172,25 +176,25 @@ module App = {
|
|
|
172
176
|
// This ensures TUI still displays synced in this case
|
|
173
177
|
Synced({
|
|
174
178
|
firstEventBlockNumber: firstEventBlock->Option.getOr(0),
|
|
175
|
-
latestProcessedBlock:
|
|
176
|
-
timestampCaughtUpToHeadOrEndblock:
|
|
179
|
+
latestProcessedBlock: committedProgressBlockNumber,
|
|
180
|
+
timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock->Option.getOr(
|
|
177
181
|
Date.now()->Date.fromTime,
|
|
178
182
|
),
|
|
179
183
|
numEventsProcessed,
|
|
180
184
|
})
|
|
181
185
|
} else {
|
|
182
|
-
switch (firstEventBlock,
|
|
186
|
+
switch (firstEventBlock, timestampCaughtUpToHeadOrEndblock) {
|
|
183
187
|
| (Some(firstEventBlockNumber), Some(timestampCaughtUpToHeadOrEndblock)) =>
|
|
184
188
|
Synced({
|
|
185
189
|
firstEventBlockNumber,
|
|
186
|
-
latestProcessedBlock:
|
|
190
|
+
latestProcessedBlock: committedProgressBlockNumber,
|
|
187
191
|
timestampCaughtUpToHeadOrEndblock,
|
|
188
192
|
numEventsProcessed,
|
|
189
193
|
})
|
|
190
194
|
| (Some(firstEventBlockNumber), None) =>
|
|
191
195
|
Syncing({
|
|
192
196
|
firstEventBlockNumber,
|
|
193
|
-
latestProcessedBlock:
|
|
197
|
+
latestProcessedBlock: committedProgressBlockNumber,
|
|
194
198
|
numEventsProcessed,
|
|
195
199
|
})
|
|
196
200
|
| (None, _) => SearchingForEvents
|
|
@@ -203,25 +207,23 @@ module App = {
|
|
|
203
207
|
knownHeight,
|
|
204
208
|
latestFetchedBlockNumber,
|
|
205
209
|
eventsProcessed: numEventsProcessed,
|
|
206
|
-
chainId:
|
|
207
|
-
progressBlock:
|
|
208
|
-
? Some(
|
|
209
|
-
: Some(
|
|
210
|
+
chainId: (cs->ChainState.chainConfig).id->Int.toString,
|
|
211
|
+
progressBlock: committedProgressBlockNumber < fetchState.startBlock
|
|
212
|
+
? Some(fetchState.startBlock)
|
|
213
|
+
: Some(committedProgressBlockNumber),
|
|
210
214
|
bufferBlock: Some(latestFetchedBlockNumber),
|
|
211
|
-
sourceBlock: Some(
|
|
212
|
-
firstEventBlockNumber:
|
|
213
|
-
startBlock:
|
|
214
|
-
endBlock:
|
|
215
|
-
poweredByHyperSync: (
|
|
216
|
-
|
|
217
|
-
).poweredByHyperSync,
|
|
218
|
-
blockUnit: switch state.ctx.config.ecosystem.name {
|
|
215
|
+
sourceBlock: Some(fetchState.knownHeight),
|
|
216
|
+
firstEventBlockNumber: fetchState.firstEventBlock,
|
|
217
|
+
startBlock: fetchState.startBlock,
|
|
218
|
+
endBlock: fetchState.endBlock,
|
|
219
|
+
poweredByHyperSync: (sourceManager->SourceManager.getActiveSource).poweredByHyperSync,
|
|
220
|
+
blockUnit: switch (state->IndexerState.config).ecosystem.name {
|
|
219
221
|
| Svm => "Slot"
|
|
220
222
|
| Evm | Fuel => "Block"
|
|
221
223
|
},
|
|
222
|
-
rateLimitTimeMs:
|
|
223
|
-
isRateLimited:
|
|
224
|
-
rateLimitResetInMs:
|
|
224
|
+
rateLimitTimeMs: sourceManager->SourceManager.getRateLimitTimeMs,
|
|
225
|
+
isRateLimited: sourceManager->SourceManager.isRateLimited,
|
|
226
|
+
rateLimitResetInMs: sourceManager->SourceManager.getRateLimitResetInMs,
|
|
225
227
|
}: TuiData.chain
|
|
226
228
|
)
|
|
227
229
|
})
|
|
@@ -269,7 +271,7 @@ module App = {
|
|
|
269
271
|
totalEventsProcessed
|
|
270
272
|
eventsPerSecond={SyncETA.isIndexerFullySynced(chains) ? None : eventsPerSecond}
|
|
271
273
|
/>
|
|
272
|
-
<SyncETA chains indexerStartTime=state.indexerStartTime />
|
|
274
|
+
<SyncETA chains indexerStartTime={state->IndexerState.indexerStartTime} />
|
|
273
275
|
{
|
|
274
276
|
let maxRateLimitTimeMs =
|
|
275
277
|
chains->Array.reduce(0., (acc, chain) => Pervasives.max(acc, chain.rateLimitTimeMs))
|
|
@@ -315,7 +317,7 @@ module App = {
|
|
|
315
317
|
}
|
|
316
318
|
}
|
|
317
319
|
</Box>
|
|
318
|
-
{if state.
|
|
320
|
+
{if (state->IndexerState.config).isDev {
|
|
319
321
|
<Box flexDirection={Row}>
|
|
320
322
|
<Text> {"Dev Console: "->React.string} </Text>
|
|
321
323
|
<Text color={Info} underline=true> {`${Env.envioAppUrl}/console`->React.string} </Text>
|
|
@@ -323,7 +325,7 @@ module App = {
|
|
|
323
325
|
} else {
|
|
324
326
|
React.null
|
|
325
327
|
}}
|
|
326
|
-
{switch (state.
|
|
328
|
+
{switch ((state->IndexerState.config).storage.clickhouse, Env.ClickHouse.host()) {
|
|
327
329
|
| (true, Some(host)) =>
|
|
328
330
|
<Box flexDirection={Row}>
|
|
329
331
|
<Text> {"ClickHouse: "->React.string} </Text>
|
|
@@ -331,7 +333,7 @@ module App = {
|
|
|
331
333
|
</Box>
|
|
332
334
|
| _ => React.null
|
|
333
335
|
}}
|
|
334
|
-
<Messages config=state.
|
|
336
|
+
<Messages config={state->IndexerState.config} />
|
|
335
337
|
</Box>
|
|
336
338
|
}
|
|
337
339
|
}
|
package/src/tui/Tui.res.mjs
CHANGED
|
@@ -6,10 +6,10 @@ import * as Ink$1 from "ink";
|
|
|
6
6
|
import * as React from "react";
|
|
7
7
|
import * as SyncETA from "./components/SyncETA.res.mjs";
|
|
8
8
|
import * as TuiData from "./components/TuiData.res.mjs";
|
|
9
|
-
import * as ChainMap from "../ChainMap.res.mjs";
|
|
10
9
|
import * as Messages from "./components/Messages.res.mjs";
|
|
10
|
+
import * as ChainState from "../ChainState.res.mjs";
|
|
11
11
|
import * as FetchState from "../FetchState.res.mjs";
|
|
12
|
-
import * as
|
|
12
|
+
import * as IndexerState from "../IndexerState.res.mjs";
|
|
13
13
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
14
14
|
import InkBigText from "ink-big-text";
|
|
15
15
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
@@ -207,47 +207,47 @@ function Tui$App(props) {
|
|
|
207
207
|
clearInterval(intervalId);
|
|
208
208
|
};
|
|
209
209
|
}, [getState]);
|
|
210
|
-
let chains =
|
|
211
|
-
let numEventsProcessed =
|
|
212
|
-
let
|
|
213
|
-
let
|
|
214
|
-
let
|
|
215
|
-
let
|
|
216
|
-
let
|
|
217
|
-
|
|
218
|
-
|
|
210
|
+
let chains = Object.values(IndexerState.chainStates(state)).map(cs => {
|
|
211
|
+
let numEventsProcessed = ChainState.numEventsProcessed(cs);
|
|
212
|
+
let fetchState = ChainState.fetchState(cs);
|
|
213
|
+
let committedProgressBlockNumber = ChainState.committedProgressBlockNumber(cs);
|
|
214
|
+
let timestampCaughtUpToHeadOrEndblock = ChainState.timestampCaughtUpToHeadOrEndblock(cs);
|
|
215
|
+
let sourceManager = ChainState.sourceManager(cs);
|
|
216
|
+
let latestFetchedBlockNumber = Primitive_int.max(FetchState.bufferBlockNumber(fetchState), 0);
|
|
217
|
+
let hasProcessedToEndblock = ChainState.hasProcessedToEndblock(cs);
|
|
218
|
+
let knownHeight = hasProcessedToEndblock ? Stdlib_Option.getOr(fetchState.endBlock, fetchState.knownHeight) : fetchState.knownHeight;
|
|
219
|
+
let firstEventBlock = fetchState.firstEventBlock;
|
|
220
|
+
let progress = hasProcessedToEndblock ? ({
|
|
219
221
|
TAG: "Synced",
|
|
220
222
|
_0: {
|
|
221
223
|
firstEventBlockNumber: Stdlib_Option.getOr(firstEventBlock, 0),
|
|
222
|
-
latestProcessedBlock:
|
|
224
|
+
latestProcessedBlock: committedProgressBlockNumber,
|
|
223
225
|
numEventsProcessed: numEventsProcessed,
|
|
224
|
-
timestampCaughtUpToHeadOrEndblock: Stdlib_Option.getOr(
|
|
226
|
+
timestampCaughtUpToHeadOrEndblock: Stdlib_Option.getOr(timestampCaughtUpToHeadOrEndblock, new Date(Date.now()))
|
|
225
227
|
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
}
|
|
248
|
-
let match$1 = state.ctx.config.ecosystem.name;
|
|
228
|
+
}) : (
|
|
229
|
+
firstEventBlock !== undefined ? (
|
|
230
|
+
timestampCaughtUpToHeadOrEndblock !== undefined ? ({
|
|
231
|
+
TAG: "Synced",
|
|
232
|
+
_0: {
|
|
233
|
+
firstEventBlockNumber: firstEventBlock,
|
|
234
|
+
latestProcessedBlock: committedProgressBlockNumber,
|
|
235
|
+
numEventsProcessed: numEventsProcessed,
|
|
236
|
+
timestampCaughtUpToHeadOrEndblock: timestampCaughtUpToHeadOrEndblock
|
|
237
|
+
}
|
|
238
|
+
}) : ({
|
|
239
|
+
TAG: "Syncing",
|
|
240
|
+
_0: {
|
|
241
|
+
firstEventBlockNumber: firstEventBlock,
|
|
242
|
+
latestProcessedBlock: committedProgressBlockNumber,
|
|
243
|
+
numEventsProcessed: numEventsProcessed
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
) : "SearchingForEvents"
|
|
247
|
+
);
|
|
248
|
+
let match = IndexerState.config(state).ecosystem.name;
|
|
249
249
|
let tmp;
|
|
250
|
-
switch (match
|
|
250
|
+
switch (match) {
|
|
251
251
|
case "evm" :
|
|
252
252
|
case "fuel" :
|
|
253
253
|
tmp = "Block";
|
|
@@ -257,22 +257,22 @@ function Tui$App(props) {
|
|
|
257
257
|
break;
|
|
258
258
|
}
|
|
259
259
|
return {
|
|
260
|
-
chainId:
|
|
260
|
+
chainId: ChainState.chainConfig(cs).id.toString(),
|
|
261
261
|
eventsProcessed: numEventsProcessed,
|
|
262
|
-
progressBlock:
|
|
262
|
+
progressBlock: committedProgressBlockNumber < fetchState.startBlock ? fetchState.startBlock : committedProgressBlockNumber,
|
|
263
263
|
bufferBlock: latestFetchedBlockNumber,
|
|
264
|
-
sourceBlock:
|
|
265
|
-
startBlock:
|
|
266
|
-
endBlock:
|
|
267
|
-
firstEventBlockNumber:
|
|
268
|
-
poweredByHyperSync: SourceManager.getActiveSource(
|
|
264
|
+
sourceBlock: fetchState.knownHeight,
|
|
265
|
+
startBlock: fetchState.startBlock,
|
|
266
|
+
endBlock: fetchState.endBlock,
|
|
267
|
+
firstEventBlockNumber: fetchState.firstEventBlock,
|
|
268
|
+
poweredByHyperSync: SourceManager.getActiveSource(sourceManager).poweredByHyperSync,
|
|
269
269
|
progress: progress,
|
|
270
270
|
latestFetchedBlockNumber: latestFetchedBlockNumber,
|
|
271
271
|
knownHeight: knownHeight,
|
|
272
272
|
blockUnit: tmp,
|
|
273
|
-
rateLimitTimeMs: SourceManager.getRateLimitTimeMs(
|
|
274
|
-
isRateLimited: SourceManager.isRateLimited(
|
|
275
|
-
rateLimitResetInMs: SourceManager.getRateLimitResetInMs(
|
|
273
|
+
rateLimitTimeMs: SourceManager.getRateLimitTimeMs(sourceManager),
|
|
274
|
+
isRateLimited: SourceManager.isRateLimited(sourceManager),
|
|
275
|
+
rateLimitResetInMs: SourceManager.getRateLimitResetInMs(sourceManager)
|
|
276
276
|
};
|
|
277
277
|
});
|
|
278
278
|
let totalEventsProcessed = Stdlib_Array.reduce(chains, 0, (acc, chain) => acc + chain.eventsProcessed);
|
|
@@ -329,7 +329,7 @@ function Tui$App(props) {
|
|
|
329
329
|
tmp = null;
|
|
330
330
|
}
|
|
331
331
|
let defaultPassword = "testing";
|
|
332
|
-
let match$1 =
|
|
332
|
+
let match$1 = IndexerState.config(state).storage.clickhouse;
|
|
333
333
|
let match$2 = Env.ClickHouse.host();
|
|
334
334
|
return JsxRuntime.jsxs(Ink$1.Box, {
|
|
335
335
|
children: [
|
|
@@ -362,7 +362,7 @@ function Tui$App(props) {
|
|
|
362
362
|
}),
|
|
363
363
|
JsxRuntime.jsx(SyncETA.make, {
|
|
364
364
|
chains: chains,
|
|
365
|
-
indexerStartTime:
|
|
365
|
+
indexerStartTime: IndexerState.indexerStartTime(state)
|
|
366
366
|
}),
|
|
367
367
|
tmp,
|
|
368
368
|
JsxRuntime.jsx(Ink.Newline.make, {}),
|
|
@@ -383,7 +383,7 @@ function Tui$App(props) {
|
|
|
383
383
|
],
|
|
384
384
|
flexDirection: "row"
|
|
385
385
|
}),
|
|
386
|
-
|
|
386
|
+
IndexerState.config(state).isDev ? JsxRuntime.jsxs(Ink$1.Box, {
|
|
387
387
|
children: [
|
|
388
388
|
JsxRuntime.jsx(Ink$1.Text, {
|
|
389
389
|
children: "Dev Console: "
|
|
@@ -410,7 +410,7 @@ function Tui$App(props) {
|
|
|
410
410
|
flexDirection: "row"
|
|
411
411
|
}) : null,
|
|
412
412
|
JsxRuntime.jsx(Messages.make, {
|
|
413
|
-
config:
|
|
413
|
+
config: IndexerState.config(state)
|
|
414
414
|
})
|
|
415
415
|
],
|
|
416
416
|
flexDirection: "column"
|