mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 04:37:13 +00:00
Pass blobs into ValidatorStore::sign_block (#7497)
While the Lighthouse implementation of the `ValidatorStore` does not really care about blobs, Anchor needs to be able to return different blobs from `sign_blocks` than what was passed into it, in case it decides to sign another Anchor node's block. Only passing the unsigned block into `sign_block` and only returning a signed block from it (without any blobs and proofs) was an oversight in #6705. - Replace `validator_store::{Uns,S}ignedBlock` with `validator_store::block_service::{Uns,S}ignedBlock`, as we need all data in there. - In `lighthouse_validator_store`, just add the received blobs back to the signed block after signing it.
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -9804,6 +9804,7 @@ dependencies = [
|
|||||||
name = "validator_store"
|
name = "validator_store"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"eth2",
|
||||||
"slashing_protection",
|
"slashing_protection",
|
||||||
"types",
|
"types",
|
||||||
]
|
]
|
||||||
@@ -10059,6 +10060,7 @@ dependencies = [
|
|||||||
"account_utils",
|
"account_utils",
|
||||||
"async-channel 1.9.0",
|
"async-channel 1.9.0",
|
||||||
"environment",
|
"environment",
|
||||||
|
"eth2",
|
||||||
"eth2_keystore",
|
"eth2_keystore",
|
||||||
"eth2_network_config",
|
"eth2_network_config",
|
||||||
"futures",
|
"futures",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ edition = { workspace = true }
|
|||||||
account_utils = { workspace = true }
|
account_utils = { workspace = true }
|
||||||
async-channel = { workspace = true }
|
async-channel = { workspace = true }
|
||||||
environment = { workspace = true }
|
environment = { workspace = true }
|
||||||
|
eth2 = { workspace = true }
|
||||||
eth2_keystore = { workspace = true }
|
eth2_keystore = { workspace = true }
|
||||||
eth2_network_config = { workspace = true }
|
eth2_network_config = { workspace = true }
|
||||||
futures = { workspace = true }
|
futures = { workspace = true }
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ mod tests {
|
|||||||
use account_utils::validator_definitions::{
|
use account_utils::validator_definitions::{
|
||||||
SigningDefinition, ValidatorDefinition, ValidatorDefinitions, Web3SignerDefinition,
|
SigningDefinition, ValidatorDefinition, ValidatorDefinitions, Web3SignerDefinition,
|
||||||
};
|
};
|
||||||
|
use eth2::types::FullBlockContents;
|
||||||
use eth2_keystore::KeystoreBuilder;
|
use eth2_keystore::KeystoreBuilder;
|
||||||
use eth2_network_config::Eth2NetworkConfig;
|
use eth2_network_config::Eth2NetworkConfig;
|
||||||
use initialized_validators::{
|
use initialized_validators::{
|
||||||
@@ -45,7 +46,9 @@ mod tests {
|
|||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
use types::{attestation::AttestationBase, *};
|
use types::{attestation::AttestationBase, *};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use validator_store::{Error as ValidatorStoreError, SignedBlock, ValidatorStore};
|
use validator_store::{
|
||||||
|
Error as ValidatorStoreError, SignedBlock, UnsignedBlock, ValidatorStore,
|
||||||
|
};
|
||||||
|
|
||||||
/// If the we are unable to reach the Web3Signer HTTP API within this time out then we will
|
/// If the we are unable to reach the Web3Signer HTTP API within this time out then we will
|
||||||
/// assume it failed to start.
|
/// assume it failed to start.
|
||||||
@@ -595,8 +598,9 @@ mod tests {
|
|||||||
async move {
|
async move {
|
||||||
let block = BeaconBlock::<E>::Base(BeaconBlockBase::empty(&spec));
|
let block = BeaconBlock::<E>::Base(BeaconBlockBase::empty(&spec));
|
||||||
let block_slot = block.slot();
|
let block_slot = block.slot();
|
||||||
|
let unsigned_block = UnsignedBlock::Full(FullBlockContents::Block(block));
|
||||||
validator_store
|
validator_store
|
||||||
.sign_block(pubkey, block.into(), block_slot)
|
.sign_block(pubkey, unsigned_block, block_slot)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -665,12 +669,10 @@ mod tests {
|
|||||||
async move {
|
async move {
|
||||||
let mut altair_block = BeaconBlockAltair::empty(&spec);
|
let mut altair_block = BeaconBlockAltair::empty(&spec);
|
||||||
altair_block.slot = altair_fork_slot;
|
altair_block.slot = altair_fork_slot;
|
||||||
|
let unsigned_block =
|
||||||
|
UnsignedBlock::Full(FullBlockContents::Block(altair_block.into()));
|
||||||
validator_store
|
validator_store
|
||||||
.sign_block(
|
.sign_block(pubkey, unsigned_block, altair_fork_slot)
|
||||||
pubkey,
|
|
||||||
BeaconBlock::<E>::Altair(altair_block).into(),
|
|
||||||
altair_fork_slot,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -752,12 +754,10 @@ mod tests {
|
|||||||
async move {
|
async move {
|
||||||
let mut bellatrix_block = BeaconBlockBellatrix::empty(&spec);
|
let mut bellatrix_block = BeaconBlockBellatrix::empty(&spec);
|
||||||
bellatrix_block.slot = bellatrix_fork_slot;
|
bellatrix_block.slot = bellatrix_fork_slot;
|
||||||
|
let unsigned_block =
|
||||||
|
UnsignedBlock::Full(FullBlockContents::Block(bellatrix_block.into()));
|
||||||
validator_store
|
validator_store
|
||||||
.sign_block(
|
.sign_block(pubkey, unsigned_block, bellatrix_fork_slot)
|
||||||
pubkey,
|
|
||||||
BeaconBlock::<E>::Bellatrix(bellatrix_block).into(),
|
|
||||||
bellatrix_fork_slot,
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
@@ -876,8 +876,9 @@ mod tests {
|
|||||||
.assert_signatures_match("first_block", |pubkey, validator_store| async move {
|
.assert_signatures_match("first_block", |pubkey, validator_store| async move {
|
||||||
let block = first_block();
|
let block = first_block();
|
||||||
let slot = block.slot();
|
let slot = block.slot();
|
||||||
|
let unsigned_block = UnsignedBlock::Full(FullBlockContents::Block(block));
|
||||||
validator_store
|
validator_store
|
||||||
.sign_block(pubkey, block.into(), slot)
|
.sign_block(pubkey, unsigned_block, slot)
|
||||||
.await
|
.await
|
||||||
.unwrap()
|
.unwrap()
|
||||||
})
|
})
|
||||||
@@ -887,8 +888,9 @@ mod tests {
|
|||||||
move |pubkey, validator_store| async move {
|
move |pubkey, validator_store| async move {
|
||||||
let block = double_vote_block();
|
let block = double_vote_block();
|
||||||
let slot = block.slot();
|
let slot = block.slot();
|
||||||
|
let unsigned_block = UnsignedBlock::Full(FullBlockContents::Block(block));
|
||||||
validator_store
|
validator_store
|
||||||
.sign_block(pubkey, block.into(), slot)
|
.sign_block(pubkey, unsigned_block, slot)
|
||||||
.await
|
.await
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use account_utils::validator_definitions::{PasswordStorage, ValidatorDefinition};
|
use account_utils::validator_definitions::{PasswordStorage, ValidatorDefinition};
|
||||||
use doppelganger_service::DoppelgangerService;
|
use doppelganger_service::DoppelgangerService;
|
||||||
|
use eth2::types::PublishBlockRequest;
|
||||||
use initialized_validators::InitializedValidators;
|
use initialized_validators::InitializedValidators;
|
||||||
use logging::crit;
|
use logging::crit;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
@@ -733,14 +734,18 @@ impl<T: SlotClock + 'static, E: EthSpec> ValidatorStore for LighthouseValidatorS
|
|||||||
current_slot: Slot,
|
current_slot: Slot,
|
||||||
) -> Result<SignedBlock<E>, Error> {
|
) -> Result<SignedBlock<E>, Error> {
|
||||||
match block {
|
match block {
|
||||||
UnsignedBlock::Full(block) => self
|
UnsignedBlock::Full(block) => {
|
||||||
.sign_abstract_block(validator_pubkey, block, current_slot)
|
let (block, blobs) = block.deconstruct();
|
||||||
|
self.sign_abstract_block(validator_pubkey, block, current_slot)
|
||||||
.await
|
.await
|
||||||
.map(SignedBlock::Full),
|
.map(|block| {
|
||||||
|
SignedBlock::Full(PublishBlockRequest::new(Arc::new(block), blobs))
|
||||||
|
})
|
||||||
|
}
|
||||||
UnsignedBlock::Blinded(block) => self
|
UnsignedBlock::Blinded(block) => self
|
||||||
.sign_abstract_block(validator_pubkey, block, current_slot)
|
.sign_abstract_block(validator_pubkey, block, current_slot)
|
||||||
.await
|
.await
|
||||||
.map(SignedBlock::Blinded),
|
.map(|block| SignedBlock::Blinded(Arc::new(block))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use beacon_node_fallback::{ApiTopic, BeaconNodeFallback, Error as FallbackError, Errors};
|
use beacon_node_fallback::{ApiTopic, BeaconNodeFallback, Error as FallbackError, Errors};
|
||||||
use bls::SignatureBytes;
|
use bls::SignatureBytes;
|
||||||
use eth2::types::{FullBlockContents, PublishBlockRequest};
|
|
||||||
use eth2::{BeaconNodeHttpClient, StatusCode};
|
use eth2::{BeaconNodeHttpClient, StatusCode};
|
||||||
use graffiti_file::{determine_graffiti, GraffitiFile};
|
use graffiti_file::{determine_graffiti, GraffitiFile};
|
||||||
use logging::crit;
|
use logging::crit;
|
||||||
@@ -13,11 +12,8 @@ use std::time::Duration;
|
|||||||
use task_executor::TaskExecutor;
|
use task_executor::TaskExecutor;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tracing::{debug, error, info, trace, warn};
|
use tracing::{debug, error, info, trace, warn};
|
||||||
use types::{
|
use types::{BlockType, ChainSpec, EthSpec, Graffiti, PublicKeyBytes, Slot};
|
||||||
BlindedBeaconBlock, BlockType, ChainSpec, EthSpec, Graffiti, PublicKeyBytes,
|
use validator_store::{Error as ValidatorStoreError, SignedBlock, UnsignedBlock, ValidatorStore};
|
||||||
SignedBlindedBeaconBlock, Slot,
|
|
||||||
};
|
|
||||||
use validator_store::{Error as ValidatorStoreError, ValidatorStore};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BlockError {
|
pub enum BlockError {
|
||||||
@@ -335,26 +331,10 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
) -> Result<(), BlockError> {
|
) -> Result<(), BlockError> {
|
||||||
let signing_timer = validator_metrics::start_timer(&validator_metrics::BLOCK_SIGNING_TIMES);
|
let signing_timer = validator_metrics::start_timer(&validator_metrics::BLOCK_SIGNING_TIMES);
|
||||||
|
|
||||||
let (block, maybe_blobs) = match unsigned_block {
|
|
||||||
UnsignedBlock::Full(block_contents) => {
|
|
||||||
let (block, maybe_blobs) = block_contents.deconstruct();
|
|
||||||
(block.into(), maybe_blobs)
|
|
||||||
}
|
|
||||||
UnsignedBlock::Blinded(block) => (block.into(), None),
|
|
||||||
};
|
|
||||||
|
|
||||||
let res = self
|
let res = self
|
||||||
.validator_store
|
.validator_store
|
||||||
.sign_block(*validator_pubkey, block, slot)
|
.sign_block(*validator_pubkey, unsigned_block, slot)
|
||||||
.await
|
.await;
|
||||||
.map(|block| match block {
|
|
||||||
validator_store::SignedBlock::Full(block) => {
|
|
||||||
SignedBlock::Full(PublishBlockRequest::new(Arc::new(block), maybe_blobs))
|
|
||||||
}
|
|
||||||
validator_store::SignedBlock::Blinded(block) => {
|
|
||||||
SignedBlock::Blinded(Arc::new(block))
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
let signed_block = match res {
|
let signed_block = match res {
|
||||||
Ok(block) => block,
|
Ok(block) => block,
|
||||||
@@ -398,12 +378,13 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let metadata = BlockMetadata::from(&signed_block);
|
||||||
info!(
|
info!(
|
||||||
block_type = ?signed_block.block_type(),
|
block_type = ?metadata.block_type,
|
||||||
deposits = signed_block.num_deposits(),
|
deposits = metadata.num_deposits,
|
||||||
attestations = signed_block.num_attestations(),
|
attestations = metadata.num_attestations,
|
||||||
graffiti = ?graffiti.map(|g| g.as_utf8_lossy()),
|
graffiti = ?graffiti.map(|g| g.as_utf8_lossy()),
|
||||||
slot = signed_block.slot().as_u64(),
|
slot = metadata.slot.as_u64(),
|
||||||
"Successfully published block"
|
"Successfully published block"
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -508,7 +489,6 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
signed_block: &SignedBlock<S::E>,
|
signed_block: &SignedBlock<S::E>,
|
||||||
beacon_node: BeaconNodeHttpClient,
|
beacon_node: BeaconNodeHttpClient,
|
||||||
) -> Result<(), BlockError> {
|
) -> Result<(), BlockError> {
|
||||||
let slot = signed_block.slot();
|
|
||||||
match signed_block {
|
match signed_block {
|
||||||
SignedBlock::Full(signed_block) => {
|
SignedBlock::Full(signed_block) => {
|
||||||
let _post_timer = validator_metrics::start_timer_vec(
|
let _post_timer = validator_metrics::start_timer_vec(
|
||||||
@@ -518,7 +498,9 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
beacon_node
|
beacon_node
|
||||||
.post_beacon_blocks_v2_ssz(signed_block, None)
|
.post_beacon_blocks_v2_ssz(signed_block, None)
|
||||||
.await
|
.await
|
||||||
.or_else(|e| handle_block_post_error(e, slot))?
|
.or_else(|e| {
|
||||||
|
handle_block_post_error(e, signed_block.signed_block().message().slot())
|
||||||
|
})?
|
||||||
}
|
}
|
||||||
SignedBlock::Blinded(signed_block) => {
|
SignedBlock::Blinded(signed_block) => {
|
||||||
let _post_timer = validator_metrics::start_timer_vec(
|
let _post_timer = validator_metrics::start_timer_vec(
|
||||||
@@ -528,7 +510,7 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
beacon_node
|
beacon_node
|
||||||
.post_beacon_blinded_blocks_v2_ssz(signed_block, None)
|
.post_beacon_blinded_blocks_v2_ssz(signed_block, None)
|
||||||
.await
|
.await
|
||||||
.or_else(|e| handle_block_post_error(e, slot))?
|
.or_else(|e| handle_block_post_error(e, signed_block.message().slot()))?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok::<_, BlockError>(())
|
Ok::<_, BlockError>(())
|
||||||
@@ -557,13 +539,17 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let unsigned_block = match block_response.data {
|
let (block_proposer, unsigned_block) = match block_response.data {
|
||||||
eth2::types::ProduceBlockV3Response::Full(block) => UnsignedBlock::Full(block),
|
eth2::types::ProduceBlockV3Response::Full(block) => {
|
||||||
eth2::types::ProduceBlockV3Response::Blinded(block) => UnsignedBlock::Blinded(block),
|
(block.block().proposer_index(), UnsignedBlock::Full(block))
|
||||||
|
}
|
||||||
|
eth2::types::ProduceBlockV3Response::Blinded(block) => {
|
||||||
|
(block.proposer_index(), UnsignedBlock::Blinded(block))
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
info!(slot = slot.as_u64(), "Received unsigned block");
|
info!(slot = slot.as_u64(), "Received unsigned block");
|
||||||
if proposer_index != Some(unsigned_block.proposer_index()) {
|
if proposer_index != Some(block_proposer) {
|
||||||
return Err(BlockError::Recoverable(
|
return Err(BlockError::Recoverable(
|
||||||
"Proposer index does not match block proposer. Beacon chain re-orged".to_string(),
|
"Proposer index does not match block proposer. Beacon chain re-orged".to_string(),
|
||||||
));
|
));
|
||||||
@@ -573,49 +559,30 @@ impl<S: ValidatorStore + 'static, T: SlotClock + 'static> BlockService<S, T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum UnsignedBlock<E: EthSpec> {
|
/// Wrapper for values we want to log about a block we signed, for easy extraction from the possible
|
||||||
Full(FullBlockContents<E>),
|
/// variants.
|
||||||
Blinded(BlindedBeaconBlock<E>),
|
struct BlockMetadata {
|
||||||
|
block_type: BlockType,
|
||||||
|
slot: Slot,
|
||||||
|
num_deposits: usize,
|
||||||
|
num_attestations: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> UnsignedBlock<E> {
|
impl<E: EthSpec> From<&SignedBlock<E>> for BlockMetadata {
|
||||||
pub fn proposer_index(&self) -> u64 {
|
fn from(value: &SignedBlock<E>) -> Self {
|
||||||
match self {
|
match value {
|
||||||
UnsignedBlock::Full(block) => block.block().proposer_index(),
|
SignedBlock::Full(block) => BlockMetadata {
|
||||||
UnsignedBlock::Blinded(block) => block.proposer_index(),
|
block_type: BlockType::Full,
|
||||||
}
|
slot: block.signed_block().message().slot(),
|
||||||
}
|
num_deposits: block.signed_block().message().body().deposits().len(),
|
||||||
}
|
num_attestations: block.signed_block().message().body().attestations_len(),
|
||||||
|
},
|
||||||
#[derive(Debug)]
|
SignedBlock::Blinded(block) => BlockMetadata {
|
||||||
pub enum SignedBlock<E: EthSpec> {
|
block_type: BlockType::Blinded,
|
||||||
Full(PublishBlockRequest<E>),
|
slot: block.message().slot(),
|
||||||
Blinded(Arc<SignedBlindedBeaconBlock<E>>),
|
num_deposits: block.message().body().deposits().len(),
|
||||||
}
|
num_attestations: block.message().body().attestations_len(),
|
||||||
|
},
|
||||||
impl<E: EthSpec> SignedBlock<E> {
|
|
||||||
pub fn block_type(&self) -> BlockType {
|
|
||||||
match self {
|
|
||||||
SignedBlock::Full(_) => BlockType::Full,
|
|
||||||
SignedBlock::Blinded(_) => BlockType::Blinded,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn slot(&self) -> Slot {
|
|
||||||
match self {
|
|
||||||
SignedBlock::Full(block) => block.signed_block().message().slot(),
|
|
||||||
SignedBlock::Blinded(block) => block.message().slot(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn num_deposits(&self) -> usize {
|
|
||||||
match self {
|
|
||||||
SignedBlock::Full(block) => block.signed_block().message().body().deposits().len(),
|
|
||||||
SignedBlock::Blinded(block) => block.message().body().deposits().len(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn num_attestations(&self) -> usize {
|
|
||||||
match self {
|
|
||||||
SignedBlock::Full(block) => block.signed_block().message().body().attestations_len(),
|
|
||||||
SignedBlock::Blinded(block) => block.message().body().attestations_len(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,6 @@ edition = { workspace = true }
|
|||||||
authors = ["Sigma Prime <contact@sigmaprime.io>"]
|
authors = ["Sigma Prime <contact@sigmaprime.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
eth2 = { workspace = true }
|
||||||
slashing_protection = { workspace = true }
|
slashing_protection = { workspace = true }
|
||||||
types = { workspace = true }
|
types = { workspace = true }
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
|
use eth2::types::{FullBlockContents, PublishBlockRequest};
|
||||||
use slashing_protection::NotSafe;
|
use slashing_protection::NotSafe;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
|
use std::sync::Arc;
|
||||||
use types::{
|
use types::{
|
||||||
Address, Attestation, AttestationError, BeaconBlock, BlindedBeaconBlock, Epoch, EthSpec,
|
Address, Attestation, AttestationError, BlindedBeaconBlock, Epoch, EthSpec, Graffiti, Hash256,
|
||||||
Graffiti, Hash256, PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof,
|
PublicKeyBytes, SelectionProof, Signature, SignedAggregateAndProof, SignedBlindedBeaconBlock,
|
||||||
SignedBeaconBlock, SignedBlindedBeaconBlock, SignedContributionAndProof,
|
SignedContributionAndProof, SignedValidatorRegistrationData, Slot, SyncCommitteeContribution,
|
||||||
SignedValidatorRegistrationData, Slot, SyncCommitteeContribution, SyncCommitteeMessage,
|
SyncCommitteeMessage, SyncSelectionProof, SyncSubnetId, ValidatorRegistrationData,
|
||||||
SyncSelectionProof, SyncSubnetId, ValidatorRegistrationData,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
@@ -170,40 +171,16 @@ pub trait ValidatorStore: Send + Sync {
|
|||||||
fn proposal_data(&self, pubkey: &PublicKeyBytes) -> Option<ProposalData>;
|
fn proposal_data(&self, pubkey: &PublicKeyBytes) -> Option<ProposalData>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Debug)]
|
||||||
pub enum UnsignedBlock<E: EthSpec> {
|
pub enum UnsignedBlock<E: EthSpec> {
|
||||||
Full(BeaconBlock<E>),
|
Full(FullBlockContents<E>),
|
||||||
Blinded(BlindedBeaconBlock<E>),
|
Blinded(BlindedBeaconBlock<E>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> From<BeaconBlock<E>> for UnsignedBlock<E> {
|
|
||||||
fn from(block: BeaconBlock<E>) -> Self {
|
|
||||||
UnsignedBlock::Full(block)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: EthSpec> From<BlindedBeaconBlock<E>> for UnsignedBlock<E> {
|
|
||||||
fn from(block: BlindedBeaconBlock<E>) -> Self {
|
|
||||||
UnsignedBlock::Blinded(block)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum SignedBlock<E: EthSpec> {
|
pub enum SignedBlock<E: EthSpec> {
|
||||||
Full(SignedBeaconBlock<E>),
|
Full(PublishBlockRequest<E>),
|
||||||
Blinded(SignedBlindedBeaconBlock<E>),
|
Blinded(Arc<SignedBlindedBeaconBlock<E>>),
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: EthSpec> From<SignedBeaconBlock<E>> for SignedBlock<E> {
|
|
||||||
fn from(block: SignedBeaconBlock<E>) -> Self {
|
|
||||||
SignedBlock::Full(block)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: EthSpec> From<SignedBlindedBeaconBlock<E>> for SignedBlock<E> {
|
|
||||||
fn from(block: SignedBlindedBeaconBlock<E>) -> Self {
|
|
||||||
SignedBlock::Blinded(block)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper around `PublicKeyBytes` which encodes information about the status of a validator
|
/// A wrapper around `PublicKeyBytes` which encodes information about the status of a validator
|
||||||
|
|||||||
Reference in New Issue
Block a user