Skip to content

Commit

Permalink
feat: Add get_block_keyed to trait BlockStore, fix wasm
Browse files Browse the repository at this point in the history
  • Loading branch information
matheus23 committed Feb 15, 2024
1 parent e2a2e2f commit 32e3528
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 36 deletions.
47 changes: 36 additions & 11 deletions wnfs-common/src/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,35 @@ pub trait BlockStore: CondSync {
///
/// This funciton allows the blockstore to choose the hashing function itself.
/// The hashing function that was chosen will be readable from the `Cid` metadata.
///
/// If you need control over the concrete hashing function that's used, see `put_block_keyed`.
fn put_block(
&self,
bytes: impl Into<Bytes> + CondSend,
codec: u64,
) -> impl Future<Output = Result<Cid>> + CondSend;
) -> impl Future<Output = Result<Cid>> + CondSend {
let bytes = bytes.into();
async move {
let cid = self.create_cid(&bytes, codec)?;
self.put_block_keyed(cid, bytes).await?;
Ok(cid)
}
}

/// Put a block of data into this blockstore. The block's CID needs to match the CID given.
///
/// It's up to the blockstore whether to check this fact or assume it when this function is called.
///
/// The default implementation of `put_block` will use this function under the hood and use
/// the correct CID provided by the `create_cid` function.
///
/// This is useful to be able to add blocks that were generated from other
/// clients with differently configured hashing functions to this blockstore.
fn put_block_keyed(
&self,
cid: Cid,
bytes: impl Into<Bytes> + CondSend,
) -> impl Future<Output = Result<()>> + CondSend;

/// Find out whether a call to `get_block` would return with a result or not.
///
Expand Down Expand Up @@ -108,6 +132,10 @@ impl<B: BlockStore> BlockStore for &B {
(**self).put_block(bytes, codec).await
}

async fn put_block_keyed(&self, cid: Cid, bytes: impl Into<Bytes> + CondSend) -> Result<()> {
(**self).put_block_keyed(cid, bytes).await
}

async fn has_block(&self, cid: &Cid) -> Result<bool> {
(**self).has_block(cid).await
}
Expand All @@ -126,6 +154,10 @@ impl<B: BlockStore> BlockStore for Box<B> {
(**self).put_block(bytes, codec).await
}

async fn put_block_keyed(&self, cid: Cid, bytes: impl Into<Bytes> + CondSend) -> Result<()> {
(**self).put_block_keyed(cid, bytes).await
}

async fn has_block(&self, cid: &Cid) -> Result<bool> {
(**self).has_block(cid).await
}
Expand Down Expand Up @@ -165,17 +197,10 @@ impl BlockStore for MemoryBlockStore {
Ok(bytes)
}

async fn put_block(&self, bytes: impl Into<Bytes> + CondSend, codec: u64) -> Result<Cid> {
// Convert the bytes into a Bytes object
let bytes: Bytes = bytes.into();
async fn put_block_keyed(&self, cid: Cid, bytes: impl Into<Bytes> + CondSend) -> Result<()> {
self.0.lock().insert(cid, bytes.into());

// Try to build the CID from the bytes and codec
let cid = self.create_cid(&bytes, codec)?;

// Insert the bytes into the HashMap using the CID as the key
self.0.lock().insert(cid, bytes);

Ok(cid)
Ok(())
}

async fn has_block(&self, cid: &Cid) -> Result<bool> {
Expand Down
5 changes: 5 additions & 0 deletions wnfs-common/src/utils/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ impl BlockStore for SnapshotBlockStore {
self.inner.put_block(bytes, codec).await
}

#[inline]
async fn put_block_keyed(&self, cid: Cid, bytes: impl Into<Bytes> + CondSend) -> Result<()> {
self.inner.put_block_keyed(cid, bytes).await
}

#[inline]
async fn has_block(&self, cid: &Cid) -> Result<bool> {
self.inner.has_block(cid).await
Expand Down
20 changes: 8 additions & 12 deletions wnfs-wasm/src/fs/blockstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ extern "C" {
#[wasm_bindgen(typescript_type = "BlockStore")]
pub type BlockStore;

#[wasm_bindgen(method, js_name = "putBlock")]
pub(crate) fn put_block(store: &BlockStore, bytes: Vec<u8>, codec: u32) -> Promise;

#[wasm_bindgen(method, js_name = "hasBlock")]
pub(crate) fn has_block(store: &BlockStore, cid: Vec<u8>) -> Promise;
#[wasm_bindgen(method, js_name = "putBlockKeyed")]
pub(crate) fn put_block_keyed(store: &BlockStore, cid: Vec<u8>, bytes: Vec<u8>) -> Promise;

#[wasm_bindgen(method, js_name = "getBlock")]
pub(crate) fn get_block(store: &BlockStore, cid: Vec<u8>) -> Promise;

#[wasm_bindgen(method, js_name = "hasBlock")]
pub(crate) fn has_block(store: &BlockStore, cid: Vec<u8>) -> Promise;
}

//--------------------------------------------------------------------------------------------------
Expand All @@ -41,18 +41,14 @@ pub struct ForeignBlockStore(pub(crate) BlockStore);
//--------------------------------------------------------------------------------------------------

impl WnfsBlockStore for ForeignBlockStore {
async fn put_block(&self, bytes: impl Into<Bytes>, codec: u64) -> Result<Cid> {
async fn put_block_keyed(&self, cid: Cid, bytes: impl Into<Bytes>) -> Result<()> {
let bytes: Bytes = bytes.into();

let value = JsFuture::from(self.0.put_block(bytes.into(), codec.try_into()?))
JsFuture::from(self.0.put_block_keyed(cid.to_bytes(), bytes.into()))
.await
.map_err(anyhow_error("Cannot put block: {:?}"))?;

// Convert the value to a vector of bytes.
let bytes = Uint8Array::new(&value).to_vec();

// Construct CID from the bytes.
Ok(Cid::try_from(&bytes[..])?)
Ok(())
}

async fn get_block(&self, cid: &Cid) -> Result<Bytes> {
Expand Down
3 changes: 2 additions & 1 deletion wnfs-wasm/src/fs/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use wasm_bindgen::prelude::wasm_bindgen;
#[wasm_bindgen(typescript_custom_section)]
const TS_BLOCKSTORE: &'static str = r#"
export interface BlockStore {
putBlock(bytes: Uint8Array, code: number): Promise<Uint8Array>;
putBlockKeyed(cid: Uint8Array, bytes: Uint8Array): Promise<void>;
getBlock(cid: Uint8Array): Promise<Uint8Array | undefined>;
hasBlock(cid: Uint8Array): Promise<boolean>;
}
"#;
8 changes: 3 additions & 5 deletions wnfs-wasm/tests/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ class MemoryBlockStore {
}

/** Retrieves an array of bytes from the block store with given CID. */
async putBlock(bytes: Uint8Array, codec: number): Promise<Uint8Array> {
const hash = await sha256.digest(bytes);
const cid = CID.create(1, codec, hash);
this.store.set(cid.toString(), bytes);
return cid.bytes;
async putBlockKeyed(cid: Uint8Array, bytes: Uint8Array): Promise<void> {
const decodedCid = CID.decode(cid);
this.store.set(decodedCid.toString(), bytes);
}

/** Finds out whether a block is retrievable from this blockstore */
Expand Down
2 changes: 1 addition & 1 deletion wnfs-wasm/tests/public.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,6 @@ test.describe("PublicDirectory", () => {
});

expect(result).not.toBeUndefined();
expect(result).toEqual("bafkreibm6jg3ux5qumhcn2b3flc3tyu6dmlb4xa7u5bf44yegnrjhc4yeq");
expect(result).toEqual("bafkr4ihkr4ld3m4gqkjf4reryxsy2s5tkbxprqkow6fin2iiyvreuzzab4");
});
});
15 changes: 9 additions & 6 deletions wnfs/examples/tiered_blockstores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,19 @@ struct TieredBlockStore<H: BlockStore, C: BlockStore> {

impl<H: BlockStore, C: BlockStore> BlockStore for TieredBlockStore<H, C> {
async fn get_block(&self, cid: &Cid) -> Result<Bytes> {
match self.hot.get_block(cid).await {
Ok(block) => Ok(block),
// We could technically get better about this
// and only match "NotFound" errors.
Err(_) => self.cold.get_block(cid).await,
if self.hot.has_block(cid).await? {
self.hot.get_block(cid).await
} else {
self.cold.get_block(cid).await
}
}

async fn put_block(&self, bytes: impl Into<Bytes> + CondSend, codec: u64) -> Result<Cid> {
self.hot.put_block(bytes.into(), codec).await
self.hot.put_block(bytes, codec).await
}

async fn put_block_keyed(&self, cid: Cid, bytes: impl Into<Bytes> + CondSend) -> Result<()> {
self.hot.put_block_keyed(cid, bytes).await
}

async fn has_block(&self, cid: &Cid) -> Result<bool> {
Expand Down

0 comments on commit 32e3528

Please sign in to comment.