Skip to content

Commit

Permalink
feat(builder): add support for a bundle submission proxy
Browse files Browse the repository at this point in the history
  • Loading branch information
dancoombs committed Jan 31, 2025
1 parent 765b775 commit a81b063
Show file tree
Hide file tree
Showing 16 changed files with 345 additions and 87 deletions.
132 changes: 108 additions & 24 deletions bin/rundler/src/cli/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@

use std::net::SocketAddr;

use alloy_primitives::Address;
use anyhow::{bail, Context};
use clap::Args;
use rundler_builder::{
self, BloxrouteSenderArgs, BuilderEvent, BuilderEventKind, BuilderTask, BuilderTaskArgs,
EntryPointBuilderSettings, FlashbotsSenderArgs, LocalBuilderBuilder, RawSenderArgs,
TransactionSenderArgs, TransactionSenderKind,
self, BloxrouteSenderArgs, BuilderEvent, BuilderEventKind, BuilderSettings, BuilderTask,
BuilderTaskArgs, EntryPointBuilderSettings, FlashbotsSenderArgs, LocalBuilderBuilder,
RawSenderArgs, TransactionSenderArgs, TransactionSenderKind,
};
use rundler_pool::RemotePoolClient;
use rundler_provider::Providers;
Expand All @@ -29,9 +30,10 @@ use rundler_task::{
};
use rundler_types::{chain::ChainSpec, EntryPointVersion};
use rundler_utils::emit::{self, WithEntryPoint, EVENT_CHANNEL_CAPACITY};
use serde::Deserialize;
use tokio::sync::broadcast;

use super::{json::get_json_config, CommonArgs};
use super::CommonArgs;

const REQUEST_CHANNEL_CAPACITY: usize = 1024;

Expand Down Expand Up @@ -245,15 +247,6 @@ pub struct BuilderArgs {
default_value = "20"
)]
max_replacement_underpriced_blocks: u64,

/// The index offset to apply to the builder index
#[arg(
long = "builder_index_offset",
name = "builder_index_offset",
env = "BUILDER_INDEX_OFFSET",
default_value = "0"
)]
pub builder_index_offset: u64,
}

impl BuilderArgs {
Expand All @@ -264,6 +257,8 @@ impl BuilderArgs {
chain_spec: ChainSpec,
common: &CommonArgs,
remote_address: Option<SocketAddr>,
mempool_configs: Option<MempoolConfigs>,
entry_point_builders: Option<EntryPointBuilderConfigs>,
) -> anyhow::Result<BuilderTaskArgs> {
let priority_fee_mode = PriorityFeeMode::try_from(
common.priority_fee_mode_kind.as_str(),
Expand All @@ -272,36 +267,58 @@ impl BuilderArgs {

let rpc_url = common.node_http.clone().context("must provide node_http")?;

let mempool_configs = match &common.mempool_config_path {
Some(path) => get_json_config::<MempoolConfigs>(path)
.await
.with_context(|| format!("should load mempool configurations from {path}"))?,
None => MempoolConfigs::default(),
};

let mempool_configs = mempool_configs.unwrap_or_default();
let mut entry_points = vec![];
let mut num_builders = 0;

if !common.disable_entry_point_v0_6 {
let builders = if let Some(ep_builder_configs) = &entry_point_builders {
ep_builder_configs
.entry_points
.iter()
.find(|ep| ep.address == chain_spec.entry_point_address_v0_6)
.map(|ep| ep.builders())
.expect("should find entry point v0.6 builders")
} else {
builder_settings_from_cli(
common.builder_index_offset_v0_6,
common.num_builders_v0_6,
)
};

entry_points.push(EntryPointBuilderSettings {
address: chain_spec.entry_point_address_v0_6,
version: EntryPointVersion::V0_6,
num_bundle_builders: common.num_builders_v0_6,
bundle_builder_index_offset: self.builder_index_offset,
mempool_configs: mempool_configs
.get_for_entry_point(chain_spec.entry_point_address_v0_6),
builders,
});

num_builders += common.num_builders_v0_6;
}
if !common.disable_entry_point_v0_7 {
let builders = if let Some(ep_builder_configs) = &entry_point_builders {
ep_builder_configs
.entry_points
.iter()
.find(|ep| ep.address == chain_spec.entry_point_address_v0_7)
.map(|ep| ep.builders())
.expect("should find entry point v0.7 builders")
} else {
builder_settings_from_cli(
common.builder_index_offset_v0_7,
common.num_builders_v0_7,
)
};

entry_points.push(EntryPointBuilderSettings {
address: chain_spec.entry_point_address_v0_7,
version: EntryPointVersion::V0_7,
num_bundle_builders: common.num_builders_v0_7,
bundle_builder_index_offset: self.builder_index_offset,
mempool_configs: mempool_configs
.get_for_entry_point(chain_spec.entry_point_address_v0_7),
builders,
});

num_builders += common.num_builders_v0_7;
}

Expand Down Expand Up @@ -413,6 +430,69 @@ impl BuilderArgs {
}
}

#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub(crate) struct EntryPointBuilderConfigs {
// Builder configs per entry point
entry_points: Vec<EntryPointBuilderConfig>,
}

#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub(crate) struct EntryPointBuilderConfig {
// Entry point address
address: Address,
// Index offset for builders
index_offset: u64,
// Builder configs
builders: Vec<BuilderConfig>,
}

#[derive(Debug, Clone, Deserialize, Default)]
#[serde(rename_all = "camelCase")]
pub(crate) struct BuilderConfig {
// Number of builders using this config
count: u64,
// Submitter proxy to use for builders
proxy: Option<Address>,
}

impl EntryPointBuilderConfigs {
pub(crate) fn set_known_proxies(&self, chain_spec: &mut ChainSpec) {
for entry_point in &self.entry_points {
for builder in &entry_point.builders {
if let Some(proxy) = builder.proxy {
chain_spec.known_entry_point_proxies.push(proxy);
}
}
}
}
}

impl EntryPointBuilderConfig {
pub fn builders(&self) -> Vec<BuilderSettings> {
let mut index = self.index_offset;
let mut builders = vec![];
for builder in &self.builders {
builders.extend((0..builder.count).map(|i| BuilderSettings {
index: index + i,
submitter_proxy: builder.proxy,
}));
index += builder.count;
}
builders
}
}

fn builder_settings_from_cli(index_offset: u64, count: u64) -> Vec<BuilderSettings> {
(0..=count)
.map(|i| BuilderSettings {
index: index_offset + i,
submitter_proxy: None,
})
.collect()
}

/// CLI options for the Builder server standalone
#[derive(Args, Debug)]
pub struct BuilderCliArgs {
Expand Down Expand Up @@ -450,11 +530,15 @@ pub async fn spawn_tasks<T: TaskSpawnerExt + 'static>(
)),
);

let (mempool_config, entry_point_builders) = super::load_configs(&common_args).await?;

let task_args = builder_args
.to_args(
chain_spec.clone(),
&common_args,
Some(format_socket_addr(&builder_args.host, builder_args.port).parse()?),
mempool_config,
entry_point_builders,
)
.await?;

Expand Down
114 changes: 103 additions & 11 deletions bin/rundler/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ mod pool;
mod rpc;
mod tracing;

use builder::BuilderCliArgs;
use builder::{BuilderCliArgs, EntryPointBuilderConfigs};
use json::get_json_config;
use node::NodeCliArgs;
use pool::PoolCliArgs;
use reth_tasks::TaskManager;
Expand All @@ -38,7 +39,8 @@ use rundler_provider::{
};
use rundler_rpc::{EthApiSettings, RundlerApiSettings};
use rundler_sim::{
EstimationSettings, PrecheckSettings, PriorityFeeMode, SimulationSettings, MIN_CALL_GAS_LIMIT,
EstimationSettings, MempoolConfigs, PrecheckSettings, PriorityFeeMode, SimulationSettings,
MIN_CALL_GAS_LIMIT,
};
use rundler_types::{
chain::ChainSpec, da::DAGasOracleType, v0_6::UserOperation as UserOperationV0_6,
Expand Down Expand Up @@ -68,17 +70,40 @@ pub async fn run() -> anyhow::Result<()> {
.context("metrics server should start")?;

let mut cs = chain_spec::resolve_chain_spec(&opt.common.network, &opt.common.chain_spec);
tracing::info!("Chain spec: {:#?}", cs);

let (mempool_configs, entry_point_builders) = load_configs(&opt.common).await?;
if let Some(entry_point_builders) = &entry_point_builders {
entry_point_builders.set_known_proxies(&mut cs);
}

let providers = construct_providers(&opt.common, &cs)?;
aggregator::instantiate_aggregators(&opt.common, &mut cs, &providers);

tracing::info!("Chain spec: {:#?}", cs);

match opt.command {
Command::Node(args) => {
node::spawn_tasks(task_spawner.clone(), cs, *args, opt.common, providers).await?
node::spawn_tasks(
task_spawner.clone(),
cs,
*args,
opt.common,
providers,
mempool_configs,
entry_point_builders,
)
.await?
}
Command::Pool(args) => {
pool::spawn_tasks(task_spawner.clone(), cs, args, opt.common, providers).await?
pool::spawn_tasks(
task_spawner.clone(),
cs,
args,
opt.common,
providers,
mempool_configs,
)
.await?
}
Command::Rpc(args) => {
rpc::spawn_tasks(task_spawner.clone(), cs, args, opt.common, providers).await?
Expand Down Expand Up @@ -307,6 +332,15 @@ pub struct CommonArgs {
)]
pub mempool_config_path: Option<String>,

/// Config path for entrypoint builders
#[arg(
long = "entry_point_builders_path",
name = "entry_point_builders_path",
env = "ENTRY_POINT_BUILDERS_PATH",
default_value = ""
)]
entry_point_builders_path: Option<String>,

#[arg(
long = "disable_entry_point_v0_6",
name = "disable_entry_point_v0_6",
Expand All @@ -316,7 +350,17 @@ pub struct CommonArgs {
)]
pub disable_entry_point_v0_6: bool,

#[arg(
long = "disable_entry_point_v0_7",
name = "disable_entry_point_v0_7",
env = "DISABLE_ENTRY_POINT_V0_7",
default_value = "false",
global = true
)]
pub disable_entry_point_v0_7: bool,

// Ignored if entry_point_v0_6_enabled is false
// Ignored if entry_point_builders_path is set
#[arg(
long = "num_builders_v0_6",
name = "num_builders_v0_6",
Expand All @@ -326,16 +370,19 @@ pub struct CommonArgs {
)]
pub num_builders_v0_6: u64,

// Ignored if entry_point_v0_6_enabled is false
// Ignored if entry_point_builders_path is set
// The index offset to apply to the builder index
#[arg(
long = "disable_entry_point_v0_7",
name = "disable_entry_point_v0_7",
env = "DISABLE_ENTRY_POINT_V0_7",
default_value = "false",
global = true
long = "builder_index_offset_v0_6",
name = "builder_index_offset_v0_6",
env = "BUILDER_INDEX_OFFSET_V0_6",
default_value = "0"
)]
pub disable_entry_point_v0_7: bool,
pub builder_index_offset_v0_6: u64,

// Ignored if entry_point_v0_7_enabled is false
// Ignored if entry_point_builders_path is set
#[arg(
long = "num_builders_v0_7",
name = "num_builders_v0_7",
Expand All @@ -345,6 +392,17 @@ pub struct CommonArgs {
)]
pub num_builders_v0_7: u64,

// Ignored if entry_point_v0_7_enabled is false
// Ignored if entry_point_builders_path is set
// The index offset to apply to the builder index
#[arg(
long = "builder_index_offset_v0_7",
name = "builder_index_offset_v0_7",
env = "BUILDER_INDEX_OFFSET_V0_7",
default_value = "0"
)]
pub builder_index_offset_v0_7: u64,

#[arg(
long = "da_gas_tracking_enabled",
name = "da_gas_tracking_enabled",
Expand Down Expand Up @@ -678,3 +736,37 @@ fn lint_da_gas_tracking(da_gas_tracking_enabled: bool, chain_spec: &ChainSpec) -
true
}
}

async fn load_configs(
args: &CommonArgs,
) -> anyhow::Result<(Option<MempoolConfigs>, Option<EntryPointBuilderConfigs>)> {
let mempool_configs = if let Some(mempool_config_path) = &args.mempool_config_path {
let mempool_configs = get_json_config::<MempoolConfigs>(mempool_config_path)
.await
.with_context(|| format!("should load mempool config from {mempool_config_path}"))?;

tracing::info!("Mempool configs: {:?}", mempool_configs);

Some(mempool_configs)
} else {
None
};

let entry_point_builders =
if let Some(entry_point_builders_path) = &args.entry_point_builders_path {
let entry_point_builders =
get_json_config::<EntryPointBuilderConfigs>(entry_point_builders_path)
.await
.with_context(|| {
format!("should load entry point builders from {entry_point_builders_path}")
})?;

tracing::info!("Entry point builders: {:?}", entry_point_builders);

Some(entry_point_builders)
} else {
None
};

Ok((mempool_configs, entry_point_builders))
}
Loading

0 comments on commit a81b063

Please sign in to comment.