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,699 changes: 2,118 additions & 581 deletions Cargo.lock

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ base-builder-cli = { path = "crates/builder/cli" }
base-builder-core = { path = "crates/builder/core" }
base-builder-publish = { path = "crates/builder/publish" }
base-builder-metering = { path = "crates/builder/metering" }
base-intent-swap = { path = "crates/builder/intent-swap" }

# Consensus
base-consensus-cli = { path = "crates/consensus/cli" }
Expand Down Expand Up @@ -289,6 +290,10 @@ base-balance-monitor = { path = "crates/utilities/balance-monitor" }
base-metrics = { path = "crates/utilities/metrics", default-features = false }
base-runtime = { path = "crates/utilities/runtime", default-features = false }

# Intent-swap engine (Propellerheads)
backrunner = { git = "ssh://git@github.com/propeller-heads/builder-integration.git", rev = "6029f1b4739c753383c0ce5ef03a70ad1bd007e5" }
builder-types = { git = "ssh://git@github.com/propeller-heads/builder-integration.git", rev = "6029f1b4739c753383c0ce5ef03a70ad1bd007e5" }

# revm
revm = { version = "40.0.3", default-features = false }
revm-bytecode = { version = "11.0.0", default-features = false }
Expand Down
5 changes: 5 additions & 0 deletions bin/builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ base-txpool-rpc.workspace = true
base-node-runner.workspace = true
base-builder-cli.workspace = true
base-builder-core.workspace = true
base-intent-swap.workspace = true
base-builder-metering.workspace = true
base-observability-events.workspace = true

Expand All @@ -33,6 +34,10 @@ base-execution-cli = { workspace = true, features = ["otlp"] }
# cli
clap.workspace = true

# misc
eyre.workspace = true
tokio = { workspace = true, features = ["sync"] }

[features]
default = [ "jemalloc" ]
jemalloc = [ "base-builder-core/jemalloc", "base-execution-cli/jemalloc" ]
49 changes: 48 additions & 1 deletion bin/builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,23 @@ fn main() {
transaction_events_enabled.then(|| builder_args.transaction_events.writer_config()),
)?;

let builder_config = builder_args
let intent_swap_args = builder_args.intent_swap.clone();
let mut builder_config = builder_args
.into_builder_config(Arc::clone(&metering_provider))
.expect("Failed to convert rollup args to builder config");
let da_config = builder_config.da_config.clone();
let gas_limit_config = builder_config.gas_limit_config.clone();

let intent_swap = if intent_swap_args.enabled {
let (event_tx, event_rx) =
tokio::sync::mpsc::channel(intent_swap_args.event_channel_capacity);
builder_config.build_event_tx = Some(event_tx);
let config = intent_swap_config(&intent_swap_args)?;
Some((config, event_rx))
} else {
None
};

let mut runner = BaseNodeRunner::new(rollup_args.clone())
.with_da_config(da_config)
.with_gas_limit_config(gas_limit_config)
Expand All @@ -54,6 +65,9 @@ fn main() {
runner.install_ext::<TxPoolRpcExtension>(TxPoolRpcConfig::default());
runner.install_ext::<BuilderApiExtension>(());
StandardBaseRethNode::install_upgrade_signal_runtime_extension(&mut runner, &rollup_args)?;
if let Some(config_and_rx) = intent_swap {
runner.install_ext::<base_intent_swap::IntentSwapExtension>(config_and_rx);
}
runner.add_started_callback(|| {
base_cli_utils::register_version_metrics!();
Ok(())
Expand All @@ -63,3 +77,36 @@ fn main() {
})
.unwrap();
}

/// Builds the intent-swap config from CLI args; errors on missing required values.
fn intent_swap_config(
args: &base_builder_cli::IntentSwapArgs,
) -> eyre::Result<base_intent_swap::IntentSwapConfig> {
Ok(base_intent_swap::IntentSwapConfig {
tycho_url: args.tycho_url.clone(),
tycho_api_key: args.tycho_api_key.clone(),
rpc_url: args
.rpc_url
.clone()
.ok_or_else(|| eyre::eyre!("--builder.intent-swap.rpc-url is required"))?,
protocols: args.protocols.clone(),
resolver_address: args
.resolver_address
.as_deref()
.ok_or_else(|| eyre::eyre!("--builder.intent-swap.resolver-address is required"))?
.parse()
.map_err(|e| eyre::eyre!("invalid resolver address: {e}"))?,
chain: args.chain.clone(),
chain_id: args.chain_id,
min_tvl: args.min_tvl,
slippage: args.slippage,
eoa_private_key: args
.eoa_key
.clone()
.ok_or_else(|| eyre::eyre!("INTENT_SWAP_EOA_KEY is required"))?,
order_queue_capacity: args.order_queue_capacity,
ready_timeout: std::time::Duration::from_secs(600),
orderbook_interval: std::time::Duration::from_secs(60),
verify_onchain_taking: args.verify_onchain_taking,
})
}
132 changes: 132 additions & 0 deletions crates/builder/cli/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,132 @@ impl TransactionEventsArgs {
}
}

/// CLI options for the intent-swap extension.
#[derive(Debug, Clone, PartialEq, clap::Args)]
pub struct IntentSwapArgs {
/// Enables the intent-swap extension.
#[arg(
id = "intent_swap_enabled",
long = "builder.intent-swap.enabled",
env = "INTENT_SWAP_ENABLED",
default_value = "false"
)]
pub enabled: bool,
/// Tycho WebSocket host.
#[arg(
long = "builder.intent-swap.tycho-url",
env = "INTENT_SWAP_TYCHO_URL",
default_value = "tycho-beta.propellerheads.xyz"
)]
pub tycho_url: String,
/// Tycho API key.
#[arg(
long = "builder.intent-swap.tycho-api-key",
env = "INTENT_SWAP_TYCHO_API_KEY",
hide_env_values = true
)]
pub tycho_api_key: Option<String>,
/// Chain JSON-RPC URL for on-chain order queries.
#[arg(long = "builder.intent-swap.rpc-url", env = "INTENT_SWAP_RPC_URL")]
pub rpc_url: Option<String>,
/// Fusion resolver contract address.
#[arg(long = "builder.intent-swap.resolver-address", env = "INTENT_SWAP_RESOLVER_ADDRESS")]
pub resolver_address: Option<String>,
/// EOA private key for signing settlements (env only in practice).
#[arg(
long = "builder.intent-swap.eoa-key",
env = "INTENT_SWAP_EOA_KEY",
hide_env_values = true
)]
pub eoa_key: Option<String>,
/// Chain slug for Tycho market data.
#[arg(
id = "intent_swap_chain",
long = "builder.intent-swap.chain",
env = "INTENT_SWAP_CHAIN",
default_value = "base",
value_name = "CHAIN"
)]
pub chain: String,
/// 1inch Fusion chain id.
#[arg(
long = "builder.intent-swap.chain-id",
env = "INTENT_SWAP_CHAIN_ID",
default_value = "8453"
)]
pub chain_id: u64,
/// Comma-separated Tycho protocol slugs.
#[arg(
long = "builder.intent-swap.protocols",
env = "INTENT_SWAP_PROTOCOLS",
default_value = "uniswap_v2,uniswap_v3,uniswap_v4",
value_delimiter = ','
)]
pub protocols: Vec<String>,
/// Minimum pool TVL filter.
#[arg(
long = "builder.intent-swap.min-tvl",
env = "INTENT_SWAP_MIN_TVL",
default_value = "10.0"
)]
pub min_tvl: f64,
/// Route slippage tolerance.
#[arg(
long = "builder.intent-swap.slippage",
env = "INTENT_SWAP_SLIPPAGE",
default_value = "0.005"
)]
pub slippage: f64,
/// Submitted-order queue capacity.
#[arg(
long = "builder.intent-swap.order-queue-capacity",
env = "INTENT_SWAP_ORDER_QUEUE_CAPACITY",
default_value = "64"
)]
pub order_queue_capacity: usize,
/// Build-event channel capacity.
#[arg(
long = "builder.intent-swap.event-channel-capacity",
env = "INTENT_SWAP_EVENT_CHANNEL_CAPACITY",
default_value = "4096"
)]
pub event_channel_capacity: usize,
/// Enables the LOP on-chain preflight that rejects unfillable or unauthentic orders
/// before signing and submitting a settlement.
#[arg(
id = "intent_swap_verify_onchain_taking",
long = "builder.intent-swap.verify-onchain-taking",
env = "INTENT_SWAP_VERIFY_ONCHAIN_TAKING",
default_value = "false"
)]
pub verify_onchain_taking: bool,
}

impl Default for IntentSwapArgs {
fn default() -> Self {
Self {
enabled: false,
tycho_url: "tycho-beta.propellerheads.xyz".to_string(),
tycho_api_key: None,
rpc_url: None,
resolver_address: None,
eoa_key: None,
chain: "base".to_string(),
chain_id: 8453,
protocols: vec![
"uniswap_v2".to_string(),
"uniswap_v3".to_string(),
"uniswap_v4".to_string(),
],
min_tvl: 10.0,
slippage: 0.005,
order_queue_capacity: 64,
event_channel_capacity: 4096,
verify_onchain_taking: false,
}
}
}

/// Parameters for rollup configuration
#[derive(Debug, Clone, clap::Args)]
#[command(next_help_heading = "Rollup")]
Expand Down Expand Up @@ -219,6 +345,10 @@ pub struct Args {
/// Transaction event journal configuration
#[command(flatten)]
pub transaction_events: TransactionEventsArgs,

/// Intent-swap extension configuration
#[command(flatten)]
pub intent_swap: IntentSwapArgs,
}

impl Args {
Expand Down Expand Up @@ -258,6 +388,7 @@ impl Default for Args {
sampling_ratio: 100,
flashblocks: FlashblocksArgs::default(),
transaction_events: TransactionEventsArgs::default(),
intent_swap: IntentSwapArgs::default(),
}
}
}
Expand Down Expand Up @@ -307,6 +438,7 @@ impl Args {
audit_archiver_url: self.audit_archiver_url,
rejected_tx_channel_size: self.rejected_tx_channel_size,
max_rejected_txs_per_block: self.max_rejected_txs_per_block,
build_event_tx: None,
})
}
}
Expand Down
2 changes: 1 addition & 1 deletion crates/builder/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
#![cfg_attr(not(test), warn(unused_crate_dependencies))]

mod args;
pub use args::{Args, FlashblocksArgs, TransactionEventsArgs};
pub use args::{Args, FlashblocksArgs, IntentSwapArgs, TransactionEventsArgs};
Loading