ponder 0.11.21 → 0.11.22
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/CHANGELOG.md +6 -0
- package/dist/esm/bin/commands/createViews.js +9 -20
- package/dist/esm/bin/commands/createViews.js.map +1 -1
- package/dist/esm/bin/commands/dev.js +1 -1
- package/dist/esm/bin/commands/dev.js.map +1 -1
- package/dist/esm/bin/commands/list.js +4 -7
- package/dist/esm/bin/commands/list.js.map +1 -1
- package/dist/esm/bin/commands/prune.js +9 -21
- package/dist/esm/bin/commands/prune.js.map +1 -1
- package/dist/esm/bin/commands/serve.js +1 -1
- package/dist/esm/bin/commands/serve.js.map +1 -1
- package/dist/esm/bin/commands/start.js +3 -3
- package/dist/esm/bin/commands/start.js.map +1 -1
- package/dist/esm/bin/utils/run.js +159 -180
- package/dist/esm/bin/utils/run.js.map +1 -1
- package/dist/esm/build/index.js +1 -48
- package/dist/esm/build/index.js.map +1 -1
- package/dist/esm/build/plugin.js +1 -1
- package/dist/esm/client/index.js +9 -13
- package/dist/esm/client/index.js.map +1 -1
- package/dist/esm/database/index.js +429 -141
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/drizzle/index.js.map +1 -1
- package/dist/esm/drizzle/kit/index.js.map +1 -1
- package/dist/esm/drizzle/onchain.js +1 -8
- package/dist/esm/drizzle/onchain.js.map +1 -1
- package/dist/esm/graphql/index.js +16 -19
- package/dist/esm/graphql/index.js.map +1 -1
- package/dist/esm/graphql/middleware.js +7 -3
- package/dist/esm/graphql/middleware.js.map +1 -1
- package/dist/esm/indexing-store/cache.js +32 -26
- package/dist/esm/indexing-store/cache.js.map +1 -1
- package/dist/esm/indexing-store/historical.js +32 -23
- package/dist/esm/indexing-store/historical.js.map +1 -1
- package/dist/esm/indexing-store/index.js +18 -1
- package/dist/esm/indexing-store/index.js.map +1 -1
- package/dist/esm/indexing-store/realtime.js +140 -89
- package/dist/esm/indexing-store/realtime.js.map +1 -1
- package/dist/esm/internal/errors.js +0 -12
- package/dist/esm/internal/errors.js.map +1 -1
- package/dist/esm/server/index.js +2 -10
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/sync-store/index.js +432 -403
- package/dist/esm/sync-store/index.js.map +1 -1
- package/dist/esm/utils/wait.js +0 -2
- package/dist/esm/utils/wait.js.map +1 -1
- package/dist/types/bin/commands/createViews.d.ts.map +1 -1
- package/dist/types/bin/commands/list.d.ts.map +1 -1
- package/dist/types/bin/commands/prune.d.ts.map +1 -1
- package/dist/types/bin/commands/start.d.ts +0 -2
- package/dist/types/bin/commands/start.d.ts.map +1 -1
- package/dist/types/bin/utils/run.d.ts +1 -1
- package/dist/types/bin/utils/run.d.ts.map +1 -1
- package/dist/types/build/index.d.ts +1 -1
- package/dist/types/build/index.d.ts.map +1 -1
- package/dist/types/client/index.d.ts.map +1 -1
- package/dist/types/database/index.d.ts +73 -25
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/drizzle/index.d.ts +3 -2
- package/dist/types/drizzle/index.d.ts.map +1 -1
- package/dist/types/drizzle/kit/index.d.ts +4 -3
- package/dist/types/drizzle/kit/index.d.ts.map +1 -1
- package/dist/types/drizzle/onchain.d.ts +5 -12
- package/dist/types/drizzle/onchain.d.ts.map +1 -1
- package/dist/types/graphql/index.d.ts +4 -2
- package/dist/types/graphql/index.d.ts.map +1 -1
- package/dist/types/graphql/middleware.d.ts +1 -1
- package/dist/types/graphql/middleware.d.ts.map +1 -1
- package/dist/types/indexing-store/cache.d.ts +12 -5
- package/dist/types/indexing-store/cache.d.ts.map +1 -1
- package/dist/types/indexing-store/historical.d.ts +7 -2
- package/dist/types/indexing-store/historical.d.ts.map +1 -1
- package/dist/types/indexing-store/index.d.ts +2 -4
- package/dist/types/indexing-store/index.d.ts.map +1 -1
- package/dist/types/indexing-store/realtime.d.ts +3 -1
- package/dist/types/indexing-store/realtime.d.ts.map +1 -1
- package/dist/types/internal/errors.d.ts +0 -4
- package/dist/types/internal/errors.d.ts.map +1 -1
- package/dist/types/server/index.d.ts +1 -1
- package/dist/types/server/index.d.ts.map +1 -1
- package/dist/types/sync/index.d.ts +1 -1
- package/dist/types/sync-store/index.d.ts.map +1 -1
- package/dist/types/utils/wait.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/bin/commands/createViews.ts +26 -37
- package/src/bin/commands/dev.ts +1 -1
- package/src/bin/commands/list.ts +4 -7
- package/src/bin/commands/prune.ts +17 -31
- package/src/bin/commands/serve.ts +1 -1
- package/src/bin/commands/start.ts +3 -4
- package/src/bin/utils/run.ts +210 -256
- package/src/build/index.ts +2 -53
- package/src/build/plugin.ts +1 -1
- package/src/client/index.ts +10 -21
- package/src/database/index.ts +742 -331
- package/src/drizzle/index.ts +3 -2
- package/src/drizzle/kit/index.ts +5 -2
- package/src/drizzle/onchain.ts +2 -26
- package/src/graphql/index.ts +26 -31
- package/src/graphql/middleware.ts +7 -5
- package/src/indexing-store/cache.ts +52 -35
- package/src/indexing-store/historical.ts +40 -28
- package/src/indexing-store/index.ts +27 -2
- package/src/indexing-store/realtime.ts +220 -176
- package/src/internal/errors.ts +0 -9
- package/src/server/index.ts +3 -14
- package/src/sync-store/index.ts +997 -870
- package/src/utils/wait.ts +0 -1
- package/dist/esm/database/queryBuilder.js +0 -206
- package/dist/esm/database/queryBuilder.js.map +0 -1
- package/dist/esm/database/utils.js +0 -100
- package/dist/esm/database/utils.js.map +0 -1
- package/dist/esm/drizzle/json.js +0 -119
- package/dist/esm/drizzle/json.js.map +0 -1
- package/dist/types/database/queryBuilder.d.ts +0 -37
- package/dist/types/database/queryBuilder.d.ts.map +0 -1
- package/dist/types/database/utils.d.ts +0 -25
- package/dist/types/database/utils.d.ts.map +0 -1
- package/dist/types/drizzle/json.d.ts +0 -51
- package/dist/types/drizzle/json.d.ts.map +0 -1
- package/src/database/queryBuilder.ts +0 -319
- package/src/database/utils.ts +0 -140
- package/src/drizzle/json.ts +0 -154
package/src/bin/utils/run.ts
CHANGED
|
@@ -1,17 +1,5 @@
|
|
|
1
1
|
import { runCodegen } from "@/bin/utils/codegen.js";
|
|
2
|
-
import {
|
|
3
|
-
type Database,
|
|
4
|
-
getPonderCheckpointTable,
|
|
5
|
-
getPonderMetaTable,
|
|
6
|
-
} from "@/database/index.js";
|
|
7
|
-
import {
|
|
8
|
-
commitBlock,
|
|
9
|
-
createIndexes,
|
|
10
|
-
createTrigger,
|
|
11
|
-
dropTrigger,
|
|
12
|
-
finalize,
|
|
13
|
-
revert,
|
|
14
|
-
} from "@/database/utils.js";
|
|
2
|
+
import type { Database } from "@/database/index.js";
|
|
15
3
|
import { createIndexingCache } from "@/indexing-store/cache.js";
|
|
16
4
|
import { createHistoricalIndexingStore } from "@/indexing-store/historical.js";
|
|
17
5
|
import { createRealtimeIndexingStore } from "@/indexing-store/realtime.js";
|
|
@@ -36,8 +24,9 @@ import { recordAsyncGenerator } from "@/utils/generators.js";
|
|
|
36
24
|
import { mutex } from "@/utils/mutex.js";
|
|
37
25
|
import { never } from "@/utils/never.js";
|
|
38
26
|
import { startClock } from "@/utils/timer.js";
|
|
39
|
-
import { getTableName, is, sql } from "drizzle-orm";
|
|
27
|
+
import { type TableConfig, getTableName, is, sql } from "drizzle-orm";
|
|
40
28
|
import { PgTable } from "drizzle-orm/pg-core";
|
|
29
|
+
import type { PgTableWithColumns } from "drizzle-orm/pg-core";
|
|
41
30
|
|
|
42
31
|
/** Starts the sync and indexing services for the specified build. */
|
|
43
32
|
export async function run({
|
|
@@ -61,12 +50,6 @@ export async function run({
|
|
|
61
50
|
onFatalError: (error: Error) => void;
|
|
62
51
|
onReloadableError: (error: Error) => void;
|
|
63
52
|
}) {
|
|
64
|
-
const PONDER_META = getPonderMetaTable(namespaceBuild.schema);
|
|
65
|
-
const PONDER_CHECKPOINT = getPonderCheckpointTable(namespaceBuild.schema);
|
|
66
|
-
const tables = Object.values(schemaBuild.schema).filter(
|
|
67
|
-
(table): table is PgTable => is(table, PgTable),
|
|
68
|
-
);
|
|
69
|
-
|
|
70
53
|
await database.migrateSync();
|
|
71
54
|
|
|
72
55
|
runCodegen({ common });
|
|
@@ -111,12 +94,6 @@ export async function run({
|
|
|
111
94
|
eventCount,
|
|
112
95
|
});
|
|
113
96
|
|
|
114
|
-
const historicalIndexingStore = createHistoricalIndexingStore({
|
|
115
|
-
common,
|
|
116
|
-
schemaBuild,
|
|
117
|
-
indexingCache,
|
|
118
|
-
});
|
|
119
|
-
|
|
120
97
|
for (const chain of indexingBuild.chains) {
|
|
121
98
|
const label = { chain: chain.name };
|
|
122
99
|
common.metrics.ponder_historical_total_indexing_seconds.set(
|
|
@@ -152,50 +129,47 @@ export async function run({
|
|
|
152
129
|
|
|
153
130
|
// If the initial checkpoint is zero, we need to run setup events.
|
|
154
131
|
if (crashRecoveryCheckpoint === undefined) {
|
|
155
|
-
await database.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
132
|
+
await database.retry(async () => {
|
|
133
|
+
await database.transaction(async (client, tx) => {
|
|
134
|
+
const historicalIndexingStore = createHistoricalIndexingStore({
|
|
135
|
+
common,
|
|
136
|
+
schemaBuild,
|
|
137
|
+
indexingCache,
|
|
138
|
+
db: tx,
|
|
139
|
+
client,
|
|
140
|
+
});
|
|
141
|
+
const result = await indexing.processSetupEvents({
|
|
142
|
+
db: historicalIndexingStore,
|
|
143
|
+
});
|
|
167
144
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
} catch (error) {
|
|
171
|
-
if (error instanceof FlushError) {
|
|
172
|
-
onReloadableError(error as Error);
|
|
145
|
+
if (result.status === "error") {
|
|
146
|
+
onReloadableError(result.error);
|
|
173
147
|
return;
|
|
174
148
|
}
|
|
175
|
-
|
|
176
|
-
|
|
149
|
+
|
|
150
|
+
try {
|
|
151
|
+
await indexingCache.flush({ client });
|
|
152
|
+
} catch (error) {
|
|
153
|
+
if (error instanceof FlushError) {
|
|
154
|
+
onReloadableError(error as Error);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
throw error;
|
|
158
|
+
}
|
|
159
|
+
});
|
|
177
160
|
});
|
|
178
161
|
}
|
|
179
162
|
|
|
180
163
|
// Note: `_ponder_checkpoint` must be updated after the setup events are processed.
|
|
181
|
-
await database
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
})),
|
|
191
|
-
)
|
|
192
|
-
.onConflictDoUpdate({
|
|
193
|
-
target: PONDER_CHECKPOINT.chainName,
|
|
194
|
-
set: {
|
|
195
|
-
safeCheckpoint: sql`excluded.safe_checkpoint`,
|
|
196
|
-
latestCheckpoint: sql`excluded.latest_checkpoint`,
|
|
197
|
-
},
|
|
198
|
-
});
|
|
164
|
+
await database.setCheckpoints({
|
|
165
|
+
checkpoints: indexingBuild.chains.map((chain) => ({
|
|
166
|
+
chainName: chain.name,
|
|
167
|
+
chainId: chain.id,
|
|
168
|
+
latestCheckpoint: sync.getStartCheckpoint(chain),
|
|
169
|
+
safeCheckpoint: sync.getStartCheckpoint(chain),
|
|
170
|
+
})),
|
|
171
|
+
db: database.qb.drizzle,
|
|
172
|
+
});
|
|
199
173
|
|
|
200
174
|
// Run historical indexing until complete.
|
|
201
175
|
for await (const events of recordAsyncGenerator(
|
|
@@ -213,10 +187,14 @@ export async function run({
|
|
|
213
187
|
)) {
|
|
214
188
|
let endClock = startClock();
|
|
215
189
|
|
|
216
|
-
indexingCache.qb = database.userQB;
|
|
217
190
|
await Promise.all([
|
|
218
|
-
indexingCache.prefetch({
|
|
219
|
-
|
|
191
|
+
indexingCache.prefetch({
|
|
192
|
+
events: events.events,
|
|
193
|
+
db: database.qb.drizzle,
|
|
194
|
+
}),
|
|
195
|
+
cachedViemClient.prefetch({
|
|
196
|
+
events: events.events,
|
|
197
|
+
}),
|
|
220
198
|
]);
|
|
221
199
|
common.metrics.ponder_historical_transform_duration.inc(
|
|
222
200
|
{ step: "prefetch" },
|
|
@@ -224,167 +202,161 @@ export async function run({
|
|
|
224
202
|
);
|
|
225
203
|
if (events.events.length > 0) {
|
|
226
204
|
endClock = startClock();
|
|
205
|
+
await database.retry(async () => {
|
|
206
|
+
await database
|
|
207
|
+
.transaction(async (client, tx) => {
|
|
208
|
+
common.metrics.ponder_historical_transform_duration.inc(
|
|
209
|
+
{ step: "begin" },
|
|
210
|
+
endClock(),
|
|
211
|
+
);
|
|
227
212
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
{ step: "begin" },
|
|
236
|
-
endClock(),
|
|
237
|
-
);
|
|
238
|
-
|
|
239
|
-
endClock = startClock();
|
|
240
|
-
|
|
241
|
-
const eventChunks = chunk(events.events, 93);
|
|
242
|
-
for (const eventChunk of eventChunks) {
|
|
243
|
-
const result = await indexing.processEvents({
|
|
244
|
-
events: eventChunk,
|
|
245
|
-
db: historicalIndexingStore,
|
|
246
|
-
cache: indexingCache,
|
|
213
|
+
endClock = startClock();
|
|
214
|
+
const historicalIndexingStore = createHistoricalIndexingStore({
|
|
215
|
+
common,
|
|
216
|
+
schemaBuild,
|
|
217
|
+
indexingCache,
|
|
218
|
+
db: tx,
|
|
219
|
+
client,
|
|
247
220
|
});
|
|
248
221
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
222
|
+
const eventChunks = chunk(events.events, 93);
|
|
223
|
+
for (const eventChunk of eventChunks) {
|
|
224
|
+
const result = await indexing.processEvents({
|
|
225
|
+
events: eventChunk,
|
|
226
|
+
db: historicalIndexingStore,
|
|
227
|
+
cache: indexingCache,
|
|
228
|
+
});
|
|
253
229
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
230
|
+
if (result.status === "error") {
|
|
231
|
+
onReloadableError(result.error);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
257
234
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
(chain) => chain.id === Number(checkpoint.chainId),
|
|
261
|
-
)!;
|
|
262
|
-
common.metrics.ponder_historical_completed_indexing_seconds.set(
|
|
263
|
-
{ chain: chain.name },
|
|
264
|
-
Math.max(
|
|
265
|
-
Number(checkpoint.blockTimestamp) -
|
|
266
|
-
Math.max(
|
|
267
|
-
sync.seconds[chain.name]!.cached,
|
|
268
|
-
sync.seconds[chain.name]!.start,
|
|
269
|
-
),
|
|
270
|
-
0,
|
|
271
|
-
),
|
|
235
|
+
const checkpoint = decodeCheckpoint(
|
|
236
|
+
eventChunk[eventChunk.length - 1]!.checkpoint,
|
|
272
237
|
);
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
for (const chain of indexingBuild.chains) {
|
|
238
|
+
|
|
239
|
+
if (preBuild.ordering === "multichain") {
|
|
240
|
+
const chain = indexingBuild.chains.find(
|
|
241
|
+
(chain) => chain.id === Number(checkpoint.chainId),
|
|
242
|
+
)!;
|
|
279
243
|
common.metrics.ponder_historical_completed_indexing_seconds.set(
|
|
280
244
|
{ chain: chain.name },
|
|
281
|
-
Math.
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
sync.seconds[chain.name]!.cached,
|
|
286
|
-
sync.seconds[chain.name]!.start,
|
|
287
|
-
),
|
|
288
|
-
0,
|
|
289
|
-
),
|
|
290
|
-
Math.max(
|
|
291
|
-
sync.seconds[chain.name]!.end -
|
|
245
|
+
Math.max(
|
|
246
|
+
Number(checkpoint.blockTimestamp) -
|
|
247
|
+
Math.max(
|
|
248
|
+
sync.seconds[chain.name]!.cached,
|
|
292
249
|
sync.seconds[chain.name]!.start,
|
|
293
|
-
|
|
294
|
-
|
|
250
|
+
),
|
|
251
|
+
0,
|
|
295
252
|
),
|
|
296
253
|
);
|
|
297
254
|
common.metrics.ponder_indexing_timestamp.set(
|
|
298
255
|
{ chain: chain.name },
|
|
299
|
-
|
|
300
|
-
Number(checkpoint.blockTimestamp),
|
|
301
|
-
sync.seconds[chain.name]!.end,
|
|
302
|
-
),
|
|
256
|
+
Number(checkpoint.blockTimestamp),
|
|
303
257
|
);
|
|
258
|
+
} else {
|
|
259
|
+
for (const chain of indexingBuild.chains) {
|
|
260
|
+
common.metrics.ponder_historical_completed_indexing_seconds.set(
|
|
261
|
+
{ chain: chain.name },
|
|
262
|
+
Math.min(
|
|
263
|
+
Math.max(
|
|
264
|
+
Number(checkpoint.blockTimestamp) -
|
|
265
|
+
Math.max(
|
|
266
|
+
sync.seconds[chain.name]!.cached,
|
|
267
|
+
sync.seconds[chain.name]!.start,
|
|
268
|
+
),
|
|
269
|
+
0,
|
|
270
|
+
),
|
|
271
|
+
Math.max(
|
|
272
|
+
sync.seconds[chain.name]!.end -
|
|
273
|
+
sync.seconds[chain.name]!.start,
|
|
274
|
+
0,
|
|
275
|
+
),
|
|
276
|
+
),
|
|
277
|
+
);
|
|
278
|
+
common.metrics.ponder_indexing_timestamp.set(
|
|
279
|
+
{ chain: chain.name },
|
|
280
|
+
Math.max(
|
|
281
|
+
Number(checkpoint.blockTimestamp),
|
|
282
|
+
sync.seconds[chain.name]!.end,
|
|
283
|
+
),
|
|
284
|
+
);
|
|
285
|
+
}
|
|
304
286
|
}
|
|
305
|
-
}
|
|
306
287
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
288
|
+
// Note: allows for terminal and logs to be updated
|
|
289
|
+
if (preBuild.databaseConfig.kind === "pglite") {
|
|
290
|
+
await new Promise(setImmediate);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
await new Promise(setImmediate);
|
|
294
|
+
|
|
295
|
+
// underlying metrics collection is actually synchronous
|
|
296
|
+
// https://github.com/siimon/prom-client/blob/master/lib/histogram.js#L102-L125
|
|
297
|
+
const { eta, progress } = await getAppProgress(common.metrics);
|
|
298
|
+
if (eta === undefined || progress === undefined) {
|
|
299
|
+
common.logger.info({
|
|
300
|
+
service: "app",
|
|
301
|
+
msg: `Indexed ${events.events.length} events`,
|
|
302
|
+
});
|
|
303
|
+
} else {
|
|
304
|
+
common.logger.info({
|
|
305
|
+
service: "app",
|
|
306
|
+
msg: `Indexed ${events.events.length} events with ${formatPercentage(progress)} complete and ${formatEta(eta * 1_000)} remaining`,
|
|
307
|
+
});
|
|
310
308
|
}
|
|
311
|
-
}
|
|
312
|
-
await new Promise(setImmediate);
|
|
313
309
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
} else {
|
|
323
|
-
common.logger.info({
|
|
324
|
-
service: "app",
|
|
325
|
-
msg: `Indexed ${events.events.length} events with ${formatPercentage(progress)} complete and ${formatEta(eta * 1_000)} remaining`,
|
|
326
|
-
});
|
|
327
|
-
}
|
|
310
|
+
common.metrics.ponder_historical_transform_duration.inc(
|
|
311
|
+
{ step: "index" },
|
|
312
|
+
endClock(),
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
endClock = startClock();
|
|
316
|
+
// Note: at this point, the next events can be preloaded, as long as the are not indexed until
|
|
317
|
+
// the "flush" + "finalize" is complete.
|
|
328
318
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
try {
|
|
339
|
-
await indexingCache.flush();
|
|
340
|
-
} catch (error) {
|
|
341
|
-
if (error instanceof FlushError) {
|
|
342
|
-
onReloadableError(error as Error);
|
|
343
|
-
return;
|
|
319
|
+
try {
|
|
320
|
+
await indexingCache.flush({ client });
|
|
321
|
+
} catch (error) {
|
|
322
|
+
if (error instanceof FlushError) {
|
|
323
|
+
onReloadableError(error as Error);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
throw error;
|
|
344
327
|
}
|
|
345
|
-
throw error;
|
|
346
|
-
}
|
|
347
328
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
.insert(PONDER_CHECKPOINT)
|
|
358
|
-
.values(
|
|
359
|
-
events.checkpoints.map(({ chainId, checkpoint }) => ({
|
|
329
|
+
common.metrics.ponder_historical_transform_duration.inc(
|
|
330
|
+
{ step: "load" },
|
|
331
|
+
endClock(),
|
|
332
|
+
);
|
|
333
|
+
endClock = startClock();
|
|
334
|
+
|
|
335
|
+
await database.setCheckpoints({
|
|
336
|
+
checkpoints: events.checkpoints.map(
|
|
337
|
+
({ chainId, checkpoint }) => ({
|
|
360
338
|
chainName: indexingBuild.chains.find(
|
|
361
339
|
(chain) => chain.id === chainId,
|
|
362
340
|
)!.name,
|
|
363
341
|
chainId,
|
|
364
342
|
latestCheckpoint: checkpoint,
|
|
365
343
|
safeCheckpoint: checkpoint,
|
|
366
|
-
})
|
|
367
|
-
)
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
set: {
|
|
371
|
-
safeCheckpoint: sql`excluded.safe_checkpoint`,
|
|
372
|
-
latestCheckpoint: sql`excluded.latest_checkpoint`,
|
|
373
|
-
},
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
common.metrics.ponder_historical_transform_duration.inc(
|
|
378
|
-
{ step: "finalize" },
|
|
379
|
-
endClock(),
|
|
380
|
-
);
|
|
381
|
-
endClock = startClock();
|
|
382
|
-
})
|
|
383
|
-
.catch((error) => {
|
|
384
|
-
indexingCache.rollback();
|
|
385
|
-
throw error;
|
|
386
|
-
});
|
|
344
|
+
}),
|
|
345
|
+
),
|
|
346
|
+
db: tx,
|
|
347
|
+
});
|
|
387
348
|
|
|
349
|
+
common.metrics.ponder_historical_transform_duration.inc(
|
|
350
|
+
{ step: "finalize" },
|
|
351
|
+
endClock(),
|
|
352
|
+
);
|
|
353
|
+
endClock = startClock();
|
|
354
|
+
})
|
|
355
|
+
.catch((error) => {
|
|
356
|
+
indexingCache.rollback();
|
|
357
|
+
throw error;
|
|
358
|
+
});
|
|
359
|
+
});
|
|
388
360
|
cachedViemClient.clear();
|
|
389
361
|
common.metrics.ponder_historical_transform_duration.inc(
|
|
390
362
|
{ step: "commit" },
|
|
@@ -428,26 +400,28 @@ export async function run({
|
|
|
428
400
|
msg: "Completed historical indexing",
|
|
429
401
|
});
|
|
430
402
|
|
|
431
|
-
await createIndexes(
|
|
432
|
-
await
|
|
433
|
-
tables.map((table) => createTrigger(database.adminQB, { table })),
|
|
434
|
-
);
|
|
403
|
+
await database.createIndexes();
|
|
404
|
+
await database.createTriggers();
|
|
435
405
|
|
|
436
406
|
if (namespaceBuild.viewsSchema) {
|
|
437
|
-
await database.
|
|
438
|
-
await
|
|
407
|
+
await database.wrap({ method: "create-views" }, async () => {
|
|
408
|
+
await database.qb.drizzle.execute(
|
|
439
409
|
sql.raw(`CREATE SCHEMA IF NOT EXISTS "${namespaceBuild.viewsSchema}"`),
|
|
440
410
|
);
|
|
441
411
|
|
|
412
|
+
const tables = Object.values(schemaBuild.schema).filter(
|
|
413
|
+
(table): table is PgTableWithColumns<TableConfig> => is(table, PgTable),
|
|
414
|
+
);
|
|
415
|
+
|
|
442
416
|
for (const table of tables) {
|
|
443
417
|
// Note: drop views before creating new ones to avoid enum errors.
|
|
444
|
-
await
|
|
418
|
+
await database.qb.drizzle.execute(
|
|
445
419
|
sql.raw(
|
|
446
420
|
`DROP VIEW IF EXISTS "${namespaceBuild.viewsSchema}"."${getTableName(table)}"`,
|
|
447
421
|
),
|
|
448
422
|
);
|
|
449
423
|
|
|
450
|
-
await
|
|
424
|
+
await database.qb.drizzle.execute(
|
|
451
425
|
sql.raw(
|
|
452
426
|
`CREATE VIEW "${namespaceBuild.viewsSchema}"."${getTableName(table)}" AS SELECT * FROM "${namespaceBuild.schema}"."${getTableName(table)}"`,
|
|
453
427
|
),
|
|
@@ -459,13 +433,13 @@ export async function run({
|
|
|
459
433
|
msg: `Created ${tables.length} views in schema "${namespaceBuild.viewsSchema}"`,
|
|
460
434
|
});
|
|
461
435
|
|
|
462
|
-
await
|
|
436
|
+
await database.qb.drizzle.execute(
|
|
463
437
|
sql.raw(
|
|
464
438
|
`CREATE OR REPLACE VIEW "${namespaceBuild.viewsSchema}"."_ponder_meta" AS SELECT * FROM "${namespaceBuild.schema}"."_ponder_meta"`,
|
|
465
439
|
),
|
|
466
440
|
);
|
|
467
441
|
|
|
468
|
-
await
|
|
442
|
+
await database.qb.drizzle.execute(
|
|
469
443
|
sql.raw(
|
|
470
444
|
`CREATE OR REPLACE VIEW "${namespaceBuild.viewsSchema}"."_ponder_checkpoint" AS SELECT * FROM "${namespaceBuild.schema}"."_ponder_checkpoint"`,
|
|
471
445
|
),
|
|
@@ -475,7 +449,7 @@ export async function run({
|
|
|
475
449
|
const notification = "status_notify()";
|
|
476
450
|
const channel = `${namespaceBuild.viewsSchema}_status_channel`;
|
|
477
451
|
|
|
478
|
-
await
|
|
452
|
+
await database.qb.drizzle.execute(
|
|
479
453
|
sql.raw(`
|
|
480
454
|
CREATE OR REPLACE FUNCTION "${namespaceBuild.viewsSchema}".${notification}
|
|
481
455
|
RETURNS TRIGGER
|
|
@@ -488,7 +462,7 @@ export async function run({
|
|
|
488
462
|
$$;`),
|
|
489
463
|
);
|
|
490
464
|
|
|
491
|
-
await
|
|
465
|
+
await database.qb.drizzle.execute(
|
|
492
466
|
sql.raw(`
|
|
493
467
|
CREATE OR REPLACE TRIGGER "${trigger}"
|
|
494
468
|
AFTER INSERT OR UPDATE OR DELETE
|
|
@@ -499,16 +473,13 @@ export async function run({
|
|
|
499
473
|
});
|
|
500
474
|
}
|
|
501
475
|
|
|
502
|
-
await database
|
|
503
|
-
.adminQB("set_ready")
|
|
504
|
-
.update(PONDER_META)
|
|
505
|
-
.set({ value: sql`jsonb_set(value, '{is_ready}', to_jsonb(1))` });
|
|
476
|
+
await database.setReady();
|
|
506
477
|
|
|
507
478
|
const realtimeIndexingStore = createRealtimeIndexingStore({
|
|
508
479
|
common,
|
|
509
480
|
schemaBuild,
|
|
481
|
+
database,
|
|
510
482
|
});
|
|
511
|
-
realtimeIndexingStore.qb = database.userQB;
|
|
512
483
|
|
|
513
484
|
const onRealtimeEvent = mutex(async (event: RealtimeEvent) => {
|
|
514
485
|
switch (event.type) {
|
|
@@ -542,11 +513,7 @@ export async function run({
|
|
|
542
513
|
|
|
543
514
|
if (result.status === "error") onReloadableError(result.error);
|
|
544
515
|
|
|
545
|
-
await
|
|
546
|
-
tables.map((table) =>
|
|
547
|
-
commitBlock(database.userQB, { table, checkpoint }),
|
|
548
|
-
),
|
|
549
|
-
);
|
|
516
|
+
await database.commitBlock({ checkpoint, db: database.qb.drizzle });
|
|
550
517
|
|
|
551
518
|
if (preBuild.ordering === "multichain") {
|
|
552
519
|
common.metrics.ponder_indexing_timestamp.set(
|
|
@@ -564,10 +531,11 @@ export async function run({
|
|
|
564
531
|
}
|
|
565
532
|
}
|
|
566
533
|
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
534
|
+
await database.wrap({ method: "setCheckpoints" }, async () => {
|
|
535
|
+
if (event.checkpoints.length === 0) return;
|
|
536
|
+
|
|
537
|
+
await database.qb.drizzle
|
|
538
|
+
.insert(database.PONDER_CHECKPOINT)
|
|
571
539
|
.values(
|
|
572
540
|
event.checkpoints.map(({ chainId, checkpoint }) => ({
|
|
573
541
|
chainName: indexingBuild.chains.find(
|
|
@@ -579,10 +547,12 @@ export async function run({
|
|
|
579
547
|
})),
|
|
580
548
|
)
|
|
581
549
|
.onConflictDoUpdate({
|
|
582
|
-
target: PONDER_CHECKPOINT.chainName,
|
|
583
|
-
set: {
|
|
550
|
+
target: database.PONDER_CHECKPOINT.chainName,
|
|
551
|
+
set: {
|
|
552
|
+
latestCheckpoint: sql`excluded.latest_checkpoint`,
|
|
553
|
+
},
|
|
584
554
|
});
|
|
585
|
-
}
|
|
555
|
+
});
|
|
586
556
|
|
|
587
557
|
break;
|
|
588
558
|
}
|
|
@@ -590,41 +560,25 @@ export async function run({
|
|
|
590
560
|
// Note: `_ponder_checkpoint` is not called here, instead it is called
|
|
591
561
|
// in the `block` case.
|
|
592
562
|
|
|
593
|
-
await database.
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
checkpoint: event.checkpoint,
|
|
599
|
-
});
|
|
600
|
-
common.logger.info({
|
|
601
|
-
service: "database",
|
|
602
|
-
msg: `Reverted ${count} unfinalized operations from '${getTableName(table)}'`,
|
|
603
|
-
});
|
|
604
|
-
await createTrigger(tx, { table });
|
|
605
|
-
}
|
|
563
|
+
await database.removeTriggers();
|
|
564
|
+
await database.retry(async () => {
|
|
565
|
+
await database.qb.drizzle.transaction(async (tx) => {
|
|
566
|
+
await database.revert({ checkpoint: event.checkpoint, tx });
|
|
567
|
+
});
|
|
606
568
|
});
|
|
569
|
+
await database.createTriggers();
|
|
607
570
|
|
|
608
571
|
break;
|
|
609
572
|
|
|
610
573
|
case "finalize":
|
|
611
|
-
await database.
|
|
612
|
-
|
|
613
|
-
safeCheckpoint: event.checkpoint,
|
|
614
|
-
});
|
|
615
|
-
|
|
616
|
-
for (const table of tables) {
|
|
617
|
-
await finalize(tx, { table, checkpoint: event.checkpoint });
|
|
618
|
-
|
|
619
|
-
const decoded = decodeCheckpoint(event.checkpoint);
|
|
620
|
-
|
|
621
|
-
common.logger.debug({
|
|
622
|
-
service: "database",
|
|
623
|
-
msg: `Updated finalized checkpoint to (timestamp=${decoded.blockTimestamp} chainId=${decoded.chainId} block=${decoded.blockNumber})`,
|
|
624
|
-
});
|
|
625
|
-
}
|
|
574
|
+
await database.qb.drizzle.update(database.PONDER_CHECKPOINT).set({
|
|
575
|
+
safeCheckpoint: event.checkpoint,
|
|
626
576
|
});
|
|
627
577
|
|
|
578
|
+
await database.finalize({
|
|
579
|
+
checkpoint: event.checkpoint,
|
|
580
|
+
db: database.qb.drizzle,
|
|
581
|
+
});
|
|
628
582
|
break;
|
|
629
583
|
|
|
630
584
|
default:
|