diff --git a/Cargo.lock b/Cargo.lock index 3e28ff094..2f0fc1cbe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9648,6 +9648,7 @@ dependencies = [ "serde_with", "sha2 0.10.9", "ssz_types", + "strum 0.27.2", "thiserror 1.0.69", "time", "tree_hash 0.8.0", diff --git a/crates/rbuilder-primitives/Cargo.toml b/crates/rbuilder-primitives/Cargo.toml index 4fe5c906d..b972ec707 100644 --- a/crates/rbuilder-primitives/Cargo.toml +++ b/crates/rbuilder-primitives/Cargo.toml @@ -50,6 +50,7 @@ eyre.workspace = true serde.workspace = true derive_more.workspace = true serde_json.workspace = true +strum = { version = "0.27.2", features = ["derive"] } [dev-dependencies] alloy-primitives = { workspace = true, features = ["arbitrary"] } diff --git a/crates/rbuilder-primitives/src/ace.rs b/crates/rbuilder-primitives/src/ace.rs new file mode 100644 index 000000000..3f86ea84d --- /dev/null +++ b/crates/rbuilder-primitives/src/ace.rs @@ -0,0 +1,832 @@ +use crate::evm_inspector::{SlotKey, UsedStateTrace}; +use alloy_primitives::{Address, FixedBytes, B256}; +use serde::Deserialize; +use std::collections::HashSet; + +/// 4-byte function selector +pub type Selector = FixedBytes<4>; + +/// Configuration for an ACE (Application Controlled Execution) protocol +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +pub struct AceConfig { + /// The primary contract address for this ACE protocol (used as unique identifier) + pub contract_address: Address, + /// Addresses that send ACE orders (used to identify force unlocks) + pub from_addresses: HashSet
, + /// Addresses that receive ACE orders (the ACE contract addresses) + pub to_addresses: HashSet, + /// Storage slots that must be read to detect ACE interaction (e.g., _lastBlockUpdated at slot 3) + pub detection_slots: HashSet(
ctx: BlockBuildingContext,
available_orders: Vec (
ctx: &BlockBuildingContext,
orders: &[Order],
randomize_insertion: bool,
+ ace_config: Vec {
run_sparse_trie_prefetcher: bool,
order_flow_tracer_manager: Box BlockBuildingPool
@@ -57,6 +59,8 @@ where
order_simulation_pool: OrderSimulationPool ,
run_sparse_trie_prefetcher: bool,
order_flow_tracer_manager: Box LiveBuilder
@@ -231,6 +234,8 @@ where
order_simulation_pool,
self.run_sparse_trie_prefetcher,
self.order_flow_tracer_manager,
+ self.ace_enabled,
+ self.ace_config.clone(),
);
ready_to_build.store(true, Ordering::Relaxed);
diff --git a/crates/rbuilder/src/live_builder/order_flow_tracing/order_flow_tracer.rs b/crates/rbuilder/src/live_builder/order_flow_tracing/order_flow_tracer.rs
index 77cfdc68d..00be23712 100644
--- a/crates/rbuilder/src/live_builder/order_flow_tracing/order_flow_tracer.rs
+++ b/crates/rbuilder/src/live_builder/order_flow_tracing/order_flow_tracer.rs
@@ -79,24 +79,30 @@ impl OrderFlowTracer {
impl SimulationJobTracer for OrderFlowTracer {
fn update_simulation_sent(&self, sim_result: &SimulatedResult) {
+ let SimulatedResult::Success {
+ simulation_time,
+ simulated_order,
+ ..
+ } = sim_result
+ else {
+ // Only Success variants are traced
+ return;
+ };
let event = SimulationEvent::SimulatedOrder(SimulatedOrderData {
- simulation_time: sim_result.simulation_time,
- order_id: sim_result.simulated_order.order.id(),
- replacement_key_and_sequence_number: sim_result
- .simulated_order
+ simulation_time: *simulation_time,
+ order_id: simulated_order.order.id(),
+ replacement_key_and_sequence_number: simulated_order
.order
.replacement_key_and_sequence_number(),
- full_profit: sim_result
- .simulated_order
+ full_profit: simulated_order
.sim_value
.full_profit_info()
.coinbase_profit(),
- non_mempool_profit: sim_result
- .simulated_order
+ non_mempool_profit: simulated_order
.sim_value
.non_mempool_profit_info()
.coinbase_profit(),
- gas_used: sim_result.simulated_order.sim_value.gas_used(),
+ gas_used: simulated_order.sim_value.gas_used(),
});
self.sim_events
.lock()
diff --git a/crates/rbuilder/src/live_builder/simulation/mod.rs b/crates/rbuilder/src/live_builder/simulation/mod.rs
index 1dfa36514..df2e86bf7 100644
--- a/crates/rbuilder/src/live_builder/simulation/mod.rs
+++ b/crates/rbuilder/src/live_builder/simulation/mod.rs
@@ -39,6 +39,10 @@ pub struct SimulationContext {
pub requests: flume::Receiver (
let mut block_state = BlockState::new_arc(state_provider.clone());
let sim_result = simulate_order(
task.parents.clone(),
- task.order,
+ task.order.clone(),
¤t_sim_context.block_ctx,
&mut local_ctx,
&mut block_state,
+ ¤t_sim_context.ace_configs,
+ &task.ace_state,
);
let sim_ok = match sim_result {
Ok(sim_result) => {
let sim_ok = match sim_result.result {
OrderSimResult::Success(simulated_order, nonces_after) => {
- let result = SimulatedResult {
+ let mut dependencies_satisfied: Vec (
}
Err(err) => {
error!(?err, ?order_id, "Critical error while simulating order");
- // @Metric
break;
}
};
diff --git a/crates/rbuilder/src/live_builder/simulation/simulation_job.rs b/crates/rbuilder/src/live_builder/simulation/simulation_job.rs
index 2fc950272..d67e38ded 100644
--- a/crates/rbuilder/src/live_builder/simulation/simulation_job.rs
+++ b/crates/rbuilder/src/live_builder/simulation/simulation_job.rs
@@ -1,7 +1,7 @@
use std::{fmt, sync::Arc};
use crate::{
- building::sim::{SimTree, SimulatedResult, SimulationRequest},
+ building::sim::{SimTree, SimulatedResult, SimulationFailure, SimulationRequest},
live_builder::{
order_input::order_sink::OrderPoolCommand,
simulation::simulation_job_tracer::SimulationJobTracer,
@@ -190,53 +190,77 @@ impl SimulationJob {
&mut self,
new_sim_results: &mut Vec