@@ -49,10 +49,7 @@ use pallet_transaction_payment::{ConstFeeMultiplier, CurrencyAdapter};
49
49
use fp_account:: EthereumSignature ;
50
50
use fp_evm:: weight_per_gas;
51
51
use fp_rpc:: TransactionStatus ;
52
- use pallet_ethereum:: {
53
- Call :: transact, PostLogContent , Transaction as EthereumTransaction , TransactionAction ,
54
- TransactionData ,
55
- } ;
52
+ use pallet_ethereum:: { Call :: transact, PostLogContent , Transaction as EthereumTransaction } ;
56
53
use pallet_evm:: {
57
54
Account as EVMAccount , EnsureAccountId20 , FeeCalculator , IdentityAddressMapping , Runner ,
58
55
} ;
@@ -794,6 +791,8 @@ impl_runtime_apis! {
794
791
estimate: bool ,
795
792
access_list: Option <Vec <( H160 , Vec <H256 >) >>,
796
793
) -> Result <pallet_evm:: CallInfo , sp_runtime:: DispatchError > {
794
+ use pallet_evm:: GasWeightMapping as _;
795
+
797
796
let config = if estimate {
798
797
let mut config = <Runtime as pallet_evm:: Config >:: config( ) . clone( ) ;
799
798
config. estimate = true ;
@@ -802,20 +801,45 @@ impl_runtime_apis! {
802
801
None
803
802
} ;
804
803
805
- let gas_limit = gas_limit. min( u64 :: MAX . into( ) ) ;
806
- let transaction_data = TransactionData :: new(
807
- TransactionAction :: Call ( to) ,
808
- data. clone( ) ,
809
- nonce. unwrap_or_default( ) ,
810
- gas_limit,
811
- None ,
812
- max_fee_per_gas,
813
- max_priority_fee_per_gas,
814
- value,
815
- Some ( <Runtime as pallet_evm:: Config >:: ChainId :: get( ) ) ,
816
- access_list. clone( ) . unwrap_or_default( ) ,
817
- ) ;
818
- let ( weight_limit, proof_size_base_cost) = pallet_ethereum:: Pallet :: <Runtime >:: transaction_weight( & transaction_data) ;
804
+ // Estimated encoded transaction size must be based on the heaviest transaction
805
+ // type (EIP1559Transaction) to be compatible with all transaction types.
806
+ let mut estimated_transaction_len = data. len( ) +
807
+ // pallet ethereum index: 1
808
+ // transact call index: 1
809
+ // Transaction enum variant: 1
810
+ // chain_id 8 bytes
811
+ // nonce: 32
812
+ // max_priority_fee_per_gas: 32
813
+ // max_fee_per_gas: 32
814
+ // gas_limit: 32
815
+ // action: 21 (enum varianrt + call address)
816
+ // value: 32
817
+ // access_list: 1 (empty vec size)
818
+ // 65 bytes signature
819
+ 258 ;
820
+
821
+ if access_list. is_some( ) {
822
+ estimated_transaction_len += access_list. encoded_size( ) ;
823
+ }
824
+
825
+
826
+ let gas_limit = if gas_limit > U256 :: from( u64 :: MAX ) {
827
+ u64 :: MAX
828
+ } else {
829
+ gas_limit. low_u64( )
830
+ } ;
831
+ let without_base_extrinsic_weight = true ;
832
+
833
+ let ( weight_limit, proof_size_base_cost) =
834
+ match <Runtime as pallet_evm:: Config >:: GasWeightMapping :: gas_to_weight(
835
+ gas_limit,
836
+ without_base_extrinsic_weight
837
+ ) {
838
+ weight_limit if weight_limit. proof_size( ) > 0 => {
839
+ ( Some ( weight_limit) , Some ( estimated_transaction_len as u64 ) )
840
+ }
841
+ _ => ( None , None ) ,
842
+ } ;
819
843
820
844
<Runtime as pallet_evm:: Config >:: Runner :: call(
821
845
from,
@@ -846,6 +870,8 @@ impl_runtime_apis! {
846
870
estimate: bool ,
847
871
access_list: Option <Vec <( H160 , Vec <H256 >) >>,
848
872
) -> Result <pallet_evm:: CreateInfo , sp_runtime:: DispatchError > {
873
+ use pallet_evm:: GasWeightMapping as _;
874
+
849
875
let config = if estimate {
850
876
let mut config = <Runtime as pallet_evm:: Config >:: config( ) . clone( ) ;
851
877
config. estimate = true ;
@@ -854,19 +880,45 @@ impl_runtime_apis! {
854
880
None
855
881
} ;
856
882
857
- let transaction_data = TransactionData :: new(
858
- TransactionAction :: Create ,
859
- data. clone( ) ,
860
- nonce. unwrap_or_default( ) ,
861
- gas_limit,
862
- None ,
863
- max_fee_per_gas,
864
- max_priority_fee_per_gas,
865
- value,
866
- Some ( <Runtime as pallet_evm:: Config >:: ChainId :: get( ) ) ,
867
- access_list. clone( ) . unwrap_or_default( ) ,
868
- ) ;
869
- let ( weight_limit, proof_size_base_cost) = pallet_ethereum:: Pallet :: <Runtime >:: transaction_weight( & transaction_data) ;
883
+
884
+ let mut estimated_transaction_len = data. len( ) +
885
+ // from: 20
886
+ // value: 32
887
+ // gas_limit: 32
888
+ // nonce: 32
889
+ // 1 byte transaction action variant
890
+ // chain id 8 bytes
891
+ // 65 bytes signature
892
+ 190 ;
893
+
894
+ if max_fee_per_gas. is_some( ) {
895
+ estimated_transaction_len += 32 ;
896
+ }
897
+ if max_priority_fee_per_gas. is_some( ) {
898
+ estimated_transaction_len += 32 ;
899
+ }
900
+ if access_list. is_some( ) {
901
+ estimated_transaction_len += access_list. encoded_size( ) ;
902
+ }
903
+
904
+
905
+ let gas_limit = if gas_limit > U256 :: from( u64 :: MAX ) {
906
+ u64 :: MAX
907
+ } else {
908
+ gas_limit. low_u64( )
909
+ } ;
910
+ let without_base_extrinsic_weight = true ;
911
+
912
+ let ( weight_limit, proof_size_base_cost) =
913
+ match <Runtime as pallet_evm:: Config >:: GasWeightMapping :: gas_to_weight(
914
+ gas_limit,
915
+ without_base_extrinsic_weight
916
+ ) {
917
+ weight_limit if weight_limit. proof_size( ) > 0 => {
918
+ ( Some ( weight_limit) , Some ( estimated_transaction_len as u64 ) )
919
+ }
920
+ _ => ( None , None ) ,
921
+ } ;
870
922
871
923
<Runtime as pallet_evm:: Config >:: Runner :: create(
872
924
from,
0 commit comments