fix: use proper type for engine_newPayloadV2 (#4630)

This commit is contained in:
Dan Cline
2023-09-18 13:02:28 -04:00
committed by GitHub
parent 20455d0550
commit cabb5bee24
3 changed files with 110 additions and 8 deletions

View File

@ -3,7 +3,7 @@ use reth_primitives::{Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, H256
use reth_rpc_types::{ use reth_rpc_types::{
engine::{ engine::{
ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3,
ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, ForkchoiceState, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3, ForkchoiceState,
ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration, ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration,
}, },
state::StateOverride, state::StateOverride,
@ -18,9 +18,9 @@ pub trait EngineApi {
#[method(name = "newPayloadV1")] #[method(name = "newPayloadV1")]
async fn new_payload_v1(&self, payload: ExecutionPayloadV1) -> RpcResult<PayloadStatus>; async fn new_payload_v1(&self, payload: ExecutionPayloadV1) -> RpcResult<PayloadStatus>;
/// See also <https://github.com/ethereum/execution-apis/blob/6709c2a795b707202e93c4f2867fa0bf2640a84f/src/engine/shanghai.md#engine_newpayloadv2> /// See also <https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2>
#[method(name = "newPayloadV2")] #[method(name = "newPayloadV2")]
async fn new_payload_v2(&self, payload: ExecutionPayloadV2) -> RpcResult<PayloadStatus>; async fn new_payload_v2(&self, payload: ExecutionPayloadInputV2) -> RpcResult<PayloadStatus>;
/// Post Cancun payload handler /// Post Cancun payload handler
/// ///

View File

@ -11,7 +11,7 @@ use reth_provider::{BlockReader, EvmEnvProvider, HeaderProvider, StateProviderFa
use reth_rpc_api::EngineApiServer; use reth_rpc_api::EngineApiServer;
use reth_rpc_types::engine::{ use reth_rpc_types::engine::{
CancunPayloadFields, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2, CancunPayloadFields, ExecutionPayload, ExecutionPayloadBodiesV1, ExecutionPayloadEnvelopeV2,
ExecutionPayloadEnvelopeV3, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, ExecutionPayloadEnvelopeV3, ExecutionPayloadInputV2, ExecutionPayloadV1, ExecutionPayloadV3,
ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration, ForkchoiceUpdated, PayloadAttributes, PayloadId, PayloadStatus, TransitionConfiguration,
CAPABILITIES, CAPABILITIES,
}; };
@ -79,10 +79,10 @@ where
Ok(self.inner.beacon_consensus.new_payload(payload, None).await?) Ok(self.inner.beacon_consensus.new_payload(payload, None).await?)
} }
/// See also <https://github.com/ethereum/execution-apis/blob/3d627c95a4d3510a8187dd02e0250ecb4331d27e/src/engine/shanghai.md#engine_newpayloadv2> /// See also <https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2>
pub async fn new_payload_v2( pub async fn new_payload_v2(
&self, &self,
payload: ExecutionPayloadV2, payload: ExecutionPayloadInputV2,
) -> EngineApiResult<PayloadStatus> { ) -> EngineApiResult<PayloadStatus> {
let payload = ExecutionPayload::from(payload); let payload = ExecutionPayload::from(payload);
let payload_or_attrs = PayloadOrAttributes::from_execution_payload(&payload, None); let payload_or_attrs = PayloadOrAttributes::from_execution_payload(&payload, None);
@ -592,8 +592,8 @@ where
} }
/// Handler for `engine_newPayloadV2` /// Handler for `engine_newPayloadV2`
/// See also <https://github.com/ethereum/execution-apis/blob/3d627c95a4d3510a8187dd02e0250ecb4331d27e/src/engine/shanghai.md#engine_newpayloadv2> /// See also <https://github.com/ethereum/execution-apis/blob/584905270d8ad665718058060267061ecfd79ca5/src/engine/shanghai.md#engine_newpayloadv2>
async fn new_payload_v2(&self, payload: ExecutionPayloadV2) -> RpcResult<PayloadStatus> { async fn new_payload_v2(&self, payload: ExecutionPayloadInputV2) -> RpcResult<PayloadStatus> {
trace!(target: "rpc::engine", "Serving engine_newPayloadV2"); trace!(target: "rpc::engine", "Serving engine_newPayloadV2");
Ok(EngineApi::new_payload_v2(self, payload).await?) Ok(EngineApi::new_payload_v2(self, payload).await?)
} }

View File

@ -71,6 +71,48 @@ impl From<SealedBlock> for ExecutionPayloadFieldV2 {
} }
} }
impl From<ExecutionPayloadFieldV2> for ExecutionPayload {
fn from(value: ExecutionPayloadFieldV2) -> Self {
match value {
ExecutionPayloadFieldV2::V1(payload) => ExecutionPayload::V1(payload),
ExecutionPayloadFieldV2::V2(payload) => ExecutionPayload::V2(payload),
}
}
}
/// This is the input to `engine_newPayloadV2`, which may or may not have a withdrawals field.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExecutionPayloadInputV2 {
/// The V1 execution payload
#[serde(flatten)]
pub execution_payload: ExecutionPayloadV1,
/// The payload withdrawals
#[serde(default, skip_serializing_if = "Option::is_none")]
pub withdrawals: Option<Vec<Withdrawal>>,
}
impl From<ExecutionPayloadInputV2> for ExecutionPayload {
fn from(value: ExecutionPayloadInputV2) -> Self {
match value.withdrawals {
Some(withdrawals) => ExecutionPayload::V2(ExecutionPayloadV2 {
payload_inner: value.execution_payload,
withdrawals,
}),
None => ExecutionPayload::V1(value.execution_payload),
}
}
}
impl From<SealedBlock> for ExecutionPayloadInputV2 {
fn from(value: SealedBlock) -> Self {
ExecutionPayloadInputV2 {
withdrawals: value.withdrawals.clone(),
execution_payload: value.into(),
}
}
}
/// This structure maps for the return value of `engine_getPayload` of the beacon chain spec, for /// This structure maps for the return value of `engine_getPayload` of the beacon chain spec, for
/// V2. /// V2.
/// ///
@ -898,4 +940,64 @@ mod tests {
let envelope: ExecutionPayloadEnvelopeV3 = serde_json::from_str(response).unwrap(); let envelope: ExecutionPayloadEnvelopeV3 = serde_json::from_str(response).unwrap();
assert_eq!(serde_json::to_string(&envelope).unwrap(), response); assert_eq!(serde_json::to_string(&envelope).unwrap(), response);
} }
#[test]
fn serde_deserialize_execution_payload_input_v2() {
let response = r#"
{
"baseFeePerGas": "0x173b30b3",
"blockHash": "0x99d486755fd046ad0bbb60457bac93d4856aa42fa00629cc7e4a28b65b5f8164",
"blockNumber": "0xb",
"extraData": "0xd883010d01846765746888676f312e32302e33856c696e7578",
"feeRecipient": "0x0000000000000000000000000000000000000000",
"gasLimit": "0x405829",
"gasUsed": "0x3f0ca0",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0xfe34aaa2b869c66a727783ee5ad3e3983b6ef22baf24a1e502add94e7bcac67a",
"prevRandao": "0x74132c32fe3ab9a470a8352544514d21b6969e7749f97742b53c18a1b22b396c",
"receiptsRoot": "0x6a5c41dc55a1bd3e74e7f6accc799efb08b00c36c15265058433fcea6323e95f",
"stateRoot": "0xde3b357f5f099e4c33d0343c9e9d204d663d7bd9c65020a38e5d0b2a9ace78a2",
"timestamp": "0x6507d6b4",
"transactions": [
"0xf86d0a8458b20efd825208946177843db3138ae69679a54b95cf345ed759450d8806f3e8d87878800080820a95a0f8bddb1dcc4558b532ff747760a6f547dd275afdbe7bdecc90680e71de105757a014f34ba38c180913c0543b0ac2eccfb77cc3f801a535008dc50e533fbe435f53",
"0xf86d0b8458b20efd82520894687704db07e902e9a8b3754031d168d46e3d586e8806f3e8d87878800080820a95a0e3108f710902be662d5c978af16109961ffaf2ac4f88522407d40949a9574276a0205719ed21889b42ab5c1026d40b759a507c12d92db0d100fa69e1ac79137caa",
"0xf86d0c8458b20efd8252089415e6a5a2e131dd5467fa1ff3acd104f45ee5940b8806f3e8d87878800080820a96a0af556ba9cda1d686239e08c24e169dece7afa7b85e0948eaa8d457c0561277fca029da03d3af0978322e54ac7e8e654da23934e0dd839804cb0430f8aaafd732dc",
"0xf8521784565adcb7830186a0808080820a96a0ec782872a673a9fe4eff028a5bdb30d6b8b7711f58a187bf55d3aec9757cb18ea001796d373da76f2b0aeda72183cce0ad070a4f03aa3e6fee4c757a9444245206",
"0xf8521284565adcb7830186a0808080820a95a08a0ea89028eff02596b385a10e0bd6ae098f3b281be2c95a9feb1685065d7384a06239d48a72e4be767bd12f317dd54202f5623a33e71e25a87cb25dd781aa2fc8",
"0xf8521384565adcb7830186a0808080820a95a0784dbd311a82f822184a46f1677a428cbe3a2b88a798fb8ad1370cdbc06429e8a07a7f6a0efd428e3d822d1de9a050b8a883938b632185c254944dd3e40180eb79"
],
"withdrawals": []
}
"#;
let payload: ExecutionPayloadInputV2 = serde_json::from_str(response).unwrap();
assert_eq!(payload.withdrawals, Some(vec![]));
let response = r#"
{
"baseFeePerGas": "0x173b30b3",
"blockHash": "0x99d486755fd046ad0bbb60457bac93d4856aa42fa00629cc7e4a28b65b5f8164",
"blockNumber": "0xb",
"extraData": "0xd883010d01846765746888676f312e32302e33856c696e7578",
"feeRecipient": "0x0000000000000000000000000000000000000000",
"gasLimit": "0x405829",
"gasUsed": "0x3f0ca0",
"logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"parentHash": "0xfe34aaa2b869c66a727783ee5ad3e3983b6ef22baf24a1e502add94e7bcac67a",
"prevRandao": "0x74132c32fe3ab9a470a8352544514d21b6969e7749f97742b53c18a1b22b396c",
"receiptsRoot": "0x6a5c41dc55a1bd3e74e7f6accc799efb08b00c36c15265058433fcea6323e95f",
"stateRoot": "0xde3b357f5f099e4c33d0343c9e9d204d663d7bd9c65020a38e5d0b2a9ace78a2",
"timestamp": "0x6507d6b4",
"transactions": [
"0xf86d0a8458b20efd825208946177843db3138ae69679a54b95cf345ed759450d8806f3e8d87878800080820a95a0f8bddb1dcc4558b532ff747760a6f547dd275afdbe7bdecc90680e71de105757a014f34ba38c180913c0543b0ac2eccfb77cc3f801a535008dc50e533fbe435f53",
"0xf86d0b8458b20efd82520894687704db07e902e9a8b3754031d168d46e3d586e8806f3e8d87878800080820a95a0e3108f710902be662d5c978af16109961ffaf2ac4f88522407d40949a9574276a0205719ed21889b42ab5c1026d40b759a507c12d92db0d100fa69e1ac79137caa",
"0xf86d0c8458b20efd8252089415e6a5a2e131dd5467fa1ff3acd104f45ee5940b8806f3e8d87878800080820a96a0af556ba9cda1d686239e08c24e169dece7afa7b85e0948eaa8d457c0561277fca029da03d3af0978322e54ac7e8e654da23934e0dd839804cb0430f8aaafd732dc",
"0xf8521784565adcb7830186a0808080820a96a0ec782872a673a9fe4eff028a5bdb30d6b8b7711f58a187bf55d3aec9757cb18ea001796d373da76f2b0aeda72183cce0ad070a4f03aa3e6fee4c757a9444245206",
"0xf8521284565adcb7830186a0808080820a95a08a0ea89028eff02596b385a10e0bd6ae098f3b281be2c95a9feb1685065d7384a06239d48a72e4be767bd12f317dd54202f5623a33e71e25a87cb25dd781aa2fc8",
"0xf8521384565adcb7830186a0808080820a95a0784dbd311a82f822184a46f1677a428cbe3a2b88a798fb8ad1370cdbc06429e8a07a7f6a0efd428e3d822d1de9a050b8a883938b632185c254944dd3e40180eb79"
]
}
"#;
let payload: ExecutionPayloadInputV2 = serde_json::from_str(response).unwrap();
assert_eq!(payload.withdrawals, None);
}
} }