merge unknown parent messages before current slot lookup

This commit is contained in:
realbigsean
2023-05-23 11:33:00 -04:00
parent c59a3fcf42
commit 8ea98c596c
12 changed files with 596 additions and 508 deletions

View File

@@ -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,
),
};
}
}

View File

@@ -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;

View File

@@ -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> {

View File

@@ -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,

View File

@@ -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(