diff --git a/beacon_node/beacon_chain/src/attestation_verification.rs b/beacon_node/beacon_chain/src/attestation_verification.rs index 6f1174c1ba..d69667f3de 100644 --- a/beacon_node/beacon_chain/src/attestation_verification.rs +++ b/beacon_node/beacon_chain/src/attestation_verification.rs @@ -272,12 +272,12 @@ pub enum Error { /// /// We were unable to process this attestation due to an internal error. It's unclear if the /// attestation is valid. - BeaconChainError(BeaconChainError), + BeaconChainError(Box), } impl From for Error { fn from(e: BeaconChainError) -> Self { - Self::BeaconChainError(e) + Self::BeaconChainError(Box::new(e)) } } @@ -525,7 +525,7 @@ impl<'a, T: BeaconChainTypes> IndexedAggregatedAttestation<'a, T> { .observed_attestations .write() .is_known_subset(attestation, observed_attestation_key_root) - .map_err(|e| Error::BeaconChainError(e.into()))? + .map_err(|e| Error::BeaconChainError(Box::new(e.into())))? { metrics::inc_counter(&metrics::AGGREGATED_ATTESTATION_SUBSETS); return Err(Error::AttestationSupersetKnown( @@ -628,7 +628,7 @@ impl<'a, T: BeaconChainTypes> IndexedAggregatedAttestation<'a, T> { if !SelectionProof::from(selection_proof) .is_aggregator(committee.committee.len(), &chain.spec) - .map_err(|e| Error::BeaconChainError(e.into()))? + .map_err(|e| Error::BeaconChainError(Box::new(e.into())))? { return Err(Error::InvalidSelectionProof { aggregator_index }); } @@ -698,7 +698,7 @@ impl<'a, T: BeaconChainTypes> VerifiedAggregatedAttestation<'a, T> { .observed_attestations .write() .observe_item(attestation, Some(observed_attestation_key_root)) - .map_err(|e| Error::BeaconChainError(e.into()))? + .map_err(|e| Error::BeaconChainError(Box::new(e.into())))? { metrics::inc_counter(&metrics::AGGREGATED_ATTESTATION_SUBSETS); return Err(Error::AttestationSupersetKnown( diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index b4eb848ec6..6dee810595 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -2733,7 +2733,7 @@ impl BeaconChain { pub fn filter_chain_segment( self: &Arc, chain_segment: Vec>, - ) -> Result>, ChainSegmentResult> { + ) -> Result>, Box> { // This function will never import any blocks. let imported_blocks = vec![]; let mut filtered_chain_segment = Vec::with_capacity(chain_segment.len()); @@ -2750,10 +2750,10 @@ impl BeaconChain { for (i, block) in chain_segment.into_iter().enumerate() { // Ensure the block is the correct structure for the fork at `block.slot()`. if let Err(e) = block.as_block().fork_name(&self.spec) { - return Err(ChainSegmentResult::Failed { + return Err(Box::new(ChainSegmentResult::Failed { imported_blocks, error: BlockError::InconsistentFork(e), - }); + })); } let block_root = block.block_root(); @@ -2765,18 +2765,18 @@ impl BeaconChain { // Without this check it would be possible to have a block verified using the // incorrect shuffling. That would be bad, mmkay. if block_root != *child_parent_root { - return Err(ChainSegmentResult::Failed { + return Err(Box::new(ChainSegmentResult::Failed { imported_blocks, error: BlockError::NonLinearParentRoots, - }); + })); } // Ensure that the slots are strictly increasing throughout the chain segment. if *child_slot <= block.slot() { - return Err(ChainSegmentResult::Failed { + return Err(Box::new(ChainSegmentResult::Failed { imported_blocks, error: BlockError::NonLinearSlots, - }); + })); } } @@ -2807,18 +2807,18 @@ impl BeaconChain { // The block has a known parent that does not descend from the finalized block. // There is no need to process this block or any children. Err(BlockError::NotFinalizedDescendant { block_parent_root }) => { - return Err(ChainSegmentResult::Failed { + return Err(Box::new(ChainSegmentResult::Failed { imported_blocks, error: BlockError::NotFinalizedDescendant { block_parent_root }, - }); + })); } // If there was an error whilst determining if the block was invalid, return that // error. Err(BlockError::BeaconChainError(e)) => { - return Err(ChainSegmentResult::Failed { + return Err(Box::new(ChainSegmentResult::Failed { imported_blocks, error: BlockError::BeaconChainError(e), - }); + })); } // If the block was decided to be irrelevant for any other reason, don't include // this block or any of it's children in the filtered chain segment. @@ -2863,11 +2863,11 @@ impl BeaconChain { ); let mut filtered_chain_segment = match filtered_chain_segment_future.await { Ok(Ok(filtered_segment)) => filtered_segment, - Ok(Err(segment_result)) => return segment_result, + Ok(Err(segment_result)) => return *segment_result, Err(error) => { return ChainSegmentResult::Failed { imported_blocks, - error: BlockError::BeaconChainError(error), + error: BlockError::BeaconChainError(error.into()), } } }; @@ -2906,7 +2906,7 @@ impl BeaconChain { Err(error) => { return ChainSegmentResult::Failed { imported_blocks, - error: BlockError::BeaconChainError(error), + error: BlockError::BeaconChainError(error.into()), }; } }; @@ -3444,20 +3444,23 @@ impl BeaconChain { Ok(status) } - Err(e @ BlockError::BeaconChainError(BeaconChainError::TokioJoin(_))) => { - debug!( - error = ?e, - "Beacon block processing cancelled" - ); - Err(e) - } - // There was an error whilst attempting to verify and import the block. The block might - // be partially verified or partially imported. Err(BlockError::BeaconChainError(e)) => { - crit!( - error = ?e, - "Beacon block processing error" - ); + match e.as_ref() { + BeaconChainError::TokioJoin(e) => { + debug!( + error = ?e, + "Beacon block processing cancelled" + ); + } + _ => { + // There was an error whilst attempting to verify and import the block. The block might + // be partially verified or partially imported. + crit!( + error = ?e, + "Beacon block processing error" + ); + } + }; Err(BlockError::BeaconChainError(e)) } // The block failed verification. @@ -3589,7 +3592,7 @@ impl BeaconChain { header.message.proposer_index, block_root, ) - .map_err(|e| BlockError::BeaconChainError(e.into()))?; + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))?; if let Some(slasher) = self.slasher.as_ref() { slasher.accept_block_header(header); } @@ -3674,7 +3677,7 @@ impl BeaconChain { header.message.proposer_index, block_root, ) - .map_err(|e| BlockError::BeaconChainError(e.into()))?; + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))?; if let Some(slasher) = self.slasher.as_ref() { slasher.accept_block_header(header.clone()); } @@ -3857,7 +3860,7 @@ impl BeaconChain { payload_verification_status, &self.spec, ) - .map_err(|e| BlockError::BeaconChainError(e.into()))?; + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))?; } // If the block is recent enough and it was not optimistically imported, check to see if it @@ -4070,7 +4073,7 @@ impl BeaconChain { warning = "The database is likely corrupt now, consider --purge-db", "No stored fork choice found to restore from" ); - Err(BlockError::BeaconChainError(e)) + Err(BlockError::BeaconChainError(Box::new(e))) } else { Ok(()) } @@ -4125,9 +4128,9 @@ impl BeaconChain { Provided block root is not a checkpoint.", )) .map_err(|err| { - BlockError::BeaconChainError( + BlockError::BeaconChainError(Box::new( BeaconChainError::WeakSubjectivtyShutdownError(err), - ) + )) })?; return Err(BlockError::WeakSubjectivityConflict); } @@ -4901,7 +4904,7 @@ impl BeaconChain { canonical_forkchoice_params: ForkchoiceUpdateParameters, ) -> Result { self.overridden_forkchoice_update_params_or_failure_reason(&canonical_forkchoice_params) - .or_else(|e| match e { + .or_else(|e| match *e { ProposerHeadError::DoNotReOrg(reason) => { trace!( %reason, @@ -4916,19 +4919,19 @@ impl BeaconChain { pub fn overridden_forkchoice_update_params_or_failure_reason( &self, canonical_forkchoice_params: &ForkchoiceUpdateParameters, - ) -> Result> { + ) -> Result>> { let _timer = metrics::start_timer(&metrics::FORK_CHOICE_OVERRIDE_FCU_TIMES); // Never override if proposer re-orgs are disabled. let re_org_head_threshold = self .config .re_org_head_threshold - .ok_or(DoNotReOrg::ReOrgsDisabled)?; + .ok_or(Box::new(DoNotReOrg::ReOrgsDisabled.into()))?; let re_org_parent_threshold = self .config .re_org_parent_threshold - .ok_or(DoNotReOrg::ReOrgsDisabled)?; + .ok_or(Box::new(DoNotReOrg::ReOrgsDisabled.into()))?; let head_block_root = canonical_forkchoice_params.head_root; @@ -4969,7 +4972,7 @@ impl BeaconChain { false }; if !current_slot_ok { - return Err(DoNotReOrg::HeadDistance.into()); + return Err(Box::new(DoNotReOrg::HeadDistance.into())); } // Only attempt a re-org if we have a proposer registered for the re-org slot. @@ -4992,7 +4995,7 @@ impl BeaconChain { decision_root = ?shuffling_decision_root, "Fork choice override proposer shuffling miss" ); - DoNotReOrg::NotProposing + Box::new(DoNotReOrg::NotProposing.into()) })? .index as u64; @@ -5002,7 +5005,7 @@ impl BeaconChain { .has_proposer_preparation_data_blocking(proposer_index) }; if !proposing_at_re_org_slot { - return Err(DoNotReOrg::NotProposing.into()); + return Err(Box::new(DoNotReOrg::NotProposing.into())); } // If the current slot is already equal to the proposal slot (or we are in the tail end of @@ -5017,18 +5020,22 @@ impl BeaconChain { (true, true) }; if !head_weak { - return Err(DoNotReOrg::HeadNotWeak { - head_weight: info.head_node.weight, - re_org_head_weight_threshold: info.re_org_head_weight_threshold, - } - .into()); + return Err(Box::new( + DoNotReOrg::HeadNotWeak { + head_weight: info.head_node.weight, + re_org_head_weight_threshold: info.re_org_head_weight_threshold, + } + .into(), + )); } if !parent_strong { - return Err(DoNotReOrg::ParentNotStrong { - parent_weight: info.parent_node.weight, - re_org_parent_weight_threshold: info.re_org_parent_weight_threshold, - } - .into()); + return Err(Box::new( + DoNotReOrg::ParentNotStrong { + parent_weight: info.parent_node.weight, + re_org_parent_weight_threshold: info.re_org_parent_weight_threshold, + } + .into(), + )); } // Check that the head block arrived late and is vulnerable to a re-org. This check is only @@ -5039,7 +5046,7 @@ impl BeaconChain { let head_block_late = self.block_observed_after_attestation_deadline(head_block_root, head_slot); if !head_block_late { - return Err(DoNotReOrg::HeadNotLate.into()); + return Err(Box::new(DoNotReOrg::HeadNotLate.into())); } let parent_head_hash = info.parent_node.execution_status.block_hash(); @@ -5253,16 +5260,16 @@ impl BeaconChain { .validators() .get(proposer_index as usize) .map(|v| v.pubkey) - .ok_or(BlockProductionError::BeaconChain( + .ok_or(BlockProductionError::BeaconChain(Box::new( BeaconChainError::ValidatorIndexUnknown(proposer_index as usize), - ))?; + )))?; let builder_params = BuilderParams { pubkey, slot: state.slot(), chain_health: self .is_healthy(&parent_root) - .map_err(BlockProductionError::BeaconChain)?, + .map_err(|e| BlockProductionError::BeaconChain(Box::new(e)))?, }; // If required, start the process of loading an execution payload from the EL early. This diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index fe9d8c6bfc..6fe710f41a 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -42,7 +42,7 @@ pub enum GossipBlobError { /// /// We were unable to process this blob due to an internal error. It's /// unclear if the blob is valid. - BeaconChainError(BeaconChainError), + BeaconChainError(Box), /// The `BlobSidecar` was gossiped over an incorrect subnet. /// @@ -147,13 +147,13 @@ impl std::fmt::Display for GossipBlobError { impl From for GossipBlobError { fn from(e: BeaconChainError) -> Self { - GossipBlobError::BeaconChainError(e) + GossipBlobError::BeaconChainError(e.into()) } } impl From for GossipBlobError { fn from(e: BeaconStateError) -> Self { - GossipBlobError::BeaconChainError(BeaconChainError::BeaconStateError(e)) + GossipBlobError::BeaconChainError(BeaconChainError::BeaconStateError(e).into()) } } @@ -446,7 +446,7 @@ pub fn validate_blob_sidecar_for_gossip( .observed_blob_sidecars .write() .observe_sidecar(blob_sidecar) - .map_err(|e| GossipBlobError::BeaconChainError(e.into()))? + .map_err(|e| GossipBlobError::BeaconChainError(Box::new(e.into())))? { return Err(GossipBlobError::RepeatBlob { proposer: blob_sidecar.block_proposer_index(), diff --git a/beacon_node/beacon_chain/src/block_verification.rs b/beacon_node/beacon_chain/src/block_verification.rs index 074ae93a79..26bf872392 100644 --- a/beacon_node/beacon_chain/src/block_verification.rs +++ b/beacon_node/beacon_chain/src/block_verification.rs @@ -252,7 +252,7 @@ pub enum BlockError { /// /// We were unable to process this block due to an internal error. It's unclear if the block is /// valid. - BeaconChainError(BeaconChainError), + BeaconChainError(Box), /// There was an error whilst verifying weak subjectivity. This block conflicts with the /// configured weak subjectivity checkpoint and was not imported. /// @@ -475,38 +475,40 @@ impl From for BlockError { block, local_shuffling, }, - e => BlockError::BeaconChainError(BeaconChainError::BlockSignatureVerifierError(e)), + e => BlockError::BeaconChainError( + BeaconChainError::BlockSignatureVerifierError(e).into(), + ), } } } impl From for BlockError { fn from(e: BeaconChainError) -> Self { - BlockError::BeaconChainError(e) + BlockError::BeaconChainError(e.into()) } } impl From for BlockError { fn from(e: BeaconStateError) -> Self { - BlockError::BeaconChainError(BeaconChainError::BeaconStateError(e)) + BlockError::BeaconChainError(BeaconChainError::BeaconStateError(e).into()) } } impl From for BlockError { fn from(e: SlotProcessingError) -> Self { - BlockError::BeaconChainError(BeaconChainError::SlotProcessingError(e)) + BlockError::BeaconChainError(BeaconChainError::SlotProcessingError(e).into()) } } impl From for BlockError { fn from(e: DBError) -> Self { - BlockError::BeaconChainError(BeaconChainError::DBError(e)) + BlockError::BeaconChainError(BeaconChainError::DBError(e).into()) } } impl From for BlockError { fn from(e: ArithError) -> Self { - BlockError::BeaconChainError(BeaconChainError::ArithError(e)) + BlockError::BeaconChainError(BeaconChainError::ArithError(e).into()) } } @@ -1000,7 +1002,7 @@ impl GossipVerifiedBlock { .observed_slashable .write() .observe_slashable(block.slot(), block.message().proposer_index(), block_root) - .map_err(|e| BlockError::BeaconChainError(e.into()))?; + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))?; // Now the signature is valid, store the proposal so we don't accept another from this // validator and slot. // @@ -1010,7 +1012,7 @@ impl GossipVerifiedBlock { .observed_block_producers .write() .observe_proposal(block_root, block.message()) - .map_err(|e| BlockError::BeaconChainError(e.into()))? + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))? { SeenBlock::Slashable => { return Err(BlockError::Slashable); @@ -1321,13 +1323,13 @@ impl ExecutionPendingBlock { .observed_slashable .write() .observe_slashable(block.slot(), block.message().proposer_index(), block_root) - .map_err(|e| BlockError::BeaconChainError(e.into()))?; + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))?; chain .observed_block_producers .write() .observe_proposal(block_root, block.message()) - .map_err(|e| BlockError::BeaconChainError(e.into()))?; + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))?; if let Some(parent) = chain .canonical_head @@ -1651,7 +1653,7 @@ impl ExecutionPendingBlock { // Ignore invalid attestations whilst importing attestations from a block. The // block might be very old and therefore the attestations useless to fork choice. Err(ForkChoiceError::InvalidAttestation(_)) => Ok(()), - Err(e) => Err(BlockError::BeaconChainError(e.into())), + Err(e) => Err(BlockError::BeaconChainError(Box::new(e.into()))), }?; } drop(fork_choice); @@ -1743,7 +1745,7 @@ pub fn check_block_is_finalized_checkpoint_or_descendant< if chain .store .block_exists(&block.parent_root()) - .map_err(|e| BlockError::BeaconChainError(e.into()))? + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))? { Err(BlockError::NotFinalizedDescendant { block_parent_root: block.parent_root(), @@ -1888,7 +1890,7 @@ fn load_parent>( let root = block.parent_root(); let parent_block = chain .get_blinded_block(&block.parent_root()) - .map_err(BlockError::BeaconChainError)? + .map_err(|e| BlockError::BeaconChainError(Box::new(e)))? .ok_or_else(|| { // Return a `MissingBeaconBlock` error instead of a `ParentUnknown` error since // we've already checked fork choice for this block. diff --git a/beacon_node/beacon_chain/src/data_column_verification.rs b/beacon_node/beacon_chain/src/data_column_verification.rs index d11c112812..b43b259cf6 100644 --- a/beacon_node/beacon_chain/src/data_column_verification.rs +++ b/beacon_node/beacon_chain/src/data_column_verification.rs @@ -32,7 +32,7 @@ pub enum GossipDataColumnError { /// /// We were unable to process this data column due to an internal error. It's /// unclear if the data column is valid. - BeaconChainError(BeaconChainError), + BeaconChainError(Box), /// The proposal signature in invalid. /// /// ## Peer scoring @@ -162,13 +162,13 @@ pub enum GossipDataColumnError { impl From for GossipDataColumnError { fn from(e: BeaconChainError) -> Self { - GossipDataColumnError::BeaconChainError(e) + GossipDataColumnError::BeaconChainError(e.into()) } } impl From for GossipDataColumnError { fn from(e: BeaconStateError) -> Self { - GossipDataColumnError::BeaconChainError(BeaconChainError::BeaconStateError(e)) + GossipDataColumnError::BeaconChainError(BeaconChainError::BeaconStateError(e).into()) } } @@ -460,7 +460,7 @@ pub fn validate_data_column_sidecar_for_gossip( .observed_column_sidecars .read() .proposer_is_known(data_column) - .map_err(|e| GossipDataColumnError::BeaconChainError(e.into()))? + .map_err(|e| GossipDataColumnError::BeaconChainError(Box::new(e.into())))? { return Err(GossipDataColumnError::PriorKnown { proposer: data_column.block_proposer_index(), @@ -616,7 +616,7 @@ fn verify_proposer_and_signature( let (parent_state_root, mut parent_state) = chain .store .get_advanced_hot_state(block_parent_root, column_slot, parent_block.state_root) - .map_err(|e| GossipDataColumnError::BeaconChainError(e.into()))? + .map_err(|e| GossipDataColumnError::BeaconChainError(Box::new(e.into())))? .ok_or_else(|| { BeaconChainError::DBInconsistent(format!( "Missing state for parent block {block_parent_root:?}", @@ -748,7 +748,7 @@ pub fn observe_gossip_data_column( .observed_column_sidecars .write() .observe_sidecar(data_column_sidecar) - .map_err(|e| GossipDataColumnError::BeaconChainError(e.into()))? + .map_err(|e| GossipDataColumnError::BeaconChainError(Box::new(e.into())))? { return Err(GossipDataColumnError::PriorKnown { proposer: data_column_sidecar.block_proposer_index(), diff --git a/beacon_node/beacon_chain/src/errors.rs b/beacon_node/beacon_chain/src/errors.rs index 8509c52c8a..2e6de463cc 100644 --- a/beacon_node/beacon_chain/src/errors.rs +++ b/beacon_node/beacon_chain/src/errors.rs @@ -296,7 +296,7 @@ pub enum BlockProductionError { MissingExecutionPayload, MissingKzgCommitment(String), TokioJoin(JoinError), - BeaconChain(BeaconChainError), + BeaconChain(Box), InvalidPayloadFork, InvalidBlockVariant(String), KzgError(kzg::Error), diff --git a/beacon_node/beacon_chain/src/eth1_finalization_cache.rs b/beacon_node/beacon_chain/src/eth1_finalization_cache.rs index 0b9d19e156..8c3bb8c483 100644 --- a/beacon_node/beacon_chain/src/eth1_finalization_cache.rs +++ b/beacon_node/beacon_chain/src/eth1_finalization_cache.rs @@ -100,22 +100,13 @@ impl CheckpointMap { /// This cache stores `Eth1CacheData` that could potentially be finalized within 4 /// future epochs. +#[derive(Default)] pub struct Eth1FinalizationCache { by_checkpoint: CheckpointMap, pending_eth1: BTreeMap, last_finalized: Option, } -impl Default for Eth1FinalizationCache { - fn default() -> Self { - Self { - by_checkpoint: CheckpointMap::new(), - pending_eth1: BTreeMap::new(), - last_finalized: None, - } - } -} - /// Provides a cache of `Eth1CacheData` at epoch boundaries. This is used to /// finalize deposits when a new epoch is finalized. /// diff --git a/beacon_node/beacon_chain/src/execution_payload.rs b/beacon_node/beacon_chain/src/execution_payload.rs index 1da8cb413b..aa98310c12 100644 --- a/beacon_node/beacon_chain/src/execution_payload.rs +++ b/beacon_node/beacon_chain/src/execution_payload.rs @@ -319,9 +319,9 @@ pub fn validate_execution_payload_for_gossip( .slot_clock .start_of(block.slot()) .map(|d| d.as_secs()) - .ok_or(BlockError::BeaconChainError( + .ok_or(BlockError::BeaconChainError(Box::new( BeaconChainError::UnableToComputeTimeAtSlot, - ))?; + )))?; // The block's execution payload timestamp is correct with respect to the slot if execution_payload.timestamp() != expected_timestamp { @@ -504,7 +504,7 @@ where "prepare_execution_payload_forkchoice_update_params", ) .await - .map_err(BlockProductionError::BeaconChain)?; + .map_err(|e| BlockProductionError::BeaconChain(Box::new(e)))?; let suggested_fee_recipient = execution_layer .get_suggested_fee_recipient(proposer_index) diff --git a/beacon_node/beacon_chain/src/fetch_blobs.rs b/beacon_node/beacon_chain/src/fetch_blobs.rs index 3b576da1c7..d91f103b9d 100644 --- a/beacon_node/beacon_chain/src/fetch_blobs.rs +++ b/beacon_node/beacon_chain/src/fetch_blobs.rs @@ -49,7 +49,7 @@ pub enum EngineGetBlobsOutput { #[derive(Debug)] pub enum FetchEngineBlobError { BeaconStateError(BeaconStateError), - BeaconChainError(BeaconChainError), + BeaconChainError(Box), BlobProcessingError(BlockError), BlobSidecarError(BlobSidecarError), DataColumnSidecarError(DataColumnSidecarError), @@ -320,7 +320,7 @@ async fn compute_and_publish_data_columns( "compute_and_publish_data_columns", ) .await - .map_err(FetchEngineBlobError::BeaconChainError) + .map_err(|e| FetchEngineBlobError::BeaconChainError(Box::new(e))) .and_then(|r| r) } diff --git a/beacon_node/beacon_chain/src/state_advance_timer.rs b/beacon_node/beacon_chain/src/state_advance_timer.rs index 9135c3ce88..f206405f67 100644 --- a/beacon_node/beacon_chain/src/state_advance_timer.rs +++ b/beacon_node/beacon_chain/src/state_advance_timer.rs @@ -44,7 +44,7 @@ const MAX_FORK_CHOICE_DISTANCE: u64 = 256; #[derive(Debug)] enum Error { - BeaconChain(BeaconChainError), + BeaconChain(Box), // We don't use the inner value directly, but it's used in the Debug impl. HeadMissingFromSnapshotCache(#[allow(dead_code)] Hash256), BeaconState(#[allow(dead_code)] BeaconStateError), @@ -64,7 +64,7 @@ enum Error { impl From for Error { fn from(e: BeaconChainError) -> Self { - Self::BeaconChain(e) + Self::BeaconChain(e.into()) } } diff --git a/beacon_node/beacon_chain/src/sync_committee_verification.rs b/beacon_node/beacon_chain/src/sync_committee_verification.rs index e1a5de56d1..768c971f94 100644 --- a/beacon_node/beacon_chain/src/sync_committee_verification.rs +++ b/beacon_node/beacon_chain/src/sync_committee_verification.rs @@ -189,7 +189,7 @@ pub enum Error { /// /// We were unable to process this sync committee message due to an internal error. It's unclear if the /// sync committee message is valid. - BeaconChainError(BeaconChainError), + BeaconChainError(Box), /// There was an error whilst processing the sync contribution. It is not known if it is valid or invalid. /// /// ## Peer scoring @@ -232,7 +232,7 @@ pub enum Error { impl From for Error { fn from(e: BeaconChainError) -> Self { - Error::BeaconChainError(e) + Error::BeaconChainError(e.into()) } } @@ -334,7 +334,7 @@ impl VerifiedSyncContribution { .observed_sync_contributions .write() .is_known_subset(contribution, contribution_data_root) - .map_err(|e| Error::BeaconChainError(e.into()))? + .map_err(|e| Error::BeaconChainError(Box::new(e.into())))? { metrics::inc_counter(&metrics::SYNC_CONTRIBUTION_SUBSETS); return Err(Error::SyncContributionSupersetKnown(contribution_data_root)); @@ -363,7 +363,7 @@ impl VerifiedSyncContribution { if !selection_proof .is_aggregator::() - .map_err(|e| Error::BeaconChainError(e.into()))? + .map_err(|e| Error::BeaconChainError(Box::new(e.into())))? { return Err(Error::InvalidSelectionProof { aggregator_index }); } @@ -395,7 +395,7 @@ impl VerifiedSyncContribution { .observed_sync_contributions .write() .observe_item(contribution, Some(contribution_data_root)) - .map_err(|e| Error::BeaconChainError(e.into()))? + .map_err(|e| Error::BeaconChainError(Box::new(e.into())))? { metrics::inc_counter(&metrics::SYNC_CONTRIBUTION_SUBSETS); return Err(Error::SyncContributionSupersetKnown(contribution_data_root)); diff --git a/beacon_node/beacon_chain/tests/payload_invalidation.rs b/beacon_node/beacon_chain/tests/payload_invalidation.rs index c6fc3416e0..6b9ff9d6ed 100644 --- a/beacon_node/beacon_chain/tests/payload_invalidation.rs +++ b/beacon_node/beacon_chain/tests/payload_invalidation.rs @@ -508,13 +508,11 @@ async fn justified_checkpoint_becomes_invalid() { let is_valid = Payload::Invalid { latest_valid_hash: Some(parent_hash_of_justified), }; - rig.import_block_parametric(is_valid, is_valid, None, |error| { - matches!( - error, - // The block import should fail since the beacon chain knows the justified payload - // is invalid. - BlockError::BeaconChainError(BeaconChainError::JustifiedPayloadInvalid { .. }) - ) + rig.import_block_parametric(is_valid, is_valid, None, |error| match error { + BlockError::BeaconChainError(e) => { + matches!(e.as_ref(), BeaconChainError::JustifiedPayloadInvalid { .. }) + } + _ => false, }) .await; diff --git a/beacon_node/http_api/src/lib.rs b/beacon_node/http_api/src/lib.rs index 386d9fe33a..93f978e3c9 100644 --- a/beacon_node/http_api/src/lib.rs +++ b/beacon_node/http_api/src/lib.rs @@ -3241,13 +3241,14 @@ pub fn serve( let direction = dir.into(); let state = peer_info.connection_status().clone().into(); - let state_matches = query.state.as_ref().is_none_or(|states| { - states.iter().any(|state_param| *state_param == state) - }); - let direction_matches = - query.direction.as_ref().is_none_or(|directions| { - directions.iter().any(|dir_param| *dir_param == direction) - }); + let state_matches = query + .state + .as_ref() + .is_none_or(|states| states.contains(&state)); + let direction_matches = query + .direction + .as_ref() + .is_none_or(|directions| directions.contains(&direction)); if state_matches && direction_matches { peers.push(api_types::PeerData { diff --git a/beacon_node/http_api/src/publish_attestations.rs b/beacon_node/http_api/src/publish_attestations.rs index cd5e912bdf..db85b8f205 100644 --- a/beacon_node/http_api/src/publish_attestations.rs +++ b/beacon_node/http_api/src/publish_attestations.rs @@ -60,13 +60,13 @@ use types::{Attestation, EthSpec, ForkName, SingleAttestation}; pub enum Error { Validation(AttestationError), Publication, - ForkChoice(#[allow(dead_code)] BeaconChainError), + ForkChoice(#[allow(dead_code)] Box), AggregationPool(#[allow(dead_code)] AttestationError), ReprocessDisabled, ReprocessFull, ReprocessTimeout, InvalidJson(#[allow(dead_code)] serde_json::Error), - FailedConversion(#[allow(dead_code)] BeaconChainError), + FailedConversion(#[allow(dead_code)] Box), } enum PublishAttestationResult { @@ -164,7 +164,7 @@ fn verify_and_publish_attestation( } if let Err(e) = fc_result { - Err(Error::ForkChoice(e)) + Err(Error::ForkChoice(Box::new(e))) } else if let Err(e) = naive_aggregation_result { Err(Error::AggregationPool(e)) } else { @@ -213,7 +213,7 @@ fn convert_to_attestation<'a, T: BeaconChainTypes>( beacon_block_root, })) } - Err(e) => Err(Error::FailedConversion(e)), + Err(e) => Err(Error::FailedConversion(Box::new(e))), } } } diff --git a/beacon_node/http_api/src/publish_blocks.rs b/beacon_node/http_api/src/publish_blocks.rs index b613cf8467..9b1a3f8677 100644 --- a/beacon_node/http_api/src/publish_blocks.rs +++ b/beacon_node/http_api/src/publish_blocks.rs @@ -123,8 +123,9 @@ pub async fn publish_block>( "Signed block published to network via HTTP API" ); - crate::publish_pubsub_message(&sender, PubsubMessage::BeaconBlock(block.clone())) - .map_err(|_| BlockError::BeaconChainError(BeaconChainError::UnableToPublish))?; + crate::publish_pubsub_message(&sender, PubsubMessage::BeaconBlock(block.clone())).map_err( + |_| BlockError::BeaconChainError(Box::new(BeaconChainError::UnableToPublish)), + )?; Ok(()) }; @@ -506,7 +507,7 @@ fn publish_blob_sidecars( ) -> Result<(), BlockError> { let pubsub_message = PubsubMessage::BlobSidecar(Box::new((blob.index(), blob.clone_blob()))); crate::publish_pubsub_message(sender_clone, pubsub_message) - .map_err(|_| BlockError::BeaconChainError(BeaconChainError::UnableToPublish)) + .map_err(|_| BlockError::BeaconChainError(Box::new(BeaconChainError::UnableToPublish))) } fn publish_column_sidecars( @@ -536,7 +537,7 @@ fn publish_column_sidecars( }) .collect::>(); crate::publish_pubsub_messages(sender_clone, pubsub_messages) - .map_err(|_| BlockError::BeaconChainError(BeaconChainError::UnableToPublish)) + .map_err(|_| BlockError::BeaconChainError(Box::new(BeaconChainError::UnableToPublish))) } async fn post_block_import_logging_and_response( @@ -593,7 +594,9 @@ async fn post_block_import_logging_and_response( Err(warp_utils::reject::custom_bad_request(msg)) } } - Err(BlockError::BeaconChainError(BeaconChainError::UnableToPublish)) => { + Err(BlockError::BeaconChainError(e)) + if matches!(e.as_ref(), BeaconChainError::UnableToPublish) => + { Err(warp_utils::reject::custom_server_error( "unable to publish to network channel".to_string(), )) @@ -789,7 +792,7 @@ fn check_slashable( block_clone.message().proposer_index(), block_root, ) - .map_err(|e| BlockError::BeaconChainError(e.into()))? + .map_err(|e| BlockError::BeaconChainError(Box::new(e.into())))? { warn!( slot = %block_clone.slot(), diff --git a/beacon_node/http_api/src/sync_committees.rs b/beacon_node/http_api/src/sync_committees.rs index 9ca1a2401a..aa126bbc82 100644 --- a/beacon_node/http_api/src/sync_committees.rs +++ b/beacon_node/http_api/src/sync_committees.rs @@ -59,7 +59,7 @@ pub fn sync_committee_duties( } let duties = duties_from_state_load(request_epoch, request_indices, altair_fork_epoch, chain) - .map_err(|e| match e { + .map_err(|e| match *e { BeaconChainError::SyncDutiesError(BeaconStateError::SyncCommitteeNotKnown { current_epoch, .. @@ -81,7 +81,7 @@ fn duties_from_state_load( request_indices: &[u64], altair_fork_epoch: Epoch, chain: &BeaconChain, -) -> Result, BeaconStateError>>, BeaconChainError> { +) -> Result, BeaconStateError>>, Box> { // Determine what the current epoch would be if we fast-forward our system clock by // `MAXIMUM_GOSSIP_CLOCK_DISPARITY`. // @@ -92,11 +92,17 @@ fn duties_from_state_load( let tolerant_current_epoch = chain .slot_clock .now_with_future_tolerance(chain.spec.maximum_gossip_clock_disparity()) - .ok_or(BeaconChainError::UnableToReadSlot)? + .ok_or(BeaconChainError::UnableToReadSlot) + .map_err(Box::new)? .epoch(T::EthSpec::slots_per_epoch()); - let max_sync_committee_period = tolerant_current_epoch.sync_committee_period(&chain.spec)? + 1; - let sync_committee_period = request_epoch.sync_committee_period(&chain.spec)?; + let max_sync_committee_period = tolerant_current_epoch + .sync_committee_period(&chain.spec) + .map_err(|e| Box::new(e.into()))? + + 1; + let sync_committee_period = request_epoch + .sync_committee_period(&chain.spec) + .map_err(|e| Box::new(e.into()))?; if tolerant_current_epoch < altair_fork_epoch { // Empty response if the epoch is pre-Altair. @@ -119,13 +125,14 @@ fn duties_from_state_load( state .get_sync_committee_duties(request_epoch, request_indices, &chain.spec) .map_err(BeaconChainError::SyncDutiesError) + .map_err(Box::new) } else { - Err(BeaconChainError::SyncDutiesError( + Err(Box::new(BeaconChainError::SyncDutiesError( BeaconStateError::SyncCommitteeNotKnown { current_epoch, epoch: request_epoch, }, - )) + ))) } } diff --git a/beacon_node/http_api/src/validator.rs b/beacon_node/http_api/src/validator.rs index baa41e33ed..25b0feb99e 100644 --- a/beacon_node/http_api/src/validator.rs +++ b/beacon_node/http_api/src/validator.rs @@ -7,9 +7,10 @@ pub fn pubkey_to_validator_index( chain: &BeaconChain, state: &BeaconState, pubkey: &PublicKeyBytes, -) -> Result, BeaconChainError> { +) -> Result, Box> { chain - .validator_index(pubkey)? + .validator_index(pubkey) + .map_err(Box::new)? .filter(|&index| { state .validators() diff --git a/beacon_node/network/src/network_beacon_processor/gossip_methods.rs b/beacon_node/network/src/network_beacon_processor/gossip_methods.rs index 2995a4d7e8..638f9e4824 100644 --- a/beacon_node/network/src/network_beacon_processor/gossip_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/gossip_methods.rs @@ -537,7 +537,7 @@ impl NetworkBeaconProcessor { attestation: single_attestation, }, None, - AttnError::BeaconChainError(error), + AttnError::BeaconChainError(Box::new(error)), seen_timestamp, ); } @@ -2734,41 +2734,57 @@ impl NetworkBeaconProcessor { "attn_to_finalized_block", ); } - AttnError::BeaconChainError(BeaconChainError::DBError(Error::HotColdDBError( - HotColdDBError::FinalizedStateNotInHotDatabase { .. }, - ))) => { - debug!(%peer_id, "Attestation for finalized state"); - self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore); - } - e @ AttnError::BeaconChainError(BeaconChainError::MaxCommitteePromises(_)) => { - debug!( - target_root = ?failed_att.attestation_data().target.root, - ?beacon_block_root, - slot = ?failed_att.attestation_data().slot, - ?attestation_type, - error = ?e, - %peer_id, - "Dropping attestation" - ); - self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore); - } AttnError::BeaconChainError(e) => { - /* - * Lighthouse hit an unexpected error whilst processing the attestation. It - * should be impossible to trigger a `BeaconChainError` from the network, - * so we have a bug. - * - * It's not clear if the message is invalid/malicious. - */ - error!( - ?beacon_block_root, - slot = ?failed_att.attestation_data().slot, - ?attestation_type, - %peer_id, - error = ?e, - "Unable to validate attestation" - ); - self.propagate_validation_result(message_id, peer_id, MessageAcceptance::Ignore); + match e.as_ref() { + BeaconChainError::DBError(Error::HotColdDBError( + HotColdDBError::FinalizedStateNotInHotDatabase { .. }, + )) => { + debug!(%peer_id, "Attestation for finalized state"); + self.propagate_validation_result( + message_id, + peer_id, + MessageAcceptance::Ignore, + ); + } + BeaconChainError::MaxCommitteePromises(e) => { + debug!( + target_root = ?failed_att.attestation_data().target.root, + ?beacon_block_root, + slot = ?failed_att.attestation_data().slot, + ?attestation_type, + error = ?e, + %peer_id, + "Dropping attestation" + ); + self.propagate_validation_result( + message_id, + peer_id, + MessageAcceptance::Ignore, + ); + } + _ => { + /* + * Lighthouse hit an unexpected error whilst processing the attestation. It + * should be impossible to trigger a `BeaconChainError` from the network, + * so we have a bug. + * + * It's not clear if the message is invalid/malicious. + */ + error!( + ?beacon_block_root, + slot = ?failed_att.attestation_data().slot, + ?attestation_type, + %peer_id, + error = ?e, + "Unable to validate attestation" + ); + self.propagate_validation_result( + message_id, + peer_id, + MessageAcceptance::Ignore, + ); + } + } } } diff --git a/beacon_node/network/src/network_beacon_processor/rpc_methods.rs b/beacon_node/network/src/network_beacon_processor/rpc_methods.rs index 96d5bc8181..7c3c854ed8 100644 --- a/beacon_node/network/src/network_beacon_processor/rpc_methods.rs +++ b/beacon_node/network/src/network_beacon_processor/rpc_methods.rs @@ -66,7 +66,7 @@ impl NetworkBeaconProcessor { fn check_peer_relevance( &self, remote: &StatusMessage, - ) -> Result, BeaconChainError> { + ) -> Result, Box> { let local = self.chain.status_message(); let start_slot = |epoch: Epoch| epoch.start_slot(T::EthSpec::slots_per_epoch()); @@ -112,7 +112,8 @@ impl NetworkBeaconProcessor { if self .chain .block_root_at_slot(remote_finalized_slot, WhenSlotSkipped::Prev) - .map(|root_opt| root_opt != Some(remote.finalized_root))? + .map(|root_opt| root_opt != Some(remote.finalized_root)) + .map_err(Box::new)? { Some("Different finalized chain".to_string()) } else { diff --git a/beacon_node/store/src/errors.rs b/beacon_node/store/src/errors.rs index ed6154da80..cff08bc655 100644 --- a/beacon_node/store/src/errors.rs +++ b/beacon_node/store/src/errors.rs @@ -57,7 +57,7 @@ pub enum Error { #[cfg(feature = "leveldb")] LevelDbError(LevelDBError), #[cfg(feature = "redb")] - RedbError(redb::Error), + RedbError(Box), CacheBuildError(EpochCacheError), RandaoMixOutOfBounds, MilhouseError(milhouse::Error), @@ -161,49 +161,49 @@ impl From for Error { #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::Error) -> Self { - Error::RedbError(e) + Error::RedbError(Box::new(e)) } } #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::TableError) -> Self { - Error::RedbError(e.into()) + Error::RedbError(Box::new(e.into())) } } #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::TransactionError) -> Self { - Error::RedbError(e.into()) + Error::RedbError(Box::new(e.into())) } } #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::DatabaseError) -> Self { - Error::RedbError(e.into()) + Error::RedbError(Box::new(e.into())) } } #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::StorageError) -> Self { - Error::RedbError(e.into()) + Error::RedbError(Box::new(e.into())) } } #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::CommitError) -> Self { - Error::RedbError(e.into()) + Error::RedbError(Box::new(e.into())) } } #[cfg(feature = "redb")] impl From for Error { fn from(e: redb::CompactionError) -> Self { - Error::RedbError(e.into()) + Error::RedbError(Box::new(e.into())) } } diff --git a/common/eth2/src/lib.rs b/common/eth2/src/lib.rs index fc12a4c5f3..d1b0dc65c4 100644 --- a/common/eth2/src/lib.rs +++ b/common/eth2/src/lib.rs @@ -56,7 +56,7 @@ pub enum Error { /// The `reqwest` client raised an error. HttpClient(PrettyReqwestError), /// The `reqwest_eventsource` client raised an error. - SseClient(reqwest_eventsource::Error), + SseClient(Box), /// The server returned an error message where the body was able to be parsed. ServerMessage(ErrorMessage), /// The server returned an error message with an array of errors. @@ -99,7 +99,7 @@ impl Error { match self { Error::HttpClient(error) => error.inner().status(), Error::SseClient(error) => { - if let reqwest_eventsource::Error::InvalidStatusCode(status, _) = error { + if let reqwest_eventsource::Error::InvalidStatusCode(status, _) = error.as_ref() { Some(*status) } else { None @@ -2693,7 +2693,7 @@ impl BeaconNodeHttpClient { while let Some(event) = es.next().await { match event { Ok(Event::Open) => break, - Err(err) => return Err(Error::SseClient(err)), + Err(err) => return Err(Error::SseClient(err.into())), // This should never happen as we are guaranteed to get the // Open event before any message starts coming through. Ok(Event::Message(_)) => continue, @@ -2705,7 +2705,7 @@ impl BeaconNodeHttpClient { Ok(Event::Message(message)) => { Some(EventKind::from_sse_bytes(&message.event, &message.data)) } - Err(err) => Some(Err(Error::SseClient(err))), + Err(err) => Some(Err(Error::SseClient(err.into()))), } }))) } diff --git a/consensus/state_processing/src/per_epoch_processing/altair.rs b/consensus/state_processing/src/per_epoch_processing/altair.rs index 5fcd147b2e..dc4dbe7cbc 100644 --- a/consensus/state_processing/src/per_epoch_processing/altair.rs +++ b/consensus/state_processing/src/per_epoch_processing/altair.rs @@ -84,7 +84,7 @@ pub fn process_epoch( Ok(EpochProcessingSummary::Altair { progressive_balances: current_epoch_progressive_balances, current_epoch_total_active_balance, - participation: participation_summary, + participation: participation_summary.into(), sync_committee, }) } diff --git a/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs b/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs index 5508b80807..b2228a5a1d 100644 --- a/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs +++ b/consensus/state_processing/src/per_epoch_processing/epoch_processing_summary.rs @@ -17,7 +17,7 @@ pub enum EpochProcessingSummary { Altair { progressive_balances: ProgressiveBalancesCache, current_epoch_total_active_balance: u64, - participation: ParticipationEpochSummary, + participation: Box>, sync_committee: Arc>, }, } diff --git a/testing/ef_tests/src/cases/merkle_proof_validity.rs b/testing/ef_tests/src/cases/merkle_proof_validity.rs index 711974dd43..b458b85fdd 100644 --- a/testing/ef_tests/src/cases/merkle_proof_validity.rs +++ b/testing/ef_tests/src/cases/merkle_proof_validity.rs @@ -22,7 +22,7 @@ pub struct MerkleProof { #[derive(Debug)] pub enum GenericMerkleProofValidity { - BeaconState(BeaconStateMerkleProofValidity), + BeaconState(Box>), BeaconBlockBody(Box>), } @@ -47,6 +47,7 @@ impl LoadCase for GenericMerkleProofValidity { if suite_name == "BeaconState" { BeaconStateMerkleProofValidity::load_from_dir(path, fork_name) + .map(Box::new) .map(GenericMerkleProofValidity::BeaconState) } else if suite_name == "BeaconBlockBody" { BeaconBlockBodyMerkleProofValidity::load_from_dir(path, fork_name)