mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-03 00:31:50 +00:00
Merge unstable 20230911 into deneb-free-blobs.
This commit is contained in:
@@ -39,7 +39,8 @@ use bytes::Bytes;
|
||||
use directory::DEFAULT_ROOT_DIR;
|
||||
use eth2::types::{
|
||||
self as api_types, BroadcastValidation, EndpointVersion, ForkChoice, ForkChoiceNode,
|
||||
SignedBlockContents, SkipRandaoVerification, ValidatorId, ValidatorStatus,
|
||||
SignedBlindedBlockContents, SignedBlockContents, SkipRandaoVerification, ValidatorId,
|
||||
ValidatorStatus,
|
||||
};
|
||||
use lighthouse_network::{types::SyncState, EnrExt, NetworkGlobals, PeerId, PubsubMessage};
|
||||
use lighthouse_version::version_with_platform;
|
||||
@@ -139,6 +140,8 @@ pub struct Config {
|
||||
pub data_dir: PathBuf,
|
||||
pub sse_capacity_multiplier: usize,
|
||||
pub enable_beacon_processor: bool,
|
||||
#[serde(with = "eth2::types::serde_status_code")]
|
||||
pub duplicate_block_status_code: StatusCode,
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
@@ -154,6 +157,7 @@ impl Default for Config {
|
||||
data_dir: PathBuf::from(DEFAULT_ROOT_DIR),
|
||||
sse_capacity_multiplier: 1,
|
||||
enable_beacon_processor: true,
|
||||
duplicate_block_status_code: StatusCode::ACCEPTED,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -510,6 +514,8 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
let task_spawner_filter =
|
||||
warp::any().map(move || TaskSpawner::new(beacon_processor_send.clone()));
|
||||
|
||||
let duplicate_block_status_code = ctx.config.duplicate_block_status_code;
|
||||
|
||||
/*
|
||||
*
|
||||
* Start of HTTP method definitions.
|
||||
@@ -1284,11 +1290,11 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|block_contents: SignedBlockContents<T::EthSpec>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
move |block_contents: SignedBlockContents<T::EthSpec>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
publish_blocks::publish_block(
|
||||
None,
|
||||
@@ -1297,9 +1303,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
&network_tx,
|
||||
log,
|
||||
BroadcastValidation::default(),
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply().into_response())
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1314,11 +1320,11 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
move |block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
let block_contents = SignedBlockContents::<T::EthSpec>::from_ssz_bytes(
|
||||
&block_bytes,
|
||||
@@ -1334,9 +1340,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
&network_tx,
|
||||
log,
|
||||
BroadcastValidation::default(),
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply().into_response())
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1352,12 +1358,12 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|validation_level: api_types::BroadcastValidationQuery,
|
||||
block_contents: SignedBlockContents<T::EthSpec>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
move |validation_level: api_types::BroadcastValidationQuery,
|
||||
block_contents: SignedBlockContents<T::EthSpec>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
publish_blocks::publish_block(
|
||||
None,
|
||||
@@ -1366,9 +1372,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
&network_tx,
|
||||
log,
|
||||
validation_level.broadcast_validation,
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply().into_response())
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1384,12 +1390,12 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|validation_level: api_types::BroadcastValidationQuery,
|
||||
block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
move |validation_level: api_types::BroadcastValidationQuery,
|
||||
block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
let block_contents = SignedBlockContents::<T::EthSpec>::from_ssz_bytes(
|
||||
&block_bytes,
|
||||
@@ -1405,9 +1411,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
&network_tx,
|
||||
log,
|
||||
validation_level.broadcast_validation,
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply().into_response())
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1427,11 +1433,11 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|block_contents: SignedBlockContents<T::EthSpec, BlindedPayload<_>>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
move |block_contents: SignedBlindedBlockContents<T::EthSpec>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
publish_blocks::publish_blinded_block(
|
||||
block_contents,
|
||||
@@ -1439,9 +1445,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
&network_tx,
|
||||
log,
|
||||
BroadcastValidation::default(),
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply().into_response())
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1457,11 +1463,11 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
move |block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
let block =
|
||||
SignedBlockContents::<T::EthSpec, BlindedPayload<_>>::from_ssz_bytes(
|
||||
@@ -1477,9 +1483,9 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
&network_tx,
|
||||
log,
|
||||
BroadcastValidation::default(),
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
.map(|()| warp::reply().into_response())
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1495,32 +1501,22 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|validation_level: api_types::BroadcastValidationQuery,
|
||||
block_contents: SignedBlockContents<T::EthSpec, BlindedPayload<_>>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async(Priority::P0, async move {
|
||||
match publish_blocks::publish_blinded_block(
|
||||
move |validation_level: api_types::BroadcastValidationQuery,
|
||||
block_contents: SignedBlindedBlockContents<T::EthSpec>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
publish_blocks::publish_blinded_block(
|
||||
block_contents,
|
||||
chain,
|
||||
&network_tx,
|
||||
log,
|
||||
validation_level.broadcast_validation,
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(()) => warp::reply().into_response(),
|
||||
Err(e) => match warp_utils::reject::handle_rejection(e).await {
|
||||
Ok(reply) => reply.into_response(),
|
||||
Err(_) => warp::reply::with_status(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
eth2::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
.into_response(),
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
);
|
||||
@@ -1531,48 +1527,36 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.and(warp::query::<api_types::BroadcastValidationQuery>())
|
||||
.and(warp::path::end())
|
||||
.and(warp::body::bytes())
|
||||
.and(task_spawner_filter.clone())
|
||||
.and(chain_filter.clone())
|
||||
.and(network_tx_filter.clone())
|
||||
.and(log_filter.clone())
|
||||
.then(
|
||||
|validation_level: api_types::BroadcastValidationQuery,
|
||||
block_bytes: Bytes,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| async move {
|
||||
let block =
|
||||
match SignedBlockContents::<T::EthSpec, BlindedPayload<_>>::from_ssz_bytes(
|
||||
&block_bytes,
|
||||
&chain.spec,
|
||||
) {
|
||||
Ok(data) => data,
|
||||
Err(_) => {
|
||||
return warp::reply::with_status(
|
||||
StatusCode::BAD_REQUEST,
|
||||
eth2::StatusCode::BAD_REQUEST,
|
||||
)
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
match publish_blocks::publish_blinded_block(
|
||||
block,
|
||||
chain,
|
||||
&network_tx,
|
||||
log,
|
||||
validation_level.broadcast_validation,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(()) => warp::reply().into_response(),
|
||||
Err(e) => match warp_utils::reject::handle_rejection(e).await {
|
||||
Ok(reply) => reply.into_response(),
|
||||
Err(_) => warp::reply::with_status(
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
eth2::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
move |validation_level: api_types::BroadcastValidationQuery,
|
||||
block_bytes: Bytes,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
chain: Arc<BeaconChain<T>>,
|
||||
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger| {
|
||||
task_spawner.spawn_async_with_rejection(Priority::P0, async move {
|
||||
let block =
|
||||
SignedBlockContents::<T::EthSpec, BlindedPayload<_>>::from_ssz_bytes(
|
||||
&block_bytes,
|
||||
&chain.spec,
|
||||
)
|
||||
.into_response(),
|
||||
},
|
||||
}
|
||||
.map_err(|e| {
|
||||
warp_utils::reject::custom_bad_request(format!("invalid SSZ: {e:?}"))
|
||||
})?;
|
||||
publish_blocks::publish_blinded_block(
|
||||
block,
|
||||
chain,
|
||||
&network_tx,
|
||||
log,
|
||||
validation_level.broadcast_validation,
|
||||
duplicate_block_status_code,
|
||||
)
|
||||
.await
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::metrics;
|
||||
|
||||
use beacon_chain::block_verification_types::AsBlock;
|
||||
use beacon_chain::block_verification_types::{AsBlock, BlockContentsError};
|
||||
use beacon_chain::validator_monitor::{get_block_delay_ms, timestamp_now};
|
||||
use beacon_chain::{
|
||||
AvailabilityProcessingStatus, BeaconChain, BeaconChainError, BeaconChainTypes, BlockError,
|
||||
IntoGossipVerifiedBlockContents, NotifyExecutionLayer,
|
||||
};
|
||||
use eth2::types::BroadcastValidation;
|
||||
use eth2::types::{BroadcastValidation, ErrorMessage};
|
||||
use eth2::types::{FullPayloadContents, SignedBlockContents};
|
||||
use execution_layer::ProvenancedPayload;
|
||||
use lighthouse_network::PubsubMessage;
|
||||
@@ -22,7 +22,8 @@ use types::{
|
||||
AbstractExecPayload, BeaconBlockRef, BlindedPayload, EthSpec, ExecPayload, ExecutionBlockHash,
|
||||
ForkName, FullPayload, FullPayloadMerge, Hash256, SignedBeaconBlock, SignedBlobSidecarList,
|
||||
};
|
||||
use warp::Rejection;
|
||||
use warp::http::StatusCode;
|
||||
use warp::{reply::Response, Rejection, Reply};
|
||||
|
||||
pub enum ProvenancedBlock<T: BeaconChainTypes, B: IntoGossipVerifiedBlockContents<T>> {
|
||||
/// The payload was built using a local EE.
|
||||
@@ -50,7 +51,8 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger,
|
||||
validation_level: BroadcastValidation,
|
||||
) -> Result<(), Rejection> {
|
||||
duplicate_status_code: StatusCode,
|
||||
) -> Result<Response, Rejection> {
|
||||
let seen_timestamp = timestamp_now();
|
||||
|
||||
let (block_contents, is_locally_built_block) = match provenanced_block {
|
||||
@@ -114,12 +116,31 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
let blobs_opt = block_contents.inner_blobs();
|
||||
|
||||
/* if we can form a `GossipVerifiedBlock`, we've passed our basic gossip checks */
|
||||
let (gossip_verified_block, gossip_verified_blobs) = block_contents
|
||||
.into_gossip_verified_block(&chain)
|
||||
.map_err(|e| {
|
||||
warn!(log, "Not publishing block, not gossip verified"; "slot" => slot, "error" => ?e);
|
||||
warp_utils::reject::custom_bad_request(e.to_string())
|
||||
})?;
|
||||
let (gossip_verified_block, gossip_verified_blobs) =
|
||||
match block_contents.into_gossip_verified_block(&chain) {
|
||||
Ok(b) => b,
|
||||
Err(BlockContentsError::BlockError(BlockError::BlockIsAlreadyKnown)) => {
|
||||
// Allow the status code for duplicate blocks to be overridden based on config.
|
||||
return Ok(warp::reply::with_status(
|
||||
warp::reply::json(&ErrorMessage {
|
||||
code: duplicate_status_code.as_u16(),
|
||||
message: "duplicate block".to_string(),
|
||||
stacktraces: vec![],
|
||||
}),
|
||||
duplicate_status_code,
|
||||
)
|
||||
.into_response());
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(
|
||||
log,
|
||||
"Not publishing block - not gossip verified";
|
||||
"slot" => slot,
|
||||
"error" => ?e
|
||||
);
|
||||
return Err(warp_utils::reject::custom_bad_request(e.to_string()));
|
||||
}
|
||||
};
|
||||
|
||||
// Clone here, so we can take advantage of the `Arc`. The block in `BlockContents` is not,
|
||||
// `Arc`'d but blobs are.
|
||||
@@ -222,8 +243,7 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
if is_locally_built_block {
|
||||
late_block_logging(&chain, seen_timestamp, block.message(), root, "local", &log)
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(warp::reply().into_response())
|
||||
}
|
||||
Ok(AvailabilityProcessingStatus::MissingComponents(_, block_root)) => {
|
||||
let msg = format!("Missing parts of block with root {:?}", block_root);
|
||||
@@ -246,10 +266,6 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlockConten
|
||||
Err(BlockError::Slashable) => Err(warp_utils::reject::custom_bad_request(
|
||||
"proposal for this slot and proposer has already been seen".to_string(),
|
||||
)),
|
||||
Err(BlockError::BlockIsAlreadyKnown) => {
|
||||
info!(log, "Block from HTTP API already known"; "block" => ?block_root);
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
if let BroadcastValidation::Gossip = validation_level {
|
||||
Err(warp_utils::reject::broadcast_without_import(format!("{e}")))
|
||||
@@ -276,7 +292,8 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
||||
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
|
||||
log: Logger,
|
||||
validation_level: BroadcastValidation,
|
||||
) -> Result<(), Rejection> {
|
||||
duplicate_status_code: StatusCode,
|
||||
) -> Result<Response, Rejection> {
|
||||
let block_root = block_contents.signed_block().canonical_root();
|
||||
let full_block: ProvenancedBlock<T, SignedBlockContents<T::EthSpec>> =
|
||||
reconstruct_block(chain.clone(), block_root, block_contents, log.clone()).await?;
|
||||
@@ -287,6 +304,7 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
|
||||
network_tx,
|
||||
log,
|
||||
validation_level,
|
||||
duplicate_status_code,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -89,9 +89,7 @@ impl StateId {
|
||||
} else {
|
||||
// This block is either old and finalized, or recent and unfinalized, so
|
||||
// it's safe to fallback to the optimistic status of the finalized block.
|
||||
chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
fork_choice
|
||||
.is_optimistic_or_invalid_block(&hot_summary.latest_block_root)
|
||||
.map_err(BeaconChainError::ForkChoiceError)
|
||||
.map_err(warp_utils::reject::beacon_chain_error)?
|
||||
|
||||
@@ -159,46 +159,6 @@ impl<E: EthSpec> TaskSpawner<E> {
|
||||
.and_then(|x| x)
|
||||
}
|
||||
}
|
||||
|
||||
/// Executes an async task which always returns a `Response`.
|
||||
pub async fn spawn_async(
|
||||
self,
|
||||
priority: Priority,
|
||||
func: impl Future<Output = Response> + Send + Sync + 'static,
|
||||
) -> Response {
|
||||
if let Some(beacon_processor_send) = &self.beacon_processor_send {
|
||||
// Create a wrapper future that will execute `func` and send the
|
||||
// result to a channel held by this thread.
|
||||
let (tx, rx) = oneshot::channel();
|
||||
let process_fn = async move {
|
||||
// Await the future, collect the return value.
|
||||
let func_result = func.await;
|
||||
// Send the result down the channel. Ignore any failures; the
|
||||
// send can only fail if the receiver is dropped.
|
||||
let _ = tx.send(func_result);
|
||||
};
|
||||
|
||||
// Send the function to the beacon processor for execution at some arbitrary time.
|
||||
let result = send_to_beacon_processor(
|
||||
beacon_processor_send,
|
||||
priority,
|
||||
BlockingOrAsync::Async(Box::pin(process_fn)),
|
||||
rx,
|
||||
)
|
||||
.await;
|
||||
convert_rejection(result).await
|
||||
} else {
|
||||
// There is no beacon processor so spawn a task directly on the
|
||||
// tokio executor.
|
||||
tokio::task::spawn(func).await.unwrap_or_else(|e| {
|
||||
warp::reply::with_status(
|
||||
warp::reply::json(&format!("Tokio did not execute task: {e:?}")),
|
||||
eth2::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
.into_response()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a task to the beacon processor and await execution.
|
||||
|
||||
@@ -21,7 +21,7 @@ use network::{NetworkReceivers, NetworkSenders};
|
||||
use sensitive_url::SensitiveUrl;
|
||||
use slog::Logger;
|
||||
use std::future::Future;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use store::MemoryStore;
|
||||
@@ -217,15 +217,9 @@ pub async fn create_api_server_on_port<T: BeaconChainTypes>(
|
||||
let ctx = Arc::new(Context {
|
||||
config: Config {
|
||||
enabled: true,
|
||||
listen_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||
listen_port: port,
|
||||
allow_origin: None,
|
||||
tls_config: None,
|
||||
allow_sync_stalled: false,
|
||||
data_dir: std::path::PathBuf::from(DEFAULT_ROOT_DIR),
|
||||
spec_fork_name: None,
|
||||
sse_capacity_multiplier: 1,
|
||||
enable_beacon_processor: true,
|
||||
..Config::default()
|
||||
},
|
||||
chain: Some(chain),
|
||||
network_senders: Some(network_senders),
|
||||
|
||||
@@ -214,19 +214,19 @@ pub async fn gossip_full_pass_ssz() {
|
||||
let slot_b = slot_a + 1;
|
||||
|
||||
let state_a = tester.harness.get_current_state();
|
||||
let ((block, _), _): ((SignedBeaconBlock<E>, _), _) =
|
||||
tester.harness.make_block(state_a, slot_b).await;
|
||||
let (block_contents_tuple, _) = tester.harness.make_block(state_a, slot_b).await;
|
||||
let block_contents = block_contents_tuple.into();
|
||||
|
||||
let response: Result<(), eth2::Error> = tester
|
||||
.client
|
||||
.post_beacon_blocks_v2_ssz(&block, validation_level)
|
||||
.post_beacon_blocks_v2_ssz(&block_contents, validation_level)
|
||||
.await;
|
||||
|
||||
assert!(response.is_ok());
|
||||
assert!(tester
|
||||
.harness
|
||||
.chain
|
||||
.block_is_known_to_fork_choice(&block.canonical_root()));
|
||||
.block_is_known_to_fork_choice(&block_contents.signed_block().canonical_root()));
|
||||
}
|
||||
|
||||
/// This test checks that a block that is **invalid** from a gossip perspective gets rejected when using `broadcast_validation=consensus`.
|
||||
@@ -378,13 +378,14 @@ pub async fn consensus_partial_pass_only_consensus() {
|
||||
/* submit `block_b` which should induce equivocation */
|
||||
let channel = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
let publication_result: Result<(), Rejection> = publish_block(
|
||||
let publication_result = publish_block(
|
||||
None,
|
||||
ProvenancedBlock::local(gossip_block_contents_b.unwrap()),
|
||||
tester.harness.chain.clone(),
|
||||
&channel.0,
|
||||
test_logger,
|
||||
validation_level.unwrap(),
|
||||
StatusCode::ACCEPTED,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -669,13 +670,14 @@ pub async fn equivocation_consensus_late_equivocation() {
|
||||
|
||||
let channel = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
let publication_result: Result<(), Rejection> = publish_block(
|
||||
let publication_result = publish_block(
|
||||
None,
|
||||
ProvenancedBlock::local(gossip_block_contents_b.unwrap()),
|
||||
tester.harness.chain,
|
||||
&channel.0,
|
||||
test_logger,
|
||||
validation_level.unwrap(),
|
||||
StatusCode::ACCEPTED,
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -1335,12 +1337,13 @@ pub async fn blinded_equivocation_consensus_late_equivocation() {
|
||||
|
||||
let channel = tokio::sync::mpsc::unbounded_channel();
|
||||
|
||||
let publication_result: Result<(), Rejection> = publish_blinded_block(
|
||||
let publication_result = publish_blinded_block(
|
||||
SignedBlockContents::new(block_b, blobs_b),
|
||||
tester.harness.chain,
|
||||
&channel.0,
|
||||
test_logger,
|
||||
validation_level.unwrap(),
|
||||
StatusCode::ACCEPTED,
|
||||
)
|
||||
.await;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use eth2::{
|
||||
mixin::{RequestAccept, ResponseForkName, ResponseOptional},
|
||||
reqwest::RequestBuilder,
|
||||
types::{BlockId as CoreBlockId, ForkChoiceNode, StateId as CoreStateId, *},
|
||||
BeaconNodeHttpClient, Error, Timeouts,
|
||||
BeaconNodeHttpClient, Error, StatusCode, Timeouts,
|
||||
};
|
||||
use execution_layer::test_utils::TestingBuilder;
|
||||
use execution_layer::test_utils::DEFAULT_BUILDER_THRESHOLD_WEI;
|
||||
@@ -1330,6 +1330,71 @@ impl ApiTester {
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn test_post_beacon_blocks_duplicate(self) -> Self {
|
||||
let block_contents = self
|
||||
.harness
|
||||
.make_block(
|
||||
self.harness.get_current_state(),
|
||||
self.harness.get_current_slot(),
|
||||
)
|
||||
.await
|
||||
.0
|
||||
.into();
|
||||
|
||||
assert!(self
|
||||
.client
|
||||
.post_beacon_blocks(&block_contents)
|
||||
.await
|
||||
.is_ok());
|
||||
|
||||
let blinded_block_contents = block_contents.clone_as_blinded();
|
||||
|
||||
// Test all the POST methods in sequence, they should all behave the same.
|
||||
let responses = vec![
|
||||
self.client
|
||||
.post_beacon_blocks(&block_contents)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blocks_v2(&block_contents, None)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blocks_ssz(&block_contents)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blocks_v2_ssz(&block_contents, None)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blinded_blocks(&blinded_block_contents)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blinded_blocks_v2(&blinded_block_contents, None)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blinded_blocks_ssz(&blinded_block_contents)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
self.client
|
||||
.post_beacon_blinded_blocks_v2_ssz(&blinded_block_contents, None)
|
||||
.await
|
||||
.unwrap_err(),
|
||||
];
|
||||
for (i, response) in responses.into_iter().enumerate() {
|
||||
assert_eq!(
|
||||
response.status().unwrap(),
|
||||
StatusCode::ACCEPTED,
|
||||
"response {i}"
|
||||
);
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn test_beacon_blocks(self) -> Self {
|
||||
for block_id in self.interesting_block_ids() {
|
||||
let expected = block_id
|
||||
@@ -4725,6 +4790,14 @@ async fn post_beacon_blocks_invalid() {
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn post_beacon_blocks_duplicate() {
|
||||
ApiTester::new()
|
||||
.await
|
||||
.test_post_beacon_blocks_duplicate()
|
||||
.await;
|
||||
}
|
||||
|
||||
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
|
||||
async fn beacon_pools_post_attestations_valid() {
|
||||
ApiTester::new()
|
||||
|
||||
Reference in New Issue
Block a user