mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-16 11:22:56 +00:00
Do not penalize peers on execution layer offline errors (#3258)
## Issue Addressed Partly resolves https://github.com/sigp/lighthouse/issues/3032 ## Proposed Changes Extracts some of the functionality of #3094 into a separate PR as the original PR requires a bit more work. Do not unnecessarily penalize peers when we fail to validate received execution payloads because our execution layer is offline.
This commit is contained in:
@@ -75,7 +75,9 @@ mod work_reprocessing_queue;
|
||||
mod worker;
|
||||
|
||||
use crate::beacon_processor::work_reprocessing_queue::QueuedBlock;
|
||||
pub use worker::{ChainSegmentProcessId, GossipAggregatePackage, GossipAttestationPackage};
|
||||
pub use worker::{
|
||||
ChainSegmentProcessId, FailureMode, GossipAggregatePackage, GossipAttestationPackage,
|
||||
};
|
||||
|
||||
/// The maximum size of the channel for work events to the `BeaconProcessor`.
|
||||
///
|
||||
|
||||
@@ -943,6 +943,16 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
);
|
||||
self.send_sync_message(SyncMessage::UnknownBlock(peer_id, block));
|
||||
}
|
||||
Err(e @ BlockError::ExecutionPayloadError(ExecutionPayloadError::RequestFailed(_)))
|
||||
| Err(
|
||||
e @ BlockError::ExecutionPayloadError(ExecutionPayloadError::NoExecutionConnection),
|
||||
) => {
|
||||
debug!(
|
||||
self.log,
|
||||
"Failed to verify execution payload";
|
||||
"error" => %e
|
||||
);
|
||||
}
|
||||
other => {
|
||||
debug!(
|
||||
self.log,
|
||||
|
||||
@@ -10,7 +10,7 @@ mod rpc_methods;
|
||||
mod sync_methods;
|
||||
|
||||
pub use gossip_methods::{GossipAggregatePackage, GossipAttestationPackage};
|
||||
pub use sync_methods::ChainSegmentProcessId;
|
||||
pub use sync_methods::{ChainSegmentProcessId, FailureMode};
|
||||
|
||||
pub(crate) const FUTURE_SLOT_TOLERANCE: u64 = 1;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ use crate::beacon_processor::DuplicateCache;
|
||||
use crate::metrics;
|
||||
use crate::sync::manager::{BlockProcessType, SyncMessage};
|
||||
use crate::sync::{BatchProcessResult, ChainId};
|
||||
use beacon_chain::ExecutionPayloadError;
|
||||
use beacon_chain::{
|
||||
BeaconChainError, BeaconChainTypes, BlockError, ChainSegmentResult, HistoricalBlockError,
|
||||
};
|
||||
@@ -31,6 +32,15 @@ struct ChainSegmentFailed {
|
||||
message: String,
|
||||
/// Used to penalize peers.
|
||||
peer_action: Option<PeerAction>,
|
||||
/// Failure mode
|
||||
mode: FailureMode,
|
||||
}
|
||||
|
||||
/// Represents if a block processing failure was on the consensus or execution side.
|
||||
#[derive(Debug)]
|
||||
pub enum FailureMode {
|
||||
ExecutionLayer { pause_sync: bool },
|
||||
ConsensusLayer,
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> Worker<T> {
|
||||
@@ -128,6 +138,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
BatchProcessResult::Failed {
|
||||
imported_blocks: imported_blocks > 0,
|
||||
peer_action: e.peer_action,
|
||||
mode: e.mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,6 +169,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
BatchProcessResult::Failed {
|
||||
imported_blocks: false,
|
||||
peer_action: e.peer_action,
|
||||
mode: e.mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,6 +189,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
BatchProcessResult::Failed {
|
||||
imported_blocks: imported_blocks > 0,
|
||||
peer_action: e.peer_action,
|
||||
mode: e.mode,
|
||||
}
|
||||
}
|
||||
(imported_blocks, Ok(_)) => {
|
||||
@@ -257,6 +270,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: String::from("mismatched_block_root"),
|
||||
// The peer is faulty if they send blocks with bad roots.
|
||||
peer_action: Some(PeerAction::LowToleranceError),
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
HistoricalBlockError::InvalidSignature
|
||||
@@ -271,6 +285,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: "invalid_signature".into(),
|
||||
// The peer is faulty if they bad signatures.
|
||||
peer_action: Some(PeerAction::LowToleranceError),
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
HistoricalBlockError::ValidatorPubkeyCacheTimeout => {
|
||||
@@ -284,6 +299,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: "pubkey_cache_timeout".into(),
|
||||
// This is an internal error, do not penalize the peer.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
HistoricalBlockError::NoAnchorInfo => {
|
||||
@@ -294,6 +310,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
// There is no need to do a historical sync, this is not a fault of
|
||||
// the peer.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
HistoricalBlockError::IndexOutOfBounds => {
|
||||
@@ -306,6 +323,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: String::from("logic_error"),
|
||||
// This should never occur, don't penalize the peer.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
HistoricalBlockError::BlockOutOfRange { .. } => {
|
||||
@@ -318,6 +336,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: String::from("unexpected_error"),
|
||||
// This should never occur, don't penalize the peer.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -327,6 +346,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: format!("{:?}", other),
|
||||
// This is an internal error, don't penalize the peer.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -365,6 +385,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: format!("Block has an unknown parent: {}", block.parent_root()),
|
||||
// Peers are faulty if they send non-sequential blocks.
|
||||
peer_action: Some(PeerAction::LowToleranceError),
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
})
|
||||
}
|
||||
BlockError::BlockIsAlreadyKnown => {
|
||||
@@ -402,6 +423,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
),
|
||||
// Peers are faulty if they send blocks from the future.
|
||||
peer_action: Some(PeerAction::LowToleranceError),
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
})
|
||||
}
|
||||
BlockError::WouldRevertFinalizedSlot { .. } => {
|
||||
@@ -423,8 +445,41 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: format!("Internal error whilst processing block: {:?}", e),
|
||||
// Do not penalize peers for internal errors.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
})
|
||||
}
|
||||
BlockError::ExecutionPayloadError(e) => match &e {
|
||||
ExecutionPayloadError::NoExecutionConnection { .. }
|
||||
| ExecutionPayloadError::RequestFailed { .. } => {
|
||||
// These errors indicate an issue with the EL and not the `ChainSegment`.
|
||||
// Pause the syncing while the EL recovers
|
||||
debug!(self.log,
|
||||
"Execution layer verification failed";
|
||||
"outcome" => "pausing sync",
|
||||
"err" => ?e
|
||||
);
|
||||
Err(ChainSegmentFailed {
|
||||
message: format!("Execution layer offline. Reason: {:?}", e),
|
||||
// Do not penalize peers for internal errors.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ExecutionLayer { pause_sync: true },
|
||||
})
|
||||
}
|
||||
err => {
|
||||
debug!(self.log,
|
||||
"Invalid execution payload";
|
||||
"error" => ?err
|
||||
);
|
||||
Err(ChainSegmentFailed {
|
||||
message: format!(
|
||||
"Peer sent a block containing invalid execution payload. Reason: {:?}",
|
||||
err
|
||||
),
|
||||
peer_action: Some(PeerAction::LowToleranceError),
|
||||
mode: FailureMode::ExecutionLayer { pause_sync: false },
|
||||
})
|
||||
}
|
||||
},
|
||||
other => {
|
||||
debug!(
|
||||
self.log, "Invalid block received";
|
||||
@@ -436,6 +491,7 @@ impl<T: BeaconChainTypes> Worker<T> {
|
||||
message: format!("Peer sent invalid block. Reason: {:?}", other),
|
||||
// Do not penalize peers for internal errors.
|
||||
peer_action: None,
|
||||
mode: FailureMode::ConsensusLayer,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user