Skip to content

Commit

Permalink
feat: add tryfrom payloadv1 for block (#1851)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Dec 27, 2024
1 parent 81f3f0e commit bbab94f
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 6 deletions.
6 changes: 3 additions & 3 deletions crates/consensus/src/proofs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ use alloc::vec::Vec;
use alloy_eips::{eip2718::Encodable2718, eip4895::Withdrawal};
use alloy_primitives::{keccak256, B256};
use alloy_rlp::Encodable;
use alloy_trie::root::{ordered_trie_root, ordered_trie_root_with_encoder};

#[doc(inline)]
pub use alloy_trie::root::{
state_root, state_root_ref_unhashed, state_root_unhashed, state_root_unsorted, storage_root,
storage_root_unhashed, storage_root_unsorted,
ordered_trie_root, ordered_trie_root_with_encoder, state_root, state_root_ref_unhashed,
state_root_unhashed, state_root_unsorted, storage_root, storage_root_unhashed,
storage_root_unsorted,
};

/// Calculate a transaction root.
Expand Down
86 changes: 83 additions & 3 deletions crates/rpc-types-engine/src/payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@ use alloc::{
string::{String, ToString},
vec::Vec,
};
use alloy_consensus::{Blob, Bytes48};
use alloy_consensus::{
constants::MAXIMUM_EXTRA_DATA_SIZE, Blob, Block, BlockBody, Bytes48, Header,
EMPTY_OMMER_ROOT_HASH,
};
use alloy_eips::{
eip4844::BlobTransactionSidecar, eip4895::Withdrawal, eip7685::Requests, BlockNumHash,
eip2718::Decodable2718, eip4844::BlobTransactionSidecar, eip4895::Withdrawal,
eip7685::Requests, BlockNumHash,
};
use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256};
use alloy_primitives::{bytes::BufMut, Address, Bloom, Bytes, B256, B64, U256};
use core::iter::{FromIterator, IntoIterator};

/// The execution payload body response that allows for `null` values.
Expand Down Expand Up @@ -195,6 +199,82 @@ impl ExecutionPayloadV1 {
pub const fn block_num_hash(&self) -> BlockNumHash {
BlockNumHash::new(self.block_number, self.block_hash)
}

/// Converts [`ExecutionPayloadV1`] to [`Block`]
pub fn try_into_block<T: Decodable2718>(self) -> Result<Block<T>, PayloadError> {
if self.extra_data.len() > MAXIMUM_EXTRA_DATA_SIZE {
return Err(PayloadError::ExtraData(self.extra_data));
}

if self.base_fee_per_gas.is_zero() {
return Err(PayloadError::BaseFee(self.base_fee_per_gas));
}

let transactions = self
.transactions
.iter()
.map(|tx| {
let mut buf = tx.as_ref();

let tx = T::decode_2718(&mut buf).map_err(alloy_rlp::Error::from)?;

if !buf.is_empty() {
return Err(alloy_rlp::Error::UnexpectedLength);
}

Ok(tx)
})
.collect::<Result<Vec<_>, _>>()?;

// Reuse the encoded bytes for root calculation
let transactions_root = alloy_consensus::proofs::ordered_trie_root_with_encoder(
&self.transactions,
|item, buf| buf.put_slice(item),
);

let header = Header {
parent_hash: self.parent_hash,
beneficiary: self.fee_recipient,
state_root: self.state_root,
transactions_root,
receipts_root: self.receipts_root,
withdrawals_root: None,
logs_bloom: self.logs_bloom,
number: self.block_number,
gas_limit: self.gas_limit,
gas_used: self.gas_used,
timestamp: self.timestamp,
mix_hash: self.prev_randao,
// WARNING: It’s allowed for a base fee in EIP1559 to increase unbounded. We assume that
// it will fit in an u64. This is not always necessarily true, although it is extremely
// unlikely not to be the case, a u64 maximum would have 2^64 which equates to 18 ETH
// per gas.
base_fee_per_gas: Some(
self.base_fee_per_gas
.try_into()
.map_err(|_| PayloadError::BaseFee(self.base_fee_per_gas))?,
),
blob_gas_used: None,
excess_blob_gas: None,
parent_beacon_block_root: None,
requests_hash: None,
extra_data: self.extra_data,
// Defaults
ommers_hash: EMPTY_OMMER_ROOT_HASH,
difficulty: Default::default(),
nonce: Default::default(),
};

Ok(Block { header, body: BlockBody { transactions, ommers: vec![], withdrawals: None } })
}
}

impl<T: Decodable2718> TryFrom<ExecutionPayloadV1> for Block<T> {
type Error = PayloadError;

fn try_from(value: ExecutionPayloadV1) -> Result<Self, Self::Error> {
value.try_into_block()
}
}

/// This structure maps on the ExecutionPayloadV2 structure of the beacon chain spec.
Expand Down

0 comments on commit bbab94f

Please sign in to comment.