From f2cb4c748f88ed619106aa4d03de9a00c8809162 Mon Sep 17 00:00:00 2001 From: m-lord-renkse <160488334+m-lord-renkse@users.noreply.github.com> Date: Wed, 11 Sep 2024 17:26:59 +0200 Subject: [PATCH] Autopilot: Remove /reveal roundtrip (#2964) # Description Currently, we have no use for reveal and we are calling settle unconditionally after it. We are storing the internalised and uninternalised calldata that is returned in the database. However, since slippage accounting moved towards counting internal buffer trades as slippage we have no more use for the "uninternalised" calldata. The final calldata can also be recovered from the settled transaction, and doesn't matter in the case settlement failed. # Changes - Remove `/reveal` roundtrip - Remove internalised and uninternalised calldata from the competition/solution objects ## How to test 1. Acceptance tests ## Related Issues Fixes #2942 --- crates/autopilot/src/database/competition.rs | 18 --- crates/autopilot/src/run_loop.rs | 123 ++++--------------- crates/driver/openapi.yml | 10 +- crates/e2e/tests/e2e/database.rs | 5 - crates/e2e/tests/e2e/solver_competition.rs | 3 - crates/e2e/tests/e2e/univ2.rs | 2 - crates/model/src/format.rs | 9 -- crates/model/src/lib.rs | 1 - crates/model/src/solver_competition.rs | 13 -- crates/orderbook/openapi.yml | 14 --- 10 files changed, 27 insertions(+), 171 deletions(-) delete mode 100644 crates/model/src/format.rs diff --git a/crates/autopilot/src/database/competition.rs b/crates/autopilot/src/database/competition.rs index 5f2b75736e..73bec9ebce 100644 --- a/crates/autopilot/src/database/competition.rs +++ b/crates/autopilot/src/database/competition.rs @@ -5,7 +5,6 @@ use { auction_participants::Participant, auction_prices::AuctionPrice, byte_array::ByteArray, - settlement_call_data::SettlementCallData, settlement_scores::Score, surplus_capturing_jit_order_owners, Address, @@ -34,12 +33,6 @@ pub struct Competition { /// chain before this block height. pub block_deadline: u64, pub competition_simulation_block: u64, - /// Winner settlement call data - #[derivative(Debug(format_with = "shared::debug_bytes"))] - pub call_data: Vec, - /// Uninternalized winner settlement call data - #[derivative(Debug(format_with = "shared::debug_bytes"))] - pub uninternalized_call_data: Vec, pub competition_table: SolverCompetitionDB, } @@ -109,17 +102,6 @@ impl super::Postgres { .await .context("auction_prices::insert")?; - database::settlement_call_data::insert( - &mut ex, - SettlementCallData { - auction_id: competition.auction_id, - call_data: competition.call_data.clone(), - uninternalized_call_data: competition.uninternalized_call_data.clone(), - }, - ) - .await - .context("settlement_call_data::insert")?; - database::auction_orders::insert( &mut ex, competition.auction_id, diff --git a/crates/autopilot/src/run_loop.rs b/crates/autopilot/src/run_loop.rs index 66b72be740..5c1e167830 100644 --- a/crates/autopilot/src/run_loop.rs +++ b/crates/autopilot/src/run_loop.rs @@ -9,7 +9,7 @@ use { }, infra::{ self, - solvers::dto::{reveal, settle, solve}, + solvers::dto::{settle, solve}, }, maintenance::Maintenance, run::Liveness, @@ -192,19 +192,6 @@ impl RunLoop { if let Some(Participant { driver, solution }) = solutions.last() { tracing::info!(driver = %driver.name, solution = %solution.id(), "winner"); - let reveal_start = Instant::now(); - let revealed = match self.reveal(driver, auction_id, solution.id()).await { - Ok(result) => { - Metrics::reveal_ok(driver, reveal_start.elapsed()); - result - } - Err(err) => { - Metrics::reveal_err(driver, reveal_start.elapsed(), &err); - tracing::warn!(driver = %driver.name, ?err, "failed to reveal winning solution"); - return; - } - }; - let block_deadline = competition_simulation_block + self.submission_deadline; // Post-processing should not be executed asynchronously since it includes steps @@ -216,7 +203,6 @@ impl RunLoop { competition_simulation_block, solution, &solutions, - revealed, block_deadline, ) .await @@ -250,7 +236,6 @@ impl RunLoop { competition_simulation_block: u64, winning_solution: &competition::SolutionWithId, solutions: &[Participant<'_>], - revealed: reveal::Response, block_deadline: u64, ) -> Result<()> { let start = Instant::now(); @@ -267,9 +252,6 @@ impl RunLoop { .collect::>(); let mut fee_policies = Vec::new(); - let call_data = revealed.calldata.internalized.clone(); - let uninternalized_call_data = revealed.calldata.uninternalized.clone(); - for order_id in winning_solution.order_ids() { match auction .orders @@ -303,38 +285,27 @@ impl RunLoop { solutions: solutions .iter() .enumerate() - .map(|(index, participant)| { - let is_winner = solutions.len() - index == 1; - let mut settlement = SolverSettlement { - solver: participant.driver.name.clone(), - solver_address: participant.solution.solver().0, - score: Some(Score::Solver(participant.solution.score().get().0)), - ranking: solutions.len() - index, - orders: participant - .solution - .orders() - .iter() - .map(|(id, order)| Order::Colocated { - id: (*id).into(), - sell_amount: order.sell.into(), - buy_amount: order.buy.into(), - }) - .collect(), - clearing_prices: participant - .solution - .prices() - .iter() - .map(|(token, price)| (token.0, price.get().into())) - .collect(), - call_data: None, - uninternalized_call_data: None, - }; - if is_winner { - settlement.call_data = Some(revealed.calldata.internalized.clone()); - settlement.uninternalized_call_data = - Some(revealed.calldata.uninternalized.clone()); - } - settlement + .map(|(index, participant)| SolverSettlement { + solver: participant.driver.name.clone(), + solver_address: participant.solution.solver().0, + score: Some(Score::Solver(participant.solution.score().get().0)), + ranking: solutions.len() - index, + orders: participant + .solution + .orders() + .iter() + .map(|(id, order)| Order::Colocated { + id: (*id).into(), + sell_amount: order.sell.into(), + buy_amount: order.buy.into(), + }) + .collect(), + clearing_prices: participant + .solution + .prices() + .iter() + .map(|(token, price)| (token.0, price.get().into())) + .collect(), }) .collect(), }; @@ -351,8 +322,6 @@ impl RunLoop { .collect(), block_deadline, competition_simulation_block, - call_data, - uninternalized_call_data, competition_table, }; @@ -647,28 +616,6 @@ impl RunLoop { Ok(futures::future::join_all(futures).await) } - /// Ask the winning solver to reveal their solution. - async fn reveal( - &self, - driver: &infra::Driver, - auction: domain::auction::Id, - solution_id: u64, - ) -> Result { - let response = driver - .reveal(&reveal::Request { solution_id }) - .await - .map_err(RevealError::Failure)?; - if !response - .calldata - .internalized - .ends_with(&auction.to_be_bytes()) - { - return Err(RevealError::AuctionMismatch); - } - - Ok(response) - } - /// Execute the solver's solution. Returns Ok when the corresponding /// transaction has been mined. async fn settle( @@ -769,14 +716,6 @@ enum SolveError { Failure(anyhow::Error), } -#[derive(Debug, thiserror::Error)] -enum RevealError { - #[error("revealed calldata does not match auction")] - AuctionMismatch, - #[error(transparent)] - Failure(anyhow::Error), -} - #[derive(Debug, thiserror::Error)] enum SettleError { #[error(transparent)] @@ -888,24 +827,6 @@ impl Metrics { .inc(); } - fn reveal_ok(driver: &infra::Driver, elapsed: Duration) { - Self::get() - .reveal - .with_label_values(&[&driver.name, "success"]) - .observe(elapsed.as_secs_f64()); - } - - fn reveal_err(driver: &infra::Driver, elapsed: Duration, err: &RevealError) { - let label = match err { - RevealError::AuctionMismatch => "mismatch", - RevealError::Failure(_) => "error", - }; - Self::get() - .reveal - .with_label_values(&[&driver.name, label]) - .observe(elapsed.as_secs_f64()); - } - fn settle_ok(driver: &infra::Driver, elapsed: Duration) { Self::get() .settle diff --git a/crates/driver/openapi.yml b/crates/driver/openapi.yml index 2149cf31ae..f52c84e5b2 100644 --- a/crates/driver/openapi.yml +++ b/crates/driver/openapi.yml @@ -93,7 +93,7 @@ paths: description: | Reveal the calldata of the previously solved auction. - This may be used by the autopilot to verify the solution before requesting its execution it on chain. + This may be used by the autopilot for the shadow competition to verify the solution before requesting its execution it on chain. requestBody: required: true content: @@ -243,7 +243,7 @@ components: type: string signingScheme: type: string - enum: ["eip712", "ethsign", "presign", "eip1271"] + enum: [ "eip712", "ethsign", "presign", "eip1271" ] signature: description: Hex encoded bytes with `0x` prefix. type: string @@ -380,7 +380,7 @@ components: solutionId: description: | The unique identifier of the solution. - + This id is used to identify the solution when executing it. type: string example: "1" @@ -408,7 +408,7 @@ components: clearingPrices: description: | Mapping of hex token address to price. - + The prices of tokens for settled user orders as passed to the settlement contract. type: object additionalProperties: @@ -467,7 +467,7 @@ components: properties: kind: type: string - enum: [ "priceImprovement" ] + enum: ["priceImprovement"] maxVolumeFactor: description: Never charge more than that percentage of the order volume. type: number diff --git a/crates/e2e/tests/e2e/database.rs b/crates/e2e/tests/e2e/database.rs index ab65ebe206..868d0554c3 100644 --- a/crates/e2e/tests/e2e/database.rs +++ b/crates/e2e/tests/e2e/database.rs @@ -37,7 +37,6 @@ pub struct Cip20Data { pub participants: Vec, pub prices: Vec, pub score: database::settlement_scores::Score, - pub call_data: database::settlement_call_data::SettlementCallData, pub competition: serde_json::Value, } @@ -74,9 +73,6 @@ SELECT * FROM settlements WHERE auction_id = $1"; let score = database::settlement_scores::fetch(&mut db, auction_id) .await .unwrap()?; - let call_data = database::settlement_call_data::fetch(&mut db, auction_id) - .await - .unwrap()?; let competition = database::solver_competition::load_by_id(&mut db, auction_id) .await .unwrap()? @@ -88,7 +84,6 @@ SELECT * FROM settlements WHERE auction_id = $1"; participants, prices, score, - call_data, competition, }) } diff --git a/crates/e2e/tests/e2e/solver_competition.rs b/crates/e2e/tests/e2e/solver_competition.rs index 127b59582c..08d851bddc 100644 --- a/crates/e2e/tests/e2e/solver_competition.rs +++ b/crates/e2e/tests/e2e/solver_competition.rs @@ -120,11 +120,8 @@ async fn solver_competition(web3: Web3) { // Non winning candidate assert!(competition.common.solutions[0].ranking == 2); - assert!(competition.common.solutions[0].call_data.is_none()); - // Winning candidate assert!(competition.common.solutions[1].ranking == 1); - assert!(competition.common.solutions[1].call_data.is_some()); } async fn fairness_check(web3: Web3) { diff --git a/crates/e2e/tests/e2e/univ2.rs b/crates/e2e/tests/e2e/univ2.rs index e8407a832a..4688785272 100644 --- a/crates/e2e/tests/e2e/univ2.rs +++ b/crates/e2e/tests/e2e/univ2.rs @@ -117,8 +117,6 @@ async fn test(web3: Web3) { && data.participants.iter().any(|p| p.participant.0 == solver.address().0) // and won the auction && data.score.winner.0 == solver.address().0 - // and calldata is present - && !data.call_data.call_data.is_empty() }; wait_for_condition(TIMEOUT, cip_20_data_updated) .await diff --git a/crates/model/src/format.rs b/crates/model/src/format.rs deleted file mode 100644 index ba62e0f67c..0000000000 --- a/crates/model/src/format.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub fn debug_optional_bytes( - bytes: &Option>, - formatter: &mut std::fmt::Formatter, -) -> Result<(), std::fmt::Error> { - match bytes { - Some(bytes) => formatter.write_fmt(format_args!("0x{}", hex::encode(bytes.as_ref()))), - None => formatter.write_str("None"), - } -} diff --git a/crates/model/src/lib.rs b/crates/model/src/lib.rs index 4817639a99..e60f82fb01 100644 --- a/crates/model/src/lib.rs +++ b/crates/model/src/lib.rs @@ -2,7 +2,6 @@ pub mod auction; pub mod fee_policy; -mod format; pub mod interaction; pub mod order; pub mod quote; diff --git a/crates/model/src/solver_competition.rs b/crates/model/src/solver_competition.rs index 014a3f4947..150f586023 100644 --- a/crates/model/src/solver_competition.rs +++ b/crates/model/src/solver_competition.rs @@ -1,6 +1,5 @@ use { crate::{auction::AuctionId, order::OrderUid}, - bytes_hex::BytesHex, derivative::Derivative, number::serialization::HexOrDecimalU256, primitive_types::{H160, H256, U256}, @@ -55,14 +54,6 @@ pub struct SolverSettlement { #[serde_as(as = "BTreeMap<_, HexOrDecimalU256>")] pub clearing_prices: BTreeMap, pub orders: Vec, - #[serde(skip_serializing_if = "Option::is_none")] - #[serde_as(as = "Option")] - #[derivative(Debug(format_with = "crate::format::debug_optional_bytes"))] - pub call_data: Option>, - #[serde(skip_serializing_if = "Option::is_none")] - #[serde_as(as = "Option")] - #[derivative(Debug(format_with = "crate::format::debug_optional_bytes"))] - pub uninternalized_call_data: Option>, } #[serde_as] @@ -176,8 +167,6 @@ mod tests { "executedAmount": "14", } ], - "callData": "0x13", - "uninternalizedCallData": "0x1314", }, ], }); @@ -219,8 +208,6 @@ mod tests { executed_amount: 14.into(), }, ], - call_data: Some(vec![0x13]), - uninternalized_call_data: Some(vec![0x13, 0x14]), }], }, }; diff --git a/crates/orderbook/openapi.yml b/crates/orderbook/openapi.yml index e7eb381ef9..00639e36b0 100644 --- a/crates/orderbook/openapi.yml +++ b/crates/orderbook/openapi.yml @@ -1552,20 +1552,6 @@ components: $ref: "#/components/schemas/UID" executedAmount: $ref: "#/components/schemas/BigUint" - callData: - allOf: - - $ref: "#/components/schemas/CallData" - description: Transaction `calldata` that is executed on-chain if the settlement is executed. - uninternalizedCallData: - allOf: - - $ref: "#/components/schemas/CallData" - description: | - Full `calldata` as generated from the original solver output. - - It can be different from the executed transaction if part of the settlements are internalised - (use internal liquidity in lieu of trading against on-chain liquidity). - - This field is omitted in case it coincides with `callData`. NativePriceResponse: description: | The estimated native price for the token