Skip to content

Commit

Permalink
Docs
Browse files Browse the repository at this point in the history
  • Loading branch information
squadgazzz committed Jan 17, 2025
1 parent e67293d commit 4743607
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
14 changes: 9 additions & 5 deletions crates/driver/src/domain/competition/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ impl Auction {
#[derive(Clone)]
pub struct AuctionProcessor {
inner: Arc<Mutex<Inner>>,
app_data_fetcher: Arc<order::app_data::AppDataFetcher>,
app_data_retriever: Arc<order::app_data::AppDataRetriever>,
}

struct Inner {
Expand All @@ -147,6 +147,9 @@ type BalanceGroup = (order::Trader, eth::TokenAddress, order::SellTokenBalance);
type Balances = HashMap<BalanceGroup, order::SellAmount>;

impl AuctionProcessor {
/// Process the auction by prioritizing the orders and filtering out
/// unfillable orders. Fetches full app data for each order and returns an
/// auction with updated orders.
pub async fn process(&self, auction: Auction, solver: &eth::H160) -> Result<Auction, Error> {
let (app_data_by_order, mut prioritized_orders) = try_join(
self.collect_orders_app_data(&auction),
Expand All @@ -166,13 +169,14 @@ impl AuctionProcessor {
})
}

/// Fetches the app data for all orders in the auction.
async fn collect_orders_app_data(
&self,
auction: &Auction,
) -> Result<HashMap<order::Uid, Option<ValidatedAppData>>, Error> {
Ok(try_join_all(auction.orders.iter().map(|order| async {
self.app_data_fetcher
.fetch(order.app_data.hash())
self.app_data_retriever
.get(order.app_data.hash())
.await
.map(|app_data| (order.uid, app_data))
.map_err(|err| Error::AppDataFetching(order.uid, err))
Expand Down Expand Up @@ -481,7 +485,7 @@ impl AuctionProcessor {
pub fn new(
eth: &infra::Ethereum,
order_priority_strategies: Vec<OrderPriorityStrategy>,
app_data_fetcher: Arc<order::app_data::AppDataFetcher>,
app_data_retriever: Arc<order::app_data::AppDataRetriever>,
) -> Self {
let eth = eth.with_metric_label("auctionPreProcessing".into());
let mut order_sorting_strategies = vec![];
Expand Down Expand Up @@ -519,7 +523,7 @@ impl AuctionProcessor {
order_sorting_strategies,
signature_validator,
})),
app_data_fetcher,
app_data_retriever,
}
}
}
Expand Down
29 changes: 23 additions & 6 deletions crates/driver/src/domain/competition/order/app_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,20 @@ use {
url::Url,
};

/// A struct for retrieving order's full app-data by its hash from a remote
/// service, with support for caching and deduplicating concurrent requests.
///
/// Ensures efficient access to application data by:
/// - Caching results to avoid redundant network requests.
/// - Sharing ongoing requests to prevent duplicate fetches for the same
/// `app_data`.
/// - Validating fetched app data.
///
/// LRU cache is used since only ~2% of app-data is unique across all orders
/// meaning that the cache hit rate is expected to be high, so there is no need
/// for TTL cache.
#[derive(Clone)]
pub struct AppDataFetcher(Arc<Inner>);
pub struct AppDataRetriever(Arc<Inner>);

struct Inner {
client: reqwest::Client,
Expand All @@ -22,18 +34,23 @@ struct Inner {
cache: Cache<super::AppDataHash, Option<app_data::ValidatedAppData>>,
}

impl AppDataFetcher {
impl AppDataRetriever {
// According to statistics, the average size of the app-data is ~800 bytes. With
// this constant, the approximate size of the cache will be ~1.6 MB.
const CACHE_SIZE: u64 = 2_000;

pub fn new(orderbook_url: Url) -> Self {
Self(Arc::new(Inner {
client: reqwest::Client::new(),
base_url: orderbook_url,
request_sharing: BoxRequestSharing::labelled("app_data".to_string()),
app_data_validator: app_data::Validator::new(usize::MAX),
cache: Cache::new(2_000),
cache: Cache::new(Self::CACHE_SIZE),
}))
}

pub async fn fetch(
/// Retrieves the full app-data for the given `app_data` hash, if exists.
pub async fn get(
&self,
app_data: super::AppDataHash,
) -> Result<Option<app_data::ValidatedAppData>, FetchingError> {
Expand Down Expand Up @@ -80,7 +97,7 @@ impl AppDataFetcher {

#[derive(Error, Debug)]
pub enum FetchingError {
#[error("unable to send a request: {0}")]
#[error("error while sending a request: {0}")]
Http(String),
#[error("received invalid app data: {0}")]
InvalidAppData(#[from] anyhow::Error),
Expand All @@ -96,7 +113,7 @@ impl From<reqwest::Error> for FetchingError {

impl From<url::ParseError> for FetchingError {
fn from(err: url::ParseError) -> Self {
FetchingError::Http(err.to_string())
FetchingError::Internal(err.to_string())
}
}

Expand Down
6 changes: 3 additions & 3 deletions crates/driver/src/infra/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use {
crate::{
domain::{
self,
competition::{bad_tokens, order::app_data::AppDataFetcher},
competition::{bad_tokens, order::app_data::AppDataRetriever},
Mempools,
},
infra::{
Expand Down Expand Up @@ -57,11 +57,11 @@ impl Api {
);

let tokens = tokens::Fetcher::new(&self.eth);
let app_data_fetcher = AppDataFetcher::new(orderbook_url);
let app_data_retriever = AppDataRetriever::new(orderbook_url);
let pre_processor = domain::competition::AuctionProcessor::new(
&self.eth,
order_priority_strategies,
Arc::new(app_data_fetcher),
Arc::new(app_data_retriever),
);

// Add the metrics and healthz endpoints.
Expand Down

0 comments on commit 4743607

Please sign in to comment.