Skip to content

Commit

Permalink
Fetch Auction from database (#2734)
Browse files Browse the repository at this point in the history
# Description
Given an `auction_id`, fetches `settlement::Auction` from database.
`settlement::Auction` contains very similar data as `domain::Auction`.

# Changes
<!-- List of detailed changes (how the change is accomplished) -->

- [ ] Implemented `infra::persistence::get_auction` to get
`settlement::Auction`.
- [ ] fetched object becomes a part of a `domain::Settlement`

## How to test
Added test log to `OnSettlementEventUpdater` that reports differences in
the promised score vs delivered score. This should be enough to observe
different settlements in prod. Locally, I've observed the output of
different e2e tests and it looks good.

Non-failure of any e2e tests should give a sanity check.
  • Loading branch information
sunce86 authored Jul 24, 2024
1 parent c2a83ab commit 0ed1c76
Show file tree
Hide file tree
Showing 11 changed files with 293 additions and 30 deletions.
10 changes: 8 additions & 2 deletions crates/autopilot/src/database/auction.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use {
super::Postgres,
crate::{boundary, infra::persistence::dto},
crate::{boundary, domain, infra::persistence::dto},
anyhow::{Context, Result},
chrono::{DateTime, Utc},
futures::{StreamExt, TryStreamExt},
Expand Down Expand Up @@ -83,7 +83,13 @@ impl Postgres {
let latest_settlement_block =
database::orders::latest_settlement_block(&mut ex).await? as u64;
let quotes = self
.read_quotes(orders.iter().map(|order| &order.metadata.uid))
.read_quotes(
orders
.iter()
.map(|order| domain::OrderUid(order.metadata.uid.0))
.collect::<Vec<_>>()
.iter(),
)
.await?;
Ok(boundary::SolvableOrders {
orders,
Expand Down
3 changes: 1 addition & 2 deletions crates/autopilot/src/database/quotes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use {
},
anyhow::{Context, Result},
database::byte_array::ByteArray,
model::order::OrderUid,
shared::maintenance::Maintaining,
sqlx::types::chrono::{DateTime, Utc},
std::collections::HashMap,
Expand All @@ -29,7 +28,7 @@ impl Postgres {
/// Doesn't guarantee that all orders have quotes.
pub async fn read_quotes(
&self,
orders: impl Iterator<Item = &OrderUid>,
orders: impl Iterator<Item = &domain::OrderUid>,
) -> Result<HashMap<domain::OrderUid, domain::Quote>> {
let mut ex = self.pool.acquire().await?;
let order_uids: Vec<_> = orders.map(|uid| ByteArray(uid.0)).collect();
Expand Down
4 changes: 3 additions & 1 deletion crates/autopilot/src/domain/competition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use {

type SolutionId = u64;

#[derive(Debug)]
pub struct Solution {
id: SolutionId,
solver: eth::Address,
Expand Down Expand Up @@ -57,14 +58,15 @@ impl Solution {
}
}

#[derive(Debug)]
pub struct TradedAmounts {
/// The effective amount that left the user's wallet including all fees.
pub sell: eth::TokenAmount,
/// The effective amount the user received after all fees.
pub buy: eth::TokenAmount,
}

#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Score(eth::Ether);

impl Score {
Expand Down
2 changes: 1 addition & 1 deletion crates/autopilot/src/domain/eth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub use primitive_types::{H160, H256, U256};
pub struct Address(pub H160);

/// Block number.
#[derive(Debug, Copy, Clone, From)]
#[derive(Debug, Copy, Clone, From, PartialEq, PartialOrd)]
pub struct BlockNo(pub u64);

/// A transaction ID, AKA transaction hash.
Expand Down
22 changes: 22 additions & 0 deletions crates/autopilot/src/domain/settlement/auction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//! Auction data related to the specific settlement.
use {
crate::domain::{self},
std::collections::HashMap,
};

#[derive(Debug)]
pub struct Auction {
pub id: domain::auction::Id,
/// All orders from a competition auction. Some of them may contain fee
/// policies.
pub orders: HashMap<domain::OrderUid, Vec<domain::fee::Policy>>,
/// Auction external prices
pub prices: domain::auction::Prices,
/// Deadline for an auction solution to be settled, so that it is eligible
/// for rewards.
pub deadline: domain::eth::BlockNo,
/// JIT orders with surplus capturing JIT order owners should capture
/// surplus if settled.
pub surplus_capturing_jit_order_owners: Vec<domain::eth::Address>,
}
32 changes: 17 additions & 15 deletions crates/autopilot/src/domain/settlement/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,39 @@
use crate::{domain::eth, infra};

mod auction;
mod solution;
mod transaction;
pub use {solution::Solution, transaction::Transaction};
pub use {auction::Auction, solution::Solution, transaction::Transaction};

/// A solution together with the transaction that executed it on-chain.
/// A solution together with the `Auction` for which it was picked as a winner
/// and executed on-chain.
///
/// Referenced as a [`Settlement`] in the codebase.
#[allow(dead_code)]
#[derive(Debug)]
pub struct Settlement {
solution: Solution,
transaction: Transaction,
auction: Auction,
}

impl Settlement {
pub async fn new(tx: eth::TxId, eth: &infra::Ethereum) -> Result<Self, Error> {
let transaction = eth.transaction(tx).await?;
let solution = Solution::new(
&transaction.input.0.clone().into(),
eth.contracts().settlement_domain_separator(),
)?;
Ok(Self {
solution,
transaction,
})
pub async fn new(
tx: &Transaction,
domain_separator: &eth::DomainSeparator,
persistence: &infra::Persistence,
) -> Result<Self, Error> {
let solution = Solution::new(&tx.input, domain_separator)?;
let auction = persistence.get_auction(solution.auction_id()).await?;

Ok(Self { solution, auction })
}
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error(transparent)]
Blockchain(#[from] infra::blockchain::Error),
#[error(transparent)]
Solution(#[from] solution::Error),
#[error(transparent)]
Auction(#[from] infra::persistence::error::Auction),
}
2 changes: 1 addition & 1 deletion crates/autopilot/src/infra/blockchain/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ fn into_domain(
.from
.ok_or(anyhow::anyhow!("missing from"))?
.into(),
input: crate::util::Bytes(transaction.input.0),
input: transaction.input.0.into(),
block: receipt
.block_number
.ok_or(anyhow::anyhow!("missing block_number"))?
Expand Down
52 changes: 52 additions & 0 deletions crates/autopilot/src/infra/persistence/dto/fee_policy.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use {
crate::{boundary, domain},
anyhow::Context,
database::fee_policies::{FeePolicy, FeePolicyKind},
};

Expand Down Expand Up @@ -48,3 +49,54 @@ pub fn from_domain(
},
}
}

pub fn try_into_domain(
policy: FeePolicy,
quote: Option<&domain::quote::Quote>,
) -> Result<domain::fee::Policy, Error> {
let policy = match policy.kind {
FeePolicyKind::Surplus => domain::fee::Policy::Surplus {
factor: policy
.surplus_factor
.context("missing surplus_factor")?
.try_into()?,
max_volume_factor: policy
.surplus_max_volume_factor
.context("missing surplus_max_volume_factor")?
.try_into()?,
},
FeePolicyKind::Volume => domain::fee::Policy::Volume {
factor: policy
.volume_factor
.context("missing volume_factor")?
.try_into()?,
},
FeePolicyKind::PriceImprovement => domain::fee::Policy::PriceImprovement {
factor: policy
.price_improvement_factor
.context("missing price_improvement_factor")?
.try_into()?,
max_volume_factor: policy
.price_improvement_max_volume_factor
.context("missing price_improvement_max_volume_factor")?
.try_into()?,
quote: {
let quote = quote.ok_or(Error::MissingQuote)?;
domain::fee::Quote {
sell_amount: quote.sell_amount.into(),
buy_amount: quote.buy_amount.into(),
fee: quote.fee.into(),
}
},
},
};
Ok(policy)
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("failed to convert database data to domain data {0}")]
Inconsistency(#[from] anyhow::Error),
#[error("missing quote for price improvement fee policy")]
MissingQuote,
}
Loading

0 comments on commit 0ed1c76

Please sign in to comment.