Skip to content

Commit

Permalink
Impl settlement (#13)
Browse files Browse the repository at this point in the history
* feat: impl settlement

* feat: impl settlement

* feat: impl settlement

* refactor: mvoe zeth_db_path to GLOBAL_ENV, fix ci

* feat: refactor settlement, impl eigen_bridge, impl eigen_global_exit_root, add settlement env

* refactor: remove prefix "eigen"

* refactor: start with CLI, move settlement layer env to config file

* fix: fix lint

* refactor: support selection of DB, fix operator, move specific env to config

* docs: update readme

* style: update fmt

* refactor: update the L1 provider_url

---------

Co-authored-by: eigmax <stephen@ieigen.com>
  • Loading branch information
captainlee1024 and eigmax authored May 2, 2024
1 parent 3937a00 commit 3cef759
Show file tree
Hide file tree
Showing 28 changed files with 2,269 additions and 610 deletions.
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

0 comments on commit 3cef759

Please sign in to comment.