11use std:: { collections:: HashMap , str:: FromStr , sync:: Arc } ;
22
3- use bytes:: Bytes ;
43use common:: types:: BlockTag ;
54use ethers:: types:: transaction:: eip2930:: AccessListItem ;
65use eyre:: { Report , Result } ;
76use futures:: future:: join_all;
87use revm:: {
98 primitives:: {
10- AccountInfo , Bytecode , Env , ExecutionResult , ResultAndState , TransactTo , B160 , B256 , U256 ,
9+ AccountInfo , Address , Bytecode , Bytes , Env , ExecutionResult , ResultAndState , TransactTo ,
10+ B256 , U256 ,
1111 } ,
1212 Database , EVM ,
1313} ;
@@ -39,7 +39,9 @@ impl<R: ExecutionRpc> Evm<R> {
3939
4040 match tx. result {
4141 ExecutionResult :: Success { output, .. } => Ok ( output. into_data ( ) . to_vec ( ) ) ,
42- ExecutionResult :: Revert { output, .. } => Err ( EvmError :: Revert ( Some ( output) ) ) ,
42+ ExecutionResult :: Revert { output, .. } => {
43+ Err ( EvmError :: Revert ( Some ( output. to_vec ( ) . into ( ) ) ) )
44+ }
4345 ExecutionResult :: Halt { .. } => Err ( EvmError :: Revert ( None ) ) ,
4446 }
4547 }
@@ -84,19 +86,21 @@ impl<R: ExecutionRpc> Evm<R> {
8486
8587 async fn get_env ( & self , opts : & CallOpts , tag : BlockTag ) -> Env {
8688 let mut env = Env :: default ( ) ;
89+ let to = convert_address ( & opts. to . unwrap_or_default ( ) ) ;
90+ let from = convert_address ( & opts. from . unwrap_or_default ( ) ) ;
8791
88- env. tx . transact_to = TransactTo :: Call ( opts . to . unwrap_or_default ( ) . into ( ) ) ;
89- env. tx . caller = opts . from . map ( B160 :: from ) . unwrap_or_default ( ) ;
92+ env. tx . transact_to = TransactTo :: Call ( to ) ;
93+ env. tx . caller = from;
9094 env. tx . value = opts
9195 . value
92- . map ( |value| B256 :: from ( value) . into ( ) )
96+ . map ( |value| convert_u256 ( & value) )
9397 . unwrap_or_default ( ) ;
9498
9599 env. tx . data = Bytes :: from ( opts. data . clone ( ) . unwrap_or_default ( ) . to_vec ( ) ) ;
96100 env. tx . gas_limit = opts. gas . map ( |v| v. as_u64 ( ) ) . unwrap_or ( u64:: MAX ) ;
97101 env. tx . gas_price = opts
98102 . gas_price
99- . map ( |g| B256 :: from ( g ) . into ( ) )
103+ . map ( |gas_price| convert_u256 ( & gas_price ) )
100104 . unwrap_or_default ( ) ;
101105
102106 let block = self
@@ -110,11 +114,10 @@ impl<R: ExecutionRpc> Evm<R> {
110114 . unwrap ( ) ;
111115
112116 env. block . number = U256 :: from ( block. number . as_u64 ( ) ) ;
113- env. block . coinbase = block. miner . into ( ) ;
117+ env. block . coinbase = convert_address ( & block. miner ) ;
114118 env. block . timestamp = U256 :: from ( block. timestamp . as_u64 ( ) ) ;
115- env. block . difficulty = block. difficulty . into ( ) ;
116-
117- env. cfg . chain_id = U256 :: from ( self . chain_id ) ;
119+ env. block . difficulty = convert_u256 ( & block. difficulty ) ;
120+ env. cfg . chain_id = self . chain_id ;
118121
119122 env
120123 }
@@ -133,15 +136,15 @@ impl<R: ExecutionRpc> ProofDB<R> {
133136}
134137
135138enum StateAccess {
136- Basic ( B160 ) ,
139+ Basic ( Address ) ,
137140 BlockHash ( u64 ) ,
138- Storage ( B160 , U256 ) ,
141+ Storage ( Address , U256 ) ,
139142}
140143
141144struct EvmState < R : ExecutionRpc > {
142- basic : HashMap < B160 , AccountInfo > ,
145+ basic : HashMap < Address , AccountInfo > ,
143146 block_hash : HashMap < u64 , B256 > ,
144- storage : HashMap < B160 , HashMap < U256 , U256 > > ,
147+ storage : HashMap < Address , HashMap < U256 , U256 > > ,
145148 block : BlockTag ,
146149 access : Option < StateAccess > ,
147150 execution : Arc < ExecutionClient < R > > ,
@@ -163,32 +166,45 @@ impl<R: ExecutionRpc> EvmState<R> {
163166 if let Some ( access) = & self . access . take ( ) {
164167 match access {
165168 StateAccess :: Basic ( address) => {
169+ let address_ethers = ethers:: types:: Address :: from_slice ( address. as_slice ( ) ) ;
166170 let account = self
167171 . execution
168- . get_account ( & ( * address ) . into ( ) , None , self . block )
172+ . get_account ( & address_ethers , None , self . block )
169173 . await ?;
174+
170175 let bytecode = Bytecode :: new_raw ( account. code . into ( ) ) ;
171- let account = AccountInfo :: new ( account. balance . into ( ) , account. nonce , bytecode) ;
176+ let code_hash = B256 :: from_slice ( account. code_hash . as_bytes ( ) ) ;
177+ let balance = convert_u256 ( & account. balance ) ;
178+
179+ let account = AccountInfo :: new ( balance, account. nonce , code_hash, bytecode) ;
172180 self . basic . insert ( * address, account) ;
173181 }
174182 StateAccess :: Storage ( address, slot) => {
183+ let address_ethers = ethers:: types:: Address :: from_slice ( address. as_slice ( ) ) ;
175184 let slot_ethers = ethers:: types:: H256 :: from_slice ( & slot. to_be_bytes :: < 32 > ( ) ) ;
176185 let slots = [ slot_ethers] ;
177186 let account = self
178187 . execution
179- . get_account ( & ( * address ) . into ( ) , Some ( & slots) , self . block )
188+ . get_account ( & address_ethers , Some ( & slots) , self . block )
180189 . await ?;
181190
182191 let storage = self . storage . entry ( * address) . or_default ( ) ;
183192 let value = * account. slots . get ( & slot_ethers) . unwrap ( ) ;
184- storage. insert ( * slot, value. into ( ) ) ;
193+
194+ let mut value_slice = [ 0u8 ; 32 ] ;
195+ value. to_big_endian ( value_slice. as_mut_slice ( ) ) ;
196+ let value = U256 :: from_be_slice ( & value_slice) ;
197+
198+ storage. insert ( * slot, value) ;
185199 }
186200 StateAccess :: BlockHash ( number) => {
187201 let block = self
188202 . execution
189203 . get_block ( BlockTag :: Number ( * number) , false )
190204 . await ?;
191- self . block_hash . insert ( * number, block. hash . into ( ) ) ;
205+
206+ let hash = B256 :: from_slice ( block. hash . as_bytes ( ) ) ;
207+ self . block_hash . insert ( * number, hash) ;
192208 }
193209 }
194210 }
@@ -200,7 +216,7 @@ impl<R: ExecutionRpc> EvmState<R> {
200216 self . access . is_some ( )
201217 }
202218
203- pub fn get_basic ( & mut self , address : B160 ) -> Result < AccountInfo > {
219+ pub fn get_basic ( & mut self , address : Address ) -> Result < AccountInfo > {
204220 if let Some ( account) = self . basic . get ( & address) {
205221 Ok ( account. clone ( ) )
206222 } else {
@@ -209,7 +225,7 @@ impl<R: ExecutionRpc> EvmState<R> {
209225 }
210226 }
211227
212- pub fn get_storage ( & mut self , address : B160 , slot : U256 ) -> Result < U256 > {
228+ pub fn get_storage ( & mut self , address : Address , slot : U256 ) -> Result < U256 > {
213229 let storage = self . storage . entry ( address) . or_default ( ) ;
214230 if let Some ( slot) = storage. get ( & slot) {
215231 Ok ( * slot)
@@ -289,19 +305,23 @@ impl<R: ExecutionRpc> EvmState<R> {
289305 }
290306
291307 for ( address, account) in account_map {
292- let info = AccountInfo :: new (
293- account. balance . into ( ) ,
294- account. nonce ,
295- Bytecode :: new_raw ( account. code . into ( ) ) ,
296- ) ;
308+ let bytecode = Bytecode :: new_raw ( account. code . into ( ) ) ;
309+ let code_hash = B256 :: from_slice ( account. code_hash . as_bytes ( ) ) ;
310+ let balance = convert_u256 ( & account. balance ) ;
297311
298- self . basic . insert ( address. into ( ) , info) ;
312+ let info = AccountInfo :: new ( balance, account. nonce , code_hash, bytecode) ;
313+
314+ let address = convert_address ( & address) ;
315+ self . basic . insert ( address, info) ;
299316
300317 for ( slot, value) in account. slots {
318+ let slot = B256 :: from_slice ( slot. as_bytes ( ) ) ;
319+ let value = convert_u256 ( & value) ;
320+
301321 self . storage
302- . entry ( address. into ( ) )
322+ . entry ( address)
303323 . or_default ( )
304- . insert ( B256 :: from ( slot) . into ( ) , value. into ( ) ) ;
324+ . insert ( B256 :: from ( slot) . into ( ) , value) ;
305325 }
306326 }
307327
@@ -312,27 +332,29 @@ impl<R: ExecutionRpc> EvmState<R> {
312332impl < R : ExecutionRpc > Database for ProofDB < R > {
313333 type Error = Report ;
314334
315- fn basic ( & mut self , address : B160 ) -> Result < Option < AccountInfo > , Report > {
335+ fn basic ( & mut self , address : Address ) -> Result < Option < AccountInfo > , Report > {
316336 if is_precompile ( & address) {
317337 return Ok ( Some ( AccountInfo :: default ( ) ) ) ;
318338 }
319339
320340 trace ! (
321341 target: "helios::evm" ,
322342 "fetch basic evm state for address=0x{}" ,
323- hex:: encode( address. as_bytes ( ) )
343+ hex:: encode( address. as_slice ( ) )
324344 ) ;
325345
326346 Ok ( Some ( self . state . get_basic ( address) ?) )
327347 }
328348
329349 fn block_hash ( & mut self , number : U256 ) -> Result < B256 , Report > {
330350 trace ! ( target: "helios::evm" , "fetch block hash for block={:?}" , number) ;
331- let number_ethers: ethers:: types:: U256 = number. into ( ) ;
332- self . state . get_block_hash ( number_ethers. as_u64 ( ) )
351+ let number = number
352+ . try_into ( )
353+ . map_err ( |_| eyre:: eyre!( "invalid block number" ) ) ?;
354+ self . state . get_block_hash ( number)
333355 }
334356
335- fn storage ( & mut self , address : B160 , slot : U256 ) -> Result < U256 , Report > {
357+ fn storage ( & mut self , address : Address , slot : U256 ) -> Result < U256 , Report > {
336358 trace ! ( target: "helios::evm" , "fetch evm state for address={:?}, slot={}" , address, slot) ;
337359 self . state . get_storage ( address, slot)
338360 }
@@ -342,13 +364,24 @@ impl<R: ExecutionRpc> Database for ProofDB<R> {
342364 }
343365}
344366
345- fn is_precompile ( address : & B160 ) -> bool {
346- address. le ( & B160 :: from_str ( "0x0000000000000000000000000000000000000009" ) . unwrap ( ) )
347- && address. gt ( & B160 :: zero ( ) )
367+ fn is_precompile ( address : & Address ) -> bool {
368+ address. le ( & Address :: from_str ( "0x0000000000000000000000000000000000000009" ) . unwrap ( ) )
369+ && address. gt ( & Address :: ZERO )
370+ }
371+
372+ fn convert_u256 ( value : & ethers:: types:: U256 ) -> U256 {
373+ let mut value_slice = [ 0u8 ; 32 ] ;
374+ value. to_big_endian ( value_slice. as_mut_slice ( ) ) ;
375+ U256 :: from_be_slice ( & value_slice)
376+ }
377+
378+ fn convert_address ( value : & ethers:: types:: Address ) -> Address {
379+ Address :: from_slice ( value. as_bytes ( ) )
348380}
349381
350382#[ cfg( test) ]
351383mod tests {
384+ use revm:: primitives:: KECCAK_EMPTY ;
352385 use tokio:: sync:: { mpsc:: channel, watch} ;
353386
354387 use crate :: { rpc:: mock_rpc:: MockRpc , state:: State } ;
@@ -371,8 +404,13 @@ mod tests {
371404 // Construct the proof database with the given client
372405 let mut proof_db = ProofDB :: new ( tag, Arc :: new ( execution) ) ;
373406
374- let address = B160 :: from_str ( "0x388C818CA8B9251b393131C08a736A67ccB19297" ) . unwrap ( ) ;
375- let info = AccountInfo :: new ( U256 :: from ( 500 ) , 10 , Bytecode :: new_raw ( Bytes :: default ( ) ) ) ;
407+ let address = Address :: from_str ( "0x388C818CA8B9251b393131C08a736A67ccB19297" ) . unwrap ( ) ;
408+ let info = AccountInfo :: new (
409+ U256 :: from ( 500 ) ,
410+ 10 ,
411+ KECCAK_EMPTY ,
412+ Bytecode :: new_raw ( Bytes :: default ( ) ) ,
413+ ) ;
376414 proof_db. state . basic . insert ( address, info. clone ( ) ) ;
377415
378416 // Get the account from the proof database
0 commit comments