1pub use alloy_evm::EvmEnv;
2use revm::{
3 Context, Database, Journal, JournalEntry,
4 context::{BlockEnv, CfgEnv, JournalInner, JournalTr, TxEnv},
5 primitives::hardfork::SpecId,
6};
7
8#[derive(Clone, Debug, Default)]
10pub struct Env {
11 pub evm_env: EvmEnv,
12 pub tx: TxEnv,
13}
14
15impl Env {
17 pub fn default_with_spec_id(spec_id: SpecId) -> Self {
18 let mut cfg = CfgEnv::default();
19 cfg.spec = spec_id;
20
21 Self::from(cfg, BlockEnv::default(), TxEnv::default())
22 }
23
24 pub fn from(cfg: CfgEnv, block: BlockEnv, tx: TxEnv) -> Self {
25 Self { evm_env: EvmEnv { cfg_env: cfg, block_env: block }, tx }
26 }
27
28 pub fn new_with_spec_id(cfg: CfgEnv, block: BlockEnv, tx: TxEnv, spec_id: SpecId) -> Self {
29 let mut cfg = cfg;
30 cfg.spec = spec_id;
31
32 Self::from(cfg, block, tx)
33 }
34}
35
36pub struct EnvMut<'a> {
38 pub block: &'a mut BlockEnv,
39 pub cfg: &'a mut CfgEnv,
40 pub tx: &'a mut TxEnv,
41}
42
43impl EnvMut<'_> {
44 pub fn to_owned(&self) -> Env {
46 Env {
47 evm_env: EvmEnv { cfg_env: self.cfg.to_owned(), block_env: self.block.to_owned() },
48 tx: self.tx.to_owned(),
49 }
50 }
51
52 pub fn set_env(&mut self, env: Env) {
58 *self.block = env.evm_env.block_env;
59 *self.cfg = env.evm_env.cfg_env;
60 *self.tx = env.tx;
61 }
62}
63
64pub trait AsEnvMut {
65 fn as_env_mut(&mut self) -> EnvMut<'_>;
66}
67
68impl AsEnvMut for EnvMut<'_> {
69 fn as_env_mut(&mut self) -> EnvMut<'_> {
70 EnvMut { block: self.block, cfg: self.cfg, tx: self.tx }
71 }
72}
73
74impl AsEnvMut for Env {
75 fn as_env_mut(&mut self) -> EnvMut<'_> {
76 EnvMut {
77 block: &mut self.evm_env.block_env,
78 cfg: &mut self.evm_env.cfg_env,
79 tx: &mut self.tx,
80 }
81 }
82}
83
84impl<DB: Database, J: JournalTr<Database = DB>, C> AsEnvMut
85 for Context<BlockEnv, TxEnv, CfgEnv, DB, J, C>
86{
87 fn as_env_mut(&mut self) -> EnvMut<'_> {
88 EnvMut { block: &mut self.block, cfg: &mut self.cfg, tx: &mut self.tx }
89 }
90}
91
92pub trait ContextExt {
93 type DB: Database;
94
95 fn as_db_env_and_journal(
96 &mut self,
97 ) -> (&mut Self::DB, &mut JournalInner<JournalEntry>, EnvMut<'_>);
98}
99
100impl<DB: Database, C> ContextExt
101 for Context<BlockEnv, TxEnv, CfgEnv, DB, Journal<DB, JournalEntry>, C>
102{
103 type DB = DB;
104
105 fn as_db_env_and_journal(
106 &mut self,
107 ) -> (&mut Self::DB, &mut JournalInner<JournalEntry>, EnvMut<'_>) {
108 (
109 &mut self.journaled_state.database,
110 &mut self.journaled_state.inner,
111 EnvMut { block: &mut self.block, cfg: &mut self.cfg, tx: &mut self.tx },
112 )
113 }
114}