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.
- package/CHANGELOG.md +20 -0
- package/dist/esm/bin/commands/codegen.js +3 -3
- package/dist/esm/bin/commands/codegen.js.map +1 -1
- package/dist/esm/bin/commands/dev.js +3 -3
- package/dist/esm/bin/commands/dev.js.map +1 -1
- package/dist/esm/bin/commands/serve.js +3 -3
- package/dist/esm/bin/commands/serve.js.map +1 -1
- package/dist/esm/bin/commands/start.js +3 -3
- package/dist/esm/bin/commands/start.js.map +1 -1
- package/dist/esm/build/config.js +19 -20
- package/dist/esm/build/config.js.map +1 -1
- package/dist/esm/build/index.js +79 -65
- package/dist/esm/build/index.js.map +1 -1
- package/dist/esm/build/plugin.js +9 -0
- package/dist/esm/build/plugin.js.map +1 -1
- package/dist/esm/build/stacktrace.js +25 -68
- package/dist/esm/build/stacktrace.js.map +1 -1
- package/dist/esm/database/index.js +83 -67
- package/dist/esm/database/index.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/indexing/client.js +35 -23
- package/dist/esm/indexing/client.js.map +1 -1
- package/dist/esm/indexing/index.js +3 -1
- package/dist/esm/indexing/index.js.map +1 -1
- package/dist/esm/rpc/actions.js +143 -67
- package/dist/esm/rpc/actions.js.map +1 -1
- package/dist/esm/runtime/events.js +33 -19
- package/dist/esm/runtime/events.js.map +1 -1
- package/dist/esm/runtime/filter.js +10 -9
- package/dist/esm/runtime/filter.js.map +1 -1
- package/dist/esm/runtime/fragments.js +50 -24
- package/dist/esm/runtime/fragments.js.map +1 -1
- package/dist/esm/runtime/historical.js +212 -68
- package/dist/esm/runtime/historical.js.map +1 -1
- package/dist/esm/runtime/index.js +11 -15
- package/dist/esm/runtime/index.js.map +1 -1
- package/dist/esm/runtime/isolated.js +1 -0
- package/dist/esm/runtime/isolated.js.map +1 -1
- package/dist/esm/runtime/multichain.js +1 -0
- package/dist/esm/runtime/multichain.js.map +1 -1
- package/dist/esm/runtime/omnichain.js +1 -0
- package/dist/esm/runtime/omnichain.js.map +1 -1
- package/dist/esm/runtime/realtime.js +17 -16
- package/dist/esm/runtime/realtime.js.map +1 -1
- package/dist/esm/server/index.js +8 -6
- package/dist/esm/server/index.js.map +1 -1
- package/dist/esm/sync-historical/in-memory.js +539 -0
- package/dist/esm/sync-historical/in-memory.js.map +1 -0
- package/dist/esm/sync-historical/index.js +46 -63
- package/dist/esm/sync-historical/index.js.map +1 -1
- package/dist/esm/sync-realtime/index.js +56 -83
- package/dist/esm/sync-realtime/index.js.map +1 -1
- package/dist/esm/sync-store/encode.js +1 -6
- package/dist/esm/sync-store/encode.js.map +1 -1
- package/dist/esm/sync-store/index.js +58 -62
- package/dist/esm/sync-store/index.js.map +1 -1
- package/dist/esm/sync-store/schema.js +23 -15
- package/dist/esm/sync-store/schema.js.map +1 -1
- package/dist/esm/sync-store/sql/ponder_rpc_cache_1/copy.sql +23 -0
- package/dist/esm/sync-store/sql/ponder_rpc_cache_1/create.sql +130 -0
- package/dist/esm/utils/finality.js +41 -32
- package/dist/esm/utils/finality.js.map +1 -1
- package/dist/esm/utils/pglite.js +0 -65
- package/dist/esm/utils/pglite.js.map +1 -1
- package/dist/types/bin/commands/codegen.d.ts.map +1 -1
- package/dist/types/bin/commands/dev.d.ts.map +1 -1
- package/dist/types/bin/commands/serve.d.ts.map +1 -1
- package/dist/types/bin/commands/start.d.ts.map +1 -1
- package/dist/types/build/config.d.ts.map +1 -1
- package/dist/types/build/index.d.ts.map +1 -1
- package/dist/types/build/plugin.d.ts.map +1 -1
- package/dist/types/build/stacktrace.d.ts +1 -12
- package/dist/types/build/stacktrace.d.ts.map +1 -1
- package/dist/types/config/index.d.ts +12 -2
- package/dist/types/config/index.d.ts.map +1 -1
- package/dist/types/database/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/indexing/client.d.ts.map +1 -1
- package/dist/types/internal/types.d.ts +8 -13
- package/dist/types/internal/types.d.ts.map +1 -1
- package/dist/types/rpc/actions.d.ts +30 -0
- package/dist/types/rpc/actions.d.ts.map +1 -1
- package/dist/types/runtime/events.d.ts.map +1 -1
- package/dist/types/runtime/filter.d.ts.map +1 -1
- package/dist/types/runtime/fragments.d.ts +9 -1
- package/dist/types/runtime/fragments.d.ts.map +1 -1
- package/dist/types/runtime/historical.d.ts +18 -1
- package/dist/types/runtime/historical.d.ts.map +1 -1
- package/dist/types/runtime/index.d.ts +1 -0
- package/dist/types/runtime/index.d.ts.map +1 -1
- package/dist/types/runtime/isolated.d.ts.map +1 -1
- package/dist/types/runtime/multichain.d.ts.map +1 -1
- package/dist/types/runtime/omnichain.d.ts.map +1 -1
- package/dist/types/runtime/realtime.d.ts.map +1 -1
- package/dist/types/server/index.d.ts.map +1 -1
- package/dist/types/sync-historical/in-memory.d.ts +24 -0
- package/dist/types/sync-historical/in-memory.d.ts.map +1 -0
- package/dist/types/sync-historical/index.d.ts.map +1 -1
- package/dist/types/sync-realtime/index.d.ts +3 -2
- package/dist/types/sync-realtime/index.d.ts.map +1 -1
- package/dist/types/sync-store/encode.d.ts.map +1 -1
- package/dist/types/sync-store/index.d.ts +3 -3
- package/dist/types/sync-store/index.d.ts.map +1 -1
- package/dist/types/sync-store/schema.d.ts +63 -98
- package/dist/types/sync-store/schema.d.ts.map +1 -1
- package/dist/types/types/eth.d.ts +2 -8
- package/dist/types/types/eth.d.ts.map +1 -1
- package/dist/types/utils/finality.d.ts +12 -9
- package/dist/types/utils/finality.d.ts.map +1 -1
- package/dist/types/utils/pglite.d.ts +0 -18
- package/dist/types/utils/pglite.d.ts.map +1 -1
- package/package.json +5 -11
- package/src/bin/commands/codegen.ts +3 -3
- package/src/bin/commands/dev.ts +3 -3
- package/src/bin/commands/serve.ts +3 -3
- package/src/bin/commands/start.ts +3 -3
- package/src/build/config.ts +29 -28
- package/src/build/index.ts +88 -71
- package/src/build/plugin.ts +6 -0
- package/src/build/stacktrace.ts +38 -65
- package/src/config/index.ts +12 -2
- package/src/database/index.ts +132 -89
- package/src/index.ts +5 -0
- package/src/indexing/client.ts +56 -40
- package/src/indexing/index.ts +4 -1
- package/src/internal/types.ts +10 -13
- package/src/rpc/actions.ts +211 -77
- package/src/runtime/events.ts +40 -19
- package/src/runtime/filter.ts +11 -11
- package/src/runtime/fragments.ts +70 -26
- package/src/runtime/historical.ts +314 -97
- package/src/runtime/index.ts +27 -14
- package/src/runtime/isolated.ts +1 -0
- package/src/runtime/multichain.ts +1 -0
- package/src/runtime/omnichain.ts +1 -0
- package/src/runtime/realtime.ts +24 -25
- package/src/server/index.ts +14 -7
- package/src/sync-historical/in-memory.ts +834 -0
- package/src/sync-historical/index.ts +76 -120
- package/src/sync-realtime/index.ts +73 -133
- package/src/sync-store/encode.ts +1 -6
- package/src/sync-store/index.ts +90 -95
- package/src/sync-store/schema.ts +24 -27
- package/src/types/eth.ts +2 -8
- package/src/utils/finality.ts +67 -34
- package/src/utils/pglite.ts +0 -79
- package/dist/esm/sync-store/migrations.js +0 -1595
- package/dist/esm/sync-store/migrations.js.map +0 -1
- package/dist/types/sync-store/migrations.d.ts +0 -8
- package/dist/types/sync-store/migrations.d.ts.map +0 -1
- package/src/sync-store/migrations.ts +0 -1801
package/src/database/index.ts
CHANGED
|
@@ -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
|
|
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,
|
|
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
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
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
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
498
|
-
|
|
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";
|
package/src/indexing/client.ts
CHANGED
|
@@ -734,26 +734,30 @@ export const createCachedViemClient = ({
|
|
|
734
734
|
({ ev }) => ev > DB_PREDICTION_THRESHOLD,
|
|
735
735
|
);
|
|
736
736
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
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
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
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 =
|
|
920
|
-
|
|
921
|
-
|
|
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
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
request
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
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 (
|
|
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] =
|
|
1109
|
-
|
|
1110
|
-
|
|
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 (
|
|
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
|
package/src/indexing/index.ts
CHANGED
|
@@ -970,7 +970,10 @@ const logText = (log?: DeepPartial<UserLog>) =>
|
|
|
970
970
|
|
|
971
971
|
const traceText = (trace?: DeepPartial<UserTrace>) =>
|
|
972
972
|
`Trace:\n${prettyPrint({
|
|
973
|
-
|
|
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
|
})}`;
|
package/src/internal/types.ts
CHANGED
|
@@ -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
|
-
|
|
306
|
-
|
|
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"] & {
|
|
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
|
-
| "
|
|
439
|
-
| "traceIndex";
|
|
436
|
+
| "traceAddress";
|
|
440
437
|
export type RequiredLogColumns = keyof Log;
|
|
441
438
|
|
|
442
439
|
export type RequiredInternalBlockColumns = RequiredBlockColumns;
|