mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-20 22:38:34 +00:00
fix blob validation for empty blobs
This commit is contained in:
@@ -28,6 +28,15 @@ impl<T: EthSpec> BlobsSidecar<T> {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
pub fn empty_from_parts(beacon_block_root: Hash256, beacon_block_slot: Slot) -> Self {
|
||||
Self {
|
||||
beacon_block_root,
|
||||
beacon_block_slot,
|
||||
blobs: VariableList::empty(),
|
||||
kzg_aggregated_proof: KzgProof::empty(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::integer_arithmetic)]
|
||||
pub fn max_size() -> usize {
|
||||
// Fixed part
|
||||
|
||||
@@ -36,6 +36,10 @@ impl From<SignedBeaconBlockHash> for Hash256 {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum BlobReconstructionError {
|
||||
BlobsMissing,
|
||||
}
|
||||
|
||||
/// A `BeaconBlock` and a signature from its proposer.
|
||||
#[superstruct(
|
||||
variants(Base, Altair, Merge, Capella, Eip4844),
|
||||
@@ -235,6 +239,29 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
pub fn canonical_root(&self) -> Hash256 {
|
||||
self.message().tree_hash_root()
|
||||
}
|
||||
|
||||
/// Reconstructs an empty `BlobsSidecar`, using the given block root if provided, else calculates it.
|
||||
/// If this block has kzg commitments, an error will be returned. If this block is from prior to the
|
||||
/// Eip4844 fork, `None` will be returned.
|
||||
pub fn reconstruct_empty_blobs(
|
||||
&self,
|
||||
block_root_opt: Option<Hash256>,
|
||||
) -> Result<Option<BlobsSidecar<E>>, BlobReconstructionError> {
|
||||
self.message()
|
||||
.body()
|
||||
.blob_kzg_commitments()
|
||||
.map(|kzg_commitments| {
|
||||
if kzg_commitments.len() > 0 {
|
||||
Err(BlobReconstructionError::BlobsMissing)
|
||||
} else {
|
||||
Ok(Some(BlobsSidecar::empty_from_parts(
|
||||
block_root_opt.unwrap_or(self.canonical_root()),
|
||||
self.slot(),
|
||||
)))
|
||||
}
|
||||
})
|
||||
.unwrap_or(Ok(None))
|
||||
}
|
||||
}
|
||||
|
||||
// We can convert pre-Bellatrix blocks without payloads into blocks with payloads.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use crate::signed_beacon_block::BlobReconstructionError;
|
||||
use crate::{BlobsSidecar, EthSpec, Hash256, SignedBeaconBlock, SignedBeaconBlockEip4844, Slot};
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError};
|
||||
@@ -35,60 +36,52 @@ impl<T: EthSpec> SignedBeaconBlockAndBlobsSidecar<T> {
|
||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`].
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum BlockWrapper<T: EthSpec> {
|
||||
Block {
|
||||
block: Arc<SignedBeaconBlock<T>>,
|
||||
},
|
||||
BlockAndBlob {
|
||||
block_sidecar_pair: SignedBeaconBlockAndBlobsSidecar<T>,
|
||||
},
|
||||
Block(Arc<SignedBeaconBlock<T>>),
|
||||
BlockAndBlob(SignedBeaconBlockAndBlobsSidecar<T>),
|
||||
}
|
||||
|
||||
impl<T: EthSpec> BlockWrapper<T> {
|
||||
pub fn slot(&self) -> Slot {
|
||||
match self {
|
||||
BlockWrapper::Block { block } => block.slot(),
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => {
|
||||
BlockWrapper::Block(block) => block.slot(),
|
||||
BlockWrapper::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.slot()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn block(&self) -> &SignedBeaconBlock<T> {
|
||||
match self {
|
||||
BlockWrapper::Block { block } => &block,
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => &block_sidecar_pair.beacon_block,
|
||||
BlockWrapper::Block(block) => &block,
|
||||
BlockWrapper::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block,
|
||||
}
|
||||
}
|
||||
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<T>> {
|
||||
match self {
|
||||
BlockWrapper::Block { block } => block.clone(),
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => {
|
||||
BlockWrapper::Block(block) => block.clone(),
|
||||
BlockWrapper::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blobs(&self) -> Option<&BlobsSidecar<T>> {
|
||||
pub fn blobs(
|
||||
&self,
|
||||
block_root: Option<Hash256>,
|
||||
) -> Result<Option<Arc<BlobsSidecar<T>>>, BlobReconstructionError> {
|
||||
match self {
|
||||
BlockWrapper::Block { .. } => None,
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => {
|
||||
Some(&block_sidecar_pair.blobs_sidecar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blobs_cloned(&self) -> Option<Arc<BlobsSidecar<T>>> {
|
||||
match self {
|
||||
BlockWrapper::Block { block: _ } => None,
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => {
|
||||
Some(block_sidecar_pair.blobs_sidecar.clone())
|
||||
BlockWrapper::Block(block) => block
|
||||
.reconstruct_empty_blobs(block_root)
|
||||
.map(|blob_opt| blob_opt.map(Arc::new)),
|
||||
BlockWrapper::BlockAndBlob(block_sidecar_pair) => {
|
||||
Ok(Some(block_sidecar_pair.blobs_sidecar.clone()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message(&self) -> crate::BeaconBlockRef<T> {
|
||||
match self {
|
||||
BlockWrapper::Block { block } => block.message(),
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => {
|
||||
BlockWrapper::Block(block) => block.message(),
|
||||
BlockWrapper::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.message()
|
||||
}
|
||||
}
|
||||
@@ -100,8 +93,8 @@ impl<T: EthSpec> BlockWrapper<T> {
|
||||
|
||||
pub fn deconstruct(self) -> (Arc<SignedBeaconBlock<T>>, Option<Arc<BlobsSidecar<T>>>) {
|
||||
match self {
|
||||
BlockWrapper::Block { block } => (block, None),
|
||||
BlockWrapper::BlockAndBlob { block_sidecar_pair } => {
|
||||
BlockWrapper::Block(block) => (block, None),
|
||||
BlockWrapper::BlockAndBlob(block_sidecar_pair) => {
|
||||
let SignedBeaconBlockAndBlobsSidecar {
|
||||
beacon_block,
|
||||
blobs_sidecar,
|
||||
@@ -112,29 +105,25 @@ impl<T: EthSpec> BlockWrapper<T> {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: probably needes to be changed. This is needed because SignedBeaconBlockAndBlobsSidecar
|
||||
// FIXME(sean): probably needs to be changed. This is needed because SignedBeaconBlockAndBlobsSidecar
|
||||
// does not implement Hash
|
||||
impl<T: EthSpec> std::hash::Hash for BlockWrapper<T> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
BlockWrapper::Block { block } => block.hash(state),
|
||||
BlockWrapper::BlockAndBlob {
|
||||
block_sidecar_pair: block_and_blob,
|
||||
} => block_and_blob.beacon_block.hash(state),
|
||||
BlockWrapper::Block(block) => block.hash(state),
|
||||
BlockWrapper::BlockAndBlob(block_and_blob) => block_and_blob.beacon_block.hash(state),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<SignedBeaconBlock<T>> for BlockWrapper<T> {
|
||||
fn from(block: SignedBeaconBlock<T>) -> Self {
|
||||
BlockWrapper::Block {
|
||||
block: Arc::new(block),
|
||||
}
|
||||
BlockWrapper::Block(Arc::new(block))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<Arc<SignedBeaconBlock<T>>> for BlockWrapper<T> {
|
||||
fn from(block: Arc<SignedBeaconBlock<T>>) -> Self {
|
||||
BlockWrapper::Block { block }
|
||||
BlockWrapper::Block(block)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user