Merge branch 'unstable' into merge-unstable-to-deneb-20230808

# Conflicts:
#	Cargo.lock
#	beacon_node/beacon_chain/src/lib.rs
#	beacon_node/execution_layer/src/engine_api.rs
#	beacon_node/execution_layer/src/engine_api/http.rs
#	beacon_node/execution_layer/src/test_utils/mod.rs
#	beacon_node/lighthouse_network/src/rpc/codec/ssz_snappy.rs
#	beacon_node/lighthouse_network/src/rpc/handler.rs
#	beacon_node/lighthouse_network/src/rpc/protocol.rs
#	beacon_node/lighthouse_network/src/service/utils.rs
#	beacon_node/lighthouse_network/tests/rpc_tests.rs
#	beacon_node/network/Cargo.toml
#	beacon_node/network/src/network_beacon_processor/tests.rs
#	lcli/src/parse_ssz.rs
#	scripts/cross/Dockerfile
#	validator_client/src/block_service.rs
#	validator_client/src/validator_store.rs
This commit is contained in:
Jimmy Chen
2023-08-08 16:33:32 +10:00
161 changed files with 8729 additions and 3368 deletions

View File

@@ -21,10 +21,14 @@ use futures_util::StreamExt;
use lighthouse_network::PeerId;
use pretty_reqwest_error::PrettyReqwestError;
pub use reqwest;
use reqwest::{IntoUrl, RequestBuilder, Response};
use reqwest::{
header::{HeaderMap, HeaderValue},
Body, IntoUrl, RequestBuilder, Response,
};
pub use reqwest::{StatusCode, Url};
pub use sensitive_url::{SensitiveError, SensitiveUrl};
use serde::{de::DeserializeOwned, Serialize};
use ssz::Encode;
use std::convert::TryFrom;
use std::fmt;
use std::iter::Iterator;
@@ -322,6 +326,25 @@ impl BeaconNodeHttpClient {
ok_or_error(response).await
}
/// Generic POST function supporting arbitrary responses and timeouts.
async fn post_generic_with_ssz_body<T: Into<Body>, U: IntoUrl>(
&self,
url: U,
body: T,
timeout: Option<Duration>,
) -> Result<Response, Error> {
let mut builder = self.client.post(url);
if let Some(timeout) = timeout {
builder = builder.timeout(timeout);
}
let response = builder
.header("Content-Type", "application/octet-stream")
.body(body)
.send()
.await?;
ok_or_error(response).await
}
/// Generic POST function supporting arbitrary responses and timeouts.
async fn post_generic_with_consensus_version<T: Serialize, U: IntoUrl>(
&self,
@@ -342,6 +365,31 @@ impl BeaconNodeHttpClient {
ok_or_error(response).await
}
/// Generic POST function supporting arbitrary responses and timeouts.
async fn post_generic_with_consensus_version_and_ssz_body<T: Into<Body>, U: IntoUrl>(
&self,
url: U,
body: T,
timeout: Option<Duration>,
fork: ForkName,
) -> Result<Response, Error> {
let mut builder = self.client.post(url);
if let Some(timeout) = timeout {
builder = builder.timeout(timeout);
}
let mut headers = HeaderMap::new();
headers.insert(
CONSENSUS_VERSION_HEADER,
HeaderValue::from_str(&fork.to_string()).expect("Failed to create header value"),
);
headers.insert(
"Content-Type",
HeaderValue::from_static("application/octet-stream"),
);
let response = builder.headers(headers).body(body).send().await?;
ok_or_error(response).await
}
/// `GET beacon/genesis`
///
/// ## Errors
@@ -654,6 +702,26 @@ impl BeaconNodeHttpClient {
Ok(())
}
/// `POST beacon/blocks`
///
/// Returns `Ok(None)` on a 404 error.
pub async fn post_beacon_blocks_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
&self,
block: &SignedBeaconBlock<T, Payload>,
) -> Result<(), Error> {
let mut path = self.eth_path(V1)?;
path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("beacon")
.push("blocks");
self.post_generic_with_ssz_body(path, block.as_ssz_bytes(), Some(self.timeouts.proposal))
.await?;
Ok(())
}
/// `POST beacon/blinded_blocks`
///
/// Returns `Ok(None)` on a 404 error.
@@ -674,6 +742,26 @@ impl BeaconNodeHttpClient {
Ok(())
}
/// `POST beacon/blinded_blocks`
///
/// Returns `Ok(None)` on a 404 error.
pub async fn post_beacon_blinded_blocks_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
&self,
block: &SignedBeaconBlock<T, Payload>,
) -> Result<(), Error> {
let mut path = self.eth_path(V1)?;
path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("beacon")
.push("blinded_blocks");
self.post_generic_with_ssz_body(path, block.as_ssz_bytes(), Some(self.timeouts.proposal))
.await?;
Ok(())
}
pub fn post_beacon_blocks_v2_path(
&self,
validation_level: Option<BroadcastValidation>,
@@ -727,6 +815,23 @@ impl BeaconNodeHttpClient {
Ok(())
}
/// `POST v2/beacon/blocks`
pub async fn post_beacon_blocks_v2_ssz<T: EthSpec, Payload: AbstractExecPayload<T>>(
&self,
block: &SignedBeaconBlock<T, Payload>,
validation_level: Option<BroadcastValidation>,
) -> Result<(), Error> {
self.post_generic_with_consensus_version_and_ssz_body(
self.post_beacon_blocks_v2_path(validation_level)?,
block.as_ssz_bytes(),
Some(self.timeouts.proposal),
block.message().body().fork_name(),
)
.await?;
Ok(())
}
/// `POST v2/beacon/blinded_blocks`
//TODO(sean) update this along with builder updates
pub async fn post_beacon_blinded_blocks_v2<T: EthSpec>(
@@ -745,6 +850,23 @@ impl BeaconNodeHttpClient {
Ok(())
}
/// `POST v2/beacon/blinded_blocks`
pub async fn post_beacon_blinded_blocks_v2_ssz<T: EthSpec>(
&self,
block: &SignedBlindedBeaconBlock<T>,
validation_level: Option<BroadcastValidation>,
) -> Result<(), Error> {
self.post_generic_with_consensus_version_and_ssz_body(
self.post_beacon_blinded_blocks_v2_path(validation_level)?,
block.as_ssz_bytes(),
Some(self.timeouts.proposal),
block.message().body().fork_name(),
)
.await?;
Ok(())
}
/// Path for `v2/beacon/blocks`
pub fn get_beacon_blocks_path(&self, block_id: BlockId) -> Result<Url, Error> {
let mut path = self.eth_path(V2)?;
@@ -1665,6 +1787,24 @@ impl BeaconNodeHttpClient {
.await
}
/// `POST validator/liveness/{epoch}`
pub async fn post_validator_liveness_epoch(
&self,
epoch: Epoch,
indices: Vec<u64>,
) -> Result<GenericResponse<Vec<StandardLivenessResponseData>>, Error> {
let mut path = self.eth_path(V1)?;
path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("validator")
.push("liveness")
.push(&epoch.to_string());
self.post_with_timeout_and_response(path, &indices, self.timeouts.liveness)
.await
}
/// `POST validator/duties/attester/{epoch}`
pub async fn post_validator_duties_attester(
&self,

View File

@@ -490,6 +490,21 @@ impl ValidatorClientHttpClient {
.await
}
/// `DELETE eth/v1/keystores`
pub async fn delete_lighthouse_keystores(
&self,
req: &DeleteKeystoresRequest,
) -> Result<ExportKeystoresResponse, Error> {
let mut path = self.server.full.clone();
path.path_segments_mut()
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
.push("lighthouse")
.push("keystores");
self.delete_with_unsigned_response(path, req).await
}
fn make_keystores_url(&self) -> Result<Url, Error> {
let mut url = self.server.full.clone();
url.path_segments_mut()

View File

@@ -1,9 +1,10 @@
use account_utils::ZeroizeString;
use eth2_keystore::Keystore;
use serde::{Deserialize, Serialize};
use slashing_protection::interchange::Interchange;
use types::{Address, PublicKeyBytes};
pub use slashing_protection::interchange::Interchange;
#[derive(Debug, Deserialize, Serialize, PartialEq)]
pub struct GetFeeRecipientResponse {
pub pubkey: PublicKeyBytes,
@@ -27,7 +28,7 @@ pub struct ListKeystoresResponse {
pub data: Vec<SingleKeystoreResponse>,
}
#[derive(Debug, Deserialize, Serialize, PartialEq)]
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Hash)]
pub struct SingleKeystoreResponse {
pub validating_pubkey: PublicKeyBytes,
pub derivation_path: Option<String>,

View File

@@ -152,3 +152,19 @@ pub struct UpdateGasLimitRequest {
pub struct VoluntaryExitQuery {
pub epoch: Option<Epoch>,
}
#[derive(Deserialize, Serialize)]
pub struct ExportKeystoresResponse {
pub data: Vec<SingleExportKeystoresResponse>,
#[serde(with = "serde_utils::json_str")]
pub slashing_protection: Interchange,
}
#[derive(Deserialize, Serialize)]
pub struct SingleExportKeystoresResponse {
pub status: Status<DeleteKeystoreStatus>,
#[serde(skip_serializing_if = "Option::is_none")]
pub validating_keystore: Option<KeystoreJsonStr>,
#[serde(skip_serializing_if = "Option::is_none")]
pub validating_keystore_password: Option<ZeroizeString>,
}

View File

@@ -1233,6 +1233,13 @@ impl FromStr for Accept {
}
}
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub struct StandardLivenessResponseData {
#[serde(with = "serde_utils::quoted_u64")]
pub index: u64,
pub is_live: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct LivenessRequestData {
pub epoch: Epoch,
@@ -1440,6 +1447,13 @@ impl<T: EthSpec, Payload: AbstractExecPayload<T>> SignedBlockContents<T, Payload
}
}
/// SSZ decode with fork variant determined by slot.
pub fn from_ssz_bytes(bytes: &[u8], spec: &ChainSpec) -> Result<Self, ssz::DecodeError> {
// FIXME(jimmy): SSZ decode not implemented for `SignedBeaconBlockAndBlobSidecars`
SignedBeaconBlock::from_ssz_bytes(bytes, spec)
.map(|block| SignedBlockContents::Block(block))
}
pub fn signed_block(&self) -> &SignedBeaconBlock<T, Payload> {
match self {
SignedBlockContents::BlockAndBlobSidecars(block_and_sidecars) => {