1
1
mod dummy;
2
2
3
3
pub use crate :: journaled_state:: StateLoad ;
4
+ use database_interface:: Database ;
4
5
pub use dummy:: DummyHost ;
5
6
6
- use crate :: { journaled_state:: AccountLoad , BlockGetter , CfgGetter , TransactionGetter } ;
7
- use auto_impl:: auto_impl;
8
- use primitives:: { Address , Bytes , Log , B256 , U256 } ;
7
+ use crate :: {
8
+ journaled_state:: AccountLoad , Block , BlockGetter , CfgGetter , Journal , JournalGetter ,
9
+ TransactionGetter ,
10
+ } ;
11
+ use primitives:: { Address , Bytes , Log , B256 , BLOCK_HASH_HISTORY , U256 } ;
12
+ use std:: boxed:: Box ;
9
13
10
14
/// EVM context host.
11
- #[ auto_impl( & mut , Box ) ]
12
- pub trait Host : TransactionGetter + BlockGetter + CfgGetter {
13
- /// Load an account code.
14
- fn load_account_delegated ( & mut self , address : Address ) -> Option < StateLoad < AccountLoad > > ;
15
+ pub trait Host : JournalGetter + TransactionGetter + BlockGetter + CfgGetter {
16
+ fn set_error (
17
+ & mut self ,
18
+ error : <<<Self as JournalGetter >:: Journal as Journal >:: Database as Database >:: Error ,
19
+ ) ;
15
20
16
21
/// Gets the block hash of the given block `number`.
17
- fn block_hash ( & mut self , number : u64 ) -> Option < B256 > ;
22
+ fn block_hash ( & mut self , requested_number : u64 ) -> Option < B256 > {
23
+ let block_number = self . block ( ) . number ( ) ;
24
+
25
+ let Some ( diff) = block_number. checked_sub ( requested_number) else {
26
+ return Some ( B256 :: ZERO ) ;
27
+ } ;
28
+
29
+ // blockhash should push zero if number is same as current block number.
30
+ if diff == 0 {
31
+ return Some ( B256 :: ZERO ) ;
32
+ }
33
+
34
+ if diff <= BLOCK_HASH_HISTORY {
35
+ return self
36
+ . journal ( )
37
+ . db ( )
38
+ . block_hash ( requested_number)
39
+ . map_err ( |e| self . set_error ( e) )
40
+ . ok ( ) ;
41
+ }
42
+
43
+ Some ( B256 :: ZERO )
44
+ }
45
+
46
+ fn load_account_delegated ( & mut self , address : Address ) -> Option < StateLoad < AccountLoad > > {
47
+ self . journal ( )
48
+ . load_account_delegated ( address)
49
+ . map_err ( |e| self . set_error ( e) )
50
+ . ok ( )
51
+ }
18
52
19
53
/// Gets balance of `address` and if the account is cold.
20
- fn balance ( & mut self , address : Address ) -> Option < StateLoad < U256 > > ;
54
+ fn balance ( & mut self , address : Address ) -> Option < StateLoad < U256 > > {
55
+ self . journal ( )
56
+ . load_account ( address)
57
+ . map ( |acc| acc. map ( |a| a. info . balance ) )
58
+ . map_err ( |e| self . set_error ( e) )
59
+ . ok ( )
60
+ }
21
61
22
62
/// Gets code of `address` and if the account is cold.
23
- fn code ( & mut self , address : Address ) -> Option < StateLoad < Bytes > > ;
63
+ fn code ( & mut self , address : Address ) -> Option < StateLoad < Bytes > > {
64
+ self . journal ( )
65
+ . code ( address)
66
+ . map_err ( |e| self . set_error ( e) )
67
+ . ok ( )
68
+ }
24
69
25
70
/// Gets code hash of `address` and if the account is cold.
26
- fn code_hash ( & mut self , address : Address ) -> Option < StateLoad < B256 > > ;
71
+ fn code_hash ( & mut self , address : Address ) -> Option < StateLoad < B256 > > {
72
+ self . journal ( )
73
+ . code_hash ( address)
74
+ . map_err ( |e| self . set_error ( e) )
75
+ . ok ( )
76
+ }
27
77
28
78
/// Gets storage value of `address` at `index` and if the account is cold.
29
- fn sload ( & mut self , address : Address , index : U256 ) -> Option < StateLoad < U256 > > ;
79
+ fn sload ( & mut self , address : Address , index : U256 ) -> Option < StateLoad < U256 > > {
80
+ self . journal ( )
81
+ . sload ( address, index)
82
+ . map_err ( |e| self . set_error ( e) )
83
+ . ok ( )
84
+ }
30
85
31
86
/// Sets storage value of account address at index.
32
87
///
@@ -36,23 +91,57 @@ pub trait Host: TransactionGetter + BlockGetter + CfgGetter {
36
91
address : Address ,
37
92
index : U256 ,
38
93
value : U256 ,
39
- ) -> Option < StateLoad < SStoreResult > > ;
94
+ ) -> Option < StateLoad < SStoreResult > > {
95
+ self . journal ( )
96
+ . sstore ( address, index, value)
97
+ . map_err ( |e| self . set_error ( e) )
98
+ . ok ( )
99
+ }
40
100
41
101
/// Gets the transient storage value of `address` at `index`.
42
- fn tload ( & mut self , address : Address , index : U256 ) -> U256 ;
102
+ fn tload ( & mut self , address : Address , index : U256 ) -> U256 {
103
+ self . journal ( ) . tload ( address, index)
104
+ }
43
105
44
106
/// Sets the transient storage value of `address` at `index`.
45
- fn tstore ( & mut self , address : Address , index : U256 , value : U256 ) ;
107
+ fn tstore ( & mut self , address : Address , index : U256 , value : U256 ) {
108
+ self . journal ( ) . tstore ( address, index, value)
109
+ }
46
110
47
111
/// Emits a log owned by `address` with given `LogData`.
48
- fn log ( & mut self , log : Log ) ;
112
+ fn log ( & mut self , log : Log ) {
113
+ self . journal ( ) . log ( log) ;
114
+ }
49
115
50
116
/// Marks `address` to be deleted, with funds transferred to `target`.
51
117
fn selfdestruct (
52
118
& mut self ,
53
119
address : Address ,
54
120
target : Address ,
55
- ) -> Option < StateLoad < SelfDestructResult > > ;
121
+ ) -> Option < StateLoad < SelfDestructResult > > {
122
+ self . journal ( )
123
+ . selfdestruct ( address, target)
124
+ . map_err ( |e| self . set_error ( e) )
125
+ . ok ( )
126
+ }
127
+ }
128
+
129
+ impl < T : Host > Host for & mut T {
130
+ fn set_error (
131
+ & mut self ,
132
+ error : <<<Self as JournalGetter >:: Journal as Journal >:: Database as Database >:: Error ,
133
+ ) {
134
+ ( * * self ) . set_error ( error)
135
+ }
136
+ }
137
+
138
+ impl < T : Host > Host for Box < T > {
139
+ fn set_error (
140
+ & mut self ,
141
+ error : <<<Self as JournalGetter >:: Journal as Journal >:: Database as Database >:: Error ,
142
+ ) {
143
+ ( * * self ) . set_error ( error)
144
+ }
56
145
}
57
146
58
147
/// Represents the result of an `sstore` operation.
0 commit comments