1use crate::{EvmError, VmDatabase};
2use ethrex_common::{
3 Address, H256, U256,
4 types::{
5 AccountState, AccountUpdate, Block, BlockHeader, ChainConfig, Code, CodeMetadata,
6 block_execution_witness::{GuestProgramState, GuestProgramStateError},
7 },
8};
9use ethrex_crypto::Crypto;
10use std::sync::{Arc, Mutex, MutexGuard};
11
12#[derive(Clone)]
13pub struct GuestProgramStateWrapper {
14 inner: Arc<Mutex<GuestProgramState>>,
15 crypto: Arc<dyn Crypto + Send + Sync>,
16}
17
18impl GuestProgramStateWrapper {
19 pub fn new(db: GuestProgramState, crypto: Arc<dyn Crypto + Send + Sync>) -> Self {
20 Self {
21 inner: Arc::new(Mutex::new(db)),
22 crypto,
23 }
24 }
25
26 pub fn lock_mutex(&self) -> Result<MutexGuard<'_, GuestProgramState>, GuestProgramStateError> {
27 self.inner
28 .lock()
29 .map_err(|_| GuestProgramStateError::Database("Failed to lock DB".to_string()))
30 }
31
32 pub fn apply_account_updates(
33 &mut self,
34 account_updates: &[AccountUpdate],
35 ) -> Result<(), GuestProgramStateError> {
36 self.lock_mutex()?
37 .apply_account_updates(account_updates, self.crypto.as_ref())
38 }
39
40 pub fn state_trie_root(&self) -> Result<H256, GuestProgramStateError> {
41 self.lock_mutex()?.state_trie_root(self.crypto.as_ref())
42 }
43
44 pub fn get_first_invalid_block_hash(&self) -> Result<Option<u64>, GuestProgramStateError> {
45 self.lock_mutex()?
46 .get_first_invalid_block_hash(self.crypto.as_ref())
47 }
48
49 pub fn get_block_parent_header(
50 &self,
51 block_number: u64,
52 ) -> Result<BlockHeader, GuestProgramStateError> {
53 self.lock_mutex()?
54 .get_block_parent_header(block_number)
55 .cloned()
56 }
57
58 pub fn initialize_block_header_hashes(
59 &self,
60 blocks: &[Block],
61 ) -> Result<(), GuestProgramStateError> {
62 self.lock_mutex()?
63 .initialize_block_header_hashes(blocks, self.crypto.as_ref())
64 }
65}
66
67impl VmDatabase for GuestProgramStateWrapper {
68 fn get_account_code(&self, code_hash: H256) -> Result<Code, EvmError> {
69 self.lock_mutex()
70 .map_err(|_| EvmError::DB("Failed to lock db".to_string()))?
71 .get_account_code(code_hash)
72 .map_err(|e| EvmError::DB(e.to_string()))
73 }
74
75 fn get_account_state(&self, address: Address) -> Result<Option<AccountState>, EvmError> {
76 self.lock_mutex()
77 .map_err(|_| EvmError::DB("Failed to lock db".to_string()))?
78 .get_account_state(address, self.crypto.as_ref())
79 .map_err(|e| EvmError::DB(e.to_string()))
80 }
81
82 fn get_block_hash(&self, block_number: u64) -> Result<H256, EvmError> {
83 self.lock_mutex()
84 .map_err(|_| EvmError::DB("Failed to lock db".to_string()))?
85 .get_block_hash(block_number, self.crypto.as_ref())
86 .map_err(|e| EvmError::DB(e.to_string()))
87 }
88
89 fn get_chain_config(&self) -> Result<ChainConfig, EvmError> {
90 self.lock_mutex()
91 .map_err(|_| EvmError::DB("Failed to lock db".to_string()))?
92 .get_chain_config()
93 .map_err(|e| EvmError::DB(e.to_string()))
94 }
95
96 fn get_storage_slot(&self, address: Address, key: H256) -> Result<Option<U256>, EvmError> {
97 self.lock_mutex()
98 .map_err(|_| EvmError::DB("Failed to lock db".to_string()))?
99 .get_storage_slot(address, key, self.crypto.as_ref())
100 .map_err(|e| EvmError::DB(e.to_string()))
101 }
102
103 fn get_code_metadata(&self, code_hash: H256) -> Result<CodeMetadata, EvmError> {
104 self.lock_mutex()
105 .map_err(|_| EvmError::DB("Failed to lock db".to_string()))?
106 .get_code_metadata(code_hash)
107 .map_err(|e| EvmError::DB(e.to_string()))
108 }
109}