Skip to content

Commit 4e853d6

Browse files
efbigZanCorDX
andauthored
feat: fail bundles with no exclusive profit after simulation (#808)
## πŸ“ Summary Fail bundles with no exclusive profit after first simulation. ## βœ… I have completed the following steps: * [x] Run `make lint` * [x] Run `make test` * [ ] Added tests (if applicable) --------- Co-authored-by: Daniel Xifra <[email protected]>
1 parent 1c49435 commit 4e853d6

File tree

3 files changed

+37
-14
lines changed

3 files changed

+37
-14
lines changed

β€Žcrates/rbuilder/src/building/builders/ordering_builder.rsβ€Ž

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ use crate::{
1212
block_building_helper::BlockBuildingHelper, BuiltBlockId, LiveBuilderInput,
1313
OrderIntakeConsumer,
1414
},
15-
BlockBuildingContext, ExecutionError, NullPartialBlockExecutionTracer, OrderPriority,
16-
PartialBlockExecutionTracer, PrioritizedOrderStore, SimulatedOrderSink, Sorting,
17-
ThreadBlockBuildingContext,
15+
order_is_worth_executing, BlockBuildingContext, ExecutionError,
16+
NullPartialBlockExecutionTracer, OrderPriority, PartialBlockExecutionTracer,
17+
PrioritizedOrderStore, SimulatedOrderSink, Sorting, ThreadBlockBuildingContext,
1818
},
1919
live_builder::building::built_block_cache::BuiltBlockCache,
2020
provider::StateProviderFactory,
@@ -423,14 +423,17 @@ impl OrderingBuilderContext {
423423
}
424424
Err(err) => {
425425
if let ExecutionError::LowerInsertedValue { inplace, .. } = &err {
426-
// try to reinsert order into the map
427-
let order_attempts = self.order_attempts.entry(sim_order.id()).or_insert(0);
428-
if *order_attempts < self.config.failed_order_retries {
429-
let mut new_order = (*sim_order).clone();
430-
new_order.sim_value = inplace.clone();
431-
block_orders.insert_order(Arc::new(new_order));
432-
*order_attempts += 1;
433-
reinserted = true;
426+
if order_is_worth_executing(inplace).is_ok() {
427+
// try to reinsert order into the map
428+
let order_attempts =
429+
self.order_attempts.entry(sim_order.id()).or_insert(0);
430+
if *order_attempts < self.config.failed_order_retries {
431+
let mut new_order = (*sim_order).clone();
432+
new_order.sim_value = inplace.clone();
433+
block_orders.insert_order(Arc::new(new_order));
434+
*order_attempts += 1;
435+
reinserted = true;
436+
}
434437
}
435438
}
436439
if !reinserted {

β€Žcrates/rbuilder/src/building/order_commit.rsβ€Ž

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use itertools::Itertools;
1818
use rbuilder_primitives::{
1919
evm_inspector::{RBuilderEVMInspector, UsedStateTrace},
2020
BlockSpace, Bundle, Order, OrderId, RefundConfig, ShareBundle, ShareBundleBody,
21-
ShareBundleInner, TransactionSignedEcRecoveredWithBlobs,
21+
ShareBundleInner, SimValue, TransactionSignedEcRecoveredWithBlobs,
2222
};
2323
use reth::{
2424
consensus_common::validation::MAX_RLP_BLOCK_SIZE, revm::database::StateProviderDatabase,
@@ -345,10 +345,27 @@ pub enum OrderErr {
345345
Transaction(#[from] TransactionErr),
346346
#[error("Bundle error: {0}")]
347347
Bundle(#[from] BundleErr),
348+
/// This is not really an error from order execution. We should probably move it away from here.
349+
/// It's used after simulation to reject orders with no exclusive profit (only profit from mempool txs)
350+
#[error("No exclusive profit")]
351+
NoExclusiveProfit,
348352
#[error("Negative profit: {0}")]
349353
NegativeProfit(U256),
350354
}
351355

356+
/// Sometimes we want to reject orders that pass simulation but we think are not going to be good for the block.
357+
pub fn order_is_worth_executing(sim_value: &SimValue) -> Result<(), OrderErr> {
358+
if sim_value
359+
.non_mempool_profit_info()
360+
.coinbase_profit()
361+
.is_zero()
362+
{
363+
Err(OrderErr::NoExclusiveProfit)
364+
} else {
365+
Ok(())
366+
}
367+
}
368+
352369
/// Tracer for PartialBlockFork execution.
353370
/// Passing the NullPartialBlockForkExecutionTracer should have 0 overhead (compiler should optimize it out).
354371
pub trait PartialBlockForkExecutionTracer {

β€Žcrates/rbuilder/src/building/sim.rsβ€Ž

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ use super::{
55
};
66
use crate::{
77
building::{
8-
BlockBuildingContext, BlockBuildingSpaceState, BlockState, CriticalCommitOrderError,
9-
NullPartialBlockForkExecutionTracer,
8+
order_is_worth_executing, BlockBuildingContext, BlockBuildingSpaceState, BlockState,
9+
CriticalCommitOrderError, NullPartialBlockForkExecutionTracer,
1010
},
1111
live_builder::order_input::mempool_txs_detector::MempoolTxsDetector,
1212
provider::StateProviderFactory,
@@ -466,6 +466,9 @@ pub fn simulate_order_using_fork<Tracer: SimulationTracer>(
466466
match result {
467467
Ok(res) => {
468468
let sim_value = create_sim_value(&order, &res, mempool_tx_detector);
469+
if let Err(err) = order_is_worth_executing(&sim_value) {
470+
return Ok(OrderSimResult::Failed(err));
471+
}
469472
let new_nonces = res.nonces_updated.into_iter().collect::<Vec<_>>();
470473
Ok(OrderSimResult::Success(
471474
Arc::new(SimulatedOrder {

0 commit comments

Comments
Β (0)