reth_evm/
either.rs

1//! Helper type that represents one of two possible executor types
2
3use core::fmt::Display;
4
5use crate::{
6    execute::{BatchExecutor, BlockExecutorProvider, Executor},
7    system_calls::OnStateHook,
8};
9use alloc::boxed::Box;
10use alloy_primitives::BlockNumber;
11use reth_prune_types::PruneModes;
12use reth_storage_errors::provider::ProviderError;
13use revm_primitives::db::Database;
14
15// re-export Either
16pub use futures_util::future::Either;
17use revm::State;
18
19impl<A, B> BlockExecutorProvider for Either<A, B>
20where
21    A: BlockExecutorProvider,
22    B: BlockExecutorProvider<Primitives = A::Primitives>,
23{
24    type Primitives = A::Primitives;
25
26    type Executor<DB: Database<Error: Into<ProviderError> + Display>> =
27        Either<A::Executor<DB>, B::Executor<DB>>;
28
29    type BatchExecutor<DB: Database<Error: Into<ProviderError> + Display>> =
30        Either<A::BatchExecutor<DB>, B::BatchExecutor<DB>>;
31
32    fn executor<DB>(&self, db: DB) -> Self::Executor<DB>
33    where
34        DB: Database<Error: Into<ProviderError> + Display>,
35    {
36        match self {
37            Self::Left(a) => Either::Left(a.executor(db)),
38            Self::Right(b) => Either::Right(b.executor(db)),
39        }
40    }
41
42    fn batch_executor<DB>(&self, db: DB) -> Self::BatchExecutor<DB>
43    where
44        DB: Database<Error: Into<ProviderError> + Display>,
45    {
46        match self {
47            Self::Left(a) => Either::Left(a.batch_executor(db)),
48            Self::Right(b) => Either::Right(b.batch_executor(db)),
49        }
50    }
51}
52
53impl<A, B, DB> Executor<DB> for Either<A, B>
54where
55    A: Executor<DB>,
56    B: for<'a> Executor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>,
57    DB: Database<Error: Into<ProviderError> + Display>,
58{
59    type Input<'a> = A::Input<'a>;
60    type Output = A::Output;
61    type Error = A::Error;
62
63    fn init(&mut self, tx_env_overrides: Box<dyn crate::TxEnvOverrides>) {
64        match self {
65            Self::Left(a) => a.init(tx_env_overrides),
66            Self::Right(b) => b.init(tx_env_overrides),
67        }
68    }
69
70    fn execute(self, input: Self::Input<'_>) -> Result<Self::Output, Self::Error> {
71        match self {
72            Self::Left(a) => a.execute(input),
73            Self::Right(b) => b.execute(input),
74        }
75    }
76
77    fn execute_with_state_closure<F>(
78        self,
79        input: Self::Input<'_>,
80        witness: F,
81    ) -> Result<Self::Output, Self::Error>
82    where
83        F: FnMut(&State<DB>),
84    {
85        match self {
86            Self::Left(a) => a.execute_with_state_closure(input, witness),
87            Self::Right(b) => b.execute_with_state_closure(input, witness),
88        }
89    }
90
91    fn execute_with_state_hook<F>(
92        self,
93        input: Self::Input<'_>,
94        state_hook: F,
95    ) -> Result<Self::Output, Self::Error>
96    where
97        F: OnStateHook + 'static,
98    {
99        match self {
100            Self::Left(a) => a.execute_with_state_hook(input, state_hook),
101            Self::Right(b) => b.execute_with_state_hook(input, state_hook),
102        }
103    }
104}
105
106impl<A, B, DB> BatchExecutor<DB> for Either<A, B>
107where
108    A: BatchExecutor<DB>,
109    B: for<'a> BatchExecutor<DB, Input<'a> = A::Input<'a>, Output = A::Output, Error = A::Error>,
110    DB: Database<Error: Into<ProviderError> + Display>,
111{
112    type Input<'a> = A::Input<'a>;
113    type Output = A::Output;
114    type Error = A::Error;
115
116    fn execute_and_verify_one(&mut self, input: Self::Input<'_>) -> Result<(), Self::Error> {
117        match self {
118            Self::Left(a) => a.execute_and_verify_one(input),
119            Self::Right(b) => b.execute_and_verify_one(input),
120        }
121    }
122
123    fn finalize(self) -> Self::Output {
124        match self {
125            Self::Left(a) => a.finalize(),
126            Self::Right(b) => b.finalize(),
127        }
128    }
129
130    fn set_tip(&mut self, tip: BlockNumber) {
131        match self {
132            Self::Left(a) => a.set_tip(tip),
133            Self::Right(b) => b.set_tip(tip),
134        }
135    }
136
137    fn set_prune_modes(&mut self, prune_modes: PruneModes) {
138        match self {
139            Self::Left(a) => a.set_prune_modes(prune_modes),
140            Self::Right(b) => b.set_prune_modes(prune_modes),
141        }
142    }
143
144    fn size_hint(&self) -> Option<usize> {
145        match self {
146            Self::Left(a) => a.size_hint(),
147            Self::Right(b) => b.size_hint(),
148        }
149    }
150}