envio 3.0.2 → 3.1.0-rc.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/README.md +0 -1
- package/evm.schema.json +15 -8
- package/fuel.schema.json +19 -12
- package/index.d.ts +0 -2
- package/package.json +6 -7
- package/rescript.json +1 -1
- package/src/Batch.res +4 -214
- package/src/Batch.res.mjs +6 -165
- package/src/ChainFetcher.res +12 -28
- package/src/ChainFetcher.res.mjs +8 -17
- package/src/ChainManager.res +10 -9
- package/src/ChainManager.res.mjs +6 -10
- package/src/Config.res +9 -25
- package/src/Config.res.mjs +17 -27
- package/src/Core.res +7 -0
- package/src/Ctx.res +1 -0
- package/src/Env.res +0 -8
- package/src/Env.res.mjs +0 -6
- package/src/EventConfigBuilder.res +13 -123
- package/src/EventConfigBuilder.res.mjs +6 -73
- package/src/EventProcessing.res +5 -29
- package/src/EventProcessing.res.mjs +11 -20
- package/src/EventUtils.res +0 -27
- package/src/EventUtils.res.mjs +0 -24
- package/src/FetchState.res +2 -15
- package/src/FetchState.res.mjs +3 -18
- package/src/GlobalState.res +26 -39
- package/src/GlobalState.res.mjs +12 -40
- package/src/HandlerLoader.res +6 -5
- package/src/HandlerLoader.res.mjs +27 -9
- package/src/HandlerRegister.res +1 -12
- package/src/HandlerRegister.res.mjs +1 -6
- package/src/HandlerRegister.resi +1 -1
- package/src/Hasura.res +96 -32
- package/src/Hasura.res.mjs +93 -38
- package/src/InMemoryStore.res +205 -45
- package/src/InMemoryStore.res.mjs +157 -40
- package/src/InMemoryTable.res +165 -249
- package/src/InMemoryTable.res.mjs +156 -227
- package/src/Internal.res +10 -34
- package/src/Internal.res.mjs +9 -3
- package/src/LoadLayer.res +5 -5
- package/src/LoadLayer.res.mjs +5 -5
- package/src/LogSelection.res +15 -19
- package/src/LogSelection.res.mjs +5 -6
- package/src/Main.res +4 -6
- package/src/Main.res.mjs +26 -15
- package/src/Persistence.res +7 -132
- package/src/Persistence.res.mjs +1 -102
- package/src/PgStorage.res +57 -40
- package/src/PgStorage.res.mjs +60 -34
- package/src/ReorgDetection.res +35 -58
- package/src/ReorgDetection.res.mjs +21 -29
- package/src/SimulateItems.res.mjs +21 -3
- package/src/Sink.res +2 -2
- package/src/Sink.res.mjs +1 -1
- package/src/TableIndices.res +9 -2
- package/src/TableIndices.res.mjs +7 -1
- package/src/TestIndexer.res +53 -60
- package/src/TestIndexer.res.mjs +77 -63
- package/src/TestIndexerProxyStorage.res +4 -14
- package/src/TestIndexerProxyStorage.res.mjs +1 -5
- package/src/UserContext.res +2 -4
- package/src/UserContext.res.mjs +4 -5
- package/src/Utils.res +0 -2
- package/src/Utils.res.mjs +0 -3
- package/src/bindings/ClickHouse.res +45 -38
- package/src/bindings/ClickHouse.res.mjs +16 -17
- package/src/bindings/Vitest.res +3 -0
- package/src/db/InternalTable.res +59 -18
- package/src/db/InternalTable.res.mjs +82 -51
- package/src/db/Table.res +9 -2
- package/src/db/Table.res.mjs +10 -7
- package/src/sources/EnvioApiClient.res +15 -0
- package/src/sources/EnvioApiClient.res.mjs +24 -0
- package/src/sources/EvmChain.res +32 -10
- package/src/sources/EvmChain.res.mjs +31 -5
- package/src/sources/HyperFuelSource.res +15 -58
- package/src/sources/HyperFuelSource.res.mjs +20 -39
- package/src/sources/HyperSync.res +54 -100
- package/src/sources/HyperSync.res.mjs +67 -96
- package/src/sources/HyperSync.resi +4 -22
- package/src/sources/HyperSyncClient.res +70 -247
- package/src/sources/HyperSyncClient.res.mjs +47 -46
- package/src/sources/HyperSyncSource.res +94 -166
- package/src/sources/HyperSyncSource.res.mjs +100 -127
- package/src/sources/RpcSource.res +43 -22
- package/src/sources/RpcSource.res.mjs +50 -35
- package/src/sources/SimulateSource.res +1 -7
- package/src/sources/SimulateSource.res.mjs +1 -7
- package/src/sources/Source.res +10 -1
- package/src/sources/Source.res.mjs +3 -0
- package/src/sources/SourceManager.res +177 -8
- package/src/sources/SourceManager.res.mjs +141 -3
- package/src/sources/SourceManager.resi +19 -0
- package/src/tui/Tui.res +44 -6
- package/src/tui/Tui.res.mjs +56 -8
- package/src/tui/components/TuiData.res +3 -0
- package/svm.schema.json +11 -4
- package/src/sources/HyperSyncJsonApi.res +0 -390
- package/src/sources/HyperSyncJsonApi.res.mjs +0 -237
|
@@ -5,13 +5,9 @@ type selectionConfig = {
|
|
|
5
5
|
~addressesByContractName: dict<array<Address.t>>,
|
|
6
6
|
) => array<LogSelection.t>,
|
|
7
7
|
fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
|
|
8
|
-
nonOptionalBlockFieldNames: array<string>,
|
|
9
|
-
nonOptionalTransactionFieldNames: array<string>,
|
|
10
8
|
}
|
|
11
9
|
|
|
12
10
|
let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
13
|
-
let nonOptionalBlockFieldNames = Utils.Set.make()
|
|
14
|
-
let nonOptionalTransactionFieldNames = Utils.Set.make()
|
|
15
11
|
let capitalizedBlockFields = Utils.Set.make()
|
|
16
12
|
let capitalizedTransactionFields = Utils.Set.make()
|
|
17
13
|
|
|
@@ -33,22 +29,18 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
33
29
|
}) => {
|
|
34
30
|
selectedBlockFields
|
|
35
31
|
->Utils.Set.toArray
|
|
36
|
-
->Array.forEach(name =>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
capitalizedBlockFields->Utils.Set.add(nameStr->Utils.String.capitalize)->ignore
|
|
42
|
-
})
|
|
32
|
+
->Array.forEach(name =>
|
|
33
|
+
capitalizedBlockFields
|
|
34
|
+
->Utils.Set.add((name :> string)->Utils.String.capitalize)
|
|
35
|
+
->ignore
|
|
36
|
+
)
|
|
43
37
|
selectedTransactionFields
|
|
44
38
|
->Utils.Set.toArray
|
|
45
|
-
->Array.forEach(name =>
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
capitalizedTransactionFields->Utils.Set.add(nameStr->Utils.String.capitalize)->ignore
|
|
51
|
-
})
|
|
39
|
+
->Array.forEach(name =>
|
|
40
|
+
capitalizedTransactionFields
|
|
41
|
+
->Utils.Set.add((name :> string)->Utils.String.capitalize)
|
|
42
|
+
->ignore
|
|
43
|
+
)
|
|
52
44
|
|
|
53
45
|
let eventFilters = getEventFiltersOrThrow(chain)
|
|
54
46
|
if dependsOnAddresses {
|
|
@@ -130,39 +122,42 @@ let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
|
130
122
|
{
|
|
131
123
|
getLogSelectionOrThrow,
|
|
132
124
|
fieldSelection,
|
|
133
|
-
nonOptionalBlockFieldNames: nonOptionalBlockFieldNames->Utils.Set.toArray,
|
|
134
|
-
nonOptionalTransactionFieldNames: nonOptionalTransactionFieldNames->Utils.Set.toArray,
|
|
135
125
|
}
|
|
136
126
|
}
|
|
137
127
|
|
|
138
128
|
let memoGetSelectionConfig = (~chain) =>
|
|
139
129
|
Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
|
|
140
130
|
|
|
131
|
+
// Surfaced by HyperSyncClient.getHeight (Rust) when HyperSync rejects the API
|
|
132
|
+
// token. The corrupted-token test feeds the real server error through this
|
|
133
|
+
// check so it can't silently drift away from what getHeightOrThrow guards on.
|
|
134
|
+
let isUnauthorizedError = (message: string) => message->String.includes("401 Unauthorized")
|
|
135
|
+
|
|
141
136
|
type options = {
|
|
142
137
|
chain: ChainMap.Chain.t,
|
|
143
138
|
endpointUrl: string,
|
|
144
|
-
|
|
139
|
+
allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
|
|
145
140
|
eventRouter: EventRouter.t<Internal.evmEventConfig>,
|
|
146
141
|
apiToken: option<string>,
|
|
147
|
-
clientMaxRetries: int,
|
|
148
142
|
clientTimeoutMillis: int,
|
|
149
143
|
lowercaseAddresses: bool,
|
|
150
144
|
serializationFormat: HyperSyncClient.serializationFormat,
|
|
151
145
|
enableQueryCaching: bool,
|
|
146
|
+
logLevel: HyperSyncClient.logLevel,
|
|
152
147
|
}
|
|
153
148
|
|
|
154
149
|
let make = (
|
|
155
150
|
{
|
|
156
151
|
chain,
|
|
157
152
|
endpointUrl,
|
|
158
|
-
|
|
153
|
+
allEventParams,
|
|
159
154
|
eventRouter,
|
|
160
155
|
apiToken,
|
|
161
|
-
clientMaxRetries,
|
|
162
156
|
clientTimeoutMillis,
|
|
163
157
|
lowercaseAddresses,
|
|
164
158
|
serializationFormat,
|
|
165
159
|
enableQueryCaching,
|
|
160
|
+
logLevel,
|
|
166
161
|
}: options,
|
|
167
162
|
): t => {
|
|
168
163
|
let name = "HyperSync"
|
|
@@ -177,45 +172,31 @@ Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
|
177
172
|
Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
178
173
|
}
|
|
179
174
|
|
|
180
|
-
let client = HyperSyncClient.make(
|
|
175
|
+
let client = switch HyperSyncClient.make(
|
|
181
176
|
~url=endpointUrl,
|
|
182
177
|
~apiToken,
|
|
183
|
-
~maxNumRetries=clientMaxRetries,
|
|
184
178
|
~httpReqTimeoutMillis=clientTimeoutMillis,
|
|
179
|
+
~eventParams=allEventParams,
|
|
185
180
|
~enableChecksumAddresses=!lowercaseAddresses,
|
|
186
181
|
~serializationFormat,
|
|
187
182
|
~enableQueryCaching,
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
switch HyperSyncClient.Decoder.fromSignatures(allEventSignatures) {
|
|
196
|
-
| exception exn =>
|
|
197
|
-
exn->ErrorHandling.mkLogAndRaise(
|
|
198
|
-
~msg="Failed to instantiate a decoder from hypersync client, please double check your ABI",
|
|
199
|
-
)
|
|
200
|
-
| decoder =>
|
|
201
|
-
if lowercaseAddresses {
|
|
202
|
-
decoder.disableChecksummedAddresses()
|
|
203
|
-
} else {
|
|
204
|
-
decoder.enableChecksummedAddresses()
|
|
205
|
-
}
|
|
206
|
-
decoder
|
|
207
|
-
}
|
|
208
|
-
}
|
|
183
|
+
~logLevel,
|
|
184
|
+
) {
|
|
185
|
+
| client => client
|
|
186
|
+
| exception exn =>
|
|
187
|
+
exn->ErrorHandling.mkLogAndRaise(
|
|
188
|
+
~msg="Failed to instantiate the hypersync client, please double check your ABI",
|
|
189
|
+
)
|
|
209
190
|
}
|
|
210
191
|
|
|
211
192
|
exception UndefinedValue
|
|
212
193
|
|
|
213
194
|
let makeEventBatchQueueItem = (
|
|
214
|
-
item:
|
|
195
|
+
item: HyperSyncClient.EventItems.item,
|
|
215
196
|
~params: Internal.eventParams,
|
|
216
197
|
~eventConfig: Internal.evmEventConfig,
|
|
217
198
|
): Internal.item => {
|
|
218
|
-
let {block,
|
|
199
|
+
let {block, transaction, logIndex, srcAddress} = item
|
|
219
200
|
let chainId = chain->ChainMap.Chain.toChainId
|
|
220
201
|
|
|
221
202
|
Internal.Event({
|
|
@@ -223,7 +204,7 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
223
204
|
timestamp: block.timestamp->Belt.Option.getUnsafe,
|
|
224
205
|
chain,
|
|
225
206
|
blockNumber: block.number->Belt.Option.getUnsafe,
|
|
226
|
-
logIndex
|
|
207
|
+
logIndex,
|
|
227
208
|
event: {
|
|
228
209
|
contractName: eventConfig.contractName,
|
|
229
210
|
eventName: eventConfig.name,
|
|
@@ -231,8 +212,8 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
231
212
|
params,
|
|
232
213
|
transaction,
|
|
233
214
|
block: block->(Utils.magic: HyperSyncClient.ResponseTypes.block => Internal.eventBlock),
|
|
234
|
-
srcAddress
|
|
235
|
-
logIndex
|
|
215
|
+
srcAddress,
|
|
216
|
+
logIndex,
|
|
236
217
|
}->Internal.fromGenericEvent,
|
|
237
218
|
})
|
|
238
219
|
}
|
|
@@ -248,7 +229,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
248
229
|
~retry,
|
|
249
230
|
~logger,
|
|
250
231
|
) => {
|
|
251
|
-
let mkLogAndRaise = ErrorHandling.mkLogAndRaise(~logger, ...)
|
|
252
232
|
let totalTimeRef = Hrtime.makeTimer()
|
|
253
233
|
|
|
254
234
|
let selectionConfig = selection->getSelectionConfig
|
|
@@ -272,8 +252,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
272
252
|
~toBlock,
|
|
273
253
|
~logSelections,
|
|
274
254
|
~fieldSelection=selectionConfig.fieldSelection,
|
|
275
|
-
~nonOptionalBlockFieldNames=selectionConfig.nonOptionalBlockFieldNames,
|
|
276
|
-
~nonOptionalTransactionFieldNames=selectionConfig.nonOptionalTransactionFieldNames,
|
|
277
255
|
) catch {
|
|
278
256
|
| HyperSync.GetLogs.Error(error) =>
|
|
279
257
|
throw(
|
|
@@ -301,6 +279,7 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
301
279
|
}),
|
|
302
280
|
),
|
|
303
281
|
)
|
|
282
|
+
| Source.RateLimited(_) as exn => throw(exn)
|
|
304
283
|
| exn =>
|
|
305
284
|
throw(
|
|
306
285
|
Source.GetItemsError(
|
|
@@ -329,64 +308,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
329
308
|
//In the query
|
|
330
309
|
let heighestBlockQueried = pageUnsafe.nextBlock - 1
|
|
331
310
|
|
|
332
|
-
let lastBlockQueriedPromise = switch pageUnsafe.rollbackGuard {
|
|
333
|
-
//In the case a rollbackGuard is returned (this only happens at the head for unconfirmed blocks)
|
|
334
|
-
//use these values
|
|
335
|
-
| Some({blockNumber, timestamp, hash}) =>
|
|
336
|
-
(
|
|
337
|
-
{
|
|
338
|
-
blockNumber,
|
|
339
|
-
blockTimestamp: timestamp,
|
|
340
|
-
blockHash: hash,
|
|
341
|
-
}: ReorgDetection.blockDataWithTimestamp
|
|
342
|
-
)->Promise.resolve
|
|
343
|
-
| None =>
|
|
344
|
-
//The optional block and timestamp of the last item returned by the query
|
|
345
|
-
//(Optional in the case that there are no logs returned in the query)
|
|
346
|
-
switch pageUnsafe.items->Belt.Array.get(pageUnsafe.items->Belt.Array.length - 1) {
|
|
347
|
-
| Some({block}) if block.number->Belt.Option.getUnsafe == heighestBlockQueried =>
|
|
348
|
-
//If the last log item in the current page is equal to the
|
|
349
|
-
//heighest block acounted for in the query. Simply return this
|
|
350
|
-
//value without making an extra query
|
|
351
|
-
|
|
352
|
-
(
|
|
353
|
-
{
|
|
354
|
-
blockNumber: block.number->Belt.Option.getUnsafe,
|
|
355
|
-
blockTimestamp: block.timestamp->Belt.Option.getUnsafe,
|
|
356
|
-
blockHash: block.hash->Belt.Option.getUnsafe,
|
|
357
|
-
}: ReorgDetection.blockDataWithTimestamp
|
|
358
|
-
)->Promise.resolve
|
|
359
|
-
//If it does not match it means that there were no matching logs in the last
|
|
360
|
-
//block so we should fetch the block data
|
|
361
|
-
| Some(_)
|
|
362
|
-
| None =>
|
|
363
|
-
//If there were no logs at all in the current page query then fetch the
|
|
364
|
-
//timestamp of the heighest block accounted for
|
|
365
|
-
HyperSync.queryBlockData(
|
|
366
|
-
~client,
|
|
367
|
-
~blockNumber=heighestBlockQueried,
|
|
368
|
-
~sourceName=name,
|
|
369
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
370
|
-
~logger,
|
|
371
|
-
)->Promise.thenResolve(res =>
|
|
372
|
-
switch res {
|
|
373
|
-
| Ok(Some(blockData)) => blockData
|
|
374
|
-
| Ok(None) =>
|
|
375
|
-
mkLogAndRaise(
|
|
376
|
-
Not_found,
|
|
377
|
-
~msg=`Failure, blockData for block ${heighestBlockQueried->Int.toString} unexpectedly returned None`,
|
|
378
|
-
)
|
|
379
|
-
| Error(e) =>
|
|
380
|
-
HyperSync.queryErrorToMsq(e)
|
|
381
|
-
->Obj.magic
|
|
382
|
-
->mkLogAndRaise(
|
|
383
|
-
~msg=`Failed to query blockData for block ${heighestBlockQueried->Int.toString}`,
|
|
384
|
-
)
|
|
385
|
-
}
|
|
386
|
-
)
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
311
|
let parsingTimeRef = Hrtime.makeTimer()
|
|
391
312
|
|
|
392
313
|
//Parse page items into queue items
|
|
@@ -417,47 +338,29 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
417
338
|
}
|
|
418
339
|
}
|
|
419
340
|
|
|
420
|
-
|
|
421
|
-
let parsedEvents = switch await getHscDecoder().decodeEvents(pageUnsafe.events) {
|
|
422
|
-
| exception exn =>
|
|
423
|
-
exn->mkLogAndRaise(
|
|
424
|
-
~msg="Failed to parse events using hypersync client, please double check your ABI.",
|
|
425
|
-
)
|
|
426
|
-
| parsedEvents => parsedEvents
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
pageUnsafe.items->Belt.Array.forEachWithIndex((index, item) => {
|
|
430
|
-
let {block, log} = item
|
|
341
|
+
pageUnsafe.items->Belt.Array.forEach(item => {
|
|
431
342
|
let chainId = chain->ChainMap.Chain.toChainId
|
|
432
|
-
let topic0 = log.topics->Utils.Array.firstUnsafe
|
|
433
343
|
let maybeEventConfig =
|
|
434
344
|
eventRouter->EventRouter.get(
|
|
435
345
|
~tag=EventRouter.getEvmEventId(
|
|
436
|
-
~sighash=topic0->EvmTypes.Hex.toString,
|
|
437
|
-
~topicCount=
|
|
346
|
+
~sighash=item.topic0->EvmTypes.Hex.toString,
|
|
347
|
+
~topicCount=item.topicCount,
|
|
438
348
|
),
|
|
439
349
|
~indexingAddresses,
|
|
440
|
-
~contractAddress=
|
|
441
|
-
~blockNumber=block.number->Belt.Option.getUnsafe,
|
|
350
|
+
~contractAddress=item.srcAddress,
|
|
351
|
+
~blockNumber=item.block.number->Belt.Option.getUnsafe,
|
|
442
352
|
)
|
|
443
|
-
let maybeDecodedEvent = parsedEvents->Array.getUnsafe(index)
|
|
444
353
|
|
|
445
|
-
switch (maybeEventConfig,
|
|
354
|
+
switch (maybeEventConfig, item.params) {
|
|
446
355
|
| (Some(eventConfig), Value(decoded)) =>
|
|
447
356
|
parsedQueueItems
|
|
448
|
-
->Array.push(
|
|
449
|
-
makeEventBatchQueueItem(
|
|
450
|
-
item,
|
|
451
|
-
~params=decoded->eventConfig.convertHyperSyncEventArgs,
|
|
452
|
-
~eventConfig,
|
|
453
|
-
),
|
|
454
|
-
)
|
|
357
|
+
->Array.push(makeEventBatchQueueItem(item, ~params=decoded, ~eventConfig))
|
|
455
358
|
->ignore
|
|
456
359
|
| (Some(eventConfig), Null | Undefined) =>
|
|
457
360
|
handleDecodeFailure(
|
|
458
361
|
~eventConfig,
|
|
459
|
-
~logIndex=
|
|
460
|
-
~blockNumber=block.number->Belt.Option.getUnsafe,
|
|
362
|
+
~logIndex=item.logIndex,
|
|
363
|
+
~blockNumber=item.block.number->Belt.Option.getUnsafe,
|
|
461
364
|
~chainId,
|
|
462
365
|
~exn=UndefinedValue,
|
|
463
366
|
)
|
|
@@ -467,14 +370,43 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
467
370
|
|
|
468
371
|
let parsingTimeElapsed = parsingTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
|
|
469
372
|
|
|
470
|
-
|
|
373
|
+
// Collect (blockNumber, blockHash) pairs we already have from the response —
|
|
374
|
+
// one per item's block plus, when present, the rollbackGuard's head block
|
|
375
|
+
// and the parent of the range's first block. Duplicates are allowed; reorg
|
|
376
|
+
// detection notices same-block-number-different-hash collisions itself.
|
|
377
|
+
let blockHashes = []
|
|
378
|
+
pageUnsafe.items->Belt.Array.forEach(({block}) => {
|
|
379
|
+
switch (block.number, block.hash) {
|
|
380
|
+
| (Some(blockNumber), Some(blockHash)) =>
|
|
381
|
+
blockHashes->Array.push({ReorgDetection.blockNumber, blockHash})->ignore
|
|
382
|
+
| _ => ()
|
|
383
|
+
}
|
|
384
|
+
})
|
|
385
|
+
switch pageUnsafe.rollbackGuard {
|
|
386
|
+
| None => ()
|
|
387
|
+
| Some({blockNumber, hash, firstBlockNumber, firstParentHash}) => {
|
|
388
|
+
blockHashes->Array.push({ReorgDetection.blockNumber, blockHash: hash})->ignore
|
|
389
|
+
blockHashes
|
|
390
|
+
->Array.push({
|
|
391
|
+
ReorgDetection.blockNumber: firstBlockNumber - 1,
|
|
392
|
+
blockHash: firstParentHash,
|
|
393
|
+
})
|
|
394
|
+
->ignore
|
|
395
|
+
}
|
|
396
|
+
}
|
|
471
397
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
398
|
+
// Best-effort timestamp for the queried-range head: prefer the rollbackGuard
|
|
399
|
+
// (set at the head for unconfirmed blocks), otherwise the last item if it
|
|
400
|
+
// happens to be in the range's last block. 0 is a tolerated placeholder
|
|
401
|
+
// when neither is available (FetchState already uses 0 in several spots).
|
|
402
|
+
let latestFetchedBlockTimestamp = switch pageUnsafe.rollbackGuard {
|
|
403
|
+
| Some({timestamp}) => timestamp
|
|
404
|
+
| None =>
|
|
405
|
+
switch pageUnsafe.items->Belt.Array.get(pageUnsafe.items->Belt.Array.length - 1) {
|
|
406
|
+
| Some({block}) if block.number->Belt.Option.getUnsafe == heighestBlockQueried =>
|
|
407
|
+
block.timestamp->Belt.Option.getUnsafe
|
|
408
|
+
| _ => 0
|
|
409
|
+
}
|
|
478
410
|
}
|
|
479
411
|
|
|
480
412
|
let totalTimeElapsed = totalTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
|
|
@@ -486,12 +418,12 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
486
418
|
}
|
|
487
419
|
|
|
488
420
|
{
|
|
489
|
-
latestFetchedBlockTimestamp
|
|
421
|
+
latestFetchedBlockTimestamp,
|
|
490
422
|
parsedQueueItems,
|
|
491
|
-
latestFetchedBlockNumber:
|
|
423
|
+
latestFetchedBlockNumber: heighestBlockQueried,
|
|
492
424
|
stats,
|
|
493
425
|
knownHeight,
|
|
494
|
-
|
|
426
|
+
blockHashes,
|
|
495
427
|
fromBlockQueried: fromBlock,
|
|
496
428
|
}
|
|
497
429
|
}
|
|
@@ -505,10 +437,6 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
505
437
|
~logger,
|
|
506
438
|
)->Promise.thenResolve(HyperSync.mapExn)
|
|
507
439
|
|
|
508
|
-
let jsonApiClient = Rest.client(endpointUrl)
|
|
509
|
-
|
|
510
|
-
let malformedTokenMessage = `Your token is malformed. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens.`
|
|
511
|
-
|
|
512
440
|
{
|
|
513
441
|
name,
|
|
514
442
|
sourceFor: Sync,
|
|
@@ -518,18 +446,18 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`)
|
|
|
518
446
|
getBlockHashes,
|
|
519
447
|
getHeightOrThrow: async () => {
|
|
520
448
|
let timerRef = Hrtime.makeTimer()
|
|
521
|
-
let result =
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
)
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
449
|
+
let result = try {
|
|
450
|
+
await client.getHeight()
|
|
451
|
+
} catch {
|
|
452
|
+
| JsExn(e) =>
|
|
453
|
+
switch e->JsExn.message {
|
|
454
|
+
| Some(message) if message->isUnauthorizedError =>
|
|
455
|
+
Logging.error(`Your ENVIO_API_TOKEN was rejected by HyperSync (401 Unauthorized). The indexer will not be able to fetch events. Update the token and try again using 'envio start' or 'envio dev'. For more info: https://docs.envio.dev/docs/HyperSync/api-tokens`)
|
|
456
|
+
// Retrying an unauthorized request can never succeed, so block forever
|
|
457
|
+
let _ = await Promise.make((_, _) => ())
|
|
458
|
+
0
|
|
459
|
+
| _ => throw(JsExn(e))
|
|
460
|
+
}
|
|
533
461
|
}
|
|
534
462
|
let seconds = timerRef->Hrtime.timeSince->Hrtime.toSecondsFloat
|
|
535
463
|
Prometheus.SourceRequestCount.increment(
|