more progress

This commit is contained in:
Pawan Dhananjay
2023-03-16 20:55:21 +05:30
parent 8c79358d35
commit 9df968c992
4 changed files with 181 additions and 135 deletions

View File

@@ -2682,6 +2682,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
metrics::inc_counter(&metrics::BLOCK_PROCESSING_REQUESTS); metrics::inc_counter(&metrics::BLOCK_PROCESSING_REQUESTS);
let slot = unverified_block.block().slot(); let slot = unverified_block.block().slot();
let chain = self.clone();
let execution_pending = unverified_block.into_execution_pending_block( let execution_pending = unverified_block.into_execution_pending_block(
block_root, block_root,
@@ -2694,8 +2695,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.into_executed_block(execution_pending, count_unrealized) .into_executed_block(execution_pending, count_unrealized)
.await?; .await?;
let chain = self.clone();
// Check if the executed block has all it's blobs available to qualify as a fully // Check if the executed block has all it's blobs available to qualify as a fully
// available block // available block
let import_block = if let Ok(blobs) = self let import_block = if let Ok(blobs) = self
@@ -2840,12 +2839,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
payload_verification_outcome, payload_verification_outcome,
parent_eth1_finalization_data, parent_eth1_finalization_data,
consensus_context, consensus_context,
} = execution_pending_block; } = executed_block;
let chain = self.clone(); let chain = self.clone();
let available_block = AvailableBlock { let available_block = AvailableBlock {
block: block, block: block.block_cloned(),
blobs: blobs, blobs: blobs,
}; };
@@ -2857,7 +2856,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
block_root, block_root,
state, state,
confirmed_state_roots, confirmed_state_roots,
payload_verification_status, payload_verification_outcome.payload_verification_status,
count_unrealized, count_unrealized,
parent_block, parent_block,
parent_eth1_finalization_data, parent_eth1_finalization_data,
@@ -2871,7 +2870,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
Ok(block_hash) Ok(block_hash)
} }
/// Accepts a fully-verified block and imports it into the chain without performing any /// Accepts a fully-verified and available block and imports it into the chain without performing any
/// additional verification. /// additional verification.
/// ///
/// An error is returned if the block was unable to be imported. It may be partially imported /// An error is returned if the block was unable to be imported. It may be partially imported
@@ -2896,7 +2895,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// ----------------------------------------------------------------------------------------- // -----------------------------------------------------------------------------------------
let current_slot = self.slot()?; let current_slot = self.slot()?;
let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch()); let current_epoch = current_slot.epoch(T::EthSpec::slots_per_epoch());
let block = signed_block.message(); let block = signed_block.block.message();
let post_exec_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_POST_EXEC_PROCESSING); let post_exec_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_POST_EXEC_PROCESSING);
// Check against weak subjectivity checkpoint. // Check against weak subjectivity checkpoint.
@@ -2933,9 +2932,14 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let mut fork_choice = self.canonical_head.fork_choice_write_lock(); let mut fork_choice = self.canonical_head.fork_choice_write_lock();
// Do not import a block that doesn't descend from the finalized root. // Do not import a block that doesn't descend from the finalized root.
let signed_block = let signed_block = check_block_is_finalized_checkpoint_or_descendant(
check_block_is_finalized_checkpoint_or_descendant(self, &fork_choice, signed_block)?; self,
let block = signed_block.message(); &fork_choice,
BlockWrapper::from(signed_block),
)?;
// TODO(pawan): fix this atrocity
let signed_block = signed_block.into_available_block().unwrap();
let block = signed_block.block.message();
// Register the new block with the fork choice service. // Register the new block with the fork choice service.
{ {
@@ -3065,7 +3069,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// margin, or younger (of higher epoch number). // margin, or younger (of higher epoch number).
if block_epoch >= import_boundary { if block_epoch >= import_boundary {
if let Some(blobs) = blobs { if let Some(blobs) = blobs {
if !blobs.blobs.is_empty() {
//FIXME(sean) using this for debugging for now //FIXME(sean) using this for debugging for now
info!( info!(
self.log, "Writing blobs to store"; self.log, "Writing blobs to store";
@@ -3075,7 +3078,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
} }
} }
} }
}
let txn_lock = self.store.hot_db.begin_rw_transaction(); let txn_lock = self.store.hot_db.begin_rw_transaction();
if let Err(e) = self.store.do_atomically_with_block_and_blobs_cache(ops) { if let Err(e) = self.store.do_atomically_with_block_and_blobs_cache(ops) {

View File

@@ -1,8 +1,5 @@
use derivative::Derivative;
use slot_clock::SlotClock; use slot_clock::SlotClock;
use ssz_types::VariableList;
use std::sync::Arc; use std::sync::Arc;
use tokio::task::JoinHandle;
use crate::beacon_chain::{ use crate::beacon_chain::{
BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY, BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
@@ -10,12 +7,10 @@ use crate::beacon_chain::{
}; };
use crate::BeaconChainError; use crate::BeaconChainError;
use state_processing::per_block_processing::eip4844::eip4844::verify_kzg_commitments_against_transactions; use state_processing::per_block_processing::eip4844::eip4844::verify_kzg_commitments_against_transactions;
use types::blob_sidecar::BlobSidecar;
use types::{ use types::{
BeaconBlockRef, BeaconStateError, EthSpec, Hash256, KzgCommitment, SignedBeaconBlock, BeaconBlockRef, BeaconStateError, BlobSidecarList, Epoch, EthSpec, Hash256, KzgCommitment,
SignedBeaconBlockHeader, SignedBlobSidecar, Slot, Transactions, SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlobSidecar, Slot, Transactions,
}; };
use types::{Epoch, ExecPayload};
#[derive(Debug)] #[derive(Debug)]
pub enum BlobError { pub enum BlobError {
@@ -190,9 +185,9 @@ pub fn validate_blob_sidecar_for_gossip<T: BeaconChainTypes>(
}; };
let blob_proposer_index = blob_sidecar.message.proposer_index; let blob_proposer_index = blob_sidecar.message.proposer_index;
if proposer_index != blob_proposer_index { if proposer_index != blob_proposer_index as usize {
return Err(BlobError::ProposerIndexMismatch { return Err(BlobError::ProposerIndexMismatch {
sidecar: blob_proposer_index, sidecar: blob_proposer_index as usize,
local: proposer_index, local: proposer_index,
}); });
} }
@@ -248,7 +243,7 @@ pub fn validate_blob_sidecar_for_gossip<T: BeaconChainTypes>(
} }
pub fn verify_data_availability<T: BeaconChainTypes>( pub fn verify_data_availability<T: BeaconChainTypes>(
blob_sidecar: &BlobsSidecar<T::EthSpec>, blob_sidecar: &BlobSidecarList<T::EthSpec>,
kzg_commitments: &[KzgCommitment], kzg_commitments: &[KzgCommitment],
transactions: &Transactions<T::EthSpec>, transactions: &Transactions<T::EthSpec>,
_block_slot: Slot, _block_slot: Slot,
@@ -306,36 +301,38 @@ impl<T: BeaconChainTypes> IntoAvailableBlock<T> for BlockWrapper<T::EthSpec> {
} }
} }
#[derive(Clone, Debug, Derivative)] #[derive(Clone, Debug, PartialEq)]
#[derivative(PartialEq, Hash(bound = "T: BeaconChainTypes"))]
pub struct AvailableBlock<T: EthSpec> { pub struct AvailableBlock<T: EthSpec> {
block: Arc<SignedBeaconBlock<T>>, pub block: Arc<SignedBeaconBlock<T>>,
blobs: Blobs<T>, pub blobs: Blobs<T>,
} }
impl<T: EthSpec> AvailableBlock<T> { impl<T: EthSpec> AvailableBlock<T> {
pub fn blobs(&self) -> Option<Arc<BlobsSidecar<T>>> { pub fn blobs(&self) -> Option<Arc<BlobSidecarList<T>>> {
match &self.blobs { match &self.blobs {
Blobs::NotRequired | Blobs::None => None, Blobs::NotRequired | Blobs::None => None,
Blobs::Available(blob_sidecar) => Some(blob_sidecar.clone()), Blobs::Available(blobs) => Some(blobs.clone()),
} }
} }
pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<T>>, Option<Arc<BlobsSidecar<T>>>) { pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<T>>, Option<Arc<BlobSidecarList<T>>>) {
match self.blobs { match self.blobs {
Blobs::NotRequired | Blobs::None => (self.block, None), Blobs::NotRequired | Blobs::None => (self.block, None),
Blobs::Available(blob_sidecars) => (self.block, Some(blob_sidecars)), Blobs::Available(blobs) => (self.block, Some(blobs)),
} }
} }
} }
#[derive(Clone, Debug, PartialEq)]
pub enum Blobs<E: EthSpec> { pub enum Blobs<E: EthSpec> {
/// These blobs are available. /// These blobs are available.
Available(VariableList<Arc<BlobSidecar<E>>, E::MaxBlobsPerBlock>), Available(Arc<BlobSidecarList<E>>),
/// This block is from outside the data availability boundary or the block is from prior /// This block is from outside the data availability boundary so doesn't require
/// to the eip4844 fork. /// a data availability check.
NotRequired, NotRequired,
/// The block doesn't have any blob transactions. /// The block's `kzg_commitments` field is empty so it does not contain any blobs.
EmptyBlobs,
/// This is a block prior to the 4844 fork, so doesn't require any blobs
None, None,
} }
@@ -351,59 +348,78 @@ pub trait AsBlock<E: EthSpec> {
fn canonical_root(&self) -> Hash256; fn canonical_root(&self) -> Hash256;
} }
#[derive(Debug, Clone)]
pub enum BlockWrapper<E: EthSpec> {
/// This variant is fully available.
/// i.e. for pre-4844 blocks, it contains a (`SignedBeaconBlock`, `Blobs::None`) and for
/// post-4844 blocks, it contains a `SignedBeaconBlock` and a Blobs variant other than `Blobs::None`.
Available(AvailableBlock<E>),
/// This variant is not fully available and requires blobs to become fully available.
AvailabilityPending(Arc<SignedBeaconBlock<E>>),
}
impl<E: EthSpec> BlockWrapper<E> {
pub fn into_available_block(self) -> Option<AvailableBlock<E>> {
match self {
BlockWrapper::AvailabilityPending(_) => None,
BlockWrapper::Available(block) => Some(block),
}
}
}
impl<E: EthSpec> AsBlock<E> for BlockWrapper<E> { impl<E: EthSpec> AsBlock<E> for BlockWrapper<E> {
fn slot(&self) -> Slot { fn slot(&self) -> Slot {
match self { match self {
BlockWrapper::Block(block) => block.slot(), BlockWrapper::Available(block) => block.block.slot(),
BlockWrapper::BlockAndBlobs(block, _) => block.slot(), BlockWrapper::AvailabilityPending(block) => block.slot(),
} }
} }
fn epoch(&self) -> Epoch { fn epoch(&self) -> Epoch {
match self { match self {
BlockWrapper::Block(block) => block.epoch(), BlockWrapper::Available(block) => block.block.epoch(),
BlockWrapper::BlockAndBlobs(block, _) => block.epoch(), BlockWrapper::AvailabilityPending(block) => block.epoch(),
} }
} }
fn parent_root(&self) -> Hash256 { fn parent_root(&self) -> Hash256 {
match self { match self {
BlockWrapper::Block(block) => block.parent_root(), BlockWrapper::Available(block) => block.block.parent_root(),
BlockWrapper::BlockAndBlobs(block, _) => block.parent_root(), BlockWrapper::AvailabilityPending(block) => block.parent_root(),
} }
} }
fn state_root(&self) -> Hash256 { fn state_root(&self) -> Hash256 {
match self { match self {
BlockWrapper::Block(block) => block.state_root(), BlockWrapper::Available(block) => block.block.state_root(),
BlockWrapper::BlockAndBlobs(block, _) => block.state_root(), BlockWrapper::AvailabilityPending(block) => block.state_root(),
} }
} }
fn signed_block_header(&self) -> SignedBeaconBlockHeader { fn signed_block_header(&self) -> SignedBeaconBlockHeader {
match &self { match &self {
BlockWrapper::Block(block) => block.signed_block_header(), BlockWrapper::Available(block) => block.block.signed_block_header(),
BlockWrapper::BlockAndBlobs(block, _) => block.signed_block_header(), BlockWrapper::AvailabilityPending(block) => block.signed_block_header(),
} }
} }
fn message(&self) -> BeaconBlockRef<E> { fn message(&self) -> BeaconBlockRef<E> {
match &self { match &self {
BlockWrapper::Block(block) => block.message(), BlockWrapper::Available(block) => block.block.message(),
BlockWrapper::BlockAndBlobs(block, _) => block.message(), BlockWrapper::AvailabilityPending(block) => block.message(),
} }
} }
fn as_block(&self) -> &SignedBeaconBlock<E> { fn as_block(&self) -> &SignedBeaconBlock<E> {
match &self { match &self {
BlockWrapper::Block(block) => &block, BlockWrapper::Available(block) => &block.block,
BlockWrapper::BlockAndBlobs(block, _) => &block, BlockWrapper::AvailabilityPending(block) => &block,
} }
} }
fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> { fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
match &self { match &self {
BlockWrapper::Block(block) => block.clone(), BlockWrapper::Available(block) => block.block.clone(),
BlockWrapper::BlockAndBlobs(block, _) => block.clone(), BlockWrapper::AvailabilityPending(block) => block.clone(),
} }
} }
fn canonical_root(&self) -> Hash256 { fn canonical_root(&self) -> Hash256 {
match &self { match &self {
BlockWrapper::Block(block) => block.canonical_root(), BlockWrapper::Available(block) => block.block.canonical_root(),
BlockWrapper::BlockAndBlobs(block, _) => block.canonical_root(), BlockWrapper::AvailabilityPending(block) => block.canonical_root(),
} }
} }
} }
@@ -411,91 +427,74 @@ impl<E: EthSpec> AsBlock<E> for BlockWrapper<E> {
impl<E: EthSpec> AsBlock<E> for &BlockWrapper<E> { impl<E: EthSpec> AsBlock<E> for &BlockWrapper<E> {
fn slot(&self) -> Slot { fn slot(&self) -> Slot {
match self { match self {
BlockWrapper::Block(block) => block.slot(), BlockWrapper::Available(block) => block.block.slot(),
BlockWrapper::BlockAndBlobs(block, _) => block.slot(), BlockWrapper::AvailabilityPending(block) => block.slot(),
} }
} }
fn epoch(&self) -> Epoch { fn epoch(&self) -> Epoch {
match self { match self {
BlockWrapper::Block(block) => block.epoch(), BlockWrapper::Available(block) => block.block.epoch(),
BlockWrapper::BlockAndBlobs(block, _) => block.epoch(), BlockWrapper::AvailabilityPending(block) => block.epoch(),
} }
} }
fn parent_root(&self) -> Hash256 { fn parent_root(&self) -> Hash256 {
match self { match self {
BlockWrapper::Block(block) => block.parent_root(), BlockWrapper::Available(block) => block.block.parent_root(),
BlockWrapper::BlockAndBlobs(block, _) => block.parent_root(), BlockWrapper::AvailabilityPending(block) => block.parent_root(),
} }
} }
fn state_root(&self) -> Hash256 { fn state_root(&self) -> Hash256 {
match self { match self {
BlockWrapper::Block(block) => block.state_root(), BlockWrapper::Available(block) => block.block.state_root(),
BlockWrapper::BlockAndBlobs(block, _) => block.state_root(), BlockWrapper::AvailabilityPending(block) => block.state_root(),
} }
} }
fn signed_block_header(&self) -> SignedBeaconBlockHeader { fn signed_block_header(&self) -> SignedBeaconBlockHeader {
match &self { match &self {
BlockWrapper::Block(block) => block.signed_block_header(), BlockWrapper::Available(block) => block.block.signed_block_header(),
BlockWrapper::BlockAndBlobs(block, _) => block.signed_block_header(), BlockWrapper::AvailabilityPending(block) => block.signed_block_header(),
} }
} }
fn message(&self) -> BeaconBlockRef<E> { fn message(&self) -> BeaconBlockRef<E> {
match &self { match &self {
BlockWrapper::Block(block) => block.message(), BlockWrapper::Available(block) => block.block.message(),
BlockWrapper::BlockAndBlobs(block, _) => block.message(), BlockWrapper::AvailabilityPending(block) => block.message(),
} }
} }
fn as_block(&self) -> &SignedBeaconBlock<E> { fn as_block(&self) -> &SignedBeaconBlock<E> {
match &self { match &self {
BlockWrapper::Block(block) => &block, BlockWrapper::Available(block) => &block.block,
BlockWrapper::BlockAndBlobs(block, _) => &block, BlockWrapper::AvailabilityPending(block) => &block,
} }
} }
fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> { fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
match &self { match &self {
BlockWrapper::Block(block) => block.clone(), BlockWrapper::Available(block) => block.block.clone(),
BlockWrapper::BlockAndBlobs(block, _) => block.clone(), BlockWrapper::AvailabilityPending(block) => block.clone(),
} }
} }
fn canonical_root(&self) -> Hash256 { fn canonical_root(&self) -> Hash256 {
match &self { match &self {
BlockWrapper::Block(block) => block.canonical_root(), BlockWrapper::Available(block) => block.block.canonical_root(),
BlockWrapper::BlockAndBlobs(block, _) => block.canonical_root(), BlockWrapper::AvailabilityPending(block) => block.canonical_root(),
}
}
}
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. This makes no
/// claims about data availability and should not be used in consensus. This struct is useful in
/// networking when we want to send blocks around without consensus checks.
#[derive(Clone, Debug, Derivative)]
#[derivative(PartialEq, Hash(bound = "E: EthSpec"))]
pub enum BlockWrapper<E: EthSpec> {
Block(Arc<SignedBeaconBlock<E>>),
BlockAndBlobs(Arc<SignedBeaconBlock<E>>, Arc<BlobsSidecar<E>>),
}
impl<E: EthSpec> BlockWrapper<E> {
pub fn new(
block: Arc<SignedBeaconBlock<E>>,
blobs_sidecar: Option<Arc<BlobsSidecar<E>>>,
) -> Self {
if let Some(blobs_sidecar) = blobs_sidecar {
BlockWrapper::BlockAndBlobs(block, blobs_sidecar)
} else {
BlockWrapper::Block(block)
} }
} }
} }
impl<E: EthSpec> From<SignedBeaconBlock<E>> for BlockWrapper<E> { impl<E: EthSpec> From<SignedBeaconBlock<E>> for BlockWrapper<E> {
fn from(block: SignedBeaconBlock<E>) -> Self { fn from(block: SignedBeaconBlock<E>) -> Self {
BlockWrapper::Block(Arc::new(block)) BlockWrapper::AvailabilityPending(Arc::new(block))
} }
} }
impl<E: EthSpec> From<Arc<SignedBeaconBlock<E>>> for BlockWrapper<E> { impl<E: EthSpec> From<Arc<SignedBeaconBlock<E>>> for BlockWrapper<E> {
fn from(block: Arc<SignedBeaconBlock<E>>) -> Self { fn from(block: Arc<SignedBeaconBlock<E>>) -> Self {
BlockWrapper::Block(block) BlockWrapper::AvailabilityPending(block)
}
}
impl<E: EthSpec> From<AvailableBlock<E>> for BlockWrapper<E> {
fn from(block: AvailableBlock<E>) -> Self {
BlockWrapper::Available(block)
} }
} }

View File

@@ -48,9 +48,7 @@
// returned alongside. // returned alongside.
#![allow(clippy::result_large_err)] #![allow(clippy::result_large_err)]
use crate::blob_verification::{ use crate::blob_verification::{AsBlock, AvailableBlock, BlobError, BlockWrapper};
AsBlock, AvailableBlock, BlobError, BlockWrapper, IntoAvailableBlock, IntoBlockWrapper,
};
use crate::eth1_finalization_cache::Eth1FinalizationData; use crate::eth1_finalization_cache::Eth1FinalizationData;
use crate::execution_payload::{ use crate::execution_payload::{
is_optimistic_candidate_block, validate_execution_payload_for_gossip, validate_merge_block, is_optimistic_candidate_block, validate_execution_payload_for_gossip, validate_merge_block,
@@ -66,7 +64,6 @@ use crate::{
}, },
metrics, BeaconChain, BeaconChainError, BeaconChainTypes, metrics, BeaconChain, BeaconChainError, BeaconChainTypes,
}; };
use derivative::Derivative;
use eth2::types::EventKind; use eth2::types::EventKind;
use execution_layer::PayloadStatus; use execution_layer::PayloadStatus;
use fork_choice::{AttestationFromBlock, PayloadVerificationStatus}; use fork_choice::{AttestationFromBlock, PayloadVerificationStatus};
@@ -595,13 +592,12 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
signature_verifier.include_all_signatures(block.as_block(), &mut consensus_context)?; signature_verifier.include_all_signatures(block.as_block(), &mut consensus_context)?;
//FIXME(sean) batch kzg verification //FIXME(sean) batch kzg verification
let available_block = block.clone().into_available_block(*block_root, chain)?;
consensus_context = consensus_context.set_kzg_commitments_consistent(true); consensus_context = consensus_context.set_kzg_commitments_consistent(true);
// Save the block and its consensus context. The context will have had its proposer index // Save the block and its consensus context. The context will have had its proposer index
// and attesting indices filled in, which can be used to accelerate later block processing. // and attesting indices filled in, which can be used to accelerate later block processing.
signature_verified_blocks.push(SignatureVerifiedBlock { signature_verified_blocks.push(SignatureVerifiedBlock {
block: available_block, block: block.clone(),
block_root: *block_root, block_root: *block_root,
parent: None, parent: None,
consensus_context, consensus_context,
@@ -623,10 +619,9 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
/// A wrapper around a `SignedBeaconBlock` that indicates it has been approved for re-gossiping on /// A wrapper around a `SignedBeaconBlock` that indicates it has been approved for re-gossiping on
/// the p2p network. /// the p2p network.
#[derive(Derivative)] #[derive(Debug)]
#[derivative(Debug(bound = "T: BeaconChainTypes"))]
pub struct GossipVerifiedBlock<T: BeaconChainTypes> { pub struct GossipVerifiedBlock<T: BeaconChainTypes> {
pub block: Arc<SignedBeaconBlock<T::EthSpec>>, pub block: BlockWrapper<T::EthSpec>,
pub block_root: Hash256, pub block_root: Hash256,
parent: Option<PreProcessingSnapshot<T::EthSpec>>, parent: Option<PreProcessingSnapshot<T::EthSpec>>,
consensus_context: ConsensusContext<T::EthSpec>, consensus_context: ConsensusContext<T::EthSpec>,
@@ -635,7 +630,7 @@ pub struct GossipVerifiedBlock<T: BeaconChainTypes> {
/// A wrapper around a `SignedBeaconBlock` that indicates that all signatures (except the deposit /// A wrapper around a `SignedBeaconBlock` that indicates that all signatures (except the deposit
/// signatures) have been verified. /// signatures) have been verified.
pub struct SignatureVerifiedBlock<T: BeaconChainTypes> { pub struct SignatureVerifiedBlock<T: BeaconChainTypes> {
block: Arc<SignedBeaconBlock<T::EthSpec>>, block: BlockWrapper<T::EthSpec>,
block_root: Hash256, block_root: Hash256,
parent: Option<PreProcessingSnapshot<T::EthSpec>>, parent: Option<PreProcessingSnapshot<T::EthSpec>>,
consensus_context: ConsensusContext<T::EthSpec>, consensus_context: ConsensusContext<T::EthSpec>,
@@ -658,7 +653,7 @@ type PayloadVerificationHandle<E> =
/// due to finality or some other event. A `ExecutionPendingBlock` should be imported into the /// due to finality or some other event. A `ExecutionPendingBlock` should be imported into the
/// `BeaconChain` immediately after it is instantiated. /// `BeaconChain` immediately after it is instantiated.
pub struct ExecutionPendingBlock<T: BeaconChainTypes> { pub struct ExecutionPendingBlock<T: BeaconChainTypes> {
pub block: Arc<SignedBeaconBlock<T::EthSpec>>, pub block: BlockWrapper<T::EthSpec>,
pub block_root: Hash256, pub block_root: Hash256,
pub state: BeaconState<T::EthSpec>, pub state: BeaconState<T::EthSpec>,
pub parent_block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>, pub parent_block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>,
@@ -669,7 +664,7 @@ pub struct ExecutionPendingBlock<T: BeaconChainTypes> {
} }
pub struct ExecutedBlock<T: BeaconChainTypes> { pub struct ExecutedBlock<T: BeaconChainTypes> {
pub block: Arc<SignedBeaconBlock<T::EthSpec>>, pub block: BlockWrapper<T::EthSpec>,
pub block_root: Hash256, pub block_root: Hash256,
pub state: BeaconState<T::EthSpec>, pub state: BeaconState<T::EthSpec>,
pub parent_block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>, pub parent_block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>,
@@ -930,13 +925,13 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
validate_execution_payload_for_gossip(&parent_block, block.message(), chain)?; validate_execution_payload_for_gossip(&parent_block, block.message(), chain)?;
// Having checked the proposer index and the block root we can cache them. // Having checked the proposer index and the block root we can cache them.
let consensus_context = ConsensusContext::new(available_block.slot()) let consensus_context = ConsensusContext::new(block.slot())
.set_current_block_root(block_root) .set_current_block_root(block_root)
.set_proposer_index(block.as_block().message().proposer_index()) .set_proposer_index(block.as_block().message().proposer_index())
.set_kzg_commitments_consistent(true); .set_kzg_commitments_consistent(true);
Ok(Self { Ok(Self {
block: available_block, block: block,
block_root, block_root,
parent, parent,
consensus_context, consensus_context,
@@ -966,7 +961,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for GossipVerifiedBlock<T
} }
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> { fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
self.block.as_ref() self.block.as_block()
} }
} }
@@ -980,6 +975,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
block_root: Hash256, block_root: Hash256,
chain: &BeaconChain<T>, chain: &BeaconChain<T>,
) -> Result<Self, BlockError<T::EthSpec>> { ) -> Result<Self, BlockError<T::EthSpec>> {
let block = BlockWrapper::from(block);
// Ensure the block is the correct structure for the fork at `block.slot()`. // Ensure the block is the correct structure for the fork at `block.slot()`.
block block
.as_block() .as_block()
@@ -1118,7 +1114,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
} }
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> { fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
self.block.as_ref() self.block.as_block()
} }
} }
@@ -1136,11 +1132,8 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?; .map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
let header = self.signed_block_header(); let header = self.signed_block_header();
let available_block = BlockWrapper::from(self)
.into_available_block(block_root, chain)
.map_err(|e| BlockSlashInfo::from_early_error(header, BlockError::BlobValidation(e)))?;
SignatureVerifiedBlock::check_slashable(available_block, block_root, chain)? SignatureVerifiedBlock::check_slashable(self, block_root, chain)?
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer) .into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
} }
@@ -1149,6 +1142,42 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
} }
} }
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for BlockWrapper<T::EthSpec> {
fn into_execution_pending_block_slashable(
self,
block_root: Hash256,
chain: &Arc<BeaconChain<T>>,
notify_execution_layer: NotifyExecutionLayer,
) -> Result<
ExecutionPendingBlock<T>,
BlockSlashInfo<BlockError<<T as BeaconChainTypes>::EthSpec>>,
> {
match self {
BlockWrapper::AvailabilityPending(block) => block
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer),
BlockWrapper::Available(AvailableBlock { block, blobs }) => {
let execution_pending_block = block.into_execution_pending_block_slashable(
block_root,
chain,
notify_execution_layer,
)?;
let block = execution_pending_block.block.block_cloned();
let available_execution_pending_block =
BlockWrapper::Available(AvailableBlock { block, blobs });
std::mem::replace(
&mut execution_pending_block.block,
available_execution_pending_block,
);
Ok(execution_pending_block)
}
}
}
fn block(&self) -> &SignedBeaconBlock<<T as BeaconChainTypes>::EthSpec> {
self.as_block()
}
}
impl<T: BeaconChainTypes> ExecutionPendingBlock<T> { impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
/// Instantiates `Self`, a wrapper that indicates that the given `block` is fully valid. See /// Instantiates `Self`, a wrapper that indicates that the given `block` is fully valid. See
/// the struct-level documentation for more information. /// the struct-level documentation for more information.
@@ -1158,7 +1187,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
/// ///
/// Returns an error if the block is invalid, or if the block was unable to be verified. /// Returns an error if the block is invalid, or if the block was unable to be verified.
pub fn from_signature_verified_components( pub fn from_signature_verified_components(
block: Arc<SignedBeaconBlock<T::EthSpec>>, block: BlockWrapper<T::EthSpec>,
block_root: Hash256, block_root: Hash256,
parent: PreProcessingSnapshot<T::EthSpec>, parent: PreProcessingSnapshot<T::EthSpec>,
mut consensus_context: ConsensusContext<T::EthSpec>, mut consensus_context: ConsensusContext<T::EthSpec>,
@@ -1188,7 +1217,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
// because it will revert finalization. Note that the finalized block is stored in fork // 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 // choice, so we will not reject any child of the finalized block (this is relevant during
// genesis). // genesis).
return Err(BlockError::ParentUnknown(block.into_block_wrapper())); return Err(BlockError::ParentUnknown(block));
} }
// Reject any block that exceeds our limit on skipped slots. // Reject any block that exceeds our limit on skipped slots.
@@ -1623,14 +1652,11 @@ fn check_block_against_finalized_slot<T: BeaconChainTypes>(
/// ## Warning /// ## Warning
/// ///
/// Taking a lock on the `chain.canonical_head.fork_choice` might cause a deadlock here. /// Taking a lock on the `chain.canonical_head.fork_choice` might cause a deadlock here.
pub fn check_block_is_finalized_checkpoint_or_descendant< pub fn check_block_is_finalized_checkpoint_or_descendant<T: BeaconChainTypes>(
T: BeaconChainTypes,
B: IntoBlockWrapper<T::EthSpec>,
>(
chain: &BeaconChain<T>, chain: &BeaconChain<T>,
fork_choice: &BeaconForkChoice<T>, fork_choice: &BeaconForkChoice<T>,
block: B, block: BlockWrapper<T::EthSpec>,
) -> Result<B, BlockError<T::EthSpec>> { ) -> Result<BlockWrapper<T::EthSpec>, BlockError<T::EthSpec>> {
if fork_choice.is_finalized_checkpoint_or_descendant(block.parent_root()) { if fork_choice.is_finalized_checkpoint_or_descendant(block.parent_root()) {
Ok(block) Ok(block)
} else { } else {
@@ -1651,7 +1677,7 @@ pub fn check_block_is_finalized_checkpoint_or_descendant<
block_parent_root: block.parent_root(), block_parent_root: block.parent_root(),
}) })
} else { } else {
Err(BlockError::ParentUnknown(block.into_block_wrapper())) Err(BlockError::ParentUnknown(block))
} }
} }
} }
@@ -1741,11 +1767,11 @@ fn verify_parent_block_is_known<T: BeaconChainTypes>(
/// Returns `Err(BlockError::ParentUnknown)` if the parent is not found, or if an error occurs /// Returns `Err(BlockError::ParentUnknown)` if the parent is not found, or if an error occurs
/// whilst attempting the operation. /// whilst attempting the operation.
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
fn load_parent<T: BeaconChainTypes, B: IntoBlockWrapper<T::EthSpec>>( fn load_parent<T: BeaconChainTypes>(
block_root: Hash256, block_root: Hash256,
block: B, block: BlockWrapper<T::EthSpec>,
chain: &BeaconChain<T>, chain: &BeaconChain<T>,
) -> Result<(PreProcessingSnapshot<T::EthSpec>, B), BlockError<T::EthSpec>> { ) -> Result<(PreProcessingSnapshot<T::EthSpec>, BlockWrapper<T::EthSpec>), BlockError<T::EthSpec>> {
let spec = &chain.spec; let spec = &chain.spec;
// Reject any block if its parent is not known to fork choice. // Reject any block if its parent is not known to fork choice.
@@ -1763,7 +1789,7 @@ fn load_parent<T: BeaconChainTypes, B: IntoBlockWrapper<T::EthSpec>>(
.fork_choice_read_lock() .fork_choice_read_lock()
.contains_block(&block.parent_root()) .contains_block(&block.parent_root())
{ {
return Err(BlockError::ParentUnknown(block.into_block_wrapper())); return Err(BlockError::ParentUnknown(block));
} }
let block_delay = chain let block_delay = chain

View File

@@ -1,4 +1,7 @@
use crate::{test_utils::TestRandom, BlobSidecar, EthSpec, Signature}; use crate::{
test_utils::TestRandom, BlobSidecar, ChainSpec, EthSpec, Fork, Hash256, PublicKey, Signature,
SignedRoot,
};
use derivative::Derivative; use derivative::Derivative;
use serde_derive::{Deserialize, Serialize}; use serde_derive::{Deserialize, Serialize};
use ssz_derive::{Decode, Encode}; use ssz_derive::{Decode, Encode};
@@ -25,3 +28,19 @@ pub struct SignedBlobSidecar<T: EthSpec> {
pub message: BlobSidecar<T>, pub message: BlobSidecar<T>,
pub signature: Signature, pub signature: Signature,
} }
impl<T: EthSpec> SignedRoot for SignedBlobSidecar<T> {}
impl<T: EthSpec> SignedBlobSidecar<T> {
pub fn verify_signature(
&self,
_object_root_opt: Option<Hash256>,
_pubkey: &PublicKey,
_fork: &Fork,
_genesis_validators_root: Hash256,
_spec: &ChainSpec,
) -> bool {
// TODO (pawan): fill up logic
unimplemented!()
}
}