@@ -694,6 +694,7 @@ where
694
694
value,
695
695
data,
696
696
access_list,
697
+ authorization_list,
697
698
..
698
699
} = request;
699
700
@@ -767,8 +768,8 @@ where
767
768
. map_err ( |err| internal_err ( format ! ( "execution fatal: {err:?}" ) ) ) ?;
768
769
769
770
( info. exit_reason , info. value , info. used_gas )
770
- } else {
771
- // Post-london + access list support
771
+ } else if api_version == 5 {
772
+ // Post-london + access list support (version 5)
772
773
let encoded_params = Encode :: encode ( & (
773
774
& from. unwrap_or_default ( ) ,
774
775
& to,
@@ -821,6 +822,78 @@ where
821
822
. map_err ( |err| internal_err ( format ! ( "execution fatal: {err:?}" ) ) ) ?;
822
823
823
824
( info. exit_reason , info. value , info. used_gas . effective )
825
+ } else if api_version == 6 {
826
+ // Pectra - authorization list support (EIP-7702)
827
+ let access_list = access_list
828
+ . unwrap_or_default ( )
829
+ . into_iter ( )
830
+ . map ( |item| ( item. address , item. storage_keys ) )
831
+ . collect :: < Vec < ( sp_core:: H160 , Vec < H256 > ) > > ( ) ;
832
+
833
+ let authorization_list = authorization_list
834
+ . unwrap_or_default ( )
835
+ . iter ( )
836
+ . map ( |d| {
837
+ (
838
+ U256 :: from ( d. chain_id ) ,
839
+ d. address ,
840
+ d. nonce ,
841
+ d. authorizing_address ( ) ,
842
+ )
843
+ } )
844
+ . collect :: < Vec < ( U256 , H160 , U256 , H160 ) > > ( ) ;
845
+
846
+ let encoded_params = Encode :: encode ( & (
847
+ & from. unwrap_or_default ( ) ,
848
+ & to,
849
+ & data,
850
+ & value. unwrap_or_default ( ) ,
851
+ & gas_limit,
852
+ & max_fee_per_gas,
853
+ & max_priority_fee_per_gas,
854
+ & None :: < Option < U256 > > ,
855
+ & estimate_mode,
856
+ & Some (
857
+ access_list
858
+ ) ,
859
+ & Some ( authorization_list) ,
860
+ ) ) ;
861
+
862
+ // Proof size recording
863
+ let recorder: sp_trie:: recorder:: Recorder < HashingFor < B > > = Default :: default ( ) ;
864
+ let ext = sp_trie:: proof_size_extension:: ProofSizeExt :: new ( recorder. clone ( ) ) ;
865
+ let mut exts = Extensions :: new ( ) ;
866
+ exts. register ( ext) ;
867
+
868
+ let params = CallApiAtParams {
869
+ at : substrate_hash,
870
+ function : "EthereumRuntimeRPCApi_call" ,
871
+ arguments : encoded_params,
872
+ overlayed_changes : & RefCell :: new ( Default :: default ( ) ) ,
873
+ call_context : CallContext :: Offchain ,
874
+ recorder : & Some ( recorder) ,
875
+ extensions : & RefCell :: new ( exts) ,
876
+ } ;
877
+
878
+ let info = self
879
+ . client
880
+ . call_api_at ( params)
881
+ . and_then ( |r| {
882
+ Result :: map_err (
883
+ <Result < ExecutionInfoV2 :: < Vec < u8 > > , DispatchError > as Decode >:: decode ( & mut & r[ ..] ) ,
884
+ |error| sp_api:: ApiError :: FailedToDecodeReturnValue {
885
+ function : "EthereumRuntimeRPCApi_call" ,
886
+ error,
887
+ raw : r
888
+ } ,
889
+ )
890
+ } )
891
+ . map_err ( |err| internal_err ( format ! ( "runtime error: {err}" ) ) ) ?
892
+ . map_err ( |err| internal_err ( format ! ( "execution fatal: {err:?}" ) ) ) ?;
893
+
894
+ ( info. exit_reason , info. value , info. used_gas . effective )
895
+ } else {
896
+ unreachable ! ( "invalid version" ) ;
824
897
}
825
898
}
826
899
None => {
@@ -884,8 +957,8 @@ where
884
957
. map_err ( |err| internal_err ( format ! ( "execution fatal: {err:?}" ) ) ) ?;
885
958
886
959
( info. exit_reason , Vec :: new ( ) , info. used_gas )
887
- } else {
888
- // Post-london + access list support
960
+ } else if api_version == 5 {
961
+ // Post-london + access list support (version 5)
889
962
let encoded_params = Encode :: encode ( & (
890
963
& from. unwrap_or_default ( ) ,
891
964
& data,
@@ -937,6 +1010,77 @@ where
937
1010
. map_err ( |err| internal_err ( format ! ( "execution fatal: {err:?}" ) ) ) ?;
938
1011
939
1012
( info. exit_reason , Vec :: new ( ) , info. used_gas . effective )
1013
+ } else if api_version == 6 {
1014
+ // Pectra - authorization list support (EIP-7702)
1015
+ let access_list = access_list
1016
+ . unwrap_or_default ( )
1017
+ . into_iter ( )
1018
+ . map ( |item| ( item. address , item. storage_keys ) )
1019
+ . collect :: < Vec < ( sp_core:: H160 , Vec < H256 > ) > > ( ) ;
1020
+
1021
+ let authorization_list = authorization_list
1022
+ . unwrap_or_default ( )
1023
+ . iter ( )
1024
+ . map ( |d| {
1025
+ (
1026
+ U256 :: from ( d. chain_id ) ,
1027
+ d. address ,
1028
+ d. nonce ,
1029
+ d. authorizing_address ( ) ,
1030
+ )
1031
+ } )
1032
+ . collect :: < Vec < ( U256 , H160 , U256 , H160 ) > > ( ) ;
1033
+
1034
+ let encoded_params = Encode :: encode ( & (
1035
+ & from. unwrap_or_default ( ) ,
1036
+ & data,
1037
+ & value. unwrap_or_default ( ) ,
1038
+ & gas_limit,
1039
+ & max_fee_per_gas,
1040
+ & max_priority_fee_per_gas,
1041
+ & None :: < Option < U256 > > ,
1042
+ & estimate_mode,
1043
+ & Some (
1044
+ access_list
1045
+ ) ,
1046
+ & Some ( authorization_list) ,
1047
+ ) ) ;
1048
+
1049
+ // Enable proof size recording
1050
+ let recorder: sp_trie:: recorder:: Recorder < HashingFor < B > > = Default :: default ( ) ;
1051
+ let ext = sp_trie:: proof_size_extension:: ProofSizeExt :: new ( recorder. clone ( ) ) ;
1052
+ let mut exts = Extensions :: new ( ) ;
1053
+ exts. register ( ext) ;
1054
+
1055
+ let params = CallApiAtParams {
1056
+ at : substrate_hash,
1057
+ function : "EthereumRuntimeRPCApi_create" ,
1058
+ arguments : encoded_params,
1059
+ overlayed_changes : & RefCell :: new ( Default :: default ( ) ) ,
1060
+ call_context : CallContext :: Offchain ,
1061
+ recorder : & Some ( recorder) ,
1062
+ extensions : & RefCell :: new ( exts) ,
1063
+ } ;
1064
+
1065
+ let info = self
1066
+ . client
1067
+ . call_api_at ( params)
1068
+ . and_then ( |r| {
1069
+ Result :: map_err (
1070
+ <Result < ExecutionInfoV2 :: < H160 > , DispatchError > as Decode >:: decode ( & mut & r[ ..] ) ,
1071
+ |error| sp_api:: ApiError :: FailedToDecodeReturnValue {
1072
+ function : "EthereumRuntimeRPCApi_create" ,
1073
+ error,
1074
+ raw : r
1075
+ } ,
1076
+ )
1077
+ } )
1078
+ . map_err ( |err| internal_err ( format ! ( "runtime error: {err}" ) ) ) ?
1079
+ . map_err ( |err| internal_err ( format ! ( "execution fatal: {err:?}" ) ) ) ?;
1080
+
1081
+ ( info. exit_reason , Vec :: new ( ) , info. used_gas . effective )
1082
+ } else {
1083
+ unreachable ! ( "invalid version" ) ;
940
1084
}
941
1085
}
942
1086
} ;
0 commit comments