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

Notifies solver if their solution simulates successfully at least once #2077

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion crates/driver/src/domain/competition/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ impl Competition {
*score_ref = None;
*self.settlement.lock().unwrap() = None;
if let Some(id) = settlement.notify_id() {
notify::simulation_failed(&self.solver, auction.id(), id, &err);
notify::simulation_failed(&self.solver, auction.id(), id, &err, true);
}
return;
}
Expand Down
11 changes: 8 additions & 3 deletions crates/driver/src/infra/notify/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use {

mod notification;

pub use notification::{Kind, Notification, ScoreKind, Settlement};
pub use notification::{Kind, Notification, ScoreKind, Settlement, SimulationSucceededAtLeastOnce};
use {
super::simulator,
crate::domain::{competition::score, eth, mempools::Error},
Expand Down Expand Up @@ -74,7 +74,7 @@ pub fn encoding_failed(
solution::Error::Blockchain(_) => return,
solution::Error::Boundary(_) => return,
solution::Error::Simulation(error) => {
simulation_failed(solver, auction_id, solution_id, error);
simulation_failed(solver, auction_id, solution_id, error, false);
return;
}
solution::Error::Execution(_) => return,
Expand All @@ -90,12 +90,17 @@ pub fn simulation_failed(
auction_id: Option<auction::Id>,
solution_id: solution::Id,
err: &simulator::Error,
succeeded_at_least_once: SimulationSucceededAtLeastOnce,
) {
if let simulator::Error::Revert(error) = err {
solver.notify(
auction_id,
Some(solution_id),
notification::Kind::SimulationFailed(error.block, error.tx.clone()),
notification::Kind::SimulationFailed(
error.block,
error.tx.clone(),
succeeded_at_least_once,
),
);
}
}
Expand Down
6 changes: 4 additions & 2 deletions crates/driver/src/infra/notify/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type RequiredEther = Ether;
type TokensUsed = BTreeSet<TokenAddress>;
type TransactionHash = eth::TxId;
type Transaction = eth::Tx;
pub type SimulationSucceededAtLeastOnce = bool;

/// A notification sent to solvers in case of important events in the driver.
#[derive(Debug)]
Expand All @@ -27,8 +28,9 @@ pub enum Kind {
EmptySolution,
/// Solution received from solver engine don't have unique id.
DuplicatedSolutionId,
/// Failed simulation during competition.
SimulationFailed(eth::BlockNo, Transaction),
/// Failed simulation during competition. Last parameter is true
/// if has simulated at least once.
SimulationFailed(eth::BlockNo, Transaction, SimulationSucceededAtLeastOnce),
/// No valid score could be computed for the solution.
ScoringFailed(ScoreKind),
/// Solution aimed to internalize tokens that are not considered safe to
Expand Down
27 changes: 15 additions & 12 deletions crates/driver/src/infra/solver/dto/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use {
competition::{auction, solution},
eth,
},
infra::notify,
infra::{notify, notify::SimulationSucceededAtLeastOnce},
util::serialize,
},
serde::Serialize,
Expand All @@ -25,16 +25,19 @@ impl Notification {
kind: match kind {
notify::Kind::Timeout => Kind::Timeout,
notify::Kind::EmptySolution => Kind::EmptySolution,
notify::Kind::SimulationFailed(block, tx) => Kind::SimulationFailed(
block.0,
Tx {
from: tx.from.into(),
to: tx.to.into(),
input: tx.input.into(),
value: tx.value.into(),
access_list: tx.access_list.into(),
},
),
notify::Kind::SimulationFailed(block, tx, simulated_once) => {
Kind::SimulationFailed(
block.0,
Tx {
from: tx.from.into(),
to: tx.to.into(),
input: tx.input.into(),
value: tx.value.into(),
access_list: tx.access_list.into(),
},
simulated_once,
)
}
notify::Kind::ScoringFailed(notify::ScoreKind::ZeroScore) => {
Kind::ScoringFailed(ScoreKind::ZeroScore)
}
Expand Down Expand Up @@ -97,7 +100,7 @@ pub enum Kind {
Timeout,
EmptySolution,
DuplicatedSolutionId,
SimulationFailed(BlockNo, Tx),
SimulationFailed(BlockNo, Tx, SimulationSucceededAtLeastOnce),
ScoringFailed(ScoreKind),
NonBufferableTokensUsed {
tokens: BTreeSet<eth::H160>,
Expand Down
4 changes: 3 additions & 1 deletion crates/shared/src/http_solver/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ pub enum AuctionResult {
SubmittedOnchain(SubmissionResult),
}

type SimulationSucceededAtLeastOnce = bool;

#[serde_as]
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
Expand Down Expand Up @@ -450,7 +452,7 @@ pub enum SolverRejectionReason {

/// The solution didn't pass simulation. Includes all data needed to
/// re-create simulation locally
SimulationFailure(TransactionWithError),
SimulationFailure(TransactionWithError, SimulationSucceededAtLeastOnce),

/// The solution doesn't have a positive score. Currently this can happen
/// only if the objective value is negative.
Expand Down
1 change: 1 addition & 0 deletions crates/solver/src/settlement_ranker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ impl SettlementRanker {
transaction: error.simulation.transaction.clone(),
error: error.error.to_string(),
},
false,
)),
);
Some((solver, Rating::Err(error)))
Expand Down
31 changes: 19 additions & 12 deletions crates/solvers/src/api/routes/notify/dto/notification.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use {
crate::{
domain::{auction, eth, notification},
domain::{
auction,
eth,
notification::{self, SimulationSucceededAtLeastOnce},
},
util::serialize,
},
ethereum_types::{H160, H256, U256},
Expand All @@ -22,16 +26,19 @@ impl Notification {
kind: match &self.kind {
Kind::Timeout => notification::Kind::Timeout,
Kind::EmptySolution => notification::Kind::EmptySolution,
Kind::SimulationFailed(block, tx) => notification::Kind::SimulationFailed(
*block,
eth::Tx {
from: tx.from.into(),
to: tx.to.into(),
input: tx.input.clone().into(),
value: tx.value.into(),
access_list: tx.access_list.clone(),
},
),
Kind::SimulationFailed(block, tx, succeeded_at_least_once) => {
notification::Kind::SimulationFailed(
*block,
eth::Tx {
from: tx.from.into(),
to: tx.to.into(),
input: tx.input.clone().into(),
value: tx.value.into(),
access_list: tx.access_list.clone(),
},
*succeeded_at_least_once,
)
}
Kind::ScoringFailed(ScoreKind::ObjectiveValueNonPositive { quality, gas_cost }) => {
notification::Kind::ScoringFailed(
notification::ScoreKind::ObjectiveValueNonPositive(
Expand Down Expand Up @@ -103,7 +110,7 @@ pub enum Kind {
Timeout,
EmptySolution,
DuplicatedSolutionId,
SimulationFailed(BlockNo, Tx),
SimulationFailed(BlockNo, Tx, SimulationSucceededAtLeastOnce),
ScoringFailed(ScoreKind),
NonBufferableTokensUsed {
tokens: BTreeSet<H160>,
Expand Down
33 changes: 18 additions & 15 deletions crates/solvers/src/boundary/legacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,22 +599,25 @@ fn to_boundary_auction_result(notification: &notification::Notification) -> (i64
AuctionResult::Rejected(SolverRejectionReason::RunError(SolverRunError::Timeout))
}
Kind::EmptySolution => AuctionResult::Rejected(SolverRejectionReason::NoUserOrders),
Kind::SimulationFailed(block_number, tx) => AuctionResult::Rejected(
SolverRejectionReason::SimulationFailure(TransactionWithError {
error: "".to_string(),
transaction: SimulatedTransaction {
from: tx.from.into(),
to: tx.to.into(),
data: tx.input.clone().into(),
internalization: InternalizationStrategy::Unknown,
block_number: *block_number,
tx_index: Default::default(),
access_list: Default::default(),
max_fee_per_gas: Default::default(),
max_priority_fee_per_gas: Default::default(),
Kind::SimulationFailed(block_number, tx, succeeded_at_least_once) => {
AuctionResult::Rejected(SolverRejectionReason::SimulationFailure(
TransactionWithError {
error: "".to_string(),
transaction: SimulatedTransaction {
from: tx.from.into(),
to: tx.to.into(),
data: tx.input.clone().into(),
internalization: InternalizationStrategy::Unknown,
block_number: *block_number,
tx_index: Default::default(),
access_list: Default::default(),
max_fee_per_gas: Default::default(),
max_priority_fee_per_gas: Default::default(),
},
},
}),
),
*succeeded_at_least_once,
))
}
Kind::ScoringFailed(ScoreKind::ObjectiveValueNonPositive(quality, gas_cost)) => {
AuctionResult::Rejected(SolverRejectionReason::ObjectiveValueNonPositive {
quality: quality.0,
Expand Down
3 changes: 2 additions & 1 deletion crates/solvers/src/domain/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type TokensUsed = BTreeSet<TokenAddress>;
type TransactionHash = eth::H256;
type Transaction = eth::Tx;
type BlockNo = u64;
pub type SimulationSucceededAtLeastOnce = bool;

/// The notification about important events happened in driver, that solvers
/// need to know about.
Expand All @@ -28,7 +29,7 @@ pub enum Kind {
Timeout,
EmptySolution,
DuplicatedSolutionId,
SimulationFailed(BlockNo, Transaction),
SimulationFailed(BlockNo, Transaction, SimulationSucceededAtLeastOnce),
ScoringFailed(ScoreKind),
NonBufferableTokensUsed(TokensUsed),
SolverAccountInsufficientBalance(RequiredEther),
Expand Down
Loading