Batch Verify RPC Blobs (#4934)
This commit is contained in:
parent
46184e5ce4
commit
78ffa378b4
@ -17,8 +17,7 @@ use ssz_types::VariableList;
|
||||
use tree_hash::TreeHash;
|
||||
use types::blob_sidecar::BlobIdentifier;
|
||||
use types::{
|
||||
BeaconStateError, BlobSidecar, BlobSidecarList, CloneConfig, EthSpec, Hash256,
|
||||
SignedBeaconBlockHeader, Slot,
|
||||
BeaconStateError, BlobSidecar, CloneConfig, EthSpec, Hash256, SignedBeaconBlockHeader, Slot,
|
||||
};
|
||||
|
||||
/// An error occurred while validating a gossip blob.
|
||||
@ -279,7 +278,6 @@ impl<T: EthSpec> KzgVerifiedBlob<T> {
|
||||
pub fn new(blob: Arc<BlobSidecar<T>>, kzg: &Kzg) -> Result<Self, KzgError> {
|
||||
verify_kzg_for_blob(blob, kzg)
|
||||
}
|
||||
|
||||
pub fn to_blob(self) -> Arc<BlobSidecar<T>> {
|
||||
self.blob
|
||||
}
|
||||
@ -310,21 +308,51 @@ pub fn verify_kzg_for_blob<T: EthSpec>(
|
||||
kzg: &Kzg,
|
||||
) -> Result<KzgVerifiedBlob<T>, KzgError> {
|
||||
validate_blob::<T>(kzg, &blob.blob, blob.kzg_commitment, blob.kzg_proof)?;
|
||||
|
||||
Ok(KzgVerifiedBlob { blob })
|
||||
}
|
||||
|
||||
pub struct KzgVerifiedBlobList<E: EthSpec> {
|
||||
verified_blobs: Vec<KzgVerifiedBlob<E>>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> KzgVerifiedBlobList<E> {
|
||||
pub fn new<I: IntoIterator<Item = Arc<BlobSidecar<E>>>>(
|
||||
blob_list: I,
|
||||
kzg: &Kzg,
|
||||
) -> Result<Self, KzgError> {
|
||||
let blobs = blob_list.into_iter().collect::<Vec<_>>();
|
||||
verify_kzg_for_blob_list(blobs.iter(), kzg)?;
|
||||
Ok(Self {
|
||||
verified_blobs: blobs
|
||||
.into_iter()
|
||||
.map(|blob| KzgVerifiedBlob { blob })
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<E: EthSpec> IntoIterator for KzgVerifiedBlobList<E> {
|
||||
type Item = KzgVerifiedBlob<E>;
|
||||
type IntoIter = std::vec::IntoIter<Self::Item>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.verified_blobs.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
/// Complete kzg verification for a list of `BlobSidecar`s.
|
||||
/// Returns an error if any of the `BlobSidecar`s fails kzg verification.
|
||||
///
|
||||
/// Note: This function should be preferred over calling `verify_kzg_for_blob`
|
||||
/// in a loop since this function kzg verifies a list of blobs more efficiently.
|
||||
pub fn verify_kzg_for_blob_list<T: EthSpec>(
|
||||
blob_list: &BlobSidecarList<T>,
|
||||
kzg: &Kzg,
|
||||
) -> Result<(), KzgError> {
|
||||
let (blobs, (commitments, proofs)): (Vec<_>, (Vec<_>, Vec<_>)) = blob_list
|
||||
.iter()
|
||||
pub fn verify_kzg_for_blob_list<'a, T: EthSpec, I>(
|
||||
blob_iter: I,
|
||||
kzg: &'a Kzg,
|
||||
) -> Result<(), KzgError>
|
||||
where
|
||||
I: Iterator<Item = &'a Arc<BlobSidecar<T>>>,
|
||||
{
|
||||
let (blobs, (commitments, proofs)): (Vec<_>, (Vec<_>, Vec<_>)) = blob_iter
|
||||
.map(|blob| (&blob.blob, (blob.kzg_commitment, blob.kzg_proof)))
|
||||
.unzip();
|
||||
validate_blobs::<T>(kzg, commitments.as_slice(), blobs, proofs.as_slice())
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::blob_verification::{verify_kzg_for_blob_list, GossipVerifiedBlob, KzgVerifiedBlob};
|
||||
use crate::blob_verification::{verify_kzg_for_blob_list, GossipVerifiedBlob, KzgVerifiedBlobList};
|
||||
use crate::block_verification_types::{
|
||||
AvailabilityPendingExecutedBlock, AvailableExecutedBlock, RpcBlock,
|
||||
};
|
||||
@ -197,15 +197,13 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
block_root: Hash256,
|
||||
blobs: FixedBlobSidecarList<T::EthSpec>,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
let mut verified_blobs = vec![];
|
||||
if let Some(kzg) = self.kzg.as_ref() {
|
||||
for blob in Vec::from(blobs).into_iter().flatten() {
|
||||
verified_blobs
|
||||
.push(KzgVerifiedBlob::new(blob, kzg).map_err(AvailabilityCheckError::Kzg)?);
|
||||
}
|
||||
} else {
|
||||
let Some(kzg) = self.kzg.as_ref() else {
|
||||
return Err(AvailabilityCheckError::KzgNotInitialized);
|
||||
};
|
||||
|
||||
let verified_blobs = KzgVerifiedBlobList::new(Vec::from(blobs).into_iter().flatten(), kzg)
|
||||
.map_err(AvailabilityCheckError::Kzg)?;
|
||||
|
||||
self.availability_cache
|
||||
.put_kzg_verified_blobs(block_root, verified_blobs)
|
||||
}
|
||||
@ -261,7 +259,7 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
.kzg
|
||||
.as_ref()
|
||||
.ok_or(AvailabilityCheckError::KzgNotInitialized)?;
|
||||
verify_kzg_for_blob_list(&blob_list, kzg)
|
||||
verify_kzg_for_blob_list(blob_list.iter(), kzg)
|
||||
.map_err(AvailabilityCheckError::Kzg)?;
|
||||
Some(blob_list)
|
||||
} else {
|
||||
@ -302,7 +300,7 @@ impl<T: BeaconChainTypes> DataAvailabilityChecker<T> {
|
||||
.kzg
|
||||
.as_ref()
|
||||
.ok_or(AvailabilityCheckError::KzgNotInitialized)?;
|
||||
verify_kzg_for_blob_list(&all_blobs, kzg)?;
|
||||
verify_kzg_for_blob_list(all_blobs.iter(), kzg)?;
|
||||
}
|
||||
|
||||
for block in blocks {
|
||||
|
@ -414,10 +414,10 @@ impl<T: BeaconChainTypes> OverflowLRUCache<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn put_kzg_verified_blobs(
|
||||
pub fn put_kzg_verified_blobs<I: IntoIterator<Item = KzgVerifiedBlob<T::EthSpec>>>(
|
||||
&self,
|
||||
block_root: Hash256,
|
||||
kzg_verified_blobs: Vec<KzgVerifiedBlob<T::EthSpec>>,
|
||||
kzg_verified_blobs: I,
|
||||
) -> Result<Availability<T::EthSpec>, AvailabilityCheckError> {
|
||||
let mut fixed_blobs = FixedVector::default();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user