envio 3.3.0-alpha.5 → 3.3.0-alpha.7
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/package.json +6 -6
- package/src/Address.res +5 -2
- package/src/Address.res.mjs +3 -1
- package/src/BatchProcessing.res +5 -0
- package/src/BatchProcessing.res.mjs +6 -0
- package/src/ChainFetching.res +14 -25
- package/src/ChainFetching.res.mjs +19 -20
- package/src/ChainState.res +4 -4
- package/src/ChainState.res.mjs +2 -2
- package/src/ChainState.resi +1 -1
- package/src/Config.res +44 -0
- package/src/Config.res.mjs +38 -0
- package/src/ContractRegisterContext.res +2 -12
- package/src/ContractRegisterContext.res.mjs +3 -5
- package/src/CrossChainState.res +5 -3
- package/src/CrossChainState.res.mjs +5 -4
- package/src/ExitOnCaughtUp.res +10 -2
- package/src/ExitOnCaughtUp.res.mjs +10 -1
- package/src/FetchState.res +49 -52
- package/src/FetchState.res.mjs +45 -47
- package/src/IndexerState.res +4 -0
- package/src/IndexerState.res.mjs +8 -1
- package/src/IndexerState.resi +1 -0
- package/src/SimulateDeadInputTracker.res +85 -0
- package/src/SimulateDeadInputTracker.res.mjs +73 -0
- package/src/SimulateDeadInputTracker.resi +12 -0
- package/src/SimulateItems.res +29 -43
- package/src/SimulateItems.res.mjs +16 -33
- package/src/TestIndexer.res +3 -27
- package/src/TestIndexer.res.mjs +2 -9
- package/src/sources/EvmChain.res +1 -1
- package/src/sources/EvmChain.res.mjs +1 -1
- package/src/sources/HyperFuelSource.res +1 -0
- package/src/sources/HyperFuelSource.res.mjs +1 -1
- package/src/sources/HyperSync.res +4 -0
- package/src/sources/HyperSync.res.mjs +5 -4
- package/src/sources/HyperSync.resi +1 -0
- package/src/sources/HyperSyncSource.res +2 -0
- package/src/sources/HyperSyncSource.res.mjs +2 -2
- package/src/sources/RpcSource.res +287 -146
- package/src/sources/RpcSource.res.mjs +286 -247
- package/src/sources/SimulateSource.res +2 -0
- package/src/sources/SimulateSource.res.mjs +3 -2
- package/src/sources/Source.res +10 -0
- package/src/sources/SourceManager.res +7 -0
- package/src/sources/SourceManager.res.mjs +2 -1
- package/src/sources/Svm.res +1 -0
- package/src/sources/Svm.res.mjs +1 -1
- package/src/sources/SvmHyperSyncSource.res +2 -0
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
|
@@ -8,7 +8,6 @@ import * as Source from "./Source.res.mjs";
|
|
|
8
8
|
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
|
-
import * as FetchState from "../FetchState.res.mjs";
|
|
12
11
|
import * as LazyLoader from "../LazyLoader.res.mjs";
|
|
13
12
|
import * as Prometheus from "../Prometheus.res.mjs";
|
|
14
13
|
import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
@@ -77,6 +76,43 @@ async function getKnownRawBlockWithBackoff(client, sourceName, chain, blockNumbe
|
|
|
77
76
|
return Stdlib_Option.getOrThrow(result, undefined);
|
|
78
77
|
}
|
|
79
78
|
|
|
79
|
+
function getErrorMessage(exn) {
|
|
80
|
+
if (exn.RE_EXN_ID === Rpc.JsonRpcError) {
|
|
81
|
+
return exn._1.message;
|
|
82
|
+
}
|
|
83
|
+
if (exn.RE_EXN_ID !== "JsExn") {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
let message = exn._1.error.message;
|
|
88
|
+
S$RescriptSchema.assertOrThrow(message, S$RescriptSchema.string);
|
|
89
|
+
return message;
|
|
90
|
+
} catch (exn$1) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let patterns = [
|
|
96
|
+
/more than \d+ logs/i,
|
|
97
|
+
/\d+ logs returned/i,
|
|
98
|
+
/too many logs/i,
|
|
99
|
+
/query returned more than \d+ results/i,
|
|
100
|
+
/query exceeds max results/i,
|
|
101
|
+
/response size should not/i,
|
|
102
|
+
/(backend )?response too large/i,
|
|
103
|
+
/logs matched by query exceeds limit/i,
|
|
104
|
+
/block range is too wide/i
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
function isResponseTooLargeError(exn) {
|
|
108
|
+
let message = getErrorMessage(exn);
|
|
109
|
+
if (message !== undefined) {
|
|
110
|
+
return patterns.some(re => re.test(message));
|
|
111
|
+
} else {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
80
116
|
let suggestedRangeRegExp = /retry with the range (\d+)-(\d+)/;
|
|
81
117
|
|
|
82
118
|
let blockRangeLimitRegExp = /limited to a (\d+) blocks range/;
|
|
@@ -103,289 +139,288 @@ let publicNodeRegExp = /maximum block range: (\d+)/;
|
|
|
103
139
|
|
|
104
140
|
let hyperliquidRegExp = /query exceeds max block range (\d+)/;
|
|
105
141
|
|
|
106
|
-
function
|
|
107
|
-
let
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
142
|
+
function getSuggestedBlockIntervalFromExn(exn) {
|
|
143
|
+
let message = getErrorMessage(exn);
|
|
144
|
+
if (message !== undefined) {
|
|
145
|
+
let extractBlockRange = (execResult, isMaxRange) => {
|
|
146
|
+
let match = execResult.slice(1);
|
|
147
|
+
if (match.length !== 1) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
let blockRangeLimit = match[0];
|
|
151
|
+
if (blockRangeLimit === undefined) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
let blockRangeLimit$1 = Stdlib_Int.fromString(blockRangeLimit, undefined);
|
|
155
|
+
if (blockRangeLimit$1 !== undefined && blockRangeLimit$1 > 0) {
|
|
156
|
+
return [
|
|
157
|
+
blockRangeLimit$1,
|
|
158
|
+
isMaxRange
|
|
159
|
+
];
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
let execResult = suggestedRangeRegExp.exec(message);
|
|
163
|
+
if (execResult == null) {
|
|
164
|
+
let execResult$1 = blockRangeLimitRegExp.exec(message);
|
|
165
|
+
if (!(execResult$1 == null)) {
|
|
166
|
+
return extractBlockRange(execResult$1, true);
|
|
167
|
+
}
|
|
168
|
+
let execResult$2 = alchemyRangeRegExp.exec(message);
|
|
169
|
+
if (!(execResult$2 == null)) {
|
|
170
|
+
return extractBlockRange(execResult$2, true);
|
|
171
|
+
}
|
|
172
|
+
let execResult$3 = cloudflareRangeRegExp.exec(message);
|
|
173
|
+
if (!(execResult$3 == null)) {
|
|
174
|
+
return extractBlockRange(execResult$3, true);
|
|
175
|
+
}
|
|
176
|
+
let execResult$4 = thirdwebRangeRegExp.exec(message);
|
|
177
|
+
if (!(execResult$4 == null)) {
|
|
178
|
+
return extractBlockRange(execResult$4, true);
|
|
179
|
+
}
|
|
180
|
+
let execResult$5 = blockpiRangeRegExp.exec(message);
|
|
181
|
+
if (!(execResult$5 == null)) {
|
|
182
|
+
return extractBlockRange(execResult$5, true);
|
|
183
|
+
}
|
|
184
|
+
let execResult$6 = maxAllowedBlocksRegExp.exec(message);
|
|
185
|
+
if (!(execResult$6 == null)) {
|
|
186
|
+
return extractBlockRange(execResult$6, true);
|
|
187
|
+
}
|
|
188
|
+
let match = baseRangeRegExp.exec(message);
|
|
189
|
+
if (!(match == null)) {
|
|
190
|
+
return [
|
|
191
|
+
2000,
|
|
192
|
+
true
|
|
193
|
+
];
|
|
194
|
+
}
|
|
195
|
+
let execResult$7 = blastPaidRegExp.exec(message);
|
|
196
|
+
if (!(execResult$7 == null)) {
|
|
197
|
+
return extractBlockRange(execResult$7, true);
|
|
198
|
+
}
|
|
199
|
+
let match$1 = chainstackRegExp.exec(message);
|
|
200
|
+
if (!(match$1 == null)) {
|
|
201
|
+
return [
|
|
202
|
+
10000,
|
|
203
|
+
true
|
|
204
|
+
];
|
|
205
|
+
}
|
|
206
|
+
let execResult$8 = coinbaseRegExp.exec(message);
|
|
207
|
+
if (!(execResult$8 == null)) {
|
|
208
|
+
return extractBlockRange(execResult$8, true);
|
|
209
|
+
}
|
|
210
|
+
let execResult$9 = publicNodeRegExp.exec(message);
|
|
211
|
+
if (!(execResult$9 == null)) {
|
|
212
|
+
return extractBlockRange(execResult$9, true);
|
|
213
|
+
}
|
|
214
|
+
let execResult$10 = hyperliquidRegExp.exec(message);
|
|
215
|
+
if (!(execResult$10 == null)) {
|
|
216
|
+
return extractBlockRange(execResult$10, true);
|
|
217
|
+
} else {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
111
220
|
}
|
|
112
|
-
let
|
|
113
|
-
if (
|
|
221
|
+
let match$2 = execResult.slice(1);
|
|
222
|
+
if (match$2.length !== 2) {
|
|
114
223
|
return;
|
|
115
224
|
}
|
|
116
|
-
let
|
|
117
|
-
if (
|
|
118
|
-
return
|
|
119
|
-
blockRangeLimit$1,
|
|
120
|
-
isMaxRange
|
|
121
|
-
];
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
let execResult = suggestedRangeRegExp.exec(message);
|
|
125
|
-
if (execResult == null) {
|
|
126
|
-
let execResult$1 = blockRangeLimitRegExp.exec(message);
|
|
127
|
-
if (!(execResult$1 == null)) {
|
|
128
|
-
return extractBlockRange(execResult$1, true);
|
|
129
|
-
}
|
|
130
|
-
let execResult$2 = alchemyRangeRegExp.exec(message);
|
|
131
|
-
if (!(execResult$2 == null)) {
|
|
132
|
-
return extractBlockRange(execResult$2, true);
|
|
133
|
-
}
|
|
134
|
-
let execResult$3 = cloudflareRangeRegExp.exec(message);
|
|
135
|
-
if (!(execResult$3 == null)) {
|
|
136
|
-
return extractBlockRange(execResult$3, true);
|
|
137
|
-
}
|
|
138
|
-
let execResult$4 = thirdwebRangeRegExp.exec(message);
|
|
139
|
-
if (!(execResult$4 == null)) {
|
|
140
|
-
return extractBlockRange(execResult$4, true);
|
|
141
|
-
}
|
|
142
|
-
let execResult$5 = blockpiRangeRegExp.exec(message);
|
|
143
|
-
if (!(execResult$5 == null)) {
|
|
144
|
-
return extractBlockRange(execResult$5, true);
|
|
145
|
-
}
|
|
146
|
-
let execResult$6 = maxAllowedBlocksRegExp.exec(message);
|
|
147
|
-
if (!(execResult$6 == null)) {
|
|
148
|
-
return extractBlockRange(execResult$6, true);
|
|
149
|
-
}
|
|
150
|
-
let match = baseRangeRegExp.exec(message);
|
|
151
|
-
if (!(match == null)) {
|
|
152
|
-
return [
|
|
153
|
-
2000,
|
|
154
|
-
true
|
|
155
|
-
];
|
|
225
|
+
let fromBlock = match$2[0];
|
|
226
|
+
if (fromBlock === undefined) {
|
|
227
|
+
return;
|
|
156
228
|
}
|
|
157
|
-
let
|
|
158
|
-
if (
|
|
159
|
-
return
|
|
229
|
+
let toBlock = match$2[1];
|
|
230
|
+
if (toBlock === undefined) {
|
|
231
|
+
return;
|
|
160
232
|
}
|
|
161
|
-
let match$
|
|
162
|
-
|
|
233
|
+
let match$3 = Stdlib_Int.fromString(fromBlock, undefined);
|
|
234
|
+
let match$4 = Stdlib_Int.fromString(toBlock, undefined);
|
|
235
|
+
if (match$3 !== undefined && match$4 !== undefined && match$4 >= match$3) {
|
|
163
236
|
return [
|
|
164
|
-
|
|
165
|
-
|
|
237
|
+
(match$4 - match$3 | 0) + 1 | 0,
|
|
238
|
+
false
|
|
166
239
|
];
|
|
167
|
-
}
|
|
168
|
-
let execResult$8 = coinbaseRegExp.exec(message);
|
|
169
|
-
if (!(execResult$8 == null)) {
|
|
170
|
-
return extractBlockRange(execResult$8, true);
|
|
171
|
-
}
|
|
172
|
-
let execResult$9 = publicNodeRegExp.exec(message);
|
|
173
|
-
if (!(execResult$9 == null)) {
|
|
174
|
-
return extractBlockRange(execResult$9, true);
|
|
175
|
-
}
|
|
176
|
-
let execResult$10 = hyperliquidRegExp.exec(message);
|
|
177
|
-
if (!(execResult$10 == null)) {
|
|
178
|
-
return extractBlockRange(execResult$10, true);
|
|
179
240
|
} else {
|
|
180
241
|
return;
|
|
181
242
|
}
|
|
182
243
|
}
|
|
183
|
-
let match$2 = execResult.slice(1);
|
|
184
|
-
if (match$2.length !== 2) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
let fromBlock = match$2[0];
|
|
188
|
-
if (fromBlock === undefined) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
let toBlock = match$2[1];
|
|
192
|
-
if (toBlock === undefined) {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
let match$3 = Stdlib_Int.fromString(fromBlock, undefined);
|
|
196
|
-
let match$4 = Stdlib_Int.fromString(toBlock, undefined);
|
|
197
|
-
if (match$3 !== undefined && match$4 !== undefined && match$4 >= match$3) {
|
|
198
|
-
return [
|
|
199
|
-
(match$4 - match$3 | 0) + 1 | 0,
|
|
200
|
-
false
|
|
201
|
-
];
|
|
202
|
-
}
|
|
203
244
|
}
|
|
204
245
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
if (exn.RE_EXN_ID !== "JsExn") {
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
try {
|
|
213
|
-
let message = exn._1.error.message;
|
|
214
|
-
S$RescriptSchema.assertOrThrow(message, S$RescriptSchema.string);
|
|
215
|
-
return parseMessageForBlockRange(message);
|
|
216
|
-
} catch (exn$1) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
246
|
+
let maxSuggestedBlockIntervalKey = "max";
|
|
247
|
+
|
|
248
|
+
function getSourceMaxBlockInterval(mutSuggestedBlockIntervals, intervalCeiling) {
|
|
249
|
+
return Stdlib_Option.getOr(mutSuggestedBlockIntervals[maxSuggestedBlockIntervalKey], intervalCeiling);
|
|
219
250
|
}
|
|
220
251
|
|
|
221
|
-
|
|
252
|
+
function mergeAndDedupItems(itemsPerSelection) {
|
|
253
|
+
let seen = new Set();
|
|
254
|
+
let merged = [];
|
|
255
|
+
itemsPerSelection.forEach(items => {
|
|
256
|
+
items.forEach(item => {
|
|
257
|
+
let key = item.log.blockNumber.toString() + `-` + item.log.logIndex.toString();
|
|
258
|
+
if (!seen.has(key)) {
|
|
259
|
+
seen.add(key);
|
|
260
|
+
merged.push(item);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
return merged;
|
|
266
|
+
}
|
|
222
267
|
|
|
223
|
-
function getNextPage(fromBlock, toBlock,
|
|
268
|
+
function getNextPage(fromBlock, toBlock, logSelections, loadBlock, sc, rpcClient, mutSuggestedBlockIntervals, partitionId, sourceName, chainId) {
|
|
224
269
|
let queryTimoutPromise = Time.resolvePromiseAfterDelay(sc.queryTimeoutMillis).then(() => Promise.reject({
|
|
225
270
|
RE_EXN_ID: QueryTimout,
|
|
226
271
|
_1: `Query took longer than ` + (sc.queryTimeoutMillis / 1000 | 0).toString() + ` seconds`
|
|
227
272
|
}));
|
|
228
273
|
let latestFetchedBlockPromise = loadBlock(toBlock);
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
274
|
+
let queryLogs = param => {
|
|
275
|
+
Prometheus.SourceRequestCount.increment(sourceName, chainId, "eth_getLogs");
|
|
276
|
+
return rpcClient.getLogs({
|
|
277
|
+
fromBlock: fromBlock,
|
|
278
|
+
toBlock: toBlock,
|
|
279
|
+
addresses: param.addresses,
|
|
280
|
+
topics: param.topicQuery.map(filter => {
|
|
281
|
+
if (filter === null) {
|
|
282
|
+
return null;
|
|
283
|
+
} else if (typeof filter === "string") {
|
|
284
|
+
return [filter];
|
|
285
|
+
} else {
|
|
286
|
+
return filter;
|
|
287
|
+
}
|
|
288
|
+
})
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
let len = logSelections.length;
|
|
292
|
+
let logsPromise;
|
|
293
|
+
if (len !== 1) {
|
|
294
|
+
logsPromise = len !== 0 ? Promise.all(logSelections.map(queryLogs)).then(async itemsPerSelection => ({
|
|
295
|
+
items: mergeAndDedupItems(itemsPerSelection),
|
|
296
|
+
latestFetchedBlockInfo: await latestFetchedBlockPromise
|
|
297
|
+
})) : latestFetchedBlockPromise.then(latestFetchedBlockInfo => ({
|
|
298
|
+
items: [],
|
|
299
|
+
latestFetchedBlockInfo: latestFetchedBlockInfo
|
|
300
|
+
}));
|
|
301
|
+
} else {
|
|
302
|
+
let logSelection = logSelections[0];
|
|
303
|
+
logsPromise = queryLogs(logSelection).then(async items => ({
|
|
304
|
+
items: items,
|
|
305
|
+
latestFetchedBlockInfo: await latestFetchedBlockPromise
|
|
306
|
+
}));
|
|
307
|
+
}
|
|
247
308
|
return Stdlib_Promise.$$catch(Promise.race([
|
|
248
309
|
queryTimoutPromise,
|
|
249
310
|
logsPromise
|
|
250
311
|
]), err => {
|
|
251
|
-
let
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
mutSuggestedBlockIntervals[match[1] ? maxSuggestedBlockIntervalKey : partitionId] = nextBlockIntervalTry;
|
|
312
|
+
let executedBlockInterval = (toBlock - fromBlock | 0) + 1 | 0;
|
|
313
|
+
let shrunkBlockInterval = Primitive_int.max(1, executedBlockInterval * sc.backoffMultiplicative | 0);
|
|
314
|
+
let throwFailedGettingItems = retry => {
|
|
255
315
|
throw {
|
|
256
316
|
RE_EXN_ID: Source.GetItemsError,
|
|
257
317
|
_1: {
|
|
258
318
|
TAG: "FailedGettingItems",
|
|
259
319
|
exn: err,
|
|
260
320
|
attemptedToBlock: toBlock,
|
|
261
|
-
retry:
|
|
262
|
-
TAG: "WithSuggestedToBlock",
|
|
263
|
-
toBlock: (fromBlock + nextBlockIntervalTry | 0) - 1 | 0
|
|
264
|
-
}
|
|
321
|
+
retry: retry
|
|
265
322
|
},
|
|
266
323
|
Error: new Error()
|
|
267
324
|
};
|
|
268
|
-
}
|
|
269
|
-
let
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
325
|
+
};
|
|
326
|
+
let throwResize = interval => throwFailedGettingItems({
|
|
327
|
+
TAG: "WithSuggestedToBlock",
|
|
328
|
+
toBlock: (fromBlock + interval | 0) - 1 | 0
|
|
329
|
+
});
|
|
330
|
+
let match = getSuggestedBlockIntervalFromExn(err);
|
|
331
|
+
if (match === undefined) {
|
|
332
|
+
if (executedBlockInterval > 1 && isResponseTooLargeError(err)) {
|
|
333
|
+
mutSuggestedBlockIntervals[partitionId] = shrunkBlockInterval;
|
|
334
|
+
return throwResize(shrunkBlockInterval);
|
|
335
|
+
} else {
|
|
336
|
+
mutSuggestedBlockIntervals[partitionId] = shrunkBlockInterval;
|
|
337
|
+
return throwFailedGettingItems({
|
|
279
338
|
TAG: "WithBackoff",
|
|
280
339
|
message: `Failed getting data for the block range. Will try smaller block range for the next attempt.`,
|
|
281
340
|
backoffMillis: sc.backoffMillis
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
let interval = match[0];
|
|
345
|
+
if (match[1]) {
|
|
346
|
+
let capped = Primitive_int.min(getSourceMaxBlockInterval(mutSuggestedBlockIntervals, sc.intervalCeiling), interval);
|
|
347
|
+
mutSuggestedBlockIntervals[maxSuggestedBlockIntervalKey] = capped;
|
|
348
|
+
return throwResize(capped);
|
|
349
|
+
}
|
|
350
|
+
mutSuggestedBlockIntervals[partitionId] = interval;
|
|
351
|
+
return throwResize(interval);
|
|
286
352
|
});
|
|
287
353
|
}
|
|
288
354
|
|
|
289
355
|
function getSelectionConfig(selection, chain) {
|
|
290
|
-
let
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
let
|
|
302
|
-
let
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (len$1 !== 1) {
|
|
316
|
-
if (len$1 !== 0) {
|
|
317
|
-
throw {
|
|
318
|
-
RE_EXN_ID: Source.GetItemsError,
|
|
319
|
-
_1: {
|
|
320
|
-
TAG: "UnsupportedSelection",
|
|
321
|
-
message: "RPC data-source currently supports event filters only when there's a single wildcard event. Please, create a GitHub issue if it's a blocker for you."
|
|
322
|
-
},
|
|
323
|
-
Error: new Error()
|
|
324
|
-
};
|
|
356
|
+
let evmEventConfigs = selection.eventConfigs;
|
|
357
|
+
if (Utils.$$Array.isEmpty(evmEventConfigs)) {
|
|
358
|
+
throw {
|
|
359
|
+
RE_EXN_ID: Source.GetItemsError,
|
|
360
|
+
_1: {
|
|
361
|
+
TAG: "UnsupportedSelection",
|
|
362
|
+
message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team."
|
|
363
|
+
},
|
|
364
|
+
Error: new Error()
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
let noAddressTopicSelections = [];
|
|
368
|
+
let staticByContract = {};
|
|
369
|
+
let dynamicByContract = {};
|
|
370
|
+
let dynamicWildcardByContract = {};
|
|
371
|
+
let contractNames = new Set();
|
|
372
|
+
evmEventConfigs.forEach(param => {
|
|
373
|
+
let contractName = param.contractName;
|
|
374
|
+
let eventFilters = param.getEventFiltersOrThrow(chain);
|
|
375
|
+
if (param.dependsOnAddresses) {
|
|
376
|
+
contractNames.add(contractName);
|
|
377
|
+
if (eventFilters.TAG === "Static") {
|
|
378
|
+
return Utils.Dict.pushMany(staticByContract, contractName, eventFilters._0);
|
|
379
|
+
} else {
|
|
380
|
+
return Utils.Dict.push(param.isWildcard ? dynamicWildcardByContract : dynamicByContract, contractName, eventFilters._0);
|
|
325
381
|
}
|
|
326
|
-
throw {
|
|
327
|
-
RE_EXN_ID: Source.GetItemsError,
|
|
328
|
-
_1: {
|
|
329
|
-
TAG: "UnsupportedSelection",
|
|
330
|
-
message: "Invalid events configuration for the partition. Nothing to fetch. Please, report to the Envio team."
|
|
331
|
-
},
|
|
332
|
-
Error: new Error()
|
|
333
|
-
};
|
|
334
382
|
}
|
|
335
|
-
let
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
383
|
+
let tmp;
|
|
384
|
+
tmp = eventFilters.TAG === "Static" ? eventFilters._0 : eventFilters._0([]);
|
|
385
|
+
noAddressTopicSelections.push(...tmp);
|
|
386
|
+
});
|
|
387
|
+
let toLogSelections = (addresses, topicSelections) => LogSelection.compressTopicSelections(topicSelections).map(topicSelection => ({
|
|
388
|
+
addresses: addresses,
|
|
389
|
+
topicQuery: Rpc.GetLogs.mapTopicQuery(topicSelection)
|
|
390
|
+
}));
|
|
391
|
+
let noAddressLogSelections = toLogSelections(undefined, noAddressTopicSelections);
|
|
392
|
+
let getLogSelectionsOrThrow = contractNames.size === 0 ? param => noAddressLogSelections : addressesByContractName => {
|
|
393
|
+
let logSelections = noAddressLogSelections.slice();
|
|
394
|
+
contractNames.forEach(contractName => {
|
|
395
|
+
let addresses = addressesByContractName[contractName];
|
|
396
|
+
if (addresses === undefined) {
|
|
397
|
+
return;
|
|
350
398
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
message: "RPC data-source currently supports event filters only when there's a single wildcard event. Please, create a GitHub issue if it's a blocker for you."
|
|
374
|
-
},
|
|
375
|
-
Error: new Error()
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
let topicQuery = Rpc.GetLogs.mapTopicQuery(topicSelection);
|
|
379
|
-
getLogSelectionOrThrow = addressesByContractName => {
|
|
380
|
-
let addresses = FetchState.addressesByContractNameGetAll(addressesByContractName);
|
|
381
|
-
return {
|
|
382
|
-
addresses: addresses.length !== 0 ? addresses : undefined,
|
|
383
|
-
topicQuery: topicQuery
|
|
384
|
-
};
|
|
399
|
+
if (addresses.length === 0) {
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
let addressedTopicSelections = [];
|
|
403
|
+
let s = staticByContract[contractName];
|
|
404
|
+
if (s !== undefined) {
|
|
405
|
+
addressedTopicSelections.push(...s);
|
|
406
|
+
}
|
|
407
|
+
let fns = dynamicByContract[contractName];
|
|
408
|
+
if (fns !== undefined) {
|
|
409
|
+
fns.forEach(fn => {
|
|
410
|
+
addressedTopicSelections.push(...fn(addresses));
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
logSelections.push(...toLogSelections(addresses, addressedTopicSelections));
|
|
414
|
+
let fns$1 = dynamicWildcardByContract[contractName];
|
|
415
|
+
if (fns$1 !== undefined) {
|
|
416
|
+
logSelections.push(...toLogSelections(undefined, fns$1.flatMap(fn => fn(addresses))));
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
});
|
|
420
|
+
return logSelections;
|
|
385
421
|
};
|
|
386
|
-
}
|
|
387
422
|
return {
|
|
388
|
-
|
|
423
|
+
getLogSelectionsOrThrow: getLogSelectionsOrThrow
|
|
389
424
|
};
|
|
390
425
|
}
|
|
391
426
|
|
|
@@ -1005,21 +1040,21 @@ function make(param) {
|
|
|
1005
1040
|
Error: new Error()
|
|
1006
1041
|
};
|
|
1007
1042
|
}, lowercaseAddresses);
|
|
1008
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, partitionId, selection, retry, param) => {
|
|
1043
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, partitionId, selection, param, retry, param$1) => {
|
|
1009
1044
|
let startFetchingBatchTimeRef = Performance.now();
|
|
1010
|
-
let
|
|
1011
|
-
let suggestedBlockInterval =
|
|
1045
|
+
let sourceMaxBlockInterval = getSourceMaxBlockInterval(mutSuggestedBlockIntervals, syncConfig.intervalCeiling);
|
|
1046
|
+
let suggestedBlockInterval = Primitive_int.min(Stdlib_Option.getOr(mutSuggestedBlockIntervals[partitionId], syncConfig.initialBlockInterval), sourceMaxBlockInterval);
|
|
1012
1047
|
let toBlock$1 = toBlock !== undefined ? Primitive_int.min(toBlock, knownHeight) : knownHeight;
|
|
1013
1048
|
let suggestedToBlock = Primitive_int.max(Primitive_int.min((fromBlock + suggestedBlockInterval | 0) - 1 | 0, toBlock$1), fromBlock);
|
|
1014
1049
|
let firstBlockParentPromise = fromBlock > 0 ? LazyLoader.get(blockLoader.contents, fromBlock - 1 | 0).then(json => parseBlockInfo(json)) : Promise.resolve(undefined);
|
|
1015
1050
|
let match = getSelectionConfig(selection);
|
|
1016
|
-
let
|
|
1017
|
-
let match$
|
|
1018
|
-
let latestFetchedBlockInfo = match$
|
|
1019
|
-
let items = match$
|
|
1051
|
+
let logSelections = match.getLogSelectionsOrThrow(addressesByContractName);
|
|
1052
|
+
let match$1 = await getNextPage(fromBlock, suggestedToBlock, logSelections, blockNumber => LazyLoader.get(blockLoader.contents, blockNumber).then(parseBlockInfo), syncConfig, rpcClient, mutSuggestedBlockIntervals, partitionId, name, chain);
|
|
1053
|
+
let latestFetchedBlockInfo = match$1.latestFetchedBlockInfo;
|
|
1054
|
+
let items = match$1.items;
|
|
1020
1055
|
let executedBlockInterval = (suggestedToBlock - fromBlock | 0) + 1 | 0;
|
|
1021
|
-
if (executedBlockInterval >= suggestedBlockInterval
|
|
1022
|
-
mutSuggestedBlockIntervals[partitionId] = Primitive_int.min(executedBlockInterval + syncConfig.accelerationAdditive | 0,
|
|
1056
|
+
if (executedBlockInterval >= suggestedBlockInterval) {
|
|
1057
|
+
mutSuggestedBlockIntervals[partitionId] = Primitive_int.min(executedBlockInterval + syncConfig.accelerationAdditive | 0, sourceMaxBlockInterval);
|
|
1023
1058
|
}
|
|
1024
1059
|
let parsedQueueItems = await Promise.all(Stdlib_Array.filterMap(items, param => {
|
|
1025
1060
|
let log = param.log;
|
|
@@ -1190,8 +1225,12 @@ export {
|
|
|
1190
1225
|
getKnownRawBlock,
|
|
1191
1226
|
parseBlockInfo,
|
|
1192
1227
|
getKnownRawBlockWithBackoff,
|
|
1228
|
+
getErrorMessage,
|
|
1229
|
+
isResponseTooLargeError,
|
|
1193
1230
|
getSuggestedBlockIntervalFromExn,
|
|
1194
1231
|
maxSuggestedBlockIntervalKey,
|
|
1232
|
+
getSourceMaxBlockInterval,
|
|
1233
|
+
mergeAndDedupItems,
|
|
1195
1234
|
getNextPage,
|
|
1196
1235
|
getSelectionConfig,
|
|
1197
1236
|
memoGetSelectionConfig,
|
|
@@ -6,6 +6,7 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
|
|
|
6
6
|
|
|
7
7
|
{
|
|
8
8
|
name: "SimulateSource",
|
|
9
|
+
simulateItems: items,
|
|
9
10
|
sourceFor: Sync,
|
|
10
11
|
chain,
|
|
11
12
|
poweredByHyperSync: false,
|
|
@@ -25,6 +26,7 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
|
|
|
25
26
|
~knownHeight as _,
|
|
26
27
|
~partitionId as _,
|
|
27
28
|
~selection as _,
|
|
29
|
+
~itemsTarget as _,
|
|
28
30
|
~retry as _,
|
|
29
31
|
~logger as _,
|
|
30
32
|
) => {
|
|
@@ -17,7 +17,7 @@ function make(items, endBlock, chain) {
|
|
|
17
17
|
_0: []
|
|
18
18
|
}),
|
|
19
19
|
getHeightOrThrow: () => Promise.resolve(Primitive_int.max(endBlock, 1)),
|
|
20
|
-
getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8) => {
|
|
20
|
+
getItemsOrThrow: (param, param$1, param$2, param$3, param$4, param$5, param$6, param$7, param$8, param$9) => {
|
|
21
21
|
let result = delivered.contents ? [] : (delivered.contents = true, items);
|
|
22
22
|
let reportedHeight = Primitive_int.max(endBlock, 1);
|
|
23
23
|
return Promise.resolve({
|
|
@@ -32,7 +32,8 @@ function make(items, endBlock, chain) {
|
|
|
32
32
|
"total time elapsed (s)": 0
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
|
-
}
|
|
35
|
+
},
|
|
36
|
+
simulateItems: items
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
|