envio 3.10.0-subgraph → 3.11.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/evm.schema.json +21 -4
- package/fuel.schema.json +21 -4
- package/index.d.ts +1 -1
- package/package.json +6 -6
- package/src/ChainState.res +9 -73
- package/src/ChainState.res.mjs +6 -58
- package/src/Config.res +73 -27
- package/src/Config.res.mjs +71 -21
- package/src/Core.res +0 -15
- package/src/Core.res.mjs +0 -11
- package/src/EventConfigBuilder.res +14 -10
- package/src/EventConfigBuilder.res.mjs +6 -4
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +6 -8
- package/src/HandlerLoader.res +8 -20
- package/src/HandlerLoader.res.mjs +2 -11
- package/src/HandlerRegister.res +12 -11
- package/src/HandlerRegister.res.mjs +6 -5
- package/src/Internal.res +20 -4
- package/src/Internal.res.mjs +9 -0
- package/src/Main.res +8 -1
- package/src/Main.res.mjs +3 -3
- package/src/Persistence.res +11 -1
- package/src/Persistence.res.mjs +6 -2
- package/src/PgStorage.res +1 -1
- package/src/PgStorage.res.mjs +1 -1
- package/src/SimulateItems.res +13 -6
- package/src/SimulateItems.res.mjs +7 -6
- package/src/TestIndexer.res +6 -5
- package/src/TestIndexer.res.mjs +5 -4
- package/src/UserContext.res +51 -358
- package/src/UserContext.res.mjs +35 -271
- package/src/db/InternalTable.res +1 -1
- package/src/db/InternalTable.res.mjs +2 -1
- package/src/sources/ChainSources.res +72 -0
- package/src/sources/ChainSources.res.mjs +55 -0
- package/src/sources/EvmHyperSyncSource.res +10 -22
- package/src/sources/EvmHyperSyncSource.res.mjs +9 -41
- package/src/sources/FuelHyperSyncSource.res +10 -18
- package/src/sources/FuelHyperSyncSource.res.mjs +8 -38
- package/src/sources/HyperSync.res +31 -0
- package/src/sources/HyperSync.res.mjs +31 -0
- package/src/sources/HyperSync.resi +16 -0
- package/src/sources/StartBlockResolver.res +173 -0
- package/src/sources/StartBlockResolver.res.mjs +134 -0
- package/src/sources/Svm.res +0 -51
- package/src/sources/Svm.res.mjs +0 -46
- package/src/sources/SvmHyperSyncSource.res +20 -9
- package/src/sources/SvmHyperSyncSource.res.mjs +34 -12
- package/svm.schema.json +78 -63
- package/src/subgraph/blocks.ts +0 -176
- package/src/subgraph/calls.ts +0 -217
- package/src/subgraph/conformance.ts +0 -102
- package/src/subgraph/division.ts +0 -133
- package/src/subgraph/errors.ts +0 -90
- package/src/subgraph/graph-ts-types/VERSION +0 -2
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +0 -70
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +0 -327
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +0 -233
- package/src/subgraph/graph-ts-types/chain/near.d.ts +0 -253
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +0 -32
- package/src/subgraph/graph-ts-types/common/collections.d.ts +0 -136
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +0 -11
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +0 -30
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +0 -17
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +0 -120
- package/src/subgraph/graph-ts-types/common/value.d.ts +0 -120
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +0 -90
- package/src/subgraph/graph-ts-types/global/global.d.ts +0 -194
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +0 -22
- package/src/subgraph/graph-ts-types/index.d.ts +0 -102
- package/src/subgraph/graph-ts.ts +0 -1948
- package/src/subgraph/hosts.ts +0 -148
- package/src/subgraph/runtime.ts +0 -863
- package/src/subgraph/scope.ts +0 -66
package/evm.schema.json
CHANGED
|
@@ -494,10 +494,8 @@
|
|
|
494
494
|
"minimum": 0
|
|
495
495
|
},
|
|
496
496
|
"start_block": {
|
|
497
|
-
"description": "The block at which the indexer should start ingesting data",
|
|
498
|
-
"
|
|
499
|
-
"format": "uint64",
|
|
500
|
-
"minimum": 0
|
|
497
|
+
"description": "The block at which the indexer should start ingesting data, or \"latest\" to start from the chain's current head block when the indexer is first deployed. Once resolved, the concrete block is persisted and reused every time the indexer resumes normally (for example recovering from a crash), so downtime is backfilled instead of skipped. Running `envio start`/`dev` with -r (--restart) resets this like any other config change: \"latest\" resolves again, against the head at that time.",
|
|
498
|
+
"$ref": "#/$defs/StartBlock"
|
|
501
499
|
},
|
|
502
500
|
"end_block": {
|
|
503
501
|
"description": "The block at which the indexer should terminate.",
|
|
@@ -685,6 +683,25 @@
|
|
|
685
683
|
"url"
|
|
686
684
|
]
|
|
687
685
|
},
|
|
686
|
+
"StartBlock": {
|
|
687
|
+
"description": "A chain's configured start block: either a concrete block number or the\nliteral \"latest\". Config parsing never touches the network, so `Latest`\nstays unresolved here — it's resolved once at runtime, right before the\nindexer's first-ever persisted state is written, and never re-resolved\non a normal resume (see packages/envio/src/sources/StartBlockResolver.res).\nNote: this repo's `-r`/`--restart` CLI flag wipes the DB and re-deploys\nfrom scratch, so it re-resolves \"latest\" too — \"resume\" here means the\nopposite: recovering from a crash or process restart without `-r`.",
|
|
688
|
+
"anyOf": [
|
|
689
|
+
{
|
|
690
|
+
"type": "integer",
|
|
691
|
+
"format": "uint64",
|
|
692
|
+
"minimum": 0
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
"$ref": "#/$defs/StartBlockTag"
|
|
696
|
+
}
|
|
697
|
+
]
|
|
698
|
+
},
|
|
699
|
+
"StartBlockTag": {
|
|
700
|
+
"type": "string",
|
|
701
|
+
"enum": [
|
|
702
|
+
"latest"
|
|
703
|
+
]
|
|
704
|
+
},
|
|
688
705
|
"ChainContract": {
|
|
689
706
|
"type": "object",
|
|
690
707
|
"properties": {
|
package/fuel.schema.json
CHANGED
|
@@ -328,10 +328,8 @@
|
|
|
328
328
|
]
|
|
329
329
|
},
|
|
330
330
|
"start_block": {
|
|
331
|
-
"description": "The block at which the indexer should start ingesting data",
|
|
332
|
-
"
|
|
333
|
-
"format": "uint64",
|
|
334
|
-
"minimum": 0
|
|
331
|
+
"description": "The block at which the indexer should start ingesting data, or \"latest\" to start from the chain's current head block when the indexer is first deployed. Once resolved, the concrete block is persisted and reused every time the indexer resumes normally (for example recovering from a crash), so downtime is backfilled instead of skipped. Running `envio start`/`dev` with -r (--restart) resets this like any other config change: \"latest\" resolves again, against the head at that time.",
|
|
332
|
+
"$ref": "#/$defs/StartBlock"
|
|
335
333
|
},
|
|
336
334
|
"end_block": {
|
|
337
335
|
"description": "The block at which the indexer should terminate.",
|
|
@@ -388,6 +386,25 @@
|
|
|
388
386
|
"start_block"
|
|
389
387
|
]
|
|
390
388
|
},
|
|
389
|
+
"StartBlock": {
|
|
390
|
+
"description": "A chain's configured start block: either a concrete block number or the\nliteral \"latest\". Config parsing never touches the network, so `Latest`\nstays unresolved here — it's resolved once at runtime, right before the\nindexer's first-ever persisted state is written, and never re-resolved\non a normal resume (see packages/envio/src/sources/StartBlockResolver.res).\nNote: this repo's `-r`/`--restart` CLI flag wipes the DB and re-deploys\nfrom scratch, so it re-resolves \"latest\" too — \"resume\" here means the\nopposite: recovering from a crash or process restart without `-r`.",
|
|
391
|
+
"anyOf": [
|
|
392
|
+
{
|
|
393
|
+
"type": "integer",
|
|
394
|
+
"format": "uint64",
|
|
395
|
+
"minimum": 0
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"$ref": "#/$defs/StartBlockTag"
|
|
399
|
+
}
|
|
400
|
+
]
|
|
401
|
+
},
|
|
402
|
+
"StartBlockTag": {
|
|
403
|
+
"type": "string",
|
|
404
|
+
"enum": [
|
|
405
|
+
"latest"
|
|
406
|
+
]
|
|
407
|
+
},
|
|
391
408
|
"HyperfuelConfig": {
|
|
392
409
|
"type": "object",
|
|
393
410
|
"properties": {
|
package/index.d.ts
CHANGED
|
@@ -1377,7 +1377,7 @@ type SvmNamedAccounts<
|
|
|
1377
1377
|
Acc extends Readonly<Record<string, unknown>>,
|
|
1378
1378
|
Fields extends SvmFieldsSelection,
|
|
1379
1379
|
> = {
|
|
1380
|
-
readonly [K in keyof Acc
|
|
1380
|
+
readonly [K in keyof Acc]: SvmInstructionAccount<Fields, K & string>;
|
|
1381
1381
|
};
|
|
1382
1382
|
|
|
1383
1383
|
/** The parent transaction of a {@link SvmInstruction}, narrowed to the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A latency and sync speed optimized, developer friendly blockchain data indexer.",
|
|
6
6
|
"bin": "./bin.mjs",
|
|
@@ -68,10 +68,10 @@
|
|
|
68
68
|
"tsx": "4.21.0"
|
|
69
69
|
},
|
|
70
70
|
"optionalDependencies": {
|
|
71
|
-
"envio-linux-x64": "3.
|
|
72
|
-
"envio-linux-x64-musl": "3.
|
|
73
|
-
"envio-linux-arm64": "3.
|
|
74
|
-
"envio-darwin-x64": "3.
|
|
75
|
-
"envio-darwin-arm64": "3.
|
|
71
|
+
"envio-linux-x64": "3.11.0",
|
|
72
|
+
"envio-linux-x64-musl": "3.11.0",
|
|
73
|
+
"envio-linux-arm64": "3.11.0",
|
|
74
|
+
"envio-darwin-x64": "3.11.0",
|
|
75
|
+
"envio-darwin-arm64": "3.11.0"
|
|
76
76
|
}
|
|
77
77
|
}
|
package/src/ChainState.res
CHANGED
|
@@ -203,7 +203,9 @@ let makeInternal = (
|
|
|
203
203
|
|
|
204
204
|
chainConfig.contracts->Array.forEach(contract => {
|
|
205
205
|
switch contract.startBlock {
|
|
206
|
-
|
|
206
|
+
// Against the resolved `~startBlock`, which came from storage:
|
|
207
|
+
// `chainConfig.startBlock` still says whatever config.yaml said.
|
|
208
|
+
| Some(contractStartBlock) if contractStartBlock < startBlock =>
|
|
207
209
|
JsError.throwWithMessage(
|
|
208
210
|
`The start block for contract "${contract.name}" is less than the chain start block. This is not supported yet.`,
|
|
209
211
|
)
|
|
@@ -262,78 +264,12 @@ let makeInternal = (
|
|
|
262
264
|
})
|
|
263
265
|
|
|
264
266
|
// Create sources lazily here - this is where API token validation happens
|
|
265
|
-
let
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
let headers = rpc.headers
|
|
272
|
-
{
|
|
273
|
-
url: rpc.url,
|
|
274
|
-
sourceFor: rpc.sourceFor,
|
|
275
|
-
?syncConfig,
|
|
276
|
-
?ws,
|
|
277
|
-
?headers,
|
|
278
|
-
}
|
|
279
|
-
})
|
|
280
|
-
EvmChain.makeSources(
|
|
281
|
-
~chainId,
|
|
282
|
-
~onEventRegistrations=onEventRegistrations->(
|
|
283
|
-
Utils.magic: array<Internal.onEventRegistration> => array<Internal.evmOnEventRegistration>
|
|
284
|
-
),
|
|
285
|
-
~hyperSync=hypersync,
|
|
286
|
-
~rpcs=evmRpcs,
|
|
287
|
-
~lowercaseAddresses,
|
|
288
|
-
~addressStore,
|
|
289
|
-
)
|
|
290
|
-
| Config.FuelSourceConfig({hypersync}) => [
|
|
291
|
-
FuelHyperSyncSource.make({
|
|
292
|
-
chainId,
|
|
293
|
-
endpointUrl: hypersync,
|
|
294
|
-
apiToken: Env.envioApiToken,
|
|
295
|
-
onEventRegistrations,
|
|
296
|
-
addressStore,
|
|
297
|
-
}),
|
|
298
|
-
]
|
|
299
|
-
| Config.SvmSourceConfig({hypersync, rpc}) =>
|
|
300
|
-
switch (hypersync, rpc) {
|
|
301
|
-
| (None, None) =>
|
|
302
|
-
JsError.throwWithMessage(`Chain ${chainId->ChainId.toString} has no SVM data source`)
|
|
303
|
-
| (None, Some(rpc)) => [Svm.makeRPCSource(~chainId, ~rpc)]
|
|
304
|
-
| (Some(hypersyncUrl), _) =>
|
|
305
|
-
// HyperSync drives instruction sync. A configured RPC is ignored for now
|
|
306
|
-
// (RPC fallback isn't wired up yet).
|
|
307
|
-
let apiToken = Env.envioApiToken
|
|
308
|
-
[
|
|
309
|
-
SvmHyperSyncSource.make({
|
|
310
|
-
chainId,
|
|
311
|
-
endpointUrl: hypersyncUrl,
|
|
312
|
-
apiToken,
|
|
313
|
-
onEventRegistrations: onEventRegistrations->(
|
|
314
|
-
Utils.magic: array<Internal.onEventRegistration> => array<
|
|
315
|
-
Internal.svmOnEventRegistration,
|
|
316
|
-
>
|
|
317
|
-
),
|
|
318
|
-
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
|
|
319
|
-
addressStore,
|
|
320
|
-
}),
|
|
321
|
-
]
|
|
322
|
-
}
|
|
323
|
-
| Config.SimulateSourceConfig({items, endBlock, ?transactionStore, ?blockStore}) => [
|
|
324
|
-
SimulateSource.make(
|
|
325
|
-
~items,
|
|
326
|
-
~endBlock,
|
|
327
|
-
~chainId,
|
|
328
|
-
~addressStore,
|
|
329
|
-
~ecosystem=config.ecosystem.name,
|
|
330
|
-
~transactionStore,
|
|
331
|
-
~blockStore,
|
|
332
|
-
),
|
|
333
|
-
]
|
|
334
|
-
// For tests: use ready-to-use sources directly
|
|
335
|
-
| Config.CustomSources(sources) => sources
|
|
336
|
-
}
|
|
267
|
+
let sources = ChainSources.make(
|
|
268
|
+
~chainConfig,
|
|
269
|
+
~onEventRegistrations,
|
|
270
|
+
~addressStore,
|
|
271
|
+
~lowercaseAddresses,
|
|
272
|
+
)
|
|
337
273
|
|
|
338
274
|
let blockStore = BlockStore.make(
|
|
339
275
|
~ecosystem=config.ecosystem.name,
|
package/src/ChainState.res.mjs
CHANGED
|
@@ -1,32 +1,28 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as Env from "./Env.res.mjs";
|
|
4
3
|
import * as Svm from "./sources/Svm.res.mjs";
|
|
5
4
|
import * as Core from "./Core.res.mjs";
|
|
6
5
|
import * as Batch from "./Batch.res.mjs";
|
|
7
6
|
import * as Utils from "./Utils.res.mjs";
|
|
8
7
|
import * as ChainId from "./ChainId.res.mjs";
|
|
9
8
|
import * as Logging from "./Logging.res.mjs";
|
|
10
|
-
import * as EvmChain from "./sources/EvmChain.res.mjs";
|
|
11
9
|
import * as FieldMask from "./sources/FieldMask.res.mjs";
|
|
12
10
|
import * as BlockStore from "./sources/BlockStore.res.mjs";
|
|
13
11
|
import * as FetchState from "./FetchState.res.mjs";
|
|
14
12
|
import * as AddressRows from "./AddressRows.res.mjs";
|
|
15
13
|
import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
|
|
16
14
|
import * as AddressStore from "./sources/AddressStore.res.mjs";
|
|
15
|
+
import * as ChainSources from "./sources/ChainSources.res.mjs";
|
|
17
16
|
import * as EntityTables from "./EntityTables.res.mjs";
|
|
18
17
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
19
18
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
20
19
|
import * as SourceManager from "./sources/SourceManager.res.mjs";
|
|
21
20
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
22
|
-
import * as SimulateSource from "./sources/SimulateSource.res.mjs";
|
|
23
21
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
24
22
|
import * as ContractMapping from "./ContractMapping.res.mjs";
|
|
25
23
|
import * as Primitive_float from "@rescript/runtime/lib/es6/Primitive_float.js";
|
|
26
24
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
27
25
|
import * as TransactionStore from "./sources/TransactionStore.res.mjs";
|
|
28
|
-
import * as SvmHyperSyncSource from "./sources/SvmHyperSyncSource.res.mjs";
|
|
29
|
-
import * as FuelHyperSyncSource from "./sources/FuelHyperSyncSource.res.mjs";
|
|
30
26
|
import * as SafeCheckpointTracking from "./SafeCheckpointTracking.res.mjs";
|
|
31
27
|
|
|
32
28
|
function configStorageRows(chainConfig, ecosystem, contractMapping) {
|
|
@@ -128,8 +124,8 @@ function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInR
|
|
|
128
124
|
});
|
|
129
125
|
let onEventRegistrations = match.onEventRegistrations;
|
|
130
126
|
chainConfig.contracts.forEach(contract => {
|
|
131
|
-
let
|
|
132
|
-
if (
|
|
127
|
+
let contractStartBlock = contract.startBlock;
|
|
128
|
+
if (contractStartBlock !== undefined && contractStartBlock < startBlock) {
|
|
133
129
|
return Stdlib_JsError.throwWithMessage(`The start block for contract "` + contract.name + `" is less than the chain start block. This is not supported yet.`);
|
|
134
130
|
}
|
|
135
131
|
});
|
|
@@ -152,55 +148,7 @@ function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInR
|
|
|
152
148
|
return reorgCheckpoint;
|
|
153
149
|
}
|
|
154
150
|
});
|
|
155
|
-
let
|
|
156
|
-
let sources = chainConfig.sourceConfig;
|
|
157
|
-
let sources$1;
|
|
158
|
-
switch (sources.TAG) {
|
|
159
|
-
case "EvmSourceConfig" :
|
|
160
|
-
let evmRpcs = sources.rpcs.map(rpc => {
|
|
161
|
-
let syncConfig = rpc.syncConfig;
|
|
162
|
-
let ws = rpc.ws;
|
|
163
|
-
let headers = rpc.headers;
|
|
164
|
-
return {
|
|
165
|
-
url: rpc.url,
|
|
166
|
-
sourceFor: rpc.sourceFor,
|
|
167
|
-
syncConfig: syncConfig,
|
|
168
|
-
ws: ws,
|
|
169
|
-
headers: headers
|
|
170
|
-
};
|
|
171
|
-
});
|
|
172
|
-
sources$1 = EvmChain.makeSources(chainId$1, onEventRegistrations, sources.hypersync, evmRpcs, lowercaseAddresses, addressStore);
|
|
173
|
-
break;
|
|
174
|
-
case "FuelSourceConfig" :
|
|
175
|
-
sources$1 = [FuelHyperSyncSource.make({
|
|
176
|
-
chainId: chainId$1,
|
|
177
|
-
endpointUrl: sources.hypersync,
|
|
178
|
-
apiToken: Env.envioApiToken,
|
|
179
|
-
onEventRegistrations: onEventRegistrations,
|
|
180
|
-
addressStore: addressStore
|
|
181
|
-
})];
|
|
182
|
-
break;
|
|
183
|
-
case "SvmSourceConfig" :
|
|
184
|
-
let rpc = sources.rpc;
|
|
185
|
-
let hypersync = sources.hypersync;
|
|
186
|
-
sources$1 = hypersync !== undefined ? [SvmHyperSyncSource.make({
|
|
187
|
-
chainId: chainId$1,
|
|
188
|
-
endpointUrl: hypersync,
|
|
189
|
-
apiToken: Env.envioApiToken,
|
|
190
|
-
onEventRegistrations: onEventRegistrations,
|
|
191
|
-
clientTimeoutMillis: Env.hyperSyncClientTimeoutMillis,
|
|
192
|
-
addressStore: addressStore
|
|
193
|
-
})] : (
|
|
194
|
-
rpc !== undefined ? [Svm.makeRPCSource(chainId$1, rpc, undefined)] : Stdlib_JsError.throwWithMessage(`Chain ` + ChainId.toString(chainId$1) + ` has no SVM data source`)
|
|
195
|
-
);
|
|
196
|
-
break;
|
|
197
|
-
case "SimulateSourceConfig" :
|
|
198
|
-
sources$1 = [SimulateSource.make(sources.items, sources.endBlock, chainId$1, addressStore, config.ecosystem.name, Primitive_option.some(sources.transactionStore), Primitive_option.some(sources.blockStore))];
|
|
199
|
-
break;
|
|
200
|
-
case "CustomSources" :
|
|
201
|
-
sources$1 = sources._0;
|
|
202
|
-
break;
|
|
203
|
-
}
|
|
151
|
+
let sources = ChainSources.make(chainConfig, onEventRegistrations, addressStore, lowercaseAddresses);
|
|
204
152
|
let blockStore = BlockStore.make(config.ecosystem.name, !lowercaseAddresses);
|
|
205
153
|
if (Utils.$$Array.notEmpty(chainReorgCheckpoints)) {
|
|
206
154
|
let seedPage = BlockStore.fromJs(chainReorgCheckpoints.map(cp => ({
|
|
@@ -211,7 +159,7 @@ function makeFromDbState(chainConfig, resumedChainState, reorgCheckpoints, isInR
|
|
|
211
159
|
}
|
|
212
160
|
let firstEventBlock$1 = fetchState.firstEventBlock;
|
|
213
161
|
let chainDensity = firstEventBlock$1 !== undefined && progressBlockNumber > firstEventBlock$1 && numEventsProcessed > 0 ? numEventsProcessed / (progressBlockNumber - firstEventBlock$1 | 0) : undefined;
|
|
214
|
-
return make(chainConfig, fetchState, onEventRegistrations, addressStore, SourceManager.make(sources
|
|
162
|
+
return make(chainConfig, fetchState, onEventRegistrations, addressStore, SourceManager.make(sources, isRealtime, undefined, undefined, undefined, reducedPollingInterval, undefined, undefined), progressBlockNumber, Primitive_option.some(SafeCheckpointTracking.make(maxReorgDepth, config.shouldRollbackOnReorg, chainReorgCheckpoints)), config.shouldRollbackOnReorg, maxReorgDepth, numEventsProcessed, Primitive_option.some(timestampCaughtUpToHeadOrEndblock), undefined, Primitive_option.some(TransactionStore.make(config.ecosystem.name, !lowercaseAddresses)), Primitive_option.some(chainDensity), Primitive_option.some(blockStore), config.reorgThresholdReadyTolerance, EntityTables.perChain(config.userEntities), logger);
|
|
215
163
|
}
|
|
216
164
|
|
|
217
165
|
function logger(cs) {
|
|
@@ -959,4 +907,4 @@ export {
|
|
|
959
907
|
markReady,
|
|
960
908
|
rollback,
|
|
961
909
|
}
|
|
962
|
-
/*
|
|
910
|
+
/* Svm Not a pure module */
|
package/src/Config.res
CHANGED
|
@@ -26,10 +26,18 @@ type evmRpcConfig = {
|
|
|
26
26
|
headers: option<dict<string>>,
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
// Unboxed so the runtime value is exactly what the public config JSON holds -
|
|
30
|
+
// a number, or the string "latest" - which is why `startBlockSchema` only has
|
|
31
|
+
// to validate it rather than convert it.
|
|
32
|
+
@unboxed
|
|
33
|
+
type startBlock =
|
|
34
|
+
| Block(int)
|
|
35
|
+
| @as("latest") Latest
|
|
36
|
+
|
|
29
37
|
type sourceConfig =
|
|
30
38
|
| EvmSourceConfig({hypersync: option<string>, rpcs: array<evmRpcConfig>})
|
|
31
39
|
| FuelSourceConfig({hypersync: string})
|
|
32
|
-
| SvmSourceConfig({hypersync:
|
|
40
|
+
| SvmSourceConfig({hypersync: string})
|
|
33
41
|
// A `simulate` run: the items the test fed in, parsed against the chain's
|
|
34
42
|
// registrations. The source itself is built with the chain's address store,
|
|
35
43
|
// like every other source, so it can apply the same gates.
|
|
@@ -46,7 +54,11 @@ type chain = {
|
|
|
46
54
|
name: string,
|
|
47
55
|
id: ChainId.t,
|
|
48
56
|
ecosystem: Ecosystem.name,
|
|
49
|
-
|
|
57
|
+
// What config.yaml says, never rewritten. Once `Latest` is resolved against
|
|
58
|
+
// the chain's head the block lives in the database
|
|
59
|
+
// (`envio_chains.start_block`), and that is what every consumer past startup
|
|
60
|
+
// reads.
|
|
61
|
+
startBlock: startBlock,
|
|
50
62
|
endBlock?: int,
|
|
51
63
|
maxReorgDepth: int,
|
|
52
64
|
blockLag: int,
|
|
@@ -127,9 +139,6 @@ type t = {
|
|
|
127
139
|
userEntitiesByName: dict<Internal.entityConfig>,
|
|
128
140
|
userEntities: array<Internal.entityConfig>,
|
|
129
141
|
allEnums: array<Table.enumConfig<Table.enum>>,
|
|
130
|
-
// Set only in subgraph mode: the translated manifest, which is what makes
|
|
131
|
-
// the subgraph runtime take over handler registration.
|
|
132
|
-
subgraph: option<JSON.t>,
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
type rpcSourceFor = | @as("sync") Sync | @as("fallback") Fallback | @as("realtime") Realtime
|
|
@@ -160,10 +169,36 @@ let chainContractSchema = S.schema(s =>
|
|
|
160
169
|
}
|
|
161
170
|
)
|
|
162
171
|
|
|
172
|
+
// For everything downstream of `StartBlockResolver`, which rewrites `Latest`
|
|
173
|
+
// into the chain's head before storage is initialized. The throw is an
|
|
174
|
+
// invariant check, not a case a user can reach.
|
|
175
|
+
let startBlockOrThrow = (chain: chain) =>
|
|
176
|
+
switch chain.startBlock {
|
|
177
|
+
| Block(startBlock) => startBlock
|
|
178
|
+
| Latest =>
|
|
179
|
+
JsError.throwWithMessage(
|
|
180
|
+
`Chain ${chain.id->ChainId.toString}: the "latest" start block was read before it was resolved. This is a bug in envio - please report it.`,
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// For the paths that have no chain to read a head from - the test indexer and
|
|
185
|
+
// simulated items - where `Latest` never gets resolved and every simulated
|
|
186
|
+
// block should be in range.
|
|
187
|
+
let startBlockOrZero = (chain: chain) =>
|
|
188
|
+
switch chain.startBlock {
|
|
189
|
+
| Block(startBlock) => startBlock
|
|
190
|
+
| Latest => 0
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
let startBlockSchema = S.union([
|
|
194
|
+
S.int->S.shape(n => Block(n)),
|
|
195
|
+
S.literal("latest")->S.shape(_ => Latest),
|
|
196
|
+
])
|
|
197
|
+
|
|
163
198
|
let publicConfigChainSchema = S.schema(s =>
|
|
164
199
|
{
|
|
165
200
|
"id": s.matches(ChainId.schema),
|
|
166
|
-
"startBlock": s.matches(
|
|
201
|
+
"startBlock": s.matches(startBlockSchema),
|
|
167
202
|
"endBlock": s.matches(S.option(S.int)),
|
|
168
203
|
"maxReorgDepth": s.matches(S.option(S.int)),
|
|
169
204
|
"blockLag": s.matches(S.option(S.int)),
|
|
@@ -171,23 +206,37 @@ let publicConfigChainSchema = S.schema(s =>
|
|
|
171
206
|
"hypersync": s.matches(S.option(S.string)),
|
|
172
207
|
"rpcs": s.matches(S.option(S.array(rpcConfigSchema))),
|
|
173
208
|
// SVM source config
|
|
174
|
-
"rpc": s.matches(S.option(S.string)),
|
|
175
209
|
// Per-chain contract data (addresses and optional start block)
|
|
176
210
|
"contracts": s.matches(S.option(S.dict(chainContractSchema))),
|
|
177
211
|
}
|
|
178
212
|
)
|
|
179
213
|
|
|
214
|
+
type svmAccountSlotItem = {"name": option<string>, "optional": option<bool>}
|
|
215
|
+
|
|
216
|
+
let svmAccountSlotSchema: S.t<svmAccountSlotItem> = S.schema(s =>
|
|
217
|
+
{
|
|
218
|
+
"name": s.matches(S.option(S.string)),
|
|
219
|
+
"optional": s.matches(S.option(S.bool)),
|
|
220
|
+
}
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
let svmAccountSlotFromItem = (slot: svmAccountSlotItem): Internal.svmAccountSlot =>
|
|
224
|
+
switch (slot["name"], slot["optional"]) {
|
|
225
|
+
| (None, _) => Unnamed
|
|
226
|
+
| (Some(name), Some(true)) => Optional(name)
|
|
227
|
+
| (Some(name), _) => Required(name)
|
|
228
|
+
}
|
|
229
|
+
|
|
180
230
|
let svmEventDescriptorSchema = S.schema(s =>
|
|
181
231
|
{
|
|
182
232
|
"discriminator": s.matches(S.option(S.string)),
|
|
183
|
-
"accounts": s.matches(S.option(S.array(
|
|
233
|
+
"accounts": s.matches(S.option(S.array(svmAccountSlotSchema))),
|
|
184
234
|
"args": s.matches(S.option(S.json(~validate=false))),
|
|
185
235
|
}
|
|
186
236
|
)
|
|
187
237
|
|
|
188
238
|
let svmAbiSchema = S.schema(s =>
|
|
189
239
|
{
|
|
190
|
-
"programId": s.matches(S.string),
|
|
191
240
|
"definedTypes": s.matches(S.json(~validate=false)),
|
|
192
241
|
"source": s.matches(S.string),
|
|
193
242
|
}
|
|
@@ -549,7 +598,6 @@ let publicConfigSchema = S.schema(s =>
|
|
|
549
598
|
"svm": s.matches(S.option(publicConfigEcosystemSchema)),
|
|
550
599
|
"enums": s.matches(S.option(S.dict(S.array(S.string)))),
|
|
551
600
|
"entities": s.matches(S.option(S.array(entityJsonSchema))),
|
|
552
|
-
"subgraph": s.matches(S.option(S.json(~validate=false))),
|
|
553
601
|
}
|
|
554
602
|
)
|
|
555
603
|
|
|
@@ -644,7 +692,6 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
644
692
|
"eventSignatures": array<string>,
|
|
645
693
|
"events": option<array<_>>,
|
|
646
694
|
"svmAbi": option<{
|
|
647
|
-
"programId": string,
|
|
648
695
|
"definedTypes": JSON.t,
|
|
649
696
|
"source": string,
|
|
650
697
|
}>,
|
|
@@ -664,7 +711,6 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
664
711
|
contractConfig->(
|
|
665
712
|
Utils.magic: _ => {
|
|
666
713
|
"svmAbi": option<{
|
|
667
|
-
"programId": string,
|
|
668
714
|
"definedTypes": JSON.t,
|
|
669
715
|
"source": string,
|
|
670
716
|
}>,
|
|
@@ -740,7 +786,7 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
740
786
|
Utils.magic: _ => {
|
|
741
787
|
"svm": option<{
|
|
742
788
|
"discriminator": option<string>,
|
|
743
|
-
"accounts": option<array<
|
|
789
|
+
"accounts": option<array<svmAccountSlotItem>>,
|
|
744
790
|
"args": option<JSON.t>,
|
|
745
791
|
}>,
|
|
746
792
|
}
|
|
@@ -757,7 +803,7 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
757
803
|
~instructionName=eventName,
|
|
758
804
|
~programId,
|
|
759
805
|
~discriminator=svm["discriminator"],
|
|
760
|
-
~accounts=svm["accounts"]->Option.getOr([]),
|
|
806
|
+
~accounts=svm["accounts"]->Option.getOr([])->Array.map(svmAccountSlotFromItem),
|
|
761
807
|
~args=svm["args"]->Option.getOr(JSON.Null),
|
|
762
808
|
~definedTypes=svmDefinedTypes,
|
|
763
809
|
) :> Internal.eventConfig)
|
|
@@ -811,6 +857,15 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
811
857
|
let contracts =
|
|
812
858
|
contractDataByName
|
|
813
859
|
->Dict.toArray
|
|
860
|
+
// Svm programs are defined once for the project and placed per chain by
|
|
861
|
+
// `program_id`. A program the config left off this chain has nothing to
|
|
862
|
+
// index here, and no dynamic registration can add it later.
|
|
863
|
+
->Array.filter(((capitalizedName, _)) =>
|
|
864
|
+
switch ecosystemName {
|
|
865
|
+
| Ecosystem.Svm => chainContracts->Dict.get(capitalizedName)->Option.isSome
|
|
866
|
+
| _ => true
|
|
867
|
+
}
|
|
868
|
+
)
|
|
814
869
|
->Array.map(((capitalizedName, contractData)) => {
|
|
815
870
|
let chainContract = chainContracts->Dict.get(capitalizedName)
|
|
816
871
|
let rawAddresses =
|
|
@@ -918,14 +973,11 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
918
973
|
JsError.throwWithMessage(`Chain ${chainName} is missing hypersync endpoint in config`)
|
|
919
974
|
}
|
|
920
975
|
| Ecosystem.Svm =>
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
JsError.throwWithMessage(
|
|
925
|
-
`Chain ${chainName} is missing a data source: provide either an rpc endpoint or an experimental hypersync config`,
|
|
926
|
-
)
|
|
976
|
+
switch publicChainConfig["hypersync"] {
|
|
977
|
+
| Some(hypersync) => SvmSourceConfig({hypersync: hypersync})
|
|
978
|
+
| None =>
|
|
979
|
+
JsError.throwWithMessage(`Chain ${chainName} is missing hypersync endpoint in config`)
|
|
927
980
|
}
|
|
928
|
-
SvmSourceConfig({hypersync, rpc})
|
|
929
981
|
}
|
|
930
982
|
|
|
931
983
|
{
|
|
@@ -1035,7 +1087,6 @@ let fromPublic = (publicConfigJson: JSON.t) => {
|
|
|
1035
1087
|
userEntitiesByName,
|
|
1036
1088
|
userEntities,
|
|
1037
1089
|
allEnums,
|
|
1038
|
-
subgraph: publicConfig["subgraph"],
|
|
1039
1090
|
}
|
|
1040
1091
|
}
|
|
1041
1092
|
|
|
@@ -1173,7 +1224,6 @@ let stripSensitiveData = (json: JSON.t): JSON.t => {
|
|
|
1173
1224
|
switch chainJson {
|
|
1174
1225
|
| Object(chain) => {
|
|
1175
1226
|
chain->Utils.Dict.deleteInPlace("rpcs")
|
|
1176
|
-
chain->Utils.Dict.deleteInPlace("rpc")
|
|
1177
1227
|
chain->Utils.Dict.deleteInPlace("hypersync")
|
|
1178
1228
|
}
|
|
1179
1229
|
| _ => ()
|
|
@@ -1189,10 +1239,6 @@ let stripSensitiveData = (json: JSON.t): JSON.t => {
|
|
|
1189
1239
|
stripChains(obj->Dict.get("evm"))
|
|
1190
1240
|
stripChains(obj->Dict.get("fuel"))
|
|
1191
1241
|
stripChains(obj->Dict.get("svm"))
|
|
1192
|
-
// The subgraph blob is how the runtime finds mappings. None of it
|
|
1193
|
-
// describes stored data — that's already in `evm` / `entities` — so a
|
|
1194
|
-
// specVersion bump or a mapping-path edit must not force a reset.
|
|
1195
|
-
obj->Utils.Dict.deleteInPlace("subgraph")
|
|
1196
1242
|
}
|
|
1197
1243
|
| _ => ()
|
|
1198
1244
|
}
|