envio 3.3.0-alpha.1 → 3.3.0-alpha.11
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/index.d.ts +45 -25
- package/licenses/CLA.md +35 -0
- package/licenses/EULA.md +67 -0
- package/licenses/LICENSE.md +45 -0
- package/licenses/README.md +35 -0
- package/package.json +10 -9
- package/src/Address.res +5 -2
- package/src/Address.res.mjs +3 -1
- package/src/Api.res +1 -1
- package/src/Api.res.mjs +1 -1
- package/src/Batch.res +0 -6
- package/src/Batch.res.mjs +1 -12
- package/src/BatchProcessing.res +7 -12
- package/src/BatchProcessing.res.mjs +8 -7
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +53 -16
- package/src/ChainFetching.res.mjs +37 -19
- package/src/ChainMetadata.res +1 -11
- package/src/ChainMetadata.res.mjs +1 -10
- package/src/ChainState.res +630 -161
- package/src/ChainState.res.mjs +438 -101
- package/src/ChainState.resi +77 -4
- package/src/Config.res +70 -38
- package/src/Config.res.mjs +52 -12
- package/src/ContractRegisterContext.res +2 -12
- package/src/ContractRegisterContext.res.mjs +3 -5
- package/src/Core.res +34 -3
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +130 -89
- package/src/CrossChainState.res.mjs +66 -61
- package/src/CrossChainState.resi +1 -1
- package/src/Ecosystem.res +5 -6
- package/src/Ecosystem.res.mjs +3 -3
- package/src/Envio.res +17 -11
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +191 -127
- package/src/EventConfigBuilder.res.mjs +116 -66
- package/src/EventProcessing.res +77 -28
- package/src/EventProcessing.res.mjs +56 -29
- package/src/ExitOnCaughtUp.res +10 -2
- package/src/ExitOnCaughtUp.res.mjs +10 -1
- package/src/FetchState.res +684 -415
- package/src/FetchState.res.mjs +505 -486
- package/src/HandlerLoader.res +8 -104
- package/src/HandlerLoader.res.mjs +2 -81
- package/src/HandlerRegister.res +520 -144
- package/src/HandlerRegister.res.mjs +286 -133
- package/src/HandlerRegister.resi +24 -8
- package/src/IndexerState.res +10 -3
- package/src/IndexerState.res.mjs +11 -4
- package/src/IndexerState.resi +2 -1
- package/src/IndexingAddresses.res +108 -0
- package/src/IndexingAddresses.res.mjs +101 -0
- package/src/IndexingAddresses.resi +34 -0
- package/src/Internal.res +166 -48
- package/src/Internal.res.mjs +30 -2
- package/src/LoadLayer.res +5 -5
- package/src/LoadLayer.res.mjs +6 -6
- package/src/LogSelection.res +92 -217
- package/src/LogSelection.res.mjs +95 -184
- package/src/Main.res +71 -236
- package/src/Main.res.mjs +60 -145
- package/src/Metrics.res +74 -0
- package/src/Metrics.res.mjs +75 -0
- package/src/PgStorage.res +4 -4
- package/src/PgStorage.res.mjs +5 -5
- package/src/Prometheus.res +10 -63
- package/src/Prometheus.res.mjs +124 -171
- package/src/PruneStaleHistory.res +2 -2
- package/src/PruneStaleHistory.res.mjs +3 -3
- package/src/RawEvent.res +7 -2
- package/src/RawEvent.res.mjs +4 -4
- package/src/Rollback.res +3 -3
- package/src/Rollback.res.mjs +4 -4
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateDeadInputTracker.res +85 -0
- package/src/SimulateDeadInputTracker.res.mjs +73 -0
- package/src/SimulateDeadInputTracker.resi +12 -0
- package/src/SimulateItems.res +128 -28
- package/src/SimulateItems.res.mjs +82 -40
- package/src/TestIndexer.res +55 -41
- package/src/TestIndexer.res.mjs +39 -32
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/bindings/Performance.res +7 -0
- package/src/bindings/Performance.res.mjs +21 -0
- package/src/bindings/Performance.resi +7 -0
- package/src/bindings/Viem.res +0 -46
- package/src/bindings/Viem.res.mjs +1 -43
- package/src/sources/BlockStore.res +46 -0
- package/src/sources/BlockStore.res.mjs +24 -0
- package/src/sources/EventRouter.res +31 -49
- package/src/sources/EventRouter.res.mjs +12 -25
- package/src/sources/Evm.res +83 -72
- package/src/sources/Evm.res.mjs +53 -69
- package/src/sources/EvmChain.res +7 -34
- package/src/sources/EvmChain.res.mjs +6 -27
- package/src/sources/EvmRpcClient.res +71 -5
- package/src/sources/EvmRpcClient.res.mjs +13 -4
- package/src/sources/FieldMask.res +39 -0
- package/src/sources/FieldMask.res.mjs +42 -0
- package/src/sources/Fuel.res +9 -6
- package/src/sources/Fuel.res.mjs +5 -10
- package/src/sources/HyperFuelSource.res +46 -50
- package/src/sources/HyperFuelSource.res.mjs +64 -54
- package/src/sources/HyperSync.res +45 -42
- package/src/sources/HyperSync.res.mjs +68 -60
- package/src/sources/HyperSync.resi +14 -4
- package/src/sources/HyperSyncClient.res +107 -119
- package/src/sources/HyperSyncClient.res.mjs +36 -31
- package/src/sources/HyperSyncHeightStream.res +1 -8
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
- package/src/sources/HyperSyncSource.res +60 -254
- package/src/sources/HyperSyncSource.res.mjs +57 -180
- package/src/sources/Rpc.res +15 -79
- package/src/sources/Rpc.res.mjs +25 -101
- package/src/sources/RpcSource.res +221 -514
- package/src/sources/RpcSource.res.mjs +216 -411
- package/src/sources/RpcWebSocketHeightStream.res +0 -5
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
- package/src/sources/SimulateSource.res +44 -20
- package/src/sources/SimulateSource.res.mjs +41 -14
- package/src/sources/Source.res +34 -6
- package/src/sources/SourceManager.res +77 -19
- package/src/sources/SourceManager.res.mjs +63 -21
- package/src/sources/SourceManager.resi +10 -0
- package/src/sources/Svm.res +31 -16
- package/src/sources/Svm.res.mjs +36 -13
- package/src/sources/SvmHyperSyncClient.res +5 -32
- package/src/sources/SvmHyperSyncSource.res +159 -134
- package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
- package/src/sources/TransactionStore.res +49 -0
- package/src/sources/TransactionStore.res.mjs +30 -0
- package/src/tui/Tui.res +13 -16
- package/src/tui/Tui.res.mjs +12 -14
- package/svm.schema.json +49 -37
- package/src/bindings/Hrtime.res +0 -58
- package/src/bindings/Hrtime.res.mjs +0 -90
- package/src/bindings/Hrtime.resi +0 -30
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
import * as Utils from "../Utils.res.mjs";
|
|
4
4
|
import * as Logging from "../Logging.res.mjs";
|
|
5
|
-
import * as Prometheus from "../Prometheus.res.mjs";
|
|
6
5
|
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
7
6
|
import * as Eventsource from "eventsource";
|
|
8
7
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
@@ -83,7 +82,6 @@ function subscribe(hyperSyncUrl, apiToken, chainId, onHeight) {
|
|
|
83
82
|
es$1.addEventListener("height", event => {
|
|
84
83
|
let height = Stdlib_Int.fromString(event.data, undefined);
|
|
85
84
|
if (height !== undefined) {
|
|
86
|
-
Prometheus.SourceRequestCount.increment("HyperSync", chainId, "heightStream");
|
|
87
85
|
updateTimeoutId();
|
|
88
86
|
return onHeight(height);
|
|
89
87
|
} else {
|
|
@@ -1,132 +1,5 @@
|
|
|
1
1
|
open Source
|
|
2
2
|
|
|
3
|
-
type selectionConfig = {
|
|
4
|
-
getLogSelectionOrThrow: (
|
|
5
|
-
~addressesByContractName: dict<array<Address.t>>,
|
|
6
|
-
) => array<LogSelection.t>,
|
|
7
|
-
fieldSelection: HyperSyncClient.QueryTypes.fieldSelection,
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let getSelectionConfig = (selection: FetchState.selection, ~chain) => {
|
|
11
|
-
let capitalizedBlockFields = Utils.Set.make()
|
|
12
|
-
let capitalizedTransactionFields = Utils.Set.make()
|
|
13
|
-
|
|
14
|
-
let staticTopicSelectionsByContract = Dict.make()
|
|
15
|
-
let dynamicEventFiltersByContract = Dict.make()
|
|
16
|
-
let dynamicWildcardEventFiltersByContract = Dict.make()
|
|
17
|
-
let noAddressesTopicSelections = []
|
|
18
|
-
let contractNames = Utils.Set.make()
|
|
19
|
-
|
|
20
|
-
selection.eventConfigs
|
|
21
|
-
->(Utils.magic: array<Internal.eventConfig> => array<Internal.evmEventConfig>)
|
|
22
|
-
->Array.forEach(({
|
|
23
|
-
dependsOnAddresses,
|
|
24
|
-
contractName,
|
|
25
|
-
getEventFiltersOrThrow,
|
|
26
|
-
selectedBlockFields,
|
|
27
|
-
selectedTransactionFields,
|
|
28
|
-
isWildcard,
|
|
29
|
-
}) => {
|
|
30
|
-
selectedBlockFields
|
|
31
|
-
->Utils.Set.toArray
|
|
32
|
-
->Array.forEach(name =>
|
|
33
|
-
capitalizedBlockFields
|
|
34
|
-
->Utils.Set.add((name :> string)->Utils.String.capitalize)
|
|
35
|
-
->ignore
|
|
36
|
-
)
|
|
37
|
-
selectedTransactionFields
|
|
38
|
-
->Utils.Set.toArray
|
|
39
|
-
->Array.forEach(name =>
|
|
40
|
-
capitalizedTransactionFields
|
|
41
|
-
->Utils.Set.add((name :> string)->Utils.String.capitalize)
|
|
42
|
-
->ignore
|
|
43
|
-
)
|
|
44
|
-
|
|
45
|
-
let eventFilters = getEventFiltersOrThrow(chain)
|
|
46
|
-
if dependsOnAddresses {
|
|
47
|
-
let _ = contractNames->Utils.Set.add(contractName)
|
|
48
|
-
switch eventFilters {
|
|
49
|
-
| Static(topicSelections) =>
|
|
50
|
-
staticTopicSelectionsByContract->Utils.Dict.pushMany(contractName, topicSelections)
|
|
51
|
-
| Dynamic(fn) =>
|
|
52
|
-
(
|
|
53
|
-
isWildcard ? dynamicWildcardEventFiltersByContract : dynamicEventFiltersByContract
|
|
54
|
-
)->Utils.Dict.push(contractName, fn)
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
noAddressesTopicSelections
|
|
58
|
-
->Array.pushMany(
|
|
59
|
-
switch eventFilters {
|
|
60
|
-
| Static(s) => s
|
|
61
|
-
| Dynamic(fn) => fn([])
|
|
62
|
-
},
|
|
63
|
-
)
|
|
64
|
-
->ignore
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
let fieldSelection: HyperSyncClient.QueryTypes.fieldSelection = {
|
|
69
|
-
log: [Address, Data, LogIndex, Topic0, Topic1, Topic2, Topic3],
|
|
70
|
-
block: capitalizedBlockFields
|
|
71
|
-
->Utils.Set.toArray
|
|
72
|
-
->(Utils.magic: array<string> => array<HyperSyncClient.QueryTypes.blockField>),
|
|
73
|
-
transaction: capitalizedTransactionFields
|
|
74
|
-
->Utils.Set.toArray
|
|
75
|
-
->(Utils.magic: array<string> => array<HyperSyncClient.QueryTypes.transactionField>),
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
let noAddressesLogSelection = LogSelection.make(
|
|
79
|
-
~addresses=[],
|
|
80
|
-
~topicSelections=noAddressesTopicSelections,
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
let getLogSelectionOrThrow = (~addressesByContractName): array<LogSelection.t> => {
|
|
84
|
-
let logSelections = []
|
|
85
|
-
if noAddressesLogSelection.topicSelections->Utils.Array.isEmpty->not {
|
|
86
|
-
logSelections->Array.push(noAddressesLogSelection)
|
|
87
|
-
}
|
|
88
|
-
contractNames->Utils.Set.forEach(contractName => {
|
|
89
|
-
switch addressesByContractName->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
90
|
-
| None
|
|
91
|
-
| Some([]) => ()
|
|
92
|
-
| Some(addresses) =>
|
|
93
|
-
switch staticTopicSelectionsByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
94
|
-
| None => ()
|
|
95
|
-
| Some(topicSelections) =>
|
|
96
|
-
logSelections->Array.push(LogSelection.make(~addresses, ~topicSelections))
|
|
97
|
-
}
|
|
98
|
-
switch dynamicEventFiltersByContract->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
99
|
-
| None => ()
|
|
100
|
-
| Some(fns) =>
|
|
101
|
-
logSelections->Array.push(
|
|
102
|
-
LogSelection.make(~addresses, ~topicSelections=fns->Array.flatMap(fn => fn(addresses))),
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
switch dynamicWildcardEventFiltersByContract->Utils.Dict.dangerouslyGetNonOption(
|
|
106
|
-
contractName,
|
|
107
|
-
) {
|
|
108
|
-
| None => ()
|
|
109
|
-
| Some(fns) =>
|
|
110
|
-
logSelections->Array.push(
|
|
111
|
-
LogSelection.make(
|
|
112
|
-
~addresses=[],
|
|
113
|
-
~topicSelections=fns->Array.flatMap(fn => fn(addresses)),
|
|
114
|
-
),
|
|
115
|
-
)
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
logSelections
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
{
|
|
123
|
-
getLogSelectionOrThrow,
|
|
124
|
-
fieldSelection,
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
let memoGetSelectionConfig = (~chain) =>
|
|
129
|
-
Utils.WeakMap.memoize(selection => selection->getSelectionConfig(~chain))
|
|
130
3
|
|
|
131
4
|
// Surfaced by HyperSyncClient.getHeight (Rust) when HyperSync rejects the API
|
|
132
5
|
// token. The corrupted-token test feeds the real server error through this
|
|
@@ -136,8 +9,8 @@ let isUnauthorizedError = (message: string) => message->String.includes("401 Una
|
|
|
136
9
|
type options = {
|
|
137
10
|
chain: ChainMap.Chain.t,
|
|
138
11
|
endpointUrl: string,
|
|
139
|
-
|
|
140
|
-
|
|
12
|
+
// The chain's registrations, indexed by their sequential `index`.
|
|
13
|
+
onEventRegistrations: array<Internal.evmOnEventRegistration>,
|
|
141
14
|
apiToken: option<string>,
|
|
142
15
|
clientTimeoutMillis: int,
|
|
143
16
|
lowercaseAddresses: bool,
|
|
@@ -150,8 +23,7 @@ let make = (
|
|
|
150
23
|
{
|
|
151
24
|
chain,
|
|
152
25
|
endpointUrl,
|
|
153
|
-
|
|
154
|
-
eventRouter,
|
|
26
|
+
onEventRegistrations,
|
|
155
27
|
apiToken,
|
|
156
28
|
clientTimeoutMillis,
|
|
157
29
|
lowercaseAddresses,
|
|
@@ -162,8 +34,6 @@ let make = (
|
|
|
162
34
|
): t => {
|
|
163
35
|
let name = "HyperSync"
|
|
164
36
|
|
|
165
|
-
let getSelectionConfig = memoGetSelectionConfig(~chain)
|
|
166
|
-
|
|
167
37
|
let apiToken = switch apiToken {
|
|
168
38
|
| Some(token) => token
|
|
169
39
|
| None =>
|
|
@@ -176,7 +46,9 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
176
46
|
~url=endpointUrl,
|
|
177
47
|
~apiToken,
|
|
178
48
|
~httpReqTimeoutMillis=clientTimeoutMillis,
|
|
179
|
-
~
|
|
49
|
+
~eventRegistrations=HyperSyncClient.Registration.fromOnEventRegistrations(
|
|
50
|
+
onEventRegistrations,
|
|
51
|
+
),
|
|
180
52
|
~enableChecksumAddresses=!lowercaseAddresses,
|
|
181
53
|
~serializationFormat,
|
|
182
54
|
~enableQueryCaching,
|
|
@@ -189,32 +61,25 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
189
61
|
)
|
|
190
62
|
}
|
|
191
63
|
|
|
192
|
-
exception UndefinedValue
|
|
193
|
-
|
|
194
64
|
let makeEventBatchQueueItem = (
|
|
195
65
|
item: HyperSyncClient.EventItems.item,
|
|
196
|
-
~
|
|
197
|
-
~eventConfig: Internal.evmEventConfig,
|
|
66
|
+
~onEventRegistration: Internal.evmOnEventRegistration,
|
|
198
67
|
): Internal.item => {
|
|
199
|
-
let {
|
|
200
|
-
let chainId = chain->ChainMap.Chain.toChainId
|
|
68
|
+
let {transactionIndex, logIndex, srcAddress} = item
|
|
201
69
|
|
|
202
70
|
Internal.Event({
|
|
203
|
-
|
|
204
|
-
timestamp: block.timestamp->Option.getUnsafe,
|
|
71
|
+
onEventRegistration: (onEventRegistration :> Internal.onEventRegistration),
|
|
205
72
|
chain,
|
|
206
|
-
blockNumber:
|
|
207
|
-
blockHash: block.hash->Option.getUnsafe,
|
|
73
|
+
blockNumber: item.blockNumber,
|
|
208
74
|
logIndex,
|
|
75
|
+
transactionIndex,
|
|
76
|
+
// `block` and `transaction` are omitted; they're materialised from the
|
|
77
|
+
// per-chain stores onto the payload at batch prep.
|
|
209
78
|
payload: {
|
|
210
|
-
contractName: eventConfig.contractName,
|
|
211
|
-
eventName: eventConfig.name,
|
|
212
|
-
chainId,
|
|
213
|
-
params,
|
|
214
|
-
transaction: transaction->(
|
|
215
|
-
Utils.magic: HyperSyncClient.ResponseTypes.transaction => Internal.eventTransaction
|
|
216
|
-
),
|
|
217
|
-
block: block->(Utils.magic: HyperSyncClient.ResponseTypes.block => Internal.eventBlock),
|
|
79
|
+
contractName: onEventRegistration.eventConfig.contractName,
|
|
80
|
+
eventName: onEventRegistration.eventConfig.name,
|
|
81
|
+
chainId: chain->ChainMap.Chain.toChainId,
|
|
82
|
+
params: item.params,
|
|
218
83
|
srcAddress,
|
|
219
84
|
logIndex,
|
|
220
85
|
}->Evm.fromPayload,
|
|
@@ -225,36 +90,26 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
225
90
|
~fromBlock,
|
|
226
91
|
~toBlock,
|
|
227
92
|
~addressesByContractName,
|
|
228
|
-
~
|
|
93
|
+
~contractNameByAddress as _,
|
|
229
94
|
~knownHeight,
|
|
230
95
|
~partitionId as _,
|
|
231
|
-
~selection,
|
|
96
|
+
~selection: FetchState.selection,
|
|
97
|
+
~itemsTarget,
|
|
232
98
|
~retry,
|
|
233
|
-
~logger,
|
|
99
|
+
~logger as _,
|
|
234
100
|
) => {
|
|
235
|
-
let totalTimeRef =
|
|
101
|
+
let totalTimeRef = Performance.now()
|
|
236
102
|
|
|
237
|
-
let
|
|
238
|
-
|
|
239
|
-
let logSelections = try selectionConfig.getLogSelectionOrThrow(~addressesByContractName) catch {
|
|
240
|
-
| exn =>
|
|
241
|
-
exn->ErrorHandling.mkLogAndRaise(~logger, ~msg="Failed getting log selection for the query")
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
let startFetchingBatchTimeRef = Hrtime.makeTimer()
|
|
103
|
+
let startFetchingBatchTimeRef = Performance.now()
|
|
245
104
|
|
|
246
105
|
//fetch batch
|
|
247
|
-
Prometheus.SourceRequestCount.increment(
|
|
248
|
-
~sourceName=name,
|
|
249
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
250
|
-
~method="getLogs",
|
|
251
|
-
)
|
|
252
106
|
let pageUnsafe = try await HyperSync.GetLogs.query(
|
|
253
107
|
~client,
|
|
254
108
|
~fromBlock,
|
|
255
109
|
~toBlock,
|
|
256
|
-
~
|
|
257
|
-
~
|
|
110
|
+
~maxNumLogs=itemsTarget,
|
|
111
|
+
~registrationIndexes=selection.onEventRegistrations->Array.map(reg => reg.index),
|
|
112
|
+
~addressesByContractName,
|
|
258
113
|
) catch {
|
|
259
114
|
| HyperSync.GetLogs.Error(error) =>
|
|
260
115
|
throw(
|
|
@@ -301,7 +156,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
301
156
|
)
|
|
302
157
|
}
|
|
303
158
|
|
|
304
|
-
let pageFetchTime = startFetchingBatchTimeRef->
|
|
159
|
+
let pageFetchTime = startFetchingBatchTimeRef->Performance.secondsSince
|
|
160
|
+
let requestStats = [{Source.method: "getLogs", seconds: pageFetchTime}]
|
|
305
161
|
|
|
306
162
|
//set height and next from block
|
|
307
163
|
let knownHeight = pageUnsafe.archiveHeight
|
|
@@ -311,82 +167,37 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
311
167
|
//In the query
|
|
312
168
|
let heighestBlockQueried = pageUnsafe.nextBlock - 1
|
|
313
169
|
|
|
314
|
-
let parsingTimeRef =
|
|
170
|
+
let parsingTimeRef = Performance.now()
|
|
315
171
|
|
|
316
172
|
//Parse page items into queue items
|
|
317
173
|
let parsedQueueItems = []
|
|
318
174
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
) => {
|
|
326
|
-
if !eventConfig.isWildcard {
|
|
327
|
-
//Wildcard events can be parsed as undefined if the number of topics
|
|
328
|
-
//don't match the event with the given topic0
|
|
329
|
-
//Non wildcard events should be expected to be parsed
|
|
330
|
-
let msg = `Event ${eventConfig.name} was unexpectedly parsed as undefined`
|
|
331
|
-
let logger = Logging.createChildFrom(
|
|
332
|
-
~logger,
|
|
333
|
-
~params={
|
|
334
|
-
"chainId": chainId,
|
|
335
|
-
"blockNumber": blockNumber,
|
|
336
|
-
"logIndex": logIndex,
|
|
337
|
-
"decoder": "hypersync-client",
|
|
338
|
-
},
|
|
339
|
-
)
|
|
340
|
-
exn->ErrorHandling.mkLogAndRaise(~msg, ~logger)
|
|
341
|
-
}
|
|
342
|
-
}
|
|
175
|
+
// Block headers are returned once per number; items reference them by blockNumber.
|
|
176
|
+
let blocksByNumber = Utils.Map.make()
|
|
177
|
+
pageUnsafe.blocks->Array.forEach(block => {
|
|
178
|
+
blocksByNumber->Utils.Map.set(block.number, block)->ignore
|
|
179
|
+
})
|
|
180
|
+
let getBlock = blockNumber => blocksByNumber->Utils.Map.unsafeGet(blockNumber)
|
|
343
181
|
|
|
344
182
|
pageUnsafe.items->Array.forEach(item => {
|
|
345
|
-
let
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
~topicCount=item.topicCount,
|
|
351
|
-
),
|
|
352
|
-
~indexingAddresses,
|
|
353
|
-
~contractAddress=item.srcAddress,
|
|
354
|
-
~blockNumber=item.block.number->Option.getUnsafe,
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
switch maybeEventConfig {
|
|
358
|
-
| None => () //ignore events that aren't registered
|
|
359
|
-
| Some(eventConfig) =>
|
|
360
|
-
switch item.params
|
|
361
|
-
->Nullable.toOption
|
|
362
|
-
->Option.flatMap(Dict.get(_, eventConfig.contractName)) {
|
|
363
|
-
| Some(params) =>
|
|
364
|
-
parsedQueueItems->Array.push(makeEventBatchQueueItem(item, ~params, ~eventConfig))->ignore
|
|
365
|
-
| None =>
|
|
366
|
-
handleDecodeFailure(
|
|
367
|
-
~eventConfig,
|
|
368
|
-
~logIndex=item.logIndex,
|
|
369
|
-
~blockNumber=item.block.number->Option.getUnsafe,
|
|
370
|
-
~chainId,
|
|
371
|
-
~exn=UndefinedValue,
|
|
372
|
-
)
|
|
373
|
-
}
|
|
374
|
-
}
|
|
183
|
+
let onEventRegistration =
|
|
184
|
+
onEventRegistrations->Array.getUnsafe(item.onEventRegistrationIndex)
|
|
185
|
+
parsedQueueItems
|
|
186
|
+
->Array.push(makeEventBatchQueueItem(item, ~onEventRegistration))
|
|
187
|
+
->ignore
|
|
375
188
|
})
|
|
376
189
|
|
|
377
|
-
let parsingTimeElapsed = parsingTimeRef->
|
|
190
|
+
let parsingTimeElapsed = parsingTimeRef->Performance.secondsSince
|
|
378
191
|
|
|
379
192
|
// Collect (blockNumber, blockHash) pairs we already have from the response —
|
|
380
|
-
// one per
|
|
193
|
+
// one per returned block plus, when present, the rollbackGuard's head block
|
|
381
194
|
// and the parent of the range's first block. Duplicates are allowed; reorg
|
|
382
195
|
// detection notices same-block-number-different-hash collisions itself.
|
|
383
196
|
let blockHashes = []
|
|
384
|
-
pageUnsafe.
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
| _ => ()
|
|
389
|
-
}
|
|
197
|
+
pageUnsafe.blocks->Array.forEach(block => {
|
|
198
|
+
blockHashes
|
|
199
|
+
->Array.push({ReorgDetection.blockNumber: block.number, blockHash: block.hash})
|
|
200
|
+
->ignore
|
|
390
201
|
})
|
|
391
202
|
switch pageUnsafe.rollbackGuard {
|
|
392
203
|
| None => ()
|
|
@@ -409,13 +220,13 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
409
220
|
| Some({timestamp}) => timestamp
|
|
410
221
|
| None =>
|
|
411
222
|
switch pageUnsafe.items->Array.get(pageUnsafe.items->Array.length - 1) {
|
|
412
|
-
| Some(
|
|
413
|
-
|
|
223
|
+
| Some(item) if item.blockNumber == heighestBlockQueried =>
|
|
224
|
+
getBlock(item.blockNumber).timestamp
|
|
414
225
|
| _ => 0
|
|
415
226
|
}
|
|
416
227
|
}
|
|
417
228
|
|
|
418
|
-
let totalTimeElapsed = totalTimeRef->
|
|
229
|
+
let totalTimeElapsed = totalTimeRef->Performance.secondsSince
|
|
419
230
|
|
|
420
231
|
let stats = {
|
|
421
232
|
totalTimeElapsed,
|
|
@@ -426,11 +237,14 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
426
237
|
{
|
|
427
238
|
latestFetchedBlockTimestamp,
|
|
428
239
|
parsedQueueItems,
|
|
240
|
+
transactionStore: Some(pageUnsafe.transactionStore),
|
|
241
|
+
blockStore: Some(pageUnsafe.blockStore),
|
|
429
242
|
latestFetchedBlockNumber: heighestBlockQueried,
|
|
430
243
|
stats,
|
|
431
244
|
knownHeight,
|
|
432
245
|
blockHashes,
|
|
433
246
|
fromBlockQueried: fromBlock,
|
|
247
|
+
requestStats,
|
|
434
248
|
}
|
|
435
249
|
}
|
|
436
250
|
|
|
@@ -441,7 +255,10 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
441
255
|
~sourceName=name,
|
|
442
256
|
~chainId=chain->ChainMap.Chain.toChainId,
|
|
443
257
|
~logger,
|
|
444
|
-
)->Promise.thenResolve(
|
|
258
|
+
)->Promise.thenResolve(((queryRes, requestStats)) => {
|
|
259
|
+
Source.result: queryRes->HyperSync.mapExn,
|
|
260
|
+
requestStats,
|
|
261
|
+
})
|
|
445
262
|
|
|
446
263
|
{
|
|
447
264
|
name,
|
|
@@ -451,8 +268,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
451
268
|
poweredByHyperSync: true,
|
|
452
269
|
getBlockHashes,
|
|
453
270
|
getHeightOrThrow: async () => {
|
|
454
|
-
let timerRef =
|
|
455
|
-
let
|
|
271
|
+
let timerRef = Performance.now()
|
|
272
|
+
let height = try {
|
|
456
273
|
await client.getHeight()
|
|
457
274
|
} catch {
|
|
458
275
|
| JsExn(e) =>
|
|
@@ -465,19 +282,8 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
465
282
|
| _ => throw(JsExn(e))
|
|
466
283
|
}
|
|
467
284
|
}
|
|
468
|
-
let seconds = timerRef->
|
|
469
|
-
|
|
470
|
-
~sourceName=name,
|
|
471
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
472
|
-
~method="getHeight",
|
|
473
|
-
)
|
|
474
|
-
Prometheus.SourceRequestCount.addSeconds(
|
|
475
|
-
~sourceName=name,
|
|
476
|
-
~chainId=chain->ChainMap.Chain.toChainId,
|
|
477
|
-
~method="getHeight",
|
|
478
|
-
~seconds,
|
|
479
|
-
)
|
|
480
|
-
result
|
|
285
|
+
let seconds = timerRef->Performance.secondsSince
|
|
286
|
+
{height, requestStats: [{method: "getHeight", seconds}]}
|
|
481
287
|
},
|
|
482
288
|
getItemsOrThrow,
|
|
483
289
|
createHeightSubscription: (~onHeight) =>
|