Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cowprotocol/services
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: tokenwood/services
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: main
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 1 commit
  • 19 files changed
  • 1 contributor

Commits on Jul 10, 2024

  1. added /gas endpoint

    tokenwood committed Jul 10, 2024
    Copy the full SHA
    2b4f36c View commit details
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
.DS_Store

driver_pid.log
nohup.out
/target
/.vscode
/.idea
44 changes: 44 additions & 0 deletions crates/driver/driver_config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[[solver]]
name = "FractalSolver" # Arbitrary name given to this solver, must be unique
endpoint = "http://0.0.0.0:6000" #
absolute-slippage = "40000000000000000" # Denominated in wei, optional
relative-slippage = "0.1" # Percentage in the [0, 1] range
account = "0xDF4296e752FD08b2d7Db4101B98a48b74E59FD56" # public key of an actual solver

[submission]
gas-price-cap = "1000000000000" # 1000 Gwei

[[submission.mempool]]
mempool = "public"
revert-protection = true

[contracts] # Optionally override the contract addresses, necessary on less popular blockchains
gp-v2-settlement = "0x9008D19f58AAbD9eD0D60971565AA8510560ab41"
weth = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"

[liquidity]
base-tokens = [
"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
"0x6B175474E89094C44Da98b954EedeAC495271d0F",
"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"0xdAC17F958D2ee523a2206206994597C13D831ec7",
"0xc00e94Cb662C3520282E6f5717214004A7f26888",
"0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2",
"0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
"0x6810e776880C02933D47DB1b9fc05908e5386b96",
]
graph-api-base-url = "https://api.thegraph.com/subgraphs/name/"

[[liquidity.uniswap-v2]] # Uniswap V2 configuration
preset = "uniswap-v2" # or "sushi-swap", "honeyswap", "baoswap", "pancake-swap", etc.

[[liquidity.uniswap-v2]] # Uniswap V2 configuration
preset = "pancake-swap"

[[liquidity.balancer-v2]] # Balancer V2 configuration
preset = "balancer-v2"
pool-deny-list = [] # optional

[[liquidity.uniswap-v3]] # Uniswap V3 configuration
preset = "uniswap-v3"
# max_pools_to_initialize = 100 # doesn't work, hardcode default_max_pools_to_initialize instead
19 changes: 19 additions & 0 deletions crates/driver/driver_config_prod.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[[solver]]
name = "FractalSolver" # Arbitrary name given to this solver, must be unique
endpoint = "http://0.0.0.0:6000" #
absolute-slippage = "40000000000000000" # Denominated in wei, optional
relative-slippage = "0.1" # Percentage in the [0, 1] range
account = "0x755BaE1cd46C9C27A3230AeF0CE923BDa13d29F7" # public key of an actual solver

[submission]
gas-price-cap = "1000000000000" # 1000 Gwei

[[submission.mempool]]
mempool = "public"
revert-protection = true

[contracts] # Optionally override the contract addresses, necessary on less popular blockchains
gp-v2-settlement = "0x9008D19f58AAbD9eD0D60971565AA8510560ab41"
weth = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"

[liquidity]
2 changes: 1 addition & 1 deletion crates/driver/src/domain/competition/auction.rs
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ use {
/// An auction is a set of orders that can be solved. The solvers calculate
/// [`super::solution::Solution`]s by picking subsets of these orders and
/// solving them.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Auction {
/// See the [`Self::id`] method.
id: Option<Id>,
66 changes: 63 additions & 3 deletions crates/driver/src/domain/competition/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use {
self::solution::settlement,
super::{time, time::Remaining, Mempools},
super::{
time::{self, Remaining},
Mempools,
},
crate::{
domain::{competition::solution::Settlement, eth},
infra::{
self,
blockchain::Ethereum,
notify,
observe,
notify, observe,
solver::{self, Solver},
Simulator,
},
@@ -18,6 +20,7 @@ use {
std::{
collections::{HashMap, HashSet},
sync::Mutex,
time::Duration,
},
tap::TapFallible,
};
@@ -53,6 +56,52 @@ pub struct Competition {
}

impl Competition {
pub async fn estimate_gas(
&self,
auction: &Auction,
solutions: Vec<Solution>,
) -> Result<Vec<(u64, (eth::U256, bool, String))>, Error> {
// encode into settlements streamed
let encoded = solutions
.into_iter()
.map(|solution| async move {
let id = solution.id();
observe::encoding(id);
let settlement = solution.encode(auction, &self.eth, &self.simulator).await;
(id, settlement)
})
.collect::<FuturesUnordered<_>>();

// collect settlements
let mut settlements = Vec::new();
if tokio::time::timeout(
Duration::from_secs(3),
collect_settlements(&mut settlements, encoded),
)
.await
.is_err()
{
tracing::warn!("gas request - postprocessing timed out");
};

// extract gas estimates
let gas_estimates = settlements
.into_iter()
.map(|(id, result)| match result {
Ok(settlement) => (
settlement.solutions().iter().next().unwrap().0,
(settlement.gas.estimate.0, true, "".to_string()),
),
Err(err) => {
observe::encoding_failed(self.solver.name(), id, &err);
(id.0, (eth::U256::zero(), false, err.to_string()))
}
})
.collect_vec();

Ok(gas_estimates)
}

/// Solve an auction as part of this competition.
pub async fn solve(&self, auction: &Auction) -> Result<Option<Solved>, Error> {
let liquidity = match self.solver.liquidity() {
@@ -351,6 +400,17 @@ async fn merge_settlements(
}
}

async fn collect_settlements(
merged: &mut Vec<(solution::Id, Result<Settlement, solution::Error>)>,
new: impl Stream<Item = (solution::Id, Result<Settlement, solution::Error>)>,
) {
let mut new = std::pin::pin!(new);
while let Some(settlement) = new.next().await {
// settlement.solutions().
merged.push(settlement);
}
}

/// Solution information sent to the protocol by the driver before the solution
/// ranking happens.
#[derive(Debug)]
11 changes: 11 additions & 0 deletions crates/driver/src/infra/api/error.rs
Original file line number Diff line number Diff line change
@@ -103,6 +103,17 @@ impl From<api::routes::AuctionError> for (hyper::StatusCode, axum::Json<Error>)
}
}

impl From<api::routes::GasError> for (hyper::StatusCode, axum::Json<Error>) {
fn from(value: api::routes::GasError) -> Self {
let error = match value {
api::routes::GasError::LiquidityError => Kind::Unknown,
api::routes::GasError::EncodeSolutionError => Kind::Unknown,
api::routes::GasError::EncodeAuctionError => Kind::Unknown,
};
error.into()
}
}

impl From<api::routes::OrderError> for (hyper::StatusCode, axum::Json<Error>) {
fn from(value: api::routes::OrderError) -> Self {
let error = match value {
8 changes: 3 additions & 5 deletions crates/driver/src/infra/api/mod.rs
Original file line number Diff line number Diff line change
@@ -2,12 +2,9 @@ use {
crate::{
domain::{self, Mempools},
infra::{
self,
liquidity,
self, liquidity,
solver::{Solver, Timeouts},
tokens,
Ethereum,
Simulator,
tokens, Ethereum, Simulator,
},
},
error::Error,
@@ -63,6 +60,7 @@ impl Api {
let router = axum::Router::new();
let router = routes::info(router);
let router = routes::quote(router);
let router = routes::gas(router);
let router = routes::solve(router);
let router = routes::reveal(router);
let router = routes::settle(router);
Loading