Skip to content

Commit 272f12d

Browse files
committed
wire new pu orderpool to simulation
1 parent 82add9a commit 272f12d

6 files changed

Lines changed: 95 additions & 141 deletions

File tree

crates/rbuilder/src/building/priority_update/priority_update_pool.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,13 @@ impl PriorityUpdateIngressOrderpool {
8282
pub fn subscribe(
8383
&self,
8484
block_number: u64,
85-
) -> Option<ReplaceEventSchedulerSubscription<Uuid, Option<Arc<Order>>>> {
85+
) -> ReplaceEventSchedulerSubscription<Uuid, Option<Arc<Order>>> {
8686
let mut inner = self.inner.write();
87-
if block_number <= inner.last_block {
88-
return None;
89-
}
90-
Some(
91-
inner
92-
.pools_for_block
93-
.entry(block_number)
94-
.or_default()
95-
.subscribe(),
96-
)
87+
inner
88+
.pools_for_block
89+
.entry(block_number)
90+
.or_default()
91+
.subscribe()
9792
}
9893

9994
pub fn head_updated(&self, new_block_number: u64) {

crates/rbuilder/src/building/priority_update/pur_simulation_job.rs

Lines changed: 52 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
use std::sync::Arc;
22

3-
use ahash::HashSet;
3+
use ahash::HashMap;
44
use parking_lot::Mutex;
5-
use rbuilder_primitives::{OrderId, SimulatedOrder};
5+
use rbuilder_primitives::{Order, OrderId, SimulatedOrder};
6+
use rbuilder_utils::replace_event_scheduler::ReplaceEventSchedulerSubscription;
67
use reth_provider::StateProvider;
7-
use tokio::sync::mpsc::{self, error::TryRecvError};
8+
use tokio::sync::mpsc;
89
use tokio_util::sync::CancellationToken;
910
use tracing::{error, trace};
11+
use uuid::Uuid;
1012

1113
use crate::{
1214
building::{BlockBuildingContext, ThreadBlockBuildingContext},
13-
live_builder::{
14-
order_input::order_sink::OrderPoolCommand,
15-
simulation::{simulation_job_tracer::SimulationJobTracer, SimulatedOrderCommand},
16-
},
15+
live_builder::simulation::{simulation_job_tracer::SimulationJobTracer, SimulatedOrderCommand},
1716
provider::StateProviderFactory,
1817
};
1918

@@ -23,67 +22,9 @@ use super::{simulate::simulate_priority_update, PriorityUpdatePool};
2322
/// [`PUSimulationContext::subscribe`]. Matches the builder pipeline channel.
2423
const PU_SUBSCRIBER_CHANNEL_CAPACITY: usize = 10_000;
2524

26-
/// Upper bound on PU messages a sim worker drains per call to
27-
/// [`PUSimWorkerOrderpool::consume_updates`].
25+
/// Upper bound on PU updates a sim worker drains per loop iteration.
2826
const PU_BATCH_DRAIN_LIMIT: usize = 256;
2927

30-
#[derive(Debug)]
31-
struct ClassifierInner {
32-
cmd_sender: mpsc::UnboundedSender<OrderPoolCommand>,
33-
tracked_orders: Mutex<HashSet<OrderId>>,
34-
}
35-
36-
/// Classifier shared with [`SimulationJob`]: PU-classified commands are
37-
/// forwarded to the PUR sim thread and swallowed from the main pipeline.
38-
#[derive(Clone, Debug)]
39-
pub struct PURCommandClassifier {
40-
inner: Arc<ClassifierInner>,
41-
}
42-
43-
/// Receiver side handed to the PUR sim thread.
44-
pub struct PURSimulationInput {
45-
cmd_receiver: mpsc::UnboundedReceiver<OrderPoolCommand>,
46-
}
47-
48-
pub fn new_pur_simulation_channel() -> (PURCommandClassifier, PURSimulationInput) {
49-
let (cmd_sender, cmd_receiver) = mpsc::unbounded_channel();
50-
let classifier = PURCommandClassifier {
51-
inner: Arc::new(ClassifierInner {
52-
cmd_sender,
53-
tracked_orders: Mutex::new(HashSet::default()),
54-
}),
55-
};
56-
let input = PURSimulationInput { cmd_receiver };
57-
(classifier, input)
58-
}
59-
60-
impl PURCommandClassifier {
61-
pub fn try_consuming_new_order_command(&self, cmd: &OrderPoolCommand) -> bool {
62-
match cmd {
63-
OrderPoolCommand::Insert(order) => {
64-
if order.metadata().priority_update_data.is_none() {
65-
return false;
66-
}
67-
self.inner.tracked_orders.lock().insert(order.id());
68-
let _ = self
69-
.inner
70-
.cmd_sender
71-
.send(OrderPoolCommand::Insert(Arc::clone(order)));
72-
true
73-
}
74-
OrderPoolCommand::Remove(id) => {
75-
let known = self.inner.tracked_orders.lock().remove(id);
76-
if known {
77-
let _ = self.inner.cmd_sender.send(OrderPoolCommand::Remove(*id));
78-
true
79-
} else {
80-
false
81-
}
82-
}
83-
}
84-
}
85-
}
86-
8728
/// Shared inner state of the priority-update pool plus the fan-out subscriber
8829
/// list.
8930
#[derive(Debug)]
@@ -139,7 +80,8 @@ impl PUSimWorkerOrderpool {
13980
Ok(SimulatedOrderCommand::Cancellation(id)) => {
14081
pool.apply_remove(&id);
14182
}
142-
Err(TryRecvError::Empty) | Err(TryRecvError::Disconnected) => break,
83+
Err(mpsc::error::TryRecvError::Empty)
84+
| Err(mpsc::error::TryRecvError::Disconnected) => break,
14385
}
14486
}
14587
}
@@ -196,10 +138,11 @@ pub fn new_pu_simulation_runtime(
196138
)
197139
}
198140

141+
/// Drives the priority-update simulation thread for one block.
199142
pub async fn run_pur_sim_worker<P>(
200143
provider: P,
201144
block_ctx: BlockBuildingContext,
202-
input: PURSimulationInput,
145+
subscription: ReplaceEventSchedulerSubscription<Uuid, Option<Arc<Order>>>,
203146
state: PUSimulationWorkerState,
204147
block_cancellation: CancellationToken,
205148
sim_tracer: Arc<dyn SimulationJobTracer>,
@@ -215,72 +158,86 @@ pub async fn run_pur_sim_worker<P>(
215158
}
216159
};
217160

218-
let PURSimulationInput { mut cmd_receiver } = input;
219-
220161
let mut local_ctx = ThreadBlockBuildingContext::default();
162+
let mut active: HashMap<Uuid, OrderId> = HashMap::default();
163+
let mut buf: Vec<(Uuid, Option<Arc<Order>>)> = Vec::new();
221164

222165
loop {
166+
buf.clear();
167+
subscription.pop_unprocessed_events(PU_BATCH_DRAIN_LIMIT, &mut buf);
168+
for (uuid, maybe_order) in buf.drain(..) {
169+
process_event(
170+
uuid,
171+
maybe_order,
172+
&block_ctx,
173+
&mut local_ctx,
174+
&parent_state,
175+
&state,
176+
&sim_tracer,
177+
&mut active,
178+
)
179+
.await;
180+
}
181+
223182
tokio::select! {
224183
_ = block_cancellation.cancelled() => return,
225-
maybe_cmd = cmd_receiver.recv() => {
226-
let Some(cmd) = maybe_cmd else { return; };
227-
process_command(
228-
cmd,
229-
&block_ctx,
230-
&mut local_ctx,
231-
&parent_state,
232-
&state,
233-
&sim_tracer,
234-
)
235-
.await;
236-
}
184+
_ = subscription.notified() => {}
237185
}
238186
}
239187
}
240188

241-
async fn process_command(
242-
cmd: OrderPoolCommand,
189+
#[allow(clippy::too_many_arguments)]
190+
async fn process_event(
191+
uuid: Uuid,
192+
maybe_order: Option<Arc<Order>>,
243193
block_ctx: &BlockBuildingContext,
244194
local_ctx: &mut ThreadBlockBuildingContext,
245195
parent_state: &Arc<dyn StateProvider>,
246196
state: &PUSimulationWorkerState,
247197
sim_tracer: &Arc<dyn SimulationJobTracer>,
198+
active: &mut HashMap<Uuid, OrderId>,
248199
) {
249-
match cmd {
250-
OrderPoolCommand::Insert(order) => {
200+
match maybe_order {
201+
Some(order) => {
251202
let order_id = order.id();
252-
253203
let sim_res = simulate_priority_update(
254204
Arc::clone(&order),
255205
block_ctx,
256206
local_ctx,
257207
Arc::clone(parent_state),
258208
);
259-
260209
let simulated_order = match sim_res {
261210
Ok(Some(res)) => {
262-
trace!(?order_id, success = true, "PU simulated");
211+
trace!(?order_id, ?uuid, success = true, "PU simulated");
263212
res
264213
}
265214
Ok(None) => {
266-
trace!(?order_id, success = false, "PU simulated");
215+
trace!(?order_id, ?uuid, success = false, "PU simulated");
267216
return;
268217
}
269218
Err(err) => {
270-
trace!(?order_id, success = false, ?err, "PU simulated");
219+
trace!(?order_id, ?uuid, success = false, ?err, "PU simulated");
271220
return;
272221
}
273222
};
274223

224+
// New version supersedes the old: drop the previous OrderId for this uuid first.
225+
if let Some(prev_id) = active.remove(&uuid) {
226+
state.apply_remove(prev_id).await;
227+
sim_tracer.update_cancellation_sent(&prev_id);
228+
}
275229
let evicted = state.apply_update(Arc::clone(&simulated_order)).await;
276230
for evicted_id in &evicted {
277231
trace!(order_id = ?evicted_id, reason = "conflicting", "PU removed");
278232
}
233+
active.insert(uuid, order_id);
279234
}
280-
OrderPoolCommand::Remove(order_id) => {
281-
trace!(?order_id, reason = "cancelled", "PU removed");
282-
state.apply_remove(order_id).await;
283-
sim_tracer.update_cancellation_sent(&order_id);
235+
None => {
236+
if let Some(prev_id) = active.remove(&uuid) {
237+
trace!(order_id = ?prev_id, ?uuid, reason = "cancelled", "PU removed");
238+
state.apply_remove(prev_id).await;
239+
sim_tracer.update_cancellation_sent(&prev_id);
240+
}
284241
}
285242
}
286243
}

crates/rbuilder/src/live_builder/mod.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ where
238238
let (header_sender, header_receiver) = mpsc::channel(CLEAN_TASKS_CHANNEL_SIZE);
239239

240240
let mempool_detector = self.mempool_detector.clone();
241-
let orderpool_subscriber = {
242-
let (handle, sub) = start_orderpool_jobs(
241+
let (orderpool_subscriber, priority_update_pool) = {
242+
let (handle, sub, pu_pool) = start_orderpool_jobs(
243243
self.order_input_config,
244244
self.provider.clone(),
245245
self.extra_rpc,
@@ -252,14 +252,15 @@ where
252252
)
253253
.await?;
254254
inner_jobs_handles.push(handle);
255-
sub
255+
(sub, pu_pool)
256256
};
257257

258258
let order_simulation_pool = OrderSimulationPool::new(
259259
self.provider.clone(),
260260
self.simulation_threads,
261261
self.simulation_use_random_coinbase,
262262
self.global_cancellation.clone(),
263+
priority_update_pool,
263264
);
264265

265266
let mut builder_pool = BlockBuildingPool::new(

crates/rbuilder/src/live_builder/order_input/mod.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,11 @@ pub async fn start_orderpool_jobs<P>(
256256
header_receiver: mpsc::Receiver<Header>,
257257
mempool_detector: Arc<mempool_txs_detector::MempoolTxsDetector>,
258258
priority_update_rules: Arc<Vec<PriorityUpdateRule>>,
259-
) -> eyre::Result<(JoinHandle<()>, OrderPoolSubscriber)>
259+
) -> eyre::Result<(
260+
JoinHandle<()>,
261+
OrderPoolSubscriber,
262+
PriorityUpdateIngressOrderpool,
263+
)>
260264
where
261265
P: StateProviderFactory + 'static,
262266
{
@@ -387,7 +391,7 @@ where
387391
info!("OrderPoolJobs: finished");
388392
});
389393

390-
Ok((handle, subscriber))
394+
Ok((handle, subscriber, priority_update_pool))
391395
}
392396

393397
pub fn expand_path(path: &Path) -> eyre::Result<PathBuf> {

0 commit comments

Comments
 (0)