From c1d0f395ccf390bea6c268970403178ec504e9b3 Mon Sep 17 00:00:00 2001 From: Rod Vagg Date: Thu, 10 Sep 2026 22:44:54 +1000 Subject: [PATCH] feat(indexer): fetch v3.5.0 and v1.4.0 events from their upgrade blocks Duplicate contract addresses but for the new versions so we can start from their upgrade blocks rather than from the complete START. --- indexer/ponder.config.ts | 16 ++++++++++++ indexer/src/fwss.ts | 2 +- indexer/src/networks.ts | 7 +++++ indexer/src/pdp-verifier.ts | 4 +-- indexer/test/networks.test.ts | 4 +++ indexer/test/upgrade-entries.test.ts | 38 ++++++++++++++++++++++++++++ 6 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 indexer/test/upgrade-entries.test.ts diff --git a/indexer/ponder.config.ts b/indexer/ponder.config.ts index 147e170..61d07c6 100644 --- a/indexer/ponder.config.ts +++ b/indexer/ponder.config.ts @@ -58,6 +58,14 @@ export default createConfig({ startBlock: network.START_BLOCK, includeTransactionReceipts: true, }, + // v3.5.0 events (PiecesAddedV2, PiecesScheduledForRemoval): same address, fetched only from the upgrade. + PDPVerifierV35: { + abi: PDPVerifierAbi, + chain: networkName, + address: network.PDP_VERIFIER, + startBlock: network.PDP_VERIFIER_V3_5_BLOCK, + includeTransactionReceipts: true, + }, FWSS: { abi: FilecoinWarmStorageServiceAbi, chain: networkName, @@ -65,6 +73,14 @@ export default createConfig({ startBlock: network.START_BLOCK, includeTransactionReceipts: true, }, + // v1.4.0 events (DataSetAuthorizerSet), likewise. + FWSSV14: { + abi: FilecoinWarmStorageServiceAbi, + chain: networkName, + address: network.FWSS, + startBlock: network.FWSS_V1_4_BLOCK, + includeTransactionReceipts: true, + }, FilecoinPay: { abi: FilecoinPayV1Abi, chain: networkName, diff --git a/indexer/src/fwss.ts b/indexer/src/fwss.ts index ba1f02b..88e93cc 100644 --- a/indexer/src/fwss.ts +++ b/indexer/src/fwss.ts @@ -145,7 +145,7 @@ ponder.on("FWSS:DataSetServiceProviderChanged", async ({ event, context }) => { .values({ id: eventId(event), dataSetId, oldServiceProvider, newServiceProvider, ...eventMeta(event) }) }) -ponder.on("FWSS:DataSetAuthorizerSet", async ({ event, context }) => { +ponder.on("FWSSV14:DataSetAuthorizerSet", async ({ event, context }) => { await recordTx(event, context) const { dataSetId, authorizer } = event.args await context.db diff --git a/indexer/src/networks.ts b/indexer/src/networks.ts index 1af0144..f9c0dc1 100644 --- a/indexer/src/networks.ts +++ b/indexer/src/networks.ts @@ -5,6 +5,9 @@ type Network = { DATABASE_URL: string RPC_URL: string START_BLOCK: number + // Upgrade blocks: ponder.config.ts entries start here so new events fetch only where they exist. + PDP_VERIFIER_V3_5_BLOCK: number + FWSS_V1_4_BLOCK: number PDP_VERIFIER: `0x${string}` FWSS: `0x${string}` FILECOIN_PAY: `0x${string}` @@ -22,6 +25,8 @@ export const MAINNET = { RPC_URL: "http://localhost:1234/rpc/v1", // v1.0.0 deployed ~epoch 5,220,000 on mainnet (Nov 2, 2025). Start slightly before. START_BLOCK: 5_215_000, + PDP_VERIFIER_V3_5_BLOCK: 6_338_104, + FWSS_V1_4_BLOCK: 6_338_200, PDP_VERIFIER: "0xBADd0B92C1c71d02E7d520f64c0876538fa2557F", FWSS: "0x8408502033C418E1bbC97cE9ac48E5528F371A9f", FILECOIN_PAY: "0x23b1e018F08BB982348b15a86ee926eEBf7F4DAa", @@ -45,6 +50,8 @@ export const CALIBNET = { // Snapshot floor is 3,090,000 (null round); start +2 so the parent is valid. // Captures FilecoinPay rail 1 (3,125,305) and PDPVerifier sets 1-48 (3,144,601 onward). START_BLOCK: 3_090_002, + PDP_VERIFIER_V3_5_BLOCK: 4_028_982, + FWSS_V1_4_BLOCK: 4_029_095, PDP_VERIFIER: "0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C", FWSS: "0x02925630df557F957f70E112bA06e50965417CA0", FILECOIN_PAY: "0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0", diff --git a/indexer/src/pdp-verifier.ts b/indexer/src/pdp-verifier.ts index 279dcde..b2283bb 100644 --- a/indexer/src/pdp-verifier.ts +++ b/indexer/src/pdp-verifier.ts @@ -87,7 +87,7 @@ ponder.on("PDPVerifier:PiecesAdded", async ({ event, context }) => { .values({ id: eventId(event), setId, pieceCount: pieceIds.length, pieces, ...eventMeta(event) }) }) -ponder.on("PDPVerifier:PiecesAddedV2", async ({ event, context }) => { +ponder.on("PDPVerifierV35:PiecesAddedV2", async ({ event, context }) => { await recordTx(event, context) const { setId, firstPieceId, pieceCids: pieceCidsRaw } = event.args @@ -112,7 +112,7 @@ ponder.on("PDPVerifier:PiecesRemoved", async ({ event, context }) => { .values({ id: eventId(event), setId, pieceCount: pieceIds.length, pieceIds: pieceIdArr, ...eventMeta(event) }) }) -ponder.on("PDPVerifier:PiecesScheduledForRemoval", async ({ event, context }) => { +ponder.on("PDPVerifierV35:PiecesScheduledForRemoval", async ({ event, context }) => { await recordTx(event, context) const { setId, pieceIds } = event.args const pieceIdArr = pieceIds.length > 0 ? JSON.stringify(pieceIds.map((id: bigint) => Number(id))) : null diff --git a/indexer/test/networks.test.ts b/indexer/test/networks.test.ts index d69f3ce..b3066b8 100644 --- a/indexer/test/networks.test.ts +++ b/indexer/test/networks.test.ts @@ -81,6 +81,8 @@ test("network registry preserves mainnet deployment configuration", () => { DATABASE_URL: "postgres://ponder:ponder@localhost:17826/ponder", RPC_URL: "http://localhost:1234/rpc/v1", START_BLOCK: 5_215_000, + PDP_VERIFIER_V3_5_BLOCK: 6_338_104, + FWSS_V1_4_BLOCK: 6_338_200, PDP_VERIFIER: "0xBADd0B92C1c71d02E7d520f64c0876538fa2557F", FWSS: "0x8408502033C418E1bbC97cE9ac48E5528F371A9f", FILECOIN_PAY: "0x23b1e018F08BB982348b15a86ee926eEBf7F4DAa", @@ -101,6 +103,8 @@ test("network registry preserves calibnet deployment configuration", () => { DATABASE_URL: "postgres://ponder:ponder@localhost:17825/ponder", RPC_URL: "http://localhost:1235/rpc/v1", START_BLOCK: 3_090_002, + PDP_VERIFIER_V3_5_BLOCK: 4_028_982, + FWSS_V1_4_BLOCK: 4_029_095, PDP_VERIFIER: "0x85e366Cf9DD2c0aE37E963d9556F5f4718d6417C", FWSS: "0x02925630df557F957f70E112bA06e50965417CA0", FILECOIN_PAY: "0x09a0fDc2723fAd1A7b8e3e00eE5DF73841df55a0", diff --git a/indexer/test/upgrade-entries.test.ts b/indexer/test/upgrade-entries.test.ts new file mode 100644 index 0000000..0748230 --- /dev/null +++ b/indexer/test/upgrade-entries.test.ts @@ -0,0 +1,38 @@ +import assert from "node:assert/strict" +import { spawnSync } from "node:child_process" +import { test } from "node:test" + +// PDPVerifierV35 and FWSSV14 share an address with their parent entries but start at +// the upgrade that introduced their events, so those fragments fetch only the range +// where the events can exist. +const configUrl = new URL("../ponder.config.ts", import.meta.url).href +const script = ` +const c = (await import(${JSON.stringify(configUrl)})).default.contracts +const pick = (e) => ({ address: e.address, startBlock: e.startBlock }) +console.log(JSON.stringify({ + PDPVerifier: pick(c.PDPVerifier), PDPVerifierV35: pick(c.PDPVerifierV35), + FWSS: pick(c.FWSS), FWSSV14: pick(c.FWSSV14), +})) +` + +function contracts(network: string) { + const env: NodeJS.ProcessEnv = { ...process.env, NODE_NO_WARNINGS: "1", PONDER_NETWORK: network } + env.DATABASE_URL = "postgres://noop:noop@localhost:5432/noop" + env.RPC_URL = "http://localhost:1234/rpc/v1" + delete env.PONDER_STRICT_ENV + const r = spawnSync(process.execPath, ["--experimental-strip-types", "--input-type=module", "--eval", script], { encoding: "utf8", env }) + assert.equal(r.status, 0, r.stderr) + return JSON.parse(r.stdout.trim().split("\n").at(-1)!) +} + +for (const network of ["mainnet", "calibnet"]) { + test(`${network}: upgrade entries share their parent's address and start later`, () => { + const c = contracts(network) + assert.equal(c.PDPVerifierV35.address, c.PDPVerifier.address) + assert.ok(c.PDPVerifierV35.startBlock > c.PDPVerifier.startBlock, "PDPVerifierV35 must start after PDPVerifier") + assert.equal(c.FWSSV14.address, c.FWSS.address) + assert.ok(c.FWSSV14.startBlock > c.FWSS.startBlock, "FWSSV14 must start after FWSS") + // FWSS v1.4.0 executed after PDPVerifier v3.5.0 on both networks. + assert.ok(c.FWSSV14.startBlock > c.PDPVerifierV35.startBlock) + }) +}