mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 17:26:04 +00:00
more progress
This commit is contained in:
@@ -7,12 +7,14 @@ 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::{AsBlock, AvailabilityPendingBlock, AvailableBlock, BlobError, BlockWrapper, IntoAvailableBlock, Blobs};
|
use crate::blob_verification::{
|
||||||
|
AsBlock, AvailableBlock, BlobError, Blobs, 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_checkpoint_or_descendant, check_block_relevancy, get_block_root,
|
check_block_is_finalized_checkpoint_or_descendant, check_block_relevancy, get_block_root,
|
||||||
signature_verify_chain_segment, BlockError, ExecutionPendingBlock, GossipVerifiedBlock,
|
signature_verify_chain_segment, BlockError, ExecutedBlock, ExecutionPendingBlock,
|
||||||
IntoExecutionPendingBlock, PayloadVerificationOutcome, POS_PANDA_BANNER, ExecutedBlock,
|
GossipVerifiedBlock, IntoExecutionPendingBlock, PayloadVerificationOutcome, POS_PANDA_BANNER,
|
||||||
};
|
};
|
||||||
pub use crate::canonical_head::{CanonicalHead, CanonicalHeadRwLock};
|
pub use crate::canonical_head::{CanonicalHead, CanonicalHeadRwLock};
|
||||||
use crate::chain_config::ChainConfig;
|
use crate::chain_config::ChainConfig;
|
||||||
@@ -82,6 +84,7 @@ use slasher::Slasher;
|
|||||||
use slog::{crit, debug, error, info, trace, warn, Logger};
|
use slog::{crit, debug, error, info, trace, warn, Logger};
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
use ssz::Encode;
|
use ssz::Encode;
|
||||||
|
use state_processing::per_block_processing::eip4844::eip4844::verify_kzg_commitments_against_transactions;
|
||||||
use state_processing::{
|
use state_processing::{
|
||||||
common::get_attesting_indices_from_state,
|
common::get_attesting_indices_from_state,
|
||||||
per_block_processing,
|
per_block_processing,
|
||||||
@@ -102,16 +105,14 @@ use std::io::prelude::*;
|
|||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use state_processing::per_block_processing::eip4844::eip4844::verify_kzg_commitments_against_transactions;
|
|
||||||
use store::iter::{BlockRootsIterator, ParentRootBlockIterator, StateRootsIterator};
|
use store::iter::{BlockRootsIterator, ParentRootBlockIterator, StateRootsIterator};
|
||||||
use store::{
|
use store::{
|
||||||
DatabaseBlock, Error as DBError, HotColdDB, KeyValueStore, KeyValueStoreOp, StoreItem, StoreOp,
|
DatabaseBlock, Error as DBError, HotColdDB, KeyValueStore, KeyValueStoreOp, StoreItem, StoreOp,
|
||||||
};
|
};
|
||||||
use task_executor::{ShutdownReason, TaskExecutor};
|
use task_executor::{ShutdownReason, TaskExecutor};
|
||||||
|
use tokio::task::JoinHandle;
|
||||||
use tree_hash::TreeHash;
|
use tree_hash::TreeHash;
|
||||||
use types::beacon_state::CloneConfig;
|
use types::beacon_state::CloneConfig;
|
||||||
use types::blobs_sidecar::KzgCommitments;
|
|
||||||
use types::consts::eip4844::MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS;
|
use types::consts::eip4844::MIN_EPOCHS_FOR_BLOBS_SIDECARS_REQUESTS;
|
||||||
use types::consts::merge::INTERVALS_PER_SLOT;
|
use types::consts::merge::INTERVALS_PER_SLOT;
|
||||||
use types::*;
|
use types::*;
|
||||||
@@ -440,8 +441,7 @@ pub struct BeaconChain<T: BeaconChainTypes> {
|
|||||||
/// Provides monitoring of a set of explicitly defined validators.
|
/// Provides monitoring of a set of explicitly defined validators.
|
||||||
pub validator_monitor: RwLock<ValidatorMonitor<T::EthSpec>>,
|
pub validator_monitor: RwLock<ValidatorMonitor<T::EthSpec>>,
|
||||||
pub blob_cache: BlobCache<T::EthSpec>,
|
pub blob_cache: BlobCache<T::EthSpec>,
|
||||||
pub blob_cache: BlobCache<T::EthSpec>,
|
pub kzg: Option<Arc<Kzg>>,
|
||||||
pub kzg: Option<Arc<kzg::Kzg>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type BeaconBlockAndState<T, Payload> = (BeaconBlock<T, Payload>, BeaconState<T>);
|
type BeaconBlockAndState<T, Payload> = (BeaconBlock<T, Payload>, BeaconState<T>);
|
||||||
@@ -1082,34 +1082,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
pub fn get_blobs(
|
pub fn get_blobs(
|
||||||
&self,
|
&self,
|
||||||
block_root: &Hash256,
|
block_root: &Hash256,
|
||||||
data_availability_boundary: Epoch,
|
) -> Result<Option<BlobSidecarList<T::EthSpec>>, Error> {
|
||||||
) -> Result<Option<BlobsSidecar<T::EthSpec>>, Error> {
|
self.store.get_blobs(block_root)
|
||||||
match self.store.get_blobs(block_root)? {
|
|
||||||
Some(blobs) => Ok(Some(blobs)),
|
|
||||||
None => {
|
|
||||||
// Check for the corresponding block to understand whether we *should* have blobs.
|
|
||||||
self.get_blinded_block(block_root)?
|
|
||||||
.map(|block| {
|
|
||||||
// If there are no KZG commitments in the block, we know the sidecar should
|
|
||||||
// be empty.
|
|
||||||
let expected_kzg_commitments =
|
|
||||||
match block.message().body().blob_kzg_commitments() {
|
|
||||||
Ok(kzg_commitments) => kzg_commitments,
|
|
||||||
Err(_) => return Err(Error::NoKzgCommitmentsFieldOnBlock),
|
|
||||||
};
|
|
||||||
if expected_kzg_commitments.is_empty() {
|
|
||||||
Ok(BlobsSidecar::empty_from_parts(*block_root, block.slot()))
|
|
||||||
} else if data_availability_boundary <= block.epoch() {
|
|
||||||
// We should have blobs for all blocks younger than the boundary.
|
|
||||||
Err(Error::BlobsUnavailable)
|
|
||||||
} else {
|
|
||||||
// We shouldn't have blobs for blocks older than the boundary.
|
|
||||||
Err(Error::BlobsOlderThanDataAvailabilityBoundary(block.epoch()))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.transpose()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_blinded_block(
|
pub fn get_blinded_block(
|
||||||
@@ -2708,7 +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,
|
||||||
@@ -2721,11 +2695,13 @@ 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.gossip_blob_cache.lock().blobs(executed_block.block_root) {
|
let import_block = if let Ok(blobs) = self
|
||||||
|
.gossip_blob_cache
|
||||||
|
.lock()
|
||||||
|
.blobs(executed_block.block_root)
|
||||||
|
{
|
||||||
self.import_available_block(executed_block, blobs, count_unrealized)
|
self.import_available_block(executed_block, blobs, count_unrealized)
|
||||||
} else {
|
} else {
|
||||||
return Ok(BlockProcessingResult::AvailabilityPending(executed_block));
|
return Ok(BlockProcessingResult::AvailabilityPending(executed_block));
|
||||||
@@ -2839,7 +2815,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
confirmed_state_roots,
|
confirmed_state_roots,
|
||||||
parent_eth1_finalization_data,
|
parent_eth1_finalization_data,
|
||||||
consensus_context,
|
consensus_context,
|
||||||
payload_verification_outcome
|
payload_verification_outcome,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2851,7 +2827,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
async fn import_available_block(
|
async fn import_available_block(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
executed_block: ExecutedBlock<T>,
|
executed_block: ExecutedBlock<T>,
|
||||||
blobs: Blobs<T::EthSpec>
|
blobs: Blobs<T::EthSpec>,
|
||||||
count_unrealized: CountUnrealized,
|
count_unrealized: CountUnrealized,
|
||||||
) -> Result<Hash256, BlockError<T::EthSpec>> {
|
) -> Result<Hash256, BlockError<T::EthSpec>> {
|
||||||
let ExecutedBlock {
|
let ExecutedBlock {
|
||||||
@@ -2863,14 +2839,13 @@ 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,
|
||||||
};
|
};
|
||||||
|
|
||||||
let block_hash = self
|
let block_hash = self
|
||||||
@@ -2881,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,
|
||||||
@@ -2895,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
|
||||||
@@ -2920,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.
|
||||||
@@ -2957,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.
|
||||||
{
|
{
|
||||||
@@ -3089,14 +3069,12 @@ 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";
|
"block_root" => ?block_root
|
||||||
"block_root" => ?block_root
|
);
|
||||||
);
|
ops.push(StoreOp::PutBlobs(block_root, blobs));
|
||||||
ops.push(StoreOp::PutBlobs(block_root, blobs));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4911,7 +4889,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
)),
|
)),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
kzg_utils::compute_blob_kzg_proof::<T::EthSpec>(kzg, blob, kzg_commitment.clone())
|
kzg_utils::compute_blob_kzg_proof::<T::EthSpec>(kzg, blob, *kzg_commitment)
|
||||||
.map_err(BlockProductionError::KzgError)
|
.map_err(BlockProductionError::KzgError)
|
||||||
})
|
})
|
||||||
.collect::<Result<Vec<KzgProof>, BlockProductionError>>()
|
.collect::<Result<Vec<KzgProof>, BlockProductionError>>()
|
||||||
@@ -6196,19 +6174,22 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
.unwrap_or(false))
|
.unwrap_or(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn check_data_availability(&self, block: Arc<SignedBeaconBlock<T::EthSpec>>) -> Result<AvailableBlock<T>, Error> {
|
pub async fn check_data_availability(
|
||||||
let kzg_commitments = block
|
&self,
|
||||||
.message()
|
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||||
.body()
|
) -> Result<AvailableBlock<T>, Error> {
|
||||||
.blob_kzg_commitments()
|
let kzg_commitments = block
|
||||||
.map_err(|_| BlobError::KzgCommitmentMissing)?;
|
.message()
|
||||||
let transactions = block
|
.body()
|
||||||
.message()
|
.blob_kzg_commitments()
|
||||||
.body()
|
.map_err(|_| BlobError::KzgCommitmentMissing)?;
|
||||||
.execution_payload_eip4844()
|
let transactions = block
|
||||||
.map(|payload| payload.transactions())
|
.message()
|
||||||
.map_err(|_| BlobError::TransactionsMissing)?
|
.body()
|
||||||
.ok_or(BlobError::TransactionsMissing)?;
|
.execution_payload_eip4844()
|
||||||
|
.map(|payload| payload.transactions())
|
||||||
|
.map_err(|_| BlobError::TransactionsMissing)?
|
||||||
|
.ok_or(BlobError::TransactionsMissing)?;
|
||||||
|
|
||||||
if verify_kzg_commitments_against_transactions::<T::EthSpec>(transactions, kzg_commitments)
|
if verify_kzg_commitments_against_transactions::<T::EthSpec>(transactions, kzg_commitments)
|
||||||
.is_err()
|
.is_err()
|
||||||
@@ -6216,9 +6197,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
return Err(BlobError::TransactionCommitmentMismatch);
|
return Err(BlobError::TransactionCommitmentMismatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.blob_cache
|
// Validate that the kzg proof is valid against the commitments and blobs
|
||||||
|
|
||||||
// Validatate that the kzg proof is valid against the commitments and blobs
|
|
||||||
let kzg = self
|
let kzg = self
|
||||||
.kzg
|
.kzg
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -6231,7 +6210,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
|||||||
kzg_commitments,
|
kzg_commitments,
|
||||||
blob_sidecar,
|
blob_sidecar,
|
||||||
)
|
)
|
||||||
.map_err(BlobError::KzgError)?
|
.map_err(BlobError::KzgError)?
|
||||||
{
|
{
|
||||||
return Err(BlobError::InvalidKzgProof);
|
return Err(BlobError::InvalidKzgProof);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,5 @@
|
|||||||
use derivative::Derivative;
|
|
||||||
use slot_clock::SlotClock;
|
use slot_clock::SlotClock;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use ssz_types::VariableList;
|
|
||||||
|
|
||||||
use crate::beacon_chain::{
|
use crate::beacon_chain::{
|
||||||
BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
|
BeaconChain, BeaconChainTypes, MAXIMUM_GOSSIP_CLOCK_DISPARITY,
|
||||||
@@ -11,12 +8,9 @@ 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::{
|
use types::{
|
||||||
BeaconBlockRef, BeaconStateError, BlobsSidecar, EthSpec, Hash256, KzgCommitment,
|
BeaconBlockRef, BeaconStateError, BlobSidecarList, Epoch, EthSpec, Hash256, KzgCommitment,
|
||||||
SignedBeaconBlock, SignedBeaconBlockAndBlobsSidecar, SignedBeaconBlockHeader,
|
SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlobSidecar, Slot, Transactions,
|
||||||
SignedBlobSidecar, Slot, Transactions,
|
|
||||||
};
|
};
|
||||||
use types::{Epoch, ExecPayload};
|
|
||||||
use types::blob_sidecar::BlobSidecar;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BlobError {
|
pub enum BlobError {
|
||||||
@@ -191,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,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -249,11 +243,11 @@ 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,
|
||||||
block_root: Hash256,
|
_block_root: Hash256,
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<(), BlobError> {
|
) -> Result<(), BlobError> {
|
||||||
if verify_kzg_commitments_against_transactions::<T::EthSpec>(transactions, kzg_commitments)
|
if verify_kzg_commitments_against_transactions::<T::EthSpec>(transactions, kzg_commitments)
|
||||||
@@ -263,7 +257,7 @@ pub fn verify_data_availability<T: BeaconChainTypes>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validatate that the kzg proof is valid against the commitments and blobs
|
// Validatate that the kzg proof is valid against the commitments and blobs
|
||||||
let kzg = chain
|
let _kzg = chain
|
||||||
.kzg
|
.kzg
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.ok_or(BlobError::TrustedSetupNotInitialized)?;
|
.ok_or(BlobError::TrustedSetupNotInitialized)?;
|
||||||
@@ -289,25 +283,6 @@ pub enum DataAvailabilityCheckRequired {
|
|||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BeaconChainTypes> BlockWrapper<T::EthSpec> {
|
|
||||||
fn into_availablilty_pending_block(
|
|
||||||
self,
|
|
||||||
block_root: Hash256,
|
|
||||||
chain: &BeaconChain<T>,
|
|
||||||
) -> Result<AvailabilityPendingBlock<T::EthSpec>, BlobError> {
|
|
||||||
match self {
|
|
||||||
BlockWrapper::Block(block) => {
|
|
||||||
AvailabilityPendingBlock::new(block, block_root, da_check_required)
|
|
||||||
}
|
|
||||||
BlockWrapper::BlockAndBlobs(block, blobs_sidecar) => {
|
|
||||||
|
|
||||||
|
|
||||||
AvailabilityPendingBlock::new_with_blobs(block, blobs_sidecar, da_check_required)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait IntoAvailableBlock<T: BeaconChainTypes> {
|
pub trait IntoAvailableBlock<T: BeaconChainTypes> {
|
||||||
fn into_available_block(
|
fn into_available_block(
|
||||||
self,
|
self,
|
||||||
@@ -316,173 +291,49 @@ pub trait IntoAvailableBlock<T: BeaconChainTypes> {
|
|||||||
) -> Result<AvailableBlock<T::EthSpec>, BlobError>;
|
) -> Result<AvailableBlock<T::EthSpec>, BlobError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. An
|
impl<T: BeaconChainTypes> IntoAvailableBlock<T> for BlockWrapper<T::EthSpec> {
|
||||||
/// `AvailableBlock` has passed any required data availability checks and should be used in
|
fn into_available_block(
|
||||||
/// consensus.
|
self,
|
||||||
#[derive(Clone, Debug, Derivative)]
|
|
||||||
#[derivative(PartialEq, Hash(bound = "T: BeaconChainTypes"))]
|
|
||||||
pub struct AvailabilityPendingBlock<T: BeaconChainTypes> {
|
|
||||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
|
||||||
data_availability_handle: DataAvailabilityHandle<T::EthSpec>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Used to await the result of data availability check.
|
|
||||||
type DataAvailabilityHandle<E> = JoinHandle<Result<Option<Blobs<E>>, BlobError>>;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Derivative)]
|
|
||||||
#[derivative(PartialEq, Hash(bound = "T: BeaconChainTypes"))]
|
|
||||||
pub struct AvailableBlock<T: BeaconChainTypes> {
|
|
||||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
|
||||||
blobs: Blobs<T::EthSpec>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl <T: BeaconChainTypes> AvailableBlock<T> {
|
|
||||||
pub fn blobs(&self) -> Option<Arc<BlobsSidecar<T>>> {
|
|
||||||
match &self.blobs {
|
|
||||||
Blobs::NotRequired | Blobs::None => None,
|
|
||||||
Blobs::Available(block_sidecar) => {
|
|
||||||
Some(block_sidecar.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<T::EthSpec>>, Option<Arc<BlobsSidecar<T::EthSpec>>>) {
|
|
||||||
match self.blobs {
|
|
||||||
Blobs::NotRequired | Blobs::None => (self.block, None),
|
|
||||||
Blobs::Available(blob_sidecars) => {
|
|
||||||
(self.block, Some(blob_sidecars))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum Blobs<E: EthSpec> {
|
|
||||||
/// These blobs are available.
|
|
||||||
Available(VariableList<Arc<BlobSidecar<E>>, E::MaxBlobsPerBlock>),
|
|
||||||
/// This block is from outside the data availability boundary or the block is from prior
|
|
||||||
/// to the eip4844 fork.
|
|
||||||
NotRequired,
|
|
||||||
/// The block doesn't have any blob transactions.
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO(sean) add block root to the availability pending block?
|
|
||||||
impl<T: BeaconChainTypes> AvailabilityPendingBlock<T> {
|
|
||||||
pub fn new(
|
|
||||||
beacon_block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<Self, BlobError> {
|
) -> Result<AvailableBlock<T::EthSpec>, BlobError> {
|
||||||
let data_availability_boundary = chain.data_availability_boundary();
|
todo!()
|
||||||
let da_check_required =
|
|
||||||
data_availability_boundary.map_or(DataAvailabilityCheckRequired::No, |boundary| {
|
|
||||||
if chain.epoch()? >= boundary {
|
|
||||||
DataAvailabilityCheckRequired::Yes
|
|
||||||
} else {
|
|
||||||
DataAvailabilityCheckRequired::No
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
match beacon_block.as_ref() {
|
|
||||||
// No data availability check required prior to Eip4844.
|
|
||||||
SignedBeaconBlock::Base(_)
|
|
||||||
| SignedBeaconBlock::Altair(_)
|
|
||||||
| SignedBeaconBlock::Capella(_)
|
|
||||||
| SignedBeaconBlock::Merge(_) => {
|
|
||||||
Ok(AvailabilityPendingBlock {
|
|
||||||
block: beacon_block ,
|
|
||||||
data_availability_handle: async{ Ok(Some(Blobs::NotRequired))}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
SignedBeaconBlock::Eip4844(_) => {
|
|
||||||
match da_check_required {
|
|
||||||
DataAvailabilityCheckRequired::Yes => {
|
|
||||||
// Attempt to reconstruct empty blobs here.
|
|
||||||
let blobs_sidecar = beacon_block
|
|
||||||
.reconstruct_empty_blobs(Some(block_root))
|
|
||||||
.map(Arc::new)?;
|
|
||||||
Ok(AvailableBlock(AvailableBlockInner::BlockAndBlob(
|
|
||||||
SignedBeaconBlockAndBlobsSidecar {
|
|
||||||
beacon_block,
|
|
||||||
blobs_sidecar,
|
|
||||||
},
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
DataAvailabilityCheckRequired::No => {
|
|
||||||
AvailabilityPendingBlock {
|
|
||||||
block: beacon_block,
|
|
||||||
data_availability_handle: async{ Ok(Some(Blobs::NotRequired))}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This function is private because an `AvailableBlock` should be
|
|
||||||
/// constructed via the `into_available_block` method.
|
|
||||||
//TODO(sean) do we want this to optionally cricumvent the beacon cache?
|
|
||||||
fn new_with_blobs(
|
|
||||||
beacon_block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
|
||||||
blobs_sidecar: Arc<BlobsSidecar<T::EthSpec>>,
|
|
||||||
chain: &BeaconChain<T>,
|
|
||||||
) -> Result<Self, BlobError> {
|
|
||||||
let data_availability_boundary = chain.data_availability_boundary();
|
|
||||||
let da_check_required =
|
|
||||||
data_availability_boundary.map_or(DataAvailabilityCheckRequired::No, |boundary| {
|
|
||||||
if chain.epoch()? >= boundary {
|
|
||||||
DataAvailabilityCheckRequired::Yes
|
|
||||||
} else {
|
|
||||||
DataAvailabilityCheckRequired::No
|
|
||||||
}
|
|
||||||
});
|
|
||||||
match beacon_block.as_ref() {
|
|
||||||
// This method shouldn't be called with a pre-Eip4844 block.
|
|
||||||
SignedBeaconBlock::Base(_)
|
|
||||||
| SignedBeaconBlock::Altair(_)
|
|
||||||
| SignedBeaconBlock::Capella(_)
|
|
||||||
| SignedBeaconBlock::Merge(_) => Err(BlobError::InconsistentFork),
|
|
||||||
SignedBeaconBlock::Eip4844(_) => {
|
|
||||||
match da_check_required {
|
|
||||||
DataAvailabilityCheckRequired::Yes => Ok(AvailableBlock{
|
|
||||||
block: beacon_block,
|
|
||||||
blobs: Blobs::Available(blobs_sidecar),
|
|
||||||
}
|
|
||||||
),
|
|
||||||
DataAvailabilityCheckRequired::No => {
|
|
||||||
// Blobs were not verified so we drop them, we'll instead just pass around
|
|
||||||
// an available `Eip4844` block without blobs.
|
|
||||||
Ok(AvailableBlock{
|
|
||||||
block: beacon_block,
|
|
||||||
blobs: Blobs::NotRequired
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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 AvailabilityPendingBlock<E> {
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
fn into_block_wrapper(self) -> BlockWrapper<E> {
|
pub struct AvailableBlock<T: EthSpec> {
|
||||||
let (block, blobs) = self.deconstruct();
|
pub block: Arc<SignedBeaconBlock<T>>,
|
||||||
if let Some(blobs) = blobs {
|
pub blobs: Blobs<T>,
|
||||||
BlockWrapper::BlockAndBlobs(block, blobs)
|
}
|
||||||
} else {
|
|
||||||
BlockWrapper::Block(block)
|
impl<T: EthSpec> AvailableBlock<T> {
|
||||||
|
pub fn blobs(&self) -> Option<Arc<BlobSidecarList<T>>> {
|
||||||
|
match &self.blobs {
|
||||||
|
Blobs::NotRequired | Blobs::None => None,
|
||||||
|
Blobs::Available(blobs) => Some(blobs.clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<T>>, Option<Arc<BlobSidecarList<T>>>) {
|
||||||
|
match self.blobs {
|
||||||
|
Blobs::NotRequired | Blobs::None => (self.block, None),
|
||||||
|
Blobs::Available(blobs) => (self.block, Some(blobs)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
|
pub enum Blobs<E: EthSpec> {
|
||||||
|
/// These blobs are available.
|
||||||
|
Available(Arc<BlobSidecarList<E>>),
|
||||||
|
/// This block is from outside the data availability boundary so doesn't require
|
||||||
|
/// a data availability check.
|
||||||
|
NotRequired,
|
||||||
|
/// 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AsBlock<E: EthSpec> {
|
pub trait AsBlock<E: EthSpec> {
|
||||||
@@ -497,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::BlockAndBlob(block, _) => block.canonical_root(),
|
BlockWrapper::AvailabilityPending(block) => block.canonical_root(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -557,131 +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::BlockAndBlob(block, _) => block.canonical_root(),
|
BlockWrapper::AvailabilityPending(block) => block.canonical_root(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: EthSpec> AsBlock<E> for AvailabilityPendingBlock<E> {
|
impl<E: EthSpec> From<SignedBeaconBlock<E>> for BlockWrapper<E> {
|
||||||
fn slot(&self) -> Slot {
|
fn from(block: SignedBeaconBlock<E>) -> Self {
|
||||||
match &self.0 {
|
BlockWrapper::AvailabilityPending(Arc::new(block))
|
||||||
AvailableBlockInner::Block(block) => block.slot(),
|
}
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
}
|
||||||
block_sidecar_pair.beacon_block.slot()
|
|
||||||
}
|
impl<E: EthSpec> From<Arc<SignedBeaconBlock<E>>> for BlockWrapper<E> {
|
||||||
}
|
fn from(block: Arc<SignedBeaconBlock<E>>) -> Self {
|
||||||
}
|
BlockWrapper::AvailabilityPending(block)
|
||||||
fn epoch(&self) -> Epoch {
|
}
|
||||||
match &self.0 {
|
}
|
||||||
AvailableBlockInner::Block(block) => block.epoch(),
|
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
impl<E: EthSpec> From<AvailableBlock<E>> for BlockWrapper<E> {
|
||||||
block_sidecar_pair.beacon_block.epoch()
|
fn from(block: AvailableBlock<E>) -> Self {
|
||||||
}
|
BlockWrapper::Available(block)
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn block_cloned(&self) -> Arc<SignedBeaconBlock<E>> {
|
|
||||||
match &self.0 {
|
|
||||||
AvailableBlockInner::Block(block) => block.clone(),
|
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
|
||||||
block_sidecar_pair.beacon_block.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn canonical_root(&self) -> Hash256 {
|
|
||||||
match &self.0 {
|
|
||||||
AvailableBlockInner::Block(block) => block.canonical_root(),
|
|
||||||
AvailableBlockInner::BlockAndBlob(block_sidecar_pair) => {
|
|
||||||
block_sidecar_pair.beacon_block.canonical_root()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,10 +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};
|
||||||
validate_blob_for_gossip, AsBlock, AvailabilityPendingBlock, 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,
|
||||||
@@ -67,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};
|
||||||
@@ -596,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,
|
||||||
@@ -624,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: AvailabilityPendingBlock<T>,
|
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>,
|
||||||
@@ -636,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: AvailabilityPendingBlock<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>,
|
||||||
@@ -659,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>>,
|
||||||
@@ -670,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>>,
|
||||||
@@ -689,7 +683,7 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
|
|||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
chain: &Arc<BeaconChain<T>>,
|
chain: &Arc<BeaconChain<T>>,
|
||||||
notify_execution_layer: NotifyExecutionLayer,
|
notify_execution_layer: NotifyExecutionLayer,
|
||||||
) -> Result<ExecutionPendingBlock<T, B>, BlockError<T::EthSpec>> {
|
) -> Result<ExecutionPendingBlock<T>, BlockError<T::EthSpec>> {
|
||||||
self.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
|
self.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
|
||||||
.map(|execution_pending| {
|
.map(|execution_pending| {
|
||||||
// Supply valid block to slasher.
|
// Supply valid block to slasher.
|
||||||
@@ -707,7 +701,7 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
|
|||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
chain: &Arc<BeaconChain<T>>,
|
chain: &Arc<BeaconChain<T>>,
|
||||||
notify_execution_layer: NotifyExecutionLayer,
|
notify_execution_layer: NotifyExecutionLayer,
|
||||||
) -> Result<ExecutionPendingBlock<T, B>, BlockSlashInfo<BlockError<T::EthSpec>>>;
|
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>>;
|
||||||
|
|
||||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec>;
|
fn block(&self) -> &SignedBeaconBlock<T::EthSpec>;
|
||||||
}
|
}
|
||||||
@@ -930,16 +924,14 @@ 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, 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(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(available_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,
|
||||||
@@ -979,10 +971,11 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<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 new(
|
pub fn new(
|
||||||
block: AvailabilityPendingBlock<T::EthSpec>,
|
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||||
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()
|
||||||
@@ -1029,7 +1022,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
|||||||
|
|
||||||
/// As for `new` above but producing `BlockSlashInfo`.
|
/// As for `new` above but producing `BlockSlashInfo`.
|
||||||
pub fn check_slashable(
|
pub fn check_slashable(
|
||||||
block: AvailabilityPendingBlock<T::EthSpec>,
|
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
chain: &BeaconChain<T>,
|
chain: &BeaconChain<T>,
|
||||||
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
) -> Result<Self, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||||
@@ -1139,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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1152,24 +1142,38 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for AvailabilityPendingBlock<T::EthSpec> {
|
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for BlockWrapper<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(
|
fn into_execution_pending_block_slashable(
|
||||||
self,
|
self,
|
||||||
block_root: Hash256,
|
block_root: Hash256,
|
||||||
chain: &Arc<BeaconChain<T>>,
|
chain: &Arc<BeaconChain<T>>,
|
||||||
notify_execution_layer: NotifyExecutionLayer,
|
notify_execution_layer: NotifyExecutionLayer,
|
||||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
) -> Result<
|
||||||
// Perform an early check to prevent wasting time on irrelevant blocks.
|
ExecutionPendingBlock<T>,
|
||||||
let block_root = check_block_relevancy(self.as_block(), block_root, chain)
|
BlockSlashInfo<BlockError<<T as BeaconChainTypes>::EthSpec>>,
|
||||||
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
|
> {
|
||||||
|
match self {
|
||||||
SignatureVerifiedBlock::check_slashable(self, block_root, chain)?
|
BlockWrapper::AvailabilityPending(block) => block
|
||||||
.into_execution_pending_block_slashable(block_root, chain, notify_execution_layer)
|
.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::EthSpec> {
|
fn block(&self) -> &SignedBeaconBlock<<T as BeaconChainTypes>::EthSpec> {
|
||||||
self.as_block()
|
self.as_block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1183,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: AvailabilityPendingBlock<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>,
|
||||||
@@ -1213,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.
|
||||||
@@ -1648,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 {
|
||||||
@@ -1676,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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1766,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.
|
||||||
@@ -1788,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
|
||||||
|
|||||||
@@ -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!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user