Skip to content
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[workspace.package]
version = "0.2.2"
edition = "2024"
rust-version = "1.86"
rust-version = "1.88"
license = "MIT OR Apache-2.0"
homepage = "https://github.com/flashbots/op-rbuilder"
repository = "https://github.com/flashbots/op-rbuilder"
Expand Down
5 changes: 1 addition & 4 deletions crates/op-rbuilder/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ fn main() -> Result<(), Box<dyn Error>> {

emitter.add_instructions(&build_builder)?;

let cargo_builder = CargoBuilder::default()
.features(true)
.target_triple(true)
.build()?;
let cargo_builder = CargoBuilder::default().features(true).target_triple(true).build()?;

emitter.add_instructions(&cargo_builder)?;

Expand Down
29 changes: 15 additions & 14 deletions crates/op-rbuilder/src/args/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,11 @@ mod op;
mod playground;

/// 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.
///
/// 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.
/// 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.
Expand All @@ -38,13 +37,15 @@ impl CliExt for Cli {
/// 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 `--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.
/// 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.
Expand All @@ -65,13 +66,13 @@ impl CliExt for Cli {
Cli::set_version().populate_defaults()
}

/// Returns the type of builder implementation that the node is started with.
/// Currently supports `Standard` and `Flashblocks` modes.
/// 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.flashblocks.enabled {
return BuilderMode::Flashblocks;
}
if let Commands::Node(ref node_command) = self.command &&
node_command.ext.flashblocks.enabled
{
return BuilderMode::Flashblocks;
}
BuilderMode::Standard
}
Expand Down
86 changes: 29 additions & 57 deletions crates/op-rbuilder/src/args/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,7 @@ pub struct OpRbuilderArgs {
pub builder_signer: Option<Signer>,

/// chain block time in milliseconds
#[arg(
long = "rollup.chain-block-time",
default_value = "1000",
env = "CHAIN_BLOCK_TIME"
)]
#[arg(long = "rollup.chain-block-time", default_value = "1000", env = "CHAIN_BLOCK_TIME")]
pub chain_block_time: u64,

/// max gas a transaction can use
Expand All @@ -41,14 +37,16 @@ pub struct OpRbuilderArgs {
#[arg(long = "builder.log-pool-transactions", default_value = "false")]
pub log_pool_transactions: bool,

/// How much time extra to wait for the block building job to complete and not get garbage collected
/// How much time extra to wait for the block building job to complete and
/// not get garbage collected
#[arg(long = "builder.extra-block-deadline-secs", default_value = "20")]
pub extra_block_deadline_secs: u64,
/// Whether to enable revert protection by default
#[arg(long = "builder.enable-revert-protection", default_value = "false")]
pub enable_revert_protection: bool,

/// Path to builder playgorund to automatically start up the node connected to it
/// Path to builder playground to automatically start up the node connected
/// to it
#[arg(
long = "builder.playground",
num_args = 0..=1,
Expand All @@ -70,9 +68,7 @@ pub struct OpRbuilderArgs {
impl Default for OpRbuilderArgs {
fn default() -> Self {
let args = crate::args::Cli::parse_from(["dummy", "node"]);
let Commands::Node(node_command) = args.command else {
unreachable!()
};
let Commands::Node(node_command) = args.command else { unreachable!() };
node_command.ext
}
}
Expand All @@ -87,65 +83,44 @@ fn expand_path(s: &str) -> Result<PathBuf> {

/// Parameters for Flashblocks configuration
/// The names in the struct are prefixed with `flashblocks` to avoid conflicts
/// with the standard block building configuration since these args are flattened
/// into the main `OpRbuilderArgs` struct with the other rollup/node args.
/// with the standard block building configuration since these args are
/// flattened into the main `OpRbuilderArgs` struct with the other rollup/node
/// args.
#[derive(Debug, Clone, PartialEq, Eq, clap::Args)]
pub struct FlashblocksArgs {
/// When set to true, the builder will build flashblocks
/// and will build standard blocks at the chain block time.
///
/// The default value will change in the future once the flashblocks
/// feature is stable.
#[arg(
long = "flashblocks.enabled",
default_value = "false",
env = "ENABLE_FLASHBLOCKS"
)]
#[arg(long = "flashblocks.enabled", default_value = "false", env = "ENABLE_FLASHBLOCKS")]
pub enabled: bool,

/// The port that we bind to for the websocket server that provides flashblocks
#[arg(
long = "flashblocks.port",
env = "FLASHBLOCKS_WS_PORT",
default_value = "1111"
)]
/// The port that we bind to for the websocket server that provides
/// flashblocks
#[arg(long = "flashblocks.port", env = "FLASHBLOCKS_WS_PORT", default_value = "1111")]
pub flashblocks_port: u16,

/// The address that we bind to for the websocket server that provides flashblocks
#[arg(
long = "flashblocks.addr",
env = "FLASHBLOCKS_WS_ADDR",
default_value = "127.0.0.1"
)]
/// The address that we bind to for the websocket server that provides
/// flashblocks
#[arg(long = "flashblocks.addr", env = "FLASHBLOCKS_WS_ADDR", default_value = "127.0.0.1")]
pub flashblocks_addr: String,

/// flashblock block time in milliseconds
#[arg(
long = "flashblocks.block-time",
default_value = "250",
env = "FLASHBLOCK_BLOCK_TIME"
)]
#[arg(long = "flashblocks.block-time", default_value = "250", env = "FLASHBLOCK_BLOCK_TIME")]
pub flashblocks_block_time: u64,

/// Builder would always thry to produce fixed number of flashblocks without regard to time of
/// FCU arrival.
/// Builder would always thry to produce fixed number of flashblocks without
/// regard to time of FCU arrival.
/// In cases of late FCU it could lead to partially filled blocks.
#[arg(
long = "flashblocks.fixed",
default_value = "false",
env = "FLASHBLOCK_FIXED"
)]
#[arg(long = "flashblocks.fixed", default_value = "false", env = "FLASHBLOCK_FIXED")]
pub flashblocks_fixed: bool,

/// Time by which blocks would be completed earlier in milliseconds.
///
/// This time used to account for latencies, this time would be deducted from total block
/// building time before calculating number of fbs.
#[arg(
long = "flashblocks.leeway-time",
default_value = "75",
env = "FLASHBLOCK_LEEWAY_TIME"
)]
/// This time used to account for latencies, this time would be deducted
/// from total block building time before calculating number of fbs.
#[arg(long = "flashblocks.leeway-time", default_value = "75", env = "FLASHBLOCK_LEEWAY_TIME")]
pub flashblocks_leeway_time: u64,

/// Should we calculate state root for each flashblock
Expand All @@ -160,9 +135,7 @@ pub struct FlashblocksArgs {
impl Default for FlashblocksArgs {
fn default() -> Self {
let args = crate::args::Cli::parse_from(["dummy", "node"]);
let Commands::Node(node_command) = args.command else {
unreachable!()
};
let Commands::Node(node_command) = args.command else { unreachable!() };
node_command.ext.flashblocks
}
}
Expand All @@ -178,11 +151,10 @@ pub struct TelemetryArgs {
#[arg(long = "telemetry.otlp-headers", env = "OTEL_EXPORTER_OTLP_HEADERS")]
pub otlp_headers: Option<String>,

/// Inverted sampling frequency in blocks. 1 - each block, 100 - every 100th block.
#[arg(
long = "telemetry.sampling-ratio",
env = "SAMPLING_RATIO",
default_value = "100"
)]
/// Inverted sampling frequency in blocks.
///
/// 1 - each block
/// 100 - every 100th block.
#[arg(long = "telemetry.sampling-ratio", env = "SAMPLING_RATIO", default_value = "100")]
pub sampling_ratio: u64,
}
35 changes: 10 additions & 25 deletions crates/op-rbuilder/src/args/playground.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,7 @@ impl PlaygroundOptions {
/// Creates a new `PlaygroundOptions` instance with the specified genesis path.
pub(super) fn new(path: &Path) -> Result<Self> {
if !path.exists() {
return Err(eyre!(
"Playground data directory {} does not exist",
path.display()
));
return Err(eyre!("Playground data directory {} does not exist", path.display()));
}

let chain = OpChainSpecParser::parse(&existing_path(path, "l2-genesis.json")?)?;
Expand Down Expand Up @@ -127,9 +124,8 @@ impl PlaygroundOptions {
// either via the command line or an environment variable. Otherwise, don't
// override the user provided values.
let matches = Cli::command().get_matches();
let matches = matches
.subcommand_matches("node")
.expect("validated that we are in the node command");
let matches =
matches.subcommand_matches("node").expect("validated that we are in the node command");

if matches.value_source("chain").is_default() {
node.chain = self.chain;
Expand Down Expand Up @@ -223,9 +219,7 @@ fn extract_chain_block_time(basepath: &Path) -> Result<Duration> {

fn extract_deterministic_p2p_key(basepath: &Path) -> Result<SecretKey> {
let key = read_to_string(existing_path(basepath, "enode-key-1.txt")?)?;
Ok(SecretKey::from_slice(
&hex::decode(key).map_err(|e| eyre!("Invalid hex key: {e}"))?,
)?)
Ok(SecretKey::from_slice(&hex::decode(key).map_err(|e| eyre!("Invalid hex key: {e}"))?)?)
}

fn read_docker_compose(basepath: &Path) -> Result<serde_yaml::Value> {
Expand All @@ -238,9 +232,7 @@ fn extract_service_command_flag(basepath: &Path, service: &str, flag: &str) -> R
let docker_compose = read_docker_compose(basepath)?;
let args = docker_compose["services"][service]["command"]
.as_sequence()
.ok_or(eyre!(
"docker-compose.yaml is missing command line arguments for {service}"
))?
.ok_or(eyre!("docker-compose.yaml is missing command line arguments for {service}"))?
.iter()
.map(|s| {
s.as_str().ok_or_else(|| {
Expand All @@ -254,9 +246,8 @@ fn extract_service_command_flag(basepath: &Path, service: &str, flag: &str) -> R
.position(|arg| *arg == flag)
.ok_or_else(|| eyre!("docker_compose: {flag} not found on {service} service"))?;

let value = args
.get(index + 1)
.ok_or_else(|| eyre!("docker_compose: {flag} value not found"))?;
let value =
args.get(index + 1).ok_or_else(|| eyre!("docker_compose: {flag} value not found"))?;

Ok(value.to_string())
}
Expand All @@ -274,9 +265,7 @@ fn extract_trusted_peer_port(basepath: &Path) -> Result<u16> {
// command line arguments used to start the op-geth service

let Some(opgeth_args) = docker_compose["services"]["op-geth"]["command"][1].as_str() else {
return Err(eyre!(
"docker-compose.yaml is missing command line arguments for op-geth"
));
return Err(eyre!("docker-compose.yaml is missing command line arguments for op-geth"));
};

let opgeth_args = opgeth_args.split_whitespace().collect::<Vec<_>>();
Expand All @@ -289,16 +278,12 @@ fn extract_trusted_peer_port(basepath: &Path) -> Result<u16> {
.get(port_param_position + 1)
.ok_or_else(|| eyre!("docker_compose: --port value not found"))?;

let port_value = port_value
.parse::<u16>()
.map_err(|e| eyre!("Invalid port value: {e}"))?;
let port_value = port_value.parse::<u16>().map_err(|e| eyre!("Invalid port value: {e}"))?;

// now we need to find the external port of the op-geth service from the docker-compose.yaml
// ports mapping used to start the op-geth service
let Some(opgeth_ports) = docker_compose["services"]["op-geth"]["ports"].as_sequence() else {
return Err(eyre!(
"docker-compose.yaml is missing ports mapping for op-geth"
));
return Err(eyre!("docker-compose.yaml is missing ports mapping for op-geth"));
};
let ports_mapping = opgeth_ports
.iter()
Expand Down
4 changes: 1 addition & 3 deletions crates/op-rbuilder/src/bin/tester/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,7 @@ pub async fn run_system(validation: bool) -> eyre::Result<()> {
let mut driver = ChainDriver::<Http>::remote(provider, engine_api);

if validation {
driver = driver
.with_validation_node(ExternalNode::reth().await?)
.await?;
driver = driver.with_validation_node(ExternalNode::reth().await?).await?;
}

// Infinite loop generating blocks
Expand Down
15 changes: 6 additions & 9 deletions crates/op-rbuilder/src/builders/builder_tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,8 @@ pub trait BuilderTransactions<ExtraCtx: Debug + Default = ()>: Debug {
db: &mut State<impl Database>,
) -> Result<Vec<BuilderTransactionCtx>, BuilderTransactionError> {
{
let mut evm = builder_ctx
.evm_config
.evm_with_env(&mut *db, builder_ctx.evm_env.clone());
let mut evm =
builder_ctx.evm_config.evm_with_env(&mut *db, builder_ctx.evm_env.clone());

let mut invalid: HashSet<Address> = HashSet::new();

Expand All @@ -109,7 +108,8 @@ pub trait BuilderTransactions<ExtraCtx: Debug + Default = ()>: Debug {
continue;
}

// Add gas used by the transaction to cumulative gas used, before creating the receipt
// Add gas used by the transaction to cumulative gas used, before creating the
// receipt
let gas_used = result.gas_used();
info.cumulative_gas_used += gas_used;

Expand All @@ -127,8 +127,7 @@ pub trait BuilderTransactions<ExtraCtx: Debug + Default = ()>: Debug {

// Append sender and transaction to the respective lists
info.executed_senders.push(builder_tx.signed_tx.signer());
info.executed_transactions
.push(builder_tx.signed_tx.clone().into_inner());
info.executed_transactions.push(builder_tx.signed_tx.clone().into_inner());
}

// Release the db reference by dropping evm
Expand All @@ -151,9 +150,7 @@ pub trait BuilderTransactions<ExtraCtx: Debug + Default = ()>: Debug {
.with_bundle_prestate(db.bundle_state.clone())
.with_bundle_update()
.build();
let mut evm = ctx
.evm_config
.evm_with_env(&mut simulation_state, ctx.evm_env.clone());
let mut evm = ctx.evm_config.evm_with_env(&mut simulation_state, ctx.evm_env.clone());

for builder_tx in builder_txs {
let ResultAndState { state, .. } = evm
Expand Down
Loading
Loading