envio 3.3.0 → 3.3.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/ChainFetching.res +4 -32
- package/src/ChainFetching.res.mjs +2 -12
- package/src/ChainState.res +73 -53
- package/src/ChainState.res.mjs +61 -30
- package/src/ChainState.resi +13 -17
- package/src/Config.res +5 -0
- package/src/Config.res.mjs +1 -0
- package/src/CrossChainState.res +2 -8
- package/src/CrossChainState.res.mjs +6 -8
- package/src/CrossChainState.resi +1 -0
- package/src/EffectState.res +183 -44
- package/src/EffectState.res.mjs +134 -26
- package/src/EffectState.resi +26 -3
- package/src/EventProcessing.res +14 -9
- package/src/EventProcessing.res.mjs +7 -7
- package/src/FetchState.res +18 -29
- package/src/FetchState.res.mjs +20 -37
- package/src/IndexerState.res +280 -31
- package/src/IndexerState.res.mjs +234 -25
- package/src/IndexerState.resi +22 -0
- package/src/LoadLayer.res +19 -65
- package/src/LoadLayer.res.mjs +13 -55
- package/src/Main.res +42 -23
- package/src/Main.res.mjs +32 -35
- package/src/Metrics.res +943 -66
- package/src/Metrics.res.mjs +367 -50
- package/src/Persistence.res +3 -0
- package/src/PgStorage.res +3 -8
- package/src/PgStorage.res.mjs +3 -4
- package/src/PruneStaleHistory.res +1 -1
- package/src/PruneStaleHistory.res.mjs +1 -2
- package/src/Rollback.res +4 -5
- package/src/Rollback.res.mjs +2 -3
- package/src/SimulateItems.res.mjs +3 -21
- package/src/TestIndexer.res.mjs +4 -23
- package/src/TestIndexerProxyStorage.res +1 -0
- package/src/TestIndexerProxyStorage.res.mjs +1 -1
- package/src/Writing.res +3 -5
- package/src/Writing.res.mjs +3 -6
- package/src/bindings/ClickHouse.res +101 -17
- package/src/bindings/ClickHouse.res.mjs +58 -19
- package/src/bindings/NodeJs.res +64 -0
- package/src/bindings/NodeJs.res.mjs +6 -0
- package/src/sources/HyperSyncClient.res +5 -11
- package/src/sources/SourceManager.res +72 -27
- package/src/sources/SourceManager.res.mjs +81 -11
- package/src/sources/SourceManager.resi +14 -0
- package/src/tui/Tui.res +1 -1
- package/src/tui/Tui.res.mjs +2 -2
- package/src/Prometheus.res +0 -789
- package/src/Prometheus.res.mjs +0 -847
- package/src/bindings/PromClient.res +0 -72
- package/src/bindings/PromClient.res.mjs +0 -38
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.mjs",
|
|
@@ -54,7 +54,6 @@
|
|
|
54
54
|
"express": "4.19.2",
|
|
55
55
|
"pino": "10.3.1",
|
|
56
56
|
"pino-pretty": "13.1.3",
|
|
57
|
-
"prom-client": "15.1.3",
|
|
58
57
|
"yargs": "17.7.2",
|
|
59
58
|
"@rescript/runtime": "12.2.0",
|
|
60
59
|
"rescript-schema": "9.5.1",
|
|
@@ -70,10 +69,10 @@
|
|
|
70
69
|
"tsx": "4.21.0"
|
|
71
70
|
},
|
|
72
71
|
"optionalDependencies": {
|
|
73
|
-
"envio-linux-x64": "3.3.
|
|
74
|
-
"envio-linux-x64-musl": "3.3.
|
|
75
|
-
"envio-linux-arm64": "3.3.
|
|
76
|
-
"envio-darwin-x64": "3.3.
|
|
77
|
-
"envio-darwin-arm64": "3.3.
|
|
72
|
+
"envio-linux-x64": "3.3.1",
|
|
73
|
+
"envio-linux-x64-musl": "3.3.1",
|
|
74
|
+
"envio-linux-arm64": "3.3.1",
|
|
75
|
+
"envio-darwin-x64": "3.3.1",
|
|
76
|
+
"envio-darwin-arm64": "3.3.1"
|
|
78
77
|
}
|
|
79
78
|
}
|
package/src/ChainFetching.res
CHANGED
|
@@ -128,19 +128,7 @@ let rec onQueryResponse = async (
|
|
|
128
128
|
fromBlockQueried,
|
|
129
129
|
} = response
|
|
130
130
|
|
|
131
|
-
|
|
132
|
-
Prometheus.SourceHeight.set(
|
|
133
|
-
~blockNumber=knownHeight,
|
|
134
|
-
~chainId=(chainState->ChainState.chainConfig).id,
|
|
135
|
-
// The knownHeight from response won't necessarily
|
|
136
|
-
// belong to the currently active source.
|
|
137
|
-
// But for simplicity, assume it does.
|
|
138
|
-
~sourceName=(chainState->ChainState.sourceManager->SourceManager.getActiveSource).name,
|
|
139
|
-
)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
Prometheus.FetchingBlockRange.increment(
|
|
143
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
131
|
+
chainState->ChainState.recordBlockRangeFetch(
|
|
144
132
|
~totalTimeElapsed=stats.totalTimeElapsed,
|
|
145
133
|
~parsingTimeElapsed=stats.parsingTimeElapsed->Option.getOr(0.),
|
|
146
134
|
~numEvents=parsedQueueItems->Array.length,
|
|
@@ -183,10 +171,8 @@ let rec onQueryResponse = async (
|
|
|
183
171
|
~shouldRollbackOnReorg=(state->IndexerState.config).shouldRollbackOnReorg,
|
|
184
172
|
),
|
|
185
173
|
)
|
|
186
|
-
|
|
187
|
-
Prometheus.ReorgDetectionBlockNumber.set(
|
|
174
|
+
chainState->ChainState.recordReorgDetected(
|
|
188
175
|
~blockNumber=reorgDetected.scannedBlock.blockNumber,
|
|
189
|
-
~chain,
|
|
190
176
|
)
|
|
191
177
|
if (state->IndexerState.config).shouldRollbackOnReorg {
|
|
192
178
|
Some(reorgDetected.scannedBlock.blockNumber)
|
|
@@ -333,22 +319,8 @@ let finishWaitingForNewBlock = (
|
|
|
333
319
|
let chainState = state->IndexerState.getChainState(~chain)
|
|
334
320
|
chainState->ChainState.updateKnownHeight(~knownHeight)
|
|
335
321
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
(state->IndexerState.config).shouldRollbackOnReorg
|
|
339
|
-
let shouldEnterReorgThreshold =
|
|
340
|
-
isBelowReorgThreshold &&
|
|
341
|
-
state
|
|
342
|
-
->IndexerState.chainStates
|
|
343
|
-
->Dict.valuesToArray
|
|
344
|
-
->Array.every(cs => {
|
|
345
|
-
cs->ChainState.isReadyToEnterReorgThreshold
|
|
346
|
-
})
|
|
347
|
-
|
|
348
|
-
// Kick processing in case there are block handlers to run.
|
|
349
|
-
if shouldEnterReorgThreshold {
|
|
350
|
-
IndexerState.enterReorgThreshold(state)
|
|
351
|
-
}
|
|
322
|
+
// No reorg-threshold check here: scheduleProcessing always runs at least one
|
|
323
|
+
// processNextBatch (even with no items), which owns the entry decision.
|
|
352
324
|
scheduleFetch()
|
|
353
325
|
scheduleProcessing()
|
|
354
326
|
}
|
|
@@ -4,7 +4,6 @@ import * as Utils from "./Utils.res.mjs";
|
|
|
4
4
|
import * as Logging from "./Logging.res.mjs";
|
|
5
5
|
import * as Ecosystem from "./Ecosystem.res.mjs";
|
|
6
6
|
import * as ChainState from "./ChainState.res.mjs";
|
|
7
|
-
import * as Prometheus from "./Prometheus.res.mjs";
|
|
8
7
|
import * as IndexerState from "./IndexerState.res.mjs";
|
|
9
8
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
10
9
|
import * as ChainMetadata from "./ChainMetadata.res.mjs";
|
|
@@ -100,10 +99,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
100
99
|
let transactionStore = response.transactionStore;
|
|
101
100
|
let parsedQueueItems = response.parsedQueueItems;
|
|
102
101
|
let knownHeight = response.knownHeight;
|
|
103
|
-
|
|
104
|
-
Prometheus.SourceHeight.set(SourceManager.getActiveSource(ChainState.sourceManager(chainState)).name, ChainState.chainConfig(chainState).id, knownHeight);
|
|
105
|
-
}
|
|
106
|
-
Prometheus.FetchingBlockRange.increment(chain, stats["total time elapsed (s)"], Stdlib_Option.getOr(stats["parsing time (s)"], 0), parsedQueueItems.length, (latestFetchedBlockNumber - fromBlockQueried | 0) + 1 | 0);
|
|
102
|
+
ChainState.recordBlockRangeFetch(chainState, stats["total time elapsed (s)"], Stdlib_Option.getOr(stats["parsing time (s)"], 0), parsedQueueItems.length, (latestFetchedBlockNumber - fromBlockQueried | 0) + 1 | 0);
|
|
107
103
|
let numContractRegisterEvents = Stdlib_Array.reduce(parsedQueueItems, 0, (count, item) => {
|
|
108
104
|
if (item.onEventRegistration.contractRegister !== undefined) {
|
|
109
105
|
return count + 1 | 0;
|
|
@@ -138,8 +134,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
138
134
|
} else {
|
|
139
135
|
let reorgDetected = reorgResult._0;
|
|
140
136
|
Logging.childInfo(ChainState.logger(chainState), ReorgDetection.reorgDetectedToLogParams(reorgDetected, IndexerState.config(state).shouldRollbackOnReorg));
|
|
141
|
-
|
|
142
|
-
Prometheus.ReorgDetectionBlockNumber.set(reorgDetected.scannedBlock.blockNumber, chain);
|
|
137
|
+
ChainState.recordReorgDetected(chainState, reorgDetected.scannedBlock.blockNumber);
|
|
143
138
|
rollbackWithReorgDetectedBlockNumber = IndexerState.config(state).shouldRollbackOnReorg ? reorgDetected.scannedBlock.blockNumber : undefined;
|
|
144
139
|
}
|
|
145
140
|
if (rollbackWithReorgDetectedBlockNumber !== undefined) {
|
|
@@ -188,11 +183,6 @@ function finishWaitingForNewBlock(state, chain, knownHeight, stateId, scheduleFe
|
|
|
188
183
|
}
|
|
189
184
|
let chainState = IndexerState.getChainState(state, chain);
|
|
190
185
|
ChainState.updateKnownHeight(chainState, knownHeight);
|
|
191
|
-
let isBelowReorgThreshold = !IndexerState.isInReorgThreshold(state) && IndexerState.config(state).shouldRollbackOnReorg;
|
|
192
|
-
let shouldEnterReorgThreshold = isBelowReorgThreshold && Object.values(IndexerState.chainStates(state)).every(ChainState.isReadyToEnterReorgThreshold);
|
|
193
|
-
if (shouldEnterReorgThreshold) {
|
|
194
|
-
IndexerState.enterReorgThreshold(state);
|
|
195
|
-
}
|
|
196
186
|
scheduleFetch();
|
|
197
187
|
scheduleProcessing();
|
|
198
188
|
}
|
package/src/ChainState.res
CHANGED
|
@@ -39,24 +39,18 @@ type t = {
|
|
|
39
39
|
// Holds this chain's blocks (kept in Rust) keyed by block number. Same merge /
|
|
40
40
|
// prune / rollback lifecycle as the transaction store.
|
|
41
41
|
blockStore: BlockStore.t,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
@as("currentBlockHeight")
|
|
55
|
-
knownHeight: int,
|
|
56
|
-
numBatchesFetched: int,
|
|
57
|
-
startBlock: int,
|
|
58
|
-
endBlock: option<int>,
|
|
59
|
-
numAddresses: int,
|
|
42
|
+
reorgThresholdReadyTolerance: int,
|
|
43
|
+
// --- Per-chain metric counters, rendered by Metrics at scrape time.
|
|
44
|
+
// Floats: cumulative counters outgrow int32. ---
|
|
45
|
+
mutable blockRangeFetchSeconds: float,
|
|
46
|
+
mutable blockRangeParseSeconds: float,
|
|
47
|
+
mutable blockRangeFetchCount: float,
|
|
48
|
+
mutable blockRangeFetchedEvents: float,
|
|
49
|
+
mutable blockRangeFetchedBlocks: float,
|
|
50
|
+
mutable reorgCount: int,
|
|
51
|
+
mutable reorgDetectedBlock: option<int>,
|
|
52
|
+
mutable rollbackTargetBlock: option<int>,
|
|
53
|
+
mutable progressLatencyMs: option<int>,
|
|
60
54
|
}
|
|
61
55
|
|
|
62
56
|
let configAddresses = (chainConfig: Config.chain): array<Internal.indexingAddress> => {
|
|
@@ -100,6 +94,7 @@ let make = (
|
|
|
100
94
|
~transactionStore=TransactionStore.make(~ecosystem=Ecosystem.Evm, ~shouldChecksum=false),
|
|
101
95
|
~chainDensity=None,
|
|
102
96
|
~blockStore=BlockStore.make(~ecosystem=Ecosystem.Evm, ~shouldChecksum=false),
|
|
97
|
+
~reorgThresholdReadyTolerance=100,
|
|
103
98
|
~logger: Pino.t,
|
|
104
99
|
): t => {
|
|
105
100
|
validateOnEventRegistrations(~chainId=chainConfig.id, onEventRegistrations)
|
|
@@ -121,6 +116,16 @@ let make = (
|
|
|
121
116
|
safeCheckpointTracking,
|
|
122
117
|
transactionStore,
|
|
123
118
|
blockStore,
|
|
119
|
+
reorgThresholdReadyTolerance,
|
|
120
|
+
blockRangeFetchSeconds: 0.,
|
|
121
|
+
blockRangeParseSeconds: 0.,
|
|
122
|
+
blockRangeFetchCount: 0.,
|
|
123
|
+
blockRangeFetchedEvents: 0.,
|
|
124
|
+
blockRangeFetchedBlocks: 0.,
|
|
125
|
+
reorgCount: 0,
|
|
126
|
+
reorgDetectedBlock: None,
|
|
127
|
+
rollbackTargetBlock: None,
|
|
128
|
+
progressLatencyMs: None,
|
|
124
129
|
}
|
|
125
130
|
}
|
|
126
131
|
|
|
@@ -282,6 +287,7 @@ let makeInternal = (
|
|
|
282
287
|
~ecosystem=config.ecosystem.name,
|
|
283
288
|
~shouldChecksum=!lowercaseAddresses,
|
|
284
289
|
),
|
|
290
|
+
~reorgThresholdReadyTolerance=config.reorgThresholdReadyTolerance,
|
|
285
291
|
~logger,
|
|
286
292
|
)
|
|
287
293
|
}
|
|
@@ -329,8 +335,6 @@ let makeFromDbState = (
|
|
|
329
335
|
let chainId = chainConfig.id
|
|
330
336
|
let logger = Logging.createChild(~params={"chainId": chainId})
|
|
331
337
|
|
|
332
|
-
Prometheus.ProgressEventsCount.set(~processedCount=resumedChainState.numEventsProcessed, ~chainId)
|
|
333
|
-
|
|
334
338
|
let progressBlockNumber =
|
|
335
339
|
// Can be -1 when not set
|
|
336
340
|
resumedChainState.progressBlockNumber >= 0
|
|
@@ -373,6 +377,29 @@ let numEventsProcessed = (cs: t) => cs.numEventsProcessed
|
|
|
373
377
|
let pendingBudget = (cs: t) => cs.pendingBudget
|
|
374
378
|
let timestampCaughtUpToHeadOrEndblock = (cs: t) => cs.timestampCaughtUpToHeadOrEndblock
|
|
375
379
|
|
|
380
|
+
// --- Metric counters. ---
|
|
381
|
+
|
|
382
|
+
let recordBlockRangeFetch = (
|
|
383
|
+
cs: t,
|
|
384
|
+
~totalTimeElapsed,
|
|
385
|
+
~parsingTimeElapsed,
|
|
386
|
+
~numEvents,
|
|
387
|
+
~blockRangeSize,
|
|
388
|
+
) => {
|
|
389
|
+
cs.blockRangeFetchSeconds = cs.blockRangeFetchSeconds +. totalTimeElapsed
|
|
390
|
+
cs.blockRangeParseSeconds = cs.blockRangeParseSeconds +. parsingTimeElapsed
|
|
391
|
+
cs.blockRangeFetchCount = cs.blockRangeFetchCount +. 1.
|
|
392
|
+
cs.blockRangeFetchedEvents = cs.blockRangeFetchedEvents +. numEvents->Int.toFloat
|
|
393
|
+
cs.blockRangeFetchedBlocks = cs.blockRangeFetchedBlocks +. blockRangeSize->Int.toFloat
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
let recordReorgDetected = (cs: t, ~blockNumber) => {
|
|
397
|
+
cs.reorgCount = cs.reorgCount + 1
|
|
398
|
+
cs.reorgDetectedBlock = Some(blockNumber)
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
let setRollbackTargetBlock = (cs: t, ~blockNumber) => cs.rollbackTargetBlock = Some(blockNumber)
|
|
402
|
+
|
|
376
403
|
// Fetch-frontier reads. The FetchState is owned here; callers go through these
|
|
377
404
|
// rather than reaching into it.
|
|
378
405
|
let knownHeight = (cs: t) => cs.fetchState.knownHeight
|
|
@@ -384,7 +411,6 @@ let getProgressPercentage = (cs: t) => cs.fetchState->FetchState.getProgressPerc
|
|
|
384
411
|
let chainDensity = (cs: t) => cs.chainDensity
|
|
385
412
|
let hasReadyItem = (cs: t) =>
|
|
386
413
|
cs.fetchState->FetchState.isActivelyIndexing && cs.fetchState->FetchState.hasReadyItem
|
|
387
|
-
let isReadyToEnterReorgThreshold = (cs: t) => cs.fetchState->FetchState.isReadyToEnterReorgThreshold
|
|
388
414
|
|
|
389
415
|
// Mark queries as in flight and reserve their estimated size against the shared
|
|
390
416
|
// buffer budget in one step, so the counter stays in sync with the pending
|
|
@@ -868,8 +894,7 @@ let toChainMetadata = (cs: t): InternalTable.Chains.metaFields => {
|
|
|
868
894
|
timestampCaughtUpToHeadOrEndblock: cs.timestampCaughtUpToHeadOrEndblock->Null.fromOption,
|
|
869
895
|
}
|
|
870
896
|
|
|
871
|
-
|
|
872
|
-
let toChainData = (cs: t): chainData => {
|
|
897
|
+
let toMetrics = (cs: t): Metrics.chainMetrics => {
|
|
873
898
|
chainId: cs.chainConfig.id->Int.toFloat,
|
|
874
899
|
poweredByHyperSync: (cs.sourceManager->SourceManager.getActiveSource).poweredByHyperSync,
|
|
875
900
|
firstEventBlockNumber: cs.fetchState.firstEventBlock,
|
|
@@ -886,6 +911,25 @@ let toChainData = (cs: t): chainData => {
|
|
|
886
911
|
startBlock: cs.fetchState.startBlock,
|
|
887
912
|
endBlock: cs.fetchState.endBlock,
|
|
888
913
|
numAddresses: cs.indexingAddresses->IndexingAddresses.size,
|
|
914
|
+
isReady: cs->isReady,
|
|
915
|
+
sourceBlockNumber: cs.fetchState.knownHeight,
|
|
916
|
+
progressBlockNumber: cs.committedProgressBlockNumber,
|
|
917
|
+
progressLatencyMs: cs.progressLatencyMs,
|
|
918
|
+
concurrency: cs.sourceManager->SourceManager.inFlightCount,
|
|
919
|
+
partitionsCount: cs.fetchState->FetchState.partitionsCount,
|
|
920
|
+
bufferSize: cs.fetchState->FetchState.bufferSize,
|
|
921
|
+
bufferBlockNumber: cs.fetchState->FetchState.bufferBlockNumber,
|
|
922
|
+
idleSeconds: cs.sourceManager->SourceManager.idleSeconds,
|
|
923
|
+
waitingForNewBlockSeconds: cs.sourceManager->SourceManager.waitingForNewBlockSeconds,
|
|
924
|
+
queryingSeconds: cs.sourceManager->SourceManager.queryingSeconds,
|
|
925
|
+
blockRangeFetchSeconds: cs.blockRangeFetchSeconds,
|
|
926
|
+
blockRangeParseSeconds: cs.blockRangeParseSeconds,
|
|
927
|
+
blockRangeFetchCount: cs.blockRangeFetchCount,
|
|
928
|
+
blockRangeFetchedEvents: cs.blockRangeFetchedEvents,
|
|
929
|
+
blockRangeFetchedBlocks: cs.blockRangeFetchedBlocks,
|
|
930
|
+
reorgCount: cs.reorgCount,
|
|
931
|
+
reorgDetectedBlock: cs.reorgDetectedBlock,
|
|
932
|
+
rollbackTargetBlock: cs.rollbackTargetBlock,
|
|
889
933
|
}
|
|
890
934
|
|
|
891
935
|
// Snapshot the inputs a batch build needs from this chain.
|
|
@@ -907,7 +951,7 @@ let isReadyToEnterReorgThresholdAfterBatch = (cs: t, ~batch: Batch.t) => {
|
|
|
907
951
|
| Some(chainAfterBatch) => chainAfterBatch.fetchState
|
|
908
952
|
| None => cs.fetchState
|
|
909
953
|
}
|
|
910
|
-
fetchState->FetchState.isReadyToEnterReorgThreshold
|
|
954
|
+
fetchState->FetchState.isReadyToEnterReorgThreshold(~tolerance=cs.reorgThresholdReadyTolerance)
|
|
911
955
|
}
|
|
912
956
|
|
|
913
957
|
// Commit the post-batch fetch frontier for a chain that progressed in the batch,
|
|
@@ -928,28 +972,15 @@ let advanceAfterBatch = (cs: t, ~batch: Batch.t, ~enteringReorgThreshold) =>
|
|
|
928
972
|
}
|
|
929
973
|
|
|
930
974
|
// Commit a processed batch's progress for this chain (progress block, events
|
|
931
|
-
// processed, head/safe-checkpoint tracking, first event block).
|
|
932
|
-
//
|
|
933
|
-
//
|
|
934
|
-
//
|
|
975
|
+
// processed, head/safe-checkpoint tracking, first event block). Readiness is
|
|
976
|
+
// decided by CrossChainState once every chain is caught up (see markReady).
|
|
977
|
+
// `blockTimestampName` is the ecosystem's block-timestamp field, read off the
|
|
978
|
+
// payload block for the latency metric.
|
|
935
979
|
let applyBatchProgress = (cs: t, ~batch: Batch.t, ~blockTimestampName: string) => {
|
|
936
980
|
let chainId = cs.chainConfig.id
|
|
937
981
|
|
|
938
982
|
switch batch.progressedChainsById->Utils.Dict.dangerouslyGetByIntNonOption(chainId) {
|
|
939
983
|
| Some(chainAfterBatch) => {
|
|
940
|
-
if cs.committedProgressBlockNumber !== chainAfterBatch.progressBlockNumber {
|
|
941
|
-
Prometheus.ProgressBlockNumber.set(
|
|
942
|
-
~blockNumber=chainAfterBatch.progressBlockNumber,
|
|
943
|
-
~chainId,
|
|
944
|
-
)
|
|
945
|
-
}
|
|
946
|
-
if cs.numEventsProcessed !== chainAfterBatch.totalEventsProcessed {
|
|
947
|
-
Prometheus.ProgressEventsCount.set(
|
|
948
|
-
~processedCount=chainAfterBatch.totalEventsProcessed,
|
|
949
|
-
~chainId,
|
|
950
|
-
)
|
|
951
|
-
}
|
|
952
|
-
|
|
953
984
|
// Calculate and set latency metrics. The payload block is materialised or
|
|
954
985
|
// inline by processing time; its timestamp may still be absent (e.g. an
|
|
955
986
|
// SVM slot with no block row) — the metric is skipped then.
|
|
@@ -967,10 +998,7 @@ let applyBatchProgress = (cs: t, ~batch: Batch.t, ~blockTimestampName: string) =
|
|
|
967
998
|
) {
|
|
968
999
|
| Some(blockTimestamp) =>
|
|
969
1000
|
let blockTimestampMs = blockTimestamp->(Utils.magic: unknown => int) * 1000
|
|
970
|
-
|
|
971
|
-
~latencyMs=Date.now()->Float.toInt - blockTimestampMs,
|
|
972
|
-
~chainId,
|
|
973
|
-
)
|
|
1001
|
+
cs.progressLatencyMs = Some(Date.now()->Float.toInt - blockTimestampMs)
|
|
974
1002
|
| None => ()
|
|
975
1003
|
}
|
|
976
1004
|
|
|
@@ -1046,7 +1074,6 @@ let applyBatchProgress = (cs: t, ~batch: Batch.t, ~blockTimestampName: string) =
|
|
|
1046
1074
|
let markReady = (cs: t) =>
|
|
1047
1075
|
if !(cs->isReady) {
|
|
1048
1076
|
cs.timestampCaughtUpToHeadOrEndblock = Date.make()->Some
|
|
1049
|
-
Prometheus.ProgressReady.set(~chainId=cs.chainConfig.id)
|
|
1050
1077
|
}
|
|
1051
1078
|
|
|
1052
1079
|
// Roll a chain back to a reorg target. With a progress diff, restore fetch/
|
|
@@ -1061,7 +1088,6 @@ let rollback = (
|
|
|
1061
1088
|
~rollbackTargetBlockNumber,
|
|
1062
1089
|
~isReorgChain,
|
|
1063
1090
|
) => {
|
|
1064
|
-
let chainId = cs.chainConfig.id
|
|
1065
1091
|
switch newProgressBlockNumber {
|
|
1066
1092
|
| Some(newProgressBlockNumber) =>
|
|
1067
1093
|
let newTotalEventsProcessed =
|
|
@@ -1072,12 +1098,6 @@ let rollback = (
|
|
|
1072
1098
|
~message="Missing events-processed diff for rolled-back chain",
|
|
1073
1099
|
)
|
|
1074
1100
|
|
|
1075
|
-
if cs.committedProgressBlockNumber !== newProgressBlockNumber {
|
|
1076
|
-
Prometheus.ProgressBlockNumber.set(~blockNumber=newProgressBlockNumber, ~chainId)
|
|
1077
|
-
}
|
|
1078
|
-
if cs.numEventsProcessed !== newTotalEventsProcessed {
|
|
1079
|
-
Prometheus.ProgressEventsCount.set(~processedCount=newTotalEventsProcessed, ~chainId)
|
|
1080
|
-
}
|
|
1081
1101
|
if isReorgChain {
|
|
1082
1102
|
cs.reorgDetection =
|
|
1083
1103
|
cs.reorgDetection->ReorgDetection.rollbackToValidBlockNumber(
|
package/src/ChainState.res.mjs
CHANGED
|
@@ -10,7 +10,6 @@ import * as EvmChain from "./sources/EvmChain.res.mjs";
|
|
|
10
10
|
import * as FieldMask from "./sources/FieldMask.res.mjs";
|
|
11
11
|
import * as BlockStore from "./sources/BlockStore.res.mjs";
|
|
12
12
|
import * as FetchState from "./FetchState.res.mjs";
|
|
13
|
-
import * as Prometheus from "./Prometheus.res.mjs";
|
|
14
13
|
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
15
14
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
16
15
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
@@ -48,7 +47,7 @@ function validateOnEventRegistrations(chainId, registrations) {
|
|
|
48
47
|
});
|
|
49
48
|
}
|
|
50
49
|
|
|
51
|
-
function make(chainConfig, fetchState, onEventRegistrationsOpt, indexingAddresses, sourceManager, reorgDetection, committedProgressBlockNumber, safeCheckpointTrackingOpt, numEventsProcessedOpt, timestampCaughtUpToHeadOrEndblockOpt, isProgressAtHeadOpt, transactionStoreOpt, chainDensityOpt, blockStoreOpt, logger) {
|
|
50
|
+
function make(chainConfig, fetchState, onEventRegistrationsOpt, indexingAddresses, sourceManager, reorgDetection, committedProgressBlockNumber, safeCheckpointTrackingOpt, numEventsProcessedOpt, timestampCaughtUpToHeadOrEndblockOpt, isProgressAtHeadOpt, transactionStoreOpt, chainDensityOpt, blockStoreOpt, reorgThresholdReadyToleranceOpt, logger) {
|
|
52
51
|
let onEventRegistrations = onEventRegistrationsOpt !== undefined ? onEventRegistrationsOpt : [];
|
|
53
52
|
let safeCheckpointTracking = safeCheckpointTrackingOpt !== undefined ? Primitive_option.valFromOption(safeCheckpointTrackingOpt) : undefined;
|
|
54
53
|
let numEventsProcessed = numEventsProcessedOpt !== undefined ? numEventsProcessedOpt : 0;
|
|
@@ -57,6 +56,7 @@ function make(chainConfig, fetchState, onEventRegistrationsOpt, indexingAddresse
|
|
|
57
56
|
let transactionStore = transactionStoreOpt !== undefined ? Primitive_option.valFromOption(transactionStoreOpt) : TransactionStore.make("evm", false);
|
|
58
57
|
let chainDensity = chainDensityOpt !== undefined ? Primitive_option.valFromOption(chainDensityOpt) : undefined;
|
|
59
58
|
let blockStore = blockStoreOpt !== undefined ? Primitive_option.valFromOption(blockStoreOpt) : BlockStore.make("evm", false);
|
|
59
|
+
let reorgThresholdReadyTolerance = reorgThresholdReadyToleranceOpt !== undefined ? reorgThresholdReadyToleranceOpt : 100;
|
|
60
60
|
validateOnEventRegistrations(chainConfig.id, onEventRegistrations);
|
|
61
61
|
return {
|
|
62
62
|
logger: logger,
|
|
@@ -75,7 +75,17 @@ function make(chainConfig, fetchState, onEventRegistrationsOpt, indexingAddresse
|
|
|
75
75
|
reorgDetection: reorgDetection,
|
|
76
76
|
safeCheckpointTracking: safeCheckpointTracking,
|
|
77
77
|
transactionStore: transactionStore,
|
|
78
|
-
blockStore: blockStore
|
|
78
|
+
blockStore: blockStore,
|
|
79
|
+
reorgThresholdReadyTolerance: reorgThresholdReadyTolerance,
|
|
80
|
+
blockRangeFetchSeconds: 0,
|
|
81
|
+
blockRangeParseSeconds: 0,
|
|
82
|
+
blockRangeFetchCount: 0,
|
|
83
|
+
blockRangeFetchedEvents: 0,
|
|
84
|
+
blockRangeFetchedBlocks: 0,
|
|
85
|
+
reorgCount: 0,
|
|
86
|
+
reorgDetectedBlock: undefined,
|
|
87
|
+
rollbackTargetBlock: undefined,
|
|
88
|
+
progressLatencyMs: undefined
|
|
79
89
|
};
|
|
80
90
|
}
|
|
81
91
|
|
|
@@ -147,7 +157,7 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
147
157
|
}
|
|
148
158
|
let firstEventBlock$1 = fetchState.firstEventBlock;
|
|
149
159
|
let chainDensity = firstEventBlock$1 !== undefined && progressBlockNumber > firstEventBlock$1 && numEventsProcessed > 0 ? numEventsProcessed / (progressBlockNumber - firstEventBlock$1 | 0) : undefined;
|
|
150
|
-
return make(chainConfig, fetchState, onEventRegistrations, indexingAddressIndex, SourceManager.make(sources$1, isRealtime, undefined, undefined, undefined, reducedPollingInterval, undefined, undefined), ReorgDetection.make(chainReorgCheckpoints, maxReorgDepth, config.shouldRollbackOnReorg), progressBlockNumber, Primitive_option.some(SafeCheckpointTracking.make(maxReorgDepth, config.shouldRollbackOnReorg, chainReorgCheckpoints)), numEventsProcessed, Primitive_option.some(timestampCaughtUpToHeadOrEndblock), undefined, Primitive_option.some(TransactionStore.make(config.ecosystem.name, !lowercaseAddresses)), Primitive_option.some(chainDensity), Primitive_option.some(BlockStore.make(config.ecosystem.name, !lowercaseAddresses)), logger);
|
|
160
|
+
return make(chainConfig, fetchState, onEventRegistrations, indexingAddressIndex, SourceManager.make(sources$1, isRealtime, undefined, undefined, undefined, reducedPollingInterval, undefined, undefined), ReorgDetection.make(chainReorgCheckpoints, maxReorgDepth, config.shouldRollbackOnReorg), progressBlockNumber, Primitive_option.some(SafeCheckpointTracking.make(maxReorgDepth, config.shouldRollbackOnReorg, chainReorgCheckpoints)), numEventsProcessed, Primitive_option.some(timestampCaughtUpToHeadOrEndblock), undefined, Primitive_option.some(TransactionStore.make(config.ecosystem.name, !lowercaseAddresses)), Primitive_option.some(chainDensity), Primitive_option.some(BlockStore.make(config.ecosystem.name, !lowercaseAddresses)), config.reorgThresholdReadyTolerance, logger);
|
|
151
161
|
}
|
|
152
162
|
|
|
153
163
|
function makeFromConfig(chainConfig, config, registrationsByChainId, knownHeight) {
|
|
@@ -162,7 +172,6 @@ function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInR
|
|
|
162
172
|
let logger = Logging.createChild({
|
|
163
173
|
chainId: chainId
|
|
164
174
|
});
|
|
165
|
-
Prometheus.ProgressEventsCount.set(resumedChainState.numEventsProcessed, chainId);
|
|
166
175
|
let progressBlockNumber = resumedChainState.progressBlockNumber >= 0 ? resumedChainState.progressBlockNumber : resumedChainState.startBlock - 1 | 0;
|
|
167
176
|
return makeInternal(chainConfig, resumedChainState.indexingAddresses, resumedChainState.startBlock, resumedChainState.endBlock, Primitive_option.some(resumedChainState.firstEventBlockNumber), progressBlockNumber, config, registrationsByChainId, logger, Env.updateSyncTimeOnRestart ? undefined : resumedChainState.timestampCaughtUpToHeadOrEndblock, resumedChainState.numEventsProcessed, isInReorgThreshold, isRealtime, reorgCheckpoints, resumedChainState.maxReorgDepth, resumedChainState.sourceBlockNumber, reducedPollingInterval);
|
|
168
177
|
}
|
|
@@ -207,6 +216,23 @@ function timestampCaughtUpToHeadOrEndblock(cs) {
|
|
|
207
216
|
return cs.timestampCaughtUpToHeadOrEndblock;
|
|
208
217
|
}
|
|
209
218
|
|
|
219
|
+
function recordBlockRangeFetch(cs, totalTimeElapsed, parsingTimeElapsed, numEvents, blockRangeSize) {
|
|
220
|
+
cs.blockRangeFetchSeconds = cs.blockRangeFetchSeconds + totalTimeElapsed;
|
|
221
|
+
cs.blockRangeParseSeconds = cs.blockRangeParseSeconds + parsingTimeElapsed;
|
|
222
|
+
cs.blockRangeFetchCount = cs.blockRangeFetchCount + 1;
|
|
223
|
+
cs.blockRangeFetchedEvents = cs.blockRangeFetchedEvents + numEvents;
|
|
224
|
+
cs.blockRangeFetchedBlocks = cs.blockRangeFetchedBlocks + blockRangeSize;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
function recordReorgDetected(cs, blockNumber) {
|
|
228
|
+
cs.reorgCount = cs.reorgCount + 1 | 0;
|
|
229
|
+
cs.reorgDetectedBlock = blockNumber;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function setRollbackTargetBlock(cs, blockNumber) {
|
|
233
|
+
cs.rollbackTargetBlock = blockNumber;
|
|
234
|
+
}
|
|
235
|
+
|
|
210
236
|
function knownHeight(cs) {
|
|
211
237
|
return cs.fetchState.knownHeight;
|
|
212
238
|
}
|
|
@@ -239,10 +265,6 @@ function hasReadyItem(cs) {
|
|
|
239
265
|
}
|
|
240
266
|
}
|
|
241
267
|
|
|
242
|
-
function isReadyToEnterReorgThreshold(cs) {
|
|
243
|
-
return FetchState.isReadyToEnterReorgThreshold(cs.fetchState);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
268
|
function startFetchingQueries(cs, queries) {
|
|
247
269
|
FetchState.startFetchingQueries(cs.fetchState, queries);
|
|
248
270
|
cs.pendingBudget = cs.pendingBudget + Stdlib_Array.reduce(queries, 0, (acc, query) => acc + query.itemsEst);
|
|
@@ -598,7 +620,7 @@ function toChainMetadata(cs) {
|
|
|
598
620
|
};
|
|
599
621
|
}
|
|
600
622
|
|
|
601
|
-
function
|
|
623
|
+
function toMetrics(cs) {
|
|
602
624
|
return {
|
|
603
625
|
chainId: cs.chainConfig.id,
|
|
604
626
|
poweredByHyperSync: SourceManager.getActiveSource(cs.sourceManager).poweredByHyperSync,
|
|
@@ -607,11 +629,30 @@ function toChainData(cs) {
|
|
|
607
629
|
timestampCaughtUpToHeadOrEndblock: cs.timestampCaughtUpToHeadOrEndblock,
|
|
608
630
|
numEventsProcessed: cs.numEventsProcessed,
|
|
609
631
|
latestFetchedBlockNumber: Primitive_int.max(FetchState.bufferBlockNumber(cs.fetchState), 0),
|
|
610
|
-
|
|
632
|
+
knownHeight: hasProcessedToEndblock(cs) ? Stdlib_Option.getOr(cs.fetchState.endBlock, cs.fetchState.knownHeight) : cs.fetchState.knownHeight,
|
|
611
633
|
numBatchesFetched: 0,
|
|
612
634
|
startBlock: cs.fetchState.startBlock,
|
|
613
635
|
endBlock: cs.fetchState.endBlock,
|
|
614
|
-
numAddresses: IndexingAddresses.size(cs.indexingAddresses)
|
|
636
|
+
numAddresses: IndexingAddresses.size(cs.indexingAddresses),
|
|
637
|
+
isReady: cs.timestampCaughtUpToHeadOrEndblock !== undefined,
|
|
638
|
+
sourceBlockNumber: cs.fetchState.knownHeight,
|
|
639
|
+
progressBlockNumber: cs.committedProgressBlockNumber,
|
|
640
|
+
progressLatencyMs: cs.progressLatencyMs,
|
|
641
|
+
concurrency: SourceManager.inFlightCount(cs.sourceManager),
|
|
642
|
+
partitionsCount: FetchState.partitionsCount(cs.fetchState),
|
|
643
|
+
bufferSize: FetchState.bufferSize(cs.fetchState),
|
|
644
|
+
bufferBlockNumber: FetchState.bufferBlockNumber(cs.fetchState),
|
|
645
|
+
idleSeconds: SourceManager.idleSeconds(cs.sourceManager),
|
|
646
|
+
waitingForNewBlockSeconds: SourceManager.waitingForNewBlockSeconds(cs.sourceManager),
|
|
647
|
+
queryingSeconds: SourceManager.queryingSeconds(cs.sourceManager),
|
|
648
|
+
blockRangeFetchSeconds: cs.blockRangeFetchSeconds,
|
|
649
|
+
blockRangeParseSeconds: cs.blockRangeParseSeconds,
|
|
650
|
+
blockRangeFetchCount: cs.blockRangeFetchCount,
|
|
651
|
+
blockRangeFetchedEvents: cs.blockRangeFetchedEvents,
|
|
652
|
+
blockRangeFetchedBlocks: cs.blockRangeFetchedBlocks,
|
|
653
|
+
reorgCount: cs.reorgCount,
|
|
654
|
+
reorgDetectedBlock: cs.reorgDetectedBlock,
|
|
655
|
+
rollbackTargetBlock: cs.rollbackTargetBlock
|
|
615
656
|
};
|
|
616
657
|
}
|
|
617
658
|
|
|
@@ -628,7 +669,8 @@ function toChainBeforeBatch(cs) {
|
|
|
628
669
|
|
|
629
670
|
function isReadyToEnterReorgThresholdAfterBatch(cs, batch) {
|
|
630
671
|
let chainAfterBatch = batch.progressedChainsById[cs.fetchState.chainId];
|
|
631
|
-
|
|
672
|
+
let fetchState = chainAfterBatch !== undefined ? chainAfterBatch.fetchState : cs.fetchState;
|
|
673
|
+
return FetchState.isReadyToEnterReorgThreshold(cs.reorgThresholdReadyTolerance, fetchState);
|
|
632
674
|
}
|
|
633
675
|
|
|
634
676
|
function advanceAfterBatch(cs, batch, enteringReorgThreshold) {
|
|
@@ -646,16 +688,10 @@ function applyBatchProgress(cs, batch, blockTimestampName) {
|
|
|
646
688
|
if (chainAfterBatch === undefined) {
|
|
647
689
|
return;
|
|
648
690
|
}
|
|
649
|
-
if (cs.committedProgressBlockNumber !== chainAfterBatch.progressBlockNumber) {
|
|
650
|
-
Prometheus.ProgressBlockNumber.set(chainAfterBatch.progressBlockNumber, chainId);
|
|
651
|
-
}
|
|
652
|
-
if (cs.numEventsProcessed !== chainAfterBatch.totalEventsProcessed) {
|
|
653
|
-
Prometheus.ProgressEventsCount.set(chainAfterBatch.totalEventsProcessed, chainId);
|
|
654
|
-
}
|
|
655
691
|
let blockTimestamp = Stdlib_Option.flatMap(Stdlib_Option.flatMap(Batch.findLastEventItem(batch, chainId), eventItem => Primitive_option.fromNullable(eventItem.payload.block)), block => block[blockTimestampName]);
|
|
656
692
|
if (blockTimestamp !== undefined) {
|
|
657
693
|
let blockTimestampMs = Primitive_option.valFromOption(blockTimestamp) * 1000 | 0;
|
|
658
|
-
|
|
694
|
+
cs.progressLatencyMs = (Date.now() | 0) - blockTimestampMs | 0;
|
|
659
695
|
}
|
|
660
696
|
let match = cs.fetchState.firstEventBlock;
|
|
661
697
|
if (match === undefined) {
|
|
@@ -717,12 +753,11 @@ function applyBatchProgress(cs, batch, blockTimestampName) {
|
|
|
717
753
|
function markReady(cs) {
|
|
718
754
|
if (cs.timestampCaughtUpToHeadOrEndblock === undefined) {
|
|
719
755
|
cs.timestampCaughtUpToHeadOrEndblock = new Date();
|
|
720
|
-
return
|
|
756
|
+
return;
|
|
721
757
|
}
|
|
722
758
|
}
|
|
723
759
|
|
|
724
760
|
function rollback(cs, newProgressBlockNumber, eventsProcessedDiff, rollbackTargetBlockNumber, isReorgChain) {
|
|
725
|
-
let chainId = cs.chainConfig.id;
|
|
726
761
|
if (newProgressBlockNumber === undefined) {
|
|
727
762
|
if (isReorgChain) {
|
|
728
763
|
cs.reorgDetection = ReorgDetection.rollbackToValidBlockNumber(cs.reorgDetection, rollbackTargetBlockNumber);
|
|
@@ -737,12 +772,6 @@ function rollback(cs, newProgressBlockNumber, eventsProcessedDiff, rollbackTarge
|
|
|
737
772
|
}
|
|
738
773
|
}
|
|
739
774
|
let newTotalEventsProcessed = cs.numEventsProcessed - Stdlib_Option.getOrThrow(eventsProcessedDiff, "Missing events-processed diff for rolled-back chain");
|
|
740
|
-
if (cs.committedProgressBlockNumber !== newProgressBlockNumber) {
|
|
741
|
-
Prometheus.ProgressBlockNumber.set(newProgressBlockNumber, chainId);
|
|
742
|
-
}
|
|
743
|
-
if (cs.numEventsProcessed !== newTotalEventsProcessed) {
|
|
744
|
-
Prometheus.ProgressEventsCount.set(newTotalEventsProcessed, chainId);
|
|
745
|
-
}
|
|
746
775
|
if (isReorgChain) {
|
|
747
776
|
cs.reorgDetection = ReorgDetection.rollbackToValidBlockNumber(cs.reorgDetection, rollbackTargetBlockNumber);
|
|
748
777
|
}
|
|
@@ -774,6 +803,9 @@ export {
|
|
|
774
803
|
pendingBudget,
|
|
775
804
|
startFetchingQueries,
|
|
776
805
|
timestampCaughtUpToHeadOrEndblock,
|
|
806
|
+
recordBlockRangeFetch,
|
|
807
|
+
recordReorgDetected,
|
|
808
|
+
setRollbackTargetBlock,
|
|
777
809
|
knownHeight,
|
|
778
810
|
contractAddresses,
|
|
779
811
|
bufferSize,
|
|
@@ -782,13 +814,12 @@ export {
|
|
|
782
814
|
chainDensity,
|
|
783
815
|
effectiveDensity,
|
|
784
816
|
hasReadyItem,
|
|
785
|
-
isReadyToEnterReorgThreshold,
|
|
786
817
|
targetBlock,
|
|
787
818
|
blockAtProgress,
|
|
788
819
|
frontierProgress,
|
|
789
820
|
getNextQuery,
|
|
790
821
|
dispatch,
|
|
791
|
-
|
|
822
|
+
toMetrics,
|
|
792
823
|
toChainMetadata,
|
|
793
824
|
toChainBeforeBatch,
|
|
794
825
|
isReadyToEnterReorgThresholdAfterBatch,
|
package/src/ChainState.resi
CHANGED
|
@@ -20,6 +20,7 @@ let make: (
|
|
|
20
20
|
~transactionStore: TransactionStore.t=?,
|
|
21
21
|
~chainDensity: option<float>=?,
|
|
22
22
|
~blockStore: BlockStore.t=?,
|
|
23
|
+
~reorgThresholdReadyTolerance: int=?,
|
|
23
24
|
~logger: Pino.t,
|
|
24
25
|
) => t
|
|
25
26
|
|
|
@@ -54,6 +55,17 @@ let pendingBudget: t => float
|
|
|
54
55
|
let startFetchingQueries: (t, ~queries: array<FetchState.query>) => unit
|
|
55
56
|
let timestampCaughtUpToHeadOrEndblock: t => option<Date.t>
|
|
56
57
|
|
|
58
|
+
// Metric counters, rendered by Metrics at scrape time.
|
|
59
|
+
let recordBlockRangeFetch: (
|
|
60
|
+
t,
|
|
61
|
+
~totalTimeElapsed: float,
|
|
62
|
+
~parsingTimeElapsed: float,
|
|
63
|
+
~numEvents: int,
|
|
64
|
+
~blockRangeSize: int,
|
|
65
|
+
) => unit
|
|
66
|
+
let recordReorgDetected: (t, ~blockNumber: int) => unit
|
|
67
|
+
let setRollbackTargetBlock: (t, ~blockNumber: int) => unit
|
|
68
|
+
|
|
57
69
|
// Fetch-frontier reads.
|
|
58
70
|
let knownHeight: t => int
|
|
59
71
|
let contractAddresses: (t, ~contractName: string) => array<Address.t>
|
|
@@ -63,7 +75,6 @@ let getProgressPercentage: t => float
|
|
|
63
75
|
let chainDensity: t => option<float>
|
|
64
76
|
let effectiveDensity: t => option<float>
|
|
65
77
|
let hasReadyItem: t => bool
|
|
66
|
-
let isReadyToEnterReorgThreshold: t => bool
|
|
67
78
|
|
|
68
79
|
// Fetch control.
|
|
69
80
|
let targetBlock: (t, ~chainTargetItems: float) => int
|
|
@@ -86,22 +97,7 @@ let dispatch: (
|
|
|
86
97
|
) => promise<unit>
|
|
87
98
|
|
|
88
99
|
// Views.
|
|
89
|
-
|
|
90
|
-
chainId: float,
|
|
91
|
-
poweredByHyperSync: bool,
|
|
92
|
-
firstEventBlockNumber: option<int>,
|
|
93
|
-
latestProcessedBlock: option<int>,
|
|
94
|
-
timestampCaughtUpToHeadOrEndblock: option<Date.t>,
|
|
95
|
-
numEventsProcessed: float,
|
|
96
|
-
latestFetchedBlockNumber: int,
|
|
97
|
-
@as("currentBlockHeight")
|
|
98
|
-
knownHeight: int,
|
|
99
|
-
numBatchesFetched: int,
|
|
100
|
-
startBlock: int,
|
|
101
|
-
endBlock: option<int>,
|
|
102
|
-
numAddresses: int,
|
|
103
|
-
}
|
|
104
|
-
let toChainData: t => chainData
|
|
100
|
+
let toMetrics: t => Metrics.chainMetrics
|
|
105
101
|
let toChainMetadata: t => InternalTable.Chains.metaFields
|
|
106
102
|
let toChainBeforeBatch: t => Batch.chainBeforeBatch
|
|
107
103
|
let isReadyToEnterReorgThresholdAfterBatch: (t, ~batch: Batch.t) => bool
|
package/src/Config.res
CHANGED
|
@@ -79,6 +79,10 @@ type t = {
|
|
|
79
79
|
enableRawEvents: bool,
|
|
80
80
|
maxAddrInPartition: int,
|
|
81
81
|
batchSize: int,
|
|
82
|
+
// Slack (in blocks) below the lagged head within which a chain still counts as
|
|
83
|
+
// ready to enter the reorg threshold, absorbing head advances between catch-up
|
|
84
|
+
// and the entry check. Overridable in tests.
|
|
85
|
+
reorgThresholdReadyTolerance: int,
|
|
82
86
|
lowercaseAddresses: bool,
|
|
83
87
|
isDev: bool,
|
|
84
88
|
userEntitiesByName: dict<Internal.entityConfig>,
|
|
@@ -997,6 +1001,7 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
997
1001
|
ecosystem,
|
|
998
1002
|
maxAddrInPartition,
|
|
999
1003
|
batchSize: publicConfig["fullBatchSize"]->Option.getOr(5000),
|
|
1004
|
+
reorgThresholdReadyTolerance: 100,
|
|
1000
1005
|
lowercaseAddresses,
|
|
1001
1006
|
isDev: publicConfig["isDev"]->Option.getOr(false),
|
|
1002
1007
|
userEntitiesByName,
|
package/src/Config.res.mjs
CHANGED
|
@@ -698,6 +698,7 @@ function fromPublic(publicConfigJson) {
|
|
|
698
698
|
enableRawEvents: Stdlib_Option.getOr(publicConfig.rawEvents, false),
|
|
699
699
|
maxAddrInPartition: Env.maxAddrInPartition,
|
|
700
700
|
batchSize: Stdlib_Option.getOr(publicConfig.fullBatchSize, 5000),
|
|
701
|
+
reorgThresholdReadyTolerance: 100,
|
|
701
702
|
lowercaseAddresses: lowercaseAddresses,
|
|
702
703
|
isDev: Stdlib_Option.getOr(publicConfig.isDev, false),
|
|
703
704
|
userEntitiesByName: userEntitiesByName,
|