ponder 0.17.12 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/esm/bin/commands/codegen.js +3 -3
  3. package/dist/esm/bin/commands/codegen.js.map +1 -1
  4. package/dist/esm/bin/commands/dev.js +3 -3
  5. package/dist/esm/bin/commands/dev.js.map +1 -1
  6. package/dist/esm/bin/commands/serve.js +3 -3
  7. package/dist/esm/bin/commands/serve.js.map +1 -1
  8. package/dist/esm/bin/commands/start.js +3 -3
  9. package/dist/esm/bin/commands/start.js.map +1 -1
  10. package/dist/esm/build/config.js +19 -20
  11. package/dist/esm/build/config.js.map +1 -1
  12. package/dist/esm/build/index.js +79 -65
  13. package/dist/esm/build/index.js.map +1 -1
  14. package/dist/esm/build/plugin.js +9 -0
  15. package/dist/esm/build/plugin.js.map +1 -1
  16. package/dist/esm/build/stacktrace.js +25 -68
  17. package/dist/esm/build/stacktrace.js.map +1 -1
  18. package/dist/esm/database/index.js +83 -67
  19. package/dist/esm/database/index.js.map +1 -1
  20. package/dist/esm/index.js +1 -0
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/indexing/client.js +35 -23
  23. package/dist/esm/indexing/client.js.map +1 -1
  24. package/dist/esm/indexing/index.js +3 -1
  25. package/dist/esm/indexing/index.js.map +1 -1
  26. package/dist/esm/rpc/actions.js +143 -67
  27. package/dist/esm/rpc/actions.js.map +1 -1
  28. package/dist/esm/runtime/events.js +33 -19
  29. package/dist/esm/runtime/events.js.map +1 -1
  30. package/dist/esm/runtime/filter.js +10 -9
  31. package/dist/esm/runtime/filter.js.map +1 -1
  32. package/dist/esm/runtime/fragments.js +50 -24
  33. package/dist/esm/runtime/fragments.js.map +1 -1
  34. package/dist/esm/runtime/historical.js +212 -68
  35. package/dist/esm/runtime/historical.js.map +1 -1
  36. package/dist/esm/runtime/index.js +11 -15
  37. package/dist/esm/runtime/index.js.map +1 -1
  38. package/dist/esm/runtime/isolated.js +1 -0
  39. package/dist/esm/runtime/isolated.js.map +1 -1
  40. package/dist/esm/runtime/multichain.js +1 -0
  41. package/dist/esm/runtime/multichain.js.map +1 -1
  42. package/dist/esm/runtime/omnichain.js +1 -0
  43. package/dist/esm/runtime/omnichain.js.map +1 -1
  44. package/dist/esm/runtime/realtime.js +17 -16
  45. package/dist/esm/runtime/realtime.js.map +1 -1
  46. package/dist/esm/server/index.js +8 -6
  47. package/dist/esm/server/index.js.map +1 -1
  48. package/dist/esm/sync-historical/in-memory.js +539 -0
  49. package/dist/esm/sync-historical/in-memory.js.map +1 -0
  50. package/dist/esm/sync-historical/index.js +46 -63
  51. package/dist/esm/sync-historical/index.js.map +1 -1
  52. package/dist/esm/sync-realtime/index.js +56 -83
  53. package/dist/esm/sync-realtime/index.js.map +1 -1
  54. package/dist/esm/sync-store/encode.js +1 -6
  55. package/dist/esm/sync-store/encode.js.map +1 -1
  56. package/dist/esm/sync-store/index.js +58 -62
  57. package/dist/esm/sync-store/index.js.map +1 -1
  58. package/dist/esm/sync-store/schema.js +23 -15
  59. package/dist/esm/sync-store/schema.js.map +1 -1
  60. package/dist/esm/sync-store/sql/ponder_rpc_cache_1/copy.sql +23 -0
  61. package/dist/esm/sync-store/sql/ponder_rpc_cache_1/create.sql +130 -0
  62. package/dist/esm/utils/finality.js +41 -32
  63. package/dist/esm/utils/finality.js.map +1 -1
  64. package/dist/esm/utils/pglite.js +0 -65
  65. package/dist/esm/utils/pglite.js.map +1 -1
  66. package/dist/types/bin/commands/codegen.d.ts.map +1 -1
  67. package/dist/types/bin/commands/dev.d.ts.map +1 -1
  68. package/dist/types/bin/commands/serve.d.ts.map +1 -1
  69. package/dist/types/bin/commands/start.d.ts.map +1 -1
  70. package/dist/types/build/config.d.ts.map +1 -1
  71. package/dist/types/build/index.d.ts.map +1 -1
  72. package/dist/types/build/plugin.d.ts.map +1 -1
  73. package/dist/types/build/stacktrace.d.ts +1 -12
  74. package/dist/types/build/stacktrace.d.ts.map +1 -1
  75. package/dist/types/config/index.d.ts +12 -2
  76. package/dist/types/config/index.d.ts.map +1 -1
  77. package/dist/types/database/index.d.ts.map +1 -1
  78. package/dist/types/index.d.ts +1 -0
  79. package/dist/types/index.d.ts.map +1 -1
  80. package/dist/types/indexing/client.d.ts.map +1 -1
  81. package/dist/types/internal/types.d.ts +8 -13
  82. package/dist/types/internal/types.d.ts.map +1 -1
  83. package/dist/types/rpc/actions.d.ts +30 -0
  84. package/dist/types/rpc/actions.d.ts.map +1 -1
  85. package/dist/types/runtime/events.d.ts.map +1 -1
  86. package/dist/types/runtime/filter.d.ts.map +1 -1
  87. package/dist/types/runtime/fragments.d.ts +9 -1
  88. package/dist/types/runtime/fragments.d.ts.map +1 -1
  89. package/dist/types/runtime/historical.d.ts +18 -1
  90. package/dist/types/runtime/historical.d.ts.map +1 -1
  91. package/dist/types/runtime/index.d.ts +1 -0
  92. package/dist/types/runtime/index.d.ts.map +1 -1
  93. package/dist/types/runtime/isolated.d.ts.map +1 -1
  94. package/dist/types/runtime/multichain.d.ts.map +1 -1
  95. package/dist/types/runtime/omnichain.d.ts.map +1 -1
  96. package/dist/types/runtime/realtime.d.ts.map +1 -1
  97. package/dist/types/server/index.d.ts.map +1 -1
  98. package/dist/types/sync-historical/in-memory.d.ts +24 -0
  99. package/dist/types/sync-historical/in-memory.d.ts.map +1 -0
  100. package/dist/types/sync-historical/index.d.ts.map +1 -1
  101. package/dist/types/sync-realtime/index.d.ts +3 -2
  102. package/dist/types/sync-realtime/index.d.ts.map +1 -1
  103. package/dist/types/sync-store/encode.d.ts.map +1 -1
  104. package/dist/types/sync-store/index.d.ts +3 -3
  105. package/dist/types/sync-store/index.d.ts.map +1 -1
  106. package/dist/types/sync-store/schema.d.ts +63 -98
  107. package/dist/types/sync-store/schema.d.ts.map +1 -1
  108. package/dist/types/types/eth.d.ts +2 -8
  109. package/dist/types/types/eth.d.ts.map +1 -1
  110. package/dist/types/utils/finality.d.ts +12 -9
  111. package/dist/types/utils/finality.d.ts.map +1 -1
  112. package/dist/types/utils/pglite.d.ts +0 -18
  113. package/dist/types/utils/pglite.d.ts.map +1 -1
  114. package/package.json +5 -11
  115. package/src/bin/commands/codegen.ts +3 -3
  116. package/src/bin/commands/dev.ts +3 -3
  117. package/src/bin/commands/serve.ts +3 -3
  118. package/src/bin/commands/start.ts +3 -3
  119. package/src/build/config.ts +29 -28
  120. package/src/build/index.ts +88 -71
  121. package/src/build/plugin.ts +6 -0
  122. package/src/build/stacktrace.ts +38 -65
  123. package/src/config/index.ts +12 -2
  124. package/src/database/index.ts +132 -89
  125. package/src/index.ts +5 -0
  126. package/src/indexing/client.ts +56 -40
  127. package/src/indexing/index.ts +4 -1
  128. package/src/internal/types.ts +10 -13
  129. package/src/rpc/actions.ts +211 -77
  130. package/src/runtime/events.ts +40 -19
  131. package/src/runtime/filter.ts +11 -11
  132. package/src/runtime/fragments.ts +70 -26
  133. package/src/runtime/historical.ts +314 -97
  134. package/src/runtime/index.ts +27 -14
  135. package/src/runtime/isolated.ts +1 -0
  136. package/src/runtime/multichain.ts +1 -0
  137. package/src/runtime/omnichain.ts +1 -0
  138. package/src/runtime/realtime.ts +24 -25
  139. package/src/server/index.ts +14 -7
  140. package/src/sync-historical/in-memory.ts +834 -0
  141. package/src/sync-historical/index.ts +76 -120
  142. package/src/sync-realtime/index.ts +73 -133
  143. package/src/sync-store/encode.ts +1 -6
  144. package/src/sync-store/index.ts +90 -95
  145. package/src/sync-store/schema.ts +24 -27
  146. package/src/types/eth.ts +2 -8
  147. package/src/utils/finality.ts +67 -34
  148. package/src/utils/pglite.ts +0 -79
  149. package/dist/esm/sync-store/migrations.js +0 -1595
  150. package/dist/esm/sync-store/migrations.js.map +0 -1
  151. package/dist/types/sync-store/migrations.d.ts +0 -8
  152. package/dist/types/sync-store/migrations.d.ts.map +0 -1
  153. package/src/sync-store/migrations.ts +0 -1801
@@ -1,8 +1,10 @@
1
+ import fs from "node:fs";
1
2
  import type { PGlite } from "@electric-sql/pglite";
2
3
  import {
3
4
  eq,
4
5
  getTableName,
5
6
  getViewName,
7
+ inArray,
6
8
  isTable,
7
9
  isView,
8
10
  sql,
@@ -10,7 +12,6 @@ import {
10
12
  import { drizzle as drizzleNodePg } from "drizzle-orm/node-postgres";
11
13
  import { pgSchema, pgTable } from "drizzle-orm/pg-core";
12
14
  import { drizzle as drizzlePglite } from "drizzle-orm/pglite";
13
- import { Kysely, Migrator, PostgresDialect, WithSchemaPlugin } from "kysely";
14
15
  import type { Pool } from "pg";
15
16
  import prometheus from "prom-client";
16
17
  import { hexToBigInt } from "viem";
@@ -22,11 +23,7 @@ import {
22
23
  getReorgTableName,
23
24
  } from "@/drizzle/onchain.js";
24
25
  import type { Common } from "@/internal/common.js";
25
- import {
26
- MigrationError,
27
- NonRetryableUserError,
28
- ShutdownError,
29
- } from "@/internal/errors.js";
26
+ import { MigrationError, UniqueConstraintError } from "@/internal/errors.js";
30
27
  import type {
31
28
  CrashRecoveryCheckpoint,
32
29
  IndexingBuild,
@@ -34,12 +31,11 @@ import type {
34
31
  PreBuild,
35
32
  SchemaBuild,
36
33
  } from "@/internal/types.js";
37
- import { buildMigrationProvider } from "@/sync-store/migrations.js";
38
34
  import * as PONDER_SYNC from "@/sync-store/schema.js";
39
35
  import { decodeCheckpoint } from "@/utils/checkpoint.js";
40
36
  import { formatEta } from "@/utils/format.js";
41
37
  import { createPool, createReadonlyPool } from "@/utils/pg.js";
42
- import { createPglite, createPgliteKyselyDialect } from "@/utils/pglite.js";
38
+ import { createPglite } from "@/utils/pglite.js";
43
39
  import { startClock } from "@/utils/timer.js";
44
40
  import { wait } from "@/utils/wait.js";
45
41
  import {
@@ -48,7 +44,7 @@ import {
48
44
  dropLiveQueryTriggers,
49
45
  dropTriggers,
50
46
  } from "./actions.js";
51
- import { createQB, parseDbError, type QB } from "./queryBuilder.js";
47
+ import { createQB, type QB } from "./queryBuilder.js";
52
48
 
53
49
  export type Database = {
54
50
  driver: PostgresDriver | PGliteDriver;
@@ -91,6 +87,11 @@ export const VIEWS = pgSchema("information_schema").table("views", (t) => ({
91
87
  table_schema: t.text().notNull(),
92
88
  }));
93
89
 
90
+ const LEGACY_MIGRATIONS = pgSchema("ponder_sync").table(
91
+ "kysely_migration",
92
+ (t) => ({ name: t.text().primaryKey() }),
93
+ );
94
+
94
95
  export const PONDER_META_TABLE_NAME = "_ponder_meta";
95
96
  /**
96
97
  * @dev Used since version 0.11.
@@ -420,90 +421,132 @@ export const createDatabase = ({
420
421
  userQB,
421
422
  readonlyQB,
422
423
  async migrateSync() {
423
- const kysely = new Kysely({
424
- dialect:
425
- dialect === "postgres"
426
- ? new PostgresDialect({ pool: (driver as PostgresDriver).admin })
427
- : createPgliteKyselyDialect((driver as PGliteDriver).instance),
428
- log(event) {
429
- if (event.level === "query") {
430
- common.metrics.ponder_postgres_query_total.inc({ pool: "migrate" });
431
- }
432
- },
433
- plugins: [new WithSchemaPlugin("ponder_sync")],
434
- });
435
-
436
- const migrationProvider = buildMigrationProvider(common.logger);
437
- const migrator = new Migrator({
438
- db: kysely,
439
- provider: migrationProvider,
440
- migrationTableSchema: "ponder_sync",
441
- });
442
-
443
- // Note: inline operation of database wrapper because this is the only place where kysely is used
444
- for (let i = 0; i <= 9; i++) {
445
- const endClock = startClock();
446
- try {
447
- const { error } = await migrator.migrateToLatest();
448
- if (error) throw error;
449
-
450
- common.metrics.ponder_database_method_duration.observe(
451
- { method: "migrate_sync" },
452
- endClock(),
453
- );
454
-
455
- return;
456
- } catch (_error) {
457
- const error = parseDbError(_error);
458
-
459
- if (common.shutdown.isKilled) {
460
- throw new ShutdownError();
461
- }
462
-
463
- common.metrics.ponder_database_method_duration.observe(
464
- { method: "migrate_sync" },
465
- endClock(),
466
- );
467
- common.metrics.ponder_database_method_error_total.inc({
468
- method: "migrate_sync",
469
- });
470
-
471
- common.logger.warn({
472
- msg: "Failed database query",
473
- query: "migrate_sync",
474
- retry_count: i,
475
- error,
476
- });
424
+ // Use a separate Drizzle instance because createQB skips PGlite transactions.
425
+ const db =
426
+ driver.dialect === "postgres"
427
+ ? drizzleNodePg(driver.admin, { casing: "snake_case" })
428
+ : drizzlePglite(driver.instance, { casing: "snake_case" });
429
+
430
+ const migratedSchemas = await adminQB
431
+ .wrap({ label: "migrate_sync" }, () =>
432
+ db.transaction(
433
+ async (tx) => {
434
+ await tx.execute(sql`SET LOCAL statement_timeout = 3600000`);
435
+
436
+ const dbSchemas = await tx
437
+ .select()
438
+ .from(SCHEMATA)
439
+ .where(
440
+ inArray(SCHEMATA.schemaName, [
441
+ ...PONDER_SYNC.PONDER_SYNC_SCHEMAS,
442
+ ]),
443
+ )
444
+ .then((result) => result.map((r) => r.schemaName));
445
+
446
+ if (dbSchemas.includes("ponder_sync")) {
447
+ const migrations = await tx.select().from(LEGACY_MIGRATIONS);
448
+
449
+ if (
450
+ migrations.some(
451
+ (migration) =>
452
+ migration.name === "2025_02_26_1_rpc_request_results",
453
+ ) === false
454
+ ) {
455
+ throw new MigrationError(
456
+ '"ponder_sync" migration failed. Please first update to v0.10 or "DROP SCHEMA ponder_sync CASCADE".',
457
+ );
458
+ }
459
+ }
477
460
 
478
- if (error instanceof NonRetryableUserError) {
479
- common.logger.warn({
480
- msg: "Failed database query",
481
- query: "migrate_sync",
482
- error,
483
- });
484
- throw error;
485
- }
461
+ const migratedSchemas: { schema: string; duration: number }[] =
462
+ [];
463
+ // Note: Run the migrations after the latest existing schema. A new
464
+ // database only creates the latest schema, and does not copy data.
465
+ let latestIndex = -1;
466
+ for (let i = 0; i < PONDER_SYNC.PONDER_SYNC_SCHEMAS.length; i++) {
467
+ if (dbSchemas.includes(PONDER_SYNC.PONDER_SYNC_SCHEMAS[i]!)) {
468
+ latestIndex = i;
469
+ }
470
+ }
471
+ const isNewDatabase = latestIndex === -1;
472
+ const schemasToMigrate = isNewDatabase
473
+ ? [PONDER_SYNC.PONDER_SYNC_SCHEMA]
474
+ : PONDER_SYNC.PONDER_SYNC_SCHEMAS.slice(latestIndex + 1);
475
+
476
+ for (const schema of schemasToMigrate) {
477
+ const endSchemaClock = startClock();
478
+
479
+ const files = isNewDatabase
480
+ ? ["create.sql"]
481
+ : ["create.sql", "copy.sql"];
482
+ const statements = files.flatMap((file) =>
483
+ fs
484
+ .readFileSync(
485
+ new URL(
486
+ `../sync-store/sql/${schema}/${file}`,
487
+ import.meta.url,
488
+ ),
489
+ "utf-8",
490
+ )
491
+ .split("--> statement-breakpoint")
492
+ .map((statement) => statement.trim())
493
+ .filter((statement) => statement.length > 0),
494
+ );
486
495
 
487
- if (i === 9) {
488
- common.logger.warn({
489
- msg: "Failed database query",
490
- query: "migrate_sync",
491
- retry_count: i,
492
- error,
493
- });
494
- throw error;
496
+ common.logger.info({
497
+ msg: `Started migrating '${schema}' schema`,
498
+ statement_count: statements.length,
499
+ });
500
+
501
+ for (let i = 0; i < statements.length; i++) {
502
+ const statement = statements[i]!;
503
+ // Log only the first non-comment line; CREATE TABLE statements span many lines.
504
+ const summary = (
505
+ statement
506
+ .split("\n")
507
+ .find((line) => line.startsWith("--") === false) ?? ""
508
+ ).slice(0, 120);
509
+
510
+ common.logger.debug({
511
+ msg: "Started migration statement",
512
+ schema,
513
+ statement_index: i,
514
+ statement: summary,
515
+ });
516
+
517
+ const endClock = startClock();
518
+ await tx.execute(sql.raw(statement));
519
+
520
+ common.logger.debug({
521
+ msg: "Completed migration statement",
522
+ schema,
523
+ statement_index: i,
524
+ statement: summary,
525
+ duration: endClock(),
526
+ });
527
+ }
528
+ migratedSchemas.push({ schema, duration: endSchemaClock() });
529
+ }
530
+ return migratedSchemas;
531
+ },
532
+ { isolationLevel: "repeatable read" },
533
+ ),
534
+ )
535
+ .catch((error) => {
536
+ // Note: Concurrent startups wait on `CREATE SCHEMA` until the first one
537
+ // commits, then fail with a unique violation. The first startup migrated
538
+ // the schemas.
539
+ if (
540
+ error instanceof UniqueConstraintError &&
541
+ error.message.includes("pg_namespace_nspname_index")
542
+ ) {
543
+ return [];
495
544
  }
545
+ throw error;
546
+ });
496
547
 
497
- const duration = 125 * 2 ** i;
498
- common.logger.debug({
499
- msg: "Failed database query",
500
- query: "migrate_sync",
501
- retry_count: i,
502
- retry_delay: duration,
503
- error,
504
- });
505
- await wait(duration);
506
- }
548
+ for (const { schema, duration } of migratedSchemas) {
549
+ common.logger.info({ msg: `Migrated '${schema}' schema`, duration });
507
550
  }
508
551
  },
509
552
  async migrate({ buildId, chains, finalizedBlocks }) {
package/src/index.ts CHANGED
@@ -129,3 +129,8 @@ export {
129
129
  } from "@/drizzle/onchain.js";
130
130
  export { graphql } from "@/graphql/middleware.js";
131
131
  export type { ReadonlyDrizzle } from "@/types/db.js";
132
+ export {
133
+ type Checkpoint,
134
+ decodeCheckpoint,
135
+ encodeCheckpoint,
136
+ } from "@/utils/checkpoint.js";
@@ -734,26 +734,30 @@ export const createCachedViemClient = ({
734
734
  ({ ev }) => ev > DB_PREDICTION_THRESHOLD,
735
735
  );
736
736
 
737
- common.metrics.ponder_indexing_rpc_prefetch_total.inc(
738
- {
739
- chain: chain.name,
740
- method: "eth_call",
741
- type: "database",
742
- },
743
- dbRequests.length,
744
- );
737
+ // Note: Without the rpc request cache, all requests miss the database.
738
+ let cachedResults: (string | undefined)[] = [];
739
+ if (chain.cacheRpcRequests) {
740
+ common.metrics.ponder_indexing_rpc_prefetch_total.inc(
741
+ {
742
+ chain: chain.name,
743
+ method: "eth_call",
744
+ type: "database",
745
+ },
746
+ dbRequests.length,
747
+ );
745
748
 
746
- const cachedResults = await syncStore.getRpcRequestResults(
747
- {
748
- requests: dbRequests.map(({ request }) => request),
749
- chainId,
750
- },
751
- context,
752
- );
749
+ cachedResults = await syncStore.getRpcRequestResults(
750
+ {
751
+ requests: dbRequests.map(({ request }) => request),
752
+ chainId,
753
+ },
754
+ context,
755
+ );
756
+ }
753
757
 
754
758
  for (let i = 0; i < dbRequests.length; i++) {
755
759
  const request = dbRequests[i]!;
756
- const cachedResult = cachedResults[i]!;
760
+ const cachedResult = cachedResults[i];
757
761
 
758
762
  if (cachedResult !== undefined) {
759
763
  cache
@@ -916,14 +920,16 @@ export const cachedTransport =
916
920
  (request) => results.has(request) === false,
917
921
  );
918
922
 
919
- const dbResults = await syncStore.getRpcRequestResults(
920
- { requests: dbRequests, chainId: chain.id },
921
- context,
922
- );
923
+ const dbResults = chain.cacheRpcRequests
924
+ ? await syncStore.getRpcRequestResults(
925
+ { requests: dbRequests, chainId: chain.id },
926
+ context,
927
+ )
928
+ : [];
923
929
 
924
930
  for (let i = 0; i < dbRequests.length; i++) {
925
931
  const request = dbRequests[i]!;
926
- const result = dbResults[i]!;
932
+ const result = dbResults[i];
927
933
 
928
934
  if (result !== undefined) {
929
935
  common.metrics.ponder_indexing_rpc_requests_total.inc({
@@ -1004,19 +1010,21 @@ export const cachedTransport =
1004
1010
 
1005
1011
  // Note: insertRpcRequestResults errors can be ignored and not awaited, since
1006
1012
  // the response is already fetched.
1007
- syncStore
1008
- .insertRpcRequestResults(
1009
- {
1010
- requests: Array.from(requestsToInsert).map((request) => ({
1011
- request,
1012
- blockNumber: encodedBlockNumber,
1013
- result: JSON.stringify(results.get(request)!.returnData),
1014
- })),
1015
- chainId: chain.id,
1016
- },
1017
- context,
1018
- )
1019
- .catch(() => {});
1013
+ if (chain.cacheRpcRequests) {
1014
+ syncStore
1015
+ .insertRpcRequestResults(
1016
+ {
1017
+ requests: Array.from(requestsToInsert).map((request) => ({
1018
+ request,
1019
+ blockNumber: encodedBlockNumber,
1020
+ result: JSON.stringify(results.get(request)!.returnData),
1021
+ })),
1022
+ chainId: chain.id,
1023
+ },
1024
+ context,
1025
+ )
1026
+ .catch(() => {});
1027
+ }
1020
1028
 
1021
1029
  // Note: at this point, it is an invariant that either `allowFailure` is true or
1022
1030
  // there are no failed requests.
@@ -1073,7 +1081,10 @@ export const cachedTransport =
1073
1081
 
1074
1082
  if (result instanceof Error) throw result;
1075
1083
 
1076
- if (UNCACHED_RESPONSES.includes(result) === false) {
1084
+ if (
1085
+ chain.cacheRpcRequests &&
1086
+ UNCACHED_RESPONSES.includes(result) === false
1087
+ ) {
1077
1088
  // Note: insertRpcRequestResults errors can be ignored and not awaited, since
1078
1089
  // the response is already fetched.
1079
1090
  syncStore
@@ -1105,10 +1116,12 @@ export const cachedTransport =
1105
1116
  return decodeResponse(cachedResult);
1106
1117
  }
1107
1118
 
1108
- const [cachedResult] = await syncStore.getRpcRequestResults(
1109
- { requests: [body], chainId: chain.id },
1110
- context,
1111
- );
1119
+ const [cachedResult] = chain.cacheRpcRequests
1120
+ ? await syncStore.getRpcRequestResults(
1121
+ { requests: [body], chainId: chain.id },
1122
+ context,
1123
+ )
1124
+ : [undefined];
1112
1125
 
1113
1126
  if (cachedResult !== undefined) {
1114
1127
  common.metrics.ponder_indexing_rpc_requests_total.inc({
@@ -1128,7 +1141,10 @@ export const cachedTransport =
1128
1141
 
1129
1142
  const response = await rpc.request(body, context);
1130
1143
 
1131
- if (UNCACHED_RESPONSES.includes(response) === false) {
1144
+ if (
1145
+ chain.cacheRpcRequests &&
1146
+ UNCACHED_RESPONSES.includes(response) === false
1147
+ ) {
1132
1148
  // Note: insertRpcRequestResults errors can be ignored and not awaited, since
1133
1149
  // the response is already fetched.
1134
1150
  syncStore
@@ -970,7 +970,10 @@ const logText = (log?: DeepPartial<UserLog>) =>
970
970
 
971
971
  const traceText = (trace?: DeepPartial<UserTrace>) =>
972
972
  `Trace:\n${prettyPrint({
973
- traceIndex: trace?.traceIndex,
973
+ traceAddress:
974
+ trace?.traceAddress === undefined
975
+ ? undefined
976
+ : JSON.stringify(trace.traceAddress),
974
977
  from: trace?.from,
975
978
  to: trace?.to,
976
979
  })}`;
@@ -60,10 +60,6 @@ export type Filter =
60
60
 
61
61
  /**
62
62
  * Filter that matches addresses.
63
- *
64
- * @dev This object is used as a unique constraint in the `ponder_sync.factories` table.
65
- * Any changes to the type must be backwards compatible and probably requires updating
66
- * `syncStore.getChildAddresses` and `syncStore.insertChildAddresses`.
67
63
  */
68
64
  export type Factory = LogFactory;
69
65
  export type FilterAddress<
@@ -91,7 +87,6 @@ export type TransactionFilter<
91
87
  sourceId: string;
92
88
  fromAddress: FilterAddress<fromFactory>;
93
89
  toAddress: FilterAddress<toFactory>;
94
- includeReverted: boolean;
95
90
  fromBlock: number | undefined;
96
91
  toBlock: number | undefined;
97
92
  hasTransactionReceipt: true;
@@ -113,7 +108,6 @@ export type TraceFilter<
113
108
  toAddress: FilterAddress<toFactory>;
114
109
  functionSelector: Hex;
115
110
  callType: Trace["type"] | undefined;
116
- includeReverted: boolean;
117
111
  fromBlock: number | undefined;
118
112
  toBlock: number | undefined;
119
113
  hasTransactionReceipt: boolean;
@@ -156,7 +150,6 @@ export type TransferFilter<
156
150
  sourceId: string;
157
151
  fromAddress: FilterAddress<fromFactory>;
158
152
  toAddress: FilterAddress<toFactory>;
159
- includeReverted: boolean;
160
153
  fromBlock: number | undefined;
161
154
  toBlock: number | undefined;
162
155
  hasTransactionReceipt: boolean;
@@ -190,12 +183,14 @@ export type FragmentAddress =
190
183
  address: Address | null;
191
184
  eventSelector: Factory["eventSelector"];
192
185
  childAddressLocation: Factory["childAddressLocation"];
186
+ fromBlock: number | null;
187
+ toBlock: number | null;
193
188
  }
194
189
  | null;
195
190
 
196
191
  export type FragmentAddressId =
197
192
  | Address
198
- | `${Address | null}_${Factory["eventSelector"]}_${Factory["childAddressLocation"]}`
193
+ | `${Address | null}_${Factory["eventSelector"]}_${Factory["childAddressLocation"]}_${number | null}_${number | null}`
199
194
  | null;
200
195
  export type FragmentTopic = Hex | null;
201
196
 
@@ -262,7 +257,10 @@ export type FragmentId =
262
257
  /** factory_log_{chainId}_{address}_{eventSelector}_{childAddressLocation}_{fromBlock}_{toBlock} */
263
258
  | `factory_log_${number}_${Address | null}_${Factory["eventSelector"]}_${Factory["childAddressLocation"]}_${number | null}_${number | null}`;
264
259
 
260
+ export type FactoryFragmentId = Extract<FragmentId, `factory_${string}`>;
261
+
265
262
  // Contract
263
+
266
264
  export type Contract = {
267
265
  abi: Abi;
268
266
  address?: Address | readonly Address[];
@@ -302,8 +300,8 @@ export type Chain = {
302
300
  rpc: string | string[] | Transport;
303
301
  ws: string | undefined;
304
302
  pollingInterval: number;
305
- finalityBlockCount: number;
306
- disableCache: boolean;
303
+ reorgWindow: number;
304
+ cacheRpcRequests: boolean;
307
305
  ethGetLogsBlockRange: number | undefined;
308
306
  viemChain: ViemChain | undefined;
309
307
  };
@@ -410,7 +408,7 @@ export type SyncBlockHeader = Omit<SyncBlock, "transactions"> & {
410
408
  export type SyncTransaction = RpcTransaction<false>;
411
409
  export type SyncTransactionReceipt = RpcTransactionReceipt;
412
410
  export type SyncTrace = {
413
- trace: DebugTrace["result"] & { index: number; subcalls: number };
411
+ trace: DebugTrace["result"] & { traceAddress: number[] };
414
412
  transactionHash: DebugTrace["txHash"];
415
413
  };
416
414
  export type SyncLog = ViemLog<Hex, Hex, false>;
@@ -435,8 +433,7 @@ export type RequiredTraceColumns =
435
433
  | "output"
436
434
  | "value"
437
435
  | "type"
438
- | "error"
439
- | "traceIndex";
436
+ | "traceAddress";
440
437
  export type RequiredLogColumns = keyof Log;
441
438
 
442
439
  export type RequiredInternalBlockColumns = RequiredBlockColumns;