envio 3.3.0-alpha.1 → 3.3.0-alpha.11
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/evm.schema.json +10 -0
- package/index.d.ts +45 -25
- 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 +10 -9
- package/src/Address.res +5 -2
- package/src/Address.res.mjs +3 -1
- package/src/Api.res +1 -1
- package/src/Api.res.mjs +1 -1
- package/src/Batch.res +0 -6
- package/src/Batch.res.mjs +1 -12
- package/src/BatchProcessing.res +7 -12
- package/src/BatchProcessing.res.mjs +8 -7
- package/src/Bin.res +3 -0
- package/src/Bin.res.mjs +4 -0
- package/src/ChainFetching.res +53 -16
- package/src/ChainFetching.res.mjs +37 -19
- package/src/ChainMetadata.res +1 -11
- package/src/ChainMetadata.res.mjs +1 -10
- package/src/ChainState.res +630 -161
- package/src/ChainState.res.mjs +438 -101
- package/src/ChainState.resi +77 -4
- package/src/Config.res +70 -38
- package/src/Config.res.mjs +52 -12
- package/src/ContractRegisterContext.res +2 -12
- package/src/ContractRegisterContext.res.mjs +3 -5
- package/src/Core.res +34 -3
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +130 -89
- package/src/CrossChainState.res.mjs +66 -61
- package/src/CrossChainState.resi +1 -1
- package/src/Ecosystem.res +5 -6
- package/src/Ecosystem.res.mjs +3 -3
- package/src/Envio.res +17 -11
- package/src/EnvioGlobal.res +53 -0
- package/src/EnvioGlobal.res.mjs +31 -0
- package/src/EventConfigBuilder.res +191 -127
- package/src/EventConfigBuilder.res.mjs +116 -66
- package/src/EventProcessing.res +77 -28
- package/src/EventProcessing.res.mjs +56 -29
- package/src/ExitOnCaughtUp.res +10 -2
- package/src/ExitOnCaughtUp.res.mjs +10 -1
- package/src/FetchState.res +684 -415
- package/src/FetchState.res.mjs +505 -486
- package/src/HandlerLoader.res +8 -104
- package/src/HandlerLoader.res.mjs +2 -81
- package/src/HandlerRegister.res +520 -144
- package/src/HandlerRegister.res.mjs +286 -133
- package/src/HandlerRegister.resi +24 -8
- package/src/IndexerState.res +10 -3
- package/src/IndexerState.res.mjs +11 -4
- package/src/IndexerState.resi +2 -1
- package/src/IndexingAddresses.res +108 -0
- package/src/IndexingAddresses.res.mjs +101 -0
- package/src/IndexingAddresses.resi +34 -0
- package/src/Internal.res +166 -48
- package/src/Internal.res.mjs +30 -2
- package/src/LoadLayer.res +5 -5
- package/src/LoadLayer.res.mjs +6 -6
- package/src/LogSelection.res +92 -217
- package/src/LogSelection.res.mjs +95 -184
- package/src/Main.res +71 -236
- package/src/Main.res.mjs +60 -145
- package/src/Metrics.res +74 -0
- package/src/Metrics.res.mjs +75 -0
- package/src/PgStorage.res +4 -4
- package/src/PgStorage.res.mjs +5 -5
- package/src/Prometheus.res +10 -63
- package/src/Prometheus.res.mjs +124 -171
- package/src/PruneStaleHistory.res +2 -2
- package/src/PruneStaleHistory.res.mjs +3 -3
- package/src/RawEvent.res +7 -2
- package/src/RawEvent.res.mjs +4 -4
- package/src/Rollback.res +3 -3
- package/src/Rollback.res.mjs +4 -4
- package/src/RollbackCommit.res +4 -1
- package/src/RollbackCommit.res.mjs +3 -2
- package/src/SimulateDeadInputTracker.res +85 -0
- package/src/SimulateDeadInputTracker.res.mjs +73 -0
- package/src/SimulateDeadInputTracker.resi +12 -0
- package/src/SimulateItems.res +128 -28
- package/src/SimulateItems.res.mjs +82 -40
- package/src/TestIndexer.res +55 -41
- package/src/TestIndexer.res.mjs +39 -32
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/bindings/Performance.res +7 -0
- package/src/bindings/Performance.res.mjs +21 -0
- package/src/bindings/Performance.resi +7 -0
- package/src/bindings/Viem.res +0 -46
- package/src/bindings/Viem.res.mjs +1 -43
- package/src/sources/BlockStore.res +46 -0
- package/src/sources/BlockStore.res.mjs +24 -0
- package/src/sources/EventRouter.res +31 -49
- package/src/sources/EventRouter.res.mjs +12 -25
- package/src/sources/Evm.res +83 -72
- package/src/sources/Evm.res.mjs +53 -69
- package/src/sources/EvmChain.res +7 -34
- package/src/sources/EvmChain.res.mjs +6 -27
- package/src/sources/EvmRpcClient.res +71 -5
- package/src/sources/EvmRpcClient.res.mjs +13 -4
- package/src/sources/FieldMask.res +39 -0
- package/src/sources/FieldMask.res.mjs +42 -0
- package/src/sources/Fuel.res +9 -6
- package/src/sources/Fuel.res.mjs +5 -10
- package/src/sources/HyperFuelSource.res +46 -50
- package/src/sources/HyperFuelSource.res.mjs +64 -54
- package/src/sources/HyperSync.res +45 -42
- package/src/sources/HyperSync.res.mjs +68 -60
- package/src/sources/HyperSync.resi +14 -4
- package/src/sources/HyperSyncClient.res +107 -119
- package/src/sources/HyperSyncClient.res.mjs +36 -31
- package/src/sources/HyperSyncHeightStream.res +1 -8
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
- package/src/sources/HyperSyncSource.res +60 -254
- package/src/sources/HyperSyncSource.res.mjs +57 -180
- package/src/sources/Rpc.res +15 -79
- package/src/sources/Rpc.res.mjs +25 -101
- package/src/sources/RpcSource.res +221 -514
- package/src/sources/RpcSource.res.mjs +216 -411
- package/src/sources/RpcWebSocketHeightStream.res +0 -5
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
- package/src/sources/SimulateSource.res +44 -20
- package/src/sources/SimulateSource.res.mjs +41 -14
- package/src/sources/Source.res +34 -6
- package/src/sources/SourceManager.res +77 -19
- package/src/sources/SourceManager.res.mjs +63 -21
- package/src/sources/SourceManager.resi +10 -0
- package/src/sources/Svm.res +31 -16
- package/src/sources/Svm.res.mjs +36 -13
- package/src/sources/SvmHyperSyncClient.res +5 -32
- package/src/sources/SvmHyperSyncSource.res +159 -134
- package/src/sources/SvmHyperSyncSource.res.mjs +164 -129
- package/src/sources/TransactionStore.res +49 -0
- package/src/sources/TransactionStore.res.mjs +30 -0
- package/src/tui/Tui.res +13 -16
- package/src/tui/Tui.res.mjs +12 -14
- package/svm.schema.json +49 -37
- package/src/bindings/Hrtime.res +0 -58
- package/src/bindings/Hrtime.res.mjs +0 -90
- package/src/bindings/Hrtime.resi +0 -30
|
@@ -1,10 +1,12 @@
|
|
|
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";
|
|
6
7
|
import * as SimulateSource from "./sources/SimulateSource.res.mjs";
|
|
7
8
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
9
|
+
import * as HandlerRegister from "./HandlerRegister.res.mjs";
|
|
8
10
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
9
11
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
10
12
|
|
|
@@ -135,7 +137,37 @@ function findEventConfig(config, contractName, eventName) {
|
|
|
135
137
|
return found.contents;
|
|
136
138
|
}
|
|
137
139
|
|
|
138
|
-
|
|
140
|
+
let dummySrcAddress = "0x0000000000000000000000000000000000000000";
|
|
141
|
+
|
|
142
|
+
function firstContractAddress(chainConfig, contractName) {
|
|
143
|
+
let found = {
|
|
144
|
+
contents: undefined
|
|
145
|
+
};
|
|
146
|
+
chainConfig.contracts.forEach(contract => {
|
|
147
|
+
if (Stdlib_Option.isNone(found.contents) && contract.name === contractName) {
|
|
148
|
+
found.contents = contract.addresses[0];
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
return found.contents;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function deriveSrcAddress(providedSrcAddress, eventConfig, chainConfig, config) {
|
|
156
|
+
if (providedSrcAddress !== undefined) {
|
|
157
|
+
return Config.normalizeSimulateAddress(config, Primitive_option.valFromOption(providedSrcAddress));
|
|
158
|
+
}
|
|
159
|
+
if (HandlerRegister.isWildcard(eventConfig.contractName, eventConfig.name)) {
|
|
160
|
+
return dummySrcAddress;
|
|
161
|
+
}
|
|
162
|
+
let addr = firstContractAddress(chainConfig, eventConfig.contractName);
|
|
163
|
+
if (addr !== undefined) {
|
|
164
|
+
return Primitive_option.valFromOption(addr);
|
|
165
|
+
} else {
|
|
166
|
+
return dummySrcAddress;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function parse(simulateItems, config, chainConfig, onEventRegistrations) {
|
|
139
171
|
let chain = ChainMap.Chain.makeUnsafe(chainConfig.id);
|
|
140
172
|
let chainId = chainConfig.id;
|
|
141
173
|
let startBlock = chainConfig.startBlock;
|
|
@@ -146,7 +178,8 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
146
178
|
contents: 0
|
|
147
179
|
};
|
|
148
180
|
let items = [];
|
|
149
|
-
|
|
181
|
+
let seenCoordinates = {};
|
|
182
|
+
simulateItems.forEach((rawJson, itemIndex) => {
|
|
150
183
|
let match = rawJson.contract;
|
|
151
184
|
let match$1 = rawJson.event;
|
|
152
185
|
if (match === undefined) {
|
|
@@ -163,32 +196,16 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
163
196
|
let li = rawJson.logIndex;
|
|
164
197
|
let logIndex;
|
|
165
198
|
if (li !== undefined) {
|
|
199
|
+
if (li >= currentLogIndex.contents) {
|
|
200
|
+
currentLogIndex.contents = li + 1 | 0;
|
|
201
|
+
}
|
|
166
202
|
logIndex = li;
|
|
167
203
|
} else {
|
|
168
204
|
let li$1 = currentLogIndex.contents;
|
|
169
205
|
currentLogIndex.contents = li$1 + 1 | 0;
|
|
170
206
|
logIndex = li$1;
|
|
171
207
|
}
|
|
172
|
-
let
|
|
173
|
-
let srcAddress;
|
|
174
|
-
if (addr !== undefined) {
|
|
175
|
-
srcAddress = Primitive_option.valFromOption(addr);
|
|
176
|
-
} else {
|
|
177
|
-
let addr$1 = {
|
|
178
|
-
contents: "0x0000000000000000000000000000000000000000"
|
|
179
|
-
};
|
|
180
|
-
chainConfig.contracts.forEach(contract => {
|
|
181
|
-
if (contract.name !== match) {
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
let a = contract.addresses[0];
|
|
185
|
-
if (a !== undefined) {
|
|
186
|
-
addr$1.contents = Primitive_option.valFromOption(a);
|
|
187
|
-
return;
|
|
188
|
-
}
|
|
189
|
-
});
|
|
190
|
-
srcAddress = addr$1.contents;
|
|
191
|
-
}
|
|
208
|
+
let srcAddress = deriveSrcAddress(rawJson.srcAddress, eventConfig, chainConfig, config);
|
|
192
209
|
let blockJson = rawJson.block;
|
|
193
210
|
let blockJson$1 = (blockJson == null) ? undefined : Primitive_option.some(blockJson);
|
|
194
211
|
let transactionJson = rawJson.transaction;
|
|
@@ -200,18 +217,14 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
200
217
|
let block = parseEvmSimulateBlock(currentBlock.contents, blockJson$1);
|
|
201
218
|
match$3 = [
|
|
202
219
|
block,
|
|
203
|
-
block.number
|
|
204
|
-
block.timestamp,
|
|
205
|
-
block.hash
|
|
220
|
+
block.number
|
|
206
221
|
];
|
|
207
222
|
break;
|
|
208
223
|
case "fuel" :
|
|
209
224
|
let block$1 = parseFuelSimulateBlock(currentBlock.contents, blockJson$1);
|
|
210
225
|
match$3 = [
|
|
211
226
|
block$1,
|
|
212
|
-
block$1.height
|
|
213
|
-
block$1.time,
|
|
214
|
-
block$1.id
|
|
227
|
+
block$1.height
|
|
215
228
|
];
|
|
216
229
|
break;
|
|
217
230
|
case "svm" :
|
|
@@ -233,14 +246,25 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
233
246
|
break;
|
|
234
247
|
}
|
|
235
248
|
currentBlock.contents = blockNumber;
|
|
249
|
+
let coordinate = blockNumber.toString() + `:` + logIndex.toString();
|
|
250
|
+
let firstIndex = seenCoordinates[coordinate];
|
|
251
|
+
if (firstIndex !== undefined) {
|
|
252
|
+
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).`);
|
|
253
|
+
} else {
|
|
254
|
+
seenCoordinates[coordinate] = itemIndex;
|
|
255
|
+
}
|
|
256
|
+
let onEventRegistration = HandlerRegister.buildOnEventRegistration(config, chainId, eventConfig, undefined);
|
|
257
|
+
let onEventRegistrationIndex = onEventRegistrations.length;
|
|
258
|
+
let newrecord = {...onEventRegistration};
|
|
259
|
+
newrecord.index = onEventRegistrationIndex;
|
|
260
|
+
onEventRegistrations.push(newrecord);
|
|
236
261
|
items.push({
|
|
237
262
|
kind: 0,
|
|
238
|
-
|
|
239
|
-
timestamp: match$3[2],
|
|
263
|
+
onEventRegistration: newrecord,
|
|
240
264
|
chain: chain,
|
|
241
265
|
blockNumber: blockNumber,
|
|
242
|
-
blockHash: match$3[3],
|
|
243
266
|
logIndex: logIndex,
|
|
267
|
+
transactionIndex: 0,
|
|
244
268
|
payload: {
|
|
245
269
|
contractName: eventConfig.contractName,
|
|
246
270
|
eventName: eventConfig.name,
|
|
@@ -248,15 +272,15 @@ function parse(simulateItems, config, chainConfig) {
|
|
|
248
272
|
chainId: chainId,
|
|
249
273
|
srcAddress: srcAddress,
|
|
250
274
|
logIndex: logIndex,
|
|
251
|
-
transaction: transaction,
|
|
252
|
-
block: match$3[0]
|
|
275
|
+
transaction: Primitive_option.some(transaction),
|
|
276
|
+
block: Primitive_option.some(match$3[0])
|
|
253
277
|
}
|
|
254
278
|
});
|
|
255
279
|
});
|
|
256
280
|
return items;
|
|
257
281
|
}
|
|
258
282
|
|
|
259
|
-
function patchConfig(config, processConfig) {
|
|
283
|
+
function patchConfig(config, processConfig, registrationsByChainId) {
|
|
260
284
|
let processChains = processConfig.chains;
|
|
261
285
|
if (processChains == null) {
|
|
262
286
|
return config;
|
|
@@ -271,18 +295,33 @@ function patchConfig(config, processConfig) {
|
|
|
271
295
|
if (simulateRaw == null) {
|
|
272
296
|
return chainConfig;
|
|
273
297
|
}
|
|
274
|
-
let
|
|
298
|
+
let registrations = registrationsByChainId[chainIdStr];
|
|
299
|
+
let chainRegistrations;
|
|
300
|
+
if (registrations !== undefined) {
|
|
301
|
+
chainRegistrations = registrations;
|
|
302
|
+
} else {
|
|
303
|
+
let registrations_onEventRegistrations = [];
|
|
304
|
+
let registrations_onBlockRegistrations = [];
|
|
305
|
+
let registrations$1 = {
|
|
306
|
+
onEventRegistrations: registrations_onEventRegistrations,
|
|
307
|
+
onBlockRegistrations: registrations_onBlockRegistrations
|
|
308
|
+
};
|
|
309
|
+
registrationsByChainId[chainIdStr] = registrations$1;
|
|
310
|
+
chainRegistrations = registrations$1;
|
|
311
|
+
}
|
|
275
312
|
let startBlock = processChainJson.startBlock;
|
|
276
313
|
let endBlock = processChainJson.endBlock;
|
|
277
|
-
let source = SimulateSource.make(items, endBlock, chain);
|
|
278
314
|
let newrecord = {...chainConfig};
|
|
279
|
-
newrecord.
|
|
315
|
+
newrecord.endBlock = endBlock;
|
|
316
|
+
newrecord.startBlock = startBlock;
|
|
317
|
+
let items = parse(simulateRaw, config, newrecord, chainRegistrations.onEventRegistrations);
|
|
318
|
+
let source = SimulateSource.make(items, endBlock, chain);
|
|
319
|
+
let newrecord$1 = {...newrecord};
|
|
320
|
+
newrecord$1.sourceConfig = {
|
|
280
321
|
TAG: "CustomSources",
|
|
281
322
|
_0: [source]
|
|
282
323
|
};
|
|
283
|
-
newrecord
|
|
284
|
-
newrecord.startBlock = startBlock;
|
|
285
|
-
return newrecord;
|
|
324
|
+
return newrecord$1;
|
|
286
325
|
});
|
|
287
326
|
return {
|
|
288
327
|
name: config.name,
|
|
@@ -317,6 +356,9 @@ export {
|
|
|
317
356
|
fuelSimulateTransactionSchema,
|
|
318
357
|
parseFuelSimulateTransaction,
|
|
319
358
|
findEventConfig,
|
|
359
|
+
dummySrcAddress,
|
|
360
|
+
firstContractAddress,
|
|
361
|
+
deriveSrcAddress,
|
|
320
362
|
parse,
|
|
321
363
|
patchConfig,
|
|
322
364
|
}
|
package/src/TestIndexer.res
CHANGED
|
@@ -43,6 +43,33 @@ let toIndexingAddress = (dc: InternalTable.EnvioAddresses.t): Internal.indexingA
|
|
|
43
43
|
registrationBlock: dc.registrationBlock,
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
// All indexing addresses (config-seeded + dynamically registered) grouped by
|
|
47
|
+
// chain id string, derived from the envio_addresses entities.
|
|
48
|
+
let getIndexingAddressesByChain = (state: testIndexerState): dict<
|
|
49
|
+
array<Internal.indexingAddress>,
|
|
50
|
+
> => {
|
|
51
|
+
let byChain = Dict.make()
|
|
52
|
+
switch state.entities->Dict.get(InternalTable.EnvioAddresses.name) {
|
|
53
|
+
| Some(dcDict) =>
|
|
54
|
+
dcDict
|
|
55
|
+
->Dict.valuesToArray
|
|
56
|
+
->Array.forEach(entity => {
|
|
57
|
+
let dc = entity->castToEnvioAddresses
|
|
58
|
+
let chainIdStr = dc.chainId->Int.toString
|
|
59
|
+
let contracts = switch byChain->Dict.get(chainIdStr) {
|
|
60
|
+
| Some(arr) => arr
|
|
61
|
+
| None =>
|
|
62
|
+
let arr = []
|
|
63
|
+
byChain->Dict.set(chainIdStr, arr)
|
|
64
|
+
arr
|
|
65
|
+
}
|
|
66
|
+
contracts->Array.push(dc->toIndexingAddress)->ignore
|
|
67
|
+
})
|
|
68
|
+
| None => ()
|
|
69
|
+
}
|
|
70
|
+
byChain
|
|
71
|
+
}
|
|
72
|
+
|
|
46
73
|
let handleLoad = (state: testIndexerState, ~tableName: string, ~filter: EntityFilter.t): JSON.t => {
|
|
47
74
|
// Loads for non-entity tables (e.g. effect caches `envio_effect_<name>`) reach
|
|
48
75
|
// here too. TestIndexer never persists those, so there's nothing to return —
|
|
@@ -566,22 +593,10 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
|
|
|
566
593
|
`Cannot access ${contract.name}.addresses while indexer.process() is running. ` ++ "Wait for process() to complete before reading contract addresses.",
|
|
567
594
|
)
|
|
568
595
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
->Dict.valuesToArray
|
|
574
|
-
->Array.forEach(
|
|
575
|
-
entity => {
|
|
576
|
-
let dc = entity->castToEnvioAddresses
|
|
577
|
-
if dc.contractName === contract.name && dc.chainId === chainConfig.id {
|
|
578
|
-
addresses->Array.push(dc->Config.EnvioAddresses.getAddress)->ignore
|
|
579
|
-
}
|
|
580
|
-
},
|
|
581
|
-
)
|
|
582
|
-
| None => ()
|
|
583
|
-
}
|
|
584
|
-
addresses
|
|
596
|
+
getIndexingAddressesByChain(state)
|
|
597
|
+
->Dict.get(chainConfig.id->Int.toString)
|
|
598
|
+
->Option.getOr([])
|
|
599
|
+
->Array.filterMap(ia => ia.contractName === contract.name ? Some(ia.address) : None)
|
|
585
600
|
},
|
|
586
601
|
},
|
|
587
602
|
)
|
|
@@ -652,7 +667,7 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
|
|
|
652
667
|
Int.compare(aId, bId)
|
|
653
668
|
})
|
|
654
669
|
|
|
655
|
-
// Parse and validate
|
|
670
|
+
// Parse and validate the block ranges upfront before starting any workers.
|
|
656
671
|
let chainEntries = sortedChainKeys->Array.map(chainIdStr => {
|
|
657
672
|
let rawChainConfig = rawChains->Dict.getUnsafe(chainIdStr)
|
|
658
673
|
let chainId = switch chainIdStr->Int.fromString {
|
|
@@ -684,26 +699,9 @@ let makeCreateTestIndexer = (~config: Config.t, ~workerPath: string): (
|
|
|
684
699
|
let chains: dict<chainConfig> = Dict.make()
|
|
685
700
|
chains->Dict.set(chainIdStr, processChainConfig)
|
|
686
701
|
|
|
687
|
-
//
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
| Some(dcDict) =>
|
|
691
|
-
dcDict
|
|
692
|
-
->Dict.valuesToArray
|
|
693
|
-
->Array.forEach(entity => {
|
|
694
|
-
let dc = entity->castToEnvioAddresses
|
|
695
|
-
let dcChainIdStr = dc.chainId->Int.toString
|
|
696
|
-
let contracts = switch indexingAddressesByChain->Dict.get(dcChainIdStr) {
|
|
697
|
-
| Some(arr) => arr
|
|
698
|
-
| None =>
|
|
699
|
-
let arr = []
|
|
700
|
-
indexingAddressesByChain->Dict.set(dcChainIdStr, arr)
|
|
701
|
-
arr
|
|
702
|
-
}
|
|
703
|
-
contracts->Array.push(dc->toIndexingAddress)->ignore
|
|
704
|
-
})
|
|
705
|
-
| None => ()
|
|
706
|
-
}
|
|
702
|
+
// Rebuilt per chain so workers see contracts registered by earlier
|
|
703
|
+
// chains in the same process() call.
|
|
704
|
+
let indexingAddressesByChain = getIndexingAddressesByChain(state)
|
|
707
705
|
|
|
708
706
|
let initialState = makeInitialState(
|
|
709
707
|
~config,
|
|
@@ -852,7 +850,7 @@ let initTestWorker = () => {
|
|
|
852
850
|
// Create proxy storage that communicates with main thread
|
|
853
851
|
let proxy = TestIndexerProxyStorage.make(~parentPort, ~initialState)
|
|
854
852
|
let storage = TestIndexerProxyStorage.makeStorage(proxy)
|
|
855
|
-
let config = Config.
|
|
853
|
+
let config = Config.load()
|
|
856
854
|
let persistence = Persistence.make(
|
|
857
855
|
~userEntities=config.userEntities,
|
|
858
856
|
~allEnums=config.allEnums,
|
|
@@ -865,8 +863,8 @@ let initTestWorker = () => {
|
|
|
865
863
|
| Some(_) => ()
|
|
866
864
|
}
|
|
867
865
|
|
|
868
|
-
let patchConfig = (config,
|
|
869
|
-
let config = SimulateItems.patchConfig(~config, ~processConfig)
|
|
866
|
+
let patchConfig = (config: Config.t, registrationsByChainId) => {
|
|
867
|
+
let config = SimulateItems.patchConfig(~config, ~processConfig, ~registrationsByChainId)
|
|
870
868
|
|
|
871
869
|
// In auto-exit mode, set batchSize=1 to process one block checkpoint at a time
|
|
872
870
|
if exitAfterFirstEventBlock {
|
|
@@ -875,7 +873,23 @@ let initTestWorker = () => {
|
|
|
875
873
|
config
|
|
876
874
|
}
|
|
877
875
|
}
|
|
878
|
-
Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)
|
|
876
|
+
Main.start(~persistence, ~isTest=true, ~patchConfig, ~exitAfterFirstEventBlock)
|
|
877
|
+
->Promise.catch(exn => {
|
|
878
|
+
// `Main.start` rejects on any fatal error: a runtime failure arrives wrapped
|
|
879
|
+
// in `Main.FatalError` (already logged), a setup throw (e.g. an invalid
|
|
880
|
+
// simulate item) arrives raw. The parent only learns of failures
|
|
881
|
+
// through the worker `error` event, which fires on an *uncaught* exception.
|
|
882
|
+
// Throwing synchronously in this catch would just reject the catch's own
|
|
883
|
+
// promise (swallowed by `ignore`); `setImmediate` re-throws outside the
|
|
884
|
+
// promise chain so it becomes uncaught and reaches the parent.
|
|
885
|
+
let toThrow = switch exn {
|
|
886
|
+
| Main.FatalError(inner) => inner
|
|
887
|
+
| _ => exn->Utils.prettifyExn
|
|
888
|
+
}
|
|
889
|
+
NodeJs.setImmediate(() => throw(toThrow))
|
|
890
|
+
Promise.resolve()
|
|
891
|
+
})
|
|
892
|
+
->ignore
|
|
879
893
|
| None =>
|
|
880
894
|
Logging.error("TestIndexerWorker: No worker data provided")
|
|
881
895
|
NodeJs.process->NodeJs.exitWithCode(Failure)
|
package/src/TestIndexer.res.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import * as Stdlib_Int from "@rescript/runtime/lib/es6/Stdlib_Int.js";
|
|
|
12
12
|
import * as Persistence from "./Persistence.res.mjs";
|
|
13
13
|
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
14
14
|
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
15
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
15
16
|
import * as InternalTable from "./db/InternalTable.res.mjs";
|
|
16
17
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
17
18
|
import * as SimulateItems from "./SimulateItems.res.mjs";
|
|
@@ -32,6 +33,27 @@ function toIndexingAddress(dc) {
|
|
|
32
33
|
};
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
function getIndexingAddressesByChain(state) {
|
|
37
|
+
let byChain = {};
|
|
38
|
+
let dcDict = state.entities[Config.EnvioAddresses.name];
|
|
39
|
+
if (dcDict !== undefined) {
|
|
40
|
+
Object.values(dcDict).forEach(entity => {
|
|
41
|
+
let chainIdStr = entity.chain_id.toString();
|
|
42
|
+
let arr = byChain[chainIdStr];
|
|
43
|
+
let contracts;
|
|
44
|
+
if (arr !== undefined) {
|
|
45
|
+
contracts = arr;
|
|
46
|
+
} else {
|
|
47
|
+
let arr$1 = [];
|
|
48
|
+
byChain[chainIdStr] = arr$1;
|
|
49
|
+
contracts = arr$1;
|
|
50
|
+
}
|
|
51
|
+
contracts.push(toIndexingAddress(entity));
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return byChain;
|
|
55
|
+
}
|
|
56
|
+
|
|
35
57
|
function handleLoad(state, tableName, filter) {
|
|
36
58
|
let entityConfig = state.entityConfigs[tableName];
|
|
37
59
|
if (entityConfig === undefined) {
|
|
@@ -403,17 +425,11 @@ function makeCreateTestIndexer(config, workerPath) {
|
|
|
403
425
|
if (state.processInProgress) {
|
|
404
426
|
Stdlib_JsError.throwWithMessage(`Cannot access ` + contract.name + `.addresses while indexer.process() is running. ` + "Wait for process() to complete before reading contract addresses.");
|
|
405
427
|
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
addresses.push(Config.EnvioAddresses.getAddress(entity));
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
return addresses;
|
|
428
|
+
return Stdlib_Array.filterMap(Stdlib_Option.getOr(getIndexingAddressesByChain(state)[chainConfig.id.toString()], []), ia => {
|
|
429
|
+
if (ia.contractName === contract.name) {
|
|
430
|
+
return Primitive_option.some(ia.address);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
417
433
|
}
|
|
418
434
|
});
|
|
419
435
|
Object.defineProperty(chainObj, contract.name, {
|
|
@@ -484,23 +500,7 @@ function makeCreateTestIndexer(config, workerPath) {
|
|
|
484
500
|
let chainId = param[1];
|
|
485
501
|
let chains = {};
|
|
486
502
|
chains[param[0]] = processChainConfig;
|
|
487
|
-
let indexingAddressesByChain =
|
|
488
|
-
let dcDict = state.entities[Config.EnvioAddresses.name];
|
|
489
|
-
if (dcDict !== undefined) {
|
|
490
|
-
Object.values(dcDict).forEach(entity => {
|
|
491
|
-
let dcChainIdStr = entity.chain_id.toString();
|
|
492
|
-
let arr = indexingAddressesByChain[dcChainIdStr];
|
|
493
|
-
let contracts;
|
|
494
|
-
if (arr !== undefined) {
|
|
495
|
-
contracts = arr;
|
|
496
|
-
} else {
|
|
497
|
-
let arr$1 = [];
|
|
498
|
-
indexingAddressesByChain[dcChainIdStr] = arr$1;
|
|
499
|
-
contracts = arr$1;
|
|
500
|
-
}
|
|
501
|
-
contracts.push(toIndexingAddress(entity));
|
|
502
|
-
});
|
|
503
|
-
}
|
|
503
|
+
let indexingAddressesByChain = getIndexingAddressesByChain(state);
|
|
504
504
|
let initialState = makeInitialState(config, chains, indexingAddressesByChain);
|
|
505
505
|
return new Promise((resolve, reject) => {
|
|
506
506
|
let workerData_startBlock = processChainConfig.startBlock;
|
|
@@ -605,15 +605,15 @@ function initTestWorker() {
|
|
|
605
605
|
};
|
|
606
606
|
let proxy = TestIndexerProxyStorage.make(parentPort, workerData.initialState);
|
|
607
607
|
let storage = TestIndexerProxyStorage.makeStorage(proxy);
|
|
608
|
-
let config = Config.
|
|
608
|
+
let config = Config.load();
|
|
609
609
|
let persistence = Persistence.make(config.userEntities, config.allEnums, storage);
|
|
610
610
|
if (Env.userLogLevel !== undefined) {
|
|
611
611
|
|
|
612
612
|
} else {
|
|
613
613
|
Logging.setLogLevel("silent");
|
|
614
614
|
}
|
|
615
|
-
let patchConfig = (config,
|
|
616
|
-
let config$1 = SimulateItems.patchConfig(config, processConfig);
|
|
615
|
+
let patchConfig = (config, registrationsByChainId) => {
|
|
616
|
+
let config$1 = SimulateItems.patchConfig(config, processConfig, registrationsByChainId);
|
|
617
617
|
if (exitAfterFirstEventBlock) {
|
|
618
618
|
return {
|
|
619
619
|
name: config$1.name,
|
|
@@ -640,11 +640,18 @@ function initTestWorker() {
|
|
|
640
640
|
return config$1;
|
|
641
641
|
}
|
|
642
642
|
};
|
|
643
|
-
Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig)
|
|
643
|
+
Stdlib_Promise.$$catch(Main.start(persistence, undefined, true, exitAfterFirstEventBlock, patchConfig), exn => {
|
|
644
|
+
let toThrow = exn.RE_EXN_ID === Main.FatalError ? exn._1 : Utils.prettifyExn(exn);
|
|
645
|
+
setImmediate(() => {
|
|
646
|
+
throw toThrow;
|
|
647
|
+
});
|
|
648
|
+
return Promise.resolve();
|
|
649
|
+
});
|
|
644
650
|
}
|
|
645
651
|
|
|
646
652
|
export {
|
|
647
653
|
toIndexingAddress,
|
|
654
|
+
getIndexingAddressesByChain,
|
|
648
655
|
handleLoad,
|
|
649
656
|
handleWriteBatch,
|
|
650
657
|
makeInitialState,
|
package/src/TopicFilter.res
CHANGED
|
@@ -1,27 +1,3 @@
|
|
|
1
|
-
let toTwosComplement = (num: bigint, ~bytesLen: int) => {
|
|
2
|
-
let maxValue = 1n->BigInt.shiftLeft(BigInt.fromInt(bytesLen * 8))
|
|
3
|
-
let mask = maxValue->BigInt.sub(1n)
|
|
4
|
-
num->BigInt.add(maxValue)->BigInt.bitwiseAnd(mask)
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
let fromSignedBigInt = val => {
|
|
8
|
-
let bytesLen = 32
|
|
9
|
-
let val = val >= 0n ? val : val->toTwosComplement(~bytesLen)
|
|
10
|
-
val->Viem.bigintToHex(~options={size: bytesLen})
|
|
11
|
-
}
|
|
12
|
-
|
|
13
1
|
type hex = EvmTypes.Hex.t
|
|
14
|
-
|
|
15
|
-
type bytesHex = string
|
|
16
|
-
let keccak256 = Viem.keccak256
|
|
17
|
-
let bytesToHex = Viem.bytesToHex
|
|
18
|
-
let concat = Viem.concat
|
|
19
|
-
let castToHexUnsafe: 'a => hex = val => val->(Utils.magic: 'a => hex)
|
|
20
|
-
let fromBigInt: bigint => hex = val => val->Viem.bigintToHex(~options={size: 32})
|
|
21
|
-
let fromDynamicString: string => hex = val => val->(Utils.magic: string => hex)->keccak256
|
|
22
|
-
let fromString: string => hex = val => val->Viem.stringToHex(~options={size: 32})
|
|
2
|
+
|
|
23
3
|
let fromAddress: Address.t => hex = addr => addr->(Utils.magic: Address.t => hex)->Viem.pad
|
|
24
|
-
let fromDynamicBytes: bytesHex => hex = bytes => bytes->(Utils.magic: bytesHex => hex)->keccak256
|
|
25
|
-
let fromBytes: bytesHex => hex = bytes =>
|
|
26
|
-
bytes->(Utils.magic: bytesHex => Uint8Array.t)->Viem.bytesToHex(~options={size: 32})
|
|
27
|
-
let fromBool: bool => hex = b => b->Viem.boolToHex(~options={size: 32})
|
package/src/TopicFilter.res.mjs
CHANGED
|
@@ -1,86 +1,12 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Viem from "viem";
|
|
4
|
-
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
5
|
-
|
|
6
|
-
function toTwosComplement(num, bytesLen) {
|
|
7
|
-
let maxValue = (1n << BigInt((bytesLen << 3)));
|
|
8
|
-
let mask = maxValue - 1n;
|
|
9
|
-
return num + maxValue & mask;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
function fromSignedBigInt(val) {
|
|
13
|
-
let val$1 = val >= 0n ? val : toTwosComplement(val, 32);
|
|
14
|
-
return Viem.numberToHex(val$1, {
|
|
15
|
-
size: 32
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
function keccak256(prim) {
|
|
20
|
-
return Viem.keccak256(prim);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function bytesToHex(prim0, prim1) {
|
|
24
|
-
return Viem.bytesToHex(prim0, prim1 !== undefined ? Primitive_option.valFromOption(prim1) : undefined);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function concat(prim) {
|
|
28
|
-
return Viem.concat(prim);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function castToHexUnsafe(val) {
|
|
32
|
-
return val;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function fromBigInt(val) {
|
|
36
|
-
return Viem.numberToHex(val, {
|
|
37
|
-
size: 32
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function fromDynamicString(val) {
|
|
42
|
-
return Viem.keccak256(val);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function fromString(val) {
|
|
46
|
-
return Viem.stringToHex(val, {
|
|
47
|
-
size: 32
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
4
|
|
|
51
5
|
function fromAddress(addr) {
|
|
52
6
|
return Viem.pad(addr);
|
|
53
7
|
}
|
|
54
8
|
|
|
55
|
-
function fromDynamicBytes(bytes) {
|
|
56
|
-
return Viem.keccak256(bytes);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function fromBytes(bytes) {
|
|
60
|
-
return Viem.bytesToHex(bytes, {
|
|
61
|
-
size: 32
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function fromBool(b) {
|
|
66
|
-
return Viem.boolToHex(b, {
|
|
67
|
-
size: 32
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
9
|
export {
|
|
72
|
-
toTwosComplement,
|
|
73
|
-
fromSignedBigInt,
|
|
74
|
-
keccak256,
|
|
75
|
-
bytesToHex,
|
|
76
|
-
concat,
|
|
77
|
-
castToHexUnsafe,
|
|
78
|
-
fromBigInt,
|
|
79
|
-
fromDynamicString,
|
|
80
|
-
fromString,
|
|
81
10
|
fromAddress,
|
|
82
|
-
fromDynamicBytes,
|
|
83
|
-
fromBytes,
|
|
84
|
-
fromBool,
|
|
85
11
|
}
|
|
86
12
|
/* viem Not a pure module */
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
function secondsSince(from) {
|
|
5
|
+
return (performance.now() - from) / 1000;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function secondsBetween(from, to) {
|
|
9
|
+
return (to - from) / 1000;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function now(prim) {
|
|
13
|
+
return performance.now();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
now,
|
|
18
|
+
secondsSince,
|
|
19
|
+
secondsBetween,
|
|
20
|
+
}
|
|
21
|
+
/* No side effect */
|
package/src/bindings/Viem.res
CHANGED
|
@@ -1,52 +1,6 @@
|
|
|
1
|
-
type eventLog = {
|
|
2
|
-
abi: EvmTypes.Abi.t,
|
|
3
|
-
data: string,
|
|
4
|
-
topics: array<EvmTypes.Hex.t>,
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
type decodedEvent<'a> = {
|
|
8
|
-
eventName: string,
|
|
9
|
-
args: 'a,
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
@module("viem") external decodeEventLogOrThrow: eventLog => decodedEvent<'a> = "decodeEventLog"
|
|
13
|
-
|
|
14
1
|
type hex = EvmTypes.Hex.t
|
|
15
2
|
@module("viem") external toHex: 'a => hex = "toHex"
|
|
16
|
-
@module("viem") external keccak256: hex => hex = "keccak256"
|
|
17
|
-
@module("viem") external keccak256Bytes: Uint8Array.t => hex = "keccak256"
|
|
18
3
|
@module("viem") external pad: hex => hex = "pad"
|
|
19
|
-
@module("viem")
|
|
20
|
-
external encodePacked: (~types: array<string>, ~values: array<'a>) => hex = "encodePacked"
|
|
21
4
|
|
|
22
5
|
type sizeOptions = {size: int}
|
|
23
|
-
@module("viem") external intToHex: (int, ~options: sizeOptions=?) => hex = "numberToHex"
|
|
24
6
|
@module("viem") external bigintToHex: (bigint, ~options: sizeOptions=?) => hex = "numberToHex"
|
|
25
|
-
@module("viem") external stringToHex: (string, ~options: sizeOptions=?) => hex = "stringToHex"
|
|
26
|
-
@module("viem") external boolToHex: (bool, ~options: sizeOptions=?) => hex = "boolToHex"
|
|
27
|
-
@module("viem") external bytesToHex: (Uint8Array.t, ~options: sizeOptions=?) => hex = "bytesToHex"
|
|
28
|
-
@module("viem") external concat: array<hex> => hex = "concat"
|
|
29
|
-
|
|
30
|
-
exception ParseError(exn)
|
|
31
|
-
exception UnknownContractName({contractName: string})
|
|
32
|
-
|
|
33
|
-
let parseLogOrThrow = (
|
|
34
|
-
contractNameAbiMapping: dict<EvmTypes.Abi.t>,
|
|
35
|
-
~contractName,
|
|
36
|
-
~topics,
|
|
37
|
-
~data,
|
|
38
|
-
) => {
|
|
39
|
-
switch contractNameAbiMapping->Utils.Dict.dangerouslyGetNonOption(contractName) {
|
|
40
|
-
| None => throw(UnknownContractName({contractName: contractName}))
|
|
41
|
-
| Some(abi) =>
|
|
42
|
-
let viemLog: eventLog = {
|
|
43
|
-
abi,
|
|
44
|
-
data,
|
|
45
|
-
topics,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
try viemLog->decodeEventLogOrThrow catch {
|
|
49
|
-
| exn => throw(ParseError(exn))
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|