mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-25 08:48:25 +00:00
merge unknown parent messages before current slot lookup
This commit is contained in:
@@ -188,7 +188,6 @@ pub enum AvailabilityProcessingStatus {
|
||||
Imported(Hash256),
|
||||
}
|
||||
|
||||
//TODO(sean) using this in tests for now
|
||||
impl TryInto<SignedBeaconBlockHash> for AvailabilityProcessingStatus {
|
||||
type Error = ();
|
||||
|
||||
@@ -2676,9 +2675,13 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// The block was imported successfully.
|
||||
}
|
||||
AvailabilityProcessingStatus::MissingComponents(slot, block_root) => {
|
||||
warn!(self.log, "Blobs missing in response to range request";
|
||||
"block_root" => ?block_root, "slot" => slot);
|
||||
return ChainSegmentResult::Failed {
|
||||
imported_blocks,
|
||||
error: BlockError::MissingBlockParts(slot, block_root),
|
||||
error: BlockError::AvailabilityCheck(
|
||||
AvailabilityCheckError::MissingBlobs,
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,17 +505,6 @@ pub enum MaybeAvailableBlock<E: EthSpec> {
|
||||
AvailabilityPending(AvailabilityPendingBlock<E>),
|
||||
}
|
||||
|
||||
impl<T: EthSpec> TryInto<AvailableBlock<T>> for MaybeAvailableBlock<T> {
|
||||
type Error = AvailabilityCheckError;
|
||||
|
||||
fn try_into(self) -> Result<AvailableBlock<T>, Self::Error> {
|
||||
match self {
|
||||
Self::Available(block) => Ok(block),
|
||||
Self::AvailabilityPending(_block) => Err(AvailabilityCheckError::MissingBlobs),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for common block operations.
|
||||
pub trait AsBlock<E: EthSpec> {
|
||||
fn slot(&self) -> Slot;
|
||||
|
||||
@@ -150,10 +150,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
/// its parent.
|
||||
ParentUnknown(BlockWrapper<T>),
|
||||
/// The block skips too many slots and is a DoS risk.
|
||||
TooManySkippedSlots {
|
||||
parent_slot: Slot,
|
||||
block_slot: Slot,
|
||||
},
|
||||
TooManySkippedSlots { parent_slot: Slot, block_slot: Slot },
|
||||
/// The block slot is greater than the present slot.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
@@ -168,10 +165,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
/// ## Peer scoring
|
||||
///
|
||||
/// The peer has incompatible state transition logic and is faulty.
|
||||
StateRootMismatch {
|
||||
block: Hash256,
|
||||
local: Hash256,
|
||||
},
|
||||
StateRootMismatch { block: Hash256, local: Hash256 },
|
||||
/// The block was a genesis block, these blocks cannot be re-imported.
|
||||
GenesisBlock,
|
||||
/// The slot is finalized, no need to import.
|
||||
@@ -190,9 +184,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
///
|
||||
/// It's unclear if this block is valid, but it conflicts with finality and shouldn't be
|
||||
/// imported.
|
||||
NotFinalizedDescendant {
|
||||
block_parent_root: Hash256,
|
||||
},
|
||||
NotFinalizedDescendant { block_parent_root: Hash256 },
|
||||
/// Block is already known, no need to re-import.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
@@ -205,10 +197,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
///
|
||||
/// The `proposer` has already proposed a block at this slot. The existing block may or may not
|
||||
/// be equal to the given block.
|
||||
RepeatProposal {
|
||||
proposer: u64,
|
||||
slot: Slot,
|
||||
},
|
||||
RepeatProposal { proposer: u64, slot: Slot },
|
||||
/// The block slot exceeds the MAXIMUM_BLOCK_SLOT_NUMBER.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
@@ -223,10 +212,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
/// ## Peer scoring
|
||||
///
|
||||
/// The block is invalid and the peer is faulty.
|
||||
IncorrectBlockProposer {
|
||||
block: u64,
|
||||
local_shuffling: u64,
|
||||
},
|
||||
IncorrectBlockProposer { block: u64, local_shuffling: u64 },
|
||||
/// The proposal signature in invalid.
|
||||
///
|
||||
/// ## Peer scoring
|
||||
@@ -250,10 +236,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
/// ## Peer scoring
|
||||
///
|
||||
/// The block is invalid and the peer is faulty.
|
||||
BlockIsNotLaterThanParent {
|
||||
block_slot: Slot,
|
||||
parent_slot: Slot,
|
||||
},
|
||||
BlockIsNotLaterThanParent { block_slot: Slot, parent_slot: Slot },
|
||||
/// At least one block in the chain segment did not have it's parent root set to the root of
|
||||
/// the prior block.
|
||||
///
|
||||
@@ -309,14 +292,11 @@ pub enum BlockError<T: EthSpec> {
|
||||
/// If it's actually our fault (e.g. our execution node database is corrupt) we have bigger
|
||||
/// problems to worry about than losing peers, and we're doing the network a favour by
|
||||
/// disconnecting.
|
||||
ParentExecutionPayloadInvalid {
|
||||
parent_root: Hash256,
|
||||
},
|
||||
/// The blob alone failed validation.
|
||||
ParentExecutionPayloadInvalid { parent_root: Hash256 },
|
||||
/// A blob alone failed validation.
|
||||
BlobValidation(BlobError<T>),
|
||||
/// The block and blob together failed validation.
|
||||
AvailabilityCheck(AvailabilityCheckError),
|
||||
MissingBlockParts(Slot, Hash256),
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<BlobError<T>> for BlockError<T> {
|
||||
|
||||
@@ -32,15 +32,14 @@ pub const OVERFLOW_LRU_CAPACITY: usize = 1024;
|
||||
#[derive(Debug, IntoStaticStr)]
|
||||
pub enum AvailabilityCheckError {
|
||||
Kzg(KzgError),
|
||||
KzgVerificationFailed,
|
||||
KzgNotInitialized,
|
||||
KzgVerificationFailed,
|
||||
SszTypes(ssz_types::Error),
|
||||
MissingBlobs,
|
||||
NumBlobsMismatch {
|
||||
/// The peer sent us an invalid block, we must penalise harshly.
|
||||
num_kzg_commitments: usize,
|
||||
num_blobs: usize,
|
||||
},
|
||||
MissingBlobs,
|
||||
TxKzgCommitmentMismatch(String),
|
||||
KzgCommitmentMismatch {
|
||||
blob_index: u64,
|
||||
@@ -53,10 +52,6 @@ pub enum AvailabilityCheckError {
|
||||
block_root: Hash256,
|
||||
blob_block_root: Hash256,
|
||||
},
|
||||
UnorderedBlobs {
|
||||
expected_index: u64,
|
||||
blob_index: u64,
|
||||
},
|
||||
}
|
||||
|
||||
impl From<ssz_types::Error> for AvailabilityCheckError {
|
||||
@@ -135,9 +130,7 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
) -> Option<Vec<BlobIdentifier>> {
|
||||
let (block, blob_indices) = self
|
||||
.availability_cache
|
||||
.get_missing_blob_ids_checking_cache(block_root);
|
||||
let (block, blob_indices) = self.availability_cache.get_missing_blob_info(block_root);
|
||||
self.get_missing_blob_ids(block_root, block.as_ref(), Some(blob_indices))
|
||||
}
|
||||
|
||||
@@ -507,7 +500,7 @@ impl<E: EthSpec> AvailabilityPendingBlock<E> {
|
||||
}
|
||||
|
||||
/// Verifies an AvailabilityPendingBlock against a set of KZG verified blobs.
|
||||
/// This does not check whether a block *should* have blobs, these checks should must have been
|
||||
/// This does not check whether a block *should* have blobs, these checks should have been
|
||||
/// completed when producing the `AvailabilityPendingBlock`.
|
||||
pub fn make_available(
|
||||
self,
|
||||
|
||||
@@ -13,6 +13,8 @@ use std::{collections::HashSet, sync::Arc};
|
||||
use types::blob_sidecar::BlobIdentifier;
|
||||
use types::{BlobSidecar, Epoch, EthSpec, Hash256, SignedBeaconBlock};
|
||||
|
||||
type MissingBlobInfo<T> = (Option<Arc<SignedBeaconBlock<T>>>, HashSet<usize>);
|
||||
|
||||
/// Caches partially available blobs and execution verified blocks corresponding
|
||||
/// to a given `block_hash` that are received over gossip.
|
||||
///
|
||||
@@ -199,7 +201,7 @@ impl<T: BeaconChainTypes> OverflowStore<T> {
|
||||
&self,
|
||||
blob_id: &BlobIdentifier,
|
||||
) -> Result<Option<Arc<BlobSidecar<T::EthSpec>>>, AvailabilityCheckError> {
|
||||
let key = OverflowKey::from_blob_id::<T::EthSpec>(blob_id.clone())?;
|
||||
let key = OverflowKey::from_blob_id::<T::EthSpec>(*blob_id)?;
|
||||
|
||||
self.0
|
||||
.hot_db
|
||||
@@ -331,11 +333,7 @@ impl<T: BeaconChainTypes> OverflowLRUCache<T> {
|
||||
pub fn has_block(&self, block_root: &Hash256) -> bool {
|
||||
self.critical.read().has_block(block_root)
|
||||
}
|
||||
|
||||
pub fn get_missing_blob_ids_checking_cache(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
) -> (Option<Arc<SignedBeaconBlock<T::EthSpec>>>, HashSet<usize>) {
|
||||
pub fn get_missing_blob_info(&self, block_root: Hash256) -> MissingBlobInfo<T::EthSpec> {
|
||||
self.critical
|
||||
.read()
|
||||
.in_memory
|
||||
@@ -497,11 +495,12 @@ impl<T: BeaconChainTypes> OverflowLRUCache<T> {
|
||||
payload_verification_outcome,
|
||||
} = executed_block;
|
||||
|
||||
let verified_blobs = Vec::from(pending_components.verified_blobs)
|
||||
let Some(verified_blobs) = Vec::from(pending_components.verified_blobs)
|
||||
.into_iter()
|
||||
.take(num_blobs_expected)
|
||||
.map(|maybe_blob| maybe_blob.ok_or(AvailabilityCheckError::MissingBlobs))
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
.collect::<Option<Vec<_>>>() else {
|
||||
return Ok(Availability::MissingComponents(import_data.block_root))
|
||||
};
|
||||
|
||||
let available_block = block.make_available(verified_blobs)?;
|
||||
Ok(Availability::Available(Box::new(
|
||||
|
||||
Reference in New Issue
Block a user