diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 544e6e006eb..1573fa574ff 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -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 { /// 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, }, } @@ -1155,7 +1155,7 @@ impl BeaconChain { pub fn process_chain_segment( &self, chain_segment: Vec>, - ) -> ChainSegmentResult { + ) -> ChainSegmentResult { let mut filtered_chain_segment = Vec::with_capacity(chain_segment.len()); let mut imported_blocks = 0; @@ -1293,7 +1293,7 @@ impl BeaconChain { pub fn verify_block_for_gossip( &self, block: SignedBeaconBlock, - ) -> Result, BlockError> { + ) -> Result, BlockError> { 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[..])); @@ -1339,7 +1339,7 @@ impl BeaconChain { pub fn process_block>( &self, unverified_block: B, - ) -> Result { + ) -> Result> { // Start the Prometheus timer. let full_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_TIMES); @@ -1350,7 +1350,7 @@ impl BeaconChain { let block = unverified_block.block().clone(); // A small closure to group the verification and import errors. - let import_block = |unverified_block: B| -> Result { + let import_block = |unverified_block: B| -> Result> { let fully_verified = unverified_block.into_fully_verified_block(self)?; self.import_block(fully_verified) }; @@ -1423,7 +1423,7 @@ impl BeaconChain { fn import_block( &self, fully_verified_block: FullyVerifiedBlock, - ) -> Result { + ) -> Result> { let signed_block = fully_verified_block.block; let block = &signed_block.message; let block_root = fully_verified_block.block_root; @@ -2138,8 +2138,8 @@ impl From for Error { } } -impl ChainSegmentResult { - pub fn to_block_error(self) -> Result<(), BlockError> { +impl ChainSegmentResult { + pub fn to_block_error(self) -> Result<(), BlockError> { match self { ChainSegmentResult::Failed { error, .. } => Err(error), ChainSegmentResult::Successful { .. } => Ok(()), diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index cc929e530b1..42ecc50c619 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -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 { /// The parent block was unknown. ParentUnknown(Hash256), + /// The parent block was unknown. + ParentUnknownCorrect(Box>), /// The block slot is greater than the present slot. FutureSlot { present_slot: Slot, @@ -134,7 +136,7 @@ pub enum BlockError { BeaconChainError(BeaconChainError), } -impl From for BlockError { +impl From for BlockError { fn from(e: BlockSignatureVerifierError) -> Self { match e { // Make a special distinction for `IncorrectBlockProposer` since it indicates an @@ -151,25 +153,25 @@ impl From for BlockError { } } -impl From for BlockError { +impl From for BlockError { fn from(e: BeaconChainError) -> Self { BlockError::BeaconChainError(e) } } -impl From for BlockError { +impl From for BlockError { fn from(e: BeaconStateError) -> Self { BlockError::BeaconChainError(BeaconChainError::BeaconStateError(e)) } } -impl From for BlockError { +impl From for BlockError { fn from(e: SlotProcessingError) -> Self { BlockError::BeaconChainError(BeaconChainError::SlotProcessingError(e)) } } -impl From for BlockError { +impl From for BlockError { fn from(e: DBError) -> Self { BlockError::BeaconChainError(BeaconChainError::DBError(e)) } @@ -188,7 +190,7 @@ impl From for BlockError { pub fn signature_verify_chain_segment( chain_segment: Vec<(Hash256, SignedBeaconBlock)>, chain: &BeaconChain, -) -> Result>, BlockError> { +) -> Result>, BlockError> { let (mut parent, slot) = if let Some(block) = chain_segment.first().map(|(_, block)| block) { let parent = load_parent(&block.message, chain)?; (parent, block.slot()) @@ -278,7 +280,7 @@ pub trait IntoFullyVerifiedBlock { fn into_fully_verified_block( self, chain: &BeaconChain, - ) -> Result, BlockError>; + ) -> Result, BlockError>; fn block(&self) -> &SignedBeaconBlock; } @@ -291,7 +293,7 @@ impl GossipVerifiedBlock { pub fn new( block: SignedBeaconBlock, chain: &BeaconChain, - ) -> Result { + ) -> Result> { // Do not gossip or process blocks from future slots. let present_slot_with_tolerance = chain .slot_clock @@ -388,7 +390,7 @@ impl IntoFullyVerifiedBlock for GossipVerifiedBlock { fn into_fully_verified_block( self, chain: &BeaconChain, - ) -> Result, BlockError> { + ) -> Result, BlockError> { let fully_verified = SignatureVerifiedBlock::from_gossip_verified_block(self, chain)?; fully_verified.into_fully_verified_block(chain) } @@ -406,7 +408,7 @@ impl SignatureVerifiedBlock { pub fn new( block: SignedBeaconBlock, chain: &BeaconChain, - ) -> Result { + ) -> Result> { let mut parent = load_parent(&block.message, chain)?; let block_root = get_block_root(&block); @@ -438,7 +440,7 @@ impl SignatureVerifiedBlock { pub fn from_gossip_verified_block( from: GossipVerifiedBlock, chain: &BeaconChain, - ) -> Result { + ) -> Result> { let mut parent = from.parent; let block = from.block; @@ -471,7 +473,7 @@ impl IntoFullyVerifiedBlock for SignatureVerifiedBlock, - ) -> Result, BlockError> { + ) -> Result, BlockError> { let block = self.block; let parent = self .parent @@ -497,7 +499,7 @@ impl IntoFullyVerifiedBlock for SignedBeaconBlock, - ) -> Result, BlockError> { + ) -> Result, BlockError> { SignatureVerifiedBlock::new(self, chain)?.into_fully_verified_block(chain) } @@ -519,7 +521,7 @@ impl FullyVerifiedBlock { block_root: Hash256, parent: BeaconSnapshot, chain: &BeaconChain, - ) -> Result { + ) -> Result> { // Reject any block if its parent is not known to fork choice. // // A block that is not in fork choice is either: @@ -670,7 +672,7 @@ impl FullyVerifiedBlock { fn check_block_against_finalized_slot( block: &BeaconBlock, chain: &BeaconChain, -) -> Result<(), BlockError> { +) -> Result<(), BlockError> { let finalized_slot = chain .head_info()? .finalized_checkpoint @@ -698,7 +700,7 @@ pub fn check_block_relevancy( signed_block: &SignedBeaconBlock, block_root: Option, chain: &BeaconChain, -) -> Result { +) -> Result> { let block = &signed_block.message; // Do not process blocks from the future. @@ -754,7 +756,7 @@ pub fn get_block_root(block: &SignedBeaconBlock) -> Hash256 { fn load_parent( block: &BeaconBlock, chain: &BeaconChain, -) -> Result, BlockError> { +) -> Result, BlockError> { let db_read_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_DB_READ); // Reject any block if its parent is not known to fork choice. @@ -828,12 +830,12 @@ fn load_parent( /// 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, +fn cheap_state_advance_to_obtain_committees<'a, T: EthSpec>( + state: &'a mut BeaconState, block_slot: Slot, spec: &ChainSpec, -) -> Result>, BlockError> { - let block_epoch = block_slot.epoch(E::slots_per_epoch()); +) -> Result>, BlockError> { + let block_epoch = block_slot.epoch(T::slots_per_epoch()); if state.current_epoch() == block_epoch { state.build_committee_cache(RelativeEpoch::Current, spec)?; @@ -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( chain: &BeaconChain, -) -> Result, BlockError> { +) -> Result, BlockError> { chain .validator_pubkey_cache .try_read_for(VALIDATOR_PUBKEY_CACHE_LOCK_TIMEOUT) diff --git a/beacon_node/beacon_chain/src/block_verification/block_processing_outcome.rs b/beacon_node/beacon_chain/src/block_verification/block_processing_outcome.rs index 8e38af47345..ba29cf149b7 100644 --- a/beacon_node/beacon_chain/src/block_verification/block_processing_outcome.rs +++ b/beacon_node/beacon_chain/src/block_verification/block_processing_outcome.rs @@ -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 { /// Block was valid and imported into the block graph. Processed { block_root: Hash256, @@ -18,6 +18,7 @@ pub enum BlockProcessingOutcome { UnknownValidator(u64), /// The parent block was unknown. ParentUnknown(Hash256), + ParentUnknownCorrect(Box>), /// The block slot is greater than the present slot. FutureSlot { present_slot: Slot, @@ -66,13 +67,16 @@ pub enum BlockProcessingOutcome { PerBlockProcessingError(BlockProcessingError), } -impl BlockProcessingOutcome { +impl BlockProcessingOutcome { pub fn shim( - result: Result, - ) -> Result { + result: Result>, + ) -> Result, 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, diff --git a/beacon_node/network/src/router/processor.rs b/beacon_node/network/src/router/processor.rs index 76f0cdf449a..929aa6f0e93 100644 --- a/beacon_node/network/src/router/processor.rs +++ b/beacon_node/network/src/router/processor.rs @@ -482,7 +482,7 @@ impl Processor { &mut self, peer_id: &PeerId, block: Box>, - ) -> Result, BlockError> { + ) -> Result, BlockError> { let result = self.chain.verify_block_for_gossip(*block.clone()); if let Err(BlockError::ParentUnknown(_)) = result { diff --git a/beacon_node/network/src/sync/block_processor.rs b/beacon_node/network/src/sync/block_processor.rs index 3284a38a3e3..eb4f84051e9 100644 --- a/beacon_node/network/src/sync/block_processor.rs +++ b/beacon_node/network/src/sync/block_processor.rs @@ -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)] @@ -178,7 +178,10 @@ fn run_fork_choice(chain: Arc>, 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( + error: BlockError, + log: &slog::Logger, +) -> Result<(), String> { match error { BlockError::ParentUnknown(parent) => { // blocks should be sequential and all parents should exist