From 72795669bee8e4f1396bb58c3b66c76f57610f29 Mon Sep 17 00:00:00 2001 From: CeciliaZ030 Date: Sun, 27 Oct 2024 04:26:37 +0800 Subject: [PATCH] --l2.chain_ids --l2.datadir ,... --- Dockerfile | 51 +++---------------------- bin/reth/src/cli/mod.rs | 44 +++++++++++++++++++--- bin/reth/src/main.rs | 26 +++++++++---- crates/cli/commands/src/node.rs | 52 +++++++++++++++++++++++++- crates/gwyneth/src/engine_api.rs | 17 +++++++++ crates/gwyneth/src/exex.rs | 12 +++--- crates/node/builder/src/builder/mod.rs | 38 +------------------ crates/rpc/ipc/src/server/mod.rs | 3 ++ 8 files changed, 142 insertions(+), 101 deletions(-) diff --git a/Dockerfile b/Dockerfile index d340803fe0ec..51531b6d89a9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,23 +1,6 @@ -FROM lukemathwalker/cargo-chef:latest-rust-1 AS chef -WORKDIR /app -LABEL org.opencontainers.image.source=https://github.com/paradigmxyz/reth -LABEL org.opencontainers.image.licenses="MIT OR Apache-2.0" - -# Install system dependencies +FROM lukemathwalker/cargo-chef:latest-rust-1 AS builder RUN apt-get update && apt-get -y upgrade && apt-get install -y libclang-dev pkg-config git -# Builds a cargo-chef plan -FROM chef AS planner -COPY ./reth/Cargo.lock ./Cargo.lock -COPY ./reth/Cargo.toml ./Cargo.toml -COPY ./reth/crates ./crates -COPY ./reth/bin ./bin -COPY ./reth/examples ./examples -COPY ./reth/testing ./testing -RUN cargo chef prepare --recipe-path recipe.json - -FROM chef AS builder -COPY --from=planner /app/recipe.json /app/reth/recipe.json COPY ./reth/Cargo.lock ./reth/Cargo.lock COPY ./reth/Cargo.toml ./reth/Cargo.toml COPY ./reth/crates ./reth/crates @@ -26,37 +9,15 @@ COPY ./reth/examples ./reth/examples COPY ./reth/testing ./reth/testing COPY ./revm ./revm COPY ./revm-inspectors ./revm-inspectors -WORKDIR /app/reth - -# Build profile, release by default -ARG BUILD_PROFILE=release -ENV BUILD_PROFILE $BUILD_PROFILE - -# Extra Cargo flags -ARG RUSTFLAGS="" -ENV RUSTFLAGS "$RUSTFLAGS" -# Extra Cargo features -ARG FEATURES="" -ENV FEATURES $FEATURES +WORKDIR /reth +RUN cargo build --release --bin reth -# Builds dependencies -RUN cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --recipe-path recipe.json -# Build application -RUN cargo build --profile $BUILD_PROFILE --features "$FEATURES" --locked --bin reth - -# Copy binaries to a temporary location -RUN cp /app/reth/target/$BUILD_PROFILE/reth /app/reth - -# Use Ubuntu as the release image FROM ubuntu:22.04 AS runtime -WORKDIR /app +COPY --from=builder /reth/target/release/reth /usr/local/bin -# Copy reth and rbuilder binaries over from the build stage -COPY --from=builder /app/reth /usr/local/bin - -# Copy licenses -COPY LICENSE-* ./ +WORKDIR /app +# RUN reth EXPOSE 30303 30303/udp 9001 8545 8546 ENTRYPOINT ["/usr/local/bin/reth"] diff --git a/bin/reth/src/cli/mod.rs b/bin/reth/src/cli/mod.rs index d6fc7d3c4df4..3b716dc00ab6 100644 --- a/bin/reth/src/cli/mod.rs +++ b/bin/reth/src/cli/mod.rs @@ -89,6 +89,23 @@ impl Cli { } } + +impl Cli { + /// Parsers only the default CLI arguments + pub fn parse_args_l2() -> Self { + Self::parse() + } + + /// Parsers only the default CLI arguments from the given iterator + pub fn try_parse_args_from_l2(itr: I) -> Result + where + I: IntoIterator, + T: Into + Clone, + { + Self::try_parse_from(itr) + } +} + impl Cli { /// Execute the configured cli command. /// @@ -242,10 +259,11 @@ mod tests { use super::*; use crate::args::ColorMode; use clap::CommandFactory; + use node::L2Args; #[test] fn parse_color_mode() { - let reth = Cli::try_parse_args_from(["reth", "node", "--color", "always"]).unwrap(); + let reth = Cli::::try_parse_args_from(["reth", "node", "--color", "always"]).unwrap(); assert_eq!(reth.logs.color, ColorMode::Always); } @@ -256,7 +274,7 @@ mod tests { fn test_parse_help_all_subcommands() { let reth = Cli::::command(); for sub_command in reth.get_subcommands() { - let err = Cli::try_parse_args_from(["reth", sub_command.get_name(), "--help"]) + let err = Cli::::try_parse_args_from(["reth", sub_command.get_name(), "--help"]) .err() .unwrap_or_else(|| { panic!("Failed to parse help message {}", sub_command.get_name()) @@ -272,7 +290,7 @@ mod tests { /// name #[test] fn parse_logs_path() { - let mut reth = Cli::try_parse_args_from(["reth", "node"]).unwrap(); + let mut reth = Cli::::try_parse_args_from(["reth", "node"]).unwrap(); reth.logs.log_file_directory = reth.logs.log_file_directory.join(reth.chain.chain.to_string()); let log_dir = reth.logs.log_file_directory; @@ -282,7 +300,7 @@ mod tests { let mut iter = SUPPORTED_CHAINS.iter(); iter.next(); for chain in iter { - let mut reth = Cli::try_parse_args_from(["reth", "node", "--chain", chain]).unwrap(); + let mut reth = Cli::::try_parse_args_from(["reth", "node", "--chain", chain]).unwrap(); reth.logs.log_file_directory = reth.logs.log_file_directory.join(reth.chain.chain.to_string()); let log_dir = reth.logs.log_file_directory; @@ -296,7 +314,7 @@ mod tests { let temp_dir = tempfile::tempdir().unwrap(); std::env::set_var("RUST_LOG", "info,evm=debug"); - let reth = Cli::try_parse_args_from([ + let reth = Cli::::try_parse_args_from([ "reth", "init", "--datadir", @@ -307,4 +325,20 @@ mod tests { .unwrap(); assert!(reth.run(|_, _| async move { Ok(()) }).is_ok()); } + + #[test] + fn parse_l2_chains() { + let reth = Cli::::try_parse_args_from_l2([ + "reth", + "node", + "--l2.chain_ids", + "160010", + "160011", + "--l2.datadirs", + "path/one", + "path/two" + ]) + .unwrap(); + assert!(reth.run(|_, _| async move { Ok(()) }).is_ok()); + } } diff --git a/bin/reth/src/main.rs b/bin/reth/src/main.rs index 6d975a178e64..c52b30f0c635 100644 --- a/bin/reth/src/main.rs +++ b/bin/reth/src/main.rs @@ -4,18 +4,21 @@ #[global_allocator] static ALLOC: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc; +use std::sync::Arc; + use gwyneth::{engine_api::RpcServerArgsExEx, GwynethNode}; use reth::args::{DiscoveryArgs, NetworkArgs, RpcServerArgs}; use reth_chainspec::ChainSpecBuilder; +use reth_cli_commands::node::L2Args; +use reth_db::init_db; use reth_node_builder::{NodeBuilder, NodeConfig, NodeHandle}; use reth_node_ethereum::EthereumNode; use reth_tasks::TaskManager; -const BASE_CHAIN_ID: u64 = gwyneth::exex::BASE_CHAIN_ID; // Base chain ID for L2s -const NUM_L2_CHAINS: u64 = 2; // Number of L2 chains to create. Todo: Shall come from config */ - fn main() -> eyre::Result<()> { - reth::cli::Cli::parse_args().run(|builder, _| async move { + println!("WTF"); + reth::cli::Cli::::parse_args_l2().run(|builder, ext| async move { + println!("Starting reth node with custom exex \n {:?}", ext); let tasks = TaskManager::current(); let exec = tasks.executor(); let network_config = NetworkArgs { @@ -25,9 +28,13 @@ fn main() -> eyre::Result<()> { let mut gwyneth_nodes = Vec::new(); - for i in 0..NUM_L2_CHAINS { - let chain_id = BASE_CHAIN_ID + i; // Increment by 1 for each L2 + // Assuming chain_ids & datadirs are mandetory + // If ports and ipc are not supported we used the default ways to derive + assert_eq!(ext.chain_ids.len(), ext.datadirs.len()); + assert!(ext.chain_ids.len() > 0); + + for (idx, (chain_id, datadir)) in ext.chain_ids.into_iter().zip(ext.datadirs).enumerate() { let chain_spec = ChainSpecBuilder::default() .chain(chain_id.into()) .genesis( @@ -46,12 +53,15 @@ fn main() -> eyre::Result<()> { .with_rpc( RpcServerArgs::default() .with_unused_ports() - .with_static_l2_rpc_ip_and_port(chain_id) + .with_ports_and_ipc(ext.ports.get(idx), ext.ipc_path.clone(), chain_id) ); + + let db = Arc::new(init_db(datadir, reth_db::mdbx::DatabaseArguments::default())?); let NodeHandle { node: gwyneth_node, node_exit_future: _ } = NodeBuilder::new(node_config.clone()) - .gwyneth_node(exec.clone(), chain_spec.chain.id()) + .with_database(db) + .with_launch_context(exec.clone()) .node(GwynethNode::default()) .launch() .await?; diff --git a/crates/cli/commands/src/node.rs b/crates/cli/commands/src/node.rs index 2cf1689fdd8f..720a04ec8e07 100644 --- a/crates/cli/commands/src/node.rs +++ b/crates/cli/commands/src/node.rs @@ -1,6 +1,6 @@ //! Main node command for launching a node -use clap::{value_parser, Args, Parser}; +use clap::{builder::Str, value_parser, Args, Parser}; use reth_chainspec::ChainSpec; use reth_cli_runner::CliContext; use reth_cli_util::parse_socket_address; @@ -199,6 +199,22 @@ impl NodeCommand { #[non_exhaustive] pub struct NoArgs; +#[derive(Debug, Clone, Default, Args, PartialEq, Eq)] +pub struct L2Args { + #[arg(long = "l2.chain_ids", required = true, num_args = 1..,)] + pub chain_ids: Vec, + + #[arg(long = "l2.datadirs", required = true, num_args = 1..,)] + pub datadirs: Vec, + + #[arg(long = "l2.ports", num_args = 1..,)] + pub ports: Vec, + + #[arg(long = "l2.ipc_path")] + pub ipc_path: String, +} + + #[cfg(test)] mod tests { use super::*; @@ -222,6 +238,40 @@ mod tests { } } + #[test] + fn parse_common_node_command_l2_args() { + let args = NodeCommand::::parse_from([ + "reth", + "--l2.chain_ids", + "160010", + "160011", + "--l2.datadirs", + "path/one", + "path/two", + "--l2.ports", + "1234", + "2345", + "--l2.ipc_path", + "/tmp/ipc", + ]); + assert_eq!( + args.ext, + L2Args { + chain_ids: vec![160010, 160011], + datadirs: vec!["path/one".into(), "path/two".into()], + ports: vec![1234, 2345], + ipc_path: "/tmp/ipc".into(), + }) + } + + #[test] + #[should_panic] + fn parse_l2_args() { + let args = NodeCommand::::try_parse_from([ + "reth", + ]).unwrap(); + } + #[test] fn parse_discovery_addr() { let cmd = diff --git a/crates/gwyneth/src/engine_api.rs b/crates/gwyneth/src/engine_api.rs index f27b61c827bd..d5e0514bbef7 100644 --- a/crates/gwyneth/src/engine_api.rs +++ b/crates/gwyneth/src/engine_api.rs @@ -116,6 +116,7 @@ impl PayloadEnvelopeExt for ExecutionPayloadEnvelopeV3 { } pub trait RpcServerArgsExEx { fn with_static_l2_rpc_ip_and_port(self, chain_id: u64) -> Self; + fn with_ports_and_ipc(self, port: Option<&u16>, ipc: String, chain_id: u64) -> Self; } impl RpcServerArgsExEx for RpcServerArgs { @@ -133,4 +134,20 @@ impl RpcServerArgsExEx for RpcServerArgs { self } + + fn with_ports_and_ipc(mut self, port: Option<&u16>, ipc: String, chain_id: u64) -> Self { + self.http = true; + self.http_addr = Ipv4Addr::new(0, 0, 0, 0).into(); + if let Some(port) = port { + self.http_port = *port; + self.ws_port = port + 100; + } else { + let port_offset = (chain_id - BASE_CHAIN_ID) as u16; + self.http_port = 10110 + (port_offset * 100); + self.ws_port = 10111 + (port_offset * 100); + } + self.ipcpath = format!("{}/l2.ipc-{}", ipc.clone(), chain_id); + println!("IPC path: {}", self.ipcpath); + self + } } diff --git a/crates/gwyneth/src/exex.rs b/crates/gwyneth/src/exex.rs index 6ae2206a7be4..f4f08fd71c92 100644 --- a/crates/gwyneth/src/exex.rs +++ b/crates/gwyneth/src/exex.rs @@ -8,7 +8,7 @@ use crate::{ GwynethPayloadBuilderAttributes, }; use reth_consensus::Consensus; -use reth_db::{test_utils::TempDatabase, DatabaseEnv}; +use reth_db::DatabaseEnv; use reth_ethereum_engine_primitives::EthPayloadAttributes; use reth_evm_ethereum::EthEvmConfig; use reth_execution_types::Chain; @@ -38,19 +38,19 @@ pub type GwynethFullNode = FullNode< NodeAdapter< FullNodeTypesAdapter< GwynethNode, - Arc>, - BlockchainProvider>>, + Arc, + BlockchainProvider>, >, Components< FullNodeTypesAdapter< GwynethNode, - Arc>, - BlockchainProvider>>, + Arc, + BlockchainProvider>, >, Pool< TransactionValidationTaskExecutor< EthTransactionValidator< - BlockchainProvider>>, + BlockchainProvider>, EthPooledTransaction, >, >, diff --git a/crates/node/builder/src/builder/mod.rs b/crates/node/builder/src/builder/mod.rs index 1d993352e7ad..4e913a7ecbfc 100644 --- a/crates/node/builder/src/builder/mod.rs +++ b/crates/node/builder/src/builder/mod.rs @@ -5,6 +5,7 @@ pub mod add_ons; mod states; +use reth_db::init_db; use reth_rpc_types::WithOtherFields; pub use states::*; @@ -23,11 +24,7 @@ use reth_network::{ }; use reth_node_api::{FullNodeTypes, FullNodeTypesAdapter, NodeAddOns, NodeTypes}; use reth_node_core::{ - cli::config::{PayloadBuilderConfig, RethTransactionPoolConfig}, - dirs::{ChainPath, DataDirPath}, - node_config::NodeConfig, - primitives::Head, - rpc::eth::{helpers::AddDevSigners, FullEthApiServer}, + cli::config::{PayloadBuilderConfig, RethTransactionPoolConfig}, dirs::{ChainPath, DataDirPath}, node_config::NodeConfig, primitives::Head, rpc::eth::{helpers::AddDevSigners, FullEthApiServer} }; use reth_primitives::revm_primitives::EnvKzgSettings; use reth_provider::{providers::BlockchainProvider, ChainSpecProvider, FullProvider}; @@ -176,37 +173,6 @@ impl NodeBuilder { WithLaunchContext { builder: self, task_executor } } - /// Creates a Gwyneth node - pub fn gwyneth_node( - mut self, - task_executor: TaskExecutor, - chain_id: u64, - ) -> WithLaunchContext>>> - { - let folder_name = format!("/data/reth/gwyneth-{}/", chain_id); - let path = reth_node_core::dirs::MaybePlatformPath::::from( - PathBuf::from(folder_name.clone()), - ); - - println!("path: {:?}", folder_name); - - fs::create_dir_all(folder_name).expect("gwyneth db dir creation failed"); - - self.config = self.config.with_datadir_args(reth_node_core::args::DatadirArgs { - datadir: path.clone(), - ..Default::default() - }); - - let data_dir = - path.unwrap_or_chain_default(self.config.chain.chain, self.config.datadir.clone()); - - println!("data_dir: {:?}", data_dir); - - let db = reth_db::test_utils::create_test_rw_db_with_path(data_dir.db()); - - WithLaunchContext { builder: self.with_database(db), task_executor } - } - /// Creates an _ephemeral_ preconfigured node for testing purposes. diff --git a/crates/rpc/ipc/src/server/mod.rs b/crates/rpc/ipc/src/server/mod.rs index 28c0f6e8cb4f..eee5bcc112b8 100644 --- a/crates/rpc/ipc/src/server/mod.rs +++ b/crates/rpc/ipc/src/server/mod.rs @@ -127,9 +127,12 @@ where ) { trace!(endpoint = ?self.endpoint, "starting ipc server"); + println!("****************"); if cfg!(unix) { + println!("Unix"); // ensure the file does not exist if std::fs::remove_file(&self.endpoint).is_ok() { + println!("Removed existing IPC endpoint file"); debug!(endpoint = ?self.endpoint, "removed existing IPC endpoint file"); } }