mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-18 12:22:51 +00:00
Sidecar inclusion proof (#4900)
* Refactor BlobSidecar to new type * Fix some compile errors * Gossip verification compiles * Fix http api types take 1 * Fix another round of compile errors * Beacon node crate compiles * EF tests compile * Remove all blob signing from VC * fmt * Tests compile * Fix some tests * Fix more http tests * get compiling * Fix gossip conditions and tests * Add basic proof generation and verification * remove unnecessary ssz decode * add back build_sidecar * remove default at fork for blobs * fix beacon chain tests * get relase tests compiling * fix lints * fix existing spec tests * add new ef tests * fix gossip duplicate rule * lints * add back sidecar signature check in gossip * add finalized descendant check to blob sidecar gossip * fix error conversion * fix release tests * sidecar inclusion self review cleanup * Add proof verification and computation metrics * Remove accidentally committed file * Unify some block and blob errors; add slashing conditions for sidecars * Address review comment * Clean up re-org tests (#4957) * Address more review comments * Add Comments & Eliminate Unnecessary Clones * update names * Update beacon_node/beacon_chain/src/metrics.rs Co-authored-by: Jimmy Chen <jchen.tc@gmail.com> * Update beacon_node/network/src/network_beacon_processor/tests.rs Co-authored-by: Jimmy Chen <jchen.tc@gmail.com> * pr feedback * fix test compile * Sidecar Inclusion proof small refactor and updates (#4967) * Update some comments, variables and small cosmetic fixes. * Couple blobs and proofs into a tuple in `PayloadAndBlobs` for simplicity and safety. * Update function comment. * Update testing/ef_tests/src/cases/merkle_proof_validity.rs Co-authored-by: Jimmy Chen <jchen.tc@gmail.com> * Rename the block and blob wrapper types used in the beacon API interfaces. * make sure gossip invalid blobs are passed to the slasher (#4970) * Add blob headers to slasher before adding to DA checker * Replace Vec with HashSet in BlockQueue * fmt * Rename gindex -> index * Simplify gossip condition --------- Co-authored-by: realbigsean <seananderson33@gmail.com> Co-authored-by: realbigsean <sean@sigmaprime.io> Co-authored-by: Michael Sproul <michael@sigmaprime.io> Co-authored-by: Mark Mackey <mark@sigmaprime.io> Co-authored-by: Jimmy Chen <jchen.tc@gmail.com>
This commit is contained in:
@@ -16,10 +16,6 @@ pub enum Error {
|
||||
BlobIndexInvalid(u64),
|
||||
StoreError(store::Error),
|
||||
DecodeError(ssz::DecodeError),
|
||||
InconsistentBlobBlockRoots {
|
||||
block_root: Hash256,
|
||||
blob_block_root: Hash256,
|
||||
},
|
||||
ParentStateMissing(Hash256),
|
||||
BlockReplayError(state_processing::BlockReplayError),
|
||||
RebuildingStateCaches(BeaconStateError),
|
||||
@@ -47,8 +43,7 @@ impl Error {
|
||||
Error::Kzg(_)
|
||||
| Error::BlobIndexInvalid(_)
|
||||
| Error::KzgCommitmentMismatch { .. }
|
||||
| Error::KzgVerificationFailed
|
||||
| Error::InconsistentBlobBlockRoots { .. } => ErrorCategory::Malicious,
|
||||
| Error::KzgVerificationFailed => ErrorCategory::Malicious,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,3 +71,9 @@ impl From<state_processing::BlockReplayError> for Error {
|
||||
Self::BlockReplayError(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<KzgError> for Error {
|
||||
fn from(value: KzgError) -> Self {
|
||||
Self::Kzg(value)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,10 @@ impl<T: EthSpec> PendingComponents<T> {
|
||||
for maybe_blob in self.verified_blobs.iter() {
|
||||
if maybe_blob.is_some() {
|
||||
return maybe_blob.as_ref().map(|kzg_verified_blob| {
|
||||
kzg_verified_blob.as_blob().slot.epoch(T::slots_per_epoch())
|
||||
kzg_verified_blob
|
||||
.as_blob()
|
||||
.slot()
|
||||
.epoch(T::slots_per_epoch())
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -418,15 +421,7 @@ impl<T: BeaconChainTypes> OverflowLRUCache<T> {
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
let mut fixed_blobs = FixedVector::default();
|
||||
|
||||
// Initial check to ensure all provided blobs have a consistent block root.
|
||||
for blob in kzg_verified_blobs {
|
||||
let blob_block_root = blob.block_root();
|
||||
if blob_block_root != block_root {
|
||||
return Err(AvailabilityCheckError::InconsistentBlobBlockRoots {
|
||||
block_root,
|
||||
blob_block_root,
|
||||
});
|
||||
}
|
||||
if let Some(blob_opt) = fixed_blobs.get_mut(blob.blob_index() as usize) {
|
||||
*blob_opt = Some(blob);
|
||||
}
|
||||
@@ -651,7 +646,7 @@ impl<T: BeaconChainTypes> OverflowLRUCache<T> {
|
||||
OverflowKey::Blob(_, _) => {
|
||||
KzgVerifiedBlob::<T::EthSpec>::from_ssz_bytes(value_bytes.as_slice())?
|
||||
.as_blob()
|
||||
.slot
|
||||
.slot()
|
||||
.epoch(T::EthSpec::slots_per_epoch())
|
||||
}
|
||||
};
|
||||
@@ -743,9 +738,7 @@ impl ssz::Decode for OverflowKey {
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{
|
||||
blob_verification::{
|
||||
validate_blob_sidecar_for_gossip, verify_kzg_for_blob, GossipVerifiedBlob,
|
||||
},
|
||||
blob_verification::{validate_blob_sidecar_for_gossip, GossipVerifiedBlob},
|
||||
block_verification::PayloadVerificationOutcome,
|
||||
block_verification_types::{AsBlock, BlockImportData},
|
||||
data_availability_checker::STATE_LRU_CAPACITY,
|
||||
@@ -926,12 +919,13 @@ mod test {
|
||||
}
|
||||
info!(log, "done printing kzg commitments");
|
||||
|
||||
let gossip_verified_blobs = if let Some(blobs) = maybe_blobs {
|
||||
Vec::from(blobs)
|
||||
let gossip_verified_blobs = if let Some((kzg_proofs, blobs)) = maybe_blobs {
|
||||
let sidecars = BlobSidecar::build_sidecars(blobs, &block, kzg_proofs).unwrap();
|
||||
Vec::from(sidecars)
|
||||
.into_iter()
|
||||
.map(|signed_blob| {
|
||||
let subnet = signed_blob.message.index;
|
||||
validate_blob_sidecar_for_gossip(signed_blob, subnet, &harness.chain)
|
||||
.map(|sidecar| {
|
||||
let subnet = sidecar.index;
|
||||
validate_blob_sidecar_for_gossip(sidecar, subnet, &harness.chain)
|
||||
.expect("should validate blob")
|
||||
})
|
||||
.collect()
|
||||
@@ -1036,17 +1030,9 @@ mod test {
|
||||
);
|
||||
}
|
||||
|
||||
let kzg = harness
|
||||
.chain
|
||||
.kzg
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.expect("kzg should exist");
|
||||
let mut kzg_verified_blobs = Vec::new();
|
||||
for (blob_index, gossip_blob) in blobs.into_iter().enumerate() {
|
||||
let kzg_verified_blob = verify_kzg_for_blob(gossip_blob.to_blob(), kzg.as_ref())
|
||||
.expect("kzg should verify");
|
||||
kzg_verified_blobs.push(kzg_verified_blob);
|
||||
kzg_verified_blobs.push(gossip_blob.into_inner());
|
||||
let availability = cache
|
||||
.put_kzg_verified_blobs(root, kzg_verified_blobs.clone())
|
||||
.expect("should put blob");
|
||||
@@ -1072,9 +1058,7 @@ mod test {
|
||||
let root = pending_block.import_data.block_root;
|
||||
let mut kzg_verified_blobs = vec![];
|
||||
for gossip_blob in blobs {
|
||||
let kzg_verified_blob = verify_kzg_for_blob(gossip_blob.to_blob(), kzg.as_ref())
|
||||
.expect("kzg should verify");
|
||||
kzg_verified_blobs.push(kzg_verified_blob);
|
||||
kzg_verified_blobs.push(gossip_blob.into_inner());
|
||||
let availability = cache
|
||||
.put_kzg_verified_blobs(root, kzg_verified_blobs.clone())
|
||||
.expect("should put blob");
|
||||
@@ -1198,20 +1182,11 @@ mod test {
|
||||
assert!(cache.critical.read().store_keys.contains(&roots[0]));
|
||||
assert!(cache.critical.read().store_keys.contains(&roots[1]));
|
||||
|
||||
let kzg = harness
|
||||
.chain
|
||||
.kzg
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.expect("kzg should exist");
|
||||
|
||||
let blobs_0 = pending_blobs.pop_front().expect("should have blobs");
|
||||
let expected_blobs = blobs_0.len();
|
||||
let mut kzg_verified_blobs = vec![];
|
||||
for (blob_index, gossip_blob) in blobs_0.into_iter().enumerate() {
|
||||
let kzg_verified_blob = verify_kzg_for_blob(gossip_blob.to_blob(), kzg.as_ref())
|
||||
.expect("kzg should verify");
|
||||
kzg_verified_blobs.push(kzg_verified_blob);
|
||||
kzg_verified_blobs.push(gossip_blob.into_inner());
|
||||
let availability = cache
|
||||
.put_kzg_verified_blobs(roots[0], kzg_verified_blobs.clone())
|
||||
.expect("should put blob");
|
||||
@@ -1278,13 +1253,6 @@ mod test {
|
||||
pending_blobs.push_back(blobs);
|
||||
}
|
||||
|
||||
let kzg = harness
|
||||
.chain
|
||||
.kzg
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.expect("kzg should exist");
|
||||
|
||||
for _ in 0..(n_epochs * capacity) {
|
||||
let pending_block = pending_blocks.pop_front().expect("should have block");
|
||||
let mut pending_block_blobs = pending_blobs.pop_front().expect("should have blobs");
|
||||
@@ -1295,9 +1263,7 @@ mod test {
|
||||
let one_blob = pending_block_blobs
|
||||
.pop()
|
||||
.expect("should have at least one blob");
|
||||
let kzg_verified_blob = verify_kzg_for_blob(one_blob.to_blob(), kzg.as_ref())
|
||||
.expect("kzg should verify");
|
||||
let kzg_verified_blobs = vec![kzg_verified_blob];
|
||||
let kzg_verified_blobs = vec![one_blob.into_inner()];
|
||||
// generate random boolean
|
||||
let block_first = (rand::random::<usize>() % 2) == 0;
|
||||
if block_first {
|
||||
@@ -1418,13 +1384,6 @@ mod test {
|
||||
pending_blobs.push_back(blobs);
|
||||
}
|
||||
|
||||
let kzg = harness
|
||||
.chain
|
||||
.kzg
|
||||
.as_ref()
|
||||
.cloned()
|
||||
.expect("kzg should exist");
|
||||
|
||||
let mut remaining_blobs = HashMap::new();
|
||||
for _ in 0..(n_epochs * capacity) {
|
||||
let pending_block = pending_blocks.pop_front().expect("should have block");
|
||||
@@ -1436,9 +1395,7 @@ mod test {
|
||||
let one_blob = pending_block_blobs
|
||||
.pop()
|
||||
.expect("should have at least one blob");
|
||||
let kzg_verified_blob = verify_kzg_for_blob(one_blob.to_blob(), kzg.as_ref())
|
||||
.expect("kzg should verify");
|
||||
let kzg_verified_blobs = vec![kzg_verified_blob];
|
||||
let kzg_verified_blobs = vec![one_blob.into_inner()];
|
||||
// generate random boolean
|
||||
let block_first = (rand::random::<usize>() % 2) == 0;
|
||||
if block_first {
|
||||
@@ -1551,9 +1508,7 @@ mod test {
|
||||
let additional_blobs = blobs.len();
|
||||
let mut kzg_verified_blobs = vec![];
|
||||
for (i, gossip_blob) in blobs.into_iter().enumerate() {
|
||||
let kzg_verified_blob = verify_kzg_for_blob(gossip_blob.to_blob(), kzg.as_ref())
|
||||
.expect("kzg should verify");
|
||||
kzg_verified_blobs.push(kzg_verified_blob);
|
||||
kzg_verified_blobs.push(gossip_blob.into_inner());
|
||||
let availability = recovered_cache
|
||||
.put_kzg_verified_blobs(root, kzg_verified_blobs.clone())
|
||||
.expect("should put blob");
|
||||
|
||||
Reference in New Issue
Block a user