envio 3.3.0-alpha.3 → 3.3.0-alpha.5
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 +10 -0
- package/package.json +7 -7
- package/src/Batch.res.mjs +1 -1
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +1 -3
- package/src/ChainFetching.res.mjs +3 -3
- package/src/ChainState.res +44 -19
- package/src/ChainState.res.mjs +25 -23
- package/src/ChainState.resi +3 -3
- package/src/Config.res +3 -0
- package/src/Config.res.mjs +3 -1
- package/src/Core.res +0 -3
- package/src/Ecosystem.res +0 -4
- package/src/EventConfigBuilder.res +3 -0
- package/src/EventConfigBuilder.res.mjs +7 -1
- package/src/FetchState.res +73 -160
- package/src/FetchState.res.mjs +120 -222
- package/src/IndexingAddresses.res +105 -0
- package/src/IndexingAddresses.res.mjs +100 -0
- package/src/IndexingAddresses.resi +32 -0
- package/src/Internal.res +5 -0
- package/src/Main.res +21 -24
- package/src/Main.res.mjs +21 -20
- package/src/Metrics.res +33 -0
- package/src/Metrics.res.mjs +39 -0
- package/src/Prometheus.res +2 -20
- package/src/Prometheus.res.mjs +83 -95
- package/src/SimulateItems.res +4 -0
- package/src/TestIndexer.res +43 -17
- package/src/TestIndexer.res.mjs +16 -9
- package/src/bindings/Viem.res +0 -41
- package/src/bindings/Viem.res.mjs +1 -43
- package/src/sources/Evm.res +17 -39
- package/src/sources/Evm.res.mjs +8 -40
- package/src/sources/EvmChain.res +3 -1
- package/src/sources/EvmChain.res.mjs +2 -1
- package/src/sources/EvmRpcClient.res +36 -5
- package/src/sources/EvmRpcClient.res.mjs +7 -4
- package/src/sources/Fuel.res +0 -2
- package/src/sources/Fuel.res.mjs +0 -1
- package/src/sources/HyperSyncClient.res +0 -35
- package/src/sources/HyperSyncClient.res.mjs +1 -8
- package/src/sources/Rpc.res +15 -47
- package/src/sources/Rpc.res.mjs +25 -56
- package/src/sources/RpcSource.res +30 -73
- package/src/sources/RpcSource.res.mjs +24 -73
- package/src/sources/SourceManager.res +1 -1
- package/src/sources/SourceManager.res.mjs +1 -1
- package/src/sources/Svm.res +10 -17
- package/src/sources/Svm.res.mjs +6 -18
- package/src/sources/TransactionStore.res +98 -76
- package/src/sources/TransactionStore.res.mjs +49 -35
package/evm.schema.json
CHANGED
|
@@ -548,6 +548,16 @@
|
|
|
548
548
|
"null"
|
|
549
549
|
]
|
|
550
550
|
},
|
|
551
|
+
"headers": {
|
|
552
|
+
"description": "Optional HTTP headers sent with every request to this RPC endpoint, e.g. an Authorization bearer token for gated endpoints. Values support ${ENV_VAR} interpolation.",
|
|
553
|
+
"type": [
|
|
554
|
+
"object",
|
|
555
|
+
"null"
|
|
556
|
+
],
|
|
557
|
+
"additionalProperties": {
|
|
558
|
+
"type": "string"
|
|
559
|
+
}
|
|
560
|
+
},
|
|
551
561
|
"initial_block_interval": {
|
|
552
562
|
"description": "The starting interval in range of blocks per query",
|
|
553
563
|
"type": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.3.0-alpha.
|
|
3
|
+
"version": "3.3.0-alpha.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.mjs",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"yargs": "17.7.2",
|
|
58
58
|
"@rescript/runtime": "12.2.0",
|
|
59
59
|
"rescript-schema": "9.5.1",
|
|
60
|
-
"viem": "2.
|
|
60
|
+
"viem": "2.54.0",
|
|
61
61
|
"dotenv": "16.4.5",
|
|
62
62
|
"date-fns": "3.3.1",
|
|
63
63
|
"@rescript/react": "0.14.1",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"tsx": "4.21.0"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
|
-
"envio-linux-x64": "3.3.0-alpha.
|
|
73
|
-
"envio-linux-x64-musl": "3.3.0-alpha.
|
|
74
|
-
"envio-linux-arm64": "3.3.0-alpha.
|
|
75
|
-
"envio-darwin-x64": "3.3.0-alpha.
|
|
76
|
-
"envio-darwin-arm64": "3.3.0-alpha.
|
|
72
|
+
"envio-linux-x64": "3.3.0-alpha.5",
|
|
73
|
+
"envio-linux-x64-musl": "3.3.0-alpha.5",
|
|
74
|
+
"envio-linux-arm64": "3.3.0-alpha.5",
|
|
75
|
+
"envio-darwin-x64": "3.3.0-alpha.5",
|
|
76
|
+
"envio-darwin-arm64": "3.3.0-alpha.5"
|
|
77
77
|
}
|
|
78
78
|
}
|
package/src/Batch.res.mjs
CHANGED
|
@@ -27,7 +27,7 @@ function getProgressedChainsById(chainsBeforeBatch, batchSizePerChain, progressB
|
|
|
27
27
|
let progressedChain;
|
|
28
28
|
if (batchSize !== undefined) {
|
|
29
29
|
let leftItems = fetchState.buffer.slice(batchSize);
|
|
30
|
-
progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, FetchState.updateInternal(fetchState, undefined,
|
|
30
|
+
progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, FetchState.updateInternal(fetchState, undefined, leftItems, undefined, undefined), batchSize);
|
|
31
31
|
} else {
|
|
32
32
|
progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, chainBeforeBatch.fetchState, 0);
|
|
33
33
|
}
|
package/src/Bin.res
CHANGED
|
@@ -71,6 +71,9 @@ let run = async args => {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
} catch {
|
|
74
|
+
| Main.FatalError(_) =>
|
|
75
|
+
// Already logged with full context by Main.start's onError; just exit.
|
|
76
|
+
NodeJs.process->NodeJs.exitWithCode(Failure)
|
|
74
77
|
| exn =>
|
|
75
78
|
// Log just the exception's own message — wrapping it in "Failed at
|
|
76
79
|
// initialization" and pino's err serializer buries the real cause under
|
package/src/Bin.res.mjs
CHANGED
|
@@ -79,6 +79,10 @@ async function run(args) {
|
|
|
79
79
|
}
|
|
80
80
|
} catch (raw_exn) {
|
|
81
81
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
82
|
+
if (exn.RE_EXN_ID === Main.FatalError) {
|
|
83
|
+
Process.exit(1);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
82
86
|
let e = Primitive_exceptions.internalToException(exn);
|
|
83
87
|
let message = e.RE_EXN_ID === "JsExn" ? Stdlib_Option.getOr(Stdlib_JsExn.message(e._1), "Failed at initialization") : "Failed at initialization";
|
|
84
88
|
Logging.error(message);
|
package/src/ChainFetching.res
CHANGED
|
@@ -11,13 +11,12 @@ type partitionQueryResponse = {
|
|
|
11
11
|
let runContractRegistersOrThrow = async (
|
|
12
12
|
~itemsWithContractRegister: array<Internal.item>,
|
|
13
13
|
~config: Config.t,
|
|
14
|
-
~chainState: ChainState.t,
|
|
15
14
|
~page: option<TransactionStore.t>,
|
|
16
15
|
) => {
|
|
17
16
|
// contractRegister handlers can read event.transaction, so materialise the
|
|
18
17
|
// selected fields onto the payloads before running them. All items belong to
|
|
19
18
|
// the chain being fetched, hence its single page store and mask.
|
|
20
|
-
await
|
|
19
|
+
await ChainState.materializePageItems(~items=itemsWithContractRegister, ~page)
|
|
21
20
|
|
|
22
21
|
let itemsWithDcs = []
|
|
23
22
|
|
|
@@ -233,7 +232,6 @@ let rec onQueryResponse = async (
|
|
|
233
232
|
switch await runContractRegistersOrThrow(
|
|
234
233
|
~itemsWithContractRegister,
|
|
235
234
|
~config=state->IndexerState.config,
|
|
236
|
-
~chainState,
|
|
237
235
|
~page=transactionStore,
|
|
238
236
|
) {
|
|
239
237
|
| exception exn => IndexerState.errorExit(state, exn->ErrorHandling.make)
|
|
@@ -16,8 +16,8 @@ import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
|
16
16
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
17
17
|
import * as ContractRegisterContext from "./ContractRegisterContext.res.mjs";
|
|
18
18
|
|
|
19
|
-
async function runContractRegistersOrThrow(itemsWithContractRegister, config,
|
|
20
|
-
await ChainState.materializePageItems(
|
|
19
|
+
async function runContractRegistersOrThrow(itemsWithContractRegister, config, page) {
|
|
20
|
+
await ChainState.materializePageItems(itemsWithContractRegister, page);
|
|
21
21
|
let itemsWithDcs = [];
|
|
22
22
|
let onRegister = (item, contractAddress, contractName) => {
|
|
23
23
|
let dc_registrationBlock = item.blockNumber;
|
|
@@ -145,7 +145,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
145
145
|
}
|
|
146
146
|
let newItemsWithDcs;
|
|
147
147
|
try {
|
|
148
|
-
newItemsWithDcs = await runContractRegistersOrThrow(itemsWithContractRegister, IndexerState.config(state),
|
|
148
|
+
newItemsWithDcs = await runContractRegistersOrThrow(itemsWithContractRegister, IndexerState.config(state), transactionStore);
|
|
149
149
|
} catch (raw_exn) {
|
|
150
150
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
151
151
|
return IndexerState.errorExit(state, ErrorHandling.make(exn, undefined, undefined));
|
package/src/ChainState.res
CHANGED
|
@@ -5,6 +5,9 @@
|
|
|
5
5
|
type t = {
|
|
6
6
|
logger: Pino.t,
|
|
7
7
|
mutable fetchState: FetchState.t,
|
|
8
|
+
// The chain-wide address index. Not `mutable`: the dict is mutated in place by
|
|
9
|
+
// register/rollback, so the reference is stable across fetchState versions.
|
|
10
|
+
indexingAddresses: IndexingAddresses.t,
|
|
8
11
|
sourceManager: SourceManager.t,
|
|
9
12
|
chainConfig: Config.chain,
|
|
10
13
|
mutable isProgressAtHead: bool,
|
|
@@ -21,8 +24,6 @@ type t = {
|
|
|
21
24
|
// transactionIndex). Fetch responses merge their page in; entries are pruned
|
|
22
25
|
// as the chain progresses and dropped above the target on rollback.
|
|
23
26
|
transactionStore: TransactionStore.t,
|
|
24
|
-
// Bitmask of the transaction fields the store materialises at batch prep.
|
|
25
|
-
transactionFieldMask: float,
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
// Per-chain shape returned by the status API.
|
|
@@ -60,6 +61,7 @@ let configAddresses = (chainConfig: Config.chain): array<Internal.indexingAddres
|
|
|
60
61
|
let make = (
|
|
61
62
|
~chainConfig: Config.chain,
|
|
62
63
|
~fetchState: FetchState.t,
|
|
64
|
+
~indexingAddresses: IndexingAddresses.t,
|
|
63
65
|
~sourceManager: SourceManager.t,
|
|
64
66
|
~reorgDetection: ReorgDetection.t,
|
|
65
67
|
~committedProgressBlockNumber: int,
|
|
@@ -67,11 +69,12 @@ let make = (
|
|
|
67
69
|
~numEventsProcessed=0.,
|
|
68
70
|
~timestampCaughtUpToHeadOrEndblock=None,
|
|
69
71
|
~isProgressAtHead=false,
|
|
70
|
-
~
|
|
72
|
+
~transactionStore=TransactionStore.make(~ecosystem=Ecosystem.Evm, ~shouldChecksum=false),
|
|
71
73
|
~logger: Pino.t,
|
|
72
74
|
): t => {
|
|
73
75
|
logger,
|
|
74
76
|
fetchState,
|
|
77
|
+
indexingAddresses,
|
|
75
78
|
sourceManager,
|
|
76
79
|
chainConfig,
|
|
77
80
|
isProgressAtHead,
|
|
@@ -81,8 +84,7 @@ let make = (
|
|
|
81
84
|
pendingBudget: 0.,
|
|
82
85
|
reorgDetection,
|
|
83
86
|
safeCheckpointTracking,
|
|
84
|
-
transactionStore
|
|
85
|
-
transactionFieldMask,
|
|
87
|
+
transactionStore,
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
let makeInternal = (
|
|
@@ -220,8 +222,12 @@ let makeInternal = (
|
|
|
220
222
|
| None => ()
|
|
221
223
|
}
|
|
222
224
|
|
|
225
|
+
let contractConfigs = IndexingAddresses.makeContractConfigs(~eventConfigs)
|
|
226
|
+
let indexingAddressIndex = IndexingAddresses.make(~contractConfigs, ~addresses=indexingAddresses)
|
|
227
|
+
|
|
223
228
|
let fetchState = FetchState.make(
|
|
224
229
|
~maxAddrInPartition=config.maxAddrInPartition,
|
|
230
|
+
~contractConfigs,
|
|
225
231
|
~addresses=indexingAddresses,
|
|
226
232
|
~progressBlockNumber,
|
|
227
233
|
~startBlock,
|
|
@@ -265,11 +271,13 @@ let makeInternal = (
|
|
|
265
271
|
let evmRpcs: array<EvmChain.rpc> = rpcs->Array.map((rpc): EvmChain.rpc => {
|
|
266
272
|
let syncConfig = rpc.syncConfig
|
|
267
273
|
let ws = rpc.ws
|
|
274
|
+
let headers = rpc.headers
|
|
268
275
|
{
|
|
269
276
|
url: rpc.url,
|
|
270
277
|
sourceFor: rpc.sourceFor,
|
|
271
278
|
?syncConfig,
|
|
272
279
|
?ws,
|
|
280
|
+
?headers,
|
|
273
281
|
}
|
|
274
282
|
})
|
|
275
283
|
EvmChain.makeSources(
|
|
@@ -314,6 +322,7 @@ let makeInternal = (
|
|
|
314
322
|
make(
|
|
315
323
|
~chainConfig,
|
|
316
324
|
~fetchState,
|
|
325
|
+
~indexingAddresses=indexingAddressIndex,
|
|
317
326
|
~sourceManager=SourceManager.make(~sources, ~isRealtime, ~reducedPollingInterval?),
|
|
318
327
|
~reorgDetection=ReorgDetection.make(
|
|
319
328
|
~chainReorgCheckpoints,
|
|
@@ -328,7 +337,10 @@ let makeInternal = (
|
|
|
328
337
|
~committedProgressBlockNumber=progressBlockNumber,
|
|
329
338
|
~timestampCaughtUpToHeadOrEndblock,
|
|
330
339
|
~numEventsProcessed,
|
|
331
|
-
~
|
|
340
|
+
~transactionStore=TransactionStore.make(
|
|
341
|
+
~ecosystem=config.ecosystem.name,
|
|
342
|
+
~shouldChecksum=!lowercaseAddresses,
|
|
343
|
+
),
|
|
332
344
|
~logger,
|
|
333
345
|
)
|
|
334
346
|
}
|
|
@@ -418,7 +430,8 @@ let timestampCaughtUpToHeadOrEndblock = (cs: t) => cs.timestampCaughtUpToHeadOrE
|
|
|
418
430
|
// Fetch-frontier reads. The FetchState is owned here; callers go through these
|
|
419
431
|
// rather than reaching into it.
|
|
420
432
|
let knownHeight = (cs: t) => cs.fetchState.knownHeight
|
|
421
|
-
let
|
|
433
|
+
let contractAddresses = (cs: t, ~contractName) =>
|
|
434
|
+
cs.indexingAddresses->IndexingAddresses.getContractAddresses(~contractName)
|
|
422
435
|
let bufferSize = (cs: t) => cs.fetchState->FetchState.bufferSize
|
|
423
436
|
let bufferReadyCount = (cs: t) => cs.fetchState->FetchState.bufferReadyCount
|
|
424
437
|
let getProgressPercentage = (cs: t) => cs.fetchState->FetchState.getProgressPercentage
|
|
@@ -503,18 +516,14 @@ let isAtHeadWithoutEndBlock = (cs: t) =>
|
|
|
503
516
|
// Materialise the chain store's selected transaction fields onto a batch's
|
|
504
517
|
// items at batch prep (the persistent-store path).
|
|
505
518
|
let materializeBatchItems = (cs: t, ~items: array<Internal.item>) =>
|
|
506
|
-
cs.transactionStore->TransactionStore.materializeItems(~items
|
|
519
|
+
cs.transactionStore->TransactionStore.materializeItems(~items)
|
|
507
520
|
|
|
508
521
|
// Materialise a fetch-response page's transactions onto its items before
|
|
509
522
|
// contract-register handlers read them. `None` pages (RPC/Fuel/Simulate keep the
|
|
510
523
|
// transaction inline) are a no-op.
|
|
511
|
-
let materializePageItems = (
|
|
512
|
-
cs: t,
|
|
513
|
-
~items: array<Internal.item>,
|
|
514
|
-
~page: option<TransactionStore.t>,
|
|
515
|
-
) =>
|
|
524
|
+
let materializePageItems = (~items: array<Internal.item>, ~page: option<TransactionStore.t>) =>
|
|
516
525
|
switch page {
|
|
517
|
-
| Some(store) => store->TransactionStore.materializeItems(~items
|
|
526
|
+
| Some(store) => store->TransactionStore.materializeItems(~items)
|
|
518
527
|
| None => Promise.resolve()
|
|
519
528
|
}
|
|
520
529
|
|
|
@@ -536,12 +545,21 @@ let handleQueryResult = (
|
|
|
536
545
|
|
|
537
546
|
let fs = switch newItemsWithDcs {
|
|
538
547
|
| [] => cs.fetchState
|
|
539
|
-
| _ =>
|
|
548
|
+
| _ =>
|
|
549
|
+
cs.fetchState->FetchState.registerDynamicContracts(
|
|
550
|
+
~indexingAddresses=cs.indexingAddresses,
|
|
551
|
+
newItemsWithDcs,
|
|
552
|
+
)
|
|
540
553
|
}
|
|
541
554
|
|
|
542
555
|
cs.fetchState =
|
|
543
556
|
fs
|
|
544
|
-
->FetchState.handleQueryResult(
|
|
557
|
+
->FetchState.handleQueryResult(
|
|
558
|
+
~indexingAddresses=cs.indexingAddresses,
|
|
559
|
+
~query,
|
|
560
|
+
~latestFetchedBlock,
|
|
561
|
+
~newItems,
|
|
562
|
+
)
|
|
545
563
|
->FetchState.updateKnownHeight(~knownHeight)
|
|
546
564
|
|
|
547
565
|
// The query is no longer in flight, so release its reservation.
|
|
@@ -611,7 +629,7 @@ let toChainData = (cs: t): chainData => {
|
|
|
611
629
|
numBatchesFetched: 0,
|
|
612
630
|
startBlock: cs.fetchState.startBlock,
|
|
613
631
|
endBlock: cs.fetchState.endBlock,
|
|
614
|
-
numAddresses: cs.
|
|
632
|
+
numAddresses: cs.indexingAddresses->IndexingAddresses.size,
|
|
615
633
|
}
|
|
616
634
|
|
|
617
635
|
// Snapshot the inputs a batch build needs from this chain.
|
|
@@ -770,7 +788,11 @@ let rollback = (
|
|
|
770
788
|
)
|
|
771
789
|
| None => ()
|
|
772
790
|
}
|
|
773
|
-
cs.fetchState =
|
|
791
|
+
cs.fetchState =
|
|
792
|
+
cs.fetchState->FetchState.rollback(
|
|
793
|
+
~indexingAddresses=cs.indexingAddresses,
|
|
794
|
+
~targetBlockNumber=newProgressBlockNumber,
|
|
795
|
+
)
|
|
774
796
|
cs.transactionStore->TransactionStore.rollback(newProgressBlockNumber)
|
|
775
797
|
cs.committedProgressBlockNumber = newProgressBlockNumber
|
|
776
798
|
cs.numEventsProcessed = newTotalEventsProcessed
|
|
@@ -781,7 +803,10 @@ let rollback = (
|
|
|
781
803
|
~blockNumber=rollbackTargetBlockNumber,
|
|
782
804
|
)
|
|
783
805
|
cs.fetchState =
|
|
784
|
-
cs.fetchState->FetchState.rollback(
|
|
806
|
+
cs.fetchState->FetchState.rollback(
|
|
807
|
+
~indexingAddresses=cs.indexingAddresses,
|
|
808
|
+
~targetBlockNumber=rollbackTargetBlockNumber,
|
|
809
|
+
)
|
|
785
810
|
cs.transactionStore->TransactionStore.rollback(rollbackTargetBlockNumber)
|
|
786
811
|
cs.committedProgressBlockNumber = Pervasives.min(
|
|
787
812
|
cs.committedProgressBlockNumber,
|
package/src/ChainState.res.mjs
CHANGED
|
@@ -21,6 +21,7 @@ import * as HyperFuelSource from "./sources/HyperFuelSource.res.mjs";
|
|
|
21
21
|
import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
|
|
22
22
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
23
23
|
import * as TransactionStore from "./sources/TransactionStore.res.mjs";
|
|
24
|
+
import * as IndexingAddresses from "./IndexingAddresses.res.mjs";
|
|
24
25
|
import * as SvmHyperSyncSource from "./sources/SvmHyperSyncSource.res.mjs";
|
|
25
26
|
import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
|
|
26
27
|
|
|
@@ -38,15 +39,16 @@ function configAddresses(chainConfig) {
|
|
|
38
39
|
return addresses;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
function make(chainConfig, fetchState, sourceManager, reorgDetection, committedProgressBlockNumber, safeCheckpointTrackingOpt, numEventsProcessedOpt, timestampCaughtUpToHeadOrEndblockOpt, isProgressAtHeadOpt,
|
|
42
|
+
function make(chainConfig, fetchState, indexingAddresses, sourceManager, reorgDetection, committedProgressBlockNumber, safeCheckpointTrackingOpt, numEventsProcessedOpt, timestampCaughtUpToHeadOrEndblockOpt, isProgressAtHeadOpt, transactionStoreOpt, logger) {
|
|
42
43
|
let safeCheckpointTracking = safeCheckpointTrackingOpt !== undefined ? Primitive_option.valFromOption(safeCheckpointTrackingOpt) : undefined;
|
|
43
44
|
let numEventsProcessed = numEventsProcessedOpt !== undefined ? numEventsProcessedOpt : 0;
|
|
44
45
|
let timestampCaughtUpToHeadOrEndblock = timestampCaughtUpToHeadOrEndblockOpt !== undefined ? Primitive_option.valFromOption(timestampCaughtUpToHeadOrEndblockOpt) : undefined;
|
|
45
46
|
let isProgressAtHead = isProgressAtHeadOpt !== undefined ? isProgressAtHeadOpt : false;
|
|
46
|
-
let
|
|
47
|
+
let transactionStore = transactionStoreOpt !== undefined ? Primitive_option.valFromOption(transactionStoreOpt) : TransactionStore.make("evm", false);
|
|
47
48
|
return {
|
|
48
49
|
logger: logger,
|
|
49
50
|
fetchState: fetchState,
|
|
51
|
+
indexingAddresses: indexingAddresses,
|
|
50
52
|
sourceManager: sourceManager,
|
|
51
53
|
chainConfig: chainConfig,
|
|
52
54
|
isProgressAtHead: isProgressAtHead,
|
|
@@ -56,8 +58,7 @@ function make(chainConfig, fetchState, sourceManager, reorgDetection, committedP
|
|
|
56
58
|
pendingBudget: 0,
|
|
57
59
|
reorgDetection: reorgDetection,
|
|
58
60
|
safeCheckpointTracking: safeCheckpointTracking,
|
|
59
|
-
transactionStore:
|
|
60
|
-
transactionFieldMask: transactionFieldMask
|
|
61
|
+
transactionStore: transactionStore
|
|
61
62
|
};
|
|
62
63
|
}
|
|
63
64
|
|
|
@@ -120,7 +121,9 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
120
121
|
}
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
|
-
let
|
|
124
|
+
let contractConfigs = IndexingAddresses.makeContractConfigs(eventConfigs);
|
|
125
|
+
let indexingAddressIndex = IndexingAddresses.make(contractConfigs, indexingAddresses);
|
|
126
|
+
let fetchState = FetchState.make(startBlock, endBlock, eventConfigs, contractConfigs, indexingAddresses, config.maxAddrInPartition, chainConfig.id, (config.batchSize << 1), knownHeight, progressBlockNumber, onBlockConfigs, Primitive_int.max(!config.shouldRollbackOnReorg || isInReorgThreshold ? 0 : chainConfig.maxReorgDepth, chainConfig.blockLag), Primitive_option.some(firstEventBlock));
|
|
124
127
|
let chainReorgCheckpoints = Stdlib_Array.filterMap(reorgCheckpoints, reorgCheckpoint => {
|
|
125
128
|
if (reorgCheckpoint.chain_id === chainConfig.id) {
|
|
126
129
|
return reorgCheckpoint;
|
|
@@ -140,11 +143,13 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
140
143
|
let evmRpcs = sources.rpcs.map(rpc => {
|
|
141
144
|
let syncConfig = rpc.syncConfig;
|
|
142
145
|
let ws = rpc.ws;
|
|
146
|
+
let headers = rpc.headers;
|
|
143
147
|
return {
|
|
144
148
|
url: rpc.url,
|
|
145
149
|
sourceFor: rpc.sourceFor,
|
|
146
150
|
syncConfig: syncConfig,
|
|
147
|
-
ws: ws
|
|
151
|
+
ws: ws,
|
|
152
|
+
headers: headers
|
|
148
153
|
};
|
|
149
154
|
});
|
|
150
155
|
sources$1 = EvmChain.makeSources(chain, evmContracts, sources.hypersync, evmRpcs, lowercaseAddresses);
|
|
@@ -176,7 +181,7 @@ function makeInternal(chainConfig, indexingAddresses, startBlock, endBlock, firs
|
|
|
176
181
|
sources$1 = sources._0;
|
|
177
182
|
break;
|
|
178
183
|
}
|
|
179
|
-
return make(chainConfig, fetchState, 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, config.ecosystem.
|
|
184
|
+
return make(chainConfig, fetchState, 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)), logger);
|
|
180
185
|
}
|
|
181
186
|
|
|
182
187
|
function makeFromConfig(chainConfig, config, registrations, knownHeight) {
|
|
@@ -240,8 +245,8 @@ function knownHeight(cs) {
|
|
|
240
245
|
return cs.fetchState.knownHeight;
|
|
241
246
|
}
|
|
242
247
|
|
|
243
|
-
function
|
|
244
|
-
return cs.
|
|
248
|
+
function contractAddresses(cs, contractName) {
|
|
249
|
+
return IndexingAddresses.getContractAddresses(cs.indexingAddresses, contractName);
|
|
245
250
|
}
|
|
246
251
|
|
|
247
252
|
function bufferSize(cs) {
|
|
@@ -326,12 +331,12 @@ function isAtHeadWithoutEndBlock(cs) {
|
|
|
326
331
|
}
|
|
327
332
|
|
|
328
333
|
function materializeBatchItems(cs, items) {
|
|
329
|
-
return TransactionStore.materializeItems(cs.transactionStore, items
|
|
334
|
+
return TransactionStore.materializeItems(cs.transactionStore, items);
|
|
330
335
|
}
|
|
331
336
|
|
|
332
|
-
function materializePageItems(
|
|
337
|
+
function materializePageItems(items, page) {
|
|
333
338
|
if (page !== undefined) {
|
|
334
|
-
return TransactionStore.materializeItems(Primitive_option.valFromOption(page), items
|
|
339
|
+
return TransactionStore.materializeItems(Primitive_option.valFromOption(page), items);
|
|
335
340
|
} else {
|
|
336
341
|
return Promise.resolve();
|
|
337
342
|
}
|
|
@@ -341,8 +346,8 @@ function handleQueryResult(cs, query, newItems, newItemsWithDcs, latestFetchedBl
|
|
|
341
346
|
if (page !== undefined) {
|
|
342
347
|
cs.transactionStore.merge(Primitive_option.valFromOption(page));
|
|
343
348
|
}
|
|
344
|
-
let fs = newItemsWithDcs.length !== 0 ? FetchState.registerDynamicContracts(cs.fetchState, newItemsWithDcs) : cs.fetchState;
|
|
345
|
-
cs.fetchState = FetchState.updateKnownHeight(FetchState.handleQueryResult(fs, query, latestFetchedBlock, newItems), knownHeight);
|
|
349
|
+
let fs = newItemsWithDcs.length !== 0 ? FetchState.registerDynamicContracts(cs.fetchState, cs.indexingAddresses, newItemsWithDcs) : cs.fetchState;
|
|
350
|
+
cs.fetchState = FetchState.updateKnownHeight(FetchState.handleQueryResult(fs, cs.indexingAddresses, query, latestFetchedBlock, newItems), knownHeight);
|
|
346
351
|
cs.pendingBudget = Primitive_float.max(0, cs.pendingBudget - query.estResponseSize);
|
|
347
352
|
}
|
|
348
353
|
|
|
@@ -376,7 +381,6 @@ function setEndBlockToFirstEvent(cs, blockNumber) {
|
|
|
376
381
|
startBlock: init.startBlock,
|
|
377
382
|
endBlock: blockNumber,
|
|
378
383
|
normalSelection: init.normalSelection,
|
|
379
|
-
indexingAddresses: init.indexingAddresses,
|
|
380
384
|
contractConfigs: init.contractConfigs,
|
|
381
385
|
chainId: init.chainId,
|
|
382
386
|
latestOnBlockBlockNumber: init.latestOnBlockBlockNumber,
|
|
@@ -395,7 +399,6 @@ function setEndBlockToFirstEvent(cs, blockNumber) {
|
|
|
395
399
|
startBlock: init$1.startBlock,
|
|
396
400
|
endBlock: blockNumber,
|
|
397
401
|
normalSelection: init$1.normalSelection,
|
|
398
|
-
indexingAddresses: init$1.indexingAddresses,
|
|
399
402
|
contractConfigs: init$1.contractConfigs,
|
|
400
403
|
chainId: init$1.chainId,
|
|
401
404
|
latestOnBlockBlockNumber: init$1.latestOnBlockBlockNumber,
|
|
@@ -409,7 +412,7 @@ function setEndBlockToFirstEvent(cs, blockNumber) {
|
|
|
409
412
|
}
|
|
410
413
|
|
|
411
414
|
function enterReorgThreshold(cs) {
|
|
412
|
-
cs.fetchState = FetchState.updateInternal(cs.fetchState, undefined, undefined,
|
|
415
|
+
cs.fetchState = FetchState.updateInternal(cs.fetchState, undefined, undefined, cs.chainConfig.blockLag, undefined);
|
|
413
416
|
}
|
|
414
417
|
|
|
415
418
|
function toChainMetadata(cs) {
|
|
@@ -434,7 +437,7 @@ function toChainData(cs) {
|
|
|
434
437
|
numBatchesFetched: 0,
|
|
435
438
|
startBlock: cs.fetchState.startBlock,
|
|
436
439
|
endBlock: cs.fetchState.endBlock,
|
|
437
|
-
numAddresses:
|
|
440
|
+
numAddresses: IndexingAddresses.size(cs.indexingAddresses)
|
|
438
441
|
};
|
|
439
442
|
}
|
|
440
443
|
|
|
@@ -457,7 +460,7 @@ function isReadyToEnterReorgThresholdAfterBatch(cs, batch) {
|
|
|
457
460
|
function advanceAfterBatch(cs, batch, enteringReorgThreshold) {
|
|
458
461
|
let chainAfterBatch = batch.progressedChainsById[cs.fetchState.chainId];
|
|
459
462
|
if (chainAfterBatch !== undefined) {
|
|
460
|
-
cs.fetchState = enteringReorgThreshold ? FetchState.updateInternal(chainAfterBatch.fetchState, undefined, undefined,
|
|
463
|
+
cs.fetchState = enteringReorgThreshold ? FetchState.updateInternal(chainAfterBatch.fetchState, undefined, undefined, cs.chainConfig.blockLag, undefined) : chainAfterBatch.fetchState;
|
|
461
464
|
return;
|
|
462
465
|
}
|
|
463
466
|
}
|
|
@@ -489,7 +492,6 @@ function applyBatchProgress(cs, batch) {
|
|
|
489
492
|
startBlock: init.startBlock,
|
|
490
493
|
endBlock: init.endBlock,
|
|
491
494
|
normalSelection: init.normalSelection,
|
|
492
|
-
indexingAddresses: init.indexingAddresses,
|
|
493
495
|
contractConfigs: init.contractConfigs,
|
|
494
496
|
chainId: init.chainId,
|
|
495
497
|
latestOnBlockBlockNumber: init.latestOnBlockBlockNumber,
|
|
@@ -525,7 +527,7 @@ function rollback(cs, newProgressBlockNumber, eventsProcessedDiff, rollbackTarge
|
|
|
525
527
|
if (newProgressBlockNumber === undefined) {
|
|
526
528
|
if (isReorgChain) {
|
|
527
529
|
cs.reorgDetection = ReorgDetection.rollbackToValidBlockNumber(cs.reorgDetection, rollbackTargetBlockNumber);
|
|
528
|
-
cs.fetchState = FetchState.rollback(cs.fetchState, rollbackTargetBlockNumber);
|
|
530
|
+
cs.fetchState = FetchState.rollback(cs.fetchState, cs.indexingAddresses, rollbackTargetBlockNumber);
|
|
529
531
|
cs.transactionStore.rollback(rollbackTargetBlockNumber);
|
|
530
532
|
cs.committedProgressBlockNumber = Primitive_int.min(cs.committedProgressBlockNumber, rollbackTargetBlockNumber);
|
|
531
533
|
return;
|
|
@@ -547,7 +549,7 @@ function rollback(cs, newProgressBlockNumber, eventsProcessedDiff, rollbackTarge
|
|
|
547
549
|
if (safeCheckpointTracking !== undefined) {
|
|
548
550
|
cs.safeCheckpointTracking = SafeCheckpointTracking.rollback(safeCheckpointTracking, newProgressBlockNumber);
|
|
549
551
|
}
|
|
550
|
-
cs.fetchState = FetchState.rollback(cs.fetchState, newProgressBlockNumber);
|
|
552
|
+
cs.fetchState = FetchState.rollback(cs.fetchState, cs.indexingAddresses, newProgressBlockNumber);
|
|
551
553
|
cs.transactionStore.rollback(newProgressBlockNumber);
|
|
552
554
|
cs.committedProgressBlockNumber = newProgressBlockNumber;
|
|
553
555
|
cs.numEventsProcessed = newTotalEventsProcessed;
|
|
@@ -570,7 +572,7 @@ export {
|
|
|
570
572
|
startFetchingQueries,
|
|
571
573
|
timestampCaughtUpToHeadOrEndblock,
|
|
572
574
|
knownHeight,
|
|
573
|
-
|
|
575
|
+
contractAddresses,
|
|
574
576
|
bufferSize,
|
|
575
577
|
bufferReadyCount,
|
|
576
578
|
getProgressPercentage,
|
package/src/ChainState.resi
CHANGED
|
@@ -8,6 +8,7 @@ let configAddresses: Config.chain => array<Internal.indexingAddress>
|
|
|
8
8
|
let make: (
|
|
9
9
|
~chainConfig: Config.chain,
|
|
10
10
|
~fetchState: FetchState.t,
|
|
11
|
+
~indexingAddresses: IndexingAddresses.t,
|
|
11
12
|
~sourceManager: SourceManager.t,
|
|
12
13
|
~reorgDetection: ReorgDetection.t,
|
|
13
14
|
~committedProgressBlockNumber: int,
|
|
@@ -15,7 +16,7 @@ let make: (
|
|
|
15
16
|
~numEventsProcessed: float=?,
|
|
16
17
|
~timestampCaughtUpToHeadOrEndblock: option<Date.t>=?,
|
|
17
18
|
~isProgressAtHead: bool=?,
|
|
18
|
-
~
|
|
19
|
+
~transactionStore: TransactionStore.t=?,
|
|
19
20
|
~logger: Pino.t,
|
|
20
21
|
) => t
|
|
21
22
|
|
|
@@ -52,7 +53,7 @@ let timestampCaughtUpToHeadOrEndblock: t => option<Date.t>
|
|
|
52
53
|
|
|
53
54
|
// Fetch-frontier reads.
|
|
54
55
|
let knownHeight: t => int
|
|
55
|
-
let
|
|
56
|
+
let contractAddresses: (t, ~contractName: string) => array<Address.t>
|
|
56
57
|
let bufferSize: t => int
|
|
57
58
|
let bufferReadyCount: t => int
|
|
58
59
|
let getProgressPercentage: t => float
|
|
@@ -112,7 +113,6 @@ let handleQueryResult: (
|
|
|
112
113
|
) => unit
|
|
113
114
|
let materializeBatchItems: (t, ~items: array<Internal.item>) => promise<unit>
|
|
114
115
|
let materializePageItems: (
|
|
115
|
-
t,
|
|
116
116
|
~items: array<Internal.item>,
|
|
117
117
|
~page: option<TransactionStore.t>,
|
|
118
118
|
) => promise<unit>
|
package/src/Config.res
CHANGED
|
@@ -23,6 +23,7 @@ type evmRpcConfig = {
|
|
|
23
23
|
sourceFor: Source.sourceFor,
|
|
24
24
|
syncConfig: option<sourceSyncOptions>,
|
|
25
25
|
ws: option<string>,
|
|
26
|
+
headers: option<dict<string>>,
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
type sourceConfig =
|
|
@@ -156,6 +157,7 @@ let rpcConfigSchema = S.schema(s =>
|
|
|
156
157
|
"url": s.matches(S.string),
|
|
157
158
|
"for": s.matches(rpcSourceForSchema),
|
|
158
159
|
"ws": s.matches(S.option(S.string)),
|
|
160
|
+
"headers": s.matches(S.option(S.dict(S.string))),
|
|
159
161
|
"initialBlockInterval": s.matches(S.option(S.int)),
|
|
160
162
|
"backoffMultiplicative": s.matches(S.option(S.float)),
|
|
161
163
|
"accelerationAdditive": s.matches(S.option(S.int)),
|
|
@@ -907,6 +909,7 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
907
909
|
sourceFor: parseRpcSourceFor(rpcConfig["for"]),
|
|
908
910
|
syncConfig,
|
|
909
911
|
ws: rpcConfig["ws"],
|
|
912
|
+
headers: rpcConfig["headers"],
|
|
910
913
|
}
|
|
911
914
|
})
|
|
912
915
|
EvmSourceConfig({hypersync: publicChainConfig["hypersync"], rpcs})
|
package/src/Config.res.mjs
CHANGED
|
@@ -81,6 +81,7 @@ let rpcConfigSchema = S$RescriptSchema.schema(s => ({
|
|
|
81
81
|
url: s.m(S$RescriptSchema.string),
|
|
82
82
|
for: s.m(rpcSourceForSchema),
|
|
83
83
|
ws: s.m(S$RescriptSchema.option(S$RescriptSchema.string)),
|
|
84
|
+
headers: s.m(S$RescriptSchema.option(S$RescriptSchema.dict(S$RescriptSchema.string))),
|
|
84
85
|
initialBlockInterval: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
85
86
|
backoffMultiplicative: s.m(S$RescriptSchema.option(S$RescriptSchema.float)),
|
|
86
87
|
accelerationAdditive: s.m(S$RescriptSchema.option(S$RescriptSchema.int)),
|
|
@@ -606,7 +607,8 @@ function fromPublic(publicConfigJson) {
|
|
|
606
607
|
url: rpcConfig.url,
|
|
607
608
|
sourceFor: parseRpcSourceFor(rpcConfig.for),
|
|
608
609
|
syncConfig: syncConfig,
|
|
609
|
-
ws: rpcConfig.ws
|
|
610
|
+
ws: rpcConfig.ws,
|
|
611
|
+
headers: rpcConfig.headers
|
|
610
612
|
};
|
|
611
613
|
});
|
|
612
614
|
sourceConfig = {
|
package/src/Core.res
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
// tighter `Null.t` captures the exact boundary shape.
|
|
7
7
|
type evmHypersyncClientCtor
|
|
8
8
|
type evmRpcClientCtor
|
|
9
|
-
type evmDecoderCtor
|
|
10
9
|
type svmHypersyncClientCtor
|
|
11
10
|
type hyperfuelClientCtor
|
|
12
11
|
type transactionStoreCtor
|
|
@@ -18,8 +17,6 @@ type addon = {
|
|
|
18
17
|
evmHypersyncClient: evmHypersyncClientCtor,
|
|
19
18
|
@as("EvmRpcClient")
|
|
20
19
|
evmRpcClient: evmRpcClientCtor,
|
|
21
|
-
@as("EvmDecoder")
|
|
22
|
-
evmDecoder: evmDecoderCtor,
|
|
23
20
|
@as("SvmHypersyncClient")
|
|
24
21
|
svmHypersyncClient: svmHypersyncClientCtor,
|
|
25
22
|
@as("HyperfuelClient")
|
package/src/Ecosystem.res
CHANGED
|
@@ -34,10 +34,6 @@ type t = {
|
|
|
34
34
|
registration from an item's opaque payload. `event.transaction` is written
|
|
35
35
|
onto the payload at batch prep (HyperSync) or inline (RPC/simulate). */
|
|
36
36
|
toEvent: Internal.eventItem => Internal.event,
|
|
37
|
-
/** Bitmask (as a float) of the transaction fields selected across the chain's
|
|
38
|
-
events — the set the store materialises at batch prep. `0.` when the
|
|
39
|
-
ecosystem carries transactions inline. */
|
|
40
|
-
transactionFieldMask: array<Internal.eventConfig> => float,
|
|
41
37
|
/** Build the per-item child logger for an event item, with
|
|
42
38
|
ecosystem-specific log fields (EVM/Fuel: contract/event/address; SVM:
|
|
43
39
|
program/instruction/programId). Closes over the injected logger. */
|
|
@@ -442,6 +442,7 @@ let buildEvmEventConfig = (
|
|
|
442
442
|
startBlock: resolvedStartBlock,
|
|
443
443
|
selectedBlockFields,
|
|
444
444
|
selectedTransactionFields,
|
|
445
|
+
transactionFieldMask: Evm.eventTransactionFieldMask(selectedTransactionFields),
|
|
445
446
|
sighash,
|
|
446
447
|
topicCount,
|
|
447
448
|
paramsMetadata: params,
|
|
@@ -500,6 +501,7 @@ let buildSvmInstructionEventConfig = (
|
|
|
500
501
|
discriminatorByteLen,
|
|
501
502
|
includeLogs,
|
|
502
503
|
selectedTransactionFields,
|
|
504
|
+
transactionFieldMask: Svm.eventTransactionFieldMask(selectedTransactionFields),
|
|
503
505
|
accountFilters,
|
|
504
506
|
isInner,
|
|
505
507
|
accounts,
|
|
@@ -568,6 +570,7 @@ let buildFuelEventConfig = (
|
|
|
568
570
|
startBlock,
|
|
569
571
|
// Fuel keeps the transaction inline on the payload; nothing to materialise.
|
|
570
572
|
selectedTransactionFields: Utils.Set.make(),
|
|
573
|
+
transactionFieldMask: 0.,
|
|
571
574
|
kind: fuelKind,
|
|
572
575
|
}
|
|
573
576
|
}
|