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
66 changes: 48 additions & 18 deletions bin/ethlambda/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,24 @@ const ASCII_ART: &str = r#"

#[derive(Debug, clap::Parser)]
#[command(name = "ethlambda", author = "LambdaClass", version = version::CLIENT_VERSION, about = "ethlambda consensus client")]
struct CliOptions {
struct Cli {
#[command(subcommand)]
command: Commands,
}

#[derive(Debug, clap::Subcommand)]
enum Commands {
/// Run the consensus node.
Node(Box<NodeArgs>),
/// Run in Hive test-driver mode (spec-asset suites only).
///
/// Skips the consensus/p2p stack and exposes only the
/// `/lean/v0/test_driver/...` endpoints driven by the hive simulator.
TestDriver(TestDriverArgs),
}

#[derive(Debug, clap::Args)]
struct NodeArgs {
/// Path to the chain genesis config (e.g., config.yaml).
#[arg(long)]
genesis: PathBuf,
Expand Down Expand Up @@ -111,6 +128,16 @@ struct CliOptions {
data_dir: PathBuf,
}

#[derive(Debug, clap::Args)]
struct TestDriverArgs {
#[arg(long, default_value = "127.0.0.1")]
http_address: IpAddr,
#[arg(long, default_value = "5052")]
api_port: u16,
#[arg(long, default_value = "5054")]
metrics_port: u16,
}

#[tokio::main]
async fn main() -> eyre::Result<()> {
let filter = EnvFilter::builder()
Expand All @@ -119,34 +146,37 @@ async fn main() -> eyre::Result<()> {
let subscriber = Registry::default().with(tracing_subscriber::fmt::layer().with_filter(filter));
tracing::subscriber::set_global_default(subscriber).unwrap();

let options = CliOptions::parse();
let cli = Cli::parse();

// Initialize metrics
ethlambda_blockchain::metrics::init();
ethlambda_blockchain::metrics::set_node_info("ethlambda", version::CLIENT_VERSION);
ethlambda_blockchain::metrics::set_node_start_time();

let rpc_config = RpcConfig {
http_address: options.http_address,
api_port: options.api_port,
metrics_port: options.metrics_port,
};

println!("{ASCII_ART}");

info!(version = version::CLIENT_VERSION, "Starting ethlambda");

// Hive lean spec-asset suites boot the client with
// HIVE_LEAN_TEST_DRIVER=1 so it skips the consensus/p2p stack and
// exposes only the `/lean/v0/test_driver/...` endpoints driven by the
// simulator. Detected here before any config / key / genesis loading
// so the driver run doesn't touch --node-key, --custom-network-config-dir,
// or any other consensus prerequisite the hive shim doesn't bother to
// provision.
if ethlambda_rpc::test_driver::test_driver_enabled() {
info!("HIVE_LEAN_TEST_DRIVER detected; booting in test-driver mode");
return run_test_driver(rpc_config).await;
match cli.command {
Commands::TestDriver(args) => {
let rpc_config = RpcConfig {
http_address: args.http_address,
api_port: args.api_port,
metrics_port: args.metrics_port,
};
info!("Booting in test-driver mode");
run_test_driver(rpc_config).await
}
Commands::Node(options) => run_node(*options).await,
}
Comment thread
pablodeymo marked this conversation as resolved.
}

async fn run_node(options: NodeArgs) -> eyre::Result<()> {
let rpc_config = RpcConfig {
http_address: options.http_address,
api_port: options.api_port,
metrics_port: options.metrics_port,
};

let node_p2p_key = read_hex_file_bytes(&options.node_key);
let p2p_socket = SocketAddr::new(IpAddr::from([0, 0, 0, 0]), options.gossipsub_port);
Expand Down
35 changes: 2 additions & 33 deletions crates/net/rpc/src/test_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
//! store-mutating operations themselves are synchronous, so the write lock is
//! never held across `.await`.
//!
//! Activated by setting `HIVE_LEAN_TEST_DRIVER=1` in the container env; see
//! [`test_driver_enabled`] and the boot path in `bin/ethlambda/src/main.rs`.
//! Activated via the `test-driver` subcommand; see the boot path in
//! `bin/ethlambda/src/main.rs`.

use std::sync::Arc;

Expand Down Expand Up @@ -51,27 +51,6 @@ use serde::{Deserialize, Serialize};
use tokio::sync::RwLock;
use tracing::debug;

/// Environment variable that activates the test driver at boot time.
///
/// The hive simulator sets this to `"1"` for each spec-asset fixture run; any
/// of `"1"`, `"true"`, or `"yes"` (case-insensitive) enables the driver.
pub const TEST_DRIVER_ENV: &str = "HIVE_LEAN_TEST_DRIVER";

/// Whether the supplied env-var value should activate the driver.
fn parse_truthy_env_value(value: &str) -> bool {
matches!(
value.trim().to_ascii_lowercase().as_str(),
"1" | "true" | "yes"
)
}

/// Returns true when the binary should boot into test-driver mode.
pub fn test_driver_enabled() -> bool {
std::env::var(TEST_DRIVER_ENV)
.map(|value| parse_truthy_env_value(&value))
.unwrap_or(false)
}

/// Shared, runtime-replaceable Store backing every test-driver handler.
///
/// `fork_choice/init` swaps the contents wholesale; all other handlers either
Expand Down Expand Up @@ -429,16 +408,6 @@ fn snapshot_store(store: &Store) -> DriverSnapshot {
mod tests {
use super::*;

#[test]
fn parse_truthy_env_value_accepts_canonical_truthy_strings() {
for value in ["1", "true", "TRUE", " Yes ", "yes\n"] {
assert!(parse_truthy_env_value(value), "{value:?} should be truthy");
}
for value in ["0", "false", "no", "", " ", "1.0"] {
assert!(!parse_truthy_env_value(value), "{value:?} should be falsy");
}
}

#[test]
fn empty_driver_store_is_usable_as_seed() {
let store = empty_driver_store();
Expand Down