envio 3.8.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 (64) hide show
  1. package/README.md +2 -2
  2. package/index.d.ts +158 -104
  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 +76 -70
  9. package/src/ChainState.res.mjs +76 -65
  10. package/src/ChainState.resi +14 -9
  11. package/src/Config.res +23 -82
  12. package/src/Config.res.mjs +19 -63
  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/EventConfigBuilder.res +0 -2
  18. package/src/EventConfigBuilder.res.mjs +0 -2
  19. package/src/FetchState.res +59 -67
  20. package/src/FetchState.res.mjs +34 -44
  21. package/src/InMemoryStore.res +17 -30
  22. package/src/InMemoryStore.res.mjs +11 -23
  23. package/src/IndexerState.res +21 -1
  24. package/src/IndexerState.res.mjs +9 -3
  25. package/src/IndexerState.resi +1 -0
  26. package/src/Main.res +25 -15
  27. package/src/Main.res.mjs +19 -14
  28. package/src/MemoryStorage.res +39 -66
  29. package/src/MemoryStorage.res.mjs +28 -65
  30. package/src/Metrics.res +15 -1
  31. package/src/Metrics.res.mjs +5 -1
  32. package/src/Persistence.res +30 -16
  33. package/src/Persistence.res.mjs +8 -5
  34. package/src/PgStorage.res +183 -65
  35. package/src/PgStorage.res.mjs +92 -58
  36. package/src/Rollback.res +14 -10
  37. package/src/Rollback.res.mjs +4 -2
  38. package/src/SimulateItems.res +5 -12
  39. package/src/SimulateItems.res.mjs +6 -10
  40. package/src/TestIndexer.res +93 -111
  41. package/src/TestIndexer.res.mjs +61 -88
  42. package/src/Utils.res +7 -0
  43. package/src/Utils.res.mjs +9 -2
  44. package/src/Writing.res +2 -0
  45. package/src/Writing.res.mjs +2 -1
  46. package/src/bindings/ClickHouse.res +6 -0
  47. package/src/bindings/ClickHouse.res.mjs +4 -0
  48. package/src/bindings/NodeJs.res +9 -0
  49. package/src/bindings/NodeJs.res.mjs +8 -1
  50. package/src/bindings/Postgres.res +9 -0
  51. package/src/bindings/Postgres.res.mjs +3 -0
  52. package/src/db/EntityHistory.res +12 -18
  53. package/src/db/EntityHistory.res.mjs +3 -14
  54. package/src/db/InternalTable.res +171 -65
  55. package/src/db/InternalTable.res.mjs +176 -73
  56. package/src/db/Table.res +24 -0
  57. package/src/db/Table.res.mjs +20 -1
  58. package/src/sources/AddressSet.res +0 -22
  59. package/src/sources/AddressStore.res +48 -88
  60. package/src/sources/AddressStore.res.mjs +11 -22
  61. package/src/sources/SvmHyperSyncClient.res +17 -21
  62. package/src/sources/SvmHyperSyncSource.res +4 -9
  63. package/src/sources/SvmHyperSyncSource.res.mjs +5 -13
  64. package/svm.schema.json +10 -4
@@ -15,6 +15,7 @@ import * as EntityId from "./EntityId.res.mjs";
15
15
  import * as Internal from "./Internal.res.mjs";
16
16
  import Postgres from "postgres";
17
17
  import * as ChainState from "./ChainState.res.mjs";
18
+ import * as AddressRows from "./AddressRows.res.mjs";
18
19
  import * as Performance from "./bindings/Performance.res.mjs";
19
20
  import * as Persistence from "./Persistence.res.mjs";
20
21
  import * as IndexCatalog from "./db/IndexCatalog.res.mjs";
@@ -26,6 +27,7 @@ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
26
27
  import * as Child_process from "child_process";
27
28
  import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
28
29
  import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
30
+ import * as ContractMapping from "./ContractMapping.res.mjs";
29
31
  import * as IndexDefinition from "./db/IndexDefinition.res.mjs";
30
32
  import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
31
33
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
@@ -84,7 +86,7 @@ function getSchemaIndexes(entities) {
84
86
  });
85
87
  }
86
88
 
87
- function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdModeOpt) {
89
+ function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdModeOpt, partitionByColumn) {
88
90
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
89
91
  let fieldsMapped = Table.getFields(table).map(field => {
90
92
  let defaultValue = field.defaultValue;
@@ -100,7 +102,14 @@ function makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdMode
100
102
  let primaryKey = primaryKeyFieldNames.map(field => `"` + field + `"`).join(", ");
101
103
  return `CREATE TABLE IF NOT EXISTS "` + pgSchema + `"."` + table.tableName + `"(` + fieldsMapped + (
102
104
  primaryKeyFieldNames.length !== 0 ? `, PRIMARY KEY(` + primaryKey + `)` : ""
103
- ) + `);`;
105
+ ) + `)` + (
106
+ partitionByColumn !== undefined ? ` PARTITION BY LIST ("` + partitionByColumn + `")` : ""
107
+ ) + `;`;
108
+ }
109
+
110
+ function partitionTableName(entityConfig, chainId) {
111
+ let chainIdStr = ChainId.toString(chainId);
112
+ return Table.fitPgTableName(entityConfig.table.tableName + `$` + chainIdStr, `$` + entityConfig.index.toString() + `$` + chainIdStr);
104
113
  }
105
114
 
106
115
  let rowSchemaCache = new WeakMap();
@@ -209,6 +218,15 @@ function getEntityHistory(entityConfig) {
209
218
  return cache$1;
210
219
  }
211
220
 
221
+ function makeCreateEntityTableQueries(entityConfig, pgSchema, isNumericArrayAsText, chainIdModeOpt, chainIds) {
222
+ let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
223
+ let createTable = (table, partitionByColumn) => makeCreateTableQuery(table, pgSchema, isNumericArrayAsText, chainIdMode, partitionByColumn);
224
+ let chainIdField = Table.getChainIdField(entityConfig.table);
225
+ return (
226
+ chainIdField !== undefined ? [createTable(entityConfig.table, Table.getPgDbFieldName(chainIdField))].concat(chainIds.map(chainId => `CREATE TABLE IF NOT EXISTS "` + pgSchema + `"."` + partitionTableName(entityConfig, chainId) + `" PARTITION OF "` + pgSchema + `"."` + entityConfig.table.tableName + `" FOR VALUES IN (` + ChainId.toString(chainId) + `);`)) : [createTable(entityConfig.table, undefined)]
227
+ ).concat([createTable(getEntityHistory(entityConfig).table, undefined)]);
228
+ }
229
+
212
230
  function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfigsOpt, entitiesOpt, enumsOpt, isEmptyPgSchemaOpt, deferSchemaIndexesOpt, chainIdModeOpt) {
213
231
  let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
214
232
  let entities = entitiesOpt !== undefined ? entitiesOpt : [];
@@ -219,14 +237,13 @@ function makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfi
219
237
  let generalTables = [
220
238
  InternalTable.Chains.table,
221
239
  InternalTable.EnvioInfo.table,
240
+ InternalTable.EnvioContracts.table,
241
+ InternalTable.EnvioAddresses.table,
222
242
  InternalTable.Checkpoints.table,
223
243
  InternalTable.RawEvents.table
224
244
  ];
225
- let allTables = generalTables.slice();
226
- entities.forEach(entityConfig => {
227
- allTables.push(entityConfig.table);
228
- allTables.push(getEntityHistory(entityConfig).table);
229
- });
245
+ let chainIds = chainConfigs.map(chainConfig => chainConfig.id);
246
+ let tableQueries = generalTables.map(table => makeCreateTableQuery(table, pgSchema, isHasuraEnabled, chainIdMode, undefined)).concat(entities.flatMap(entityConfig => makeCreateEntityTableQueries(entityConfig, pgSchema, isHasuraEnabled, chainIdMode, chainIds)));
230
247
  let schemaIndexes = getSchemaIndexes(entities);
231
248
  let query = {
232
249
  contents: (
@@ -239,8 +256,8 @@ GRANT ALL ON SCHEMA "` + pgSchema + `" TO public;`)
239
256
  let enumCreateQuery = `CREATE TYPE "` + pgSchema + `".` + enumConfig.name + ` AS ENUM(` + enumConfig.variants.map(v => `'` + v + `'`).join(", ") + `);`;
240
257
  query.contents = query.contents + "\n" + enumCreateQuery;
241
258
  });
242
- allTables.forEach(table => {
243
- query.contents = query.contents + "\n" + makeCreateTableQuery(table, pgSchema, isHasuraEnabled, chainIdMode);
259
+ tableQueries.forEach(tableQuery => {
260
+ query.contents = query.contents + "\n" + tableQuery;
244
261
  });
245
262
  if (!deferSchemaIndexes) {
246
263
  schemaIndexes.forEach(definition => {
@@ -298,15 +315,21 @@ function makeFilterCondition(filter, table, params) {
298
315
  };
299
316
  switch (filter.operator) {
300
317
  case "=" :
301
- return scalarCondition(filter.fieldName, filter.fieldValue, "=");
318
+ let fieldValue = filter.fieldValue;
319
+ let fieldName = filter.fieldName;
320
+ if (getQueryFieldOrThrow(fieldName).isChainId) {
321
+ return `"` + getQueryFieldOrThrow(fieldName).pgDbFieldName + `" = ` + ChainId.toString(ChainId.normalizeOrThrow(fieldValue));
322
+ } else {
323
+ return scalarCondition(fieldName, fieldValue, "=");
324
+ }
302
325
  case ">" :
303
326
  return scalarCondition(filter.fieldName, filter.fieldValue, ">");
304
327
  case "<" :
305
328
  return scalarCondition(filter.fieldName, filter.fieldValue, "<");
306
329
  case "in" :
307
- let fieldName = filter.fieldName;
308
- let queryField = getQueryFieldOrThrow(fieldName);
309
- return `"` + queryField.pgDbFieldName + `" = ANY(` + serializeParamOrThrow(queryField, fieldName, filter.fieldValue, true) + `)`;
330
+ let fieldName$1 = filter.fieldName;
331
+ let queryField = getQueryFieldOrThrow(fieldName$1);
332
+ return `"` + queryField.pgDbFieldName + `" = ANY(` + serializeParamOrThrow(queryField, fieldName$1, filter.fieldValue, true) + `)`;
310
333
  case "and" :
311
334
  let filters = filter.filters;
312
335
  if (filters.length !== 0) {
@@ -324,7 +347,7 @@ function makeFilterCondition(filter, table, params) {
324
347
  function makeChainIdCondition(table, chainId) {
325
348
  let match = Table.getChainIdField(table);
326
349
  if (match !== undefined && chainId !== undefined) {
327
- return ` AND "` + Table.getPgDbFieldName(match) + `" = $2`;
350
+ return ` AND "` + Table.getPgDbFieldName(match) + `" = ` + ChainId.toString(Primitive_option.valFromOption(chainId));
328
351
  } else {
329
352
  return "";
330
353
  }
@@ -597,13 +620,10 @@ async function getConnectedPsqlExec(pgUser, pgHost, pgDatabase, pgPort, containe
597
620
  async function deleteByIdsOrThrow(sql, pgSchema, ids, table, chainIdOpt) {
598
621
  let chainId = chainIdOpt !== undefined ? Primitive_option.valFromOption(chainIdOpt) : undefined;
599
622
  let chainIdCondition = makeChainIdCondition(table, chainId);
600
- let chainIdParams = chainId !== undefined ? (
601
- chainIdCondition !== "" ? [Primitive_option.valFromOption(chainId)] : []
602
- ) : [];
603
623
  let idsJson = Table.encodeIdsToJson(table, ids);
604
624
  try {
605
625
  await (
606
- ids.length !== 1 ? sql.unsafe(makeDeleteByIdsQuery(pgSchema, table.tableName, Table.getIdPgFieldType(table, pgSchema), chainIdCondition), [idsJson].concat(chainIdParams), {prepare: true}) : sql.unsafe(makeDeleteByIdQuery(pgSchema, table.tableName, chainIdCondition), idsJson.concat(chainIdParams), {prepare: true})
626
+ ids.length !== 1 ? sql.unsafe(makeDeleteByIdsQuery(pgSchema, table.tableName, Table.getIdPgFieldType(table, pgSchema), chainIdCondition), [idsJson], {prepare: true}) : sql.unsafe(makeDeleteByIdQuery(pgSchema, table.tableName, chainIdCondition), idsJson, {prepare: true})
607
627
  );
608
628
  return;
609
629
  } catch (raw_exn) {
@@ -658,7 +678,7 @@ function executeSet(sql, items, dbFunction) {
658
678
  }
659
679
  }
660
680
 
661
- async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, sinkPromise, chainMetaData, escapeTables) {
681
+ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, escapeTables) {
662
682
  try {
663
683
  let chainIdMode = config.chainIdMode;
664
684
  let shouldSaveHistory = Config.shouldSaveHistory(config, isInReorgThreshold);
@@ -815,10 +835,14 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
815
835
  });
816
836
  let rollbackTables;
817
837
  if (rollback !== undefined) {
838
+ let rolledBackAddresses = rollback.rolledBackAddresses;
818
839
  let rollbackTargetCheckpointId = rollback.targetCheckpointId;
819
840
  rollbackTables = sql => {
820
841
  let promises = allEntities.filter(entityConfig => entityConfig.storage.postgres).map(entityConfig => EntityHistory.rollback(sql, pgSchema, entityConfig.name, entityConfig.index, rollbackTargetCheckpointId));
821
842
  promises.push(InternalTable.Checkpoints.rollback(sql, pgSchema, rollbackTargetCheckpointId));
843
+ if (Utils.$$Array.notEmpty(rolledBackAddresses)) {
844
+ promises.push(InternalTable.EnvioAddresses.$$delete(sql, pgSchema, rolledBackAddresses, chainIdMode));
845
+ }
822
846
  return Promise.all(promises);
823
847
  };
824
848
  } else {
@@ -842,6 +866,9 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
842
866
  if (chainMetaData !== undefined) {
843
867
  setOperations.push(sql => InternalTable.Chains.setMeta(sql, pgSchema, chainMetaData));
844
868
  }
869
+ if (Utils.$$Array.notEmpty(registeredAddresses)) {
870
+ setOperations.push(sql => InternalTable.EnvioAddresses.insert(sql, pgSchema, registeredAddresses.map(staged => staged.row), chainIdMode));
871
+ }
845
872
  if (shouldSaveHistory) {
846
873
  setOperations.push(sql => InternalTable.Checkpoints.insert(sql, pgSchema, batch.checkpointIds, batch.checkpointChainIds, batch.checkpointBlockNumbers, batch.checkpointBlockHashes, batch.checkpointEventsProcessed, chainIdMode));
847
874
  }
@@ -872,7 +899,7 @@ async function writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, co
872
899
  if (exn$1.RE_EXN_ID === PgEncodingError) {
873
900
  let escapeTables$1 = escapeTables !== undefined ? Primitive_option.valFromOption(escapeTables) : new Set();
874
901
  escapeTables$1.add(exn$1.table);
875
- return await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, sinkPromise, chainMetaData, Primitive_option.some(escapeTables$1));
902
+ return await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, updatedEntities, registeredAddresses, sinkPromise, chainMetaData, Primitive_option.some(escapeTables$1));
876
903
  }
877
904
  throw exn$1;
878
905
  }
@@ -937,7 +964,7 @@ let rollbackChainIdSchema = Utils.$$WeakMap.memoize(table => Stdlib_Option.map(T
937
964
 
938
965
  let rollbackRemovedIdSchema = Utils.$$WeakMap.memoize(table => S$RescriptSchema.object(s => s.f(Table.idFieldName, Table.getIdSchema(table))));
939
966
 
940
- function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isHasuraEnabled, chainIdModeOpt, sink, onInitialize, onNewTables) {
967
+ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isHasuraEnabled, chainIdModeOpt, ecosystem, sink, onInitialize, onNewTables) {
941
968
  let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
942
969
  let containerName = "envio-postgres";
943
970
  let psqlExecOptions_env = Object.fromEntries([
@@ -1040,7 +1067,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1040
1067
  await Promise.all(entries.map(param => {
1041
1068
  let inputFile = param[1];
1042
1069
  let table = param[0];
1043
- return sql.unsafe(makeCreateTableQuery(table, pgSchema, false, undefined)).then(() => {
1070
+ return sql.unsafe(makeCreateTableQuery(table, pgSchema, false, undefined, undefined)).then(() => {
1044
1071
  let command = psqlExec$1 + ` -c 'COPY "` + pgSchema + `"."` + table.tableName + `" FROM STDIN WITH (FORMAT text, HEADER);' < ` + inputFile;
1045
1072
  return new Promise((resolve, reject) => {
1046
1073
  Child_process.exec(command, psqlExecOptions, (error, stdout, param) => {
@@ -1081,7 +1108,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1081
1108
  });
1082
1109
  return cache;
1083
1110
  };
1084
- let initialize = async (chainConfigsOpt, entitiesOpt, enumsOpt, envioInfo) => {
1111
+ let initialize = async (chainConfigsOpt, entitiesOpt, enumsOpt, contractMapping, envioInfo) => {
1085
1112
  let chainConfigs = chainConfigsOpt !== undefined ? chainConfigsOpt : [];
1086
1113
  let entities = entitiesOpt !== undefined ? entitiesOpt : [];
1087
1114
  let enums = enumsOpt !== undefined ? enumsOpt : [];
@@ -1095,31 +1122,16 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
1095
1122
  await sink.initialize(chainConfigs, chEntities, enums);
1096
1123
  }
1097
1124
  let queries = makeInitializeTransaction(pgSchema, pgUser, isHasuraEnabled, chainConfigs, pgEntities, enums, Utils.$$Array.isEmpty(schemaTableNames), true, chainIdMode);
1125
+ let rowsByChain = chainConfigs.map(chainConfig => ChainState.configStorageRows(chainConfig, ecosystem, contractMapping));
1126
+ let configAddressRows = rowsByChain.flat();
1098
1127
  await sql.begin(async sql => {
1099
1128
  await Promise.all(queries.map(query => sql.unsafe(query)));
1100
- return await InternalTable.EnvioInfo.write(sql, pgSchema, envioInfo);
1101
- });
1102
- let ids = [];
1103
- let addrChainIds = [];
1104
- let addrContractNames = [];
1105
- chainConfigs.forEach(chain => {
1106
- chain.contracts.forEach(contract => {
1107
- contract.addresses.forEach(address => {
1108
- ids.push(Config.EnvioAddresses.makeId(chain.id, address));
1109
- addrChainIds.push(chain.id);
1110
- addrContractNames.push(contract.name);
1111
- });
1112
- });
1129
+ await InternalTable.EnvioInfo.write(sql, pgSchema, envioInfo);
1130
+ await InternalTable.EnvioContracts.insert(sql, pgSchema, ContractMapping.names(contractMapping));
1131
+ if (Utils.$$Array.notEmpty(configAddressRows)) {
1132
+ return await InternalTable.EnvioAddresses.insert(sql, pgSchema, configAddressRows, chainIdMode);
1133
+ }
1113
1134
  });
1114
- if (ids.length !== 0) {
1115
- let addrChainIdArrayType = Table.getPgFieldType("ChainId", pgSchema, true, false, false, chainIdMode);
1116
- await sql.unsafe(`INSERT INTO "` + pgSchema + `"."` + Config.EnvioAddresses.table.tableName + `" ("id", "chain_id", "registration_block", "registration_log_index", "contract_name")
1117
- SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrChainIdArrayType + `,$3::text[]) AS t(id, chain_id, contract_name);`, [
1118
- ids,
1119
- addrChainIds,
1120
- addrContractNames
1121
- ]);
1122
- }
1123
1135
  let cache = await restoreEffectCache(true);
1124
1136
  await reloadIndexCatalog();
1125
1137
  if (onInitialize !== undefined) {
@@ -1127,8 +1139,10 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1127
1139
  }
1128
1140
  return {
1129
1141
  cleanRun: true,
1142
+ contractMapping: contractMapping,
1143
+ envioInfo: envioInfo,
1130
1144
  cache: cache,
1131
- chains: chainConfigs.map(chainConfig => ({
1145
+ chains: chainConfigs.map((chainConfig, idx) => ({
1132
1146
  id: chainConfig.id,
1133
1147
  startBlock: chainConfig.startBlock,
1134
1148
  endBlock: chainConfig.endBlock,
@@ -1137,12 +1151,11 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1137
1151
  numEventsProcessed: 0,
1138
1152
  firstEventBlockNumber: undefined,
1139
1153
  timestampCaughtUpToHeadOrEndblock: undefined,
1140
- indexingAddresses: ChainState.configAddresses(chainConfig),
1154
+ addressRows: AddressRows.seedRowsOf(rowsByChain[idx]),
1141
1155
  sourceBlockNumber: 0
1142
1156
  })),
1143
1157
  checkpointId: InternalTable.Checkpoints.initialCheckpointId,
1144
- reorgCheckpoints: [],
1145
- envioInfo: envioInfo
1158
+ reorgCheckpoints: []
1146
1159
  };
1147
1160
  };
1148
1161
  let loadOrThrow = async (filter, table) => {
@@ -1331,7 +1344,7 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1331
1344
  let setOrThrow$1 = (items, table, itemSchema) => setOrThrow(sql, items, table, itemSchema, pgSchema, setQueryCache, chainIdMode);
1332
1345
  let setEffectCacheOrThrow = async (table, itemSchema, items, initialize) => {
1333
1346
  if (initialize) {
1334
- await sql.unsafe(makeCreateTableQuery(table, pgSchema, false, undefined));
1347
+ await sql.unsafe(makeCreateTableQuery(table, pgSchema, false, undefined, undefined));
1335
1348
  if (onNewTables !== undefined) {
1336
1349
  await onNewTables([table.tableName]);
1337
1350
  }
@@ -1397,13 +1410,31 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1397
1410
  numEventsProcessed: rawInitialState.numEventsProcessed,
1398
1411
  firstEventBlockNumber: Primitive_option.fromNull(rawInitialState.firstEventBlockNumber),
1399
1412
  timestampCaughtUpToHeadOrEndblock: Primitive_option.fromNull(rawInitialState.timestampCaughtUpToHeadOrEndblock),
1400
- indexingAddresses: rawInitialState.indexingAddresses,
1413
+ addressRows: rawInitialState.addressRows,
1401
1414
  sourceBlockNumber: rawInitialState.sourceBlockNumber
1402
1415
  }))),
1403
1416
  sql.unsafe(InternalTable.Checkpoints.makeCommitedCheckpointIdQuery(pgSchema)),
1404
1417
  sql.unsafe(InternalTable.Checkpoints.makeGetReorgCheckpointsQuery(pgSchema)),
1405
- InternalTable.EnvioInfo.read(sql, pgSchema)
1418
+ Promise.all([
1419
+ InternalTable.EnvioInfo.read(sql, pgSchema),
1420
+ InternalTable.EnvioContracts.read(sql, pgSchema)
1421
+ ]).then(param => {
1422
+ let names = param[1];
1423
+ let info = param[0];
1424
+ if (info !== undefined && names !== undefined) {
1425
+ return [
1426
+ info,
1427
+ ContractMapping.fromStoredNames(names)
1428
+ ];
1429
+ } else {
1430
+ return [
1431
+ undefined,
1432
+ ContractMapping.empty
1433
+ ];
1434
+ }
1435
+ })
1406
1436
  ]);
1437
+ let match$1 = match[4];
1407
1438
  await reloadIndexCatalog();
1408
1439
  let checkpointId = BigInt(match[2][0].id);
1409
1440
  let reorgCheckpoints = match[3].map(raw => ({
@@ -1417,11 +1448,12 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1417
1448
  }
1418
1449
  return {
1419
1450
  cleanRun: false,
1451
+ contractMapping: match$1[1],
1452
+ envioInfo: match$1[0],
1420
1453
  cache: match[0],
1421
1454
  chains: match[1],
1422
1455
  checkpointId: checkpointId,
1423
- reorgCheckpoints: reorgCheckpoints,
1424
- envioInfo: match[4]
1456
+ reorgCheckpoints: reorgCheckpoints
1425
1457
  };
1426
1458
  };
1427
1459
  let reset = async () => {
@@ -1467,7 +1499,7 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1467
1499
  S$RescriptSchema.parseOrThrow(restoredEntitiesResult, Table.pgRowsSchema(entityConfig.table))
1468
1500
  ];
1469
1501
  };
1470
- let writeBatchMethod = async (batch, rollback, isInReorgThreshold, config, allEntities, updatedEffectsCache, updatedEntities, chainMetaData, onWrite) => {
1502
+ let writeBatchMethod = async (batch, rollback, isInReorgThreshold, config, allEntities, updatedEffectsCache, updatedEntities, registeredAddresses, chainMetaData, onWrite) => {
1471
1503
  let pgUpdates = [];
1472
1504
  let chUpdates = [];
1473
1505
  for (let i = 0, i_finish = updatedEntities.length; i < i_finish; ++i) {
@@ -1490,7 +1522,7 @@ SELECT id, chain_id, -1, -1, contract_name FROM unnest($1::text[],$2::` + addrCh
1490
1522
  sinkPromise = undefined;
1491
1523
  }
1492
1524
  let primaryTimerRef = Performance.now();
1493
- await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, pgUpdates, sinkPromise, chainMetaData, undefined);
1525
+ await writeBatch(sql, batch, pgSchema, rollback, isInReorgThreshold, config, allEntities, setEffectCacheOrThrow, setQueryCache, updatedEffectsCache, pgUpdates, registeredAddresses, sinkPromise, chainMetaData, undefined);
1494
1526
  return onWrite(storageName, Performance.secondsSince(primaryTimerRef));
1495
1527
  };
1496
1528
  let close = () => sql.end();
@@ -1546,10 +1578,10 @@ function makeStorageFromEnv(config, sqlOpt, pgSchemaOpt, isHasuraEnabledOpt) {
1546
1578
  } else {
1547
1579
  tmp = undefined;
1548
1580
  }
1549
- return make(sql, Env.Db.host, pgSchema, Env.Db.port, Env.Db.user, Env.Db.database, Env.Db.password, isHasuraEnabled, config.chainIdMode, tmp, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(Env.Hasura.graphqlEndpoint, {
1581
+ return make(sql, Env.Db.host, pgSchema, Env.Db.port, Env.Db.user, Env.Db.database, Env.Db.password, isHasuraEnabled, config.chainIdMode, config.ecosystem.name, tmp, isHasuraEnabled ? () => Stdlib_Promise.$$catch(Hasura.trackDatabase(Env.Hasura.graphqlEndpoint, {
1550
1582
  role: Env.Hasura.role,
1551
1583
  secret: Env.Hasura.secret
1552
- }, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.allEntities.map(e => e.table))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking tables`))) : undefined, isHasuraEnabled ? tableNames => Stdlib_Promise.$$catch(Hasura.trackTables(Env.Hasura.graphqlEndpoint, {
1584
+ }, pgSchema, Config.getPgUserEntities(config), Env.Hasura.aggregateEntities, Env.Hasura.responseLimit, Schema.make(config.userEntities.map(e => e.table))), err => Promise.resolve(Logging.errorWithExn(Utils.prettifyExn(err), `Error tracking tables`))) : undefined, isHasuraEnabled ? tableNames => Stdlib_Promise.$$catch(Hasura.trackTables(Env.Hasura.graphqlEndpoint, {
1553
1585
  role: Env.Hasura.role,
1554
1586
  secret: Env.Hasura.secret
1555
1587
  }, pgSchema, tableNames.map(tableName => ({
@@ -1572,10 +1604,12 @@ export {
1572
1604
  slowOnLargeDatabaseNotice,
1573
1605
  getSchemaIndexes,
1574
1606
  makeCreateTableQuery,
1607
+ partitionTableName,
1575
1608
  rowSchemaCache,
1576
1609
  getRowSchema,
1577
1610
  entityHistoryCache,
1578
1611
  getEntityHistory,
1612
+ makeCreateEntityTableQueries,
1579
1613
  makeInitializeTransaction,
1580
1614
  makeLoadQuery,
1581
1615
  makeFilterCondition,
package/src/Rollback.res CHANGED
@@ -158,21 +158,24 @@ and executeRollback = async (
158
158
  }
159
159
 
160
160
  let rolledBackChains = []
161
+ let rolledBackAddresses = []
161
162
  state
162
163
  ->IndexerState.chainStates
163
164
  ->Utils.Dict.forEach(cs => {
164
165
  let chainId = (cs->ChainState.chainConfig).id
165
166
  let fromBlock = cs->ChainState.committedProgressBlockNumber
166
- cs->ChainState.rollback(
167
- ~newProgressBlockNumber=newProgressBlockNumberPerChain->ChainId.Dict.dangerouslyGetNonOption(
168
- chainId,
169
- ),
170
- ~eventsProcessedDiff=eventsProcessedDiffByChain->ChainId.Dict.dangerouslyGetNonOption(
171
- chainId,
172
- ),
173
- ~rollbackTargetBlockNumber,
174
- ~isReorgChain=chainId === reorgChain,
175
- )
167
+ let killedAddresses =
168
+ cs->ChainState.rollback(
169
+ ~newProgressBlockNumber=newProgressBlockNumberPerChain->ChainId.Dict.dangerouslyGetNonOption(
170
+ chainId,
171
+ ),
172
+ ~eventsProcessedDiff=eventsProcessedDiffByChain->ChainId.Dict.dangerouslyGetNonOption(
173
+ chainId,
174
+ ),
175
+ ~rollbackTargetBlockNumber,
176
+ ~isReorgChain=chainId === reorgChain,
177
+ )
178
+ rolledBackAddresses->Array.pushMany(killedAddresses)->ignore
176
179
  let toBlock = cs->ChainState.committedProgressBlockNumber
177
180
  if fromBlock !== toBlock {
178
181
  rolledBackChains
@@ -192,6 +195,7 @@ and executeRollback = async (
192
195
  ~rollbackTargetCheckpointId,
193
196
  ~rollbackDiffCheckpointId=state->IndexerState.committedCheckpointId->BigInt.add(1n),
194
197
  ~progressBlockNumberByChainId=newProgressBlockNumberPerChain,
198
+ ~rolledBackAddresses,
195
199
  )
196
200
 
197
201
  rolledBackChains->Array.forEach(rolledBack => {
@@ -54,10 +54,12 @@ async function executeRollback(state, reorgChain, rollbackTargetBlockNumber, sch
54
54
  newProgressBlockNumberPerChain[diff.chain_id] = rollbackTargetCheckpointId === 0n && diff.chain_id === reorgChain ? Primitive_int.min(diff.new_progress_block_number, rollbackTargetBlockNumber) : diff.new_progress_block_number;
55
55
  }
56
56
  let rolledBackChains = [];
57
+ let rolledBackAddresses = [];
57
58
  Utils.Dict.forEach(IndexerState.chainStates(state), cs => {
58
59
  let chainId = ChainState.chainConfig(cs).id;
59
60
  let fromBlock = ChainState.committedProgressBlockNumber(cs);
60
- ChainState.rollback(cs, newProgressBlockNumberPerChain[chainId], eventsProcessedDiffByChain[chainId], rollbackTargetBlockNumber, chainId === reorgChain);
61
+ let killedAddresses = ChainState.rollback(cs, newProgressBlockNumberPerChain[chainId], eventsProcessedDiffByChain[chainId], rollbackTargetBlockNumber, chainId === reorgChain);
62
+ rolledBackAddresses.push(...killedAddresses);
61
63
  let toBlock = ChainState.committedProgressBlockNumber(cs);
62
64
  if (fromBlock !== toBlock) {
63
65
  rolledBackChains.push({
@@ -69,7 +71,7 @@ async function executeRollback(state, reorgChain, rollbackTargetBlockNumber, sch
69
71
  return;
70
72
  }
71
73
  });
72
- let diff$1 = await InMemoryStore.prepareRollbackDiff(state, rollbackTargetCheckpointId, IndexerState.committedCheckpointId(state) + 1n, newProgressBlockNumberPerChain);
74
+ let diff$1 = await InMemoryStore.prepareRollbackDiff(state, rollbackTargetCheckpointId, IndexerState.committedCheckpointId(state) + 1n, newProgressBlockNumberPerChain, rolledBackAddresses);
73
75
  rolledBackChains.forEach(rolledBack => Logging.childInfo(logger, {
74
76
  msg: "Rollbacked",
75
77
  chainId: rolledBack.chainId,
@@ -372,18 +372,11 @@ let parse = (
372
372
  }
373
373
  }
374
374
  let data = item.data->Option.getOr(svmEventConfig.discriminator->Option.getOr("0x"))
375
- let decoded = item.args->Option.map(args => (
376
- {
377
- SvmHyperSyncClient.ResponseTypes.name: instructionName,
378
- argsJson: args->JSON.stringify,
379
- accountsJson: "{}",
380
- extraAccounts: [],
381
- }: SvmHyperSyncClient.ResponseTypes.decodedInstruction
382
- ))
375
+ let argsJson = item.args->Option.mapOr("{}", args => args->JSON.stringify)
383
376
  let logs = item.logs->Option.map(logs =>
384
377
  logs->Array.map((log): SvmHyperSyncClient.EventItems.log => {
385
- kind: ?log.kind,
386
- message: ?log.message,
378
+ kind: log.kind->Null.fromOption,
379
+ message: log.message->Null.fromOption,
387
380
  })
388
381
  )
389
382
 
@@ -463,8 +456,8 @@ let parse = (
463
456
  accounts: accountArguments,
464
457
  data,
465
458
  isInner: item.isInner->Option.getOr(false),
466
- ?decoded,
467
- ?logs,
459
+ argsJson,
460
+ logs: logs->Null.fromOption,
468
461
  },
469
462
  ~programName,
470
463
  ~instructionName,
@@ -6,6 +6,7 @@ import * as Address from "./Address.res.mjs";
6
6
  import * as ChainId from "./ChainId.res.mjs";
7
7
  import * as ChainMap from "./ChainMap.res.mjs";
8
8
  import * as BlockStore from "./sources/BlockStore.res.mjs";
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 HandlerRegister from "./HandlerRegister.res.mjs";
@@ -245,15 +246,10 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
245
246
  }) : [];
246
247
  }
247
248
  let data = Stdlib_Option.getOr(rawJson.data, Stdlib_Option.getOr(eventConfig.discriminator, "0x"));
248
- let decoded = Stdlib_Option.map(rawJson.args, args => ({
249
- name: match$2,
250
- argsJson: JSON.stringify(args),
251
- accountsJson: "{}",
252
- extraAccounts: []
253
- }));
249
+ let argsJson = Stdlib_Option.mapOr(rawJson.args, "{}", args => JSON.stringify(args));
254
250
  let logs = Stdlib_Option.map(rawJson.logs, logs => logs.map(log => ({
255
- kind: log.kind,
256
- message: log.message
251
+ kind: Stdlib_Null.fromOption(log.kind),
252
+ message: Stdlib_Null.fromOption(log.message)
257
253
  })));
258
254
  let liveRegistrations = liveRegistrationsFor(config, chainId, eventConfig);
259
255
  if (Utils.$$Array.isEmpty(liveRegistrations)) {
@@ -316,8 +312,8 @@ function parse(simulateItems, config, chainConfig, onEventRegistrations) {
316
312
  accounts: accountArguments,
317
313
  data: data,
318
314
  isInner: Stdlib_Option.getOr(rawJson.isInner, false),
319
- decoded: decoded,
320
- logs: logs
315
+ argsJson: argsJson,
316
+ logs: Stdlib_Null.fromOption(logs)
321
317
  }, match$1, match$2, eventConfig, newrecord.fieldSelection);
322
318
  payload["srcAddress"] = programId;
323
319
  items.push({