Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions beacon_node/execution_layer/src/engine_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ use crate::http::{
ENGINE_FORKCHOICE_UPDATED_V1, ENGINE_FORKCHOICE_UPDATED_V2, ENGINE_FORKCHOICE_UPDATED_V3,
ENGINE_FORKCHOICE_UPDATED_V4, ENGINE_GET_BLOBS_V2, ENGINE_GET_CLIENT_VERSION_V1,
ENGINE_GET_INCLUSION_LIST_V1, ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1, ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2,
ENGINE_GET_PAYLOAD_V3, ENGINE_GET_PAYLOAD_V4, ENGINE_GET_PAYLOAD_V5, ENGINE_GET_PAYLOAD_V6,
ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2, ENGINE_NEW_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V4,
ENGINE_NEW_PAYLOAD_V5,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2, ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_GET_PAYLOAD_V1, ENGINE_GET_PAYLOAD_V2, ENGINE_GET_PAYLOAD_V3, ENGINE_GET_PAYLOAD_V4,
ENGINE_GET_PAYLOAD_V5, ENGINE_GET_PAYLOAD_V6, ENGINE_NEW_PAYLOAD_V1, ENGINE_NEW_PAYLOAD_V2,
ENGINE_NEW_PAYLOAD_V3, ENGINE_NEW_PAYLOAD_V4, ENGINE_NEW_PAYLOAD_V5,
};
use eth2::types::{
BlobsBundle, SsePayloadAttributes, SsePayloadAttributesV1, SsePayloadAttributesV2,
Expand All @@ -25,9 +25,9 @@ pub use types::{
Withdrawal, Withdrawals,
};
use types::{
ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
BlockAccessList, ExecutionPayloadBellatrix, ExecutionPayloadCapella, ExecutionPayloadDeneb,
ExecutionPayloadElectra, ExecutionPayloadFulu, ExecutionPayloadGloas, ExecutionPayloadHeze,
ExecutionRequests, KzgProofs,
ExecutionRequests, KzgProofs, ProgressiveTransactions, ProgressiveWithdrawals,
};
use types::{GRAFFITI_BYTES_LEN, Graffiti};

Expand Down Expand Up @@ -449,6 +449,14 @@ pub struct ExecutionPayloadBodyV1<E: EthSpec> {
pub withdrawals: Option<Withdrawals<E>>,
}

/// The execution payload body returned by `engine_getPayloadBodiesByHashV2`.
#[derive(Clone, Debug, PartialEq)]
pub struct ExecutionPayloadBodyV2 {
pub transactions: ProgressiveTransactions,
pub withdrawals: ProgressiveWithdrawals,
pub block_access_list: BlockAccessList,
}

impl<E: EthSpec> ExecutionPayloadBodyV1<E> {
pub fn to_payload(
self,
Expand Down Expand Up @@ -605,6 +613,7 @@ pub struct EngineCapabilities {
pub forkchoice_updated_v3: bool,
pub forkchoice_updated_v4: bool,
pub get_payload_bodies_by_hash_v1: bool,
pub get_payload_bodies_by_hash_v2: bool,
pub get_payload_bodies_by_range_v1: bool,
pub get_payload_v1: bool,
pub get_payload_v2: bool,
Expand Down Expand Up @@ -651,6 +660,9 @@ impl EngineCapabilities {
if self.get_payload_bodies_by_hash_v1 {
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1);
}
if self.get_payload_bodies_by_hash_v2 {
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2);
}
if self.get_payload_bodies_by_range_v1 {
response.push(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1);
}
Expand Down
24 changes: 24 additions & 0 deletions beacon_node/execution_layer/src/engine_api/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub const ENGINE_FORKCHOICE_UPDATED_V4: &str = "engine_forkchoiceUpdatedV4";
pub const ENGINE_FORKCHOICE_UPDATED_TIMEOUT: Duration = Duration::from_secs(8);

pub const ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1: &str = "engine_getPayloadBodiesByHashV1";
pub const ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2: &str = "engine_getPayloadBodiesByHashV2";
pub const ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1: &str = "engine_getPayloadBodiesByRangeV1";
pub const ENGINE_GET_PAYLOAD_BODIES_TIMEOUT: Duration = Duration::from_secs(10);

Expand Down Expand Up @@ -94,6 +95,7 @@ pub static LIGHTHOUSE_CAPABILITIES: &[&str] = &[
ENGINE_FORKCHOICE_UPDATED_V3,
ENGINE_FORKCHOICE_UPDATED_V4,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1,
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2,
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1,
ENGINE_GET_CLIENT_VERSION_V1,
ENGINE_GET_BLOBS_V2,
Expand Down Expand Up @@ -1204,6 +1206,26 @@ impl HttpJsonRpc {
.collect::<Result<Vec<_>, _>>()
}

pub async fn get_payload_bodies_by_hash_v2(
&self,
block_hashes: Vec<ExecutionBlockHash>,
) -> Result<Vec<Option<ExecutionPayloadBodyV2>>, Error> {
let params = json!([block_hashes]);

let response: Vec<Option<JsonExecutionPayloadBodyV2>> = self
.rpc_request(
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2,
params,
ENGINE_GET_PAYLOAD_BODIES_TIMEOUT * self.execution_timeout_multiplier,
)
.await?;

Ok(response
.into_iter()
.map(|body| body.map(Into::into))
.collect())
}

pub async fn get_payload_bodies_by_range_v1<E: EthSpec>(
&self,
start: u64,
Expand Down Expand Up @@ -1255,6 +1277,8 @@ impl HttpJsonRpc {
forkchoice_updated_v4: capabilities.contains(ENGINE_FORKCHOICE_UPDATED_V4),
get_payload_bodies_by_hash_v1: capabilities
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V1),
get_payload_bodies_by_hash_v2: capabilities
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2),
get_payload_bodies_by_range_v1: capabilities
.contains(ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1),
get_payload_v1: capabilities.contains(ENGINE_GET_PAYLOAD_V1),
Expand Down
30 changes: 30 additions & 0 deletions beacon_node/execution_layer/src/engine_api/json_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,36 @@ pub struct JsonExecutionPayloadBodyV1<E: EthSpec> {
pub withdrawals: Option<VariableList<JsonWithdrawal, E::MaxWithdrawalsPerPayload>>,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JsonExecutionPayloadBodyV2 {
#[serde(with = "ssz_types::serde_utils::prog_list_of_hex_prog_var_list")]
pub transactions: ProgressiveTransactions,
pub withdrawals: ProgressiveVariableList<JsonWithdrawal>,
#[serde(with = "ssz_types::serde_utils::hex_prog_var_list")]
pub block_access_list: BlockAccessList,
}

impl From<JsonExecutionPayloadBodyV2> for ExecutionPayloadBodyV2 {
fn from(value: JsonExecutionPayloadBodyV2) -> Self {
Self {
transactions: value.transactions,
withdrawals: value.withdrawals.into_iter().map(Into::into).collect(),
block_access_list: value.block_access_list,
}
}
}

impl From<ExecutionPayloadBodyV2> for JsonExecutionPayloadBodyV2 {
fn from(value: ExecutionPayloadBodyV2) -> Self {
Self {
transactions: value.transactions,
withdrawals: value.withdrawals.into_iter().map(Into::into).collect(),
block_access_list: value.block_access_list,
}
}
}

impl<E: EthSpec> TryFrom<JsonExecutionPayloadBodyV1<E>> for ExecutionPayloadBodyV1<E> {
type Error = ssz_types::Error;

Expand Down
43 changes: 42 additions & 1 deletion beacon_node/execution_layer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1674,6 +1674,20 @@ impl<E: EthSpec> ExecutionLayer<E> {
.map_err(Error::EngineError)
}

/// Fetch Gloas execution payload bodies by block hash.
pub async fn get_payload_bodies_by_hash_v2(
&self,
hashes: Vec<ExecutionBlockHash>,
) -> Result<Vec<Option<ExecutionPayloadBodyV2>>, Error> {
self.engine()
.request(|engine: &Engine| async move {
engine.api.get_payload_bodies_by_hash_v2(hashes).await
})
.await
.map_err(Box::new)
.map_err(Error::EngineError)
}

pub async fn get_payload_bodies_by_range(
&self,
start: u64,
Expand Down Expand Up @@ -2175,7 +2189,7 @@ fn noop<E: EthSpec>(
#[cfg(test)]
mod test {
use super::*;
use crate::test_utils::MockExecutionLayer as GenericMockExecutionLayer;
use crate::test_utils::{Block, MockExecutionLayer as GenericMockExecutionLayer};
use task_executor::test_utils::TestRuntime;
use types::MainnetEthSpec;

Expand All @@ -2193,6 +2207,33 @@ mod test {
.await;
}

#[tokio::test]
async fn get_gloas_payload_bodies_by_hash() {
let runtime = TestRuntime::default();
let mock = MockExecutionLayer::default_params(runtime.task_executor.clone());
let block_hash = ExecutionBlockHash::repeat_byte(0x42);
let payload = ExecutionPayloadGloas {
block_hash,
..Default::default()
};
let expected_body = ExecutionPayloadBodyV2 {
transactions: payload.transactions.clone(),
withdrawals: payload.withdrawals.clone(),
block_access_list: payload.block_access_list.clone(),
};
mock.server
.execution_block_generator()
.insert_block_without_checks(Block::PoS(payload.clone().into()));

let bodies = mock
.el
.get_payload_bodies_by_hash_v2(vec![block_hash, ExecutionBlockHash::zero()])
.await
.expect("payload body request should succeed");

assert_eq!(bodies, vec![Some(expected_body), None]);
}

#[tokio::test]
async fn test_expected_gas_limit() {
let spec = ChainSpec::mainnet();
Expand Down
27 changes: 27 additions & 0 deletions beacon_node/execution_layer/src/test_utils/handle_rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,33 @@ pub async fn handle_rpc<E: EthSpec>(

Ok(serde_json::to_value(response).unwrap())
}
ENGINE_GET_PAYLOAD_BODIES_BY_HASH_V2 => {
let block_hashes = get_param::<Vec<ExecutionBlockHash>>(params, 0)
.map_err(|s| (s, BAD_PARAMS_ERROR_CODE))?;

let mut response = vec![];
for block_hash in block_hashes {
let payload = ctx
.execution_block_generator
.read()
.execution_payload_by_hash(block_hash);

match payload {
Some(ExecutionPayload::Gloas(payload)) => {
response.push(Some(JsonExecutionPayloadBodyV2::from(
ExecutionPayloadBodyV2 {
transactions: payload.transactions,
withdrawals: payload.withdrawals,
block_access_list: payload.block_access_list,
},
)));
}
_ => response.push(None),
}
}

Ok(serde_json::to_value(response).unwrap())
}
ENGINE_GET_PAYLOAD_BODIES_BY_RANGE_V1 => {
#[derive(Deserialize)]
#[serde(transparent)]
Expand Down
1 change: 1 addition & 0 deletions beacon_node/execution_layer/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub const DEFAULT_ENGINE_CAPABILITIES: EngineCapabilities = EngineCapabilities {
forkchoice_updated_v3: true,
forkchoice_updated_v4: true,
get_payload_bodies_by_hash_v1: true,
get_payload_bodies_by_hash_v2: true,
get_payload_bodies_by_range_v1: true,
get_payload_v1: true,
get_payload_v2: true,
Expand Down
Loading