mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 04:37:13 +00:00
Resolve merge conflicts
This commit is contained in:
@@ -38,6 +38,6 @@ types = { workspace = true }
|
||||
zeroize = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
rand = { workspace = true }
|
||||
test_random_derive = { path = "../../common/test_random_derive" }
|
||||
arbitrary = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
types = { workspace = true, features = ["arbitrary"] }
|
||||
|
||||
@@ -46,7 +46,7 @@ use ssz::{Decode, Encode};
|
||||
use std::fmt;
|
||||
use std::future::Future;
|
||||
use std::time::Duration;
|
||||
use types::{PayloadAttestationData, PayloadAttestationMessage};
|
||||
use types::{PayloadAttestationData, PayloadAttestationMessage, SignedProposerPreferences};
|
||||
|
||||
pub const V1: EndpointVersion = EndpointVersion(1);
|
||||
pub const V2: EndpointVersion = EndpointVersion(2);
|
||||
@@ -1875,6 +1875,46 @@ impl BeaconNodeHttpClient {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `POST validator/proposer_preferences`
|
||||
pub async fn post_validator_proposer_preferences(
|
||||
&self,
|
||||
signed_preferences: &[SignedProposerPreferences],
|
||||
fork_name: ForkName,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
path.path_segments_mut()
|
||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||
.push("validator")
|
||||
.push("proposer_preferences");
|
||||
|
||||
self.post_generic_with_consensus_version(path, &signed_preferences, None, fork_name)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `POST validator/proposer_preferences` (SSZ)
|
||||
pub async fn post_validator_proposer_preferences_ssz(
|
||||
&self,
|
||||
signed_preferences: &Vec<SignedProposerPreferences>,
|
||||
fork_name: ForkName,
|
||||
) -> Result<(), Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
path.path_segments_mut()
|
||||
.map_err(|()| Error::InvalidUrl(self.server.clone()))?
|
||||
.push("validator")
|
||||
.push("proposer_preferences");
|
||||
|
||||
let ssz_body = signed_preferences.as_ssz_bytes();
|
||||
|
||||
self.post_generic_with_consensus_version_and_ssz_body(path, ssz_body, None, fork_name)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// `POST beacon/rewards/sync_committee`
|
||||
pub async fn post_beacon_rewards_sync_committee(
|
||||
&self,
|
||||
@@ -3016,10 +3056,11 @@ impl BeaconNodeHttpClient {
|
||||
}
|
||||
|
||||
/// `GET validator/payload_attestation_data/{slot}`
|
||||
/// Returns `None` if no block has been received for the requested slot (404).
|
||||
pub async fn get_validator_payload_attestation_data(
|
||||
&self,
|
||||
slot: Slot,
|
||||
) -> Result<BeaconResponse<PayloadAttestationData>, Error> {
|
||||
) -> Result<Option<BeaconResponse<PayloadAttestationData>>, Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
path.path_segments_mut()
|
||||
@@ -3028,16 +3069,23 @@ impl BeaconNodeHttpClient {
|
||||
.push("payload_attestation_data")
|
||||
.push(&slot.to_string());
|
||||
|
||||
self.get_with_timeout(path, self.timeouts.payload_attestation)
|
||||
let opt_response = self
|
||||
.get_response(path, |b| b.timeout(self.timeouts.payload_attestation))
|
||||
.await
|
||||
.map(BeaconResponse::ForkVersioned)
|
||||
.optional()?;
|
||||
|
||||
match opt_response {
|
||||
Some(response) => Ok(Some(BeaconResponse::ForkVersioned(response.json().await?))),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
/// `GET validator/payload_attestation_data/{slot}` in SSZ format
|
||||
/// Returns `None` if no block has been received for the requested slot (404).
|
||||
pub async fn get_validator_payload_attestation_data_ssz(
|
||||
&self,
|
||||
slot: Slot,
|
||||
) -> Result<PayloadAttestationData, Error> {
|
||||
) -> Result<Option<PayloadAttestationData>, Error> {
|
||||
let mut path = self.eth_path(V1)?;
|
||||
|
||||
path.path_segments_mut()
|
||||
@@ -3050,9 +3098,9 @@ impl BeaconNodeHttpClient {
|
||||
.get_bytes_opt_accept_header(path, Accept::Ssz, self.timeouts.payload_attestation)
|
||||
.await?;
|
||||
|
||||
let response_bytes = opt_response.ok_or(Error::StatusCode(StatusCode::NOT_FOUND))?;
|
||||
|
||||
PayloadAttestationData::from_ssz_bytes(&response_bytes).map_err(Error::InvalidSsz)
|
||||
opt_response
|
||||
.map(|bytes| PayloadAttestationData::from_ssz_bytes(&bytes).map_err(Error::InvalidSsz))
|
||||
.transpose()
|
||||
}
|
||||
|
||||
/// `GET v1/validator/aggregate_attestation?slot,attestation_data_root`
|
||||
|
||||
@@ -26,11 +26,6 @@ use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use superstruct::superstruct;
|
||||
|
||||
#[cfg(test)]
|
||||
use test_random_derive::TestRandom;
|
||||
#[cfg(test)]
|
||||
use types::test_utils::TestRandom;
|
||||
|
||||
// TODO(mac): Temporary module and re-export hack to expose old `consensus/types` via `eth2/types`.
|
||||
pub use crate::beacon_response::*;
|
||||
pub mod beacon_response {
|
||||
@@ -2390,7 +2385,7 @@ pub enum ContentType {
|
||||
Ssz,
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(TestRandom))]
|
||||
#[cfg_attr(test, derive(arbitrary::Arbitrary))]
|
||||
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize, Encode, Decode)]
|
||||
#[serde(bound = "E: EthSpec")]
|
||||
pub struct BlobsBundle<E: EthSpec> {
|
||||
@@ -2496,7 +2491,7 @@ pub struct BlobWrapper<E: EthSpec> {
|
||||
mod test {
|
||||
use std::fmt::Debug;
|
||||
|
||||
use types::test_utils::{SeedableRng, TestRandom, XorShiftRng};
|
||||
use arbitrary::Arbitrary;
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -2524,13 +2519,16 @@ mod test {
|
||||
assert_eq!(request, deserialized_request);
|
||||
};
|
||||
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
let mut u = types::test_utils::test_unstructured();
|
||||
for fork_name in ForkName::list_all() {
|
||||
let signed_beacon_block =
|
||||
map_fork_name!(fork_name, SignedBeaconBlock, <_>::random_for_test(rng));
|
||||
let signed_beacon_block = map_fork_name!(
|
||||
fork_name,
|
||||
SignedBeaconBlock,
|
||||
<_>::arbitrary(&mut u).unwrap()
|
||||
);
|
||||
let request = if fork_name.deneb_enabled() && !fork_name.gloas_enabled() {
|
||||
let kzg_proofs = KzgProofs::<MainnetEthSpec>::random_for_test(rng);
|
||||
let blobs = BlobsList::<MainnetEthSpec>::random_for_test(rng);
|
||||
let kzg_proofs = KzgProofs::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
let blobs = BlobsList::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
let block_contents = SignedBlockContents {
|
||||
signed_block: Arc::new(signed_beacon_block),
|
||||
kzg_proofs,
|
||||
@@ -2558,12 +2556,15 @@ mod test {
|
||||
};
|
||||
|
||||
let mut fork_name = ForkName::Deneb;
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
let mut u = types::test_utils::test_unstructured();
|
||||
loop {
|
||||
let signed_beacon_block =
|
||||
map_fork_name!(fork_name, SignedBeaconBlock, <_>::random_for_test(rng));
|
||||
let kzg_proofs = KzgProofs::<MainnetEthSpec>::random_for_test(rng);
|
||||
let blobs = BlobsList::<MainnetEthSpec>::random_for_test(rng);
|
||||
let signed_beacon_block = map_fork_name!(
|
||||
fork_name,
|
||||
SignedBeaconBlock,
|
||||
<_>::arbitrary(&mut u).unwrap()
|
||||
);
|
||||
let kzg_proofs = KzgProofs::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
let blobs = BlobsList::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
let block_contents = SignedBlockContents {
|
||||
signed_block: Arc::new(signed_beacon_block),
|
||||
kzg_proofs,
|
||||
@@ -2581,27 +2582,30 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_execution_payload_execution_payload_deserialize_by_fork() {
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
let mut u = types::test_utils::test_unstructured();
|
||||
|
||||
let payloads = [
|
||||
ExecutionPayload::Bellatrix(
|
||||
ExecutionPayloadBellatrix::<MainnetEthSpec>::random_for_test(rng),
|
||||
ExecutionPayloadBellatrix::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Capella(
|
||||
ExecutionPayloadCapella::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Deneb(
|
||||
ExecutionPayloadDeneb::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Electra(
|
||||
ExecutionPayloadElectra::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Fulu(
|
||||
ExecutionPayloadFulu::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Gloas(
|
||||
ExecutionPayloadGloas::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Heze(
|
||||
ExecutionPayloadHeze::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
),
|
||||
ExecutionPayload::Capella(ExecutionPayloadCapella::<MainnetEthSpec>::random_for_test(
|
||||
rng,
|
||||
)),
|
||||
ExecutionPayload::Deneb(ExecutionPayloadDeneb::<MainnetEthSpec>::random_for_test(
|
||||
rng,
|
||||
)),
|
||||
ExecutionPayload::Electra(ExecutionPayloadElectra::<MainnetEthSpec>::random_for_test(
|
||||
rng,
|
||||
)),
|
||||
ExecutionPayload::Heze(ExecutionPayloadHeze::<MainnetEthSpec>::random_for_test(rng)),
|
||||
ExecutionPayload::Fulu(ExecutionPayloadFulu::<MainnetEthSpec>::random_for_test(rng)),
|
||||
ExecutionPayload::Gloas(ExecutionPayloadGloas::<MainnetEthSpec>::random_for_test(
|
||||
rng,
|
||||
)),
|
||||
ExecutionPayload::Heze(ExecutionPayloadHeze::<MainnetEthSpec>::random_for_test(rng)),
|
||||
];
|
||||
let merged_forks = &ForkName::list_all()[2..];
|
||||
assert_eq!(
|
||||
@@ -2620,70 +2624,54 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_execution_payload_and_blobs_deserialize_by_fork() {
|
||||
let rng = &mut XorShiftRng::from_seed([42; 16]);
|
||||
let mut u = types::test_utils::test_unstructured();
|
||||
|
||||
let payloads = [
|
||||
{
|
||||
let execution_payload =
|
||||
ExecutionPayload::Deneb(
|
||||
ExecutionPayloadDeneb::<MainnetEthSpec>::random_for_test(rng),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::random_for_test(rng);
|
||||
let execution_payload = ExecutionPayload::Deneb(
|
||||
ExecutionPayloadDeneb::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
ExecutionPayloadAndBlobs {
|
||||
execution_payload,
|
||||
blobs_bundle,
|
||||
}
|
||||
},
|
||||
{
|
||||
let execution_payload =
|
||||
ExecutionPayload::Electra(
|
||||
ExecutionPayloadElectra::<MainnetEthSpec>::random_for_test(rng),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::random_for_test(rng);
|
||||
let execution_payload = ExecutionPayload::Electra(
|
||||
ExecutionPayloadElectra::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
ExecutionPayloadAndBlobs {
|
||||
execution_payload,
|
||||
blobs_bundle,
|
||||
}
|
||||
},
|
||||
{
|
||||
let execution_payload =
|
||||
ExecutionPayload::Heze(
|
||||
ExecutionPayloadHeze::<MainnetEthSpec>::random_for_test(rng),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::random_for_test(rng);
|
||||
let execution_payload = ExecutionPayload::Fulu(
|
||||
ExecutionPayloadFulu::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
ExecutionPayloadAndBlobs {
|
||||
execution_payload,
|
||||
blobs_bundle,
|
||||
}
|
||||
},
|
||||
{
|
||||
let execution_payload =
|
||||
ExecutionPayload::Fulu(
|
||||
ExecutionPayloadFulu::<MainnetEthSpec>::random_for_test(rng),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::random_for_test(rng);
|
||||
let execution_payload = ExecutionPayload::Gloas(
|
||||
ExecutionPayloadGloas::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
ExecutionPayloadAndBlobs {
|
||||
execution_payload,
|
||||
blobs_bundle,
|
||||
}
|
||||
},
|
||||
{
|
||||
let execution_payload =
|
||||
ExecutionPayload::Gloas(
|
||||
ExecutionPayloadGloas::<MainnetEthSpec>::random_for_test(rng),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::random_for_test(rng);
|
||||
ExecutionPayloadAndBlobs {
|
||||
execution_payload,
|
||||
blobs_bundle,
|
||||
}
|
||||
},
|
||||
{
|
||||
let execution_payload =
|
||||
ExecutionPayload::Heze(
|
||||
ExecutionPayloadHeze::<MainnetEthSpec>::random_for_test(rng),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::random_for_test(rng);
|
||||
let execution_payload = ExecutionPayload::Heze(
|
||||
ExecutionPayloadHeze::<MainnetEthSpec>::arbitrary(&mut u).unwrap(),
|
||||
);
|
||||
let blobs_bundle = BlobsBundle::<MainnetEthSpec>::arbitrary(&mut u).unwrap();
|
||||
ExecutionPayloadAndBlobs {
|
||||
execution_payload,
|
||||
blobs_bundle,
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
[package]
|
||||
name = "test_random_derive"
|
||||
version = "0.2.0"
|
||||
authors = ["thojest <thojest@gmail.com>"]
|
||||
edition = { workspace = true }
|
||||
description = "Procedural derive macros for implementation of TestRandom trait"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
quote = { workspace = true }
|
||||
syn = { workspace = true }
|
||||
@@ -1,59 +0,0 @@
|
||||
use proc_macro::TokenStream;
|
||||
use quote::quote;
|
||||
use syn::{DeriveInput, parse_macro_input};
|
||||
|
||||
/// Returns true if some field has an attribute declaring it should be generated from default (not
|
||||
/// randomized).
|
||||
///
|
||||
/// The field attribute is: `#[test_random(default)]`
|
||||
fn should_use_default(field: &syn::Field) -> bool {
|
||||
field.attrs.iter().any(|attr| {
|
||||
attr.path().is_ident("test_random")
|
||||
&& matches!(&attr.meta, syn::Meta::List(list) if list.tokens.to_string().replace(' ', "") == "default")
|
||||
})
|
||||
}
|
||||
|
||||
#[proc_macro_derive(TestRandom, attributes(test_random))]
|
||||
pub fn test_random_derive(input: TokenStream) -> TokenStream {
|
||||
let derived_input = parse_macro_input!(input as DeriveInput);
|
||||
let name = &derived_input.ident;
|
||||
let (impl_generics, ty_generics, where_clause) = &derived_input.generics.split_for_impl();
|
||||
|
||||
let syn::Data::Struct(struct_data) = &derived_input.data else {
|
||||
panic!("test_random_derive only supports structs.");
|
||||
};
|
||||
|
||||
// Build quotes for fields that should be generated and those that should be built from
|
||||
// `Default`.
|
||||
let mut quotes = vec![];
|
||||
for field in &struct_data.fields {
|
||||
match &field.ident {
|
||||
Some(ident) => {
|
||||
if should_use_default(field) {
|
||||
quotes.push(quote! {
|
||||
#ident: <_>::default(),
|
||||
});
|
||||
} else {
|
||||
quotes.push(quote! {
|
||||
#ident: <_>::random_for_test(rng),
|
||||
});
|
||||
}
|
||||
}
|
||||
_ => panic!("test_random_derive only supports named struct fields."),
|
||||
};
|
||||
}
|
||||
|
||||
let output = quote! {
|
||||
impl #impl_generics TestRandom for #name #ty_generics #where_clause {
|
||||
fn random_for_test(rng: &mut impl rand::RngCore) -> Self {
|
||||
Self {
|
||||
#(
|
||||
#quotes
|
||||
)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
output.into()
|
||||
}
|
||||
@@ -110,6 +110,17 @@ pub fn not_synced(msg: String) -> warp::reject::Rejection {
|
||||
warp::reject::custom(NotSynced(msg))
|
||||
}
|
||||
|
||||
/// A 404 Not Found response for when no block has been received for the
|
||||
/// requested slot.
|
||||
#[derive(Debug)]
|
||||
pub struct BlockNotFound(pub String);
|
||||
|
||||
impl Reject for BlockNotFound {}
|
||||
|
||||
pub fn block_not_found(msg: String) -> warp::reject::Rejection {
|
||||
warp::reject::custom(BlockNotFound(msg))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct InvalidAuthorization(pub String);
|
||||
|
||||
@@ -199,6 +210,9 @@ pub async fn handle_rejection(err: warp::Rejection) -> Result<impl warp::Reply,
|
||||
} else if let Some(e) = err.find::<crate::reject::NotSynced>() {
|
||||
code = StatusCode::SERVICE_UNAVAILABLE;
|
||||
message = format!("SERVICE_UNAVAILABLE: beacon node is syncing: {}", e.0);
|
||||
} else if let Some(e) = err.find::<crate::reject::BlockNotFound>() {
|
||||
code = StatusCode::NOT_FOUND;
|
||||
message = format!("NOT_FOUND: {}", e.0);
|
||||
} else if let Some(e) = err.find::<crate::reject::InvalidAuthorization>() {
|
||||
code = StatusCode::FORBIDDEN;
|
||||
message = format!("FORBIDDEN: Invalid auth token: {}", e.0);
|
||||
|
||||
Reference in New Issue
Block a user