Skip to content

Commit f0a03de

Browse files
committed
fix: 🐛 manage API v6 case in Eth::estimate_gas
1 parent a7381c3 commit f0a03de

File tree

1 file changed

+148
-4
lines changed

1 file changed

+148
-4
lines changed

client/rpc/src/eth/execute.rs

Lines changed: 148 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,7 @@ where
694694
value,
695695
data,
696696
access_list,
697+
authorization_list,
697698
..
698699
} = request;
699700

@@ -767,8 +768,8 @@ where
767768
.map_err(|err| internal_err(format!("execution fatal: {err:?}")))?;
768769

769770
(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)
772773
let encoded_params = Encode::encode(&(
773774
&from.unwrap_or_default(),
774775
&to,
@@ -821,6 +822,78 @@ where
821822
.map_err(|err| internal_err(format!("execution fatal: {err:?}")))?;
822823

823824
(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");
824897
}
825898
}
826899
None => {
@@ -884,8 +957,8 @@ where
884957
.map_err(|err| internal_err(format!("execution fatal: {err:?}")))?;
885958

886959
(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)
889962
let encoded_params = Encode::encode(&(
890963
&from.unwrap_or_default(),
891964
&data,
@@ -937,6 +1010,77 @@ where
9371010
.map_err(|err| internal_err(format!("execution fatal: {err:?}")))?;
9381011

9391012
(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");
9401084
}
9411085
}
9421086
};

0 commit comments

Comments
 (0)