Skip to content

Commit 5883735

Browse files
authored
Merge branch 'cowprotocol:main' into main
2 parents ba2e2a9 + 5f8ca05 commit 5883735

File tree

92 files changed

+514
-212
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+514
-212
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/autopilot/src/database/ethflow_events/event_retriever.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! A component that listens exclusively for `OrderRefund` events of the ethflow
22
//! contract.
3+
34
use {
45
ethcontract::{H160, H256, contract::AllEventsBuilder, transport::DynTransport},
56
hex_literal::hex,

crates/autopilot/src/database/onchain_order_events/ethflow_events.rs

Lines changed: 15 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use {
2525
},
2626
hex_literal::hex,
2727
sqlx::{PgPool, types::BigDecimal},
28-
std::{collections::HashMap, convert::TryInto, time::Duration},
28+
std::{collections::HashMap, convert::TryInto},
2929
web3::types::U64,
3030
};
3131

@@ -154,7 +154,7 @@ async fn settlement_deployment_block_number_hash(
154154
let block_number = deployment_block(GPv2Settlement::raw_contract(), chain_id)?;
155155
block_number_to_block_number_hash(web3, U64::from(block_number).into())
156156
.await
157-
.ok_or_else(|| anyhow!("Deployment block not found"))
157+
.context("Deployment block not found")
158158
}
159159

160160
/// The block from which to start indexing eth-flow events. Note that this
@@ -241,17 +241,13 @@ pub async fn determine_ethflow_refund_indexing_start(
241241
.expect("Should be able to find a valid start block")
242242
}
243243

244-
/// 1. Check the `last_indexed_blocks` table for the `index_name`. Use the next
245-
/// block as the starting point.
244+
/// 1. Check the `last_indexed_blocks` table for the `index_name`.
246245
/// 2. If no value found or the index is 0, use `fallback_start_block`, if
247246
/// provided.
248247
/// 3. Fallback to the settlement deployment block number, if the `chain_id` is
249248
/// provided.
250249
/// 4. Try to fetch the block number to ensure the node is able to continue
251250
/// indexing.
252-
///
253-
/// Each option except the DB read is retried up to 3 times with a delay of
254-
/// 500ms.
255251
async fn find_indexing_start_block(
256252
db: &PgPool,
257253
web3: &Web3,
@@ -263,65 +259,28 @@ async fn find_indexing_start_block(
263259
.await
264260
.context("failed to read last indexed block from db")?;
265261

266-
let retries = 3;
267-
let retry_delay = Duration::from_millis(500);
268262
if last_indexed_block > 0 {
269-
return retry(
270-
|| async {
271-
block_number_to_block_number_hash(web3, U64::from(last_indexed_block + 1).into())
272-
.await
273-
.map(Some)
274-
.context("failed to fetch block")
275-
},
276-
retries,
277-
retry_delay,
278-
)
279-
.await;
263+
return block_number_to_block_number_hash(web3, U64::from(last_indexed_block).into())
264+
.await
265+
.map(Some)
266+
.context("failed to fetch block");
280267
}
281268
if let Some(start_block) = fallback_start_block {
282-
return retry(
283-
|| async {
284-
block_number_to_block_number_hash(web3, start_block.into())
285-
.await
286-
.map(Some)
287-
.context("failed to fetch fallback indexing start block")
288-
},
289-
retries,
290-
retry_delay,
291-
)
292-
.await;
269+
return block_number_to_block_number_hash(web3, start_block.into())
270+
.await
271+
.map(Some)
272+
.context("failed to fetch fallback indexing start block");
293273
}
294274
if let Some(chain_id) = settlement_fallback_chain_id {
295-
return retry(
296-
|| settlement_deployment_block_number_hash(web3, chain_id),
297-
retries,
298-
retry_delay,
299-
)
300-
.await
301-
.map(Some)
302-
.context("failed to fetch settlement deployment block");
275+
return settlement_deployment_block_number_hash(web3, chain_id)
276+
.await
277+
.map(Some)
278+
.context("failed to fetch settlement deployment block");
303279
}
304280

305281
Ok(None)
306282
}
307283

308-
async fn retry<F, T, E>(mut f: impl FnMut() -> F, retries: usize, delay: Duration) -> Result<T, E>
309-
where
310-
F: Future<Output = Result<T, E>>,
311-
{
312-
let mut attempts = 0;
313-
loop {
314-
match f().await {
315-
Ok(val) => return Ok(val),
316-
Err(_) if attempts < retries => {
317-
attempts += 1;
318-
tokio::time::sleep(delay).await;
319-
}
320-
Err(err) => return Err(err),
321-
}
322-
}
323-
}
324-
325284
#[cfg(test)]
326285
mod test {
327286
use {

crates/autopilot/src/domain/competition/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type SolutionId = u64;
1818

1919
#[derive(Debug, Clone)]
2020
pub struct Solution {
21+
/// A solution ID provided by the solver.
2122
id: SolutionId,
2223
solver: eth::Address,
2324
/// Score reported by the solver in their response.

crates/autopilot/src/domain/competition/winner_selection/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ impl Ranking {
2626
self.ranked.iter().chain(&self.filtered_out)
2727
}
2828

29+
/// Enumerates all solutions. The index is used as solution UID.
30+
pub fn enumerated(&self) -> impl Iterator<Item = (usize, &Participant<Ranked>)> {
31+
self.all().enumerate()
32+
}
33+
2934
/// All solutions that won the right to get executed.
3035
pub fn winners(&self) -> impl Iterator<Item = &Participant<Ranked>> {
3136
self.ranked.iter().filter(|p| p.is_winner())

crates/autopilot/src/domain/settlement/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ impl From<infra::persistence::DatabaseError> for Error {
325325
pub struct ExecutionStarted {
326326
pub auction_id: AuctionId,
327327
pub solver: eth::Address,
328+
pub solution_uid: usize,
328329
pub start_timestamp: DateTime<Utc>,
329330
pub start_block: u64,
330331
pub deadline_block: u64,
@@ -334,6 +335,7 @@ pub struct ExecutionStarted {
334335
pub struct ExecutionEnded {
335336
pub auction_id: AuctionId,
336337
pub solver: eth::Address,
338+
pub solution_uid: usize,
337339
pub end_timestamp: DateTime<Utc>,
338340
pub end_block: u64,
339341
pub outcome: String,

crates/autopilot/src/infra/persistence/mod.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,10 @@ impl Persistence {
823823
&mut ex,
824824
event.auction_id,
825825
ByteArray(event.solver.0.0),
826+
event
827+
.solution_uid
828+
.try_into()
829+
.context("solution uid overflow")?,
826830
event.start_timestamp,
827831
event
828832
.start_block
@@ -852,6 +856,10 @@ impl Persistence {
852856
&mut ex,
853857
event.auction_id,
854858
ByteArray(event.solver.0.0),
859+
event
860+
.solution_uid
861+
.try_into()
862+
.context("solution uid overflow")?,
855863
event.end_timestamp,
856864
event.end_block.try_into().context("end block overflow")?,
857865
event.outcome,

crates/autopilot/src/run.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,11 @@ pub async fn run(args: Arguments) {
388388
.unwrap();
389389

390390
let skip_event_sync_start = if args.skip_event_sync {
391-
block_number_to_block_number_hash(&web3, BlockNumber::Latest).await
391+
Some(
392+
block_number_to_block_number_hash(&web3, BlockNumber::Latest)
393+
.await
394+
.expect("Failed to fetch latest block"),
395+
)
392396
} else {
393397
None
394398
};

crates/autopilot/src/run_loop.rs

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,10 @@ impl RunLoop {
325325
OrderEventLabel::Considered,
326326
);
327327

328-
for winner in ranking.winners() {
328+
for (solution_uid, winner) in ranking
329+
.enumerated()
330+
.filter(|(_, participant)| participant.is_winner())
331+
{
329332
let (driver, solution) = (winner.driver(), winner.solution());
330333
tracing::info!(driver = %driver.name, solution = %solution.id(), "winner");
331334

@@ -334,6 +337,7 @@ impl RunLoop {
334337
single_run_start,
335338
driver,
336339
solution,
340+
solution_uid,
337341
block_deadline,
338342
)
339343
.await;
@@ -349,6 +353,7 @@ impl RunLoop {
349353
single_run_start: Instant,
350354
driver: &Arc<infra::Driver>,
351355
solution: &Solution,
356+
solution_uid: usize,
352357
block_deadline: u64,
353358
) {
354359
let solved_order_uids: HashSet<_> = solution.orders().keys().cloned().collect();
@@ -369,10 +374,11 @@ impl RunLoop {
369374
match self_
370375
.settle(
371376
&driver_,
372-
solution_id,
373377
solved_order_uids.clone(),
374378
solver,
375379
auction_id,
380+
solution_id,
381+
solution_uid,
376382
block_deadline,
377383
)
378384
.await
@@ -457,8 +463,7 @@ impl RunLoop {
457463
}
458464

459465
let mut solutions: Vec<_> = ranking
460-
.all()
461-
.enumerate()
466+
.enumerated()
462467
.map(|(index, participant)| SolverSettlement {
463468
solver: participant.driver().name.clone(),
464469
solver_address: participant.solution().solver().0,
@@ -699,13 +704,15 @@ impl RunLoop {
699704

700705
/// Execute the solver's solution. Returns Ok when the corresponding
701706
/// transaction has been mined.
707+
#[allow(clippy::too_many_arguments)]
702708
async fn settle(
703709
&self,
704710
driver: &infra::Driver,
705-
solution_id: u64,
706711
solved_order_uids: HashSet<OrderUid>,
707712
solver: eth::Address,
708713
auction_id: i64,
714+
solution_id: u64,
715+
solution_uid: usize,
709716
submission_deadline_latest_block: u64,
710717
) -> Result<TxId, SettleError> {
711718
let settle = async move {
@@ -724,6 +731,7 @@ impl RunLoop {
724731
self.store_execution_started(
725732
auction_id,
726733
solver,
734+
solution_uid,
727735
current_block,
728736
submission_deadline_latest_block,
729737
);
@@ -749,7 +757,7 @@ impl RunLoop {
749757
}
750758
};
751759

752-
self.store_execution_ended(solver, auction_id, &result);
760+
self.store_execution_ended(solver, auction_id, solution_uid, &result);
753761

754762
// Clean up the in-flight orders regardless the result.
755763
self.in_flight_orders
@@ -766,6 +774,7 @@ impl RunLoop {
766774
&self,
767775
auction_id: i64,
768776
solver: eth::Address,
777+
solution_uid: usize,
769778
start_block: u64,
770779
deadline_block: u64,
771780
) {
@@ -774,6 +783,7 @@ impl RunLoop {
774783
let execution_started = ExecutionStarted {
775784
auction_id,
776785
solver,
786+
solution_uid,
777787
start_timestamp: chrono::Utc::now(),
778788
start_block,
779789
deadline_block,
@@ -794,6 +804,7 @@ impl RunLoop {
794804
&self,
795805
solver: eth::Address,
796806
auction_id: i64,
807+
solution_uid: usize,
797808
result: &Result<TxId, SettleError>,
798809
) {
799810
let end_timestamp = chrono::Utc::now();
@@ -809,6 +820,7 @@ impl RunLoop {
809820
let execution_ended = ExecutionEnded {
810821
auction_id,
811822
solver,
823+
solution_uid,
812824
end_timestamp,
813825
end_block: current_block,
814826
outcome,

crates/database/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ hex = { workspace = true }
1414
sqlx = { workspace = true }
1515
strum = { workspace = true }
1616
serde_json = { workspace = true }
17+
tracing = { workspace = true }
1718

1819
[dev-dependencies]
1920
maplit = { workspace = true }

0 commit comments

Comments
 (0)