Skip to content

Commit 04937bc

Browse files
committed
proper StateProvider life Arc->Box
1 parent f2b86b6 commit 04937bc

23 files changed

Lines changed: 235 additions & 192 deletions

crates/rbuilder/src/backtest/restore_landed_orders/resim_landed_block.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ use eyre::Context;
1616
use rbuilder_primitives::evm_inspector::SlotKey;
1717
use reth_chainspec::ChainSpec;
1818
use reth_primitives::{Receipt, Recovered, TransactionSigned};
19-
use reth_provider::StateProvider;
2019
use std::sync::Arc;
2120

2221
#[derive(Debug)]
@@ -69,11 +68,10 @@ where
6968

7069
let mut local_ctx = ThreadBlockBuildingContext::default();
7170

72-
let state_provider: Arc<dyn StateProvider + Send + Sync> =
73-
crate::provider::shared_state_provider(
74-
provider.history_by_block_hash(ctx.attributes.parent)?,
75-
);
76-
let cached = CachedDB::new(state_provider, ctx.shared_cached_reads.clone());
71+
let cached = CachedDB::new(
72+
provider.history_by_block_hash(ctx.attributes.parent)?,
73+
ctx.shared_cached_reads.clone(),
74+
);
7775
let mut partial_block = PartialBlock::new(true);
7876
let mut state = BlockState::new(cached);
7977

crates/rbuilder/src/bin/debug-bench-machine.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,9 @@ async fn main() -> eyre::Result<()> {
103103
mev_blocker_price,
104104
);
105105

106-
let state_provider = rbuilder::provider::shared_state_provider(
107-
provider_factory
108-
.provider_factory_unchecked()
109-
.history_by_block_number(last_block)?,
106+
let source = rbuilder::provider::StateProviderSource::new(
107+
Arc::new(provider_factory.clone()),
108+
parent_num_hash.hash,
110109
);
111110

112111
let mut build_times_ms = Vec::new();
@@ -121,11 +120,12 @@ async fn main() -> eyre::Result<()> {
121120
.into_iter()
122121
.collect();
123122
let txs = txs.clone();
124-
let state_provider = state_provider.clone();
123+
let source = source.clone();
125124
let (build_time, finalize_time) =
126125
tokio::task::spawn_blocking(move || -> eyre::Result<_> {
127126
let mut partial_block = PartialBlock::new(true);
128-
let cached = CachedDB::new(state_provider, ctx.shared_cached_reads.clone());
127+
let cached =
128+
CachedDB::new(source.state_provider()?, ctx.shared_cached_reads.clone());
129129
let mut state = BlockState::new(cached);
130130
let mut local_ctx = ThreadBlockBuildingContext::default();
131131

crates/rbuilder/src/bin/run-bundle-on-prefix.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use rbuilder::{
2020
OrderPriority, ThreadBlockBuildingContext,
2121
},
2222
live_builder::{cli::LiveBuilderConfig, config::Config},
23-
provider::StateProviderFactory,
2423
utils::{extract_onchain_block_txs, find_suggested_fee_recipient},
2524
};
2625
use rbuilder_config::load_toml_config;
@@ -156,14 +155,13 @@ impl LandedBlockInfo {
156155
.config
157156
.base_config()
158157
.create_reth_provider_factory(true)?;
159-
let block_state = rbuilder::provider::shared_state_provider(
160-
provider.history_by_block_hash(ctx.attributes.parent)?,
161-
);
158+
let source =
159+
rbuilder::provider::StateProviderSource::new(Arc::new(provider), ctx.attributes.parent);
162160
let order_statistics = OrderStatistics::new();
163161
Ok(BlockBuildingHelperFromProvider::new(
164162
BuiltBlockId::ZERO,
165163
0,
166-
block_state,
164+
source,
167165
ctx,
168166
"TEST".to_string(),
169167
false,
@@ -225,7 +223,7 @@ async fn main() -> eyre::Result<()> {
225223
// Test backruns after prefix.
226224
println!("Backruns after prefix");
227225
for sim_order in sim_orders {
228-
let mut builder = builder.box_clone();
226+
let mut builder = builder.try_clone()?;
229227
let res = builder.commit_order(&mut block_info.local_ctx, &sim_order, &|sim_result| {
230228
simulation_too_low::<OrderMaxProfitPriority<FullProfitInfoGetter>>(
231229
&sim_order.sim_value,

crates/rbuilder/src/building/builders/block_building_helper.rs

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use alloy_primitives::{utils::format_ether, Address, TxHash, I256, U256};
2-
use reth_provider::StateProvider;
32
use std::{
43
cmp::max,
5-
sync::Arc,
64
time::{Duration, Instant},
75
};
86
use time::OffsetDateTime;
@@ -20,6 +18,7 @@ use crate::{
2018
ThreadBlockBuildingContext,
2119
},
2220
live_builder::block_output::bidding_service_interface::CompetitionBidContext,
21+
provider::StateProviderSource,
2322
telemetry::{self, add_block_fill_time, add_order_simulation_time},
2423
utils::{check_block_hash_reader_health, elapsed_ms, HistoricalBlockError},
2524
};
@@ -37,8 +36,9 @@ use super::Block;
3736
/// 2 - Call lots of commit_order.
3837
/// 3 - Call set_trace_fill_time when you are done calling commit_order (we still have to review this step).
3938
/// 4 - Call finalize_block.
40-
pub trait BlockBuildingHelper: Send + Sync {
41-
fn box_clone(&self) -> Box<dyn BlockBuildingHelper>;
39+
pub trait BlockBuildingHelper: Send {
40+
/// Clones the helper, reopening its state provider. Fallible because reopening can fail.
41+
fn try_clone(&self) -> Result<Box<dyn BlockBuildingHelper>, BlockBuildingHelperError>;
4242

4343
/// Tries to add an order to the end of the block.
4444
/// Block state changes only on Ok(Ok)
@@ -112,16 +112,6 @@ pub struct BiddableUnfinishedBlock {
112112
pub chosen_as_best_at: OffsetDateTime,
113113
}
114114

115-
impl Clone for BiddableUnfinishedBlock {
116-
fn clone(&self) -> Self {
117-
Self {
118-
block: self.block.box_clone(),
119-
true_block_value: self.true_block_value,
120-
chosen_as_best_at: self.chosen_as_best_at,
121-
}
122-
}
123-
}
124-
125115
impl BiddableUnfinishedBlock {
126116
pub fn new(block: Box<dyn BlockBuildingHelper>) -> Result<Self, BlockBuildingHelperError> {
127117
let true_block_value = block.true_block_value()?;
@@ -131,6 +121,16 @@ impl BiddableUnfinishedBlock {
131121
chosen_as_best_at: OffsetDateTime::now_utc(),
132122
})
133123
}
124+
125+
/// Clones the block by reopening the underlying state provider. Fallible because reopening the
126+
/// provider can fail.
127+
pub fn try_clone(&self) -> Result<Self, BlockBuildingHelperError> {
128+
Ok(Self {
129+
block: self.block.try_clone()?,
130+
true_block_value: self.true_block_value,
131+
chosen_as_best_at: self.chosen_as_best_at,
132+
})
133+
}
134134
pub fn id(&self) -> BuiltBlockId {
135135
self.block.id()
136136
}
@@ -145,12 +145,13 @@ impl BiddableUnfinishedBlock {
145145
}
146146

147147
/// Implementation of BlockBuildingHelper based on a generic Provider
148-
#[derive(Clone)]
149148
pub struct BlockBuildingHelperFromProvider<
150149
PartialBlockExecutionTracerType: PartialBlockExecutionTracer + Clone + Send + Sync + 'static,
151150
> {
152151
/// Balance of fee recipient before we stared building.
153152
_fee_recipient_balance_start: U256,
153+
/// Reopens a fresh state provider when the helper is cloned for bidding/finalization.
154+
source: StateProviderSource,
154155
/// Accumulated changes for the block (due to commit_order calls).
155156
block_state: BlockState<CachedDB>,
156157
partial_block: PartialBlock<GasUsedSimulationTracer, PartialBlockExecutionTracerType>,
@@ -215,7 +216,7 @@ impl BlockBuildingHelperFromProvider<NullPartialBlockExecutionTracer> {
215216
pub fn new(
216217
built_block_id: BuiltBlockId,
217218
next_journal_sequence_number: JournalSequenceNumber,
218-
state_provider: Arc<dyn StateProvider + Send + Sync>,
219+
state_provider_source: StateProviderSource,
219220
building_ctx: BlockBuildingContext,
220221
builder_name: String,
221222
discard_txs: bool,
@@ -226,7 +227,7 @@ impl BlockBuildingHelperFromProvider<NullPartialBlockExecutionTracer> {
226227
BlockBuildingHelperFromProvider::new_with_execution_tracer(
227228
built_block_id,
228229
next_journal_sequence_number,
229-
state_provider,
230+
state_provider_source,
230231
building_ctx,
231232
builder_name,
232233
discard_txs,
@@ -251,7 +252,7 @@ impl<
251252
pub fn new_with_execution_tracer(
252253
built_block_id: BuiltBlockId,
253254
next_journal_sequence_number: JournalSequenceNumber,
254-
state_provider: Arc<dyn StateProvider + Send + Sync>,
255+
state_provider_source: StateProviderSource,
255256
building_ctx: BlockBuildingContext,
256257
builder_name: String,
257258
discard_txs: bool,
@@ -260,6 +261,7 @@ impl<
260261
partial_block_execution_tracer: PartialBlockExecutionTracerType,
261262
max_order_execution_duration_warning: Option<Duration>,
262263
) -> Result<Self, BlockBuildingHelperError> {
264+
let state_provider = state_provider_source.state_provider()?;
263265
let last_committed_block = building_ctx.block() - 1;
264266
check_block_hash_reader_health(last_committed_block, &state_provider)?;
265267

@@ -288,6 +290,7 @@ impl<
288290
built_block_trace.available_orders_statistics = available_orders_statistics;
289291
Ok(Self {
290292
_fee_recipient_balance_start: fee_recipient_balance_start,
293+
source: state_provider_source,
291294
block_state,
292295
partial_block,
293296
payout_tx_gas,
@@ -621,8 +624,27 @@ impl<
621624
&self.building_ctx
622625
}
623626

624-
fn box_clone(&self) -> Box<dyn BlockBuildingHelper> {
625-
Box::new(self.clone())
627+
fn try_clone(&self) -> Result<Box<dyn BlockBuildingHelper>, BlockBuildingHelperError> {
628+
let state_provider = self.source.state_provider()?;
629+
let cached = CachedDB::new(
630+
state_provider,
631+
self.building_ctx.shared_cached_reads.clone(),
632+
);
633+
let block_state =
634+
BlockState::new(cached).with_bundle_state(self.block_state.clone_bundle());
635+
Ok(Box::new(Self {
636+
_fee_recipient_balance_start: self._fee_recipient_balance_start,
637+
source: self.source.clone(),
638+
block_state,
639+
partial_block: self.partial_block.clone(),
640+
payout_tx_gas: self.payout_tx_gas,
641+
builder_name: self.builder_name.clone(),
642+
building_ctx: self.building_ctx.clone(),
643+
built_block_trace: self.built_block_trace.clone(),
644+
cancel_on_fatal_error: self.cancel_on_fatal_error.clone(),
645+
finalize_adjustment_state: self.finalize_adjustment_state.clone(),
646+
max_order_execution_duration_warning: self.max_order_execution_duration_warning,
647+
}))
626648
}
627649

628650
fn builder_name(&self) -> &str {

crates/rbuilder/src/building/builders/block_building_helper_stats_logger.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ impl<'a> BlockBuildingHelperStatsLogger<'a> {
160160

161161
impl BlockBuildingHelper for BlockBuildingHelperStatsLogger<'_> {
162162
/// logging is not cloned
163-
fn box_clone(&self) -> Box<dyn BlockBuildingHelper> {
164-
self.block_building_helper.box_clone()
163+
fn try_clone(&self) -> Result<Box<dyn BlockBuildingHelper>, BlockBuildingHelperError> {
164+
self.block_building_helper.try_clone()
165165
}
166166

167167
fn commit_order(

crates/rbuilder/src/building/builders/mock_block_building_helper.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ impl MockBlockBuildingHelper {
5959
}
6060

6161
impl BlockBuildingHelper for MockBlockBuildingHelper {
62-
fn box_clone(&self) -> Box<dyn BlockBuildingHelper> {
63-
Box::new(self.clone())
62+
fn try_clone(&self) -> Result<Box<dyn BlockBuildingHelper>, BlockBuildingHelperError> {
63+
Ok(Box::new(self.clone()))
6464
}
6565

6666
fn commit_order(

crates/rbuilder/src/building/builders/ordering_builder.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::{
2121
block_output::bidding_service_interface::CompetitionBidContext,
2222
building::built_block_cache::BuiltBlockCache,
2323
},
24-
provider::StateProviderFactory,
24+
provider::{StateProviderFactory, StateProviderSource},
2525
telemetry::{
2626
add_ordering_builder_base_stage_stats, add_ordering_builder_pre_filtered_stage_stats,
2727
mark_builder_considers_order, OrderInclusionRatio,
@@ -32,7 +32,6 @@ use ahash::{HashMap, HashSet};
3232
use alloy_primitives::I256;
3333
use derivative::Derivative;
3434
use rbuilder_primitives::{AccountNonce, OrderId, SimValue, SimulatedOrder};
35-
use reth_provider::StateProvider;
3635
use serde::Deserialize;
3736
use std::{
3837
marker::PhantomData,
@@ -95,11 +94,12 @@ pub fn run_ordering_builder<P, OrderPriorityType>(
9594
{
9695
let payload_id = input.ctx.payload_id;
9796

98-
let block_state: Arc<dyn StateProvider + Send + Sync> = match input
99-
.provider
100-
.history_by_block_hash(input.ctx.attributes.parent)
101-
{
102-
Ok(state) => crate::provider::shared_state_provider(state),
97+
let source = StateProviderSource::new(
98+
Arc::new(input.provider.clone()),
99+
input.ctx.attributes.parent,
100+
);
101+
let state_provider = match source.state_provider() {
102+
Ok(state_provider) => state_provider,
103103
Err(err) => {
104104
error!(
105105
?err,
@@ -111,13 +111,13 @@ pub fn run_ordering_builder<P, OrderPriorityType>(
111111
}
112112
};
113113

114-
let nonces = NonceCache::new(block_state.clone());
114+
let nonces = NonceCache::new(state_provider);
115115

116116
let mut order_intake_consumer =
117117
OrderIntakeConsumer::<OrderPriorityType>::new(nonces, input.input);
118118

119119
let mut builder = OrderingBuilderContext::new(
120-
block_state.clone(),
120+
source,
121121
input.builder_name,
122122
input.ctx,
123123
config.clone(),
@@ -156,7 +156,9 @@ pub fn run_ordering_builder<P, OrderPriorityType>(
156156
) {
157157
Ok(block) => {
158158
if let Ok(block) = BiddableUnfinishedBlock::new(block) {
159-
input.sink.new_block(block);
159+
if let Err(err) = input.sink.new_block(block) {
160+
error!(?err, payload_id, "Failed to submit unfinished block");
161+
}
160162
}
161163
}
162164
Err(err) => {
@@ -190,8 +192,12 @@ where
190192
let block_orders =
191193
block_orders_from_sim_orders::<OrderPriorityType>(input.sim_orders, &state_provider)?;
192194
let mut local_ctx = ThreadBlockBuildingContext::default();
195+
let source = StateProviderSource::new(
196+
Arc::new(input.provider.clone()),
197+
input.ctx.attributes.parent,
198+
);
193199
let mut builder = OrderingBuilderContext::new(
194-
crate::provider::shared_state_provider(state_provider),
200+
source,
195201
input.builder_name,
196202
input.ctx.clone(),
197203
ordering_config,
@@ -220,7 +226,7 @@ where
220226
#[derivative(Debug)]
221227
pub struct OrderingBuilderContext {
222228
#[derivative(Debug = "ignore")]
223-
state: Arc<dyn StateProvider + Send + Sync>,
229+
source: StateProviderSource,
224230
builder_name: String,
225231
ctx: BlockBuildingContext,
226232
config: OrderingBuilderConfig,
@@ -238,15 +244,15 @@ pub struct OrderingBuilderContext {
238244

239245
impl OrderingBuilderContext {
240246
pub fn new(
241-
state: Arc<dyn StateProvider + Send + Sync>,
247+
source: StateProviderSource,
242248
builder_name: String,
243249
ctx: BlockBuildingContext,
244250
config: OrderingBuilderConfig,
245251
max_order_execution_duration_warning: Option<Duration>,
246252
built_block_cache: Arc<BuiltBlockCache>,
247253
) -> Self {
248254
Self {
249-
state,
255+
source,
250256
builder_name,
251257
ctx,
252258
local_ctx: Default::default(),
@@ -301,7 +307,7 @@ impl OrderingBuilderContext {
301307
let mut block_building_helper = BlockBuildingHelperFromProvider::new_with_execution_tracer(
302308
built_block_id,
303309
next_journal_sequence_number,
304-
self.state.clone(),
310+
self.source.clone(),
305311
self.ctx.clone(),
306312
self.builder_name.clone(),
307313
self.config.discard_txs,

0 commit comments

Comments
 (0)