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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Utils from "./Utils.res.mjs";
|
|
4
|
+
import * as ChainMap from "./ChainMap.res.mjs";
|
|
5
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
6
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
|
|
8
|
+
function itemKey(item) {
|
|
9
|
+
if (item.kind === 0) {
|
|
10
|
+
return item.chain.toString() + `:` + item.blockNumber.toString() + `:` + item.logIndex.toString();
|
|
11
|
+
} else {
|
|
12
|
+
return "";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function makeFromConfig(config) {
|
|
17
|
+
let entries = ChainMap.values(config.chainMap).flatMap(chainConfig => {
|
|
18
|
+
let sources = chainConfig.sourceConfig;
|
|
19
|
+
if (sources.TAG === "CustomSources") {
|
|
20
|
+
return sources._0.flatMap(source => Stdlib_Option.getOr(source.simulateItems, []).map((item, index) => ({
|
|
21
|
+
chainId: chainConfig.id,
|
|
22
|
+
index: index,
|
|
23
|
+
key: itemKey(item)
|
|
24
|
+
})));
|
|
25
|
+
} else {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
if (entries.length !== 0) {
|
|
30
|
+
return {
|
|
31
|
+
unprocessed: entries
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function recordProcessed(t, batch) {
|
|
37
|
+
let processedKeys = new Set(batch.items.map(itemKey));
|
|
38
|
+
t.unprocessed = t.unprocessed.filter(entry => !processedKeys.has(entry.key));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function unroutedByChain(t) {
|
|
42
|
+
let indicesByChain = {};
|
|
43
|
+
let chainOrder = [];
|
|
44
|
+
t.unprocessed.forEach(entry => {
|
|
45
|
+
let key = entry.chainId.toString();
|
|
46
|
+
if (Stdlib_Option.isNone(indicesByChain[key])) {
|
|
47
|
+
chainOrder.push(entry.chainId);
|
|
48
|
+
}
|
|
49
|
+
Utils.Dict.push(indicesByChain, key, entry.index);
|
|
50
|
+
});
|
|
51
|
+
return chainOrder.map(chainId => [
|
|
52
|
+
chainId,
|
|
53
|
+
indicesByChain[chainId.toString()]
|
|
54
|
+
]);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function failureMessage(t) {
|
|
58
|
+
let byChain = unroutedByChain(t);
|
|
59
|
+
if (byChain.length === 0) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let count = Stdlib_Array.reduce(byChain, 0, (acc, param) => acc + param[1].length | 0);
|
|
63
|
+
let itemWord = count === 1 ? "item" : "items";
|
|
64
|
+
let lines = byChain.map(param => ` - chain ` + param[0].toString() + `: ` + param[1].map(index => index.toString()).join(", ")).join("\n");
|
|
65
|
+
return `simulate: ` + count.toString() + ` ` + itemWord + ` you passed to simulate never reached a handler, so nothing ran for them. Each was filtered out before the handler — usually a non-wildcard srcAddress that isn't indexed for the contract, or a where/block filter that excluded the event. Unrouted items, by index in each chain's simulate array:\n` + lines;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {
|
|
69
|
+
makeFromConfig,
|
|
70
|
+
recordProcessed,
|
|
71
|
+
failureMessage,
|
|
72
|
+
}
|
|
73
|
+
/* Utils Not a pure module */
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type t
|
|
2
|
+
|
|
3
|
+
// Builds a tracker from the run's config, seeded with every item each simulate
|
|
4
|
+
// source provided. None when no chain has a simulate source.
|
|
5
|
+
let makeFromConfig: Config.t => option<t>
|
|
6
|
+
|
|
7
|
+
// Drop the batch's items from the not-yet-routed set, matched by event coordinate.
|
|
8
|
+
let recordProcessed: (t, ~batch: Batch.t) => unit
|
|
9
|
+
|
|
10
|
+
// The error to fail the run with when items never reached a handler, listing them
|
|
11
|
+
// by chain and index within that chain's `simulate` array. None when all routed.
|
|
12
|
+
let failureMessage: t => option<string>
|
package/src/SimulateItems.res
CHANGED
|
@@ -216,9 +216,13 @@ let deriveSrcAddress = (
|
|
|
216
216
|
~providedSrcAddress: option<Address.t>,
|
|
217
217
|
~eventConfig: Internal.eventConfig,
|
|
218
218
|
~chainConfig: Config.chain,
|
|
219
|
+
~config: Config.t,
|
|
219
220
|
): Address.t => {
|
|
220
221
|
switch providedSrcAddress {
|
|
221
|
-
|
|
222
|
+
// Canonicalize to the configured casing; the fallback addresses below already
|
|
223
|
+
// come from the parsed config and need no normalization. Relaxed (not
|
|
224
|
+
// Config.normalizeUserAddress) so test placeholders like "0xfoo" are allowed.
|
|
225
|
+
| Some(addr) => config->Config.normalizeSimulateAddress(addr)
|
|
222
226
|
| None =>
|
|
223
227
|
if eventConfig.isWildcard {
|
|
224
228
|
dummySrcAddress
|
|
@@ -231,46 +235,6 @@ let deriveSrcAddress = (
|
|
|
231
235
|
}
|
|
232
236
|
}
|
|
233
237
|
|
|
234
|
-
// A non-wildcard event is gated by `clientAddressFilter` on srcAddress ownership,
|
|
235
|
-
// so a simulate item whose srcAddress isn't indexed on this chain would be
|
|
236
|
-
// silently dropped (handler never runs). Fail loudly instead.
|
|
237
|
-
//
|
|
238
|
-
// `config` must already have handler registrations applied, otherwise an event
|
|
239
|
-
// made wildcard purely through `indexer.onEvent({ wildcard: true })` reads back
|
|
240
|
-
// as non-wildcard and gets wrongly rejected.
|
|
241
|
-
let validateSrcAddresses = (
|
|
242
|
-
~simulateItems: array<JSON.t>,
|
|
243
|
-
~config: Config.t,
|
|
244
|
-
~chainConfig: Config.chain,
|
|
245
|
-
~indexingAddresses: array<Internal.indexingAddress>,
|
|
246
|
-
): unit => {
|
|
247
|
-
let known = Utils.Set.make()
|
|
248
|
-
indexingAddresses->Array.forEach(ia => known->Utils.Set.add(ia.address->Address.toString)->ignore)
|
|
249
|
-
simulateItems->Array.forEach(rawJson => {
|
|
250
|
-
let raw = rawJson->(Utils.magic: JSON.t => rawSimulateItem)
|
|
251
|
-
switch (raw->getContract, raw->getEvent) {
|
|
252
|
-
| (Some(contractName), Some(eventName)) =>
|
|
253
|
-
switch findEventConfig(~config, ~contractName, ~eventName) {
|
|
254
|
-
| Some(eventConfig) if !eventConfig.isWildcard =>
|
|
255
|
-
let item = rawJson->(Utils.magic: JSON.t => Envio.evmSimulateItem)
|
|
256
|
-
let srcAddress = deriveSrcAddress(
|
|
257
|
-
~providedSrcAddress=item.srcAddress,
|
|
258
|
-
~eventConfig,
|
|
259
|
-
~chainConfig,
|
|
260
|
-
)
|
|
261
|
-
if !(known->Utils.Set.has(srcAddress->Address.toString)) {
|
|
262
|
-
JsError.throwWithMessage(
|
|
263
|
-
`simulate: ${contractName}.${eventName} resolved to address ${srcAddress->Address.toString}, which isn't indexed on chain ${chainConfig.id->Int.toString}. ` ++
|
|
264
|
-
`Provide a "srcAddress" configured or registered for ${contractName} on this chain, or use a wildcard event.`,
|
|
265
|
-
)
|
|
266
|
-
}
|
|
267
|
-
| _ => ()
|
|
268
|
-
}
|
|
269
|
-
| _ => ()
|
|
270
|
-
}
|
|
271
|
-
})
|
|
272
|
-
}
|
|
273
|
-
|
|
274
238
|
let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Config.chain): array<
|
|
275
239
|
Internal.item,
|
|
276
240
|
> => {
|
|
@@ -281,8 +245,11 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
|
|
|
281
245
|
let currentLogIndex = ref(0)
|
|
282
246
|
|
|
283
247
|
let items = []
|
|
248
|
+
// Coordinate "block:logIndex" -> the index of the first item that claimed it,
|
|
249
|
+
// used to reject two items resolving to the same (block, logIndex).
|
|
250
|
+
let seenCoordinates = Dict.make()
|
|
284
251
|
|
|
285
|
-
simulateItems->Array.
|
|
252
|
+
simulateItems->Array.forEachWithIndex((rawJson, itemIndex) => {
|
|
286
253
|
let raw = rawJson->(Utils.magic: JSON.t => rawSimulateItem)
|
|
287
254
|
|
|
288
255
|
switch (raw->getContract, raw->getEvent) {
|
|
@@ -306,8 +273,14 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
|
|
|
306
273
|
}
|
|
307
274
|
let params = paramsJson->S.convertOrThrow(eventConfig.simulateParamsSchema)
|
|
308
275
|
|
|
276
|
+
// An explicit logIndex advances the auto-increment counter past itself, so a
|
|
277
|
+
// later item that omits logIndex picks up after it instead of colliding.
|
|
309
278
|
let logIndex = switch item.logIndex {
|
|
310
|
-
| Some(li) =>
|
|
279
|
+
| Some(li) =>
|
|
280
|
+
if li >= currentLogIndex.contents {
|
|
281
|
+
currentLogIndex := li + 1
|
|
282
|
+
}
|
|
283
|
+
li
|
|
311
284
|
| None =>
|
|
312
285
|
let li = currentLogIndex.contents
|
|
313
286
|
currentLogIndex := li + 1
|
|
@@ -318,6 +291,7 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
|
|
|
318
291
|
~providedSrcAddress=item.srcAddress,
|
|
319
292
|
~eventConfig,
|
|
320
293
|
~chainConfig,
|
|
294
|
+
~config,
|
|
321
295
|
)
|
|
322
296
|
|
|
323
297
|
let rawItem = rawJson->(Utils.magic: JSON.t => {..})
|
|
@@ -345,6 +319,18 @@ let parse = (~simulateItems: array<JSON.t>, ~config: Config.t, ~chainConfig: Con
|
|
|
345
319
|
// Update currentBlock for subsequent items
|
|
346
320
|
currentBlock := blockNumber
|
|
347
321
|
|
|
322
|
+
// A simulate item must land on a distinct (block, logIndex): event ordering
|
|
323
|
+
// and the dead-input tracker both key on it. Catch explicit duplicates and
|
|
324
|
+
// explicit-vs-auto-increment collisions here, naming both offending indices.
|
|
325
|
+
let coordinate = `${blockNumber->Int.toString}:${logIndex->Int.toString}`
|
|
326
|
+
switch seenCoordinates->Dict.get(coordinate) {
|
|
327
|
+
| Some(firstIndex) =>
|
|
328
|
+
JsError.throwWithMessage(
|
|
329
|
+
`simulate: items at index ${firstIndex->Int.toString} and ${itemIndex->Int.toString} on chain ${chainId->Int.toString} both resolve to block ${blockNumber->Int.toString}, logIndex ${logIndex->Int.toString}. Give each item a distinct logIndex (or omit logIndex so they auto-increment).`,
|
|
330
|
+
)
|
|
331
|
+
| None => seenCoordinates->Dict.set(coordinate, itemIndex)
|
|
332
|
+
}
|
|
333
|
+
|
|
348
334
|
items
|
|
349
335
|
->Array.push(
|
|
350
336
|
Internal.Event({
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
+
import * as Config from "./Config.res.mjs";
|
|
3
4
|
import * as Address from "./Address.res.mjs";
|
|
4
5
|
import * as ChainMap from "./ChainMap.res.mjs";
|
|
5
6
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
@@ -150,9 +151,9 @@ function firstContractAddress(chainConfig, contractName) {
|
|
|
150
151
|
return found.contents;
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig) {
|
|
154
|
+
function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig, config) {
|
|
154
155
|
if (providedSrcAddress !== undefined) {
|
|
155
|
-
return Primitive_option.valFromOption(providedSrcAddress);
|
|
156
|
+
return Config.normalizeSimulateAddress(config, Primitive_option.valFromOption(providedSrcAddress));
|
|
156
157
|
}
|
|
157
158
|
if (eventConfig.isWildcard) {
|
|
158
159
|
return dummySrcAddress;
|
|
@@ -165,34 +166,6 @@ function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig) {
|
|
|
165
166
|
}
|
|
166
167
|
}
|
|
167
168
|
|
|
168
|
-
function validateSrcAddresses(simulateItems, config, chainConfig, indexingAddresses) {
|
|
169
|
-
let known = new Set();
|
|
170
|
-
indexingAddresses.forEach(ia => {
|
|
171
|
-
known.add(ia.address);
|
|
172
|
-
});
|
|
173
|
-
simulateItems.forEach(rawJson => {
|
|
174
|
-
let match = rawJson.contract;
|
|
175
|
-
let match$1 = rawJson.event;
|
|
176
|
-
if (match === undefined) {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
if (match$1 === undefined) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
let eventConfig = findEventConfig(config, match, match$1);
|
|
183
|
-
if (eventConfig === undefined) {
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
if (eventConfig.isWildcard) {
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig);
|
|
190
|
-
if (!known.has(srcAddress)) {
|
|
191
|
-
return Stdlib_JsError.throwWithMessage(`simulate: ` + match + `.` + match$1 + ` resolved to address ` + srcAddress + `, which isn't indexed on chain ` + chainConfig.id.toString() + `. ` + (`Provide a "srcAddress" configured or registered for ` + match + ` on this chain, or use a wildcard event.`));
|
|
192
|
-
}
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
|
|
196
169
|
function parse(simulateItems, config, chainConfig) {
|
|
197
170
|
let chain = ChainMap.Chain.makeUnsafe(chainConfig.id);
|
|
198
171
|
let chainId = chainConfig.id;
|
|
@@ -204,7 +177,8 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
204
177
|
contents: 0
|
|
205
178
|
};
|
|
206
179
|
let items = [];
|
|
207
|
-
|
|
180
|
+
let seenCoordinates = {};
|
|
181
|
+
simulateItems.forEach((rawJson, itemIndex) => {
|
|
208
182
|
let match = rawJson.contract;
|
|
209
183
|
let match$1 = rawJson.event;
|
|
210
184
|
if (match === undefined) {
|
|
@@ -221,13 +195,16 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
221
195
|
let li = rawJson.logIndex;
|
|
222
196
|
let logIndex;
|
|
223
197
|
if (li !== undefined) {
|
|
198
|
+
if (li >= currentLogIndex.contents) {
|
|
199
|
+
currentLogIndex.contents = li + 1 | 0;
|
|
200
|
+
}
|
|
224
201
|
logIndex = li;
|
|
225
202
|
} else {
|
|
226
203
|
let li$1 = currentLogIndex.contents;
|
|
227
204
|
currentLogIndex.contents = li$1 + 1 | 0;
|
|
228
205
|
logIndex = li$1;
|
|
229
206
|
}
|
|
230
|
-
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig);
|
|
207
|
+
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig, config);
|
|
231
208
|
let blockJson = rawJson.block;
|
|
232
209
|
let blockJson$1 = (blockJson == null) ? undefined : Primitive_option.some(blockJson);
|
|
233
210
|
let transactionJson = rawJson.transaction;
|
|
@@ -272,6 +249,13 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
272
249
|
break;
|
|
273
250
|
}
|
|
274
251
|
currentBlock.contents = blockNumber;
|
|
252
|
+
let coordinate = blockNumber.toString() + `:` + logIndex.toString();
|
|
253
|
+
let firstIndex = seenCoordinates[coordinate];
|
|
254
|
+
if (firstIndex !== undefined) {
|
|
255
|
+
Stdlib_JsError.throwWithMessage(`simulate: items at index ` + firstIndex.toString() + ` and ` + itemIndex.toString() + ` on chain ` + chainId.toString() + ` both resolve to block ` + blockNumber.toString() + `, logIndex ` + logIndex.toString() + `. Give each item a distinct logIndex (or omit logIndex so they auto-increment).`);
|
|
256
|
+
} else {
|
|
257
|
+
seenCoordinates[coordinate] = itemIndex;
|
|
258
|
+
}
|
|
275
259
|
items.push({
|
|
276
260
|
kind: 0,
|
|
277
261
|
eventConfig: eventConfig,
|
|
@@ -360,7 +344,6 @@ export {
|
|
|
360
344
|
dummySrcAddress,
|
|
361
345
|
firstContractAddress,
|
|
362
346
|
deriveSrcAddress,
|
|
363
|
-
validateSrcAddresses,
|
|
364
347
|
parse,
|
|
365
348
|
patchConfig,
|
|
366
349
|
}
|
package/src/TestIndexer.res
CHANGED
|
@@ -667,11 +667,7 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
|
|
|
667
667
|
Int.compare(aId, bId)
|
|
668
668
|
})
|
|
669
669
|
|
|
670
|
-
// Parse and validate the block ranges upfront before starting any
|
|
671
|
-
// workers. srcAddress validation can't run here: it depends on which
|
|
672
|
-
// events are wildcard, and `config` reflects config.yaml only —
|
|
673
|
-
// handler-level `wildcard: true` takes effect only once registrations
|
|
674
|
-
// are applied.
|
|
670
|
+
// Parse and validate the block ranges upfront before starting any workers.
|
|
675
671
|
let chainEntries = sortedChainKeys->Array.map(chainIdStr => {
|
|
676
672
|
let rawChainConfig = rawChains->Dict.getUnsafe(chainIdStr)
|
|
677
673
|
let chainId = switch chainIdStr->Int.fromString {
|
|
@@ -868,26 +864,6 @@ let initTestWorker = () => {
|
|
|
868
864
|
}
|
|
869
865
|
|
|
870
866
|
let patchConfig = (config: Config.t, _registrations) => {
|
|
871
|
-
// `config` here has handler registrations applied, so `isWildcard`
|
|
872
|
-
// reflects `indexer.onEvent({ wildcard: true })` — which the main thread
|
|
873
|
-
// can't see. Validate srcAddresses against it before patching in the
|
|
874
|
-
// simulate source.
|
|
875
|
-
switch simulate {
|
|
876
|
-
| Some(simulateItems) =>
|
|
877
|
-
let chainConfig = config.chainMap->ChainMap.get(ChainMap.Chain.makeUnsafe(~chainId))
|
|
878
|
-
let indexingAddresses =
|
|
879
|
-
initialState.chains
|
|
880
|
-
->Array.find(c => c.id == chainId)
|
|
881
|
-
->Option.mapOr([], c => c.indexingAddresses)
|
|
882
|
-
SimulateItems.validateSrcAddresses(
|
|
883
|
-
~simulateItems,
|
|
884
|
-
~config,
|
|
885
|
-
~chainConfig,
|
|
886
|
-
~indexingAddresses,
|
|
887
|
-
)
|
|
888
|
-
| None => ()
|
|
889
|
-
}
|
|
890
|
-
|
|
891
867
|
let config = SimulateItems.patchConfig(~config, ~processConfig)
|
|
892
868
|
|
|
893
869
|
// In auto-exit mode, set batchSize=1 to process one block checkpoint at a time
|
|
@@ -900,8 +876,8 @@ let initTestWorker = () => {
|
|
|
900
876
|
Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)
|
|
901
877
|
->Promise.catch(exn => {
|
|
902
878
|
// `Main.start` rejects on any fatal error: a runtime failure arrives wrapped
|
|
903
|
-
// in `Main.FatalError` (already logged), a setup throw (e.g.
|
|
904
|
-
//
|
|
879
|
+
// in `Main.FatalError` (already logged), a setup throw (e.g. an invalid
|
|
880
|
+
// simulate item) arrives raw. The parent only learns of failures
|
|
905
881
|
// through the worker `error` event, which fires on an *uncaught* exception.
|
|
906
882
|
// Throwing synchronously in this catch would just reject the catch's own
|
|
907
883
|
// promise (swallowed by `ignore`); `setImmediate` re-throws outside the
|
package/src/TestIndexer.res.mjs
CHANGED
|
@@ -586,11 +586,9 @@ function initTestWorker() {
|
|
|
586
586
|
Process.exit(1);
|
|
587
587
|
return;
|
|
588
588
|
}
|
|
589
|
-
let initialState = workerData.initialState;
|
|
590
589
|
let simulate = workerData.simulate;
|
|
591
590
|
let endBlock = workerData.endBlock;
|
|
592
|
-
let
|
|
593
|
-
let chainIdStr = chainId.toString();
|
|
591
|
+
let chainIdStr = workerData.chainId.toString();
|
|
594
592
|
let exitAfterFirstEventBlock = Stdlib_Option.isNone(endBlock);
|
|
595
593
|
let resolvedChainDict = {};
|
|
596
594
|
resolvedChainDict["startBlock"] = workerData.startBlock;
|
|
@@ -605,7 +603,7 @@ function initTestWorker() {
|
|
|
605
603
|
let processConfig = {
|
|
606
604
|
chains: resolvedChainsDict
|
|
607
605
|
};
|
|
608
|
-
let proxy = TestIndexerProxyStorage.make(parentPort, initialState);
|
|
606
|
+
let proxy = TestIndexerProxyStorage.make(parentPort, workerData.initialState);
|
|
609
607
|
let storage = TestIndexerProxyStorage.makeStorage(proxy);
|
|
610
608
|
let config = Config.loadWithoutRegistrations();
|
|
611
609
|
let persistence = Persistence.make(config.userEntities, config.allEnums, storage);
|
|
@@ -615,11 +613,6 @@ function initTestWorker() {
|
|
|
615
613
|
Logging.setLogLevel("silent");
|
|
616
614
|
}
|
|
617
615
|
let patchConfig = (config, _registrations) => {
|
|
618
|
-
if (simulate !== undefined) {
|
|
619
|
-
let chainConfig = ChainMap.get(config.chainMap, ChainMap.Chain.makeUnsafe(chainId));
|
|
620
|
-
let indexingAddresses = Stdlib_Option.mapOr(initialState.chains.find(c => c.id === chainId), [], c => c.indexingAddresses);
|
|
621
|
-
SimulateItems.validateSrcAddresses(simulate, config, chainConfig, indexingAddresses);
|
|
622
|
-
}
|
|
623
616
|
let config$1 = SimulateItems.patchConfig(config, processConfig);
|
|
624
617
|
if (exitAfterFirstEventBlock) {
|
|
625
618
|
return {
|
package/src/sources/EvmChain.res
CHANGED
|
@@ -32,7 +32,7 @@ let getSyncConfig = (
|
|
|
32
32
|
intervalCeiling: Env.Configurable.SyncConfig.intervalCeiling->Option.getOr(
|
|
33
33
|
intervalCeiling->Option.getOr(10_000),
|
|
34
34
|
),
|
|
35
|
-
backoffMillis: backoffMillis->Option.getOr(
|
|
35
|
+
backoffMillis: backoffMillis->Option.getOr(2000),
|
|
36
36
|
queryTimeoutMillis,
|
|
37
37
|
fallbackStallTimeout: fallbackStallTimeout->Option.getOr(queryTimeoutMillis / 2),
|
|
38
38
|
pollingInterval: pollingInterval->Option.getOr(1000),
|
|
@@ -13,7 +13,7 @@ function getSyncConfig(param) {
|
|
|
13
13
|
backoffMultiplicative: Stdlib_Option.getOr(Env.Configurable.SyncConfig.backoffMultiplicative, Stdlib_Option.getOr(param.backoffMultiplicative, 0.8)),
|
|
14
14
|
accelerationAdditive: Stdlib_Option.getOr(Env.Configurable.SyncConfig.accelerationAdditive, Stdlib_Option.getOr(param.accelerationAdditive, 500)),
|
|
15
15
|
intervalCeiling: Stdlib_Option.getOr(Env.Configurable.SyncConfig.intervalCeiling, Stdlib_Option.getOr(param.intervalCeiling, 10000)),
|
|
16
|
-
backoffMillis: Stdlib_Option.getOr(param.backoffMillis,
|
|
16
|
+
backoffMillis: Stdlib_Option.getOr(param.backoffMillis, 2000),
|
|
17
17
|
queryTimeoutMillis: queryTimeoutMillis,
|
|
18
18
|
fallbackStallTimeout: Stdlib_Option.getOr(param.fallbackStallTimeout, queryTimeoutMillis / 2 | 0),
|
|
19
19
|
pollingInterval: Stdlib_Option.getOr(param.pollingInterval, 1000)
|
|
@@ -196,7 +196,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
196
196
|
client = ErrorHandling.mkLogAndRaise(undefined, "Failed to instantiate the HyperFuel client", exn);
|
|
197
197
|
}
|
|
198
198
|
let getSelectionConfig = memoGetSelectionConfig(chain);
|
|
199
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, retry, logger) => {
|
|
199
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, param$1, retry, logger) => {
|
|
200
200
|
let totalTimeRef = Performance.now();
|
|
201
201
|
let selectionConfig = getSelectionConfig(selection);
|
|
202
202
|
let recieptsSelection = selectionConfig.getRecieptsSelection(addressesByContractName);
|
|
@@ -64,6 +64,7 @@ module GetLogs = {
|
|
|
64
64
|
~toBlockInclusive,
|
|
65
65
|
~addressesWithTopics,
|
|
66
66
|
~fieldSelection,
|
|
67
|
+
~maxNumLogs,
|
|
67
68
|
): HyperSyncClient.QueryTypes.query => {
|
|
68
69
|
fromBlock,
|
|
69
70
|
toBlockExclusive: ?switch toBlockInclusive {
|
|
@@ -72,6 +73,7 @@ module GetLogs = {
|
|
|
72
73
|
},
|
|
73
74
|
logs: addressesWithTopics,
|
|
74
75
|
fieldSelection,
|
|
76
|
+
maxNumLogs,
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
// Rust encodes structured failures as a JSON payload in the napi error's
|
|
@@ -105,6 +107,7 @@ module GetLogs = {
|
|
|
105
107
|
~toBlock,
|
|
106
108
|
~logSelections: array<LogSelection.t>,
|
|
107
109
|
~fieldSelection,
|
|
110
|
+
~maxNumLogs,
|
|
108
111
|
): logsQueryPage => {
|
|
109
112
|
let addressesWithTopics = logSelections->Array.flatMap(({addresses, topicSelections}) =>
|
|
110
113
|
topicSelections->Array.map(({topic0, topic1, topic2, topic3}) => {
|
|
@@ -123,6 +126,7 @@ module GetLogs = {
|
|
|
123
126
|
~toBlockInclusive=toBlock,
|
|
124
127
|
~addressesWithTopics,
|
|
125
128
|
~fieldSelection,
|
|
129
|
+
~maxNumLogs,
|
|
126
130
|
)
|
|
127
131
|
|
|
128
132
|
let (res, transactionStore) = switch await client.getEventItems(~query) {
|
|
@@ -62,12 +62,13 @@ function mapExn(queryResponse) {
|
|
|
62
62
|
|
|
63
63
|
let $$Error = /* @__PURE__ */Primitive_exceptions.create("HyperSync.GetLogs.Error");
|
|
64
64
|
|
|
65
|
-
function makeRequestBody(fromBlock, toBlockInclusive, addressesWithTopics, fieldSelection) {
|
|
65
|
+
function makeRequestBody(fromBlock, toBlockInclusive, addressesWithTopics, fieldSelection, maxNumLogs) {
|
|
66
66
|
return {
|
|
67
67
|
fromBlock: fromBlock,
|
|
68
68
|
toBlock: toBlockInclusive !== undefined ? toBlockInclusive + 1 | 0 : undefined,
|
|
69
69
|
logs: addressesWithTopics,
|
|
70
|
-
fieldSelection: fieldSelection
|
|
70
|
+
fieldSelection: fieldSelection,
|
|
71
|
+
maxNumLogs: maxNumLogs
|
|
71
72
|
};
|
|
72
73
|
}
|
|
73
74
|
|
|
@@ -92,7 +93,7 @@ function extractMissingParams(exn) {
|
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
|
|
95
|
-
async function query(client, fromBlock, toBlock, logSelections, fieldSelection) {
|
|
96
|
+
async function query(client, fromBlock, toBlock, logSelections, fieldSelection, maxNumLogs) {
|
|
96
97
|
let addressesWithTopics = logSelections.flatMap(param => {
|
|
97
98
|
let addresses = param.addresses;
|
|
98
99
|
return param.topicSelections.map(param => {
|
|
@@ -100,7 +101,7 @@ async function query(client, fromBlock, toBlock, logSelections, fieldSelection)
|
|
|
100
101
|
return HyperSyncClient.QueryTypes.makeLogSelection(addresses, topics);
|
|
101
102
|
});
|
|
102
103
|
});
|
|
103
|
-
let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection);
|
|
104
|
+
let query$1 = makeRequestBody(fromBlock, toBlock, addressesWithTopics, fieldSelection, maxNumLogs);
|
|
104
105
|
let match;
|
|
105
106
|
try {
|
|
106
107
|
match = await client.getEventItems(query$1);
|
|
@@ -232,6 +232,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
232
232
|
~knownHeight,
|
|
233
233
|
~partitionId as _,
|
|
234
234
|
~selection,
|
|
235
|
+
~itemsTarget,
|
|
235
236
|
~retry,
|
|
236
237
|
~logger,
|
|
237
238
|
) => {
|
|
@@ -258,6 +259,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
258
259
|
~toBlock,
|
|
259
260
|
~logSelections,
|
|
260
261
|
~fieldSelection=selectionConfig.fieldSelection,
|
|
262
|
+
~maxNumLogs=itemsTarget,
|
|
261
263
|
) catch {
|
|
262
264
|
| HyperSync.GetLogs.Error(error) =>
|
|
263
265
|
throw(
|
|
@@ -149,7 +149,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
149
149
|
}
|
|
150
150
|
};
|
|
151
151
|
};
|
|
152
|
-
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, retry, logger) => {
|
|
152
|
+
let getItemsOrThrow = async (fromBlock, toBlock, addressesByContractName, contractNameByAddress, knownHeight, param, selection, itemsTarget, retry, logger) => {
|
|
153
153
|
let totalTimeRef = Performance.now();
|
|
154
154
|
let selectionConfig = getSelectionConfig(selection);
|
|
155
155
|
let logSelections;
|
|
@@ -163,7 +163,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
163
163
|
Prometheus.SourceRequestCount.increment(name, chain, "getLogs");
|
|
164
164
|
let pageUnsafe;
|
|
165
165
|
try {
|
|
166
|
-
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection);
|
|
166
|
+
pageUnsafe = await HyperSync.GetLogs.query(client, fromBlock, toBlock, logSelections, selectionConfig.fieldSelection, itemsTarget);
|
|
167
167
|
} catch (raw_error) {
|
|
168
168
|
let error = Primitive_exceptions.internalToException(raw_error);
|
|
169
169
|
if (error.RE_EXN_ID === HyperSync.GetLogs.$$Error) {
|