Skip to content
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

Show JIT orders on COW explorer #2920

Merged
merged 62 commits into from
Sep 4, 2024
Merged

Show JIT orders on COW explorer #2920

merged 62 commits into from
Sep 4, 2024

Conversation

sunce86
Copy link
Contributor

@sunce86 sunce86 commented Aug 22, 2024

Description

Fixes #2825

Changes

  • Added jit_orders database table and read/write functions
  • Refactored domain::Settlement so that user orders and JIT orders can be differentiated using Trade enum.
  • Saved JIT orders from OnSettlementEventUpdater
  • Return jit orders on /get_order and /get_trades

Todo in follow up PR: return on get_order_by_tx and get_order_by_owner

How to test

  1. Updated unit tests for surplus/fee calculation
  2. Added one new unit test for settlement with cow amm.
  3. Added unit test for read/write to the new database table.
  4. Jit order expanded to prove that jit orders are returned on endpoints.

I would suggest to review in IDE, since it's not easy to follow the changes as code diff.

Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have almost only nits. The only launchblocking comment for me is the FullJitOrder type which I think should be removed.

The test looks great!

crates/autopilot/src/domain/settlement/trade/math.rs Outdated Show resolved Hide resolved
crates/autopilot/src/domain/settlement/trade/mod.rs Outdated Show resolved Hide resolved
/// Adjusted uniform prices to account for fees (gas cost and protocol fees)
pub custom: ClearingPrices,
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any reason? I personally think clearing prices make more sense in the context of a trade than in the context of a transaction?

/// Jit order combined with trades table and order_execution table, suitable for
/// API responses.
#[derive(Debug, Clone, Default, PartialEq, sqlx::FromRow)]
pub struct FullJitOrder {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this type is not needed. The API expects a orders::FullOrder. Instead of creating a new type (that has a very vague "Full" prefix which isn't really expressive) can we just explicitly return Option<orders::FullOrder> here (it's also not easy to find where the From trait is called and there is no strong reason to use this abstraction because the type is never used in a generic Vec or the like)

Copy link
Contributor Author

@sunce86 sunce86 Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want this then conversion from FullJitOrder to orders::FullOrder is either:

  1. Part of sql query (hardcoded) which is not reusable and not compiler checked.
  2. Directly implemented inside single_full_jit_order to avoid defining FullJitOrder struct, which again in not reusable.

Reusability is important since in a follow up PR I will implement similar function to orders::full_orders_in_tx that will reuse this.

I ended refactoring so that FullJitOrder is now private function and conversion is done inside jit_orders::single_full_jit_order which resolves most of your concerns.

crates/database/src/trades.rs Outdated Show resolved Hide resolved
@@ -45,47 +45,58 @@ impl JitOrder {
signing_scheme: EcdsaSigningScheme,
domain: &DomainSeparator,
key: SecretKeyRef,
) -> solvers_dto::solution::JitOrder {
) -> (solvers_dto::solution::JitOrder, OrderUid) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nanonit: uid is not dependent on signing and should (it's a pure coincidence that this method is called in the test where it is used, and happens to also depend on DomainSeperator). It makes more sense to have this as a standalone method imo.

crates/autopilot/src/domain/settlement/mod.rs Outdated Show resolved Hide resolved
crates/autopilot/src/domain/settlement/trade/math.rs Outdated Show resolved Hide resolved
crates/autopilot/src/domain/settlement/trade/mod.rs Outdated Show resolved Hide resolved
crates/autopilot/src/domain/settlement/trade/mod.rs Outdated Show resolved Hide resolved
pub executed_surplus_fee: BigDecimal,
}

/// 1:1 mapping to the `jit_orders` table, used to store orders.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This type does not have to be leaked.
It could either be declared in the single_full_jit_order() function or probably better you could design the query such that we can directly deserialize the row into the regular full order struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is used for storing orders as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

answer might be related to #2920 (comment)

.push_bind(jit_order.buy_token_balance);
});

query_builder.push(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is a simple insert no sufficient here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not following? Ilya previously suggested to have a function that inserts batch of jit orders.

Copy link
Contributor

@MartinquaXD MartinquaXD Sep 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean why do we need to manage conflicts on inserts here?

Copy link
Contributor Author

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 leftover from when the OnSettlementEventUpdater was doing reindexing and in case of some bug in event indexing logic we might get stuck on a same insert.
I am also fine putting ON CONFLICT DO NOTHING if it seems cleaner in this case?

crates/database/src/settlements.rs Outdated Show resolved Hide resolved
crates/e2e/src/setup/solver/solution.rs Outdated Show resolved Hide resolved
database/README.md Outdated Show resolved Hide resolved
@@ -263,7 +263,7 @@ pub struct Event {
}

/// Any type of on-chain transaction.
#[derive(Debug)]
#[derive(Debug, Clone, Default)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need the Default here, and in the structs above?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

needed for settlement unit tests

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in that case, we could use #[cfg_attr(test, derive(Default))]. In production code, those struct shouldn't have a default 🤔

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now that I accidentally resolved this comment without fixing. Will address it in another PR.

Copy link
Contributor

@fleupold fleupold left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing blocking from my side, just naming nits.

/// Adjusted uniform prices to account for fees (gas cost and protocol fees)
pub custom: ClearingPrices,
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't have put it in math::Trade but in the highlevel thing that hosts the enum. But also no strong feeling

},
};

pub async fn single_full_jit_order(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why not

Suggested change
pub async fn single_full_jit_order(
pub async fn fetch(

so it will be called via database::jit_orders::fetch(...) or by_uid or something elegant.

/// Jit order combined with trades table and order_execution table, suitable for
/// API responses.
#[derive(Debug, Clone, Default, PartialEq, sqlx::FromRow)]
struct FullJitOrder {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit

Suggested change
struct FullJitOrder {
struct JitOrderWithExecutions {

Full is a bit vague

Copy link
Contributor

@squadgazzz squadgazzz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@sunce86 sunce86 enabled auto-merge (squash) September 4, 2024 07:59
@sunce86 sunce86 merged commit 41334ea into main Sep 4, 2024
10 checks passed
@sunce86 sunce86 deleted the jit-orders-database-v2 branch September 4, 2024 08:03
@github-actions github-actions bot locked and limited conversation to collaborators Sep 4, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: Surplus capturing JIT orders to be shown on cow explorer
5 participants