Implement skip_randao_verification
and blinded block rewards API (#3540)
## Issue Addressed https://github.com/ethereum/beacon-APIs/pull/222 ## Proposed Changes Update Lighthouse's randao verification API to match the `beacon-APIs` spec. We implemented the API before spec stabilisation, and it changed slightly in the course of review. Rather than a flag `verify_randao` taking a boolean value, the new API uses a `skip_randao_verification` flag which takes no argument. The new spec also requires the randao reveal to be present and equal to the point-at-infinity when `skip_randao_verification` is set. I've also updated the `POST /lighthouse/analysis/block_rewards` API to take blinded blocks as input, as the execution payload is irrelevant and we may want to assess blocks produced by builders. ## Additional Info This is technically a breaking change, but seeing as I suspect I'm the only one using these parameters/APIs, I think we're OK to include this in a patch release.
This commit is contained in:
parent
ca42ef2e5a
commit
f2ac0738d8
@ -4,7 +4,7 @@ use lru::LruCache;
|
|||||||
use slog::{debug, warn, Logger};
|
use slog::{debug, warn, Logger};
|
||||||
use state_processing::BlockReplayer;
|
use state_processing::BlockReplayer;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use types::BeaconBlock;
|
use types::BlindedBeaconBlock;
|
||||||
use warp_utils::reject::{
|
use warp_utils::reject::{
|
||||||
beacon_chain_error, beacon_state_error, custom_bad_request, custom_server_error,
|
beacon_chain_error, beacon_state_error, custom_bad_request, custom_server_error,
|
||||||
};
|
};
|
||||||
@ -96,7 +96,7 @@ pub fn get_block_rewards<T: BeaconChainTypes>(
|
|||||||
|
|
||||||
/// Compute block rewards for blocks passed in as input.
|
/// Compute block rewards for blocks passed in as input.
|
||||||
pub fn compute_block_rewards<T: BeaconChainTypes>(
|
pub fn compute_block_rewards<T: BeaconChainTypes>(
|
||||||
blocks: Vec<BeaconBlock<T::EthSpec>>,
|
blocks: Vec<BlindedBeaconBlock<T::EthSpec>>,
|
||||||
chain: Arc<BeaconChain<T>>,
|
chain: Arc<BeaconChain<T>>,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
) -> Result<Vec<BlockReward>, warp::Rejection> {
|
) -> Result<Vec<BlockReward>, warp::Rejection> {
|
||||||
|
@ -25,7 +25,9 @@ use beacon_chain::{
|
|||||||
BeaconChainTypes, ProduceBlockVerification, WhenSlotSkipped,
|
BeaconChainTypes, ProduceBlockVerification, WhenSlotSkipped,
|
||||||
};
|
};
|
||||||
pub use block_id::BlockId;
|
pub use block_id::BlockId;
|
||||||
use eth2::types::{self as api_types, EndpointVersion, ValidatorId, ValidatorStatus};
|
use eth2::types::{
|
||||||
|
self as api_types, EndpointVersion, SkipRandaoVerification, ValidatorId, ValidatorStatus,
|
||||||
|
};
|
||||||
use lighthouse_network::{types::SyncState, EnrExt, NetworkGlobals, PeerId, PubsubMessage};
|
use lighthouse_network::{types::SyncState, EnrExt, NetworkGlobals, PeerId, PubsubMessage};
|
||||||
use lighthouse_version::version_with_platform;
|
use lighthouse_version::version_with_platform;
|
||||||
use network::{NetworkMessage, NetworkSenders, ValidatorSubscriptionMessage};
|
use network::{NetworkMessage, NetworkSenders, ValidatorSubscriptionMessage};
|
||||||
@ -35,7 +37,6 @@ use slot_clock::SlotClock;
|
|||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
pub use state_id::StateId;
|
pub use state_id::StateId;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::convert::TryInto;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -46,7 +47,7 @@ use tokio_stream::{wrappers::BroadcastStream, StreamExt};
|
|||||||
use types::{
|
use types::{
|
||||||
Attestation, AttestationData, AttesterSlashing, BeaconStateError, BlindedPayload,
|
Attestation, AttestationData, AttesterSlashing, BeaconStateError, BlindedPayload,
|
||||||
CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, FullPayload,
|
CommitteeCache, ConfigAndPreset, Epoch, EthSpec, ForkName, FullPayload,
|
||||||
ProposerPreparationData, ProposerSlashing, RelativeEpoch, Signature, SignedAggregateAndProof,
|
ProposerPreparationData, ProposerSlashing, RelativeEpoch, SignedAggregateAndProof,
|
||||||
SignedBeaconBlock, SignedBlindedBeaconBlock, SignedContributionAndProof,
|
SignedBeaconBlock, SignedBlindedBeaconBlock, SignedContributionAndProof,
|
||||||
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncCommitteeMessage,
|
SignedValidatorRegistrationData, SignedVoluntaryExit, Slot, SyncCommitteeMessage,
|
||||||
SyncContributionData,
|
SyncContributionData,
|
||||||
@ -2002,31 +2003,25 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
slot: Slot,
|
slot: Slot,
|
||||||
query: api_types::ValidatorBlocksQuery,
|
query: api_types::ValidatorBlocksQuery,
|
||||||
chain: Arc<BeaconChain<T>>| async move {
|
chain: Arc<BeaconChain<T>>| async move {
|
||||||
let randao_reveal = query.randao_reveal.as_ref().map_or_else(
|
let randao_reveal = query.randao_reveal.decompress().map_err(|e| {
|
||||||
|| {
|
warp_utils::reject::custom_bad_request(format!(
|
||||||
if query.verify_randao {
|
"randao reveal is not a valid BLS signature: {:?}",
|
||||||
Err(warp_utils::reject::custom_bad_request(
|
e
|
||||||
"randao_reveal is mandatory unless verify_randao=false".into(),
|
))
|
||||||
))
|
})?;
|
||||||
} else {
|
|
||||||
Ok(Signature::empty())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|sig_bytes| {
|
|
||||||
sig_bytes.try_into().map_err(|e| {
|
|
||||||
warp_utils::reject::custom_bad_request(format!(
|
|
||||||
"randao reveal is not a valid BLS signature: {:?}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let randao_verification = if query.verify_randao {
|
let randao_verification =
|
||||||
ProduceBlockVerification::VerifyRandao
|
if query.skip_randao_verification == SkipRandaoVerification::Yes {
|
||||||
} else {
|
if !randao_reveal.is_infinity() {
|
||||||
ProduceBlockVerification::NoVerification
|
return Err(warp_utils::reject::custom_bad_request(
|
||||||
};
|
"randao_reveal must be point-at-infinity if verification is skipped"
|
||||||
|
.into(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ProduceBlockVerification::NoVerification
|
||||||
|
} else {
|
||||||
|
ProduceBlockVerification::VerifyRandao
|
||||||
|
};
|
||||||
|
|
||||||
let (block, _) = chain
|
let (block, _) = chain
|
||||||
.produce_block_with_verification::<FullPayload<T::EthSpec>>(
|
.produce_block_with_verification::<FullPayload<T::EthSpec>>(
|
||||||
@ -2064,31 +2059,25 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
|slot: Slot,
|
|slot: Slot,
|
||||||
query: api_types::ValidatorBlocksQuery,
|
query: api_types::ValidatorBlocksQuery,
|
||||||
chain: Arc<BeaconChain<T>>| async move {
|
chain: Arc<BeaconChain<T>>| async move {
|
||||||
let randao_reveal = query.randao_reveal.as_ref().map_or_else(
|
let randao_reveal = query.randao_reveal.decompress().map_err(|e| {
|
||||||
|| {
|
warp_utils::reject::custom_bad_request(format!(
|
||||||
if query.verify_randao {
|
"randao reveal is not a valid BLS signature: {:?}",
|
||||||
Err(warp_utils::reject::custom_bad_request(
|
e
|
||||||
"randao_reveal is mandatory unless verify_randao=false".into(),
|
))
|
||||||
))
|
})?;
|
||||||
} else {
|
|
||||||
Ok(Signature::empty())
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|sig_bytes| {
|
|
||||||
sig_bytes.try_into().map_err(|e| {
|
|
||||||
warp_utils::reject::custom_bad_request(format!(
|
|
||||||
"randao reveal is not a valid BLS signature: {:?}",
|
|
||||||
e
|
|
||||||
))
|
|
||||||
})
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let randao_verification = if query.verify_randao {
|
let randao_verification =
|
||||||
ProduceBlockVerification::VerifyRandao
|
if query.skip_randao_verification == SkipRandaoVerification::Yes {
|
||||||
} else {
|
if !randao_reveal.is_infinity() {
|
||||||
ProduceBlockVerification::NoVerification
|
return Err(warp_utils::reject::custom_bad_request(
|
||||||
};
|
"randao_reveal must be point-at-infinity if verification is skipped"
|
||||||
|
.into()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
ProduceBlockVerification::NoVerification
|
||||||
|
} else {
|
||||||
|
ProduceBlockVerification::VerifyRandao
|
||||||
|
};
|
||||||
|
|
||||||
let (block, _) = chain
|
let (block, _) = chain
|
||||||
.produce_block_with_verification::<BlindedPayload<T::EthSpec>>(
|
.produce_block_with_verification::<BlindedPayload<T::EthSpec>>(
|
||||||
@ -2103,6 +2092,7 @@ pub fn serve<T: BeaconChainTypes>(
|
|||||||
.to_ref()
|
.to_ref()
|
||||||
.fork_name(&chain.spec)
|
.fork_name(&chain.spec)
|
||||||
.map_err(inconsistent_fork_rejection)?;
|
.map_err(inconsistent_fork_rejection)?;
|
||||||
|
|
||||||
// Pose as a V2 endpoint so we return the fork `version`.
|
// Pose as a V2 endpoint so we return the fork `version`.
|
||||||
fork_versioned_response(V2, fork_name, block)
|
fork_versioned_response(V2, fork_name, block)
|
||||||
.map(|response| warp::reply::json(&response))
|
.map(|response| warp::reply::json(&response))
|
||||||
|
@ -1939,11 +1939,11 @@ impl ApiTester {
|
|||||||
|
|
||||||
let block = self
|
let block = self
|
||||||
.client
|
.client
|
||||||
.get_validator_blocks_with_verify_randao::<E, FullPayload<E>>(
|
.get_validator_blocks_modular::<E, FullPayload<E>>(
|
||||||
slot,
|
slot,
|
||||||
|
&Signature::infinity().unwrap().into(),
|
||||||
None,
|
None,
|
||||||
None,
|
SkipRandaoVerification::Yes,
|
||||||
Some(false),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -1993,45 +1993,23 @@ impl ApiTester {
|
|||||||
sk.sign(message).into()
|
sk.sign(message).into()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check failure with no `verify_randao` passed.
|
// Check failure with no `skip_randao_verification` passed.
|
||||||
self.client
|
self.client
|
||||||
.get_validator_blocks::<E, FullPayload<E>>(slot, &bad_randao_reveal, None)
|
.get_validator_blocks::<E, FullPayload<E>>(slot, &bad_randao_reveal, None)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
// Check failure with `verify_randao=true`.
|
// Check failure with `skip_randao_verification` (requires infinity sig).
|
||||||
self.client
|
self.client
|
||||||
.get_validator_blocks_with_verify_randao::<E, FullPayload<E>>(
|
.get_validator_blocks_modular::<E, FullPayload<E>>(
|
||||||
slot,
|
slot,
|
||||||
Some(&bad_randao_reveal),
|
&bad_randao_reveal,
|
||||||
None,
|
None,
|
||||||
Some(true),
|
SkipRandaoVerification::Yes,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
// Check failure with no randao reveal provided.
|
|
||||||
self.client
|
|
||||||
.get_validator_blocks_with_verify_randao::<E, FullPayload<E>>(
|
|
||||||
slot, None, None, None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
// Check success with `verify_randao=false`.
|
|
||||||
let block = self
|
|
||||||
.client
|
|
||||||
.get_validator_blocks_with_verify_randao::<E, FullPayload<E>>(
|
|
||||||
slot,
|
|
||||||
Some(&bad_randao_reveal),
|
|
||||||
None,
|
|
||||||
Some(false),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.data;
|
|
||||||
|
|
||||||
assert_eq!(block.slot(), slot);
|
|
||||||
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2106,11 +2084,11 @@ impl ApiTester {
|
|||||||
|
|
||||||
let block = self
|
let block = self
|
||||||
.client
|
.client
|
||||||
.get_validator_blinded_blocks_with_verify_randao::<E, Payload>(
|
.get_validator_blinded_blocks_modular::<E, Payload>(
|
||||||
slot,
|
slot,
|
||||||
|
&Signature::infinity().unwrap().into(),
|
||||||
None,
|
None,
|
||||||
None,
|
SkipRandaoVerification::Yes,
|
||||||
Some(false),
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -2162,45 +2140,23 @@ impl ApiTester {
|
|||||||
sk.sign(message).into()
|
sk.sign(message).into()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check failure with no `verify_randao` passed.
|
// Check failure with full randao verification enabled.
|
||||||
self.client
|
self.client
|
||||||
.get_validator_blinded_blocks::<E, Payload>(slot, &bad_randao_reveal, None)
|
.get_validator_blinded_blocks::<E, Payload>(slot, &bad_randao_reveal, None)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
// Check failure with `verify_randao=true`.
|
// Check failure with `skip_randao_verification` (requires infinity sig).
|
||||||
self.client
|
self.client
|
||||||
.get_validator_blinded_blocks_with_verify_randao::<E, Payload>(
|
.get_validator_blinded_blocks_modular::<E, Payload>(
|
||||||
slot,
|
slot,
|
||||||
Some(&bad_randao_reveal),
|
&bad_randao_reveal,
|
||||||
None,
|
None,
|
||||||
Some(true),
|
SkipRandaoVerification::Yes,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
|
|
||||||
// Check failure with no randao reveal provided.
|
|
||||||
self.client
|
|
||||||
.get_validator_blinded_blocks_with_verify_randao::<E, Payload>(
|
|
||||||
slot, None, None, None,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap_err();
|
|
||||||
|
|
||||||
// Check success with `verify_randao=false`.
|
|
||||||
let block = self
|
|
||||||
.client
|
|
||||||
.get_validator_blinded_blocks_with_verify_randao::<E, Payload>(
|
|
||||||
slot,
|
|
||||||
Some(&bad_randao_reveal),
|
|
||||||
None,
|
|
||||||
Some(false),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.data;
|
|
||||||
|
|
||||||
assert_eq!(block.slot(), slot);
|
|
||||||
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
self.chain.slot_clock.set_slot(slot.as_u64() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1233,17 +1233,17 @@ impl BeaconNodeHttpClient {
|
|||||||
randao_reveal: &SignatureBytes,
|
randao_reveal: &SignatureBytes,
|
||||||
graffiti: Option<&Graffiti>,
|
graffiti: Option<&Graffiti>,
|
||||||
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
||||||
self.get_validator_blocks_with_verify_randao(slot, Some(randao_reveal), graffiti, None)
|
self.get_validator_blocks_modular(slot, randao_reveal, graffiti, SkipRandaoVerification::No)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `GET v2/validator/blocks/{slot}`
|
/// `GET v2/validator/blocks/{slot}`
|
||||||
pub async fn get_validator_blocks_with_verify_randao<T: EthSpec, Payload: ExecPayload<T>>(
|
pub async fn get_validator_blocks_modular<T: EthSpec, Payload: ExecPayload<T>>(
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
randao_reveal: Option<&SignatureBytes>,
|
randao_reveal: &SignatureBytes,
|
||||||
graffiti: Option<&Graffiti>,
|
graffiti: Option<&Graffiti>,
|
||||||
verify_randao: Option<bool>,
|
skip_randao_verification: SkipRandaoVerification,
|
||||||
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
||||||
let mut path = self.eth_path(V2)?;
|
let mut path = self.eth_path(V2)?;
|
||||||
|
|
||||||
@ -1253,19 +1253,17 @@ impl BeaconNodeHttpClient {
|
|||||||
.push("blocks")
|
.push("blocks")
|
||||||
.push(&slot.to_string());
|
.push(&slot.to_string());
|
||||||
|
|
||||||
if let Some(randao_reveal) = randao_reveal {
|
path.query_pairs_mut()
|
||||||
path.query_pairs_mut()
|
.append_pair("randao_reveal", &randao_reveal.to_string());
|
||||||
.append_pair("randao_reveal", &randao_reveal.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(graffiti) = graffiti {
|
if let Some(graffiti) = graffiti {
|
||||||
path.query_pairs_mut()
|
path.query_pairs_mut()
|
||||||
.append_pair("graffiti", &graffiti.to_string());
|
.append_pair("graffiti", &graffiti.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(verify_randao) = verify_randao {
|
if skip_randao_verification == SkipRandaoVerification::Yes {
|
||||||
path.query_pairs_mut()
|
path.query_pairs_mut()
|
||||||
.append_pair("verify_randao", &verify_randao.to_string());
|
.append_pair("skip_randao_verification", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.get(path).await
|
self.get(path).await
|
||||||
@ -1278,25 +1276,22 @@ impl BeaconNodeHttpClient {
|
|||||||
randao_reveal: &SignatureBytes,
|
randao_reveal: &SignatureBytes,
|
||||||
graffiti: Option<&Graffiti>,
|
graffiti: Option<&Graffiti>,
|
||||||
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
||||||
self.get_validator_blinded_blocks_with_verify_randao(
|
self.get_validator_blinded_blocks_modular(
|
||||||
slot,
|
slot,
|
||||||
Some(randao_reveal),
|
randao_reveal,
|
||||||
graffiti,
|
graffiti,
|
||||||
None,
|
SkipRandaoVerification::No,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `GET v1/validator/blinded_blocks/{slot}`
|
/// `GET v1/validator/blinded_blocks/{slot}`
|
||||||
pub async fn get_validator_blinded_blocks_with_verify_randao<
|
pub async fn get_validator_blinded_blocks_modular<T: EthSpec, Payload: ExecPayload<T>>(
|
||||||
T: EthSpec,
|
|
||||||
Payload: ExecPayload<T>,
|
|
||||||
>(
|
|
||||||
&self,
|
&self,
|
||||||
slot: Slot,
|
slot: Slot,
|
||||||
randao_reveal: Option<&SignatureBytes>,
|
randao_reveal: &SignatureBytes,
|
||||||
graffiti: Option<&Graffiti>,
|
graffiti: Option<&Graffiti>,
|
||||||
verify_randao: Option<bool>,
|
skip_randao_verification: SkipRandaoVerification,
|
||||||
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
) -> Result<ForkVersionedResponse<BeaconBlock<T, Payload>>, Error> {
|
||||||
let mut path = self.eth_path(V1)?;
|
let mut path = self.eth_path(V1)?;
|
||||||
|
|
||||||
@ -1306,19 +1301,17 @@ impl BeaconNodeHttpClient {
|
|||||||
.push("blinded_blocks")
|
.push("blinded_blocks")
|
||||||
.push(&slot.to_string());
|
.push(&slot.to_string());
|
||||||
|
|
||||||
if let Some(randao_reveal) = randao_reveal {
|
path.query_pairs_mut()
|
||||||
path.query_pairs_mut()
|
.append_pair("randao_reveal", &randao_reveal.to_string());
|
||||||
.append_pair("randao_reveal", &randao_reveal.to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(graffiti) = graffiti {
|
if let Some(graffiti) = graffiti {
|
||||||
path.query_pairs_mut()
|
path.query_pairs_mut()
|
||||||
.append_pair("graffiti", &graffiti.to_string());
|
.append_pair("graffiti", &graffiti.to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(verify_randao) = verify_randao {
|
if skip_randao_verification == SkipRandaoVerification::Yes {
|
||||||
path.query_pairs_mut()
|
path.query_pairs_mut()
|
||||||
.append_pair("verify_randao", &verify_randao.to_string());
|
.append_key_only("skip_randao_verification");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.get(path).await
|
self.get(path).await
|
||||||
|
@ -658,16 +658,34 @@ pub struct ProposerData {
|
|||||||
pub slot: Slot,
|
pub slot: Slot,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Deserialize)]
|
||||||
pub struct ValidatorBlocksQuery {
|
pub struct ValidatorBlocksQuery {
|
||||||
pub randao_reveal: Option<SignatureBytes>,
|
pub randao_reveal: SignatureBytes,
|
||||||
pub graffiti: Option<Graffiti>,
|
pub graffiti: Option<Graffiti>,
|
||||||
#[serde(default = "default_verify_randao")]
|
pub skip_randao_verification: SkipRandaoVerification,
|
||||||
pub verify_randao: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_verify_randao() -> bool {
|
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Deserialize)]
|
||||||
true
|
#[serde(try_from = "Option<String>")]
|
||||||
|
pub enum SkipRandaoVerification {
|
||||||
|
Yes,
|
||||||
|
#[default]
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Parse a `skip_randao_verification` query parameter.
|
||||||
|
impl TryFrom<Option<String>> for SkipRandaoVerification {
|
||||||
|
type Error = String;
|
||||||
|
|
||||||
|
fn try_from(opt: Option<String>) -> Result<Self, String> {
|
||||||
|
match opt.as_deref() {
|
||||||
|
None => Ok(SkipRandaoVerification::No),
|
||||||
|
Some("") => Ok(SkipRandaoVerification::Yes),
|
||||||
|
Some(s) => Err(format!(
|
||||||
|
"skip_randao_verification does not take a value, got: {s}"
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
|
@ -66,6 +66,8 @@ pub struct BeaconBlock<T: EthSpec, Payload: ExecPayload<T> = FullPayload<T>> {
|
|||||||
pub body: BeaconBlockBodyMerge<T, Payload>,
|
pub body: BeaconBlockBodyMerge<T, Payload>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type BlindedBeaconBlock<E> = BeaconBlock<E, BlindedPayload<E>>;
|
||||||
|
|
||||||
impl<T: EthSpec, Payload: ExecPayload<T>> SignedRoot for BeaconBlock<T, Payload> {}
|
impl<T: EthSpec, Payload: ExecPayload<T>> SignedRoot for BeaconBlock<T, Payload> {}
|
||||||
impl<'a, T: EthSpec, Payload: ExecPayload<T>> SignedRoot for BeaconBlockRef<'a, T, Payload> {}
|
impl<'a, T: EthSpec, Payload: ExecPayload<T>> SignedRoot for BeaconBlockRef<'a, T, Payload> {}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ pub use crate::attestation_duty::AttestationDuty;
|
|||||||
pub use crate::attester_slashing::AttesterSlashing;
|
pub use crate::attester_slashing::AttesterSlashing;
|
||||||
pub use crate::beacon_block::{
|
pub use crate::beacon_block::{
|
||||||
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, BeaconBlockRef,
|
BeaconBlock, BeaconBlockAltair, BeaconBlockBase, BeaconBlockMerge, BeaconBlockRef,
|
||||||
BeaconBlockRefMut,
|
BeaconBlockRefMut, BlindedBeaconBlock,
|
||||||
};
|
};
|
||||||
pub use crate::beacon_block_body::{
|
pub use crate::beacon_block_body::{
|
||||||
BeaconBlockBody, BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyMerge,
|
BeaconBlockBody, BeaconBlockBodyAltair, BeaconBlockBodyBase, BeaconBlockBodyMerge,
|
||||||
|
@ -80,6 +80,18 @@ where
|
|||||||
self.point.is_none()
|
self.point.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Initialize self to the point-at-infinity.
|
||||||
|
///
|
||||||
|
/// In general `AggregateSignature::infinity` should be used in favour of this function.
|
||||||
|
pub fn infinity() -> Result<Self, Error> {
|
||||||
|
Self::deserialize(&INFINITY_SIGNATURE)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if `self` is equal to the point at infinity.
|
||||||
|
pub fn is_infinity(&self) -> bool {
|
||||||
|
self.is_infinity
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a reference to the underlying BLS point.
|
/// Returns a reference to the underlying BLS point.
|
||||||
pub(crate) fn point(&self) -> Option<&Sig> {
|
pub(crate) fn point(&self) -> Option<&Sig> {
|
||||||
self.point.as_ref()
|
self.point.as_ref()
|
||||||
|
Loading…
Reference in New Issue
Block a user