mirror of
https://github.com/sigp/lighthouse.git
synced 2026-07-02 20:34:27 +00:00
merge conflict resolution
This commit is contained in:
@@ -18,10 +18,8 @@ pub struct ConsensusContext<T: EthSpec> {
|
||||
/// Cache of indexed attestations constructed during block processing.
|
||||
indexed_attestations:
|
||||
HashMap<(AttestationData, BitList<T::MaxValidatorsPerCommittee>), IndexedAttestation<T>>,
|
||||
/// Whether `validate_blobs_sidecar` has successfully passed.
|
||||
blobs_sidecar_validated: bool,
|
||||
/// Whether `verify_kzg_commitments_against_transactions` has successfully passed.
|
||||
blobs_verified_vs_txs: bool,
|
||||
kzg_commitments_consistent: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
@@ -44,8 +42,7 @@ impl<T: EthSpec> ConsensusContext<T> {
|
||||
proposer_index: None,
|
||||
current_block_root: None,
|
||||
indexed_attestations: HashMap::new(),
|
||||
blobs_sidecar_validated: false,
|
||||
blobs_verified_vs_txs: false,
|
||||
kzg_commitments_consistent: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,21 +159,12 @@ impl<T: EthSpec> ConsensusContext<T> {
|
||||
self.indexed_attestations.len()
|
||||
}
|
||||
|
||||
pub fn set_blobs_sidecar_validated(mut self, blobs_sidecar_validated: bool) -> Self {
|
||||
self.blobs_sidecar_validated = blobs_sidecar_validated;
|
||||
pub fn set_kzg_commitments_consistent(mut self, kzg_commitments_consistent: bool) -> Self {
|
||||
self.kzg_commitments_consistent = kzg_commitments_consistent;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_blobs_verified_vs_txs(mut self, blobs_verified_vs_txs: bool) -> Self {
|
||||
self.blobs_verified_vs_txs = blobs_verified_vs_txs;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn blobs_sidecar_validated(&self) -> bool {
|
||||
self.blobs_sidecar_validated
|
||||
}
|
||||
|
||||
pub fn blobs_verified_vs_txs(&self) -> bool {
|
||||
self.blobs_verified_vs_txs
|
||||
pub fn kzg_commitments_consistent(&self) -> bool {
|
||||
self.kzg_commitments_consistent
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,10 +180,7 @@ pub fn per_block_processing<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
)?;
|
||||
}
|
||||
|
||||
process_blob_kzg_commitments(block.body())?;
|
||||
|
||||
//FIXME(sean) add `validate_blobs_sidecar` (is_data_available) and only run it if the consensus
|
||||
// context tells us it wasnt already run
|
||||
process_blob_kzg_commitments(block.body(), ctxt)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::BlockProcessingError;
|
||||
use crate::{BlockProcessingError, ConsensusContext};
|
||||
use eth2_hashing::hash_fixed;
|
||||
use itertools::{EitherOrBoth, Itertools};
|
||||
use safe_arith::SafeArith;
|
||||
@@ -11,13 +11,17 @@ use types::{
|
||||
|
||||
pub fn process_blob_kzg_commitments<T: EthSpec, Payload: AbstractExecPayload<T>>(
|
||||
block_body: BeaconBlockBodyRef<T, Payload>,
|
||||
ctxt: &mut ConsensusContext<T>,
|
||||
) -> Result<(), BlockProcessingError> {
|
||||
// Return early if this check has already been run.
|
||||
if ctxt.kzg_commitments_consistent() {
|
||||
return Ok(());
|
||||
}
|
||||
if let (Ok(payload), Ok(kzg_commitments)) = (
|
||||
block_body.execution_payload(),
|
||||
block_body.blob_kzg_commitments(),
|
||||
) {
|
||||
if let Some(transactions) = payload.transactions() {
|
||||
//FIXME(sean) only run if this wasn't run in gossip (use consensus context)
|
||||
if !verify_kzg_commitments_against_transactions::<T>(transactions, kzg_commitments)? {
|
||||
return Err(BlockProcessingError::BlobVersionHashMismatch);
|
||||
}
|
||||
|
||||
@@ -35,8 +35,12 @@ impl From<SignedBeaconBlockHash> for Hash256 {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum BlobReconstructionError {
|
||||
BlobsMissing,
|
||||
/// No blobs for the specified block where we would expect blobs.
|
||||
UnavailableBlobs,
|
||||
/// Blobs provided for a pre-Eip4844 fork.
|
||||
InconsistentFork,
|
||||
}
|
||||
|
||||
/// A `BeaconBlock` and a signature from its proposer.
|
||||
@@ -249,25 +253,24 @@ impl<E: EthSpec, Payload: AbstractExecPayload<E>> SignedBeaconBlock<E, Payload>
|
||||
|
||||
/// 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.
|
||||
/// Eip4844 fork, this will error.
|
||||
pub fn reconstruct_empty_blobs(
|
||||
&self,
|
||||
block_root_opt: Option<Hash256>,
|
||||
) -> Result<Option<BlobsSidecar<E>>, BlobReconstructionError> {
|
||||
self.message()
|
||||
) -> Result<BlobsSidecar<E>, BlobReconstructionError> {
|
||||
let kzg_commitments = 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))
|
||||
.map_err(|_| BlobReconstructionError::InconsistentFork)?;
|
||||
if kzg_commitments.is_empty() {
|
||||
Ok(BlobsSidecar::empty_from_parts(
|
||||
block_root_opt.unwrap_or(self.canonical_root()),
|
||||
self.slot(),
|
||||
))
|
||||
} else {
|
||||
Err(BlobReconstructionError::UnavailableBlobs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
use crate::signed_beacon_block::BlobReconstructionError;
|
||||
use crate::{
|
||||
BlobsSidecar, Epoch, EthSpec, Hash256, SignedBeaconBlock, SignedBeaconBlockEip4844, Slot,
|
||||
};
|
||||
use crate::{BlobsSidecar, EthSpec, SignedBeaconBlock, SignedBeaconBlockEip4844};
|
||||
use derivative::Derivative;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use ssz::{Decode, DecodeError};
|
||||
@@ -35,136 +32,3 @@ impl<T: EthSpec> SignedBeaconBlockAndBlobsSidecar<T> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`]. This newtype
|
||||
/// wraps the `BlockWrapperInner` to ensure blobs cannot be accessed via an enum match. This would
|
||||
/// circumvent empty blob reconstruction when accessing blobs.
|
||||
#[derive(Clone, Debug, Derivative)]
|
||||
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
|
||||
pub struct BlockWrapper<T: EthSpec>(BlockWrapperInner<T>);
|
||||
|
||||
/// A wrapper over a [`SignedBeaconBlock`] or a [`SignedBeaconBlockAndBlobsSidecar`].
|
||||
#[derive(Clone, Debug, Derivative)]
|
||||
#[derivative(PartialEq, Hash(bound = "T: EthSpec"))]
|
||||
pub enum BlockWrapperInner<T: EthSpec> {
|
||||
Block(Arc<SignedBeaconBlock<T>>),
|
||||
BlockAndBlob(SignedBeaconBlockAndBlobsSidecar<T>),
|
||||
}
|
||||
|
||||
impl<T: EthSpec> BlockWrapper<T> {
|
||||
pub fn new(block: Arc<SignedBeaconBlock<T>>) -> Self {
|
||||
Self(BlockWrapperInner::Block(block))
|
||||
}
|
||||
|
||||
pub fn new_with_blobs(
|
||||
beacon_block: Arc<SignedBeaconBlock<T>>,
|
||||
blobs_sidecar: Arc<BlobsSidecar<T>>,
|
||||
) -> Self {
|
||||
Self(BlockWrapperInner::BlockAndBlob(
|
||||
SignedBeaconBlockAndBlobsSidecar {
|
||||
beacon_block,
|
||||
blobs_sidecar,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
pub fn slot(&self) -> Slot {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => block.slot(),
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.slot()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn epoch(&self) -> Epoch {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => block.epoch(),
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.epoch()
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn block(&self) -> &SignedBeaconBlock<T> {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => &block,
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => &block_sidecar_pair.beacon_block,
|
||||
}
|
||||
}
|
||||
pub fn block_cloned(&self) -> Arc<SignedBeaconBlock<T>> {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => block.clone(),
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn blobs(
|
||||
&self,
|
||||
block_root: Option<Hash256>,
|
||||
) -> Result<Option<Arc<BlobsSidecar<T>>>, BlobReconstructionError> {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => block
|
||||
.reconstruct_empty_blobs(block_root)
|
||||
.map(|blob_opt| blob_opt.map(Arc::new)),
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
Ok(Some(block_sidecar_pair.blobs_sidecar.clone()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn message(&self) -> crate::BeaconBlockRef<T> {
|
||||
match &self.0 {
|
||||
BlockWrapperInner::Block(block) => block.message(),
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
block_sidecar_pair.beacon_block.message()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parent_root(&self) -> Hash256 {
|
||||
self.block().parent_root()
|
||||
}
|
||||
|
||||
pub fn deconstruct(
|
||||
self,
|
||||
block_root: Option<Hash256>,
|
||||
) -> (
|
||||
Arc<SignedBeaconBlock<T>>,
|
||||
Result<Option<Arc<BlobsSidecar<T>>>, BlobReconstructionError>,
|
||||
) {
|
||||
match self.0 {
|
||||
BlockWrapperInner::Block(block) => {
|
||||
let blobs = block
|
||||
.reconstruct_empty_blobs(block_root)
|
||||
.map(|blob_opt| blob_opt.map(Arc::new));
|
||||
(block, blobs)
|
||||
}
|
||||
BlockWrapperInner::BlockAndBlob(block_sidecar_pair) => {
|
||||
let SignedBeaconBlockAndBlobsSidecar {
|
||||
beacon_block,
|
||||
blobs_sidecar,
|
||||
} = block_sidecar_pair;
|
||||
(beacon_block, Ok(Some(blobs_sidecar)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<SignedBeaconBlock<T>> for BlockWrapper<T> {
|
||||
fn from(block: SignedBeaconBlock<T>) -> Self {
|
||||
BlockWrapper(BlockWrapperInner::Block(Arc::new(block)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<Arc<SignedBeaconBlock<T>>> for BlockWrapper<T> {
|
||||
fn from(block: Arc<SignedBeaconBlock<T>>) -> Self {
|
||||
BlockWrapper(BlockWrapperInner::Block(block))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: EthSpec> From<SignedBeaconBlockAndBlobsSidecar<T>> for BlockWrapper<T> {
|
||||
fn from(block: SignedBeaconBlockAndBlobsSidecar<T>) -> Self {
|
||||
BlockWrapper(BlockWrapperInner::BlockAndBlob(block))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user