diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index c4d49550c8..00c2bca3c9 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -41,8 +41,7 @@ ] }, "extensions": [ - "rust-lang.rust-analyzer", - "serayuzgur.crates" + "rust-lang.rust-analyzer" ] } }, diff --git a/crates/autopilot/src/boundary/events/settlement.rs b/crates/autopilot/src/boundary/events/settlement.rs index 440f16b245..1f2859cfa7 100644 --- a/crates/autopilot/src/boundary/events/settlement.rs +++ b/crates/autopilot/src/boundary/events/settlement.rs @@ -11,14 +11,16 @@ impl_event_retrieving! { pub struct Indexer { db: Postgres, + start_index: u64, settlement_observer: settlement::Observer, } impl Indexer { - pub fn new(db: Postgres, settlement_observer: settlement::Observer) -> Self { + pub fn new(db: Postgres, settlement_observer: settlement::Observer, start_index: u64) -> Self { Self { db, settlement_observer, + start_index, } } } @@ -29,7 +31,9 @@ const INDEX_NAME: &str = "settlements"; #[async_trait::async_trait] impl EventStoring for Indexer { async fn last_event_block(&self) -> Result { - super::read_last_block_from_db(&self.db.pool, INDEX_NAME).await + super::read_last_block_from_db(&self.db.pool, INDEX_NAME) + .await + .map(|last_block| last_block.max(self.start_index)) } async fn persist_last_indexed_block(&mut self, latest_block: u64) -> Result<()> { diff --git a/crates/autopilot/src/infra/solvers/dto/reveal.rs b/crates/autopilot/src/infra/solvers/dto/reveal.rs index 1cd0848919..e8ac28f02a 100644 --- a/crates/autopilot/src/infra/solvers/dto/reveal.rs +++ b/crates/autopilot/src/infra/solvers/dto/reveal.rs @@ -1,9 +1,10 @@ use { serde::{Deserialize, Serialize}, - serde_with::serde_as, + serde_with::{serde_as, skip_serializing_none}, }; #[serde_as] +#[skip_serializing_none] #[derive(Clone, Debug, Default, Serialize)] #[serde(rename_all = "camelCase")] pub struct Request { @@ -11,8 +12,8 @@ pub struct Request { #[serde_as(as = "serde_with::DisplayFromStr")] pub solution_id: u64, /// Auction ID in which the specified solution ID is competing. - #[serde_as(as = "serde_with::DisplayFromStr")] - pub auction_id: i64, + #[serde_as(as = "Option")] + pub auction_id: Option, } #[serde_as] diff --git a/crates/autopilot/src/infra/solvers/dto/settle.rs b/crates/autopilot/src/infra/solvers/dto/settle.rs index 3ffba83df3..0269e9425d 100644 --- a/crates/autopilot/src/infra/solvers/dto/settle.rs +++ b/crates/autopilot/src/infra/solvers/dto/settle.rs @@ -1,10 +1,11 @@ use { primitive_types::H256, serde::{Deserialize, Serialize}, - serde_with::serde_as, + serde_with::{serde_as, skip_serializing_none}, }; #[serde_as] +#[skip_serializing_none] #[derive(Clone, Debug, Default, Serialize)] #[serde(rename_all = "camelCase")] pub struct Request { @@ -14,8 +15,8 @@ pub struct Request { /// The last block number in which the solution TX can be included pub submission_deadline_latest_block: u64, /// Auction ID in which the specified solution ID is competing. - #[serde_as(as = "serde_with::DisplayFromStr")] - pub auction_id: i64, + #[serde_as(as = "Option")] + pub auction_id: Option, } #[serde_as] diff --git a/crates/autopilot/src/run.rs b/crates/autopilot/src/run.rs index 22db9d47c3..4a5f0a6503 100644 --- a/crates/autopilot/src/run.rs +++ b/crates/autopilot/src/run.rs @@ -26,7 +26,7 @@ use { chain::Chain, clap::Parser, contracts::{BalancerV2Vault, IUniswapV3Factory}, - ethcontract::{dyns::DynWeb3, errors::DeployError, BlockNumber}, + ethcontract::{common::DeploymentInformation, dyns::DynWeb3, errors::DeployError, BlockNumber}, ethrpc::block_stream::block_number_to_block_number_hash, futures::StreamExt, model::DomainSeparator, @@ -363,11 +363,28 @@ pub async fn run(args: Arguments) { infra::persistence::Persistence::new(args.s3.into().unwrap(), Arc::new(db.clone())).await; let settlement_observer = crate::domain::settlement::Observer::new(eth.clone(), persistence.clone()); + let settlement_contract_start_index = + if let Some(DeploymentInformation::BlockNumber(settlement_contract_start_index)) = + eth.contracts().settlement().deployment_information() + { + settlement_contract_start_index + } else { + // If the deployment information can't be found, start from 0 (default + // behaviour). For real contracts, the deployment information is specified + // for all the networks, but it isn't specified for the e2e tests which deploy + // the contracts from scratch + tracing::warn!("Settlement contract deployment information not found"); + 0 + }; let settlement_event_indexer = EventUpdater::new( boundary::events::settlement::GPv2SettlementContract::new( eth.contracts().settlement().clone(), ), - boundary::events::settlement::Indexer::new(db.clone(), settlement_observer), + boundary::events::settlement::Indexer::new( + db.clone(), + settlement_observer, + settlement_contract_start_index, + ), block_retriever.clone(), skip_event_sync_start, ); diff --git a/crates/autopilot/src/run_loop.rs b/crates/autopilot/src/run_loop.rs index d1eac70afe..6228d81fcd 100644 --- a/crates/autopilot/src/run_loop.rs +++ b/crates/autopilot/src/run_loop.rs @@ -807,7 +807,7 @@ impl RunLoop { let request = settle::Request { solution_id, submission_deadline_latest_block, - auction_id, + auction_id: None, // Requires 2-stage release for API-break change }; driver .settle(&request, self.config.max_settlement_transaction_wait) diff --git a/crates/autopilot/src/shadow.rs b/crates/autopilot/src/shadow.rs index 44db5bd203..beddd86acc 100644 --- a/crates/autopilot/src/shadow.rs +++ b/crates/autopilot/src/shadow.rs @@ -276,7 +276,7 @@ impl RunLoop { let revealed = driver .reveal(&reveal::Request { solution_id, - auction_id: request.id, + auction_id: None, // Requires 2-stage release for API-break change }) .await .map_err(Error::Reveal)?; diff --git a/crates/contracts/build.rs b/crates/contracts/build.rs index 229922c496..7a6e4369bb 100644 --- a/crates/contracts/build.rs +++ b/crates/contracts/build.rs @@ -860,7 +860,10 @@ fn main() { .add_network_str(GOERLI, "0xE592427A0AEce92De3Edee1F18E0157C05861564") .add_network_str(SEPOLIA, "0xE592427A0AEce92De3Edee1F18E0157C05861564") .add_network_str(ARBITRUM_ONE, "0xE592427A0AEce92De3Edee1F18E0157C05861564") - // Not available on Gnosis Chain and Base + // For Base it is only available SwapRouter02 + // + .add_network_str(BASE, "0x2626664c2603336E57B271c5C0b26F421741e481") + // Not available on Gnosis Chain }); generate_contract("UniswapV3Pool"); generate_contract_with_config("WETH9", |builder| { diff --git a/crates/driver/src/domain/competition/mod.rs b/crates/driver/src/domain/competition/mod.rs index 5fb3cab346..dd3aa06073 100644 --- a/crates/driver/src/domain/competition/mod.rs +++ b/crates/driver/src/domain/competition/mod.rs @@ -267,13 +267,20 @@ impl Competition { Ok(score) } - pub async fn reveal(&self, solution_id: u64, auction_id: i64) -> Result { + pub async fn reveal( + &self, + solution_id: u64, + auction_id: Option, + ) -> Result { let settlement = self .settlements .lock() .unwrap() .iter() - .find(|s| s.solution().get() == solution_id && s.auction_id.0 == auction_id) + .find(|s| { + s.solution().get() == solution_id + && auction_id.is_none_or(|id| s.auction_id.0 == id) + }) .cloned() .ok_or(Error::SolutionNotAvailable)?; Ok(Revealed { @@ -292,7 +299,7 @@ impl Competition { /// [`Competition::solve`] to generate the solution. pub async fn settle( &self, - auction_id: i64, + auction_id: Option, solution_id: u64, submission_deadline: u64, ) -> Result { @@ -300,7 +307,10 @@ impl Competition { let mut lock = self.settlements.lock().unwrap(); let index = lock .iter() - .position(|s| s.solution().get() == solution_id && s.auction_id.0 == auction_id) + .position(|s| { + s.solution().get() == solution_id + && auction_id.is_none_or(|id| s.auction_id.0 == id) + }) .ok_or(Error::SolutionNotAvailable)?; // remove settlement to ensure we can't settle it twice by accident lock.swap_remove_front(index) diff --git a/crates/driver/src/infra/api/routes/reveal/dto/solution.rs b/crates/driver/src/infra/api/routes/reveal/dto/solution.rs index 60e8f564bc..77a80e28b1 100644 --- a/crates/driver/src/infra/api/routes/reveal/dto/solution.rs +++ b/crates/driver/src/infra/api/routes/reveal/dto/solution.rs @@ -2,12 +2,12 @@ use {serde::Deserialize, serde_with::serde_as}; #[serde_as] #[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] +#[serde(rename_all = "camelCase")] pub struct Solution { /// Unique ID of the solution (per driver competition), to reveal. #[serde_as(as = "serde_with::DisplayFromStr")] pub solution_id: u64, /// Auction ID in which the specified solution ID is competing. - #[serde_as(as = "serde_with::DisplayFromStr")] - pub auction_id: i64, + #[serde_as(as = "Option")] + pub auction_id: Option, } diff --git a/crates/driver/src/infra/api/routes/settle/dto/solution.rs b/crates/driver/src/infra/api/routes/settle/dto/solution.rs index ab2a52e2ec..cbe0441ac3 100644 --- a/crates/driver/src/infra/api/routes/settle/dto/solution.rs +++ b/crates/driver/src/infra/api/routes/settle/dto/solution.rs @@ -2,7 +2,7 @@ use {serde::Deserialize, serde_with::serde_as}; #[serde_as] #[derive(Debug, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] +#[serde(rename_all = "camelCase")] pub struct Solution { /// Unique ID of the solution (per driver competition), to settle. #[serde_as(as = "serde_with::DisplayFromStr")] @@ -10,6 +10,6 @@ pub struct Solution { /// The last block number in which the solution TX can be included pub submission_deadline_latest_block: u64, /// Auction ID in which this solution is competing. - #[serde_as(as = "serde_with::DisplayFromStr")] - pub auction_id: i64, + #[serde_as(as = "Option")] + pub auction_id: Option, } diff --git a/crates/shared/src/event_handling.rs b/crates/shared/src/event_handling.rs index 9534e513db..79b846d613 100644 --- a/crates/shared/src/event_handling.rs +++ b/crates/shared/src/event_handling.rs @@ -12,6 +12,7 @@ use { futures::{future, Stream, StreamExt, TryStreamExt}, std::sync::Arc, tokio::sync::Mutex, + tracing::Instrument, }; // We expect that there is never a reorg that changes more than the last n @@ -537,7 +538,12 @@ where S: EventStoring + Send + Sync, { async fn run_maintenance(&self) -> Result<()> { - self.lock().await.update_events().await + let mut inner = self.lock().await; + let address = inner.contract.get_events().filter.address; + inner + .update_events() + .instrument(tracing::info_span!("address", ?address)) + .await } fn name(&self) -> &str {