Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Impl settlement #13

Merged
merged 12 commits into from
May 2, 2024
842 changes: 797 additions & 45 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,18 @@ reth-libmdbx = { git = "https://github.com/0xEigenLabs/reth", package = "reth-li
#reth-rpc-types = { path = "../reth/crates/rpc/rpc-types" }
ethers-providers = { version = "2.0.14", features = ["ws"] }
ethers-core = { version = "2.0.14", default-features = false }
ethers-contract = { version = "2.0.14", features = ["abigen"] }
ethers = "2.0.14"

# lazy_static
once_cell = "1.8.0"

# command
clap = "4.4.8"

# config
config = "0.14.0"

# Async
futures = "0.3.26"
tokio = { version = "1.28.2", features = ["full"] }
Expand All @@ -55,6 +63,7 @@ tokio-stream = { version = "0.1" }
# Misc
eyre = "0.6.8"
thiserror = "1.0.40"
anyhow = "1.0"

c-kzg = "0.4.2"

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rm -rf /tmp/chain
reth init --datadir /tmp/chain --chain testdata/chain.json
RUST_LOG="debug,evm=trace,consensus::auto=trace,consensus::engine=trace,rpc::eth=trace" reth node -d --chain testdata/chain.json --datadir /tmp/chain --auto-mine --http --http.port 8546 --http.api debug,eth,net,trace,web3,rpc

RUST_LOG="rpc::eth=trace" ZETH_DB_PATH=/tmp/chain ZETH_OPERATOR_DB=/tmp/operator PROVER_ADDR=localhost:50061 ZETH_L2_ADDR=http://localhost:8546 HOST=0.0.0.0:8182 cargo run -r
RUST_LOG="rpc::eth=trace" ZETH_DB_PATH=/tmp/chain PROVER_ADDR=http://localhost:50061 ZETH_L2_ADDR=http://localhost:8546 HOST=0.0.0.0:8182 cargo run -r -- run --database mdbx
```


Expand Down
3 changes: 3 additions & 0 deletions configs/database.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[mdbx_config]
path = "/tmp/operator"
max_dbs = 10
11 changes: 11 additions & 0 deletions configs/settlement.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[ethereum_settlement_config]
provider_url = "http://localhost:8545"

[ethereum_settlement_config.local_wallet]
private_key = "0x76af8cc59ecfabf983d423e2054b07c11212cabc532062da0bd8067c59cf4a40"
chain_id = 12345

[ethereum_settlement_config.l1_contracts_addr]
bridge = "0x732200433EE79cCBf5842F9b5aD8fda6BF569F01"
global_exit = "0xAC97e12d0Ae20B2E0BF94e8Bd5752494577fC799"
zkvm = "0x12bfb8B59144b96bE5E74ECbC9896667261c004A"
File renamed without changes.
29 changes: 29 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1 +1,30 @@
use crate::commands::{chain_info::ChainInfoCmd, config::ConfigCmd, run::RunCmd};
use anyhow::{bail, Result};

/// Cli is the root command for the CLI.
#[derive(clap::Parser, Debug, Clone)]
#[command(version, author, about)]
pub struct Cli {
#[command(subcommand)]
pub subcommand: Option<SubCommand>,
}

#[derive(clap::Subcommand, Debug, Clone)]
pub enum SubCommand {
Run(RunCmd),
ChainInfo(ChainInfoCmd),
Config(ConfigCmd),
}

impl Cli {
pub async fn run(&self) -> Result<()> {
match &self.subcommand {
Some(SubCommand::Run(cmd)) => cmd.run().await,
Some(SubCommand::ChainInfo(cmd)) => cmd.run().await,
Some(SubCommand::Config(cmd)) => cmd.run().await,
None => {
bail!("No subcommand provided")
}
}
}
}
11 changes: 11 additions & 0 deletions src/commands/chain_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use anyhow::Result;

/// ChainInfoCmd used to print the Eigen-Zeth information.
#[derive(clap::Parser, Debug, Clone, PartialEq, Eq)]
pub struct ChainInfoCmd {}

impl ChainInfoCmd {
pub async fn run(&self) -> Result<()> {
unimplemented!("TODO: implement ChainInfoCmd::run()")
}
}
11 changes: 11 additions & 0 deletions src/commands/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
use anyhow::Result;

/// ConfigCmd used to write configuration to the stdout.
#[derive(clap::Parser, Debug, Clone, PartialEq, Eq)]
pub struct ConfigCmd {}

impl ConfigCmd {
pub async fn run(&self) -> Result<()> {
unimplemented!("TODO: implement ConfigCmd::run()")
}
}
3 changes: 3 additions & 0 deletions src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub(crate) mod chain_info;
pub(crate) mod config;
pub(crate) mod run;
225 changes: 225 additions & 0 deletions src/commands/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
use std::fmt;

use anyhow::Result;
use tokio::select;
use tokio::signal::unix::{signal, SignalKind};
use tokio::sync::mpsc;

use crate::config::env::GLOBAL_ENV;
use crate::custom_reth;
use crate::db::lfs;
use crate::operator;
use crate::settlement::ethereum::EthereumSettlementConfig;
use crate::settlement::NetworkSpec;

/// The `RunCmd` struct is a command that runs the eigen-zeth.
#[derive(clap::Args, Debug, Clone, PartialEq, Eq)]
#[command(version, author, about, long_about)]
pub struct RunCmd {
/// The log level of the node.
#[arg(
long,
value_name = "LOG_LEVEL",
verbatim_doc_comment,
default_value_t = LogLevel::Debug,
ignore_case = true,
)]
pub log_level: LogLevel,

/// The settlement layer to use.
#[arg(
long,
default_value_t = SettlementLayer::Ethereum,
verbatim_doc_comment
)]
pub settlement: SettlementLayer,

/// Path to a file containing the settlement configuration.
#[arg(
long,
value_name = "FILE",
value_hint = clap::ValueHint::FilePath,
requires = "settlement",
default_value = "configs/settlement.toml"
)]
pub settlement_conf: Option<String>,

#[clap(flatten)]
pub base_params: BaseParams,
}

#[derive(clap::Args, Debug, Clone, PartialEq, Eq)]
pub struct BaseParams {
#[clap(flatten)]
pub databases: DatabaseParams,

/// Aggregator's EOA address, used to prove batch by the aggregator.
#[arg(
long,
value_name = "EOA_ADDR",
verbatim_doc_comment,
default_value = "479881985774944702531460751064278034642760119942"
)]
pub aggregator_addr: String,
}

#[derive(clap::Args, Debug, Clone, PartialEq, Eq)]
pub struct DatabaseParams {
/// Choose a supported database.
#[arg(
long,
value_name = "DB",
verbatim_doc_comment,
default_value_t = Database::Mdbx,
ignore_case = true,
)]
pub database: Database,

/// Path to a file containing the database configuration.
#[arg(
long,
value_name = "FILE",
value_hint = clap::ValueHint::FilePath,
requires = "database",
default_value = "configs/database.toml"
)]
pub database_conf: String,
}

#[derive(Debug, Clone, Eq, PartialEq, clap::ValueEnum)]
pub enum Database {
Memory,
Mdbx,
}

impl fmt::Display for Database {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Database::Memory => write!(f, "memory"),
Database::Mdbx => write!(f, "mdbx"),
}
}
}

#[derive(Debug, Clone, Eq, PartialEq, clap::ValueEnum)]
pub enum LogLevel {
Trace,
Debug,
Info,
Warn,
Error,
}

impl fmt::Display for LogLevel {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
LogLevel::Debug => write!(f, "debug"),
LogLevel::Info => write!(f, "info"),
LogLevel::Warn => write!(f, "warn"),
LogLevel::Error => write!(f, "error"),
LogLevel::Trace => write!(f, "trace"),
}
}
}

impl fmt::Display for SettlementLayer {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SettlementLayer::Ethereum => write!(f, "ethereum"),
}
}
}

#[derive(Debug, Clone, Eq, PartialEq, clap::ValueEnum)]
#[non_exhaustive]
pub enum SettlementLayer {
Ethereum,
}

impl RunCmd {
pub async fn run(&self) -> Result<()> {
// initialize the logger
std::env::set_var("RUST_LOG", self.log_level.to_string());
env_logger::init();
log::info!("Initialized logger with level: {}", self.log_level);

// Load the settlement configuration
let settlement_spec = match self.settlement {
SettlementLayer::Ethereum => match &self.settlement_conf {
None => {
log::info!("Using Ethereum SettlementLayer");
return Err(anyhow::anyhow!(
"Settlement configuration is required for Ethereum settlement layer"
));
}
Some(settlement_conf_path) => {
log::info!("Using Ethereum SettlementLayer");
NetworkSpec::Ethereum(EthereumSettlementConfig::from_conf_path(
settlement_conf_path,
)?)
}
},
};

// Load the database configuration
let db_config = match self.base_params.databases.database {
Database::Memory => {
log::info!("Using in-memory database");
lfs::DBConfig::Memory
}
Database::Mdbx => {
log::info!("Using mdbx database");
lfs::DBConfig::Mdbx(lfs::libmdbx::Config::from_conf_path(
&self.base_params.databases.database_conf,
)?)
}
};

let aggregator_addr = &self.base_params.aggregator_addr;
log::info!(
"Load Aggregator address: {}",
self.base_params.aggregator_addr
);

// Initialize the operator
let mut op = operator::Operator::new(
&GLOBAL_ENV.l1addr,
&GLOBAL_ENV.prover_addr,
settlement_spec,
db_config,
aggregator_addr,
)
.unwrap();

let mut sigterm = signal(SignalKind::terminate()).unwrap();
let mut sigint = signal(SignalKind::interrupt()).unwrap();

// initialize the signal channel
let (stop_tx, stop_rx) = mpsc::channel::<()>(1);

// Handle the SIGTERM and SIGINT signals
tokio::spawn(async move {
#[allow(clippy::let_underscore_future)]
#[allow(clippy::never_loop)]
loop {
select! {
_ = sigterm.recv() => {
println!("Recieve SIGTERM");
break;
}
_ = sigint.recv() => {
println!("Recieve SIGTERM");
break;
}
};
}
stop_tx.send(()).await.unwrap();
});

// Launch the custom reth service
custom_reth::launch_custom_node().await?;

// Run the operator
op.run(stop_rx).await
}
}
15 changes: 8 additions & 7 deletions src/env.rs → src/config/env.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
//! This module contains the environment variables for the EigenZeth service

use once_cell::sync::Lazy;
use std::string::ToString;

/// EigenZethEnv is a struct that holds the environment variables
pub struct EigenZethEnv {
pub db_path: String,
pub struct GlobalEnv {
pub l1addr: String,
pub prover_addr: String,
pub curve_type: String,
pub host: String,
pub zeth_db_path: String,
pub chain_id: u64,
pub program_name: String,
}

/// EIGEN_ZETH_ENV is a global variable that holds the environment variables,
/// GLOBAL_ENV is a global variable that holds the environment variables,
/// it is lazy loaded and thread safe
pub static GLOBAL_ENV: Lazy<EigenZethEnv> = Lazy::new(|| EigenZethEnv {
db_path: std::env::var("ZETH_OPERATOR_DB").unwrap(),
l1addr: std::env::var("ZETH_L2_ADDR").unwrap(),
pub static GLOBAL_ENV: Lazy<GlobalEnv> = Lazy::new(|| GlobalEnv {
l1addr: std::env::var("ZETH_L2_ADDR").unwrap_or("http://localhost:8546".to_string()),
prover_addr: std::env::var("PROVER_ADDR").unwrap_or("http://127.0.0.1:50061".to_string()),
curve_type: std::env::var("CURVE_TYPE").unwrap_or("BN128".to_string()),
host: std::env::var("HOST").unwrap_or(":8545".to_string()),
host: std::env::var("HOST").unwrap_or("0.0.0.0:8182".to_string()),
zeth_db_path: std::env::var("ZETH_DB_PATH").unwrap_or("/tmp/chain".to_string()),
chain_id: std::env::var("CHAIN_ID")
.unwrap_or("12345".to_string())
.parse::<u64>()
Expand Down
1 change: 1 addition & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub(crate) mod env;
Loading
Loading