Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/lean_spec/subspecs/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
API server module for checkpoint sync and node status endpoints.

Provides HTTP endpoints for:
- /lean/states/finalized - Serve finalized checkpoint state as SSZ
- /health - Health check endpoint
- /lean/v0/states/finalized - Serve finalized checkpoint state as SSZ
- /lean/v0/health - Health check endpoint

Also provides a client for checkpoint sync:
- fetch_finalized_state: Download finalized state from a node
Expand Down
2 changes: 1 addition & 1 deletion src/lean_spec/subspecs/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
DEFAULT_TIMEOUT = 60.0
"""HTTP request timeout in seconds. Large states may take time to transfer."""

FINALIZED_STATE_ENDPOINT = "/lean/states/finalized"
FINALIZED_STATE_ENDPOINT = "/lean/v0/states/finalized"
"""API endpoint for fetching finalized state. Follows Beacon API conventions."""


Expand Down
18 changes: 9 additions & 9 deletions src/lean_spec/subspecs/api/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
API server for checkpoint sync, node status, and metrics endpoints.

Provides HTTP endpoints for:
- /lean/states/finalized - Serve finalized checkpoint state as SSZ
- /lean/states/justified - Return latest justified checkpoint information
- /health - Health check endpoint
- /lean/v0/states/finalized - Serve finalized checkpoint state as SSZ
- /lean/v0/states/justified - Return latest justified checkpoint information
- /lean/v0/health - Health check endpoint
- /metrics - Prometheus metrics endpoint

This matches the checkpoint sync API implemented in zeam.
Expand Down Expand Up @@ -98,10 +98,10 @@ async def start(self) -> None:
app = web.Application()
app.add_routes(
[
web.get("/health", _handle_health),
web.get("/lean/v0/health", _handle_health),
web.get("/metrics", _handle_metrics),
web.get("/lean/states/finalized", self._handle_finalized_state),
web.get("/lean/states/justified", self._handle_justified),
web.get("/lean/v0/states/finalized", self._handle_finalized_state),
web.get("/lean/v0/states/justified", self._handle_justified_state),
]
)

Expand Down Expand Up @@ -142,7 +142,7 @@ async def _handle_finalized_state(self, _request: web.Request) -> web.Response:
"""
Handle finalized checkpoint state endpoint.

Serves the finalized state as SSZ binary at /lean/states/finalized.
Serves the finalized state as SSZ binary at /lean/v0/states/finalized.
This endpoint is used for checkpoint sync - clients can download
the finalized state to bootstrap quickly instead of syncing from genesis.
"""
Expand All @@ -166,11 +166,11 @@ async def _handle_finalized_state(self, _request: web.Request) -> web.Response:

return web.Response(body=ssz_bytes, content_type="application/octet-stream")

async def _handle_justified(self, _request: web.Request) -> web.Response:
async def _handle_justified_state(self, _request: web.Request) -> web.Response:
"""
Handle latest justified checkpoint endpoint.

Returns the latest justified checkpoint information as JSON at /lean/states/justified.
Returns the latest justified checkpoint information as JSON at /lean/v0/states/justified.
This provides the slot number and root hash of the most recent justified checkpoint,
which is useful for monitoring consensus progress and fork choice state.

Expand Down
16 changes: 8 additions & 8 deletions tests/lean_spec/subspecs/api/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def test_store_getter_provides_access_to_store(self, base_store: Store) -> None:


class TestHealthEndpoint:
"""Tests for the /health endpoint behavior."""
"""Tests for the /lean/v0/health endpoint behavior."""

def test_returns_healthy_status_json(self) -> None:
"""Health endpoint returns JSON with healthy status."""
Expand All @@ -75,7 +75,7 @@ async def run_test() -> None:

try:
async with httpx.AsyncClient() as client:
response = await client.get("http://127.0.0.1:15052/health")
response = await client.get("http://127.0.0.1:15052/lean/v0/health")

assert response.status_code == 200
data = response.json()
Expand All @@ -90,7 +90,7 @@ async def run_test() -> None:


class TestFinalizedStateEndpoint:
"""Tests for the /lean/states/finalized endpoint behavior."""
"""Tests for the /lean/v0/states/finalized endpoint behavior."""

def test_returns_503_when_store_not_initialized(self) -> None:
"""Endpoint returns 503 Service Unavailable when store is not set."""
Expand All @@ -103,7 +103,7 @@ async def run_test() -> None:

try:
async with httpx.AsyncClient() as client:
response = await client.get("http://127.0.0.1:15054/lean/states/finalized")
response = await client.get("http://127.0.0.1:15054/lean/v0/states/finalized")

assert response.status_code == 503

Expand All @@ -124,7 +124,7 @@ async def run_test() -> None:

try:
async with httpx.AsyncClient() as client:
response = await client.get("http://127.0.0.1:15056/lean/states/finalized")
response = await client.get("http://127.0.0.1:15056/lean/v0/states/finalized")

assert response.status_code == 200
assert response.headers["content-type"] == "application/octet-stream"
Expand All @@ -143,7 +143,7 @@ async def run_test() -> None:


class TestJustifiedEndpoint:
"""Tests for the /lean/states/justified endpoint behavior."""
"""Tests for the /lean/v0/states/justified endpoint behavior."""

def test_returns_503_when_store_not_initialized(self) -> None:
"""Endpoint returns 503 Service Unavailable when store is not set."""
Expand All @@ -156,7 +156,7 @@ async def run_test() -> None:

try:
async with httpx.AsyncClient() as client:
response = await client.get("http://127.0.0.1:15057/lean/states/justified")
response = await client.get("http://127.0.0.1:15057/lean/v0/states/justified")

assert response.status_code == 503

Expand All @@ -177,7 +177,7 @@ async def run_test() -> None:

try:
async with httpx.AsyncClient() as client:
response = await client.get("http://127.0.0.1:15058/lean/states/justified")
response = await client.get("http://127.0.0.1:15058/lean/v0/states/justified")

assert response.status_code == 200
assert "application/json" in response.headers["content-type"]
Expand Down
Loading