@@ -117,19 +117,19 @@ impl Precompiles for () {
117
117
118
118
struct WeightForCallCreate ;
119
119
120
- impl WeighData < ( & H160 , & Vec < u8 > , & U256 , & u32 , & U256 ) > for WeightForCallCreate {
120
+ impl WeighData < ( & H160 , & Vec < u8 > , & U256 , & u32 , & U256 , & Option < U256 > ) > for WeightForCallCreate {
121
121
fn weigh_data (
122
122
& self ,
123
- ( _, _, _, gas_provided, gas_price) : ( & H160 , & Vec < u8 > , & U256 , & u32 , & U256 )
123
+ ( _, _, _, gas_provided, gas_price, _ ) : ( & H160 , & Vec < u8 > , & U256 , & u32 , & U256 , & Option < U256 > )
124
124
) -> Weight {
125
125
( * gas_price) . saturated_into :: < Weight > ( ) . saturating_mul ( * gas_provided)
126
126
}
127
127
}
128
128
129
- impl WeighData < ( & Vec < u8 > , & U256 , & u32 , & U256 ) > for WeightForCallCreate {
129
+ impl WeighData < ( & Vec < u8 > , & U256 , & u32 , & U256 , & Option < U256 > ) > for WeightForCallCreate {
130
130
fn weigh_data (
131
131
& self ,
132
- ( _, _, gas_provided, gas_price) : ( & Vec < u8 > , & U256 , & u32 , & U256 )
132
+ ( _, _, gas_provided, gas_price, _ ) : ( & Vec < u8 > , & U256 , & u32 , & U256 , & Option < U256 > )
133
133
) -> Weight {
134
134
( * gas_price) . saturated_into :: < Weight > ( ) . saturating_mul ( * gas_provided)
135
135
}
@@ -197,6 +197,8 @@ decl_error! {
197
197
ExitReasonRevert ,
198
198
/// Call returned VM fatal error
199
199
ExitReasonFatal ,
200
+ /// Nonce is invalid
201
+ InvalidNonce ,
200
202
}
201
203
}
202
204
@@ -258,6 +260,7 @@ decl_module! {
258
260
value: U256 ,
259
261
gas_limit: u32 ,
260
262
gas_price: U256 ,
263
+ nonce: Option <U256 >,
261
264
) -> DispatchResult {
262
265
let sender = ensure_signed( origin) ?;
263
266
ensure!( gas_price >= T :: FeeCalculator :: min_gas_price( ) , Error :: <T >:: GasPriceTooLow ) ;
@@ -278,13 +281,15 @@ decl_module! {
278
281
279
282
let total_fee = gas_price. checked_mul( U256 :: from( gas_limit) )
280
283
. ok_or( Error :: <T >:: FeeOverflow ) ?;
281
- if Accounts :: get( & source) . balance <
282
- value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?
283
- {
284
- Err ( Error :: <T >:: BalanceLow ) ?
285
- }
284
+ let total_payment = value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?;
285
+ let source_account = Accounts :: get( & source) ;
286
+ ensure!( source_account. balance >= total_payment, Error :: <T >:: BalanceLow ) ;
286
287
executor. withdraw( source, total_fee) . map_err( |_| Error :: <T >:: WithdrawFailed ) ?;
287
288
289
+ if let Some ( nonce) = nonce {
290
+ ensure!( source_account. nonce == nonce, Error :: <T >:: InvalidNonce ) ;
291
+ }
292
+
288
293
let reason = executor. transact_call(
289
294
source,
290
295
target,
@@ -317,6 +322,7 @@ decl_module! {
317
322
value: U256 ,
318
323
gas_limit: u32 ,
319
324
gas_price: U256 ,
325
+ nonce: Option <U256 >,
320
326
) -> DispatchResult {
321
327
let sender = ensure_signed( origin) ?;
322
328
ensure!( gas_price >= T :: FeeCalculator :: min_gas_price( ) , Error :: <T >:: GasPriceTooLow ) ;
@@ -338,13 +344,15 @@ decl_module! {
338
344
339
345
let total_fee = gas_price. checked_mul( U256 :: from( gas_limit) )
340
346
. ok_or( Error :: <T >:: FeeOverflow ) ?;
341
- if Accounts :: get( & source) . balance <
342
- value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?
343
- {
344
- Err ( Error :: <T >:: BalanceLow ) ?
345
- }
347
+ let total_payment = value. checked_add( total_fee) . ok_or( Error :: <T >:: PaymentOverflow ) ?;
348
+ let source_account = Accounts :: get( & source) ;
349
+ ensure!( source_account. balance >= total_payment, Error :: <T >:: BalanceLow ) ;
346
350
executor. withdraw( source, total_fee) . map_err( |_| Error :: <T >:: WithdrawFailed ) ?;
347
351
352
+ if let Some ( nonce) = nonce {
353
+ ensure!( source_account. nonce == nonce, Error :: <T >:: InvalidNonce ) ;
354
+ }
355
+
348
356
let create_address = executor. create_address( source, evm:: CreateScheme :: Dynamic ) ;
349
357
let reason = executor. transact_create(
350
358
source,
0 commit comments