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

Rundler v0.3 Feature Branch #736

Merged
merged 17 commits into from
Jun 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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 .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
toolchain: 1.75.0
toolchain: 1.79.0
- name: Install toolchain (nightly)
run: rustup toolchain add nightly --component rustfmt --profile minimal
- uses: Swatinem/rust-cache@v2
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
toolchain: 1.75.0
toolchain: 1.79.0

- name: Install toolchain (nightly)
run: rustup toolchain add nightly --component rustfmt --profile minimal
Expand Down
22 changes: 11 additions & 11 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ default-members = ["bin/rundler"]
resolver = "2"

[workspace.package]
version = "0.2.2"
version = "0.3.0"
edition = "2021"
rust-version = "1.75"
rust-version = "1.79"
license = "MIT OR Apache-2.0"
repository = "https://github.com/alchemyplatform/rundler"

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Adapted from https://github.com/paradigmxyz/reth/blob/main/Dockerfile
# syntax=docker/dockerfile:1.4

FROM --platform=$TARGETPLATFORM rust:1.75.0 AS chef-builder
FROM --platform=$TARGETPLATFORM rust:1.79.0 AS chef-builder

# Install system dependencies
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
Expand Down
2 changes: 0 additions & 2 deletions bin/rundler/chain_specs/polygon_amoy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,3 @@ base = "polygon"

name = "Polygon Amoy"
id = 80002

min_max_priority_fee_per_gas = "0x59682F00" # 1_500_000_000
130 changes: 104 additions & 26 deletions bin/rundler/src/cli/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

use std::{net::SocketAddr, time::Duration};

use anyhow::Context;
use anyhow::{bail, Context};
use clap::Args;
use rundler_builder::{
self, BloxrouteSenderArgs, BuilderEvent, BuilderEventKind, BuilderTask, BuilderTaskArgs,
EntryPointBuilderSettings, FlashbotsSenderArgs, LocalBuilderBuilder, TransactionSenderArgs,
TransactionSenderKind,
EntryPointBuilderSettings, FlashbotsSenderArgs, LocalBuilderBuilder, RawSenderArgs,
TransactionSenderArgs, TransactionSenderKind,
};
use rundler_pool::RemotePoolClient;
use rundler_sim::{MempoolConfigs, PriorityFeeMode};
Expand Down Expand Up @@ -57,13 +57,28 @@ pub struct BuilderArgs {
host: String,

/// Private key to use for signing transactions
/// DEPRECATED: Use `builder.private_keys` instead
///
/// If both `builder.private_key` and `builder.private_keys` are set, `builder.private_key` is appended
/// to `builder.private_keys`. Keys must be unique.
#[arg(
long = "builder.private_key",
name = "builder.private_key",
env = "BUILDER_PRIVATE_KEY"
)]
private_key: Option<String>,

/// Private keys to use for signing transactions
///
/// Cannot use both `builder.private_keys` and `builder.aws_kms_key_ids` at the same time.
#[arg(
long = "builder.private_keys",
name = "builder.private_keys",
env = "BUILDER_PRIVATE_KEYS",
value_delimiter = ','
)]
private_keys: Vec<String>,

/// AWS KMS key IDs to use for signing transactions
#[arg(
long = "builder.aws_kms_key_ids",
Expand Down Expand Up @@ -115,14 +130,47 @@ pub struct BuilderArgs {
/// If present, the url of the ETH provider that will be used to send
/// transactions. Defaults to the value of `node_http`.
///
/// Only used when BUILDER_SENDER is "raw" or "conditional"
/// Only used when BUILDER_SENDER is "raw"
#[arg(
long = "builder.submit_url",
name = "builder.submit_url",
env = "BUILDER_SUBMIT_URL"
)]
pub submit_url: Option<String>,

/// If true, use the submit endpoint for transaction status checks.
///
/// Only used when BUILDER_SENDER is "raw"
#[arg(
long = "builder.use_submit_for_status",
name = "builder.use_submit_for_status",
env = "BUILDER_USE_SUBMIT_FOR_STATUS",
default_value = "false"
)]
pub use_submit_for_status: bool,

/// Use the conditional RPC endpoint for transaction submission.
///
/// Only used when BUILDER_SENDER is "raw"
#[arg(
long = "builder.use_conditional_rpc",
name = "builder.use_conditional_rpc",
env = "BUILDER_USE_CONDITIONAL_RPC",
default_value = "false"
)]
pub use_conditional_rpc: bool,

/// If the "dropped" status is unsupported by the status provider.
///
/// Only used when BUILDER_SENDER is "raw"
#[arg(
long = "builder.dropped_status_unsupported",
name = "builder.dropped_status_unsupported",
env = "BUILDER_DROPPED_STATUS_UNSUPPORTED",
default_value = "false"
)]
pub dropped_status_unsupported: bool,

/// A list of builders to pass into the Flashbots Relay RPC.
///
/// Only used when BUILDER_SENDER is "flashbots"
Expand Down Expand Up @@ -177,16 +225,25 @@ pub struct BuilderArgs {
)]
replacement_fee_percent_increase: u64,

/// Maximum number of times to increase gas fees when retrying a transaction
/// Maximum number of times to increase gas fees when retrying a cancellation transaction
/// before giving up.
#[arg(
long = "builder.max_fee_increases",
name = "builder.max_fee_increases",
env = "BUILDER_MAX_FEE_INCREASES",
// Seven increases of 10% is roughly 2x the initial fees.
default_value = "7"
long = "builder.max_cancellation_fee_increases",
name = "builder.max_cancellation_fee_increases",
env = "BUILDER_MAX_CANCELLATION_FEE_INCREASES",
default_value = "15"
)]
max_fee_increases: u64,
max_cancellation_fee_increases: u64,

/// The maximum number of blocks to wait in a replacement underpriced state before issuing
/// a cancellation transaction.
#[arg(
long = "builder.max_replacement_underpriced_blocks",
name = "builder.max_replacement_underpriced_blocks",
env = "BUILDER_MAX_REPLACEMENT_UNDERPRICED_BLOCKS",
default_value = "20"
)]
max_replacement_underpriced_blocks: u64,

/// The index offset to apply to the builder index
#[arg(
Expand Down Expand Up @@ -216,7 +273,6 @@ impl BuilderArgs {
.node_http
.clone()
.context("should have a node HTTP URL")?;
let submit_url = self.submit_url.clone().unwrap_or_else(|| rpc_url.clone());

let mempool_configs = match &common.mempool_config_path {
Some(path) => get_json_config::<MempoolConfigs>(path, &common.aws_region)
Expand Down Expand Up @@ -251,27 +307,41 @@ impl BuilderArgs {
num_builders += common.num_builders_v0_7;
}

if self.private_key.is_some() {
if num_builders > 1 {
return Err(anyhow::anyhow!(
"Cannot use a private key with multiple builders. You may need to disable one of the entry points."
));
if (self.private_key.is_some() || !self.private_keys.is_empty())
&& !self.aws_kms_key_ids.is_empty()
{
bail!(
"Cannot use both builder.private_key(s) and builder.aws_kms_key_ids at the same time."
);
}

let mut private_keys = self.private_keys.clone();
if self.private_key.is_some() || !self.private_keys.is_empty() {
if let Some(pk) = &self.private_key {
private_keys.push(pk.clone());
}

if num_builders > private_keys.len() as u64 {
bail!(
"Found {} private keys, but need {} keys for the number of builders. You may need to disable one of the entry points.",
private_keys.len(), num_builders
);
}
} else if self.aws_kms_key_ids.len() < num_builders as usize {
return Err(anyhow::anyhow!(
bail!(
"Not enough AWS KMS key IDs for the number of builders. Need {} keys, found {}. You may need to disable one of the entry points.",
num_builders, self.aws_kms_key_ids.len()
));
);
}

let sender_args = self.sender_args(&chain_spec)?;
let sender_args = self.sender_args(&chain_spec, &rpc_url)?;

Ok(BuilderTaskArgs {
entry_points,
chain_spec,
unsafe_mode: common.unsafe_mode,
rpc_url,
private_key: self.private_key.clone(),
private_keys,
aws_kms_key_ids: self.aws_kms_key_ids.clone(),
aws_kms_region: common
.aws_region
Expand All @@ -281,23 +351,31 @@ impl BuilderArgs {
redis_lock_ttl_millis: self.redis_lock_ttl_millis,
max_bundle_size: self.max_bundle_size,
max_bundle_gas: common.max_bundle_gas,
submit_url,
bundle_priority_fee_overhead_percent: common.bundle_priority_fee_overhead_percent,
priority_fee_mode,
sender_args,
eth_poll_interval: Duration::from_millis(common.eth_poll_interval_millis),
sim_settings: common.try_into()?,
max_blocks_to_wait_for_mine: self.max_blocks_to_wait_for_mine,
replacement_fee_percent_increase: self.replacement_fee_percent_increase,
max_fee_increases: self.max_fee_increases,
max_cancellation_fee_increases: self.max_cancellation_fee_increases,
max_replacement_underpriced_blocks: self.max_replacement_underpriced_blocks,
remote_address,
})
}

fn sender_args(&self, chain_spec: &ChainSpec) -> anyhow::Result<TransactionSenderArgs> {
fn sender_args(
&self,
chain_spec: &ChainSpec,
rpc_url: &str,
) -> anyhow::Result<TransactionSenderArgs> {
match self.sender_type {
TransactionSenderKind::Raw => Ok(TransactionSenderArgs::Raw),
TransactionSenderKind::Conditional => Ok(TransactionSenderArgs::Conditional),
TransactionSenderKind::Raw => Ok(TransactionSenderArgs::Raw(RawSenderArgs {
submit_url: self.submit_url.clone().unwrap_or_else(|| rpc_url.into()),
use_submit_for_status: self.use_submit_for_status,
dropped_status_supported: !self.dropped_status_unsupported,
use_conditional_rpc: self.use_conditional_rpc,
})),
TransactionSenderKind::Flashbots => {
if !chain_spec.flashbots_enabled {
return Err(anyhow::anyhow!("Flashbots sender is not enabled for chain"));
Expand Down
1 change: 1 addition & 0 deletions bin/rundler/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ impl TryFrom<&CommonArgs> for EstimationSettings {
max_call_gas,
max_paymaster_verification_gas: value.max_verification_gas,
max_paymaster_post_op_gas: max_call_gas,
max_total_execution_gas: value.max_bundle_gas,
max_simulate_handle_ops_gas: value.max_simulate_handle_ops_gas,
verification_estimation_gas_fee: value.verification_estimation_gas_fee,
})
Expand Down
7 changes: 0 additions & 7 deletions bin/rundler/src/cli/node/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

use std::fmt::Display;

use ethers::types::Address;
use rundler_builder::BuilderEvent;
use rundler_pool::PoolEvent;

Expand All @@ -23,12 +22,6 @@ pub enum Event {
BuilderEvent(BuilderEvent),
}

#[derive(Clone, Debug)]
pub struct WithEntryPoint<T> {
pub entry_point: Address,
pub event: T,
}

impl From<PoolEvent> for Event {
fn from(event: PoolEvent) -> Self {
Self::PoolEvent(event)
Expand Down
Loading
Loading