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.
Files changed (123) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/esm/bin/commands/createViews.js +9 -20
  3. package/dist/esm/bin/commands/createViews.js.map +1 -1
  4. package/dist/esm/bin/commands/dev.js +1 -1
  5. package/dist/esm/bin/commands/dev.js.map +1 -1
  6. package/dist/esm/bin/commands/list.js +4 -7
  7. package/dist/esm/bin/commands/list.js.map +1 -1
  8. package/dist/esm/bin/commands/prune.js +9 -21
  9. package/dist/esm/bin/commands/prune.js.map +1 -1
  10. package/dist/esm/bin/commands/serve.js +1 -1
  11. package/dist/esm/bin/commands/serve.js.map +1 -1
  12. package/dist/esm/bin/commands/start.js +3 -3
  13. package/dist/esm/bin/commands/start.js.map +1 -1
  14. package/dist/esm/bin/utils/run.js +159 -180
  15. package/dist/esm/bin/utils/run.js.map +1 -1
  16. package/dist/esm/build/index.js +1 -48
  17. package/dist/esm/build/index.js.map +1 -1
  18. package/dist/esm/build/plugin.js +1 -1
  19. package/dist/esm/client/index.js +9 -13
  20. package/dist/esm/client/index.js.map +1 -1
  21. package/dist/esm/database/index.js +429 -141
  22. package/dist/esm/database/index.js.map +1 -1
  23. package/dist/esm/drizzle/index.js.map +1 -1
  24. package/dist/esm/drizzle/kit/index.js.map +1 -1
  25. package/dist/esm/drizzle/onchain.js +1 -8
  26. package/dist/esm/drizzle/onchain.js.map +1 -1
  27. package/dist/esm/graphql/index.js +16 -19
  28. package/dist/esm/graphql/index.js.map +1 -1
  29. package/dist/esm/graphql/middleware.js +7 -3
  30. package/dist/esm/graphql/middleware.js.map +1 -1
  31. package/dist/esm/indexing-store/cache.js +32 -26
  32. package/dist/esm/indexing-store/cache.js.map +1 -1
  33. package/dist/esm/indexing-store/historical.js +32 -23
  34. package/dist/esm/indexing-store/historical.js.map +1 -1
  35. package/dist/esm/indexing-store/index.js +18 -1
  36. package/dist/esm/indexing-store/index.js.map +1 -1
  37. package/dist/esm/indexing-store/realtime.js +140 -89
  38. package/dist/esm/indexing-store/realtime.js.map +1 -1
  39. package/dist/esm/internal/errors.js +0 -12
  40. package/dist/esm/internal/errors.js.map +1 -1
  41. package/dist/esm/server/index.js +2 -10
  42. package/dist/esm/server/index.js.map +1 -1
  43. package/dist/esm/sync-store/index.js +432 -403
  44. package/dist/esm/sync-store/index.js.map +1 -1
  45. package/dist/esm/utils/wait.js +0 -2
  46. package/dist/esm/utils/wait.js.map +1 -1
  47. package/dist/types/bin/commands/createViews.d.ts.map +1 -1
  48. package/dist/types/bin/commands/list.d.ts.map +1 -1
  49. package/dist/types/bin/commands/prune.d.ts.map +1 -1
  50. package/dist/types/bin/commands/start.d.ts +0 -2
  51. package/dist/types/bin/commands/start.d.ts.map +1 -1
  52. package/dist/types/bin/utils/run.d.ts +1 -1
  53. package/dist/types/bin/utils/run.d.ts.map +1 -1
  54. package/dist/types/build/index.d.ts +1 -1
  55. package/dist/types/build/index.d.ts.map +1 -1
  56. package/dist/types/client/index.d.ts.map +1 -1
  57. package/dist/types/database/index.d.ts +73 -25
  58. package/dist/types/database/index.d.ts.map +1 -1
  59. package/dist/types/drizzle/index.d.ts +3 -2
  60. package/dist/types/drizzle/index.d.ts.map +1 -1
  61. package/dist/types/drizzle/kit/index.d.ts +4 -3
  62. package/dist/types/drizzle/kit/index.d.ts.map +1 -1
  63. package/dist/types/drizzle/onchain.d.ts +5 -12
  64. package/dist/types/drizzle/onchain.d.ts.map +1 -1
  65. package/dist/types/graphql/index.d.ts +4 -2
  66. package/dist/types/graphql/index.d.ts.map +1 -1
  67. package/dist/types/graphql/middleware.d.ts +1 -1
  68. package/dist/types/graphql/middleware.d.ts.map +1 -1
  69. package/dist/types/indexing-store/cache.d.ts +12 -5
  70. package/dist/types/indexing-store/cache.d.ts.map +1 -1
  71. package/dist/types/indexing-store/historical.d.ts +7 -2
  72. package/dist/types/indexing-store/historical.d.ts.map +1 -1
  73. package/dist/types/indexing-store/index.d.ts +2 -4
  74. package/dist/types/indexing-store/index.d.ts.map +1 -1
  75. package/dist/types/indexing-store/realtime.d.ts +3 -1
  76. package/dist/types/indexing-store/realtime.d.ts.map +1 -1
  77. package/dist/types/internal/errors.d.ts +0 -4
  78. package/dist/types/internal/errors.d.ts.map +1 -1
  79. package/dist/types/server/index.d.ts +1 -1
  80. package/dist/types/server/index.d.ts.map +1 -1
  81. package/dist/types/sync/index.d.ts +1 -1
  82. package/dist/types/sync-store/index.d.ts.map +1 -1
  83. package/dist/types/utils/wait.d.ts.map +1 -1
  84. package/package.json +2 -2
  85. package/src/bin/commands/createViews.ts +26 -37
  86. package/src/bin/commands/dev.ts +1 -1
  87. package/src/bin/commands/list.ts +4 -7
  88. package/src/bin/commands/prune.ts +17 -31
  89. package/src/bin/commands/serve.ts +1 -1
  90. package/src/bin/commands/start.ts +3 -4
  91. package/src/bin/utils/run.ts +210 -256
  92. package/src/build/index.ts +2 -53
  93. package/src/build/plugin.ts +1 -1
  94. package/src/client/index.ts +10 -21
  95. package/src/database/index.ts +742 -331
  96. package/src/drizzle/index.ts +3 -2
  97. package/src/drizzle/kit/index.ts +5 -2
  98. package/src/drizzle/onchain.ts +2 -26
  99. package/src/graphql/index.ts +26 -31
  100. package/src/graphql/middleware.ts +7 -5
  101. package/src/indexing-store/cache.ts +52 -35
  102. package/src/indexing-store/historical.ts +40 -28
  103. package/src/indexing-store/index.ts +27 -2
  104. package/src/indexing-store/realtime.ts +220 -176
  105. package/src/internal/errors.ts +0 -9
  106. package/src/server/index.ts +3 -14
  107. package/src/sync-store/index.ts +997 -870
  108. package/src/utils/wait.ts +0 -1
  109. package/dist/esm/database/queryBuilder.js +0 -206
  110. package/dist/esm/database/queryBuilder.js.map +0 -1
  111. package/dist/esm/database/utils.js +0 -100
  112. package/dist/esm/database/utils.js.map +0 -1
  113. package/dist/esm/drizzle/json.js +0 -119
  114. package/dist/esm/drizzle/json.js.map +0 -1
  115. package/dist/types/database/queryBuilder.d.ts +0 -37
  116. package/dist/types/database/queryBuilder.d.ts.map +0 -1
  117. package/dist/types/database/utils.d.ts +0 -25
  118. package/dist/types/database/utils.d.ts.map +0 -1
  119. package/dist/types/drizzle/json.d.ts +0 -51
  120. package/dist/types/drizzle/json.d.ts.map +0 -1
  121. package/src/database/queryBuilder.ts +0 -319
  122. package/src/database/utils.ts +0 -140
  123. package/src/drizzle/json.ts +0 -154
@@ -58,7 +58,7 @@ import {
58
58
  encodeTransaction,
59
59
  encodeTransactionReceipt,
60
60
  } from "./encode.js";
61
- import * as PONDER_SYNC from "./schema.js";
61
+ import * as ponderSyncSchema from "./schema.js";
62
62
 
63
63
  export type SyncStore = {
64
64
  insertIntervals(args: {
@@ -141,931 +141,1046 @@ export const createSyncStore = ({
141
141
  insertIntervals: async ({ intervals, chainId }) => {
142
142
  if (intervals.length === 0) return;
143
143
 
144
- const perFragmentIntervals = new Map<FragmentId, Interval[]>();
145
- const values: (typeof PONDER_SYNC.intervals.$inferInsert)[] = [];
144
+ await database.wrap(
145
+ { method: "insertIntervals", includeTraceLogs: true },
146
+ async () => {
147
+ const perFragmentIntervals = new Map<FragmentId, Interval[]>();
148
+ const values: (typeof ponderSyncSchema.intervals.$inferInsert)[] = [];
146
149
 
147
- // dedupe and merge matching fragments
150
+ // dedupe and merge matching fragments
148
151
 
149
- for (const { filter, interval } of intervals) {
150
- for (const fragment of getFragments(filter)) {
151
- const fragmentId = encodeFragment(fragment.fragment);
152
- if (perFragmentIntervals.has(fragmentId) === false) {
153
- perFragmentIntervals.set(fragmentId, []);
154
- }
155
-
156
- perFragmentIntervals.get(fragmentId)!.push(interval);
157
- }
158
- }
152
+ for (const { filter, interval } of intervals) {
153
+ for (const fragment of getFragments(filter)) {
154
+ const fragmentId = encodeFragment(fragment.fragment);
155
+ if (perFragmentIntervals.has(fragmentId) === false) {
156
+ perFragmentIntervals.set(fragmentId, []);
157
+ }
159
158
 
160
- // NOTE: In order to force proper range union behavior, `interval[1]` must
161
- // be rounded up.
159
+ perFragmentIntervals.get(fragmentId)!.push(interval);
160
+ }
161
+ }
162
162
 
163
- for (const [fragmentId, intervals] of perFragmentIntervals) {
164
- const numranges = intervals
165
- .map((interval) => {
166
- const start = interval[0];
167
- const end = interval[1] + 1;
168
- return `numrange(${start}, ${end}, '[]')`;
169
- })
170
- .join(", ");
171
-
172
- values.push({
173
- fragmentId: fragmentId,
174
- chainId: BigInt(chainId),
175
- // @ts-expect-error
176
- blocks: sql.raw(`nummultirange(${numranges})`),
177
- });
178
- }
163
+ // NOTE: In order to force proper range union behavior, `interval[1]` must
164
+ // be rounded up.
165
+
166
+ for (const [fragmentId, intervals] of perFragmentIntervals) {
167
+ const numranges = intervals
168
+ .map((interval) => {
169
+ const start = interval[0];
170
+ const end = interval[1] + 1;
171
+ return `numrange(${start}, ${end}, '[]')`;
172
+ })
173
+ .join(", ");
174
+
175
+ values.push({
176
+ fragmentId: fragmentId,
177
+ chainId: BigInt(chainId),
178
+ // @ts-expect-error
179
+ blocks: sql.raw(`nummultirange(${numranges})`),
180
+ });
181
+ }
179
182
 
180
- await database
181
- .syncQB("insert_intervals")
182
- .insert(PONDER_SYNC.intervals)
183
- .values(values)
184
- .onConflictDoUpdate({
185
- target: PONDER_SYNC.intervals.fragmentId,
186
- set: {
187
- blocks: sql`intervals.blocks + excluded.blocks`,
188
- },
189
- });
183
+ await database.qb.sync
184
+ .insert(ponderSyncSchema.intervals)
185
+ .values(values)
186
+ .onConflictDoUpdate({
187
+ target: ponderSyncSchema.intervals.fragmentId,
188
+ set: {
189
+ blocks: sql`intervals.blocks + excluded.blocks`,
190
+ },
191
+ });
192
+ },
193
+ );
190
194
  },
191
- getIntervals: async ({ filters }) => {
192
- const queries = filters.flatMap((filter, i) => {
193
- const fragments = getFragments(filter);
194
- return fragments.map((fragment, j) =>
195
- database
196
- .syncQB("select_intervals")
197
- .select({
198
- mergedBlocks: sql<string>`range_agg(unnested.blocks)`.as(
199
- "merged_blocks",
200
- ),
201
- filter: sql.raw(`'${i}'`).as("filter"),
202
- fragment: sql.raw(`'${j}'`).as("fragment"),
203
- })
204
- .from(
205
- database
206
- .syncQB()
207
- .select({ blocks: sql.raw("unnest(blocks)").as("blocks") })
208
- .from(PONDER_SYNC.intervals)
209
- .where(
210
- inArray(PONDER_SYNC.intervals.fragmentId, fragment.adjacentIds),
211
- )
212
- .as("unnested"),
213
- ),
214
- );
215
- });
195
+ getIntervals: async ({ filters }) =>
196
+ database.wrap(
197
+ { method: "getIntervals", includeTraceLogs: true },
198
+ async () => {
199
+ const queries = filters.flatMap((filter, i) => {
200
+ const fragments = getFragments(filter);
201
+ return fragments.map((fragment, j) =>
202
+ database.qb.sync
203
+ .select({
204
+ mergedBlocks: sql<string>`range_agg(unnested.blocks)`.as(
205
+ "merged_blocks",
206
+ ),
207
+ filter: sql.raw(`'${i}'`).as("filter"),
208
+ fragment: sql.raw(`'${j}'`).as("fragment"),
209
+ })
210
+ .from(
211
+ database.qb.sync
212
+ .select({ blocks: sql.raw("unnest(blocks)").as("blocks") })
213
+ .from(ponderSyncSchema.intervals)
214
+ .where(
215
+ inArray(
216
+ ponderSyncSchema.intervals.fragmentId,
217
+ fragment.adjacentIds,
218
+ ),
219
+ )
220
+ .as("unnested"),
221
+ ),
222
+ );
223
+ });
216
224
 
217
- let rows: Awaited<(typeof queries)[number]>;
225
+ let rows: Awaited<(typeof queries)[number]>;
218
226
 
219
- if (queries.length > 1) {
220
- // @ts-expect-error
221
- rows = await unionAll(...queries);
222
- } else {
223
- rows = await queries[0]!.execute();
224
- }
227
+ if (queries.length > 1) {
228
+ // @ts-expect-error
229
+ rows = await unionAll(...queries);
230
+ } else {
231
+ rows = await queries[0]!.execute();
232
+ }
225
233
 
226
- const result = new Map<
227
- Filter,
228
- { fragment: Fragment; intervals: Interval[] }[]
229
- >();
230
-
231
- // NOTE: `interval[1]` must be rounded down in order to offset the previous
232
- // rounding.
233
-
234
- for (let i = 0; i < filters.length; i++) {
235
- const filter = filters[i]!;
236
- const fragments = getFragments(filter);
237
- result.set(filter, []);
238
- for (let j = 0; j < fragments.length; j++) {
239
- const fragment = fragments[j]!;
240
- const intervals = rows
241
- .filter((row) => row.filter === `${i}`)
242
- .filter((row) => row.fragment === `${j}`)
243
- .map((row) =>
244
- (row.mergedBlocks
245
- ? (JSON.parse(`[${row.mergedBlocks.slice(1, -1)}]`) as Interval[])
246
- : []
247
- ).map((interval) => [interval[0], interval[1] - 1] as Interval),
248
- )[0]!;
249
-
250
- result.get(filter)!.push({ fragment: fragment.fragment, intervals });
251
- }
252
- }
234
+ const result = new Map<
235
+ Filter,
236
+ { fragment: Fragment; intervals: Interval[] }[]
237
+ >();
238
+
239
+ // NOTE: `interval[1]` must be rounded down in order to offset the previous
240
+ // rounding.
241
+
242
+ for (let i = 0; i < filters.length; i++) {
243
+ const filter = filters[i]!;
244
+ const fragments = getFragments(filter);
245
+ result.set(filter, []);
246
+ for (let j = 0; j < fragments.length; j++) {
247
+ const fragment = fragments[j]!;
248
+ const intervals = rows
249
+ .filter((row) => row.filter === `${i}`)
250
+ .filter((row) => row.fragment === `${j}`)
251
+ .map((row) =>
252
+ (row.mergedBlocks
253
+ ? (JSON.parse(
254
+ `[${row.mergedBlocks.slice(1, -1)}]`,
255
+ ) as Interval[])
256
+ : []
257
+ ).map((interval) => [interval[0], interval[1] - 1] as Interval),
258
+ )[0]!;
259
+
260
+ result
261
+ .get(filter)!
262
+ .push({ fragment: fragment.fragment, intervals });
263
+ }
264
+ }
253
265
 
254
- return result;
255
- },
266
+ return result;
267
+ },
268
+ ),
256
269
  insertChildAddresses: async ({ factory, childAddresses, chainId }) => {
257
270
  if (childAddresses.size === 0) return;
271
+ await database.wrap(
272
+ { method: "insertChildAddresses", includeTraceLogs: true },
273
+ async () => {
274
+ const batchSize = Math.floor(
275
+ common.options.databaseMaxQueryParameters / 3,
276
+ );
258
277
 
259
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters / 3);
278
+ const values: (typeof ponderSyncSchema.factoryAddresses.$inferInsert)[] =
279
+ [];
280
+
281
+ const factoryInsert = database.qb.sync.$with("factory_insert").as(
282
+ database.qb.sync
283
+ .insert(ponderSyncSchema.factories)
284
+ .values({ factory })
285
+ // @ts-expect-error bug with drizzle-orm
286
+ .returning({ id: ponderSyncSchema.factories.id })
287
+ .onConflictDoUpdate({
288
+ target: ponderSyncSchema.factories.factory,
289
+ set: { factory: sql`excluded.factory` },
290
+ }),
291
+ );
260
292
 
261
- const values: (typeof PONDER_SYNC.factoryAddresses.$inferInsert)[] = [];
293
+ for (const [address, blockNumber] of childAddresses) {
294
+ values.push({
295
+ // @ts-expect-error
296
+ factoryId: sql`(SELECT id FROM factory_insert)`,
297
+ chainId: BigInt(chainId),
298
+ blockNumber: BigInt(blockNumber),
299
+ address,
300
+ });
301
+ }
262
302
 
263
- const factoryInsert = database
264
- .syncQB()
265
- .$with("factory_insert")
266
- .as(
267
- database
268
- .syncQB()
269
- .insert(PONDER_SYNC.factories)
270
- .values({ factory })
271
- // @ts-expect-error bug with drizzle-orm
272
- .returning({ id: PONDER_SYNC.factories.id })
273
- .onConflictDoUpdate({
274
- target: PONDER_SYNC.factories.factory,
275
- set: { factory: sql`excluded.factory` },
276
- }),
277
- );
303
+ for (let i = 0; i < values.length; i += batchSize) {
304
+ await database.qb.sync
305
+ .with(factoryInsert)
306
+ .insert(ponderSyncSchema.factoryAddresses)
307
+ .values(values.slice(i, i + batchSize));
308
+ }
309
+ },
310
+ );
311
+ },
312
+ getChildAddresses: ({ factory }) =>
313
+ database.wrap(
314
+ { method: "getChildAddresses", includeTraceLogs: true },
315
+ () => {
316
+ const factoryInsert = database.qb.sync.$with("factory_insert").as(
317
+ database.qb.sync
318
+ .insert(ponderSyncSchema.factories)
319
+ .values({ factory })
320
+ // @ts-expect-error bug with drizzle-orm
321
+ .returning({ id: ponderSyncSchema.factories.id })
322
+ .onConflictDoUpdate({
323
+ target: ponderSyncSchema.factories.factory,
324
+ set: { factory: sql`excluded.factory` },
325
+ }),
326
+ );
278
327
 
279
- for (const [address, blockNumber] of childAddresses) {
280
- values.push({
281
- // @ts-expect-error
282
- factoryId: sql`(SELECT id FROM factory_insert)`,
283
- chainId: BigInt(chainId),
284
- blockNumber: BigInt(blockNumber),
285
- address,
286
- });
287
- }
328
+ return database.qb.sync
329
+ .with(factoryInsert)
330
+ .select({
331
+ address: ponderSyncSchema.factoryAddresses.address,
332
+ blockNumber: ponderSyncSchema.factoryAddresses.blockNumber,
333
+ })
334
+ .from(ponderSyncSchema.factoryAddresses)
335
+ .where(
336
+ eq(
337
+ ponderSyncSchema.factoryAddresses.factoryId,
338
+ database.qb.sync
339
+ .select({ id: factoryInsert.id })
340
+ .from(factoryInsert),
341
+ ),
342
+ )
343
+ .then((rows) => {
344
+ const result = new Map<Address, number>();
345
+ for (const { address, blockNumber } of rows) {
346
+ if (
347
+ result.has(address) === false ||
348
+ result.get(address)! > Number(blockNumber)
349
+ ) {
350
+ result.set(address, Number(blockNumber));
351
+ }
352
+ }
353
+ return result;
354
+ });
355
+ },
356
+ ),
288
357
 
289
- for (let i = 0; i < values.length; i += batchSize) {
290
- await database
291
- .syncQB("insert_child_addresses")
292
- .with(factoryInsert)
293
- .insert(PONDER_SYNC.factoryAddresses)
294
- .values(values.slice(i, i + batchSize));
295
- }
296
- },
297
358
  getSafeCrashRecoveryBlock: async ({ chainId, timestamp }) => {
298
- const rows = await database
299
- .syncQB()
300
- .select({
301
- number: PONDER_SYNC.blocks.number,
302
- timestamp: PONDER_SYNC.blocks.timestamp,
303
- })
304
- .from(PONDER_SYNC.blocks)
305
- .where(
306
- and(
307
- eq(PONDER_SYNC.blocks.chainId, BigInt(chainId)),
308
- lt(PONDER_SYNC.blocks.timestamp, BigInt(timestamp)),
309
- ),
310
- )
311
- .orderBy(desc(PONDER_SYNC.blocks.number))
312
- .limit(1);
313
-
314
- return rows[0];
315
- },
316
- getChildAddresses: ({ factory }) => {
317
- const factoryInsert = database
318
- .syncQB()
319
- .$with("factory_insert")
320
- .as(
321
- database
322
- .syncQB()
323
- .insert(PONDER_SYNC.factories)
324
- .values({ factory })
325
- // @ts-expect-error bug with drizzle-orm
326
- .returning({ id: PONDER_SYNC.factories.id })
327
- .onConflictDoUpdate({
328
- target: PONDER_SYNC.factories.factory,
329
- set: { factory: sql`excluded.factory` },
330
- }),
331
- );
359
+ return database.wrap({ method: "getSafeCrashRecoveryBlock" }, async () => {
360
+ const rows = await database.qb.sync
361
+ .select({
362
+ number: ponderSyncSchema.blocks.number,
363
+ timestamp: ponderSyncSchema.blocks.timestamp,
364
+ })
365
+ .from(ponderSyncSchema.blocks)
366
+ .where(
367
+ and(
368
+ eq(ponderSyncSchema.blocks.chainId, BigInt(chainId)),
369
+ lt(ponderSyncSchema.blocks.timestamp, BigInt(timestamp)),
370
+ ),
371
+ )
372
+ .orderBy(desc(ponderSyncSchema.blocks.number))
373
+ .limit(1);
332
374
 
333
- return database
334
- .syncQB("select_child_addresses")
335
- .with(factoryInsert)
336
- .select({
337
- address: PONDER_SYNC.factoryAddresses.address,
338
- blockNumber: PONDER_SYNC.factoryAddresses.blockNumber,
339
- })
340
- .from(PONDER_SYNC.factoryAddresses)
341
- .where(
342
- eq(
343
- PONDER_SYNC.factoryAddresses.factoryId,
344
- database
345
- .syncQB()
346
- .select({ id: factoryInsert.id })
347
- .from(factoryInsert),
348
- ),
349
- )
350
- .then((rows) => {
351
- const result = new Map<Address, number>();
352
- for (const { address, blockNumber } of rows) {
353
- if (
354
- result.has(address) === false ||
355
- result.get(address)! > Number(blockNumber)
356
- ) {
357
- result.set(address, Number(blockNumber));
358
- }
359
- }
360
- return result;
361
- });
375
+ return rows[0];
376
+ });
362
377
  },
363
378
  insertLogs: async ({ logs, chainId }) => {
364
379
  if (logs.length === 0) return;
380
+ await database.wrap(
381
+ { method: "insertLogs", includeTraceLogs: true },
382
+ async () => {
383
+ // Calculate `batchSize` based on how many parameters the
384
+ // input will have
385
+ const batchSize = Math.floor(
386
+ common.options.databaseMaxQueryParameters /
387
+ Object.keys(encodeLog({ log: logs[0]!, chainId })).length,
388
+ );
365
389
 
366
- // Calculate `batchSize` based on how many parameters the
367
- // input will have
368
- const batchSize = Math.floor(
369
- common.options.databaseMaxQueryParameters /
370
- Object.keys(encodeLog({ log: logs[0]!, chainId })).length,
390
+ // As an optimization, logs that are matched by a factory do
391
+ // not contain a checkpoint, because not corresponding block is
392
+ // fetched (no block.timestamp). However, when a log is matched by
393
+ // both a log filter and a factory, the checkpoint must be included
394
+ // in the db.
395
+
396
+ for (let i = 0; i < logs.length; i += batchSize) {
397
+ await database.qb.sync
398
+ .insert(ponderSyncSchema.logs)
399
+ .values(
400
+ logs
401
+ .slice(i, i + batchSize)
402
+ .map((log) => encodeLog({ log, chainId })),
403
+ )
404
+ .onConflictDoNothing({
405
+ target: [
406
+ ponderSyncSchema.logs.chainId,
407
+ ponderSyncSchema.logs.blockNumber,
408
+ ponderSyncSchema.logs.logIndex,
409
+ ],
410
+ });
411
+ }
412
+ },
371
413
  );
372
-
373
- for (let i = 0; i < logs.length; i += batchSize) {
374
- await database
375
- .syncQB("insert_logs")
376
- .insert(PONDER_SYNC.logs)
377
- .values(
378
- logs
379
- .slice(i, i + batchSize)
380
- .map((log) => encodeLog({ log, chainId })),
381
- )
382
- .onConflictDoNothing({
383
- target: [
384
- PONDER_SYNC.logs.chainId,
385
- PONDER_SYNC.logs.blockNumber,
386
- PONDER_SYNC.logs.logIndex,
387
- ],
388
- });
389
- }
390
414
  },
391
415
  insertBlocks: async ({ blocks, chainId }) => {
392
416
  if (blocks.length === 0) return;
417
+ await database.wrap(
418
+ { method: "insertBlocks", includeTraceLogs: true },
419
+ async () => {
420
+ // Calculate `batchSize` based on how many parameters the
421
+ // input will have
422
+ const batchSize = Math.floor(
423
+ common.options.databaseMaxQueryParameters /
424
+ Object.keys(encodeBlock({ block: blocks[0]!, chainId })).length,
425
+ );
393
426
 
394
- // Calculate `batchSize` based on how many parameters the
395
- // input will have
396
- const batchSize = Math.floor(
397
- common.options.databaseMaxQueryParameters /
398
- Object.keys(encodeBlock({ block: blocks[0]!, chainId })).length,
427
+ for (let i = 0; i < blocks.length; i += batchSize) {
428
+ await database.qb.sync
429
+ .insert(ponderSyncSchema.blocks)
430
+ .values(
431
+ blocks
432
+ .slice(i, i + batchSize)
433
+ .map((block) => encodeBlock({ block, chainId })),
434
+ )
435
+ .onConflictDoNothing({
436
+ target: [
437
+ ponderSyncSchema.blocks.chainId,
438
+ ponderSyncSchema.blocks.number,
439
+ ],
440
+ });
441
+ }
442
+ },
399
443
  );
400
-
401
- for (let i = 0; i < blocks.length; i += batchSize) {
402
- await database
403
- .syncQB("insert_blocks")
404
- .insert(PONDER_SYNC.blocks)
405
- .values(
406
- blocks
407
- .slice(i, i + batchSize)
408
- .map((block) => encodeBlock({ block, chainId })),
409
- )
410
- .onConflictDoNothing({
411
- target: [PONDER_SYNC.blocks.chainId, PONDER_SYNC.blocks.number],
412
- });
413
- }
414
444
  },
415
445
  insertTransactions: async ({ transactions, chainId }) => {
416
446
  if (transactions.length === 0) return;
447
+ await database.wrap(
448
+ { method: "insertTransactions", includeTraceLogs: true },
449
+ async () => {
450
+ // Calculate `batchSize` based on how many parameters the
451
+ // input will have
452
+ const batchSize = Math.floor(
453
+ common.options.databaseMaxQueryParameters /
454
+ Object.keys(
455
+ encodeTransaction({
456
+ transaction: transactions[0]!,
457
+ chainId,
458
+ }),
459
+ ).length,
460
+ );
417
461
 
418
- // Calculate `batchSize` based on how many parameters the
419
- // input will have
420
- const batchSize = Math.floor(
421
- common.options.databaseMaxQueryParameters /
422
- Object.keys(
423
- encodeTransaction({
424
- transaction: transactions[0]!,
425
- chainId,
426
- }),
427
- ).length,
462
+ // As an optimization for the migration, transactions inserted before 0.8 do not
463
+ // contain a checkpoint. However, for correctness the checkpoint must be inserted
464
+ // for new transactions (using onConflictDoUpdate).
465
+
466
+ for (let i = 0; i < transactions.length; i += batchSize) {
467
+ await database.qb.sync
468
+ .insert(ponderSyncSchema.transactions)
469
+ .values(
470
+ transactions
471
+ .slice(i, i + batchSize)
472
+ .map((transaction) =>
473
+ encodeTransaction({ transaction, chainId }),
474
+ ),
475
+ )
476
+ .onConflictDoNothing({
477
+ target: [
478
+ ponderSyncSchema.transactions.chainId,
479
+ ponderSyncSchema.transactions.blockNumber,
480
+ ponderSyncSchema.transactions.transactionIndex,
481
+ ],
482
+ });
483
+ }
484
+ },
428
485
  );
429
-
430
- // As an optimization for the migration, transactions inserted before 0.8 do not
431
- // contain a checkpoint. However, for correctness the checkpoint must be inserted
432
- // for new transactions (using onConflictDoUpdate).
433
-
434
- for (let i = 0; i < transactions.length; i += batchSize) {
435
- await database
436
- .syncQB("insert_transactions")
437
- .insert(PONDER_SYNC.transactions)
438
- .values(
439
- transactions
440
- .slice(i, i + batchSize)
441
- .map((transaction) => encodeTransaction({ transaction, chainId })),
442
- )
443
- .onConflictDoNothing({
444
- target: [
445
- PONDER_SYNC.transactions.chainId,
446
- PONDER_SYNC.transactions.blockNumber,
447
- PONDER_SYNC.transactions.transactionIndex,
448
- ],
449
- });
450
- }
451
486
  },
452
487
  insertTransactionReceipts: async ({ transactionReceipts, chainId }) => {
453
488
  if (transactionReceipts.length === 0) return;
454
-
455
- // Calculate `batchSize` based on how many parameters the
456
- // input will have
457
- const batchSize = Math.floor(
458
- common.options.databaseMaxQueryParameters /
459
- Object.keys(
460
- encodeTransactionReceipt({
461
- transactionReceipt: transactionReceipts[0]!,
462
- chainId,
463
- }),
464
- ).length,
465
- );
466
-
467
- for (let i = 0; i < transactionReceipts.length; i += batchSize) {
468
- await database
469
- .syncQB("insert_transaction_receipts")
470
- .insert(PONDER_SYNC.transactionReceipts)
471
- .values(
472
- transactionReceipts
473
- .slice(i, i + batchSize)
474
- .map((transactionReceipt) =>
489
+ await database.wrap(
490
+ { method: "insertTransactionReceipts", includeTraceLogs: true },
491
+ async () => {
492
+ // Calculate `batchSize` based on how many parameters the
493
+ // input will have
494
+ const batchSize = Math.floor(
495
+ common.options.databaseMaxQueryParameters /
496
+ Object.keys(
475
497
  encodeTransactionReceipt({
476
- transactionReceipt,
498
+ transactionReceipt: transactionReceipts[0]!,
477
499
  chainId,
478
500
  }),
479
- ),
480
- )
481
- .onConflictDoNothing({
482
- target: [
483
- PONDER_SYNC.transactionReceipts.chainId,
484
- PONDER_SYNC.transactionReceipts.blockNumber,
485
- PONDER_SYNC.transactionReceipts.transactionIndex,
486
- ],
487
- });
488
- }
501
+ ).length,
502
+ );
503
+
504
+ for (let i = 0; i < transactionReceipts.length; i += batchSize) {
505
+ await database.qb.sync
506
+ .insert(ponderSyncSchema.transactionReceipts)
507
+ .values(
508
+ transactionReceipts
509
+ .slice(i, i + batchSize)
510
+ .map((transactionReceipt) =>
511
+ encodeTransactionReceipt({
512
+ transactionReceipt,
513
+ chainId,
514
+ }),
515
+ ),
516
+ )
517
+ .onConflictDoNothing({
518
+ target: [
519
+ ponderSyncSchema.transactionReceipts.chainId,
520
+ ponderSyncSchema.transactionReceipts.blockNumber,
521
+ ponderSyncSchema.transactionReceipts.transactionIndex,
522
+ ],
523
+ });
524
+ }
525
+ },
526
+ );
489
527
  },
490
528
  insertTraces: async ({ traces, chainId }) => {
491
529
  if (traces.length === 0) return;
530
+ await database.wrap(
531
+ { method: "insertTraces", includeTraceLogs: true },
532
+ async () => {
533
+ // Calculate `batchSize` based on how many parameters the
534
+ // input will have
535
+ const batchSize = Math.floor(
536
+ common.options.databaseMaxQueryParameters /
537
+ Object.keys(
538
+ encodeTrace({
539
+ trace: traces[0]!.trace,
540
+ block: traces[0]!.block,
541
+ transaction: traces[0]!.transaction,
542
+ chainId,
543
+ }),
544
+ ).length,
545
+ );
492
546
 
493
- // Calculate `batchSize` based on how many parameters the
494
- // input will have
495
- const batchSize = Math.floor(
496
- common.options.databaseMaxQueryParameters /
497
- Object.keys(
498
- encodeTrace({
499
- trace: traces[0]!.trace,
500
- block: traces[0]!.block,
501
- transaction: traces[0]!.transaction,
502
- chainId,
503
- }),
504
- ).length,
547
+ for (let i = 0; i < traces.length; i += batchSize) {
548
+ await database.qb.sync
549
+ .insert(ponderSyncSchema.traces)
550
+ .values(
551
+ traces
552
+ .slice(i, i + batchSize)
553
+ .map(({ trace, block, transaction }) =>
554
+ encodeTrace({ trace, block, transaction, chainId }),
555
+ ),
556
+ )
557
+ .onConflictDoNothing({
558
+ target: [
559
+ ponderSyncSchema.traces.chainId,
560
+ ponderSyncSchema.traces.blockNumber,
561
+ ponderSyncSchema.traces.transactionIndex,
562
+ ponderSyncSchema.traces.traceIndex,
563
+ ],
564
+ });
565
+ }
566
+ },
505
567
  );
506
-
507
- for (let i = 0; i < traces.length; i += batchSize) {
508
- await database
509
- .syncQB("insert_traces")
510
- .insert(PONDER_SYNC.traces)
511
- .values(
512
- traces
513
- .slice(i, i + batchSize)
514
- .map(({ trace, block, transaction }) =>
515
- encodeTrace({ trace, block, transaction, chainId }),
516
- ),
517
- )
518
- .onConflictDoNothing({
519
- target: [
520
- PONDER_SYNC.traces.chainId,
521
- PONDER_SYNC.traces.blockNumber,
522
- PONDER_SYNC.traces.transactionIndex,
523
- PONDER_SYNC.traces.traceIndex,
524
- ],
525
- });
526
- }
527
568
  },
528
- getEventBlockData: async ({
529
- filters,
530
- fromBlock,
531
- toBlock,
532
- chainId,
533
- limit,
534
- }) => {
535
- const logFilters = filters.filter((f): f is LogFilter => f.type === "log");
536
- const transactionFilters = filters.filter(
537
- (f): f is TransactionFilter => f.type === "transaction",
538
- );
539
- const traceFilters = filters.filter(
540
- (f): f is TraceFilter => f.type === "trace",
541
- );
542
- const transferFilters = filters.filter(
543
- (f): f is TransferFilter => f.type === "transfer",
544
- );
569
+ getEventBlockData: async ({ filters, fromBlock, toBlock, chainId, limit }) =>
570
+ database.wrap(
571
+ { method: "getEventBlockData", includeTraceLogs: true },
572
+ async () => {
573
+ const logFilters = filters.filter(
574
+ (f): f is LogFilter => f.type === "log",
575
+ );
576
+ const transactionFilters = filters.filter(
577
+ (f): f is TransactionFilter => f.type === "transaction",
578
+ );
579
+ const traceFilters = filters.filter(
580
+ (f): f is TraceFilter => f.type === "trace",
581
+ );
582
+ const transferFilters = filters.filter(
583
+ (f): f is TransferFilter => f.type === "transfer",
584
+ );
545
585
 
546
- const shouldQueryBlocks = true;
547
- const shouldQueryLogs = logFilters.length > 0;
548
- const shouldQueryTraces =
549
- traceFilters.length > 0 || transferFilters.length > 0;
550
- const shouldQueryTransactions =
551
- transactionFilters.length > 0 || shouldQueryLogs || shouldQueryTraces;
552
- const shouldQueryTransactionReceipts = filters.some(
553
- shouldGetTransactionReceipt,
554
- );
586
+ const shouldQueryBlocks = true;
587
+ const shouldQueryLogs = logFilters.length > 0;
588
+ const shouldQueryTraces =
589
+ traceFilters.length > 0 || transferFilters.length > 0;
590
+ const shouldQueryTransactions =
591
+ transactionFilters.length > 0 || shouldQueryLogs || shouldQueryTraces;
592
+ const shouldQueryTransactionReceipts = filters.some(
593
+ shouldGetTransactionReceipt,
594
+ );
555
595
 
556
- const blocksQuery = database
557
- .syncQB("select_blocks")
558
- .select({
559
- number: PONDER_SYNC.blocks.number,
560
- timestamp: PONDER_SYNC.blocks.timestamp,
561
- hash: PONDER_SYNC.blocks.hash,
562
- parentHash: PONDER_SYNC.blocks.parentHash,
563
- logsBloom: PONDER_SYNC.blocks.logsBloom,
564
- miner: PONDER_SYNC.blocks.miner,
565
- gasUsed: PONDER_SYNC.blocks.gasUsed,
566
- gasLimit: PONDER_SYNC.blocks.gasLimit,
567
- baseFeePerGas: PONDER_SYNC.blocks.baseFeePerGas,
568
- nonce: PONDER_SYNC.blocks.nonce,
569
- mixHash: PONDER_SYNC.blocks.mixHash,
570
- stateRoot: PONDER_SYNC.blocks.stateRoot,
571
- receiptsRoot: PONDER_SYNC.blocks.receiptsRoot,
572
- transactionsRoot: PONDER_SYNC.blocks.transactionsRoot,
573
- sha3Uncles: PONDER_SYNC.blocks.sha3Uncles,
574
- size: PONDER_SYNC.blocks.size,
575
- difficulty: PONDER_SYNC.blocks.difficulty,
576
- totalDifficulty: PONDER_SYNC.blocks.totalDifficulty,
577
- extraData: PONDER_SYNC.blocks.extraData,
578
- })
579
- .from(PONDER_SYNC.blocks)
580
- .where(
581
- and(
582
- eq(PONDER_SYNC.blocks.chainId, BigInt(chainId)),
583
- gte(PONDER_SYNC.blocks.number, BigInt(fromBlock)),
584
- lte(PONDER_SYNC.blocks.number, BigInt(toBlock)),
585
- ),
586
- )
587
- .orderBy(asc(PONDER_SYNC.blocks.number))
588
- .limit(limit);
589
-
590
- const transactionsQuery = database
591
- .syncQB("select_transactions")
592
- .select({
593
- blockNumber: PONDER_SYNC.transactions.blockNumber,
594
- transactionIndex: PONDER_SYNC.transactions.transactionIndex,
595
- hash: PONDER_SYNC.transactions.hash,
596
- from: PONDER_SYNC.transactions.from,
597
- to: PONDER_SYNC.transactions.to,
598
- input: PONDER_SYNC.transactions.input,
599
- value: PONDER_SYNC.transactions.value,
600
- nonce: PONDER_SYNC.transactions.nonce,
601
- r: PONDER_SYNC.transactions.r,
602
- s: PONDER_SYNC.transactions.s,
603
- v: PONDER_SYNC.transactions.v,
604
- type: PONDER_SYNC.transactions.type,
605
- gas: PONDER_SYNC.transactions.gas,
606
- gasPrice: PONDER_SYNC.transactions.gasPrice,
607
- maxFeePerGas: PONDER_SYNC.transactions.maxFeePerGas,
608
- maxPriorityFeePerGas: PONDER_SYNC.transactions.maxPriorityFeePerGas,
609
- accessList: PONDER_SYNC.transactions.accessList,
610
- })
611
- .from(PONDER_SYNC.transactions)
612
- .where(
613
- and(
614
- eq(PONDER_SYNC.transactions.chainId, BigInt(chainId)),
615
- gte(PONDER_SYNC.transactions.blockNumber, BigInt(fromBlock)),
616
- lte(PONDER_SYNC.transactions.blockNumber, BigInt(toBlock)),
617
- ),
618
- )
619
- .orderBy(
620
- asc(PONDER_SYNC.transactions.blockNumber),
621
- asc(PONDER_SYNC.transactions.transactionIndex),
622
- )
623
- .limit(limit);
624
-
625
- const transactionReceiptsQuery = database
626
- .syncQB("select_transaction_receipts")
627
- .select({
628
- blockNumber: PONDER_SYNC.transactionReceipts.blockNumber,
629
- transactionIndex: PONDER_SYNC.transactionReceipts.transactionIndex,
630
- from: PONDER_SYNC.transactionReceipts.from,
631
- to: PONDER_SYNC.transactionReceipts.to,
632
- contractAddress: PONDER_SYNC.transactionReceipts.contractAddress,
633
- logsBloom: PONDER_SYNC.transactionReceipts.logsBloom,
634
- gasUsed: PONDER_SYNC.transactionReceipts.gasUsed,
635
- cumulativeGasUsed: PONDER_SYNC.transactionReceipts.cumulativeGasUsed,
636
- effectiveGasPrice: PONDER_SYNC.transactionReceipts.effectiveGasPrice,
637
- status: PONDER_SYNC.transactionReceipts.status,
638
- type: PONDER_SYNC.transactionReceipts.type,
639
- })
640
- .from(PONDER_SYNC.transactionReceipts)
641
- .where(
642
- and(
643
- eq(PONDER_SYNC.transactionReceipts.chainId, BigInt(chainId)),
644
- gte(PONDER_SYNC.transactionReceipts.blockNumber, BigInt(fromBlock)),
645
- lte(PONDER_SYNC.transactionReceipts.blockNumber, BigInt(toBlock)),
646
- ),
647
- )
648
- .orderBy(
649
- asc(PONDER_SYNC.transactionReceipts.blockNumber),
650
- asc(PONDER_SYNC.transactionReceipts.transactionIndex),
651
- )
652
- .limit(limit);
653
-
654
- const logsQuery = database
655
- .syncQB("select_logs")
656
- .select({
657
- blockNumber: PONDER_SYNC.logs.blockNumber,
658
- logIndex: PONDER_SYNC.logs.logIndex,
659
- transactionIndex: PONDER_SYNC.logs.transactionIndex,
660
- address: PONDER_SYNC.logs.address,
661
- topic0: PONDER_SYNC.logs.topic0,
662
- topic1: PONDER_SYNC.logs.topic1,
663
- topic2: PONDER_SYNC.logs.topic2,
664
- topic3: PONDER_SYNC.logs.topic3,
665
- data: PONDER_SYNC.logs.data,
666
- })
667
- .from(PONDER_SYNC.logs)
668
- .where(
669
- and(
670
- eq(PONDER_SYNC.logs.chainId, BigInt(chainId)),
671
- gte(PONDER_SYNC.logs.blockNumber, BigInt(fromBlock)),
672
- lte(PONDER_SYNC.logs.blockNumber, BigInt(toBlock)),
673
- or(...logFilters.map((filter) => logFilter(filter))),
674
- ),
675
- )
676
- .orderBy(
677
- asc(PONDER_SYNC.logs.blockNumber),
678
- asc(PONDER_SYNC.logs.logIndex),
679
- )
680
- .limit(limit);
681
-
682
- const tracesQuery = database
683
- .syncQB("select_traces")
684
- .select({
685
- blockNumber: PONDER_SYNC.traces.blockNumber,
686
- transactionIndex: PONDER_SYNC.traces.transactionIndex,
687
- traceIndex: PONDER_SYNC.traces.traceIndex,
688
- from: PONDER_SYNC.traces.from,
689
- to: PONDER_SYNC.traces.to,
690
- input: PONDER_SYNC.traces.input,
691
- output: PONDER_SYNC.traces.output,
692
- value: PONDER_SYNC.traces.value,
693
- type: PONDER_SYNC.traces.type,
694
- gas: PONDER_SYNC.traces.gas,
695
- gasUsed: PONDER_SYNC.traces.gasUsed,
696
- error: PONDER_SYNC.traces.error,
697
- revertReason: PONDER_SYNC.traces.revertReason,
698
- subcalls: PONDER_SYNC.traces.subcalls,
699
- })
700
- .from(PONDER_SYNC.traces)
701
- .where(
702
- and(
703
- eq(PONDER_SYNC.traces.chainId, BigInt(chainId)),
704
- gte(PONDER_SYNC.traces.blockNumber, BigInt(fromBlock)),
705
- lte(PONDER_SYNC.traces.blockNumber, BigInt(toBlock)),
706
- or(
707
- ...traceFilters.map((filter) => traceFilter(filter)),
708
- ...transferFilters.map((filter) => transferFilter(filter)),
709
- ),
710
- ),
711
- )
712
- .orderBy(
713
- asc(PONDER_SYNC.traces.blockNumber),
714
- asc(PONDER_SYNC.traces.traceIndex),
715
- )
716
- .limit(limit);
717
-
718
- let endClock = startClock();
719
-
720
- const [
721
- blocksRows,
722
- transactionsRows,
723
- transactionReceiptsRows,
724
- logsRows,
725
- tracesRows,
726
- ] = await Promise.all([
727
- shouldQueryBlocks ? blocksQuery : [],
728
- shouldQueryTransactions ? transactionsQuery : [],
729
- shouldQueryTransactionReceipts ? transactionReceiptsQuery : [],
730
- shouldQueryLogs ? logsQuery : [],
731
- shouldQueryTraces ? tracesQuery : [],
732
- ]);
733
-
734
- const supremum = Math.min(
735
- blocksRows.length < limit
736
- ? Number.POSITIVE_INFINITY
737
- : Number(blocksRows[blocksRows.length - 1]!.number),
738
- transactionsRows.length < limit
739
- ? Number.POSITIVE_INFINITY
740
- : Number(transactionsRows[transactionsRows.length - 1]!.blockNumber),
741
- transactionReceiptsRows.length < limit
742
- ? Number.POSITIVE_INFINITY
743
- : Number(
744
- transactionReceiptsRows[transactionReceiptsRows.length - 1]!
745
- .blockNumber,
746
- ),
747
- logsRows.length < limit
748
- ? Number.POSITIVE_INFINITY
749
- : Number(logsRows[logsRows.length - 1]!.blockNumber),
750
- tracesRows.length < limit
751
- ? Number.POSITIVE_INFINITY
752
- : Number(tracesRows[tracesRows.length - 1]!.blockNumber),
753
- );
596
+ const blocksQuery = database.qb.sync
597
+ .select({
598
+ number: ponderSyncSchema.blocks.number,
599
+ timestamp: ponderSyncSchema.blocks.timestamp,
600
+ hash: ponderSyncSchema.blocks.hash,
601
+ parentHash: ponderSyncSchema.blocks.parentHash,
602
+ logsBloom: ponderSyncSchema.blocks.logsBloom,
603
+ miner: ponderSyncSchema.blocks.miner,
604
+ gasUsed: ponderSyncSchema.blocks.gasUsed,
605
+ gasLimit: ponderSyncSchema.blocks.gasLimit,
606
+ baseFeePerGas: ponderSyncSchema.blocks.baseFeePerGas,
607
+ nonce: ponderSyncSchema.blocks.nonce,
608
+ mixHash: ponderSyncSchema.blocks.mixHash,
609
+ stateRoot: ponderSyncSchema.blocks.stateRoot,
610
+ receiptsRoot: ponderSyncSchema.blocks.receiptsRoot,
611
+ transactionsRoot: ponderSyncSchema.blocks.transactionsRoot,
612
+ sha3Uncles: ponderSyncSchema.blocks.sha3Uncles,
613
+ size: ponderSyncSchema.blocks.size,
614
+ difficulty: ponderSyncSchema.blocks.difficulty,
615
+ totalDifficulty: ponderSyncSchema.blocks.totalDifficulty,
616
+ extraData: ponderSyncSchema.blocks.extraData,
617
+ })
618
+ .from(ponderSyncSchema.blocks)
619
+ .where(
620
+ and(
621
+ eq(ponderSyncSchema.blocks.chainId, BigInt(chainId)),
622
+ gte(ponderSyncSchema.blocks.number, BigInt(fromBlock)),
623
+ lte(ponderSyncSchema.blocks.number, BigInt(toBlock)),
624
+ ),
625
+ )
626
+ .orderBy(asc(ponderSyncSchema.blocks.number))
627
+ .limit(limit);
754
628
 
755
- endClock = startClock();
629
+ const transactionsQuery = database.qb.sync
630
+ .select({
631
+ blockNumber: ponderSyncSchema.transactions.blockNumber,
632
+ transactionIndex: ponderSyncSchema.transactions.transactionIndex,
633
+ hash: ponderSyncSchema.transactions.hash,
634
+ from: ponderSyncSchema.transactions.from,
635
+ to: ponderSyncSchema.transactions.to,
636
+ input: ponderSyncSchema.transactions.input,
637
+ value: ponderSyncSchema.transactions.value,
638
+ nonce: ponderSyncSchema.transactions.nonce,
639
+ r: ponderSyncSchema.transactions.r,
640
+ s: ponderSyncSchema.transactions.s,
641
+ v: ponderSyncSchema.transactions.v,
642
+ type: ponderSyncSchema.transactions.type,
643
+ gas: ponderSyncSchema.transactions.gas,
644
+ gasPrice: ponderSyncSchema.transactions.gasPrice,
645
+ maxFeePerGas: ponderSyncSchema.transactions.maxFeePerGas,
646
+ maxPriorityFeePerGas:
647
+ ponderSyncSchema.transactions.maxPriorityFeePerGas,
648
+ accessList: ponderSyncSchema.transactions.accessList,
649
+ })
650
+ .from(ponderSyncSchema.transactions)
651
+ .where(
652
+ and(
653
+ eq(ponderSyncSchema.transactions.chainId, BigInt(chainId)),
654
+ gte(ponderSyncSchema.transactions.blockNumber, BigInt(fromBlock)),
655
+ lte(ponderSyncSchema.transactions.blockNumber, BigInt(toBlock)),
656
+ ),
657
+ )
658
+ .orderBy(
659
+ asc(ponderSyncSchema.transactions.blockNumber),
660
+ asc(ponderSyncSchema.transactions.transactionIndex),
661
+ )
662
+ .limit(limit);
663
+
664
+ const transactionReceiptsQuery = database.qb.sync
665
+ .select({
666
+ blockNumber: ponderSyncSchema.transactionReceipts.blockNumber,
667
+ transactionIndex:
668
+ ponderSyncSchema.transactionReceipts.transactionIndex,
669
+ from: ponderSyncSchema.transactionReceipts.from,
670
+ to: ponderSyncSchema.transactionReceipts.to,
671
+ contractAddress:
672
+ ponderSyncSchema.transactionReceipts.contractAddress,
673
+ logsBloom: ponderSyncSchema.transactionReceipts.logsBloom,
674
+ gasUsed: ponderSyncSchema.transactionReceipts.gasUsed,
675
+ cumulativeGasUsed:
676
+ ponderSyncSchema.transactionReceipts.cumulativeGasUsed,
677
+ effectiveGasPrice:
678
+ ponderSyncSchema.transactionReceipts.effectiveGasPrice,
679
+ status: ponderSyncSchema.transactionReceipts.status,
680
+ type: ponderSyncSchema.transactionReceipts.type,
681
+ })
682
+ .from(ponderSyncSchema.transactionReceipts)
683
+ .where(
684
+ and(
685
+ eq(ponderSyncSchema.transactionReceipts.chainId, BigInt(chainId)),
686
+ gte(
687
+ ponderSyncSchema.transactionReceipts.blockNumber,
688
+ BigInt(fromBlock),
689
+ ),
690
+ lte(
691
+ ponderSyncSchema.transactionReceipts.blockNumber,
692
+ BigInt(toBlock),
693
+ ),
694
+ ),
695
+ )
696
+ .orderBy(
697
+ asc(ponderSyncSchema.transactionReceipts.blockNumber),
698
+ asc(ponderSyncSchema.transactionReceipts.transactionIndex),
699
+ )
700
+ .limit(limit);
701
+
702
+ const logsQuery = database.qb.sync
703
+ .select({
704
+ blockNumber: ponderSyncSchema.logs.blockNumber,
705
+ logIndex: ponderSyncSchema.logs.logIndex,
706
+ transactionIndex: ponderSyncSchema.logs.transactionIndex,
707
+ address: ponderSyncSchema.logs.address,
708
+ topic0: ponderSyncSchema.logs.topic0,
709
+ topic1: ponderSyncSchema.logs.topic1,
710
+ topic2: ponderSyncSchema.logs.topic2,
711
+ topic3: ponderSyncSchema.logs.topic3,
712
+ data: ponderSyncSchema.logs.data,
713
+ })
714
+ .from(ponderSyncSchema.logs)
715
+ .where(
716
+ and(
717
+ eq(ponderSyncSchema.logs.chainId, BigInt(chainId)),
718
+ gte(ponderSyncSchema.logs.blockNumber, BigInt(fromBlock)),
719
+ lte(ponderSyncSchema.logs.blockNumber, BigInt(toBlock)),
720
+ or(...logFilters.map((filter) => logFilter(filter))),
721
+ ),
722
+ )
723
+ .orderBy(
724
+ asc(ponderSyncSchema.logs.blockNumber),
725
+ asc(ponderSyncSchema.logs.logIndex),
726
+ )
727
+ .limit(limit);
728
+
729
+ const tracesQuery = database.qb.sync
730
+ .select({
731
+ blockNumber: ponderSyncSchema.traces.blockNumber,
732
+ transactionIndex: ponderSyncSchema.traces.transactionIndex,
733
+ traceIndex: ponderSyncSchema.traces.traceIndex,
734
+ from: ponderSyncSchema.traces.from,
735
+ to: ponderSyncSchema.traces.to,
736
+ input: ponderSyncSchema.traces.input,
737
+ output: ponderSyncSchema.traces.output,
738
+ value: ponderSyncSchema.traces.value,
739
+ type: ponderSyncSchema.traces.type,
740
+ gas: ponderSyncSchema.traces.gas,
741
+ gasUsed: ponderSyncSchema.traces.gasUsed,
742
+ error: ponderSyncSchema.traces.error,
743
+ revertReason: ponderSyncSchema.traces.revertReason,
744
+ subcalls: ponderSyncSchema.traces.subcalls,
745
+ })
746
+ .from(ponderSyncSchema.traces)
747
+ .where(
748
+ and(
749
+ eq(ponderSyncSchema.traces.chainId, BigInt(chainId)),
750
+ gte(ponderSyncSchema.traces.blockNumber, BigInt(fromBlock)),
751
+ lte(ponderSyncSchema.traces.blockNumber, BigInt(toBlock)),
752
+ or(
753
+ ...traceFilters.map((filter) => traceFilter(filter)),
754
+ ...transferFilters.map((filter) => transferFilter(filter)),
755
+ ),
756
+ ),
757
+ )
758
+ .orderBy(
759
+ asc(ponderSyncSchema.traces.blockNumber),
760
+ asc(ponderSyncSchema.traces.traceIndex),
761
+ )
762
+ .limit(limit);
763
+
764
+ let endClock = startClock();
765
+
766
+ const [
767
+ blocksRows,
768
+ transactionsRows,
769
+ transactionReceiptsRows,
770
+ logsRows,
771
+ tracesRows,
772
+ ] = await Promise.all([
773
+ shouldQueryBlocks
774
+ ? blocksQuery.then((res) => {
775
+ common.metrics.ponder_database_method_duration.observe(
776
+ { method: "getEventBlockData_blocks" },
777
+ endClock(),
778
+ );
779
+
780
+ return res;
781
+ })
782
+ : [],
783
+ shouldQueryTransactions
784
+ ? transactionsQuery.then((res) => {
785
+ common.metrics.ponder_database_method_duration.observe(
786
+ { method: "getEventBlockData_transactions" },
787
+ endClock(),
788
+ );
789
+
790
+ return res;
791
+ })
792
+ : [],
793
+ shouldQueryTransactionReceipts
794
+ ? transactionReceiptsQuery.then((res) => {
795
+ common.metrics.ponder_database_method_duration.observe(
796
+ { method: "getEventBlockData_transaction_receipts" },
797
+ endClock(),
798
+ );
799
+
800
+ return res;
801
+ })
802
+ : [],
803
+ shouldQueryLogs
804
+ ? logsQuery.then((res) => {
805
+ common.metrics.ponder_database_method_duration.observe(
806
+ { method: "getEventBlockData_logs" },
807
+ endClock(),
808
+ );
809
+
810
+ return res;
811
+ })
812
+ : [],
813
+ shouldQueryTraces
814
+ ? tracesQuery.then((res) => {
815
+ common.metrics.ponder_database_method_duration.observe(
816
+ { method: "getEventBlockData_traces" },
817
+ endClock(),
818
+ );
819
+
820
+ return res;
821
+ })
822
+ : [],
823
+ ]);
824
+
825
+ const supremum = Math.min(
826
+ blocksRows.length < limit
827
+ ? Number.POSITIVE_INFINITY
828
+ : Number(blocksRows[blocksRows.length - 1]!.number),
829
+ transactionsRows.length < limit
830
+ ? Number.POSITIVE_INFINITY
831
+ : Number(
832
+ transactionsRows[transactionsRows.length - 1]!.blockNumber,
833
+ ),
834
+ transactionReceiptsRows.length < limit
835
+ ? Number.POSITIVE_INFINITY
836
+ : Number(
837
+ transactionReceiptsRows[transactionReceiptsRows.length - 1]!
838
+ .blockNumber,
839
+ ),
840
+ logsRows.length < limit
841
+ ? Number.POSITIVE_INFINITY
842
+ : Number(logsRows[logsRows.length - 1]!.blockNumber),
843
+ tracesRows.length < limit
844
+ ? Number.POSITIVE_INFINITY
845
+ : Number(tracesRows[tracesRows.length - 1]!.blockNumber),
846
+ );
756
847
 
757
- const blockData: {
758
- block: InternalBlock;
759
- logs: InternalLog[];
760
- transactions: InternalTransaction[];
761
- transactionReceipts: InternalTransactionReceipt[];
762
- traces: InternalTrace[];
763
- }[] = [];
764
- let transactionIndex = 0;
765
- let transactionReceiptIndex = 0;
766
- let traceIndex = 0;
767
- let logIndex = 0;
768
- for (const block of blocksRows) {
769
- if (Number(block.number) > supremum) {
770
- break;
771
- }
772
-
773
- const transactions: InternalTransaction[] = [];
774
- const transactionReceipts: InternalTransactionReceipt[] = [];
775
- const logs: InternalLog[] = [];
776
- const traces: InternalTrace[] = [];
777
-
778
- while (
779
- transactionIndex < transactionsRows.length &&
780
- transactionsRows[transactionIndex]!.blockNumber === block.number
781
- ) {
782
- const transaction = transactionsRows[transactionIndex]!;
783
- const internalTransaction =
784
- transaction as unknown as InternalTransaction;
785
-
786
- internalTransaction.blockNumber = Number(transaction.blockNumber);
787
- lazyChecksumAddress(internalTransaction, "from");
788
- if (transaction.to !== null) {
789
- lazyChecksumAddress(internalTransaction, "to");
790
- }
848
+ endClock = startClock();
849
+
850
+ const blockData: {
851
+ block: InternalBlock;
852
+ logs: InternalLog[];
853
+ transactions: InternalTransaction[];
854
+ transactionReceipts: InternalTransactionReceipt[];
855
+ traces: InternalTrace[];
856
+ }[] = [];
857
+ let transactionIndex = 0;
858
+ let transactionReceiptIndex = 0;
859
+ let traceIndex = 0;
860
+ let logIndex = 0;
861
+ for (const block of blocksRows) {
862
+ if (Number(block.number) > supremum) {
863
+ break;
864
+ }
791
865
 
792
- if (transaction.type === "0x0") {
793
- internalTransaction.type = "legacy";
794
- internalTransaction.accessList = undefined;
795
- internalTransaction.maxFeePerGas = undefined;
796
- internalTransaction.maxPriorityFeePerGas = undefined;
797
- } else if (transaction.type === "0x1") {
798
- internalTransaction.type = "eip2930";
799
- internalTransaction.accessList = JSON.parse(transaction.accessList!);
800
- internalTransaction.maxFeePerGas = undefined;
801
- internalTransaction.maxPriorityFeePerGas = undefined;
802
- } else if (transaction.type === "0x2") {
803
- internalTransaction.type = "eip1559";
804
- internalTransaction.gasPrice = undefined;
805
- internalTransaction.accessList = undefined;
806
- } else if (transaction.type === "0x7e") {
807
- internalTransaction.type = "deposit";
808
- internalTransaction.gasPrice = undefined;
809
- internalTransaction.accessList = undefined;
810
- }
866
+ const transactions: InternalTransaction[] = [];
867
+ const transactionReceipts: InternalTransactionReceipt[] = [];
868
+ const logs: InternalLog[] = [];
869
+ const traces: InternalTrace[] = [];
811
870
 
812
- transactions.push(internalTransaction);
813
- transactionIndex++;
814
- }
871
+ while (
872
+ transactionIndex < transactionsRows.length &&
873
+ transactionsRows[transactionIndex]!.blockNumber === block.number
874
+ ) {
875
+ const transaction = transactionsRows[transactionIndex]!;
876
+ const internalTransaction =
877
+ transaction as unknown as InternalTransaction;
878
+
879
+ internalTransaction.blockNumber = Number(transaction.blockNumber);
880
+ lazyChecksumAddress(internalTransaction, "from");
881
+ if (transaction.to !== null) {
882
+ lazyChecksumAddress(internalTransaction, "to");
883
+ }
884
+
885
+ if (transaction.type === "0x0") {
886
+ internalTransaction.type = "legacy";
887
+ internalTransaction.accessList = undefined;
888
+ internalTransaction.maxFeePerGas = undefined;
889
+ internalTransaction.maxPriorityFeePerGas = undefined;
890
+ } else if (transaction.type === "0x1") {
891
+ internalTransaction.type = "eip2930";
892
+ internalTransaction.accessList = JSON.parse(
893
+ transaction.accessList!,
894
+ );
895
+ internalTransaction.maxFeePerGas = undefined;
896
+ internalTransaction.maxPriorityFeePerGas = undefined;
897
+ } else if (transaction.type === "0x2") {
898
+ internalTransaction.type = "eip1559";
899
+ internalTransaction.gasPrice = undefined;
900
+ internalTransaction.accessList = undefined;
901
+ } else if (transaction.type === "0x7e") {
902
+ internalTransaction.type = "deposit";
903
+ internalTransaction.gasPrice = undefined;
904
+ internalTransaction.accessList = undefined;
905
+ }
906
+
907
+ transactions.push(internalTransaction);
908
+ transactionIndex++;
909
+ }
815
910
 
816
- while (
817
- transactionReceiptIndex < transactionReceiptsRows.length &&
818
- transactionReceiptsRows[transactionReceiptIndex]!.blockNumber ===
819
- block.number
820
- ) {
821
- const transactionReceipt =
822
- transactionReceiptsRows[transactionReceiptIndex]!;
911
+ while (
912
+ transactionReceiptIndex < transactionReceiptsRows.length &&
913
+ transactionReceiptsRows[transactionReceiptIndex]!.blockNumber ===
914
+ block.number
915
+ ) {
916
+ const transactionReceipt =
917
+ transactionReceiptsRows[transactionReceiptIndex]!;
918
+
919
+ const internalTransactionReceipt =
920
+ transactionReceipt as unknown as InternalTransactionReceipt;
921
+
922
+ internalTransactionReceipt.blockNumber = Number(
923
+ transactionReceipt.blockNumber,
924
+ );
925
+ if (transactionReceipt.contractAddress !== null) {
926
+ lazyChecksumAddress(
927
+ internalTransactionReceipt,
928
+ "contractAddress",
929
+ );
930
+ }
931
+ lazyChecksumAddress(internalTransactionReceipt, "from");
932
+ if (transactionReceipt.to !== null) {
933
+ lazyChecksumAddress(internalTransactionReceipt, "to");
934
+ }
935
+ internalTransactionReceipt.status =
936
+ transactionReceipt.status === "0x1"
937
+ ? "success"
938
+ : transactionReceipt.status === "0x0"
939
+ ? "reverted"
940
+ : (transactionReceipt.status as InternalTransactionReceipt["status"]);
941
+ internalTransactionReceipt.type =
942
+ transactionReceipt.type === "0x0"
943
+ ? "legacy"
944
+ : transactionReceipt.type === "0x1"
945
+ ? "eip2930"
946
+ : transactionReceipt.type === "0x2"
947
+ ? "eip1559"
948
+ : transactionReceipt.type === "0x7e"
949
+ ? "deposit"
950
+ : transactionReceipt.type;
951
+
952
+ transactionReceipts.push(internalTransactionReceipt);
953
+ transactionReceiptIndex++;
954
+ }
823
955
 
824
- const internalTransactionReceipt =
825
- transactionReceipt as unknown as InternalTransactionReceipt;
956
+ while (
957
+ logIndex < logsRows.length &&
958
+ logsRows[logIndex]!.blockNumber === block.number
959
+ ) {
960
+ const log = logsRows[logIndex]!;
961
+ const internalLog = log as unknown as InternalLog;
962
+
963
+ internalLog.blockNumber = Number(log.blockNumber);
964
+ lazyChecksumAddress(internalLog, "address");
965
+ internalLog.removed = false;
966
+ internalLog.topics = [
967
+ // @ts-ignore
968
+ log.topic0,
969
+ log.topic1,
970
+ log.topic2,
971
+ log.topic3,
972
+ ];
973
+ // @ts-ignore
974
+ log.topic0 = undefined;
975
+ // @ts-ignore
976
+ log.topic1 = undefined;
977
+ // @ts-ignore
978
+ log.topic2 = undefined;
979
+ // @ts-ignore
980
+ log.topic3 = undefined;
981
+
982
+ logs.push(internalLog);
983
+ logIndex++;
984
+ }
826
985
 
827
- internalTransactionReceipt.blockNumber = Number(
828
- transactionReceipt.blockNumber,
829
- );
830
- if (transactionReceipt.contractAddress !== null) {
831
- lazyChecksumAddress(internalTransactionReceipt, "contractAddress");
832
- }
833
- lazyChecksumAddress(internalTransactionReceipt, "from");
834
- if (transactionReceipt.to !== null) {
835
- lazyChecksumAddress(internalTransactionReceipt, "to");
836
- }
837
- internalTransactionReceipt.status =
838
- transactionReceipt.status === "0x1"
839
- ? "success"
840
- : transactionReceipt.status === "0x0"
841
- ? "reverted"
842
- : (transactionReceipt.status as InternalTransactionReceipt["status"]);
843
- internalTransactionReceipt.type =
844
- transactionReceipt.type === "0x0"
845
- ? "legacy"
846
- : transactionReceipt.type === "0x1"
847
- ? "eip2930"
848
- : transactionReceipt.type === "0x2"
849
- ? "eip1559"
850
- : transactionReceipt.type === "0x7e"
851
- ? "deposit"
852
- : transactionReceipt.type;
853
-
854
- transactionReceipts.push(internalTransactionReceipt);
855
- transactionReceiptIndex++;
856
- }
857
-
858
- while (
859
- logIndex < logsRows.length &&
860
- logsRows[logIndex]!.blockNumber === block.number
861
- ) {
862
- const log = logsRows[logIndex]!;
863
- const internalLog = log as unknown as InternalLog;
864
-
865
- internalLog.blockNumber = Number(log.blockNumber);
866
- lazyChecksumAddress(internalLog, "address");
867
- internalLog.removed = false;
868
- internalLog.topics = [
869
- // @ts-ignore
870
- log.topic0,
871
- log.topic1,
872
- log.topic2,
873
- log.topic3,
874
- ];
875
- // @ts-ignore
876
- log.topic0 = undefined;
877
- // @ts-ignore
878
- log.topic1 = undefined;
879
- // @ts-ignore
880
- log.topic2 = undefined;
881
- // @ts-ignore
882
- log.topic3 = undefined;
883
-
884
- logs.push(internalLog);
885
- logIndex++;
886
- }
887
-
888
- while (
889
- traceIndex < tracesRows.length &&
890
- tracesRows[traceIndex]!.blockNumber === block.number
891
- ) {
892
- const trace = tracesRows[traceIndex]!;
893
- const internalTrace = trace as unknown as InternalTrace;
894
-
895
- internalTrace.blockNumber = Number(trace.blockNumber);
896
-
897
- lazyChecksumAddress(internalTrace, "from");
898
- if (trace.to !== null) {
899
- lazyChecksumAddress(internalTrace, "to");
900
- }
986
+ while (
987
+ traceIndex < tracesRows.length &&
988
+ tracesRows[traceIndex]!.blockNumber === block.number
989
+ ) {
990
+ const trace = tracesRows[traceIndex]!;
991
+ const internalTrace = trace as unknown as InternalTrace;
901
992
 
902
- if (trace.output === null) {
903
- internalTrace.output = undefined;
904
- }
993
+ internalTrace.blockNumber = Number(trace.blockNumber);
905
994
 
906
- if (trace.error === null) {
907
- internalTrace.error = undefined;
908
- }
995
+ lazyChecksumAddress(internalTrace, "from");
996
+ if (trace.to !== null) {
997
+ lazyChecksumAddress(internalTrace, "to");
998
+ }
909
999
 
910
- if (trace.revertReason === null) {
911
- internalTrace.revertReason = undefined;
912
- }
1000
+ if (trace.output === null) {
1001
+ internalTrace.output = undefined;
1002
+ }
913
1003
 
914
- traces.push(internalTrace);
915
- traceIndex++;
916
- }
1004
+ if (trace.error === null) {
1005
+ internalTrace.error = undefined;
1006
+ }
917
1007
 
918
- lazyChecksumAddress(block, "miner");
1008
+ if (trace.revertReason === null) {
1009
+ internalTrace.revertReason = undefined;
1010
+ }
919
1011
 
920
- blockData.push({
921
- block,
922
- logs,
923
- transactions,
924
- traces,
925
- transactionReceipts,
926
- });
927
- }
1012
+ traces.push(internalTrace);
1013
+ traceIndex++;
1014
+ }
928
1015
 
929
- common.metrics.ponder_historical_extract_duration.inc(
930
- { step: "format" },
931
- endClock(),
932
- );
1016
+ lazyChecksumAddress(block, "miner");
933
1017
 
934
- await new Promise(setImmediate);
935
-
936
- let cursor: number;
937
- if (
938
- Math.max(
939
- blocksRows.length,
940
- transactionsRows.length,
941
- transactionReceiptsRows.length,
942
- logsRows.length,
943
- tracesRows.length,
944
- ) !== limit
945
- ) {
946
- cursor = toBlock;
947
- } else if (
948
- blocksRows.length === limit &&
949
- Math.max(
950
- transactionsRows.length,
951
- transactionReceiptsRows.length,
952
- logsRows.length,
953
- tracesRows.length,
954
- ) !== limit
955
- ) {
956
- // all events for `supremum` block have been extracted
957
- cursor = supremum;
958
- } else {
959
- // there may be events for `supremum` block that have not been extracted
960
- blockData.pop();
961
- cursor = supremum - 1;
962
- }
1018
+ blockData.push({
1019
+ block,
1020
+ logs,
1021
+ transactions,
1022
+ traces,
1023
+ transactionReceipts,
1024
+ });
1025
+ }
963
1026
 
964
- return { blockData, cursor };
965
- },
1027
+ common.metrics.ponder_historical_extract_duration.inc(
1028
+ { step: "format" },
1029
+ endClock(),
1030
+ );
966
1031
 
1032
+ await new Promise(setImmediate);
1033
+
1034
+ let cursor: number;
1035
+ if (
1036
+ Math.max(
1037
+ blocksRows.length,
1038
+ transactionsRows.length,
1039
+ transactionReceiptsRows.length,
1040
+ logsRows.length,
1041
+ tracesRows.length,
1042
+ ) !== limit
1043
+ ) {
1044
+ cursor = toBlock;
1045
+ } else if (
1046
+ blocksRows.length === limit &&
1047
+ Math.max(
1048
+ transactionsRows.length,
1049
+ transactionReceiptsRows.length,
1050
+ logsRows.length,
1051
+ tracesRows.length,
1052
+ ) !== limit
1053
+ ) {
1054
+ // all events for `supremum` block have been extracted
1055
+ cursor = supremum;
1056
+ } else {
1057
+ // there may be events for `supremum` block that have not been extracted
1058
+ blockData.pop();
1059
+ cursor = supremum - 1;
1060
+ }
1061
+
1062
+ return { blockData, cursor };
1063
+ },
1064
+ ),
967
1065
  insertRpcRequestResults: async ({ requests, chainId }) => {
968
1066
  if (requests.length === 0) return;
969
-
970
- const values = requests.map(({ request, blockNumber, result }) => ({
971
- requestHash: crypto
972
- .createHash("md5")
973
- .update(toLowerCase(JSON.stringify(orderObject(request))))
974
- .digest("hex"),
975
- chainId: BigInt(chainId),
976
- blockNumber: blockNumber ? BigInt(blockNumber) : undefined,
977
- result,
978
- }));
979
-
980
- await database
981
- .syncQB("insert_rpc_request_results")
982
- .insert(PONDER_SYNC.rpcRequestResults)
983
- .values(values)
984
- .onConflictDoUpdate({
985
- target: [
986
- PONDER_SYNC.rpcRequestResults.requestHash,
987
- PONDER_SYNC.rpcRequestResults.chainId,
988
- ],
989
- set: {
990
- result: sql`EXCLUDED.result`,
991
- },
992
- });
1067
+ return database.wrap(
1068
+ { method: "insertRpcRequestResults", includeTraceLogs: true },
1069
+ async () => {
1070
+ const values = requests.map(({ request, blockNumber, result }) => ({
1071
+ requestHash: crypto
1072
+ .createHash("md5")
1073
+ .update(toLowerCase(JSON.stringify(orderObject(request))))
1074
+ .digest("hex"),
1075
+ chainId: BigInt(chainId),
1076
+ blockNumber: blockNumber ? BigInt(blockNumber) : undefined,
1077
+ result,
1078
+ }));
1079
+
1080
+ await database.qb.sync
1081
+ .insert(ponderSyncSchema.rpcRequestResults)
1082
+ .values(values)
1083
+ .onConflictDoUpdate({
1084
+ target: [
1085
+ ponderSyncSchema.rpcRequestResults.requestHash,
1086
+ ponderSyncSchema.rpcRequestResults.chainId,
1087
+ ],
1088
+ set: {
1089
+ result: sql`EXCLUDED.result`,
1090
+ },
1091
+ });
1092
+ },
1093
+ );
993
1094
  },
994
1095
  getRpcRequestResults: async ({ requests, chainId }) => {
995
1096
  if (requests.length === 0) return [];
1097
+ return database.wrap(
1098
+ { method: "getRpcRequestResults", includeTraceLogs: true },
1099
+ async () => {
1100
+ const requestHashes = requests.map((request) =>
1101
+ crypto
1102
+ .createHash("md5")
1103
+ .update(toLowerCase(JSON.stringify(orderObject(request))))
1104
+ .digest("hex"),
1105
+ );
996
1106
 
997
- const requestHashes = requests.map((request) =>
998
- crypto
999
- .createHash("md5")
1000
- .update(toLowerCase(JSON.stringify(orderObject(request))))
1001
- .digest("hex"),
1002
- );
1003
-
1004
- const result = await database
1005
- .syncQB("select_rpc_request_results")
1006
- .select({
1007
- request_hash: PONDER_SYNC.rpcRequestResults.requestHash,
1008
- result: PONDER_SYNC.rpcRequestResults.result,
1009
- })
1010
- .from(PONDER_SYNC.rpcRequestResults)
1011
- .where(
1012
- and(
1013
- eq(PONDER_SYNC.rpcRequestResults.chainId, BigInt(chainId)),
1014
- inArray(PONDER_SYNC.rpcRequestResults.requestHash, requestHashes),
1015
- ),
1016
- )
1017
- .execute();
1107
+ const result = await database.qb.sync
1108
+ .select({
1109
+ request_hash: ponderSyncSchema.rpcRequestResults.requestHash,
1110
+ result: ponderSyncSchema.rpcRequestResults.result,
1111
+ })
1112
+ .from(ponderSyncSchema.rpcRequestResults)
1113
+ .where(
1114
+ and(
1115
+ eq(ponderSyncSchema.rpcRequestResults.chainId, BigInt(chainId)),
1116
+ inArray(
1117
+ ponderSyncSchema.rpcRequestResults.requestHash,
1118
+ requestHashes,
1119
+ ),
1120
+ ),
1121
+ )
1122
+ .execute();
1018
1123
 
1019
- const results = new Map<string, string | undefined>();
1020
- for (const row of result) {
1021
- results.set(row.request_hash, row.result);
1022
- }
1124
+ const results = new Map<string, string | undefined>();
1125
+ for (const row of result) {
1126
+ results.set(row.request_hash, row.result);
1127
+ }
1023
1128
 
1024
- return requestHashes.map((requestHash) => results.get(requestHash));
1129
+ return requestHashes.map((requestHash) => results.get(requestHash));
1130
+ },
1131
+ );
1025
1132
  },
1026
1133
  pruneRpcRequestResults: async ({ blocks, chainId }) => {
1027
1134
  if (blocks.length === 0) return;
1028
-
1029
- const numbers = blocks.map(({ number }) => BigInt(hexToNumber(number)));
1030
-
1031
- await database
1032
- .syncQB("delete_rpc_request_results")
1033
- .delete(PONDER_SYNC.rpcRequestResults)
1034
- .where(
1035
- and(
1036
- eq(PONDER_SYNC.rpcRequestResults.chainId, BigInt(chainId)),
1037
- inArray(PONDER_SYNC.rpcRequestResults.blockNumber, numbers),
1038
- ),
1039
- )
1040
- .execute();
1135
+ return database.wrap(
1136
+ { method: "pruneRpcRequestResults", includeTraceLogs: true },
1137
+ async () => {
1138
+ const numbers = blocks.map(({ number }) => BigInt(hexToNumber(number)));
1139
+
1140
+ await database.qb.sync
1141
+ .delete(ponderSyncSchema.rpcRequestResults)
1142
+ .where(
1143
+ and(
1144
+ eq(ponderSyncSchema.rpcRequestResults.chainId, BigInt(chainId)),
1145
+ inArray(ponderSyncSchema.rpcRequestResults.blockNumber, numbers),
1146
+ ),
1147
+ )
1148
+ .execute();
1149
+ },
1150
+ );
1041
1151
  },
1042
1152
  pruneByChain: async ({ chainId }) =>
1043
- database.syncQB().transaction(async (tx) => {
1044
- await tx("delete_logs")
1045
- .delete(PONDER_SYNC.logs)
1046
- .where(eq(PONDER_SYNC.logs.chainId, BigInt(chainId)))
1047
- .execute();
1048
- await tx("delete_blocks")
1049
- .delete(PONDER_SYNC.blocks)
1050
- .where(eq(PONDER_SYNC.blocks.chainId, BigInt(chainId)))
1051
- .execute();
1052
- await tx("delete_traces")
1053
- .delete(PONDER_SYNC.traces)
1054
- .where(eq(PONDER_SYNC.traces.chainId, BigInt(chainId)))
1055
- .execute();
1056
- await tx("delete_transactions")
1057
- .delete(PONDER_SYNC.transactions)
1058
- .where(eq(PONDER_SYNC.transactions.chainId, BigInt(chainId)))
1059
- .execute();
1060
- await tx("delete_transaction_receipts")
1061
- .delete(PONDER_SYNC.transactionReceipts)
1062
- .where(eq(PONDER_SYNC.transactionReceipts.chainId, BigInt(chainId)))
1063
- .execute();
1064
- await tx("delete_factory_addresses")
1065
- .delete(PONDER_SYNC.factoryAddresses)
1066
- .where(eq(PONDER_SYNC.factoryAddresses.chainId, BigInt(chainId)))
1067
- .execute();
1068
- }),
1153
+ database.wrap({ method: "pruneByChain", includeTraceLogs: true }, () =>
1154
+ database.qb.sync.transaction(async (tx) => {
1155
+ await tx
1156
+ .delete(ponderSyncSchema.logs)
1157
+ .where(eq(ponderSyncSchema.logs.chainId, BigInt(chainId)))
1158
+ .execute();
1159
+ await tx
1160
+ .delete(ponderSyncSchema.blocks)
1161
+ .where(eq(ponderSyncSchema.blocks.chainId, BigInt(chainId)))
1162
+ .execute();
1163
+
1164
+ await tx
1165
+ .delete(ponderSyncSchema.traces)
1166
+ .where(eq(ponderSyncSchema.traces.chainId, BigInt(chainId)))
1167
+ .execute();
1168
+ await tx
1169
+ .delete(ponderSyncSchema.transactions)
1170
+ .where(eq(ponderSyncSchema.transactions.chainId, BigInt(chainId)))
1171
+ .execute();
1172
+ await tx
1173
+ .delete(ponderSyncSchema.transactionReceipts)
1174
+ .where(
1175
+ eq(ponderSyncSchema.transactionReceipts.chainId, BigInt(chainId)),
1176
+ )
1177
+ .execute();
1178
+ await tx
1179
+ .delete(ponderSyncSchema.factoryAddresses)
1180
+ .where(eq(ponderSyncSchema.factoryAddresses.chainId, BigInt(chainId)))
1181
+ .execute();
1182
+ }),
1183
+ ),
1069
1184
  });
1070
1185
 
1071
1186
  const addressFilter = (
@@ -1093,21 +1208,23 @@ export const logFilter = (filter: LogFilter): SQL => {
1093
1208
  if (raw === null) continue;
1094
1209
  const topic = Array.isArray(raw) && raw.length === 1 ? raw[0]! : raw;
1095
1210
  if (Array.isArray(topic)) {
1096
- conditions.push(inArray(PONDER_SYNC.logs[`topic${idx}`], topic));
1211
+ conditions.push(inArray(ponderSyncSchema.logs[`topic${idx}`], topic));
1097
1212
  } else {
1098
- conditions.push(eq(PONDER_SYNC.logs[`topic${idx}`], topic));
1213
+ conditions.push(eq(ponderSyncSchema.logs[`topic${idx}`], topic));
1099
1214
  }
1100
1215
  }
1101
1216
 
1102
- conditions.push(addressFilter(filter.address, PONDER_SYNC.logs.address));
1217
+ conditions.push(addressFilter(filter.address, ponderSyncSchema.logs.address));
1103
1218
 
1104
1219
  if (filter.fromBlock !== undefined) {
1105
1220
  conditions.push(
1106
- gte(PONDER_SYNC.logs.blockNumber, BigInt(filter.fromBlock!)),
1221
+ gte(ponderSyncSchema.logs.blockNumber, BigInt(filter.fromBlock!)),
1107
1222
  );
1108
1223
  }
1109
1224
  if (filter.toBlock !== undefined) {
1110
- conditions.push(lte(PONDER_SYNC.logs.blockNumber, BigInt(filter.toBlock!)));
1225
+ conditions.push(
1226
+ lte(ponderSyncSchema.logs.blockNumber, BigInt(filter.toBlock!)),
1227
+ );
1111
1228
  }
1112
1229
 
1113
1230
  return and(...conditions)!;
@@ -1121,10 +1238,14 @@ export const blockFilter = (filter: BlockFilter): SQL => {
1121
1238
  );
1122
1239
 
1123
1240
  if (filter.fromBlock !== undefined) {
1124
- conditions.push(gte(PONDER_SYNC.blocks.number, BigInt(filter.fromBlock!)));
1241
+ conditions.push(
1242
+ gte(ponderSyncSchema.blocks.number, BigInt(filter.fromBlock!)),
1243
+ );
1125
1244
  }
1126
1245
  if (filter.toBlock !== undefined) {
1127
- conditions.push(lte(PONDER_SYNC.blocks.number, BigInt(filter.toBlock!)));
1246
+ conditions.push(
1247
+ lte(ponderSyncSchema.blocks.number, BigInt(filter.toBlock!)),
1248
+ );
1128
1249
  }
1129
1250
 
1130
1251
  return and(...conditions)!;
@@ -1134,18 +1255,20 @@ export const transactionFilter = (filter: TransactionFilter): SQL => {
1134
1255
  const conditions: SQL[] = [];
1135
1256
 
1136
1257
  conditions.push(
1137
- addressFilter(filter.fromAddress, PONDER_SYNC.transactions.from),
1258
+ addressFilter(filter.fromAddress, ponderSyncSchema.transactions.from),
1259
+ );
1260
+ conditions.push(
1261
+ addressFilter(filter.toAddress, ponderSyncSchema.transactions.to),
1138
1262
  );
1139
- conditions.push(addressFilter(filter.toAddress, PONDER_SYNC.transactions.to));
1140
1263
 
1141
1264
  if (filter.fromBlock !== undefined) {
1142
1265
  conditions.push(
1143
- gte(PONDER_SYNC.transactions.blockNumber, BigInt(filter.fromBlock!)),
1266
+ gte(ponderSyncSchema.transactions.blockNumber, BigInt(filter.fromBlock!)),
1144
1267
  );
1145
1268
  }
1146
1269
  if (filter.toBlock !== undefined) {
1147
1270
  conditions.push(
1148
- lte(PONDER_SYNC.transactions.blockNumber, BigInt(filter.toBlock!)),
1271
+ lte(ponderSyncSchema.transactions.blockNumber, BigInt(filter.toBlock!)),
1149
1272
  );
1150
1273
  }
1151
1274
 
@@ -1155,21 +1278,23 @@ export const transactionFilter = (filter: TransactionFilter): SQL => {
1155
1278
  export const transferFilter = (filter: TransferFilter): SQL => {
1156
1279
  const conditions: SQL[] = [];
1157
1280
 
1158
- conditions.push(addressFilter(filter.fromAddress, PONDER_SYNC.traces.from));
1159
- conditions.push(addressFilter(filter.toAddress, PONDER_SYNC.traces.to));
1281
+ conditions.push(
1282
+ addressFilter(filter.fromAddress, ponderSyncSchema.traces.from),
1283
+ );
1284
+ conditions.push(addressFilter(filter.toAddress, ponderSyncSchema.traces.to));
1160
1285
 
1161
1286
  if (filter.includeReverted === false) {
1162
- conditions.push(isNull(PONDER_SYNC.traces.error));
1287
+ conditions.push(isNull(ponderSyncSchema.traces.error));
1163
1288
  }
1164
1289
 
1165
1290
  if (filter.fromBlock !== undefined) {
1166
1291
  conditions.push(
1167
- gte(PONDER_SYNC.traces.blockNumber, BigInt(filter.fromBlock!)),
1292
+ gte(ponderSyncSchema.traces.blockNumber, BigInt(filter.fromBlock!)),
1168
1293
  );
1169
1294
  }
1170
1295
  if (filter.toBlock !== undefined) {
1171
1296
  conditions.push(
1172
- lte(PONDER_SYNC.traces.blockNumber, BigInt(filter.toBlock!)),
1297
+ lte(ponderSyncSchema.traces.blockNumber, BigInt(filter.toBlock!)),
1173
1298
  );
1174
1299
  }
1175
1300
 
@@ -1179,15 +1304,17 @@ export const transferFilter = (filter: TransferFilter): SQL => {
1179
1304
  export const traceFilter = (filter: TraceFilter): SQL => {
1180
1305
  const conditions: SQL[] = [];
1181
1306
 
1182
- conditions.push(addressFilter(filter.fromAddress, PONDER_SYNC.traces.from));
1183
- conditions.push(addressFilter(filter.toAddress, PONDER_SYNC.traces.to));
1307
+ conditions.push(
1308
+ addressFilter(filter.fromAddress, ponderSyncSchema.traces.from),
1309
+ );
1310
+ conditions.push(addressFilter(filter.toAddress, ponderSyncSchema.traces.to));
1184
1311
 
1185
1312
  if (filter.includeReverted === false) {
1186
- conditions.push(isNull(PONDER_SYNC.traces.error));
1313
+ conditions.push(isNull(ponderSyncSchema.traces.error));
1187
1314
  }
1188
1315
 
1189
1316
  if (filter.callType !== undefined) {
1190
- conditions.push(eq(PONDER_SYNC.traces.type, filter.callType));
1317
+ conditions.push(eq(ponderSyncSchema.traces.type, filter.callType));
1191
1318
  }
1192
1319
 
1193
1320
  if (filter.functionSelector !== undefined) {
@@ -1207,12 +1334,12 @@ export const traceFilter = (filter: TraceFilter): SQL => {
1207
1334
 
1208
1335
  if (filter.fromBlock !== undefined) {
1209
1336
  conditions.push(
1210
- gte(PONDER_SYNC.traces.blockNumber, BigInt(filter.fromBlock!)),
1337
+ gte(ponderSyncSchema.traces.blockNumber, BigInt(filter.fromBlock!)),
1211
1338
  );
1212
1339
  }
1213
1340
  if (filter.toBlock !== undefined) {
1214
1341
  conditions.push(
1215
- lte(PONDER_SYNC.traces.blockNumber, BigInt(filter.toBlock!)),
1342
+ lte(ponderSyncSchema.traces.blockNumber, BigInt(filter.toBlock!)),
1216
1343
  );
1217
1344
  }
1218
1345