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.
- package/README.md +2 -2
- package/index.d.ts +158 -104
- package/package.json +6 -6
- package/src/AddressRows.res +121 -0
- package/src/AddressRows.res.mjs +143 -0
- package/src/Batch.res +2 -0
- package/src/Batch.res.mjs +2 -1
- package/src/ChainState.res +76 -70
- package/src/ChainState.res.mjs +76 -65
- package/src/ChainState.resi +14 -9
- package/src/Config.res +23 -82
- package/src/Config.res.mjs +19 -63
- package/src/ContractMapping.res +66 -0
- package/src/ContractMapping.res.mjs +73 -0
- package/src/Core.res +20 -0
- package/src/Core.res.mjs +4 -0
- package/src/EventConfigBuilder.res +0 -2
- package/src/EventConfigBuilder.res.mjs +0 -2
- package/src/FetchState.res +59 -67
- package/src/FetchState.res.mjs +34 -44
- package/src/InMemoryStore.res +17 -30
- package/src/InMemoryStore.res.mjs +11 -23
- package/src/IndexerState.res +21 -1
- package/src/IndexerState.res.mjs +9 -3
- package/src/IndexerState.resi +1 -0
- package/src/Main.res +25 -15
- package/src/Main.res.mjs +19 -14
- package/src/MemoryStorage.res +39 -66
- package/src/MemoryStorage.res.mjs +28 -65
- package/src/Metrics.res +15 -1
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +30 -16
- package/src/Persistence.res.mjs +8 -5
- package/src/PgStorage.res +183 -65
- package/src/PgStorage.res.mjs +92 -58
- package/src/Rollback.res +14 -10
- package/src/Rollback.res.mjs +4 -2
- package/src/SimulateItems.res +5 -12
- package/src/SimulateItems.res.mjs +6 -10
- package/src/TestIndexer.res +93 -111
- package/src/TestIndexer.res.mjs +61 -88
- package/src/Utils.res +7 -0
- package/src/Utils.res.mjs +9 -2
- package/src/Writing.res +2 -0
- package/src/Writing.res.mjs +2 -1
- package/src/bindings/ClickHouse.res +6 -0
- package/src/bindings/ClickHouse.res.mjs +4 -0
- package/src/bindings/NodeJs.res +9 -0
- package/src/bindings/NodeJs.res.mjs +8 -1
- package/src/bindings/Postgres.res +9 -0
- package/src/bindings/Postgres.res.mjs +3 -0
- package/src/db/EntityHistory.res +12 -18
- package/src/db/EntityHistory.res.mjs +3 -14
- package/src/db/InternalTable.res +171 -65
- package/src/db/InternalTable.res.mjs +176 -73
- package/src/db/Table.res +24 -0
- package/src/db/Table.res.mjs +20 -1
- package/src/sources/AddressSet.res +0 -22
- package/src/sources/AddressStore.res +48 -88
- package/src/sources/AddressStore.res.mjs +11 -22
- package/src/sources/SvmHyperSyncClient.res +17 -21
- package/src/sources/SvmHyperSyncSource.res +4 -9
- package/src/sources/SvmHyperSyncSource.res.mjs +5 -13
- package/svm.schema.json +10 -4
package/src/PgStorage.res.mjs
CHANGED
|
@@ -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
|
|
226
|
-
entities.
|
|
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
|
-
|
|
243
|
-
query.contents = query.contents + "\n" +
|
|
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
|
-
|
|
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) + `" =
|
|
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]
|
|
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
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
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 => {
|
package/src/Rollback.res.mjs
CHANGED
|
@@ -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,
|
package/src/SimulateItems.res
CHANGED
|
@@ -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
|
|
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:
|
|
386
|
-
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
|
-
|
|
467
|
-
|
|
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
|
|
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
|
-
|
|
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({
|