ContextDeserialize and Beacon API Improvements (#7372)

* #7286
* BeaconAPI is not returning a versioned response when it should for some V1 endpoints
* these [strange functions with vX in the name that still accept `endpoint_version` arguments](https://github.com/sigp/lighthouse/blob/stable/beacon_node/http_api/src/produce_block.rs#L192)

This refactor is a prerequisite to get the fulu EF tests running.
This commit is contained in:
ethDreamer
2025-05-19 00:05:16 -05:00
committed by GitHub
parent fcfcbf9a11
commit 7684d1f866
92 changed files with 1863 additions and 827 deletions

View File

@@ -4,7 +4,7 @@ use crate::version::{add_consensus_version_header, V1, V2};
use beacon_chain::{BeaconChain, BeaconChainTypes};
use eth2::types::{self, EndpointVersion, Hash256, Slot};
use std::sync::Arc;
use types::fork_versioned_response::EmptyMetadata;
use types::beacon_response::EmptyMetadata;
use types::{CommitteeIndex, ForkVersionedResponse};
use warp::{
hyper::{Body, Response},
@@ -52,7 +52,7 @@ pub fn get_aggregate_attestation<T: BeaconChainTypes>(
if endpoint_version == V2 {
let fork_versioned_response = ForkVersionedResponse {
version: Some(fork_name),
version: fork_name,
metadata: EmptyMetadata {},
data: aggregate_attestation,
};

View File

@@ -34,7 +34,7 @@ mod validators;
mod version;
use crate::light_client::{get_light_client_bootstrap, get_light_client_updates};
use crate::produce_block::{produce_blinded_block_v2, produce_block_v2, produce_block_v3};
use crate::version::fork_versioned_response;
use crate::version::beacon_response;
use beacon_chain::{
attestation_verification::VerifiedAttestation, observed_operations::ObservationOutcome,
validator_monitor::timestamp_now, AttestationError as AttnError, BeaconChain, BeaconChainError,
@@ -47,9 +47,9 @@ use bytes::Bytes;
use directory::DEFAULT_ROOT_DIR;
use either::Either;
use eth2::types::{
self as api_types, BroadcastValidation, EndpointVersion, ForkChoice, ForkChoiceNode,
LightClientUpdatesQuery, PublishBlockRequest, ValidatorBalancesRequestBody, ValidatorId,
ValidatorStatus, ValidatorsRequestBody,
self as api_types, BroadcastValidation, ContextDeserialize, EndpointVersion, ForkChoice,
ForkChoiceNode, LightClientUpdatesQuery, PublishBlockRequest, ValidatorBalancesRequestBody,
ValidatorId, ValidatorStatus, ValidatorsRequestBody,
};
use eth2::{CONSENSUS_VERSION_HEADER, CONTENT_TYPE_HEADER, SSZ_CONTENT_TYPE_HEADER};
use health_metrics::observe::Observe;
@@ -89,18 +89,17 @@ use tokio_stream::{
use tracing::{debug, error, info, warn};
use types::AttestationData;
use types::{
fork_versioned_response::EmptyMetadata, Attestation, AttestationShufflingId, AttesterSlashing,
BeaconStateError, ChainSpec, Checkpoint, CommitteeCache, ConfigAndPreset, Epoch, EthSpec,
ForkName, ForkVersionedResponse, Hash256, ProposerPreparationData, ProposerSlashing,
RelativeEpoch, SignedAggregateAndProof, SignedBlindedBeaconBlock, SignedBlsToExecutionChange,
SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot,
SyncCommitteeMessage, SyncContributionData,
Attestation, AttestationShufflingId, AttesterSlashing, BeaconStateError, ChainSpec, Checkpoint,
CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, Hash256, ProposerPreparationData,
ProposerSlashing, RelativeEpoch, SignedAggregateAndProof, SignedBlindedBeaconBlock,
SignedBlsToExecutionChange, SignedContributionAndProof, SignedValidatorRegistrationData,
SignedVoluntaryExit, Slot, SyncCommitteeMessage, SyncContributionData,
};
use validator::pubkey_to_validator_index;
use version::{
add_consensus_version_header, add_ssz_content_type_header,
execution_optimistic_finalized_fork_versioned_response, inconsistent_fork_rejection,
unsupported_version_rejection, V1, V2, V3,
execution_optimistic_finalized_beacon_response, inconsistent_fork_rejection,
unsupported_version_rejection, ResponseIncludesVersion, V1, V2, V3,
};
use warp::http::StatusCode;
use warp::hyper::Body;
@@ -1153,8 +1152,8 @@ pub fn serve<T: BeaconChainTypes>(
|state_id: StateId,
task_spawner: TaskSpawner<T::EthSpec>,
chain: Arc<BeaconChain<T>>| {
task_spawner.blocking_json_task(Priority::P1, move || {
let (data, execution_optimistic, finalized) = state_id
task_spawner.blocking_response_task(Priority::P1, move || {
let (data, execution_optimistic, finalized, fork_name) = state_id
.map_state_and_execution_optimistic_and_finalized(
&chain,
|state, execution_optimistic, finalized| {
@@ -1164,15 +1163,23 @@ pub fn serve<T: BeaconChainTypes>(
));
};
Ok((deposits.clone(), execution_optimistic, finalized))
Ok((
deposits.clone(),
execution_optimistic,
finalized,
state.fork_name_unchecked(),
))
},
)?;
Ok(api_types::ExecutionOptimisticFinalizedResponse {
execution_optimistic_finalized_beacon_response(
ResponseIncludesVersion::Yes(fork_name),
execution_optimistic,
finalized,
data,
execution_optimistic: Some(execution_optimistic),
finalized: Some(finalized),
})
)
.map(|res| warp::reply::json(&res).into_response())
.map(|resp| add_consensus_version_header(resp, fork_name))
})
},
);
@@ -1186,8 +1193,8 @@ pub fn serve<T: BeaconChainTypes>(
|state_id: StateId,
task_spawner: TaskSpawner<T::EthSpec>,
chain: Arc<BeaconChain<T>>| {
task_spawner.blocking_json_task(Priority::P1, move || {
let (data, execution_optimistic, finalized) = state_id
task_spawner.blocking_response_task(Priority::P1, move || {
let (data, execution_optimistic, finalized, fork_name) = state_id
.map_state_and_execution_optimistic_and_finalized(
&chain,
|state, execution_optimistic, finalized| {
@@ -1197,15 +1204,23 @@ pub fn serve<T: BeaconChainTypes>(
));
};
Ok((withdrawals.clone(), execution_optimistic, finalized))
Ok((
withdrawals.clone(),
execution_optimistic,
finalized,
state.fork_name_unchecked(),
))
},
)?;
Ok(api_types::ExecutionOptimisticFinalizedResponse {
execution_optimistic_finalized_beacon_response(
ResponseIncludesVersion::Yes(fork_name),
execution_optimistic,
finalized,
data,
execution_optimistic: Some(execution_optimistic),
finalized: Some(finalized),
})
)
.map(|res| warp::reply::json(&res).into_response())
.map(|resp| add_consensus_version_header(resp, fork_name))
})
},
);
@@ -1405,21 +1420,30 @@ pub fn serve<T: BeaconChainTypes>(
.and(warp::path("beacon"))
.and(warp::path("blocks"))
.and(warp::path::end())
.and(warp_utils::json::json())
.and(warp::body::json())
.and(consensus_version_header_filter)
.and(task_spawner_filter.clone())
.and(chain_filter.clone())
.and(network_tx_filter.clone())
.and(network_globals.clone())
.then(
move |block_contents: PublishBlockRequest<T::EthSpec>,
move |value: serde_json::Value,
consensus_version: ForkName,
task_spawner: TaskSpawner<T::EthSpec>,
chain: Arc<BeaconChain<T>>,
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
network_globals: Arc<NetworkGlobals<T::EthSpec>>| {
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
let request = PublishBlockRequest::<T::EthSpec>::context_deserialize(
&value,
consensus_version,
)
.map_err(|e| {
warp_utils::reject::custom_bad_request(format!("invalid JSON: {e:?}"))
})?;
publish_blocks::publish_block(
None,
ProvenancedBlock::local_from_publish_request(block_contents),
ProvenancedBlock::local_from_publish_request(request),
chain,
&network_tx,
BroadcastValidation::default(),
@@ -1475,22 +1499,32 @@ pub fn serve<T: BeaconChainTypes>(
.and(warp::path("blocks"))
.and(warp::query::<api_types::BroadcastValidationQuery>())
.and(warp::path::end())
.and(warp_utils::json::json())
.and(warp::body::json())
.and(consensus_version_header_filter)
.and(task_spawner_filter.clone())
.and(chain_filter.clone())
.and(network_tx_filter.clone())
.and(network_globals.clone())
.then(
move |validation_level: api_types::BroadcastValidationQuery,
block_contents: PublishBlockRequest<T::EthSpec>,
value: serde_json::Value,
consensus_version: ForkName,
task_spawner: TaskSpawner<T::EthSpec>,
chain: Arc<BeaconChain<T>>,
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
network_globals: Arc<NetworkGlobals<T::EthSpec>>| {
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
let request = PublishBlockRequest::<T::EthSpec>::context_deserialize(
&value,
consensus_version,
)
.map_err(|e| {
warp_utils::reject::custom_bad_request(format!("invalid JSON: {e:?}"))
})?;
publish_blocks::publish_block(
None,
ProvenancedBlock::local_from_publish_request(block_contents),
ProvenancedBlock::local_from_publish_request(request),
chain,
&network_tx,
validation_level.broadcast_validation,
@@ -1723,6 +1757,12 @@ pub fn serve<T: BeaconChainTypes>(
.fork_name(&chain.spec)
.map_err(inconsistent_fork_rejection)?;
let require_version = match endpoint_version {
V1 => ResponseIncludesVersion::No,
V2 => ResponseIncludesVersion::Yes(fork_name),
_ => return Err(unsupported_version_rejection(endpoint_version)),
};
match accept_header {
Some(api_types::Accept::Ssz) => Response::builder()
.status(200)
@@ -1734,9 +1774,8 @@ pub fn serve<T: BeaconChainTypes>(
e
))
}),
_ => execution_optimistic_finalized_fork_versioned_response(
endpoint_version,
fork_name,
_ => execution_optimistic_finalized_beacon_response(
require_version,
execution_optimistic,
finalized,
block,
@@ -1796,9 +1835,15 @@ pub fn serve<T: BeaconChainTypes>(
.attestations()
.map(|att| att.clone_as_attestation())
.collect::<Vec<_>>();
let res = execution_optimistic_finalized_fork_versioned_response(
endpoint_version,
fork_name,
let require_version = match endpoint_version {
V1 => ResponseIncludesVersion::No,
V2 => ResponseIncludesVersion::Yes(fork_name),
_ => return Err(unsupported_version_rejection(endpoint_version)),
};
let res = execution_optimistic_finalized_beacon_response(
require_version,
execution_optimistic,
finalized,
&atts,
@@ -1845,9 +1890,8 @@ pub fn serve<T: BeaconChainTypes>(
}),
_ => {
// Post as a V2 endpoint so we return the fork version.
execution_optimistic_finalized_fork_versioned_response(
V2,
fork_name,
execution_optimistic_finalized_beacon_response(
ResponseIncludesVersion::Yes(fork_name),
execution_optimistic,
finalized,
block,
@@ -1901,9 +1945,8 @@ pub fn serve<T: BeaconChainTypes>(
}),
_ => {
// Post as a V2 endpoint so we return the fork version.
let res = execution_optimistic_finalized_fork_versioned_response(
V2,
fork_name,
let res = execution_optimistic_finalized_beacon_response(
ResponseIncludesVersion::Yes(fork_name),
execution_optimistic,
finalized,
&blob_sidecar_list_filtered,
@@ -2063,7 +2106,13 @@ pub fn serve<T: BeaconChainTypes>(
})
.collect::<Vec<_>>();
let res = fork_versioned_response(endpoint_version, fork_name, &attestations)?;
let require_version = match endpoint_version {
V1 => ResponseIncludesVersion::No,
V2 => ResponseIncludesVersion::Yes(fork_name),
_ => return Err(unsupported_version_rejection(endpoint_version)),
};
let res = beacon_response(require_version, &attestations);
Ok(add_consensus_version_header(
warp::reply::json(&res).into_response(),
fork_name,
@@ -2152,7 +2201,13 @@ pub fn serve<T: BeaconChainTypes>(
})
.collect::<Vec<_>>();
let res = fork_versioned_response(endpoint_version, fork_name, &slashings)?;
let require_version = match endpoint_version {
V1 => ResponseIncludesVersion::No,
V2 => ResponseIncludesVersion::Yes(fork_name),
_ => return Err(unsupported_version_rejection(endpoint_version)),
};
let res = beacon_response(require_version, &slashings);
Ok(add_consensus_version_header(
warp::reply::json(&res).into_response(),
fork_name,
@@ -2588,7 +2643,7 @@ pub fn serve<T: BeaconChainTypes>(
let fork_name = chain
.spec
.fork_name_at_slot::<T::EthSpec>(*update.signature_slot());
.fork_name_at_slot::<T::EthSpec>(update.get_slot());
match accept_header {
Some(api_types::Accept::Ssz) => Response::builder()
.status(200)
@@ -2600,11 +2655,10 @@ pub fn serve<T: BeaconChainTypes>(
e
))
}),
_ => Ok(warp::reply::json(&ForkVersionedResponse {
version: Some(fork_name),
metadata: EmptyMetadata {},
data: update,
})
_ => Ok(warp::reply::json(&beacon_response(
ResponseIncludesVersion::Yes(fork_name),
update,
))
.into_response()),
}
.map(|resp| add_consensus_version_header(resp, fork_name))
@@ -2649,11 +2703,10 @@ pub fn serve<T: BeaconChainTypes>(
e
))
}),
_ => Ok(warp::reply::json(&ForkVersionedResponse {
version: Some(fork_name),
metadata: EmptyMetadata {},
data: update,
})
_ => Ok(warp::reply::json(&beacon_response(
ResponseIncludesVersion::Yes(fork_name),
update,
))
.into_response()),
}
.map(|resp| add_consensus_version_header(resp, fork_name))
@@ -2845,7 +2898,7 @@ pub fn serve<T: BeaconChainTypes>(
.and(task_spawner_filter.clone())
.and(chain_filter.clone())
.then(
|endpoint_version: EndpointVersion,
|_endpoint_version: EndpointVersion,
state_id: StateId,
accept_header: Option<api_types::Accept>,
task_spawner: TaskSpawner<T::EthSpec>,
@@ -2889,9 +2942,8 @@ pub fn serve<T: BeaconChainTypes>(
let fork_name = state
.fork_name(&chain.spec)
.map_err(inconsistent_fork_rejection)?;
let res = execution_optimistic_finalized_fork_versioned_response(
endpoint_version,
fork_name,
let res = execution_optimistic_finalized_beacon_response(
ResponseIncludesVersion::Yes(fork_name),
execution_optimistic,
finalized,
&state,
@@ -3372,7 +3424,7 @@ pub fn serve<T: BeaconChainTypes>(
if endpoint_version == V3 {
produce_block_v3(accept_header, chain, slot, query).await
} else {
produce_block_v2(endpoint_version, accept_header, chain, slot, query).await
produce_block_v2(accept_header, chain, slot, query).await
}
})
},
@@ -3402,8 +3454,7 @@ pub fn serve<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>| {
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
not_synced_filter?;
produce_blinded_block_v2(EndpointVersion(2), accept_header, chain, slot, query)
.await
produce_blinded_block_v2(accept_header, chain, slot, query).await
})
},
);

View File

@@ -1,14 +1,15 @@
use crate::version::{
add_consensus_version_header, add_ssz_content_type_header, fork_versioned_response, V1,
add_consensus_version_header, add_ssz_content_type_header, beacon_response,
ResponseIncludesVersion,
};
use beacon_chain::{BeaconChain, BeaconChainError, BeaconChainTypes};
use eth2::types::{
self as api_types, ChainSpec, ForkVersionedResponse, LightClientUpdate,
LightClientUpdateResponseChunk, LightClientUpdateResponseChunkInner, LightClientUpdatesQuery,
self as api_types, ChainSpec, LightClientUpdate, LightClientUpdateResponseChunk,
LightClientUpdateResponseChunkInner, LightClientUpdatesQuery,
};
use ssz::Encode;
use std::sync::Arc;
use types::{ForkName, Hash256, LightClientBootstrap};
use types::{BeaconResponse, ForkName, Hash256, LightClientBootstrap};
use warp::{
hyper::{Body, Response},
reply::Reply,
@@ -52,7 +53,7 @@ pub fn get_light_client_updates<T: BeaconChainTypes>(
let fork_versioned_response = light_client_updates
.iter()
.map(|update| map_light_client_update_to_json_response::<T>(&chain, update.clone()))
.collect::<Result<Vec<ForkVersionedResponse<LightClientUpdate<T::EthSpec>>>, Rejection>>()?;
.collect::<Vec<BeaconResponse<LightClientUpdate<T::EthSpec>>>>();
Ok(warp::reply::json(&fork_versioned_response).into_response())
}
}
@@ -88,10 +89,8 @@ pub fn get_light_client_bootstrap<T: BeaconChainTypes>(
warp_utils::reject::custom_server_error(format!("failed to create response: {}", e))
}),
_ => {
let fork_versioned_response = map_light_client_bootstrap_to_json_response::<T>(
fork_name,
light_client_bootstrap,
)?;
let fork_versioned_response =
map_light_client_bootstrap_to_json_response::<T>(fork_name, light_client_bootstrap);
Ok(warp::reply::json(&fork_versioned_response).into_response())
}
}
@@ -177,17 +176,20 @@ fn map_light_client_update_to_ssz_chunk<T: BeaconChainTypes>(
fn map_light_client_bootstrap_to_json_response<T: BeaconChainTypes>(
fork_name: ForkName,
light_client_bootstrap: LightClientBootstrap<T::EthSpec>,
) -> Result<ForkVersionedResponse<LightClientBootstrap<T::EthSpec>>, Rejection> {
fork_versioned_response(V1, fork_name, light_client_bootstrap)
) -> BeaconResponse<LightClientBootstrap<T::EthSpec>> {
beacon_response(
ResponseIncludesVersion::Yes(fork_name),
light_client_bootstrap,
)
}
fn map_light_client_update_to_json_response<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
light_client_update: LightClientUpdate<T::EthSpec>,
) -> Result<ForkVersionedResponse<LightClientUpdate<T::EthSpec>>, Rejection> {
) -> BeaconResponse<LightClientUpdate<T::EthSpec>> {
let fork_name = chain
.spec
.fork_name_at_slot::<T::EthSpec>(*light_client_update.signature_slot());
fork_versioned_response(V1, fork_name, light_client_update)
beacon_response(ResponseIncludesVersion::Yes(fork_name), light_client_update)
}

View File

@@ -3,15 +3,14 @@ use crate::{
version::{
add_consensus_block_value_header, add_consensus_version_header,
add_execution_payload_blinded_header, add_execution_payload_value_header,
add_ssz_content_type_header, fork_versioned_response, inconsistent_fork_rejection,
add_ssz_content_type_header, beacon_response, inconsistent_fork_rejection,
ResponseIncludesVersion,
},
};
use beacon_chain::{
BeaconBlockResponseWrapper, BeaconChain, BeaconChainTypes, ProduceBlockVerification,
};
use eth2::types::{
self as api_types, EndpointVersion, ProduceBlockV3Metadata, SkipRandaoVerification,
};
use eth2::types::{self as api_types, ProduceBlockV3Metadata, SkipRandaoVerification};
use ssz::Encode;
use std::sync::Arc;
use types::{payload::BlockProductionVersion, *};
@@ -115,7 +114,7 @@ pub fn build_response_v3<T: BeaconChainTypes>(
warp_utils::reject::custom_server_error(format!("failed to create response: {}", e))
}),
_ => Ok(warp::reply::json(&ForkVersionedResponse {
version: Some(fork_name),
version: fork_name,
metadata,
data: block_contents,
})
@@ -129,7 +128,6 @@ pub fn build_response_v3<T: BeaconChainTypes>(
}
pub async fn produce_blinded_block_v2<T: BeaconChainTypes>(
endpoint_version: EndpointVersion,
accept_header: Option<api_types::Accept>,
chain: Arc<BeaconChain<T>>,
slot: Slot,
@@ -155,11 +153,10 @@ pub async fn produce_blinded_block_v2<T: BeaconChainTypes>(
.await
.map_err(warp_utils::reject::unhandled_error)?;
build_response_v2(chain, block_response_type, endpoint_version, accept_header)
build_response_v2(chain, block_response_type, accept_header)
}
pub async fn produce_block_v2<T: BeaconChainTypes>(
endpoint_version: EndpointVersion,
accept_header: Option<api_types::Accept>,
chain: Arc<BeaconChain<T>>,
slot: Slot,
@@ -186,13 +183,12 @@ pub async fn produce_block_v2<T: BeaconChainTypes>(
.await
.map_err(warp_utils::reject::unhandled_error)?;
build_response_v2(chain, block_response_type, endpoint_version, accept_header)
build_response_v2(chain, block_response_type, accept_header)
}
pub fn build_response_v2<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>,
block_response: BeaconBlockResponseWrapper<T::EthSpec>,
endpoint_version: EndpointVersion,
accept_header: Option<api_types::Accept>,
) -> Result<Response<Body>, warp::Rejection> {
let fork_name = block_response
@@ -210,8 +206,10 @@ pub fn build_response_v2<T: BeaconChainTypes>(
.map_err(|e| {
warp_utils::reject::custom_server_error(format!("failed to create response: {}", e))
}),
_ => fork_versioned_response(endpoint_version, fork_name, block_contents)
.map(|response| warp::reply::json(&response).into_response())
.map(|res| add_consensus_version_header(res, fork_name)),
_ => Ok(warp::reply::json(&beacon_response(
ResponseIncludesVersion::Yes(fork_name),
block_contents,
))
.into_response()),
}
}

View File

@@ -5,10 +5,11 @@ use eth2::{
};
use serde::Serialize;
use types::{
fork_versioned_response::{
ExecutionOptimisticFinalizedForkVersionedResponse, ExecutionOptimisticFinalizedMetadata,
beacon_response::{
ExecutionOptimisticFinalizedBeaconResponse, ExecutionOptimisticFinalizedMetadata,
},
ForkName, ForkVersionedResponse, InconsistentFork, Uint256,
BeaconResponse, ForkName, ForkVersionedResponse, InconsistentFork, Uint256,
UnversionedResponse,
};
use warp::reply::{self, Reply, Response};
@@ -16,47 +17,54 @@ pub const V1: EndpointVersion = EndpointVersion(1);
pub const V2: EndpointVersion = EndpointVersion(2);
pub const V3: EndpointVersion = EndpointVersion(3);
pub fn fork_versioned_response<T: Serialize>(
endpoint_version: EndpointVersion,
fork_name: ForkName,
data: T,
) -> Result<ForkVersionedResponse<T>, warp::reject::Rejection> {
let fork_name = if endpoint_version == V1 {
None
} else if endpoint_version == V2 || endpoint_version == V3 {
Some(fork_name)
} else {
return Err(unsupported_version_rejection(endpoint_version));
};
Ok(ForkVersionedResponse {
version: fork_name,
metadata: Default::default(),
data,
})
#[derive(Debug, PartialEq, Clone, Serialize)]
pub enum ResponseIncludesVersion {
Yes(ForkName),
No,
}
pub fn execution_optimistic_finalized_fork_versioned_response<T: Serialize>(
endpoint_version: EndpointVersion,
fork_name: ForkName,
pub fn beacon_response<T: Serialize>(
require_version: ResponseIncludesVersion,
data: T,
) -> BeaconResponse<T> {
match require_version {
ResponseIncludesVersion::Yes(fork_name) => {
BeaconResponse::ForkVersioned(ForkVersionedResponse {
version: fork_name,
metadata: Default::default(),
data,
})
}
ResponseIncludesVersion::No => BeaconResponse::Unversioned(UnversionedResponse {
metadata: Default::default(),
data,
}),
}
}
pub fn execution_optimistic_finalized_beacon_response<T: Serialize>(
require_version: ResponseIncludesVersion,
execution_optimistic: bool,
finalized: bool,
data: T,
) -> Result<ExecutionOptimisticFinalizedForkVersionedResponse<T>, warp::reject::Rejection> {
let fork_name = if endpoint_version == V1 {
None
} else if endpoint_version == V2 {
Some(fork_name)
} else {
return Err(unsupported_version_rejection(endpoint_version));
) -> Result<ExecutionOptimisticFinalizedBeaconResponse<T>, warp::reject::Rejection> {
let metadata = ExecutionOptimisticFinalizedMetadata {
execution_optimistic: Some(execution_optimistic),
finalized: Some(finalized),
};
Ok(ExecutionOptimisticFinalizedForkVersionedResponse {
version: fork_name,
metadata: ExecutionOptimisticFinalizedMetadata {
execution_optimistic: Some(execution_optimistic),
finalized: Some(finalized),
},
data,
})
match require_version {
ResponseIncludesVersion::Yes(fork_name) => {
Ok(BeaconResponse::ForkVersioned(ForkVersionedResponse {
version: fork_name,
metadata,
data,
}))
}
ResponseIncludesVersion::No => Ok(BeaconResponse::Unversioned(UnversionedResponse {
metadata,
data,
})),
}
}
/// Add the 'Content-Type application/octet-stream` header to a response.

View File

@@ -115,10 +115,10 @@ async fn state_by_root_pruned_from_fork_choice() {
.unwrap()
.unwrap();
assert!(response.metadata.finalized.unwrap());
assert!(!response.metadata.execution_optimistic.unwrap());
assert!(response.metadata().finalized.unwrap());
assert!(!response.metadata().execution_optimistic.unwrap());
let mut state = response.data;
let mut state = response.into_data();
assert_eq!(state.update_tree_hash_cache().unwrap(), state_root);
}
}
@@ -846,7 +846,7 @@ pub async fn fork_choice_before_proposal() {
.get_validator_blocks::<E>(slot_d, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.deconstruct()
.0;

View File

@@ -682,7 +682,7 @@ impl ApiTester {
.await
.unwrap()
.unwrap()
.metadata
.metadata()
.finalized
.unwrap();
@@ -719,7 +719,7 @@ impl ApiTester {
.await
.unwrap()
.unwrap()
.metadata
.metadata()
.finalized
.unwrap();
@@ -757,7 +757,7 @@ impl ApiTester {
.await
.unwrap()
.unwrap()
.metadata
.metadata()
.finalized
.unwrap();
@@ -1597,9 +1597,9 @@ impl ApiTester {
let json_result = self.client.get_beacon_blocks(block_id.0).await.unwrap();
if let (Some(json), Some(expected)) = (&json_result, &expected) {
assert_eq!(&json.data, expected.as_ref(), "{:?}", block_id);
assert_eq!(json.data(), expected.as_ref(), "{:?}", block_id);
assert_eq!(
json.version,
json.version(),
Some(expected.fork_name(&self.chain.spec).unwrap())
);
} else {
@@ -1623,8 +1623,8 @@ impl ApiTester {
// Check that the legacy v1 API still works but doesn't return a version field.
let v1_result = self.client.get_beacon_blocks_v1(block_id.0).await.unwrap();
if let (Some(v1_result), Some(expected)) = (&v1_result, &expected) {
assert_eq!(v1_result.version, None);
assert_eq!(&v1_result.data, expected.as_ref());
assert_eq!(v1_result.version(), None);
assert_eq!(v1_result.data(), expected.as_ref());
} else {
assert_eq!(v1_result, None);
assert_eq!(expected, None);
@@ -1685,9 +1685,9 @@ impl ApiTester {
.unwrap();
if let (Some(json), Some(expected)) = (&json_result, &expected) {
assert_eq!(&json.data, expected, "{:?}", block_id);
assert_eq!(json.data(), expected, "{:?}", block_id);
assert_eq!(
json.version,
json.version(),
Some(expected.fork_name(&self.chain.spec).unwrap())
);
} else {
@@ -1750,10 +1750,14 @@ impl ApiTester {
};
let result = match self
.client
.get_blobs::<E>(CoreBlockId::Root(block_root), blob_indices.as_deref())
.get_blobs::<E>(
CoreBlockId::Root(block_root),
blob_indices.as_deref(),
&self.chain.spec,
)
.await
{
Ok(result) => result.unwrap().data,
Ok(result) => result.unwrap().into_data(),
Err(e) => panic!("query failed incorrectly: {e:?}"),
};
@@ -1806,13 +1810,13 @@ impl ApiTester {
match self
.client
.get_blobs::<E>(CoreBlockId::Slot(test_slot), None)
.get_blobs::<E>(CoreBlockId::Slot(test_slot), None, &self.chain.spec)
.await
{
Ok(result) => {
if zero_blobs {
assert_eq!(
&result.unwrap().data[..],
&result.unwrap().into_data()[..],
&[],
"empty blobs are always available"
);
@@ -1844,7 +1848,7 @@ impl ApiTester {
match self
.client
.get_blobs::<E>(CoreBlockId::Slot(test_slot), None)
.get_blobs::<E>(CoreBlockId::Slot(test_slot), None, &self.chain.spec)
.await
{
Ok(result) => panic!("queries for pre-Deneb slots should fail. got: {result:?}"),
@@ -1861,7 +1865,7 @@ impl ApiTester {
.get_beacon_blocks_attestations_v2(block_id.0)
.await
.unwrap()
.map(|res| res.data);
.map(|res| res.into_data());
let expected = block_id.full_block(&self.chain).await.ok().map(
|(block, _execution_optimistic, _finalized)| {
@@ -2071,7 +2075,7 @@ impl ApiTester {
.get_light_client_bootstrap(&self.chain.store, &block_root, 1u64, &self.chain.spec);
assert!(expected.is_ok());
assert_eq!(result.unwrap().data, expected.unwrap().unwrap().0);
assert_eq!(result.unwrap().data(), &expected.unwrap().unwrap().0);
self
}
@@ -2083,7 +2087,7 @@ impl ApiTester {
.get_beacon_light_client_optimistic_update::<E>()
.await
{
Ok(result) => result.map(|res| res.data),
Ok(result) => result.map(|res| res.into_data()),
Err(e) => panic!("query failed incorrectly: {e:?}"),
};
@@ -2102,7 +2106,7 @@ impl ApiTester {
.get_beacon_light_client_finality_update::<E>()
.await
{
Ok(result) => result.map(|res| res.data),
Ok(result) => result.map(|res| res.into_data()),
Err(e) => panic!("query failed incorrectly: {e:?}"),
};
@@ -2133,7 +2137,7 @@ impl ApiTester {
.get_beacon_pool_attestations_v2(None, None)
.await
.unwrap()
.data;
.into_data();
assert_eq!(result, expected);
@@ -2195,7 +2199,7 @@ impl ApiTester {
.get_beacon_pool_attestations_v2(None, Some(0))
.await
.unwrap()
.data;
.into_data();
let mut expected = self.chain.op_pool.get_all_attestations();
expected.extend(self.chain.naive_aggregation_pool.read().iter().cloned());
let expected_committee_index_filtered = expected
@@ -2311,7 +2315,7 @@ impl ApiTester {
.get_beacon_pool_attester_slashings_v2()
.await
.unwrap()
.data;
.into_data();
assert_eq!(result, expected);
self
@@ -2649,9 +2653,9 @@ impl ApiTester {
expected.as_mut().map(|state| state.drop_all_caches());
if let (Some(json), Some(expected)) = (&result_json, &expected) {
assert_eq!(json.data, *expected, "{:?}", state_id);
assert_eq!(json.data(), expected, "{:?}", state_id);
assert_eq!(
json.version,
json.version(),
Some(expected.fork_name(&self.chain.spec).unwrap())
);
} else {
@@ -3157,7 +3161,7 @@ impl ApiTester {
.get_validator_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.deconstruct()
.0;
@@ -3254,7 +3258,7 @@ impl ApiTester {
) {
// Compare fork name to ForkVersionedResponse rather than metadata consensus_version, which
// is deserialized to a dummy value.
assert_eq!(Some(metadata.consensus_version), response.version);
assert_eq!(metadata.consensus_version, response.version);
assert_eq!(ForkName::Base, response.metadata.consensus_version);
assert_eq!(
metadata.execution_payload_blinded,
@@ -3380,7 +3384,7 @@ impl ApiTester {
)
.await
.unwrap()
.data
.into_data()
.deconstruct()
.0;
assert_eq!(block.slot(), slot);
@@ -3494,7 +3498,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data;
.into_data();
let signed_block = block.sign(&sk, &fork, genesis_validators_root, &self.chain.spec);
@@ -3509,7 +3513,7 @@ impl ApiTester {
.await
.unwrap()
.unwrap()
.data;
.into_data();
assert_eq!(head_block.clone_as_blinded(), signed_block);
@@ -3582,7 +3586,7 @@ impl ApiTester {
.await
.unwrap()
.unwrap()
.data;
.into_data();
let signed_block = signed_block_contents.signed_block();
assert_eq!(head_block, **signed_block);
@@ -3605,7 +3609,7 @@ impl ApiTester {
)
.await
.unwrap()
.data;
.into_data();
assert_eq!(blinded_block.slot(), slot);
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
}
@@ -3749,7 +3753,7 @@ impl ApiTester {
.await
.unwrap()
.unwrap()
.data;
.into_data();
let expected = attestation;
assert_eq!(result, expected);
@@ -4323,7 +4327,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4369,7 +4373,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4413,7 +4417,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4487,7 +4491,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4573,7 +4577,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4665,7 +4669,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4755,7 +4759,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4844,7 +4848,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4919,7 +4923,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -4982,7 +4986,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5058,7 +5062,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(next_slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5089,7 +5093,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(next_slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5197,7 +5201,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(next_slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5238,7 +5242,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(next_slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5354,7 +5358,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5435,7 +5439,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5503,7 +5507,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5571,7 +5575,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5638,7 +5642,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()
@@ -5709,7 +5713,7 @@ impl ApiTester {
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.into_data()
.body()
.execution_payload()
.unwrap()