Skip to content
Merged
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 crates/driver/src/domain/competition/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl Auction {
id,
orders,
tokens,
gas_price: eth.gas_price(None).await?,
gas_price: eth.gas_price().await?,
deadline,
surplus_capturing_jit_order_owners,
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ impl Settlement {
simulator,
)
.await?;
let price = eth.gas_price(None).await?;
let price = eth.gas_price().await?;
let gas = Gas::new(gas, eth.block_gas_limit())?;

// Ensure that the solver has sufficient balance for the settlement to be mined
Expand Down
8 changes: 3 additions & 5 deletions crates/driver/src/domain/mempools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,11 @@ impl Mempools {
// deadline
let current_gas_price = self
.ethereum
.gas_price(None)
.gas_price()
.await
.context("failed to compute current gas price")?;
let submission_block = self.ethereum.current_block().borrow().number;
let blocks_until_deadline = submission_deadline.saturating_sub(submission_block);
let estimated_gas_price =
current_gas_price * GAS_PRICE_BUMP.powi(blocks_until_deadline as i32);

// if there is still a tx pending we also have to make sure we outbid that one
// enough to make the node replace it in the mempool
Expand All @@ -148,11 +146,11 @@ impl Mempools {
.await;
let final_gas_price = match &replacement_gas_price {
Ok(Some(replacement_gas_price))
if replacement_gas_price.max() > estimated_gas_price.max() =>
if replacement_gas_price.max() > current_gas_price.max() =>
{
*replacement_gas_price
}
_ => estimated_gas_price,
_ => current_gas_price,
};

tracing::debug!(
Expand Down
2 changes: 1 addition & 1 deletion crates/driver/src/infra/api/routes/gasprice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async fn route(
eth: axum::extract::State<Ethereum>,
) -> Result<Json<GasPriceResponse>, (hyper::StatusCode, axum::Json<Error>)> {
// For simplicity we use the default time limit (None)
let gas_price = eth.gas_price(None).await?;
let gas_price = eth.gas_price().await?;

Ok(Json(GasPriceResponse {
max_fee_per_gas: gas_price.max().0.0,
Expand Down
12 changes: 3 additions & 9 deletions crates/driver/src/infra/blockchain/gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ use {
},
ethrpc::Web3,
gas_estimation::{
DEFAULT_GAS_LIMIT,
DEFAULT_TIME_LIMIT,
GasPriceEstimating,
nativegasestimator::{NativeGasEstimator, Params},
},
shared::gas_price_estimation::alloy::AlloyGasPriceEstimator,
std::{sync::Arc, time::Duration},
std::sync::Arc,
};

type MaxAdditionalTip = eth::U256;
Expand Down Expand Up @@ -94,12 +92,8 @@ impl GasPriceEstimator {
/// If additional tip is configured, it will be added to the gas price. This
/// is to increase the chance of a transaction being included in a block, in
/// case private submission networks are used.
pub async fn estimate(&self, time_limit: Option<Duration>) -> Result<eth::GasPrice, Error> {
let estimate = self
.gas
.estimate_with_limits(DEFAULT_GAS_LIMIT, time_limit.unwrap_or(DEFAULT_TIME_LIMIT))
.await
.map_err(Error::GasPrice)?;
pub async fn estimate(&self) -> Result<eth::GasPrice, Error> {
let estimate = self.gas.estimate().await.map_err(Error::GasPrice)?;

let max_priority_fee_per_gas = {
// the driver supports tweaking the tx gas price tip in case the gas
Expand Down
8 changes: 4 additions & 4 deletions crates/driver/src/infra/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use {
BalanceOverriding,
},
},
std::{fmt, sync::Arc, time::Duration},
std::{fmt, sync::Arc},
thiserror::Error,
tracing::{Level, instrument},
url::Url,
Expand Down Expand Up @@ -237,8 +237,8 @@ impl Ethereum {
/// The gas price is determined based on the deadline by which the
/// transaction must be included on-chain. A shorter deadline requires a
/// higher gas price to increase the likelihood of timely inclusion.
pub async fn gas_price(&self, time_limit: Option<Duration>) -> Result<eth::GasPrice, Error> {
self.inner.gas.estimate(time_limit).await
pub async fn gas_price(&self) -> Result<eth::GasPrice, Error> {
self.inner.gas.estimate().await
}

pub fn block_gas_limit(&self) -> eth::Gas {
Expand Down Expand Up @@ -306,7 +306,7 @@ impl Ethereum {
// the node specific fallback value instead of failing the whole call.
self.inner
.gas
.estimate(None)
.estimate()
.await
.ok()
.map(|gas| gas.effective().0.0)
Expand Down
2 changes: 1 addition & 1 deletion crates/driver/src/tests/setup/solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl Solver {
move |axum::extract::State(state): axum::extract::State<State>,
axum::extract::Json(req): axum::extract::Json<serde_json::Value>| async move {
let effective_gas_price = eth
.gas_price(None)
.gas_price()
.await
.unwrap()
.effective()
Expand Down
47 changes: 12 additions & 35 deletions crates/shared/src/gas_price_estimation/alloy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
//! for the implementation details.

use {
alloy::{consensus::BlockHeader, providers::Provider},
alloy::providers::Provider,
anyhow::{Context, Result},
ethrpc::AlloyProvider,
futures::TryFutureExt,
gas_estimation::{GasPrice1559, GasPriceEstimating},
std::{ops::Mul, time::Duration},
std::time::Duration,
tracing::instrument,
};

Expand All @@ -31,37 +31,21 @@ impl GasPriceEstimating for AlloyGasPriceEstimator {
_gas_limit: f64,
_time_limit: Duration,
) -> Result<GasPrice1559> {
let estimate_fees = self
let fees = self
.0
.estimate_eip1559_fees()
.map_err(|err| anyhow::anyhow!("could not estimate EIP 1559 fees: {err:?}"));
let get_block = self
.0
.get_block(alloy::eips::BlockId::Number(
alloy::eips::BlockNumberOrTag::Latest,
))
.into_future()
.map_err(|err| anyhow::anyhow!("could not fetch latest block: {err:?}"));
let (fees, block) = tokio::try_join!(estimate_fees, get_block)?;

/// `Alloy`'s constant growth factor to estimate the base_fee
/// of the next block. (<https://github.com/alloy-rs/alloy/blob/ad56bf0b974974179ee39daf694e400dba0f8ff7/crates/provider/src/utils.rs#L19>)
const MAX_GAS_PRICE_INCREASE_PER_BLOCK: f64 = 2.;
.map_err(|err| anyhow::anyhow!("could not estimate EIP 1559 fees: {err:?}"))
.await?;

let base_fee_per_gas = u64_to_f64(
block
.context("latest block is missing")?
.into_consensus_header()
.base_fee_per_gas()
.context("no base_fee_per_gas")?,
)
.context("could not convert base_fee_per_gas to f64")?
.mul(MAX_GAS_PRICE_INCREASE_PER_BLOCK);
let max_fee_per_gas = u128_to_f64(fees.max_fee_per_gas)
.context("could not convert max_fee_per_gas to f64")?;

Ok(GasPrice1559 {
base_fee_per_gas,
max_fee_per_gas: u128_to_f64(fees.max_fee_per_gas)
.context("could not convert max_fee_per_gas to f64")?,
// We reuse `max_fee_per_gas` since the base fee only actually
// exists in a mined block. For price estimates used to configure
// the gas price of a transaction the base fee doesn't matter.
base_fee_per_gas: max_fee_per_gas,
max_fee_per_gas,
max_priority_fee_per_gas: u128_to_f64(fees.max_priority_fee_per_gas)
.context("could not convert max_priority_fee_per_gas to f64")?,
})
Expand All @@ -74,10 +58,3 @@ fn u128_to_f64(val: u128) -> Result<f64> {
}
Ok(val as f64)
}

fn u64_to_f64(val: u64) -> Result<f64> {
if val > 2u64.pow(f64::MANTISSA_DIGITS) {
anyhow::bail!(format!("could not convert u64 to f64: {val}"));
}
Ok(val as f64)
}
Loading