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
15 changes: 10 additions & 5 deletions crates/driver/example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,16 @@ gas-price-cap = "1000000000000"
max-additional-tip = "5000000000"
additional-tip-percentage = 0.05

[[submission.mempool]]
url = "https://your.custom.rpc.endpoint"
# optional args
name = "custom_name"
mines-reverting-txs = true
# Where to send the settlement to. Set exactly one of
# `[submission.public-mempool]` or `[submission.private-relay]`.
[submission.public-mempool]
urls = ["https://your.custom.rpc.endpoint", "https://your.backup.rpc.endpoint"]

# A private relay, e.g. MEV Blocker:
# [submission.private-relay]
# url = "https://rpc.mevblocker.io"
# # optional args
# mines-reverting-txs = false

[contracts] # Optionally override the contract addresses, necessary on less popular blockchains
gp-v2-settlement = "0x9008D19f58AAbD9eD0D60971565AA8510560ab41"
Expand Down
13 changes: 0 additions & 13 deletions crates/driver/src/domain/competition/solution/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -696,19 +696,6 @@ impl Solution {
let token = token.as_erc20(self.weth);
self.prices.get(&token).map(ToOwned::to_owned)
}

/// Whether there is a reasonable risk of this solution reverting on chain.
pub fn revertable(&self) -> bool {
self.interactions
.iter()
.any(|interaction| !interaction.internalize())
|| self.user_trades().any(|trade| {
matches!(
trade.order().signature.scheme,
order::signature::Scheme::Eip1271
)
})
}
}

/// Given two solutions returns the factors with
Expand Down
4 changes: 0 additions & 4 deletions crates/driver/src/domain/competition/solution/settlement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ impl Settlement {
internalized: encode_one(Internalization::Enable)?,
uninternalized: encode_one(Internalization::Disable)?,
gas: self.gas,
may_revert: self.solution.revertable(),
gas_fee_override: self.solution.gas_fee_override(),
})
}
Expand Down Expand Up @@ -349,9 +348,6 @@ pub struct EncodedSettlement {
/// Gas parameters (limit used for mempool submission, estimate for
/// observability).
pub gas: Gas,
/// Effectively indicates whether the settlement interacts with
/// AMMs which can revert when arbitrage bots snipe good liquidity.
pub may_revert: bool,
/// Solver-provided override for the gas fee at submission time.
pub gas_fee_override: Option<super::GasFeeOverride>,
}
Expand Down
60 changes: 5 additions & 55 deletions crates/driver/src/domain/mempools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use {
futures::{FutureExt, StreamExt, future::select_ok},
itertools::Itertools,
num::Saturating,
thiserror::Error,
tracing::Instrument,
};

Expand Down Expand Up @@ -51,15 +50,11 @@ pub struct Mempools {
}

impl Mempools {
pub fn try_new(mempools: Vec<infra::Mempool>, ethereum: Ethereum) -> Result<Self, NoMempools> {
if mempools.is_empty() {
Err(NoMempools)
} else {
Ok(Self { mempools, ethereum })
}
pub fn new(mempools: Vec<infra::Mempool>, ethereum: Ethereum) -> Self {
Self { mempools, ethereum }
}

/// Race the enabled mempools concurrently; first success wins. Pending
/// Race the mempools concurrently; first success wins. Pending
/// submission futures are dropped at that point and every other mempool is
/// recorded as `Superseded`. If every mempool fails, return one of the
/// failure errors.
Expand Down Expand Up @@ -102,41 +97,13 @@ impl Mempools {
Ok(res?.tx_hash)
}

/// A mempool is disabled if all of the following are true:
/// * the settlement may revert (see [`EncodedSettlement::may_revert`])
/// * the pool has revert protection enabled (see
/// [`Self::revert_protection`])
/// * reverts can get mined (see [`infra::Mempool::reverts_can_get_mined`])
fn is_disabled(&self, mempool: &infra::Mempool, settlement: &EncodedSettlement) -> bool {
settlement.may_revert
&& matches!(self.revert_protection(), RevertProtection::Enabled)
&& mempool.reverts_can_get_mined()
}

/// Defines if the mempools are configured in a way that guarantees that
/// settled solution will not revert.
pub fn revert_protection(&self) -> RevertProtection {
match self
.mempools
.iter()
.all(|mempool| mempool.reverts_can_get_mined())
{
true => RevertProtection::Disabled,
false => RevertProtection::Enabled,
}
}

async fn submit(
&self,
mempool: &infra::mempool::Mempool,
settlement: &EncodedSettlement,
submission_deadline: BlockNo,
mode: &SubmissionMode,
) -> Result<SubmissionSuccess, Error> {
if self.is_disabled(mempool, settlement) {
return Err(Error::Disabled);
}

let tx = prepare_submission(&settlement.internalized, mode);
let signer = tx.from;

Expand Down Expand Up @@ -476,7 +443,6 @@ enum Outcome {
reason: &'static str,
blocks_passed: Option<u64>,
},
Disabled,
}

impl Outcome {
Expand All @@ -485,13 +451,12 @@ impl Outcome {
Outcome::Superseded => "Superseded",
Outcome::Success { .. } => "Success",
Outcome::Failed { reason, .. } => reason,
Outcome::Disabled => "Disabled",
}
}

fn blocks_passed(self) -> Option<u64> {
match self {
Outcome::Superseded | Outcome::Disabled => None,
Outcome::Superseded => None,
Outcome::Success { blocks_passed } => Some(blocks_passed),
Outcome::Failed { blocks_passed, .. } => blocks_passed,
}
Expand All @@ -504,7 +469,6 @@ impl From<&Result<SubmissionSuccess, Error>> for Outcome {
Ok(s) => Outcome::Success {
blocks_passed: s.blocks_passed(),
},
Err(Error::Disabled) => Outcome::Disabled,
Err(err @ (Error::Revert { .. } | Error::SimulationRevert { .. })) => Outcome::Failed {
reason: "Revert",
blocks_passed: err.blocks_passed(),
Expand Down Expand Up @@ -600,18 +564,6 @@ impl SubmissionSuccess {
}
}

#[derive(Debug, Error)]
#[error("no mempools configured, cannot execute settlements")]
pub struct NoMempools;

/// Defines if the mempools are configured in a way that guarantees that
/// /settle'd solution will not revert.
#[derive(Debug, Clone, Copy)]
pub enum RevertProtection {
Enabled,
Disabled,
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(
Expand Down Expand Up @@ -640,8 +592,6 @@ pub enum Error {
submitted_at_block: BlockNo,
submission_deadline: BlockNo,
},
#[error("Strategy disabled for this tx")]
Disabled,
#[error("Failed to submit: {0:?}")]
Other(#[from] anyhow::Error),
}
Expand All @@ -665,7 +615,7 @@ impl Error {
submission_deadline,
..
} => (*submitted_at_block, *submission_deadline),
Self::Disabled | Self::Other(_) => return None,
Self::Other(_) => return None,
};
Some(end.saturating_sub(start).0)
}
Expand Down
2 changes: 1 addition & 1 deletion crates/driver/src/domain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ pub use {
flashloan::Flashloan,
interaction::Interaction,
liquidity::Liquidity,
mempools::{Mempools, RevertProtection},
mempools::Mempools,
};
22 changes: 1 addition & 21 deletions crates/driver/src/infra/config/file/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use {
blockchain,
config::file,
liquidity,
mempool,
notify,
solver::{self, Account, BadOrderDetection, SolutionMerging},
},
Expand Down Expand Up @@ -344,26 +343,7 @@ pub async fn load(chain: Chain, path: &Path) -> infra::Config {
max_fee_per_gas: config.submission.gas_price_cap,
min_priority_fee: config.submission.min_priority_fee,
},
mempools: config
.submission
.mempools
.iter()
.enumerate()
.map(|(index, mempool)| mempool::Config {
target_confirm_time: config.submission.target_confirm_time,
retry_interval: config.submission.retry_interval,
nonce_block_number: config.submission.nonce_block_number.map(Into::into),
name: mempool
.name
.clone()
.unwrap_or_else(|| format!("mempool_{index}")),
url: mempool.url.clone(),
revert_protection: match mempool.mines_reverting_txs {
true => mempool::RevertProtection::Disabled,
false => mempool::RevertProtection::Enabled,
},
})
.collect(),
mempools: config.submission.to_domain(),
simulator: config.simulator,
contracts: blockchain::contracts::Addresses {
settlement: config.contracts.gp_v2_settlement.map(Into::into),
Expand Down
Loading
Loading