envio 2.19.2 → 2.20.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/evm.schema.json CHANGED
@@ -27,7 +27,7 @@
27
27
  ]
28
28
  },
29
29
  "schema": {
30
- "description": "Custom path to schema.yaml file",
30
+ "description": "Custom path to schema.graphql file",
31
31
  "type": [
32
32
  "string",
33
33
  "null"
package/fuel.schema.json CHANGED
@@ -20,7 +20,7 @@
20
20
  "$ref": "#/$defs/EcosystemTag"
21
21
  },
22
22
  "schema": {
23
- "description": "Custom path to schema.yaml file",
23
+ "description": "Custom path to schema.graphql file",
24
24
  "type": [
25
25
  "string",
26
26
  "null"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envio",
3
- "version": "v2.19.2",
3
+ "version": "v2.20.1",
4
4
  "description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
5
5
  "bin": "./bin.js",
6
6
  "main": "./index.js",
@@ -25,10 +25,10 @@
25
25
  },
26
26
  "homepage": "https://envio.dev",
27
27
  "optionalDependencies": {
28
- "envio-linux-x64": "v2.19.2",
29
- "envio-linux-arm64": "v2.19.2",
30
- "envio-darwin-x64": "v2.19.2",
31
- "envio-darwin-arm64": "v2.19.2"
28
+ "envio-linux-x64": "v2.20.1",
29
+ "envio-linux-arm64": "v2.20.1",
30
+ "envio-darwin-x64": "v2.20.1",
31
+ "envio-darwin-arm64": "v2.20.1"
32
32
  },
33
33
  "dependencies": {
34
34
  "@envio-dev/hypersync-client": "0.6.3",
package/src/Envio.gen.ts CHANGED
@@ -9,7 +9,7 @@ import type {Effect as $$effect} from './Types.ts';
9
9
 
10
10
  import type {Logger as $$logger} from './Types.ts';
11
11
 
12
- import type {S_t as RescriptSchema_S_t} from './RescriptSchema.gen';
12
+ import type {S_t as RescriptSchema_S_t} from 'rescript-schema/RescriptSchema.gen';
13
13
 
14
14
  export type logger = $$logger;
15
15
 
@@ -22,12 +22,6 @@ let eventsProcessedCounter = PromClient.Gauge.makeGauge({
22
22
  "labelNames": ["chainId"],
23
23
  })
24
24
 
25
- let reorgsDetectedCounter = PromClient.Counter.makeCounter({
26
- "name": "reorgs_detected",
27
- "help": "Total number of reorgs detected",
28
- "labelNames": ["chainId"],
29
- })
30
-
31
25
  let allChainsSyncedToHead = PromClient.Gauge.makeGauge({
32
26
  "name": "hyperindex_synced_to_head",
33
27
  "help": "All chains fully synced",
@@ -88,6 +82,7 @@ module MakeSafePromMetric = (
88
82
  let makeOrThrow: (~name: string, ~help: string, ~labelSchema: S.t<'a>) => t<'a>
89
83
  let handleInt: (t<'a>, ~labels: 'a, ~value: int) => unit
90
84
  let handleFloat: (t<'a>, ~labels: 'a, ~value: float) => unit
85
+ let increment: (t<'a>, ~labels: 'a) => unit
91
86
  } => {
92
87
  type t<'a> = {metric: M.t, labelSchema: S.t<'a>}
93
88
 
@@ -119,6 +114,13 @@ module MakeSafePromMetric = (
119
114
  metric
120
115
  ->M.labels(labels->S.reverseConvertToJsonOrThrow(labelSchema))
121
116
  ->M.handleInt(value)
117
+
118
+ let increment = ({metric, labelSchema}: t<'a>, ~labels: 'a) =>
119
+ (
120
+ metric
121
+ ->M.labels(labels->S.reverseConvertToJsonOrThrow(labelSchema))
122
+ ->Obj.magic
123
+ )["inc"]()
122
124
  }
123
125
 
124
126
  module SafeCounter = MakeSafePromMetric({
@@ -137,6 +139,21 @@ module SafeGauge = MakeSafePromMetric({
137
139
  let handleFloat = PromClient.Gauge.setFloat
138
140
  })
139
141
 
142
+ let makeSafeHistogramOrThrow = (~name, ~help, ~labelSchema, ~backets=?) => {
143
+ let histogram = PromClient.Histogram.make({
144
+ "name": name,
145
+ "help": help,
146
+ "labelNames": labelSchema->Labels.getLabelNames->Belt.Result.getExn,
147
+ "buckets": backets,
148
+ })
149
+
150
+ labels => {
151
+ histogram
152
+ ->PromClient.Histogram.labels(labels->S.reverseConvertToJsonOrThrow(labelSchema))
153
+ ->PromClient.Histogram.startTimer
154
+ }
155
+ }
156
+
140
157
  module BenchmarkSummaryData = {
141
158
  type labels = {
142
159
  group: string,
@@ -188,12 +205,6 @@ let processedUntilHeight = PromClient.Gauge.makeGauge({
188
205
  "labelNames": ["chainId"],
189
206
  })
190
207
 
191
- let fetchedUntilHeight = PromClient.Gauge.makeGauge({
192
- "name": "chain_block_height_fully_fetched",
193
- "help": "Block height fully fetched by indexer",
194
- "labelNames": ["chainId"],
195
- })
196
-
197
208
  let incrementLoadEntityDurationCounter = (~duration) => {
198
209
  loadEntitiesDurationCounter->PromClient.Counter.incMany(duration)
199
210
  }
@@ -212,10 +223,6 @@ let setEventsProcessedGuage = (~number, ~chainId) => {
212
223
  ->PromClient.Gauge.set(number)
213
224
  }
214
225
 
215
- let incrementReorgsDetected = (~chain) => {
216
- reorgsDetectedCounter->PromClient.Counter.incLabels({"chainId": chain->ChainMap.Chain.toString})
217
- }
218
-
219
226
  let setSourceChainHeight = (~blockNumber, ~chain) => {
220
227
  sourceChainHeight
221
228
  ->PromClient.Gauge.labels({"chainId": chain->ChainMap.Chain.toString})
@@ -232,12 +239,6 @@ let setProcessedUntilHeight = (~blockNumber, ~chain) => {
232
239
  ->PromClient.Gauge.set(blockNumber)
233
240
  }
234
241
 
235
- let setFetchedUntilHeight = (~blockNumber, ~chain) => {
236
- fetchedUntilHeight
237
- ->PromClient.Gauge.labels({"chainId": chain->ChainMap.Chain.toString})
238
- ->PromClient.Gauge.set(blockNumber)
239
- }
240
-
241
242
  module BenchmarkCounters = {
242
243
  type labels = {label: string}
243
244
  let labelSchema = S.schema(s => {
@@ -279,6 +280,34 @@ let chainIdLabelsSchema = S.object(s => {
279
280
  s.field("chainId", S.string->S.coerce(S.int))
280
281
  })
281
282
 
283
+ module Info = {
284
+ let gauge = SafeGauge.makeOrThrow(
285
+ ~name="envio_info",
286
+ ~help="Information about the indexer",
287
+ ~labelSchema=S.schema(s =>
288
+ {
289
+ "version": s.matches(S.string),
290
+ }
291
+ ),
292
+ )
293
+
294
+ let set = (~version) => {
295
+ gauge->SafeGauge.handleInt(~labels={"version": version}, ~value=1)
296
+ }
297
+ }
298
+
299
+ module ProgressBlockNumber = {
300
+ let gauge = SafeGauge.makeOrThrow(
301
+ ~name="envio_progress_block_number",
302
+ ~help="The block number to track the progress of indexing at. Currently uses the fully fetched block number. In the future will be changed to block number processed and stored in the database.",
303
+ ~labelSchema=chainIdLabelsSchema,
304
+ )
305
+
306
+ let set = (~blockNumber, ~chainId) => {
307
+ gauge->SafeGauge.handleInt(~labels=chainId, ~value=blockNumber)
308
+ }
309
+ }
310
+
282
311
  module IndexingAddresses = {
283
312
  let gauge = SafeGauge.makeOrThrow(
284
313
  ~name="envio_indexing_addresses",
@@ -291,6 +320,77 @@ module IndexingAddresses = {
291
320
  }
292
321
  }
293
322
 
323
+ module IndexingMaxConcurrency = {
324
+ let gauge = SafeGauge.makeOrThrow(
325
+ ~name="envio_indexing_max_concurrency",
326
+ ~help="The maximum number of concurrent queries to the chain data-source.",
327
+ ~labelSchema=chainIdLabelsSchema,
328
+ )
329
+
330
+ let set = (~maxConcurrency, ~chainId) => {
331
+ gauge->SafeGauge.handleInt(~labels=chainId, ~value=maxConcurrency)
332
+ }
333
+ }
334
+
335
+ module IndexingConcurrency = {
336
+ let gauge = SafeGauge.makeOrThrow(
337
+ ~name="envio_indexing_concurrency",
338
+ ~help="The current number of concurrent queries to the chain data-source.",
339
+ ~labelSchema=chainIdLabelsSchema,
340
+ )
341
+
342
+ let set = (~concurrency, ~chainId) => {
343
+ gauge->SafeGauge.handleInt(~labels=chainId, ~value=concurrency)
344
+ }
345
+ }
346
+
347
+ module IndexingBufferSize = {
348
+ let gauge = SafeGauge.makeOrThrow(
349
+ ~name="envio_indexing_buffer_size",
350
+ ~help="The current number of items in the indexing buffer.",
351
+ ~labelSchema=chainIdLabelsSchema,
352
+ )
353
+
354
+ let set = (~bufferSize, ~chainId) => {
355
+ gauge->SafeGauge.handleInt(~labels=chainId, ~value=bufferSize)
356
+ }
357
+ }
358
+
359
+ module IndexingMaxBufferSize = {
360
+ let gauge = SafeGauge.makeOrThrow(
361
+ ~name="envio_indexing_max_buffer_size",
362
+ ~help="The maximum number of items allowed in the indexing buffer for the chain.",
363
+ ~labelSchema=chainIdLabelsSchema,
364
+ )
365
+
366
+ let set = (~maxBufferSize, ~chainId) => {
367
+ gauge->SafeGauge.handleInt(~labels=chainId, ~value=maxBufferSize)
368
+ }
369
+ }
370
+
371
+ module IndexingBufferBlockNumber = {
372
+ let deprecatedGauge = PromClient.Gauge.makeGauge({
373
+ "name": "chain_block_height_fully_fetched",
374
+ "help": "Block height fully fetched by indexer",
375
+ "labelNames": ["chainId"],
376
+ })
377
+
378
+ let gauge = SafeGauge.makeOrThrow(
379
+ ~name="envio_indexing_buffer_block_number",
380
+ ~help="The highest block number that has been fully fetched by the indexer.",
381
+ ~labelSchema=chainIdLabelsSchema,
382
+ )
383
+
384
+ let set = (~blockNumber, ~chainId) => {
385
+ deprecatedGauge
386
+ ->PromClient.Gauge.labels({"chainId": chainId})
387
+ ->PromClient.Gauge.set(blockNumber)
388
+ // TODO: Use the block number stored in the database instead
389
+ ProgressBlockNumber.set(~blockNumber, ~chainId)
390
+ gauge->SafeGauge.handleInt(~labels=chainId, ~value=blockNumber)
391
+ }
392
+ }
393
+
294
394
  module IndexingEndBlock = {
295
395
  let gauge = SafeGauge.makeOrThrow(
296
396
  ~name="envio_indexing_end_block",
@@ -303,14 +403,101 @@ module IndexingEndBlock = {
303
403
  }
304
404
  }
305
405
 
306
- module ProgressBlockNumber = {
406
+ let sourceLabelsSchema = S.schema(s =>
407
+ {
408
+ "source": s.matches(S.string),
409
+ "chainId": s.matches(S.string->S.coerce(S.int)),
410
+ }
411
+ )
412
+
413
+ module SourceHeight = {
307
414
  let gauge = SafeGauge.makeOrThrow(
308
- ~name="envio_progress_block_number",
309
- ~help="The block number to track the progress of indexing at. Currently uses the fully fetched block number. In the future will be changed to block number processed and stored in the database.",
415
+ ~name="envio_source_height",
416
+ ~help="The latest known block number reported by the source. This value may lag behind the actual chain height, as it is updated only when queried.",
417
+ ~labelSchema=sourceLabelsSchema,
418
+ )
419
+
420
+ let set = (~sourceName, ~chainId, ~blockNumber) => {
421
+ gauge->SafeGauge.handleInt(
422
+ ~labels={"source": sourceName, "chainId": chainId},
423
+ ~value=blockNumber,
424
+ )
425
+ }
426
+ }
427
+
428
+ module SourceGetHeightDuration = {
429
+ let startTimer = makeSafeHistogramOrThrow(
430
+ ~name="envio_source_get_height_duration",
431
+ ~help="Duration of the source get height requests in seconds",
432
+ ~labelSchema=sourceLabelsSchema,
433
+ ~backets=[0.1, 0.5, 1., 10.],
434
+ )
435
+ }
436
+
437
+ module ReorgCount = {
438
+ let deprecatedCounter = PromClient.Counter.makeCounter({
439
+ "name": "reorgs_detected",
440
+ "help": "Total number of reorgs detected",
441
+ "labelNames": ["chainId"],
442
+ })
443
+
444
+ let counter = SafeGauge.makeOrThrow(
445
+ ~name="envio_reorg_count",
446
+ ~help="Total number of reorgs detected",
310
447
  ~labelSchema=chainIdLabelsSchema,
311
448
  )
312
449
 
313
- let set = (~endBlock, ~chainId) => {
314
- gauge->SafeGauge.handleInt(~labels=chainId, ~value=endBlock)
450
+ let increment = (~chain) => {
451
+ deprecatedCounter
452
+ ->PromClient.Counter.labels({"chainId": chain->ChainMap.Chain.toString})
453
+ ->PromClient.Counter.inc
454
+ counter->SafeGauge.increment(~labels=chain->ChainMap.Chain.toChainId)
455
+ }
456
+ }
457
+
458
+ module ReorgDetectionBlockNumber = {
459
+ let gauge = SafeGauge.makeOrThrow(
460
+ ~name="envio_reorg_detection_block_number",
461
+ ~help="The block number where reorg was detected the last time. This doesn't mean that the block was reorged, this is simply where we found block hash to be different.",
462
+ ~labelSchema=chainIdLabelsSchema,
463
+ )
464
+
465
+ let set = (~blockNumber, ~chain) => {
466
+ gauge->SafeGauge.handleInt(~labels=chain->ChainMap.Chain.toChainId, ~value=blockNumber)
467
+ }
468
+ }
469
+
470
+ module RollbackEnabled = {
471
+ let gauge = PromClient.Gauge.makeGauge({
472
+ "name": "envio_rollback_enabled",
473
+ "help": "Whether rollback on reorg is enabled",
474
+ })
475
+
476
+ let set = (~enabled) => {
477
+ gauge->PromClient.Gauge.set(enabled ? 1 : 0)
478
+ }
479
+ }
480
+
481
+ module RollbackDuration = {
482
+ let histogram = PromClient.Histogram.make({
483
+ "name": "envio_rollback_duration",
484
+ "help": "Rollback on reorg duration in seconds",
485
+ "buckets": [0.5, 1., 5., 10.],
486
+ })
487
+
488
+ let startTimer = () => {
489
+ histogram->PromClient.Histogram.startTimer
490
+ }
491
+ }
492
+
493
+ module RollbackTargetBlockNumber = {
494
+ let gauge = SafeGauge.makeOrThrow(
495
+ ~name="envio_rollback_target_block_number",
496
+ ~help="The block number reorg was rollbacked to the last time.",
497
+ ~labelSchema=chainIdLabelsSchema,
498
+ )
499
+
500
+ let set = (~blockNumber, ~chain) => {
501
+ gauge->SafeGauge.handleInt(~labels=chain->ChainMap.Chain.toChainId, ~value=blockNumber)
315
502
  }
316
503
  }
@@ -5,7 +5,7 @@
5
5
 
6
6
  const BigDecimalJS = require('./BigDecimal.bs.js');
7
7
 
8
- import type {S_t as RescriptSchema_S_t} from './RescriptSchema.gen';
8
+ import type {S_t as RescriptSchema_S_t} from 'rescript-schema/RescriptSchema.gen';
9
9
 
10
10
  import type {default as $$t} from 'bignumber.js';
11
11
 
@@ -0,0 +1,41 @@
1
+ type seconds = float
2
+ type milliseconds = float
3
+ type nanoseconds = float
4
+
5
+ type timeTuple = (seconds, nanoseconds)
6
+
7
+ type timeRef = timeTuple
8
+
9
+ type timeElapsed = timeTuple
10
+
11
+ @val @scope("process") external makeTimer: unit => timeRef = "hrtime"
12
+
13
+ @val @scope("process") external timeSince: timeRef => timeElapsed = "hrtime"
14
+
15
+ let nanoToMilli = (nano: nanoseconds): milliseconds => nano /. 1_000_000.
16
+ let secToMilli = (sec: seconds): milliseconds => sec *. 1_000.
17
+
18
+ let nanoToTimeTuple = (nano: nanoseconds): timeTuple => {
19
+ let factor = 1_000_000_000.
20
+ let seconds = Js.Math.floor_float(nano /. factor)
21
+ let nanos = mod_float(nano, factor)
22
+ (seconds, nanos)
23
+ }
24
+
25
+ let timeElapsedToNewRef = (elapsed: timeElapsed, ref: timeRef): timeRef => {
26
+ let (elapsedSeconds, elapsedNano) = elapsed
27
+ let (refSeconds, refNano) = ref
28
+
29
+ let (nanoExtraSeconds, remainderNanos) = nanoToTimeTuple(elapsedNano +. refNano)
30
+ (elapsedSeconds +. refSeconds +. nanoExtraSeconds, remainderNanos)
31
+ }
32
+
33
+ let toMillis = ((sec, nano): timeElapsed): milliseconds => {
34
+ sec->secToMilli +. nano->nanoToMilli
35
+ }
36
+
37
+ let toInt = float => float->Belt.Int.fromFloat
38
+ let intFromMillis = toInt
39
+ let intFromNanos = toInt
40
+ let intFromSeconds = toInt
41
+ let floatFromMillis = Utils.magic
@@ -0,0 +1,24 @@
1
+ type seconds
2
+ type milliseconds
3
+ type nanoseconds
4
+
5
+ type timeTuple = (seconds, nanoseconds)
6
+
7
+ type timeRef
8
+
9
+ type timeElapsed = timeTuple
10
+
11
+ let makeTimer: unit => timeRef
12
+
13
+ let timeSince: timeRef => timeElapsed
14
+
15
+ let nanoToMilli: nanoseconds => milliseconds
16
+ let secToMilli: seconds => milliseconds
17
+
18
+ let timeElapsedToNewRef: (timeElapsed, timeRef) => timeRef
19
+ let toMillis: timeElapsed => milliseconds
20
+
21
+ let intFromMillis: milliseconds => int
22
+ let intFromNanos: nanoseconds => int
23
+ let intFromSeconds: seconds => int
24
+ let floatFromMillis: milliseconds => float
@@ -18,7 +18,6 @@ module Counter = {
18
18
  @send external inc: counter => unit = "inc"
19
19
  @send external incMany: (counter, int) => unit = "inc"
20
20
 
21
- @send external incLabels: (counter, 'labelsObject) => unit = "labels"
22
21
  @send external labels: (counter, 'labelsObject) => counter = "labels"
23
22
  }
24
23
 
@@ -41,10 +40,10 @@ module Gauge = {
41
40
 
42
41
  module Histogram = {
43
42
  type histogram
44
- @new @module("prom-client") external makeHistogram: customMetric<'a> => histogram = "Histogram"
43
+ @new @module("prom-client") external make: customMetric<'a> => histogram = "Histogram"
45
44
 
46
45
  @send external observe: (histogram, float) => unit = "observe"
47
- @send external startTimer: (histogram, unit) => float = "startTimer"
46
+ @send external startTimer: histogram => unit => unit = "startTimer"
48
47
 
49
48
  @send external labels: (histogram, 'labelsObject) => histogram = "labels"
50
49
  }
@@ -24,6 +24,15 @@ type historyRow<'entity> = {
24
24
  current: historyFields,
25
25
  previous: option<historyFields>,
26
26
  entityData: entityData<'entity>,
27
+ // In the event of a rollback, some entity updates may have been
28
+ // been affected by a rollback diff. If there was no rollback diff
29
+ // this will always be false.
30
+ // If there was a rollback diff, this will be false in the case of a
31
+ // new entity update (where entity affected is not present in the diff) b
32
+ // but true if the update is related to an entity that is
33
+ // currently present in the diff
34
+ // Optional since it's discarded during parsing/serialization
35
+ containsRollbackDiffChange?: bool,
27
36
  }
28
37
 
29
38
  type previousHistoryFields = historyFieldsGeneral<option<int>>
@@ -134,6 +143,7 @@ type t<'entity> = {
134
143
  table: table,
135
144
  createInsertFnQuery: string,
136
145
  schema: S.t<historyRow<'entity>>,
146
+ // Used for parsing
137
147
  schemaRows: S.t<array<historyRow<'entity>>>,
138
148
  insertFn: (Postgres.sql, Js.Json.t, ~shouldCopyCurrentEntity: bool) => promise<unit>,
139
149
  }
@@ -148,19 +158,13 @@ let insertRow = (
148
158
  self.insertFn(sql, row, ~shouldCopyCurrentEntity)
149
159
  }
150
160
 
151
- let batchInsertRows = (
152
- self: t<'entity>,
153
- ~sql,
154
- ~rows: array<historyRow<'entity>>,
155
- ~shouldCopyCurrentEntity,
156
- ) => {
157
- let rows =
158
- rows
159
- ->S.reverseConvertToJsonOrThrow(self.schemaRows)
160
- ->(Utils.magic: Js.Json.t => array<Js.Json.t>)
161
+ let batchInsertRows = (self: t<'entity>, ~sql, ~rows: array<historyRow<'entity>>) => {
161
162
  rows
162
- ->Belt.Array.map(row => {
163
- self.insertFn(sql, row, ~shouldCopyCurrentEntity)
163
+ ->Belt.Array.map(historyRow => {
164
+ let containsRollbackDiffChange =
165
+ historyRow.containsRollbackDiffChange->Belt.Option.getWithDefault(false)
166
+ let shouldCopyCurrentEntity = !containsRollbackDiffChange
167
+ self->insertRow(~sql, ~historyRow, ~shouldCopyCurrentEntity)
164
168
  })
165
169
  ->Promise.all
166
170
  ->Promise.thenResolve(_ => ())