From 8b9cee2dd3a0589a0474659b9898e2e65268dc73 Mon Sep 17 00:00:00 2001 From: Luiz Gustavo Abou Hatem de Liz Date: Tue, 2 Jun 2026 11:03:37 -0300 Subject: [PATCH 1/3] fix: rename progressPct to historicalSyncProgressPct in sync-progress API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes the field name self-documenting — it clearly tracks historical block-fetch progress (not handler completion), consistent with the distinction between progressPct=100 and isComplete=false. Co-Authored-By: Claude Sonnet 4.6 --- src/api/endpoints/sync-progress.ts | 4 ++-- src/api/routes.ts | 2 +- src/api/schemas/sync-progress.ts | 2 +- tests/api/sync-progress.test.ts | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/api/endpoints/sync-progress.ts b/src/api/endpoints/sync-progress.ts index c72bb35..998074e 100644 --- a/src/api/endpoints/sync-progress.ts +++ b/src/api/endpoints/sync-progress.ts @@ -56,7 +56,7 @@ export const syncProgressHandler: RouteHandler = { totalBlocks: number; processedBlocks: number; - progressPct: number; + historicalSyncProgressPct: number; isRealtime: boolean; isComplete: boolean; } @@ -72,7 +72,7 @@ export const syncProgressHandler: RouteHandler = result[chain] = { totalBlocks: t, processedBlocks: processed, - progressPct: pct, + historicalSyncProgressPct: pct, isRealtime: (isRealtime.get(chain) ?? 0) === 1, isComplete: (isComplete.get(chain) ?? 0) === 1, }; diff --git a/src/api/routes.ts b/src/api/routes.ts index cc7b777..a0a7c0f 100644 --- a/src/api/routes.ts +++ b/src/api/routes.ts @@ -35,7 +35,7 @@ export const syncProgressRoute = createRoute({ tags: ["Indexer"], summary: "Per-chain historical sync progress", description: - "Returns the indexer's historical backfill progress per chain: total blocks to process, blocks already processed, percentage complete, and whether the chain is in realtime mode. Reads from Ponder's built-in Prometheus metrics. During initial sync, progressPct will rise from 0 to 100 and isComplete will flip to true once the chain is fully caught up.", + "Returns the indexer's historical backfill progress per chain: total blocks to process, blocks already processed, percentage complete, and whether the chain is in realtime mode. Reads from Ponder's built-in Prometheus metrics. During initial sync, historicalSyncProgressPct will rise from 0 to 100 and isComplete will flip to true once the chain is fully caught up.", responses: { 200: { description: "Per-chain sync progress.", diff --git a/src/api/schemas/sync-progress.ts b/src/api/schemas/sync-progress.ts index 25f525a..a5c518d 100644 --- a/src/api/schemas/sync-progress.ts +++ b/src/api/schemas/sync-progress.ts @@ -9,7 +9,7 @@ export const ChainProgressSchema = z.object({ .number() .int() .describe("Blocks already processed (completed + served from cache)."), - progressPct: z + historicalSyncProgressPct: z .number() .describe("Completion percentage (0–100). Rounded to one decimal place."), isRealtime: z diff --git a/tests/api/sync-progress.test.ts b/tests/api/sync-progress.test.ts index 87857ad..4404ff2 100644 --- a/tests/api/sync-progress.test.ts +++ b/tests/api/sync-progress.test.ts @@ -5,7 +5,7 @@ import { syncProgressHandler } from "../../src/api/endpoints/sync-progress"; type ChainProgress = { totalBlocks: number; processedBlocks: number; - progressPct: number; + historicalSyncProgressPct: number; isRealtime: boolean; isComplete: boolean; }; @@ -84,15 +84,15 @@ describe("GET /api/sync-progress", () => { expect(body["gnosis"]!.processedBlocks).toBe(2_400_000); }); - it("computes progressPct correctly (rounded to 1 decimal)", async () => { + it("computes historicalSyncProgressPct correctly (rounded to 1 decimal)", async () => { mockFetch(SAMPLE_METRICS); const app = buildApp(); const res = await app.request("http://localhost/api/sync-progress"); const body = (await res.json()) as Record; // mainnet: 3_000_000 / 7_000_000 = 42.857... → 42.9 - expect(body["mainnet"]!.progressPct).toBe(42.9); + expect(body["mainnet"]!.historicalSyncProgressPct).toBe(42.9); // gnosis: 2_400_000 / 17_000_000 = 14.117... → 14.1 - expect(body["gnosis"]!.progressPct).toBe(14.1); + expect(body["gnosis"]!.historicalSyncProgressPct).toBe(14.1); }); it("sets isRealtime and isComplete from metrics flags", async () => { From b732822cdf066dffb8154e932e9376e4426246a2 Mon Sep 17 00:00:00 2001 From: Luiz Gustavo Abou Hatem de Liz Date: Tue, 2 Jun 2026 17:05:58 -0300 Subject: [PATCH 2/3] fix: update docs/api-reference.md to use historicalSyncProgressPct field name Co-Authored-By: Claude Sonnet 4.6 --- docs/api-reference.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 89fa309..0552804 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -53,21 +53,21 @@ Example response: "mainnet": { "totalBlocks": 7000000, "processedBlocks": 3000000, - "progressPct": 42.9, + "historicalSyncProgressPct": 42.9, "isRealtime": false, "isComplete": false }, "gnosis": { "totalBlocks": 17000000, "processedBlocks": 17000000, - "progressPct": 100.0, + "historicalSyncProgressPct": 100.0, "isRealtime": true, "isComplete": true } } ``` -- `progressPct` is rounded to one decimal place (0–100). +- `historicalSyncProgressPct` is rounded to one decimal place (0–100). - `isRealtime` flips to `true` once the chain enters live-sync mode. - `isComplete` flips to `true` once all historical blocks are processed. - Returns `{}` if the `/metrics` endpoint is unreachable. From 9e9cac2f644fc2af57f9e804354bc7d4fafd4a96 Mon Sep 17 00:00:00 2001 From: Luiz Gustavo Abou Hatem de Liz Date: Thu, 4 Jun 2026 21:09:07 -0300 Subject: [PATCH 3/3] fix: rename historicalSyncProgressPct -> historicalBlocksFetchedPct The new name is precise: it measures eth_getLogs block-fetch progress (ponder_historical_completed_blocks + cached / total), not handler execution. Co-Authored-By: Claude Sonnet 4.6 --- docs/api-reference.md | 6 +++--- src/api/endpoints/sync-progress.ts | 4 ++-- src/api/routes.ts | 2 +- src/api/schemas/sync-progress.ts | 2 +- tests/api/sync-progress.test.ts | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 0552804..00fa0b0 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -53,21 +53,21 @@ Example response: "mainnet": { "totalBlocks": 7000000, "processedBlocks": 3000000, - "historicalSyncProgressPct": 42.9, + "historicalBlocksFetchedPct": 42.9, "isRealtime": false, "isComplete": false }, "gnosis": { "totalBlocks": 17000000, "processedBlocks": 17000000, - "historicalSyncProgressPct": 100.0, + "historicalBlocksFetchedPct": 100.0, "isRealtime": true, "isComplete": true } } ``` -- `historicalSyncProgressPct` is rounded to one decimal place (0–100). +- `historicalBlocksFetchedPct` is rounded to one decimal place (0–100). - `isRealtime` flips to `true` once the chain enters live-sync mode. - `isComplete` flips to `true` once all historical blocks are processed. - Returns `{}` if the `/metrics` endpoint is unreachable. diff --git a/src/api/endpoints/sync-progress.ts b/src/api/endpoints/sync-progress.ts index 998074e..4caf985 100644 --- a/src/api/endpoints/sync-progress.ts +++ b/src/api/endpoints/sync-progress.ts @@ -56,7 +56,7 @@ export const syncProgressHandler: RouteHandler = { totalBlocks: number; processedBlocks: number; - historicalSyncProgressPct: number; + historicalBlocksFetchedPct: number; isRealtime: boolean; isComplete: boolean; } @@ -72,7 +72,7 @@ export const syncProgressHandler: RouteHandler = result[chain] = { totalBlocks: t, processedBlocks: processed, - historicalSyncProgressPct: pct, + historicalBlocksFetchedPct: pct, isRealtime: (isRealtime.get(chain) ?? 0) === 1, isComplete: (isComplete.get(chain) ?? 0) === 1, }; diff --git a/src/api/routes.ts b/src/api/routes.ts index a0a7c0f..8b65a80 100644 --- a/src/api/routes.ts +++ b/src/api/routes.ts @@ -35,7 +35,7 @@ export const syncProgressRoute = createRoute({ tags: ["Indexer"], summary: "Per-chain historical sync progress", description: - "Returns the indexer's historical backfill progress per chain: total blocks to process, blocks already processed, percentage complete, and whether the chain is in realtime mode. Reads from Ponder's built-in Prometheus metrics. During initial sync, historicalSyncProgressPct will rise from 0 to 100 and isComplete will flip to true once the chain is fully caught up.", + "Returns the indexer's historical backfill progress per chain: total blocks to process, blocks already processed, percentage complete, and whether the chain is in realtime mode. Reads from Ponder's built-in Prometheus metrics. During initial sync, historicalBlocksFetchedPct will rise from 0 to 100 and isComplete will flip to true once the chain is fully caught up.", responses: { 200: { description: "Per-chain sync progress.", diff --git a/src/api/schemas/sync-progress.ts b/src/api/schemas/sync-progress.ts index a5c518d..fded028 100644 --- a/src/api/schemas/sync-progress.ts +++ b/src/api/schemas/sync-progress.ts @@ -9,7 +9,7 @@ export const ChainProgressSchema = z.object({ .number() .int() .describe("Blocks already processed (completed + served from cache)."), - historicalSyncProgressPct: z + historicalBlocksFetchedPct: z .number() .describe("Completion percentage (0–100). Rounded to one decimal place."), isRealtime: z diff --git a/tests/api/sync-progress.test.ts b/tests/api/sync-progress.test.ts index 4404ff2..b39e401 100644 --- a/tests/api/sync-progress.test.ts +++ b/tests/api/sync-progress.test.ts @@ -5,7 +5,7 @@ import { syncProgressHandler } from "../../src/api/endpoints/sync-progress"; type ChainProgress = { totalBlocks: number; processedBlocks: number; - historicalSyncProgressPct: number; + historicalBlocksFetchedPct: number; isRealtime: boolean; isComplete: boolean; }; @@ -84,15 +84,15 @@ describe("GET /api/sync-progress", () => { expect(body["gnosis"]!.processedBlocks).toBe(2_400_000); }); - it("computes historicalSyncProgressPct correctly (rounded to 1 decimal)", async () => { + it("computes historicalBlocksFetchedPct correctly (rounded to 1 decimal)", async () => { mockFetch(SAMPLE_METRICS); const app = buildApp(); const res = await app.request("http://localhost/api/sync-progress"); const body = (await res.json()) as Record; // mainnet: 3_000_000 / 7_000_000 = 42.857... → 42.9 - expect(body["mainnet"]!.historicalSyncProgressPct).toBe(42.9); + expect(body["mainnet"]!.historicalBlocksFetchedPct).toBe(42.9); // gnosis: 2_400_000 / 17_000_000 = 14.117... → 14.1 - expect(body["gnosis"]!.historicalSyncProgressPct).toBe(14.1); + expect(body["gnosis"]!.historicalBlocksFetchedPct).toBe(14.1); }); it("sets isRealtime and isComplete from metrics flags", async () => {