envio 3.3.0 → 3.3.1-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 -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
|
@@ -44,6 +44,11 @@ type t = {
|
|
|
44
44
|
sourcesState: array<sourceState>,
|
|
45
45
|
mutable statusStart: Performance.timeRef,
|
|
46
46
|
mutable status: sourceManagerStatus,
|
|
47
|
+
// Cumulative time spent in each status, rendered into the
|
|
48
|
+
// envio_indexing_idle/source_waiting/source_querying_seconds counters.
|
|
49
|
+
mutable idleSeconds: float,
|
|
50
|
+
mutable waitingForNewBlockSeconds: float,
|
|
51
|
+
mutable queryingSeconds: float,
|
|
47
52
|
newBlockStallTimeout: int,
|
|
48
53
|
newBlockStallTimeoutRealtime: int,
|
|
49
54
|
stalledPollingInterval: int,
|
|
@@ -92,6 +97,55 @@ let getRequestStatSamples = (sourceManager: t): array<requestStatSample> => {
|
|
|
92
97
|
samples
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
// Per-source known heights for envio_source_known_height. Sources with no
|
|
101
|
+
// observed height yet are skipped.
|
|
102
|
+
type sourceHeightSample = {
|
|
103
|
+
sourceName: string,
|
|
104
|
+
chainId: int,
|
|
105
|
+
height: int,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
let getSourceHeightSamples = (sourceManager: t): array<sourceHeightSample> => {
|
|
109
|
+
let samples = []
|
|
110
|
+
sourceManager.sourcesState->Array.forEach(sourceState => {
|
|
111
|
+
if sourceState.knownHeight > 0 {
|
|
112
|
+
samples->Array.push({
|
|
113
|
+
sourceName: sourceState.source.name,
|
|
114
|
+
chainId: sourceState.source.chain->ChainMap.Chain.toChainId,
|
|
115
|
+
height: sourceState.knownHeight,
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
})
|
|
119
|
+
samples
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Each accessor adds the in-progress interval of the current status, so a
|
|
123
|
+
// scrape during a long idle/wait/query isn't stale until the next transition.
|
|
124
|
+
let idleSeconds = (sourceManager: t) =>
|
|
125
|
+
sourceManager.idleSeconds +.
|
|
126
|
+
switch sourceManager.status {
|
|
127
|
+
| Idle => sourceManager.statusStart->Performance.secondsSince
|
|
128
|
+
| _ => 0.
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
let waitingForNewBlockSeconds = (sourceManager: t) =>
|
|
132
|
+
sourceManager.waitingForNewBlockSeconds +.
|
|
133
|
+
switch sourceManager.status {
|
|
134
|
+
| WaitingForNewBlock => sourceManager.statusStart->Performance.secondsSince
|
|
135
|
+
| _ => 0.
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
let queryingSeconds = (sourceManager: t) =>
|
|
139
|
+
sourceManager.queryingSeconds +.
|
|
140
|
+
switch sourceManager.status {
|
|
141
|
+
| Querying => sourceManager.statusStart->Performance.secondsSince
|
|
142
|
+
| _ => 0.
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Partition queries currently in flight on this chain's sources. Summed across
|
|
146
|
+
// chains by CrossChainState to enforce the indexer-wide concurrency budget.
|
|
147
|
+
let inFlightCount = sourceManager => sourceManager.fetchingPartitionsCount
|
|
148
|
+
|
|
95
149
|
let getRateLimitTimeMs = sourceManager =>
|
|
96
150
|
sourceManager.committedRateLimitTimeMs +.
|
|
97
151
|
switch sourceManager.activeRateLimitStartMs {
|
|
@@ -217,10 +271,6 @@ let make = (
|
|
|
217
271
|
| None =>
|
|
218
272
|
JsError.throwWithMessage("Invalid configuration, no data-source for historical sync provided")
|
|
219
273
|
}
|
|
220
|
-
Prometheus.IndexingConcurrency.set(
|
|
221
|
-
~concurrency=0,
|
|
222
|
-
~chainId=initialActiveSource.chain->ChainMap.Chain.toChainId,
|
|
223
|
-
)
|
|
224
274
|
{
|
|
225
275
|
sourcesState: sources->Array.map(source => {
|
|
226
276
|
source,
|
|
@@ -243,6 +293,9 @@ let make = (
|
|
|
243
293
|
recoveryTimeout,
|
|
244
294
|
statusStart: Performance.now(),
|
|
245
295
|
status: Idle,
|
|
296
|
+
idleSeconds: 0.,
|
|
297
|
+
waitingForNewBlockSeconds: 0.,
|
|
298
|
+
queryingSeconds: 0.,
|
|
246
299
|
hasRealtime,
|
|
247
300
|
committedRateLimitTimeMs: 0.0,
|
|
248
301
|
rateLimitWaiters: 0,
|
|
@@ -252,15 +305,13 @@ let make = (
|
|
|
252
305
|
}
|
|
253
306
|
|
|
254
307
|
let trackNewStatus = (sourceManager: t, ~newStatus) => {
|
|
255
|
-
let
|
|
256
|
-
|
|
257
|
-
|
|
|
258
|
-
|
|
|
308
|
+
let elapsed = sourceManager.statusStart->Performance.secondsSince
|
|
309
|
+
switch sourceManager.status {
|
|
310
|
+
| Idle => sourceManager.idleSeconds = sourceManager.idleSeconds +. elapsed
|
|
311
|
+
| WaitingForNewBlock =>
|
|
312
|
+
sourceManager.waitingForNewBlockSeconds = sourceManager.waitingForNewBlockSeconds +. elapsed
|
|
313
|
+
| Querying => sourceManager.queryingSeconds = sourceManager.queryingSeconds +. elapsed
|
|
259
314
|
}
|
|
260
|
-
promCounter->Prometheus.SafeCounter.handleFloat(
|
|
261
|
-
~labels=sourceManager.activeSource.chain->ChainMap.Chain.toChainId,
|
|
262
|
-
~value=sourceManager.statusStart->Performance.secondsSince,
|
|
263
|
-
)
|
|
264
315
|
sourceManager.statusStart = Performance.now()
|
|
265
316
|
sourceManager.status = newStatus
|
|
266
317
|
}
|
|
@@ -303,20 +354,12 @@ let dispatch = async (
|
|
|
303
354
|
// when they were admitted; here we just execute them.
|
|
304
355
|
sourceManager.fetchingPartitionsCount =
|
|
305
356
|
sourceManager.fetchingPartitionsCount + queries->Array.length
|
|
306
|
-
Prometheus.IndexingConcurrency.set(
|
|
307
|
-
~concurrency=sourceManager.fetchingPartitionsCount,
|
|
308
|
-
~chainId=sourceManager.activeSource.chain->ChainMap.Chain.toChainId,
|
|
309
|
-
)
|
|
310
357
|
sourceManager->trackNewStatus(~newStatus=Querying)
|
|
311
358
|
let _ = await queries
|
|
312
359
|
->Array.map(q => {
|
|
313
360
|
let promise = q->executeQuery
|
|
314
361
|
let _ = promise->Promise.thenResolve(_ => {
|
|
315
362
|
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount - 1
|
|
316
|
-
Prometheus.IndexingConcurrency.set(
|
|
317
|
-
~concurrency=sourceManager.fetchingPartitionsCount,
|
|
318
|
-
~chainId=sourceManager.activeSource.chain->ChainMap.Chain.toChainId,
|
|
319
|
-
)
|
|
320
363
|
if sourceManager.fetchingPartitionsCount === 0 {
|
|
321
364
|
sourceManager->trackNewStatus(~newStatus=Idle)
|
|
322
365
|
}
|
|
@@ -461,13 +504,8 @@ let getSourceNewHeight = async (
|
|
|
461
504
|
}
|
|
462
505
|
}
|
|
463
506
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
Prometheus.SourceHeight.set(
|
|
467
|
-
~sourceName=source.name,
|
|
468
|
-
~chainId=source.chain->ChainMap.Chain.toChainId,
|
|
469
|
-
~blockNumber=newHeight.contents,
|
|
470
|
-
)
|
|
507
|
+
if newHeight.contents > sourceState.knownHeight {
|
|
508
|
+
sourceState.knownHeight = newHeight.contents
|
|
471
509
|
}
|
|
472
510
|
|
|
473
511
|
newHeight.contents
|
|
@@ -736,6 +774,13 @@ let executeQuery = async (
|
|
|
736
774
|
)
|
|
737
775
|
sourceState->recordRequestStats(response.requestStats)
|
|
738
776
|
sourceState.lastFailedAt = None
|
|
777
|
+
|
|
778
|
+
// The response carries a fresh height for exactly this source, so during a
|
|
779
|
+
// long backfill (when the wait loop doesn't run) it keeps the per-source
|
|
780
|
+
// envio_source_known_height current.
|
|
781
|
+
if response.knownHeight > sourceState.knownHeight {
|
|
782
|
+
sourceState.knownHeight = response.knownHeight
|
|
783
|
+
}
|
|
739
784
|
responseRef := Some(response)
|
|
740
785
|
} catch {
|
|
741
786
|
| Source.RateLimited({resetMs}) =>
|
|
@@ -4,7 +4,6 @@ import * as Utils from "../Utils.res.mjs";
|
|
|
4
4
|
import * as Source from "./Source.res.mjs";
|
|
5
5
|
import * as Logging from "../Logging.res.mjs";
|
|
6
6
|
import * as FetchState from "../FetchState.res.mjs";
|
|
7
|
-
import * as Prometheus from "../Prometheus.res.mjs";
|
|
8
7
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
9
8
|
import * as ErrorHandling from "../ErrorHandling.res.mjs";
|
|
10
9
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
@@ -52,6 +51,70 @@ function getRequestStatSamples(sourceManager) {
|
|
|
52
51
|
return samples;
|
|
53
52
|
}
|
|
54
53
|
|
|
54
|
+
function getSourceHeightSamples(sourceManager) {
|
|
55
|
+
let samples = [];
|
|
56
|
+
sourceManager.sourcesState.forEach(sourceState => {
|
|
57
|
+
if (sourceState.knownHeight > 0) {
|
|
58
|
+
samples.push({
|
|
59
|
+
sourceName: sourceState.source.name,
|
|
60
|
+
chainId: sourceState.source.chain,
|
|
61
|
+
height: sourceState.knownHeight
|
|
62
|
+
});
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return samples;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function idleSeconds(sourceManager) {
|
|
70
|
+
let match = sourceManager.status;
|
|
71
|
+
let tmp;
|
|
72
|
+
switch (match) {
|
|
73
|
+
case "Idle" :
|
|
74
|
+
tmp = Performance.secondsSince(sourceManager.statusStart);
|
|
75
|
+
break;
|
|
76
|
+
case "WaitingForNewBlock" :
|
|
77
|
+
case "Querying" :
|
|
78
|
+
tmp = 0;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
return sourceManager.idleSeconds + tmp;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function waitingForNewBlockSeconds(sourceManager) {
|
|
85
|
+
let match = sourceManager.status;
|
|
86
|
+
let tmp;
|
|
87
|
+
switch (match) {
|
|
88
|
+
case "WaitingForNewBlock" :
|
|
89
|
+
tmp = Performance.secondsSince(sourceManager.statusStart);
|
|
90
|
+
break;
|
|
91
|
+
case "Idle" :
|
|
92
|
+
case "Querying" :
|
|
93
|
+
tmp = 0;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
return sourceManager.waitingForNewBlockSeconds + tmp;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function queryingSeconds(sourceManager) {
|
|
100
|
+
let match = sourceManager.status;
|
|
101
|
+
let tmp;
|
|
102
|
+
switch (match) {
|
|
103
|
+
case "Idle" :
|
|
104
|
+
case "WaitingForNewBlock" :
|
|
105
|
+
tmp = 0;
|
|
106
|
+
break;
|
|
107
|
+
case "Querying" :
|
|
108
|
+
tmp = Performance.secondsSince(sourceManager.statusStart);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
return sourceManager.queryingSeconds + tmp;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function inFlightCount(sourceManager) {
|
|
115
|
+
return sourceManager.fetchingPartitionsCount;
|
|
116
|
+
}
|
|
117
|
+
|
|
55
118
|
function getRateLimitTimeMs(sourceManager) {
|
|
56
119
|
let startMs = sourceManager.activeRateLimitStartMs;
|
|
57
120
|
return sourceManager.committedRateLimitTimeMs + (
|
|
@@ -159,7 +222,6 @@ function make(sources, isRealtime, newBlockStallTimeoutOpt, newBlockStallTimeout
|
|
|
159
222
|
let hasRealtime = sources.some(s => s.sourceFor === "Realtime");
|
|
160
223
|
let source = sources.find(source => getSourceRole(source.sourceFor, isRealtime, hasRealtime) === "Primary");
|
|
161
224
|
let initialActiveSource = source !== undefined ? source : Stdlib_JsError.throwWithMessage("Invalid configuration, no data-source for historical sync provided");
|
|
162
|
-
Prometheus.IndexingConcurrency.set(0, initialActiveSource.chain);
|
|
163
225
|
return {
|
|
164
226
|
sourcesState: sources.map(source => ({
|
|
165
227
|
source: source,
|
|
@@ -172,6 +234,9 @@ function make(sources, isRealtime, newBlockStallTimeoutOpt, newBlockStallTimeout
|
|
|
172
234
|
})),
|
|
173
235
|
statusStart: Performance.now(),
|
|
174
236
|
status: "Idle",
|
|
237
|
+
idleSeconds: 0,
|
|
238
|
+
waitingForNewBlockSeconds: 0,
|
|
239
|
+
queryingSeconds: 0,
|
|
175
240
|
newBlockStallTimeout: newBlockStallTimeout,
|
|
176
241
|
newBlockStallTimeoutRealtime: newBlockStallTimeoutRealtime,
|
|
177
242
|
stalledPollingInterval: stalledPollingInterval,
|
|
@@ -191,20 +256,19 @@ function make(sources, isRealtime, newBlockStallTimeoutOpt, newBlockStallTimeout
|
|
|
191
256
|
}
|
|
192
257
|
|
|
193
258
|
function trackNewStatus(sourceManager, newStatus) {
|
|
259
|
+
let elapsed = Performance.secondsSince(sourceManager.statusStart);
|
|
194
260
|
let match = sourceManager.status;
|
|
195
|
-
let promCounter;
|
|
196
261
|
switch (match) {
|
|
197
262
|
case "Idle" :
|
|
198
|
-
|
|
263
|
+
sourceManager.idleSeconds = sourceManager.idleSeconds + elapsed;
|
|
199
264
|
break;
|
|
200
265
|
case "WaitingForNewBlock" :
|
|
201
|
-
|
|
266
|
+
sourceManager.waitingForNewBlockSeconds = sourceManager.waitingForNewBlockSeconds + elapsed;
|
|
202
267
|
break;
|
|
203
268
|
case "Querying" :
|
|
204
|
-
|
|
269
|
+
sourceManager.queryingSeconds = sourceManager.queryingSeconds + elapsed;
|
|
205
270
|
break;
|
|
206
271
|
}
|
|
207
|
-
Prometheus.SafeCounter.handleFloat(promCounter, sourceManager.activeSource.chain, Performance.secondsSince(sourceManager.statusStart));
|
|
208
272
|
sourceManager.statusStart = Performance.now();
|
|
209
273
|
sourceManager.status = newStatus;
|
|
210
274
|
}
|
|
@@ -232,13 +296,11 @@ async function dispatch(sourceManager, fetchState, executeQuery, waitForNewBlock
|
|
|
232
296
|
} else {
|
|
233
297
|
let queries = action._0;
|
|
234
298
|
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount + queries.length | 0;
|
|
235
|
-
Prometheus.IndexingConcurrency.set(sourceManager.fetchingPartitionsCount, sourceManager.activeSource.chain);
|
|
236
299
|
trackNewStatus(sourceManager, "Querying");
|
|
237
300
|
await Promise.all(queries.map(q => {
|
|
238
301
|
let promise = executeQuery(q);
|
|
239
302
|
promise.then(param => {
|
|
240
303
|
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount - 1 | 0;
|
|
241
|
-
Prometheus.IndexingConcurrency.set(sourceManager.fetchingPartitionsCount, sourceManager.activeSource.chain);
|
|
242
304
|
if (sourceManager.fetchingPartitionsCount === 0) {
|
|
243
305
|
return trackNewStatus(sourceManager, "Idle");
|
|
244
306
|
}
|
|
@@ -361,8 +423,8 @@ async function getSourceNewHeight(sourceManager, sourceState, knownHeight, stall
|
|
|
361
423
|
}
|
|
362
424
|
}
|
|
363
425
|
};
|
|
364
|
-
if (newHeight.contents >
|
|
365
|
-
|
|
426
|
+
if (newHeight.contents > sourceState.knownHeight) {
|
|
427
|
+
sourceState.knownHeight = newHeight.contents;
|
|
366
428
|
}
|
|
367
429
|
return newHeight.contents;
|
|
368
430
|
}
|
|
@@ -542,6 +604,9 @@ async function executeQuery(sourceManager, query, knownHeight, isRealtime) {
|
|
|
542
604
|
let response = await source.getItemsOrThrow(query.fromBlock, toBlock, query.addressesByContractName, FetchState.deriveContractNameByAddress(query.addressesByContractName), knownHeight, query.partitionId, query.selection, query.itemsTarget, retry, logger$2);
|
|
543
605
|
recordRequestStats(sourceState, response.requestStats);
|
|
544
606
|
sourceState.lastFailedAt = undefined;
|
|
607
|
+
if (response.knownHeight > sourceState.knownHeight) {
|
|
608
|
+
sourceState.knownHeight = response.knownHeight;
|
|
609
|
+
}
|
|
545
610
|
responseRef = response;
|
|
546
611
|
} catch (raw_error) {
|
|
547
612
|
let error = Primitive_exceptions.internalToException(raw_error);
|
|
@@ -715,6 +780,11 @@ export {
|
|
|
715
780
|
make,
|
|
716
781
|
getActiveSource,
|
|
717
782
|
getRequestStatSamples,
|
|
783
|
+
getSourceHeightSamples,
|
|
784
|
+
idleSeconds,
|
|
785
|
+
waitingForNewBlockSeconds,
|
|
786
|
+
queryingSeconds,
|
|
787
|
+
inFlightCount,
|
|
718
788
|
onReorg,
|
|
719
789
|
dispatch,
|
|
720
790
|
waitForNewBlock,
|
|
@@ -31,6 +31,20 @@ type requestStatSample = {
|
|
|
31
31
|
|
|
32
32
|
let getRequestStatSamples: t => array<requestStatSample>
|
|
33
33
|
|
|
34
|
+
type sourceHeightSample = {
|
|
35
|
+
sourceName: string,
|
|
36
|
+
chainId: int,
|
|
37
|
+
height: int,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let getSourceHeightSamples: t => array<sourceHeightSample>
|
|
41
|
+
|
|
42
|
+
let idleSeconds: t => float
|
|
43
|
+
let waitingForNewBlockSeconds: t => float
|
|
44
|
+
let queryingSeconds: t => float
|
|
45
|
+
|
|
46
|
+
let inFlightCount: t => int
|
|
47
|
+
|
|
34
48
|
let onReorg: (t, ~rollbackTargetBlock: int) => unit
|
|
35
49
|
|
|
36
50
|
let dispatch: (
|
package/src/tui/Tui.res
CHANGED
|
@@ -157,7 +157,7 @@ module App = {
|
|
|
157
157
|
->IndexerState.chainStates
|
|
158
158
|
->Dict.valuesToArray
|
|
159
159
|
->Array.map(cs => {
|
|
160
|
-
let data = cs->ChainState.
|
|
160
|
+
let data = cs->ChainState.toMetrics
|
|
161
161
|
let numEventsProcessed = data.numEventsProcessed
|
|
162
162
|
let committedProgressBlockNumber = cs->ChainState.committedProgressBlockNumber
|
|
163
163
|
let timestampCaughtUpToHeadOrEndblock = data.timestampCaughtUpToHeadOrEndblock
|
package/src/tui/Tui.res.mjs
CHANGED
|
@@ -207,7 +207,7 @@ function Tui$App(props) {
|
|
|
207
207
|
};
|
|
208
208
|
}, [getState]);
|
|
209
209
|
let chains = Object.values(IndexerState.chainStates(state)).map(cs => {
|
|
210
|
-
let data = ChainState.
|
|
210
|
+
let data = ChainState.toMetrics(cs);
|
|
211
211
|
let numEventsProcessed = data.numEventsProcessed;
|
|
212
212
|
let committedProgressBlockNumber = ChainState.committedProgressBlockNumber(cs);
|
|
213
213
|
let timestampCaughtUpToHeadOrEndblock = data.timestampCaughtUpToHeadOrEndblock;
|
|
@@ -266,7 +266,7 @@ function Tui$App(props) {
|
|
|
266
266
|
poweredByHyperSync: data.poweredByHyperSync,
|
|
267
267
|
progress: progress,
|
|
268
268
|
latestFetchedBlockNumber: latestFetchedBlockNumber,
|
|
269
|
-
knownHeight: data.
|
|
269
|
+
knownHeight: data.knownHeight,
|
|
270
270
|
blockUnit: tmp,
|
|
271
271
|
rateLimitTimeMs: SourceManager.getRateLimitTimeMs(sourceManager),
|
|
272
272
|
isRateLimited: SourceManager.isRateLimited(sourceManager),
|