Skip to content

new OrderStatistics logs #639

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

Merged
merged 1 commit into from
Jun 4, 2025
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
10 changes: 8 additions & 2 deletions crates/rbuilder/src/bin/dummy-builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ use rbuilder::{
LiveBuilder,
},
mev_boost::RelayClient,
primitives::{mev_boost::MevBoostRelaySlotInfoProvider, SimulatedOrder},
primitives::{
mev_boost::MevBoostRelaySlotInfoProvider, order_statistics::OrderStatistics, SimulatedOrder,
},
provider::StateProviderFactory,
utils::{ProviderFactoryReopener, Signer},
};
Expand Down Expand Up @@ -213,13 +215,17 @@ impl DummyBuildingAlgorithm {
let block_state = provider
.history_by_block_hash(ctx.attributes.parent)?
.into();

let mut order_statistics = OrderStatistics::new();
for sim_order in &orders {
order_statistics.add(&sim_order.order);
}
let mut block_building_helper = BlockBuildingHelperFromProvider::new(
block_state,
ctx.clone(),
&mut local_ctx,
BUILDER_NAME.to_string(),
false,
order_statistics,
CancellationToken::new(),
)?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use alloy_primitives::Address;
use priority_queue::PriorityQueue;

use crate::{
primitives::{AccountNonce, Nonce, OrderId, SimulatedOrder},
primitives::{order_statistics::OrderStatistics, AccountNonce, Nonce, OrderId, SimulatedOrder},
telemetry::mark_order_not_ready_for_immediate_inclusion,
};

Expand Down Expand Up @@ -39,6 +39,8 @@ pub struct PrioritizedOrderStore<OrderPriorityType> {
pending_orders: HashMap<AccountNonce, Vec<OrderId>>,
/// Id -> order for all orders we manage. Carefully maintained by remove/insert
orders: HashMap<OrderId, Arc<SimulatedOrder>>,
/// Everything in orders
orders_statistics: OrderStatistics,
}

impl<OrderPriorityType: OrderPriority> PrioritizedOrderStore<OrderPriorityType> {
Expand All @@ -53,9 +55,14 @@ impl<OrderPriorityType: OrderPriority> PrioritizedOrderStore<OrderPriorityType>
onchain_nonces,
pending_orders: HashMap::default(),
orders: HashMap::default(),
orders_statistics: Default::default(),
}
}

pub fn orders_statistics(&self) -> OrderStatistics {
self.orders_statistics.clone()
}

pub fn pop_order(&mut self) -> Option<Arc<SimulatedOrder>> {
let (id, _) = self.main_queue.pop()?;

Expand All @@ -67,7 +74,7 @@ impl<OrderPriorityType: OrderPriority> PrioritizedOrderStore<OrderPriorityType>

/// Clean up after some order was removed from main_queue
fn remove_poped_order(&mut self, id: &OrderId) -> Option<Arc<SimulatedOrder>> {
let sim_order = self.orders.remove(id)?;
let sim_order = self.remove_from_orders(id)?;
for Nonce { address, .. } in sim_order.order.nonces() {
match self.main_queue_nonces.entry(address) {
Entry::Occupied(mut entry) => {
Expand Down Expand Up @@ -135,7 +142,7 @@ impl<OrderPriorityType: OrderPriority> PrioritizedOrderStore<OrderPriorityType>
if let Some(pending) = self.pending_orders.remove(new_nonce) {
let orders = pending
.iter()
.filter_map(|id| self.orders.remove(id))
.filter_map(|id| self.remove_from_orders(id))
.collect::<Vec<_>>();
for order in orders {
self.insert_order(order);
Expand All @@ -147,6 +154,15 @@ impl<OrderPriorityType: OrderPriority> PrioritizedOrderStore<OrderPriorityType>
pub fn get_all_orders(&self) -> Vec<Arc<SimulatedOrder>> {
self.orders.values().cloned().collect()
}

/// Removes from self.orders and updates statistics
fn remove_from_orders(&mut self, id: &OrderId) -> Option<Arc<SimulatedOrder>> {
let res = self.orders.remove(id);
if let Some(sim_order) = &res {
self.orders_statistics.remove(&sim_order.order);
}
res
}
}

impl<OrderPriorityType: OrderPriority> SimulatedOrderSink
Expand Down Expand Up @@ -196,6 +212,8 @@ impl<OrderPriorityType: OrderPriority> SimulatedOrderSink
}
}
}
self.orders_statistics.add(&sim_order.order);
// We don't check the result to update orders_statistics since we already checked !self.orders.contains_key
self.orders.insert(sim_order.id(), sim_order);
}

Expand All @@ -204,6 +222,6 @@ impl<OrderPriorityType: OrderPriority> SimulatedOrderSink
if self.main_queue.remove(&id).is_some() {
self.remove_poped_order(&id);
}
self.orders.remove(&id)
self.remove_from_orders(&id)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
EstimatePayoutGasErr, ExecutionError, ExecutionResult, FinalizeError, FinalizeResult,
PartialBlock, ThreadBlockBuildingContext,
},
primitives::{SimValue, SimulatedOrder},
primitives::{order_statistics::OrderStatistics, SimValue, SimulatedOrder},
telemetry::{self, add_block_fill_time, add_order_simulation_time},
utils::{check_block_hash_reader_health, elapsed_ms, HistoricalBlockError},
};
Expand Down Expand Up @@ -192,6 +192,7 @@ impl BlockBuildingHelperFromProvider {
local_ctx: &mut ThreadBlockBuildingContext,
builder_name: String,
discard_txs: bool,
available_orders_statistics: OrderStatistics,
cancel_on_fatal_error: CancellationToken,
) -> Result<Self, BlockBuildingHelperError> {
let last_committed_block = building_ctx.block() - 1;
Expand Down Expand Up @@ -220,14 +221,16 @@ impl BlockBuildingHelperFromProvider {
Some(payout_tx_gas)
};

let mut built_block_trace = BuiltBlockTrace::new();
built_block_trace.available_orders_statistics = available_orders_statistics;
Ok(Self {
_fee_recipient_balance_start: fee_recipient_balance_start,
block_state,
partial_block,
payout_tx_gas,
builder_name,
building_ctx,
built_block_trace: BuiltBlockTrace::new(),
built_block_trace,
cancel_on_fatal_error,
})
}
Expand Down Expand Up @@ -338,6 +341,7 @@ impl BlockBuildingHelper for BlockBuildingHelperFromProvider {
order: &SimulatedOrder,
result_filter: &dyn Fn(&SimValue) -> Result<(), ExecutionError>,
) -> Result<Result<&ExecutionResult, ExecutionError>, CriticalCommitOrderError> {
self.built_block_trace.add_considered_order(order);
let start = Instant::now();
let result = self.partial_block.commit_order(
order,
Expand All @@ -359,6 +363,7 @@ impl BlockBuildingHelper for BlockBuildingHelperFromProvider {
Err(err) => {
self.built_block_trace
.modify_payment_when_no_signer_error(&err);
self.built_block_trace.add_failed_order(order);
(Ok(Err(err)), false)
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ impl OrderingBuilderContext {
&mut self.local_ctx,
self.builder_name.clone(),
self.config.discard_txs,
block_orders.orders_statistics(),
cancel_block,
)?;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{
},
BlockBuildingContext, ThreadBlockBuildingContext,
},
primitives::order_statistics::OrderStatistics,
telemetry::mark_builder_considers_order,
utils::elapsed_ms,
};
Expand Down Expand Up @@ -200,6 +201,7 @@ impl BlockBuildingResultAssembler {
&mut self.local_ctx,
self.builder_name.clone(),
self.discard_txs,
OrderStatistics::default(),
self.cancellation_token.clone(),
)?;
block_building_helper.set_trace_orders_closed_at(orders_closed_at);
Expand Down Expand Up @@ -272,6 +274,7 @@ impl BlockBuildingResultAssembler {
&mut self.local_ctx,
String::from("backtest_builder"),
self.discard_txs,
OrderStatistics::default(),
CancellationToken::new(),
)?;

Expand Down
25 changes: 23 additions & 2 deletions crates/rbuilder/src/building/built_block_trace.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use super::{BundleErr, ExecutionError, ExecutionResult, OrderErr};
use crate::primitives::{Order, OrderId, OrderReplacementKey};
use crate::primitives::{
order_statistics::OrderStatistics, Order, OrderId, OrderReplacementKey, SimulatedOrder,
};
use ahash::{AHasher, HashMap, HashSet};
use alloy_primitives::{Address, TxHash, U256};
use std::{collections::hash_map, hash::Hasher, time::Duration};
Expand All @@ -8,7 +10,7 @@ use time::OffsetDateTime;
/// Structs for recording data about a built block, such as what bundles were included, and where txs came from.
/// Trace can be used to verify bundle invariants.

#[derive(Debug, Clone, PartialEq, Eq)]
#[derive(Debug, Clone)]
pub struct BuiltBlockTrace {
pub included_orders: Vec<ExecutionResult>,
/// How much we bid (pay to the validator)
Expand All @@ -28,6 +30,12 @@ pub struct BuiltBlockTrace {
pub root_hash_time: Duration,
/// Value we saw in the competition when we decided to make this bid.
pub seen_competition_bid: Option<U256>,
/// Orders we had available to build the block (we might have not use all of them because of timeouts)
pub available_orders_statistics: OrderStatistics,
/// Every call to BlockBuildingHelper::commit_order impacts here.
pub considered_orders_statistics: OrderStatistics,
/// Anything we call BlockBuildingHelper::commit_order on but didn't include (redundant with considered_orders_statistics-included_orders)
pub failed_orders_statistics: OrderStatistics,
}

impl Default for BuiltBlockTrace {
Expand Down Expand Up @@ -62,6 +70,9 @@ impl BuiltBlockTrace {
finalize_time: Duration::from_secs(0),
root_hash_time: Duration::from_secs(0),
seen_competition_bid: None,
considered_orders_statistics: Default::default(),
failed_orders_statistics: Default::default(),
available_orders_statistics: Default::default(),
}
}

Expand All @@ -77,6 +88,16 @@ impl BuiltBlockTrace {
self.included_orders.push(execution_result);
}

/// Call before commit_order
pub fn add_considered_order(&mut self, sim_order: &SimulatedOrder) {
self.considered_orders_statistics.add(&sim_order.order);
}

/// Call after a commit_order Err
pub fn add_failed_order(&mut self, sim_order: &SimulatedOrder) {
self.failed_orders_statistics.add(&sim_order.order);
}

/// Call after a commit_order error
pub fn modify_payment_when_no_signer_error(&mut self, err: &ExecutionError) {
if let ExecutionError::OrderError(OrderErr::Bundle(BundleErr::NoSigner)) = err {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ async fn run_submit_to_relays_job(
);
info!(
parent: &submission_span,
available_orders_statistics = ?block.trace.available_orders_statistics,
considered_orders_statistics = ?block.trace.considered_orders_statistics,
failed_orders_statistics = ?block.trace.failed_orders_statistics,
"Submitting bid",
);
let relay_filter = get_relay_filter_and_update_metrics(
Expand Down
1 change: 1 addition & 0 deletions crates/rbuilder/src/primitives/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub mod fmt;
pub mod mev_boost;
pub mod order_builder;
pub mod order_statistics;
pub mod serialize;
mod test_data_generator;

Expand Down
31 changes: 31 additions & 0 deletions crates/rbuilder/src/primitives/order_statistics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::primitives::Order;

/// Simple struct to count orders by type.
#[derive(Clone, Debug, Default)]
pub struct OrderStatistics {
tx_count: i32,
bundle_count: i32,
sbundle_count: i32,
}

impl OrderStatistics {
pub fn new() -> Self {
Self::default()
}

pub fn add(&mut self, order: &Order) {
match order {
Order::Bundle(_) => self.tx_count += 1,
Order::Tx(_) => self.bundle_count += 1,
Order::ShareBundle(_) => self.sbundle_count += 1,
}
}

pub fn remove(&mut self, order: &Order) {
match order {
Order::Bundle(_) => self.tx_count -= 1,
Order::Tx(_) => self.bundle_count -= 1,
Order::ShareBundle(_) => self.sbundle_count -= 1,
}
}
}
Loading