envio 3.3.0-alpha.7 → 3.3.0-alpha.8
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 +23 -5
- package/package.json +6 -6
- package/src/Api.res +1 -1
- package/src/Api.res.mjs +1 -1
- package/src/ChainFetching.res +21 -10
- package/src/ChainFetching.res.mjs +11 -10
- package/src/ChainState.res +328 -165
- package/src/ChainState.res.mjs +205 -100
- package/src/ChainState.resi +16 -7
- package/src/Config.res +11 -27
- package/src/Config.res.mjs +8 -7
- package/src/Core.res +7 -0
- package/src/CrossChainState.res +53 -80
- package/src/CrossChainState.res.mjs +43 -59
- package/src/CrossChainState.resi +1 -1
- package/src/Ecosystem.res +3 -3
- package/src/Ecosystem.res.mjs +3 -3
- package/src/Envio.res +14 -9
- package/src/EventConfigBuilder.res +105 -56
- package/src/EventConfigBuilder.res.mjs +69 -33
- package/src/EventProcessing.res +19 -15
- package/src/EventProcessing.res.mjs +13 -12
- package/src/FetchState.res +375 -171
- package/src/FetchState.res.mjs +249 -251
- package/src/HandlerLoader.res +7 -112
- package/src/HandlerLoader.res.mjs +1 -87
- package/src/HandlerRegister.res +209 -6
- package/src/HandlerRegister.res.mjs +90 -5
- package/src/HandlerRegister.resi +13 -2
- package/src/IndexerState.res +6 -3
- package/src/IndexerState.res.mjs +3 -3
- package/src/IndexerState.resi +1 -1
- package/src/IndexingAddresses.res +10 -7
- package/src/IndexingAddresses.res.mjs +8 -7
- package/src/IndexingAddresses.resi +3 -1
- package/src/Internal.res +82 -36
- package/src/Internal.res.mjs +11 -1
- package/src/Main.res +22 -23
- package/src/Main.res.mjs +15 -17
- package/src/Metrics.res +43 -2
- package/src/Metrics.res.mjs +39 -3
- package/src/Prometheus.res +0 -35
- package/src/Prometheus.res.mjs +33 -68
- package/src/RawEvent.res +7 -2
- package/src/RawEvent.res.mjs +4 -4
- package/src/SimulateItems.res +20 -7
- package/src/SimulateItems.res.mjs +7 -11
- package/src/TestIndexer.res +1 -1
- package/src/TestIndexer.res.mjs +1 -1
- package/src/sources/BlockStore.res +46 -0
- package/src/sources/BlockStore.res.mjs +24 -0
- package/src/sources/EventRouter.res +19 -12
- package/src/sources/EventRouter.res.mjs +7 -5
- package/src/sources/Evm.res +54 -4
- package/src/sources/Evm.res.mjs +43 -4
- package/src/sources/EvmChain.res +14 -18
- package/src/sources/EvmChain.res.mjs +12 -13
- package/src/sources/FieldMask.res +39 -0
- package/src/sources/FieldMask.res.mjs +42 -0
- package/src/sources/Fuel.res +5 -2
- package/src/sources/Fuel.res.mjs +4 -3
- package/src/sources/HyperFuelSource.res +31 -40
- package/src/sources/HyperFuelSource.res.mjs +52 -44
- package/src/sources/HyperSync.res +31 -9
- package/src/sources/HyperSync.res.mjs +47 -31
- package/src/sources/HyperSync.resi +10 -3
- package/src/sources/HyperSyncClient.res +15 -4
- package/src/sources/HyperSyncHeightStream.res +1 -8
- package/src/sources/HyperSyncHeightStream.res.mjs +0 -2
- package/src/sources/HyperSyncSource.res +37 -58
- package/src/sources/HyperSyncSource.res.mjs +42 -42
- package/src/sources/RpcSource.res +91 -82
- package/src/sources/RpcSource.res.mjs +76 -45
- package/src/sources/RpcWebSocketHeightStream.res +0 -5
- package/src/sources/RpcWebSocketHeightStream.res.mjs +0 -2
- package/src/sources/SimulateSource.res +5 -3
- package/src/sources/SimulateSource.res.mjs +12 -4
- package/src/sources/Source.res +19 -5
- package/src/sources/SourceManager.res +62 -6
- package/src/sources/SourceManager.res.mjs +55 -8
- package/src/sources/SourceManager.resi +10 -0
- package/src/sources/Svm.res +14 -10
- package/src/sources/Svm.res.mjs +23 -6
- package/src/sources/SvmHyperSyncClient.res +5 -6
- package/src/sources/SvmHyperSyncSource.res +82 -41
- package/src/sources/SvmHyperSyncSource.res.mjs +86 -41
- package/src/sources/TransactionStore.res +6 -107
- package/src/sources/TransactionStore.res.mjs +5 -86
- package/svm.schema.json +19 -0
package/index.d.ts
CHANGED
|
@@ -979,13 +979,24 @@ export type SvmInstructionParams = {
|
|
|
979
979
|
readonly extraAccounts: readonly string[];
|
|
980
980
|
};
|
|
981
981
|
|
|
982
|
-
/**
|
|
982
|
+
/** Permissive fallback shape for an instruction's `block`. The generated
|
|
983
|
+
* per-instruction type narrows this to `slot`/`hash` (always present) and
|
|
984
|
+
* `time` (always present but possibly `undefined`), plus the selected
|
|
985
|
+
* `field_selection.block_fields`. */
|
|
983
986
|
export type SvmInstructionBlock = {
|
|
984
987
|
/** Slot this instruction's block was matched in. */
|
|
985
988
|
readonly slot: number;
|
|
986
|
-
|
|
987
|
-
|
|
989
|
+
/** Unix block time (seconds). Absent when HyperSync/Solana doesn't report a
|
|
990
|
+
* block time for this slot. */
|
|
991
|
+
readonly time?: number;
|
|
992
|
+
/** Block hash. */
|
|
988
993
|
readonly hash: string;
|
|
994
|
+
/** Block height. Select via `field_selection.block_fields`. */
|
|
995
|
+
readonly height?: number;
|
|
996
|
+
/** Parent slot. Select via `field_selection.block_fields`. */
|
|
997
|
+
readonly parentSlot?: number;
|
|
998
|
+
/** Parent block hash. Select via `field_selection.block_fields`. */
|
|
999
|
+
readonly parentHash?: string;
|
|
989
1000
|
};
|
|
990
1001
|
|
|
991
1002
|
export type SvmTokenBalance = {
|
|
@@ -1016,6 +1027,7 @@ export type SvmLog = {
|
|
|
1016
1027
|
export type SvmInstruction<
|
|
1017
1028
|
Params extends SvmInstructionParams = SvmInstructionParams,
|
|
1018
1029
|
Tx = SvmTransaction,
|
|
1030
|
+
Block = SvmInstructionBlock,
|
|
1019
1031
|
> = {
|
|
1020
1032
|
/** Program name as declared under `programs[].name` in `config.yaml`. */
|
|
1021
1033
|
readonly programName: string;
|
|
@@ -1041,7 +1053,12 @@ export type SvmInstruction<
|
|
|
1041
1053
|
/** Present when the instruction's `include_logs` is `true`; only logs
|
|
1042
1054
|
* scoped to this exact instruction (matching `instruction_address`). */
|
|
1043
1055
|
readonly logs?: readonly SvmLog[];
|
|
1044
|
-
|
|
1056
|
+
/** The block this instruction's slot belongs to. Carries `slot`/`hash`
|
|
1057
|
+
* (always present) and `time` (always present but possibly `undefined`),
|
|
1058
|
+
* plus the fields selected via this instruction's
|
|
1059
|
+
* `field_selection.block_fields`; unselected fields are typed as
|
|
1060
|
+
* `FieldNotSelected<...>`. */
|
|
1061
|
+
readonly block: Block;
|
|
1045
1062
|
};
|
|
1046
1063
|
|
|
1047
1064
|
/** Arguments passed to handlers registered via `indexer.onInstruction`. */
|
|
@@ -1315,7 +1332,8 @@ type SvmEcosystem<Config extends IndexerConfigTypes = GlobalConfig> =
|
|
|
1315
1332
|
Config,
|
|
1316
1333
|
SvmInstruction<
|
|
1317
1334
|
SvmParamsFromProgramTable<Programs[P][I]>,
|
|
1318
|
-
Programs[P][I]["transaction"]
|
|
1335
|
+
Programs[P][I]["transaction"],
|
|
1336
|
+
Programs[P][I]["block"]
|
|
1319
1337
|
>
|
|
1320
1338
|
>,
|
|
1321
1339
|
) => Promise<void>,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.3.0-alpha.
|
|
3
|
+
"version": "3.3.0-alpha.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.mjs",
|
|
@@ -69,10 +69,10 @@
|
|
|
69
69
|
"tsx": "4.21.0"
|
|
70
70
|
},
|
|
71
71
|
"optionalDependencies": {
|
|
72
|
-
"envio-linux-x64": "3.3.0-alpha.
|
|
73
|
-
"envio-linux-x64-musl": "3.3.0-alpha.
|
|
74
|
-
"envio-linux-arm64": "3.3.0-alpha.
|
|
75
|
-
"envio-darwin-x64": "3.3.0-alpha.
|
|
76
|
-
"envio-darwin-arm64": "3.3.0-alpha.
|
|
72
|
+
"envio-linux-x64": "3.3.0-alpha.8",
|
|
73
|
+
"envio-linux-x64-musl": "3.3.0-alpha.8",
|
|
74
|
+
"envio-linux-arm64": "3.3.0-alpha.8",
|
|
75
|
+
"envio-darwin-x64": "3.3.0-alpha.8",
|
|
76
|
+
"envio-darwin-arm64": "3.3.0-alpha.8"
|
|
77
77
|
}
|
|
78
78
|
}
|
package/src/Api.res
CHANGED
|
@@ -9,7 +9,7 @@ let createTestIndexer: unit => unknown = () => {
|
|
|
9
9
|
NodeJs.Path.getDirname(NodeJs.ImportMeta.importMeta),
|
|
10
10
|
"TestIndexerWorker.res.mjs",
|
|
11
11
|
)->NodeJs.Path.toString
|
|
12
|
-
TestIndexer.makeCreateTestIndexer(~config=Config.
|
|
12
|
+
TestIndexer.makeCreateTestIndexer(~config=Config.load(), ~workerPath)()->(
|
|
13
13
|
Utils.magic: TestIndexer.t<'a> => unknown
|
|
14
14
|
)
|
|
15
15
|
}
|
package/src/Api.res.mjs
CHANGED
|
@@ -10,7 +10,7 @@ let indexer = Main.getGlobalIndexer();
|
|
|
10
10
|
|
|
11
11
|
function createTestIndexer() {
|
|
12
12
|
let workerPath = Path.join(NodeJs.Path.getDirname(import.meta), "TestIndexerWorker.res.mjs");
|
|
13
|
-
return TestIndexer.makeCreateTestIndexer(Config.
|
|
13
|
+
return TestIndexer.makeCreateTestIndexer(Config.load(), workerPath)();
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export {
|
package/src/ChainFetching.res
CHANGED
|
@@ -11,12 +11,18 @@ type partitionQueryResponse = {
|
|
|
11
11
|
let runContractRegistersOrThrow = async (
|
|
12
12
|
~itemsWithContractRegister: array<Internal.item>,
|
|
13
13
|
~config: Config.t,
|
|
14
|
-
~
|
|
14
|
+
~transactionStore: option<TransactionStore.t>,
|
|
15
|
+
~blockStore: option<BlockStore.t>,
|
|
15
16
|
) => {
|
|
16
|
-
// contractRegister handlers can read event.transaction, so
|
|
17
|
-
// selected fields onto the payloads before running them. All
|
|
18
|
-
// the chain being fetched, hence its single page
|
|
19
|
-
await ChainState.materializePageItems(
|
|
17
|
+
// contractRegister handlers can read event.transaction and event.block, so
|
|
18
|
+
// materialise the selected fields onto the payloads before running them. All
|
|
19
|
+
// items belong to the chain being fetched, hence its single page stores.
|
|
20
|
+
await ChainState.materializePageItems(
|
|
21
|
+
~items=itemsWithContractRegister,
|
|
22
|
+
~transactionStore,
|
|
23
|
+
~blockStore,
|
|
24
|
+
~ecosystem=config.ecosystem.name,
|
|
25
|
+
)
|
|
20
26
|
|
|
21
27
|
let itemsWithDcs = []
|
|
22
28
|
|
|
@@ -44,8 +50,8 @@ let runContractRegistersOrThrow = async (
|
|
|
44
50
|
let item = itemsWithContractRegister->Array.getUnsafe(idx)
|
|
45
51
|
let eventItem = item->Internal.castUnsafeEventItem
|
|
46
52
|
let contractRegister = switch eventItem {
|
|
47
|
-
| {
|
|
48
|
-
| {
|
|
53
|
+
| {onEventRegistration: {contractRegister: Some(contractRegister)}} => contractRegister
|
|
54
|
+
| {onEventRegistration: {contractRegister: None, eventConfig: {name: eventName}}} =>
|
|
49
55
|
// Unexpected case, since we should pass only events with contract register to this function
|
|
50
56
|
JsError.throwWithMessage("Contract register is not set for event " ++ eventName)
|
|
51
57
|
}
|
|
@@ -113,6 +119,7 @@ let rec onQueryResponse = async (
|
|
|
113
119
|
let {
|
|
114
120
|
parsedQueueItems,
|
|
115
121
|
transactionStore,
|
|
122
|
+
blockStore,
|
|
116
123
|
latestFetchedBlockNumber,
|
|
117
124
|
latestFetchedBlockTimestamp,
|
|
118
125
|
stats,
|
|
@@ -142,7 +149,7 @@ let rec onQueryResponse = async (
|
|
|
142
149
|
|
|
143
150
|
let numContractRegisterEvents = parsedQueueItems->Array.reduce(0, (count, item) => {
|
|
144
151
|
let eventItem = item->Internal.castUnsafeEventItem
|
|
145
|
-
eventItem.
|
|
152
|
+
eventItem.onEventRegistration.contractRegister !== None ? count + 1 : count
|
|
146
153
|
})
|
|
147
154
|
Logging.trace({
|
|
148
155
|
"msg": "Finished querying",
|
|
@@ -210,7 +217,7 @@ let rec onQueryResponse = async (
|
|
|
210
217
|
for idx in 0 to parsedQueueItems->Array.length - 1 {
|
|
211
218
|
let item = parsedQueueItems->Array.getUnsafe(idx)
|
|
212
219
|
let eventItem = item->Internal.castUnsafeEventItem
|
|
213
|
-
if eventItem.
|
|
220
|
+
if eventItem.onEventRegistration.contractRegister !== None {
|
|
214
221
|
itemsWithContractRegister->Array.push(item)
|
|
215
222
|
}
|
|
216
223
|
// TODO: Don't really need to keep it in the queue
|
|
@@ -234,6 +241,7 @@ let rec onQueryResponse = async (
|
|
|
234
241
|
},
|
|
235
242
|
~query,
|
|
236
243
|
~transactionStore,
|
|
244
|
+
~blockStore,
|
|
237
245
|
)
|
|
238
246
|
ChainMetadata.stage(state)
|
|
239
247
|
scheduleFetch()
|
|
@@ -246,7 +254,8 @@ let rec onQueryResponse = async (
|
|
|
246
254
|
switch await runContractRegistersOrThrow(
|
|
247
255
|
~itemsWithContractRegister,
|
|
248
256
|
~config=state->IndexerState.config,
|
|
249
|
-
~
|
|
257
|
+
~transactionStore,
|
|
258
|
+
~blockStore,
|
|
250
259
|
) {
|
|
251
260
|
| exception exn => IndexerState.errorExit(state, exn->ErrorHandling.make)
|
|
252
261
|
| newItemsWithDcs => proceed(~newItemsWithDcs)
|
|
@@ -264,6 +273,7 @@ and applyQueryResponse = (
|
|
|
264
273
|
~latestFetchedBlock,
|
|
265
274
|
~query,
|
|
266
275
|
~transactionStore,
|
|
276
|
+
~blockStore,
|
|
267
277
|
) => {
|
|
268
278
|
let chainState = state->IndexerState.getChainState(~chain)
|
|
269
279
|
let wasFetchingAtHead = chainState->ChainState.isFetchingAtHead
|
|
@@ -275,6 +285,7 @@ and applyQueryResponse = (
|
|
|
275
285
|
~newItemsWithDcs,
|
|
276
286
|
~knownHeight,
|
|
277
287
|
~transactionStore,
|
|
288
|
+
~blockStore,
|
|
278
289
|
)
|
|
279
290
|
|
|
280
291
|
// In auto-exit mode, set endBlock to the first event's block when events arrive.
|
|
@@ -17,8 +17,8 @@ import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
|
17
17
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
18
18
|
import * as ContractRegisterContext from "./ContractRegisterContext.res.mjs";
|
|
19
19
|
|
|
20
|
-
async function runContractRegistersOrThrow(itemsWithContractRegister, config,
|
|
21
|
-
await ChainState.materializePageItems(itemsWithContractRegister,
|
|
20
|
+
async function runContractRegistersOrThrow(itemsWithContractRegister, config, transactionStore, blockStore) {
|
|
21
|
+
await ChainState.materializePageItems(itemsWithContractRegister, transactionStore, blockStore, config.ecosystem.name);
|
|
22
22
|
let itemsWithDcs = [];
|
|
23
23
|
let onRegister = (item, contractAddress, contractName) => {
|
|
24
24
|
let dc_registrationBlock = item.blockNumber;
|
|
@@ -38,9 +38,9 @@ async function runContractRegistersOrThrow(itemsWithContractRegister, config, pa
|
|
|
38
38
|
let promises = [];
|
|
39
39
|
for (let idx = 0, idx_finish = itemsWithContractRegister.length; idx < idx_finish; ++idx) {
|
|
40
40
|
let item = itemsWithContractRegister[idx];
|
|
41
|
-
let match = item.
|
|
41
|
+
let match = item.onEventRegistration;
|
|
42
42
|
let contractRegister = match.contractRegister;
|
|
43
|
-
let contractRegister$1 = contractRegister !== undefined ? contractRegister : Stdlib_JsError.throwWithMessage("Contract register is not set for event " + match.name);
|
|
43
|
+
let contractRegister$1 = contractRegister !== undefined ? contractRegister : Stdlib_JsError.throwWithMessage("Contract register is not set for event " + match.eventConfig.name);
|
|
44
44
|
let errorMessage = "Event contractRegister failed, please fix the error to keep the indexer running smoothly";
|
|
45
45
|
try {
|
|
46
46
|
let params = {
|
|
@@ -72,10 +72,10 @@ async function runContractRegistersOrThrow(itemsWithContractRegister, config, pa
|
|
|
72
72
|
return itemsWithDcs;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function applyQueryResponse(state, chain, newItems, newItemsWithDcs, knownHeight, latestFetchedBlock, query, transactionStore) {
|
|
75
|
+
function applyQueryResponse(state, chain, newItems, newItemsWithDcs, knownHeight, latestFetchedBlock, query, transactionStore, blockStore) {
|
|
76
76
|
let chainState = IndexerState.getChainState(state, chain);
|
|
77
77
|
let wasFetchingAtHead = ChainState.isFetchingAtHead(chainState);
|
|
78
|
-
ChainState.handleQueryResult(chainState, query, newItems, newItemsWithDcs, latestFetchedBlock, knownHeight, transactionStore);
|
|
78
|
+
ChainState.handleQueryResult(chainState, query, newItems, newItemsWithDcs, latestFetchedBlock, knownHeight, transactionStore, blockStore);
|
|
79
79
|
if (IndexerState.exitAfterFirstEventBlock(state) && newItems.length !== 0) {
|
|
80
80
|
ChainState.setEndBlockToFirstEvent(chainState, newItems[0].blockNumber);
|
|
81
81
|
}
|
|
@@ -96,6 +96,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
96
96
|
let latestFetchedBlockTimestamp = response.latestFetchedBlockTimestamp;
|
|
97
97
|
let latestFetchedBlockNumber = response.latestFetchedBlockNumber;
|
|
98
98
|
let fromBlockQueried = response.fromBlockQueried;
|
|
99
|
+
let blockStore = response.blockStore;
|
|
99
100
|
let transactionStore = response.transactionStore;
|
|
100
101
|
let parsedQueueItems = response.parsedQueueItems;
|
|
101
102
|
let knownHeight = response.knownHeight;
|
|
@@ -104,7 +105,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
104
105
|
}
|
|
105
106
|
Prometheus.FetchingBlockRange.increment(chain, stats["total time elapsed (s)"], Stdlib_Option.getOr(stats["parsing time (s)"], 0), parsedQueueItems.length, (latestFetchedBlockNumber - fromBlockQueried | 0) + 1 | 0);
|
|
106
107
|
let numContractRegisterEvents = Stdlib_Array.reduce(parsedQueueItems, 0, (count, item) => {
|
|
107
|
-
if (item.
|
|
108
|
+
if (item.onEventRegistration.contractRegister !== undefined) {
|
|
108
109
|
return count + 1 | 0;
|
|
109
110
|
} else {
|
|
110
111
|
return count;
|
|
@@ -142,7 +143,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
142
143
|
let newItems = [];
|
|
143
144
|
for (let idx = 0, idx_finish = parsedQueueItems.length; idx < idx_finish; ++idx) {
|
|
144
145
|
let item = parsedQueueItems[idx];
|
|
145
|
-
if (item.
|
|
146
|
+
if (item.onEventRegistration.contractRegister !== undefined) {
|
|
146
147
|
itemsWithContractRegister.push(item);
|
|
147
148
|
}
|
|
148
149
|
newItems.push(item);
|
|
@@ -152,7 +153,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
152
153
|
applyQueryResponse(state, chain, newItems, newItemsWithDcs, knownHeight, {
|
|
153
154
|
blockNumber: latestFetchedBlockNumber,
|
|
154
155
|
blockTimestamp: latestFetchedBlockTimestamp
|
|
155
|
-
}, query, transactionStore);
|
|
156
|
+
}, query, transactionStore, blockStore);
|
|
156
157
|
ChainMetadata.stage(state);
|
|
157
158
|
scheduleFetch();
|
|
158
159
|
return scheduleProcessing();
|
|
@@ -163,7 +164,7 @@ async function onQueryResponse(state, param, stateId, scheduleFetch, schedulePro
|
|
|
163
164
|
}
|
|
164
165
|
let newItemsWithDcs;
|
|
165
166
|
try {
|
|
166
|
-
newItemsWithDcs = await runContractRegistersOrThrow(itemsWithContractRegister, IndexerState.config(state), transactionStore);
|
|
167
|
+
newItemsWithDcs = await runContractRegistersOrThrow(itemsWithContractRegister, IndexerState.config(state), transactionStore, blockStore);
|
|
167
168
|
} catch (raw_exn) {
|
|
168
169
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
169
170
|
return IndexerState.errorExit(state, ErrorHandling.make(exn, undefined, undefined));
|