@@ -8,9 +8,11 @@ use alloy_eips::{
88} ;
99use alloy_primitives:: { Bytes , U256 } ;
1010use alloy_rpc_types_engine:: {
11- BlobsBundleV1 , BlobsBundleV2 , ExecutionPayloadEnvelopeV2 , ExecutionPayloadEnvelopeV3 ,
12- ExecutionPayloadEnvelopeV4 , ExecutionPayloadEnvelopeV5 , ExecutionPayloadEnvelopeV6 ,
13- ExecutionPayloadFieldV2 , ExecutionPayloadV1 , ExecutionPayloadV3 , ExecutionPayloadV4 ,
11+ BlobsBundleV1 , BlobsBundleV2 , CancunPayloadFields , ExecutionData , ExecutionPayload ,
12+ ExecutionPayloadEnvelopeV2 , ExecutionPayloadEnvelopeV3 , ExecutionPayloadEnvelopeV4 ,
13+ ExecutionPayloadEnvelopeV5 , ExecutionPayloadEnvelopeV6 , ExecutionPayloadFieldV2 ,
14+ ExecutionPayloadSidecar , ExecutionPayloadV1 , ExecutionPayloadV3 , ExecutionPayloadV4 ,
15+ PraguePayloadFields ,
1416} ;
1517use reth_ethereum_primitives:: EthPrimitives ;
1618use reth_payload_primitives:: BuiltPayload ;
@@ -189,6 +191,39 @@ impl EthBuiltPayload {
189191 execution_requests : requests. unwrap_or_default ( ) ,
190192 } )
191193 }
194+
195+ /// Converts built payload into [`ExecutionData`].
196+ pub fn into_execution_data ( self ) -> ExecutionData {
197+ let Self { block, requests, block_access_list, .. } = self ;
198+ let block_hash = block. hash ( ) ;
199+ let block = Arc :: unwrap_or_clone ( block) . into_block ( ) ;
200+
201+ let ( payload, sidecar) = ExecutionPayload :: from_block_unchecked_with_extras (
202+ block_hash,
203+ & block,
204+ block_access_list,
205+ ) ;
206+
207+ let sidecar = if let Some ( requests) = requests {
208+ block. header . parent_beacon_block_root . map_or ( sidecar, |parent_beacon_block_root| {
209+ ExecutionPayloadSidecar :: v4 (
210+ CancunPayloadFields {
211+ parent_beacon_block_root,
212+ versioned_hashes : block
213+ . body
214+ . blob_versioned_hashes_iter ( )
215+ . copied ( )
216+ . collect ( ) ,
217+ } ,
218+ PraguePayloadFields :: new ( requests) ,
219+ )
220+ } )
221+ } else {
222+ sidecar
223+ } ;
224+
225+ ExecutionData :: new ( payload, sidecar)
226+ }
192227}
193228
194229impl < N : NodePrimitives > BuiltPayload for EthBuiltPayload < N > {
@@ -264,6 +299,12 @@ impl TryFrom<EthBuiltPayload> for ExecutionPayloadEnvelopeV6 {
264299 }
265300}
266301
302+ impl From < EthBuiltPayload > for ExecutionData {
303+ fn from ( value : EthBuiltPayload ) -> Self {
304+ value. into_execution_data ( )
305+ }
306+ }
307+
267308/// An enum representing blob transaction sidecars belonging to [`EthBuiltPayload`].
268309#[ derive( Clone , Default , Debug ) ]
269310pub enum BlobSidecars {
@@ -350,3 +391,62 @@ impl From<alloc::vec::IntoIter<BlobTransactionSidecarEip7594>> for BlobSidecars
350391 value. collect :: < Vec < _ > > ( ) . into ( )
351392 }
352393}
394+
395+ #[ cfg( test) ]
396+ mod tests {
397+ use super :: * ;
398+ use alloy_primitives:: B256 ;
399+ use reth_primitives_traits:: Block as _;
400+
401+ #[ test]
402+ fn into_execution_data_preserves_requests ( ) {
403+ let requests = Requests :: from_requests ( [ Bytes :: from_static ( & [ 1 , 2 ] ) ] ) ;
404+ let parent_beacon_block_root = B256 :: with_last_byte ( 1 ) ;
405+
406+ let mut block = reth_ethereum_primitives:: Block :: default ( ) ;
407+ block. header . parent_beacon_block_root = Some ( parent_beacon_block_root) ;
408+ block. header . requests_hash = Some ( requests. requests_hash ( ) ) ;
409+
410+ let payload = EthBuiltPayload :: new (
411+ Arc :: new ( block. seal_slow ( ) ) ,
412+ U256 :: ZERO ,
413+ Some ( requests. clone ( ) ) ,
414+ None ,
415+ ) ;
416+
417+ let execution_data: ExecutionData = payload. into ( ) ;
418+
419+ assert_eq ! (
420+ execution_data. sidecar. parent_beacon_block_root( ) ,
421+ Some ( parent_beacon_block_root)
422+ ) ;
423+ assert_eq ! ( execution_data. sidecar. requests( ) , Some ( & requests) ) ;
424+ }
425+
426+ #[ test]
427+ fn into_execution_data_preserves_block_access_list ( ) {
428+ let block_access_list = Bytes :: from_static ( & [ 0xc0 ] ) ;
429+
430+ let mut block = reth_ethereum_primitives:: Block :: default ( ) ;
431+ block. header . parent_beacon_block_root = Some ( B256 :: ZERO ) ;
432+ block. header . block_access_list_hash = Some ( B256 :: ZERO ) ;
433+
434+ let payload = EthBuiltPayload :: new (
435+ Arc :: new ( block. seal_slow ( ) ) ,
436+ U256 :: ZERO ,
437+ None ,
438+ Some ( block_access_list. clone ( ) ) ,
439+ ) ;
440+
441+ let execution_data: ExecutionData = payload. into ( ) ;
442+
443+ assert_eq ! ( execution_data. payload. block_access_list( ) , Some ( & block_access_list) ) ;
444+ }
445+
446+ #[ test]
447+ fn execution_data_has_infallible_try_from_impl ( ) {
448+ fn assert_try_from < T : TryFrom < EthBuiltPayload , Error = core:: convert:: Infallible > > ( ) { }
449+
450+ assert_try_from :: < ExecutionData > ( ) ;
451+ }
452+ }
0 commit comments