@@ -12,11 +12,13 @@ use self::ethereum_types::{Address, H160, H256, U128, U256};
12
12
13
13
use self :: bytes:: Bytes ;
14
14
15
+ use self :: evm:: Ext ;
15
16
use self :: evm:: Factory ;
16
17
17
18
use self :: vm:: {
18
19
ActionParams , ActionValue , CallType , CleanDustMode , ContractCreateResult ,
19
20
CreateContractAddress , EnvInfo , GasLeft , MessageCallResult , Result , ReturnData , Schedule ,
21
+ TrapKind ,
20
22
} ;
21
23
22
24
// For some explanation see ethcore/vm/src/tests.rs::FakeExt
@@ -29,6 +31,11 @@ struct EwasmExt {
29
31
}
30
32
31
33
impl vm:: Ext for EwasmExt {
34
+ /// Returns the storage value for a given key if reversion happens on the current transaction.
35
+ fn initial_storage_at ( & self , key : & H256 ) -> Result < H256 > {
36
+ unimplemented ! ( )
37
+ }
38
+
32
39
/// Returns a value for given key.
33
40
fn storage_at ( & self , key : & H256 ) -> Result < H256 > {
34
41
// FIXME: why isn't there a From trait for converting between [u8;32] and H256?
@@ -90,7 +97,8 @@ impl vm::Ext for EwasmExt {
90
97
value : & U256 ,
91
98
code : & [ u8 ] ,
92
99
address : CreateContractAddress ,
93
- ) -> ContractCreateResult {
100
+ trap : bool ,
101
+ ) -> :: std:: result:: Result < ContractCreateResult , TrapKind > {
94
102
// FIXME: implement
95
103
unimplemented ! ( )
96
104
// ContractCreateResult::Failed
@@ -109,9 +117,9 @@ impl vm::Ext for EwasmExt {
109
117
value : Option < U256 > ,
110
118
data : & [ u8 ] ,
111
119
code_address : & Address ,
112
- output : & mut [ u8 ] ,
113
120
call_type : CallType ,
114
- ) -> MessageCallResult {
121
+ trap : bool ,
122
+ ) -> :: std:: result:: Result < MessageCallResult , TrapKind > {
115
123
// FIXME: set this properly
116
124
//let gas_limit = u64::from(gas);
117
125
let gas_limit = gas. as_u64 ( ) ;
@@ -148,26 +156,22 @@ impl vm::Ext for EwasmExt {
148
156
// Retrieve the entire returndata as it needs to be returned
149
157
let ret = ewasm_api:: returndata_acquire ( ) ;
150
158
151
- // Copy from returndata into the requested output len
152
- // The requested len may be smaller than available or returndata may be smaller than requested
153
- let copy_len = cmp:: min ( output. len ( ) , ret. len ( ) ) ;
154
- output. copy_from_slice ( & ret[ 0 ..copy_len] ) ;
155
-
156
159
let ret_len = ret. len ( ) ;
157
- MessageCallResult :: Success ( gas_used, ReturnData :: new ( ret, 0 , ret_len) )
160
+ Ok ( MessageCallResult :: Success (
161
+ gas_used,
162
+ ReturnData :: new ( ret, 0 , ret_len) ,
163
+ ) )
158
164
}
159
- ewasm_api:: CallResult :: Failure => MessageCallResult :: Failed ,
165
+ ewasm_api:: CallResult :: Failure => Ok ( MessageCallResult :: Failed ) ,
160
166
ewasm_api:: CallResult :: Revert => {
161
167
// Retrieve the entire returndata as it needs to be returned
162
168
let ret = ewasm_api:: returndata_acquire ( ) ;
163
169
164
- // Copy from returndata into the requested output len
165
- // The requested len may be smaller than available or returndata may be smaller than requested
166
- let copy_len = cmp:: min ( output. len ( ) , ret. len ( ) ) ;
167
- output. copy_from_slice ( & ret[ 0 ..copy_len] ) ;
168
-
169
170
let ret_len = ret. len ( ) ;
170
- MessageCallResult :: Reverted ( gas_used, ReturnData :: new ( ret, 0 , ret_len) )
171
+ Ok ( MessageCallResult :: Reverted (
172
+ gas_used,
173
+ ReturnData :: new ( ret, 0 , ret_len) ,
174
+ ) )
171
175
}
172
176
}
173
177
@@ -234,10 +238,14 @@ impl vm::Ext for EwasmExt {
234
238
0
235
239
}
236
240
237
- /// Increments sstore refunds count by 1.
238
- fn inc_sstore_clears ( & mut self ) {
239
- // NOTE: used for gas refund on SSTORE deletion (non-zero to zero)
240
- // FIXME: implement
241
+ /// Increments sstore refunds counter.
242
+ fn add_sstore_refund ( & mut self , value : usize ) {
243
+ unimplemented ! ( )
244
+ }
245
+
246
+ /// Decrements sstore refunds counter.
247
+ fn sub_sstore_refund ( & mut self , value : usize ) {
248
+ unimplemented ! ( )
241
249
}
242
250
243
251
/// Decide if any more operations should be traced. Passthrough for the VM trace.
@@ -246,18 +254,19 @@ impl vm::Ext for EwasmExt {
246
254
}
247
255
248
256
/// Prepare to trace an operation. Passthrough for the VM trace.
249
- fn trace_prepare_execute ( & mut self , _pc : usize , _instruction : u8 , _gas_cost : U256 ) { }
250
-
251
- /// Trace the finalised execution of a single instruction.
252
- fn trace_executed (
257
+ fn trace_prepare_execute (
253
258
& mut self ,
254
- _gas_used : U256 ,
255
- _stack_push : & [ U256 ] ,
256
- _mem_diff : Option < ( usize , & [ u8 ] ) > ,
257
- _store_diff : Option < ( U256 , U256 ) > ,
259
+ _pc : usize ,
260
+ _instruction : u8 ,
261
+ _gas_cost : U256 ,
262
+ _mem_written : Option < ( usize , usize ) > ,
263
+ _store_written : Option < ( U256 , U256 ) > ,
258
264
) {
259
265
}
260
266
267
+ /// Trace the finalised execution of a single instruction.
268
+ fn trace_executed ( & mut self , _gas_used : U256 , _stack_push : & [ U256 ] , _mem : & [ u8 ] ) { }
269
+
261
270
/// Check if running in static context.
262
271
fn is_static ( & self ) -> bool {
263
272
// NOTE: this is used by CREATE/CALL*, but since ewasm in the upper layer will handle this anyway, we can just ignore it here
@@ -267,11 +276,8 @@ impl vm::Ext for EwasmExt {
267
276
268
277
#[ no_mangle]
269
278
pub extern "C" fn main ( ) {
270
- // It is fine using U256::zero() here because the main point of the
271
- // factory is to determine if gas is 64bit or not. In ewasm it is always 64bit.
272
- let mut instance = Factory :: default ( ) . create ( & U256 :: zero ( ) ) ;
273
-
274
279
let mut params = ActionParams :: default ( ) ;
280
+
275
281
// FIXME: do we need to set this?
276
282
// params.call_type = if code.is_none() { CallType::Call } else { CallType::None };
277
283
params. code_address = Address :: from ( ewasm_api:: current_address ( ) ) ;
@@ -285,22 +291,26 @@ pub extern "C" fn main() {
285
291
params. data = Some ( ewasm_api:: calldata_acquire ( ) ) ;
286
292
287
293
let mut ext = EwasmExt :: default ( ) ;
288
- let result = instance. exec ( params, & mut ext) ;
294
+
295
+ let mut instance = Factory :: default ( ) . create ( params, ext. schedule ( ) , ext. depth ( ) ) ;
296
+ let result = instance. exec ( & mut ext) ;
289
297
// Could run `result.finalize(ext)` here, but processing manually seemed simpler.
290
298
match result {
291
- Ok ( GasLeft :: Known ( gas_left) ) => {
299
+ Ok ( Ok ( GasLeft :: Known ( gas_left) ) ) => {
292
300
if ext. selfdestruct_address . is_some ( ) {
293
301
let beneficiary: [ u8 ; 20 ] = ext. selfdestruct_address . unwrap ( ) . into ( ) ;
294
302
ewasm_api:: selfdestruct ( & beneficiary)
295
303
} else {
296
304
ewasm_api:: finish ( )
297
305
}
298
306
}
299
- Ok ( GasLeft :: NeedsReturn {
307
+ Ok ( Ok ( GasLeft :: NeedsReturn {
300
308
gas_left,
301
309
data,
302
310
apply_state,
303
- } ) => ewasm_api:: finish_data ( & data. deref ( ) ) ,
311
+ } ) ) => ewasm_api:: finish_data ( & data. deref ( ) ) ,
312
+ // FIXME: not sure what this state means
313
+ Ok ( Err ( err) ) => ewasm_api:: revert ( ) ,
304
314
// FIXME: add support for pushing the error message as revert data
305
315
Err ( err) => ewasm_api:: revert ( ) ,
306
316
}
0 commit comments