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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envio",
3
- "version": "3.7.0-svm-alpha.1",
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-svm-alpha.1",
73
- "envio-linux-x64-musl": "3.7.0-svm-alpha.1",
74
- "envio-linux-arm64": "3.7.0-svm-alpha.1",
75
- "envio-darwin-x64": "3.7.0-svm-alpha.1",
76
- "envio-darwin-arm64": "3.7.0-svm-alpha.1"
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 exec: (client, execParams) => promise<unit> = "exec"
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->exec({
636
+ await client->command({
632
637
  query: `DROP DATABASE IF EXISTS ${database} ON CLUSTER '{cluster}' SYNC`,
633
638
  })
634
639
  } else {
635
- await client->exec({
640
+ await client->command({
636
641
  query: `TRUNCATE DATABASE IF EXISTS ${database}${onClusterClause(~onCluster=ddlOnCluster)}`,
637
642
  })
638
643
  }
639
- await client->exec({
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->exec({
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->exec({
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->exec({
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->exec({
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->exec({query: `USE ${database}`})
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->exec({
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->exec({
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.exec({
431
+ await client.command({
432
432
  query: `DROP DATABASE IF EXISTS ` + database + ` ON CLUSTER '{cluster}' SYNC`
433
433
  });
434
434
  } else {
435
- await client.exec({
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.exec({
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.exec({
444
+ await Promise.all(entities.map(entityConfig => client.command({
445
445
  query: makeCreateHistoryTableQuery(entityConfig, database, replicated, ddlOnCluster, chainIdMode)
446
446
  })));
447
- await client.exec({
447
+ await client.command({
448
448
  query: makeCreateCheckpointsTableQuery(database, replicated, ddlOnCluster, chainIdMode)
449
449
  });
450
450
  if (hasReplicatedDatabaseEngine) {
451
- await client.exec({
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.exec({
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.exec({
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.exec({
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.exec({
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
- let getBlockHashes = HyperSync.makeGetBlockHashes(~query=client.getBlockHashes)
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
- let getBlockHashes = HyperSync.makeGetBlockHashes(~query=client.getBlockHashes)
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",