envio 3.12.1 → 3.13.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -8
- package/src/BatchProcessing.res +15 -14
- package/src/BatchProcessing.res.mjs +8 -15
- package/src/Bin.res +24 -17
- package/src/Bin.res.mjs +5 -0
- package/src/ChainFetching.res +18 -24
- package/src/ChainFetching.res.mjs +14 -15
- package/src/ChainState.res +103 -38
- package/src/ChainState.res.mjs +79 -22
- package/src/ChainState.resi +14 -2
- package/src/Config.res +32 -0
- package/src/Config.res.mjs +24 -0
- package/src/Core.res +4 -0
- package/src/Core.res.mjs +4 -0
- package/src/CrossChainState.res +109 -11
- package/src/CrossChainState.res.mjs +71 -7
- package/src/CrossChainState.resi +11 -1
- package/src/Env.res +4 -0
- package/src/ErrorHandling.res +15 -4
- package/src/ErrorHandling.res.mjs +16 -5
- package/src/FinalizeBackfill.res +10 -4
- package/src/FinalizeBackfill.res.mjs +5 -3
- package/src/HandlerRegister.res +0 -37
- package/src/HandlerRegister.res.mjs +0 -18
- package/src/IndexerLoop.res +2 -0
- package/src/IndexerLoop.res.mjs +1 -0
- package/src/IndexerState.res +43 -1
- package/src/IndexerState.res.mjs +48 -4
- package/src/IndexerState.resi +11 -0
- package/src/Main.res +128 -268
- package/src/Main.res.mjs +27 -153
- package/src/Metrics.res +268 -102
- package/src/Metrics.res.mjs +227 -48
- package/src/Persistence.res +30 -2
- package/src/Persistence.res.mjs +12 -3
- package/src/PgStorage.res +19 -11
- package/src/PgStorage.res.mjs +13 -10
- package/src/Rollback.res +3 -3
- package/src/Server.res +178 -0
- package/src/Server.res.mjs +143 -0
- package/src/SimulateItems.res +1 -1
- package/src/SimulateItems.res.mjs +1 -1
- package/src/Supervisor.res +542 -0
- package/src/Supervisor.res.mjs +455 -0
- package/src/TestIndexer.res +1 -1
- package/src/TestIndexer.res.mjs +2 -2
- package/src/Worker.res +101 -0
- package/src/Worker.res.mjs +81 -0
- package/src/bindings/NodeJs.res +50 -0
- package/src/bindings/NodeJs.res.mjs +8 -1
- package/src/db/InternalTable.res +8 -1
- package/src/db/InternalTable.res.mjs +5 -1
- package/src/sources/AddressSet.res +5 -3
- package/src/sources/AddressStore.res +19 -11
- package/src/sources/AddressStore.res.mjs +2 -7
- package/src/sources/BlockStore.res +10 -9
- package/src/sources/BlockStore.res.mjs +4 -4
- package/src/sources/ChainSources.res +4 -0
- package/src/sources/ChainSources.res.mjs +2 -2
- package/src/sources/EvmChain.res +4 -0
- package/src/sources/EvmChain.res.mjs +3 -1
- package/src/sources/EvmEventItem.res +56 -0
- package/src/sources/EvmEventItem.res.mjs +32 -0
- package/src/sources/EvmHyperSyncSource.res +7 -37
- package/src/sources/EvmHyperSyncSource.res.mjs +8 -29
- package/src/sources/EvmRpcClient.res +41 -59
- package/src/sources/EvmRpcClient.res.mjs +4 -54
- package/src/sources/EvmRpcWs.res +4 -1
- package/src/sources/EvmRpcWs.res.mjs +6 -2
- package/src/sources/FuelHyperSyncSource.res +6 -4
- package/src/sources/FuelHyperSyncSource.res.mjs +7 -9
- package/src/sources/HeightFeed.res +7 -1
- package/src/sources/HeightFeed.res.mjs +9 -7
- package/src/sources/HyperSyncClient.res +1 -14
- package/src/sources/RequestStat.res +7 -0
- package/src/sources/RequestStat.res.mjs +14 -1
- package/src/sources/RpcSource.res +100 -1043
- package/src/sources/RpcSource.res.mjs +81 -1056
- package/src/sources/SimulateSource.res +2 -5
- package/src/sources/SimulateSource.res.mjs +2 -3
- package/src/sources/Source.res +34 -12
- package/src/sources/Source.res.mjs +11 -0
- package/src/sources/SourceManager.res +111 -31
- package/src/sources/SourceManager.res.mjs +65 -31
- package/src/sources/SourceManager.resi +4 -0
- package/src/sources/StartBlockResolver.res +8 -5
- package/src/sources/StartBlockResolver.res.mjs +4 -2
- package/src/sources/SvmHyperSyncSource.res +4 -2
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -6
- package/src/sources/TransactionStore.res +9 -6
- package/src/sources/TransactionStore.res.mjs +2 -2
- package/src/tui/Tui.res +10 -0
- package/src/tui/Tui.res.mjs +15 -0
- package/src/tui/components/SyncETA.res +12 -6
- package/src/tui/components/SyncETA.res.mjs +12 -8
- package/src/LazyLoader.res +0 -135
- package/src/LazyLoader.res.mjs +0 -118
- package/src/bindings/SDSL.res +0 -12
- package/src/bindings/SDSL.res.mjs +0 -9
- package/src/bindings/Yargs.res +0 -8
- package/src/bindings/Yargs.res.mjs +0 -2
- package/src/sources/Rpc.res +0 -185
- package/src/sources/Rpc.res.mjs +0 -183
package/src/IndexerLoop.res
CHANGED
package/src/IndexerLoop.res.mjs
CHANGED
package/src/IndexerState.res
CHANGED
|
@@ -115,6 +115,10 @@ type t = {
|
|
|
115
115
|
// waitForNewBlock waiter is bound to the old, pre-realtime source). A fetch
|
|
116
116
|
// response or waiter carrying an older epoch than this is discarded.
|
|
117
117
|
mutable epoch: int,
|
|
118
|
+
// The loop's one door in from outside it: IndexerLoop owns scheduling and
|
|
119
|
+
// wires this when it starts, so an event the loop can't see for itself can
|
|
120
|
+
// still make it re-evaluate. A no-op before then.
|
|
121
|
+
mutable scheduleProcessing: unit => unit,
|
|
118
122
|
// None off the simulate path.
|
|
119
123
|
simulateDeadInputTracker: option<SimulateDeadInputTracker.t>,
|
|
120
124
|
// --- Metric counters, rendered by Metrics at scrape time. ---
|
|
@@ -141,6 +145,7 @@ let make = (
|
|
|
141
145
|
~chainStates: dict<ChainState.t>,
|
|
142
146
|
~isRealtime: bool,
|
|
143
147
|
~targetBufferSize=CrossChainState.calculateTargetBufferSize(),
|
|
148
|
+
~holdRealtime=false,
|
|
144
149
|
~committedFrontier=Frontier.empty(),
|
|
145
150
|
~isDevelopmentMode=false,
|
|
146
151
|
~shouldUseTui=false,
|
|
@@ -180,11 +185,17 @@ let make = (
|
|
|
180
185
|
chainMetaDirty: false,
|
|
181
186
|
chainMetaThrottler,
|
|
182
187
|
isProcessing: false,
|
|
183
|
-
crossChainState: CrossChainState.make(
|
|
188
|
+
crossChainState: CrossChainState.make(
|
|
189
|
+
~chainStates,
|
|
190
|
+
~isRealtime,
|
|
191
|
+
~targetBufferSize,
|
|
192
|
+
~holdRealtime,
|
|
193
|
+
),
|
|
184
194
|
indexerStartTime: Date.make(),
|
|
185
195
|
indexerStartTimeRef: Performance.now(),
|
|
186
196
|
rollbackState: NoRollback,
|
|
187
197
|
lastPrunedAtMillis: Dict.make(),
|
|
198
|
+
scheduleProcessing: () => (),
|
|
188
199
|
loadManager: LoadManager.make(),
|
|
189
200
|
keepProcessAlive: isDevelopmentMode || shouldUseTui,
|
|
190
201
|
exitAfterFirstEventBlock,
|
|
@@ -227,6 +238,9 @@ let makeFromDbState = (
|
|
|
227
238
|
~exitAfterFirstEventBlock=false,
|
|
228
239
|
~reducedPollingInterval=?,
|
|
229
240
|
~targetBufferSize=CrossChainState.calculateTargetBufferSize(),
|
|
241
|
+
// A process driving part of a split run waits for its supervisor before
|
|
242
|
+
// entering the reorg threshold or switching to realtime.
|
|
243
|
+
~holdRealtime=false,
|
|
230
244
|
~onError,
|
|
231
245
|
~onExit=?,
|
|
232
246
|
) => {
|
|
@@ -274,6 +288,7 @@ let makeFromDbState = (
|
|
|
274
288
|
~chainStates,
|
|
275
289
|
~isRealtime,
|
|
276
290
|
~targetBufferSize,
|
|
291
|
+
~holdRealtime,
|
|
277
292
|
~committedFrontier=initialState.checkpointFrontier,
|
|
278
293
|
~isDevelopmentMode,
|
|
279
294
|
~shouldUseTui,
|
|
@@ -500,11 +515,37 @@ let isFinalizingIndexes = (state: t) =>
|
|
|
500
515
|
state.crossChainState->CrossChainState.isCaughtUp &&
|
|
501
516
|
!(state.crossChainState->CrossChainState.isRealtime)
|
|
502
517
|
|
|
518
|
+
// The FinalizingIndexes phase is the transition a held process waits on: it
|
|
519
|
+
// ends with `ready_at` committed and the indexer realtime.
|
|
520
|
+
let shouldFinalizeIndexes = (state: t) =>
|
|
521
|
+
state->isFinalizingIndexes && !(state.crossChainState->CrossChainState.isHoldingRealtime)
|
|
522
|
+
|
|
503
523
|
let markCaughtUpIfSettled = (state: t) =>
|
|
504
524
|
state.crossChainState->CrossChainState.markCaughtUpIfSettled
|
|
505
525
|
|
|
526
|
+
let isReadyToEnterReorgThreshold = (state: t, ~batch) =>
|
|
527
|
+
state.crossChainState->CrossChainState.isReadyToEnterReorgThreshold(~batch)
|
|
528
|
+
|
|
529
|
+
let bindScheduleProcessing = (state: t, scheduleProcessing) =>
|
|
530
|
+
state.scheduleProcessing = scheduleProcessing
|
|
531
|
+
|
|
532
|
+
// A process still waiting on its supervisor owes the schema the indexes its
|
|
533
|
+
// chains deferred, so reaching every end block doesn't make it done.
|
|
534
|
+
let isHoldingRealtime = (state: t) => state.crossChainState->CrossChainState.isHoldingRealtime
|
|
535
|
+
|
|
536
|
+
let hasArrivedAtHead = (state: t) => state.crossChainState->CrossChainState.hasArrivedAtHead
|
|
537
|
+
|
|
538
|
+
let releaseRealtime = (state: t) => {
|
|
539
|
+
state.crossChainState->CrossChainState.releaseRealtime
|
|
540
|
+
// Every chain is parked at the head with no batch coming, so nothing would
|
|
541
|
+
// notice the hold is gone without a pass through processing.
|
|
542
|
+
state.scheduleProcessing()
|
|
543
|
+
}
|
|
544
|
+
|
|
506
545
|
let markReady = (state: t, ~readyAt) => state.crossChainState->CrossChainState.markReady(~readyAt)
|
|
507
546
|
|
|
547
|
+
let reportFinished = (state: t) => state.crossChainState->CrossChainState.reportFinished
|
|
548
|
+
|
|
508
549
|
let rollbackState = (state: t) => state.rollbackState
|
|
509
550
|
let indexerStartTime = (state: t) => state.indexerStartTime
|
|
510
551
|
let loadManager = (state: t) => state.loadManager
|
|
@@ -572,6 +613,7 @@ let toMetrics = (state: t): Metrics.t => {
|
|
|
572
613
|
elapsedSeconds: state.indexerStartTimeRef->Performance.secondsSince,
|
|
573
614
|
targetBufferSize: state.crossChainState->CrossChainState.targetBufferSize,
|
|
574
615
|
isInReorgThreshold: state.crossChainState->CrossChainState.isInReorgThreshold,
|
|
616
|
+
hasArrivedAtHead: state.crossChainState->CrossChainState.hasArrivedAtHead,
|
|
575
617
|
rollbackEnabled: state.config.shouldRollbackOnReorg,
|
|
576
618
|
maxBatchSize: state.config.batchSize,
|
|
577
619
|
preloadSeconds: state.preloadSeconds,
|
package/src/IndexerState.res.mjs
CHANGED
|
@@ -24,8 +24,9 @@ import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js
|
|
|
24
24
|
import * as CheckpointSequence from "./db/CheckpointSequence.res.mjs";
|
|
25
25
|
import * as SimulateDeadInputTracker from "./SimulateDeadInputTracker.res.mjs";
|
|
26
26
|
|
|
27
|
-
function make(config, persistence, chainStates, isRealtime, targetBufferSizeOpt, committedFrontierOpt, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, onError, onExit) {
|
|
27
|
+
function make(config, persistence, chainStates, isRealtime, targetBufferSizeOpt, holdRealtimeOpt, committedFrontierOpt, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, onError, onExit) {
|
|
28
28
|
let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : CrossChainState.calculateTargetBufferSize();
|
|
29
|
+
let holdRealtime = holdRealtimeOpt !== undefined ? holdRealtimeOpt : false;
|
|
29
30
|
let committedFrontier = committedFrontierOpt !== undefined ? committedFrontierOpt : Frontier.empty();
|
|
30
31
|
let isDevelopmentMode = isDevelopmentModeOpt !== undefined ? isDevelopmentModeOpt : false;
|
|
31
32
|
let shouldUseTui = shouldUseTuiOpt !== undefined ? shouldUseTuiOpt : false;
|
|
@@ -54,7 +55,7 @@ function make(config, persistence, chainStates, isRealtime, targetBufferSizeOpt,
|
|
|
54
55
|
chainMetaDirty: false,
|
|
55
56
|
chainMetaThrottler: chainMetaThrottler,
|
|
56
57
|
isProcessing: false,
|
|
57
|
-
crossChainState: CrossChainState.make(chainStates, isRealtime, targetBufferSize),
|
|
58
|
+
crossChainState: CrossChainState.make(chainStates, isRealtime, targetBufferSize, holdRealtime),
|
|
58
59
|
rollbackState: "NoRollback",
|
|
59
60
|
indexerStartTime: new Date(),
|
|
60
61
|
indexerStartTimeRef: Performance.now(),
|
|
@@ -66,6 +67,7 @@ function make(config, persistence, chainStates, isRealtime, targetBufferSizeOpt,
|
|
|
66
67
|
onExit: onExit,
|
|
67
68
|
isStopped: false,
|
|
68
69
|
epoch: 0,
|
|
70
|
+
scheduleProcessing: () => {},
|
|
69
71
|
simulateDeadInputTracker: SimulateDeadInputTracker.makeFromConfig(config),
|
|
70
72
|
preloadSeconds: 0,
|
|
71
73
|
processingSeconds: 0,
|
|
@@ -82,11 +84,12 @@ function make(config, persistence, chainStates, isRealtime, targetBufferSizeOpt,
|
|
|
82
84
|
};
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
function makeFromDbState(config, persistence, initialState, registrationsByChainId, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, reducedPollingInterval, targetBufferSizeOpt, onError, onExit) {
|
|
87
|
+
function makeFromDbState(config, persistence, initialState, registrationsByChainId, isDevelopmentModeOpt, shouldUseTuiOpt, exitAfterFirstEventBlockOpt, reducedPollingInterval, targetBufferSizeOpt, holdRealtimeOpt, onError, onExit) {
|
|
86
88
|
let isDevelopmentMode = isDevelopmentModeOpt !== undefined ? isDevelopmentModeOpt : false;
|
|
87
89
|
let shouldUseTui = shouldUseTuiOpt !== undefined ? shouldUseTuiOpt : false;
|
|
88
90
|
let exitAfterFirstEventBlock = exitAfterFirstEventBlockOpt !== undefined ? exitAfterFirstEventBlockOpt : false;
|
|
89
91
|
let targetBufferSize = targetBufferSizeOpt !== undefined ? targetBufferSizeOpt : CrossChainState.calculateTargetBufferSize();
|
|
92
|
+
let holdRealtime = holdRealtimeOpt !== undefined ? holdRealtimeOpt : false;
|
|
90
93
|
let isInReorgThreshold = initialState.cleanRun ? false : initialState.chains.some(resumedChainState => {
|
|
91
94
|
let progressBlockNumber = resumedChainState.progressBlockNumber;
|
|
92
95
|
let sourceBlockNumber = resumedChainState.sourceBlockNumber;
|
|
@@ -104,7 +107,7 @@ function makeFromDbState(config, persistence, initialState, registrationsByChain
|
|
|
104
107
|
let chainConfig = ChainMap.get(config.chainMap, chainId);
|
|
105
108
|
chainStates[resumedChainState.id] = ChainState.makeFromDbState(chainConfig, resumedChainState, initialState.reorgCheckpoints, isInReorgThreshold, isRealtime, config, initialState.contractMapping, registrationsByChainId, reducedPollingInterval);
|
|
106
109
|
});
|
|
107
|
-
let state = make(config, persistence, chainStates, isRealtime, targetBufferSize, initialState.checkpointFrontier, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, onError, onExit);
|
|
110
|
+
let state = make(config, persistence, chainStates, isRealtime, targetBufferSize, holdRealtime, initialState.checkpointFrontier, isDevelopmentMode, shouldUseTui, exitAfterFirstEventBlock, onError, onExit);
|
|
108
111
|
CrossChainState.markCaughtUpOnResume(state.crossChainState);
|
|
109
112
|
Utils.Dict.forEach(initialState.cache, param => {
|
|
110
113
|
let count = param.count;
|
|
@@ -350,14 +353,47 @@ function isFinalizingIndexes(state) {
|
|
|
350
353
|
}
|
|
351
354
|
}
|
|
352
355
|
|
|
356
|
+
function shouldFinalizeIndexes(state) {
|
|
357
|
+
if (isFinalizingIndexes(state)) {
|
|
358
|
+
return !CrossChainState.isHoldingRealtime(state.crossChainState);
|
|
359
|
+
} else {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
353
364
|
function markCaughtUpIfSettled(state) {
|
|
354
365
|
CrossChainState.markCaughtUpIfSettled(state.crossChainState);
|
|
355
366
|
}
|
|
356
367
|
|
|
368
|
+
function isReadyToEnterReorgThreshold(state, batch) {
|
|
369
|
+
return CrossChainState.isReadyToEnterReorgThreshold(state.crossChainState, batch);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function bindScheduleProcessing(state, scheduleProcessing) {
|
|
373
|
+
state.scheduleProcessing = scheduleProcessing;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function isHoldingRealtime(state) {
|
|
377
|
+
return CrossChainState.isHoldingRealtime(state.crossChainState);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
function hasArrivedAtHead(state) {
|
|
381
|
+
return CrossChainState.hasArrivedAtHead(state.crossChainState);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
function releaseRealtime(state) {
|
|
385
|
+
CrossChainState.releaseRealtime(state.crossChainState);
|
|
386
|
+
state.scheduleProcessing();
|
|
387
|
+
}
|
|
388
|
+
|
|
357
389
|
function markReady(state, readyAt) {
|
|
358
390
|
CrossChainState.markReady(state.crossChainState, readyAt);
|
|
359
391
|
}
|
|
360
392
|
|
|
393
|
+
function reportFinished(state) {
|
|
394
|
+
CrossChainState.reportFinished(state.crossChainState);
|
|
395
|
+
}
|
|
396
|
+
|
|
361
397
|
function rollbackState(state) {
|
|
362
398
|
return state.rollbackState;
|
|
363
399
|
}
|
|
@@ -447,6 +483,7 @@ function toMetrics(state) {
|
|
|
447
483
|
elapsedSeconds: Performance.secondsSince(state.indexerStartTimeRef),
|
|
448
484
|
targetBufferSize: CrossChainState.targetBufferSize(state.crossChainState),
|
|
449
485
|
isInReorgThreshold: CrossChainState.isInReorgThreshold(state.crossChainState),
|
|
486
|
+
hasArrivedAtHead: CrossChainState.hasArrivedAtHead(state.crossChainState),
|
|
450
487
|
rollbackEnabled: state.config.shouldRollbackOnReorg,
|
|
451
488
|
maxBatchSize: state.config.batchSize,
|
|
452
489
|
preloadSeconds: state.preloadSeconds,
|
|
@@ -844,7 +881,14 @@ export {
|
|
|
844
881
|
isRealtime,
|
|
845
882
|
isFinalizingIndexes,
|
|
846
883
|
markCaughtUpIfSettled,
|
|
884
|
+
isReadyToEnterReorgThreshold,
|
|
885
|
+
shouldFinalizeIndexes,
|
|
886
|
+
bindScheduleProcessing,
|
|
887
|
+
isHoldingRealtime,
|
|
888
|
+
hasArrivedAtHead,
|
|
889
|
+
releaseRealtime,
|
|
847
890
|
markReady,
|
|
891
|
+
reportFinished,
|
|
848
892
|
rollbackState,
|
|
849
893
|
indexerStartTime,
|
|
850
894
|
loadManager,
|
package/src/IndexerState.resi
CHANGED
|
@@ -16,6 +16,7 @@ let make: (
|
|
|
16
16
|
~chainStates: dict<ChainState.t>,
|
|
17
17
|
~isRealtime: bool,
|
|
18
18
|
~targetBufferSize: int=?,
|
|
19
|
+
~holdRealtime: bool=?,
|
|
19
20
|
~committedFrontier: Frontier.t=?,
|
|
20
21
|
~isDevelopmentMode: bool=?,
|
|
21
22
|
~shouldUseTui: bool=?,
|
|
@@ -34,6 +35,7 @@ let makeFromDbState: (
|
|
|
34
35
|
~exitAfterFirstEventBlock: bool=?,
|
|
35
36
|
~reducedPollingInterval: int=?,
|
|
36
37
|
~targetBufferSize: int=?,
|
|
38
|
+
~holdRealtime: bool=?,
|
|
37
39
|
~onError: ErrorHandling.t => unit,
|
|
38
40
|
~onExit: unit => unit=?,
|
|
39
41
|
) => t
|
|
@@ -93,7 +95,16 @@ let shouldSaveHistory: t => dict<bool>
|
|
|
93
95
|
let isRealtime: t => bool
|
|
94
96
|
let isFinalizingIndexes: t => bool
|
|
95
97
|
let markCaughtUpIfSettled: t => unit
|
|
98
|
+
let isReadyToEnterReorgThreshold: (t, ~batch: Batch.t) => bool
|
|
99
|
+
let shouldFinalizeIndexes: t => bool
|
|
100
|
+
// Wires the loop's way back in. IndexerLoop calls this as it starts.
|
|
101
|
+
let bindScheduleProcessing: (t, unit => unit) => unit
|
|
102
|
+
let isHoldingRealtime: t => bool
|
|
103
|
+
let hasArrivedAtHead: t => bool
|
|
104
|
+
// The supervisor's go-ahead for a process driving part of a split run.
|
|
105
|
+
let releaseRealtime: t => unit
|
|
96
106
|
let markReady: (t, ~readyAt: Date.t) => unit
|
|
107
|
+
let reportFinished: t => unit
|
|
97
108
|
let rollbackState: t => rollbackState
|
|
98
109
|
let indexerStartTime: t => Date.t
|
|
99
110
|
let loadManager: t => LoadManager.t
|