add new traits
This commit is contained in:
parent
3cb8fb7973
commit
eb9feed784
@ -7,7 +7,7 @@ use crate::attester_cache::{AttesterCache, AttesterCacheKey};
|
|||||||
use crate::beacon_proposer_cache::compute_proposer_duties_from_head;
|
use crate::beacon_proposer_cache::compute_proposer_duties_from_head;
|
||||||
use crate::beacon_proposer_cache::BeaconProposerCache;
|
use crate::beacon_proposer_cache::BeaconProposerCache;
|
||||||
use crate::blob_cache::BlobCache;
|
use crate::blob_cache::BlobCache;
|
||||||
use crate::blob_verification::{AvailableBlock, BlockWrapper, IntoAvailableBlock};
|
use crate::blob_verification::{AsBlock, AvailableBlock, BlockWrapper, IntoAvailableBlock};
|
||||||
use crate::block_times_cache::BlockTimesCache;
|
use crate::block_times_cache::BlockTimesCache;
|
||||||
use crate::block_verification::{
|
use crate::block_verification::{
|
||||||
check_block_is_finalized_descendant, check_block_relevancy, get_block_root,
|
check_block_is_finalized_descendant, check_block_relevancy, get_block_root,
|
||||||
@ -2367,22 +2367,19 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
let children = chain_segment
|
let children = chain_segment
|
||||||
.iter()
|
.iter()
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.map(|block| (block.block().parent_root(), block.slot()))
|
.map(|block| (block.parent_root(), block.slot()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
for (i, block) in chain_segment.into_iter().enumerate() {
|
for (i, block) in chain_segment.into_iter().enumerate() {
|
||||||
// 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()`.
|
||||||
if let Err(e) = block.block().fork_name(&self.spec) {
|
if let Err(e) = block.as_block().fork_name(&self.spec) {
|
||||||
return Err(ChainSegmentResult::Failed {
|
return Err(ChainSegmentResult::Failed {
|
||||||
imported_blocks,
|
imported_blocks,
|
||||||
error: BlockError::InconsistentFork(e),
|
error: BlockError::InconsistentFork(e),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let block_root = get_block_root(block.block());
|
let block_root = get_block_root(block.as_block());
|
||||||
|
|
||||||
//FIXME(sean)
|
|
||||||
let available_block = block.into_available_block(block_root);
|
|
||||||
|
|
||||||
if let Some((child_parent_root, child_slot)) = children.get(i) {
|
if let Some((child_parent_root, child_slot)) = children.get(i) {
|
||||||
// If this block has a child in this chain segment, ensure that its parent root matches
|
// If this block has a child in this chain segment, ensure that its parent root matches
|
||||||
@ -2406,7 +2403,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match check_block_relevancy(block.block(), block_root, self) {
|
match check_block_relevancy(block.as_block(), block_root, self) {
|
||||||
// If the block is relevant, add it to the filtered chain segment.
|
// If the block is relevant, add it to the filtered chain segment.
|
||||||
Ok(_) => filtered_chain_segment.push((block_root, block)),
|
Ok(_) => filtered_chain_segment.push((block_root, block)),
|
||||||
// If the block is already known, simply ignore this block.
|
// If the block is already known, simply ignore this block.
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
use derivative::Derivative;
|
use derivative::Derivative;
|
||||||
use slasher::test_utils::block;
|
use slasher::test_utils::{block, E};
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::beacon_chain::{BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY};
|
use crate::beacon_chain::{BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY};
|
||||||
|
use crate::block_verification::IntoExecutionPendingBlock;
|
||||||
use crate::BlockError::BlobValidation;
|
use crate::BlockError::BlobValidation;
|
||||||
use crate::{kzg_utils, BeaconChainError, BlockError};
|
use crate::{kzg_utils, BeaconChainError, BlockError};
|
||||||
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::signed_beacon_block::BlobReconstructionError;
|
use types::signed_beacon_block::BlobReconstructionError;
|
||||||
use types::{BeaconStateError, BlobsSidecar, Epoch, EthSpec, Hash256, KzgCommitment, SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, Slot, Transactions};
|
use types::{
|
||||||
|
BeaconBlockRef, BeaconStateError, BlobsSidecar, Epoch, EthSpec, Hash256, KzgCommitment,
|
||||||
|
SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, SignedBeaconBlockHeader, Slot,
|
||||||
|
Transactions,
|
||||||
|
};
|
||||||
|
use types::ExecPayload;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BlobError {
|
pub enum BlobError {
|
||||||
@ -33,15 +39,6 @@ pub enum BlobError {
|
|||||||
block_slot: Slot,
|
block_slot: Slot,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The blob sidecar contains a KZGCommitment that is not a valid G1 point on
|
|
||||||
/// the bls curve.
|
|
||||||
///
|
|
||||||
/// ## Peer scoring
|
|
||||||
///
|
|
||||||
/// The peer has sent an invalid message.
|
|
||||||
//FIXME(sean3)
|
|
||||||
InvalidKZGCommitment,
|
|
||||||
|
|
||||||
/// No kzg ccommitment associated with blob sidecar.
|
/// No kzg ccommitment associated with blob sidecar.
|
||||||
KzgCommitmentMissing,
|
KzgCommitmentMissing,
|
||||||
|
|
||||||
@ -109,7 +106,7 @@ pub fn validate_blob_for_gossip<T: BeaconChainTypes>(
|
|||||||
if blob_slot != block.slot() {
|
if blob_slot != block.slot() {
|
||||||
return Err(BlobError::SlotMismatch {
|
return Err(BlobError::SlotMismatch {
|
||||||
blob_slot,
|
blob_slot,
|
||||||
block_slot,
|
block_slot: block.slot(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,16 +153,16 @@ fn verify_data_availability<T: BeaconChainTypes>(
|
|||||||
/// claims about data availability and should not be used in consensus. This struct is useful in
|
/// 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 adding consensus logic.
|
/// networking when we want to send blocks around without adding consensus logic.
|
||||||
#[derive(Clone, Debug, Derivative)]
|
#[derive(Clone, Debug, Derivative)]
|
||||||
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
|
#[derivative(PartialEq, Hash(bound = "E: EthSpec"))]
|
||||||
pub enum BlockWrapper<T: EthSpec> {
|
pub enum BlockWrapper<E: EthSpec> {
|
||||||
Block(Arc<SignedBeaconBlock<T>>),
|
Block(Arc<SignedBeaconBlock<E>>),
|
||||||
BlockAndBlob(Arc<SignedBeaconBlock<T>>, Arc<BlobsSidecar<T>>),
|
BlockAndBlob(Arc<SignedBeaconBlock<E>>, Arc<BlobsSidecar<E>>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> BlockWrapper<T> {
|
impl<E: EthSpec> BlockWrapper<E> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
block: Arc<SignedBeaconBlock<T>>,
|
block: Arc<SignedBeaconBlock<E>>,
|
||||||
blobs_sidecar: Option<Arc<BlobsSidecar<T>>>,
|
blobs_sidecar: Option<Arc<BlobsSidecar<E>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
if let Some(blobs_sidecar) = blobs_sidecar {
|
if let Some(blobs_sidecar) = blobs_sidecar {
|
||||||
BlockWrapper::BlockAndBlob(block, blobs_sidecar)
|
BlockWrapper::BlockAndBlob(block, blobs_sidecar)
|
||||||
@ -175,18 +172,24 @@ impl<T: EthSpec> BlockWrapper<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<SignedBeaconBlock<T>> for BlockWrapper<T> {
|
impl<E: EthSpec> From<SignedBeaconBlock<E>> for BlockWrapper<E> {
|
||||||
fn from(block: SignedBeaconBlock<T>) -> Self {
|
fn from(block: SignedBeaconBlock<E>) -> Self {
|
||||||
BlockWrapper::Block(Arc::new(block))
|
BlockWrapper::Block(Arc::new(block))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> From<Arc<SignedBeaconBlock<T>>> for BlockWrapper<T> {
|
impl<E: EthSpec> From<Arc<SignedBeaconBlock<E>>> for BlockWrapper<E> {
|
||||||
fn from(block: Arc<SignedBeaconBlock<T>>) -> Self {
|
fn from(block: Arc<SignedBeaconBlock<E>>) -> Self {
|
||||||
BlockWrapper::Block(block)
|
BlockWrapper::Block(block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub enum DataAvailabilityCheckRequired {
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
}
|
||||||
|
|
||||||
pub trait IntoAvailableBlock<T: BeaconChainTypes> {
|
pub trait IntoAvailableBlock<T: BeaconChainTypes> {
|
||||||
fn into_available_block(
|
fn into_available_block(
|
||||||
self,
|
self,
|
||||||
@ -195,12 +198,6 @@ pub trait IntoAvailableBlock<T: BeaconChainTypes> {
|
|||||||
) -> Result<AvailableBlock<T::EthSpec>, BlobError>;
|
) -> Result<AvailableBlock<T::EthSpec>, BlobError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub enum DataAvailabilityCheckRequired {
|
|
||||||
Yes,
|
|
||||||
No
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: BeaconChainTypes> IntoAvailableBlock<T> for BlockWrapper<T::EthSpec> {
|
impl<T: BeaconChainTypes> IntoAvailableBlock<T> for BlockWrapper<T::EthSpec> {
|
||||||
fn into_available_block(
|
fn into_available_block(
|
||||||
self,
|
self,
|
||||||
@ -208,8 +205,9 @@ impl<T: BeaconChainTypes> IntoAvailableBlock<T> for BlockWrapper<T::EthSpec> {
|
|||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<AvailableBlock<T::EthSpec>, BlobError> {
|
) -> Result<AvailableBlock<T::EthSpec>, BlobError> {
|
||||||
let data_availability_boundary = chain.data_availability_boundary();
|
let data_availability_boundary = chain.data_availability_boundary();
|
||||||
let da_check_required = data_availability_boundary.map_or(DataAvailabilityCheckRequired::No, |boundary|{
|
let da_check_required =
|
||||||
if self.epoch() >= boundary {
|
data_availability_boundary.map_or(DataAvailabilityCheckRequired::No, |boundary| {
|
||||||
|
if self.slot().epoch(T::EthSpec::slots_per_epoch()) >= boundary {
|
||||||
DataAvailabilityCheckRequired::Yes
|
DataAvailabilityCheckRequired::Yes
|
||||||
} else {
|
} else {
|
||||||
DataAvailabilityCheckRequired::No
|
DataAvailabilityCheckRequired::No
|
||||||
@ -251,20 +249,20 @@ impl<T: BeaconChainTypes> IntoAvailableBlock<T> for BlockWrapper<T::EthSpec> {
|
|||||||
/// wraps the `BlockWrapperInner` to ensure blobs cannot be accessed via an enum match. This would
|
/// wraps the `BlockWrapperInner` to ensure blobs cannot be accessed via an enum match. This would
|
||||||
/// circumvent empty blob reconstruction when accessing blobs.
|
/// circumvent empty blob reconstruction when accessing blobs.
|
||||||
#[derive(Clone, Debug, Derivative)]
|
#[derive(Clone, Debug, Derivative)]
|
||||||
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
|
#[derivative(PartialEq, Hash(bound = "E: EthSpec"))]
|
||||||
pub struct AvailableBlock<T: EthSpec>(AvailableBlockInner<T>);
|
pub struct AvailableBlock<E: EthSpec>(AvailableBlockInner<E>);
|
||||||
|
|
||||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`].
|
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`].
|
||||||
#[derive(Clone, Debug, Derivative)]
|
#[derive(Clone, Debug, Derivative)]
|
||||||
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
|
#[derivative(PartialEq, Hash(bound = "E: EthSpec"))]
|
||||||
pub enum AvailableBlockInner<T: EthSpec> {
|
pub enum AvailableBlockInner<E: EthSpec> {
|
||||||
Block(Arc<SignedBeaconBlock<T>>),
|
Block(Arc<SignedBeaconBlock<E>>),
|
||||||
BlockAndBlob(SignedBeaconBlockAndBlobsSidecar<T>),
|
BlockAndBlob(SignedBeaconBlockAndBlobsSidecar<E>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: EthSpec> AvailableBlock<T> {
|
impl<E: EthSpec> AvailableBlock<E> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
beacon_block: Arc<SignedBeaconBlock<T>>,
|
beacon_block: Arc<SignedBeaconBlock<E>>,
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
da_check_required: DataAvailabilityCheckRequired,
|
da_check_required: DataAvailabilityCheckRequired,
|
||||||
) -> Result<Self, BlobError> {
|
) -> Result<Self, BlobError> {
|
||||||
@ -288,7 +286,7 @@ impl<T: EthSpec> AvailableBlock<T> {
|
|||||||
beacon_block,
|
beacon_block,
|
||||||
blobs_sidecar,
|
blobs_sidecar,
|
||||||
},
|
},
|
||||||
)))
|
)));
|
||||||
}
|
}
|
||||||
DataAvailabilityCheckRequired::No => {
|
DataAvailabilityCheckRequired::No => {
|
||||||
Ok(AvailableBlock(AvailableBlockInner::Block(beacon_block)))
|
Ok(AvailableBlock(AvailableBlockInner::Block(beacon_block)))
|
||||||
@ -301,9 +299,9 @@ impl<T: EthSpec> AvailableBlock<T> {
|
|||||||
/// This function is private because an `AvailableBlock` should be
|
/// This function is private because an `AvailableBlock` should be
|
||||||
/// constructed via the `into_available_block` method.
|
/// constructed via the `into_available_block` method.
|
||||||
fn new_with_blobs(
|
fn new_with_blobs(
|
||||||
beacon_block: Arc<SignedBeaconBlock<T>>,
|
beacon_block: Arc<SignedBeaconBlock<E>>,
|
||||||
blobs_sidecar: Arc<BlobsSidecar<T>>,
|
blobs_sidecar: Arc<BlobsSidecar<E>>,
|
||||||
da_check_required: DataAvailabilityCheckRequired
|
da_check_required: DataAvailabilityCheckRequired,
|
||||||
) -> Result<Self, BlobError> {
|
) -> Result<Self, BlobError> {
|
||||||
match beacon_block.as_ref() {
|
match beacon_block.as_ref() {
|
||||||
// This method shouldn't be called with a pre-Eip4844 block.
|
// This method shouldn't be called with a pre-Eip4844 block.
|
||||||
@ -313,42 +311,23 @@ impl<T: EthSpec> AvailableBlock<T> {
|
|||||||
| SignedBeaconBlock::Merge(_) => Err(BlobError::InconsistentFork),
|
| SignedBeaconBlock::Merge(_) => Err(BlobError::InconsistentFork),
|
||||||
SignedBeaconBlock::Eip4844(_) => {
|
SignedBeaconBlock::Eip4844(_) => {
|
||||||
match da_check_required {
|
match da_check_required {
|
||||||
DataAvailabilityCheckRequired::Yes => {
|
DataAvailabilityCheckRequired::Yes => Ok(AvailableBlock(
|
||||||
Ok(AvailableBlock(AvailableBlockInner::BlockAndBlob(
|
AvailableBlockInner::BlockAndBlob(SignedBeaconBlockAndBlobsSidecar {
|
||||||
SignedBeaconBlockAndBlobsSidecar {
|
|
||||||
beacon_block,
|
beacon_block,
|
||||||
blobs_sidecar,
|
blobs_sidecar,
|
||||||
},
|
}),
|
||||||
)))
|
)),
|
||||||
}
|
|
||||||
DataAvailabilityCheckRequired::No => {
|
DataAvailabilityCheckRequired::No => {
|
||||||
// Blobs were not verified so we drop them, we'll instead just pass around
|
// Blobs were not verified so we drop them, we'll instead just pass around
|
||||||
// an available `Eip4844` block without blobs.
|
// an available `Eip4844` block without blobs.
|
||||||
Ok(AvailableBlock(AvailableBlockInner::Block(beacon_block)))
|
Ok(AvailableBlock(AvailableBlockInner::Block(beacon_block)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn slot(&self) -> Slot {
|
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
|
||||||
match &self.0 {
|
|
||||||
AvailableBlockInner::Block(block) => block.slot(),
|
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
|
||||||
block_sidecar_pair.beacon_block.slot()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn block(&self) -> &SignedBeaconBlock<T> {
|
|
||||||
match &self.0 {
|
|
||||||
AvailableBlockInner::Block(block) => &block,
|
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
|
||||||
&block_sidecar_pair.beacon_block
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<T>> {
|
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
AvailableBlockInner::Block(block) => block.clone(),
|
AvailableBlockInner::Block(block) => block.clone(),
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
@ -357,7 +336,7 @@ impl<T: EthSpec> AvailableBlock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blobs(&self) -> Option<Arc<BlobsSidecar<T>>> {
|
pub fn blobs(&self) -> Option<Arc<BlobsSidecar<E>>> {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
AvailableBlockInner::Block(_) => None,
|
AvailableBlockInner::Block(_) => None,
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
@ -366,20 +345,7 @@ impl<T: EthSpec> AvailableBlock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn message(&self) -> crate::BeaconBlockRef<T> {
|
pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<E>>, Option<Arc<BlobsSidecar<E>>>) {
|
||||||
match &self.0 {
|
|
||||||
AvailableBlockInner::Block(block) => block.message(),
|
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
|
||||||
block_sidecar_pair.beacon_block.message()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parent_root(&self) -> Hash256 {
|
|
||||||
self.block().parent_root()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<T>>, Option<Arc<BlobsSidecar<T>>>) {
|
|
||||||
match self.0 {
|
match self.0 {
|
||||||
AvailableBlockInner::Block(block) => (block, None),
|
AvailableBlockInner::Block(block) => (block, None),
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
@ -392,3 +358,166 @@ impl<T: EthSpec> AvailableBlock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IntoBlockWrapper<E: EthSpec>: AsBlock<E> {
|
||||||
|
fn into_block_wrapper(self) -> BlockWrapper<E>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> IntoBlockWrapper<E> for BlockWrapper<E> {
|
||||||
|
fn into_block_wrapper(self) -> BlockWrapper<E> {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> IntoBlockWrapper<E> for AvailableBlock<E> {
|
||||||
|
fn into_block_wrapper(self) -> BlockWrapper<E> {
|
||||||
|
let (block, blobs) = self.deconstruct();
|
||||||
|
if let Some(blobs) = blobs {
|
||||||
|
BlockWrapper::BlockAndBlob(block, blobs)
|
||||||
|
} else {
|
||||||
|
BlockWrapper::Block(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait AsBlock<E: EthSpec> {
|
||||||
|
fn slot(&self) -> Slot;
|
||||||
|
fn parent_root(&self) -> Hash256;
|
||||||
|
fn state_root(&self) -> Hash256;
|
||||||
|
fn signed_block_header(&self) -> SignedBeaconBlockHeader;
|
||||||
|
fn as_block(&self) -> &SignedBeaconBlock<E>;
|
||||||
|
fn message(&self) -> BeaconBlockRef<E>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> AsBlock<E> for BlockWrapper<E> {
|
||||||
|
fn slot(&self) -> Slot {
|
||||||
|
match self {
|
||||||
|
BlockWrapper::Block(block) => block.slot(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.slot(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn parent_root(&self) -> Hash256 {
|
||||||
|
match self {
|
||||||
|
BlockWrapper::Block(block) => block.parent_root(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.parent_root(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn state_root(&self) -> Hash256 {
|
||||||
|
match self {
|
||||||
|
BlockWrapper::Block(block) => block.state_root(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.state_root(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn signed_block_header(&self) -> SignedBeaconBlockHeader {
|
||||||
|
match &self {
|
||||||
|
BlockWrapper::Block(block) => block.signed_block_header(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.signed_block_header(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn message(&self) -> BeaconBlockRef<E> {
|
||||||
|
match &self {
|
||||||
|
BlockWrapper::Block(block) => block.message(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => {
|
||||||
|
block.message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn as_block(&self) -> &SignedBeaconBlock<E> {
|
||||||
|
match &self {
|
||||||
|
BlockWrapper::Block(block) => &block,
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => &block,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> AsBlock<E> for &BlockWrapper<E> {
|
||||||
|
fn slot(&self) -> Slot {
|
||||||
|
match self {
|
||||||
|
BlockWrapper::Block(block) => block.slot(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.slot(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn parent_root(&self) -> Hash256 {
|
||||||
|
match self {
|
||||||
|
BlockWrapper::Block(block) => block.parent_root(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.parent_root(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn state_root(&self) -> Hash256 {
|
||||||
|
match self {
|
||||||
|
BlockWrapper::Block(block) => block.state_root(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.state_root(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn signed_block_header(&self) -> SignedBeaconBlockHeader {
|
||||||
|
match &self {
|
||||||
|
BlockWrapper::Block(block) => block.signed_block_header(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => block.signed_block_header(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn message(&self) -> BeaconBlockRef<E> {
|
||||||
|
match &self {
|
||||||
|
BlockWrapper::Block(block) => block.message(),
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => {
|
||||||
|
block.message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn as_block(&self) -> &SignedBeaconBlock<E> {
|
||||||
|
match &self {
|
||||||
|
BlockWrapper::Block(block) => &block,
|
||||||
|
BlockWrapper::BlockAndBlob(block, _) => &block,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> AsBlock<E> for AvailableBlock<E> {
|
||||||
|
fn slot(&self) -> Slot {
|
||||||
|
match &self.0 {
|
||||||
|
AvailableBlockInner::Block(block) => block.slot(),
|
||||||
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
|
block_sidecar_pair.beacon_block.slot()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn parent_root(&self) -> Hash256 {
|
||||||
|
match &self.0 {
|
||||||
|
AvailableBlockInner::Block(block) => block.parent_root(),
|
||||||
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
|
block_sidecar_pair.beacon_block.parent_root()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn state_root(&self) -> Hash256 {
|
||||||
|
match &self.0 {
|
||||||
|
AvailableBlockInner::Block(block) => block.state_root(),
|
||||||
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
|
block_sidecar_pair.beacon_block.state_root()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn signed_block_header(&self) -> SignedBeaconBlockHeader {
|
||||||
|
match &self.0 {
|
||||||
|
AvailableBlockInner::Block(block) => block.signed_block_header(),
|
||||||
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
|
block_sidecar_pair.beacon_block.signed_block_header()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn message(&self) -> BeaconBlockRef<E> {
|
||||||
|
match &self.0 {
|
||||||
|
AvailableBlockInner::Block(block) => block.message(),
|
||||||
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
|
block_sidecar_pair.beacon_block.message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn as_block(&self) -> &SignedBeaconBlock<E> {
|
||||||
|
match &self.0 {
|
||||||
|
AvailableBlockInner::Block(block) => &block,
|
||||||
|
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
||||||
|
&block_sidecar_pair.beacon_block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -45,7 +45,10 @@
|
|||||||
//! END
|
//! END
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
use crate::blob_verification::{validate_blob_for_gossip, AvailableBlock, BlobError, BlockWrapper};
|
use crate::blob_verification::{
|
||||||
|
validate_blob_for_gossip, 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,
|
||||||
@ -87,6 +90,7 @@ use std::fs;
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use slasher::test_utils::{block, E};
|
||||||
use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp};
|
use store::{Error as DBError, HotStateSummary, KeyValueStore, StoreOp};
|
||||||
use task_executor::JoinHandle;
|
use task_executor::JoinHandle;
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
@ -310,6 +314,12 @@ pub enum BlockError<T: EthSpec> {
|
|||||||
BlobValidation(BlobError),
|
BlobValidation(BlobError),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl <T: EthSpec>From<BlobError> for BlockError<T> {
|
||||||
|
fn from(e: BlobError) -> Self {
|
||||||
|
Self::BlobValidation(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Returned when block validation failed due to some issue verifying
|
/// Returned when block validation failed due to some issue verifying
|
||||||
/// the execution payload.
|
/// the execution payload.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -591,12 +601,15 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
|
|||||||
let mut consensus_context =
|
let mut consensus_context =
|
||||||
ConsensusContext::new(block.slot()).set_current_block_root(*block_root);
|
ConsensusContext::new(block.slot()).set_current_block_root(*block_root);
|
||||||
|
|
||||||
signature_verifier.include_all_signatures(block.block(), &mut consensus_context)?;
|
//FIXME(sean) batch kzg verification
|
||||||
|
let available_block = block.into_available_block(*block_root, chain)?;
|
||||||
|
|
||||||
|
signature_verifier.include_all_signatures(available_block.as_block(), &mut consensus_context)?;
|
||||||
|
|
||||||
// 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: block.clone(),
|
block: available_block,
|
||||||
block_root: *block_root,
|
block_root: *block_root,
|
||||||
parent: None,
|
parent: None,
|
||||||
consensus_context,
|
consensus_context,
|
||||||
@ -677,8 +690,7 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
|
|||||||
.map(|execution_pending| {
|
.map(|execution_pending| {
|
||||||
// Supply valid block to slasher.
|
// Supply valid block to slasher.
|
||||||
if let Some(slasher) = chain.slasher.as_ref() {
|
if let Some(slasher) = chain.slasher.as_ref() {
|
||||||
slasher
|
slasher.accept_block_header(execution_pending.block.signed_block_header());
|
||||||
.accept_block_header(execution_pending.block.block().signed_block_header());
|
|
||||||
}
|
}
|
||||||
execution_pending
|
execution_pending
|
||||||
})
|
})
|
||||||
@ -709,7 +721,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
|||||||
// we assume it will be transformed into a fully verified block. We *do* need to supply
|
// we assume it will be transformed into a fully verified block. We *do* need to supply
|
||||||
// it to the slasher if an error occurs, because that's the end of this block's journey,
|
// it to the slasher if an error occurs, because that's the end of this block's journey,
|
||||||
// and it could be a repeat proposal (a likely cause for slashing!).
|
// and it could be a repeat proposal (a likely cause for slashing!).
|
||||||
let header = block.block().signed_block_header();
|
let header = block.signed_block_header();
|
||||||
Self::new_without_slasher_checks(block, chain).map_err(|e| {
|
Self::new_without_slasher_checks(block, chain).map_err(|e| {
|
||||||
process_block_slash_info(chain, BlockSlashInfo::from_early_error(header, e))
|
process_block_slash_info(chain, BlockSlashInfo::from_early_error(header, e))
|
||||||
})
|
})
|
||||||
@ -722,7 +734,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
|||||||
) -> Result<Self, BlockError<T::EthSpec>> {
|
) -> Result<Self, BlockError<T::EthSpec>> {
|
||||||
// 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
|
||||||
.block()
|
.as_block()
|
||||||
.fork_name(&chain.spec)
|
.fork_name(&chain.spec)
|
||||||
.map_err(BlockError::InconsistentFork)?;
|
.map_err(BlockError::InconsistentFork)?;
|
||||||
|
|
||||||
@ -738,7 +750,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let block_root = get_block_root(block.block());
|
let block_root = get_block_root(block.as_block());
|
||||||
|
|
||||||
// Disallow blocks that conflict with the anchor (weak subjectivity checkpoint), if any.
|
// Disallow blocks that conflict with the anchor (weak subjectivity checkpoint), if any.
|
||||||
check_block_against_anchor_slot(block.message(), chain)?;
|
check_block_against_anchor_slot(block.message(), chain)?;
|
||||||
@ -874,7 +886,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
|||||||
let pubkey = pubkey_cache
|
let pubkey = pubkey_cache
|
||||||
.get(block.message().proposer_index() as usize)
|
.get(block.message().proposer_index() as usize)
|
||||||
.ok_or_else(|| BlockError::UnknownValidator(block.message().proposer_index()))?;
|
.ok_or_else(|| BlockError::UnknownValidator(block.message().proposer_index()))?;
|
||||||
block.block().verify_signature(
|
block.as_block().verify_signature(
|
||||||
Some(block_root),
|
Some(block_root),
|
||||||
pubkey,
|
pubkey,
|
||||||
&fork,
|
&fork,
|
||||||
@ -914,15 +926,15 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
|||||||
// Validate the block's execution_payload (if any).
|
// Validate the block's execution_payload (if any).
|
||||||
validate_execution_payload_for_gossip(&parent_block, block.message(), chain)?;
|
validate_execution_payload_for_gossip(&parent_block, block.message(), chain)?;
|
||||||
|
|
||||||
let available_block = validate_blob_for_gossip(block)?;
|
let available_block = validate_blob_for_gossip(block, block_root, 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(block.slot())
|
let consensus_context = ConsensusContext::new(available_block.slot())
|
||||||
.set_current_block_root(block_root)
|
.set_current_block_root(block_root)
|
||||||
.set_proposer_index(block.message().proposer_index());
|
.set_proposer_index(available_block.as_block().message().proposer_index());
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
block,
|
block: available_block,
|
||||||
block_root,
|
block_root,
|
||||||
parent,
|
parent,
|
||||||
consensus_context,
|
consensus_context,
|
||||||
@ -952,7 +964,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for GossipVerifiedBlock<T
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
||||||
self.block.block()
|
self.block.as_block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -968,7 +980,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
) -> Result<Self, BlockError<T::EthSpec>> {
|
) -> Result<Self, BlockError<T::EthSpec>> {
|
||||||
// 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
|
||||||
.block()
|
.as_block()
|
||||||
.fork_name(&chain.spec)
|
.fork_name(&chain.spec)
|
||||||
.map_err(BlockError::InconsistentFork)?;
|
.map_err(BlockError::InconsistentFork)?;
|
||||||
|
|
||||||
@ -994,7 +1006,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
let mut consensus_context =
|
let mut consensus_context =
|
||||||
ConsensusContext::new(block.slot()).set_current_block_root(block_root);
|
ConsensusContext::new(block.slot()).set_current_block_root(block_root);
|
||||||
|
|
||||||
signature_verifier.include_all_signatures(block.block(), &mut consensus_context)?;
|
signature_verifier.include_all_signatures(block.as_block(), &mut consensus_context)?;
|
||||||
|
|
||||||
if signature_verifier.verify().is_ok() {
|
if signature_verifier.verify().is_ok() {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -1014,7 +1026,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||||
let header = block.block().signed_block_header();
|
let header = block.signed_block_header();
|
||||||
Self::new(block, block_root, chain).map_err(|e| BlockSlashInfo::from_early_error(header, e))
|
Self::new(block, block_root, chain).map_err(|e| BlockSlashInfo::from_early_error(header, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1027,7 +1039,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
let (mut parent, block) = if let Some(parent) = from.parent {
|
let (mut parent, block) = if let Some(parent) = from.parent {
|
||||||
(parent, from.block)
|
(parent, from.block)
|
||||||
} else {
|
} else {
|
||||||
load_parent(from.block_root, from.block.block(), chain)?
|
load_parent(from.block_root, from.block, chain)?
|
||||||
};
|
};
|
||||||
|
|
||||||
let state = cheap_state_advance_to_obtain_committees(
|
let state = cheap_state_advance_to_obtain_committees(
|
||||||
@ -1045,7 +1057,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
// signature.
|
// signature.
|
||||||
let mut consensus_context = from.consensus_context;
|
let mut consensus_context = from.consensus_context;
|
||||||
signature_verifier
|
signature_verifier
|
||||||
.include_all_signatures_except_proposal(block.block(), &mut consensus_context)?;
|
.include_all_signatures_except_proposal(block.as_block(), &mut consensus_context)?;
|
||||||
|
|
||||||
if signature_verifier.verify().is_ok() {
|
if signature_verifier.verify().is_ok() {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -1064,7 +1076,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
from: GossipVerifiedBlock<T>,
|
from: GossipVerifiedBlock<T>,
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||||
let header = from.block.block().signed_block_header();
|
let header = from.block.signed_block_header();
|
||||||
Self::from_gossip_verified_block(from, chain)
|
Self::from_gossip_verified_block(from, chain)
|
||||||
.map_err(|e| BlockSlashInfo::from_early_error(header, e))
|
.map_err(|e| BlockSlashInfo::from_early_error(header, e))
|
||||||
}
|
}
|
||||||
@ -1082,11 +1094,11 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
|
|||||||
chain: &Arc<BeaconChain<T>>,
|
chain: &Arc<BeaconChain<T>>,
|
||||||
notify_execution_layer: NotifyExecutionLayer,
|
notify_execution_layer: NotifyExecutionLayer,
|
||||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||||
let header = self.block.block().signed_block_header();
|
let header = self.block.signed_block_header();
|
||||||
let (parent, block) = if let Some(parent) = self.parent {
|
let (parent, block) = if let Some(parent) = self.parent {
|
||||||
(parent, self.block)
|
(parent, self.block)
|
||||||
} else {
|
} else {
|
||||||
load_parent(self.block_root, self.block.block(), chain)
|
load_parent(self.block_root, self.block, chain)
|
||||||
.map_err(|e| BlockSlashInfo::SignatureValid(header.clone(), e))?
|
.map_err(|e| BlockSlashInfo::SignatureValid(header.clone(), e))?
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1102,7 +1114,7 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBloc
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
||||||
&self.block.block()
|
&self.block.as_block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1119,7 +1131,12 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
|
|||||||
let block_root = check_block_relevancy(&self, block_root, chain)
|
let block_root = check_block_relevancy(&self, block_root, chain)
|
||||||
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
|
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
|
||||||
|
|
||||||
SignatureVerifiedBlock::check_slashable(self.into(), block_root, chain)?
|
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)?
|
||||||
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
|
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1138,16 +1155,15 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for AvailableBlock<T::Eth
|
|||||||
notify_execution_layer: NotifyExecutionLayer,
|
notify_execution_layer: NotifyExecutionLayer,
|
||||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||||
// Perform an early check to prevent wasting time on irrelevant blocks.
|
// Perform an early check to prevent wasting time on irrelevant blocks.
|
||||||
let block_root = check_block_relevancy(self.block(), block_root, chain).map_err(|e| {
|
let block_root = check_block_relevancy(self.as_block(), block_root, chain)
|
||||||
BlockSlashInfo::SignatureNotChecked(self.block().signed_block_header(), e)
|
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
|
||||||
})?;
|
|
||||||
|
|
||||||
SignatureVerifiedBlock::check_slashable(self, 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)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
||||||
self.block()
|
self.as_block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1190,7 +1206,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));
|
return Err(BlockError::ParentUnknown(block.into_block_wrapper()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reject any block that exceeds our limit on skipped slots.
|
// Reject any block that exceeds our limit on skipped slots.
|
||||||
@ -1200,7 +1216,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
|||||||
* Perform cursory checks to see if the block is even worth processing.
|
* Perform cursory checks to see if the block is even worth processing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
check_block_relevancy(block.block(), block_root, chain)?;
|
check_block_relevancy(block.as_block(), block_root, chain)?;
|
||||||
|
|
||||||
// Define a future that will verify the execution payload with an execution engine.
|
// Define a future that will verify the execution payload with an execution engine.
|
||||||
//
|
//
|
||||||
@ -1449,13 +1465,13 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
|||||||
&state,
|
&state,
|
||||||
&chain.log,
|
&chain.log,
|
||||||
);
|
);
|
||||||
write_block(block.block(), block_root, &chain.log);
|
write_block(block.as_block(), block_root, &chain.log);
|
||||||
|
|
||||||
let core_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_CORE);
|
let core_timer = metrics::start_timer(&metrics::BLOCK_PROCESSING_CORE);
|
||||||
|
|
||||||
if let Err(err) = per_block_processing(
|
if let Err(err) = per_block_processing(
|
||||||
&mut state,
|
&mut state,
|
||||||
block.block(),
|
block.as_block(),
|
||||||
// Signatures were verified earlier in this function.
|
// Signatures were verified earlier in this function.
|
||||||
BlockSignatureStrategy::NoVerification,
|
BlockSignatureStrategy::NoVerification,
|
||||||
VerifyBlockRoot::True,
|
VerifyBlockRoot::True,
|
||||||
@ -1492,9 +1508,9 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
|||||||
* Check to ensure the state root on the block matches the one we have calculated.
|
* Check to ensure the state root on the block matches the one we have calculated.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if block.block().state_root() != state_root {
|
if block.state_root() != state_root {
|
||||||
return Err(BlockError::StateRootMismatch {
|
return Err(BlockError::StateRootMismatch {
|
||||||
block: block.block().state_root(),
|
block: block.state_root(),
|
||||||
local: state_root,
|
local: state_root,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -1623,11 +1639,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_descendant<T: BeaconChainTypes>(
|
pub fn check_block_is_finalized_descendant<T: BeaconChainTypes, B: IntoBlockWrapper<T::EthSpec>>(
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
fork_choice: &BeaconForkChoice<T>,
|
fork_choice: &BeaconForkChoice<T>,
|
||||||
block: BlockWrapper<T::EthSpec>,
|
block: B,
|
||||||
) -> Result<BlockWrapper<T::EthSpec>, BlockError<T::EthSpec>> {
|
) -> Result<B, BlockError<T::EthSpec>> {
|
||||||
if fork_choice.is_descendant_of_finalized(block.parent_root()) {
|
if fork_choice.is_descendant_of_finalized(block.parent_root()) {
|
||||||
Ok(block)
|
Ok(block)
|
||||||
} else {
|
} else {
|
||||||
@ -1648,7 +1664,7 @@ pub fn check_block_is_finalized_descendant<T: BeaconChainTypes>(
|
|||||||
block_parent_root: block.parent_root(),
|
block_parent_root: block.parent_root(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Err(BlockError::ParentUnknown(block))
|
Err(BlockError::ParentUnknown(block.into_block_wrapper()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1725,7 +1741,7 @@ fn verify_parent_block_is_known<T: BeaconChainTypes>(
|
|||||||
if let Some(proto_block) = chain
|
if let Some(proto_block) = chain
|
||||||
.canonical_head
|
.canonical_head
|
||||||
.fork_choice_read_lock()
|
.fork_choice_read_lock()
|
||||||
.get_block(&block.message().parent_root())
|
.get_block(&block.parent_root())
|
||||||
{
|
{
|
||||||
Ok((proto_block, block))
|
Ok((proto_block, block))
|
||||||
} else {
|
} else {
|
||||||
@ -1738,11 +1754,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>(
|
fn load_parent<T: BeaconChainTypes, B: IntoBlockWrapper<T::EthSpec>>(
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
block: BlockWrapper<T::EthSpec>,
|
block: B,
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<(PreProcessingSnapshot<T::EthSpec>, &SignedBeaconBlock<T::EthSpec>), BlockError<T::EthSpec>> {
|
) -> Result<(PreProcessingSnapshot<T::EthSpec>, B), 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.
|
||||||
@ -1760,7 +1776,7 @@ fn load_parent<T: BeaconChainTypes>(
|
|||||||
.fork_choice_read_lock()
|
.fork_choice_read_lock()
|
||||||
.contains_block(&block.parent_root())
|
.contains_block(&block.parent_root())
|
||||||
{
|
{
|
||||||
return Err(BlockError::ParentUnknown(block));
|
return Err(BlockError::ParentUnknown(block.into_block_wrapper()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let block_delay = chain
|
let block_delay = chain
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::blob_verification::AvailableBlock;
|
||||||
use crate::{
|
use crate::{
|
||||||
attester_cache::{CommitteeLengths, Error},
|
attester_cache::{CommitteeLengths, Error},
|
||||||
metrics,
|
metrics,
|
||||||
@ -5,7 +6,6 @@ use crate::{
|
|||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
use proto_array::Block as ProtoBlock;
|
use proto_array::Block as ProtoBlock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use store::signed_block_and_blobs::AvailableBlock;
|
|
||||||
use types::*;
|
use types::*;
|
||||||
|
|
||||||
pub struct CacheItem<E: EthSpec> {
|
pub struct CacheItem<E: EthSpec> {
|
||||||
|
Loading…
Reference in New Issue
Block a user