envio 3.5.1 → 3.6.1-subgraph
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/evm.schema.json +7 -0
- package/fuel.schema.json +7 -0
- package/index.d.ts +33 -10
- package/package.json +6 -6
- package/src/ChainState.res +22 -4
- package/src/ChainState.res.mjs +20 -3
- package/src/ChainState.resi +3 -0
- package/src/Config.res +72 -2
- package/src/Config.res.mjs +57 -15
- package/src/Core.res +15 -0
- package/src/Core.res.mjs +11 -0
- package/src/EffectState.res +2 -2
- package/src/EffectState.res.mjs +2 -2
- package/src/EntityTables.res +32 -0
- package/src/EntityTables.res.mjs +44 -0
- package/src/Envio.res +7 -7
- package/src/Envio.res.mjs +5 -6
- package/src/EventProcessing.res +6 -6
- package/src/EventProcessing.res.mjs +8 -6
- package/src/HandlerLoader.res +20 -8
- package/src/HandlerLoader.res.mjs +11 -2
- package/src/Hasura.res +37 -3
- package/src/Hasura.res.mjs +23 -5
- package/src/InMemoryStore.res +48 -8
- package/src/InMemoryStore.res.mjs +37 -7
- package/src/IndexerState.res +30 -24
- package/src/IndexerState.res.mjs +20 -35
- package/src/IndexerState.resi +8 -6
- package/src/Internal.res +29 -11
- package/src/Internal.res.mjs +27 -10
- package/src/LoadLayer.res +39 -8
- package/src/LoadLayer.res.mjs +36 -9
- package/src/LoadLayer.resi +2 -0
- package/src/Metrics.res +5 -5
- package/src/Metrics.res.mjs +5 -1
- package/src/Persistence.res +12 -1
- package/src/PgStorage.res +183 -37
- package/src/PgStorage.res.mjs +149 -34
- package/src/PruneStaleHistory.res +1 -0
- package/src/PruneStaleHistory.res.mjs +2 -1
- package/src/Sink.res +3 -3
- package/src/Sink.res.mjs +2 -2
- package/src/TestIndexer.res +128 -17
- package/src/TestIndexer.res.mjs +75 -9
- package/src/UserContext.res +375 -53
- package/src/UserContext.res.mjs +281 -39
- package/src/Writing.res +8 -16
- package/src/Writing.res.mjs +10 -10
- package/src/bindings/ClickHouse.res +40 -4
- package/src/bindings/ClickHouse.res.mjs +37 -5
- package/src/db/EntityHistory.res +64 -21
- package/src/db/EntityHistory.res.mjs +43 -22
- package/src/db/InternalTable.res.mjs +31 -31
- package/src/db/Table.res +24 -1
- package/src/db/Table.res.mjs +26 -4
- package/src/sources/SourceManager.res +6 -12
- package/src/sources/SourceManager.res.mjs +8 -5
- package/src/subgraph/blocks.ts +176 -0
- package/src/subgraph/calls.ts +213 -0
- package/src/subgraph/conformance.ts +99 -0
- package/src/subgraph/division.ts +100 -0
- package/src/subgraph/errors.ts +90 -0
- package/src/subgraph/graph-ts-types/VERSION +2 -0
- package/src/subgraph/graph-ts-types/chain/arweave.d.ts +70 -0
- package/src/subgraph/graph-ts-types/chain/cosmos.d.ts +327 -0
- package/src/subgraph/graph-ts-types/chain/ethereum.d.ts +233 -0
- package/src/subgraph/graph-ts-types/chain/near.d.ts +253 -0
- package/src/subgraph/graph-ts-types/chain/starknet.d.ts +32 -0
- package/src/subgraph/graph-ts-types/common/collections.d.ts +136 -0
- package/src/subgraph/graph-ts-types/common/conversion.d.ts +11 -0
- package/src/subgraph/graph-ts-types/common/datasource.d.ts +30 -0
- package/src/subgraph/graph-ts-types/common/eager-offset.d.ts +0 -0
- package/src/subgraph/graph-ts-types/common/json.d.ts +17 -0
- package/src/subgraph/graph-ts-types/common/numbers.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/value.d.ts +120 -0
- package/src/subgraph/graph-ts-types/common/yaml.d.ts +90 -0
- package/src/subgraph/graph-ts-types/global/global.d.ts +194 -0
- package/src/subgraph/graph-ts-types/helper-functions.d.ts +22 -0
- package/src/subgraph/graph-ts-types/index.d.ts +102 -0
- package/src/subgraph/graph-ts.ts +1695 -0
- package/src/subgraph/hosts.ts +148 -0
- package/src/subgraph/runtime.ts +827 -0
- package/src/subgraph/scope.ts +63 -0
- package/svm.schema.json +7 -0
|
@@ -5,6 +5,7 @@ import * as Table from "../db/Table.res.mjs";
|
|
|
5
5
|
import * as Utils from "../Utils.res.mjs";
|
|
6
6
|
import * as ChainId from "../ChainId.res.mjs";
|
|
7
7
|
import * as Logging from "../Logging.res.mjs";
|
|
8
|
+
import * as Internal from "../Internal.res.mjs";
|
|
8
9
|
import * as Persistence from "../Persistence.res.mjs";
|
|
9
10
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
10
11
|
import * as EntityHistory from "../db/EntityHistory.res.mjs";
|
|
@@ -197,11 +198,14 @@ async function setCheckpointsOrThrow(client, batch, database) {
|
|
|
197
198
|
}
|
|
198
199
|
}
|
|
199
200
|
|
|
200
|
-
async function setUpdatesOrThrow(client, cache, changes, entityConfig, database) {
|
|
201
|
+
async function setUpdatesOrThrow(client, cache, changes, entityConfig, scope, database) {
|
|
201
202
|
if (changes.length === 0) {
|
|
202
203
|
return;
|
|
203
204
|
}
|
|
204
|
-
let
|
|
205
|
+
let chainIdField = Table.getChainIdField(entityConfig.table);
|
|
206
|
+
let scopeChainId = Internal.chainScopeChainId(scope);
|
|
207
|
+
let cacheKey = entityConfig.name + `|` + Internal.chainScopeToString(scope);
|
|
208
|
+
let cached = cache[cacheKey];
|
|
205
209
|
let match;
|
|
206
210
|
if (cached !== undefined) {
|
|
207
211
|
match = cached;
|
|
@@ -211,6 +215,9 @@ async function setUpdatesOrThrow(client, cache, changes, entityConfig, database)
|
|
|
211
215
|
EntityHistory.makeSetUpdateSchema(Table.getIdSchema(entityConfig.table), makeClickHouseEntitySchema(entityConfig.table)),
|
|
212
216
|
S$RescriptSchema.object(s => {
|
|
213
217
|
s.tag(EntityHistory.changeFieldName, "DELETE");
|
|
218
|
+
if (chainIdField !== undefined && scopeChainId !== undefined) {
|
|
219
|
+
s.tag(Table.getClickHouseDbFieldName(chainIdField), Primitive_option.valFromOption(scopeChainId));
|
|
220
|
+
}
|
|
214
221
|
return {
|
|
215
222
|
type: "DELETE",
|
|
216
223
|
entityId: s.f(Table.idFieldName, Table.getIdSchema(entityConfig.table)),
|
|
@@ -222,12 +229,30 @@ async function setUpdatesOrThrow(client, cache, changes, entityConfig, database)
|
|
|
222
229
|
tableName: cached_tableName,
|
|
223
230
|
convertOrThrow: cached_convertOrThrow
|
|
224
231
|
};
|
|
225
|
-
cache
|
|
232
|
+
cache[cacheKey] = cached$1;
|
|
226
233
|
match = cached$1;
|
|
227
234
|
}
|
|
228
235
|
let tableName = match.tableName;
|
|
236
|
+
let changes$1;
|
|
237
|
+
if (chainIdField !== undefined && scopeChainId !== undefined) {
|
|
238
|
+
let chainId = Primitive_option.valFromOption(scopeChainId);
|
|
239
|
+
changes$1 = changes.map(change => {
|
|
240
|
+
if (change.type === "SET") {
|
|
241
|
+
return {
|
|
242
|
+
type: "SET",
|
|
243
|
+
entityId: change.entityId,
|
|
244
|
+
entity: Internal.stampChainId(change.entity, chainIdField.fieldName, chainId),
|
|
245
|
+
checkpointId: change.checkpointId
|
|
246
|
+
};
|
|
247
|
+
} else {
|
|
248
|
+
return change;
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
} else {
|
|
252
|
+
changes$1 = changes;
|
|
253
|
+
}
|
|
229
254
|
try {
|
|
230
|
-
let values = match.convertOrThrow(changes);
|
|
255
|
+
let values = match.convertOrThrow(changes$1);
|
|
231
256
|
return await insertWithRetry(client, tableName, values, "JSONEachRow", undefined);
|
|
232
257
|
} catch (raw_exn) {
|
|
233
258
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
@@ -346,6 +371,13 @@ ORDER BY (` + "id" + `)`;
|
|
|
346
371
|
function makeCreateViewQuery(entityConfig, database, onClusterOpt) {
|
|
347
372
|
let onCluster = onClusterOpt !== undefined ? onClusterOpt : false;
|
|
348
373
|
let historyTableName = EntityHistory.historyTableName(entityConfig.name, entityConfig.index);
|
|
374
|
+
let field = Table.getChainIdField(entityConfig.table);
|
|
375
|
+
let dedupKey = (
|
|
376
|
+
field !== undefined ? [
|
|
377
|
+
Table.idFieldName,
|
|
378
|
+
Table.getClickHouseDbFieldName(field)
|
|
379
|
+
] : [Table.idFieldName]
|
|
380
|
+
).map(name => `\`` + name + `\``).join(", ");
|
|
349
381
|
let checkpointsTableName = InternalTable.Checkpoints.table.tableName;
|
|
350
382
|
let entityFields = Stdlib_Array.filterMap(entityConfig.table.fields, field => {
|
|
351
383
|
if (field.TAG !== "Field") {
|
|
@@ -363,7 +395,7 @@ FROM (
|
|
|
363
395
|
FROM ` + database + `.\`` + historyTableName + `\`
|
|
364
396
|
WHERE \`` + EntityHistory.checkpointIdFieldName + `\` <= (SELECT max(` + "id" + `) FROM ` + database + `.\`` + checkpointsTableName + `\`)
|
|
365
397
|
ORDER BY \`` + EntityHistory.checkpointIdFieldName + `\` DESC
|
|
366
|
-
LIMIT 1 BY
|
|
398
|
+
LIMIT 1 BY ` + dedupKey + `
|
|
367
399
|
)
|
|
368
400
|
WHERE \`` + EntityHistory.changeFieldName + `\` = '` + "SET" + `'`;
|
|
369
401
|
}
|
package/src/db/EntityHistory.res
CHANGED
|
@@ -82,27 +82,41 @@ type safeReorgBlocks = {
|
|
|
82
82
|
// - Rollbacks will not cross the safe checkpoint id, so rows older than the anchor can never be referenced again.
|
|
83
83
|
// - If nothing changed in reorg threshold (after the safe checkpoint), the current state for that id can be reconstructed from the
|
|
84
84
|
// origin table; we do not need a pre-safe anchor for it.
|
|
85
|
-
|
|
85
|
+
// A per-chain entity's rows are only comparable within a chain, so every id
|
|
86
|
+
// correlation in the history SQL widens to (id, chain id).
|
|
87
|
+
let makeKeyColumns = (~chainIdColumn: option<string>) =>
|
|
88
|
+
switch chainIdColumn {
|
|
89
|
+
| Some(column) => ["id", `"${column}"`]
|
|
90
|
+
| None => ["id"]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
let makeKeyMatch = (~chainIdColumn, ~left, ~right) =>
|
|
94
|
+
makeKeyColumns(~chainIdColumn)
|
|
95
|
+
->Array.map(column => `${left}.${column} = ${right}.${column}`)
|
|
96
|
+
->Array.joinUnsafe(" AND ")
|
|
97
|
+
|
|
98
|
+
let makePruneStaleEntityHistoryQuery = (~entityName, ~entityIndex, ~pgSchema, ~chainIdColumn) => {
|
|
86
99
|
let historyTableRef = `"${pgSchema}"."${historyTableName(~entityName, ~entityIndex)}"`
|
|
100
|
+
let keyColumns = makeKeyColumns(~chainIdColumn)
|
|
101
|
+
let anchorKeys = keyColumns->Array.map(column => `t.${column}`)->Array.joinUnsafe(", ")
|
|
87
102
|
|
|
103
|
+
// Whether a key still has a row above the safe checkpoint is an aggregate
|
|
104
|
+
// over the same groups as the anchor, so it's computed in the one pass
|
|
105
|
+
// rather than as a per-row correlated lookup.
|
|
106
|
+
// `d.envio_checkpoint_id <= $1` is implied by the rest of the predicate — it
|
|
107
|
+
// is there to keep the rows above the safe checkpoint out of the join.
|
|
88
108
|
`WITH anchors AS (
|
|
89
|
-
SELECT
|
|
90
|
-
|
|
91
|
-
|
|
109
|
+
SELECT ${anchorKeys},
|
|
110
|
+
MAX(t.${checkpointIdFieldName}) FILTER (WHERE t.${checkpointIdFieldName} <= $1) AS keep_checkpoint_id,
|
|
111
|
+
bool_or(t.${checkpointIdFieldName} > $1) AS has_above
|
|
112
|
+
FROM ${historyTableRef} t
|
|
113
|
+
GROUP BY ${anchorKeys}
|
|
92
114
|
)
|
|
93
115
|
DELETE FROM ${historyTableRef} d
|
|
94
116
|
USING anchors a
|
|
95
|
-
WHERE d
|
|
96
|
-
AND
|
|
97
|
-
|
|
98
|
-
OR (
|
|
99
|
-
d.${checkpointIdFieldName} = a.keep_checkpoint_id AND
|
|
100
|
-
NOT EXISTS (
|
|
101
|
-
SELECT 1 FROM ${historyTableRef} ps
|
|
102
|
-
WHERE ps.id = d.id AND ps.${checkpointIdFieldName} > $1
|
|
103
|
-
)
|
|
104
|
-
)
|
|
105
|
-
);`
|
|
117
|
+
WHERE ${makeKeyMatch(~chainIdColumn, ~left="d", ~right="a")}
|
|
118
|
+
AND d.${checkpointIdFieldName} <= $1
|
|
119
|
+
AND (d.${checkpointIdFieldName} < a.keep_checkpoint_id OR NOT a.has_above);`
|
|
106
120
|
}
|
|
107
121
|
|
|
108
122
|
let pruneStaleEntityHistory = (
|
|
@@ -110,26 +124,40 @@ let pruneStaleEntityHistory = (
|
|
|
110
124
|
~entityName,
|
|
111
125
|
~entityIndex,
|
|
112
126
|
~pgSchema,
|
|
127
|
+
~chainIdColumn,
|
|
113
128
|
~safeCheckpointId,
|
|
114
129
|
): promise<unit> => {
|
|
115
130
|
sql->Postgres.preparedUnsafe(
|
|
116
|
-
makePruneStaleEntityHistoryQuery(~entityName, ~entityIndex, ~pgSchema),
|
|
131
|
+
makePruneStaleEntityHistoryQuery(~entityName, ~entityIndex, ~pgSchema, ~chainIdColumn),
|
|
117
132
|
[safeCheckpointId->BigInt.toString]->(Utils.magic: array<string> => unknown),
|
|
118
133
|
)
|
|
119
134
|
}
|
|
120
135
|
|
|
121
136
|
// If an entity doesn't have a history before the update
|
|
122
137
|
// we create it automatically with envio_checkpoint_id 0
|
|
123
|
-
|
|
138
|
+
// The ids belong to a single chain (the flush group's scope), so the chain is
|
|
139
|
+
// bound once as $2 rather than unnested alongside them.
|
|
140
|
+
let makeBackfillHistoryQuery = (
|
|
141
|
+
~pgSchema,
|
|
142
|
+
~entityName,
|
|
143
|
+
~entityIndex,
|
|
144
|
+
~idPgType,
|
|
145
|
+
~chainIdColumn,
|
|
146
|
+
~chainId: option<ChainId.t>,
|
|
147
|
+
) => {
|
|
124
148
|
let historyTableRef = `"${pgSchema}"."${historyTableName(~entityName, ~entityIndex)}"`
|
|
149
|
+
let chainFilter = switch (chainIdColumn, chainId) {
|
|
150
|
+
| (Some(column), Some(_)) => ` AND e."${column}" = $2`
|
|
151
|
+
| _ => ""
|
|
152
|
+
}
|
|
125
153
|
`WITH target_ids AS (
|
|
126
154
|
SELECT UNNEST($1::${idPgType}[]) AS id
|
|
127
155
|
),
|
|
128
156
|
missing_history AS (
|
|
129
157
|
SELECT e.*
|
|
130
158
|
FROM "${pgSchema}"."${entityName}" e
|
|
131
|
-
JOIN target_ids t ON e.id = t.id
|
|
132
|
-
LEFT JOIN ${historyTableRef} h ON h
|
|
159
|
+
JOIN target_ids t ON e.id = t.id${chainFilter}
|
|
160
|
+
LEFT JOIN ${historyTableRef} h ON ${makeKeyMatch(~chainIdColumn, ~left="h", ~right="e")}
|
|
133
161
|
WHERE h.id IS NULL
|
|
134
162
|
)
|
|
135
163
|
INSERT INTO ${historyTableRef}
|
|
@@ -142,13 +170,28 @@ let backfillHistory = (
|
|
|
142
170
|
~pgSchema,
|
|
143
171
|
~table: Table.table,
|
|
144
172
|
~entityIndex,
|
|
173
|
+
~chainId: option<ChainId.t>,
|
|
145
174
|
~ids: array<EntityId.t>,
|
|
146
175
|
) => {
|
|
147
176
|
let idPgType = table->Table.getIdPgFieldType(~pgSchema)
|
|
177
|
+
let chainIdColumn = table->Table.getChainIdField->Option.map(Table.getPgDbFieldName)
|
|
178
|
+
let params = [table->Table.encodeIdsToJson(ids)->(Utils.magic: JSON.t => unknown)]
|
|
179
|
+
switch (chainIdColumn, chainId) {
|
|
180
|
+
| (Some(_), Some(chainId)) =>
|
|
181
|
+
params->Array.push(chainId->(Utils.magic: ChainId.t => unknown))->ignore
|
|
182
|
+
| _ => ()
|
|
183
|
+
}
|
|
148
184
|
sql
|
|
149
185
|
->Postgres.preparedUnsafe(
|
|
150
|
-
makeBackfillHistoryQuery(
|
|
151
|
-
|
|
186
|
+
makeBackfillHistoryQuery(
|
|
187
|
+
~entityName=table.tableName,
|
|
188
|
+
~entityIndex,
|
|
189
|
+
~pgSchema,
|
|
190
|
+
~idPgType,
|
|
191
|
+
~chainIdColumn,
|
|
192
|
+
~chainId,
|
|
193
|
+
),
|
|
194
|
+
params->Obj.magic,
|
|
152
195
|
)
|
|
153
196
|
->Utils.Promise.ignoreValue
|
|
154
197
|
}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
import * as Table from "./Table.res.mjs";
|
|
4
4
|
import * as Js_string from "@rescript/runtime/lib/es6/Js_string.js";
|
|
5
5
|
import * as Stdlib_BigInt from "@rescript/runtime/lib/es6/Stdlib_BigInt.js";
|
|
6
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
7
|
+
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
6
8
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
7
9
|
|
|
8
10
|
let variants = [
|
|
@@ -71,42 +73,54 @@ function historyTableName(entityName, entityIndex) {
|
|
|
71
73
|
return Js_string.slice(0, 63 - entityIndexStr.length | 0, fullName) + entityIndexStr;
|
|
72
74
|
}
|
|
73
75
|
|
|
74
|
-
function
|
|
76
|
+
function makeKeyColumns(chainIdColumn) {
|
|
77
|
+
if (chainIdColumn !== undefined) {
|
|
78
|
+
return [
|
|
79
|
+
"id",
|
|
80
|
+
`"` + chainIdColumn + `"`
|
|
81
|
+
];
|
|
82
|
+
} else {
|
|
83
|
+
return ["id"];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function makeKeyMatch(chainIdColumn, left, right) {
|
|
88
|
+
return makeKeyColumns(chainIdColumn).map(column => left + `.` + column + ` = ` + right + `.` + column).join(" AND ");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function makePruneStaleEntityHistoryQuery(entityName, entityIndex, pgSchema, chainIdColumn) {
|
|
75
92
|
let historyTableRef = `"` + pgSchema + `"."` + historyTableName(entityName, entityIndex) + `"`;
|
|
93
|
+
let keyColumns = makeKeyColumns(chainIdColumn);
|
|
94
|
+
let anchorKeys = keyColumns.map(column => `t.` + column).join(", ");
|
|
76
95
|
return `WITH anchors AS (
|
|
77
|
-
SELECT
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
SELECT ` + anchorKeys + `,
|
|
97
|
+
MAX(t.` + checkpointIdFieldName + `) FILTER (WHERE t.` + checkpointIdFieldName + ` <= $1) AS keep_checkpoint_id,
|
|
98
|
+
bool_or(t.` + checkpointIdFieldName + ` > $1) AS has_above
|
|
99
|
+
FROM ` + historyTableRef + ` t
|
|
100
|
+
GROUP BY ` + anchorKeys + `
|
|
80
101
|
)
|
|
81
102
|
DELETE FROM ` + historyTableRef + ` d
|
|
82
103
|
USING anchors a
|
|
83
|
-
WHERE d
|
|
84
|
-
AND
|
|
85
|
-
|
|
86
|
-
OR (
|
|
87
|
-
d.` + checkpointIdFieldName + ` = a.keep_checkpoint_id AND
|
|
88
|
-
NOT EXISTS (
|
|
89
|
-
SELECT 1 FROM ` + historyTableRef + ` ps
|
|
90
|
-
WHERE ps.id = d.id AND ps.` + checkpointIdFieldName + ` > $1
|
|
91
|
-
)
|
|
92
|
-
)
|
|
93
|
-
);`;
|
|
104
|
+
WHERE ` + makeKeyMatch(chainIdColumn, "d", "a") + `
|
|
105
|
+
AND d.` + checkpointIdFieldName + ` <= $1
|
|
106
|
+
AND (d.` + checkpointIdFieldName + ` < a.keep_checkpoint_id OR NOT a.has_above);`;
|
|
94
107
|
}
|
|
95
108
|
|
|
96
|
-
function pruneStaleEntityHistory(sql, entityName, entityIndex, pgSchema, safeCheckpointId) {
|
|
97
|
-
return sql.unsafe(makePruneStaleEntityHistoryQuery(entityName, entityIndex, pgSchema), [safeCheckpointId.toString()], {prepare: true});
|
|
109
|
+
function pruneStaleEntityHistory(sql, entityName, entityIndex, pgSchema, chainIdColumn, safeCheckpointId) {
|
|
110
|
+
return sql.unsafe(makePruneStaleEntityHistoryQuery(entityName, entityIndex, pgSchema, chainIdColumn), [safeCheckpointId.toString()], {prepare: true});
|
|
98
111
|
}
|
|
99
112
|
|
|
100
|
-
function makeBackfillHistoryQuery(pgSchema, entityName, entityIndex, idPgType) {
|
|
113
|
+
function makeBackfillHistoryQuery(pgSchema, entityName, entityIndex, idPgType, chainIdColumn, chainId) {
|
|
101
114
|
let historyTableRef = `"` + pgSchema + `"."` + historyTableName(entityName, entityIndex) + `"`;
|
|
115
|
+
let chainFilter = chainIdColumn !== undefined && chainId !== undefined ? ` AND e."` + chainIdColumn + `" = $2` : "";
|
|
102
116
|
return `WITH target_ids AS (
|
|
103
117
|
SELECT UNNEST($1::` + idPgType + `[]) AS id
|
|
104
118
|
),
|
|
105
119
|
missing_history AS (
|
|
106
120
|
SELECT e.*
|
|
107
121
|
FROM "` + pgSchema + `"."` + entityName + `" e
|
|
108
|
-
JOIN target_ids t ON e.id = t.id
|
|
109
|
-
LEFT JOIN ` + historyTableRef + ` h ON h
|
|
122
|
+
JOIN target_ids t ON e.id = t.id` + chainFilter + `
|
|
123
|
+
LEFT JOIN ` + historyTableRef + ` h ON ` + makeKeyMatch(chainIdColumn, "h", "e") + `
|
|
110
124
|
WHERE h.id IS NULL
|
|
111
125
|
)
|
|
112
126
|
INSERT INTO ` + historyTableRef + `
|
|
@@ -114,9 +128,14 @@ SELECT *, 0 AS ` + checkpointIdFieldName + `, '` + "SET" + `' as ` + changeField
|
|
|
114
128
|
FROM missing_history;`;
|
|
115
129
|
}
|
|
116
130
|
|
|
117
|
-
function backfillHistory(sql, pgSchema, table, entityIndex, ids) {
|
|
131
|
+
function backfillHistory(sql, pgSchema, table, entityIndex, chainId, ids) {
|
|
118
132
|
let idPgType = Table.getIdPgFieldType(table, pgSchema);
|
|
119
|
-
|
|
133
|
+
let chainIdColumn = Stdlib_Option.map(Table.getChainIdField(table), Table.getPgDbFieldName);
|
|
134
|
+
let params = [Table.encodeIdsToJson(table, ids)];
|
|
135
|
+
if (chainIdColumn !== undefined && chainId !== undefined) {
|
|
136
|
+
params.push(Primitive_option.valFromOption(chainId));
|
|
137
|
+
}
|
|
138
|
+
return sql.unsafe(makeBackfillHistoryQuery(pgSchema, table.tableName, entityIndex, idPgType, chainIdColumn, chainId), params, {prepare: true});
|
|
120
139
|
}
|
|
121
140
|
|
|
122
141
|
function rollback(sql, pgSchema, entityName, entityIndex, rollbackTargetCheckpointId) {
|
|
@@ -138,6 +157,8 @@ export {
|
|
|
138
157
|
maxPgTableNameLength,
|
|
139
158
|
historyTablePrefix,
|
|
140
159
|
historyTableName,
|
|
160
|
+
makeKeyColumns,
|
|
161
|
+
makeKeyMatch,
|
|
141
162
|
makePruneStaleEntityHistoryQuery,
|
|
142
163
|
pruneStaleEntityHistory,
|
|
143
164
|
makeBackfillHistoryQuery,
|
|
@@ -26,17 +26,17 @@ let fields = [
|
|
|
26
26
|
];
|
|
27
27
|
|
|
28
28
|
let table = Table.mkTable("envio_chains", undefined, [
|
|
29
|
-
Table.mkField("id", "ChainId", ChainId.schema, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined),
|
|
30
|
-
Table.mkField("start_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
31
|
-
Table.mkField("end_block", "Int32", S$RescriptSchema.$$null(S$RescriptSchema.int), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
32
|
-
Table.mkField("max_reorg_depth", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
33
|
-
Table.mkField("buffer_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
34
|
-
Table.mkField("source_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
35
|
-
Table.mkField("first_event_block", "Int32", S$RescriptSchema.$$null(S$RescriptSchema.int), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
36
|
-
Table.mkField("ready_at", "Date", S$RescriptSchema.$$null(Utils.Schema.dbDate), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
37
|
-
Table.mkField("events_processed", "UInt52", S$RescriptSchema.float, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
38
|
-
Table.mkField("_is_hyper_sync", "Boolean", S$RescriptSchema.bool, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
39
|
-
Table.mkField("progress_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
29
|
+
Table.mkField("id", "ChainId", ChainId.schema, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
30
|
+
Table.mkField("start_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
31
|
+
Table.mkField("end_block", "Int32", S$RescriptSchema.$$null(S$RescriptSchema.int), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
32
|
+
Table.mkField("max_reorg_depth", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
33
|
+
Table.mkField("buffer_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
34
|
+
Table.mkField("source_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
35
|
+
Table.mkField("first_event_block", "Int32", S$RescriptSchema.$$null(S$RescriptSchema.int), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
36
|
+
Table.mkField("ready_at", "Date", S$RescriptSchema.$$null(Utils.Schema.dbDate), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
37
|
+
Table.mkField("events_processed", "UInt52", S$RescriptSchema.float, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
38
|
+
Table.mkField("_is_hyper_sync", "Boolean", S$RescriptSchema.bool, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
39
|
+
Table.mkField("progress_block", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
40
40
|
], undefined);
|
|
41
41
|
|
|
42
42
|
function initialFromConfig(chainConfig) {
|
|
@@ -235,8 +235,8 @@ let Chains = {
|
|
|
235
235
|
};
|
|
236
236
|
|
|
237
237
|
let table$1 = Table.mkTable("envio_info", undefined, [
|
|
238
|
-
Table.mkField("id", "Int32", S$RescriptSchema.int, "1", undefined, undefined, true, undefined, undefined, undefined, undefined, undefined),
|
|
239
|
-
Table.mkField("config", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
238
|
+
Table.mkField("id", "Int32", S$RescriptSchema.int, "1", undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
239
|
+
Table.mkField("config", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
240
240
|
], undefined);
|
|
241
241
|
|
|
242
242
|
let undefinedTableSqlState = "42P01";
|
|
@@ -284,11 +284,11 @@ let dbSchema = S$RescriptSchema.object(s => ({
|
|
|
284
284
|
}));
|
|
285
285
|
|
|
286
286
|
let table$2 = Table.mkTable("envio_checkpoints", undefined, [
|
|
287
|
-
Table.mkField("id", "UInt64", S$RescriptSchema.bigint, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined),
|
|
288
|
-
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
289
|
-
Table.mkField("block_number", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
290
|
-
Table.mkField("block_hash", "String", S$RescriptSchema.$$null(S$RescriptSchema.string), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
291
|
-
Table.mkField("events_processed", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
287
|
+
Table.mkField("id", "UInt64", S$RescriptSchema.bigint, undefined, undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
288
|
+
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
289
|
+
Table.mkField("block_number", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
290
|
+
Table.mkField("block_hash", "String", S$RescriptSchema.$$null(S$RescriptSchema.string), undefined, undefined, true, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
291
|
+
Table.mkField("events_processed", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
292
292
|
], undefined);
|
|
293
293
|
|
|
294
294
|
function makeGetReorgCheckpointsQuery(pgSchema) {
|
|
@@ -412,19 +412,19 @@ let schema = S$RescriptSchema.schema(s => ({
|
|
|
412
412
|
}));
|
|
413
413
|
|
|
414
414
|
let table$3 = Table.mkTable("raw_events", undefined, [
|
|
415
|
-
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
416
|
-
Table.mkField("event_id", "UInt64", S$RescriptSchema.bigint, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
417
|
-
Table.mkField("event_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
418
|
-
Table.mkField("contract_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
419
|
-
Table.mkField("block_number", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
420
|
-
Table.mkField("log_index", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
421
|
-
Table.mkField("src_address", "String", Address.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
422
|
-
Table.mkField("block_hash", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
423
|
-
Table.mkField("block_timestamp", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
424
|
-
Table.mkField("block_fields", "Json", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
425
|
-
Table.mkField("transaction_fields", "Json", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
426
|
-
Table.mkField("params", "Json", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
427
|
-
Table.mkField("serial", "BigSerial", S$RescriptSchema.$$null(S$RescriptSchema.bigint), undefined, undefined, true, true, undefined, undefined, undefined, undefined, undefined)
|
|
415
|
+
Table.mkField("chain_id", "ChainId", ChainId.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
416
|
+
Table.mkField("event_id", "UInt64", S$RescriptSchema.bigint, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
417
|
+
Table.mkField("event_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
418
|
+
Table.mkField("contract_name", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
419
|
+
Table.mkField("block_number", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
420
|
+
Table.mkField("log_index", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
421
|
+
Table.mkField("src_address", "String", Address.schema, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
422
|
+
Table.mkField("block_hash", "String", S$RescriptSchema.string, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
423
|
+
Table.mkField("block_timestamp", "Int32", S$RescriptSchema.int, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
424
|
+
Table.mkField("block_fields", "Json", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
425
|
+
Table.mkField("transaction_fields", "Json", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
426
|
+
Table.mkField("params", "Json", S$RescriptSchema.json(false), undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined),
|
|
427
|
+
Table.mkField("serial", "BigSerial", S$RescriptSchema.$$null(S$RescriptSchema.bigint), undefined, undefined, true, true, undefined, undefined, undefined, undefined, undefined, undefined)
|
|
428
428
|
], undefined);
|
|
429
429
|
|
|
430
430
|
let RawEvents = {
|
package/src/db/Table.res
CHANGED
|
@@ -43,6 +43,10 @@ type field = {
|
|
|
43
43
|
isNullable: bool,
|
|
44
44
|
isPrimaryKey: bool,
|
|
45
45
|
isIndex: bool,
|
|
46
|
+
// The chain-id column appended to a per-chain entity's table. It's part of
|
|
47
|
+
// the primary key but not of the entity schema the handlers see, so the
|
|
48
|
+
// read paths skip it and the write path stamps it from the flush scope.
|
|
49
|
+
isChainId: bool,
|
|
46
50
|
linkedEntity: option<string>,
|
|
47
51
|
defaultValue: option<string>,
|
|
48
52
|
description: option<string>,
|
|
@@ -71,6 +75,7 @@ let mkField = (
|
|
|
71
75
|
~isNullable=false,
|
|
72
76
|
~isPrimaryKey=false,
|
|
73
77
|
~isIndex=false,
|
|
78
|
+
~isChainId=false,
|
|
74
79
|
~linkedEntity=?,
|
|
75
80
|
~description=?,
|
|
76
81
|
~postgresDbName=?,
|
|
@@ -84,6 +89,7 @@ let mkField = (
|
|
|
84
89
|
isNullable,
|
|
85
90
|
isPrimaryKey,
|
|
86
91
|
isIndex,
|
|
92
|
+
isChainId,
|
|
87
93
|
linkedEntity,
|
|
88
94
|
defaultValue: default,
|
|
89
95
|
description,
|
|
@@ -252,6 +258,16 @@ let getDerivedFromFields = table =>
|
|
|
252
258
|
}
|
|
253
259
|
)
|
|
254
260
|
|
|
261
|
+
// The chain-id column of a per-chain entity table. None for cross-chain
|
|
262
|
+
// entities and every internal table.
|
|
263
|
+
let getChainIdField = (table): option<field> =>
|
|
264
|
+
table.fields->Array.findMap(field =>
|
|
265
|
+
switch field {
|
|
266
|
+
| Field({isChainId: true} as field) => Some(field)
|
|
267
|
+
| _ => None
|
|
268
|
+
}
|
|
269
|
+
)
|
|
270
|
+
|
|
255
271
|
let getFieldByName = (table, fieldName) =>
|
|
256
272
|
table.fields->Array.find(field => field->getUserDefinedFieldName === fieldName)
|
|
257
273
|
|
|
@@ -334,12 +350,13 @@ let queryFields: table => dict<queryField> = Utils.WeakMap.memoize(table => {
|
|
|
334
350
|
// Parses rows into entity objects keyed by API field names (the camelCase
|
|
335
351
|
// record field names are type-level only), reading each value from the
|
|
336
352
|
// row key produced by ~rowFieldName.
|
|
337
|
-
let makeRowsSchema = (table, ~rowFieldName) =>
|
|
353
|
+
let makeRowsSchema = (table, ~rowFieldName, ~skipChainId=false) =>
|
|
338
354
|
S.array(
|
|
339
355
|
S.object(s => {
|
|
340
356
|
let dict = Dict.make()
|
|
341
357
|
table.fields->Array.forEach(field =>
|
|
342
358
|
switch field {
|
|
359
|
+
| Field({isChainId: true}) if skipChainId => ()
|
|
343
360
|
| Field(field) =>
|
|
344
361
|
dict->Dict.set(field->getApiFieldName, s.field(field->rowFieldName, field.fieldSchema))
|
|
345
362
|
| DerivedFrom(_) => ()
|
|
@@ -361,6 +378,12 @@ let pgRowsSchema: table => S.t<array<unknown>> = Utils.WeakMap.memoize(table =>
|
|
|
361
378
|
table->makeRowsSchema(~rowFieldName=getPgDbFieldName)
|
|
362
379
|
)
|
|
363
380
|
|
|
381
|
+
// Rows shaped like the entity the handlers see: the chain-id column is dropped,
|
|
382
|
+
// since the chain is already known from the scope the rows were loaded for.
|
|
383
|
+
let pgEntityRowsSchema: table => S.t<array<unknown>> = Utils.WeakMap.memoize(table =>
|
|
384
|
+
table->makeRowsSchema(~rowFieldName=getPgDbFieldName, ~skipChainId=true)
|
|
385
|
+
)
|
|
386
|
+
|
|
364
387
|
exception NonExistingTableField(string)
|
|
365
388
|
|
|
366
389
|
/*
|
package/src/db/Table.res.mjs
CHANGED
|
@@ -16,11 +16,12 @@ function makeEnumConfig(name, variants) {
|
|
|
16
16
|
};
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function mkField(fieldName, fieldType, fieldSchema, $$default, isArrayOpt, isNullableOpt, isPrimaryKeyOpt, isIndexOpt, linkedEntity, description, postgresDbName, clickhouseDbName) {
|
|
19
|
+
function mkField(fieldName, fieldType, fieldSchema, $$default, isArrayOpt, isNullableOpt, isPrimaryKeyOpt, isIndexOpt, isChainIdOpt, linkedEntity, description, postgresDbName, clickhouseDbName) {
|
|
20
20
|
let isArray = isArrayOpt !== undefined ? isArrayOpt : false;
|
|
21
21
|
let isNullable = isNullableOpt !== undefined ? isNullableOpt : false;
|
|
22
22
|
let isPrimaryKey = isPrimaryKeyOpt !== undefined ? isPrimaryKeyOpt : false;
|
|
23
23
|
let isIndex = isIndexOpt !== undefined ? isIndexOpt : false;
|
|
24
|
+
let isChainId = isChainIdOpt !== undefined ? isChainIdOpt : false;
|
|
24
25
|
return {
|
|
25
26
|
TAG: "Field",
|
|
26
27
|
_0: {
|
|
@@ -31,6 +32,7 @@ function mkField(fieldName, fieldType, fieldSchema, $$default, isArrayOpt, isNul
|
|
|
31
32
|
isNullable: isNullable,
|
|
32
33
|
isPrimaryKey: isPrimaryKey,
|
|
33
34
|
isIndex: isIndex,
|
|
35
|
+
isChainId: isChainId,
|
|
34
36
|
linkedEntity: linkedEntity,
|
|
35
37
|
defaultValue: $$default,
|
|
36
38
|
description: description,
|
|
@@ -225,6 +227,18 @@ function getDerivedFromFields(table) {
|
|
|
225
227
|
});
|
|
226
228
|
}
|
|
227
229
|
|
|
230
|
+
function getChainIdField(table) {
|
|
231
|
+
return Stdlib_Array.findMap(table.fields, field => {
|
|
232
|
+
if (field.TAG !== "Field") {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
let field$1 = field._0;
|
|
236
|
+
if (field$1.isChainId) {
|
|
237
|
+
return field$1;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
228
242
|
function getFieldByName(table, fieldName) {
|
|
229
243
|
return table.fields.find(field => getUserDefinedFieldName(field) === fieldName);
|
|
230
244
|
}
|
|
@@ -288,7 +302,8 @@ let queryFields = Utils.$$WeakMap.memoize(table => {
|
|
|
288
302
|
return dict;
|
|
289
303
|
});
|
|
290
304
|
|
|
291
|
-
function makeRowsSchema(table, rowFieldName) {
|
|
305
|
+
function makeRowsSchema(table, rowFieldName, skipChainIdOpt) {
|
|
306
|
+
let skipChainId = skipChainIdOpt !== undefined ? skipChainIdOpt : false;
|
|
292
307
|
return S$RescriptSchema.array(S$RescriptSchema.object(s => {
|
|
293
308
|
let dict = {};
|
|
294
309
|
table.fields.forEach(field => {
|
|
@@ -296,15 +311,20 @@ function makeRowsSchema(table, rowFieldName) {
|
|
|
296
311
|
return;
|
|
297
312
|
}
|
|
298
313
|
let field$1 = field._0;
|
|
314
|
+
if (field$1.isChainId && skipChainId) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
299
317
|
dict[getApiFieldName(field$1)] = s.f(rowFieldName(field$1), field$1.fieldSchema);
|
|
300
318
|
});
|
|
301
319
|
return dict;
|
|
302
320
|
}));
|
|
303
321
|
}
|
|
304
322
|
|
|
305
|
-
let rowsSchema = Utils.$$WeakMap.memoize(table => makeRowsSchema(table, getApiFieldName));
|
|
323
|
+
let rowsSchema = Utils.$$WeakMap.memoize(table => makeRowsSchema(table, getApiFieldName, undefined));
|
|
324
|
+
|
|
325
|
+
let pgRowsSchema = Utils.$$WeakMap.memoize(table => makeRowsSchema(table, getPgDbFieldName, undefined));
|
|
306
326
|
|
|
307
|
-
let
|
|
327
|
+
let pgEntityRowsSchema = Utils.$$WeakMap.memoize(table => makeRowsSchema(table, getPgDbFieldName, true));
|
|
308
328
|
|
|
309
329
|
let NonExistingTableField = /* @__PURE__ */Primitive_exceptions.create("Table.NonExistingTableField");
|
|
310
330
|
|
|
@@ -465,6 +485,7 @@ export {
|
|
|
465
485
|
getNonDefaultFields,
|
|
466
486
|
getLinkedEntityFields,
|
|
467
487
|
getDerivedFromFields,
|
|
488
|
+
getChainIdField,
|
|
468
489
|
getFieldByName,
|
|
469
490
|
NoIdField,
|
|
470
491
|
getIdFieldOrThrow,
|
|
@@ -477,6 +498,7 @@ export {
|
|
|
477
498
|
makeRowsSchema,
|
|
478
499
|
rowsSchema,
|
|
479
500
|
pgRowsSchema,
|
|
501
|
+
pgEntityRowsSchema,
|
|
480
502
|
NonExistingTableField,
|
|
481
503
|
getUnfilteredCompositeIndexesUnsafe,
|
|
482
504
|
toSqlParams,
|
|
@@ -468,16 +468,16 @@ let getSourceNewHeight = async (
|
|
|
468
468
|
// head on every (re)connect; waking the wait loop on a height we already
|
|
469
469
|
// know spins it and leaks fallback pollers (#1270).
|
|
470
470
|
if newHeight > sourceState.knownHeight {
|
|
471
|
+
sourceState->recordRequestStats([{Source.method: "heightPush", seconds: 0.}])
|
|
471
472
|
sourceState.knownHeight = newHeight
|
|
472
473
|
let resolvers = sourceState.pendingHeightResolvers
|
|
473
474
|
sourceState.pendingHeightResolvers = []
|
|
474
475
|
resolvers->Array.forEach(resolve => resolve(newHeight))
|
|
476
|
+
} else {
|
|
477
|
+
sourceState->recordRequestStats([{Source.method: "heightPushIgnored", seconds: 0.}])
|
|
475
478
|
}
|
|
476
479
|
})
|
|
477
480
|
sourceState.unsubscribe = Some(unsubscribe)
|
|
478
|
-
// Count a subscription (re)start rather than every pushed height —
|
|
479
|
-
// there's no request/response to time here.
|
|
480
|
-
sourceState->recordRequestStats([{Source.method: "heightSubscription", seconds: 0.}])
|
|
481
481
|
| _ =>
|
|
482
482
|
// Slowdown polling when the chain isn't progressing
|
|
483
483
|
let pollingInterval = if reducedPolling {
|
|
@@ -724,9 +724,7 @@ let executeQuery = async (
|
|
|
724
724
|
) {
|
|
725
725
|
| Some(s) =>
|
|
726
726
|
if s.source !== sourceManager.activeSource {
|
|
727
|
-
let logger = Logging.createChild(
|
|
728
|
-
~params={"chainId": sourceManager.activeSource.chainId},
|
|
729
|
-
)
|
|
727
|
+
let logger = Logging.createChild(~params={"chainId": sourceManager.activeSource.chainId})
|
|
730
728
|
logger->Logging.childInfo({
|
|
731
729
|
"msg": "Switching data-source",
|
|
732
730
|
"source": s.source.name,
|
|
@@ -736,9 +734,7 @@ let executeQuery = async (
|
|
|
736
734
|
}
|
|
737
735
|
s
|
|
738
736
|
| None =>
|
|
739
|
-
let logger = Logging.createChild(
|
|
740
|
-
~params={"chainId": sourceManager.activeSource.chainId},
|
|
741
|
-
)
|
|
737
|
+
let logger = Logging.createChild(~params={"chainId": sourceManager.activeSource.chainId})
|
|
742
738
|
%raw(`null`)->ErrorHandling.mkLogAndRaise(~logger, ~msg=noSourcesError)
|
|
743
739
|
}
|
|
744
740
|
sourceManager.activeSource = sourceState.source
|
|
@@ -895,9 +891,7 @@ let getBlockHashes = async (sourceManager: t, ~blockNumbers: array<int>, ~isReal
|
|
|
895
891
|
let sourceState = switch sourceManager->getNextSource(~isRealtime) {
|
|
896
892
|
| Some(s) => s
|
|
897
893
|
| None =>
|
|
898
|
-
let logger = Logging.createChild(
|
|
899
|
-
~params={"chainId": sourceManager.activeSource.chainId},
|
|
900
|
-
)
|
|
894
|
+
let logger = Logging.createChild(~params={"chainId": sourceManager.activeSource.chainId})
|
|
901
895
|
%raw(`null`)->ErrorHandling.mkLogAndRaise(
|
|
902
896
|
~logger,
|
|
903
897
|
~msg="No data-sources available for fetching block hashes.",
|