diff --git a/crates/node/src/builder.rs b/crates/node/src/builder.rs index 4acb482..edfc15a 100644 --- a/crates/node/src/builder.rs +++ b/crates/node/src/builder.rs @@ -61,6 +61,7 @@ where pub async fn build_payload( &self, attributes: EvolvePayloadAttributes, + parent_header: SealedHeader, ) -> Result { // Validate attributes attributes @@ -77,15 +78,12 @@ where .with_bundle_update() .build(); - // Get parent header using the client's HeaderProvider trait - let parent_header = self - .client - .header(&attributes.parent_hash) - .map_err(PayloadBuilderError::other)? - .ok_or_else(|| { - PayloadBuilderError::Internal(RethError::Other("Parent header not found".into())) - })?; - let sealed_parent = SealedHeader::new(parent_header, attributes.parent_hash); + debug_assert_eq!( + parent_header.hash(), + attributes.parent_hash, + "parent header mismatch" + ); + let sealed_parent = parent_header; // Create next block environment attributes let gas_limit = attributes.gas_limit.ok_or_else(|| { diff --git a/crates/node/src/payload_service.rs b/crates/node/src/payload_service.rs index 26e9df4..089e3a2 100644 --- a/crates/node/src/payload_service.rs +++ b/crates/node/src/payload_service.rs @@ -141,7 +141,8 @@ where // Convert Engine API attributes to Evolve payload attributes. // If no gas_limit provided, default to the parent header's gas limit (genesis for first block). - let effective_gas_limit = attributes.gas_limit.unwrap_or(parent_header.gas_limit); + let parent_header_ref = parent_header.as_ref(); + let effective_gas_limit = attributes.gas_limit.unwrap_or(parent_header_ref.gas_limit); // Publish effective gas limit for RPC alignment. set_current_block_gas_limit(effective_gas_limit); @@ -164,13 +165,16 @@ where attributes.prev_randao(), fee_recipient, attributes.parent(), - parent_header.number + 1, + parent_header_ref.number + 1, ); // Build the payload using the evolve payload builder - use spawn_blocking for async work. let evolve_builder = self.evolve_builder.clone(); - let sealed_block = tokio::task::block_in_place(|| { - Handle::current().block_on(evolve_builder.build_payload(evolve_attrs)) + let parent_header_for_builder = parent_header_ref.clone(); + let sealed_block = tokio::task::block_in_place(move || { + Handle::current().block_on( + evolve_builder.build_payload(evolve_attrs, parent_header_for_builder), + ) }) .map_err(PayloadBuilderError::other)?; @@ -208,7 +212,8 @@ where // Create empty evolve attributes (no transactions). // If no gas_limit provided, default to the parent header's gas limit (genesis for first block). - let effective_gas_limit = attributes.gas_limit.unwrap_or(parent_header.gas_limit); + let parent_header_ref = parent_header.as_ref(); + let effective_gas_limit = attributes.gas_limit.unwrap_or(parent_header_ref.gas_limit); // Publish effective gas limit for RPC alignment. set_current_block_gas_limit(effective_gas_limit); @@ -231,13 +236,16 @@ where attributes.prev_randao(), fee_recipient, attributes.parent(), - parent_header.number + 1, + parent_header_ref.number + 1, ); // Build empty payload - use spawn_blocking for async work. let evolve_builder = self.evolve_builder.clone(); - let sealed_block = tokio::task::block_in_place(|| { - Handle::current().block_on(evolve_builder.build_payload(evolve_attrs)) + let parent_header_for_builder = parent_header_ref.clone(); + let sealed_block = tokio::task::block_in_place(move || { + Handle::current().block_on( + evolve_builder.build_payload(evolve_attrs, parent_header_for_builder), + ) }) .map_err(PayloadBuilderError::other)?;