Skip to content
This repository has been archived by the owner on Sep 21, 2024. It is now read-only.

chore: Genercize storage across gateway and rename "default" storages #622

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions rust/noosphere-cli/src/native/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
use anyhow::{anyhow, Result};
use cid::Cid;
use directories::ProjectDirs;
use noosphere::sphere::SphereContextBuilder;
use noosphere::{platform::PlatformStorage, sphere::SphereContextBuilder};
use noosphere_core::authority::Author;
use noosphere_core::data::{Did, Link, LinkRecord, MemoIpld};
use noosphere_sphere::{SphereContentRead, SphereContext, SphereCursor, COUNTERPART, GATEWAY_URL};
use noosphere_storage::{KeyValueStore, NativeStorage, SphereDb};
use noosphere_storage::{KeyValueStore, SphereDb};
use serde_json::Value;
use std::path::{Path, PathBuf};
use std::sync::Arc;
Expand All @@ -24,7 +24,7 @@ use super::paths::SpherePaths;
use super::render::SphereRenderer;

/// The flavor of [SphereContext] used through the CLI
pub type CliSphereContext = SphereContext<NativeStorage>;
pub type CliSphereContext = SphereContext<PlatformStorage>;

/// Metadata about a given sphere, including the sphere ID, a [Link]
/// to it and a corresponding [LinkRecord] (if one is available).
Expand Down Expand Up @@ -68,7 +68,7 @@ impl Workspace {
/// Get an owned referenced to the [SphereDb] that backs the local sphere.
/// Note that this will initialize the [SphereContext] if it has not been
/// already.
pub async fn db(&self) -> Result<SphereDb<NativeStorage>> {
pub async fn db(&self) -> Result<SphereDb<PlatformStorage>> {
let context = self.sphere_context().await?;
let context = context.lock().await;
Ok(context.db().clone())
Expand Down
10 changes: 5 additions & 5 deletions rust/noosphere-cli/tests/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ pub use cli::*;

use anyhow::Result;
use noosphere_ipfs::{IpfsStore, KuboClient};
use noosphere_storage::{BlockStoreRetry, MemoryStore, NativeStorage, UcanStore};
use noosphere_storage::{BlockStoreRetry, MemoryStore, UcanStore};
use std::{net::TcpListener, sync::Arc, time::Duration};
use tempfile::TempDir;

use noosphere_cli::{
cli::ConfigSetCommand,
commands::{key::key_create, sphere::config_set, sphere::sphere_create},
workspace::Workspace,
workspace::{CliSphereContext, Workspace},
};
use noosphere_core::data::Did;
use noosphere_gateway::{start_gateway, GatewayScope};
use noosphere_ns::{helpers::NameSystemNetwork, server::start_name_system_api_server};
use noosphere_sphere::{HasSphereContext, SphereContext};
use noosphere_sphere::HasSphereContext;
use tokio::{sync::Mutex, task::JoinHandle};
use url::Url;

Expand Down Expand Up @@ -222,14 +222,14 @@ impl SpherePair {
}

/// Returns a [SphereContext] for the client sphere.
pub async fn sphere_context(&self) -> Result<Arc<Mutex<SphereContext<NativeStorage>>>> {
pub async fn sphere_context(&self) -> Result<Arc<Mutex<CliSphereContext>>> {
self.client.workspace.sphere_context().await
}

pub async fn spawn<T, F, Fut>(&self, f: F) -> Result<T>
where
T: Send + 'static,
F: FnOnce(Arc<Mutex<SphereContext<NativeStorage>>>) -> Fut + Send + 'static,
F: FnOnce(Arc<Mutex<CliSphereContext>>) -> Fut + Send + 'static,
Fut: std::future::Future<Output = Result<T>> + Send + 'static,
{
let context = self.sphere_context().await?;
Expand Down
20 changes: 13 additions & 7 deletions rust/noosphere-gateway/src/authority.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use axum::{
use libipld_core::cid::Cid;
use noosphere_core::authority::{SphereAbility, SphereReference, SPHERE_SEMANTICS};
use noosphere_sphere::SphereContext;
use noosphere_storage::NativeStorage;

use noosphere_storage::Storage;
use tokio::sync::Mutex;
use ucan::{capability::CapabilityView, chain::ProofChain, store::UcanJwtStore};

Expand All @@ -23,12 +23,16 @@ use super::GatewayScope;
/// represented by a UCAN. Any request handler can use a GatewayAuthority
/// to test if a required capability is satisfied by the authorization
/// presented by the maker of the request.
pub struct GatewayAuthority {
pub struct GatewayAuthority<S> {
proof: ProofChain,
scope: GatewayScope,
marker: std::marker::PhantomData<S>,
}

impl GatewayAuthority {
impl<S> GatewayAuthority<S>
where
S: Storage + 'static,
{
pub fn try_authorize(
&self,
capability: &CapabilityView<SphereReference, SphereAbility>,
Expand All @@ -52,16 +56,17 @@ impl GatewayAuthority {
}

#[async_trait]
impl<S> FromRequestParts<S> for GatewayAuthority
impl<S, St> FromRequestParts<St> for GatewayAuthority<S>
where
S: Send + Sync,
St: Send + Sync,
S: Storage + 'static,
Comment on lines +61 to +62
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that there is no t (you named it St) in Send + Sync and there are three in Storage + 'static, which will probably confuse people w/ naming.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch! The St type reflects the underlying axum State as rationale for naming, but you make a great point, will update to something less ambiguous

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I personally wouldn't balk at a non-abbreviated identifier for the generic type.

{
type Rejection = StatusCode;

async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
async fn from_request_parts(parts: &mut Parts, state: &St) -> Result<Self, Self::Rejection> {
let sphere_context = parts
.extensions
.get::<Arc<Mutex<SphereContext<NativeStorage>>>>()
.get::<Arc<Mutex<SphereContext<S>>>>()
.ok_or_else(|| {
error!("Could not find DidParser in extensions");
StatusCode::INTERNAL_SERVER_ERROR
Expand Down Expand Up @@ -141,6 +146,7 @@ where
Ok(GatewayAuthority {
scope: gateway_scope.clone(),
proof: proof_chain,
marker: std::marker::PhantomData,
})
}
}
2 changes: 1 addition & 1 deletion rust/noosphere-gateway/src/route/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{authority::GatewayAuthority, GatewayScope};

#[instrument(level = "debug", skip(authority, scope, sphere_context, ipfs_client))]
pub async fn fetch_route<C, S>(
authority: GatewayAuthority,
authority: GatewayAuthority<S>,
Query(FetchParameters { since }): Query<FetchParameters>,
Extension(scope): Extension<GatewayScope>,
Extension(ipfs_client): Extension<KuboClient>,
Expand Down
4 changes: 2 additions & 2 deletions rust/noosphere-gateway/src/route/identify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use noosphere_storage::Storage;
pub async fn identify_route<C, S>(
Extension(scope): Extension<GatewayScope>,
Extension(sphere_context): Extension<C>,
authority: GatewayAuthority,
authority: GatewayAuthority<S>,
) -> Result<impl IntoResponse, StatusCode>
where
C: HasSphereContext<S>,
S: Storage,
S: Storage + 'static,
{
debug!("Invoking identify route...");

Expand Down
2 changes: 1 addition & 1 deletion rust/noosphere-gateway/src/route/push.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use crate::{
)
)]
pub async fn push_route<C, S>(
authority: GatewayAuthority,
authority: GatewayAuthority<S>,
Extension(sphere_context): Extension<C>,
Extension(gateway_scope): Extension<GatewayScope>,
Extension(syndication_tx): Extension<UnboundedSender<SyndicationJob<C>>>,
Expand Down
2 changes: 1 addition & 1 deletion rust/noosphere-gateway/src/route/replicate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub type ReplicationCarStreamBody =
/// fetch from the gateway.
#[instrument(level = "debug", skip(authority, scope, sphere_context,))]
pub async fn replicate_route<C, S>(
authority: GatewayAuthority,
authority: GatewayAuthority<S>,
// NOTE: Cannot go from string to CID via serde
Path(memo_version): Path<String>,
Query(ReplicateParameters { since }): Query<ReplicateParameters>,
Expand Down
13 changes: 6 additions & 7 deletions rust/noosphere-storage/src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,33 @@ use crate::Storage;
use anyhow::Result;

#[cfg(not(target_arch = "wasm32"))]
use crate::{NativeStorage, NativeStorageInit, NativeStore};
use crate::{SledStorage, SledStorageInit, SledStore};

#[cfg(not(target_arch = "wasm32"))]
pub async fn make_disposable_store() -> Result<NativeStore> {
pub async fn make_disposable_store() -> Result<SledStore> {
let temp_dir = std::env::temp_dir();
let temp_name: String = witty_phrase_generator::WPGen::new()
.with_words(3)
.unwrap()
.into_iter()
.map(String::from)
.collect();
let db = sled::open(temp_dir.join(temp_name)).unwrap();
let provider = NativeStorage::new(NativeStorageInit::Db(db))?;
let provider = SledStorage::new(SledStorageInit::Path(temp_dir.join(temp_name)))?;
provider.get_block_store("foo").await
}

#[cfg(target_arch = "wasm32")]
use crate::{WebStorage, WebStore};
use crate::{IndexedDbStorage, IndexedDbStore};

#[cfg(target_arch = "wasm32")]
pub async fn make_disposable_store() -> Result<WebStore> {
pub async fn make_disposable_store() -> Result<IndexedDbStore> {
let temp_name: String = witty_phrase_generator::WPGen::new()
.with_words(3)
.unwrap()
.into_iter()
.map(|word| String::from(word))
.collect();

let provider = WebStorage::new(&temp_name).await?;
let provider = IndexedDbStorage::new(&temp_name).await?;
provider.get_block_store(crate::db::BLOCK_STORE).await
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,17 @@ use wasm_bindgen::{JsCast, JsValue};
pub const INDEXEDDB_STORAGE_VERSION: u32 = 1;

#[derive(Clone)]
pub struct WebStorage {
pub struct IndexedDbStorage {
db: Rc<Rexie>,
}

impl Debug for WebStorage {
impl Debug for IndexedDbStorage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("WebStorage").finish()
f.debug_struct("IndexedDbStorage").finish()
}
}

impl WebStorage {
impl IndexedDbStorage {
pub async fn new(db_name: &str) -> Result<Self> {
Self::configure(INDEXEDDB_STORAGE_VERSION, db_name, SPHERE_DB_STORE_NAMES).await
}
Expand All @@ -39,10 +39,10 @@ impl WebStorage {
.await
.map_err(|error| anyhow!("{:?}", error))?;

Ok(WebStorage { db: Rc::new(db) })
Ok(IndexedDbStorage { db: Rc::new(db) })
}

async fn get_store(&self, name: &str) -> Result<WebStore> {
async fn get_store(&self, name: &str) -> Result<IndexedDbStore> {
if self
.db
.store_names()
Expand All @@ -53,18 +53,18 @@ impl WebStorage {
return Err(anyhow!("No such store named {}", name));
}

Ok(WebStore {
Ok(IndexedDbStore {
db: self.db.clone(),
store_name: name.to_string(),
})
}
}

#[async_trait(?Send)]
impl Storage for WebStorage {
type BlockStore = WebStore;
impl Storage for IndexedDbStorage {
type BlockStore = IndexedDbStore;

type KeyValueStore = WebStore;
type KeyValueStore = IndexedDbStore;

async fn get_block_store(&self, name: &str) -> Result<Self::BlockStore> {
self.get_store(name).await
Expand All @@ -76,12 +76,12 @@ impl Storage for WebStorage {
}

#[derive(Clone)]
pub struct WebStore {
pub struct IndexedDbStore {
db: Rc<Rexie>,
store_name: String,
}

impl WebStore {
impl IndexedDbStore {
fn start_transaction(&self, mode: TransactionMode) -> Result<(IdbStore, Transaction)> {
let tx = self
.db
Expand Down Expand Up @@ -116,7 +116,7 @@ impl WebStore {
}

async fn read(key: &JsValue, store: &IdbStore) -> Result<Option<Vec<u8>>> {
Ok(match WebStore::contains(&key, &store).await? {
Ok(match IndexedDbStore::contains(&key, &store).await? {
true => Some(
store
.get(&key)
Expand All @@ -132,49 +132,49 @@ impl WebStore {
}

#[async_trait(?Send)]
impl Store for WebStore {
impl Store for IndexedDbStore {
async fn read(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
let (store, tx) = self.start_transaction(TransactionMode::ReadOnly)?;
let key = WebStore::bytes_to_typed_array(key)?;
let key = IndexedDbStore::bytes_to_typed_array(key)?;

let maybe_dag = WebStore::read(&key, &store).await?;
let maybe_dag = IndexedDbStore::read(&key, &store).await?;

WebStore::finish_transaction(tx).await?;
IndexedDbStore::finish_transaction(tx).await?;

Ok(maybe_dag)
}

async fn write(&mut self, key: &[u8], bytes: &[u8]) -> Result<Option<Vec<u8>>> {
let (store, tx) = self.start_transaction(TransactionMode::ReadWrite)?;

let key = WebStore::bytes_to_typed_array(key)?;
let value = WebStore::bytes_to_typed_array(bytes)?;
let key = IndexedDbStore::bytes_to_typed_array(key)?;
let value = IndexedDbStore::bytes_to_typed_array(bytes)?;

let old_bytes = WebStore::read(&key, &store).await?;
let old_bytes = IndexedDbStore::read(&key, &store).await?;

store
.put(&value, Some(&key))
.await
.map_err(|error| anyhow!("{:?}", error))?;

WebStore::finish_transaction(tx).await?;
IndexedDbStore::finish_transaction(tx).await?;

Ok(old_bytes)
}

async fn remove(&mut self, key: &[u8]) -> Result<Option<Vec<u8>>> {
let (store, tx) = self.start_transaction(TransactionMode::ReadWrite)?;

let key = WebStore::bytes_to_typed_array(key)?;
let key = IndexedDbStore::bytes_to_typed_array(key)?;

let old_value = WebStore::read(&key, &store).await?;
let old_value = IndexedDbStore::read(&key, &store).await?;

store
.delete(&key)
.await
.map_err(|error| anyhow!("{:?}", error))?;

WebStore::finish_transaction(tx).await?;
IndexedDbStore::finish_transaction(tx).await?;

Ok(old_value)
}
Expand Down
8 changes: 4 additions & 4 deletions rust/noosphere-storage/src/implementation/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ pub use memory::*;
pub use tracking::*;

#[cfg(not(target_arch = "wasm32"))]
mod native;
mod sled;

#[cfg(not(target_arch = "wasm32"))]
pub use native::*;
pub use self::sled::*;

#[cfg(target_arch = "wasm32")]
mod web;
mod indexed_db;

#[cfg(target_arch = "wasm32")]
pub use web::*;
pub use indexed_db::*;
Loading