envio 3.3.0-alpha.9 → 3.3.0
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/index.d.ts +19 -0
- 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 +9 -8
- package/src/Batch.res.mjs +1 -1
- package/src/BatchProcessing.res +0 -7
- package/src/BatchProcessing.res.mjs +1 -8
- package/src/ChainFetching.res +30 -18
- package/src/ChainFetching.res.mjs +23 -13
- package/src/ChainState.res +134 -55
- package/src/ChainState.res.mjs +78 -36
- package/src/ChainState.resi +14 -2
- package/src/Config.res +9 -5
- package/src/Config.res.mjs +2 -2
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +115 -34
- package/src/CrossChainState.res.mjs +37 -14
- package/src/EffectState.res +100 -0
- package/src/EffectState.res.mjs +74 -0
- package/src/EffectState.resi +32 -0
- package/src/Envio.res +25 -7
- package/src/Envio.res.mjs +15 -19
- package/src/EventConfigBuilder.res +21 -46
- package/src/EventConfigBuilder.res.mjs +18 -25
- package/src/EventProcessing.res +8 -5
- package/src/EventProcessing.res.mjs +2 -1
- package/src/FetchState.res +814 -467
- package/src/FetchState.res.mjs +541 -369
- package/src/HandlerRegister.res +3 -1
- package/src/HandlerRegister.res.mjs +3 -2
- package/src/InMemoryStore.res +14 -26
- package/src/InMemoryStore.res.mjs +6 -19
- package/src/IndexerState.res +15 -39
- package/src/IndexerState.res.mjs +18 -29
- package/src/IndexerState.resi +2 -10
- package/src/Internal.res +98 -14
- package/src/Internal.res.mjs +96 -2
- package/src/LoadLayer.res +44 -24
- package/src/LoadLayer.res.mjs +43 -20
- package/src/LoadLayer.resi +1 -0
- package/src/LogSelection.res +0 -62
- package/src/LogSelection.res.mjs +0 -74
- package/src/Metrics.res +1 -1
- package/src/Metrics.res.mjs +1 -1
- package/src/Persistence.res +12 -3
- package/src/PgStorage.res +155 -82
- package/src/PgStorage.res.mjs +130 -77
- package/src/Prometheus.res +20 -10
- package/src/Prometheus.res.mjs +22 -10
- package/src/PruneStaleHistory.res +146 -35
- package/src/PruneStaleHistory.res.mjs +114 -20
- package/src/RawEvent.res +2 -2
- package/src/Rollback.res +32 -13
- package/src/Rollback.res.mjs +24 -11
- package/src/SimulateDeadInputTracker.res +1 -1
- package/src/SimulateItems.res +38 -6
- package/src/SimulateItems.res.mjs +28 -9
- package/src/TestIndexer.res +2 -2
- package/src/TestIndexer.res.mjs +2 -2
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/UserContext.res +62 -23
- package/src/UserContext.res.mjs +26 -6
- package/src/Writing.res +60 -21
- package/src/Writing.res.mjs +27 -9
- package/src/bindings/NodeJs.res +5 -0
- package/src/bindings/Viem.res +0 -5
- package/src/sources/EventRouter.res +0 -21
- package/src/sources/EventRouter.res.mjs +0 -12
- package/src/sources/EvmChain.res +2 -27
- package/src/sources/EvmChain.res.mjs +2 -23
- package/src/sources/EvmRpcClient.res +58 -23
- package/src/sources/EvmRpcClient.res.mjs +11 -5
- package/src/sources/HyperSync.res +9 -38
- package/src/sources/HyperSync.res.mjs +16 -28
- package/src/sources/HyperSync.resi +2 -2
- package/src/sources/HyperSyncClient.res +88 -11
- package/src/sources/HyperSyncClient.res.mjs +39 -6
- package/src/sources/HyperSyncSource.res +18 -199
- package/src/sources/HyperSyncSource.res.mjs +9 -128
- package/src/sources/Rpc.res +0 -32
- package/src/sources/Rpc.res.mjs +1 -46
- package/src/sources/RpcSource.res +129 -522
- package/src/sources/RpcSource.res.mjs +161 -366
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SourceManager.res +3 -7
- package/src/sources/SourceManager.res.mjs +2 -7
- package/src/sources/SourceManager.resi +0 -2
- package/src/sources/SvmHyperSyncSource.res +13 -3
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
|
@@ -9,23 +9,21 @@ import * as Address from "../Address.res.mjs";
|
|
|
9
9
|
import * as Logging from "../Logging.res.mjs";
|
|
10
10
|
import * as Internal from "../Internal.res.mjs";
|
|
11
11
|
import * as LazyLoader from "../LazyLoader.res.mjs";
|
|
12
|
-
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
13
|
-
import * as EventRouter from "./EventRouter.res.mjs";
|
|
14
12
|
import * as Performance from "../bindings/Performance.res.mjs";
|
|
13
|
+
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
15
14
|
import * as EvmRpcClient from "./EvmRpcClient.res.mjs";
|
|
16
|
-
import * as LogSelection from "../LogSelection.res.mjs";
|
|
17
15
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
16
|
+
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
18
17
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
19
18
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
20
19
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
21
20
|
import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
21
|
+
import * as HyperSyncClient from "./HyperSyncClient.res.mjs";
|
|
22
22
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
23
23
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
24
24
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
25
25
|
import * as RpcWebSocketHeightStream from "./RpcWebSocketHeightStream.res.mjs";
|
|
26
26
|
|
|
27
|
-
let QueryTimout = /* @__PURE__ */Primitive_exceptions.create("RpcSource.QueryTimout");
|
|
28
|
-
|
|
29
27
|
let TransactionDataNotFound = /* @__PURE__ */Primitive_exceptions.create("RpcSource.TransactionDataNotFound");
|
|
30
28
|
|
|
31
29
|
async function getKnownRawBlock(client, blockNumber) {
|
|
@@ -84,339 +82,114 @@ function getErrorMessage(exn) {
|
|
|
84
82
|
if (exn.RE_EXN_ID !== "JsExn") {
|
|
85
83
|
return;
|
|
86
84
|
}
|
|
85
|
+
let msg = Stdlib_JsExn.message(exn._1);
|
|
86
|
+
if (msg === undefined) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let obj;
|
|
87
90
|
try {
|
|
88
|
-
|
|
89
|
-
S$RescriptSchema.assertOrThrow(message, S$RescriptSchema.string);
|
|
90
|
-
return message;
|
|
91
|
+
obj = Stdlib_JSON.Decode.object(JSON.parse(msg));
|
|
91
92
|
} catch (exn$1) {
|
|
92
93
|
return;
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
let patterns = [
|
|
97
|
-
/more than \d+ logs/i,
|
|
98
|
-
/\d+ logs returned/i,
|
|
99
|
-
/too many logs/i,
|
|
100
|
-
/query returned more than \d+ results/i,
|
|
101
|
-
/query exceeds max results/i,
|
|
102
|
-
/response size should not/i,
|
|
103
|
-
/(backend )?response too large/i,
|
|
104
|
-
/logs matched by query exceeds limit/i,
|
|
105
|
-
/block range is too wide/i
|
|
106
|
-
];
|
|
107
|
-
|
|
108
|
-
function isResponseTooLargeError(exn) {
|
|
109
|
-
let message = getErrorMessage(exn);
|
|
110
|
-
if (message !== undefined) {
|
|
111
|
-
return patterns.some(re => re.test(message));
|
|
112
|
-
} else {
|
|
113
|
-
return false;
|
|
95
|
+
if (obj === undefined) {
|
|
96
|
+
return;
|
|
114
97
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
let blockRangeLimitRegExp = /limited to a (\d+) blocks range/;
|
|
120
|
-
|
|
121
|
-
let alchemyRangeRegExp = /up to a (\d+) block range/;
|
|
122
|
-
|
|
123
|
-
let cloudflareRangeRegExp = /Max range: (\d+)/;
|
|
124
|
-
|
|
125
|
-
let thirdwebRangeRegExp = /Maximum allowed number of requested blocks is (\d+)/;
|
|
126
|
-
|
|
127
|
-
let blockpiRangeRegExp = /limited to (\d+) block/;
|
|
128
|
-
|
|
129
|
-
let baseRangeRegExp = /block range too large/;
|
|
130
|
-
|
|
131
|
-
let maxAllowedBlocksRegExp = /maximum allowed is (\d+) blocks/;
|
|
132
|
-
|
|
133
|
-
let blastPaidRegExp = /exceeds the range allowed for your plan \(\d+ > (\d+)\)/;
|
|
134
|
-
|
|
135
|
-
let chainstackRegExp = /Block range limit exceeded./;
|
|
136
|
-
|
|
137
|
-
let coinbaseRegExp = /please limit the query to at most (\d+) blocks/;
|
|
138
|
-
|
|
139
|
-
let publicNodeRegExp = /maximum block range: (\d+)/;
|
|
140
|
-
|
|
141
|
-
let hyperliquidRegExp = /query exceeds max block range (\d+)/;
|
|
142
|
-
|
|
143
|
-
function getSuggestedBlockIntervalFromExn(exn) {
|
|
144
|
-
let message = getErrorMessage(exn);
|
|
145
|
-
if (message !== undefined) {
|
|
146
|
-
let extractBlockRange = (execResult, isMaxRange) => {
|
|
147
|
-
let match = execResult.slice(1);
|
|
148
|
-
if (match.length !== 1) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
let blockRangeLimit = match[0];
|
|
152
|
-
if (blockRangeLimit === undefined) {
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
let blockRangeLimit$1 = Stdlib_Int.fromString(blockRangeLimit, undefined);
|
|
156
|
-
if (blockRangeLimit$1 !== undefined && blockRangeLimit$1 > 0) {
|
|
157
|
-
return [
|
|
158
|
-
blockRangeLimit$1,
|
|
159
|
-
isMaxRange
|
|
160
|
-
];
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
|
-
let execResult = suggestedRangeRegExp.exec(message);
|
|
164
|
-
if (execResult == null) {
|
|
165
|
-
let execResult$1 = blockRangeLimitRegExp.exec(message);
|
|
166
|
-
if (!(execResult$1 == null)) {
|
|
167
|
-
return extractBlockRange(execResult$1, true);
|
|
168
|
-
}
|
|
169
|
-
let execResult$2 = alchemyRangeRegExp.exec(message);
|
|
170
|
-
if (!(execResult$2 == null)) {
|
|
171
|
-
return extractBlockRange(execResult$2, true);
|
|
172
|
-
}
|
|
173
|
-
let execResult$3 = cloudflareRangeRegExp.exec(message);
|
|
174
|
-
if (!(execResult$3 == null)) {
|
|
175
|
-
return extractBlockRange(execResult$3, true);
|
|
176
|
-
}
|
|
177
|
-
let execResult$4 = thirdwebRangeRegExp.exec(message);
|
|
178
|
-
if (!(execResult$4 == null)) {
|
|
179
|
-
return extractBlockRange(execResult$4, true);
|
|
180
|
-
}
|
|
181
|
-
let execResult$5 = blockpiRangeRegExp.exec(message);
|
|
182
|
-
if (!(execResult$5 == null)) {
|
|
183
|
-
return extractBlockRange(execResult$5, true);
|
|
184
|
-
}
|
|
185
|
-
let execResult$6 = maxAllowedBlocksRegExp.exec(message);
|
|
186
|
-
if (!(execResult$6 == null)) {
|
|
187
|
-
return extractBlockRange(execResult$6, true);
|
|
188
|
-
}
|
|
189
|
-
let match = baseRangeRegExp.exec(message);
|
|
190
|
-
if (!(match == null)) {
|
|
191
|
-
return [
|
|
192
|
-
2000,
|
|
193
|
-
true
|
|
194
|
-
];
|
|
195
|
-
}
|
|
196
|
-
let execResult$7 = blastPaidRegExp.exec(message);
|
|
197
|
-
if (!(execResult$7 == null)) {
|
|
198
|
-
return extractBlockRange(execResult$7, true);
|
|
199
|
-
}
|
|
200
|
-
let match$1 = chainstackRegExp.exec(message);
|
|
201
|
-
if (!(match$1 == null)) {
|
|
202
|
-
return [
|
|
203
|
-
10000,
|
|
204
|
-
true
|
|
205
|
-
];
|
|
206
|
-
}
|
|
207
|
-
let execResult$8 = coinbaseRegExp.exec(message);
|
|
208
|
-
if (!(execResult$8 == null)) {
|
|
209
|
-
return extractBlockRange(execResult$8, true);
|
|
210
|
-
}
|
|
211
|
-
let execResult$9 = publicNodeRegExp.exec(message);
|
|
212
|
-
if (!(execResult$9 == null)) {
|
|
213
|
-
return extractBlockRange(execResult$9, true);
|
|
214
|
-
}
|
|
215
|
-
let execResult$10 = hyperliquidRegExp.exec(message);
|
|
216
|
-
if (!(execResult$10 == null)) {
|
|
217
|
-
return extractBlockRange(execResult$10, true);
|
|
218
|
-
} else {
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
let match$2 = execResult.slice(1);
|
|
223
|
-
if (match$2.length !== 2) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
let fromBlock = match$2[0];
|
|
227
|
-
if (fromBlock === undefined) {
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
let toBlock = match$2[1];
|
|
231
|
-
if (toBlock === undefined) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
let match$3 = Stdlib_Int.fromString(fromBlock, undefined);
|
|
235
|
-
let match$4 = Stdlib_Int.fromString(toBlock, undefined);
|
|
236
|
-
if (match$3 !== undefined && match$4 !== undefined && match$4 >= match$3) {
|
|
237
|
-
return [
|
|
238
|
-
(match$4 - match$3 | 0) + 1 | 0,
|
|
239
|
-
false
|
|
240
|
-
];
|
|
241
|
-
} else {
|
|
242
|
-
return;
|
|
243
|
-
}
|
|
98
|
+
let match = obj["errorMessage"];
|
|
99
|
+
if (typeof match === "string") {
|
|
100
|
+
return match;
|
|
244
101
|
}
|
|
245
102
|
}
|
|
246
103
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
return Stdlib_Option.getOr(mutSuggestedBlockIntervals[maxSuggestedBlockIntervalKey], intervalCeiling);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function mergeAndDedupItems(itemsPerSelection) {
|
|
254
|
-
let seen = new Set();
|
|
255
|
-
let merged = [];
|
|
256
|
-
itemsPerSelection.forEach(items => {
|
|
257
|
-
items.forEach(item => {
|
|
258
|
-
let key = item.log.blockNumber.toString() + `-` + item.log.logIndex.toString();
|
|
259
|
-
if (!seen.has(key)) {
|
|
260
|
-
seen.add(key);
|
|
261
|
-
merged.push(item);
|
|
262
|
-
return;
|
|
263
|
-
}
|
|
264
|
-
});
|
|
265
|
-
});
|
|
266
|
-
return merged;
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function getNextPage(fromBlock, toBlock, logSelections, loadBlock, sc, rpcClient, mutSuggestedBlockIntervals, partitionId, recordRequest) {
|
|
270
|
-
let queryTimoutPromise = Time.resolvePromiseAfterDelay(sc.queryTimeoutMillis).then(() => Promise.reject({
|
|
271
|
-
RE_EXN_ID: QueryTimout,
|
|
272
|
-
_1: `Query took longer than ` + (sc.queryTimeoutMillis / 1000 | 0).toString() + ` seconds`
|
|
273
|
-
}));
|
|
274
|
-
let latestFetchedBlockPromise = loadBlock(toBlock);
|
|
275
|
-
let queryLogs = param => {
|
|
276
|
-
let timerRef = Performance.now();
|
|
277
|
-
return rpcClient.getLogs({
|
|
278
|
-
fromBlock: fromBlock,
|
|
279
|
-
toBlock: toBlock,
|
|
280
|
-
addresses: param.addresses,
|
|
281
|
-
topics: param.topicQuery.map(filter => {
|
|
282
|
-
if (filter === null) {
|
|
283
|
-
return null;
|
|
284
|
-
} else if (typeof filter === "string") {
|
|
285
|
-
return [filter];
|
|
286
|
-
} else {
|
|
287
|
-
return filter;
|
|
288
|
-
}
|
|
289
|
-
})
|
|
290
|
-
}).then(items => {
|
|
291
|
-
recordRequest("eth_getLogs", Performance.secondsSince(timerRef));
|
|
292
|
-
return items;
|
|
293
|
-
});
|
|
294
|
-
};
|
|
295
|
-
let len = logSelections.length;
|
|
296
|
-
let logsPromise;
|
|
297
|
-
if (len !== 1) {
|
|
298
|
-
logsPromise = len !== 0 ? Promise.all(logSelections.map(queryLogs)).then(async itemsPerSelection => ({
|
|
299
|
-
items: mergeAndDedupItems(itemsPerSelection),
|
|
300
|
-
latestFetchedBlockInfo: await latestFetchedBlockPromise
|
|
301
|
-
})) : latestFetchedBlockPromise.then(latestFetchedBlockInfo => ({
|
|
302
|
-
items: [],
|
|
303
|
-
latestFetchedBlockInfo: latestFetchedBlockInfo
|
|
304
|
-
}));
|
|
305
|
-
} else {
|
|
306
|
-
let logSelection = logSelections[0];
|
|
307
|
-
logsPromise = queryLogs(logSelection).then(async items => ({
|
|
308
|
-
items: items,
|
|
309
|
-
latestFetchedBlockInfo: await latestFetchedBlockPromise
|
|
310
|
-
}));
|
|
104
|
+
function parseGetNextPageRetryError(exn) {
|
|
105
|
+
if (exn.RE_EXN_ID !== "JsExn") {
|
|
106
|
+
return;
|
|
311
107
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
]), err => {
|
|
316
|
-
let executedBlockInterval = (toBlock - fromBlock | 0) + 1 | 0;
|
|
317
|
-
let shrunkBlockInterval = Primitive_int.max(1, executedBlockInterval * sc.backoffMultiplicative | 0);
|
|
318
|
-
let throwFailedGettingItems = retry => {
|
|
319
|
-
throw {
|
|
320
|
-
RE_EXN_ID: Source.GetItemsError,
|
|
321
|
-
_1: {
|
|
322
|
-
TAG: "FailedGettingItems",
|
|
323
|
-
exn: err,
|
|
324
|
-
attemptedToBlock: toBlock,
|
|
325
|
-
retry: retry
|
|
326
|
-
},
|
|
327
|
-
Error: new Error()
|
|
328
|
-
};
|
|
329
|
-
};
|
|
330
|
-
let throwResize = interval => throwFailedGettingItems({
|
|
331
|
-
TAG: "WithSuggestedToBlock",
|
|
332
|
-
toBlock: (fromBlock + interval | 0) - 1 | 0
|
|
333
|
-
});
|
|
334
|
-
let match = getSuggestedBlockIntervalFromExn(err);
|
|
335
|
-
if (match === undefined) {
|
|
336
|
-
if (executedBlockInterval > 1 && isResponseTooLargeError(err)) {
|
|
337
|
-
mutSuggestedBlockIntervals[partitionId] = shrunkBlockInterval;
|
|
338
|
-
return throwResize(shrunkBlockInterval);
|
|
339
|
-
} else {
|
|
340
|
-
mutSuggestedBlockIntervals[partitionId] = shrunkBlockInterval;
|
|
341
|
-
return throwFailedGettingItems({
|
|
342
|
-
TAG: "WithBackoff",
|
|
343
|
-
message: `Failed getting data for the block range. Will try smaller block range for the next attempt.`,
|
|
344
|
-
backoffMillis: sc.backoffMillis
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
let interval = match[0];
|
|
349
|
-
if (match[1]) {
|
|
350
|
-
let capped = Primitive_int.min(getSourceMaxBlockInterval(mutSuggestedBlockIntervals, sc.intervalCeiling), interval);
|
|
351
|
-
mutSuggestedBlockIntervals[maxSuggestedBlockIntervalKey] = capped;
|
|
352
|
-
return throwResize(capped);
|
|
353
|
-
}
|
|
354
|
-
mutSuggestedBlockIntervals[partitionId] = interval;
|
|
355
|
-
return throwResize(interval);
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
function getSelectionConfig(selection) {
|
|
360
|
-
let evmOnEventRegistrations = selection.onEventRegistrations;
|
|
361
|
-
if (Utils.$$Array.isEmpty(evmOnEventRegistrations)) {
|
|
362
|
-
throw {
|
|
363
|
-
RE_EXN_ID: Source.GetItemsError,
|
|
364
|
-
_1: {
|
|
365
|
-
TAG: "UnsupportedSelection",
|
|
366
|
-
message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team."
|
|
367
|
-
},
|
|
368
|
-
Error: new Error()
|
|
369
|
-
};
|
|
108
|
+
let msg = Stdlib_JsExn.message(exn._1);
|
|
109
|
+
if (msg === undefined) {
|
|
110
|
+
return;
|
|
370
111
|
}
|
|
371
|
-
let
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
112
|
+
let obj;
|
|
113
|
+
try {
|
|
114
|
+
obj = Stdlib_JSON.Decode.object(JSON.parse(msg));
|
|
115
|
+
} catch (exn$1) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (obj === undefined) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
let match = obj["kind"];
|
|
122
|
+
let match$1 = obj["attemptedToBlock"];
|
|
123
|
+
let match$2 = obj["retry"];
|
|
124
|
+
if (match === undefined) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (typeof match !== "string") {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (match !== "Retry") {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (match$1 === undefined) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (typeof match$1 !== "number") {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
if (match$2 === undefined) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (typeof match$2 !== "object" || match$2 === null || Array.isArray(match$2)) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
let match$3 = obj["requestStats"];
|
|
146
|
+
let requestStats = match$3 !== undefined ? (
|
|
147
|
+
Array.isArray(match$3) ? Stdlib_Array.filterMap(match$3, s => {
|
|
148
|
+
let o = Stdlib_JSON.Decode.object(s);
|
|
149
|
+
if (o === undefined) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
let match = o["method"];
|
|
153
|
+
let match$1 = o["seconds"];
|
|
154
|
+
if (typeof match === "string" && typeof match$1 === "number") {
|
|
155
|
+
return {
|
|
156
|
+
method: match,
|
|
157
|
+
seconds: match$1
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}) : []
|
|
161
|
+
) : [];
|
|
162
|
+
let match$4 = match$2["tag"];
|
|
163
|
+
let retry;
|
|
164
|
+
if (typeof match$4 === "string") {
|
|
165
|
+
switch (match$4) {
|
|
166
|
+
case "WithBackoff" :
|
|
167
|
+
let match$5 = match$2["message"];
|
|
168
|
+
let match$6 = match$2["backoffMillis"];
|
|
169
|
+
retry = typeof match$5 === "string" && typeof match$6 === "number" ? ({
|
|
170
|
+
TAG: "WithBackoff",
|
|
171
|
+
message: match$5,
|
|
172
|
+
backoffMillis: match$6 | 0
|
|
173
|
+
}) : undefined;
|
|
174
|
+
break;
|
|
175
|
+
case "WithSuggestedToBlock" :
|
|
176
|
+
let match$7 = match$2["toBlock"];
|
|
177
|
+
retry = typeof match$7 === "number" ? ({
|
|
178
|
+
TAG: "WithSuggestedToBlock",
|
|
179
|
+
toBlock: match$7 | 0
|
|
180
|
+
}) : undefined;
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
retry = undefined;
|
|
384
184
|
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
contractNames.forEach(contractName => {
|
|
394
|
-
let addresses = addressesByContractName[contractName];
|
|
395
|
-
if (addresses === undefined) {
|
|
396
|
-
return;
|
|
397
|
-
}
|
|
398
|
-
if (addresses.length === 0) {
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
let topicSelections = byContract[contractName];
|
|
402
|
-
if (topicSelections !== undefined) {
|
|
403
|
-
logSelections.push(...toLogSelections(addresses, LogSelection.materializeTopicSelections(topicSelections, addresses)));
|
|
404
|
-
}
|
|
405
|
-
let topicSelections$1 = wildcardByContract[contractName];
|
|
406
|
-
if (topicSelections$1 !== undefined) {
|
|
407
|
-
logSelections.push(...toLogSelections(undefined, LogSelection.materializeTopicSelections(topicSelections$1, addresses)));
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
});
|
|
411
|
-
return logSelections;
|
|
412
|
-
};
|
|
413
|
-
return {
|
|
414
|
-
getLogSelectionsOrThrow: getLogSelectionsOrThrow
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
function memoGetSelectionConfig() {
|
|
419
|
-
return Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
185
|
+
} else {
|
|
186
|
+
retry = undefined;
|
|
187
|
+
}
|
|
188
|
+
return Stdlib_Option.map(retry, retry => [
|
|
189
|
+
match$1 | 0,
|
|
190
|
+
retry,
|
|
191
|
+
requestStats
|
|
192
|
+
]);
|
|
420
193
|
}
|
|
421
194
|
|
|
422
195
|
let lowercaseAddressSchema = S$RescriptSchema.transform(S$RescriptSchema.string, param => ({
|
|
@@ -953,17 +726,15 @@ function makeThrowingGetEventTransaction(getTransactionJson, getReceiptJson, low
|
|
|
953
726
|
function make(param) {
|
|
954
727
|
let headers = param.headers;
|
|
955
728
|
let lowercaseAddresses = param.lowercaseAddresses;
|
|
956
|
-
let
|
|
729
|
+
let onEventRegistrations = param.onEventRegistrations;
|
|
957
730
|
let chain = param.chain;
|
|
958
731
|
let url = param.url;
|
|
959
732
|
let syncConfig = param.syncConfig;
|
|
960
733
|
let host = Utils.Url.getHostFromUrl(url);
|
|
961
734
|
let urlHost = host !== undefined ? host : Stdlib_JsError.throwWithMessage(`The RPC url for chain ` + chain.toString() + ` is in incorrect format. The RPC url needs to start with either http:// or https://`);
|
|
962
735
|
let name = `RPC (` + urlHost + `)`;
|
|
963
|
-
let getSelectionConfig$1 = Utils.$$WeakMap.memoize(getSelectionConfig);
|
|
964
|
-
let mutSuggestedBlockIntervals = {};
|
|
965
736
|
let client = Rpc.makeClient(url, headers);
|
|
966
|
-
let rpcClient = EvmRpcClient.make(url, !lowercaseAddresses, undefined, headers,
|
|
737
|
+
let rpcClient = EvmRpcClient.make(url, !lowercaseAddresses, syncConfig, undefined, headers, HyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations));
|
|
967
738
|
let pendingRequestStats = [];
|
|
968
739
|
let recordRequest = (method, seconds) => {
|
|
969
740
|
pendingRequestStats.push({
|
|
@@ -1049,36 +820,68 @@ function make(param) {
|
|
|
1049
820
|
Error: new Error()
|
|
1050
821
|
};
|
|
1051
822
|
}, lowercaseAddresses);
|
|
1052
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName,
|
|
823
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, param, knownHeight, partitionId, selection, param$1, retry, param$2) => {
|
|
1053
824
|
let startFetchingBatchTimeRef = Performance.now();
|
|
1054
|
-
let sourceMaxBlockInterval = getSourceMaxBlockInterval(mutSuggestedBlockIntervals, syncConfig.intervalCeiling);
|
|
1055
|
-
let suggestedBlockInterval = Primitive_int.min(Stdlib_Option.getOr(mutSuggestedBlockIntervals[partitionId], syncConfig.initialBlockInterval), sourceMaxBlockInterval);
|
|
1056
825
|
let toBlock$1 = toBlock !== undefined ? Primitive_int.min(toBlock, knownHeight) : knownHeight;
|
|
1057
|
-
let suggestedToBlock = Primitive_int.max(Primitive_int.min((fromBlock + suggestedBlockInterval | 0) - 1 | 0, toBlock$1), fromBlock);
|
|
1058
826
|
let firstBlockParentPromise = fromBlock > 0 ? LazyLoader.get(blockLoader.contents, fromBlock - 1 | 0).then(json => parseBlockInfo(json)) : Promise.resolve(undefined);
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
827
|
+
if (Utils.$$Array.isEmpty(selection.onEventRegistrations)) {
|
|
828
|
+
throw {
|
|
829
|
+
RE_EXN_ID: Source.GetItemsError,
|
|
830
|
+
_1: {
|
|
831
|
+
TAG: "UnsupportedSelection",
|
|
832
|
+
message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team."
|
|
833
|
+
},
|
|
834
|
+
Error: new Error()
|
|
835
|
+
};
|
|
1067
836
|
}
|
|
1068
|
-
let
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
837
|
+
let match;
|
|
838
|
+
try {
|
|
839
|
+
match = await rpcClient.getNextPage({
|
|
840
|
+
fromBlock: fromBlock,
|
|
841
|
+
toBlockCeiling: toBlock$1,
|
|
842
|
+
partitionId: partitionId,
|
|
843
|
+
registrationIndexes: selection.onEventRegistrations.map(reg => reg.index),
|
|
844
|
+
addressesByContractName: addressesByContractName
|
|
845
|
+
});
|
|
846
|
+
} catch (raw_exn) {
|
|
847
|
+
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
848
|
+
let match$1 = parseGetNextPageRetryError(exn);
|
|
849
|
+
if (match$1 !== undefined) {
|
|
850
|
+
match$1[2].forEach(stat => recordRequest(stat.method, stat.seconds));
|
|
851
|
+
throw {
|
|
852
|
+
RE_EXN_ID: Source.GetItemsError,
|
|
853
|
+
_1: {
|
|
854
|
+
TAG: "FailedGettingItems",
|
|
855
|
+
exn: exn,
|
|
856
|
+
attemptedToBlock: match$1[0],
|
|
857
|
+
retry: match$1[1]
|
|
858
|
+
},
|
|
859
|
+
Error: new Error()
|
|
860
|
+
};
|
|
1075
861
|
}
|
|
862
|
+
throw {
|
|
863
|
+
RE_EXN_ID: Source.GetItemsError,
|
|
864
|
+
_1: {
|
|
865
|
+
TAG: "FailedGettingItems",
|
|
866
|
+
exn: exn,
|
|
867
|
+
attemptedToBlock: toBlock$1,
|
|
868
|
+
retry: {
|
|
869
|
+
TAG: "WithBackoff",
|
|
870
|
+
message: "Unexpected issue while fetching events from the RPC client. Attempt a retry.",
|
|
871
|
+
backoffMillis: retry !== 0 ? 1000 * retry | 0 : 500
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
Error: new Error()
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
let items = match.items;
|
|
878
|
+
match.requestStats.forEach(stat => recordRequest(stat.method, stat.seconds));
|
|
879
|
+
let latestFetchedBlockInfo = await LazyLoader.get(blockLoader.contents, match.toBlock).then(parseBlockInfo);
|
|
880
|
+
let parsedQueueItems = await Promise.all(items.map(param => {
|
|
881
|
+
let decoded = param.params;
|
|
882
|
+
let log = param.log;
|
|
883
|
+
let onEventRegistration = onEventRegistrations[param.onEventRegistrationIndex];
|
|
1076
884
|
let eventConfig = onEventRegistration.eventConfig;
|
|
1077
|
-
let decoded = Stdlib_Option.flatMap(Primitive_option.fromNullable(param.params), __x => __x[eventConfig.contractName]);
|
|
1078
|
-
if (decoded === undefined) {
|
|
1079
|
-
return;
|
|
1080
|
-
}
|
|
1081
|
-
let decoded$1 = Primitive_option.valFromOption(decoded);
|
|
1082
885
|
return (async () => {
|
|
1083
886
|
let match;
|
|
1084
887
|
try {
|
|
@@ -1128,9 +931,9 @@ function make(param) {
|
|
|
1128
931
|
payload: {
|
|
1129
932
|
contractName: eventConfig.contractName,
|
|
1130
933
|
eventName: eventConfig.name,
|
|
1131
|
-
params: decoded
|
|
934
|
+
params: decoded,
|
|
1132
935
|
chainId: chain,
|
|
1133
|
-
srcAddress:
|
|
936
|
+
srcAddress: log.address,
|
|
1134
937
|
logIndex: log.logIndex,
|
|
1135
938
|
transaction: Primitive_option.some(match[1]),
|
|
1136
939
|
block: Primitive_option.some(block)
|
|
@@ -1238,20 +1041,12 @@ function make(param) {
|
|
|
1238
1041
|
}
|
|
1239
1042
|
|
|
1240
1043
|
export {
|
|
1241
|
-
QueryTimout,
|
|
1242
1044
|
TransactionDataNotFound,
|
|
1243
1045
|
getKnownRawBlock,
|
|
1244
1046
|
parseBlockInfo,
|
|
1245
1047
|
getKnownRawBlockWithBackoff,
|
|
1246
1048
|
getErrorMessage,
|
|
1247
|
-
|
|
1248
|
-
getSuggestedBlockIntervalFromExn,
|
|
1249
|
-
maxSuggestedBlockIntervalKey,
|
|
1250
|
-
getSourceMaxBlockInterval,
|
|
1251
|
-
mergeAndDedupItems,
|
|
1252
|
-
getNextPage,
|
|
1253
|
-
getSelectionConfig,
|
|
1254
|
-
memoGetSelectionConfig,
|
|
1049
|
+
parseGetNextPageRetryError,
|
|
1255
1050
|
lowercaseAddressSchema,
|
|
1256
1051
|
checksumAddressSchema,
|
|
1257
1052
|
makeBlockFieldRegistry,
|