Skip to content

Commit

Permalink
Update interface
Browse files Browse the repository at this point in the history
  • Loading branch information
grod220 committed Jul 8, 2024
1 parent 483ea08 commit 5502149
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 65 deletions.
5 changes: 5 additions & 0 deletions .changeset/warm-shrimps-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@penumbra-zone/wasm': minor
---

Internally use dependency injection for storage for easier testing
35 changes: 22 additions & 13 deletions packages/wasm/crate/src/database/indexed_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ use indexed_db_futures::idb_object_store::IdbObjectStoreParameters;
use indexed_db_futures::prelude::{IdbOpenDbRequestLike, OpenDbRequest};
use indexed_db_futures::{IdbDatabase, IdbKeyPath, IdbQuerySource, IdbVersionChangeEvent};
use serde::de::DeserializeOwned;
use wasm_bindgen::{JsCast, JsValue};
use serde::Serialize;
use wasm_bindgen::JsValue;
use web_sys::IdbTransactionMode::Readwrite;

use crate::database::interface::Database;
Expand Down Expand Up @@ -65,21 +66,27 @@ async fn mock_test_database(mut db_req: OpenDbRequest) -> OpenDbRequest {
}

impl Database for IdbDatabase {
async fn get<T, K>(&self, table: &str, key: K, index: Option<&str>) -> WasmResult<Option<T>>
async fn get<T, K>(&self, table: &str, key: K) -> WasmResult<Option<T>>
where
T: DeserializeOwned,
K: Into<JsValue>,
{
let tx = self.transaction_on_one(table)?;
let store = tx.object_store(table)?;

let js_value = match index {
Some(i) => store.index(i)?.get_owned(key)?.await?,
None => store.get_owned(key)?.await?,
};

let js_value = store.get_owned(key)?.await?;
let result = js_value.map(serde_wasm_bindgen::from_value).transpose()?;
Ok(result)
}

async fn get_with_index<T, K>(&self, table: &str, key: K, index: &str) -> WasmResult<Option<T>>
where
T: DeserializeOwned,
K: Into<JsValue>,
{
let tx = self.transaction_on_one(table)?;
let store = tx.object_store(table)?;
let js_value = store.index(index)?.get_owned(key)?.await?;
let result = js_value.map(serde_wasm_bindgen::from_value).transpose()?;
Ok(result)
}

Expand Down Expand Up @@ -107,24 +114,26 @@ impl Database for IdbDatabase {
Ok(serialized)
}

async fn put<V>(&self, table: &str, value: V) -> WasmResult<()>
async fn put<V>(&self, table: &str, value: &V) -> WasmResult<()>
where
V: Into<JsValue>,
V: Serialize + ?Sized,
{
let tx = self.transaction_on_one_with_mode(table, Readwrite)?;
let store = tx.object_store(table)?;
store.put_val_owned(value)?;
let serialized = serde_wasm_bindgen::to_value(value)?;
store.put_val_owned(serialized)?;
Ok(())
}

async fn put_with_key<K, V>(&self, table: &str, key: K, value: &V) -> WasmResult<()>
where
K: Into<JsValue>,
V: JsCast,
V: Serialize + ?Sized,
{
let tx = self.transaction_on_one_with_mode(table, Readwrite)?;
let store = tx.object_store(table)?;
store.put_key_val_owned(key, value)?;
let serialized = serde_wasm_bindgen::to_value(value)?;
store.put_key_val_owned(key, &serialized)?;
Ok(())
}
}
20 changes: 14 additions & 6 deletions packages/wasm/crate/src/database/interface.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
use std::future::Future;

use serde::de::DeserializeOwned;
use wasm_bindgen::{JsCast, JsValue};
use serde::Serialize;
use wasm_bindgen::JsValue;

use crate::error::WasmResult;

pub trait Database {
fn get<T, K>(
fn get<T, K>(&self, table: &str, key: K) -> impl Future<Output = WasmResult<Option<T>>>
where
T: DeserializeOwned,
K: Into<JsValue>;

fn get_with_index<T, K>(
&self,
table: &str,
key: K,
index: Option<&str>,
index: &str,
) -> impl Future<Output = WasmResult<Option<T>>>
where
T: DeserializeOwned,
Expand All @@ -20,11 +26,13 @@ pub trait Database {
fn get_latest<T>(&self, table: &str) -> impl Future<Output = WasmResult<Option<T>>>
where
T: DeserializeOwned;

fn get_all<T: DeserializeOwned>(&self, table: &str)
-> impl Future<Output = WasmResult<Vec<T>>>;
fn put<V>(&self, table: &str, value: V) -> impl Future<Output = WasmResult<()>>

fn put<V>(&self, table: &str, value: &V) -> impl Future<Output = WasmResult<()>>
where
V: Into<JsValue>;
V: Serialize + ?Sized;

fn put_with_key<K, V>(
&self,
Expand All @@ -34,5 +42,5 @@ pub trait Database {
) -> impl Future<Output = WasmResult<()>>
where
K: Into<JsValue>,
V: JsCast;
V: Serialize + ?Sized;
}
23 changes: 16 additions & 7 deletions packages/wasm/crate/src/database/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::collections::HashMap;
use std::rc::Rc;

use serde::de::DeserializeOwned;
use wasm_bindgen::{JsCast, JsValue};
use serde::Serialize;
use wasm_bindgen::JsValue;

use crate::database::interface::Database;
use crate::error::WasmResult;
Expand Down Expand Up @@ -55,7 +56,7 @@ impl MockDb {
}

impl Database for MockDb {
async fn get<T, K>(&self, table: &str, key: K, _index: Option<&str>) -> WasmResult<Option<T>>
async fn get<T, K>(&self, table: &str, key: K) -> WasmResult<Option<T>>
where
T: DeserializeOwned,
K: Into<JsValue>,
Expand All @@ -71,6 +72,14 @@ impl Database for MockDb {
Ok(result)
}

async fn get_with_index<T, K>(&self, _: &str, _: K, _: &str) -> WasmResult<Option<T>>
where
T: DeserializeOwned,
K: Into<JsValue>,
{
unimplemented!()
}

async fn get_latest<T>(&self, _table: &str) -> WasmResult<Option<T>>
where
T: DeserializeOwned,
Expand All @@ -92,22 +101,22 @@ impl Database for MockDb {
Ok(results)
}

async fn put<V>(&self, _table: &str, _value: V) -> WasmResult<()>
async fn put<V>(&self, _table: &str, _value: &V) -> WasmResult<()>
where
V: Into<JsValue>,
V: Serialize + ?Sized,
{
unimplemented!()
}

async fn put_with_key<K, V>(&self, table: &str, key: K, value: &V) -> WasmResult<()>
where
K: Into<JsValue>,
V: JsCast,
V: Serialize + ?Sized,
{
let table = self.get_table(table);
let key = key.into().as_string().unwrap_or_default();

table.borrow_mut().insert(key, value.into());
let serialized = serde_wasm_bindgen::to_value(value)?;
table.borrow_mut().insert(key, serialized);

Ok(())
}
Expand Down
39 changes: 13 additions & 26 deletions packages/wasm/crate/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,21 +120,17 @@ impl<T: Database> Storage<T> {

pub async fn get_asset(&self, id: &Id) -> WasmResult<Option<Metadata>> {
let key = byte_array_to_base64(&id.to_proto().inner);
let result: Option<Metadata> = self.db.get(&self.tables.assets, key, None).await?;
let result: Option<Metadata> = self.db.get(&self.tables.assets, key).await?;
Ok(result)
}

pub async fn add_asset(&self, metadata: &Metadata) -> WasmResult<()> {
let metadata_js = serde_wasm_bindgen::to_value(&metadata.to_proto())?;
self.db.put(&self.tables.assets, &metadata_js).await?;
self.db.put(&self.tables.assets, metadata).await?;
Ok(())
}

pub async fn get_full_sync_height(&self) -> WasmResult<Option<u64>> {
let result = self
.db
.get(&self.tables.full_sync_height, "height", None)
.await?;
let result = self.db.get(&self.tables.full_sync_height, "height").await?;
Ok(result)
}

Expand All @@ -143,7 +139,7 @@ impl<T: Database> Storage<T> {
commitment: &note::StateCommitment,
) -> WasmResult<Option<SpendableNoteRecord>> {
let key = byte_array_to_base64(&commitment.to_proto().inner);
let result = self.db.get(&self.tables.spendable_notes, key, None).await?;
let result = self.db.get(&self.tables.spendable_notes, key).await?;
Ok(result)
}

Expand All @@ -154,25 +150,22 @@ impl<T: Database> Storage<T> {
let key = byte_array_to_base64(&nullifier.to_proto().inner);
let result = self
.db
.get(&self.tables.spendable_notes, key, Some("nullifier"))
.get_with_index(&self.tables.spendable_notes, key, "nullifier")
.await?;
Ok(result)
}

pub async fn store_advice(&self, note: Note) -> WasmResult<()> {
let note_proto: penumbra_proto::core::component::shielded_pool::v1::Note =
note.clone().into();
let note_js = serde_wasm_bindgen::to_value(&note_proto)?;
let key = byte_array_to_base64(&note.commit().to_proto().inner);
self.db
.put_with_key(&self.tables.advice_notes, key, &note_js)
.put_with_key(&self.tables.advice_notes, key, &note)
.await?;
Ok(())
}

pub async fn read_advice(&self, commitment: note::StateCommitment) -> WasmResult<Option<Note>> {
let key = byte_array_to_base64(&commitment.to_proto().inner);
let result = self.db.get(&self.tables.advice_notes, key, None).await?;
let result = self.db.get(&self.tables.advice_notes, key).await?;
Ok(result)
}

Expand All @@ -181,7 +174,7 @@ impl<T: Database> Storage<T> {
swap_commitment: StateCommitment,
) -> WasmResult<Option<SwapRecord>> {
let key = byte_array_to_base64(&swap_commitment.inner);
let result = self.db.get(&self.tables.advice_notes, key, None).await?;
let result = self.db.get(&self.tables.advice_notes, key).await?;
Ok(result)
}

Expand All @@ -192,30 +185,24 @@ impl<T: Database> Storage<T> {
let key = byte_array_to_base64(&nullifier.to_proto().inner);
let result = self
.db
.get(&self.tables.swaps, key, Some("nullifier"))
.get_with_index(&self.tables.swaps, key, "nullifier")
.await?;
Ok(result)
}

pub async fn get_fmd_params(&self) -> WasmResult<Option<fmd::Parameters>> {
let result = self
.db
.get(&self.tables.fmd_parameters, "params", None)
.await?;
let result = self.db.get(&self.tables.fmd_parameters, "params").await?;
Ok(result)
}

pub async fn get_app_params(&self) -> WasmResult<Option<AppParameters>> {
let result = self
.db
.get(&self.tables.app_parameters, "params", None)
.await?;
let result = self.db.get(&self.tables.app_parameters, "params").await?;
Ok(result)
}

pub async fn get_gas_prices_by_asset_id(&self, asset_id: &Id) -> WasmResult<Option<GasPrices>> {
let key = byte_array_to_base64(&asset_id.to_proto().inner);
let result = self.db.get(&self.tables.gas_prices, key, None).await?;
let result = self.db.get(&self.tables.gas_prices, key).await?;
Ok(result)
}

Expand All @@ -239,7 +226,7 @@ impl<T: Database> Storage<T> {
let key = byte_array_to_base64(&auction_id.to_proto().inner);
let result: Option<OutstandingReserves> = self
.db
.get(&self.tables.auction_outstanding_reserves, key, None)
.get(&self.tables.auction_outstanding_reserves, key)
.await?;

result.ok_or_else(|| WasmError::Anyhow(anyhow!("could not find reserves")))
Expand Down
20 changes: 7 additions & 13 deletions packages/wasm/crate/tests/test_mock_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ fn test_get_and_put() {
let key = "test_key";
let value = AddressIndex::new(1);

let serialized = serde_wasm_bindgen::to_value(&value).unwrap();

block_on(db.put_with_key(table_name, key, &serialized)).unwrap();
let retrieved: Option<AddressIndex> = block_on(db.get(table_name, key, None)).unwrap();
block_on(db.put_with_key(table_name, key, &value)).unwrap();
let retrieved: Option<AddressIndex> = block_on(db.get(table_name, key)).unwrap();

assert_eq!(value, retrieved.unwrap());
}
Expand All @@ -36,8 +34,7 @@ fn test_get_all() {

for (i, value) in values.iter().enumerate() {
let key = format!("test_key_{}", i);
let serialized = serde_wasm_bindgen::to_value(value).unwrap();
block_on(db.put_with_key(table_name, &key, &serialized)).unwrap();
block_on(db.put_with_key(table_name, &key, value)).unwrap();
}

let retrieved: Vec<AddressIndex> = block_on(db.get_all::<AddressIndex>(table_name)).unwrap();
Expand All @@ -64,14 +61,11 @@ fn test_multiple_tables() {
let key2 = "key2";
let value2 = AddressIndex::new(202);

let serialized1 = serde_wasm_bindgen::to_value(&value1).unwrap();
let serialized2 = serde_wasm_bindgen::to_value(&value2).unwrap();

block_on(db.put_with_key(table1, key1, &serialized1)).unwrap();
block_on(db.put_with_key(table2, key2, &serialized2)).unwrap();
block_on(db.put_with_key(table1, key1, &value1)).unwrap();
block_on(db.put_with_key(table2, key2, &value2)).unwrap();

let retrieved1: Option<AddressIndex> = block_on(db.get(table1, key1, None)).unwrap();
let retrieved2: Option<AddressIndex> = block_on(db.get(table2, key2, None)).unwrap();
let retrieved1: Option<AddressIndex> = block_on(db.get(table1, key1)).unwrap();
let retrieved2: Option<AddressIndex> = block_on(db.get(table2, key2)).unwrap();

assert_eq!(value1, retrieved1.unwrap());
assert_eq!(value2, retrieved2.unwrap());
Expand Down

0 comments on commit 5502149

Please sign in to comment.