diff --git a/crates/evm/execution-types/src/chain.rs b/crates/evm/execution-types/src/chain.rs index 064cd62a1db0..3a1998cfade7 100644 --- a/crates/evm/execution-types/src/chain.rs +++ b/crates/evm/execution-types/src/chain.rs @@ -8,6 +8,7 @@ use alloy_primitives::{Address, BlockHash, BlockNumber, TxHash}; use core::{fmt, ops::RangeInclusive}; use reth_execution_errors::{BlockExecutionError, InternalBlockExecutionError}; use reth_primitives_traits::{ + serde_bincode_compat::SerdeBincodeCompat, transaction::signed::SignedTransactionIntoRecoveredExt, Block, BlockBody, NodePrimitives, RecoveredBlock, SealedHeader, SignedTransaction, }; @@ -526,7 +527,7 @@ pub enum ChainSplit /// Bincode-compatible [`Chain`] serde implementation. #[cfg(feature = "serde-bincode-compat")] pub(super) mod serde_bincode_compat { - use crate::ExecutionOutcome; + use crate::{ExecutionOutcome, ExecutionOutcomeBincode}; use alloc::borrow::Cow; use alloy_primitives::BlockNumber; use reth_ethereum_primitives::EthPrimitives; @@ -554,15 +555,29 @@ pub(super) mod serde_bincode_compat { /// chain: Chain, /// } /// ``` + // #[derive(Debug, Serialize, Deserialize)] + // pub struct Chain<'a, N = EthPrimitives> + // where + // N: NodePrimitives< + // Block: Block + 'static, + // >, + // { + // blocks: RecoveredBlocks<'a, N::Block>, + // execution_outcome: Cow<'a, ExecutionOutcome>, + // trie_updates: Option>, + // } + #[derive(Debug, Serialize, Deserialize)] pub struct Chain<'a, N = EthPrimitives> where N: NodePrimitives< Block: Block + 'static, + Receipt: SerdeBincodeCompat, >, + ::BincodeRepr<'a>: Clone, { blocks: RecoveredBlocks<'a, N::Block>, - execution_outcome: Cow<'a, ExecutionOutcome>, + execution_outcome: Cow<'a, ExecutionOutcomeBincode<'a, N::Receipt>>, // Use the new type trie_updates: Option>, } @@ -610,12 +625,14 @@ pub(super) mod serde_bincode_compat { where N: NodePrimitives< Block: Block + 'static, + Receipt: SerdeBincodeCompat, >, + ::BincodeRepr<'a>: Clone, { fn from(value: &'a super::Chain) -> Self { Self { blocks: RecoveredBlocks(Cow::Borrowed(&value.blocks)), - execution_outcome: Cow::Borrowed(&value.execution_outcome), + execution_outcome: Cow::Owned(value.execution_outcome.as_repr()), trie_updates: value.trie_updates.as_ref().map(Into::into), } } @@ -625,12 +642,30 @@ pub(super) mod serde_bincode_compat { where N: NodePrimitives< Block: Block + 'static, + Receipt: SerdeBincodeCompat, >, + for<'b> ::BincodeRepr<'b>: Clone, { fn from(value: Chain<'a, N>) -> Self { + let converted_execution_outcome = { + let original = value.execution_outcome.into_owned(); + let converted_receipts = original + .receipts + .into_iter() + .map(|vec| vec.into_iter().map(N::Receipt::from_repr).collect::>()) + .collect::>(); + + ExecutionOutcome { + bundle: original.bundle.into_owned(), + receipts: converted_receipts, + requests: original.requests.into_owned(), + first_block: original.first_block, + } + }; + Self { blocks: value.blocks.0.into_owned(), - execution_outcome: value.execution_outcome.into_owned(), + execution_outcome: converted_execution_outcome, trie_updates: value.trie_updates.map(Into::into), } } @@ -640,7 +675,9 @@ pub(super) mod serde_bincode_compat { where N: NodePrimitives< Block: Block + 'static, + Receipt: SerdeBincodeCompat, >, + for<'a> ::BincodeRepr<'a>: Clone, { fn serialize_as(source: &super::Chain, serializer: S) -> Result where @@ -654,7 +691,9 @@ pub(super) mod serde_bincode_compat { where N: NodePrimitives< Block: Block + 'static, + Receipt: SerdeBincodeCompat, >, + for<'a> ::BincodeRepr<'a>: Clone, { fn deserialize_as(deserializer: D) -> Result, D::Error> where diff --git a/crates/evm/execution-types/src/execution_outcome.rs b/crates/evm/execution-types/src/execution_outcome.rs index fff6d201993c..cd8e91966869 100644 --- a/crates/evm/execution-types/src/execution_outcome.rs +++ b/crates/evm/execution-types/src/execution_outcome.rs @@ -2,10 +2,13 @@ use crate::{BlockExecutionOutput, BlockExecutionResult}; use alloc::{vec, vec::Vec}; use alloy_eips::eip7685::Requests; use alloy_primitives::{logs_bloom, map::HashMap, Address, BlockNumber, Bloom, Log, B256, U256}; -use reth_primitives_traits::{Account, Bytecode, Receipt, StorageEntry}; +use reth_primitives_traits::{ + serde_bincode_compat::SerdeBincodeCompat, Account, Bytecode, Receipt, StorageEntry, +}; use reth_trie_common::{HashedPostState, KeyHasher}; use revm::state::AccountInfo; use revm_database::{states::BundleState, BundleAccount}; +use std::borrow::Cow; /// Represents a changed account #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -49,6 +52,48 @@ pub struct ExecutionOutcome { pub requests: Vec, } +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct ExecutionOutcomeBincode<'a, T: SerdeBincodeCompat + std::fmt::Debug> { + pub bundle: Cow<'a, BundleState>, + pub receipts: Vec>>, + pub first_block: BlockNumber, + pub requests: Cow<'a, Vec>, +} + +impl SerdeBincodeCompat for ExecutionOutcome { + type BincodeRepr<'a> + = ExecutionOutcomeBincode<'a, T> + where + Self: 'a; + + fn as_repr(&self) -> Self::BincodeRepr<'_> { + ExecutionOutcomeBincode { + bundle: Cow::Borrowed(&self.bundle), + receipts: self + .receipts + .iter() + .map(|vec| vec.iter().map(|receipt| T::as_repr(receipt)).collect()) + .collect(), + first_block: self.first_block, + requests: Cow::Borrowed(&self.requests), + } + } + + fn from_repr(repr: Self::BincodeRepr<'_>) -> Self { + ExecutionOutcome { + bundle: repr.bundle.into_owned(), + receipts: repr + .receipts + .into_iter() + .map(|vec| vec.into_iter().map(|receipt| T::from_repr(receipt)).collect()) + .collect(), + first_block: repr.first_block, + requests: repr.requests.into_owned(), + } + } +} + impl Default for ExecutionOutcome { fn default() -> Self { Self {