mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-31 21:27:12 +00:00
Merge unstable
This commit is contained in:
@@ -31,7 +31,6 @@ mod validator;
|
||||
mod validator_inclusion;
|
||||
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;
|
||||
@@ -45,12 +44,15 @@ pub use block_id::BlockId;
|
||||
use builder_states::get_next_withdrawals;
|
||||
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,
|
||||
};
|
||||
use eth2::{CONSENSUS_VERSION_HEADER, CONTENT_TYPE_HEADER, SSZ_CONTENT_TYPE_HEADER};
|
||||
use health_metrics::observe::Observe;
|
||||
use lighthouse_network::rpc::methods::MetaData;
|
||||
use lighthouse_network::{types::SyncState, EnrExt, NetworkGlobals, PeerId, PubsubMessage};
|
||||
use lighthouse_version::version_with_platform;
|
||||
use logging::SSELoggingComponents;
|
||||
@@ -61,6 +63,7 @@ pub use publish_blocks::{
|
||||
publish_blinded_block, publish_block, reconstruct_block, ProvenancedBlock,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use slog::{crit, debug, error, info, warn, Logger};
|
||||
use slot_clock::SlotClock;
|
||||
use ssz::Encode;
|
||||
@@ -83,11 +86,11 @@ use tokio_stream::{
|
||||
};
|
||||
use types::{
|
||||
fork_versioned_response::EmptyMetadata, Attestation, AttestationData, AttestationShufflingId,
|
||||
AttesterSlashing, BeaconStateError, CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName,
|
||||
ForkVersionedResponse, Hash256, ProposerPreparationData, ProposerSlashing, RelativeEpoch,
|
||||
SignedAggregateAndProof, SignedBlindedBeaconBlock, SignedBlsToExecutionChange,
|
||||
SignedContributionAndProof, SignedInclusionList, SignedValidatorRegistrationData,
|
||||
SignedVoluntaryExit, Slot, SyncCommitteeMessage, SyncContributionData,
|
||||
AttesterSlashing, BeaconStateError, ChainSpec, CommitteeCache, ConfigAndPreset, Epoch, EthSpec,
|
||||
ForkName, ForkVersionedResponse, Hash256, ProposerPreparationData, ProposerSlashing,
|
||||
RelativeEpoch, SignedAggregateAndProof, SignedBlindedBeaconBlock, SignedBlsToExecutionChange,
|
||||
SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot,
|
||||
SyncCommitteeMessage, SyncContributionData, SignedInclusionList
|
||||
};
|
||||
use validator::pubkey_to_validator_index;
|
||||
use version::{
|
||||
@@ -941,9 +944,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
warp_utils::reject::beacon_chain_error(e.into())
|
||||
}
|
||||
_ => warp_utils::reject::unhandled_error(
|
||||
BeaconChainError::from(e),
|
||||
),
|
||||
}
|
||||
})?;
|
||||
|
||||
@@ -1070,7 +1073,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
|
||||
let validators = chain
|
||||
.validator_indices(sync_committee.pubkeys.iter())
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
|
||||
let validator_aggregates = validators
|
||||
.chunks_exact(T::EthSpec::sync_subcommittee_size())
|
||||
@@ -1150,7 +1153,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
let (cached_head, execution_status) = chain
|
||||
.canonical_head
|
||||
.head_and_execution_status()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
(
|
||||
cached_head.head_block_root(),
|
||||
cached_head.snapshot.beacon_block.clone_as_blinded(),
|
||||
@@ -1164,13 +1167,13 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
BlockId::from_root(parent_root).blinded_block(&chain)?;
|
||||
let (root, _slot) = chain
|
||||
.forwards_iter_block_roots(parent.slot())
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?
|
||||
.map_err(warp_utils::reject::unhandled_error)?
|
||||
// Ignore any skip-slots immediately following the parent.
|
||||
.find(|res| {
|
||||
res.as_ref().map_or(false, |(root, _)| *root != parent_root)
|
||||
res.as_ref().is_ok_and(|(root, _)| *root != parent_root)
|
||||
})
|
||||
.transpose()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?
|
||||
.map_err(warp_utils::reject::unhandled_error)?
|
||||
.ok_or_else(|| {
|
||||
warp_utils::reject::custom_not_found(format!(
|
||||
"child of block with root {}",
|
||||
@@ -1251,8 +1254,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
|
||||
let canonical = chain
|
||||
.block_root_at_slot(block.slot(), WhenSlotSkipped::None)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?
|
||||
.map_or(false, |canonical| root == canonical);
|
||||
.map_err(warp_utils::reject::unhandled_error)?
|
||||
.is_some_and(|canonical| root == canonical);
|
||||
|
||||
let data = api_types::BlockHeaderData {
|
||||
root,
|
||||
@@ -1278,6 +1281,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
let consensus_version_header_filter =
|
||||
warp::header::header::<ForkName>(CONSENSUS_VERSION_HEADER);
|
||||
|
||||
let optional_consensus_version_header_filter =
|
||||
warp::header::optional::<ForkName>(CONSENSUS_VERSION_HEADER);
|
||||
|
||||
// POST beacon/blocks
|
||||
let post_beacon_blocks = eth_v1
|
||||
.and(warp::path("beacon"))
|
||||
@@ -1828,32 +1834,86 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(task_spawner_filter.clone())
|
||||
.and(chain_filter.clone());
|
||||
|
||||
let beacon_pool_path_v2 = eth_v2
|
||||
.and(warp::path("beacon"))
|
||||
.and(warp::path("pool"))
|
||||
.and(task_spawner_filter.clone())
|
||||
.and(chain_filter.clone());
|
||||
|
||||
let beacon_pool_path_any = any_version
|
||||
.and(warp::path("beacon"))
|
||||
.and(warp::path("pool"))
|
||||
.and(task_spawner_filter.clone())
|
||||
.and(chain_filter.clone());
|
||||
|
||||
// POST beacon/pool/attestations
|
||||
let post_beacon_pool_attestations = beacon_pool_path_any
|
||||
let post_beacon_pool_attestations_v1 = beacon_pool_path
|
||||
.clone()
|
||||
.and(warp::path("attestations"))
|
||||
.and(warp::path::end())
|
||||
.and(warp_utils::json::json())
|
||||
.and(network_tx_filter.clone())
|
||||
.and(reprocess_send_filter)
|
||||
.and(reprocess_send_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
// V1 and V2 are identical except V2 has a consensus version header in the request.
|
||||
// We only require this header for SSZ deserialization, which isn't supported for
|
||||
// this endpoint presently.
|
||||
|_endpoint_version: EndpointVersion,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
|task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
attestations: Vec<Attestation<T::EthSpec>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
reprocess_tx: Option<Sender<ReprocessQueueMessage>>,
|
||||
log: Logger| async move {
|
||||
let attestations = attestations.into_iter().map(Either::Left).collect();
|
||||
let result = crate::publish_attestations::publish_attestations(
|
||||
task_spawner,
|
||||
chain,
|
||||
attestations,
|
||||
network_tx,
|
||||
reprocess_tx,
|
||||
log,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply::json(&()));
|
||||
convert_rejection(result).await
|
||||
},
|
||||
);
|
||||
|
||||
let post_beacon_pool_attestations_v2 = beacon_pool_path_v2
|
||||
.clone()
|
||||
.and(warp::path("attestations"))
|
||||
.and(warp::path::end())
|
||||
.and(warp_utils::json::json::<Value>())
|
||||
.and(optional_consensus_version_header_filter)
|
||||
.and(network_tx_filter.clone())
|
||||
.and(reprocess_send_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
payload: Value,
|
||||
fork_name: Option<ForkName>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
reprocess_tx: Option<Sender<ReprocessQueueMessage>>,
|
||||
log: Logger| async move {
|
||||
let attestations =
|
||||
match crate::publish_attestations::deserialize_attestation_payload::<T>(
|
||||
payload, fork_name, &log,
|
||||
) {
|
||||
Ok(attestations) => attestations,
|
||||
Err(err) => {
|
||||
warn!(
|
||||
log,
|
||||
"Unable to deserialize attestation POST request";
|
||||
"error" => ?err
|
||||
);
|
||||
return warp::reply::with_status(
|
||||
warp::reply::json(
|
||||
&"Unable to deserialize request body".to_string(),
|
||||
),
|
||||
eth2::StatusCode::BAD_REQUEST,
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
|
||||
let result = crate::publish_attestations::publish_attestations(
|
||||
task_spawner,
|
||||
chain,
|
||||
@@ -2891,36 +2951,24 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(warp::path::end())
|
||||
.and(task_spawner_filter.clone())
|
||||
.and(network_globals.clone())
|
||||
.and(chain_filter.clone())
|
||||
.then(
|
||||
|task_spawner: TaskSpawner<T::EthSpec>,
|
||||
network_globals: Arc<NetworkGlobals<T::EthSpec>>| {
|
||||
network_globals: Arc<NetworkGlobals<T::EthSpec>>,
|
||||
chain: Arc<BeaconChain<T>>| {
|
||||
task_spawner.blocking_json_task(Priority::P1, move || {
|
||||
let enr = network_globals.local_enr();
|
||||
let p2p_addresses = enr.multiaddr_p2p_tcp();
|
||||
let discovery_addresses = enr.multiaddr_p2p_udp();
|
||||
let meta_data = network_globals.local_metadata.read();
|
||||
Ok(api_types::GenericResponse::from(api_types::IdentityData {
|
||||
peer_id: network_globals.local_peer_id().to_base58(),
|
||||
enr,
|
||||
p2p_addresses,
|
||||
discovery_addresses,
|
||||
metadata: api_types::MetaData {
|
||||
seq_number: *meta_data.seq_number(),
|
||||
attnets: format!(
|
||||
"0x{}",
|
||||
hex::encode(meta_data.attnets().clone().into_bytes()),
|
||||
),
|
||||
syncnets: format!(
|
||||
"0x{}",
|
||||
hex::encode(
|
||||
meta_data
|
||||
.syncnets()
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_bytes()
|
||||
)
|
||||
),
|
||||
},
|
||||
metadata: from_meta_data::<T::EthSpec>(
|
||||
&network_globals.local_metadata,
|
||||
&chain.spec,
|
||||
),
|
||||
}))
|
||||
})
|
||||
},
|
||||
@@ -2963,7 +3011,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
let (head, head_execution_status) = chain
|
||||
.canonical_head
|
||||
.head_and_execution_status()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
let head_slot = head.head_slot();
|
||||
let current_slot =
|
||||
chain.slot_clock.now_or_genesis().ok_or_else(|| {
|
||||
@@ -3023,7 +3071,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.blocking_response_task(Priority::P0, move || {
|
||||
let is_optimistic = chain
|
||||
.is_optimistic_or_invalid_head()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
|
||||
let is_syncing = !network_globals.sync_state.read().is_synced();
|
||||
|
||||
@@ -3333,9 +3381,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
task_spawner.blocking_json_task(Priority::P0, move || {
|
||||
not_synced_filter?;
|
||||
|
||||
let current_slot = chain
|
||||
.slot()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
let current_slot = chain.slot().map_err(warp_utils::reject::unhandled_error)?;
|
||||
|
||||
// allow a tolerance of one slot to account for clock skew
|
||||
if query.slot > current_slot + 1 {
|
||||
@@ -3349,7 +3395,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.produce_unaggregated_attestation(query.slot, query.committee_index)
|
||||
.map(|attestation| attestation.data().clone())
|
||||
.map(api_types::GenericResponse::from)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)
|
||||
.map_err(warp_utils::reject::unhandled_error)
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -3544,7 +3590,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
|
||||
let current_slot = chain
|
||||
.slot()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.unwrap();
|
||||
// TODO(focil) unwrap
|
||||
// .map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
|
||||
// allow a tolerance of one slot to account for clock skew
|
||||
//
|
||||
@@ -3560,7 +3608,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.produce_inclusion_list(query.slot)
|
||||
.await
|
||||
.map(api_types::GenericResponse::from)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
// TODO(focil) unwrap
|
||||
.unwrap();
|
||||
// .map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
Ok::<_, warp::reject::Rejection>(warp::reply::json(&data).into_response())
|
||||
})
|
||||
},
|
||||
@@ -3789,11 +3839,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.execution_layer
|
||||
.as_ref()
|
||||
.ok_or(BeaconChainError::ExecutionLayerMissing)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
|
||||
let current_slot = chain
|
||||
.slot()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
let current_slot = chain.slot().map_err(warp_utils::reject::unhandled_error)?;
|
||||
let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
|
||||
debug!(
|
||||
@@ -3846,12 +3894,12 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.execution_layer
|
||||
.as_ref()
|
||||
.ok_or(BeaconChainError::ExecutionLayerMissing)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
let current_slot = chain
|
||||
.slot_clock
|
||||
.now_or_genesis()
|
||||
.ok_or(BeaconChainError::UnableToReadSlot)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
|
||||
debug!(
|
||||
@@ -3947,12 +3995,12 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.execution_layer
|
||||
.as_ref()
|
||||
.ok_or(BeaconChainError::ExecutionLayerMissing)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?
|
||||
.map_err(warp_utils::reject::unhandled_error)?
|
||||
.builder();
|
||||
let builder = arc_builder
|
||||
.as_ref()
|
||||
.ok_or(BeaconChainError::BuilderMissing)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
.map_err(warp_utils::reject::unhandled_error)?;
|
||||
builder
|
||||
.post_builder_validators(&filtered_registration_data)
|
||||
.await
|
||||
@@ -4068,9 +4116,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
chain: Arc<BeaconChain<T>>| {
|
||||
task_spawner.blocking_json_task(Priority::P0, move || {
|
||||
// Ensure the request is for either the current, previous or next epoch.
|
||||
let current_epoch = chain
|
||||
.epoch()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
let current_epoch =
|
||||
chain.epoch().map_err(warp_utils::reject::unhandled_error)?;
|
||||
let prev_epoch = current_epoch.saturating_sub(Epoch::new(1));
|
||||
let next_epoch = current_epoch.saturating_add(Epoch::new(1));
|
||||
|
||||
@@ -4109,9 +4156,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
chain: Arc<BeaconChain<T>>| {
|
||||
task_spawner.blocking_json_task(Priority::P0, move || {
|
||||
// Ensure the request is for either the current, previous or next epoch.
|
||||
let current_epoch = chain
|
||||
.epoch()
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?;
|
||||
let current_epoch =
|
||||
chain.epoch().map_err(warp_utils::reject::unhandled_error)?;
|
||||
let prev_epoch = current_epoch.saturating_sub(Epoch::new(1));
|
||||
let next_epoch = current_epoch.saturating_add(Epoch::new(1));
|
||||
|
||||
@@ -4613,6 +4659,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
api_types::EventTopic::Attestation => {
|
||||
event_handler.subscribe_attestation()
|
||||
}
|
||||
api_types::EventTopic::SingleAttestation => {
|
||||
event_handler.subscribe_single_attestation()
|
||||
}
|
||||
api_types::EventTopic::VoluntaryExit => {
|
||||
event_handler.subscribe_exit()
|
||||
}
|
||||
@@ -4840,7 +4889,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.uor(post_beacon_blinded_blocks)
|
||||
.uor(post_beacon_blocks_v2)
|
||||
.uor(post_beacon_blinded_blocks_v2)
|
||||
.uor(post_beacon_pool_attestations)
|
||||
.uor(post_beacon_pool_attestations_v1)
|
||||
.uor(post_beacon_pool_attestations_v2)
|
||||
.uor(post_beacon_pool_attester_slashings)
|
||||
.uor(post_beacon_pool_proposer_slashings)
|
||||
.uor(post_beacon_pool_voluntary_exits)
|
||||
@@ -4909,6 +4959,39 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
Ok(http_server)
|
||||
}
|
||||
|
||||
fn from_meta_data<E: EthSpec>(
|
||||
meta_data: &RwLock<MetaData<E>>,
|
||||
spec: &ChainSpec,
|
||||
) -> api_types::MetaData {
|
||||
let meta_data = meta_data.read();
|
||||
let format_hex = |bytes: &[u8]| format!("0x{}", hex::encode(bytes));
|
||||
|
||||
let seq_number = *meta_data.seq_number();
|
||||
let attnets = format_hex(&meta_data.attnets().clone().into_bytes());
|
||||
let syncnets = format_hex(
|
||||
&meta_data
|
||||
.syncnets()
|
||||
.cloned()
|
||||
.unwrap_or_default()
|
||||
.into_bytes(),
|
||||
);
|
||||
|
||||
if spec.is_peer_das_scheduled() {
|
||||
api_types::MetaData::V3(api_types::MetaDataV3 {
|
||||
seq_number,
|
||||
attnets,
|
||||
syncnets,
|
||||
custody_group_count: meta_data.custody_group_count().cloned().unwrap_or_default(),
|
||||
})
|
||||
} else {
|
||||
api_types::MetaData::V2(api_types::MetaDataV2 {
|
||||
seq_number,
|
||||
attnets,
|
||||
syncnets,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Publish a message to the libp2p pubsub network.
|
||||
fn publish_pubsub_message<E: EthSpec>(
|
||||
network_tx: &UnboundedSender<NetworkMessage<E>>,
|
||||
|
||||
Reference in New Issue
Block a user