envio 3.0.0-alpha.21 → 3.0.0-alpha.22
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/bin.mjs +2 -48
- package/evm.schema.json +67 -0
- package/fuel.schema.json +67 -0
- package/index.d.ts +822 -38
- package/index.js +5 -3
- package/package.json +10 -8
- package/rescript.json +5 -9
- package/src/Address.res +4 -5
- package/src/Address.res.mjs +9 -12
- package/src/Api.res +15 -0
- package/src/Api.res.mjs +20 -0
- package/src/Batch.res +32 -34
- package/src/Batch.res.mjs +172 -187
- package/src/Bin.res +89 -0
- package/src/Bin.res.mjs +97 -0
- package/src/ChainFetcher.res +33 -57
- package/src/ChainFetcher.res.mjs +197 -227
- package/src/ChainManager.res +6 -14
- package/src/ChainManager.res.mjs +74 -85
- package/src/ChainMap.res +14 -16
- package/src/ChainMap.res.mjs +38 -38
- package/src/Config.res +193 -135
- package/src/Config.res.mjs +566 -592
- package/src/Core.res +182 -0
- package/src/Core.res.mjs +207 -0
- package/src/Ecosystem.res +25 -4
- package/src/Ecosystem.res.mjs +12 -13
- package/src/Env.res +20 -13
- package/src/Env.res.mjs +124 -113
- package/src/EnvSafe.res +269 -0
- package/src/EnvSafe.res.mjs +296 -0
- package/src/EnvSafe.resi +18 -0
- package/src/Envio.res +37 -26
- package/src/Envio.res.mjs +59 -60
- package/src/ErrorHandling.res +2 -2
- package/src/ErrorHandling.res.mjs +15 -15
- package/src/EventConfigBuilder.res +219 -81
- package/src/EventConfigBuilder.res.mjs +259 -202
- package/src/EventProcessing.res +27 -38
- package/src/EventProcessing.res.mjs +165 -183
- package/src/EventUtils.res +11 -11
- package/src/EventUtils.res.mjs +21 -22
- package/src/EvmTypes.res +0 -1
- package/src/EvmTypes.res.mjs +5 -5
- package/src/FetchState.res +360 -256
- package/src/FetchState.res.mjs +958 -914
- package/src/GlobalState.res +365 -351
- package/src/GlobalState.res.mjs +958 -992
- package/src/GlobalStateManager.res +1 -2
- package/src/GlobalStateManager.res.mjs +36 -44
- package/src/HandlerLoader.res +107 -23
- package/src/HandlerLoader.res.mjs +128 -38
- package/src/HandlerRegister.res +127 -103
- package/src/HandlerRegister.res.mjs +164 -164
- package/src/HandlerRegister.resi +12 -4
- package/src/Hasura.res +35 -22
- package/src/Hasura.res.mjs +158 -167
- package/src/InMemoryStore.res +20 -27
- package/src/InMemoryStore.res.mjs +64 -80
- package/src/InMemoryTable.res +34 -39
- package/src/InMemoryTable.res.mjs +165 -170
- package/src/Internal.res +52 -33
- package/src/Internal.res.mjs +84 -81
- package/src/LazyLoader.res.mjs +55 -61
- package/src/LoadLayer.res +77 -78
- package/src/LoadLayer.res.mjs +160 -189
- package/src/LoadManager.res +16 -21
- package/src/LoadManager.res.mjs +79 -84
- package/src/LogSelection.res +236 -68
- package/src/LogSelection.res.mjs +211 -141
- package/src/Logging.res +13 -9
- package/src/Logging.res.mjs +130 -143
- package/src/Main.res +428 -51
- package/src/Main.res.mjs +528 -271
- package/src/Persistence.res +77 -84
- package/src/Persistence.res.mjs +131 -132
- package/src/PgStorage.res +291 -167
- package/src/PgStorage.res.mjs +797 -817
- package/src/Prometheus.res +50 -58
- package/src/Prometheus.res.mjs +345 -373
- package/src/ReorgDetection.res +22 -24
- package/src/ReorgDetection.res.mjs +100 -106
- package/src/SafeCheckpointTracking.res +7 -7
- package/src/SafeCheckpointTracking.res.mjs +40 -43
- package/src/SimulateItems.res +41 -49
- package/src/SimulateItems.res.mjs +257 -272
- package/src/Sink.res +2 -2
- package/src/Sink.res.mjs +22 -26
- package/src/TableIndices.res +1 -2
- package/src/TableIndices.res.mjs +42 -48
- package/src/TestIndexer.res +196 -189
- package/src/TestIndexer.res.mjs +536 -536
- package/src/TestIndexerProxyStorage.res +15 -16
- package/src/TestIndexerProxyStorage.res.mjs +98 -122
- package/src/TestIndexerWorker.res +4 -0
- package/src/TestIndexerWorker.res.mjs +7 -0
- package/src/Throttler.res +3 -3
- package/src/Throttler.res.mjs +23 -24
- package/src/Time.res +1 -1
- package/src/Time.res.mjs +18 -21
- package/src/TopicFilter.res +3 -3
- package/src/TopicFilter.res.mjs +29 -30
- package/src/UserContext.res +93 -54
- package/src/UserContext.res.mjs +197 -182
- package/src/Utils.res +141 -86
- package/src/Utils.res.mjs +334 -295
- package/src/bindings/BigDecimal.res +0 -2
- package/src/bindings/BigDecimal.res.mjs +19 -23
- package/src/bindings/ClickHouse.res +28 -27
- package/src/bindings/ClickHouse.res.mjs +243 -240
- package/src/bindings/DateFns.res +11 -11
- package/src/bindings/DateFns.res.mjs +7 -7
- package/src/bindings/EventSource.res.mjs +2 -2
- package/src/bindings/Express.res +2 -5
- package/src/bindings/Hrtime.res +2 -2
- package/src/bindings/Hrtime.res.mjs +30 -32
- package/src/bindings/Lodash.res.mjs +1 -1
- package/src/bindings/NodeJs.res +14 -9
- package/src/bindings/NodeJs.res.mjs +20 -20
- package/src/bindings/Pino.res +8 -10
- package/src/bindings/Pino.res.mjs +40 -43
- package/src/bindings/Postgres.res +2 -5
- package/src/bindings/Postgres.res.mjs +9 -9
- package/src/bindings/PromClient.res +17 -2
- package/src/bindings/PromClient.res.mjs +30 -7
- package/src/bindings/SDSL.res.mjs +2 -2
- package/src/bindings/Viem.res +4 -4
- package/src/bindings/Viem.res.mjs +20 -22
- package/src/bindings/Vitest.res +1 -1
- package/src/bindings/Vitest.res.mjs +2 -2
- package/src/bindings/WebSocket.res +1 -1
- package/src/db/EntityHistory.res +9 -3
- package/src/db/EntityHistory.res.mjs +84 -59
- package/src/db/InternalTable.res +62 -60
- package/src/db/InternalTable.res.mjs +271 -203
- package/src/db/Schema.res +1 -2
- package/src/db/Schema.res.mjs +28 -32
- package/src/db/Table.res +28 -27
- package/src/db/Table.res.mjs +276 -292
- package/src/sources/EventRouter.res +21 -16
- package/src/sources/EventRouter.res.mjs +55 -57
- package/src/sources/Evm.res +17 -1
- package/src/sources/Evm.res.mjs +16 -8
- package/src/sources/EvmChain.res +15 -17
- package/src/sources/EvmChain.res.mjs +40 -42
- package/src/sources/Fuel.res +14 -1
- package/src/sources/Fuel.res.mjs +16 -8
- package/src/sources/FuelSDK.res +1 -1
- package/src/sources/FuelSDK.res.mjs +6 -8
- package/src/sources/HyperFuel.res +8 -10
- package/src/sources/HyperFuel.res.mjs +113 -123
- package/src/sources/HyperFuelClient.res.mjs +6 -7
- package/src/sources/HyperFuelSource.res +19 -20
- package/src/sources/HyperFuelSource.res.mjs +339 -356
- package/src/sources/HyperSync.res +11 -13
- package/src/sources/HyperSync.res.mjs +206 -220
- package/src/sources/HyperSyncClient.res +5 -7
- package/src/sources/HyperSyncClient.res.mjs +70 -75
- package/src/sources/HyperSyncHeightStream.res +8 -9
- package/src/sources/HyperSyncHeightStream.res.mjs +78 -86
- package/src/sources/HyperSyncJsonApi.res +18 -15
- package/src/sources/HyperSyncJsonApi.res.mjs +201 -231
- package/src/sources/HyperSyncSource.res +17 -21
- package/src/sources/HyperSyncSource.res.mjs +268 -290
- package/src/sources/Rpc.res +5 -5
- package/src/sources/Rpc.res.mjs +168 -192
- package/src/sources/RpcSource.res +166 -167
- package/src/sources/RpcSource.res.mjs +972 -1046
- package/src/sources/RpcWebSocketHeightStream.res +10 -11
- package/src/sources/RpcWebSocketHeightStream.res.mjs +131 -145
- package/src/sources/SimulateSource.res +1 -1
- package/src/sources/SimulateSource.res.mjs +35 -38
- package/src/sources/Source.res +1 -1
- package/src/sources/Source.res.mjs +3 -3
- package/src/sources/SourceManager.res +39 -20
- package/src/sources/SourceManager.res.mjs +340 -371
- package/src/sources/SourceManager.resi +2 -1
- package/src/sources/Svm.res +12 -5
- package/src/sources/Svm.res.mjs +44 -41
- package/src/tui/Tui.res +23 -12
- package/src/tui/Tui.res.mjs +292 -290
- package/src/tui/bindings/Ink.res +2 -4
- package/src/tui/bindings/Ink.res.mjs +35 -41
- package/src/tui/components/BufferedProgressBar.res +7 -7
- package/src/tui/components/BufferedProgressBar.res.mjs +46 -46
- package/src/tui/components/CustomHooks.res +1 -2
- package/src/tui/components/CustomHooks.res.mjs +102 -122
- package/src/tui/components/Messages.res +1 -2
- package/src/tui/components/Messages.res.mjs +38 -42
- package/src/tui/components/SyncETA.res +10 -11
- package/src/tui/components/SyncETA.res.mjs +178 -196
- package/src/tui/components/TuiData.res +1 -1
- package/src/tui/components/TuiData.res.mjs +7 -6
- package/src/vendored/Rest.res +52 -66
- package/src/vendored/Rest.res.mjs +324 -364
- package/svm.schema.json +67 -0
- package/src/Address.gen.ts +0 -8
- package/src/Config.gen.ts +0 -19
- package/src/Envio.gen.ts +0 -55
- package/src/EvmTypes.gen.ts +0 -6
- package/src/InMemoryStore.gen.ts +0 -6
- package/src/Internal.gen.ts +0 -64
- package/src/PgStorage.gen.ts +0 -10
- package/src/PgStorage.res.d.mts +0 -5
- package/src/Types.ts +0 -56
- package/src/bindings/BigDecimal.gen.ts +0 -14
- package/src/bindings/BigDecimal.res.d.mts +0 -5
- package/src/bindings/BigInt.gen.ts +0 -10
- package/src/bindings/BigInt.res +0 -70
- package/src/bindings/BigInt.res.d.mts +0 -5
- package/src/bindings/BigInt.res.mjs +0 -154
- package/src/bindings/Ethers.res.d.mts +0 -5
- package/src/bindings/Pino.gen.ts +0 -17
- package/src/bindings/Postgres.gen.ts +0 -8
- package/src/bindings/Postgres.res.d.mts +0 -5
- package/src/bindings/Promise.res +0 -67
- package/src/bindings/Promise.res.mjs +0 -26
- package/src/db/InternalTable.gen.ts +0 -36
- package/src/sources/HyperSyncClient.gen.ts +0 -19
package/src/GlobalState.res
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
open Belt
|
|
2
|
-
|
|
3
1
|
type chain = ChainMap.Chain.t
|
|
4
2
|
type rollbackState =
|
|
5
3
|
| NoRollback
|
|
@@ -45,7 +43,7 @@ type t = {
|
|
|
45
43
|
processedBatches: int,
|
|
46
44
|
currentlyProcessingBatch: bool,
|
|
47
45
|
rollbackState: rollbackState,
|
|
48
|
-
indexerStartTime:
|
|
46
|
+
indexerStartTime: Date.t,
|
|
49
47
|
writeThrottlers: WriteThrottlers.t,
|
|
50
48
|
loadManager: LoadManager.t,
|
|
51
49
|
keepProcessAlive: bool,
|
|
@@ -67,7 +65,7 @@ let make = (
|
|
|
67
65
|
currentlyProcessingBatch: false,
|
|
68
66
|
processedBatches: 0,
|
|
69
67
|
chainManager,
|
|
70
|
-
indexerStartTime:
|
|
68
|
+
indexerStartTime: Date.make(),
|
|
71
69
|
rollbackState: NoRollback,
|
|
72
70
|
writeThrottlers: WriteThrottlers.make(),
|
|
73
71
|
loadManager: LoadManager.make(),
|
|
@@ -153,25 +151,25 @@ let updateChainMetadataTable = (
|
|
|
153
151
|
~persistence: Persistence.t,
|
|
154
152
|
~throttler: Throttler.t,
|
|
155
153
|
) => {
|
|
156
|
-
let chainsData: dict<InternalTable.Chains.metaFields> =
|
|
154
|
+
let chainsData: dict<InternalTable.Chains.metaFields> = Dict.make()
|
|
157
155
|
|
|
158
156
|
cm.chainFetchers
|
|
159
157
|
->ChainMap.values
|
|
160
158
|
->Belt.Array.forEach(cf => {
|
|
161
|
-
chainsData->
|
|
159
|
+
chainsData->Dict.set(
|
|
162
160
|
cf.chainConfig.id->Belt.Int.toString,
|
|
163
161
|
{
|
|
164
|
-
firstEventBlockNumber: cf.fetchState.firstEventBlock->
|
|
162
|
+
firstEventBlockNumber: cf.fetchState.firstEventBlock->Null.fromOption,
|
|
165
163
|
isHyperSync: (cf.sourceManager->SourceManager.getActiveSource).poweredByHyperSync,
|
|
166
164
|
latestFetchedBlockNumber: cf.fetchState->FetchState.bufferBlockNumber,
|
|
167
|
-
timestampCaughtUpToHeadOrEndblock: cf.timestampCaughtUpToHeadOrEndblock->
|
|
165
|
+
timestampCaughtUpToHeadOrEndblock: cf.timestampCaughtUpToHeadOrEndblock->Null.fromOption,
|
|
168
166
|
},
|
|
169
167
|
)
|
|
170
168
|
})
|
|
171
169
|
|
|
172
170
|
//Don't await this set, it can happen in its own time
|
|
173
171
|
throttler->Throttler.schedule(() =>
|
|
174
|
-
persistence.storage.setChainMeta(chainsData)->Promise.ignoreValue
|
|
172
|
+
persistence.storage.setChainMeta(chainsData)->Utils.Promise.ignoreValue
|
|
175
173
|
)
|
|
176
174
|
}
|
|
177
175
|
|
|
@@ -213,7 +211,7 @@ let updateProgressedChains = (chainManager: ChainManager.t, ~batch: Batch.t, ~ct
|
|
|
213
211
|
switch batch->Batch.findLastEventItem(~chainId=chain->ChainMap.Chain.toChainId) {
|
|
214
212
|
| Some(eventItem) => {
|
|
215
213
|
let blockTimestamp = eventItem.event.block->ctx.config.ecosystem.getTimestamp
|
|
216
|
-
let currentTimeMs =
|
|
214
|
+
let currentTimeMs = Date.now()->Float.toInt
|
|
217
215
|
let blockTimestampMs = blockTimestamp * 1000
|
|
218
216
|
let latencyMs = currentTimeMs - blockTimestampMs
|
|
219
217
|
|
|
@@ -278,7 +276,7 @@ let updateProgressedChains = (chainManager: ChainManager.t, ~batch: Batch.t, ~ct
|
|
|
278
276
|
let cf = if cf->ChainFetcher.hasProcessedToEndblock {
|
|
279
277
|
// in the case this is already set, don't reset and instead propagate the existing value
|
|
280
278
|
let timestampCaughtUpToHeadOrEndblock =
|
|
281
|
-
cf->ChainFetcher.isReady ? cf.timestampCaughtUpToHeadOrEndblock :
|
|
279
|
+
cf->ChainFetcher.isReady ? cf.timestampCaughtUpToHeadOrEndblock : Date.make()->Some
|
|
282
280
|
{
|
|
283
281
|
...cf,
|
|
284
282
|
timestampCaughtUpToHeadOrEndblock,
|
|
@@ -292,7 +290,7 @@ let updateProgressedChains = (chainManager: ChainManager.t, ~batch: Batch.t, ~ct
|
|
|
292
290
|
if nextQueueItemIsNone && allChainsAtHead {
|
|
293
291
|
{
|
|
294
292
|
...cf,
|
|
295
|
-
timestampCaughtUpToHeadOrEndblock:
|
|
293
|
+
timestampCaughtUpToHeadOrEndblock: Date.make()->Some,
|
|
296
294
|
}
|
|
297
295
|
} else {
|
|
298
296
|
//CASE2 -> Only calculate if case1 fails
|
|
@@ -303,7 +301,7 @@ let updateProgressedChains = (chainManager: ChainManager.t, ~batch: Batch.t, ~ct
|
|
|
303
301
|
if hasNoMoreEventsToProcess {
|
|
304
302
|
{
|
|
305
303
|
...cf,
|
|
306
|
-
timestampCaughtUpToHeadOrEndblock:
|
|
304
|
+
timestampCaughtUpToHeadOrEndblock: Date.make()->Some,
|
|
307
305
|
}
|
|
308
306
|
} else {
|
|
309
307
|
//Default to just returning cf
|
|
@@ -554,7 +552,6 @@ let processPartitionQueryResponse = async (
|
|
|
554
552
|
| _ =>
|
|
555
553
|
await ChainFetcher.runContractRegistersOrThrow(
|
|
556
554
|
~itemsWithContractRegister,
|
|
557
|
-
~chain,
|
|
558
555
|
~config=state.ctx.config,
|
|
559
556
|
)
|
|
560
557
|
}
|
|
@@ -818,403 +815,420 @@ let checkAndFetchForChain = (
|
|
|
818
815
|
//required args
|
|
819
816
|
~state,
|
|
820
817
|
~dispatchAction,
|
|
821
|
-
) =>
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
818
|
+
) =>
|
|
819
|
+
async chain => {
|
|
820
|
+
let chainFetcher = state.chainManager.chainFetchers->ChainMap.get(chain)
|
|
821
|
+
if !isPreparingRollback(state) {
|
|
822
|
+
let {fetchState} = chainFetcher
|
|
823
|
+
|
|
824
|
+
// Reduce polling to 60s when this chain is caught up but waiting for other chains
|
|
825
|
+
let reducedPolling = if state.ctx.config.shouldRollbackOnReorg {
|
|
826
|
+
!state.chainManager.isInReorgThreshold &&
|
|
827
|
+
fetchState->FetchState.isReadyToEnterReorgThreshold
|
|
828
|
+
} else {
|
|
829
|
+
chainFetcher->ChainFetcher.isReady &&
|
|
830
|
+
state.chainManager.chainFetchers
|
|
831
|
+
->ChainMap.values
|
|
832
|
+
->Array.some(cf => !(cf->ChainFetcher.isReady))
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
await chainFetcher.sourceManager->SourceManager.fetchNext(
|
|
836
|
+
~fetchState,
|
|
837
|
+
~waitForNewBlock=(~knownHeight) =>
|
|
838
|
+
chainFetcher.sourceManager->waitForNewBlock(
|
|
839
|
+
~knownHeight,
|
|
840
|
+
~isLive=chainFetcher->ChainFetcher.isReady,
|
|
841
|
+
~reducedPolling,
|
|
842
|
+
),
|
|
843
|
+
~onNewBlock=(~knownHeight) =>
|
|
844
|
+
dispatchAction(FinishWaitingForNewBlock({chain, knownHeight})),
|
|
845
|
+
~executeQuery=async query => {
|
|
846
|
+
try {
|
|
847
|
+
let response = await chainFetcher.sourceManager->executeQuery(
|
|
838
848
|
~query,
|
|
839
849
|
~knownHeight=fetchState.knownHeight,
|
|
840
850
|
~isLive=chainFetcher->ChainFetcher.isReady,
|
|
841
851
|
)
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
852
|
+
dispatchAction(ValidatePartitionQueryResponse({chain, response, query}))
|
|
853
|
+
} catch {
|
|
854
|
+
| exn => dispatchAction(ErrorExit(exn->ErrorHandling.make))
|
|
855
|
+
}
|
|
856
|
+
},
|
|
857
|
+
~stateId=state.id,
|
|
858
|
+
)
|
|
859
|
+
}
|
|
849
860
|
}
|
|
850
|
-
}
|
|
851
861
|
|
|
852
862
|
let injectedTaskReducer = (
|
|
853
863
|
//Used for dependency injection for tests
|
|
854
864
|
~waitForNewBlock,
|
|
855
865
|
~executeQuery,
|
|
856
866
|
~getLastKnownValidBlock,
|
|
857
|
-
) =>
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
867
|
+
) =>
|
|
868
|
+
async (
|
|
869
|
+
//required args
|
|
870
|
+
state: t,
|
|
871
|
+
task: task,
|
|
872
|
+
~dispatchAction,
|
|
873
|
+
) => {
|
|
874
|
+
switch task {
|
|
875
|
+
| ProcessPartitionQueryResponse(partitionQueryResponse) =>
|
|
876
|
+
state->processPartitionQueryResponse(partitionQueryResponse, ~dispatchAction)->Promise.ignore
|
|
877
|
+
| PruneStaleEntityHistory =>
|
|
878
|
+
let runPrune = async () => {
|
|
879
|
+
switch state.chainManager->ChainManager.getSafeCheckpointId {
|
|
880
|
+
| None => ()
|
|
881
|
+
| Some(safeCheckpointId) =>
|
|
882
|
+
await state.ctx.persistence.storage.pruneStaleCheckpoints(~safeCheckpointId)
|
|
883
|
+
|
|
884
|
+
for idx in 0 to state.ctx.persistence.allEntities->Array.length - 1 {
|
|
885
|
+
if idx !== 0 {
|
|
886
|
+
// Add some delay between entities
|
|
887
|
+
// To unblock the pg client if it's needed for something else
|
|
888
|
+
await Utils.delay(1000)
|
|
889
|
+
}
|
|
890
|
+
let entityConfig = state.ctx.persistence.allEntities->Array.getUnsafe(idx)
|
|
891
|
+
let timeRef = Hrtime.makeTimer()
|
|
892
|
+
try {
|
|
893
|
+
let () = await state.ctx.persistence.storage.pruneStaleEntityHistory(
|
|
894
|
+
~entityName=entityConfig.name,
|
|
895
|
+
~entityIndex=entityConfig.index,
|
|
896
|
+
~safeCheckpointId,
|
|
897
|
+
)
|
|
898
|
+
} catch {
|
|
899
|
+
| exn =>
|
|
900
|
+
exn->ErrorHandling.mkLogAndRaise(
|
|
901
|
+
~msg=`Failed to prune stale entity history`,
|
|
902
|
+
~logger=Logging.createChild(
|
|
903
|
+
~params={
|
|
904
|
+
"entityName": entityConfig.name,
|
|
905
|
+
"safeCheckpointId": safeCheckpointId,
|
|
906
|
+
},
|
|
907
|
+
),
|
|
908
|
+
)
|
|
909
|
+
}
|
|
910
|
+
Prometheus.RollbackHistoryPrune.increment(
|
|
911
|
+
~timeSeconds=Hrtime.timeSince(timeRef)->Hrtime.toSecondsFloat,
|
|
883
912
|
~entityName=entityConfig.name,
|
|
884
|
-
~entityIndex=entityConfig.index,
|
|
885
|
-
~safeCheckpointId,
|
|
886
|
-
)
|
|
887
|
-
} catch {
|
|
888
|
-
| exn =>
|
|
889
|
-
exn->ErrorHandling.mkLogAndRaise(
|
|
890
|
-
~msg=`Failed to prune stale entity history`,
|
|
891
|
-
~logger=Logging.createChild(
|
|
892
|
-
~params={
|
|
893
|
-
"entityName": entityConfig.name,
|
|
894
|
-
"safeCheckpointId": safeCheckpointId,
|
|
895
|
-
},
|
|
896
|
-
),
|
|
897
913
|
)
|
|
898
914
|
}
|
|
899
|
-
Prometheus.RollbackHistoryPrune.increment(
|
|
900
|
-
~timeSeconds=Hrtime.timeSince(timeRef)->Hrtime.toSecondsFloat,
|
|
901
|
-
~entityName=entityConfig.name,
|
|
902
|
-
)
|
|
903
915
|
}
|
|
904
916
|
}
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
917
|
+
state.writeThrottlers.pruneStaleEntityHistory->Throttler.schedule(runPrune)
|
|
918
|
+
|
|
919
|
+
| UpdateChainMetaDataAndCheckForExit(shouldExit) =>
|
|
920
|
+
let {chainManager, writeThrottlers} = state
|
|
921
|
+
switch shouldExit {
|
|
922
|
+
| ExitWithSuccess =>
|
|
923
|
+
updateChainMetadataTable(
|
|
924
|
+
chainManager,
|
|
925
|
+
~throttler=writeThrottlers.chainMetaData,
|
|
926
|
+
~persistence=state.ctx.persistence,
|
|
927
|
+
)
|
|
928
|
+
dispatchAction(SuccessExit)
|
|
929
|
+
| ExitWithError(msg) =>
|
|
930
|
+
dispatchAction(ErrorExit(ErrorHandling.make(JsError.throwWithMessage(msg))))
|
|
931
|
+
| NoExit =>
|
|
932
|
+
updateChainMetadataTable(
|
|
933
|
+
chainManager,
|
|
934
|
+
~throttler=writeThrottlers.chainMetaData,
|
|
935
|
+
~persistence=state.ctx.persistence,
|
|
936
|
+
)->ignore
|
|
937
|
+
}
|
|
938
|
+
| NextQuery(chainCheck) =>
|
|
939
|
+
let fetchForChain = checkAndFetchForChain(
|
|
940
|
+
~waitForNewBlock,
|
|
941
|
+
~executeQuery,
|
|
942
|
+
~state,
|
|
943
|
+
~dispatchAction,
|
|
916
944
|
)
|
|
917
|
-
dispatchAction(SuccessExit)
|
|
918
|
-
| ExitWithError(msg) => dispatchAction(ErrorExit(ErrorHandling.make(Js.Exn.raiseError(msg))))
|
|
919
|
-
| NoExit =>
|
|
920
|
-
updateChainMetadataTable(
|
|
921
|
-
chainManager,
|
|
922
|
-
~throttler=writeThrottlers.chainMetaData,
|
|
923
|
-
~persistence=state.ctx.persistence,
|
|
924
|
-
)->ignore
|
|
925
|
-
}
|
|
926
|
-
| NextQuery(chainCheck) =>
|
|
927
|
-
let fetchForChain = checkAndFetchForChain(
|
|
928
|
-
~waitForNewBlock,
|
|
929
|
-
~executeQuery,
|
|
930
|
-
~state,
|
|
931
|
-
~dispatchAction,
|
|
932
|
-
)
|
|
933
945
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
await state.chainManager.chainFetchers
|
|
946
|
+
switch chainCheck {
|
|
947
|
+
| Chain(chain) => await chain->fetchForChain
|
|
948
|
+
| CheckAllChains =>
|
|
949
|
+
//Mapping from the states chainManager so we can construct tests that don't use
|
|
950
|
+
//all chains
|
|
951
|
+
let _ = await state.chainManager.chainFetchers
|
|
941
952
|
->ChainMap.keys
|
|
942
953
|
->Array.map(fetchForChain(_))
|
|
943
954
|
->Promise.all
|
|
944
|
-
}
|
|
945
|
-
| ProcessEventBatch =>
|
|
946
|
-
if !state.currentlyProcessingBatch && !isPreparingRollback(state) {
|
|
947
|
-
//In the case of a rollback, use the provided in memory store
|
|
948
|
-
//With rolled back values
|
|
949
|
-
let rollbackInMemStore = switch state.rollbackState {
|
|
950
|
-
| RollbackReady({diffInMemoryStore}) => Some(diffInMemoryStore)
|
|
951
|
-
| _ => None
|
|
952
955
|
}
|
|
956
|
+
| ProcessEventBatch =>
|
|
957
|
+
if !state.currentlyProcessingBatch && !isPreparingRollback(state) {
|
|
958
|
+
//In the case of a rollback, use the provided in memory store
|
|
959
|
+
//With rolled back values
|
|
960
|
+
let rollbackInMemStore = switch state.rollbackState {
|
|
961
|
+
| RollbackReady({diffInMemoryStore}) => Some(diffInMemoryStore)
|
|
962
|
+
| _ => None
|
|
963
|
+
}
|
|
953
964
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
965
|
+
let batch =
|
|
966
|
+
state.chainManager->ChainManager.createBatch(
|
|
967
|
+
~batchSizeTarget=state.ctx.config.batchSize,
|
|
968
|
+
~isRollback=rollbackInMemStore !== None,
|
|
969
|
+
)
|
|
959
970
|
|
|
960
|
-
|
|
971
|
+
let progressedChainsById = batch.progressedChainsById
|
|
961
972
|
|
|
962
|
-
|
|
963
|
-
|
|
973
|
+
let isInReorgThreshold = state.chainManager.isInReorgThreshold
|
|
974
|
+
let shouldSaveHistory = state.ctx.config->Config.shouldSaveHistory(~isInReorgThreshold)
|
|
964
975
|
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
976
|
+
let isBelowReorgThreshold =
|
|
977
|
+
!state.chainManager.isInReorgThreshold && state.ctx.config.shouldRollbackOnReorg
|
|
978
|
+
let shouldEnterReorgThreshold =
|
|
979
|
+
isBelowReorgThreshold &&
|
|
980
|
+
state.chainManager.chainFetchers
|
|
981
|
+
->ChainMap.values
|
|
982
|
+
->Array.every(chainFetcher => {
|
|
983
|
+
let fetchState = switch progressedChainsById->Utils.Dict.dangerouslyGetByIntNonOption(
|
|
984
|
+
chainFetcher.fetchState.chainId,
|
|
985
|
+
) {
|
|
986
|
+
| Some(chainAfterBatch) => chainAfterBatch.fetchState
|
|
987
|
+
| None => chainFetcher.fetchState
|
|
988
|
+
}
|
|
989
|
+
fetchState->FetchState.isReadyToEnterReorgThreshold
|
|
990
|
+
})
|
|
980
991
|
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
992
|
+
if shouldEnterReorgThreshold {
|
|
993
|
+
dispatchAction(EnterReorgThreshold)
|
|
994
|
+
}
|
|
984
995
|
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
996
|
+
if progressedChainsById->Utils.Dict.isEmpty {
|
|
997
|
+
// When resuming from persisted state, all events may already be processed.
|
|
998
|
+
// Log the same completion message and handle exit just like EventBatchProcessed does.
|
|
999
|
+
if EventProcessing.allChainsEventsProcessedToEndblock(state.chainManager.chainFetchers) {
|
|
1000
|
+
Logging.info("All chains are caught up to end blocks.")
|
|
1001
|
+
if !state.keepProcessAlive {
|
|
1002
|
+
updateChainMetadataTable(
|
|
1003
|
+
state.chainManager,
|
|
1004
|
+
~persistence=state.ctx.persistence,
|
|
1005
|
+
~throttler=state.writeThrottlers.chainMetaData,
|
|
1006
|
+
)
|
|
1007
|
+
dispatchAction(SuccessExit)
|
|
1008
|
+
}
|
|
997
1009
|
}
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
dispatchAction(UpdateQueues({progressedChainsById, shouldEnterReorgThreshold}))
|
|
1010
|
+
} else {
|
|
1011
|
+
dispatchAction(StartProcessingBatch)
|
|
1012
|
+
dispatchAction(UpdateQueues({progressedChainsById, shouldEnterReorgThreshold}))
|
|
1002
1013
|
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1014
|
+
let inMemoryStore =
|
|
1015
|
+
rollbackInMemStore->Option.getOr(
|
|
1016
|
+
InMemoryStore.make(~entities=state.ctx.persistence.allEntities),
|
|
1017
|
+
)
|
|
1007
1018
|
|
|
1008
|
-
|
|
1019
|
+
inMemoryStore->InMemoryStore.setBatchDcs(~batch, ~shouldSaveHistory)
|
|
1009
1020
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
|
1027
|
-
|
|
1021
|
+
switch await EventProcessing.processEventBatch(
|
|
1022
|
+
~batch,
|
|
1023
|
+
~inMemoryStore,
|
|
1024
|
+
~isInReorgThreshold,
|
|
1025
|
+
~loadManager=state.loadManager,
|
|
1026
|
+
~ctx=state.ctx,
|
|
1027
|
+
~chainFetchers=state.chainManager.chainFetchers,
|
|
1028
|
+
) {
|
|
1029
|
+
| exception exn =>
|
|
1030
|
+
//All casese should be handled/caught before this with better user messaging.
|
|
1031
|
+
//This is just a safety in case something unexpected happens
|
|
1032
|
+
let errHandler =
|
|
1033
|
+
exn->ErrorHandling.make(
|
|
1034
|
+
~msg="A top level unexpected error occurred during processing",
|
|
1035
|
+
)
|
|
1036
|
+
dispatchAction(ErrorExit(errHandler))
|
|
1037
|
+
| res =>
|
|
1038
|
+
switch res {
|
|
1039
|
+
| Ok() => dispatchAction(EventBatchProcessed({batch: batch}))
|
|
1040
|
+
| Error(errHandler) => dispatchAction(ErrorExit(errHandler))
|
|
1041
|
+
}
|
|
1028
1042
|
}
|
|
1029
1043
|
}
|
|
1030
1044
|
}
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
dispatchAction(FindReorgDepth({chain, rollbackTargetBlockNumber}))
|
|
1045
|
-
}
|
|
1046
|
-
// We can come to this case when event batch finished processing
|
|
1047
|
-
// while we are still finding the reorg depth
|
|
1048
|
-
// Do nothing here, just wait for reorg depth to be found
|
|
1049
|
-
| {rollbackState: FindingReorgDepth} => ()
|
|
1050
|
-
| {rollbackState: FoundReorgDepth(_), currentlyProcessingBatch: true} =>
|
|
1051
|
-
Logging.info("Waiting for batch to finish processing before executing rollback")
|
|
1052
|
-
| {rollbackState: FoundReorgDepth({chain: reorgChain, rollbackTargetBlockNumber})} =>
|
|
1053
|
-
let startTime = Hrtime.makeTimer()
|
|
1054
|
-
|
|
1055
|
-
let chainFetcher = state.chainManager.chainFetchers->ChainMap.get(reorgChain)
|
|
1056
|
-
|
|
1057
|
-
let logger = Logging.createChildFrom(
|
|
1058
|
-
~logger=chainFetcher.logger,
|
|
1059
|
-
~params={
|
|
1060
|
-
"action": "Rollback",
|
|
1061
|
-
"reorgChain": reorgChain,
|
|
1062
|
-
"targetBlockNumber": rollbackTargetBlockNumber,
|
|
1063
|
-
},
|
|
1064
|
-
)
|
|
1065
|
-
logger->Logging.childInfo("Started rollback on reorg")
|
|
1066
|
-
Prometheus.RollbackTargetBlockNumber.set(
|
|
1067
|
-
~blockNumber=rollbackTargetBlockNumber,
|
|
1068
|
-
~chain=reorgChain,
|
|
1069
|
-
)
|
|
1070
|
-
|
|
1071
|
-
let reorgChainId = reorgChain->ChainMap.Chain.toChainId
|
|
1045
|
+
| Rollback =>
|
|
1046
|
+
//If it isn't processing a batch currently continue with rollback otherwise wait for current batch to finish processing
|
|
1047
|
+
switch state {
|
|
1048
|
+
| {rollbackState: NoRollback | RollbackReady(_)} =>
|
|
1049
|
+
JsError.throwWithMessage("Internal error: Rollback initiated with invalid state")
|
|
1050
|
+
| {rollbackState: ReorgDetected({chain, blockNumber: reorgBlockNumber})} => {
|
|
1051
|
+
let chainFetcher = state.chainManager.chainFetchers->ChainMap.get(chain)
|
|
1052
|
+
|
|
1053
|
+
dispatchAction(StartFindingReorgDepth)
|
|
1054
|
+
let rollbackTargetBlockNumber = await chainFetcher->getLastKnownValidBlock(
|
|
1055
|
+
~reorgBlockNumber,
|
|
1056
|
+
)
|
|
1072
1057
|
|
|
1073
|
-
|
|
1074
|
-
switch await state.ctx.persistence.storage.getRollbackTargetCheckpoint(
|
|
1075
|
-
~reorgChainId,
|
|
1076
|
-
~lastKnownValidBlockNumber=rollbackTargetBlockNumber,
|
|
1077
|
-
) {
|
|
1078
|
-
| Some(checkpointId) => checkpointId
|
|
1079
|
-
| None => 0n
|
|
1058
|
+
dispatchAction(FindReorgDepth({chain, rollbackTargetBlockNumber}))
|
|
1080
1059
|
}
|
|
1081
|
-
|
|
1060
|
+
// We can come to this case when event batch finished processing
|
|
1061
|
+
// while we are still finding the reorg depth
|
|
1062
|
+
// Do nothing here, just wait for reorg depth to be found
|
|
1063
|
+
| {rollbackState: FindingReorgDepth} => ()
|
|
1064
|
+
| {rollbackState: FoundReorgDepth(_), currentlyProcessingBatch: true} =>
|
|
1065
|
+
Logging.info("Waiting for batch to finish processing before executing rollback")
|
|
1066
|
+
| {rollbackState: FoundReorgDepth({chain: reorgChain, rollbackTargetBlockNumber})} =>
|
|
1067
|
+
let startTime = Hrtime.makeTimer()
|
|
1068
|
+
|
|
1069
|
+
let chainFetcher = state.chainManager.chainFetchers->ChainMap.get(reorgChain)
|
|
1070
|
+
|
|
1071
|
+
let logger = Logging.createChildFrom(
|
|
1072
|
+
~logger=chainFetcher.logger,
|
|
1073
|
+
~params={
|
|
1074
|
+
"action": "Rollback",
|
|
1075
|
+
"reorgChain": reorgChain,
|
|
1076
|
+
"targetBlockNumber": rollbackTargetBlockNumber,
|
|
1077
|
+
},
|
|
1078
|
+
)
|
|
1079
|
+
logger->Logging.childInfo("Started rollback on reorg")
|
|
1080
|
+
Prometheus.RollbackTargetBlockNumber.set(
|
|
1081
|
+
~blockNumber=rollbackTargetBlockNumber,
|
|
1082
|
+
~chain=reorgChain,
|
|
1083
|
+
)
|
|
1082
1084
|
|
|
1083
|
-
|
|
1084
|
-
let newProgressBlockNumberPerChain = Js.Dict.empty()
|
|
1085
|
-
let rollbackedProcessedEvents = ref(0.)
|
|
1085
|
+
let reorgChainId = reorgChain->ChainMap.Chain.toChainId
|
|
1086
1086
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
{
|
|
1096
|
-
let eventsProcessedDiff =
|
|
1097
|
-
Float.fromString(diff["events_processed_diff"])->Option.getExn
|
|
1098
|
-
rollbackedProcessedEvents := rollbackedProcessedEvents.contents +. eventsProcessedDiff
|
|
1099
|
-
eventsProcessedDiff
|
|
1100
|
-
},
|
|
1101
|
-
)
|
|
1102
|
-
newProgressBlockNumberPerChain->Utils.Dict.setByInt(
|
|
1103
|
-
diff["chain_id"],
|
|
1104
|
-
if rollbackTargetCheckpointId === 0n && diff["chain_id"] === reorgChainId {
|
|
1105
|
-
Pervasives.min(diff["new_progress_block_number"], rollbackTargetBlockNumber)
|
|
1106
|
-
} else {
|
|
1107
|
-
diff["new_progress_block_number"]
|
|
1108
|
-
},
|
|
1109
|
-
)
|
|
1087
|
+
let rollbackTargetCheckpointId = {
|
|
1088
|
+
switch await state.ctx.persistence.storage.getRollbackTargetCheckpoint(
|
|
1089
|
+
~reorgChainId,
|
|
1090
|
+
~lastKnownValidBlockNumber=rollbackTargetBlockNumber,
|
|
1091
|
+
) {
|
|
1092
|
+
| Some(checkpointId) => checkpointId
|
|
1093
|
+
| None => 0n
|
|
1094
|
+
}
|
|
1110
1095
|
}
|
|
1111
|
-
}
|
|
1112
1096
|
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
let
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
->Utils.Dict.
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1097
|
+
let eventsProcessedDiffByChain = Dict.make()
|
|
1098
|
+
let newProgressBlockNumberPerChain = Dict.make()
|
|
1099
|
+
let rollbackedProcessedEvents = ref(0.)
|
|
1100
|
+
|
|
1101
|
+
{
|
|
1102
|
+
let rollbackProgressDiff = await state.ctx.persistence.storage.getRollbackProgressDiff(
|
|
1103
|
+
~rollbackTargetCheckpointId,
|
|
1104
|
+
)
|
|
1105
|
+
for idx in 0 to rollbackProgressDiff->Array.length - 1 {
|
|
1106
|
+
let diff = rollbackProgressDiff->Array.getUnsafe(idx)
|
|
1107
|
+
eventsProcessedDiffByChain->Utils.Dict.setByInt(
|
|
1108
|
+
diff["chain_id"],
|
|
1109
|
+
{
|
|
1110
|
+
let eventsProcessedDiff =
|
|
1111
|
+
Float.fromString(diff["events_processed_diff"])->Option.getOrThrow
|
|
1112
|
+
rollbackedProcessedEvents :=
|
|
1113
|
+
rollbackedProcessedEvents.contents +. eventsProcessedDiff
|
|
1114
|
+
eventsProcessedDiff
|
|
1115
|
+
},
|
|
1130
1116
|
)
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1117
|
+
newProgressBlockNumberPerChain->Utils.Dict.setByInt(
|
|
1118
|
+
diff["chain_id"],
|
|
1119
|
+
if rollbackTargetCheckpointId === 0n && diff["chain_id"] === reorgChainId {
|
|
1120
|
+
Pervasives.min(diff["new_progress_block_number"], rollbackTargetBlockNumber)
|
|
1121
|
+
} else {
|
|
1122
|
+
diff["new_progress_block_number"]
|
|
1123
|
+
},
|
|
1136
1124
|
)
|
|
1137
1125
|
}
|
|
1126
|
+
}
|
|
1138
1127
|
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1128
|
+
let chainFetchers = state.chainManager.chainFetchers->ChainMap.mapWithKey((chain, cf) => {
|
|
1129
|
+
switch newProgressBlockNumberPerChain->Utils.Dict.dangerouslyGetByIntNonOption(
|
|
1130
|
+
chain->ChainMap.Chain.toChainId,
|
|
1131
|
+
) {
|
|
1132
|
+
| Some(newProgressBlockNumber) =>
|
|
1133
|
+
let fetchState =
|
|
1134
|
+
cf.fetchState->FetchState.rollback(~targetBlockNumber=newProgressBlockNumber)
|
|
1135
|
+
let newTotalEventsProcessed =
|
|
1136
|
+
cf.numEventsProcessed -.
|
|
1137
|
+
eventsProcessedDiffByChain
|
|
1138
|
+
->Utils.Dict.dangerouslyGetByIntNonOption(chain->ChainMap.Chain.toChainId)
|
|
1139
|
+
->Option.getUnsafe
|
|
1140
|
+
|
|
1141
|
+
if cf.committedProgressBlockNumber !== newProgressBlockNumber {
|
|
1142
|
+
Prometheus.ProgressBlockNumber.set(
|
|
1143
|
+
~blockNumber=newProgressBlockNumber,
|
|
1144
|
+
~chainId=chain->ChainMap.Chain.toChainId,
|
|
1152
1145
|
)
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1146
|
+
}
|
|
1147
|
+
if cf.numEventsProcessed !== newTotalEventsProcessed {
|
|
1148
|
+
Prometheus.ProgressEventsCount.set(
|
|
1149
|
+
~processedCount=newTotalEventsProcessed,
|
|
1150
|
+
~chainId=chain->ChainMap.Chain.toChainId,
|
|
1151
|
+
)
|
|
1152
|
+
}
|
|
1159
1153
|
|
|
1160
|
-
| None =>
|
|
1161
|
-
// Even without a progress diff entry, the reorg chain must have its
|
|
1162
|
-
// reorgDetection and fetchState rolled back. Otherwise the stale block hash
|
|
1163
|
-
// stays in dataByBlockNumber and the same reorg is re-detected on the next
|
|
1164
|
-
// fetch, causing an infinite reorg→rollback loop.
|
|
1165
|
-
if chain == reorgChain {
|
|
1166
1154
|
{
|
|
1167
1155
|
...cf,
|
|
1168
|
-
reorgDetection:
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1156
|
+
reorgDetection: chain == reorgChain
|
|
1157
|
+
? cf.reorgDetection->ReorgDetection.rollbackToValidBlockNumber(
|
|
1158
|
+
~blockNumber=rollbackTargetBlockNumber,
|
|
1159
|
+
)
|
|
1160
|
+
: cf.reorgDetection,
|
|
1161
|
+
safeCheckpointTracking: switch cf.safeCheckpointTracking {
|
|
1162
|
+
| Some(safeCheckpointTracking) =>
|
|
1163
|
+
Some(
|
|
1164
|
+
safeCheckpointTracking->SafeCheckpointTracking.rollback(
|
|
1165
|
+
~targetBlockNumber=newProgressBlockNumber,
|
|
1166
|
+
),
|
|
1167
|
+
)
|
|
1168
|
+
| None => None
|
|
1169
|
+
},
|
|
1170
|
+
fetchState,
|
|
1171
|
+
committedProgressBlockNumber: newProgressBlockNumber,
|
|
1172
|
+
numEventsProcessed: newTotalEventsProcessed,
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
| None =>
|
|
1176
|
+
// Even without a progress diff entry, the reorg chain must have its
|
|
1177
|
+
// reorgDetection and fetchState rolled back. Otherwise the stale block hash
|
|
1178
|
+
// stays in dataByBlockNumber and the same reorg is re-detected on the next
|
|
1179
|
+
// fetch, causing an infinite reorg→rollback loop.
|
|
1180
|
+
if chain == reorgChain {
|
|
1181
|
+
{
|
|
1182
|
+
...cf,
|
|
1183
|
+
reorgDetection: cf.reorgDetection->ReorgDetection.rollbackToValidBlockNumber(
|
|
1184
|
+
~blockNumber=rollbackTargetBlockNumber,
|
|
1185
|
+
),
|
|
1186
|
+
fetchState: cf.fetchState->FetchState.rollback(
|
|
1187
|
+
~targetBlockNumber=rollbackTargetBlockNumber,
|
|
1188
|
+
),
|
|
1189
|
+
}
|
|
1190
|
+
} else {
|
|
1191
|
+
cf
|
|
1174
1192
|
}
|
|
1175
|
-
} else {
|
|
1176
|
-
cf
|
|
1177
1193
|
}
|
|
1178
|
-
}
|
|
1179
|
-
})
|
|
1194
|
+
})
|
|
1180
1195
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
await state.ctx.persistence->Persistence.prepareRollbackDiff(
|
|
1196
|
+
// Construct in Memory store with rollback diff
|
|
1197
|
+
let diff = await state.ctx.persistence->Persistence.prepareRollbackDiff(
|
|
1184
1198
|
~rollbackTargetCheckpointId,
|
|
1185
1199
|
~rollbackDiffCheckpointId=state.chainManager.committedCheckpointId->BigInt.add(1n),
|
|
1186
1200
|
)
|
|
1187
1201
|
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1202
|
+
let chainManager = {
|
|
1203
|
+
...state.chainManager,
|
|
1204
|
+
chainFetchers,
|
|
1205
|
+
}
|
|
1192
1206
|
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
+
logger->Logging.childTrace({
|
|
1208
|
+
"msg": "Finished rollback on reorg",
|
|
1209
|
+
"entityChanges": {
|
|
1210
|
+
"deleted": diff["deletedEntities"],
|
|
1211
|
+
"upserted": diff["setEntities"],
|
|
1212
|
+
},
|
|
1213
|
+
"rollbackedEvents": rollbackedProcessedEvents.contents,
|
|
1214
|
+
"beforeCheckpointId": state.chainManager.committedCheckpointId,
|
|
1215
|
+
"targetCheckpointId": rollbackTargetCheckpointId,
|
|
1216
|
+
})
|
|
1217
|
+
Prometheus.RollbackSuccess.increment(
|
|
1218
|
+
~timeSeconds=Hrtime.timeSince(startTime)->Hrtime.toSecondsFloat,
|
|
1219
|
+
~rollbackedProcessedEvents=rollbackedProcessedEvents.contents,
|
|
1220
|
+
)
|
|
1207
1221
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1222
|
+
dispatchAction(
|
|
1223
|
+
SetRollbackState({
|
|
1224
|
+
diffInMemoryStore: diff["inMemStore"],
|
|
1225
|
+
rollbackedChainManager: chainManager,
|
|
1226
|
+
eventsProcessedDiffByChain,
|
|
1227
|
+
}),
|
|
1228
|
+
)
|
|
1229
|
+
}
|
|
1215
1230
|
}
|
|
1216
1231
|
}
|
|
1217
|
-
}
|
|
1218
1232
|
|
|
1219
1233
|
let taskReducer = injectedTaskReducer(
|
|
1220
1234
|
~waitForNewBlock=SourceManager.waitForNewBlock,
|