1use crate::{InnerDb, SimDb, TimeLimited};
2use signet_evm::{signet_precompiles, EvmNeedsTx, OrderDetector, SignetLayered};
3use signet_types::constants::SignetSystemConstants;
4use std::{marker::PhantomData, sync::Arc};
5use tokio::time::Instant;
6use trevm::{
7 db::TryCachingDb,
8 helpers::Ctx,
9 inspectors::{Layered, TimeLimit},
10 revm::{
11 context::{BlockEnv, CfgEnv},
12 database::{Cache, CacheDB},
13 inspector::{Inspector, NoOpInspector},
14 DatabaseRef,
15 },
16 Block, Cfg, TrevmBuilder,
17};
18
19#[derive(Debug)]
21pub struct HostEnv<Db, Insp = NoOpInspector> {
22 db: InnerDb<Db>,
23
24 constants: SignetSystemConstants,
25
26 cfg: CfgEnv,
27 block: BlockEnv,
28
29 _pd: PhantomData<fn() -> Insp>,
30}
31
32impl<Db, Insp> Clone for HostEnv<Db, Insp> {
33 fn clone(&self) -> Self {
34 Self {
35 db: self.db.clone(),
36 constants: self.constants.clone(),
37 cfg: self.cfg.clone(),
38 block: self.block.clone(),
39 _pd: PhantomData,
40 }
41 }
42}
43
44impl<Db, Insp> HostEnv<Db, Insp> {
45 pub fn new<C, B>(db: Db, constants: SignetSystemConstants, cfg_ref: &C, block_ref: &B) -> Self
47 where
48 C: Cfg,
49 B: Block,
50 {
51 let mut cfg = CfgEnv::default();
52 cfg_ref.fill_cfg_env(&mut cfg);
53 let mut block = BlockEnv::default();
54 block_ref.fill_block_env(&mut block);
55
56 Self { db: Arc::new(CacheDB::new(db)), constants, cfg, block, _pd: PhantomData }
57 }
58
59 pub const fn db(&self) -> &InnerDb<Db> {
61 &self.db
62 }
63
64 pub const fn db_mut(&mut self) -> &mut InnerDb<Db> {
66 &mut self.db
67 }
68
69 pub const fn constants(&self) -> &SignetSystemConstants {
71 &self.constants
72 }
73
74 pub const fn cfg(&self) -> &CfgEnv {
76 &self.cfg
77 }
78
79 pub const fn cfg_mut(&mut self) -> &mut CfgEnv {
81 &mut self.cfg
82 }
83
84 pub const fn block(&self) -> &BlockEnv {
86 &self.block
87 }
88
89 pub const fn block_mut(&mut self) -> &mut BlockEnv {
91 &mut self.block
92 }
93}
94
95impl<Db, Insp> HostEnv<Db, Insp>
96where
97 Db: DatabaseRef + Send + Sync,
98 Insp: Inspector<Ctx<SimDb<Db>>> + Default + Sync,
99{
100 pub fn sim_db(&self) -> crate::SimDb<Db> {
102 crate::SimDb::new(self.db.clone())
103 }
104
105 pub fn create_evm(
108 &self,
109 finish_by: Instant,
110 ) -> EvmNeedsTx<crate::SimDb<Db>, TimeLimited<Insp>> {
111 let db = self.sim_db();
112 let inspector = Layered::new(TimeLimit::new(finish_by - Instant::now()), Insp::default());
113
114 let inspector =
116 SignetLayered::new(inspector, OrderDetector::for_host(self.constants.clone()));
117
118 TrevmBuilder::new()
122 .with_db(db)
123 .with_insp(inspector)
124 .with_precompiles(signet_precompiles())
125 .build_trevm()
126 .fill_cfg(&self.cfg)
127 .fill_block(&self.block)
128 }
129}
130
131impl<Db, Insp> HostEnv<Db, Insp>
132where
133 Db: DatabaseRef,
134 Insp: Inspector<Ctx<SimDb<Db>>> + Default + Sync,
135{
136 pub fn accept_cache(
138 &mut self,
139 cache: Cache,
140 ) -> Result<(), <InnerDb<Db> as TryCachingDb>::Error> {
141 self.db_mut().try_extend(cache)
142 }
143
144 pub fn accept_cache_ref(
146 &mut self,
147 cache: &Cache,
148 ) -> Result<(), <InnerDb<Db> as TryCachingDb>::Error> {
149 self.db_mut().try_extend_ref(cache)
150 }
151}