envio 3.3.0-alpha.9 → 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 +134 -55
- package/src/ChainState.res.mjs +78 -36
- package/src/ChainState.resi +14 -2
- package/src/Config.res +9 -5
- package/src/Config.res.mjs +2 -2
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +12 -0
- package/src/CrossChainState.res +115 -34
- package/src/CrossChainState.res.mjs +37 -14
- package/src/EffectState.res +100 -0
- package/src/EffectState.res.mjs +74 -0
- package/src/EffectState.resi +32 -0
- package/src/Envio.res +25 -7
- package/src/Envio.res.mjs +15 -19
- package/src/EventConfigBuilder.res +21 -46
- package/src/EventConfigBuilder.res.mjs +18 -25
- package/src/EventProcessing.res +8 -5
- package/src/EventProcessing.res.mjs +2 -1
- package/src/FetchState.res +814 -467
- package/src/FetchState.res.mjs +541 -369
- package/src/HandlerRegister.res +3 -1
- package/src/HandlerRegister.res.mjs +3 -2
- package/src/InMemoryStore.res +14 -26
- package/src/InMemoryStore.res.mjs +6 -19
- package/src/IndexerState.res +15 -39
- package/src/IndexerState.res.mjs +18 -29
- package/src/IndexerState.resi +2 -10
- package/src/Internal.res +98 -14
- package/src/Internal.res.mjs +96 -2
- package/src/LoadLayer.res +44 -24
- package/src/LoadLayer.res.mjs +43 -20
- package/src/LoadLayer.resi +1 -0
- package/src/LogSelection.res +0 -62
- package/src/LogSelection.res.mjs +0 -74
- package/src/Metrics.res +1 -1
- package/src/Metrics.res.mjs +1 -1
- package/src/Persistence.res +12 -3
- package/src/PgStorage.res +155 -82
- package/src/PgStorage.res.mjs +130 -77
- package/src/Prometheus.res +20 -10
- package/src/Prometheus.res.mjs +22 -10
- package/src/PruneStaleHistory.res +146 -35
- package/src/PruneStaleHistory.res.mjs +114 -20
- package/src/RawEvent.res +2 -2
- package/src/Rollback.res +32 -13
- package/src/Rollback.res.mjs +24 -11
- package/src/SimulateDeadInputTracker.res +1 -1
- package/src/SimulateItems.res +38 -6
- package/src/SimulateItems.res.mjs +28 -9
- package/src/TestIndexer.res +2 -2
- package/src/TestIndexer.res.mjs +2 -2
- package/src/TopicFilter.res +1 -25
- package/src/TopicFilter.res.mjs +0 -74
- package/src/UserContext.res +62 -23
- package/src/UserContext.res.mjs +26 -6
- package/src/Writing.res +60 -21
- package/src/Writing.res.mjs +27 -9
- package/src/bindings/NodeJs.res +5 -0
- package/src/bindings/Viem.res +0 -5
- package/src/sources/EventRouter.res +0 -21
- package/src/sources/EventRouter.res.mjs +0 -12
- package/src/sources/EvmChain.res +2 -27
- package/src/sources/EvmChain.res.mjs +2 -23
- package/src/sources/EvmRpcClient.res +58 -23
- package/src/sources/EvmRpcClient.res.mjs +11 -5
- package/src/sources/HyperSync.res +9 -38
- package/src/sources/HyperSync.res.mjs +16 -28
- package/src/sources/HyperSync.resi +2 -2
- package/src/sources/HyperSyncClient.res +88 -11
- package/src/sources/HyperSyncClient.res.mjs +39 -6
- package/src/sources/HyperSyncSource.res +18 -199
- package/src/sources/HyperSyncSource.res.mjs +9 -128
- package/src/sources/Rpc.res +0 -32
- package/src/sources/Rpc.res.mjs +1 -46
- package/src/sources/RpcSource.res +129 -522
- package/src/sources/RpcSource.res.mjs +161 -366
- package/src/sources/SimulateSource.res +37 -19
- package/src/sources/SimulateSource.res.mjs +27 -10
- package/src/sources/SourceManager.res +3 -7
- package/src/sources/SourceManager.res.mjs +2 -7
- package/src/sources/SourceManager.resi +0 -2
- package/src/sources/SvmHyperSyncSource.res +13 -3
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain.t): Source.t => {
|
|
2
|
-
|
|
3
|
-
// Return all items on the first call and empty on subsequent calls to prevent
|
|
4
|
-
// duplicate event processing.
|
|
5
|
-
let delivered = ref(false)
|
|
2
|
+
let reportedHeight = max(endBlock, 1)
|
|
6
3
|
|
|
7
4
|
{
|
|
8
5
|
name: "SimulateSource",
|
|
@@ -16,38 +13,59 @@ let make = (~items: array<Internal.item>, ~endBlock: int, ~chain: ChainMap.Chain
|
|
|
16
13
|
},
|
|
17
14
|
getHeightOrThrow: () => {
|
|
18
15
|
// Report at least height 1 so the engine doesn't treat 0 as "no blocks available"
|
|
19
|
-
Promise.resolve({Source.height:
|
|
16
|
+
Promise.resolve({Source.height: reportedHeight, requestStats: []})
|
|
20
17
|
},
|
|
21
18
|
getItemsOrThrow: (
|
|
22
|
-
~fromBlock
|
|
23
|
-
~toBlock
|
|
19
|
+
~fromBlock,
|
|
20
|
+
~toBlock,
|
|
24
21
|
~addressesByContractName as _,
|
|
25
|
-
~contractNameByAddress
|
|
22
|
+
~contractNameByAddress,
|
|
26
23
|
~knownHeight as _,
|
|
27
24
|
~partitionId as _,
|
|
28
|
-
~selection
|
|
25
|
+
~selection: FetchState.selection,
|
|
29
26
|
~itemsTarget as _,
|
|
30
27
|
~retry as _,
|
|
31
28
|
~logger as _,
|
|
32
29
|
) => {
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
30
|
+
// Mirror a real backend: return only the items this query would match —
|
|
31
|
+
// in the block range, part of the selection, and (for non-wildcard events)
|
|
32
|
+
// emitted by an address the partition is querying. Wildcard events are
|
|
33
|
+
// over-fetched regardless of srcAddress, leaving the client-side address
|
|
34
|
+
// filter to gate them exactly as it does for a HyperSync response. Overlapping
|
|
35
|
+
// queries may return the same item more than once; the buffer dedups it.
|
|
36
|
+
let toBlockQueried = switch toBlock {
|
|
37
|
+
| Some(toBlock) => toBlock
|
|
38
|
+
| None => reportedHeight
|
|
39
39
|
}
|
|
40
|
+
let selectionEventIds = Utils.Set.make()
|
|
41
|
+
selection.onEventRegistrations->Array.forEach(reg =>
|
|
42
|
+
selectionEventIds->Utils.Set.add(reg.eventConfig.id)->ignore
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
let parsedQueueItems = items->Array.filter(item => {
|
|
46
|
+
let eventItem = item->Internal.castUnsafeEventItem
|
|
47
|
+
let {blockNumber, onEventRegistration} = eventItem
|
|
48
|
+
if blockNumber < fromBlock || blockNumber > toBlockQueried {
|
|
49
|
+
false
|
|
50
|
+
} else if !(selectionEventIds->Utils.Set.has(onEventRegistration.eventConfig.id)) {
|
|
51
|
+
false
|
|
52
|
+
} else if onEventRegistration.isWildcard {
|
|
53
|
+
true
|
|
54
|
+
} else {
|
|
55
|
+
let sa = eventItem.payload->Internal.getPayloadSrcAddress->Address.toString
|
|
56
|
+
contractNameByAddress->Utils.Dict.dangerouslyGetNonOption(sa)->Option.isSome
|
|
57
|
+
}
|
|
58
|
+
})
|
|
40
59
|
|
|
41
|
-
let reportedHeight = max(endBlock, 1)
|
|
42
60
|
Promise.resolve({
|
|
43
61
|
Source.knownHeight: reportedHeight,
|
|
44
62
|
blockHashes: [],
|
|
45
|
-
parsedQueueItems
|
|
63
|
+
parsedQueueItems,
|
|
46
64
|
// Simulate keeps the transaction and block inline on the payload; no store pages.
|
|
47
65
|
transactionStore: None,
|
|
48
66
|
blockStore: None,
|
|
49
|
-
fromBlockQueried:
|
|
50
|
-
latestFetchedBlockNumber:
|
|
67
|
+
fromBlockQueried: fromBlock,
|
|
68
|
+
latestFetchedBlockNumber: toBlockQueried,
|
|
51
69
|
latestFetchedBlockTimestamp: 0,
|
|
52
70
|
stats: {
|
|
53
71
|
totalTimeElapsed: 0.,
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
4
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
5
|
|
|
5
6
|
function make(items, endBlock, chain) {
|
|
6
|
-
let
|
|
7
|
-
contents: false
|
|
8
|
-
};
|
|
7
|
+
let reportedHeight = Primitive_int.max(endBlock, 1);
|
|
9
8
|
return {
|
|
10
9
|
name: "SimulateSource",
|
|
11
10
|
sourceFor: "Sync",
|
|
@@ -20,20 +19,38 @@ function make(items, endBlock, chain) {
|
|
|
20
19
|
requestStats: []
|
|
21
20
|
}),
|
|
22
21
|
getHeightOrThrow: () => Promise.resolve({
|
|
23
|
-
height:
|
|
22
|
+
height: reportedHeight,
|
|
24
23
|
requestStats: []
|
|
25
24
|
}),
|
|
26
|
-
getItemsOrThrow: (
|
|
27
|
-
let
|
|
28
|
-
let
|
|
25
|
+
getItemsOrThrow: (fromBlock, toBlock, param, contractNameByAddress, param$1, param$2, selection, param$3, param$4, param$5) => {
|
|
26
|
+
let toBlockQueried = toBlock !== undefined ? toBlock : reportedHeight;
|
|
27
|
+
let selectionEventIds = new Set();
|
|
28
|
+
selection.onEventRegistrations.forEach(reg => {
|
|
29
|
+
selectionEventIds.add(reg.eventConfig.id);
|
|
30
|
+
});
|
|
31
|
+
let parsedQueueItems = items.filter(item => {
|
|
32
|
+
let blockNumber = item.blockNumber;
|
|
33
|
+
if (blockNumber < fromBlock || blockNumber > toBlockQueried) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
let onEventRegistration = item.onEventRegistration;
|
|
37
|
+
if (!selectionEventIds.has(onEventRegistration.eventConfig.id)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
if (onEventRegistration.isWildcard) {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
let sa = item.payload.srcAddress;
|
|
44
|
+
return Stdlib_Option.isSome(contractNameByAddress[sa]);
|
|
45
|
+
});
|
|
29
46
|
return Promise.resolve({
|
|
30
47
|
knownHeight: reportedHeight,
|
|
31
48
|
blockHashes: [],
|
|
32
|
-
parsedQueueItems:
|
|
49
|
+
parsedQueueItems: parsedQueueItems,
|
|
33
50
|
transactionStore: undefined,
|
|
34
51
|
blockStore: undefined,
|
|
35
|
-
fromBlockQueried:
|
|
36
|
-
latestFetchedBlockNumber:
|
|
52
|
+
fromBlockQueried: fromBlock,
|
|
53
|
+
latestFetchedBlockNumber: toBlockQueried,
|
|
37
54
|
latestFetchedBlockTimestamp: 0,
|
|
38
55
|
stats: {
|
|
39
56
|
"total time elapsed (s)": 0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
type sourceManagerStatus = Idle | WaitingForNewBlock |
|
|
1
|
+
type sourceManagerStatus = Idle | WaitingForNewBlock | Querying
|
|
2
2
|
|
|
3
3
|
// Cumulative per-method request count/time for a source, aggregated from the
|
|
4
4
|
// requestStat arrays returned by its methods. Rendered into
|
|
@@ -92,10 +92,6 @@ let getRequestStatSamples = (sourceManager: t): array<requestStatSample> => {
|
|
|
92
92
|
samples
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
// Partition queries currently in flight on this chain's sources. Summed across
|
|
96
|
-
// chains by CrossChainState to enforce the indexer-wide concurrency budget.
|
|
97
|
-
let inFlightCount = sourceManager => sourceManager.fetchingPartitionsCount
|
|
98
|
-
|
|
99
95
|
let getRateLimitTimeMs = sourceManager =>
|
|
100
96
|
sourceManager.committedRateLimitTimeMs +.
|
|
101
97
|
switch sourceManager.activeRateLimitStartMs {
|
|
@@ -259,7 +255,7 @@ let trackNewStatus = (sourceManager: t, ~newStatus) => {
|
|
|
259
255
|
let promCounter = switch sourceManager.status {
|
|
260
256
|
| Idle => Prometheus.IndexingIdleTime.counter
|
|
261
257
|
| WaitingForNewBlock => Prometheus.IndexingSourceWaitingTime.counter
|
|
262
|
-
|
|
|
258
|
+
| Querying => Prometheus.IndexingQueryTime.counter
|
|
263
259
|
}
|
|
264
260
|
promCounter->Prometheus.SafeCounter.handleFloat(
|
|
265
261
|
~labels=sourceManager.activeSource.chain->ChainMap.Chain.toChainId,
|
|
@@ -311,7 +307,7 @@ let dispatch = async (
|
|
|
311
307
|
~concurrency=sourceManager.fetchingPartitionsCount,
|
|
312
308
|
~chainId=sourceManager.activeSource.chain->ChainMap.Chain.toChainId,
|
|
313
309
|
)
|
|
314
|
-
sourceManager->trackNewStatus(~newStatus=
|
|
310
|
+
sourceManager->trackNewStatus(~newStatus=Querying)
|
|
315
311
|
let _ = await queries
|
|
316
312
|
->Array.map(q => {
|
|
317
313
|
let promise = q->executeQuery
|
|
@@ -52,10 +52,6 @@ function getRequestStatSamples(sourceManager) {
|
|
|
52
52
|
return samples;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
function inFlightCount(sourceManager) {
|
|
56
|
-
return sourceManager.fetchingPartitionsCount;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
55
|
function getRateLimitTimeMs(sourceManager) {
|
|
60
56
|
let startMs = sourceManager.activeRateLimitStartMs;
|
|
61
57
|
return sourceManager.committedRateLimitTimeMs + (
|
|
@@ -204,7 +200,7 @@ function trackNewStatus(sourceManager, newStatus) {
|
|
|
204
200
|
case "WaitingForNewBlock" :
|
|
205
201
|
promCounter = Prometheus.IndexingSourceWaitingTime.counter;
|
|
206
202
|
break;
|
|
207
|
-
case "
|
|
203
|
+
case "Querying" :
|
|
208
204
|
promCounter = Prometheus.IndexingQueryTime.counter;
|
|
209
205
|
break;
|
|
210
206
|
}
|
|
@@ -237,7 +233,7 @@ async function dispatch(sourceManager, fetchState, executeQuery, waitForNewBlock
|
|
|
237
233
|
let queries = action._0;
|
|
238
234
|
sourceManager.fetchingPartitionsCount = sourceManager.fetchingPartitionsCount + queries.length | 0;
|
|
239
235
|
Prometheus.IndexingConcurrency.set(sourceManager.fetchingPartitionsCount, sourceManager.activeSource.chain);
|
|
240
|
-
trackNewStatus(sourceManager, "
|
|
236
|
+
trackNewStatus(sourceManager, "Querying");
|
|
241
237
|
await Promise.all(queries.map(q => {
|
|
242
238
|
let promise = executeQuery(q);
|
|
243
239
|
promise.then(param => {
|
|
@@ -719,7 +715,6 @@ export {
|
|
|
719
715
|
make,
|
|
720
716
|
getActiveSource,
|
|
721
717
|
getRequestStatSamples,
|
|
722
|
-
inFlightCount,
|
|
723
718
|
onReorg,
|
|
724
719
|
dispatch,
|
|
725
720
|
waitForNewBlock,
|
|
@@ -285,8 +285,8 @@ let make = (
|
|
|
285
285
|
): t => {
|
|
286
286
|
let name = "SvmHyperSync"
|
|
287
287
|
|
|
288
|
-
// Definitions drive query/decode building;
|
|
289
|
-
//
|
|
288
|
+
// Definitions drive query/decode building; registrations drive routing and
|
|
289
|
+
// are attached directly to decoded runtime items.
|
|
290
290
|
let eventConfigs =
|
|
291
291
|
onEventRegistrations->Array.map(reg =>
|
|
292
292
|
reg.eventConfig->(Utils.magic: Internal.eventConfig => Internal.svmInstructionEventConfig)
|
|
@@ -488,6 +488,16 @@ let make = (
|
|
|
488
488
|
|
|
489
489
|
switch maybeConfig {
|
|
490
490
|
| None => ()
|
|
491
|
+
// Exclude instructions from failed transactions. HyperSync has no
|
|
492
|
+
// server-side predicate to filter instructions by parent-transaction
|
|
493
|
+
// success (`InstructionSelection` only exposes `is_inner`, and
|
|
494
|
+
// instruction/transaction selections union at block level rather than
|
|
495
|
+
// joining), so we filter client-side on the `isCommitted` flag HyperSync
|
|
496
|
+
// already delivers on every instruction row (a required column, zero extra
|
|
497
|
+
// bandwidth). When HyperSync adds a server-side `is_committed` predicate the
|
|
498
|
+
// query can push this down and the client-side check becomes a redundant
|
|
499
|
+
// safety net.
|
|
500
|
+
| Some(_) if !instr.isCommitted => ()
|
|
491
501
|
| Some(onEventRegistration) =>
|
|
492
502
|
let eventConfig =
|
|
493
503
|
onEventRegistration.eventConfig->(
|
|
@@ -521,7 +531,7 @@ let make = (
|
|
|
521
531
|
parsedQueueItems
|
|
522
532
|
->Array.push(
|
|
523
533
|
Internal.Event({
|
|
524
|
-
onEventRegistration,
|
|
534
|
+
onEventRegistration: (onEventRegistration :> Internal.onEventRegistration),
|
|
525
535
|
chain,
|
|
526
536
|
blockNumber: instr.slot,
|
|
527
537
|
logIndex: synthLogIndex(instr),
|
|
@@ -415,7 +415,7 @@ function make(param) {
|
|
|
415
415
|
let byteLengths = Stdlib_Option.getOr(orderingByProgram[instr.programId], []);
|
|
416
416
|
let contractAddress = instr.programId;
|
|
417
417
|
let maybeConfig = probeRouter(eventRouter, programId, instr, byteLengths, contractAddress, contractNameByAddress);
|
|
418
|
-
if (maybeConfig !== undefined) {
|
|
418
|
+
if (maybeConfig !== undefined && instr.isCommitted) {
|
|
419
419
|
let eventConfig = maybeConfig.eventConfig;
|
|
420
420
|
let logKey = instr.slot.toString() + ":" + instr.transactionIndex.toString() + ":" + serializeInstructionAddress(instr.instructionAddress);
|
|
421
421
|
let maybeLogs = Stdlib_Option.map(logsByKey[logKey], logs => logs.map(log => ({
|