// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers // All rights reserved. // Licensed under the Apache License, Version 2.0 // // or the MIT license , // at your option. All files in the project carrying such // notice may not be copied, modified, or distributed except // according to those terms. //! Types for Verifier use core::fmt; //use oxigraph::io::{RdfFormat, RdfParser, RdfSerializer}; use oxigraph::store::Store; //use oxigraph::model::GroundQuad; #[cfg(not(target_family = "wasm"))] use crate::rocksdb_user_storage::RocksDbUserStorage; use crate::user_storage::{InMemoryUserStorage, UserStorage}; use std::path::PathBuf; use ng_net::{ types::*, utils::{Receiver, Sender}, }; use ng_repo::{ errors::{NgError, StorageError}, types::*, }; use serde::{Deserialize, Serialize}; //use yrs::{StateVector, Update}; #[derive(Debug, Clone)] pub enum VerifierType { /// nothing will be saved on disk during the session Memory, /// will save all user data locally, with RocksDb backend RocksDb, /// the verifier will be remote. a Noise connection will be opened /// optional peerId to connect to. If None, will try any that has the flag `can_verify` Remote(Option), /// IndexedDb based rocksdb compiled to WASM... not ready yet. obviously. only works in the browser WebRocksDb, } impl VerifierType { pub fn is_memory(&self) -> bool { match self { Self::Memory => true, _ => false, } } } //type LastSeqFn = fn(PubKey, u16) -> Result; pub type LastSeqFn = dyn Fn(PubKey, u16) -> Result + 'static + Sync + Send; // peer_id: PubKey, seq_num:u64, event_ser: vec, pub type OutboxWriteFn = dyn Fn(PubKey, u64, Vec) -> Result<(), NgError> + 'static + Sync + Send; // peer_id: PubKey, pub type OutboxReadFn = dyn Fn(PubKey) -> Result>, NgError> + 'static + Sync + Send; pub struct JsSaveSessionConfig { pub last_seq_function: Box, pub outbox_write_function: Box, pub outbox_read_function: Box, } impl fmt::Debug for JsSaveSessionConfig { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "JsSaveSessionConfig") } } #[derive(Debug)] pub enum VerifierConfigType { /// nothing will be saved on disk during the session Memory, JsSaveSession(JsSaveSessionConfig), /// will save all user data locally, with RocksDb backend RocksDb(PathBuf), /// the verifier will be remote. a Noise connection will be opened /// optional peerId to connect to. If None, will try any that has the flag `can_verify` /// // TODO: Pass the AppConfig Remote(Option), /// IndexedDb based rocksdb compiled to WASM... not ready yet. obviously. only works in the browser WebRocksDb, } #[derive(Debug)] pub struct VerifierConfig { pub config_type: VerifierConfigType, /// not used for Memory pub user_master_key: [u8; 32], /// not used for Memory pub peer_priv_key: PrivKey, pub user_priv_key: PrivKey, pub private_store_read_cap: ObjectRef, } pub type CancelFn = Box; pub struct Verifier { pub config: VerifierConfig, pub connected_server_id: Option, graph_dataset: Option, user_storage: Option>, } impl fmt::Debug for Verifier { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { writeln!(f, "Verifier\nconfig: {:?}", self.config)?; writeln!(f, "connected_server_id: {:?}", self.connected_server_id) } } impl Verifier { pub fn new(config: VerifierConfig) -> Result { let (graph, user) = match &config.config_type { VerifierConfigType::Memory | VerifierConfigType::JsSaveSession(_) => ( Some(Store::new().unwrap()), Some(Box::new(InMemoryUserStorage::new()) as Box), ), #[cfg(not(target_family = "wasm"))] VerifierConfigType::RocksDb(path) => ( // FIXME BIG TIME: we are reusing the same encryption key here. // this is very temporary, until we remove the code in oxi_rocksdb of oxigraph, // and have oxigraph use directly the UserStorage Some(Store::open_with_key(path, config.user_master_key).unwrap()), Some( Box::new(RocksDbUserStorage::open(path, config.user_master_key)?) as Box, ), ), VerifierConfigType::Remote(_) => (None, None), _ => unimplemented!(), // can be WebRocksDb or RocksDb on wasm platforms }; Ok(Verifier { config, connected_server_id: None, graph_dataset: graph, user_storage: user, }) } pub fn doc_fetch( &self, nuri: String, payload: Option, ) -> Result<(Receiver, CancelFn), NgError> { unimplemented!(); } } // // APP PROTOCOL (between APP and VERIFIER) // #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppRequestV0 {} #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AppRequest { V0(AppRequestV0), } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct GraphUpdate { sparql_update: String, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum DiscreteUpdate { /// A yrs::Update YMap(Vec), YXml(Vec), YText(Vec), /// An automerge::Patch Automerge(Vec), } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppUpdate { heads: Vec, graph: Option, discrete: Option, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppCreate { store: StoreRepo, content_type: BranchContentType, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppDelete { /// Nuri of doc to delete nuri: String, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AppRequestPayloadV0 { Create(AppCreate), Update(AppUpdate), Delete(AppDelete), } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AppRequestPayload { V0(AppRequestPayloadV0), } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum DiscretePatch { /// A yrs::Update YMap(Vec), YXml(Vec), YText(Vec), /// An automerge::Patch Automerge(Vec), } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct GraphPatch { /// oxigraph::model::GroundQuad serialized in turtle with oxrdfio pub adds: Vec, pub removes: Vec, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum DiscreteState { /// A yrs::StateVector YMap(Vec), YXml(Vec), YText(Vec), // the output of Automerge::save() Automerge(Vec), } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct GraphState { pub tuples: Vec, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppState { heads: Vec, graph: Option, // there is always a graph present in the branch. but it might not have been asked in the request discrete: Option, } #[derive(Clone, Debug, Serialize, Deserialize)] pub struct AppPatch { heads: Vec, graph: Option, discrete: Option, } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AppResponseV0 { State(AppState), Patch(AppPatch), } #[derive(Clone, Debug, Serialize, Deserialize)] pub enum AppResponse { V0(AppResponseV0), }