envio 3.7.0 → 3.9.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.
Files changed (79) hide show
  1. package/README.md +2 -2
  2. package/index.d.ts +399 -156
  3. package/package.json +6 -6
  4. package/src/AddressRows.res +121 -0
  5. package/src/AddressRows.res.mjs +143 -0
  6. package/src/Batch.res +2 -0
  7. package/src/Batch.res.mjs +2 -1
  8. package/src/ChainState.res +82 -68
  9. package/src/ChainState.res.mjs +81 -65
  10. package/src/ChainState.resi +14 -9
  11. package/src/Config.res +41 -91
  12. package/src/Config.res.mjs +34 -68
  13. package/src/ContractMapping.res +66 -0
  14. package/src/ContractMapping.res.mjs +73 -0
  15. package/src/Core.res +20 -0
  16. package/src/Core.res.mjs +4 -0
  17. package/src/Envio.res +54 -76
  18. package/src/EventConfigBuilder.res +157 -30
  19. package/src/EventConfigBuilder.res.mjs +118 -24
  20. package/src/FetchState.res +59 -67
  21. package/src/FetchState.res.mjs +34 -44
  22. package/src/HandlerRegister.res +20 -11
  23. package/src/HandlerRegister.res.mjs +22 -5
  24. package/src/Hasura.res +30 -22
  25. package/src/Hasura.res.mjs +11 -5
  26. package/src/InMemoryStore.res +18 -36
  27. package/src/InMemoryStore.res.mjs +12 -26
  28. package/src/IndexerState.res +21 -1
  29. package/src/IndexerState.res.mjs +9 -3
  30. package/src/IndexerState.resi +1 -0
  31. package/src/Internal.res +33 -13
  32. package/src/Internal.res.mjs +12 -16
  33. package/src/Main.res +27 -20
  34. package/src/Main.res.mjs +19 -14
  35. package/src/MemoryStorage.res +78 -73
  36. package/src/MemoryStorage.res.mjs +66 -81
  37. package/src/Metrics.res +15 -1
  38. package/src/Metrics.res.mjs +5 -1
  39. package/src/Persistence.res +34 -18
  40. package/src/Persistence.res.mjs +8 -5
  41. package/src/PgStorage.res +189 -66
  42. package/src/PgStorage.res.mjs +93 -59
  43. package/src/Rollback.res +14 -10
  44. package/src/Rollback.res.mjs +4 -2
  45. package/src/SimulateItems.res +254 -9
  46. package/src/SimulateItems.res.mjs +214 -47
  47. package/src/TestIndexer.res +119 -121
  48. package/src/TestIndexer.res.mjs +95 -100
  49. package/src/Utils.res +7 -0
  50. package/src/Utils.res.mjs +9 -2
  51. package/src/Writing.res +2 -0
  52. package/src/Writing.res.mjs +2 -1
  53. package/src/bindings/ClickHouse.res +39 -6
  54. package/src/bindings/ClickHouse.res.mjs +29 -4
  55. package/src/bindings/NodeJs.res +9 -0
  56. package/src/bindings/NodeJs.res.mjs +8 -1
  57. package/src/bindings/Postgres.res +9 -0
  58. package/src/bindings/Postgres.res.mjs +3 -0
  59. package/src/db/EntityHistory.res +12 -18
  60. package/src/db/EntityHistory.res.mjs +3 -14
  61. package/src/db/InternalTable.res +182 -65
  62. package/src/db/InternalTable.res.mjs +183 -73
  63. package/src/db/Table.res +24 -0
  64. package/src/db/Table.res.mjs +20 -1
  65. package/src/sources/AddressSet.res +0 -22
  66. package/src/sources/AddressStore.res +48 -88
  67. package/src/sources/AddressStore.res.mjs +11 -22
  68. package/src/sources/EvmHyperSyncSource.res +3 -2
  69. package/src/sources/SimulateSource.res +8 -4
  70. package/src/sources/SimulateSource.res.mjs +7 -3
  71. package/src/sources/Svm.res +34 -7
  72. package/src/sources/Svm.res.mjs +32 -4
  73. package/src/sources/SvmHyperSyncClient.res +24 -30
  74. package/src/sources/SvmHyperSyncClient.res.mjs +3 -2
  75. package/src/sources/SvmHyperSyncSource.res +88 -36
  76. package/src/sources/SvmHyperSyncSource.res.mjs +71 -39
  77. package/src/sources/TransactionStore.res +38 -0
  78. package/src/sources/TransactionStore.res.mjs +5 -0
  79. package/svm.schema.json +37 -82
@@ -2,17 +2,153 @@
2
2
 
3
3
  import * as Table from "./Table.res.mjs";
4
4
  import * as Utils from "../Utils.res.mjs";
5
- import * as Config from "../Config.res.mjs";
6
5
  import * as Address from "../Address.res.mjs";
7
6
  import * as ChainId from "../ChainId.res.mjs";
7
+ import * as Postgres from "../bindings/Postgres.res.mjs";
8
+ import * as AddressRows from "../AddressRows.res.mjs";
8
9
  import * as Stdlib_Null from "@rescript/runtime/lib/es6/Stdlib_Null.js";
9
10
  import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
10
11
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
11
12
  import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
12
13
  import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
13
14
 
15
+ let undefinedTableSqlState = "42P01";
16
+
17
+ function isUndefinedTable(exn) {
18
+ let e = Primitive_exceptions.internalToException(exn);
19
+ if (e.RE_EXN_ID === "JsExn") {
20
+ return e._1.code === undefinedTableSqlState;
21
+ } else {
22
+ return false;
23
+ }
24
+ }
25
+
26
+ function chainIdArrayType(pgSchema, chainIdMode) {
27
+ return Table.getPgFieldType("ChainId", pgSchema, true, false, false, chainIdMode);
28
+ }
29
+
30
+ let table = Table.mkTable("envio_contracts", undefined, [
31
+ Table.mkField("id", "SmallInt", S$RescriptSchema.int, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
32
+ Table.mkField("name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
33
+ ], undefined);
34
+
35
+ function makeInsertQuery(pgSchema) {
36
+ return `INSERT INTO "` + pgSchema + `"."` + table.tableName + `" ("id", "name")
37
+ SELECT * FROM unnest($1::` + "SMALLINT" + `[],$2::` + "TEXT" + `[]);`;
38
+ }
39
+
40
+ function insert(sql, pgSchema, contractNames) {
41
+ return sql.unsafe(makeInsertQuery(pgSchema), [
42
+ contractNames.map((param, idx) => idx),
43
+ contractNames
44
+ ], {prepare: true});
45
+ }
46
+
47
+ async function read(sql, pgSchema) {
48
+ try {
49
+ let rows = await sql.unsafe(`SELECT "name" FROM "` + pgSchema + `"."` + table.tableName + `" ORDER BY "id";`);
50
+ return rows.map(row => row.name);
51
+ } catch (raw_exn) {
52
+ let exn = Primitive_exceptions.internalToException(raw_exn);
53
+ if (isUndefinedTable(exn)) {
54
+ return;
55
+ }
56
+ throw exn;
57
+ }
58
+ }
59
+
60
+ let EnvioContracts = {
61
+ table: table,
62
+ makeInsertQuery: makeInsertQuery,
63
+ insert: insert,
64
+ read: read
65
+ };
66
+
67
+ let name = "envio_addresses";
68
+
69
+ let table$1 = Table.mkTable(name, undefined, [
70
+ Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
71
+ Table.mkField("address", "Bytea", S$RescriptSchema.string, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
72
+ Table.mkField("contract_id", "SmallInt", S$RescriptSchema.int, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
73
+ Table.mkField("registration_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
74
+ ], undefined);
75
+
76
+ function makeInsertQuery$1(pgSchema, chainIdModeOpt) {
77
+ let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
78
+ let chainIdArrayType$1 = chainIdArrayType(pgSchema, chainIdMode);
79
+ return `INSERT INTO "` + pgSchema + `"."` + table$1.tableName + `" ("chain_id", "address", "contract_id", "registration_block")
80
+ SELECT * FROM unnest($1::` + chainIdArrayType$1 + `,$2::` + "BYTEA" + `[],$3::` + "SMALLINT" + `[],$4::` + "INTEGER" + `[])
81
+ ON CONFLICT ("chain_id", "address", "contract_id") DO NOTHING;`;
82
+ }
83
+
84
+ function insert$1(sql, pgSchema, rows, chainIdModeOpt) {
85
+ let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
86
+ let chainIds = [];
87
+ let addresses = [];
88
+ let contractIds = [];
89
+ let registrationBlocks = [];
90
+ rows.forEach(row => {
91
+ chainIds.push(row.chainId);
92
+ addresses.push(row.address);
93
+ contractIds.push(row.contractId);
94
+ registrationBlocks.push(row.registrationBlock);
95
+ });
96
+ return sql.unsafe(makeInsertQuery$1(pgSchema, chainIdMode), [
97
+ chainIds,
98
+ sql.typed(addresses, Postgres.byteaArrayOid),
99
+ contractIds,
100
+ registrationBlocks
101
+ ], {prepare: true});
102
+ }
103
+
104
+ function makeDeleteQuery(pgSchema, chainIdModeOpt) {
105
+ let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
106
+ let chainIdArrayType$1 = chainIdArrayType(pgSchema, chainIdMode);
107
+ return `DELETE FROM "` + pgSchema + `"."` + table$1.tableName + `"
108
+ USING unnest($1::` + chainIdArrayType$1 + `,$2::` + "BYTEA" + `[],$3::` + "SMALLINT" + `[]) AS dead(chain_id, address, contract_id)
109
+ WHERE "` + table$1.tableName + `"."chain_id" = dead.chain_id
110
+ AND "` + table$1.tableName + `"."address" = dead.address
111
+ AND "` + table$1.tableName + `"."contract_id" = dead.contract_id;`;
112
+ }
113
+
114
+ function $$delete(sql, pgSchema, keys, chainIdModeOpt) {
115
+ let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
116
+ let chainIds = [];
117
+ let addresses = [];
118
+ let contractIds = [];
119
+ keys.forEach(key => {
120
+ chainIds.push(key.chainId);
121
+ addresses.push(key.address);
122
+ contractIds.push(key.contractId);
123
+ });
124
+ return sql.unsafe(makeDeleteQuery(pgSchema, chainIdMode), [
125
+ chainIds,
126
+ sql.typed(addresses, Postgres.byteaArrayOid),
127
+ contractIds
128
+ ], {prepare: true});
129
+ }
130
+
131
+ function makeGetRowsQuery(pgSchema) {
132
+ return `SELECT "chain_id" as "chainId",
133
+ "address" as "address",
134
+ "contract_id" as "contractId",
135
+ "registration_block" as "registrationBlock"
136
+ FROM "` + pgSchema + `"."` + table$1.tableName + `";`;
137
+ }
138
+
139
+ let EnvioAddresses = {
140
+ name: name,
141
+ table: table$1,
142
+ makeInsertQuery: makeInsertQuery$1,
143
+ insert: insert$1,
144
+ makeDeleteQuery: makeDeleteQuery,
145
+ $$delete: $$delete,
146
+ makeGetRowsQuery: makeGetRowsQuery
147
+ };
148
+
14
149
  let fields = [
15
150
  "id",
151
+ "ecosystem",
16
152
  "start_block",
17
153
  "end_block",
18
154
  "max_reorg_depth",
@@ -25,8 +161,9 @@ let fields = [
25
161
  "_is_hyper_sync"
26
162
  ];
27
163
 
28
- let table = Table.mkTable("envio_chains", undefined, [
164
+ let table$2 = Table.mkTable("envio_chains", undefined, [
29
165
  Table.mkField("id", "ChainId", ChainId.schema, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
166
+ Table.mkField("ecosystem", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
30
167
  Table.mkField("start_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
31
168
  Table.mkField("end_block", "Int32", S$RescriptSchema.$$null(S$RescriptSchema.int), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
32
169
  Table.mkField("max_reorg_depth", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
@@ -42,6 +179,7 @@ let table = Table.mkTable("envio_chains", undefined, [
42
179
  function initialFromConfig(chainConfig) {
43
180
  return {
44
181
  id: chainConfig.id,
182
+ ecosystem: chainConfig.ecosystem,
45
183
  start_block: chainConfig.startBlock,
46
184
  end_block: Stdlib_Null.fromOption(chainConfig.endBlock),
47
185
  max_reorg_depth: chainConfig.maxReorgDepth,
@@ -73,6 +211,8 @@ function makeInitialValuesQuery(pgSchema, chainConfigs) {
73
211
  } else {
74
212
  return "false";
75
213
  }
214
+ } else if (match === "string") {
215
+ return `'` + value + `'`;
76
216
  } else if (match === "object") {
77
217
  return "NULL";
78
218
  } else {
@@ -81,7 +221,7 @@ function makeInitialValuesQuery(pgSchema, chainConfigs) {
81
221
  });
82
222
  return `(` + values.join(", ") + `)`;
83
223
  });
84
- return `INSERT INTO "` + pgSchema + `"."` + table.tableName + `" (` + columnNames.join(", ") + `)
224
+ return `INSERT INTO "` + pgSchema + `"."` + table$2.tableName + `" (` + columnNames.join(", ") + `)
85
225
  VALUES ` + valuesRows.join(",\n ") + `;`;
86
226
  }
87
227
 
@@ -97,13 +237,13 @@ function makeMetaFieldsUpdateQuery(pgSchema) {
97
237
  let paramIndex = index + 2 | 0;
98
238
  return `"` + field + `" = $` + paramIndex.toString();
99
239
  });
100
- return `UPDATE "` + pgSchema + `"."` + table.tableName + `"
240
+ return `UPDATE "` + pgSchema + `"."` + table$2.tableName + `"
101
241
  SET ` + setClauses.join(",\n ") + `
102
242
  WHERE "` + "id" + `" = $1;`;
103
243
  }
104
244
 
105
245
  function makeSetReadyAtQuery(pgSchema) {
106
- return `UPDATE "` + pgSchema + `"."` + table.tableName + `"
246
+ return `UPDATE "` + pgSchema + `"."` + table$2.tableName + `"
107
247
  SET "` + "ready_at" + `" = $1
108
248
  WHERE "` + "id" + `" = $2
109
249
  AND "` + "ready_at" + `" IS NULL;`;
@@ -119,40 +259,15 @@ function makeGetInitialStateQuery(pgSchema) {
119
259
  "` + "events_processed" + `"::float8 as "numEventsProcessed",
120
260
  "` + "progress_block" + `" as "progressBlockNumber",
121
261
  "` + "source_block" + `" as "sourceBlockNumber"
122
- FROM "` + pgSchema + `"."` + table.tableName + `";`;
123
- }
124
-
125
- function makeGetIndexingAddressesQuery(pgSchema) {
126
- return `SELECT "chain_id" as "chainId",
127
- SUBSTRING("id" FROM POSITION('-' IN "id") + 1) as "address",
128
- "contract_name" as "contractName",
129
- "registration_block" as "registrationBlock"
130
- FROM "` + pgSchema + `"."` + Config.EnvioAddresses.table.tableName + `";`;
262
+ FROM "` + pgSchema + `"."` + table$2.tableName + `";`;
131
263
  }
132
264
 
133
265
  async function getInitialState(sql, pgSchema) {
134
266
  let match = await Promise.all([
135
267
  sql.unsafe(makeGetInitialStateQuery(pgSchema)),
136
- sql.unsafe(makeGetIndexingAddressesQuery(pgSchema))
268
+ sql.unsafe(makeGetRowsQuery(pgSchema))
137
269
  ]);
138
- let indexingAddressesByChainId = {};
139
- match[1].forEach(row => {
140
- let key = ChainId.toString(ChainId.normalizeOrThrow(row.chainId));
141
- let addresses = indexingAddressesByChainId[key];
142
- let addresses$1;
143
- if (addresses !== undefined) {
144
- addresses$1 = addresses;
145
- } else {
146
- let addresses$2 = [];
147
- indexingAddressesByChainId[key] = addresses$2;
148
- addresses$1 = addresses$2;
149
- }
150
- addresses$1.push({
151
- address: row.address,
152
- contractName: row.contractName,
153
- registrationBlock: row.registrationBlock
154
- });
155
- });
270
+ let addressRowsByChainId = AddressRows.group(match[1]);
156
271
  return match[0].map(rawInitialState => {
157
272
  let id = ChainId.normalizeOrThrow(rawInitialState.id);
158
273
  return {
@@ -164,7 +279,7 @@ async function getInitialState(sql, pgSchema) {
164
279
  timestampCaughtUpToHeadOrEndblock: rawInitialState.timestampCaughtUpToHeadOrEndblock,
165
280
  numEventsProcessed: rawInitialState.numEventsProcessed,
166
281
  progressBlockNumber: rawInitialState.progressBlockNumber,
167
- indexingAddresses: Stdlib_Option.getOr(indexingAddressesByChainId[ChainId.toString(id)], []),
282
+ addressRows: Stdlib_Option.getOr(addressRowsByChainId[ChainId.toString(id)], AddressRows.emptySeedRows()),
168
283
  sourceBlockNumber: rawInitialState.sourceBlockNumber
169
284
  };
170
285
  });
@@ -181,7 +296,7 @@ function makeProgressFieldsUpdateQuery(pgSchema) {
181
296
  let paramIndex = index + 2 | 0;
182
297
  return `"` + field + `" = $` + paramIndex.toString();
183
298
  });
184
- return `UPDATE "` + pgSchema + `"."` + table.tableName + `"
299
+ return `UPDATE "` + pgSchema + `"."` + table$2.tableName + `"
185
300
  SET ` + setClauses.join(",\n ") + `
186
301
  WHERE "id" = $1;`;
187
302
  }
@@ -219,14 +334,13 @@ function setProgressedChains(sql, pgSchema, progressedChains) {
219
334
 
220
335
  let Chains = {
221
336
  fields: fields,
222
- table: table,
337
+ table: table$2,
223
338
  initialFromConfig: initialFromConfig,
224
339
  makeInitialValuesQuery: makeInitialValuesQuery,
225
340
  metaFields: metaFields,
226
341
  makeMetaFieldsUpdateQuery: makeMetaFieldsUpdateQuery,
227
342
  makeSetReadyAtQuery: makeSetReadyAtQuery,
228
343
  makeGetInitialStateQuery: makeGetInitialStateQuery,
229
- makeGetIndexingAddressesQuery: makeGetIndexingAddressesQuery,
230
344
  getInitialState: getInitialState,
231
345
  progressFields: progressFields,
232
346
  makeProgressFieldsUpdateQuery: makeProgressFieldsUpdateQuery,
@@ -234,26 +348,19 @@ let Chains = {
234
348
  setProgressedChains: setProgressedChains
235
349
  };
236
350
 
237
- let table$1 = Table.mkTable("envio_info", undefined, [
351
+ let table$3 = Table.mkTable("envio_info", undefined, [
238
352
  Table.mkField("id", "Int32", S$RescriptSchema.int, "1", undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
239
353
  Table.mkField("config", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
240
354
  ], undefined);
241
355
 
242
- let undefinedTableSqlState = "42P01";
243
-
244
- async function read(sql, pgSchema) {
356
+ async function read$1(sql, pgSchema) {
245
357
  let rows;
246
358
  try {
247
- rows = await sql.unsafe(`SELECT "config" FROM "` + pgSchema + `"."` + table$1.tableName + `" LIMIT 1;`);
359
+ rows = await sql.unsafe(`SELECT "config" FROM "` + pgSchema + `"."` + table$3.tableName + `" LIMIT 1;`);
248
360
  } catch (raw_exn) {
249
361
  let exn = Primitive_exceptions.internalToException(raw_exn);
250
- let e = Primitive_exceptions.internalToException(exn);
251
- if (e.RE_EXN_ID === "JsExn") {
252
- if (e._1.code === undefinedTableSqlState) {
253
- rows = [];
254
- } else {
255
- throw exn;
256
- }
362
+ if (isUndefinedTable(exn)) {
363
+ rows = [];
257
364
  } else {
258
365
  throw exn;
259
366
  }
@@ -262,13 +369,12 @@ async function read(sql, pgSchema) {
262
369
  }
263
370
 
264
371
  function write(sql, pgSchema, envioInfo) {
265
- return sql.unsafe(`INSERT INTO "` + pgSchema + `"."` + table$1.tableName + `" ("id", "config") VALUES (1, $1) ON CONFLICT ("id") DO UPDATE SET "config" = EXCLUDED."config";`, [JSON.stringify(envioInfo)], {prepare: true});
372
+ return sql.unsafe(`INSERT INTO "` + pgSchema + `"."` + table$3.tableName + `" ("id", "config") VALUES (1, $1) ON CONFLICT ("id") DO UPDATE SET "config" = EXCLUDED."config";`, [JSON.stringify(envioInfo)], {prepare: true});
266
373
  }
267
374
 
268
375
  let EnvioInfo = {
269
- table: table$1,
270
- undefinedTableSqlState: undefinedTableSqlState,
271
- read: read,
376
+ table: table$3,
377
+ read: read$1,
272
378
  write: write
273
379
  };
274
380
 
@@ -283,7 +389,7 @@ let dbSchema = S$RescriptSchema.object(s => ({
283
389
  events_processed: s.f("events_processed", S$RescriptSchema.int)
284
390
  }));
285
391
 
286
- let table$2 = Table.mkTable("envio_checkpoints", undefined, [
392
+ let table$4 = Table.mkTable("envio_checkpoints", undefined, [
287
393
  Table.mkField("id", "UInt64", S$RescriptSchema.bigint, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
288
394
  Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
289
395
  Table.mkField("block_number", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
@@ -296,7 +402,7 @@ function makeGetReorgCheckpointsQuery(pgSchema) {
296
402
  SELECT
297
403
  "` + "id" + `" as id,
298
404
  "` + "source_block" + `" - "` + "max_reorg_depth" + `" AS safe_block
299
- FROM "` + pgSchema + `"."` + table.tableName + `"
405
+ FROM "` + pgSchema + `"."` + table$2.tableName + `"
300
406
  WHERE "` + "max_reorg_depth" + `" > 0
301
407
  AND "` + "progress_block" + `" > "` + "source_block" + `" - "` + "max_reorg_depth" + `"
302
408
  )
@@ -305,7 +411,7 @@ SELECT
305
411
  cp."` + "chain_id" + `",
306
412
  cp."` + "block_number" + `",
307
413
  cp."` + "block_hash" + `"
308
- FROM "` + pgSchema + `"."` + table$2.tableName + `" cp
414
+ FROM "` + pgSchema + `"."` + table$4.tableName + `" cp
309
415
  INNER JOIN reorg_chains rc
310
416
  ON cp."` + "chain_id" + `" = rc.id
311
417
  WHERE cp."` + "block_hash" + `" IS NOT NULL
@@ -313,17 +419,17 @@ WHERE cp."` + "block_hash" + `" IS NOT NULL
313
419
  }
314
420
 
315
421
  function makeCommitedCheckpointIdQuery(pgSchema) {
316
- return `SELECT COALESCE(MAX(` + "id" + `), ` + (0n).toString() + `) AS id FROM "` + pgSchema + `"."` + table$2.tableName + `";`;
422
+ return `SELECT COALESCE(MAX(` + "id" + `), ` + (0n).toString() + `) AS id FROM "` + pgSchema + `"."` + table$4.tableName + `";`;
317
423
  }
318
424
 
319
425
  function makeInsertCheckpointQuery(pgSchema, chainIdModeOpt) {
320
426
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
321
- let chainIdArrayType = Table.getPgFieldType("ChainId", pgSchema, true, false, false, chainIdMode);
322
- return `INSERT INTO "` + pgSchema + `"."` + table$2.tableName + `" ("` + "id" + `", "` + "chain_id" + `", "` + "block_number" + `", "` + "block_hash" + `", "` + "events_processed" + `")
323
- SELECT * FROM unnest($1::` + "BIGINT" + `[],$2::` + chainIdArrayType + `,$3::` + "INTEGER" + `[],$4::` + "TEXT" + `[],$5::` + "INTEGER" + `[]);`;
427
+ let chainIdArrayType$1 = chainIdArrayType(pgSchema, chainIdMode);
428
+ return `INSERT INTO "` + pgSchema + `"."` + table$4.tableName + `" ("` + "id" + `", "` + "chain_id" + `", "` + "block_number" + `", "` + "block_hash" + `", "` + "events_processed" + `")
429
+ SELECT * FROM unnest($1::` + "BIGINT" + `[],$2::` + chainIdArrayType$1 + `,$3::` + "INTEGER" + `[],$4::` + "TEXT" + `[],$5::` + "INTEGER" + `[]);`;
324
430
  }
325
431
 
326
- function insert(sql, pgSchema, checkpointIds, checkpointChainIds, checkpointBlockNumbers, checkpointBlockHashes, checkpointEventsProcessed, chainIdModeOpt) {
432
+ function insert$2(sql, pgSchema, checkpointIds, checkpointChainIds, checkpointBlockNumbers, checkpointBlockHashes, checkpointEventsProcessed, chainIdModeOpt) {
327
433
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
328
434
  let query = makeInsertCheckpointQuery(pgSchema, chainIdMode);
329
435
  let checkpointIdStrings = Utils.$$BigInt.arrayToStringArray(checkpointIds);
@@ -337,11 +443,11 @@ function insert(sql, pgSchema, checkpointIds, checkpointChainIds, checkpointBloc
337
443
  }
338
444
 
339
445
  function rollback(sql, pgSchema, rollbackTargetCheckpointId) {
340
- return sql.unsafe(`DELETE FROM "` + pgSchema + `"."` + table$2.tableName + `" WHERE "` + "id" + `" > $1;`, [rollbackTargetCheckpointId.toString()], {prepare: true});
446
+ return sql.unsafe(`DELETE FROM "` + pgSchema + `"."` + table$4.tableName + `" WHERE "` + "id" + `" > $1;`, [rollbackTargetCheckpointId.toString()], {prepare: true});
341
447
  }
342
448
 
343
449
  function makePruneStaleCheckpointsQuery(pgSchema) {
344
- return `DELETE FROM "` + pgSchema + `"."` + table$2.tableName + `" WHERE "` + "id" + `" < $1;`;
450
+ return `DELETE FROM "` + pgSchema + `"."` + table$4.tableName + `" WHERE "` + "id" + `" < $1;`;
345
451
  }
346
452
 
347
453
  function pruneStaleCheckpoints(sql, pgSchema, safeCheckpointId) {
@@ -349,7 +455,7 @@ function pruneStaleCheckpoints(sql, pgSchema, safeCheckpointId) {
349
455
  }
350
456
 
351
457
  function makeGetRollbackTargetCheckpointQuery(pgSchema) {
352
- return `SELECT "` + "id" + `" FROM "` + pgSchema + `"."` + table$2.tableName + `"
458
+ return `SELECT "` + "id" + `" FROM "` + pgSchema + `"."` + table$4.tableName + `"
353
459
  WHERE
354
460
  "` + "chain_id" + `" = $1 AND
355
461
  "` + "block_number" + `" <= $2
@@ -370,7 +476,7 @@ function makeGetRollbackProgressDiffQuery(pgSchema) {
370
476
  "` + "chain_id" + `"::float8 as "` + "chain_id" + `",
371
477
  SUM("` + "events_processed" + `") as events_processed_diff,
372
478
  MIN("` + "block_number" + `") - 1 as new_progress_block_number
373
- FROM "` + pgSchema + `"."` + table$2.tableName + `"
479
+ FROM "` + pgSchema + `"."` + table$4.tableName + `"
374
480
  WHERE "` + "id" + `" > $1
375
481
  GROUP BY "` + "chain_id" + `";`;
376
482
  }
@@ -382,11 +488,11 @@ function getRollbackProgressDiff(sql, pgSchema, rollbackTargetCheckpointId) {
382
488
  let Checkpoints = {
383
489
  dbSchema: dbSchema,
384
490
  initialCheckpointId: 0n,
385
- table: table$2,
491
+ table: table$4,
386
492
  makeGetReorgCheckpointsQuery: makeGetReorgCheckpointsQuery,
387
493
  makeCommitedCheckpointIdQuery: makeCommitedCheckpointIdQuery,
388
494
  makeInsertCheckpointQuery: makeInsertCheckpointQuery,
389
- insert: insert,
495
+ insert: insert$2,
390
496
  rollback: rollback,
391
497
  makePruneStaleCheckpointsQuery: makePruneStaleCheckpointsQuery,
392
498
  pruneStaleCheckpoints: pruneStaleCheckpoints,
@@ -411,7 +517,7 @@ let schema = S$RescriptSchema.schema(s => ({
411
517
  params: s.m(S$RescriptSchema.json(false))
412
518
  }));
413
519
 
414
- let table$3 = Table.mkTable("raw_events", undefined, [
520
+ let table$5 = Table.mkTable("raw_events", undefined, [
415
521
  Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
416
522
  Table.mkField("event_id", "UInt64", S$RescriptSchema.bigint, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
417
523
  Table.mkField("event_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
@@ -429,7 +535,7 @@ let table$3 = Table.mkTable("raw_events", undefined, [
429
535
 
430
536
  let RawEvents = {
431
537
  schema: schema,
432
- table: table$3
538
+ table: table$5
433
539
  };
434
540
 
435
541
  let metaViewName = "_meta";
@@ -440,6 +546,7 @@ function makeMetaViewQuery(pgSchema) {
440
546
  return `CREATE VIEW "` + pgSchema + `"."` + metaViewName + `" AS
441
547
  SELECT
442
548
  "` + "id" + `" AS "chainId",
549
+ "` + "ecosystem" + `" AS "ecosystem",
443
550
  "` + "start_block" + `" AS "startBlock",
444
551
  "` + "end_block" + `" AS "endBlock",
445
552
  "` + "progress_block" + `" AS "progressBlock",
@@ -449,7 +556,7 @@ SELECT
449
556
  "` + "source_block" + `" AS "sourceBlock",
450
557
  "` + "ready_at" + `" AS "readyAt",
451
558
  ("` + "ready_at" + `" IS NOT NULL) AS "isReady"
452
- FROM "` + pgSchema + `"."` + table.tableName + `"
559
+ FROM "` + pgSchema + `"."` + table$2.tableName + `"
453
560
  ORDER BY "` + "id" + `";`;
454
561
  }
455
562
 
@@ -458,6 +565,7 @@ function makeChainMetadataViewQuery(pgSchema) {
458
565
  SELECT
459
566
  "` + "source_block" + `" AS "block_height",
460
567
  "` + "id" + `" AS "chain_id",
568
+ "` + "ecosystem" + `" AS "ecosystem",
461
569
  "` + "end_block" + `" AS "end_block",
462
570
  "` + "first_event_block" + `" AS "first_event_block_number",
463
571
  "` + "_is_hyper_sync" + `" AS "is_hyper_sync",
@@ -467,7 +575,7 @@ SELECT
467
575
  "` + "events_processed" + `"::float4 AS "num_events_processed",
468
576
  "` + "start_block" + `" AS "start_block",
469
577
  "` + "ready_at" + `" AS "timestamp_caught_up_to_head_or_endblock"
470
- FROM "` + pgSchema + `"."` + table.tableName + `";`;
578
+ FROM "` + pgSchema + `"."` + table$2.tableName + `";`;
471
579
  }
472
580
 
473
581
  let Views = {
@@ -483,12 +591,14 @@ let isNullable = true;
483
591
 
484
592
  let isIndex = true;
485
593
 
486
- let EnvioAddresses;
487
-
488
594
  export {
489
595
  isPrimaryKey,
490
596
  isNullable,
491
597
  isIndex,
598
+ undefinedTableSqlState,
599
+ isUndefinedTable,
600
+ chainIdArrayType,
601
+ EnvioContracts,
492
602
  EnvioAddresses,
493
603
  Chains,
494
604
  EnvioInfo,
package/src/db/Table.res CHANGED
@@ -21,6 +21,10 @@ type fieldType =
21
21
  | Boolean
22
22
  | Uint32
23
23
  | UInt52
24
+ | SmallInt
25
+ // Raw bytes. Only the internal tables use it — the one column that stores an
26
+ // address in the binary form the Rust address store keys on.
27
+ | Bytea
24
28
  | UInt64
25
29
  | Int32
26
30
  // Resolved to Int32 or UInt64 storage from the config's `ChainId.mode`, so
@@ -141,6 +145,20 @@ let getPgFieldName = fieldOrDerived =>
141
145
 
142
146
  let idFieldName = "id"
143
147
 
148
+ let maxPgTableNameLength = 63
149
+
150
+ // Postgres truncates identifiers past its limit on its own, which would collapse
151
+ // two long names onto one. Cutting the readable half and keeping `uniqueSuffix`
152
+ // whole makes every generated name distinct by construction, so the suffix has
153
+ // to be something already unique to the table it names.
154
+ let fitPgTableName = (fullName, ~uniqueSuffix) =>
155
+ if fullName->String.length > maxPgTableNameLength {
156
+ fullName->String.slice(~start=0, ~end=maxPgTableNameLength - uniqueSuffix->String.length) ++
157
+ uniqueSuffix
158
+ } else {
159
+ fullName
160
+ }
161
+
144
162
  let getPgFieldType = (
145
163
  ~fieldType: fieldType,
146
164
  ~pgSchema,
@@ -160,6 +178,8 @@ let getPgFieldType = (
160
178
  }
161
179
  | Uint32 => (Postgres.BigInt :> string)
162
180
  | UInt52 => (Postgres.BigInt :> string)
181
+ | SmallInt => (Postgres.SmallInt :> string)
182
+ | Bytea => (Postgres.Bytea :> string)
163
183
  | UInt64 => (Postgres.BigInt :> string)
164
184
  | Number => (Postgres.DoublePrecision :> string)
165
185
  | BigInt({?precision}) =>
@@ -327,6 +347,9 @@ type queryField = {
327
347
  // Loads are served by Postgres only (ClickHouse is a write-only sink), so
328
348
  // no ClickHouse counterpart is needed here.
329
349
  pgDbFieldName: string,
350
+ // The chain-id column a per-chain entity's table is partitioned by, which a
351
+ // filter has to write into the SQL rather than bind. See `makeFilterCondition`.
352
+ isChainId: bool,
330
353
  }
331
354
  let queryFields: table => dict<queryField> = Utils.WeakMap.memoize(table => {
332
355
  let dict = Dict.make()
@@ -339,6 +362,7 @@ let queryFields: table => dict<queryField> = Utils.WeakMap.memoize(table => {
339
362
  fieldSchema: field.fieldSchema,
340
363
  arrayFieldSchema: S.array(field.fieldSchema)->S.toUnknown,
341
364
  pgDbFieldName: field->getPgDbFieldName,
365
+ isChainId: field.isChainId,
342
366
  },
343
367
  )
344
368
  | DerivedFrom(_) => ()
@@ -98,6 +98,14 @@ function getPgFieldName(fieldOrDerived) {
98
98
 
99
99
  let idFieldName = "id";
100
100
 
101
+ function fitPgTableName(fullName, uniqueSuffix) {
102
+ if (fullName.length > 63) {
103
+ return fullName.slice(0, 63 - uniqueSuffix.length | 0) + uniqueSuffix;
104
+ } else {
105
+ return fullName;
106
+ }
107
+ }
108
+
101
109
  function getPgFieldType(fieldType, pgSchema, isArray, isNumericArrayAsText, isNullable, chainIdModeOpt) {
102
110
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
103
111
  let columnType;
@@ -109,6 +117,12 @@ function getPgFieldType(fieldType, pgSchema, isArray, isNumericArrayAsText, isNu
109
117
  case "Boolean" :
110
118
  columnType = "BOOLEAN";
111
119
  break;
120
+ case "SmallInt" :
121
+ columnType = "SMALLINT";
122
+ break;
123
+ case "Bytea" :
124
+ columnType = "BYTEA";
125
+ break;
112
126
  case "Int32" :
113
127
  columnType = "INTEGER";
114
128
  break;
@@ -296,7 +310,8 @@ let queryFields = Utils.$$WeakMap.memoize(table => {
296
310
  dict[getApiFieldName(field$1)] = {
297
311
  fieldSchema: field$1.fieldSchema,
298
312
  arrayFieldSchema: S$RescriptSchema.array(field$1.fieldSchema),
299
- pgDbFieldName: getPgDbFieldName(field$1)
313
+ pgDbFieldName: getPgDbFieldName(field$1),
314
+ isChainId: field$1.isChainId
300
315
  };
301
316
  });
302
317
  return dict;
@@ -467,6 +482,8 @@ function getCompositeIndexes(table) {
467
482
  return getUnfilteredCompositeIndexesUnsafe(table).filter(ind => ind.length > 1);
468
483
  }
469
484
 
485
+ let maxPgTableNameLength = 63;
486
+
470
487
  export {
471
488
  makeEnumConfig,
472
489
  mkField,
@@ -478,6 +495,8 @@ export {
478
495
  getClickHouseDbFieldName,
479
496
  getPgFieldName,
480
497
  idFieldName,
498
+ maxPgTableNameLength,
499
+ fitPgTableName,
481
500
  getPgFieldType,
482
501
  mkTable,
483
502
  getPgPrimaryKeyFieldNames,
@@ -1,47 +1,25 @@
1
- // Binding to the Rust `AddressSet` napi class: an immutable, ordered snapshot
2
- // of some of a chain's indexed addresses, handed to a fetch-state partition
3
- // instead of a JS address array. Sets are ordered by
4
- // `(effectiveStartBlock, address)`, so the same addresses always produce the
5
- // same set however they were registered or restored. Everything a query derives
6
- // from one (padded topics, the routing owner index, per-contract counts) is
7
- // built once inside Rust and shared by every query the partition makes.
8
1
  type t
9
2
 
10
3
  type startBlockGroup = {startBlock: int, count: int}
11
4
 
12
5
  @send external size: t => int = "size"
13
6
 
14
- // Live addresses of one contract, derived once per set inside Rust — so the
15
- // fetch state can size and split partitions without ever walking the addresses.
16
7
  @send external countFor: (t, string) => int = "countFor"
17
8
 
18
- // This set holds the address under the contract and it has already started at
19
- // the block — the gate a real source's router applies to a server-side
20
- // address-filtered query. The temporal half still comes from the store: a
21
- // merged partition's addresses don't all start at the same block.
22
9
  @send external containsAt: (t, Address.t, string, int) => bool = "containsAt"
23
10
 
24
11
  @send external contractNames: t => array<string> = "contractNames"
25
12
 
26
- // Distinct effective start blocks in this set, ascending — how partition
27
- // creation decides where one partition ends and the next begins.
28
13
  @send external startBlockGroups: t => array<startBlockGroup> = "startBlockGroups"
29
14
 
30
15
  @send external slice: (t, ~offset: int, ~limit: option<int>) => t = "slice"
31
16
 
32
- // Keeps only the named contracts' addresses, in set order.
33
17
  @send external filterByContracts: (t, array<string>) => t = "filterByContracts"
34
18
 
35
- // Drops addresses registered after the target block, and any the store has
36
- // tombstoned since this set was built.
37
19
  @send external filterByRegistrationBlock: (t, int) => t = "filterByRegistrationBlock"
38
20
 
39
- // Union with another set of the same store, keeping set order; duplicates
40
- // collapse.
41
21
  @send external merge: (t, t) => t = "merge"
42
22
 
43
- // Canonical address strings in set order. Not on a query path — queries read
44
- // the set's cached slices inside Rust.
45
23
  @send external addresses: t => array<Address.t> = "addresses"
46
24
 
47
25
  @send external entries: t => array<Internal.indexingContract> = "entries"