envio 3.7.0-svm-alpha.1 → 3.7.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/package.json +6 -6
- package/src/Core.res +4 -0
- package/src/bindings/ClickHouse.res +16 -11
- package/src/bindings/ClickHouse.res.mjs +10 -10
- package/src/sources/EvmHyperSyncSource.res +5 -1
- package/src/sources/EvmHyperSyncSource.res.mjs +1 -1
- package/src/sources/SvmHyperSyncSource.res +5 -1
- package/src/sources/SvmHyperSyncSource.res.mjs +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "envio",
|
|
3
|
-
"version": "3.7.0
|
|
3
|
+
"version": "3.7.0",
|
|
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.7.0
|
|
73
|
-
"envio-linux-x64-musl": "3.7.0
|
|
74
|
-
"envio-linux-arm64": "3.7.0
|
|
75
|
-
"envio-darwin-x64": "3.7.0
|
|
76
|
-
"envio-darwin-arm64": "3.7.0
|
|
72
|
+
"envio-linux-x64": "3.7.0",
|
|
73
|
+
"envio-linux-x64-musl": "3.7.0",
|
|
74
|
+
"envio-linux-arm64": "3.7.0",
|
|
75
|
+
"envio-darwin-x64": "3.7.0",
|
|
76
|
+
"envio-darwin-arm64": "3.7.0"
|
|
77
77
|
}
|
|
78
78
|
}
|
package/src/Core.res
CHANGED
|
@@ -11,6 +11,8 @@ type fuelHyperSyncClientCtor
|
|
|
11
11
|
type transactionStoreCtor
|
|
12
12
|
type blockStoreCtor
|
|
13
13
|
type addressStoreCtor
|
|
14
|
+
// Test-only: a local HyperSync server, bound by MockHyperSyncServer in envio-tests.
|
|
15
|
+
type mockHyperSyncServerCtor
|
|
14
16
|
type fromUserApiOptions = {
|
|
15
17
|
schema?: string,
|
|
16
18
|
env?: dict<string>,
|
|
@@ -43,6 +45,8 @@ type addon = {
|
|
|
43
45
|
blockStore: blockStoreCtor,
|
|
44
46
|
@as("AddressStore")
|
|
45
47
|
addressStore: addressStoreCtor,
|
|
48
|
+
@as("MockHyperSyncServer")
|
|
49
|
+
mockHyperSyncServer: mockHyperSyncServerCtor,
|
|
46
50
|
// Ordered transaction-field names exposed for the field-code contract test
|
|
47
51
|
// (the ReScript `transactionFields` arrays must match the Rust ordinals).
|
|
48
52
|
evmTransactionFieldNames: unit => array<string>,
|
|
@@ -14,8 +14,13 @@ type execParams = {query: string}
|
|
|
14
14
|
@module("@clickhouse/client")
|
|
15
15
|
external createClient: clientConfig => client = "createClient"
|
|
16
16
|
|
|
17
|
+
// `command`, not `exec`: exec hands its response stream to the caller and holds
|
|
18
|
+
// the socket until it is consumed, which nothing here does. The pool is 10
|
|
19
|
+
// sockets wide, so a schema whose DDL needs more than that — initialize issues
|
|
20
|
+
// 2N+3 statements for N entities — stalled every statement past the tenth until
|
|
21
|
+
// the 30s request timeout freed one. command destroys the stream for us.
|
|
17
22
|
@send
|
|
18
|
-
external
|
|
23
|
+
external command: (client, execParams) => promise<unit> = "command"
|
|
19
24
|
|
|
20
25
|
@send
|
|
21
26
|
external close: client => promise<unit> = "close"
|
|
@@ -628,21 +633,21 @@ let initialize = async (
|
|
|
628
633
|
// CLUSTER removes the database from every node — the engine's own log
|
|
629
634
|
// can't replicate the drop of the database it lives in — and SYNC waits
|
|
630
635
|
// for the drop to finish before the CREATE below.
|
|
631
|
-
await client->
|
|
636
|
+
await client->command({
|
|
632
637
|
query: `DROP DATABASE IF EXISTS ${database} ON CLUSTER '{cluster}' SYNC`,
|
|
633
638
|
})
|
|
634
639
|
} else {
|
|
635
|
-
await client->
|
|
640
|
+
await client->command({
|
|
636
641
|
query: `TRUNCATE DATABASE IF EXISTS ${database}${onClusterClause(~onCluster=ddlOnCluster)}`,
|
|
637
642
|
})
|
|
638
643
|
}
|
|
639
|
-
await client->
|
|
644
|
+
await client->command({
|
|
640
645
|
query: `CREATE DATABASE IF NOT EXISTS ${database}${databaseOnClusterClause}${databaseEngineClause}`,
|
|
641
646
|
})
|
|
642
647
|
|
|
643
648
|
await Promise.all(
|
|
644
649
|
entities->Array.map(entityConfig =>
|
|
645
|
-
client->
|
|
650
|
+
client->command({
|
|
646
651
|
query: makeCreateHistoryTableQuery(
|
|
647
652
|
~entityConfig,
|
|
648
653
|
~database,
|
|
@@ -653,7 +658,7 @@ let initialize = async (
|
|
|
653
658
|
})
|
|
654
659
|
),
|
|
655
660
|
)->Utils.Promise.ignoreValue
|
|
656
|
-
await client->
|
|
661
|
+
await client->command({
|
|
657
662
|
query: makeCreateCheckpointsTableQuery(
|
|
658
663
|
~database,
|
|
659
664
|
~replicated,
|
|
@@ -670,14 +675,14 @@ let initialize = async (
|
|
|
670
675
|
// caught up before creating the views. ON CLUSTER must precede the
|
|
671
676
|
// database name in this command's grammar.
|
|
672
677
|
if hasReplicatedDatabaseEngine {
|
|
673
|
-
await client->
|
|
678
|
+
await client->command({
|
|
674
679
|
query: `SYSTEM SYNC DATABASE REPLICA ON CLUSTER '{cluster}' ${database}`,
|
|
675
680
|
})
|
|
676
681
|
}
|
|
677
682
|
|
|
678
683
|
await Promise.all(
|
|
679
684
|
entities->Array.map(entityConfig =>
|
|
680
|
-
client->
|
|
685
|
+
client->command({
|
|
681
686
|
query: makeCreateViewQuery(~entityConfig, ~database, ~onCluster=ddlOnCluster),
|
|
682
687
|
})
|
|
683
688
|
),
|
|
@@ -697,7 +702,7 @@ let resume = async (client, ~database: string, ~checkpointId: Internal.checkpoin
|
|
|
697
702
|
try {
|
|
698
703
|
// Try to use the database - will throw if it doesn't exist
|
|
699
704
|
try {
|
|
700
|
-
await client->
|
|
705
|
+
await client->command({query: `USE ${database}`})
|
|
701
706
|
} catch {
|
|
702
707
|
| exn =>
|
|
703
708
|
Logging.errorWithExn(
|
|
@@ -717,14 +722,14 @@ let resume = async (client, ~database: string, ~checkpointId: Internal.checkpoin
|
|
|
717
722
|
await Promise.all(
|
|
718
723
|
tables->Array.map(table => {
|
|
719
724
|
let tableName = table["name"]
|
|
720
|
-
client->
|
|
725
|
+
client->command({
|
|
721
726
|
query: `ALTER TABLE ${database}.\`${tableName}\` DELETE WHERE \`${EntityHistory.checkpointIdFieldName}\` > ${checkpointId->BigInt.toString}`,
|
|
722
727
|
})
|
|
723
728
|
}),
|
|
724
729
|
)->Utils.Promise.ignoreValue
|
|
725
730
|
|
|
726
731
|
// Delete stale checkpoints
|
|
727
|
-
await client->
|
|
732
|
+
await client->command({
|
|
728
733
|
query: `DELETE FROM ${database}.\`${InternalTable.Checkpoints.table.tableName}\` WHERE \`${Table.idFieldName}\` > ${checkpointId->BigInt.toString}`,
|
|
729
734
|
})
|
|
730
735
|
} catch {
|
|
@@ -428,31 +428,31 @@ async function initialize(client, database, entities, param, chainIdModeOpt) {
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
if (hasReplicatedDatabaseEngine) {
|
|
431
|
-
await client.
|
|
431
|
+
await client.command({
|
|
432
432
|
query: `DROP DATABASE IF EXISTS ` + database + ` ON CLUSTER '{cluster}' SYNC`
|
|
433
433
|
});
|
|
434
434
|
} else {
|
|
435
|
-
await client.
|
|
435
|
+
await client.command({
|
|
436
436
|
query: `TRUNCATE DATABASE IF EXISTS ` + database + (
|
|
437
437
|
ddlOnCluster ? ` ON CLUSTER '{cluster}'` : ""
|
|
438
438
|
)
|
|
439
439
|
});
|
|
440
440
|
}
|
|
441
|
-
await client.
|
|
441
|
+
await client.command({
|
|
442
442
|
query: `CREATE DATABASE IF NOT EXISTS ` + database + databaseOnClusterClause + databaseEngineClause
|
|
443
443
|
});
|
|
444
|
-
await Promise.all(entities.map(entityConfig => client.
|
|
444
|
+
await Promise.all(entities.map(entityConfig => client.command({
|
|
445
445
|
query: makeCreateHistoryTableQuery(entityConfig, database, replicated, ddlOnCluster, chainIdMode)
|
|
446
446
|
})));
|
|
447
|
-
await client.
|
|
447
|
+
await client.command({
|
|
448
448
|
query: makeCreateCheckpointsTableQuery(database, replicated, ddlOnCluster, chainIdMode)
|
|
449
449
|
});
|
|
450
450
|
if (hasReplicatedDatabaseEngine) {
|
|
451
|
-
await client.
|
|
451
|
+
await client.command({
|
|
452
452
|
query: `SYSTEM SYNC DATABASE REPLICA ON CLUSTER '{cluster}' ` + database
|
|
453
453
|
});
|
|
454
454
|
}
|
|
455
|
-
await Promise.all(entities.map(entityConfig => client.
|
|
455
|
+
await Promise.all(entities.map(entityConfig => client.command({
|
|
456
456
|
query: makeCreateViewQuery(entityConfig, database, ddlOnCluster)
|
|
457
457
|
})));
|
|
458
458
|
return Logging.trace("ClickHouse storage initialization completed successfully");
|
|
@@ -466,7 +466,7 @@ async function initialize(client, database, entities, param, chainIdModeOpt) {
|
|
|
466
466
|
async function resume(client, database, checkpointId) {
|
|
467
467
|
try {
|
|
468
468
|
try {
|
|
469
|
-
await client.
|
|
469
|
+
await client.command({
|
|
470
470
|
query: `USE ` + database
|
|
471
471
|
});
|
|
472
472
|
} catch (raw_exn) {
|
|
@@ -480,11 +480,11 @@ async function resume(client, database, checkpointId) {
|
|
|
480
480
|
let tables = (await tablesResult.json()).data;
|
|
481
481
|
await Promise.all(tables.map(table => {
|
|
482
482
|
let tableName = table.name;
|
|
483
|
-
return client.
|
|
483
|
+
return client.command({
|
|
484
484
|
query: `ALTER TABLE ` + database + `.\`` + tableName + `\` DELETE WHERE \`` + EntityHistory.checkpointIdFieldName + `\` > ` + checkpointId.toString()
|
|
485
485
|
});
|
|
486
486
|
}));
|
|
487
|
-
return await client.
|
|
487
|
+
return await client.command({
|
|
488
488
|
query: `DELETE FROM ` + database + `.\`` + InternalTable.Checkpoints.table.tableName + `\` WHERE \`` + Table.idFieldName + `\` > ` + checkpointId.toString()
|
|
489
489
|
});
|
|
490
490
|
} catch (raw_exn$1) {
|
|
@@ -194,7 +194,11 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`)
|
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
// Called through the client rather than passed as a value: the client is a
|
|
198
|
+
// napi class, so a detached method reference loses the instance it belongs to.
|
|
199
|
+
let getBlockHashes = HyperSync.makeGetBlockHashes(
|
|
200
|
+
~query=(~blockNumbers) => client.getBlockHashes(~blockNumbers),
|
|
201
|
+
)
|
|
198
202
|
|
|
199
203
|
{
|
|
200
204
|
name,
|
|
@@ -137,7 +137,7 @@ Learn more or get a free Envio API token at: https://envio.dev/app/api-tokens`);
|
|
|
137
137
|
requestStats: requestStats
|
|
138
138
|
};
|
|
139
139
|
};
|
|
140
|
-
let getBlockHashes = HyperSync.makeGetBlockHashes(client.getBlockHashes);
|
|
140
|
+
let getBlockHashes = HyperSync.makeGetBlockHashes(blockNumbers => client.getBlockHashes(blockNumbers));
|
|
141
141
|
return {
|
|
142
142
|
name: "HyperSync",
|
|
143
143
|
sourceFor: "Sync",
|
|
@@ -182,7 +182,11 @@ let make = (
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
// Called through the client rather than passed as a value: the client is a
|
|
186
|
+
// napi class, so a detached method reference loses the instance it belongs to.
|
|
187
|
+
let getBlockHashes = HyperSync.makeGetBlockHashes(
|
|
188
|
+
~query=(~blockNumbers) => client.getBlockHashes(~blockNumbers),
|
|
189
|
+
)
|
|
186
190
|
|
|
187
191
|
{
|
|
188
192
|
name,
|
|
@@ -127,7 +127,7 @@ function make(param) {
|
|
|
127
127
|
requestStats: requestStats
|
|
128
128
|
};
|
|
129
129
|
};
|
|
130
|
-
let getBlockHashes = HyperSync.makeGetBlockHashes(client.getBlockHashes);
|
|
130
|
+
let getBlockHashes = HyperSync.makeGetBlockHashes(blockNumbers => client.getBlockHashes(blockNumbers));
|
|
131
131
|
return {
|
|
132
132
|
name: "SvmHyperSync",
|
|
133
133
|
sourceFor: "Sync",
|