From 5b883dbb1a4bf6365466907321f39c9d491f8b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Kr=C3=BCger?= Date: Thu, 15 Feb 2024 18:17:20 +0100 Subject: [PATCH] feat: Use new error types for `BlockStoreError` --- Cargo.lock | 3 +- .../benches/artificially_slow_blockstore.rs | 18 ++-- car-mirror/src/cache.rs | 87 +++++++++++++------ car-mirror/src/dag_walk.rs | 4 +- car-mirror/src/error.rs | 19 +--- 5 files changed, 79 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 75495d2..c04ed00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2570,12 +2570,13 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "wnfs-common" version = "0.1.26" -source = "git+https://github.com/wnfs-wg/rs-wnfs?branch=matheus23/evolve-trait#adc78239d7c9351f21ea33d8a6a14a77e5d8213d" +source = "git+https://github.com/wnfs-wg/rs-wnfs?branch=matheus23/evolve-trait#3e2ae56bb1f54cba75968ff189ef81c3442640ac" dependencies = [ "anyhow", "async-once-cell", "bytes", "chrono", + "cid", "dashmap", "futures", "libipld", diff --git a/car-mirror-benches/benches/artificially_slow_blockstore.rs b/car-mirror-benches/benches/artificially_slow_blockstore.rs index 7e29f01..f2af76b 100644 --- a/car-mirror-benches/benches/artificially_slow_blockstore.rs +++ b/car-mirror-benches/benches/artificially_slow_blockstore.rs @@ -9,7 +9,7 @@ use car_mirror::{ use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use libipld::Cid; use std::time::Duration; -use wnfs_common::{utils::CondSend, BlockStore, MemoryBlockStore}; +use wnfs_common::{utils::CondSend, BlockStore, BlockStoreError, MemoryBlockStore}; pub fn push_throttled(c: &mut Criterion) { let mut rvg = car_mirror::test_utils::Rvg::deterministic(); @@ -116,20 +116,28 @@ pub fn pull_throttled(c: &mut Criterion) { struct ThrottledBlockStore(MemoryBlockStore); impl BlockStore for ThrottledBlockStore { - async fn get_block(&self, cid: &Cid) -> Result { + async fn get_block(&self, cid: &Cid) -> Result { async_std::task::sleep(Duration::from_micros(50)).await; // Block fetching is artifically slowed by 50 microseconds self.0.get_block(cid).await } - async fn put_block(&self, bytes: impl Into + CondSend, codec: u64) -> Result { + async fn put_block( + &self, + bytes: impl Into + CondSend, + codec: u64, + ) -> Result { self.0.put_block(bytes, codec).await } - async fn put_block_keyed(&self, cid: Cid, bytes: impl Into + CondSend) -> Result<()> { + async fn put_block_keyed( + &self, + cid: Cid, + bytes: impl Into + CondSend, + ) -> Result<(), BlockStoreError> { self.0.put_block_keyed(cid, bytes).await } - async fn has_block(&self, cid: &Cid) -> Result { + async fn has_block(&self, cid: &Cid) -> Result { async_std::task::sleep(Duration::from_micros(50)).await; // Block fetching is artifically slowed by 50 microseconds self.0.has_block(cid).await } diff --git a/car-mirror/src/cache.rs b/car-mirror/src/cache.rs index 21aeff4..6613a24 100644 --- a/car-mirror/src/cache.rs +++ b/car-mirror/src/cache.rs @@ -1,10 +1,9 @@ use crate::common::references; -use anyhow::Result; use futures::Future; use libipld::{Cid, IpldCodec}; use wnfs_common::{ utils::{CondSend, CondSync}, - BlockStore, + BlockStore, BlockStoreError, }; /// This trait abstracts caches used by the car mirror implementation. @@ -25,14 +24,14 @@ pub trait Cache: CondSync { fn get_references_cache( &self, cid: Cid, - ) -> impl Future>>> + CondSend; + ) -> impl Future>, BlockStoreError>> + CondSend; /// Populates the references cache for given CID with given references. fn put_references_cache( &self, cid: Cid, references: Vec, - ) -> impl Future> + CondSend; + ) -> impl Future> + CondSend; /// Find out any CIDs that are linked to from the block with given CID. /// @@ -43,7 +42,7 @@ pub trait Cache: CondSync { &self, cid: Cid, store: &impl BlockStore, - ) -> impl Future>> + CondSend { + ) -> impl Future, BlockStoreError>> + CondSend { async move { // raw blocks don't have further links let raw_codec: u64 = IpldCodec::Raw.into(); @@ -64,21 +63,29 @@ pub trait Cache: CondSync { } impl Cache for &C { - async fn get_references_cache(&self, cid: Cid) -> Result>> { + async fn get_references_cache(&self, cid: Cid) -> Result>, BlockStoreError> { (**self).get_references_cache(cid).await } - async fn put_references_cache(&self, cid: Cid, references: Vec) -> Result<()> { + async fn put_references_cache( + &self, + cid: Cid, + references: Vec, + ) -> Result<(), BlockStoreError> { (**self).put_references_cache(cid, references).await } } impl Cache for Box { - async fn get_references_cache(&self, cid: Cid) -> Result>> { + async fn get_references_cache(&self, cid: Cid) -> Result>, BlockStoreError> { (**self).get_references_cache(cid).await } - async fn put_references_cache(&self, cid: Cid, references: Vec) -> Result<()> { + async fn put_references_cache( + &self, + cid: Cid, + references: Vec, + ) -> Result<(), BlockStoreError> { (**self).put_references_cache(cid, references).await } } @@ -88,11 +95,11 @@ impl Cache for Box { pub struct NoCache; impl Cache for NoCache { - async fn get_references_cache(&self, _: Cid) -> Result>> { + async fn get_references_cache(&self, _: Cid) -> Result>, BlockStoreError> { Ok(None) } - async fn put_references_cache(&self, _: Cid, _: Vec) -> Result<()> { + async fn put_references_cache(&self, _: Cid, _: Vec) -> Result<(), BlockStoreError> { Ok(()) } } @@ -103,7 +110,6 @@ pub use quick_cache::*; #[cfg(feature = "quick_cache")] mod quick_cache { use super::Cache; - use anyhow::{anyhow, Result}; use bytes::Bytes; use libipld::Cid; use quick_cache::{sync, OptionsBuilder, Weighter}; @@ -157,11 +163,18 @@ mod quick_cache { } impl Cache for InMemoryCache { - async fn get_references_cache(&self, cid: Cid) -> Result>> { + async fn get_references_cache( + &self, + cid: Cid, + ) -> Result>, BlockStoreError> { Ok(self.references.get(&cid)) } - async fn put_references_cache(&self, cid: Cid, references: Vec) -> Result<()> { + async fn put_references_cache( + &self, + cid: Cid, + references: Vec, + ) -> Result<(), BlockStoreError> { self.references.insert(cid, references); Ok(()) } @@ -191,23 +204,20 @@ mod quick_cache { } impl BlockStore for CacheMissing { - async fn get_block(&self, cid: &Cid) -> Result { + async fn get_block(&self, cid: &Cid) -> Result { match self.has_blocks.get_value_or_guard_async(cid).await { - Ok(false) => Err(anyhow!(BlockStoreError::CIDNotFound(*cid))), + Ok(false) => Err(BlockStoreError::CIDNotFound(*cid)), Ok(true) => self.inner.get_block(cid).await, Err(guard) => match self.inner.get_block(cid).await { Ok(block) => { let _ignore_meantime_eviction = guard.insert(true); Ok(block) } - Err(e) => { - if let Some(BlockStoreError::CIDNotFound(_)) = e.downcast_ref() { - let _ignore_meantime_eviction = guard.insert(false); - Err(e) - } else { - Err(e) - } + e @ Err(BlockStoreError::CIDNotFound(_)) => { + let _ignore_meantime_eviction = guard.insert(false); + e } + Err(e) => Err(e), }, } } @@ -216,17 +226,31 @@ mod quick_cache { &self, cid: Cid, bytes: impl Into + CondSend, - ) -> Result<()> { + ) -> Result<(), BlockStoreError> { self.inner.put_block_keyed(cid, bytes).await?; self.has_blocks.insert(cid, true); Ok(()) } - async fn has_block(&self, cid: &Cid) -> Result { + async fn has_block(&self, cid: &Cid) -> Result { self.has_blocks .get_or_insert_async(cid, self.inner.has_block(cid)) .await } + + async fn put_block( + &self, + bytes: impl Into + CondSend, + codec: u64, + ) -> Result { + let cid = self.inner.put_block(bytes, codec).await?; + self.has_blocks.insert(cid, true); + Ok(cid) + } + + fn create_cid(&self, bytes: &[u8], codec: u64) -> Result { + self.inner.create_cid(bytes, codec) + } } #[derive(Debug, Clone)] @@ -293,7 +317,7 @@ mod tests { use libipld::{cbor::DagCborCodec, Cid, Ipld, IpldCodec}; use std::{collections::HashMap, sync::RwLock}; use testresult::TestResult; - use wnfs_common::{encode, BlockStore, MemoryBlockStore}; + use wnfs_common::{encode, BlockStore, BlockStoreError, MemoryBlockStore}; #[derive(Debug, Default)] struct HashMapCache { @@ -301,11 +325,18 @@ mod tests { } impl Cache for HashMapCache { - async fn get_references_cache(&self, cid: Cid) -> Result>> { + async fn get_references_cache( + &self, + cid: Cid, + ) -> Result>, BlockStoreError> { Ok(self.references.read().unwrap().get(&cid).cloned()) } - async fn put_references_cache(&self, cid: Cid, references: Vec) -> Result<()> { + async fn put_references_cache( + &self, + cid: Cid, + references: Vec, + ) -> Result<(), BlockStoreError> { self.references.write().unwrap().insert(cid, references); Ok(()) } diff --git a/car-mirror/src/dag_walk.rs b/car-mirror/src/dag_walk.rs index fa7edcf..25238ca 100644 --- a/car-mirror/src/dag_walk.rs +++ b/car-mirror/src/dag_walk.rs @@ -35,9 +35,7 @@ impl TraversedItem { pub fn to_cid(self) -> Result { match self { Self::Have(cid) => Ok(cid), - Self::Missing(cid) => Err(Error::BlockStoreError( - BlockStoreError::CIDNotFound(cid).into(), - )), + Self::Missing(cid) => Err(Error::BlockStoreError(BlockStoreError::CIDNotFound(cid))), } } } diff --git a/car-mirror/src/error.rs b/car-mirror/src/error.rs index 1dbc1ac..2d76029 100644 --- a/car-mirror/src/error.rs +++ b/car-mirror/src/error.rs @@ -1,4 +1,5 @@ use libipld::Cid; +use wnfs_common::BlockStoreError; use crate::incremental_verification::BlockState; @@ -31,17 +32,9 @@ pub enum Error { cid: Cid, }, - /// This error is raised when the hash function that the `BlockStore` uses a different hashing function - /// than the blocks which are received over the wire. - /// This error will be removed in the future, when the block store trait gets modified to support specifying - /// the hash function. - #[error("BlockStore uses an incompatible hashing function: CID mismatched, expected {cid}, got {actual_cid}")] - BlockStoreIncompatible { - /// The expected CID - cid: Box, - /// The CID returned from the BlockStore implementation - actual_cid: Box, - }, + /// An error rasied from the blockstore. + #[error("BlockStore error: {0}")] + BlockStoreError(#[from] BlockStoreError), // ------------- // Anyhow Errors @@ -50,10 +43,6 @@ pub enum Error { #[error("Error during block parsing: {0}")] ParsingError(anyhow::Error), - /// An error rasied from the blockstore. - #[error("BlockStore error: {0}")] - BlockStoreError(anyhow::Error), - // ---------- // Sub-errors // ----------