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

feat(mono): relative path + cli configuration for multiple L2s #54

Open
wants to merge 19 commits into
base: gwyneth
Choose a base branch
from
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
1,369 changes: 753 additions & 616 deletions Cargo.lock

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -566,8 +566,8 @@ tempfile = "3.8"
test-fuzz = "5"

[patch.crates-io]
revm = { git = "https://github.com/taikoxyz/revm.git", branch = "v43-gwyneth" }
revm-primitives = { git = "https://github.com/taikoxyz/revm.git", branch = "v43-gwyneth" }
revm-interpreter = { git = "https://github.com/taikoxyz/revm.git", branch = "v43-gwyneth" }
revm-precompile = { git = "https://github.com/taikoxyz/revm.git", branch = "v43-gwyneth" }
revm-inspectors = { git = "https://github.com/taikoxyz/revm-inspectors.git", branch = "main-rbuilder" }
revm = { path = "../revm/crates/revm" }
revm-primitives = { path = "../revm/crates/primitives" }
revm-interpreter = { path = "../revm/crates/interpreter" }
revm-precompile = { path = "../revm/crates/precompile" }
revm-inspectors = { path = "../revm-inspectors" }
84 changes: 14 additions & 70 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,79 +1,23 @@
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 . .
RUN cargo chef prepare --recipe-path recipe.json

FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json

# 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

# Builds dependencies
RUN cargo chef cook --profile $BUILD_PROFILE --features "$FEATURES" --recipe-path recipe.json
# Build application
COPY . .
RUN cargo build --profile $BUILD_PROFILE --features "$FEATURES" --locked --bin reth

# Hack: Add a cache busting step (above steps are the more
# time consuming ones but we need to make sure the rbuilder is
# always freshly cloned and not cached !)
# Since the content of this file will change
# with each build, Docker will consider this
# layer (and all subsequent layers) as modified,
# forcing a re-execution of the following steps.
# ADD https://worldtimeapi.org/api/ip /tmp/bustcache
COPY ./reth/Cargo.lock ./reth/Cargo.lock
COPY ./reth/Cargo.toml ./reth/Cargo.toml
COPY ./reth/crates ./reth/crates
COPY ./reth/bin ./reth/bin
COPY ./reth/examples ./reth/examples
COPY ./reth/testing ./reth/testing
COPY ./revm ./revm
COPY ./revm-inspectors ./revm-inspectors

# Clone and build rbuilder (gwyneth branch)
RUN git clone -b gwyneth https://github.com/taikoxyz/rbuilder.git /app/rbuilder
WORKDIR /app/rbuilder
RUN cargo build --release
WORKDIR /reth
RUN cargo build --release --bin reth

# Copy binaries to a temporary location
RUN cp /app/target/$BUILD_PROFILE/reth /app/reth
RUN cp /app/rbuilder/target/release/rbuilder /app/rbuilder

# Use Ubuntu as the release image
FROM ubuntu:22.04 AS runtime
WORKDIR /app

# Install necessary runtime dependencies and Rust/Cargo
RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/*

# Install Rust and Cargo
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
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 --from=builder /app/rbuilder /usr/local/bin

# Copy the entire rbuilder repository
COPY --from=builder /app/rbuilder /app/rbuilder

# Copy licenses
COPY LICENSE-* ./

# Create start script
RUN echo '#!/bin/bash\nrbuilder run /app/rbuilder/config-gwyneth-reth.toml' > /app/start_rbuilder.sh && \
chmod +x /app/start_rbuilder.sh
WORKDIR /app
# RUN reth

EXPOSE 30303 30303/udp 9001 8545 8546
ENTRYPOINT ["/usr/local/bin/reth"]
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@
Block explorer: http://127.0.0.1:64003
```

```
chain_id: 167011
name: Gwyneth-2
rpc: http://127.0.0.1:32006
Currency: ETH
Block explorer: http://127.0.0.1:64005
```

```
chain_id: 160010
name: Gwyneth L1
Expand All @@ -35,6 +43,16 @@

Rabby/Brave wallet works, but some issues with nonces so you may have to manually input the correct nonce.

# How to add extra layer2s ?

In order to add extra layer 2 networks, you need to increase the the `NUM_L2_CHAINS` in the main function [here](https://github.com/taikoxyz/gwyneth/blob/5f6d3a6ffcf0ea359e4c52bbd94a251aef28b54c/bin/reth/src/main.rs#L15). (Later on it will be a configurational setting - no code !)

If you want infrastructure support too, namingly:

1. Exposing the jspn rpc port to the host machine (since everything is running in Docker with Kurtosis), you need to specify as a config param like [here](https://github.com/taikoxyz/gwyneth/blob/5f6d3a6ffcf0ea359e4c52bbd94a251aef28b54c/packages/protocol/scripts/confs/network_params.yaml#L6). (By default, if you dont specify this param, the first Layer2 port - which is 10110 - will be exposed to the host anyways. You only need to add this param if you are exposing more than 1 ports to the outter world.)

Check failure on line 52 in README.md

View workflow job for this annotation

GitHub Actions / codespell

outter ==> outer
2. Blockscout support: [Here](https://github.com/taikoxyz/gwyneth/blob/5f6d3a6ffcf0ea359e4c52bbd94a251aef28b54c/packages/protocol/scripts/confs/network_params.yaml#L16) you can see a pattern, how to shoot up blockscout service too. If you want 3 layer2 explorers, just use the service name `blockscout_l2_3`.


# reth

[![CI status](https://github.com/paradigmxyz/reth/workflows/unit/badge.svg)][gh-ci]
Expand Down
44 changes: 39 additions & 5 deletions bin/reth/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,23 @@ impl Cli {
}
}


impl<Ext: clap::Args + fmt::Debug> Cli<Ext> {
/// 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<I, T>(itr: I) -> Result<Self, clap::error::Error>
where
I: IntoIterator<Item = T>,
T: Into<OsString> + Clone,
{
Self::try_parse_from(itr)
}
}

impl<Ext: clap::Args + fmt::Debug> Cli<Ext> {
/// Execute the configured cli command.
///
Expand Down Expand Up @@ -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::<NoArgs>::try_parse_args_from(["reth", "node", "--color", "always"]).unwrap();
assert_eq!(reth.logs.color, ColorMode::Always);
}

Expand All @@ -256,7 +274,7 @@ mod tests {
fn test_parse_help_all_subcommands() {
let reth = Cli::<NoArgs>::command();
for sub_command in reth.get_subcommands() {
let err = Cli::try_parse_args_from(["reth", sub_command.get_name(), "--help"])
let err = Cli::<NoArgs>::try_parse_args_from(["reth", sub_command.get_name(), "--help"])
.err()
.unwrap_or_else(|| {
panic!("Failed to parse help message {}", sub_command.get_name())
Expand All @@ -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::<NoArgs>::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;
Expand All @@ -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::<NoArgs>::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;
Expand All @@ -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::<NoArgs>::try_parse_args_from([
"reth",
"init",
"--datadir",
Expand All @@ -307,4 +325,20 @@ mod tests {
.unwrap();
assert!(reth.run(|_, _| async move { Ok(()) }).is_ok());
}

#[test]
fn parse_l2_chains() {
let reth = Cli::<L2Args>::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());
}
}
77 changes: 49 additions & 28 deletions bin/reth/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,56 +1,77 @@
#![allow(missing_docs)]

// We use jemalloc for performance reasons.
#[cfg(all(feature = "jemalloc", unix))]
#[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::{args::{DiscoveryArgs, NetworkArgs, RpcServerArgs}, dirs::ChainPath};
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;

fn main() -> eyre::Result<()> {
reth::cli::Cli::parse_args().run(|builder, _| async move {
println!("WTF");
reth::cli::Cli::<L2Args>::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 {
discovery: DiscoveryArgs { disable_discovery: true, ..DiscoveryArgs::default() },
..NetworkArgs::default()
};

let chain_spec = ChainSpecBuilder::default()
.chain(gwyneth::exex::CHAIN_ID.into())
.genesis(
serde_json::from_str(include_str!(
"../../../crates/ethereum/node/tests/assets/genesis.json"
))
.unwrap(),
)
.cancun_activated()
.build();
let mut gwyneth_nodes = Vec::new();


let node_config = NodeConfig::test()
.with_chain(chain_spec.clone())
.with_network(network_config.clone())
.with_unused_ports()
.with_rpc(RpcServerArgs::default().with_unused_ports().with_static_l2_rpc_ip_and_port(chain_spec.chain.id()))
.set_dev(true);
// 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);

let NodeHandle { node: gwyneth_node, node_exit_future: _ } =
NodeBuilder::new(node_config.clone())
.gwyneth_node(exec.clone(), chain_spec.chain.id())
.node(GwynethNode::default())
.launch()
.await?;
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(
serde_json::from_str(include_str!(
"../../../crates/ethereum/node/tests/assets/genesis.json"
))
.unwrap(),
)
.cancun_activated()
.build();

let node_config = NodeConfig::test()
.with_chain(chain_spec.clone())
.with_network(network_config.clone())
.with_unused_ports()
.with_rpc(
RpcServerArgs::default()
.with_unused_ports()
.with_ports_and_ipc(ext.ports.get(idx), ext.ipc_path.clone(), chain_id)
);

// let db = Arc::new(init_db(node_config.datadir().db(), reth_db::mdbx::DatabaseArguments::default())?);

let NodeHandle { node: gwyneth_node, node_exit_future: _ } =
NodeBuilder::new(node_config.clone())
.gwyneth_node(exec.clone(), datadir)
.node(GwynethNode::default())
.launch()
.await?;

gwyneth_nodes.push(gwyneth_node);
}

let handle = builder
.node(EthereumNode::default())
.install_exex("Rollup", move |ctx| async {
Ok(gwyneth::exex::Rollup::new(ctx, gwyneth_node).await?.start())
Ok(gwyneth::exex::Rollup::new(ctx, gwyneth_nodes).await?.start())
})
.launch()
.await?;
Expand All @@ -70,4 +91,4 @@ mod tests {
#[command(flatten)]
args: T,
}
}
}
Loading
Loading