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
@@ -9,66 +9,65 @@ import { and, asc, desc, eq, gte, inArray, isNull, lt, lte, or, sql, } from "dri
9
9
  import { unionAll } from "drizzle-orm/pg-core";
10
10
  import { hexToNumber } from "viem";
11
11
  import { encodeBlock, encodeLog, encodeTrace, encodeTransaction, encodeTransactionReceipt, } from "./encode.js";
12
- import * as PONDER_SYNC from "./schema.js";
12
+ import * as ponderSyncSchema from "./schema.js";
13
13
  export const createSyncStore = ({ common, database, }) => ({
14
14
  insertIntervals: async ({ intervals, chainId }) => {
15
15
  if (intervals.length === 0)
16
16
  return;
17
- const perFragmentIntervals = new Map();
18
- const values = [];
19
- // dedupe and merge matching fragments
20
- for (const { filter, interval } of intervals) {
21
- for (const fragment of getFragments(filter)) {
22
- const fragmentId = encodeFragment(fragment.fragment);
23
- if (perFragmentIntervals.has(fragmentId) === false) {
24
- perFragmentIntervals.set(fragmentId, []);
17
+ await database.wrap({ method: "insertIntervals", includeTraceLogs: true }, async () => {
18
+ const perFragmentIntervals = new Map();
19
+ const values = [];
20
+ // dedupe and merge matching fragments
21
+ for (const { filter, interval } of intervals) {
22
+ for (const fragment of getFragments(filter)) {
23
+ const fragmentId = encodeFragment(fragment.fragment);
24
+ if (perFragmentIntervals.has(fragmentId) === false) {
25
+ perFragmentIntervals.set(fragmentId, []);
26
+ }
27
+ perFragmentIntervals.get(fragmentId).push(interval);
25
28
  }
26
- perFragmentIntervals.get(fragmentId).push(interval);
27
29
  }
28
- }
29
- // NOTE: In order to force proper range union behavior, `interval[1]` must
30
- // be rounded up.
31
- for (const [fragmentId, intervals] of perFragmentIntervals) {
32
- const numranges = intervals
33
- .map((interval) => {
34
- const start = interval[0];
35
- const end = interval[1] + 1;
36
- return `numrange(${start}, ${end}, '[]')`;
37
- })
38
- .join(", ");
39
- values.push({
40
- fragmentId: fragmentId,
41
- chainId: BigInt(chainId),
42
- // @ts-expect-error
43
- blocks: sql.raw(`nummultirange(${numranges})`),
30
+ // NOTE: In order to force proper range union behavior, `interval[1]` must
31
+ // be rounded up.
32
+ for (const [fragmentId, intervals] of perFragmentIntervals) {
33
+ const numranges = intervals
34
+ .map((interval) => {
35
+ const start = interval[0];
36
+ const end = interval[1] + 1;
37
+ return `numrange(${start}, ${end}, '[]')`;
38
+ })
39
+ .join(", ");
40
+ values.push({
41
+ fragmentId: fragmentId,
42
+ chainId: BigInt(chainId),
43
+ // @ts-expect-error
44
+ blocks: sql.raw(`nummultirange(${numranges})`),
45
+ });
46
+ }
47
+ await database.qb.sync
48
+ .insert(ponderSyncSchema.intervals)
49
+ .values(values)
50
+ .onConflictDoUpdate({
51
+ target: ponderSyncSchema.intervals.fragmentId,
52
+ set: {
53
+ blocks: sql `intervals.blocks + excluded.blocks`,
54
+ },
44
55
  });
45
- }
46
- await database
47
- .syncQB("insert_intervals")
48
- .insert(PONDER_SYNC.intervals)
49
- .values(values)
50
- .onConflictDoUpdate({
51
- target: PONDER_SYNC.intervals.fragmentId,
52
- set: {
53
- blocks: sql `intervals.blocks + excluded.blocks`,
54
- },
55
56
  });
56
57
  },
57
- getIntervals: async ({ filters }) => {
58
+ getIntervals: async ({ filters }) => database.wrap({ method: "getIntervals", includeTraceLogs: true }, async () => {
58
59
  const queries = filters.flatMap((filter, i) => {
59
60
  const fragments = getFragments(filter);
60
- return fragments.map((fragment, j) => database
61
- .syncQB("select_intervals")
61
+ return fragments.map((fragment, j) => database.qb.sync
62
62
  .select({
63
63
  mergedBlocks: sql `range_agg(unnested.blocks)`.as("merged_blocks"),
64
64
  filter: sql.raw(`'${i}'`).as("filter"),
65
65
  fragment: sql.raw(`'${j}'`).as("fragment"),
66
66
  })
67
- .from(database
68
- .syncQB()
67
+ .from(database.qb.sync
69
68
  .select({ blocks: sql.raw("unnest(blocks)").as("blocks") })
70
- .from(PONDER_SYNC.intervals)
71
- .where(inArray(PONDER_SYNC.intervals.fragmentId, fragment.adjacentIds))
69
+ .from(ponderSyncSchema.intervals)
70
+ .where(inArray(ponderSyncSchema.intervals.fragmentId, fragment.adjacentIds))
72
71
  .as("unnested")));
73
72
  });
74
73
  let rows;
@@ -94,83 +93,63 @@ export const createSyncStore = ({ common, database, }) => ({
94
93
  .map((row) => (row.mergedBlocks
95
94
  ? JSON.parse(`[${row.mergedBlocks.slice(1, -1)}]`)
96
95
  : []).map((interval) => [interval[0], interval[1] - 1]))[0];
97
- result.get(filter).push({ fragment: fragment.fragment, intervals });
96
+ result
97
+ .get(filter)
98
+ .push({ fragment: fragment.fragment, intervals });
98
99
  }
99
100
  }
100
101
  return result;
101
- },
102
+ }),
102
103
  insertChildAddresses: async ({ factory, childAddresses, chainId }) => {
103
104
  if (childAddresses.size === 0)
104
105
  return;
105
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters / 3);
106
- const values = [];
107
- const factoryInsert = database
108
- .syncQB()
109
- .$with("factory_insert")
110
- .as(database
111
- .syncQB()
112
- .insert(PONDER_SYNC.factories)
113
- .values({ factory })
114
- // @ts-expect-error bug with drizzle-orm
115
- .returning({ id: PONDER_SYNC.factories.id })
116
- .onConflictDoUpdate({
117
- target: PONDER_SYNC.factories.factory,
118
- set: { factory: sql `excluded.factory` },
119
- }));
120
- for (const [address, blockNumber] of childAddresses) {
121
- values.push({
122
- // @ts-expect-error
123
- factoryId: sql `(SELECT id FROM factory_insert)`,
124
- chainId: BigInt(chainId),
125
- blockNumber: BigInt(blockNumber),
126
- address,
127
- });
128
- }
129
- for (let i = 0; i < values.length; i += batchSize) {
130
- await database
131
- .syncQB("insert_child_addresses")
132
- .with(factoryInsert)
133
- .insert(PONDER_SYNC.factoryAddresses)
134
- .values(values.slice(i, i + batchSize));
135
- }
136
- },
137
- getSafeCrashRecoveryBlock: async ({ chainId, timestamp }) => {
138
- const rows = await database
139
- .syncQB()
140
- .select({
141
- number: PONDER_SYNC.blocks.number,
142
- timestamp: PONDER_SYNC.blocks.timestamp,
143
- })
144
- .from(PONDER_SYNC.blocks)
145
- .where(and(eq(PONDER_SYNC.blocks.chainId, BigInt(chainId)), lt(PONDER_SYNC.blocks.timestamp, BigInt(timestamp))))
146
- .orderBy(desc(PONDER_SYNC.blocks.number))
147
- .limit(1);
148
- return rows[0];
106
+ await database.wrap({ method: "insertChildAddresses", includeTraceLogs: true }, async () => {
107
+ const batchSize = Math.floor(common.options.databaseMaxQueryParameters / 3);
108
+ const values = [];
109
+ const factoryInsert = database.qb.sync.$with("factory_insert").as(database.qb.sync
110
+ .insert(ponderSyncSchema.factories)
111
+ .values({ factory })
112
+ // @ts-expect-error bug with drizzle-orm
113
+ .returning({ id: ponderSyncSchema.factories.id })
114
+ .onConflictDoUpdate({
115
+ target: ponderSyncSchema.factories.factory,
116
+ set: { factory: sql `excluded.factory` },
117
+ }));
118
+ for (const [address, blockNumber] of childAddresses) {
119
+ values.push({
120
+ // @ts-expect-error
121
+ factoryId: sql `(SELECT id FROM factory_insert)`,
122
+ chainId: BigInt(chainId),
123
+ blockNumber: BigInt(blockNumber),
124
+ address,
125
+ });
126
+ }
127
+ for (let i = 0; i < values.length; i += batchSize) {
128
+ await database.qb.sync
129
+ .with(factoryInsert)
130
+ .insert(ponderSyncSchema.factoryAddresses)
131
+ .values(values.slice(i, i + batchSize));
132
+ }
133
+ });
149
134
  },
150
- getChildAddresses: ({ factory }) => {
151
- const factoryInsert = database
152
- .syncQB()
153
- .$with("factory_insert")
154
- .as(database
155
- .syncQB()
156
- .insert(PONDER_SYNC.factories)
135
+ getChildAddresses: ({ factory }) => database.wrap({ method: "getChildAddresses", includeTraceLogs: true }, () => {
136
+ const factoryInsert = database.qb.sync.$with("factory_insert").as(database.qb.sync
137
+ .insert(ponderSyncSchema.factories)
157
138
  .values({ factory })
158
139
  // @ts-expect-error bug with drizzle-orm
159
- .returning({ id: PONDER_SYNC.factories.id })
140
+ .returning({ id: ponderSyncSchema.factories.id })
160
141
  .onConflictDoUpdate({
161
- target: PONDER_SYNC.factories.factory,
142
+ target: ponderSyncSchema.factories.factory,
162
143
  set: { factory: sql `excluded.factory` },
163
144
  }));
164
- return database
165
- .syncQB("select_child_addresses")
145
+ return database.qb.sync
166
146
  .with(factoryInsert)
167
147
  .select({
168
- address: PONDER_SYNC.factoryAddresses.address,
169
- blockNumber: PONDER_SYNC.factoryAddresses.blockNumber,
148
+ address: ponderSyncSchema.factoryAddresses.address,
149
+ blockNumber: ponderSyncSchema.factoryAddresses.blockNumber,
170
150
  })
171
- .from(PONDER_SYNC.factoryAddresses)
172
- .where(eq(PONDER_SYNC.factoryAddresses.factoryId, database
173
- .syncQB()
151
+ .from(ponderSyncSchema.factoryAddresses)
152
+ .where(eq(ponderSyncSchema.factoryAddresses.factoryId, database.qb.sync
174
153
  .select({ id: factoryInsert.id })
175
154
  .from(factoryInsert)))
176
155
  .then((rows) => {
@@ -183,137 +162,164 @@ export const createSyncStore = ({ common, database, }) => ({
183
162
  }
184
163
  return result;
185
164
  });
165
+ }),
166
+ getSafeCrashRecoveryBlock: async ({ chainId, timestamp }) => {
167
+ return database.wrap({ method: "getSafeCrashRecoveryBlock" }, async () => {
168
+ const rows = await database.qb.sync
169
+ .select({
170
+ number: ponderSyncSchema.blocks.number,
171
+ timestamp: ponderSyncSchema.blocks.timestamp,
172
+ })
173
+ .from(ponderSyncSchema.blocks)
174
+ .where(and(eq(ponderSyncSchema.blocks.chainId, BigInt(chainId)), lt(ponderSyncSchema.blocks.timestamp, BigInt(timestamp))))
175
+ .orderBy(desc(ponderSyncSchema.blocks.number))
176
+ .limit(1);
177
+ return rows[0];
178
+ });
186
179
  },
187
180
  insertLogs: async ({ logs, chainId }) => {
188
181
  if (logs.length === 0)
189
182
  return;
190
- // Calculate `batchSize` based on how many parameters the
191
- // input will have
192
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
193
- Object.keys(encodeLog({ log: logs[0], chainId })).length);
194
- for (let i = 0; i < logs.length; i += batchSize) {
195
- await database
196
- .syncQB("insert_logs")
197
- .insert(PONDER_SYNC.logs)
198
- .values(logs
199
- .slice(i, i + batchSize)
200
- .map((log) => encodeLog({ log, chainId })))
201
- .onConflictDoNothing({
202
- target: [
203
- PONDER_SYNC.logs.chainId,
204
- PONDER_SYNC.logs.blockNumber,
205
- PONDER_SYNC.logs.logIndex,
206
- ],
207
- });
208
- }
183
+ await database.wrap({ method: "insertLogs", includeTraceLogs: true }, async () => {
184
+ // Calculate `batchSize` based on how many parameters the
185
+ // input will have
186
+ const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
187
+ Object.keys(encodeLog({ log: logs[0], chainId })).length);
188
+ // As an optimization, logs that are matched by a factory do
189
+ // not contain a checkpoint, because not corresponding block is
190
+ // fetched (no block.timestamp). However, when a log is matched by
191
+ // both a log filter and a factory, the checkpoint must be included
192
+ // in the db.
193
+ for (let i = 0; i < logs.length; i += batchSize) {
194
+ await database.qb.sync
195
+ .insert(ponderSyncSchema.logs)
196
+ .values(logs
197
+ .slice(i, i + batchSize)
198
+ .map((log) => encodeLog({ log, chainId })))
199
+ .onConflictDoNothing({
200
+ target: [
201
+ ponderSyncSchema.logs.chainId,
202
+ ponderSyncSchema.logs.blockNumber,
203
+ ponderSyncSchema.logs.logIndex,
204
+ ],
205
+ });
206
+ }
207
+ });
209
208
  },
210
209
  insertBlocks: async ({ blocks, chainId }) => {
211
210
  if (blocks.length === 0)
212
211
  return;
213
- // Calculate `batchSize` based on how many parameters the
214
- // input will have
215
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
216
- Object.keys(encodeBlock({ block: blocks[0], chainId })).length);
217
- for (let i = 0; i < blocks.length; i += batchSize) {
218
- await database
219
- .syncQB("insert_blocks")
220
- .insert(PONDER_SYNC.blocks)
221
- .values(blocks
222
- .slice(i, i + batchSize)
223
- .map((block) => encodeBlock({ block, chainId })))
224
- .onConflictDoNothing({
225
- target: [PONDER_SYNC.blocks.chainId, PONDER_SYNC.blocks.number],
226
- });
227
- }
212
+ await database.wrap({ method: "insertBlocks", includeTraceLogs: true }, async () => {
213
+ // Calculate `batchSize` based on how many parameters the
214
+ // input will have
215
+ const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
216
+ Object.keys(encodeBlock({ block: blocks[0], chainId })).length);
217
+ for (let i = 0; i < blocks.length; i += batchSize) {
218
+ await database.qb.sync
219
+ .insert(ponderSyncSchema.blocks)
220
+ .values(blocks
221
+ .slice(i, i + batchSize)
222
+ .map((block) => encodeBlock({ block, chainId })))
223
+ .onConflictDoNothing({
224
+ target: [
225
+ ponderSyncSchema.blocks.chainId,
226
+ ponderSyncSchema.blocks.number,
227
+ ],
228
+ });
229
+ }
230
+ });
228
231
  },
229
232
  insertTransactions: async ({ transactions, chainId }) => {
230
233
  if (transactions.length === 0)
231
234
  return;
232
- // Calculate `batchSize` based on how many parameters the
233
- // input will have
234
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
235
- Object.keys(encodeTransaction({
236
- transaction: transactions[0],
237
- chainId,
238
- })).length);
239
- // As an optimization for the migration, transactions inserted before 0.8 do not
240
- // contain a checkpoint. However, for correctness the checkpoint must be inserted
241
- // for new transactions (using onConflictDoUpdate).
242
- for (let i = 0; i < transactions.length; i += batchSize) {
243
- await database
244
- .syncQB("insert_transactions")
245
- .insert(PONDER_SYNC.transactions)
246
- .values(transactions
247
- .slice(i, i + batchSize)
248
- .map((transaction) => encodeTransaction({ transaction, chainId })))
249
- .onConflictDoNothing({
250
- target: [
251
- PONDER_SYNC.transactions.chainId,
252
- PONDER_SYNC.transactions.blockNumber,
253
- PONDER_SYNC.transactions.transactionIndex,
254
- ],
255
- });
256
- }
235
+ await database.wrap({ method: "insertTransactions", includeTraceLogs: true }, async () => {
236
+ // Calculate `batchSize` based on how many parameters the
237
+ // input will have
238
+ const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
239
+ Object.keys(encodeTransaction({
240
+ transaction: transactions[0],
241
+ chainId,
242
+ })).length);
243
+ // As an optimization for the migration, transactions inserted before 0.8 do not
244
+ // contain a checkpoint. However, for correctness the checkpoint must be inserted
245
+ // for new transactions (using onConflictDoUpdate).
246
+ for (let i = 0; i < transactions.length; i += batchSize) {
247
+ await database.qb.sync
248
+ .insert(ponderSyncSchema.transactions)
249
+ .values(transactions
250
+ .slice(i, i + batchSize)
251
+ .map((transaction) => encodeTransaction({ transaction, chainId })))
252
+ .onConflictDoNothing({
253
+ target: [
254
+ ponderSyncSchema.transactions.chainId,
255
+ ponderSyncSchema.transactions.blockNumber,
256
+ ponderSyncSchema.transactions.transactionIndex,
257
+ ],
258
+ });
259
+ }
260
+ });
257
261
  },
258
262
  insertTransactionReceipts: async ({ transactionReceipts, chainId }) => {
259
263
  if (transactionReceipts.length === 0)
260
264
  return;
261
- // Calculate `batchSize` based on how many parameters the
262
- // input will have
263
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
264
- Object.keys(encodeTransactionReceipt({
265
- transactionReceipt: transactionReceipts[0],
266
- chainId,
267
- })).length);
268
- for (let i = 0; i < transactionReceipts.length; i += batchSize) {
269
- await database
270
- .syncQB("insert_transaction_receipts")
271
- .insert(PONDER_SYNC.transactionReceipts)
272
- .values(transactionReceipts
273
- .slice(i, i + batchSize)
274
- .map((transactionReceipt) => encodeTransactionReceipt({
275
- transactionReceipt,
276
- chainId,
277
- })))
278
- .onConflictDoNothing({
279
- target: [
280
- PONDER_SYNC.transactionReceipts.chainId,
281
- PONDER_SYNC.transactionReceipts.blockNumber,
282
- PONDER_SYNC.transactionReceipts.transactionIndex,
283
- ],
284
- });
285
- }
265
+ await database.wrap({ method: "insertTransactionReceipts", includeTraceLogs: true }, async () => {
266
+ // Calculate `batchSize` based on how many parameters the
267
+ // input will have
268
+ const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
269
+ Object.keys(encodeTransactionReceipt({
270
+ transactionReceipt: transactionReceipts[0],
271
+ chainId,
272
+ })).length);
273
+ for (let i = 0; i < transactionReceipts.length; i += batchSize) {
274
+ await database.qb.sync
275
+ .insert(ponderSyncSchema.transactionReceipts)
276
+ .values(transactionReceipts
277
+ .slice(i, i + batchSize)
278
+ .map((transactionReceipt) => encodeTransactionReceipt({
279
+ transactionReceipt,
280
+ chainId,
281
+ })))
282
+ .onConflictDoNothing({
283
+ target: [
284
+ ponderSyncSchema.transactionReceipts.chainId,
285
+ ponderSyncSchema.transactionReceipts.blockNumber,
286
+ ponderSyncSchema.transactionReceipts.transactionIndex,
287
+ ],
288
+ });
289
+ }
290
+ });
286
291
  },
287
292
  insertTraces: async ({ traces, chainId }) => {
288
293
  if (traces.length === 0)
289
294
  return;
290
- // Calculate `batchSize` based on how many parameters the
291
- // input will have
292
- const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
293
- Object.keys(encodeTrace({
294
- trace: traces[0].trace,
295
- block: traces[0].block,
296
- transaction: traces[0].transaction,
297
- chainId,
298
- })).length);
299
- for (let i = 0; i < traces.length; i += batchSize) {
300
- await database
301
- .syncQB("insert_traces")
302
- .insert(PONDER_SYNC.traces)
303
- .values(traces
304
- .slice(i, i + batchSize)
305
- .map(({ trace, block, transaction }) => encodeTrace({ trace, block, transaction, chainId })))
306
- .onConflictDoNothing({
307
- target: [
308
- PONDER_SYNC.traces.chainId,
309
- PONDER_SYNC.traces.blockNumber,
310
- PONDER_SYNC.traces.transactionIndex,
311
- PONDER_SYNC.traces.traceIndex,
312
- ],
313
- });
314
- }
295
+ await database.wrap({ method: "insertTraces", includeTraceLogs: true }, async () => {
296
+ // Calculate `batchSize` based on how many parameters the
297
+ // input will have
298
+ const batchSize = Math.floor(common.options.databaseMaxQueryParameters /
299
+ Object.keys(encodeTrace({
300
+ trace: traces[0].trace,
301
+ block: traces[0].block,
302
+ transaction: traces[0].transaction,
303
+ chainId,
304
+ })).length);
305
+ for (let i = 0; i < traces.length; i += batchSize) {
306
+ await database.qb.sync
307
+ .insert(ponderSyncSchema.traces)
308
+ .values(traces
309
+ .slice(i, i + batchSize)
310
+ .map(({ trace, block, transaction }) => encodeTrace({ trace, block, transaction, chainId })))
311
+ .onConflictDoNothing({
312
+ target: [
313
+ ponderSyncSchema.traces.chainId,
314
+ ponderSyncSchema.traces.blockNumber,
315
+ ponderSyncSchema.traces.transactionIndex,
316
+ ponderSyncSchema.traces.traceIndex,
317
+ ],
318
+ });
319
+ }
320
+ });
315
321
  },
316
- getEventBlockData: async ({ filters, fromBlock, toBlock, chainId, limit, }) => {
322
+ getEventBlockData: async ({ filters, fromBlock, toBlock, chainId, limit }) => database.wrap({ method: "getEventBlockData", includeTraceLogs: true }, async () => {
317
323
  const logFilters = filters.filter((f) => f.type === "log");
318
324
  const transactionFilters = filters.filter((f) => f.type === "transaction");
319
325
  const traceFilters = filters.filter((f) => f.type === "trace");
@@ -323,123 +329,143 @@ export const createSyncStore = ({ common, database, }) => ({
323
329
  const shouldQueryTraces = traceFilters.length > 0 || transferFilters.length > 0;
324
330
  const shouldQueryTransactions = transactionFilters.length > 0 || shouldQueryLogs || shouldQueryTraces;
325
331
  const shouldQueryTransactionReceipts = filters.some(shouldGetTransactionReceipt);
326
- const blocksQuery = database
327
- .syncQB("select_blocks")
332
+ const blocksQuery = database.qb.sync
328
333
  .select({
329
- number: PONDER_SYNC.blocks.number,
330
- timestamp: PONDER_SYNC.blocks.timestamp,
331
- hash: PONDER_SYNC.blocks.hash,
332
- parentHash: PONDER_SYNC.blocks.parentHash,
333
- logsBloom: PONDER_SYNC.blocks.logsBloom,
334
- miner: PONDER_SYNC.blocks.miner,
335
- gasUsed: PONDER_SYNC.blocks.gasUsed,
336
- gasLimit: PONDER_SYNC.blocks.gasLimit,
337
- baseFeePerGas: PONDER_SYNC.blocks.baseFeePerGas,
338
- nonce: PONDER_SYNC.blocks.nonce,
339
- mixHash: PONDER_SYNC.blocks.mixHash,
340
- stateRoot: PONDER_SYNC.blocks.stateRoot,
341
- receiptsRoot: PONDER_SYNC.blocks.receiptsRoot,
342
- transactionsRoot: PONDER_SYNC.blocks.transactionsRoot,
343
- sha3Uncles: PONDER_SYNC.blocks.sha3Uncles,
344
- size: PONDER_SYNC.blocks.size,
345
- difficulty: PONDER_SYNC.blocks.difficulty,
346
- totalDifficulty: PONDER_SYNC.blocks.totalDifficulty,
347
- extraData: PONDER_SYNC.blocks.extraData,
334
+ number: ponderSyncSchema.blocks.number,
335
+ timestamp: ponderSyncSchema.blocks.timestamp,
336
+ hash: ponderSyncSchema.blocks.hash,
337
+ parentHash: ponderSyncSchema.blocks.parentHash,
338
+ logsBloom: ponderSyncSchema.blocks.logsBloom,
339
+ miner: ponderSyncSchema.blocks.miner,
340
+ gasUsed: ponderSyncSchema.blocks.gasUsed,
341
+ gasLimit: ponderSyncSchema.blocks.gasLimit,
342
+ baseFeePerGas: ponderSyncSchema.blocks.baseFeePerGas,
343
+ nonce: ponderSyncSchema.blocks.nonce,
344
+ mixHash: ponderSyncSchema.blocks.mixHash,
345
+ stateRoot: ponderSyncSchema.blocks.stateRoot,
346
+ receiptsRoot: ponderSyncSchema.blocks.receiptsRoot,
347
+ transactionsRoot: ponderSyncSchema.blocks.transactionsRoot,
348
+ sha3Uncles: ponderSyncSchema.blocks.sha3Uncles,
349
+ size: ponderSyncSchema.blocks.size,
350
+ difficulty: ponderSyncSchema.blocks.difficulty,
351
+ totalDifficulty: ponderSyncSchema.blocks.totalDifficulty,
352
+ extraData: ponderSyncSchema.blocks.extraData,
348
353
  })
349
- .from(PONDER_SYNC.blocks)
350
- .where(and(eq(PONDER_SYNC.blocks.chainId, BigInt(chainId)), gte(PONDER_SYNC.blocks.number, BigInt(fromBlock)), lte(PONDER_SYNC.blocks.number, BigInt(toBlock))))
351
- .orderBy(asc(PONDER_SYNC.blocks.number))
354
+ .from(ponderSyncSchema.blocks)
355
+ .where(and(eq(ponderSyncSchema.blocks.chainId, BigInt(chainId)), gte(ponderSyncSchema.blocks.number, BigInt(fromBlock)), lte(ponderSyncSchema.blocks.number, BigInt(toBlock))))
356
+ .orderBy(asc(ponderSyncSchema.blocks.number))
352
357
  .limit(limit);
353
- const transactionsQuery = database
354
- .syncQB("select_transactions")
358
+ const transactionsQuery = database.qb.sync
355
359
  .select({
356
- blockNumber: PONDER_SYNC.transactions.blockNumber,
357
- transactionIndex: PONDER_SYNC.transactions.transactionIndex,
358
- hash: PONDER_SYNC.transactions.hash,
359
- from: PONDER_SYNC.transactions.from,
360
- to: PONDER_SYNC.transactions.to,
361
- input: PONDER_SYNC.transactions.input,
362
- value: PONDER_SYNC.transactions.value,
363
- nonce: PONDER_SYNC.transactions.nonce,
364
- r: PONDER_SYNC.transactions.r,
365
- s: PONDER_SYNC.transactions.s,
366
- v: PONDER_SYNC.transactions.v,
367
- type: PONDER_SYNC.transactions.type,
368
- gas: PONDER_SYNC.transactions.gas,
369
- gasPrice: PONDER_SYNC.transactions.gasPrice,
370
- maxFeePerGas: PONDER_SYNC.transactions.maxFeePerGas,
371
- maxPriorityFeePerGas: PONDER_SYNC.transactions.maxPriorityFeePerGas,
372
- accessList: PONDER_SYNC.transactions.accessList,
360
+ blockNumber: ponderSyncSchema.transactions.blockNumber,
361
+ transactionIndex: ponderSyncSchema.transactions.transactionIndex,
362
+ hash: ponderSyncSchema.transactions.hash,
363
+ from: ponderSyncSchema.transactions.from,
364
+ to: ponderSyncSchema.transactions.to,
365
+ input: ponderSyncSchema.transactions.input,
366
+ value: ponderSyncSchema.transactions.value,
367
+ nonce: ponderSyncSchema.transactions.nonce,
368
+ r: ponderSyncSchema.transactions.r,
369
+ s: ponderSyncSchema.transactions.s,
370
+ v: ponderSyncSchema.transactions.v,
371
+ type: ponderSyncSchema.transactions.type,
372
+ gas: ponderSyncSchema.transactions.gas,
373
+ gasPrice: ponderSyncSchema.transactions.gasPrice,
374
+ maxFeePerGas: ponderSyncSchema.transactions.maxFeePerGas,
375
+ maxPriorityFeePerGas: ponderSyncSchema.transactions.maxPriorityFeePerGas,
376
+ accessList: ponderSyncSchema.transactions.accessList,
373
377
  })
374
- .from(PONDER_SYNC.transactions)
375
- .where(and(eq(PONDER_SYNC.transactions.chainId, BigInt(chainId)), gte(PONDER_SYNC.transactions.blockNumber, BigInt(fromBlock)), lte(PONDER_SYNC.transactions.blockNumber, BigInt(toBlock))))
376
- .orderBy(asc(PONDER_SYNC.transactions.blockNumber), asc(PONDER_SYNC.transactions.transactionIndex))
378
+ .from(ponderSyncSchema.transactions)
379
+ .where(and(eq(ponderSyncSchema.transactions.chainId, BigInt(chainId)), gte(ponderSyncSchema.transactions.blockNumber, BigInt(fromBlock)), lte(ponderSyncSchema.transactions.blockNumber, BigInt(toBlock))))
380
+ .orderBy(asc(ponderSyncSchema.transactions.blockNumber), asc(ponderSyncSchema.transactions.transactionIndex))
377
381
  .limit(limit);
378
- const transactionReceiptsQuery = database
379
- .syncQB("select_transaction_receipts")
382
+ const transactionReceiptsQuery = database.qb.sync
380
383
  .select({
381
- blockNumber: PONDER_SYNC.transactionReceipts.blockNumber,
382
- transactionIndex: PONDER_SYNC.transactionReceipts.transactionIndex,
383
- from: PONDER_SYNC.transactionReceipts.from,
384
- to: PONDER_SYNC.transactionReceipts.to,
385
- contractAddress: PONDER_SYNC.transactionReceipts.contractAddress,
386
- logsBloom: PONDER_SYNC.transactionReceipts.logsBloom,
387
- gasUsed: PONDER_SYNC.transactionReceipts.gasUsed,
388
- cumulativeGasUsed: PONDER_SYNC.transactionReceipts.cumulativeGasUsed,
389
- effectiveGasPrice: PONDER_SYNC.transactionReceipts.effectiveGasPrice,
390
- status: PONDER_SYNC.transactionReceipts.status,
391
- type: PONDER_SYNC.transactionReceipts.type,
384
+ blockNumber: ponderSyncSchema.transactionReceipts.blockNumber,
385
+ transactionIndex: ponderSyncSchema.transactionReceipts.transactionIndex,
386
+ from: ponderSyncSchema.transactionReceipts.from,
387
+ to: ponderSyncSchema.transactionReceipts.to,
388
+ contractAddress: ponderSyncSchema.transactionReceipts.contractAddress,
389
+ logsBloom: ponderSyncSchema.transactionReceipts.logsBloom,
390
+ gasUsed: ponderSyncSchema.transactionReceipts.gasUsed,
391
+ cumulativeGasUsed: ponderSyncSchema.transactionReceipts.cumulativeGasUsed,
392
+ effectiveGasPrice: ponderSyncSchema.transactionReceipts.effectiveGasPrice,
393
+ status: ponderSyncSchema.transactionReceipts.status,
394
+ type: ponderSyncSchema.transactionReceipts.type,
392
395
  })
393
- .from(PONDER_SYNC.transactionReceipts)
394
- .where(and(eq(PONDER_SYNC.transactionReceipts.chainId, BigInt(chainId)), gte(PONDER_SYNC.transactionReceipts.blockNumber, BigInt(fromBlock)), lte(PONDER_SYNC.transactionReceipts.blockNumber, BigInt(toBlock))))
395
- .orderBy(asc(PONDER_SYNC.transactionReceipts.blockNumber), asc(PONDER_SYNC.transactionReceipts.transactionIndex))
396
+ .from(ponderSyncSchema.transactionReceipts)
397
+ .where(and(eq(ponderSyncSchema.transactionReceipts.chainId, BigInt(chainId)), gte(ponderSyncSchema.transactionReceipts.blockNumber, BigInt(fromBlock)), lte(ponderSyncSchema.transactionReceipts.blockNumber, BigInt(toBlock))))
398
+ .orderBy(asc(ponderSyncSchema.transactionReceipts.blockNumber), asc(ponderSyncSchema.transactionReceipts.transactionIndex))
396
399
  .limit(limit);
397
- const logsQuery = database
398
- .syncQB("select_logs")
400
+ const logsQuery = database.qb.sync
399
401
  .select({
400
- blockNumber: PONDER_SYNC.logs.blockNumber,
401
- logIndex: PONDER_SYNC.logs.logIndex,
402
- transactionIndex: PONDER_SYNC.logs.transactionIndex,
403
- address: PONDER_SYNC.logs.address,
404
- topic0: PONDER_SYNC.logs.topic0,
405
- topic1: PONDER_SYNC.logs.topic1,
406
- topic2: PONDER_SYNC.logs.topic2,
407
- topic3: PONDER_SYNC.logs.topic3,
408
- data: PONDER_SYNC.logs.data,
402
+ blockNumber: ponderSyncSchema.logs.blockNumber,
403
+ logIndex: ponderSyncSchema.logs.logIndex,
404
+ transactionIndex: ponderSyncSchema.logs.transactionIndex,
405
+ address: ponderSyncSchema.logs.address,
406
+ topic0: ponderSyncSchema.logs.topic0,
407
+ topic1: ponderSyncSchema.logs.topic1,
408
+ topic2: ponderSyncSchema.logs.topic2,
409
+ topic3: ponderSyncSchema.logs.topic3,
410
+ data: ponderSyncSchema.logs.data,
409
411
  })
410
- .from(PONDER_SYNC.logs)
411
- .where(and(eq(PONDER_SYNC.logs.chainId, BigInt(chainId)), gte(PONDER_SYNC.logs.blockNumber, BigInt(fromBlock)), lte(PONDER_SYNC.logs.blockNumber, BigInt(toBlock)), or(...logFilters.map((filter) => logFilter(filter)))))
412
- .orderBy(asc(PONDER_SYNC.logs.blockNumber), asc(PONDER_SYNC.logs.logIndex))
412
+ .from(ponderSyncSchema.logs)
413
+ .where(and(eq(ponderSyncSchema.logs.chainId, BigInt(chainId)), gte(ponderSyncSchema.logs.blockNumber, BigInt(fromBlock)), lte(ponderSyncSchema.logs.blockNumber, BigInt(toBlock)), or(...logFilters.map((filter) => logFilter(filter)))))
414
+ .orderBy(asc(ponderSyncSchema.logs.blockNumber), asc(ponderSyncSchema.logs.logIndex))
413
415
  .limit(limit);
414
- const tracesQuery = database
415
- .syncQB("select_traces")
416
+ const tracesQuery = database.qb.sync
416
417
  .select({
417
- blockNumber: PONDER_SYNC.traces.blockNumber,
418
- transactionIndex: PONDER_SYNC.traces.transactionIndex,
419
- traceIndex: PONDER_SYNC.traces.traceIndex,
420
- from: PONDER_SYNC.traces.from,
421
- to: PONDER_SYNC.traces.to,
422
- input: PONDER_SYNC.traces.input,
423
- output: PONDER_SYNC.traces.output,
424
- value: PONDER_SYNC.traces.value,
425
- type: PONDER_SYNC.traces.type,
426
- gas: PONDER_SYNC.traces.gas,
427
- gasUsed: PONDER_SYNC.traces.gasUsed,
428
- error: PONDER_SYNC.traces.error,
429
- revertReason: PONDER_SYNC.traces.revertReason,
430
- subcalls: PONDER_SYNC.traces.subcalls,
418
+ blockNumber: ponderSyncSchema.traces.blockNumber,
419
+ transactionIndex: ponderSyncSchema.traces.transactionIndex,
420
+ traceIndex: ponderSyncSchema.traces.traceIndex,
421
+ from: ponderSyncSchema.traces.from,
422
+ to: ponderSyncSchema.traces.to,
423
+ input: ponderSyncSchema.traces.input,
424
+ output: ponderSyncSchema.traces.output,
425
+ value: ponderSyncSchema.traces.value,
426
+ type: ponderSyncSchema.traces.type,
427
+ gas: ponderSyncSchema.traces.gas,
428
+ gasUsed: ponderSyncSchema.traces.gasUsed,
429
+ error: ponderSyncSchema.traces.error,
430
+ revertReason: ponderSyncSchema.traces.revertReason,
431
+ subcalls: ponderSyncSchema.traces.subcalls,
431
432
  })
432
- .from(PONDER_SYNC.traces)
433
- .where(and(eq(PONDER_SYNC.traces.chainId, BigInt(chainId)), gte(PONDER_SYNC.traces.blockNumber, BigInt(fromBlock)), lte(PONDER_SYNC.traces.blockNumber, BigInt(toBlock)), or(...traceFilters.map((filter) => traceFilter(filter)), ...transferFilters.map((filter) => transferFilter(filter)))))
434
- .orderBy(asc(PONDER_SYNC.traces.blockNumber), asc(PONDER_SYNC.traces.traceIndex))
433
+ .from(ponderSyncSchema.traces)
434
+ .where(and(eq(ponderSyncSchema.traces.chainId, BigInt(chainId)), gte(ponderSyncSchema.traces.blockNumber, BigInt(fromBlock)), lte(ponderSyncSchema.traces.blockNumber, BigInt(toBlock)), or(...traceFilters.map((filter) => traceFilter(filter)), ...transferFilters.map((filter) => transferFilter(filter)))))
435
+ .orderBy(asc(ponderSyncSchema.traces.blockNumber), asc(ponderSyncSchema.traces.traceIndex))
435
436
  .limit(limit);
436
437
  let endClock = startClock();
437
438
  const [blocksRows, transactionsRows, transactionReceiptsRows, logsRows, tracesRows,] = await Promise.all([
438
- shouldQueryBlocks ? blocksQuery : [],
439
- shouldQueryTransactions ? transactionsQuery : [],
440
- shouldQueryTransactionReceipts ? transactionReceiptsQuery : [],
441
- shouldQueryLogs ? logsQuery : [],
442
- shouldQueryTraces ? tracesQuery : [],
439
+ shouldQueryBlocks
440
+ ? blocksQuery.then((res) => {
441
+ common.metrics.ponder_database_method_duration.observe({ method: "getEventBlockData_blocks" }, endClock());
442
+ return res;
443
+ })
444
+ : [],
445
+ shouldQueryTransactions
446
+ ? transactionsQuery.then((res) => {
447
+ common.metrics.ponder_database_method_duration.observe({ method: "getEventBlockData_transactions" }, endClock());
448
+ return res;
449
+ })
450
+ : [],
451
+ shouldQueryTransactionReceipts
452
+ ? transactionReceiptsQuery.then((res) => {
453
+ common.metrics.ponder_database_method_duration.observe({ method: "getEventBlockData_transaction_receipts" }, endClock());
454
+ return res;
455
+ })
456
+ : [],
457
+ shouldQueryLogs
458
+ ? logsQuery.then((res) => {
459
+ common.metrics.ponder_database_method_duration.observe({ method: "getEventBlockData_logs" }, endClock());
460
+ return res;
461
+ })
462
+ : [],
463
+ shouldQueryTraces
464
+ ? tracesQuery.then((res) => {
465
+ common.metrics.ponder_database_method_duration.observe({ method: "getEventBlockData_traces" }, endClock());
466
+ return res;
467
+ })
468
+ : [],
443
469
  ]);
444
470
  const supremum = Math.min(blocksRows.length < limit
445
471
  ? Number.POSITIVE_INFINITY
@@ -605,91 +631,94 @@ export const createSyncStore = ({ common, database, }) => ({
605
631
  cursor = supremum - 1;
606
632
  }
607
633
  return { blockData, cursor };
608
- },
634
+ }),
609
635
  insertRpcRequestResults: async ({ requests, chainId }) => {
610
636
  if (requests.length === 0)
611
637
  return;
612
- const values = requests.map(({ request, blockNumber, result }) => ({
613
- requestHash: crypto
614
- .createHash("md5")
615
- .update(toLowerCase(JSON.stringify(orderObject(request))))
616
- .digest("hex"),
617
- chainId: BigInt(chainId),
618
- blockNumber: blockNumber ? BigInt(blockNumber) : undefined,
619
- result,
620
- }));
621
- await database
622
- .syncQB("insert_rpc_request_results")
623
- .insert(PONDER_SYNC.rpcRequestResults)
624
- .values(values)
625
- .onConflictDoUpdate({
626
- target: [
627
- PONDER_SYNC.rpcRequestResults.requestHash,
628
- PONDER_SYNC.rpcRequestResults.chainId,
629
- ],
630
- set: {
631
- result: sql `EXCLUDED.result`,
632
- },
638
+ return database.wrap({ method: "insertRpcRequestResults", includeTraceLogs: true }, async () => {
639
+ const values = requests.map(({ request, blockNumber, result }) => ({
640
+ requestHash: crypto
641
+ .createHash("md5")
642
+ .update(toLowerCase(JSON.stringify(orderObject(request))))
643
+ .digest("hex"),
644
+ chainId: BigInt(chainId),
645
+ blockNumber: blockNumber ? BigInt(blockNumber) : undefined,
646
+ result,
647
+ }));
648
+ await database.qb.sync
649
+ .insert(ponderSyncSchema.rpcRequestResults)
650
+ .values(values)
651
+ .onConflictDoUpdate({
652
+ target: [
653
+ ponderSyncSchema.rpcRequestResults.requestHash,
654
+ ponderSyncSchema.rpcRequestResults.chainId,
655
+ ],
656
+ set: {
657
+ result: sql `EXCLUDED.result`,
658
+ },
659
+ });
633
660
  });
634
661
  },
635
662
  getRpcRequestResults: async ({ requests, chainId }) => {
636
663
  if (requests.length === 0)
637
664
  return [];
638
- const requestHashes = requests.map((request) => crypto
639
- .createHash("md5")
640
- .update(toLowerCase(JSON.stringify(orderObject(request))))
641
- .digest("hex"));
642
- const result = await database
643
- .syncQB("select_rpc_request_results")
644
- .select({
645
- request_hash: PONDER_SYNC.rpcRequestResults.requestHash,
646
- result: PONDER_SYNC.rpcRequestResults.result,
647
- })
648
- .from(PONDER_SYNC.rpcRequestResults)
649
- .where(and(eq(PONDER_SYNC.rpcRequestResults.chainId, BigInt(chainId)), inArray(PONDER_SYNC.rpcRequestResults.requestHash, requestHashes)))
650
- .execute();
651
- const results = new Map();
652
- for (const row of result) {
653
- results.set(row.request_hash, row.result);
654
- }
655
- return requestHashes.map((requestHash) => results.get(requestHash));
665
+ return database.wrap({ method: "getRpcRequestResults", includeTraceLogs: true }, async () => {
666
+ const requestHashes = requests.map((request) => crypto
667
+ .createHash("md5")
668
+ .update(toLowerCase(JSON.stringify(orderObject(request))))
669
+ .digest("hex"));
670
+ const result = await database.qb.sync
671
+ .select({
672
+ request_hash: ponderSyncSchema.rpcRequestResults.requestHash,
673
+ result: ponderSyncSchema.rpcRequestResults.result,
674
+ })
675
+ .from(ponderSyncSchema.rpcRequestResults)
676
+ .where(and(eq(ponderSyncSchema.rpcRequestResults.chainId, BigInt(chainId)), inArray(ponderSyncSchema.rpcRequestResults.requestHash, requestHashes)))
677
+ .execute();
678
+ const results = new Map();
679
+ for (const row of result) {
680
+ results.set(row.request_hash, row.result);
681
+ }
682
+ return requestHashes.map((requestHash) => results.get(requestHash));
683
+ });
656
684
  },
657
685
  pruneRpcRequestResults: async ({ blocks, chainId }) => {
658
686
  if (blocks.length === 0)
659
687
  return;
660
- const numbers = blocks.map(({ number }) => BigInt(hexToNumber(number)));
661
- await database
662
- .syncQB("delete_rpc_request_results")
663
- .delete(PONDER_SYNC.rpcRequestResults)
664
- .where(and(eq(PONDER_SYNC.rpcRequestResults.chainId, BigInt(chainId)), inArray(PONDER_SYNC.rpcRequestResults.blockNumber, numbers)))
665
- .execute();
688
+ return database.wrap({ method: "pruneRpcRequestResults", includeTraceLogs: true }, async () => {
689
+ const numbers = blocks.map(({ number }) => BigInt(hexToNumber(number)));
690
+ await database.qb.sync
691
+ .delete(ponderSyncSchema.rpcRequestResults)
692
+ .where(and(eq(ponderSyncSchema.rpcRequestResults.chainId, BigInt(chainId)), inArray(ponderSyncSchema.rpcRequestResults.blockNumber, numbers)))
693
+ .execute();
694
+ });
666
695
  },
667
- pruneByChain: async ({ chainId }) => database.syncQB().transaction(async (tx) => {
668
- await tx("delete_logs")
669
- .delete(PONDER_SYNC.logs)
670
- .where(eq(PONDER_SYNC.logs.chainId, BigInt(chainId)))
696
+ pruneByChain: async ({ chainId }) => database.wrap({ method: "pruneByChain", includeTraceLogs: true }, () => database.qb.sync.transaction(async (tx) => {
697
+ await tx
698
+ .delete(ponderSyncSchema.logs)
699
+ .where(eq(ponderSyncSchema.logs.chainId, BigInt(chainId)))
671
700
  .execute();
672
- await tx("delete_blocks")
673
- .delete(PONDER_SYNC.blocks)
674
- .where(eq(PONDER_SYNC.blocks.chainId, BigInt(chainId)))
701
+ await tx
702
+ .delete(ponderSyncSchema.blocks)
703
+ .where(eq(ponderSyncSchema.blocks.chainId, BigInt(chainId)))
675
704
  .execute();
676
- await tx("delete_traces")
677
- .delete(PONDER_SYNC.traces)
678
- .where(eq(PONDER_SYNC.traces.chainId, BigInt(chainId)))
705
+ await tx
706
+ .delete(ponderSyncSchema.traces)
707
+ .where(eq(ponderSyncSchema.traces.chainId, BigInt(chainId)))
679
708
  .execute();
680
- await tx("delete_transactions")
681
- .delete(PONDER_SYNC.transactions)
682
- .where(eq(PONDER_SYNC.transactions.chainId, BigInt(chainId)))
709
+ await tx
710
+ .delete(ponderSyncSchema.transactions)
711
+ .where(eq(ponderSyncSchema.transactions.chainId, BigInt(chainId)))
683
712
  .execute();
684
- await tx("delete_transaction_receipts")
685
- .delete(PONDER_SYNC.transactionReceipts)
686
- .where(eq(PONDER_SYNC.transactionReceipts.chainId, BigInt(chainId)))
713
+ await tx
714
+ .delete(ponderSyncSchema.transactionReceipts)
715
+ .where(eq(ponderSyncSchema.transactionReceipts.chainId, BigInt(chainId)))
687
716
  .execute();
688
- await tx("delete_factory_addresses")
689
- .delete(PONDER_SYNC.factoryAddresses)
690
- .where(eq(PONDER_SYNC.factoryAddresses.chainId, BigInt(chainId)))
717
+ await tx
718
+ .delete(ponderSyncSchema.factoryAddresses)
719
+ .where(eq(ponderSyncSchema.factoryAddresses.chainId, BigInt(chainId)))
691
720
  .execute();
692
- }),
721
+ })),
693
722
  });
694
723
  const addressFilter = (address, column) => {
695
724
  // `factory` filtering is handled in-memory
@@ -712,18 +741,18 @@ export const logFilter = (filter) => {
712
741
  continue;
713
742
  const topic = Array.isArray(raw) && raw.length === 1 ? raw[0] : raw;
714
743
  if (Array.isArray(topic)) {
715
- conditions.push(inArray(PONDER_SYNC.logs[`topic${idx}`], topic));
744
+ conditions.push(inArray(ponderSyncSchema.logs[`topic${idx}`], topic));
716
745
  }
717
746
  else {
718
- conditions.push(eq(PONDER_SYNC.logs[`topic${idx}`], topic));
747
+ conditions.push(eq(ponderSyncSchema.logs[`topic${idx}`], topic));
719
748
  }
720
749
  }
721
- conditions.push(addressFilter(filter.address, PONDER_SYNC.logs.address));
750
+ conditions.push(addressFilter(filter.address, ponderSyncSchema.logs.address));
722
751
  if (filter.fromBlock !== undefined) {
723
- conditions.push(gte(PONDER_SYNC.logs.blockNumber, BigInt(filter.fromBlock)));
752
+ conditions.push(gte(ponderSyncSchema.logs.blockNumber, BigInt(filter.fromBlock)));
724
753
  }
725
754
  if (filter.toBlock !== undefined) {
726
- conditions.push(lte(PONDER_SYNC.logs.blockNumber, BigInt(filter.toBlock)));
755
+ conditions.push(lte(ponderSyncSchema.logs.blockNumber, BigInt(filter.toBlock)));
727
756
  }
728
757
  return and(...conditions);
729
758
  };
@@ -731,49 +760,49 @@ export const blockFilter = (filter) => {
731
760
  const conditions = [];
732
761
  conditions.push(sql `(blocks.number - ${filter.offset}) % ${filter.interval} = 0`);
733
762
  if (filter.fromBlock !== undefined) {
734
- conditions.push(gte(PONDER_SYNC.blocks.number, BigInt(filter.fromBlock)));
763
+ conditions.push(gte(ponderSyncSchema.blocks.number, BigInt(filter.fromBlock)));
735
764
  }
736
765
  if (filter.toBlock !== undefined) {
737
- conditions.push(lte(PONDER_SYNC.blocks.number, BigInt(filter.toBlock)));
766
+ conditions.push(lte(ponderSyncSchema.blocks.number, BigInt(filter.toBlock)));
738
767
  }
739
768
  return and(...conditions);
740
769
  };
741
770
  export const transactionFilter = (filter) => {
742
771
  const conditions = [];
743
- conditions.push(addressFilter(filter.fromAddress, PONDER_SYNC.transactions.from));
744
- conditions.push(addressFilter(filter.toAddress, PONDER_SYNC.transactions.to));
772
+ conditions.push(addressFilter(filter.fromAddress, ponderSyncSchema.transactions.from));
773
+ conditions.push(addressFilter(filter.toAddress, ponderSyncSchema.transactions.to));
745
774
  if (filter.fromBlock !== undefined) {
746
- conditions.push(gte(PONDER_SYNC.transactions.blockNumber, BigInt(filter.fromBlock)));
775
+ conditions.push(gte(ponderSyncSchema.transactions.blockNumber, BigInt(filter.fromBlock)));
747
776
  }
748
777
  if (filter.toBlock !== undefined) {
749
- conditions.push(lte(PONDER_SYNC.transactions.blockNumber, BigInt(filter.toBlock)));
778
+ conditions.push(lte(ponderSyncSchema.transactions.blockNumber, BigInt(filter.toBlock)));
750
779
  }
751
780
  return and(...conditions);
752
781
  };
753
782
  export const transferFilter = (filter) => {
754
783
  const conditions = [];
755
- conditions.push(addressFilter(filter.fromAddress, PONDER_SYNC.traces.from));
756
- conditions.push(addressFilter(filter.toAddress, PONDER_SYNC.traces.to));
784
+ conditions.push(addressFilter(filter.fromAddress, ponderSyncSchema.traces.from));
785
+ conditions.push(addressFilter(filter.toAddress, ponderSyncSchema.traces.to));
757
786
  if (filter.includeReverted === false) {
758
- conditions.push(isNull(PONDER_SYNC.traces.error));
787
+ conditions.push(isNull(ponderSyncSchema.traces.error));
759
788
  }
760
789
  if (filter.fromBlock !== undefined) {
761
- conditions.push(gte(PONDER_SYNC.traces.blockNumber, BigInt(filter.fromBlock)));
790
+ conditions.push(gte(ponderSyncSchema.traces.blockNumber, BigInt(filter.fromBlock)));
762
791
  }
763
792
  if (filter.toBlock !== undefined) {
764
- conditions.push(lte(PONDER_SYNC.traces.blockNumber, BigInt(filter.toBlock)));
793
+ conditions.push(lte(ponderSyncSchema.traces.blockNumber, BigInt(filter.toBlock)));
765
794
  }
766
795
  return and(...conditions);
767
796
  };
768
797
  export const traceFilter = (filter) => {
769
798
  const conditions = [];
770
- conditions.push(addressFilter(filter.fromAddress, PONDER_SYNC.traces.from));
771
- conditions.push(addressFilter(filter.toAddress, PONDER_SYNC.traces.to));
799
+ conditions.push(addressFilter(filter.fromAddress, ponderSyncSchema.traces.from));
800
+ conditions.push(addressFilter(filter.toAddress, ponderSyncSchema.traces.to));
772
801
  if (filter.includeReverted === false) {
773
- conditions.push(isNull(PONDER_SYNC.traces.error));
802
+ conditions.push(isNull(ponderSyncSchema.traces.error));
774
803
  }
775
804
  if (filter.callType !== undefined) {
776
- conditions.push(eq(PONDER_SYNC.traces.type, filter.callType));
805
+ conditions.push(eq(ponderSyncSchema.traces.type, filter.callType));
777
806
  }
778
807
  if (filter.functionSelector !== undefined) {
779
808
  if (Array.isArray(filter.functionSelector)) {
@@ -784,10 +813,10 @@ export const traceFilter = (filter) => {
784
813
  }
785
814
  }
786
815
  if (filter.fromBlock !== undefined) {
787
- conditions.push(gte(PONDER_SYNC.traces.blockNumber, BigInt(filter.fromBlock)));
816
+ conditions.push(gte(ponderSyncSchema.traces.blockNumber, BigInt(filter.fromBlock)));
788
817
  }
789
818
  if (filter.toBlock !== undefined) {
790
- conditions.push(lte(PONDER_SYNC.traces.blockNumber, BigInt(filter.toBlock)));
819
+ conditions.push(lte(ponderSyncSchema.traces.blockNumber, BigInt(filter.toBlock)));
791
820
  }
792
821
  return and(...conditions);
793
822
  };