Skip to content

Commit ee63c7d

Browse files
authored
refactor: simplify rpc state provider traits (#19920)
1 parent 1702107 commit ee63c7d

File tree

9 files changed

+90
-224
lines changed

9 files changed

+90
-224
lines changed

crates/optimism/rpc/src/eth/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ impl<N, Rpc> Trace for OpEthApi<N, Rpc>
332332
where
333333
N: RpcNodeCore,
334334
OpEthApiError: FromEvmError<N::Evm>,
335-
Rpc: RpcConvert<Primitives = N::Primitives>,
335+
Rpc: RpcConvert<Primitives = N::Primitives, Error = OpEthApiError, Evm = N::Evm>,
336336
{
337337
}
338338

crates/rpc/rpc-eth-api/src/helpers/call.rs

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ use reth_primitives_traits::Recovered;
2828
use reth_revm::{database::StateProviderDatabase, db::State};
2929
use reth_rpc_convert::{RpcConvert, RpcTxReq};
3030
use reth_rpc_eth_types::{
31-
cache::db::{StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
31+
cache::db::StateProviderTraitObjWrapper,
3232
error::FromEthApiError,
3333
simulate::{self, EthSimulateError},
3434
EthApiError, StateCacheDb,
3535
};
36-
use reth_storage_api::{BlockIdReader, ProviderTx};
36+
use reth_storage_api::{BlockIdReader, ProviderTx, StateProvider};
3737
use revm::{
3838
context::Block,
3939
context_interface::{result::ResultAndState, Transaction},
@@ -89,10 +89,7 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
8989
self.recovered_block(block).await?.ok_or(EthApiError::HeaderNotFound(block))?;
9090
let mut parent = base_block.sealed_header().clone();
9191

92-
let this = self.clone();
93-
self.spawn_with_state_at_block(block, move |state| {
94-
let mut db =
95-
State::builder().with_database(StateProviderDatabase::new(state)).build();
92+
self.spawn_with_state_at_block(block, move |this, mut db| {
9693
let mut blocks: Vec<SimulatedBlock<RpcBlock<Self::NetworkTypes>>> =
9794
Vec::with_capacity(block_state_calls.len());
9895
for block in block_state_calls {
@@ -277,11 +274,8 @@ pub trait EthCall: EstimateCall + Call + LoadPendingBlock + LoadBlock + FullEthA
277274
replay_block_txs = false;
278275
}
279276

280-
let this = self.clone();
281-
self.spawn_with_state_at_block(at.into(), move |state| {
277+
self.spawn_with_state_at_block(at, move |this, mut db| {
282278
let mut all_results = Vec::with_capacity(bundles.len());
283-
let mut db =
284-
State::builder().with_database(StateProviderDatabase::new(state)).build();
285279

286280
if replay_block_txs {
287281
// only need to replay the transactions in the block if not all transactions are
@@ -487,13 +481,11 @@ pub trait Call:
487481
) -> impl Future<Output = Result<R, Self::Error>> + Send
488482
where
489483
R: Send + 'static,
490-
F: FnOnce(Self, StateProviderTraitObjWrapper<'_>) -> Result<R, Self::Error>
491-
+ Send
492-
+ 'static,
484+
F: FnOnce(Self, &dyn StateProvider) -> Result<R, Self::Error> + Send + 'static,
493485
{
494486
self.spawn_blocking_io_fut(move |this| async move {
495487
let state = this.state_at_block_id(at).await?;
496-
f(this, StateProviderTraitObjWrapper(&state))
488+
f(this, &state)
497489
})
498490
}
499491

@@ -552,16 +544,20 @@ pub trait Call:
552544
/// Executes the closure with the state that corresponds to the given [`BlockId`] on a new task
553545
fn spawn_with_state_at_block<F, R>(
554546
&self,
555-
at: BlockId,
547+
at: impl Into<BlockId>,
556548
f: F,
557549
) -> impl Future<Output = Result<R, Self::Error>> + Send
558550
where
559-
F: FnOnce(StateProviderTraitObjWrapper<'_>) -> Result<R, Self::Error> + Send + 'static,
551+
F: FnOnce(Self, StateCacheDb) -> Result<R, Self::Error> + Send + 'static,
560552
R: Send + 'static,
561553
{
554+
let at = at.into();
562555
self.spawn_blocking_io_fut(move |this| async move {
563556
let state = this.state_at_block_id(at).await?;
564-
f(StateProviderTraitObjWrapper(&state))
557+
let db = State::builder()
558+
.with_database(StateProviderDatabase::new(StateProviderTraitObjWrapper(state)))
559+
.build();
560+
f(this, db)
565561
})
566562
}
567563

@@ -590,7 +586,7 @@ pub trait Call:
590586
where
591587
Self: LoadPendingBlock,
592588
F: FnOnce(
593-
StateCacheDbRefMutWrapper<'_, '_>,
589+
&mut StateCacheDb,
594590
EvmEnvFor<Self::Evm>,
595591
TxEnvFor<Self::Evm>,
596592
) -> Result<R, Self::Error>
@@ -600,17 +596,11 @@ pub trait Call:
600596
{
601597
async move {
602598
let (evm_env, at) = self.evm_env_at(at).await?;
603-
let this = self.clone();
604-
self.spawn_blocking_io_fut(move |_| async move {
605-
let state = this.state_at_block_id(at).await?;
606-
let mut db = State::builder()
607-
.with_database(StateProviderDatabase::new(StateProviderTraitObjWrapper(&state)))
608-
.build();
609-
599+
self.spawn_with_state_at_block(at, move |this, mut db| {
610600
let (evm_env, tx_env) =
611601
this.prepare_call_env(evm_env, request, &mut db, overrides)?;
612602

613-
f(StateCacheDbRefMutWrapper(&mut db), evm_env, tx_env)
603+
f(&mut db, evm_env, tx_env)
614604
})
615605
.await
616606
}
@@ -635,7 +625,7 @@ pub trait Call:
635625
F: FnOnce(
636626
TransactionInfo,
637627
ResultAndState<HaltReasonFor<Self::Evm>>,
638-
StateCacheDb<'_>,
628+
StateCacheDb,
639629
) -> Result<R, Self::Error>
640630
+ Send
641631
+ 'static,
@@ -654,10 +644,7 @@ pub trait Call:
654644
// block the transaction is included in
655645
let parent_block = block.parent_hash();
656646

657-
let this = self.clone();
658-
self.spawn_with_state_at_block(parent_block.into(), move |state| {
659-
let mut db =
660-
State::builder().with_database(StateProviderDatabase::new(state)).build();
647+
self.spawn_with_state_at_block(parent_block, move |this, mut db| {
661648
let block_txs = block.transactions_recovered();
662649

663650
// replay all transactions prior to the targeted transaction

crates/rpc/rpc-eth-api/src/helpers/trace.rs

Lines changed: 22 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! Loads a pending block from database. Helper trait for `eth_` call and trace RPC methods.
22
3-
use super::{Call, LoadBlock, LoadPendingBlock, LoadState, LoadTransaction};
3+
use super::{Call, LoadBlock, LoadState, LoadTransaction};
44
use crate::FromEvmError;
55
use alloy_consensus::{transaction::TxHashRef, BlockHeader};
66
use alloy_primitives::B256;
@@ -14,17 +14,14 @@ use reth_evm::{
1414
};
1515
use reth_primitives_traits::{BlockBody, Recovered, RecoveredBlock};
1616
use reth_revm::{database::StateProviderDatabase, db::State};
17-
use reth_rpc_eth_types::{
18-
cache::db::{StateCacheDb, StateCacheDbRefMutWrapper, StateProviderTraitObjWrapper},
19-
EthApiError,
20-
};
17+
use reth_rpc_eth_types::{cache::db::StateCacheDb, EthApiError};
2118
use reth_storage_api::{ProviderBlock, ProviderTx};
2219
use revm::{context::Block, context_interface::result::ResultAndState, DatabaseCommit};
2320
use revm_inspectors::tracing::{TracingInspector, TracingInspectorConfig};
2421
use std::sync::Arc;
2522

2623
/// Executes CPU heavy tasks.
27-
pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
24+
pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> + Call {
2825
/// Executes the [`TxEnvFor`] with [`reth_evm::EvmEnv`] against the given [Database] without
2926
/// committing state changes.
3027
fn inspect<DB, I>(
@@ -58,7 +55,6 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
5855
f: F,
5956
) -> impl Future<Output = Result<R, Self::Error>> + Send
6057
where
61-
Self: Call,
6258
R: Send + 'static,
6359
F: FnOnce(
6460
TracingInspector,
@@ -91,19 +87,16 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
9187
f: F,
9288
) -> impl Future<Output = Result<R, Self::Error>> + Send
9389
where
94-
Self: LoadPendingBlock + Call,
9590
F: FnOnce(
9691
TracingInspector,
9792
ResultAndState<HaltReasonFor<Self::Evm>>,
98-
StateCacheDb<'_>,
93+
StateCacheDb,
9994
) -> Result<R, Self::Error>
10095
+ Send
10196
+ 'static,
10297
R: Send + 'static,
10398
{
104-
let this = self.clone();
105-
self.spawn_with_state_at_block(at, move |state| {
106-
let mut db = State::builder().with_database(StateProviderDatabase::new(state)).build();
99+
self.spawn_with_state_at_block(at, move |this, mut db| {
107100
let mut inspector = TracingInspector::new(config);
108101
let res = this.inspect(&mut db, evm_env, tx_env, &mut inspector)?;
109102
f(inspector, res, db)
@@ -126,12 +119,12 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
126119
f: F,
127120
) -> impl Future<Output = Result<Option<R>, Self::Error>> + Send
128121
where
129-
Self: LoadPendingBlock + LoadTransaction + Call,
122+
Self: LoadTransaction,
130123
F: FnOnce(
131124
TransactionInfo,
132125
TracingInspector,
133126
ResultAndState<HaltReasonFor<Self::Evm>>,
134-
StateCacheDb<'_>,
127+
StateCacheDb,
135128
) -> Result<R, Self::Error>
136129
+ Send
137130
+ 'static,
@@ -156,17 +149,16 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
156149
f: F,
157150
) -> impl Future<Output = Result<Option<R>, Self::Error>> + Send
158151
where
159-
Self: LoadPendingBlock + LoadTransaction + Call,
152+
Self: LoadTransaction,
160153
F: FnOnce(
161154
TransactionInfo,
162155
Insp,
163156
ResultAndState<HaltReasonFor<Self::Evm>>,
164-
StateCacheDb<'_>,
157+
StateCacheDb,
165158
) -> Result<R, Self::Error>
166159
+ Send
167160
+ 'static,
168-
Insp:
169-
for<'a, 'b> InspectorFor<Self::Evm, StateCacheDbRefMutWrapper<'a, 'b>> + Send + 'static,
161+
Insp: for<'a> InspectorFor<Self::Evm, &'a mut StateCacheDb> + Send + 'static,
170162
R: Send + 'static,
171163
{
172164
async move {
@@ -182,10 +174,7 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
182174
// block the transaction is included in
183175
let parent_block = block.parent_hash();
184176

185-
let this = self.clone();
186-
self.spawn_with_state_at_block(parent_block.into(), move |state| {
187-
let mut db =
188-
State::builder().with_database(StateProviderDatabase::new(state)).build();
177+
self.spawn_with_state_at_block(parent_block, move |this, mut db| {
189178
let block_txs = block.transactions_recovered();
190179

191180
this.apply_pre_execution_changes(&block, &mut db, &evm_env)?;
@@ -194,12 +183,7 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
194183
this.replay_transactions_until(&mut db, evm_env.clone(), block_txs, *tx.tx_hash())?;
195184

196185
let tx_env = this.evm_config().tx_env(tx);
197-
let res = this.inspect(
198-
StateCacheDbRefMutWrapper(&mut db),
199-
evm_env,
200-
tx_env,
201-
&mut inspector,
202-
)?;
186+
let res = this.inspect(&mut db, evm_env, tx_env, &mut inspector)?;
203187
f(tx_info, inspector, res, db)
204188
})
205189
.await
@@ -228,7 +212,7 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
228212
TracingCtx<
229213
'_,
230214
Recovered<&ProviderTx<Self::Provider>>,
231-
EvmFor<Self::Evm, StateCacheDbRefMutWrapper<'_, '_>, TracingInspector>,
215+
EvmFor<Self::Evm, &mut StateCacheDb, TracingInspector>,
232216
>,
233217
) -> Result<R, Self::Error>
234218
+ Send
@@ -269,13 +253,13 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
269253
TracingCtx<
270254
'_,
271255
Recovered<&ProviderTx<Self::Provider>>,
272-
EvmFor<Self::Evm, StateCacheDbRefMutWrapper<'_, '_>, Insp>,
256+
EvmFor<Self::Evm, &mut StateCacheDb, Insp>,
273257
>,
274258
) -> Result<R, Self::Error>
275259
+ Send
276260
+ 'static,
277261
Setup: FnMut() -> Insp + Send + 'static,
278-
Insp: Clone + for<'a, 'b> InspectorFor<Self::Evm, StateCacheDbRefMutWrapper<'a, 'b>>,
262+
Insp: Clone + for<'a> InspectorFor<Self::Evm, &'a mut StateCacheDb>,
279263
R: Send + 'static,
280264
{
281265
async move {
@@ -296,21 +280,14 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
296280
}
297281

298282
// replay all transactions of the block
299-
self.spawn_blocking_io_fut(move |this| async move {
300-
// we need to get the state of the parent block because we're replaying this block
301-
// on top of its parent block's state
302-
let state_at = block.parent_hash();
283+
// we need to get the state of the parent block because we're replaying this block
284+
// on top of its parent block's state
285+
self.spawn_with_state_at_block(block.parent_hash(), move |this, mut db| {
303286
let block_hash = block.hash();
304287

305288
let block_number = evm_env.block_env.number().saturating_to();
306289
let base_fee = evm_env.block_env.basefee();
307290

308-
// now get the state
309-
let state = this.state_at_block_id(state_at.into()).await?;
310-
let mut db = State::builder()
311-
.with_database(StateProviderDatabase::new(StateProviderTraitObjWrapper(&state)))
312-
.build();
313-
314291
this.apply_pre_execution_changes(&block, &mut db, &evm_env)?;
315292

316293
// prepare transactions, we do everything upfront to reduce time spent with open
@@ -328,7 +305,7 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
328305
let results = this
329306
.evm_config()
330307
.evm_factory()
331-
.create_tracer(StateCacheDbRefMutWrapper(&mut db), evm_env, inspector_setup())
308+
.create_tracer(&mut db, evm_env, inspector_setup())
332309
.try_trace_many(block.transactions_recovered().take(max_transactions), |ctx| {
333310
let tx_info = TransactionInfo {
334311
hash: Some(*ctx.tx.tx_hash()),
@@ -375,7 +352,7 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
375352
TracingCtx<
376353
'_,
377354
Recovered<&ProviderTx<Self::Provider>>,
378-
EvmFor<Self::Evm, StateCacheDbRefMutWrapper<'_, '_>, TracingInspector>,
355+
EvmFor<Self::Evm, &mut StateCacheDb, TracingInspector>,
379356
>,
380357
) -> Result<R, Self::Error>
381358
+ Send
@@ -415,13 +392,13 @@ pub trait Trace: LoadState<Error: FromEvmError<Self::Evm>> {
415392
TracingCtx<
416393
'_,
417394
Recovered<&ProviderTx<Self::Provider>>,
418-
EvmFor<Self::Evm, StateCacheDbRefMutWrapper<'_, '_>, Insp>,
395+
EvmFor<Self::Evm, &mut StateCacheDb, Insp>,
419396
>,
420397
) -> Result<R, Self::Error>
421398
+ Send
422399
+ 'static,
423400
Setup: FnMut() -> Insp + Send + 'static,
424-
Insp: Clone + for<'a, 'b> InspectorFor<Self::Evm, StateCacheDbRefMutWrapper<'a, 'b>>,
401+
Insp: Clone + for<'a> InspectorFor<Self::Evm, &'a mut StateCacheDb>,
425402
R: Send + 'static,
426403
{
427404
self.trace_block_until_with_inspector(block_id, block, None, insp_setup, f)

0 commit comments

Comments
 (0)