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

Storing call_data in quotes and order_quotes tables #3124

Open
wants to merge 53 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
f46b82d
Implementation
mstrug Nov 14, 2024
d9eb189
Added call_data to quotes table
mstrug Nov 15, 2024
2c0e92e
Updated order_quotes table
mstrug Nov 15, 2024
006a873
Added comments
mstrug Nov 15, 2024
7d2bb01
Added db migration
mstrug Nov 15, 2024
9947257
Fixed formatting
mstrug Nov 15, 2024
692d94e
Fixed sql query
mstrug Nov 15, 2024
6fb1ae7
Updated db querying for order with quote
mstrug Nov 15, 2024
a8f349f
Added test
mstrug Nov 15, 2024
eaf09d2
Merge branch 'main' into feature/storing-call-data-in-quotes
mstrug Nov 15, 2024
67c20ff
Fixed formatting
mstrug Nov 15, 2024
e9026a4
Updated tests
mstrug Nov 15, 2024
6671767
Added verified column to quotes table
mstrug Nov 21, 2024
086e579
Added quotes_interactions table
mstrug Nov 23, 2024
bca89ac
Fixed tests compilation
mstrug Nov 23, 2024
7c6983c
Fixed formatting
mstrug Nov 23, 2024
a847647
Updated orders database tables
mstrug Nov 23, 2024
1868aae
Fixed sql
mstrug Nov 25, 2024
507f6ae
Update
mstrug Nov 25, 2024
aff0468
Added removing quote_interactions on quote remove
mstrug Nov 25, 2024
189222b
Added order_quotes_interactions table
mstrug Nov 26, 2024
7a0cdc3
Added filling order quote interaction table
mstrug Nov 26, 2024
ae1115a
Fixed clippy warning
mstrug Nov 26, 2024
33a4cc4
Fixed missing variant
mstrug Nov 26, 2024
c62ac2d
Returning quote interactions in QuoteStoring implementation
mstrug Nov 27, 2024
dc36269
Added waiting for db migrations before tests
mstrug Nov 27, 2024
888e576
Added db dependency to migrations docker container
mstrug Nov 27, 2024
ec9eae0
Temporarily disabled restarts on migration
mstrug Nov 27, 2024
0210d3c
Reverted yaml file changes
mstrug Nov 27, 2024
77fc406
Fixed migration script
mstrug Nov 27, 2024
69dd7fa
Fixed test
mstrug Nov 27, 2024
828ec19
Merge branch 'main' into feature/storing-call-data-in-quotes
mstrug Nov 27, 2024
757029a
Updated new table names
mstrug Nov 28, 2024
085c530
Updated db readme & migration script
mstrug Nov 28, 2024
1e91d31
Merge branch 'main' into feature/storing-call-data-in-quotes
mstrug Nov 28, 2024
0921924
Merge branch 'main' into feature/storing-call-data-in-quotes
mstrug Nov 28, 2024
67cd65c
Code cleanup
mstrug Nov 28, 2024
39cade5
Updated tests
mstrug Nov 28, 2024
5239901
Added transaction for storing interactions
mstrug Nov 29, 2024
5aac1dc
Updated removing of expired quote interactions
mstrug Nov 29, 2024
23b2182
Removed updated on conflict from insert order quote interaction
mstrug Nov 29, 2024
f4f040c
Updated test
mstrug Nov 29, 2024
8848b73
Updated db readme
mstrug Nov 29, 2024
0afb9ad
Ensuring repeated db inserts uses transaction
mstrug Nov 29, 2024
2f610ae
Fixed tests
mstrug Nov 29, 2024
9979645
Optimized db queries using join
mstrug Nov 29, 2024
9a7f510
Added test
mstrug Dec 2, 2024
d8ff00b
Small refactorings
mstrug Dec 2, 2024
726376a
Function rename
mstrug Dec 2, 2024
1e23f0d
Using array_agg function for getting quote with interactions from db
mstrug Dec 2, 2024
f5cbc3e
Removed new error variant, fixed comment in sql script
mstrug Dec 2, 2024
59e39a2
Merge branch 'main' into feature/storing-call-data-in-quotes
mstrug Dec 2, 2024
ddaf4b2
Updated table descriptions
mstrug Dec 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 53 additions & 8 deletions crates/autopilot/src/database/auction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ use {
anyhow::{Context, Result},
chrono::{DateTime, Utc},
futures::{StreamExt, TryStreamExt},
model::{order::Order, quote::QuoteId},
model::{interaction::InteractionData, order::Order, quote::QuoteId},
num::ToPrimitive,
number::conversions::big_decimal_to_u256,
primitive_types::H160,
shared::{
db_order_conversions::full_order_into_model_order,
event_storing_helpers::{create_db_search_parameters, create_quote_row},
event_storing_helpers::{
create_db_search_parameters,
create_quote_interactions_insert_data,
create_quote_row,
},
order_quoting::{QuoteData, QuoteSearchParameters, QuoteStoring},
},
sqlx::{Acquire, PgConnection},
std::{collections::HashMap, ops::DerefMut},
};

Expand All @@ -23,8 +30,15 @@ impl QuoteStoring for Postgres {
.start_timer();

let mut ex = self.pool.acquire().await?;
let row = create_quote_row(data);
let id = database::quotes::save(&mut ex, &row).await?;
let row = create_quote_row(&data);

let mut transaction = ex.begin().await?;
let id = database::quotes::save(&mut transaction, &row).await?;
if !data.interactions.is_empty() {
let interactions = create_quote_interactions_insert_data(id, &data)?;
database::quotes::insert_quote_interactions(&mut transaction, &interactions).await?;
}
transaction.commit().await.context("commit")?;
Ok(id)
}

Expand All @@ -36,7 +50,14 @@ impl QuoteStoring for Postgres {

let mut ex = self.pool.acquire().await?;
let quote = database::quotes::get(&mut ex, id).await?;
quote.map(TryFrom::try_from).transpose()
let quote_interactions = Self::get_quote_interactions(&mut ex, id).await?;
mstrug marked this conversation as resolved.
Show resolved Hide resolved
Ok(quote
.map(QuoteData::try_from)
.transpose()?
.map(|mut quote_data| {
quote_data.interactions = quote_interactions;
quote_data
}))
}

async fn find(
Expand All @@ -54,9 +75,15 @@ impl QuoteStoring for Postgres {
let quote = database::quotes::find(&mut ex, &params)
.await
.context("failed finding quote by parameters")?;
quote
mstrug marked this conversation as resolved.
Show resolved Hide resolved
.map(|quote| Ok((quote.id, quote.try_into()?)))
.transpose()
if let Some(quote) = quote {
let quote_id = quote.id;
let quote_interactions = Self::get_quote_interactions(&mut ex, quote_id).await?;
mstrug marked this conversation as resolved.
Show resolved Hide resolved
let mut quote_data = QuoteData::try_from(quote)?;
quote_data.interactions = quote_interactions;
mstrug marked this conversation as resolved.
Show resolved Hide resolved
Ok(Some((quote_id, quote_data)))
} else {
Ok(None)
}
}
}

Expand Down Expand Up @@ -111,4 +138,22 @@ impl Postgres {
let id = database::auction::replace_auction(&mut ex, &data).await?;
Ok(id)
}

async fn get_quote_interactions(
ex: &mut PgConnection,
quote_id: QuoteId,
) -> Result<Vec<InteractionData>> {
database::quotes::get_quote_interactions(ex, quote_id)
.await?
.iter()
.map(|data| {
Ok(InteractionData {
target: H160(data.target.0),
value: big_decimal_to_u256(&data.value)
.context("quote interaction value is not a valid U256")?,
call_data: data.call_data.clone(),
})
squadgazzz marked this conversation as resolved.
Show resolved Hide resolved
})
.collect::<Result<Vec<InteractionData>>>()
}
}
2 changes: 2 additions & 0 deletions crates/autopilot/src/database/onchain_order_events/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,7 @@ async fn parse_general_onchain_order_placement_data<'a>(
sell_amount: u256_to_big_decimal(&quote.sell_amount),
buy_amount: u256_to_big_decimal(&quote.buy_amount),
solver: ByteArray(quote.data.solver.0),
verified: quote.data.verified,
}),
Err(err) => {
let err_label = err.to_metrics_label();
Expand Down Expand Up @@ -1187,6 +1188,7 @@ mod test {
sell_amount: u256_to_big_decimal(&quote.sell_amount),
buy_amount: u256_to_big_decimal(&quote.buy_amount),
solver: ByteArray(quote.data.solver.0),
verified: quote.data.verified,
};
assert_eq!(result.1, vec![Some(expected_quote)]);
assert_eq!(
Expand Down
2 changes: 2 additions & 0 deletions crates/database/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub const TABLES: &[&str] = &[
"auction_participants",
"app_data",
"jit_orders",
"quote_interactions",
"order_quote_interactions",
];

/// The names of potentially big volume tables we use in the db.
Expand Down
144 changes: 141 additions & 3 deletions crates/database/src/orders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ pub struct Quote {
pub sell_amount: BigDecimal,
pub buy_amount: BigDecimal,
pub solver: Address,
pub verified: bool,
m-lord-renkse marked this conversation as resolved.
Show resolved Hide resolved
}

pub async fn insert_quotes(ex: &mut PgConnection, quotes: &[Quote]) -> Result<(), sqlx::Error> {
Expand All @@ -346,9 +347,10 @@ INSERT INTO order_quotes (
sell_token_price,
sell_amount,
buy_amount,
solver
solver,
verified
)
VALUES ($1, $2, $3, $4, $5, $6, $7)"#;
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)"#;

pub async fn insert_quote_and_update_on_conflict(
ex: &mut PgConnection,
Expand All @@ -362,7 +364,7 @@ pub async fn insert_quote_and_update_on_conflict(
" ON CONFLICT (order_uid) DO UPDATE
SET gas_amount = $2, gas_price = $3,
sell_token_price = $4, sell_amount = $5,
buy_amount = $6
buy_amount = $6, verified = $8
"
);
sqlx::query(QUERY)
Expand All @@ -373,6 +375,7 @@ buy_amount = $6
.bind(&quote.sell_amount)
.bind(&quote.buy_amount)
.bind(quote.solver)
.bind(quote.verified)
.execute(ex)
.await?;
Ok(())
Expand All @@ -387,6 +390,7 @@ pub async fn insert_quote(ex: &mut PgConnection, quote: &Quote) -> Result<(), sq
.bind(&quote.sell_amount)
.bind(&quote.buy_amount)
.bind(quote.solver)
.bind(quote.verified)
.execute(ex)
.await?;
Ok(())
Expand Down Expand Up @@ -445,6 +449,61 @@ AND cancellation_timestamp IS NULL
.map(|_| ())
}

/// One row in the `order_quote_interactions` table.
#[derive(Clone, Default, Debug, PartialEq, sqlx::FromRow)]
pub struct OrderQuoteInteraction {
pub order_uid: OrderUid,
pub index: i32,
pub target: Address,
pub value: BigDecimal,
pub call_data: Vec<u8>,
}

pub async fn insert_order_quote_interaction(
ex: &mut PgConnection,
quote_interaction: &OrderQuoteInteraction,
) -> Result<(), sqlx::Error> {
const INSERT_ORDER_QUOTE_INTERACTION_QUERY: &str = r#"
INSERT INTO order_quote_interactions (
order_uid,
index,
target,
value,
call_data
)
VALUES ($1, $2, $3, $4, $5)
ON CONFLICT (order_uid, index) DO UPDATE SET
mstrug marked this conversation as resolved.
Show resolved Hide resolved
mstrug marked this conversation as resolved.
Show resolved Hide resolved
(
target,
value,
call_data
) = (
EXCLUDED.target,
EXCLUDED.value,
EXCLUDED.call_data
)
"#;
sqlx::query(INSERT_ORDER_QUOTE_INTERACTION_QUERY)
.bind(quote_interaction.order_uid)
.bind(quote_interaction.index)
.bind(quote_interaction.target)
.bind(&quote_interaction.value)
.bind(&quote_interaction.call_data)
.execute(ex)
.await?;
Ok(())
}

pub async fn insert_order_quote_interactions(
ex: &mut PgConnection,
quote_interactions: &[OrderQuoteInteraction],
) -> Result<(), sqlx::Error> {
for interactions in quote_interactions {
insert_order_quote_interaction(ex, interactions).await?;
}
Ok(())
}

/// Interactions are read as arrays of their fields: target, value, data.
/// This is done as sqlx does not support reading arrays of more complicated
/// types than just one field. The pre_ and post_interaction's data of
Expand Down Expand Up @@ -498,6 +557,7 @@ pub struct FullOrderWithQuote {
pub quote_gas_amount: Option<f64>,
pub quote_gas_price: Option<f64>,
pub quote_sell_token_price: Option<f64>,
pub quote_verified: Option<bool>,
pub solver: Option<Address>,
}

Expand Down Expand Up @@ -591,6 +651,7 @@ pub async fn single_full_order_with_quote(
", o_quotes.gas_amount as quote_gas_amount",
", o_quotes.gas_price as quote_gas_price",
", o_quotes.sell_token_price as quote_sell_token_price",
", o_quotes.verified as quote_verified",
", o_quotes.solver as solver",
" FROM ", FROM,
" LEFT JOIN order_quotes o_quotes ON o.uid = o_quotes.order_uid",
Expand Down Expand Up @@ -1201,6 +1262,7 @@ mod tests {
sell_amount: 4.into(),
buy_amount: 5.into(),
solver: ByteArray([1; 20]),
verified: false,
};
insert_quote(&mut db, &quote).await.unwrap();
insert_quote_and_update_on_conflict(&mut db, &quote)
Expand Down Expand Up @@ -1261,6 +1323,7 @@ mod tests {
sell_amount: 4.into(),
buy_amount: 5.into(),
solver: ByteArray([1; 20]),
verified: false,
};
insert_quote(&mut db, &quote).await.unwrap();
let quote_ = read_quote(&mut db, &quote.order_uid)
Expand All @@ -1287,6 +1350,7 @@ mod tests {
sell_amount: 4.into(),
buy_amount: 5.into(),
solver: ByteArray([1; 20]),
verified: false,
};
insert_quote(&mut db, &quote).await.unwrap();
let order_with_quote = single_full_order_with_quote(&mut db, &quote.order_uid)
Expand Down Expand Up @@ -2142,4 +2206,78 @@ mod tests {
]
);
}

#[tokio::test]
#[ignore]
async fn postgres_insert_order_quote_interaction() {
let mut db = PgConnection::connect("postgresql://").await.unwrap();
let mut db = db.begin().await.unwrap();
crate::clear_DANGER_(&mut db).await.unwrap();

let interaction = OrderQuoteInteraction {
order_uid: Default::default(),
index: Default::default(),
target: ByteArray([1; 20]),
value: 2.into(),
call_data: vec![3; 20],
};
insert_order_quote_interaction(&mut db, &interaction)
.await
.unwrap();

const QUERY: &str = r#"
SELECT * FROM order_quote_interactions
WHERE order_uid = $1
"#;

let interactions: Vec<OrderQuoteInteraction> = sqlx::query_as(QUERY)
.bind(interaction.order_uid)
.fetch_all(&mut db as &mut PgConnection)
.await
.unwrap();
assert_eq!(*interactions.first().unwrap(), interaction);
}

#[tokio::test]
#[ignore]
async fn postgres_insert_order_quote_interaction_on_conflict() {
let mut db = PgConnection::connect("postgresql://").await.unwrap();
let mut db = db.begin().await.unwrap();
crate::clear_DANGER_(&mut db).await.unwrap();

let order_uid = Default::default();
let interaction1 = OrderQuoteInteraction {
order_uid,
index: Default::default(),
target: ByteArray([1; 20]),
value: 2.into(),
call_data: vec![3; 20],
};
insert_order_quote_interaction(&mut db, &interaction1)
.await
.unwrap();

let interaction2 = OrderQuoteInteraction {
order_uid,
index: Default::default(),
target: ByteArray([4; 20]),
value: 4.into(),
call_data: vec![5; 20],
};
insert_order_quote_interaction(&mut db, &interaction2)
.await
.unwrap();

const QUERY: &str = r#"
SELECT * FROM order_quote_interactions
WHERE order_uid = $1
"#;

let interactions: Vec<OrderQuoteInteraction> = sqlx::query_as(QUERY)
.bind(order_uid)
.fetch_all(&mut db as &mut PgConnection)
.await
.unwrap();
assert_eq!(*interactions.first().unwrap(), interaction2);
}
}
Loading
Loading