@@ -232,54 +232,22 @@ decl_module! {
232
232
nonce: Option <U256 >,
233
233
) -> DispatchResult {
234
234
let sender = ensure_signed( origin) ?;
235
- ensure!( gas_price >= T :: FeeCalculator :: min_gas_price( ) , Error :: <T >:: GasPriceTooLow ) ;
236
235
let source = T :: ConvertAccountId :: convert_account_id( & sender) ;
237
236
238
- let vicinity = Vicinity {
239
- gas_price,
240
- origin: source,
241
- } ;
242
-
243
- let mut backend = Backend :: <T >:: new( & vicinity) ;
244
- let mut executor = StackExecutor :: new_with_precompile(
245
- & backend,
246
- gas_limit as usize ,
247
- & backend:: GASOMETER_CONFIG ,
248
- T :: Precompiles :: execute,
249
- ) ;
250
-
251
- let total_fee = gas_price. checked_mul( U256 :: from( gas_limit) )
252
- . ok_or( Error :: <T >:: FeeOverflow ) ?;
253
- let total_payment = value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?;
254
- let source_account = Accounts :: get( & source) ;
255
- ensure!( source_account. balance >= total_payment, Error :: <T >:: BalanceLow ) ;
256
- executor. withdraw( source, total_fee) . map_err( |_| Error :: <T >:: WithdrawFailed ) ?;
257
-
258
- if let Some ( nonce) = nonce {
259
- ensure!( source_account. nonce == nonce, Error :: <T >:: InvalidNonce ) ;
260
- }
261
-
262
- let reason = executor. transact_call(
237
+ Self :: execute_evm(
263
238
source,
264
- target,
265
239
value,
266
- input,
267
- gas_limit as usize ,
268
- ) ;
269
-
270
- let ret = match reason {
271
- ExitReason :: Succeed ( _) => Ok ( ( ) ) ,
272
- ExitReason :: Error ( _) => Err ( Error :: <T >:: ExitReasonFailed ) ,
273
- ExitReason :: Revert ( _) => Err ( Error :: <T >:: ExitReasonRevert ) ,
274
- ExitReason :: Fatal ( _) => Err ( Error :: <T >:: ExitReasonFatal ) ,
275
- } ;
276
- let actual_fee = executor. fee( gas_price) ;
277
- executor. deposit( source, total_fee. saturating_sub( actual_fee) ) ;
278
-
279
- let ( values, logs) = executor. deconstruct( ) ;
280
- backend. apply( values, logs, true ) ;
281
-
282
- ret. map_err( Into :: into)
240
+ gas_limit,
241
+ gas_price,
242
+ nonce,
243
+ |executor| ( ( ) , executor. transact_call(
244
+ source,
245
+ target,
246
+ value,
247
+ input,
248
+ gas_limit as usize ,
249
+ ) ) ,
250
+ ) . map_err( Into :: into)
283
251
}
284
252
285
253
/// Issue an EVM create operation. This is similar to a contract creation transaction in
@@ -294,60 +262,28 @@ decl_module! {
294
262
nonce: Option <U256 >,
295
263
) -> DispatchResult {
296
264
let sender = ensure_signed( origin) ?;
297
- ensure!( gas_price >= T :: FeeCalculator :: min_gas_price( ) , Error :: <T >:: GasPriceTooLow ) ;
298
-
299
265
let source = T :: ConvertAccountId :: convert_account_id( & sender) ;
300
266
301
- let vicinity = Vicinity {
302
- gas_price,
303
- origin: source,
304
- } ;
305
-
306
- let mut backend = Backend :: <T >:: new( & vicinity) ;
307
- let mut executor = StackExecutor :: new_with_precompile(
308
- & backend,
309
- gas_limit as usize ,
310
- & backend:: GASOMETER_CONFIG ,
311
- T :: Precompiles :: execute,
312
- ) ;
313
-
314
- let total_fee = gas_price. checked_mul( U256 :: from( gas_limit) )
315
- . ok_or( Error :: <T >:: FeeOverflow ) ?;
316
- let total_payment = value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?;
317
- let source_account = Accounts :: get( & source) ;
318
- ensure!( source_account. balance >= total_payment, Error :: <T >:: BalanceLow ) ;
319
- executor. withdraw( source, total_fee) . map_err( |_| Error :: <T >:: WithdrawFailed ) ?;
320
-
321
- if let Some ( nonce) = nonce {
322
- ensure!( source_account. nonce == nonce, Error :: <T >:: InvalidNonce ) ;
323
- }
324
-
325
- let create_address = executor. create_address(
326
- evm:: CreateScheme :: Legacy { caller: source }
327
- ) ;
328
- let reason = executor. transact_create(
267
+ let create_address = Self :: execute_evm(
329
268
source,
330
269
value,
331
- init,
332
- gas_limit as usize ,
333
- ) ;
334
-
335
- let ret = match reason {
336
- ExitReason :: Succeed ( _) => {
337
- Module :: <T >:: deposit_event( Event :: Created ( create_address) ) ;
338
- Ok ( ( ) )
270
+ gas_limit,
271
+ gas_price,
272
+ nonce,
273
+ |executor| {
274
+ ( executor. create_address(
275
+ evm:: CreateScheme :: Legacy { caller: source } ,
276
+ ) , executor. transact_create(
277
+ source,
278
+ value,
279
+ init,
280
+ gas_limit as usize ,
281
+ ) )
339
282
} ,
340
- ExitReason :: Error ( _) => Err ( Error :: <T >:: ExitReasonFailed ) ,
341
- ExitReason :: Revert ( _) => Err ( Error :: <T >:: ExitReasonRevert ) ,
342
- ExitReason :: Fatal ( _) => Err ( Error :: <T >:: ExitReasonFatal ) ,
343
- } ;
344
- let actual_fee = executor. fee( gas_price) ;
345
- executor. deposit( source, total_fee. saturating_sub( actual_fee) ) ;
346
-
347
- let ( values, logs) = executor. deconstruct( ) ;
348
- backend. apply( values, logs, true ) ;
283
+ ) ?;
349
284
350
- ret. map_err( Into :: into)
285
+ Module :: <T >:: deposit_event( Event :: Created ( create_address) ) ;
286
+ Ok ( ( ) )
351
287
}
352
288
353
289
/// Issue an EVM create2 operation.
@@ -362,62 +298,30 @@ decl_module! {
362
298
nonce: Option <U256 >,
363
299
) -> DispatchResult {
364
300
let sender = ensure_signed( origin) ?;
365
- ensure!( gas_price >= T :: FeeCalculator :: min_gas_price( ) , Error :: <T >:: GasPriceTooLow ) ;
366
-
367
301
let source = T :: ConvertAccountId :: convert_account_id( & sender) ;
368
302
369
- let vicinity = Vicinity {
370
- gas_price,
371
- origin: source,
372
- } ;
373
-
374
- let mut backend = Backend :: <T >:: new( & vicinity) ;
375
- let mut executor = StackExecutor :: new_with_precompile(
376
- & backend,
377
- gas_limit as usize ,
378
- & backend:: GASOMETER_CONFIG ,
379
- T :: Precompiles :: execute,
380
- ) ;
381
-
382
- let total_fee = gas_price. checked_mul( U256 :: from( gas_limit) )
383
- . ok_or( Error :: <T >:: FeeOverflow ) ?;
384
- let total_payment = value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?;
385
- let source_account = Accounts :: get( & source) ;
386
- ensure!( source_account. balance >= total_payment, Error :: <T >:: BalanceLow ) ;
387
- executor. withdraw( source, total_fee) . map_err( |_| Error :: <T >:: WithdrawFailed ) ?;
388
-
389
- if let Some ( nonce) = nonce {
390
- ensure!( source_account. nonce == nonce, Error :: <T >:: InvalidNonce ) ;
391
- }
392
-
393
303
let code_hash = H256 :: from_slice( Keccak256 :: digest( & init) . as_slice( ) ) ;
394
- let create_address = executor. create_address(
395
- evm:: CreateScheme :: Create2 { caller: source, code_hash, salt }
396
- ) ;
397
- let reason = executor. transact_create2(
304
+ let create_address = Self :: execute_evm(
398
305
source,
399
306
value,
400
- init,
401
- salt,
402
- gas_limit as usize ,
403
- ) ;
404
-
405
- let ret = match reason {
406
- ExitReason :: Succeed ( _) => {
407
- Module :: <T >:: deposit_event( Event :: Created ( create_address) ) ;
408
- Ok ( ( ) )
307
+ gas_limit,
308
+ gas_price,
309
+ nonce,
310
+ |executor| {
311
+ ( executor. create_address(
312
+ evm:: CreateScheme :: Create2 { caller: source, code_hash, salt } ,
313
+ ) , executor. transact_create2(
314
+ source,
315
+ value,
316
+ init,
317
+ salt,
318
+ gas_limit as usize ,
319
+ ) )
409
320
} ,
410
- ExitReason :: Error ( _) => Err ( Error :: <T >:: ExitReasonFailed ) ,
411
- ExitReason :: Revert ( _) => Err ( Error :: <T >:: ExitReasonRevert ) ,
412
- ExitReason :: Fatal ( _) => Err ( Error :: <T >:: ExitReasonFatal ) ,
413
- } ;
414
- let actual_fee = executor. fee( gas_price) ;
415
- executor. deposit( source, total_fee. saturating_sub( actual_fee) ) ;
416
-
417
- let ( values, logs) = executor. deconstruct( ) ;
418
- backend. apply( values, logs, true ) ;
321
+ ) ?;
419
322
420
- ret. map_err( Into :: into)
323
+ Module :: <T >:: deposit_event( Event :: Created ( create_address) ) ;
324
+ Ok ( ( ) )
421
325
}
422
326
}
423
327
}
@@ -454,4 +358,59 @@ impl<T: Trait> Module<T> {
454
358
AccountCodes :: remove ( address) ;
455
359
AccountStorages :: remove_prefix ( address) ;
456
360
}
361
+
362
+ /// Execute an EVM operation.
363
+ fn execute_evm < F , R > (
364
+ source : H160 ,
365
+ value : U256 ,
366
+ gas_limit : u32 ,
367
+ gas_price : U256 ,
368
+ nonce : Option < U256 > ,
369
+ f : F ,
370
+ ) -> Result < R , Error < T > > where
371
+ F : FnOnce ( & mut StackExecutor < Backend < T > > ) -> ( R , ExitReason ) ,
372
+ {
373
+ ensure ! ( gas_price >= T :: FeeCalculator :: min_gas_price( ) , Error :: <T >:: GasPriceTooLow ) ;
374
+
375
+ let vicinity = Vicinity {
376
+ gas_price,
377
+ origin : source,
378
+ } ;
379
+
380
+ let mut backend = Backend :: < T > :: new ( & vicinity) ;
381
+ let mut executor = StackExecutor :: new_with_precompile (
382
+ & backend,
383
+ gas_limit as usize ,
384
+ & backend:: GASOMETER_CONFIG ,
385
+ T :: Precompiles :: execute,
386
+ ) ;
387
+
388
+ let total_fee = gas_price. checked_mul ( U256 :: from ( gas_limit) )
389
+ . ok_or ( Error :: < T > :: FeeOverflow ) ?;
390
+ let total_payment = value. checked_add ( total_fee) . ok_or ( Error :: < T > :: PaymentOverflow ) ?;
391
+ let source_account = Accounts :: get ( & source) ;
392
+ ensure ! ( source_account. balance >= total_payment, Error :: <T >:: BalanceLow ) ;
393
+ executor. withdraw ( source, total_fee) . map_err ( |_| Error :: < T > :: WithdrawFailed ) ?;
394
+
395
+ if let Some ( nonce) = nonce {
396
+ ensure ! ( source_account. nonce == nonce, Error :: <T >:: InvalidNonce ) ;
397
+ }
398
+
399
+ let ( retv, reason) = f ( & mut executor) ;
400
+
401
+ let ret = match reason {
402
+ ExitReason :: Succeed ( _) => Ok ( retv) ,
403
+ ExitReason :: Error ( _) => Err ( Error :: < T > :: ExitReasonFailed ) ,
404
+ ExitReason :: Revert ( _) => Err ( Error :: < T > :: ExitReasonRevert ) ,
405
+ ExitReason :: Fatal ( _) => Err ( Error :: < T > :: ExitReasonFatal ) ,
406
+ } ;
407
+
408
+ let actual_fee = executor. fee ( gas_price) ;
409
+ executor. deposit ( source, total_fee. saturating_sub ( actual_fee) ) ;
410
+
411
+ let ( values, logs) = executor. deconstruct ( ) ;
412
+ backend. apply ( values, logs, true ) ;
413
+
414
+ ret
415
+ }
457
416
}
0 commit comments