-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fee Policies API #2809
Fee Policies API #2809
Conversation
crates/model/src/trade.rs
Outdated
num::BigUint, | ||
primitive_types::{H160, H256}, | ||
serde::{Deserialize, Serialize}, | ||
serde_with::{serde_as, DisplayFromStr}, | ||
}; | ||
|
||
#[serde_as] | ||
#[derive(Eq, PartialEq, Clone, Debug, Default, Deserialize, Serialize)] | ||
#[derive(PartialEq, Clone, Debug, Default, Deserialize, Serialize)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Eq
was removed since FeePolicy contains f64
fields that don't derive this trait. Also, couldn't find a reason why this was required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a good approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Despite having additional comments in the PR, I think the description should contain a clear overview for the reviewer and future reader of the change summarising of the core challenge faced here, the different options considered and why the one that was chosen prevailed.
IMO, we should keep our queries very lean and basic (ie pretty straight forward "fetch raw data") and do joins and filtering logic in the rust code (unless there is very big performance considerations, which I don't believe is the case here).
Otherwise we will stand in front of a monumental challenge the day we need to move away from postgres (which will likely come at some point as we scale and receive more and more orders).
Concretely, here this would mean to first fetch the trades and then fetch the fee policies in a second roundtrip by using the order and auction ids.
Makes sense. Initially, it looked like a tiny change, but due to |
Got rid of the additional complexity, as Felix suggested. Now it uses 3 SQL queries instead of a single one. There is an option to include the quote fetching right into the trades SQL query, but semantically, the quote is required for the policy fee where the latter is no longer a part of the trades SQL. |
4f044a5
to
368b534
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach looks good. Some questions around inconsistencies and combining the third roundtrip to the db (fetching all required quotes at once)
}; | ||
|
||
#[async_trait::async_trait] | ||
pub trait FeePolicyRetrieving: Send + Sync { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this trait if there is only a single impl?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not required, removed.
.with_label_values(&["order_quote"]) | ||
.start_timer(); | ||
|
||
let order_quote = database::orders::read_quote(&mut ex, &order_uid) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be collected and then fetched in a single roundtrip imo (can use existing read_quotes
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense, reworked.
crates/orderbook/src/database.rs
Outdated
@@ -1,5 +1,6 @@ | |||
pub mod app_data; | |||
pub mod auctions; | |||
mod fee_policy; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any reason this is the only module that's using singular (c.f auctions, trades, etc).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed.
80778b5
to
4ee3cde
Compare
async move { | ||
match trade.auction_id { | ||
Some(auction_id) => { | ||
self.fee_policies(auction_id, trade.order_uid, quote).await |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be a single roundtrip (fetch fee policies for a list of auction/order
pairs) and then only for the ones that require a quote we fetch the quote (in another roundtrip)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replaced with a single roundtrip.
c275939
to
f47f8cd
Compare
if i > 0 { | ||
query_builder.push(" OR "); | ||
} | ||
query_builder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not to use format!()
instead? it has many string reallocation...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use QueryBuilder for such cases as the most convenient option, which should be safe since it uses write!
macro under the hood.
) -> anyhow::Result<HashMap<(AuctionId, OrderUid), Vec<FeePolicy>>> { | ||
let mut ex = self.pool.acquire().await?; | ||
|
||
let _timer = super::Metrics::get() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it this timer stopped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, forgot to stop it after refactoring.
a6bebad
to
22bac33
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly nits
"missing price improvement quote for order '{:?}'", | ||
order_uid | ||
))?; | ||
let fee = quote.gas_amount * quote.gas_price / quote.sell_token_price; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function already supports error handling so I would suggest to use checked_div()
here just to be safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair point. Used BigRational
.
PriceImprovement { | ||
factor: f64, | ||
max_volume_factor: f64, | ||
quote: Quote, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, this is not documented in the openapi.yml definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description
Includes policy fees in the
/trades
API associated with the trade/order.Changes
More details are in the PR comments.
How to test
Existing and new tests.
Related Issues
Fixes #2642