From cbc0514c9e349bf5c3dcd689accd1c3671ec3ee9 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Sun, 29 Oct 2023 16:25:23 -0600 Subject: [PATCH] refactor to expose full reth cli --- Cargo.lock | 1 + bin/mev/Cargo.toml | 2 +- bin/mev/src/cmd/build.rs | 31 +------- bin/mev/src/main.rs | 6 +- book/mev-build-rs.md | 5 +- example.config.toml | 4 +- mev-build-rs/src/reth_builder/mod.rs | 2 +- mev-build-rs/src/reth_builder/service.rs | 11 ++- mev-build-rs/src/reth_builder/service_ext.rs | 74 ++++++++------------ 9 files changed, 49 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f79094a..5132800a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4394,6 +4394,7 @@ dependencies = [ "mev-build-rs", "mev-relay-rs", "mev-rs", + "reth", "serde", "tokio", "tracing", diff --git a/bin/mev/Cargo.toml b/bin/mev/Cargo.toml index d72991f5..275d70d4 100644 --- a/bin/mev/Cargo.toml +++ b/bin/mev/Cargo.toml @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" [features] default = ["boost", "build", "relay"] boost = ["mev-boost-rs"] -build = ["mev-build-rs"] +build = ["mev-build-rs", "reth"] relay = ["mev-relay-rs"] [dependencies] diff --git a/bin/mev/src/cmd/build.rs b/bin/mev/src/cmd/build.rs index acfa7e82..3799bb2f 100644 --- a/bin/mev/src/cmd/build.rs +++ b/bin/mev/src/cmd/build.rs @@ -1,29 +1,4 @@ -use crate::cmd::config::Config; -use clap::Args; -use mev_build_rs::reth_builder::Service; -use tracing::info; +use mev_build_rs::reth_builder::ServiceExt; +use reth::cli::Cli; -#[derive(Debug, Args)] -#[clap(about = "🛠️ building blocks since 2023")] -pub struct Command { - #[clap(env, default_value = "config.toml")] - config_file: String, -} - -impl Command { - pub async fn execute(&self) -> eyre::Result<()> { - let config_file = &self.config_file; - - let config = Config::from_toml_file(config_file)?; - - let network = config.network; - info!("configured for `{network}`"); - - if let Some(config) = config.build { - Service::from(network, config).spawn().await; - Ok(()) - } else { - Err(eyre::eyre!("missing build config from file provided")) - } - } -} +pub type Command = Cli; diff --git a/bin/mev/src/main.rs b/bin/mev/src/main.rs index 3dd3b83a..838e9faf 100644 --- a/bin/mev/src/main.rs +++ b/bin/mev/src/main.rs @@ -33,6 +33,8 @@ fn setup_logging() { } async fn run_task_until_signal(task: impl Future>) -> eyre::Result<()> { + setup_logging(); + tokio::select! { task = task => task, _ = signal::ctrl_c() => { @@ -46,13 +48,11 @@ async fn run_task_until_signal(task: impl Future>) -> async fn main() -> eyre::Result<()> { let cli = Cli::parse(); - setup_logging(); - match cli.command { #[cfg(feature = "boost")] Commands::Boost(cmd) => run_task_until_signal(cmd.execute()).await, #[cfg(feature = "build")] - Commands::Build(cmd) => run_task_until_signal(cmd.execute()).await, + Commands::Build(cmd) => tokio::task::block_in_place(|| cmd.run()), #[cfg(feature = "relay")] Commands::Relay(cmd) => run_task_until_signal(cmd.execute()).await, Commands::Config(cmd) => run_task_until_signal(cmd.execute()).await, diff --git a/book/mev-build-rs.md b/book/mev-build-rs.md index 8f0048ae..63425793 100644 --- a/book/mev-build-rs.md +++ b/book/mev-build-rs.md @@ -49,7 +49,6 @@ Fields you should change: This wallet will be used to author payment transactions to the proposer and also is used as the source of funds for any subsidy value you wish to add to the block. You can select a particular index (following BIP-39) by terminating the seed phrase with a `:N` and integer index `N`. Otherwise the builder will just use the first index from the key tree. * `subsidy_gwei`: set this value to 0 if your execution layer address has no ETH in it; otherwise, the blocks will be invalid. -* `jwt_secret_path`: this path points to the JWT secret file created previously and is specific to your deployment. ### Launch @@ -62,9 +61,11 @@ the tip of the chain, the CL and EL nodes will sync. To expedite syncing times, 1. Run `mev` with config file `config.toml`: ```sh - mev build config.toml + mev build node --mev-builder-config config.toml --authrpc.jwtsecret $JWT_SECRET_FILE_PATH ``` +> NOTE: `mev build` exposes the same CLI interface as stock `reth`, so refer to that command's help for further settings you may be interested in. + 2. Run `lighthouse`: ```sh lighthouse --network sepolia \ diff --git a/example.config.toml b/example.config.toml index 279bda32..872c5202 100644 --- a/example.config.toml +++ b/example.config.toml @@ -26,7 +26,7 @@ relays = [ "https://0x845bd072b7cd566f02faeb0a4033ce9399e42839ced64e8b2adcfc859ed1e8e1a5a293336a49feac6d9a5edb779be53a@boost-relay-sepolia.flashbots.net", ] # extra data to write into built execution payload -extra_data = "hello world" +extra_data = "0x68656C6C6F20776F726C640A" # "hello world" # wallet seed for builder to author payment transactions execution_mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about" # number of milliseconds to submit bids ahead of the target slot @@ -36,5 +36,3 @@ bid_percent = 0.9 # amount to add to the bid on top of the payload's revenue, # currently sourced from the builder's wallet authoring the payment transaction subsidy_gwei = 100000000 # 0.1 eth -# path for the Engine API credentials shared between consensus and execution clients -jwt_secret_path = "/secrets/jwt.hex" diff --git a/mev-build-rs/src/reth_builder/mod.rs b/mev-build-rs/src/reth_builder/mod.rs index f1610ec5..86f868e8 100644 --- a/mev-build-rs/src/reth_builder/mod.rs +++ b/mev-build-rs/src/reth_builder/mod.rs @@ -14,4 +14,4 @@ mod types; pub use bidder::DeadlineBidder; pub use service::Config; -pub use service_ext::ServiceExt as Service; +pub use service_ext::ServiceExt; diff --git a/mev-build-rs/src/reth_builder/service.rs b/mev-build-rs/src/reth_builder/service.rs index becefe30..8a1d8873 100644 --- a/mev-build-rs/src/reth_builder/service.rs +++ b/mev-build-rs/src/reth_builder/service.rs @@ -23,7 +23,7 @@ const DEFAULT_BID_PERCENT: f64 = 0.9; pub struct Config { pub secret_key: SecretKey, pub relays: Vec, - pub extra_data: String, + pub extra_data: Bytes, pub execution_mnemonic: String, // amount in milliseconds pub bidding_deadline_ms: u64, @@ -31,7 +31,6 @@ pub struct Config { pub bid_percent: Option, // amount to add from the builder's wallet as a subsidy to the auction bid pub subsidy_gwei: Option, - pub jwt_secret_path: Option, } pub struct Service { @@ -67,7 +66,7 @@ impl< > Service { pub fn from( - config: Config, + config: &Config, context: Arc, clock: Clock, pool: Pool, @@ -75,7 +74,7 @@ impl< bidder: Arc, chain_spec: Arc, ) -> Result<(Self, Builder), Error> { - let secret_key = config.secret_key; + let secret_key = &config.secret_key; let relays = parse_relays(&config.relays); let mut derivation_index = 0; @@ -94,14 +93,14 @@ impl< let builder_wallet = wallet.with_chain_id(chain_spec.chain.id()); let builder = Builder::new( - secret_key, + secret_key.clone(), context.clone(), clock.clone(), relays, pool, client, chain_spec, - Bytes::from(config.extra_data), + config.extra_data.clone(), builder_wallet, config.bid_percent.unwrap_or(DEFAULT_BID_PERCENT), config.subsidy_gwei.unwrap_or_default(), diff --git a/mev-build-rs/src/reth_builder/service_ext.rs b/mev-build-rs/src/reth_builder/service_ext.rs index 98f2a6f4..31d0c526 100644 --- a/mev-build-rs/src/reth_builder/service_ext.rs +++ b/mev-build-rs/src/reth_builder/service_ext.rs @@ -1,63 +1,36 @@ -use crate::reth_builder::{service::Service, Config, DeadlineBidder}; -use clap::{Args, Parser}; +use crate::reth_builder::{service::Service, Config as BuildConfig, DeadlineBidder}; +use clap::Args; use ethereum_consensus::{ networks::{self, Network}, state_transition::Context, }; +use mev_rs::config::from_toml_file; use reth::{ cli::{ components::RethNodeComponents, config::PayloadBuilderConfig, ext::{RethCliExt, RethNodeCommandConfig}, }, - node::NodeCommand, - runner::CliContext, - tasks::{TaskManager, TaskSpawner}, + tasks::TaskSpawner, }; use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService}; use std::{sync::Arc, time::Duration}; -use tracing::warn; +use tracing::info; #[derive(Debug, Args)] pub struct ServiceExt { + #[clap(env, long = "mev-builder-config", default_value = "config.toml")] + config_file: String, #[clap(skip)] - network: Network, - #[clap(skip)] - config: Config, + config: Option, } -impl ServiceExt { - pub fn from(network: Network, config: Config) -> Self { - Self { network, config } - } - - pub async fn spawn(self) { - let task_manager = TaskManager::new(tokio::runtime::Handle::current()); - let task_executor = task_manager.executor(); - let ctx = CliContext { task_executor }; - - let network = &self.network; - let network_name = format!("{0}", network); - - let mut params = vec![ - "".into(), - "--chain".into(), - network_name.to_string(), - "--full".into(), - "--http".into(), - ]; - if let Some(path) = self.config.jwt_secret_path.as_ref() { - params.push("--authrpc.jwtsecret".into()); - params.push(path.clone()); - } - - let mut node = NodeCommand::::parse_from(params); - // NOTE: shim to pass in config - node.ext = self; - if let Err(err) = node.execute(ctx).await { - warn!("{err:?}"); - } - } +// NOTE: this is duplicated here to avoid circular import b/t `mev` bin and `mev-rs` crate +#[derive(Debug, serde::Deserialize)] +struct Config { + pub network: Network, + #[serde(rename = "builder")] + pub build: BuildConfig, } impl RethCliExt for ServiceExt { @@ -65,6 +38,20 @@ impl RethCliExt for ServiceExt { } impl RethNodeCommandConfig for ServiceExt { + fn on_components_initialized( + &mut self, + _components: &Reth, + ) -> eyre::Result<()> { + let config_file = &self.config_file; + + let config = from_toml_file::<_, Config>(config_file)?; + let network = &config.network; + info!("configured for `{network}`"); + + self.config = Some(config); + Ok(()) + } + fn spawn_payload_builder_service( &mut self, _conf: &Conf, @@ -74,12 +61,13 @@ impl RethNodeCommandConfig for ServiceExt { Conf: PayloadBuilderConfig, Reth: RethNodeComponents, { - let build_config = self.config.clone(); - let context = Arc::new(Context::try_from(self.network.clone())?); + let config = self.config.as_ref().expect("already loaded config"); + let context = Arc::new(Context::try_from(config.network.clone())?); let clock = context.clock().unwrap_or_else(|| { let genesis_time = networks::typical_genesis_time(&context); context.clock_at(genesis_time) }); + let build_config = &config.build; let deadline = Duration::from_millis(build_config.bidding_deadline_ms); let bidder = Arc::new(DeadlineBidder::new(clock.clone(), deadline)); let (service, builder) = Service::from(