Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 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
6 changes: 0 additions & 6 deletions .github/workflows/checks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -135,12 +135,6 @@ jobs:
- name: Run integration tests
run: cargo test --package op-rbuilder --lib

- name: Build flashblocks rbuilder
run: cargo build -p op-rbuilder --bin op-rbuilder --features flashblocks

- name: Run flashblocks builder integration tests
run: cargo test --package op-rbuilder --lib --features flashblocks

- name: Aggregate playground logs
# This steps fails if the test fails early and the playground logs dir has not been created
if: ${{ failure() }}
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ lint: ## Run the linters
test: ## Run the tests for rbuilder and op-rbuilder
cargo test --verbose --features "$(FEATURES)"
cargo test -p op-rbuilder --verbose --features "$(FEATURES)"
cargo test -p op-rbuilder --verbose --features "$(FEATURES),flashblocks"

.PHONY: lt
lt: lint test ## Run "lint" and "test"
Expand Down
1 change: 0 additions & 1 deletion crates/op-rbuilder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ min-debug-logs = ["tracing/release_max_level_debug"]
min-trace-logs = ["tracing/release_max_level_trace"]

testing = []
flashblocks = []

[[bin]]
name = "op-rbuilder"
Expand Down
80 changes: 78 additions & 2 deletions crates/op-rbuilder/src/args/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,81 @@
use crate::builders::BuilderMode;
use clap::Parser;
pub use op::OpRbuilderArgs;
use playground::PlaygroundOptions;
use reth_optimism_cli::{chainspec::OpChainSpecParser, commands::Commands};

mod op;
mod playground;

pub use op::OpRbuilderArgs;
pub use playground::CliExt;
/// This trait is used to extend Reth's CLI with additional functionality that
/// are specific to the OP builder, such as populating default values for CLI arguments
/// when running in the playground mode or checking the builder mode.
///
pub trait CliExt {
/// Populates the default values for the CLI arguments when the user specifies
/// the `--builder.playground` flag.
fn populate_defaults(self) -> Self;

/// Returns the builder mode that the node is started with.
fn builder_mode(&self) -> BuilderMode;

/// Returns the Cli instance with the parsed command line arguments
/// and defaults populated if applicable.
fn parsed() -> Self;
}

pub type Cli = reth_optimism_cli::Cli<OpChainSpecParser, OpRbuilderArgs>;

impl CliExt for Cli {
/// Checks if the node is started with the `--builder.playground` flag,
/// and if so, populates the default values for the CLI arguments from the
/// playground configuration.
///
/// The `--builder.playground` flag is used to populate the CLI arguments with
/// default values for running the builder against the playground environment.
///
/// The values are populated from the default directory of the playground
/// configuration, which is `$HOME/.playground/devnet/` by default.
///
/// Any manually specified CLI arguments by the user will override the defaults.
fn populate_defaults(self) -> Self {
let Commands::Node(ref node_command) = self.command else {
// playground defaults are only relevant if running the node commands.
return self;
};

let Some(ref playground_dir) = node_command.ext.playground else {
// not running in playground mode.
return self;
};

let options = match PlaygroundOptions::new(playground_dir) {
Ok(options) => options,
Err(e) => exit(e),
};

options.apply(self)
}

fn parsed() -> Self {
Cli::parse().populate_defaults()
}

/// Returns the type of builder implementation that the node is started with.
/// Currently supports `Standard` and `Flashblocks` modes.
fn builder_mode(&self) -> BuilderMode {
if let Commands::Node(ref node_command) = self.command {
if node_command.ext.enable_flashblocks {
return BuilderMode::Flashblocks;
}
}
BuilderMode::Standard
}
}

/// Following clap's convention, a failure to parse the command line arguments
/// will result in terminating the program with a non-zero exit code.
fn exit(error: eyre::Report) -> ! {
eprintln!("{error}");
std::process::exit(-1);
}
13 changes: 13 additions & 0 deletions crates/op-rbuilder/src/args/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@ pub struct OpRbuilderArgs {
/// Builder secret key for signing last transaction in block
#[arg(long = "rollup.builder-secret-key", env = "BUILDER_SECRET_KEY")]
pub builder_signer: Option<Signer>,

/// When set to true, the builder will build flashblocks
/// and will only build standard blocks at the chain block time.
///
/// The default value will change in the future once the flashblocks
/// feature is stable.
#[arg(
long = "rollup.enable-flashblocks",
default_value = "false",
env = "ENABLE_FLASHBLOCKS"
)]
pub enable_flashblocks: bool,

/// Websocket port for flashblock payload builder
#[arg(
long = "rollup.flashblocks-ws-url",
Expand Down
50 changes: 2 additions & 48 deletions crates/op-rbuilder/src/args/playground.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
//! directory to use. This is useful for testing against different playground
//! configurations.

use super::OpRbuilderArgs;
use alloy_primitives::hex;
use clap::{parser::ValueSource, CommandFactory};
use core::{
Expand All @@ -49,47 +48,9 @@ use std::{
};
use url::{Host, Url};

/// This trait is used to extend Reth's CLI with additional functionality that
/// populates the default values for the command line arguments when the user
/// specifies that they want to use the playground.
///
/// The `--builder.playground` flag is used to populate the CLI arguments with
/// default values for running the builder against the playground environment.
///
/// The values are populated from the default directory of the playground
/// configuration, which is `$HOME/.playground/devnet/` by default.
///
/// Any manually specified CLI arguments by the user will override the defaults.
pub trait CliExt {
/// Populates the default values for the CLI arguments when the user specifies
/// the `--builder.playground` flag.
fn populate_defaults(self) -> Self;
}

type Cli = reth_optimism_cli::Cli<OpChainSpecParser, OpRbuilderArgs>;

impl CliExt for Cli {
fn populate_defaults(self) -> Self {
let Commands::Node(ref node_command) = self.command else {
// playground defaults are only relevant if running the node commands.
return self;
};

let Some(ref playground_dir) = node_command.ext.playground else {
// not running in playground mode.
return self;
};
use super::Cli;

let options = match PlaygroundOptions::new(playground_dir) {
Ok(options) => options,
Err(e) => exit(e),
};

options.apply(self)
}
}

struct PlaygroundOptions {
pub struct PlaygroundOptions {
/// Sets node.chain in NodeCommand
pub chain: Arc<OpChainSpec>,

Expand Down Expand Up @@ -210,13 +171,6 @@ impl PlaygroundOptions {
}
}

/// Following clap's convention, a failure to parse the command line arguments
/// will result in terminating the program with a non-zero exit code.
fn exit(error: eyre::Report) -> ! {
eprintln!("{error}");
std::process::exit(-1);
}

fn existing_path(base: &Path, relative: &str) -> Result<String> {
let path = base.join(relative);
if path.exists() {
Expand Down
55 changes: 55 additions & 0 deletions crates/op-rbuilder/src/builders/flashblocks/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
use crate::{args::OpRbuilderArgs, builders::BuilderConfig};
use core::{
net::{Ipv4Addr, SocketAddr},
time::Duration,
};

/// Configuration values that are specific to the flashblocks builder.
#[derive(Debug, Clone)]
pub struct FlashblocksConfig {
/// The address of the websockets endpoint that listens for subscriptions to
/// new flashblocks updates.
pub ws_addr: SocketAddr,

/// How often a flashblock is produced. This is independent of the block time of the chain.
/// Each block will contain one or more flashblocks. On average, the number of flashblocks
/// per block is equal to the block time divided by the flashblock interval.
pub interval: Duration,
}

impl Default for FlashblocksConfig {
fn default() -> Self {
Self {
ws_addr: SocketAddr::new(Ipv4Addr::UNSPECIFIED.into(), 1111),
interval: Duration::from_millis(250),
}
}
}

impl TryFrom<OpRbuilderArgs> for FlashblocksConfig {
type Error = eyre::Report;

fn try_from(args: OpRbuilderArgs) -> Result<Self, Self::Error> {
let ws_addr = args
.flashblocks_ws_url
.parse()
.map_err(|_| eyre::eyre!("Invalid flashblocks websocket address"))?;

let interval = Duration::from_millis(args.flashblock_block_time);

Ok(Self { ws_addr, interval })
}
}

pub trait FlashBlocksConfigExt {
fn flashblocks_per_block(&self) -> u64;
}

impl FlashBlocksConfigExt for BuilderConfig<FlashblocksConfig> {
fn flashblocks_per_block(&self) -> u64 {
if self.block_time.as_millis() == 0 {
return 0;
}
(self.block_time.as_millis() / self.specific.interval.as_millis()) as u64
}
}
Loading
Loading