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
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Rest from "../vendored/Rest.res.mjs";
|
|
4
3
|
import * as Utils from "../Utils.res.mjs";
|
|
5
4
|
import * as Hrtime from "../bindings/Hrtime.res.mjs";
|
|
6
5
|
import * as Source from "./Source.res.mjs";
|
|
7
6
|
import * as Logging from "../Logging.res.mjs";
|
|
8
|
-
import * as Internal from "../Internal.res.mjs";
|
|
9
7
|
import * as HyperSync from "./HyperSync.res.mjs";
|
|
10
8
|
import * as Belt_Array from "@rescript/runtime/lib/es6/Belt_Array.js";
|
|
11
9
|
import * as Prometheus from "../Prometheus.res.mjs";
|
|
12
10
|
import * as EventRouter from "./EventRouter.res.mjs";
|
|
13
11
|
import * as LogSelection from "../LogSelection.res.mjs";
|
|
12
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
14
13
|
import * as ErrorHandling from "../ErrorHandling.res.mjs";
|
|
15
14
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
16
15
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
17
16
|
import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
|
|
18
|
-
import * as HyperSyncJsonApi from "./HyperSyncJsonApi.res.mjs";
|
|
19
17
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
20
18
|
import * as HyperSyncHeightStream from "./HyperSyncHeightStream.res.mjs";
|
|
21
19
|
|
|
22
20
|
function getSelectionConfig(selection, chain) {
|
|
23
|
-
let nonOptionalBlockFieldNames = new Set();
|
|
24
|
-
let nonOptionalTransactionFieldNames = new Set();
|
|
25
21
|
let capitalizedBlockFields = new Set();
|
|
26
22
|
let capitalizedTransactionFields = new Set();
|
|
27
23
|
let staticTopicSelectionsByContract = {};
|
|
@@ -32,15 +28,9 @@ function getSelectionConfig(selection, chain) {
|
|
|
32
28
|
selection.eventConfigs.forEach(param => {
|
|
33
29
|
let contractName = param.contractName;
|
|
34
30
|
Array.from(param.selectedBlockFields).forEach(name => {
|
|
35
|
-
if (!Internal.evmNullableBlockFields.has(name)) {
|
|
36
|
-
nonOptionalBlockFieldNames.add(name);
|
|
37
|
-
}
|
|
38
31
|
capitalizedBlockFields.add(Utils.$$String.capitalize(name));
|
|
39
32
|
});
|
|
40
33
|
Array.from(param.selectedTransactionFields).forEach(name => {
|
|
41
|
-
if (!Internal.evmNullableTransactionFields.has(name)) {
|
|
42
|
-
nonOptionalTransactionFieldNames.add(name);
|
|
43
|
-
}
|
|
44
34
|
capitalizedTransactionFields.add(Utils.$$String.capitalize(name));
|
|
45
35
|
});
|
|
46
36
|
let eventFilters = param.getEventFiltersOrThrow(chain);
|
|
@@ -104,9 +94,7 @@ function getSelectionConfig(selection, chain) {
|
|
|
104
94
|
};
|
|
105
95
|
return {
|
|
106
96
|
getLogSelectionOrThrow: getLogSelectionOrThrow,
|
|
107
|
-
fieldSelection: fieldSelection
|
|
108
|
-
nonOptionalBlockFieldNames: Array.from(nonOptionalBlockFieldNames),
|
|
109
|
-
nonOptionalTransactionFieldNames: Array.from(nonOptionalTransactionFieldNames)
|
|
97
|
+
fieldSelection: fieldSelection
|
|
110
98
|
};
|
|
111
99
|
}
|
|
112
100
|
|
|
@@ -114,11 +102,13 @@ function memoGetSelectionConfig(chain) {
|
|
|
114
102
|
return Utils.$$WeakMap.memoize(selection => getSelectionConfig(selection, chain));
|
|
115
103
|
}
|
|
116
104
|
|
|
105
|
+
function isUnauthorizedError(message) {
|
|
106
|
+
return message.includes("401 Unauthorized");
|
|
107
|
+
}
|
|
108
|
+
|
|
117
109
|
function make(param) {
|
|
118
|
-
let lowercaseAddresses = param.lowercaseAddresses;
|
|
119
110
|
let apiToken = param.apiToken;
|
|
120
111
|
let eventRouter = param.eventRouter;
|
|
121
|
-
let allEventSignatures = param.allEventSignatures;
|
|
122
112
|
let endpointUrl = param.endpointUrl;
|
|
123
113
|
let chain = param.chain;
|
|
124
114
|
let name = "HyperSync";
|
|
@@ -126,54 +116,37 @@ function make(param) {
|
|
|
126
116
|
let apiToken$1 = apiToken !== undefined ? apiToken : Stdlib_JsError.throwWithMessage(`An API token is required for using HyperSync as a data-source.
|
|
127
117
|
Set the ENVIO_API_TOKEN environment variable in your .env file.
|
|
128
118
|
Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
129
|
-
let client
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return decoder;
|
|
137
|
-
}
|
|
138
|
-
let decoder$1;
|
|
139
|
-
try {
|
|
140
|
-
decoder$1 = HyperSyncClient.Decoder.fromSignatures(allEventSignatures);
|
|
141
|
-
} catch (raw_exn) {
|
|
142
|
-
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
143
|
-
return ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate a decoder from hypersync client, please double check your ABI", exn);
|
|
144
|
-
}
|
|
145
|
-
if (lowercaseAddresses) {
|
|
146
|
-
decoder$1.disableChecksummedAddresses();
|
|
147
|
-
} else {
|
|
148
|
-
decoder$1.enableChecksummedAddresses();
|
|
149
|
-
}
|
|
150
|
-
return decoder$1;
|
|
151
|
-
};
|
|
119
|
+
let client;
|
|
120
|
+
try {
|
|
121
|
+
client = HyperSyncClient.make(endpointUrl, apiToken$1, param.clientTimeoutMillis, param.allEventParams, !param.lowercaseAddresses, param.serializationFormat, param.enableQueryCaching, undefined, undefined, undefined, param.logLevel);
|
|
122
|
+
} catch (raw_exn) {
|
|
123
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
124
|
+
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the hypersync client, please double check your ABI", exn);
|
|
125
|
+
}
|
|
152
126
|
let UndefinedValue = /* @__PURE__ */Primitive_exceptions.create("UndefinedValue");
|
|
153
127
|
let makeEventBatchQueueItem = (item, params, eventConfig) => {
|
|
154
128
|
let block = item.block;
|
|
155
|
-
let
|
|
129
|
+
let logIndex = item.logIndex;
|
|
156
130
|
return {
|
|
157
131
|
kind: 0,
|
|
158
132
|
eventConfig: eventConfig,
|
|
159
133
|
timestamp: block.timestamp,
|
|
160
134
|
chain: chain,
|
|
161
135
|
blockNumber: block.number,
|
|
162
|
-
logIndex:
|
|
136
|
+
logIndex: logIndex,
|
|
163
137
|
event: {
|
|
164
138
|
contractName: eventConfig.contractName,
|
|
165
139
|
eventName: eventConfig.name,
|
|
166
140
|
params: params,
|
|
167
141
|
chainId: chain,
|
|
168
|
-
srcAddress:
|
|
169
|
-
logIndex:
|
|
142
|
+
srcAddress: item.srcAddress,
|
|
143
|
+
logIndex: logIndex,
|
|
170
144
|
transaction: item.transaction,
|
|
171
145
|
block: block
|
|
172
146
|
}
|
|
173
147
|
};
|
|
174
148
|
};
|
|
175
149
|
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, indexingAddresses, knownHeight, param, selection, retry, logger) => {
|
|
176
|
-
let mkLogAndRaise = (extra, extra$1) => ErrorHandling.mkLogAndRaise(logger, extra, extra$1);
|
|
177
150
|
let totalTimeRef = Hrtime.makeTimer();
|
|
178
151
|
let selectionConfig = getSelectionConfig(selection);
|
|
179
152
|
let logSelections;
|
|
@@ -187,7 +160,7 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
187
160
|
Prometheus.SourceRequestCount.increment(name, chain, "getLogs");
|
|
188
161
|
let pageUnsafe;
|
|
189
162
|
try {
|
|
190
|
-
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection
|
|
163
|
+
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection);
|
|
191
164
|
} catch (raw_error) {
|
|
192
165
|
let error = Primitive_exceptions.internalToException(raw_error);
|
|
193
166
|
if (error.RE_EXN_ID === HyperSync.GetLogs.$$Error) {
|
|
@@ -217,6 +190,9 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
217
190
|
Error: new Error()
|
|
218
191
|
};
|
|
219
192
|
}
|
|
193
|
+
if (error.RE_EXN_ID === Source.RateLimited) {
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
220
196
|
throw {
|
|
221
197
|
RE_EXN_ID: Source.GetItemsError,
|
|
222
198
|
_1: {
|
|
@@ -235,73 +211,22 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
235
211
|
let pageFetchTime = Hrtime.toSecondsFloat(Hrtime.timeSince(startFetchingBatchTimeRef));
|
|
236
212
|
let knownHeight$1 = pageUnsafe.archiveHeight;
|
|
237
213
|
let heighestBlockQueried = pageUnsafe.nextBlock - 1 | 0;
|
|
238
|
-
let match = pageUnsafe.rollbackGuard;
|
|
239
|
-
let lastBlockQueriedPromise;
|
|
240
|
-
if (match !== undefined) {
|
|
241
|
-
lastBlockQueriedPromise = Promise.resolve({
|
|
242
|
-
blockHash: match.hash,
|
|
243
|
-
blockNumber: match.blockNumber,
|
|
244
|
-
blockTimestamp: match.timestamp
|
|
245
|
-
});
|
|
246
|
-
} else {
|
|
247
|
-
let match$1 = Belt_Array.get(pageUnsafe.items, pageUnsafe.items.length - 1 | 0);
|
|
248
|
-
let exit = 0;
|
|
249
|
-
if (match$1 !== undefined) {
|
|
250
|
-
let block = match$1.block;
|
|
251
|
-
if (block.number === heighestBlockQueried) {
|
|
252
|
-
lastBlockQueriedPromise = Promise.resolve({
|
|
253
|
-
blockHash: block.hash,
|
|
254
|
-
blockNumber: block.number,
|
|
255
|
-
blockTimestamp: block.timestamp
|
|
256
|
-
});
|
|
257
|
-
} else {
|
|
258
|
-
exit = 1;
|
|
259
|
-
}
|
|
260
|
-
} else {
|
|
261
|
-
exit = 1;
|
|
262
|
-
}
|
|
263
|
-
if (exit === 1) {
|
|
264
|
-
lastBlockQueriedPromise = HyperSync.queryBlockData(client, heighestBlockQueried, name, chain, logger).then(res => {
|
|
265
|
-
if (res.TAG !== "Ok") {
|
|
266
|
-
return mkLogAndRaise(`Failed to query blockData for block ` + heighestBlockQueried.toString(), HyperSync.queryErrorToMsq(res._0));
|
|
267
|
-
}
|
|
268
|
-
let blockData = res._0;
|
|
269
|
-
if (blockData !== undefined) {
|
|
270
|
-
return blockData;
|
|
271
|
-
} else {
|
|
272
|
-
return mkLogAndRaise(`Failure, blockData for block ` + heighestBlockQueried.toString() + ` unexpectedly returned None`, {
|
|
273
|
-
RE_EXN_ID: "Not_found"
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
});
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
214
|
let parsingTimeRef = Hrtime.makeTimer();
|
|
280
215
|
let parsedQueueItems = [];
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
} catch (raw_exn$1) {
|
|
285
|
-
let exn$1 = Primitive_exceptions.internalToException(raw_exn$1);
|
|
286
|
-
parsedEvents = mkLogAndRaise("Failed to parse events using hypersync client, please double check your ABI.", exn$1);
|
|
287
|
-
}
|
|
288
|
-
Belt_Array.forEachWithIndex(pageUnsafe.items, (index, item) => {
|
|
289
|
-
let block = item.block;
|
|
290
|
-
let log = item.log;
|
|
291
|
-
let topic0 = Utils.$$Array.firstUnsafe(log.topics);
|
|
292
|
-
let maybeEventConfig = EventRouter.get(eventRouter, EventRouter.getEvmEventId(topic0, log.topics.length), log.address, block.number, indexingAddresses);
|
|
293
|
-
let maybeDecodedEvent = parsedEvents[index];
|
|
216
|
+
Belt_Array.forEach(pageUnsafe.items, item => {
|
|
217
|
+
let maybeEventConfig = EventRouter.get(eventRouter, EventRouter.getEvmEventId(item.topic0, item.topicCount), item.srcAddress, item.block.number, indexingAddresses);
|
|
218
|
+
let match = item.params;
|
|
294
219
|
if (maybeEventConfig === undefined) {
|
|
295
220
|
return;
|
|
296
221
|
}
|
|
297
|
-
if (
|
|
298
|
-
|
|
222
|
+
if (match == null) {
|
|
223
|
+
match === null;
|
|
299
224
|
} else {
|
|
300
|
-
parsedQueueItems.push(makeEventBatchQueueItem(item,
|
|
225
|
+
parsedQueueItems.push(makeEventBatchQueueItem(item, match, maybeEventConfig));
|
|
301
226
|
return;
|
|
302
227
|
}
|
|
303
|
-
let logIndex =
|
|
304
|
-
let blockNumber = block.number;
|
|
228
|
+
let logIndex = item.logIndex;
|
|
229
|
+
let blockNumber = item.block.number;
|
|
305
230
|
let exn = {
|
|
306
231
|
RE_EXN_ID: UndefinedValue
|
|
307
232
|
};
|
|
@@ -318,15 +243,43 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
318
243
|
ErrorHandling.mkLogAndRaise(logger$1, msg, exn);
|
|
319
244
|
});
|
|
320
245
|
let parsingTimeElapsed = Hrtime.toSecondsFloat(Hrtime.timeSince(parsingTimeRef));
|
|
321
|
-
let
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
246
|
+
let blockHashes = [];
|
|
247
|
+
Belt_Array.forEach(pageUnsafe.items, param => {
|
|
248
|
+
let block = param.block;
|
|
249
|
+
let match = block.number;
|
|
250
|
+
let match$1 = block.hash;
|
|
251
|
+
if (match !== undefined && match$1 !== undefined) {
|
|
252
|
+
blockHashes.push({
|
|
253
|
+
blockHash: match$1,
|
|
254
|
+
blockNumber: match
|
|
255
|
+
});
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
let match = pageUnsafe.rollbackGuard;
|
|
260
|
+
if (match !== undefined) {
|
|
261
|
+
blockHashes.push({
|
|
262
|
+
blockHash: match.hash,
|
|
263
|
+
blockNumber: match.blockNumber
|
|
264
|
+
});
|
|
265
|
+
blockHashes.push({
|
|
266
|
+
blockHash: match.firstParentHash,
|
|
267
|
+
blockNumber: match.firstBlockNumber - 1 | 0
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
let match$1 = pageUnsafe.rollbackGuard;
|
|
271
|
+
let latestFetchedBlockTimestamp;
|
|
272
|
+
if (match$1 !== undefined) {
|
|
273
|
+
latestFetchedBlockTimestamp = match$1.timestamp;
|
|
274
|
+
} else {
|
|
275
|
+
let match$2 = Belt_Array.get(pageUnsafe.items, pageUnsafe.items.length - 1 | 0);
|
|
276
|
+
if (match$2 !== undefined) {
|
|
277
|
+
let block = match$2.block;
|
|
278
|
+
latestFetchedBlockTimestamp = block.number === heighestBlockQueried ? block.timestamp : 0;
|
|
279
|
+
} else {
|
|
280
|
+
latestFetchedBlockTimestamp = 0;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
330
283
|
let totalTimeElapsed = Hrtime.toSecondsFloat(Hrtime.timeSince(totalTimeRef));
|
|
331
284
|
let stats_parsing$unknowntime$unknown$lpars$rpar = parsingTimeElapsed;
|
|
332
285
|
let stats_page$unknownfetch$unknowntime$unknown$lpars$rpar = pageFetchTime;
|
|
@@ -337,16 +290,15 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
337
290
|
};
|
|
338
291
|
return {
|
|
339
292
|
knownHeight: knownHeight$1,
|
|
340
|
-
|
|
293
|
+
blockHashes: blockHashes,
|
|
341
294
|
parsedQueueItems: parsedQueueItems,
|
|
342
295
|
fromBlockQueried: fromBlock,
|
|
343
|
-
latestFetchedBlockNumber:
|
|
344
|
-
latestFetchedBlockTimestamp:
|
|
296
|
+
latestFetchedBlockNumber: heighestBlockQueried,
|
|
297
|
+
latestFetchedBlockTimestamp: latestFetchedBlockTimestamp,
|
|
345
298
|
stats: stats
|
|
346
299
|
};
|
|
347
300
|
};
|
|
348
301
|
let getBlockHashes = (blockNumbers, logger) => HyperSync.queryBlockDataMulti(client, blockNumbers, name, chain, logger).then(HyperSync.mapExn);
|
|
349
|
-
let jsonApiClient = Rest.client(endpointUrl, undefined);
|
|
350
302
|
return {
|
|
351
303
|
name: name,
|
|
352
304
|
sourceFor: "Sync",
|
|
@@ -356,16 +308,36 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
356
308
|
getBlockHashes: getBlockHashes,
|
|
357
309
|
getHeightOrThrow: async () => {
|
|
358
310
|
let timerRef = Hrtime.makeTimer();
|
|
359
|
-
let height = await Rest.fetch(HyperSyncJsonApi.heightRoute, apiToken$1, jsonApiClient);
|
|
360
311
|
let result;
|
|
361
|
-
|
|
362
|
-
result =
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
312
|
+
try {
|
|
313
|
+
result = await client.getHeight();
|
|
314
|
+
} catch (raw_e) {
|
|
315
|
+
let e = Primitive_exceptions.internalToException(raw_e);
|
|
316
|
+
if (e.RE_EXN_ID === "JsExn") {
|
|
317
|
+
let e$1 = e._1;
|
|
318
|
+
let message = Stdlib_JsExn.message(e$1);
|
|
319
|
+
if (message !== undefined) {
|
|
320
|
+
if (message.includes("401 Unauthorized")) {
|
|
321
|
+
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`);
|
|
322
|
+
await new Promise((param, param$1) => {});
|
|
323
|
+
result = 0;
|
|
324
|
+
} else {
|
|
325
|
+
throw {
|
|
326
|
+
RE_EXN_ID: "JsExn",
|
|
327
|
+
_1: e$1,
|
|
328
|
+
Error: new Error()
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
} else {
|
|
332
|
+
throw {
|
|
333
|
+
RE_EXN_ID: "JsExn",
|
|
334
|
+
_1: e$1,
|
|
335
|
+
Error: new Error()
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
} else {
|
|
339
|
+
throw e;
|
|
340
|
+
}
|
|
369
341
|
}
|
|
370
342
|
let seconds = Hrtime.toSecondsFloat(Hrtime.timeSince(timerRef));
|
|
371
343
|
Prometheus.SourceRequestCount.increment(name, chain, "getHeight");
|
|
@@ -380,6 +352,7 @@ Learn more or get a free API token at: https://envio.dev/app/api-tokens`);
|
|
|
380
352
|
export {
|
|
381
353
|
getSelectionConfig,
|
|
382
354
|
memoGetSelectionConfig,
|
|
355
|
+
isUnauthorizedError,
|
|
383
356
|
make,
|
|
384
357
|
}
|
|
385
|
-
/*
|
|
358
|
+
/* Utils Not a pure module */
|
|
@@ -7,6 +7,7 @@ type blockInfo = {
|
|
|
7
7
|
number: int,
|
|
8
8
|
timestamp: int,
|
|
9
9
|
hash: string,
|
|
10
|
+
parentHash: string,
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
let getKnownRawBlock = async (~client, ~blockNumber) =>
|
|
@@ -29,6 +30,9 @@ let parseBlockInfo = (json: JSON.t): blockInfo => {
|
|
|
29
30
|
hash: jsonDict
|
|
30
31
|
->Dict.getUnsafe("hash")
|
|
31
32
|
->S.parseOrThrow(S.string),
|
|
33
|
+
parentHash: jsonDict
|
|
34
|
+
->Dict.getUnsafe("parentHash")
|
|
35
|
+
->S.parseOrThrow(S.string),
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
38
|
|
|
@@ -838,7 +842,7 @@ type options = {
|
|
|
838
842
|
url: string,
|
|
839
843
|
chain: ChainMap.Chain.t,
|
|
840
844
|
eventRouter: EventRouter.t<Internal.evmEventConfig>,
|
|
841
|
-
|
|
845
|
+
allEventParams: array<HyperSyncClient.Decoder.eventParamsInput>,
|
|
842
846
|
lowercaseAddresses: bool,
|
|
843
847
|
ws?: string,
|
|
844
848
|
}
|
|
@@ -850,7 +854,7 @@ let make = (
|
|
|
850
854
|
url,
|
|
851
855
|
chain,
|
|
852
856
|
eventRouter,
|
|
853
|
-
|
|
857
|
+
allEventParams,
|
|
854
858
|
lowercaseAddresses,
|
|
855
859
|
?ws,
|
|
856
860
|
}: options,
|
|
@@ -993,12 +997,16 @@ let make = (
|
|
|
993
997
|
{log: hyperSyncLog}
|
|
994
998
|
}
|
|
995
999
|
|
|
996
|
-
let hscDecoder: ref<option<HyperSyncClient.Decoder.
|
|
1000
|
+
let hscDecoder: ref<option<HyperSyncClient.Decoder.tWithParams>> = ref(None)
|
|
997
1001
|
let getHscDecoder = () => {
|
|
998
1002
|
switch hscDecoder.contents {
|
|
999
1003
|
| Some(decoder) => decoder
|
|
1000
1004
|
| None => {
|
|
1001
|
-
let decoder = HyperSyncClient.Decoder.
|
|
1005
|
+
let decoder = HyperSyncClient.Decoder.fromParams(
|
|
1006
|
+
allEventParams,
|
|
1007
|
+
~checksumAddresses=!lowercaseAddresses,
|
|
1008
|
+
)
|
|
1009
|
+
hscDecoder := Some(decoder)
|
|
1002
1010
|
decoder
|
|
1003
1011
|
}
|
|
1004
1012
|
}
|
|
@@ -1071,7 +1079,7 @@ let make = (
|
|
|
1071
1079
|
// We also don't care about it when we have a hard max block interval
|
|
1072
1080
|
if (
|
|
1073
1081
|
executedBlockInterval >= suggestedBlockInterval &&
|
|
1074
|
-
!(mutSuggestedBlockIntervals->
|
|
1082
|
+
!(mutSuggestedBlockIntervals->Dict.has(maxSuggestedBlockIntervalKey))
|
|
1075
1083
|
) {
|
|
1076
1084
|
// Increase batch size going forward, but do not increase past a configured maximum
|
|
1077
1085
|
// See: https://en.wikipedia.org/wiki/Additive_increase/multiplicative_decrease
|
|
@@ -1088,7 +1096,7 @@ let make = (
|
|
|
1088
1096
|
let hyperSyncEvents = logs->Belt.Array.map(convertLogToHyperSyncEvent)
|
|
1089
1097
|
|
|
1090
1098
|
// Decode using HyperSyncClient decoder
|
|
1091
|
-
let parsedEvents = try await getHscDecoder().
|
|
1099
|
+
let parsedEvents = try await getHscDecoder().decodeLogs(hyperSyncEvents) catch {
|
|
1092
1100
|
| exn =>
|
|
1093
1101
|
throw(
|
|
1094
1102
|
Source.GetItemsError(
|
|
@@ -1107,7 +1115,7 @@ let make = (
|
|
|
1107
1115
|
->Array.zip(parsedEvents)
|
|
1108
1116
|
->Array.filterMap(((
|
|
1109
1117
|
log: Rpc.GetLogs.log,
|
|
1110
|
-
maybeDecodedEvent: Nullable.t<
|
|
1118
|
+
maybeDecodedEvent: Nullable.t<Internal.eventParams>,
|
|
1111
1119
|
)) => {
|
|
1112
1120
|
let topic0 = log.topics[0]->Option.getOr("0x0")
|
|
1113
1121
|
let routedAddress = if lowercaseAddresses {
|
|
@@ -1158,7 +1166,7 @@ let make = (
|
|
|
1158
1166
|
contractName: eventConfig.contractName,
|
|
1159
1167
|
eventName: eventConfig.name,
|
|
1160
1168
|
chainId: chain->ChainMap.Chain.toChainId,
|
|
1161
|
-
params: decoded
|
|
1169
|
+
params: decoded,
|
|
1162
1170
|
transaction,
|
|
1163
1171
|
block,
|
|
1164
1172
|
srcAddress: routedAddress,
|
|
@@ -1178,16 +1186,27 @@ let make = (
|
|
|
1178
1186
|
|
|
1179
1187
|
let totalTimeElapsed = startFetchingBatchTimeRef->Hrtime.timeSince->Hrtime.toSecondsFloat
|
|
1180
1188
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
})
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
blockHash:
|
|
1189
|
-
|
|
1189
|
+
// Every fetched block carries `hash` and `parentHash`, so each one yields
|
|
1190
|
+
// two confirmed (number, hash) pairs for reorg detection at no extra cost.
|
|
1191
|
+
let blockHashes = []
|
|
1192
|
+
let pushBlockInfo = (b: blockInfo) => {
|
|
1193
|
+
blockHashes->Array.push({ReorgDetection.blockNumber: b.number, blockHash: b.hash})->ignore
|
|
1194
|
+
if b.number > 0 {
|
|
1195
|
+
blockHashes
|
|
1196
|
+
->Array.push({ReorgDetection.blockNumber: b.number - 1, blockHash: b.parentHash})
|
|
1197
|
+
->ignore
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
pushBlockInfo(latestFetchedBlockInfo)
|
|
1201
|
+
switch optFirstBlockParent {
|
|
1202
|
+
| Some(b) => pushBlockInfo(b)
|
|
1203
|
+
| None => ()
|
|
1190
1204
|
}
|
|
1205
|
+
logs->Belt.Array.forEach(log =>
|
|
1206
|
+
blockHashes
|
|
1207
|
+
->Array.push({ReorgDetection.blockNumber: log.blockNumber, blockHash: log.blockHash})
|
|
1208
|
+
->ignore
|
|
1209
|
+
)
|
|
1191
1210
|
|
|
1192
1211
|
{
|
|
1193
1212
|
latestFetchedBlockTimestamp: latestFetchedBlockInfo.timestamp,
|
|
@@ -1197,19 +1216,20 @@ let make = (
|
|
|
1197
1216
|
totalTimeElapsed: totalTimeElapsed,
|
|
1198
1217
|
},
|
|
1199
1218
|
knownHeight,
|
|
1200
|
-
|
|
1219
|
+
blockHashes,
|
|
1201
1220
|
fromBlockQueried: fromBlock,
|
|
1202
1221
|
}
|
|
1203
1222
|
}
|
|
1204
1223
|
|
|
1205
|
-
let
|
|
1206
|
-
//
|
|
1207
|
-
//
|
|
1208
|
-
// function when a reorg is detected
|
|
1224
|
+
let onReorg = (~rollbackTargetBlock as _) => {
|
|
1225
|
+
// Drop cached block/transaction/receipt data — after a reorg the cached
|
|
1226
|
+
// entries may refer to orphaned-chain values.
|
|
1209
1227
|
blockLoader := makeBlockLoader()
|
|
1210
1228
|
transactionLoader := makeTransactionLoader()
|
|
1211
1229
|
receiptLoader := makeReceiptLoader()
|
|
1230
|
+
}
|
|
1212
1231
|
|
|
1232
|
+
let getBlockHashes = (~blockNumbers, ~logger as _currentlyUnusedLogger) => {
|
|
1213
1233
|
blockNumbers
|
|
1214
1234
|
->Array.map(blockNum => blockLoader.contents->LazyLoader.get(blockNum))
|
|
1215
1235
|
->Promise.all
|
|
@@ -1243,6 +1263,7 @@ let make = (
|
|
|
1243
1263
|
poweredByHyperSync: false,
|
|
1244
1264
|
pollingInterval: syncConfig.pollingInterval,
|
|
1245
1265
|
getBlockHashes,
|
|
1266
|
+
onReorg,
|
|
1246
1267
|
getHeightOrThrow: async () => {
|
|
1247
1268
|
let timerRef = Hrtime.makeTimer()
|
|
1248
1269
|
let height = try {
|
|
@@ -43,7 +43,8 @@ function parseBlockInfo(json) {
|
|
|
43
43
|
return {
|
|
44
44
|
number: S$RescriptSchema.parseOrThrow(json["number"], Rpc.hexIntSchema),
|
|
45
45
|
timestamp: S$RescriptSchema.parseOrThrow(json["timestamp"], Rpc.hexIntSchema),
|
|
46
|
-
hash: S$RescriptSchema.parseOrThrow(json["hash"], S$RescriptSchema.string)
|
|
46
|
+
hash: S$RescriptSchema.parseOrThrow(json["hash"], S$RescriptSchema.string),
|
|
47
|
+
parentHash: S$RescriptSchema.parseOrThrow(json["parentHash"], S$RescriptSchema.string)
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
|
|
@@ -917,7 +918,7 @@ function makeThrowingGetEventTransaction(getTransactionJson, getReceiptJson, low
|
|
|
917
918
|
|
|
918
919
|
function make(param) {
|
|
919
920
|
let lowercaseAddresses = param.lowercaseAddresses;
|
|
920
|
-
let
|
|
921
|
+
let allEventParams = param.allEventParams;
|
|
921
922
|
let eventRouter = param.eventRouter;
|
|
922
923
|
let chain = param.chain;
|
|
923
924
|
let url = param.url;
|
|
@@ -1021,9 +1022,10 @@ function make(param) {
|
|
|
1021
1022
|
let decoder = hscDecoder.contents;
|
|
1022
1023
|
if (decoder !== undefined) {
|
|
1023
1024
|
return decoder;
|
|
1024
|
-
} else {
|
|
1025
|
-
return HyperSyncClient.Decoder.fromSignatures(allEventSignatures);
|
|
1026
1025
|
}
|
|
1026
|
+
let decoder$1 = HyperSyncClient.Decoder.fromParams(allEventParams, !lowercaseAddresses);
|
|
1027
|
+
hscDecoder.contents = decoder$1;
|
|
1028
|
+
return decoder$1;
|
|
1027
1029
|
};
|
|
1028
1030
|
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, indexingAddresses, knownHeight, partitionId, selection, param, param$1) => {
|
|
1029
1031
|
let startFetchingBatchTimeRef = Hrtime.makeTimer();
|
|
@@ -1038,13 +1040,13 @@ function make(param) {
|
|
|
1038
1040
|
let latestFetchedBlockInfo = match$2.latestFetchedBlockInfo;
|
|
1039
1041
|
let logs = match$2.logs;
|
|
1040
1042
|
let executedBlockInterval = (suggestedToBlock - fromBlock | 0) + 1 | 0;
|
|
1041
|
-
if (executedBlockInterval >= suggestedBlockInterval && !
|
|
1043
|
+
if (executedBlockInterval >= suggestedBlockInterval && !(maxSuggestedBlockIntervalKey in mutSuggestedBlockIntervals)) {
|
|
1042
1044
|
mutSuggestedBlockIntervals[partitionId] = Primitive_int.min(executedBlockInterval + syncConfig.accelerationAdditive | 0, syncConfig.intervalCeiling);
|
|
1043
1045
|
}
|
|
1044
1046
|
let hyperSyncEvents = Belt_Array.map(logs, convertLogToHyperSyncEvent);
|
|
1045
1047
|
let parsedEvents;
|
|
1046
1048
|
try {
|
|
1047
|
-
parsedEvents = await getHscDecoder().
|
|
1049
|
+
parsedEvents = await getHscDecoder().decodeLogs(hyperSyncEvents);
|
|
1048
1050
|
} catch (raw_exn) {
|
|
1049
1051
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
1050
1052
|
throw {
|
|
@@ -1100,7 +1102,7 @@ function make(param) {
|
|
|
1100
1102
|
event: {
|
|
1101
1103
|
contractName: eventConfig.contractName,
|
|
1102
1104
|
eventName: eventConfig.name,
|
|
1103
|
-
params:
|
|
1105
|
+
params: maybeDecodedEvent,
|
|
1104
1106
|
chainId: chain,
|
|
1105
1107
|
srcAddress: routedAddress,
|
|
1106
1108
|
logIndex: log.logIndex,
|
|
@@ -1113,21 +1115,33 @@ function make(param) {
|
|
|
1113
1115
|
}));
|
|
1114
1116
|
let optFirstBlockParent = await firstBlockParentPromise;
|
|
1115
1117
|
let totalTimeElapsed = Hrtime.toSecondsFloat(Hrtime.timeSince(startFetchingBatchTimeRef));
|
|
1116
|
-
let
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1118
|
+
let blockHashes = [];
|
|
1119
|
+
let pushBlockInfo = b => {
|
|
1120
|
+
blockHashes.push({
|
|
1121
|
+
blockHash: b.hash,
|
|
1122
|
+
blockNumber: b.number
|
|
1123
|
+
});
|
|
1124
|
+
if (b.number > 0) {
|
|
1125
|
+
blockHashes.push({
|
|
1126
|
+
blockHash: b.parentHash,
|
|
1127
|
+
blockNumber: b.number - 1 | 0
|
|
1128
|
+
});
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1127
1131
|
};
|
|
1132
|
+
pushBlockInfo(latestFetchedBlockInfo);
|
|
1133
|
+
if (optFirstBlockParent !== undefined) {
|
|
1134
|
+
pushBlockInfo(optFirstBlockParent);
|
|
1135
|
+
}
|
|
1136
|
+
Belt_Array.forEach(logs, log => {
|
|
1137
|
+
blockHashes.push({
|
|
1138
|
+
blockHash: log.blockHash,
|
|
1139
|
+
blockNumber: log.blockNumber
|
|
1140
|
+
});
|
|
1141
|
+
});
|
|
1128
1142
|
return {
|
|
1129
1143
|
knownHeight: knownHeight,
|
|
1130
|
-
|
|
1144
|
+
blockHashes: blockHashes,
|
|
1131
1145
|
parsedQueueItems: parsedQueueItems,
|
|
1132
1146
|
fromBlockQueried: fromBlock,
|
|
1133
1147
|
latestFetchedBlockNumber: latestFetchedBlockInfo.number,
|
|
@@ -1137,25 +1151,25 @@ function make(param) {
|
|
|
1137
1151
|
}
|
|
1138
1152
|
};
|
|
1139
1153
|
};
|
|
1140
|
-
let
|
|
1154
|
+
let onReorg = param => {
|
|
1141
1155
|
blockLoader.contents = makeBlockLoader();
|
|
1142
1156
|
transactionLoader.contents = makeTransactionLoader();
|
|
1143
1157
|
receiptLoader.contents = makeReceiptLoader();
|
|
1144
|
-
return Stdlib_Promise.$$catch(Promise.all(blockNumbers.map(blockNum => LazyLoader.get(blockLoader.contents, blockNum))).then(rawBlocks => ({
|
|
1145
|
-
TAG: "Ok",
|
|
1146
|
-
_0: rawBlocks.map(json => {
|
|
1147
|
-
let b = parseBlockInfo(json);
|
|
1148
|
-
return {
|
|
1149
|
-
blockHash: b.hash,
|
|
1150
|
-
blockNumber: b.number,
|
|
1151
|
-
blockTimestamp: b.timestamp
|
|
1152
|
-
};
|
|
1153
|
-
})
|
|
1154
|
-
})), exn => Promise.resolve({
|
|
1155
|
-
TAG: "Error",
|
|
1156
|
-
_0: exn
|
|
1157
|
-
}));
|
|
1158
1158
|
};
|
|
1159
|
+
let getBlockHashes = (blockNumbers, _currentlyUnusedLogger) => Stdlib_Promise.$$catch(Promise.all(blockNumbers.map(blockNum => LazyLoader.get(blockLoader.contents, blockNum))).then(rawBlocks => ({
|
|
1160
|
+
TAG: "Ok",
|
|
1161
|
+
_0: rawBlocks.map(json => {
|
|
1162
|
+
let b = parseBlockInfo(json);
|
|
1163
|
+
return {
|
|
1164
|
+
blockHash: b.hash,
|
|
1165
|
+
blockNumber: b.number,
|
|
1166
|
+
blockTimestamp: b.timestamp
|
|
1167
|
+
};
|
|
1168
|
+
})
|
|
1169
|
+
})), exn => Promise.resolve({
|
|
1170
|
+
TAG: "Error",
|
|
1171
|
+
_0: exn
|
|
1172
|
+
}));
|
|
1159
1173
|
let createHeightSubscription = Belt_Option.map(param.ws, wsUrl => (onHeight => RpcWebSocketHeightStream.subscribe(wsUrl, chain, onHeight)));
|
|
1160
1174
|
return {
|
|
1161
1175
|
name: name,
|
|
@@ -1181,7 +1195,8 @@ function make(param) {
|
|
|
1181
1195
|
return height;
|
|
1182
1196
|
},
|
|
1183
1197
|
getItemsOrThrow: getItemsOrThrow,
|
|
1184
|
-
createHeightSubscription: createHeightSubscription
|
|
1198
|
+
createHeightSubscription: createHeightSubscription,
|
|
1199
|
+
onReorg: onReorg
|
|
1185
1200
|
};
|
|
1186
1201
|
}
|
|
1187
1202
|
|