@@ -64,6 +64,7 @@ use fp_evm::{
6464 CallOrCreateInfo , CheckEvmTransaction , CheckEvmTransactionConfig , TransactionValidationError ,
6565} ;
6666pub use fp_rpc:: TransactionStatus ;
67+ pub use fp_rent:: EvmRentCalculator ;
6768use fp_storage:: { EthereumStorageSchema , PALLET_ETHEREUM_SCHEMA } ;
6869use pallet_evm:: { BlockHashMapping , FeeCalculator , GasWeightMapping , Runner } ;
6970
@@ -489,6 +490,43 @@ impl<T: Config> Pallet<T> {
489490 }
490491 }
491492
493+ fn calculate_max_transaction_fee (
494+ transaction_data : & TransactionData ,
495+ ) -> Result < U256 , TransactionValidityError > {
496+ match (
497+ transaction_data. gas_price ,
498+ transaction_data. max_fee_per_gas ,
499+ transaction_data. max_priority_fee_per_gas ,
500+ ) {
501+ // Legacy or EIP-2930 transaction
502+ ( Some ( gas_price) , None , None ) => {
503+ Ok ( gas_price. saturating_mul ( transaction_data. gas_limit ) )
504+ } ,
505+
506+ // EIP-1559 transaction without tip
507+ ( None , Some ( max_fee_per_gas) , None ) => {
508+ Ok ( max_fee_per_gas. saturating_mul ( transaction_data. gas_limit ) )
509+ } ,
510+
511+ // EIP-1559 with tip
512+ ( None , Some ( max_fee_per_gas) , Some ( max_priority_fee_per_gas) ) => {
513+ if max_priority_fee_per_gas > max_fee_per_gas {
514+ return Err ( TransactionValidityError :: Invalid (
515+ InvalidTransaction :: Custom ( TransactionValidationError :: PriorityFeeTooHigh as u8 )
516+ ) ) ;
517+ }
518+ Ok ( max_fee_per_gas. saturating_mul ( transaction_data. gas_limit ) )
519+ }
520+
521+ _ => {
522+ // must be transactional tx
523+ Err ( TransactionValidityError :: Invalid (
524+ InvalidTransaction :: Custom ( TransactionValidationError :: InvalidFeeInput as u8 )
525+ ) )
526+ }
527+ }
528+ }
529+
492530 // Controls that must be performed by the pool.
493531 // The controls common with the State Transition Function (STF) are in
494532 // the function `validate_transaction_common`.
@@ -520,6 +558,22 @@ impl<T: Config> Pallet<T> {
520558 . and_then ( |v| v. with_balance_for ( & who) )
521559 . map_err ( |e| e. 0 ) ?;
522560
561+ let rent_amount = T :: EvmRentCalculator :: estimate_rent ( origin) . 0 ;
562+ if rent_amount > 0 {
563+ let fee = Self :: calculate_max_transaction_fee ( & transaction_data) ?;
564+
565+ let total_payment = transaction_data. value . saturating_add ( fee) ;
566+ let total_with_rent = total_payment. saturating_add ( U256 :: from ( rent_amount) ) ;
567+
568+ if who. balance < total_with_rent {
569+ return Err (
570+ TransactionValidityError :: Invalid (
571+ InvalidTransaction :: Custom ( TransactionValidationError :: InsufficientRent as u8 )
572+ )
573+ ) ;
574+ }
575+ }
576+
523577 // EIP-3607: https://eips.ethereum.org/EIPS/eip-3607
524578 // Do not allow transactions for which `tx.sender` has any code deployed.
525579 //
@@ -948,7 +1002,7 @@ impl<T: Config> Pallet<T> {
9481002 chain_id : T :: ChainId :: get ( ) ,
9491003 is_transactional : true ,
9501004 } ,
951- transaction_data. into ( ) ,
1005+ transaction_data. clone ( ) . into ( ) ,
9521006 weight_limit,
9531007 proof_size_base_cost,
9541008 )
@@ -958,6 +1012,22 @@ impl<T: Config> Pallet<T> {
9581012 . and_then ( |v| v. with_balance_for ( & who) )
9591013 . map_err ( |e| TransactionValidityError :: Invalid ( e. 0 ) ) ?;
9601014
1015+ let rent_amount = T :: EvmRentCalculator :: estimate_rent ( origin) . 0 ;
1016+ if rent_amount > 0 {
1017+ let fee = Self :: calculate_max_transaction_fee ( & transaction_data) ?;
1018+
1019+ let total_payment = transaction_data. value . saturating_add ( fee) ;
1020+ let total_with_rent = total_payment. saturating_add ( U256 :: from ( rent_amount) ) ;
1021+
1022+ if who. balance < total_with_rent {
1023+ return Err (
1024+ TransactionValidityError :: Invalid (
1025+ InvalidTransaction :: Custom ( TransactionValidationError :: InsufficientRent as u8 )
1026+ )
1027+ ) ;
1028+ }
1029+ }
1030+
9611031 Ok ( ( ) )
9621032 }
9631033
@@ -1094,6 +1164,9 @@ impl From<TransactionValidationError> for InvalidTransactionWrapper {
10941164 TransactionValidationError :: GasPriceTooLow => InvalidTransactionWrapper (
10951165 InvalidTransaction :: Custom ( TransactionValidationError :: GasPriceTooLow as u8 ) ,
10961166 ) ,
1167+ TransactionValidationError :: InsufficientRent => InvalidTransactionWrapper (
1168+ InvalidTransaction :: Custom ( TransactionValidationError :: InsufficientRent as u8 ) ,
1169+ ) ,
10971170 TransactionValidationError :: UnknownError => InvalidTransactionWrapper (
10981171 InvalidTransaction :: Custom ( TransactionValidationError :: UnknownError as u8 ) ,
10991172 ) ,
0 commit comments