Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@ pub const FORK_CHOICE_DB_KEY: [u8; 32] = [0; 32];

/// The result of a chain segment processing.
#[derive(Debug)]
pub enum ChainSegmentResult {
pub enum ChainSegmentResult<T: EthSpec> {
/// Processing this chain segment finished successfully.
Successful { imported_blocks: usize },
/// There was an error processing this chain segment. Before the error, some blocks could
/// have been imported.
Failed {
imported_blocks: usize,
error: BlockError,
error: BlockError<T>,
},
}

Expand Down Expand Up @@ -1155,7 +1155,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
pub fn process_chain_segment(
&self,
chain_segment: Vec<SignedBeaconBlock<T::EthSpec>>,
) -> ChainSegmentResult {
) -> ChainSegmentResult<T::EthSpec> {
let mut filtered_chain_segment = Vec::with_capacity(chain_segment.len());
let mut imported_blocks = 0;

Expand Down Expand Up @@ -1293,7 +1293,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
pub fn verify_block_for_gossip(
&self,
block: SignedBeaconBlock<T::EthSpec>,
) -> Result<GossipVerifiedBlock<T>, BlockError> {
) -> Result<GossipVerifiedBlock<T>, BlockError<T::EthSpec>> {
let slot = block.message.slot;
let graffiti_string = String::from_utf8(block.message.body.graffiti[..].to_vec())
.unwrap_or_else(|_| format!("{:?}", &block.message.body.graffiti[..]));
Expand Down Expand Up @@ -1339,7 +1339,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
pub fn process_block<B: IntoFullyVerifiedBlock<T>>(
&self,
unverified_block: B,
) -> Result<Hash256, BlockError> {
) -> Result<Hash256, BlockError<T::EthSpec>> {
// Start the Prometheus timer.
let full_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_TIMES);

Expand All @@ -1350,7 +1350,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let block = unverified_block.block().clone();

// A small closure to group the verification and import errors.
let import_block = |unverified_block: B| -> Result<Hash256, BlockError> {
let import_block = |unverified_block: B| -> Result<Hash256, BlockError<T::EthSpec>> {
let fully_verified = unverified_block.into_fully_verified_block(self)?;
self.import_block(fully_verified)
};
Expand Down Expand Up @@ -1423,7 +1423,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
fn import_block(
&self,
fully_verified_block: FullyVerifiedBlock<T>,
) -> Result<Hash256, BlockError> {
) -> Result<Hash256, BlockError<T::EthSpec>> {
let signed_block = fully_verified_block.block;
let block = &signed_block.message;
let block_root = fully_verified_block.block_root;
Expand Down Expand Up @@ -2138,8 +2138,8 @@ impl From<BeaconStateError> for Error {
}
}

impl ChainSegmentResult {
pub fn to_block_error(self) -> Result<(), BlockError> {
impl<T: EthSpec> ChainSegmentResult<T> {
pub fn to_block_error(self) -> Result<(), BlockError<T>> {
match self {
ChainSegmentResult::Failed { error, .. } => Err(error),
ChainSegmentResult::Successful { .. } => Ok(()),
Expand Down
48 changes: 25 additions & 23 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ const WRITE_BLOCK_PROCESSING_SSZ: bool = cfg!(feature = "write_ssz_files");
/// - The block is malformed/invalid (indicated by all results other than `BeaconChainError`.
/// - We encountered an error whilst trying to verify the block (a `BeaconChainError`).
#[derive(Debug, PartialEq)]
pub enum BlockError {
pub enum BlockError<T: EthSpec> {
/// The parent block was unknown.
ParentUnknown(Hash256),
/// The parent block was unknown.
ParentUnknownCorrect(Box<SignedBeaconBlock<T>>),
/// The block slot is greater than the present slot.
FutureSlot {
present_slot: Slot,
Expand Down Expand Up @@ -134,7 +136,7 @@ pub enum BlockError {
BeaconChainError(BeaconChainError),
}

impl From<BlockSignatureVerifierError> for BlockError {
impl<T: EthSpec> From<BlockSignatureVerifierError> for BlockError<T> {
fn from(e: BlockSignatureVerifierError) -> Self {
match e {
// Make a special distinction for `IncorrectBlockProposer` since it indicates an
Expand All @@ -151,25 +153,25 @@ impl From<BlockSignatureVerifierError> for BlockError {
}
}

impl From<BeaconChainError> for BlockError {
impl<T: EthSpec> From<BeaconChainError> for BlockError<T> {
fn from(e: BeaconChainError) -> Self {
BlockError::BeaconChainError(e)
}
}

impl From<BeaconStateError> for BlockError {
impl<T: EthSpec> From<BeaconStateError> for BlockError<T> {
fn from(e: BeaconStateError) -> Self {
BlockError::BeaconChainError(BeaconChainError::BeaconStateError(e))
}
}

impl From<SlotProcessingError> for BlockError {
impl<T: EthSpec> From<SlotProcessingError> for BlockError<T> {
fn from(e: SlotProcessingError) -> Self {
BlockError::BeaconChainError(BeaconChainError::SlotProcessingError(e))
}
}

impl From<DBError> for BlockError {
impl<T: EthSpec> From<DBError> for BlockError<T> {
fn from(e: DBError) -> Self {
BlockError::BeaconChainError(BeaconChainError::DBError(e))
}
Expand All @@ -188,7 +190,7 @@ impl From<DBError> for BlockError {
pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
chain_segment: Vec<(Hash256, SignedBeaconBlock<T::EthSpec>)>,
chain: &BeaconChain<T>,
) -> Result<Vec<SignatureVerifiedBlock<T>>, BlockError> {
) -> Result<Vec<SignatureVerifiedBlock<T>>, BlockError<T::EthSpec>> {
let (mut parent, slot) = if let Some(block) = chain_segment.first().map(|(_, block)| block) {
let parent = load_parent(&block.message, chain)?;
(parent, block.slot())
Expand Down Expand Up @@ -278,7 +280,7 @@ pub trait IntoFullyVerifiedBlock<T: BeaconChainTypes> {
fn into_fully_verified_block(
self,
chain: &BeaconChain<T>,
) -> Result<FullyVerifiedBlock<T>, BlockError>;
) -> Result<FullyVerifiedBlock<T>, BlockError<T::EthSpec>>;

fn block(&self) -> &SignedBeaconBlock<T::EthSpec>;
}
Expand All @@ -291,7 +293,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
pub fn new(
block: SignedBeaconBlock<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<Self, BlockError> {
) -> Result<Self, BlockError<T::EthSpec>> {
// Do not gossip or process blocks from future slots.
let present_slot_with_tolerance = chain
.slot_clock
Expand Down Expand Up @@ -388,7 +390,7 @@ impl<T: BeaconChainTypes> IntoFullyVerifiedBlock<T> for GossipVerifiedBlock<T> {
fn into_fully_verified_block(
self,
chain: &BeaconChain<T>,
) -> Result<FullyVerifiedBlock<T>, BlockError> {
) -> Result<FullyVerifiedBlock<T>, BlockError<T::EthSpec>> {
let fully_verified = SignatureVerifiedBlock::from_gossip_verified_block(self, chain)?;
fully_verified.into_fully_verified_block(chain)
}
Expand All @@ -406,7 +408,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
pub fn new(
block: SignedBeaconBlock<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<Self, BlockError> {
) -> Result<Self, BlockError<T::EthSpec>> {
let mut parent = load_parent(&block.message, chain)?;
let block_root = get_block_root(&block);

Expand Down Expand Up @@ -438,7 +440,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
pub fn from_gossip_verified_block(
from: GossipVerifiedBlock<T>,
chain: &BeaconChain<T>,
) -> Result<Self, BlockError> {
) -> Result<Self, BlockError<T::EthSpec>> {
let mut parent = from.parent;
let block = from.block;

Expand Down Expand Up @@ -471,7 +473,7 @@ impl<T: BeaconChainTypes> IntoFullyVerifiedBlock<T> for SignatureVerifiedBlock<T
fn into_fully_verified_block(
self,
chain: &BeaconChain<T>,
) -> Result<FullyVerifiedBlock<T>, BlockError> {
) -> Result<FullyVerifiedBlock<T>, BlockError<T::EthSpec>> {
let block = self.block;
let parent = self
.parent
Expand All @@ -497,7 +499,7 @@ impl<T: BeaconChainTypes> IntoFullyVerifiedBlock<T> for SignedBeaconBlock<T::Eth
fn into_fully_verified_block(
self,
chain: &BeaconChain<T>,
) -> Result<FullyVerifiedBlock<T>, BlockError> {
) -> Result<FullyVerifiedBlock<T>, BlockError<T::EthSpec>> {
SignatureVerifiedBlock::new(self, chain)?.into_fully_verified_block(chain)
}

Expand All @@ -519,7 +521,7 @@ impl<T: BeaconChainTypes> FullyVerifiedBlock<T> {
block_root: Hash256,
parent: BeaconSnapshot<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<Self, BlockError> {
) -> Result<Self, BlockError<T::EthSpec>> {
// Reject any block if its parent is not known to fork choice.
//
// A block that is not in fork choice is either:
Expand Down Expand Up @@ -670,7 +672,7 @@ impl<T: BeaconChainTypes> FullyVerifiedBlock<T> {
fn check_block_against_finalized_slot<T: BeaconChainTypes>(
block: &BeaconBlock<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<(), BlockError> {
) -> Result<(), BlockError<T::EthSpec>> {
let finalized_slot = chain
.head_info()?
.finalized_checkpoint
Expand Down Expand Up @@ -698,7 +700,7 @@ pub fn check_block_relevancy<T: BeaconChainTypes>(
signed_block: &SignedBeaconBlock<T::EthSpec>,
block_root: Option<Hash256>,
chain: &BeaconChain<T>,
) -> Result<Hash256, BlockError> {
) -> Result<Hash256, BlockError<T::EthSpec>> {
let block = &signed_block.message;

// Do not process blocks from the future.
Expand Down Expand Up @@ -754,7 +756,7 @@ pub fn get_block_root<E: EthSpec>(block: &SignedBeaconBlock<E>) -> Hash256 {
fn load_parent<T: BeaconChainTypes>(
block: &BeaconBlock<T::EthSpec>,
chain: &BeaconChain<T>,
) -> Result<BeaconSnapshot<T::EthSpec>, BlockError> {
) -> Result<BeaconSnapshot<T::EthSpec>, BlockError<T::EthSpec>> {
let db_read_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_DB_READ);

// Reject any block if its parent is not known to fork choice.
Expand Down Expand Up @@ -828,12 +830,12 @@ fn load_parent<T: BeaconChainTypes>(
/// and `Cow::Borrowed(state)` will be returned. Otherwise, the state will be cloned, cheaply
/// advanced and then returned as a `Cow::Owned`. The end result is that the given `state` is never
/// mutated to be invalid (in fact, it is never changed beyond a simple committee cache build).
fn cheap_state_advance_to_obtain_committees<'a, E: EthSpec>(
state: &'a mut BeaconState<E>,
fn cheap_state_advance_to_obtain_committees<'a, T: EthSpec>(
state: &'a mut BeaconState<T>,
block_slot: Slot,
spec: &ChainSpec,
) -> Result<Cow<'a, BeaconState<E>>, BlockError> {
let block_epoch = block_slot.epoch(E::slots_per_epoch());
) -> Result<Cow<'a, BeaconState<T>>, BlockError<T>> {
let block_epoch = block_slot.epoch(T::slots_per_epoch());

if state.current_epoch() == block_epoch {
state.build_committee_cache(RelativeEpoch::Current, spec)?;
Expand Down Expand Up @@ -864,7 +866,7 @@ fn cheap_state_advance_to_obtain_committees<'a, E: EthSpec>(
/// Obtains a read-locked `ValidatorPubkeyCache` from the `chain`.
fn get_validator_pubkey_cache<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
) -> Result<RwLockReadGuard<ValidatorPubkeyCache>, BlockError> {
) -> Result<RwLockReadGuard<ValidatorPubkeyCache>, BlockError<T::EthSpec>> {
chain
.validator_pubkey_cache
.try_read_for(VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use crate::{BeaconChainError, BlockError};
use state_processing::BlockProcessingError;
use types::{Hash256, Slot};
use types::{EthSpec, Hash256, SignedBeaconBlock, Slot};

/// This is a legacy object that is being kept around to reduce merge conflicts.
///
/// TODO: As soon as this is merged into master, it should be removed as soon as possible.
#[derive(Debug, PartialEq)]
pub enum BlockProcessingOutcome {
pub enum BlockProcessingOutcome<T: EthSpec> {
/// Block was valid and imported into the block graph.
Processed {
block_root: Hash256,
Expand All @@ -18,6 +18,7 @@ pub enum BlockProcessingOutcome {
UnknownValidator(u64),
/// The parent block was unknown.
ParentUnknown(Hash256),
ParentUnknownCorrect(Box<SignedBeaconBlock<T>>),
/// The block slot is greater than the present slot.
FutureSlot {
present_slot: Slot,
Expand Down Expand Up @@ -66,13 +67,16 @@ pub enum BlockProcessingOutcome {
PerBlockProcessingError(BlockProcessingError),
}

impl BlockProcessingOutcome {
impl<T: EthSpec> BlockProcessingOutcome<T> {
pub fn shim(
result: Result<Hash256, BlockError>,
) -> Result<BlockProcessingOutcome, BeaconChainError> {
result: Result<Hash256, BlockError<T>>,
) -> Result<BlockProcessingOutcome<T>, BeaconChainError> {
match result {
Ok(block_root) => Ok(BlockProcessingOutcome::Processed { block_root }),
Err(BlockError::ParentUnknown(root)) => Ok(BlockProcessingOutcome::ParentUnknown(root)),
Err(BlockError::ParentUnknownCorrect(block)) => {
Ok(BlockProcessingOutcome::ParentUnknownCorrect(block))
}
Err(BlockError::FutureSlot {
present_slot,
block_slot,
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/network/src/router/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ impl<T: BeaconChainTypes> Processor<T> {
&mut self,
peer_id: &PeerId,
block: Box<SignedBeaconBlock<T::EthSpec>>,
) -> Result<GossipVerifiedBlock<T>, BlockError> {
) -> Result<GossipVerifiedBlock<T>, BlockError<T::EthSpec>> {
let result = self.chain.verify_block_for_gossip(*block.clone());

if let Err(BlockError::ParentUnknown(_)) = result {
Expand Down
7 changes: 5 additions & 2 deletions beacon_node/network/src/sync/block_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use eth2_libp2p::PeerId;
use slog::{debug, error, trace, warn};
use std::sync::{Arc, Weak};
use tokio::sync::mpsc;
use types::SignedBeaconBlock;
use types::{EthSpec, SignedBeaconBlock};

/// Id associated to a block processing request, either a batch or a single block.
#[derive(Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -178,7 +178,10 @@ fn run_fork_choice<T: BeaconChainTypes>(chain: Arc<BeaconChain<T>>, log: &slog::
}

/// Helper function to handle a `BlockError` from `process_chain_segment`
fn handle_failed_chain_segment(error: BlockError, log: &slog::Logger) -> Result<(), String> {
fn handle_failed_chain_segment<T: EthSpec>(
error: BlockError<T>,
log: &slog::Logger,
) -> Result<(), String> {
match error {
BlockError::ParentUnknown(parent) => {
// blocks should be sequential and all parents should exist
Expand Down