mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-23 23:04:53 +00:00
add a bunch of blob coupling boiler plate, add a blobs by root request
This commit is contained in:
@@ -6,7 +6,6 @@ use crate::attestation_verification::{
|
||||
use crate::attester_cache::{AttesterCache, AttesterCacheKey};
|
||||
use crate::beacon_proposer_cache::compute_proposer_duties_from_head;
|
||||
use crate::beacon_proposer_cache::BeaconProposerCache;
|
||||
use crate::blob_verification::{BlobError, VerifiedBlobsSidecar};
|
||||
use crate::block_times_cache::BlockTimesCache;
|
||||
use crate::block_verification::{
|
||||
check_block_is_finalized_descendant, check_block_relevancy, get_block_root,
|
||||
@@ -103,11 +102,12 @@ use task_executor::{ShutdownReason, TaskExecutor};
|
||||
use tree_hash::TreeHash;
|
||||
use types::beacon_state::CloneConfig;
|
||||
use types::*;
|
||||
use types::signed_block_and_blobs::BlockMaybeBlobs;
|
||||
|
||||
pub type ForkChoiceError = fork_choice::Error<crate::ForkChoiceStoreError>;
|
||||
|
||||
/// Alias to appease clippy.
|
||||
type HashBlockTuple<E> = (Hash256, Arc<SignedBeaconBlock<E>>);
|
||||
type HashBlockTuple<E> = (Hash256, BlockMaybeBlobs<E>);
|
||||
|
||||
/// The time-out before failure during an operation to take a read/write RwLock on the block
|
||||
/// processing cache.
|
||||
@@ -1784,23 +1784,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
})
|
||||
}
|
||||
|
||||
/// Accepts some `BlobsSidecar` received over from the network and attempts to verify it,
|
||||
/// returning `Ok(_)` if it is valid to be (re)broadcast on the gossip network.
|
||||
pub fn verify_blobs_sidecar_for_gossip<'a>(
|
||||
&self,
|
||||
blobs_sidecar: &'a BlobsSidecar<T::EthSpec>,
|
||||
) -> Result<VerifiedBlobsSidecar<'a, T>, BlobError> {
|
||||
metrics::inc_counter(&metrics::BLOBS_SIDECAR_PROCESSING_REQUESTS);
|
||||
let _timer = metrics::start_timer(&metrics::BLOBS_SIDECAR_GOSSIP_VERIFICATION_TIMES);
|
||||
VerifiedBlobsSidecar::verify(blobs_sidecar, self).map(|v| {
|
||||
if let Some(_event_handler) = self.event_handler.as_ref() {
|
||||
// TODO: Handle sse events
|
||||
}
|
||||
metrics::inc_counter(&metrics::BLOBS_SIDECAR_PROCESSING_SUCCESSES);
|
||||
v
|
||||
})
|
||||
}
|
||||
|
||||
/// Accepts some attestation-type object and attempts to verify it in the context of fork
|
||||
/// choice. If it is valid it is applied to `self.fork_choice`.
|
||||
///
|
||||
@@ -2215,7 +2198,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// This method is potentially long-running and should not run on the core executor.
|
||||
pub fn filter_chain_segment(
|
||||
self: &Arc<Self>,
|
||||
chain_segment: Vec<Arc<SignedBeaconBlock<T::EthSpec>>>,
|
||||
chain_segment: Vec<BlockMaybeBlobs<T::EthSpec>>,
|
||||
) -> Result<Vec<HashBlockTuple<T::EthSpec>>, ChainSegmentResult<T::EthSpec>> {
|
||||
// This function will never import any blocks.
|
||||
let imported_blocks = 0;
|
||||
@@ -2321,7 +2304,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// `Self::process_block`.
|
||||
pub async fn process_chain_segment(
|
||||
self: &Arc<Self>,
|
||||
chain_segment: Vec<Arc<SignedBeaconBlock<T::EthSpec>>>,
|
||||
chain_segment: Vec<BlockMaybeBlobs<T::EthSpec>>,
|
||||
count_unrealized: CountUnrealized,
|
||||
) -> ChainSegmentResult<T::EthSpec> {
|
||||
let mut imported_blocks = 0;
|
||||
@@ -2343,7 +2326,10 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
}
|
||||
};
|
||||
|
||||
while let Some((_root, block)) = filtered_chain_segment.first() {
|
||||
while let Some((_root, block_wrapper)) = filtered_chain_segment.first() {
|
||||
|
||||
let block: &SignedBeaconBlock<T::EthSpec> = block_wrapper.block();
|
||||
|
||||
// Determine the epoch of the first block in the remaining segment.
|
||||
let start_epoch = block.slot().epoch(T::EthSpec::slots_per_epoch());
|
||||
|
||||
@@ -2354,7 +2340,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
let last_index = filtered_chain_segment
|
||||
.iter()
|
||||
.position(|(_root, block)| {
|
||||
block.slot().epoch(T::EthSpec::slots_per_epoch()) > start_epoch
|
||||
block.block().slot().epoch(T::EthSpec::slots_per_epoch()) > start_epoch
|
||||
})
|
||||
.unwrap_or(filtered_chain_segment.len());
|
||||
|
||||
@@ -2420,17 +2406,17 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// Returns an `Err` if the given block was invalid, or an error was encountered during
|
||||
pub async fn verify_block_for_gossip(
|
||||
self: &Arc<Self>,
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block_wrapper: BlockMaybeBlobs<T::EthSpec>,
|
||||
) -> Result<GossipVerifiedBlock<T>, BlockError<T::EthSpec>> {
|
||||
let chain = self.clone();
|
||||
self.task_executor
|
||||
.clone()
|
||||
.spawn_blocking_handle(
|
||||
move || {
|
||||
let slot = block.slot();
|
||||
let graffiti_string = block.message().body().graffiti().as_utf8_lossy();
|
||||
let slot = block_wrapper.block().slot();
|
||||
let graffiti_string = block_wrapper.block().message().body().graffiti().as_utf8_lossy();
|
||||
|
||||
match GossipVerifiedBlock::new(block, &chain) {
|
||||
match GossipVerifiedBlock::new(block_wrapper, &chain) {
|
||||
Ok(verified) => {
|
||||
debug!(
|
||||
chain.log,
|
||||
@@ -2486,9 +2472,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// Increment the Prometheus counter for block processing requests.
|
||||
metrics::inc_counter(&metrics::BLOCK_PROCESSING_REQUESTS);
|
||||
|
||||
// Clone the block so we can provide it to the event handler.
|
||||
let block = unverified_block.block().clone();
|
||||
|
||||
// A small closure to group the verification and import errors.
|
||||
let chain = self.clone();
|
||||
let import_block = async move {
|
||||
@@ -2499,6 +2482,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.await
|
||||
};
|
||||
|
||||
let slot = unverified_block.block().slot();
|
||||
|
||||
// Verify and import the block.
|
||||
match import_block.await {
|
||||
// The block was successfully verified and imported. Yay.
|
||||
@@ -2507,7 +2492,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
self.log,
|
||||
"Beacon block imported";
|
||||
"block_root" => ?block_root,
|
||||
"block_slot" => %block.slot(),
|
||||
"block_slot" => slot,
|
||||
);
|
||||
|
||||
// Increment the Prometheus counter for block processing successes.
|
||||
@@ -2633,7 +2618,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn import_block(
|
||||
&self,
|
||||
signed_block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block_wrapper: BlockMaybeBlobs<T::EthSpec>,
|
||||
block_root: Hash256,
|
||||
mut state: BeaconState<T::EthSpec>,
|
||||
confirmed_state_roots: Vec<Hash256>,
|
||||
@@ -2642,6 +2627,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
parent_block: SignedBlindedBeaconBlock<T::EthSpec>,
|
||||
parent_eth1_finalization_data: Eth1FinalizationData,
|
||||
) -> Result<Hash256, BlockError<T::EthSpec>> {
|
||||
let signed_block = block_wrapper.block();
|
||||
let current_slot = self.slot()?;
|
||||
let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use std::sync::Arc;
|
||||
use derivative::Derivative;
|
||||
use slot_clock::SlotClock;
|
||||
|
||||
@@ -79,58 +80,45 @@ impl From<BeaconStateError> for BlobError {
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper around a `BlobsSidecar` that indicates it has been verified w.r.t the corresponding
|
||||
/// `SignedBeaconBlock`.
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug(bound = "T: BeaconChainTypes"))]
|
||||
pub struct VerifiedBlobsSidecar<'a, T: BeaconChainTypes> {
|
||||
pub blob_sidecar: &'a BlobsSidecar<T::EthSpec>,
|
||||
}
|
||||
|
||||
impl<'a, T: BeaconChainTypes> VerifiedBlobsSidecar<'a, T> {
|
||||
pub fn verify(
|
||||
blob_sidecar: &'a BlobsSidecar<T::EthSpec>,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Self, BlobError> {
|
||||
let blob_slot = blob_sidecar.beacon_block_slot;
|
||||
// Do not gossip or process blobs from future or past slots.
|
||||
let latest_permissible_slot = chain
|
||||
.slot_clock
|
||||
.now_with_future_tolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
|
||||
.ok_or(BeaconChainError::UnableToReadSlot)?;
|
||||
if blob_slot > latest_permissible_slot {
|
||||
return Err(BlobError::FutureSlot {
|
||||
message_slot: latest_permissible_slot,
|
||||
latest_permissible_slot: blob_slot,
|
||||
});
|
||||
}
|
||||
|
||||
let earliest_permissible_slot = chain
|
||||
.slot_clock
|
||||
.now_with_past_tolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
|
||||
.ok_or(BeaconChainError::UnableToReadSlot)?;
|
||||
if blob_slot > earliest_permissible_slot {
|
||||
return Err(BlobError::PastSlot {
|
||||
message_slot: earliest_permissible_slot,
|
||||
earliest_permissible_slot: blob_slot,
|
||||
});
|
||||
}
|
||||
|
||||
// Verify that blobs are properly formatted
|
||||
//TODO: add the check while constructing a Blob type from bytes instead of after
|
||||
for (i, blob) in blob_sidecar.blobs.iter().enumerate() {
|
||||
if blob.iter().any(|b| *b >= *BLS_MODULUS) {
|
||||
return Err(BlobError::BlobOutOfRange { blob_index: i });
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the KZG proof is a valid G1 point
|
||||
if PublicKey::deserialize(&blob_sidecar.kzg_aggregate_proof.0).is_err() {
|
||||
return Err(BlobError::InvalidKZGCommitment);
|
||||
}
|
||||
|
||||
// TODO: Check that we have not already received a sidecar with a valid signature for this slot.
|
||||
|
||||
Ok(Self { blob_sidecar })
|
||||
pub fn validate_blob_for_gossip<T: BeaconChainTypes>(blob_sidecar: &BlobsSidecar<T::EthSpec>, chain: &Arc<BeaconChain<T>>) -> Result<(), BlobError>{
|
||||
let blob_slot = blob_sidecar.beacon_block_slot;
|
||||
// Do not gossip or process blobs from future or past slots.
|
||||
let latest_permissible_slot = chain
|
||||
.slot_clock
|
||||
.now_with_future_tolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
|
||||
.ok_or(BeaconChainError::UnableToReadSlot)?;
|
||||
if blob_slot > latest_permissible_slot {
|
||||
return Err(BlobError::FutureSlot {
|
||||
message_slot: latest_permissible_slot,
|
||||
latest_permissible_slot: blob_slot,
|
||||
});
|
||||
}
|
||||
|
||||
let earliest_permissible_slot = chain
|
||||
.slot_clock
|
||||
.now_with_past_tolerance(MAXIMUM_GOSSIP_CLOCK_DISPARITY)
|
||||
.ok_or(BeaconChainError::UnableToReadSlot)?;
|
||||
if blob_slot > earliest_permissible_slot {
|
||||
return Err(BlobError::PastSlot {
|
||||
message_slot: earliest_permissible_slot,
|
||||
earliest_permissible_slot: blob_slot,
|
||||
});
|
||||
}
|
||||
|
||||
// Verify that blobs are properly formatted
|
||||
//TODO: add the check while constructing a Blob type from bytes instead of after
|
||||
for (i, blob) in blob_sidecar.blobs.iter().enumerate() {
|
||||
if blob.iter().any(|b| *b >= *BLS_MODULUS) {
|
||||
return Err(BlobError::BlobOutOfRange { blob_index: i });
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that the KZG proof is a valid G1 point
|
||||
if PublicKey::deserialize(&blob_sidecar.kzg_aggregate_proof.0).is_err() {
|
||||
return Err(BlobError::InvalidKZGCommitment);
|
||||
}
|
||||
|
||||
// TODO: `validate_blobs_sidecar`
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -83,12 +83,14 @@ use std::time::Duration;
|
||||
use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp};
|
||||
use task_executor::JoinHandle;
|
||||
use tree_hash::TreeHash;
|
||||
use types::ExecPayload;
|
||||
use types::{BlobsSidecar, ExecPayload, SignedBeaconBlockAndBlobsSidecar};
|
||||
use types::{
|
||||
BeaconBlockRef, BeaconState, BeaconStateError, BlindedPayload, ChainSpec, CloneConfig, Epoch,
|
||||
EthSpec, ExecutionBlockHash, Hash256, InconsistentFork, PublicKey, PublicKeyBytes,
|
||||
RelativeEpoch, SignedBeaconBlock, SignedBeaconBlockHeader, Slot,
|
||||
};
|
||||
use types::signed_block_and_blobs::BlockMaybeBlobs;
|
||||
use crate::blob_verification::validate_blob_for_gossip;
|
||||
|
||||
pub const POS_PANDA_BANNER: &str = r#"
|
||||
,,, ,,, ,,, ,,,
|
||||
@@ -135,7 +137,7 @@ pub enum BlockError<T: EthSpec> {
|
||||
///
|
||||
/// It's unclear if this block is valid, but it cannot be processed without already knowing
|
||||
/// its parent.
|
||||
ParentUnknown(Arc<SignedBeaconBlock<T>>),
|
||||
ParentUnknown(BlockMaybeBlobs<T>),
|
||||
/// The block skips too many slots and is a DoS risk.
|
||||
TooManySkippedSlots { parent_slot: Slot, block_slot: Slot },
|
||||
/// The block slot is greater than the present slot.
|
||||
@@ -524,7 +526,7 @@ fn process_block_slash_info<T: BeaconChainTypes>(
|
||||
/// The given `chain_segment` must contain only blocks from the same epoch, otherwise an error
|
||||
/// will be returned.
|
||||
pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
|
||||
mut chain_segment: Vec<(Hash256, Arc<SignedBeaconBlock<T::EthSpec>>)>,
|
||||
mut chain_segment: Vec<(Hash256, BlockMaybeBlobs<T::EthSpec>)>,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Vec<SignatureVerifiedBlock<T>>, BlockError<T::EthSpec>> {
|
||||
if chain_segment.is_empty() {
|
||||
@@ -589,7 +591,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug(bound = "T: BeaconChainTypes"))]
|
||||
pub struct GossipVerifiedBlock<T: BeaconChainTypes> {
|
||||
pub block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
pub block: BlockMaybeBlobs<T::EthSpec>,
|
||||
pub block_root: Hash256,
|
||||
parent: Option<PreProcessingSnapshot<T::EthSpec>>,
|
||||
consensus_context: ConsensusContext<T::EthSpec>,
|
||||
@@ -598,7 +600,7 @@ pub struct GossipVerifiedBlock<T: BeaconChainTypes> {
|
||||
/// A wrapper around a `SignedBeaconBlock` that indicates that all signatures (except the deposit
|
||||
/// signatures) have been verified.
|
||||
pub struct SignatureVerifiedBlock<T: BeaconChainTypes> {
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block: BlockMaybeBlobs<T::EthSpec>,
|
||||
block_root: Hash256,
|
||||
parent: Option<PreProcessingSnapshot<T::EthSpec>>,
|
||||
consensus_context: ConsensusContext<T::EthSpec>,
|
||||
@@ -620,7 +622,7 @@ type PayloadVerificationHandle<E> =
|
||||
/// due to finality or some other event. A `ExecutionPendingBlock` should be imported into the
|
||||
/// `BeaconChain` immediately after it is instantiated.
|
||||
pub struct ExecutionPendingBlock<T: BeaconChainTypes> {
|
||||
pub block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
pub block: BlockMaybeBlobs<T::EthSpec>,
|
||||
pub block_root: Hash256,
|
||||
pub state: BeaconState<T::EthSpec>,
|
||||
pub parent_block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>,
|
||||
@@ -665,7 +667,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
||||
///
|
||||
/// Returns an error if the block is invalid, or if the block was unable to be verified.
|
||||
pub fn new(
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block: BlockMaybeBlobs<T::EthSpec>,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Self, BlockError<T::EthSpec>> {
|
||||
// If the block is valid for gossip we don't supply it to the slasher here because
|
||||
@@ -680,9 +682,10 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
||||
|
||||
/// As for new, but doesn't pass the block to the slasher.
|
||||
fn new_without_slasher_checks(
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block_wrapper: BlockMaybeBlobs<T::EthSpec>,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Self, BlockError<T::EthSpec>> {
|
||||
let block = block_wrapper.block();
|
||||
// Ensure the block is the correct structure for the fork at `block.slot()`.
|
||||
block
|
||||
.fork_name(&chain.spec)
|
||||
@@ -876,13 +879,17 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
||||
// Validate the block's execution_payload (if any).
|
||||
validate_execution_payload_for_gossip(&parent_block, block.message(), chain)?;
|
||||
|
||||
if let Some(blobs_sidecar) = block_wrapper.blobs() {
|
||||
validate_blob_for_gossip(blobs_sidecar, chain)?;
|
||||
}
|
||||
|
||||
// Having checked the proposer index and the block root we can cache them.
|
||||
let consensus_context = ConsensusContext::new(block.slot())
|
||||
.set_current_block_root(block_root)
|
||||
.set_proposer_index(block.message().proposer_index());
|
||||
|
||||
Ok(Self {
|
||||
block,
|
||||
block: block_wrapper,
|
||||
block_root,
|
||||
parent,
|
||||
consensus_context,
|
||||
@@ -917,7 +924,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
///
|
||||
/// Returns an error if the block is invalid, or if the block was unable to be verified.
|
||||
pub fn new(
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block: BlockMaybeBlobs<T::EthSpec>,
|
||||
block_root: Hash256,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Self, BlockError<T::EthSpec>> {
|
||||
@@ -963,7 +970,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
|
||||
/// As for `new` above but producing `BlockSlashInfo`.
|
||||
pub fn check_slashable(
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block: BlockMaybeBlobs<T::EthSpec>,
|
||||
block_root: Hash256,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||
@@ -1057,7 +1064,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock<T::EthSpec>> {
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for BlockMaybeBlobs<T::EthSpec> {
|
||||
/// Verifies the `SignedBeaconBlock` by first transforming it into a `SignatureVerifiedBlock`
|
||||
/// and then using that implementation of `IntoExecutionPendingBlock` to complete verification.
|
||||
fn into_execution_pending_block_slashable(
|
||||
@@ -1074,7 +1081,10 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
|
||||
}
|
||||
|
||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
||||
self
|
||||
match self {
|
||||
Self::Block(block) => block,
|
||||
Self::BlockAndBlobs(block) => &block.beacon_block,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1087,12 +1097,14 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
||||
///
|
||||
/// Returns an error if the block is invalid, or if the block was unable to be verified.
|
||||
pub fn from_signature_verified_components(
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block_wrapper: BlockMaybeBlobs<T::EthSpec>,
|
||||
block_root: Hash256,
|
||||
parent: PreProcessingSnapshot<T::EthSpec>,
|
||||
mut consensus_context: ConsensusContext<T::EthSpec>,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
) -> Result<Self, BlockError<T::EthSpec>> {
|
||||
let block = block_wrapper.block();
|
||||
|
||||
if let Some(parent) = chain
|
||||
.canonical_head
|
||||
.fork_choice_read_lock()
|
||||
@@ -1116,7 +1128,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
||||
// because it will revert finalization. Note that the finalized block is stored in fork
|
||||
// choice, so we will not reject any child of the finalized block (this is relevant during
|
||||
// genesis).
|
||||
return Err(BlockError::ParentUnknown(block));
|
||||
return Err(BlockError::ParentUnknown(block_wrapper));
|
||||
}
|
||||
|
||||
// Reject any block that exceeds our limit on skipped slots.
|
||||
@@ -1532,7 +1544,8 @@ pub fn check_block_is_finalized_descendant<T: BeaconChainTypes>(
|
||||
block_parent_root: block.parent_root(),
|
||||
})
|
||||
} else {
|
||||
Err(BlockError::ParentUnknown(block.clone()))
|
||||
//FIXME(sean) does this matter if it only returns a block?
|
||||
Err(BlockError::ParentUnknown(BlockMaybeBlobs::Block(block.clone())))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1624,15 +1637,16 @@ fn verify_parent_block_is_known<T: BeaconChainTypes>(
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn load_parent<T: BeaconChainTypes>(
|
||||
block_root: Hash256,
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
block_wrapper: BlockMaybeBlobs<T::EthSpec>,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<
|
||||
(
|
||||
PreProcessingSnapshot<T::EthSpec>,
|
||||
Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
BlockMaybeBlobs<T::EthSpec>,
|
||||
),
|
||||
BlockError<T::EthSpec>,
|
||||
> {
|
||||
let block = block_wrapper.block();
|
||||
let spec = &chain.spec;
|
||||
|
||||
// Reject any block if its parent is not known to fork choice.
|
||||
@@ -1650,7 +1664,7 @@ fn load_parent<T: BeaconChainTypes>(
|
||||
.fork_choice_read_lock()
|
||||
.contains_block(&block.parent_root())
|
||||
{
|
||||
return Err(BlockError::ParentUnknown(block));
|
||||
return Err(BlockError::ParentUnknown(block_wrapper));
|
||||
}
|
||||
|
||||
let block_delay = chain
|
||||
@@ -1689,7 +1703,7 @@ fn load_parent<T: BeaconChainTypes>(
|
||||
"block_delay" => ?block_delay,
|
||||
);
|
||||
}
|
||||
Ok((snapshot, block))
|
||||
Ok((snapshot, block_wrapper))
|
||||
} else {
|
||||
// Load the blocks parent block from the database, returning invalid if that block is not
|
||||
// found.
|
||||
@@ -1736,7 +1750,7 @@ fn load_parent<T: BeaconChainTypes>(
|
||||
pre_state: parent_state,
|
||||
beacon_state_root: Some(parent_state_root),
|
||||
},
|
||||
block,
|
||||
block_wrapper,
|
||||
))
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user