envio 3.3.0-alpha.8 → 3.3.0-rc.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 +205 -59
- package/src/ChainState.res.mjs +130 -27
- package/src/ChainState.resi +16 -1
- 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 +147 -39
- package/src/CrossChainState.res.mjs +42 -10
- 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/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +30 -56
- package/src/EventConfigBuilder.res.mjs +24 -30
- package/src/EventProcessing.res +8 -5
- package/src/EventProcessing.res.mjs +2 -1
- package/src/FetchState.res +842 -474
- package/src/FetchState.res.mjs +545 -356
- package/src/HandlerLoader.res +1 -1
- package/src/HandlerLoader.res.mjs +1 -1
- package/src/HandlerRegister.res +478 -305
- package/src/HandlerRegister.res.mjs +277 -209
- package/src/HandlerRegister.resi +11 -6
- 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 +121 -18
- 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 +92 -217
- package/src/LogSelection.res.mjs +95 -184
- package/src/Main.res +29 -143
- package/src/Main.res.mjs +25 -88
- 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/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateDeadInputTracker.res +1 -1
- package/src/SimulateItems.res +39 -7
- 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/Evm.res +4 -1
- package/src/sources/Evm.res.mjs +1 -1
- 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/Fuel.res +3 -1
- package/src/sources/Fuel.res.mjs +1 -1
- 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 -210
- package/src/sources/HyperSyncSource.res.mjs +9 -137
- package/src/sources/Rpc.res +0 -32
- package/src/sources/Rpc.res.mjs +1 -46
- package/src/sources/RpcSource.res +129 -533
- package/src/sources/RpcSource.res.mjs +161 -379
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SourceManager.res +4 -14
- package/src/sources/SourceManager.res.mjs +3 -9
- 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,352 +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, chain) {
|
|
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
|
-
|
|
384
|
-
|
|
385
|
-
|
|
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;
|
|
386
184
|
}
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
let noAddressLogSelections = toLogSelections(undefined, noAddressTopicSelections);
|
|
396
|
-
let getLogSelectionsOrThrow = contractNames.size === 0 ? param => noAddressLogSelections : addressesByContractName => {
|
|
397
|
-
let logSelections = noAddressLogSelections.slice();
|
|
398
|
-
contractNames.forEach(contractName => {
|
|
399
|
-
let addresses = addressesByContractName[contractName];
|
|
400
|
-
if (addresses === undefined) {
|
|
401
|
-
return;
|
|
402
|
-
}
|
|
403
|
-
if (addresses.length === 0) {
|
|
404
|
-
return;
|
|
405
|
-
}
|
|
406
|
-
let addressedTopicSelections = [];
|
|
407
|
-
let s = staticByContract[contractName];
|
|
408
|
-
if (s !== undefined) {
|
|
409
|
-
addressedTopicSelections.push(...s);
|
|
410
|
-
}
|
|
411
|
-
let fns = dynamicByContract[contractName];
|
|
412
|
-
if (fns !== undefined) {
|
|
413
|
-
fns.forEach(fn => {
|
|
414
|
-
addressedTopicSelections.push(...fn(addresses));
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
logSelections.push(...toLogSelections(addresses, addressedTopicSelections));
|
|
418
|
-
let fns$1 = dynamicWildcardByContract[contractName];
|
|
419
|
-
if (fns$1 !== undefined) {
|
|
420
|
-
logSelections.push(...toLogSelections(undefined, fns$1.flatMap(fn => fn(addresses))));
|
|
421
|
-
return;
|
|
422
|
-
}
|
|
423
|
-
});
|
|
424
|
-
return logSelections;
|
|
425
|
-
};
|
|
426
|
-
return {
|
|
427
|
-
getLogSelectionsOrThrow: getLogSelectionsOrThrow
|
|
428
|
-
};
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
function memoGetSelectionConfig(chain) {
|
|
432
|
-
return Utils.$$WeakMap.memoize(selection => getSelectionConfig(selection, chain));
|
|
185
|
+
} else {
|
|
186
|
+
retry = undefined;
|
|
187
|
+
}
|
|
188
|
+
return Stdlib_Option.map(retry, retry => [
|
|
189
|
+
match$1 | 0,
|
|
190
|
+
retry,
|
|
191
|
+
requestStats
|
|
192
|
+
]);
|
|
433
193
|
}
|
|
434
194
|
|
|
435
195
|
let lowercaseAddressSchema = S$RescriptSchema.transform(S$RescriptSchema.string, param => ({
|
|
@@ -966,17 +726,15 @@ function makeThrowingGetEventTransaction(getTransactionJson, getReceiptJson, low
|
|
|
966
726
|
function make(param) {
|
|
967
727
|
let headers = param.headers;
|
|
968
728
|
let lowercaseAddresses = param.lowercaseAddresses;
|
|
969
|
-
let
|
|
729
|
+
let onEventRegistrations = param.onEventRegistrations;
|
|
970
730
|
let chain = param.chain;
|
|
971
731
|
let url = param.url;
|
|
972
732
|
let syncConfig = param.syncConfig;
|
|
973
733
|
let host = Utils.Url.getHostFromUrl(url);
|
|
974
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://`);
|
|
975
735
|
let name = `RPC (` + urlHost + `)`;
|
|
976
|
-
let getSelectionConfig = memoGetSelectionConfig(chain);
|
|
977
|
-
let mutSuggestedBlockIntervals = {};
|
|
978
736
|
let client = Rpc.makeClient(url, headers);
|
|
979
|
-
let rpcClient = EvmRpcClient.make(url, !lowercaseAddresses, undefined, headers,
|
|
737
|
+
let rpcClient = EvmRpcClient.make(url, !lowercaseAddresses, syncConfig, undefined, headers, HyperSyncClient.Registration.fromOnEventRegistrations(onEventRegistrations));
|
|
980
738
|
let pendingRequestStats = [];
|
|
981
739
|
let recordRequest = (method, seconds) => {
|
|
982
740
|
pendingRequestStats.push({
|
|
@@ -1062,36 +820,68 @@ function make(param) {
|
|
|
1062
820
|
Error: new Error()
|
|
1063
821
|
};
|
|
1064
822
|
}, lowercaseAddresses);
|
|
1065
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName,
|
|
823
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, param, knownHeight, partitionId, selection, param$1, retry, param$2) => {
|
|
1066
824
|
let startFetchingBatchTimeRef = Performance.now();
|
|
1067
|
-
let sourceMaxBlockInterval = getSourceMaxBlockInterval(mutSuggestedBlockIntervals, syncConfig.intervalCeiling);
|
|
1068
|
-
let suggestedBlockInterval = Primitive_int.min(Stdlib_Option.getOr(mutSuggestedBlockIntervals[partitionId], syncConfig.initialBlockInterval), sourceMaxBlockInterval);
|
|
1069
825
|
let toBlock$1 = toBlock !== undefined ? Primitive_int.min(toBlock, knownHeight) : knownHeight;
|
|
1070
|
-
let suggestedToBlock = Primitive_int.max(Primitive_int.min((fromBlock + suggestedBlockInterval | 0) - 1 | 0, toBlock$1), fromBlock);
|
|
1071
826
|
let firstBlockParentPromise = fromBlock > 0 ? LazyLoader.get(blockLoader.contents, fromBlock - 1 | 0).then(json => parseBlockInfo(json)) : Promise.resolve(undefined);
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
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
|
+
};
|
|
1080
836
|
}
|
|
1081
|
-
let
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
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
|
+
};
|
|
1088
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];
|
|
1089
884
|
let eventConfig = onEventRegistration.eventConfig;
|
|
1090
|
-
let decoded = Stdlib_Option.flatMap(Primitive_option.fromNullable(param.params), __x => __x[eventConfig.contractName]);
|
|
1091
|
-
if (decoded === undefined) {
|
|
1092
|
-
return;
|
|
1093
|
-
}
|
|
1094
|
-
let decoded$1 = Primitive_option.valFromOption(decoded);
|
|
1095
885
|
return (async () => {
|
|
1096
886
|
let match;
|
|
1097
887
|
try {
|
|
@@ -1141,9 +931,9 @@ function make(param) {
|
|
|
1141
931
|
payload: {
|
|
1142
932
|
contractName: eventConfig.contractName,
|
|
1143
933
|
eventName: eventConfig.name,
|
|
1144
|
-
params: decoded
|
|
934
|
+
params: decoded,
|
|
1145
935
|
chainId: chain,
|
|
1146
|
-
srcAddress:
|
|
936
|
+
srcAddress: log.address,
|
|
1147
937
|
logIndex: log.logIndex,
|
|
1148
938
|
transaction: Primitive_option.some(match[1]),
|
|
1149
939
|
block: Primitive_option.some(block)
|
|
@@ -1251,20 +1041,12 @@ function make(param) {
|
|
|
1251
1041
|
}
|
|
1252
1042
|
|
|
1253
1043
|
export {
|
|
1254
|
-
QueryTimout,
|
|
1255
1044
|
TransactionDataNotFound,
|
|
1256
1045
|
getKnownRawBlock,
|
|
1257
1046
|
parseBlockInfo,
|
|
1258
1047
|
getKnownRawBlockWithBackoff,
|
|
1259
1048
|
getErrorMessage,
|
|
1260
|
-
|
|
1261
|
-
getSuggestedBlockIntervalFromExn,
|
|
1262
|
-
maxSuggestedBlockIntervalKey,
|
|
1263
|
-
getSourceMaxBlockInterval,
|
|
1264
|
-
mergeAndDedupItems,
|
|
1265
|
-
getNextPage,
|
|
1266
|
-
getSelectionConfig,
|
|
1267
|
-
memoGetSelectionConfig,
|
|
1049
|
+
parseGetNextPageRetryError,
|
|
1268
1050
|
lowercaseAddressSchema,
|
|
1269
1051
|
checksumAddressSchema,
|
|
1270
1052
|
makeBlockFieldRegistry,
|