From 50ab155b8dd31dfada0ee030c65f55ba5d15d86f Mon Sep 17 00:00:00 2001 From: Ayush Dubey <61616662+Ayushdubey86@users.noreply.github.com> Date: Thu, 22 May 2025 18:31:10 +0530 Subject: [PATCH] =?UTF-8?q?chore:=20Implementing=20get=5Fby=5Fversioned=5F?= =?UTF-8?q?hashes=5Fv2=20for=20InMemoryBlobStre=20a=E2=80=A6=20(#16390)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> Co-authored-by: Matthias Seitz --- crates/transaction-pool/src/blobstore/disk.rs | 62 ++++++++++++++++++- crates/transaction-pool/src/blobstore/mem.rs | 22 ++++++- crates/transaction-pool/src/blobstore/mod.rs | 7 +++ 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/crates/transaction-pool/src/blobstore/disk.rs b/crates/transaction-pool/src/blobstore/disk.rs index a3520b9757..76e6f61eef 100644 --- a/crates/transaction-pool/src/blobstore/disk.rs +++ b/crates/transaction-pool/src/blobstore/disk.rs @@ -194,9 +194,67 @@ impl BlobStore for DiskFileBlobStore { fn get_by_versioned_hashes_v2( &self, - _versioned_hashes: &[B256], + versioned_hashes: &[B256], ) -> Result>, BlobStoreError> { - Ok(None) + // we must return the blobs in order but we don't necessarily find them in the requested + // order + let mut result = vec![None; versioned_hashes.len()]; + + // first scan all cached full sidecars + for (_tx_hash, blob_sidecar) in self.inner.blob_cache.lock().iter() { + if let Some(blob_sidecar) = blob_sidecar.as_eip7594() { + for (hash_idx, match_result) in + blob_sidecar.match_versioned_hashes(versioned_hashes) + { + result[hash_idx] = Some(match_result); + } + } + + // return early if all blobs are found. + if result.iter().all(|blob| blob.is_some()) { + // got all blobs, can return early + return Ok(Some(result.into_iter().map(Option::unwrap).collect())) + } + } + + // not all versioned hashes were found, try to look up a matching tx + let mut missing_tx_hashes = Vec::new(); + + { + let mut versioned_to_txhashes = self.inner.versioned_hashes_to_txhash.lock(); + for (idx, _) in + result.iter().enumerate().filter(|(_, blob_and_proof)| blob_and_proof.is_none()) + { + // this is safe because the result vec has the same len + let versioned_hash = versioned_hashes[idx]; + if let Some(tx_hash) = versioned_to_txhashes.get(&versioned_hash).copied() { + missing_tx_hashes.push(tx_hash); + } + } + } + + // if we have missing blobs, try to read them from disk and try again + if !missing_tx_hashes.is_empty() { + let blobs_from_disk = self.inner.read_many_decoded(missing_tx_hashes); + for (_, blob_sidecar) in blobs_from_disk { + if let Some(blob_sidecar) = blob_sidecar.as_eip7594() { + for (hash_idx, match_result) in + blob_sidecar.match_versioned_hashes(versioned_hashes) + { + if result[hash_idx].is_none() { + result[hash_idx] = Some(match_result); + } + } + } + } + } + + // only return the blobs if we found all requested versioned hashes + if result.iter().all(|blob| blob.is_some()) { + Ok(Some(result.into_iter().map(Option::unwrap).collect())) + } else { + Ok(None) + } } fn data_size_hint(&self) -> Option { diff --git a/crates/transaction-pool/src/blobstore/mem.rs b/crates/transaction-pool/src/blobstore/mem.rs index 89655c2c23..44dff1cceb 100644 --- a/crates/transaction-pool/src/blobstore/mem.rs +++ b/crates/transaction-pool/src/blobstore/mem.rs @@ -127,9 +127,27 @@ impl BlobStore for InMemoryBlobStore { fn get_by_versioned_hashes_v2( &self, - _versioned_hashes: &[B256], + versioned_hashes: &[B256], ) -> Result>, BlobStoreError> { - Ok(None) + let mut result = vec![None; versioned_hashes.len()]; + for (_tx_hash, blob_sidecar) in self.inner.store.read().iter() { + if let Some(blob_sidecar) = blob_sidecar.as_eip7594() { + for (hash_idx, match_result) in + blob_sidecar.match_versioned_hashes(versioned_hashes) + { + result[hash_idx] = Some(match_result); + } + } + + if result.iter().all(|blob| blob.is_some()) { + break; + } + } + if result.iter().all(|blob| blob.is_some()) { + Ok(Some(result.into_iter().map(Option::unwrap).collect())) + } else { + Ok(None) + } } fn data_size_hint(&self) -> Option { diff --git a/crates/transaction-pool/src/blobstore/mod.rs b/crates/transaction-pool/src/blobstore/mod.rs index 603b781665..29844994bc 100644 --- a/crates/transaction-pool/src/blobstore/mod.rs +++ b/crates/transaction-pool/src/blobstore/mod.rs @@ -86,6 +86,13 @@ pub trait BlobStore: fmt::Debug + Send + Sync + 'static { /// Return the [`BlobAndProofV2`]s for a list of blob versioned hashes. /// Blobs and proofs are returned only if they are present for _all_ requested /// versioned hashes. + /// + /// This differs from [`BlobStore::get_by_versioned_hashes_v1`] in that it also returns all the + /// cell proofs in [`BlobAndProofV2`] supported by the EIP-7594 blob sidecar variant. + /// + /// The response also differs from [`BlobStore::get_by_versioned_hashes_v1`] in that this + /// returns `None` if any of the requested versioned hashes are not present in the blob store: + /// e.g. where v1 would return `[A, None, C]` v2 would return `None`. See also fn get_by_versioned_hashes_v2( &self, versioned_hashes: &[B256],