1#![doc(
10 html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png",
11 html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256",
12 issue_tracker_base_url = "https://github.com/SeismicSystems/seismic-reth/issues/"
13)]
14#![cfg_attr(not(test), warn(unused_crate_dependencies))]
15#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
16#![cfg_attr(not(feature = "std"), no_std)]
17
18extern crate alloc;
19
20use crate::builder::RethEvmBuilder;
21use alloy_consensus::{transaction::TxSeismicElements, BlockHeader as _, TxSeismic};
22use alloy_primitives::{Address, Bytes, TxHash, B256, U256};
23use reth_enclave::{EnclaveError, SchnorrkelKeypair};
24use reth_primitives_traits::BlockHeader;
25use revm::{seismic::RngContainer, Database, Evm, GetInspector};
26use revm_primitives::{
27 BlockEnv, CfgEnvWithHandlerCfg, EVMError, EVMResultGeneric, Env, EnvWithHandlerCfg, SpecId,
28 TxEnv,
29};
30
31pub mod builder;
32pub mod either;
33pub mod execute;
34#[cfg(feature = "std")]
35pub mod metrics;
36pub mod noop;
37pub mod provider;
38pub mod state_change;
39pub mod system_calls;
40#[cfg(any(test, feature = "test-utils"))]
41pub mod test_utils;
43
44#[auto_impl::auto_impl(&, Arc)]
46pub trait ConfigureEvm: ConfigureEvmEnv {
47 type DefaultExternalContext<'a>;
49
50 fn evm<DB: Database>(&self, db: DB) -> Evm<'_, Self::DefaultExternalContext<'_>, DB> {
56 RethEvmBuilder::new(db, self.default_external_context()).build()
57 }
58
59 fn evm_with_env<DB: Database>(
64 &self,
65 db: DB,
66 env: EnvWithHandlerCfg,
67 ) -> Evm<'_, Self::DefaultExternalContext<'_>, DB> {
68 let mut evm = self.evm(db);
69 evm.modify_spec_id(env.spec_id());
70
71 if env.spec_id() == SpecId::MERCURY {
73 let keypair = match self.get_eph_rng_keypair() {
74 Ok(kp) => kp,
75 Err(err) => {
76 panic!("Failed to get ephemeral RNG keypair: {err:?}");
77 }
78 };
79 evm.context.evm = evm.context.evm.with_rng_container(RngContainer::new(keypair));
80 }
81
82 evm.context.evm.env = env.env;
83 evm
84 }
85
86 fn evm_with_env_and_inspector<DB, I>(
93 &self,
94 db: DB,
95 env: EnvWithHandlerCfg,
96 inspector: I,
97 ) -> Evm<'_, I, DB>
98 where
99 DB: Database,
100 I: GetInspector<DB>,
101 {
102 let mut evm = self.evm_with_inspector(db, inspector);
103 evm.modify_spec_id(env.spec_id());
104 evm.context.evm.env = env.env;
105 evm
106 }
107
108 fn evm_with_inspector<DB, I>(&self, db: DB, inspector: I) -> Evm<'_, I, DB>
114 where
115 DB: Database,
116 I: GetInspector<DB>,
117 {
118 RethEvmBuilder::new(db, self.default_external_context()).build_with_inspector(inspector)
119 }
120
121 fn default_external_context<'a>(&self) -> Self::DefaultExternalContext<'a>;
123}
124
125#[auto_impl::auto_impl(&, Arc)]
130pub trait ConfigureEvmEnv: Send + Sync + Unpin + Clone + 'static {
131 type Header: BlockHeader;
133
134 type Transaction;
136
137 type Error: core::error::Error + Send + Sync;
139
140 fn encrypt(
142 &self,
143 _data: &Bytes,
144 _seismic_elements: &TxSeismicElements,
145 ) -> EVMResultGeneric<Bytes, EnclaveError>;
146
147 fn decrypt(
149 &self,
150 _data: &Bytes,
151 _seismic_elements: &TxSeismicElements,
152 ) -> EVMResultGeneric<Bytes, EnclaveError>;
153
154 fn get_eph_rng_keypair(&self) -> EVMResultGeneric<SchnorrkelKeypair, EnclaveError>;
156
157 fn fill_seismic_tx_env(
159 &self,
160 _tx_env: &mut TxEnv,
161 _tx: &TxSeismic,
162 _sender: Address,
163 _tx_hash: TxHash,
164 ) -> EVMResultGeneric<(), EnclaveError> {
165 Err(EVMError::Database(EnclaveError::DecryptionError))
166 }
167
168 fn tx_env(
170 &self,
171 transaction: &Self::Transaction,
172 signer: Address,
173 ) -> EVMResultGeneric<TxEnv, EnclaveError> {
174 let mut tx_env = TxEnv::default();
175 self.fill_tx_env(&mut tx_env, transaction, signer)?;
176 Ok(tx_env)
177 }
178
179 fn fill_tx_env(
181 &self,
182 tx_env: &mut TxEnv,
183 transaction: &Self::Transaction,
184 sender: Address,
185 ) -> EVMResultGeneric<(), EnclaveError>;
186
187 fn fill_tx_env_system_contract_call(
189 &self,
190 env: &mut Env,
191 caller: Address,
192 contract: Address,
193 data: Bytes,
194 );
195
196 fn cfg_env(&self, header: &Self::Header, total_difficulty: U256) -> CfgEnvWithHandlerCfg {
198 let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default());
199 self.fill_cfg_env(&mut cfg, header, total_difficulty);
200 cfg
201 }
202
203 fn fill_cfg_env(
208 &self,
209 cfg_env: &mut CfgEnvWithHandlerCfg,
210 header: &Self::Header,
211 total_difficulty: U256,
212 );
213
214 fn fill_block_env(&self, block_env: &mut BlockEnv, header: &Self::Header, after_merge: bool) {
216 block_env.number = U256::from(header.number());
217 block_env.coinbase = header.beneficiary();
218 block_env.timestamp = U256::from(header.timestamp());
219 if after_merge {
220 block_env.prevrandao = header.mix_hash();
221 block_env.difficulty = U256::ZERO;
222 } else {
223 block_env.difficulty = header.difficulty();
224 block_env.prevrandao = None;
225 }
226 block_env.basefee = U256::from(header.base_fee_per_gas().unwrap_or_default());
227 block_env.gas_limit = U256::from(header.gas_limit());
228
229 if let Some(excess_blob_gas) = header.excess_blob_gas() {
231 block_env.set_blob_excess_gas_and_price(excess_blob_gas);
232 }
233 }
234
235 fn cfg_and_block_env(
237 &self,
238 header: &Self::Header,
239 total_difficulty: U256,
240 ) -> (CfgEnvWithHandlerCfg, BlockEnv) {
241 let mut cfg = CfgEnvWithHandlerCfg::new(Default::default(), Default::default());
242 let mut block_env = BlockEnv::default();
243 self.fill_cfg_and_block_env(&mut cfg, &mut block_env, header, total_difficulty);
244 (cfg, block_env)
245 }
246
247 fn fill_cfg_and_block_env(
252 &self,
253 cfg: &mut CfgEnvWithHandlerCfg,
254 block_env: &mut BlockEnv,
255 header: &Self::Header,
256 total_difficulty: U256,
257 ) {
258 self.fill_cfg_env(cfg, header, total_difficulty);
259 let after_merge = cfg.handler_cfg.spec_id >= SpecId::MERGE;
260 self.fill_block_env(block_env, header, after_merge);
261 }
262
263 fn next_cfg_and_block_env(
269 &self,
270 parent: &Self::Header,
271 attributes: NextBlockEnvAttributes,
272 ) -> Result<(CfgEnvWithHandlerCfg, BlockEnv), Self::Error>;
273}
274
275#[derive(Debug, Clone, Copy, PartialEq, Eq)]
280pub struct NextBlockEnvAttributes {
281 pub timestamp: u64,
283 pub suggested_fee_recipient: Address,
285 pub prev_randao: B256,
287}
288
289pub trait TxEnvOverrides {
291 fn apply(&mut self, env: &mut TxEnv);
293}
294
295impl<F> TxEnvOverrides for F
296where
297 F: FnMut(&mut TxEnv),
298{
299 fn apply(&mut self, env: &mut TxEnv) {
300 self(env)
301 }
302}