Use JsonPayload for payload reconstruction (#3797)

This commit is contained in:
Michael Sproul 2022-12-14 11:52:46 +11:00 committed by GitHub
parent 07d6ef749a
commit 75dd8780e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 46 additions and 20 deletions

View File

@ -1,10 +1,11 @@
use crate::engines::ForkchoiceState; use crate::engines::ForkchoiceState;
pub use ethers_core::types::Transaction; pub use ethers_core::types::Transaction;
use ethers_core::utils::rlp::{Decodable, Rlp}; use ethers_core::utils::rlp::{self, Decodable, Rlp};
use http::deposit_methods::RpcError; use http::deposit_methods::RpcError;
pub use json_structures::TransitionConfigurationV1; pub use json_structures::{JsonWithdrawal, TransitionConfigurationV1};
use reqwest::StatusCode; use reqwest::StatusCode;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::convert::TryFrom;
use strum::IntoStaticStr; use strum::IntoStaticStr;
use superstruct::superstruct; use superstruct::superstruct;
pub use types::{ pub use types::{
@ -46,6 +47,7 @@ pub enum Error {
RequiredMethodUnsupported(&'static str), RequiredMethodUnsupported(&'static str),
UnsupportedForkVariant(String), UnsupportedForkVariant(String),
BadConversion(String), BadConversion(String),
RlpDecoderError(rlp::DecoderError),
} }
impl From<reqwest::Error> for Error { impl From<reqwest::Error> for Error {
@ -79,6 +81,12 @@ impl From<builder_client::Error> for Error {
} }
} }
impl From<rlp::DecoderError> for Error {
fn from(e: rlp::DecoderError) -> Self {
Error::RlpDecoderError(e)
}
}
#[derive(Clone, Copy, Debug, PartialEq, IntoStaticStr)] #[derive(Clone, Copy, Debug, PartialEq, IntoStaticStr)]
#[strum(serialize_all = "snake_case")] #[strum(serialize_all = "snake_case")]
pub enum PayloadStatusV1Status { pub enum PayloadStatusV1Status {
@ -159,12 +167,14 @@ pub struct ExecutionBlockWithTransactions<T: EthSpec> {
pub transactions: Vec<Transaction>, pub transactions: Vec<Transaction>,
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
#[superstruct(only(Capella, Eip4844))] #[superstruct(only(Capella, Eip4844))]
pub withdrawals: Vec<Withdrawal>, pub withdrawals: Vec<JsonWithdrawal>,
} }
impl<T: EthSpec> From<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T> { impl<T: EthSpec> TryFrom<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T> {
fn from(payload: ExecutionPayload<T>) -> Self { type Error = Error;
match payload {
fn try_from(payload: ExecutionPayload<T>) -> Result<Self, Error> {
let json_payload = match payload {
ExecutionPayload::Merge(block) => Self::Merge(ExecutionBlockWithTransactionsMerge { ExecutionPayload::Merge(block) => Self::Merge(ExecutionBlockWithTransactionsMerge {
parent_hash: block.parent_hash, parent_hash: block.parent_hash,
fee_recipient: block.fee_recipient, fee_recipient: block.fee_recipient,
@ -183,8 +193,7 @@ impl<T: EthSpec> From<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T>
.transactions .transactions
.iter() .iter()
.map(|tx| Transaction::decode(&Rlp::new(tx))) .map(|tx| Transaction::decode(&Rlp::new(tx)))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()?,
.unwrap_or_else(|_| Vec::new()),
}), }),
ExecutionPayload::Capella(block) => { ExecutionPayload::Capella(block) => {
Self::Capella(ExecutionBlockWithTransactionsCapella { Self::Capella(ExecutionBlockWithTransactionsCapella {
@ -205,10 +214,12 @@ impl<T: EthSpec> From<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T>
.transactions .transactions
.iter() .iter()
.map(|tx| Transaction::decode(&Rlp::new(tx))) .map(|tx| Transaction::decode(&Rlp::new(tx)))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()?,
.unwrap_or_else(|_| Vec::new()),
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
withdrawals: block.withdrawals.into(), withdrawals: Vec::from(block.withdrawals)
.into_iter()
.map(|withdrawal| withdrawal.into())
.collect(),
}) })
} }
ExecutionPayload::Eip4844(block) => { ExecutionPayload::Eip4844(block) => {
@ -231,13 +242,16 @@ impl<T: EthSpec> From<ExecutionPayload<T>> for ExecutionBlockWithTransactions<T>
.transactions .transactions
.iter() .iter()
.map(|tx| Transaction::decode(&Rlp::new(tx))) .map(|tx| Transaction::decode(&Rlp::new(tx)))
.collect::<Result<Vec<_>, _>>() .collect::<Result<Vec<_>, _>>()?,
.unwrap_or_else(|_| Vec::new()),
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
withdrawals: block.withdrawals.into(), withdrawals: Vec::from(block.withdrawals)
.into_iter()
.map(|withdrawal| withdrawal.into())
.collect(),
}) })
} }
} };
Ok(json_payload)
} }
} }

View File

@ -1622,8 +1622,14 @@ impl<T: EthSpec> ExecutionLayer<T> {
} }
ExecutionBlockWithTransactions::Capella(capella_block) => { ExecutionBlockWithTransactions::Capella(capella_block) => {
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
let withdrawals = VariableList::new(capella_block.withdrawals.clone()) let withdrawals = VariableList::new(
.map_err(ApiError::DeserializeWithdrawals)?; capella_block
.withdrawals
.into_iter()
.map(|w| w.into())
.collect(),
)
.map_err(ApiError::DeserializeWithdrawals)?;
ExecutionPayload::Capella(ExecutionPayloadCapella { ExecutionPayload::Capella(ExecutionPayloadCapella {
parent_hash: capella_block.parent_hash, parent_hash: capella_block.parent_hash,
@ -1646,8 +1652,14 @@ impl<T: EthSpec> ExecutionLayer<T> {
} }
ExecutionBlockWithTransactions::Eip4844(eip4844_block) => { ExecutionBlockWithTransactions::Eip4844(eip4844_block) => {
#[cfg(feature = "withdrawals")] #[cfg(feature = "withdrawals")]
let withdrawals = VariableList::new(eip4844_block.withdrawals.clone()) let withdrawals = VariableList::new(
.map_err(ApiError::DeserializeWithdrawals)?; eip4844_block
.withdrawals
.into_iter()
.map(|w| w.into())
.collect(),
)
.map_err(ApiError::DeserializeWithdrawals)?;
ExecutionPayload::Eip4844(ExecutionPayloadEip4844 { ExecutionPayload::Eip4844(ExecutionPayloadEip4844 {
parent_hash: eip4844_block.parent_hash, parent_hash: eip4844_block.parent_hash,

View File

@ -76,7 +76,7 @@ impl<T: EthSpec> Block<T> {
pub fn as_execution_block_with_tx(&self) -> Option<ExecutionBlockWithTransactions<T>> { pub fn as_execution_block_with_tx(&self) -> Option<ExecutionBlockWithTransactions<T>> {
match self { match self {
Block::PoS(payload) => Some(payload.clone().into()), Block::PoS(payload) => Some(payload.clone().try_into().unwrap()),
Block::PoW(_) => None, Block::PoW(_) => None,
} }
} }