Skip to content
Open
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
10 changes: 10 additions & 0 deletions crates/common/types/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
//! Protocol constants shared across crates.

/// Fork digest embedded in every gossipsub topic string, as lowercase hex
/// without a `0x` prefix.
///
/// The [leanSpec](https://github.com/leanEthereum/leanSpec/pull/622)
/// currently mandates a dummy value shared across all clients; this will
/// eventually be derived from the fork version and genesis validators root.
// TODO: derive dynamically once the spec defines fork identification.
pub const FORK_DIGEST: &str = "12345678";
1 change: 1 addition & 0 deletions crates/common/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod aggregator;
pub mod attestation;
pub mod block;
pub mod checkpoint;
pub mod constants;
pub mod genesis;
pub mod primitives;
pub mod signature;
Expand Down
9 changes: 1 addition & 8 deletions crates/net/p2p/src/gossipsub/messages.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,4 @@
/// Fork digest embedded in every gossipsub topic string, as lowercase hex
/// without a `0x` prefix.
///
/// The [leanSpec](https://github.com/leanEthereum/leanSpec/pull/622)
/// currently mandates a dummy value shared across all clients; this will
/// eventually be derived from the fork version and genesis validators root.
// TODO: derive dynamically once the spec defines fork identification.
pub const FORK_DIGEST: &str = "12345678";
pub use ethlambda_types::constants::FORK_DIGEST;

/// Topic kind for block gossip
pub const BLOCK_TOPIC_KIND: &str = "block";
Expand Down
2 changes: 2 additions & 0 deletions crates/net/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ mod fork_choice;
mod genesis;
mod heap_profiling;
pub mod metrics;
mod spec;
pub mod test_driver;

pub(crate) use base::json_response;
Expand Down Expand Up @@ -102,6 +103,7 @@ fn build_api_router(store: Store) -> Router {
.merge(fork_choice::routes())
.merge(admin::routes())
.merge(genesis::routes())
.merge(spec::routes())
.with_state(store)
}

Expand Down
79 changes: 79 additions & 0 deletions crates/net/rpc/src/spec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use axum::{Router, response::IntoResponse, routing::get};
use ethlambda_blockchain::{INTERVALS_PER_SLOT, MILLISECONDS_PER_INTERVAL, MILLISECONDS_PER_SLOT};
use ethlambda_storage::Store;
use ethlambda_types::{constants::FORK_DIGEST, state::HISTORICAL_ROOTS_LIMIT};
use serde::Serialize;

use crate::json_response;

#[derive(Serialize)]
struct SpecResponse {
#[serde(rename = "MILLISECONDS_PER_SLOT")]
ms_per_slot: u64,
#[serde(rename = "INTERVALS_PER_SLOT")]
intervals_per_slot: u64,
#[serde(rename = "MILLISECONDS_PER_INTERVAL")]
ms_per_interval: u64,
#[serde(rename = "HISTORICAL_ROOTS_LIMIT")]
historical_roots_limit: u64,
#[serde(rename = "FORK_DIGEST")]
fork_digest: &'static str,
}

async fn get_spec() -> impl IntoResponse {
json_response(SpecResponse {
ms_per_slot: MILLISECONDS_PER_SLOT,
intervals_per_slot: INTERVALS_PER_SLOT,
ms_per_interval: MILLISECONDS_PER_INTERVAL,
historical_roots_limit: HISTORICAL_ROOTS_LIMIT as u64,
fork_digest: FORK_DIGEST,
})
}

pub(crate) fn routes() -> Router<Store> {
Router::new().route("/lean/v0/config/spec", get(get_spec))
}

#[cfg(test)]
mod tests {
use super::FORK_DIGEST;
use crate::test_utils::create_test_state;
use axum::{
body::Body,
http::{Request, StatusCode},
};
use ethlambda_blockchain::{
INTERVALS_PER_SLOT, MILLISECONDS_PER_INTERVAL, MILLISECONDS_PER_SLOT,
};
use ethlambda_storage::{Store, backend::InMemoryBackend};
use ethlambda_types::state::HISTORICAL_ROOTS_LIMIT;
use http_body_util::BodyExt;
use std::sync::Arc;
use tower::ServiceExt;

#[tokio::test]
async fn spec_returns_lean_constants() {
let store = Store::from_anchor_state(Arc::new(InMemoryBackend::new()), create_test_state());
let app = crate::build_api_router(store);
let resp = app
.oneshot(
Request::builder()
.uri("/lean/v0/config/spec")
.body(Body::empty())
.unwrap(),
)
.await
.unwrap();
assert_eq!(resp.status(), StatusCode::OK);
let body = resp.into_body().collect().await.unwrap().to_bytes();
let json: serde_json::Value = serde_json::from_slice(&body).unwrap();
assert_eq!(json["MILLISECONDS_PER_SLOT"], MILLISECONDS_PER_SLOT);
assert_eq!(json["INTERVALS_PER_SLOT"], INTERVALS_PER_SLOT);
assert_eq!(json["MILLISECONDS_PER_INTERVAL"], MILLISECONDS_PER_INTERVAL);
assert_eq!(
json["HISTORICAL_ROOTS_LIMIT"],
HISTORICAL_ROOTS_LIMIT as u64
);
assert_eq!(json["FORK_DIGEST"], FORK_DIGEST);
Comment thread
MegaRedHand marked this conversation as resolved.
}
}
17 changes: 17 additions & 0 deletions docs/rpc.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ If `--api-port` and `--metrics-port` are equal, all routers are merged onto a si
| Method | Path | Response | Description |
|--------|------|----------|-------------|
| `GET` | `/lean/v0/health` | JSON | Liveness check |
| `GET` | `/lean/v0/config/spec` | JSON | Protocol constants the node runs with |
| `GET` | `/lean/v0/genesis` | JSON | Genesis time and validator count |
| `GET` | `/lean/v0/states/finalized` | SSZ | Latest finalized `State` |
| `GET` | `/lean/v0/blocks/finalized` | SSZ | Latest finalized `SignedBlock` |
Expand All @@ -42,6 +43,22 @@ The handler emits a fixed, compact body (no whitespace):
{"status":"healthy","service":"lean-rpc-api"}
```

### `GET /lean/v0/config/spec`

Protocol constants the node was built with. Keys mirror the leanSpec constant names:

```json
{
"MILLISECONDS_PER_SLOT": 4000,
"INTERVALS_PER_SLOT": 5,
"MILLISECONDS_PER_INTERVAL": 800,
"HISTORICAL_ROOTS_LIMIT": 262144,
"FORK_DIGEST": "12345678"
}
```

`FORK_DIGEST` is the 4-byte hex string (no `0x` prefix) embedded in gossipsub topic names.

### `GET /lean/v0/genesis`

```json
Expand Down
Loading