@@ -48,7 +48,8 @@ use fp_evm::weight_per_gas;
4848use fp_rpc:: TransactionStatus ;
4949use pallet_ethereum:: { Call :: transact, PostLogContent , Transaction as EthereumTransaction } ;
5050use pallet_evm:: {
51- Account as EVMAccount , EnsureAccountId20 , FeeCalculator , IdentityAddressMapping , Runner ,
51+ Account as EVMAccount , EnsureAccountId20 , FeeCalculator , GasWeightMapping ,
52+ IdentityAddressMapping , Runner ,
5253} ;
5354
5455// A few exports that help ease life for downstream crates.
@@ -689,6 +690,41 @@ impl_runtime_apis! {
689690 let is_transactional = false ;
690691 let validate = true ;
691692 let evm_config = config. as_ref( ) . unwrap_or( <Runtime as pallet_evm:: Config >:: config( ) ) ;
693+
694+ let mut estimated_transaction_len = data. len( ) +
695+ 20 + // to
696+ 20 + // from
697+ 32 + // value
698+ 32 + // gas_limit
699+ 32 + // nonce
700+ 1 + // TransactionAction
701+ 8 + // chain id
702+ 65 ; // signature
703+
704+ if max_fee_per_gas. is_some( ) {
705+ estimated_transaction_len += 32 ;
706+ }
707+ if max_priority_fee_per_gas. is_some( ) {
708+ estimated_transaction_len += 32 ;
709+ }
710+ if access_list. is_some( ) {
711+ estimated_transaction_len += access_list. encoded_size( ) ;
712+ }
713+
714+ let gas_limit = gas_limit. min( u64 :: MAX . into( ) ) . low_u64( ) ;
715+ let without_base_extrinsic_weight = true ;
716+
717+ let ( weight_limit, proof_size_base_cost) =
718+ match <Runtime as pallet_evm:: Config >:: GasWeightMapping :: gas_to_weight(
719+ gas_limit,
720+ without_base_extrinsic_weight
721+ ) {
722+ weight_limit if weight_limit. proof_size( ) > 0 => {
723+ ( Some ( weight_limit) , Some ( estimated_transaction_len as u64 ) )
724+ }
725+ _ => ( None , None ) ,
726+ } ;
727+
692728 <Runtime as pallet_evm:: Config >:: Runner :: call(
693729 from,
694730 to,
@@ -701,9 +737,8 @@ impl_runtime_apis! {
701737 access_list. unwrap_or_default( ) ,
702738 is_transactional,
703739 validate,
704- // TODO we probably want to support external cost recording in non-transactional calls
705- None ,
706- None ,
740+ weight_limit,
741+ proof_size_base_cost,
707742 evm_config,
708743 ) . map_err( |err| err. error. into( ) )
709744 }
@@ -730,6 +765,44 @@ impl_runtime_apis! {
730765 let is_transactional = false ;
731766 let validate = true ;
732767 let evm_config = config. as_ref( ) . unwrap_or( <Runtime as pallet_evm:: Config >:: config( ) ) ;
768+
769+ let mut estimated_transaction_len = data. len( ) +
770+ 20 + // from
771+ 32 + // value
772+ 32 + // gas_limit
773+ 32 + // nonce
774+ 1 + // TransactionAction
775+ 8 + // chain id
776+ 65 ; // signature
777+
778+ if max_fee_per_gas. is_some( ) {
779+ estimated_transaction_len += 32 ;
780+ }
781+ if max_priority_fee_per_gas. is_some( ) {
782+ estimated_transaction_len += 32 ;
783+ }
784+ if access_list. is_some( ) {
785+ estimated_transaction_len += access_list. encoded_size( ) ;
786+ }
787+
788+ let gas_limit = if gas_limit > U256 :: from( u64 :: MAX ) {
789+ u64 :: MAX
790+ } else {
791+ gas_limit. low_u64( )
792+ } ;
793+ let without_base_extrinsic_weight = true ;
794+
795+ let ( weight_limit, proof_size_base_cost) =
796+ match <Runtime as pallet_evm:: Config >:: GasWeightMapping :: gas_to_weight(
797+ gas_limit,
798+ without_base_extrinsic_weight
799+ ) {
800+ weight_limit if weight_limit. proof_size( ) > 0 => {
801+ ( Some ( weight_limit) , Some ( estimated_transaction_len as u64 ) )
802+ }
803+ _ => ( None , None ) ,
804+ } ;
805+
733806 <Runtime as pallet_evm:: Config >:: Runner :: create(
734807 from,
735808 data,
@@ -741,9 +814,8 @@ impl_runtime_apis! {
741814 access_list. unwrap_or_default( ) ,
742815 is_transactional,
743816 validate,
744- // TODO we probably want to support external cost recording in non-transactional calls
745- None ,
746- None ,
817+ weight_limit,
818+ proof_size_base_cost,
747819 evm_config,
748820 ) . map_err( |err| err. error. into( ) )
749821 }
0 commit comments