mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-14 10:22:38 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -3,13 +3,13 @@ use eth2::lighthouse::{BlockReward, BlockRewardsQuery};
|
||||
use lru::LruCache;
|
||||
use slog::{debug, warn, Logger};
|
||||
use state_processing::BlockReplayer;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::Arc;
|
||||
use types::beacon_block::BlindedBeaconBlock;
|
||||
use warp_utils::reject::{
|
||||
beacon_chain_error, beacon_state_error, custom_bad_request, custom_server_error,
|
||||
};
|
||||
use types::non_zero_usize::new_non_zero_usize;
|
||||
use warp_utils::reject::{beacon_chain_error, beacon_state_error, custom_bad_request};
|
||||
|
||||
const STATE_CACHE_SIZE: usize = 2;
|
||||
const STATE_CACHE_SIZE: NonZeroUsize = new_non_zero_usize(2);
|
||||
|
||||
/// Fetch block rewards for blocks from the canonical chain.
|
||||
pub fn get_block_rewards<T: BeaconChainTypes>(
|
||||
@@ -164,11 +164,7 @@ pub fn compute_block_rewards<T: BeaconChainTypes>(
|
||||
.build_all_committee_caches(&chain.spec)
|
||||
.map_err(beacon_state_error)?;
|
||||
|
||||
state_cache
|
||||
.get_or_insert((parent_root, block.slot()), || state)
|
||||
.ok_or_else(|| {
|
||||
custom_server_error("LRU cache insert should always succeed".into())
|
||||
})?
|
||||
state_cache.get_or_insert((parent_root, block.slot()), || state)
|
||||
};
|
||||
|
||||
// Compute block reward.
|
||||
|
||||
@@ -76,12 +76,12 @@ use tokio_stream::{
|
||||
StreamExt,
|
||||
};
|
||||
use types::{
|
||||
Attestation, AttestationData, AttestationShufflingId, AttesterSlashing, BeaconStateError,
|
||||
CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, ForkVersionedResponse, Hash256,
|
||||
ProposerPreparationData, ProposerSlashing, RelativeEpoch, SignedAggregateAndProof,
|
||||
SignedBlindedBeaconBlock, SignedBlsToExecutionChange, SignedContributionAndProof,
|
||||
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncCommitteeMessage,
|
||||
SyncContributionData,
|
||||
fork_versioned_response::EmptyMetadata, Attestation, AttestationData, AttestationShufflingId,
|
||||
AttesterSlashing, BeaconStateError, CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName,
|
||||
ForkVersionedResponse, Hash256, ProposerPreparationData, ProposerSlashing, RelativeEpoch,
|
||||
SignedAggregateAndProof, SignedBlindedBeaconBlock, SignedBlsToExecutionChange,
|
||||
SignedContributionAndProof, SignedValidatorRegistrationData, SignedVoluntaryExit, Slot,
|
||||
SyncCommitteeMessage, SyncContributionData,
|
||||
};
|
||||
use validator::pubkey_to_validator_index;
|
||||
use version::{
|
||||
@@ -2397,6 +2397,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
}),
|
||||
_ => Ok(warp::reply::json(&ForkVersionedResponse {
|
||||
version: Some(fork_name),
|
||||
metadata: EmptyMetadata {},
|
||||
data: bootstrap,
|
||||
})
|
||||
.into_response()),
|
||||
@@ -2444,6 +2445,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
}),
|
||||
_ => Ok(warp::reply::json(&ForkVersionedResponse {
|
||||
version: Some(fork_name),
|
||||
metadata: EmptyMetadata {},
|
||||
data: update,
|
||||
})
|
||||
.into_response()),
|
||||
@@ -2491,6 +2493,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
}),
|
||||
_ => Ok(warp::reply::json(&ForkVersionedResponse {
|
||||
version: Some(fork_name),
|
||||
metadata: EmptyMetadata {},
|
||||
data: update,
|
||||
})
|
||||
.into_response()),
|
||||
@@ -3191,7 +3194,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
);
|
||||
|
||||
if endpoint_version == V3 {
|
||||
produce_block_v3(endpoint_version, accept_header, chain, slot, query).await
|
||||
produce_block_v3(accept_header, chain, slot, query).await
|
||||
} else {
|
||||
produce_block_v2(endpoint_version, accept_header, chain, slot, query).await
|
||||
}
|
||||
|
||||
@@ -1,17 +1,3 @@
|
||||
use bytes::Bytes;
|
||||
use std::sync::Arc;
|
||||
use types::{payload::BlockProductionVersion, *};
|
||||
|
||||
use beacon_chain::{
|
||||
BeaconBlockResponseWrapper, BeaconChain, BeaconChainTypes, ProduceBlockVerification,
|
||||
};
|
||||
use eth2::types::{self as api_types, EndpointVersion, SkipRandaoVerification};
|
||||
use ssz::Encode;
|
||||
use warp::{
|
||||
hyper::{Body, Response},
|
||||
Reply,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
build_block_contents,
|
||||
version::{
|
||||
@@ -20,6 +6,20 @@ use crate::{
|
||||
fork_versioned_response, inconsistent_fork_rejection,
|
||||
},
|
||||
};
|
||||
use beacon_chain::{
|
||||
BeaconBlockResponseWrapper, BeaconChain, BeaconChainTypes, ProduceBlockVerification,
|
||||
};
|
||||
use bytes::Bytes;
|
||||
use eth2::types::{
|
||||
self as api_types, EndpointVersion, ProduceBlockV3Metadata, SkipRandaoVerification,
|
||||
};
|
||||
use ssz::Encode;
|
||||
use std::sync::Arc;
|
||||
use types::{payload::BlockProductionVersion, *};
|
||||
use warp::{
|
||||
hyper::{Body, Response},
|
||||
Reply,
|
||||
};
|
||||
|
||||
pub fn get_randao_verification(
|
||||
query: &api_types::ValidatorBlocksQuery,
|
||||
@@ -40,7 +40,6 @@ pub fn get_randao_verification(
|
||||
}
|
||||
|
||||
pub async fn produce_block_v3<T: BeaconChainTypes>(
|
||||
endpoint_version: EndpointVersion,
|
||||
accept_header: Option<api_types::Accept>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
slot: Slot,
|
||||
@@ -59,8 +58,9 @@ pub async fn produce_block_v3<T: BeaconChainTypes>(
|
||||
.produce_block_with_verification(
|
||||
randao_reveal,
|
||||
slot,
|
||||
query.graffiti.map(Into::into),
|
||||
query.graffiti,
|
||||
randao_verification,
|
||||
query.builder_boost_factor,
|
||||
BlockProductionVersion::V3,
|
||||
)
|
||||
.await
|
||||
@@ -68,22 +68,28 @@ pub async fn produce_block_v3<T: BeaconChainTypes>(
|
||||
warp_utils::reject::custom_bad_request(format!("failed to fetch a block: {:?}", e))
|
||||
})?;
|
||||
|
||||
build_response_v3(chain, block_response_type, endpoint_version, accept_header)
|
||||
build_response_v3(chain, block_response_type, accept_header)
|
||||
}
|
||||
|
||||
pub fn build_response_v3<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
|
||||
.fork_name(&chain.spec)
|
||||
.map_err(inconsistent_fork_rejection)?;
|
||||
let execution_payload_value = block_response.execution_payload_value();
|
||||
let consensus_block_value = block_response.consensus_block_value();
|
||||
let consensus_block_value = block_response.consensus_block_value_wei();
|
||||
let execution_payload_blinded = block_response.is_blinded();
|
||||
|
||||
let metadata = ProduceBlockV3Metadata {
|
||||
consensus_version: fork_name,
|
||||
execution_payload_blinded,
|
||||
execution_payload_value,
|
||||
consensus_block_value,
|
||||
};
|
||||
|
||||
let block_contents = build_block_contents::build_block_contents(fork_name, block_response)?;
|
||||
|
||||
match accept_header {
|
||||
@@ -100,12 +106,17 @@ pub fn build_response_v3<T: BeaconChainTypes>(
|
||||
.map_err(|e| -> warp::Rejection {
|
||||
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))
|
||||
.map(|res| add_execution_payload_blinded_header(res, execution_payload_blinded))
|
||||
.map(|res| add_execution_payload_value_header(res, execution_payload_value))
|
||||
.map(|res| add_consensus_block_value_header(res, consensus_block_value)),
|
||||
_ => Ok(warp::reply::json(&ForkVersionedResponse {
|
||||
version: Some(fork_name),
|
||||
metadata,
|
||||
data: block_contents,
|
||||
})
|
||||
.into_response())
|
||||
.map(|res| res.into_response())
|
||||
.map(|res| add_consensus_version_header(res, fork_name))
|
||||
.map(|res| add_execution_payload_blinded_header(res, execution_payload_blinded))
|
||||
.map(|res| add_execution_payload_value_header(res, execution_payload_value))
|
||||
.map(|res| add_consensus_block_value_header(res, consensus_block_value)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +141,7 @@ pub async fn produce_blinded_block_v2<T: BeaconChainTypes>(
|
||||
slot,
|
||||
query.graffiti.map(Into::into),
|
||||
randao_verification,
|
||||
None,
|
||||
BlockProductionVersion::BlindedV2,
|
||||
)
|
||||
.await
|
||||
@@ -160,6 +172,7 @@ pub async fn produce_block_v2<T: BeaconChainTypes>(
|
||||
slot,
|
||||
query.graffiti.map(Into::into),
|
||||
randao_verification,
|
||||
None,
|
||||
BlockProductionVersion::FullV2,
|
||||
)
|
||||
.await
|
||||
|
||||
@@ -60,7 +60,7 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
ProvenancedBlock::Local(block_contents, _) => (block_contents, true),
|
||||
ProvenancedBlock::Builder(block_contents, _) => (block_contents, false),
|
||||
};
|
||||
let block = block_contents.inner_block();
|
||||
let block = block_contents.inner_block().clone();
|
||||
let delay = get_block_delay_ms(seen_timestamp, block.message(), &chain.slot_clock);
|
||||
debug!(log, "Signed block received in HTTP API"; "slot" => block.slot());
|
||||
|
||||
@@ -113,7 +113,10 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
let (gossip_verified_block, gossip_verified_blobs) =
|
||||
match block_contents.into_gossip_verified_block(&chain) {
|
||||
Ok(b) => b,
|
||||
Err(BlockContentsError::BlockError(BlockError::BlockIsAlreadyKnown)) => {
|
||||
Err(BlockContentsError::BlockError(BlockError::BlockIsAlreadyKnown))
|
||||
| Err(BlockContentsError::BlobError(
|
||||
beacon_chain::blob_verification::GossipBlobError::RepeatBlob { .. },
|
||||
)) => {
|
||||
// Allow the status code for duplicate blocks to be overridden based on config.
|
||||
return Ok(warp::reply::with_status(
|
||||
warp::reply::json(&ErrorMessage {
|
||||
@@ -172,28 +175,20 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
seen_timestamp,
|
||||
),
|
||||
BroadcastValidation::ConsensusAndEquivocation => {
|
||||
if chain_clone
|
||||
.observed_block_producers
|
||||
.read()
|
||||
.proposer_has_been_observed(block_clone.message(), block_root)
|
||||
.map_err(|e| BlockError::BeaconChainError(e.into()))?
|
||||
.is_slashable()
|
||||
{
|
||||
warn!(
|
||||
log_clone,
|
||||
"Not publishing equivocating block";
|
||||
"slot" => block_clone.slot()
|
||||
);
|
||||
Err(BlockError::Slashable)
|
||||
} else {
|
||||
publish_block(
|
||||
block_clone,
|
||||
blobs_opt,
|
||||
sender_clone,
|
||||
log_clone,
|
||||
seen_timestamp,
|
||||
)
|
||||
}
|
||||
check_slashable(
|
||||
&chain_clone,
|
||||
&blobs_opt,
|
||||
block_root,
|
||||
&block_clone,
|
||||
&log_clone,
|
||||
)?;
|
||||
publish_block(
|
||||
block_clone,
|
||||
blobs_opt,
|
||||
sender_clone,
|
||||
log_clone,
|
||||
seen_timestamp,
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -450,3 +445,46 @@ fn late_block_logging<T: BeaconChainTypes, P: AbstractExecPayload<T::EthSpec>>(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if any of the blobs or the block are slashable. Returns `BlockError::Slashable` if so.
|
||||
fn check_slashable<T: BeaconChainTypes>(
|
||||
chain_clone: &BeaconChain<T>,
|
||||
blobs_opt: &Option<BlobSidecarList<T::EthSpec>>,
|
||||
block_root: Hash256,
|
||||
block_clone: &SignedBeaconBlock<T::EthSpec, FullPayload<T::EthSpec>>,
|
||||
log_clone: &Logger,
|
||||
) -> Result<(), BlockError<T::EthSpec>> {
|
||||
let slashable_cache = chain_clone.observed_slashable.read();
|
||||
if let Some(blobs) = blobs_opt.as_ref() {
|
||||
blobs.iter().try_for_each(|blob| {
|
||||
if slashable_cache
|
||||
.is_slashable(blob.slot(), blob.block_proposer_index(), blob.block_root())
|
||||
.map_err(|e| BlockError::BeaconChainError(e.into()))?
|
||||
{
|
||||
warn!(
|
||||
log_clone,
|
||||
"Not publishing equivocating blob";
|
||||
"slot" => block_clone.slot()
|
||||
);
|
||||
return Err(BlockError::Slashable);
|
||||
}
|
||||
Ok(())
|
||||
})?;
|
||||
};
|
||||
if slashable_cache
|
||||
.is_slashable(
|
||||
block_clone.slot(),
|
||||
block_clone.message().proposer_index(),
|
||||
block_root,
|
||||
)
|
||||
.map_err(|e| BlockError::BeaconChainError(e.into()))?
|
||||
{
|
||||
warn!(
|
||||
log_clone,
|
||||
"Not publishing equivocating block";
|
||||
"slot" => block_clone.slot()
|
||||
);
|
||||
return Err(BlockError::Slashable);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ use beacon_processor::{BeaconProcessor, BeaconProcessorChannels, BeaconProcessor
|
||||
use directory::DEFAULT_ROOT_DIR;
|
||||
use eth2::{BeaconNodeHttpClient, Timeouts};
|
||||
use lighthouse_network::{
|
||||
discv5::enr::{CombinedKey, EnrBuilder},
|
||||
discv5::enr::CombinedKey,
|
||||
libp2p::swarm::{
|
||||
behaviour::{ConnectionEstablished, FromSwarm},
|
||||
ConnectionId, NetworkBehaviour,
|
||||
@@ -138,7 +138,7 @@ pub async fn create_api_server<T: BeaconChainTypes>(
|
||||
syncnets: EnrSyncCommitteeBitfield::<T::EthSpec>::default(),
|
||||
});
|
||||
let enr_key = CombinedKey::generate_secp256k1();
|
||||
let enr = EnrBuilder::new("v4").build(&enr_key).unwrap();
|
||||
let enr = Enr::builder().build(&enr_key).unwrap();
|
||||
let network_globals = Arc::new(NetworkGlobals::new(
|
||||
enr.clone(),
|
||||
meta_data,
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
use crate::api_types::fork_versioned_response::ExecutionOptimisticFinalizedForkVersionedResponse;
|
||||
use crate::api_types::EndpointVersion;
|
||||
use eth2::{
|
||||
CONSENSUS_BLOCK_VALUE_HEADER, CONSENSUS_VERSION_HEADER, EXECUTION_PAYLOAD_BLINDED_HEADER,
|
||||
EXECUTION_PAYLOAD_VALUE_HEADER,
|
||||
};
|
||||
use serde::Serialize;
|
||||
use types::{ForkName, ForkVersionedResponse, InconsistentFork, Uint256};
|
||||
use types::{
|
||||
fork_versioned_response::{
|
||||
ExecutionOptimisticFinalizedForkVersionedResponse, ExecutionOptimisticFinalizedMetadata,
|
||||
},
|
||||
ForkName, ForkVersionedResponse, InconsistentFork, Uint256,
|
||||
};
|
||||
use warp::reply::{self, Reply, Response};
|
||||
|
||||
pub const V1: EndpointVersion = EndpointVersion(1);
|
||||
@@ -26,6 +30,7 @@ pub fn fork_versioned_response<T: Serialize>(
|
||||
};
|
||||
Ok(ForkVersionedResponse {
|
||||
version: fork_name,
|
||||
metadata: Default::default(),
|
||||
data,
|
||||
})
|
||||
}
|
||||
@@ -46,8 +51,10 @@ pub fn execution_optimistic_finalized_fork_versioned_response<T: Serialize>(
|
||||
};
|
||||
Ok(ExecutionOptimisticFinalizedForkVersionedResponse {
|
||||
version: fork_name,
|
||||
execution_optimistic: Some(execution_optimistic),
|
||||
finalized: Some(finalized),
|
||||
metadata: ExecutionOptimisticFinalizedMetadata {
|
||||
execution_optimistic: Some(execution_optimistic),
|
||||
finalized: Some(finalized),
|
||||
},
|
||||
data,
|
||||
})
|
||||
}
|
||||
@@ -73,12 +80,12 @@ pub fn add_execution_payload_blinded_header<T: Reply>(
|
||||
/// Add the `Eth-Execution-Payload-Value` header to a response.
|
||||
pub fn add_execution_payload_value_header<T: Reply>(
|
||||
reply: T,
|
||||
execution_payload_value: Option<Uint256>,
|
||||
execution_payload_value: Uint256,
|
||||
) -> Response {
|
||||
reply::with_header(
|
||||
reply,
|
||||
EXECUTION_PAYLOAD_VALUE_HEADER,
|
||||
execution_payload_value.unwrap_or_default().to_string(),
|
||||
execution_payload_value.to_string(),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
@@ -86,12 +93,12 @@ pub fn add_execution_payload_value_header<T: Reply>(
|
||||
/// Add the `Eth-Consensus-Block-Value` header to a response.
|
||||
pub fn add_consensus_block_value_header<T: Reply>(
|
||||
reply: T,
|
||||
consensus_payload_value: Option<u64>,
|
||||
consensus_payload_value: Uint256,
|
||||
) -> Response {
|
||||
reply::with_header(
|
||||
reply,
|
||||
CONSENSUS_BLOCK_VALUE_HEADER,
|
||||
consensus_payload_value.unwrap_or_default().to_string(),
|
||||
consensus_payload_value.to_string(),
|
||||
)
|
||||
.into_response()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user