From 19c627e1b93502f9f46f21149116a092d07c5509 Mon Sep 17 00:00:00 2001 From: Niko PLP Date: Mon, 29 Apr 2024 03:14:01 +0300 Subject: [PATCH] refactor helper Class/Column for KVC storage --- ng-broker/src/actors/mod.rs | 1 + ng-broker/src/lib.rs | 2 + ng-broker/src/server_broker.rs | 9 +- ng-broker/src/server_storage/admin/account.rs | 38 +- .../src/server_storage/admin/invitation.rs | 31 +- ng-broker/src/server_storage/admin/wallet.rs | 14 +- ng-broker/src/server_storage/core/overlay.rs | 36 +- ng-broker/src/server_storage/core/peer.rs | 32 +- ng-broker/src/server_storage/core/topic.rs | 243 +++++++------ .../src/actors/{ => admin}/add_invitation.rs | 2 +- ng-net/src/actors/{ => admin}/add_user.rs | 2 +- ng-net/src/actors/{ => admin}/del_user.rs | 2 +- .../actors/{ => admin}/list_invitations.rs | 2 +- ng-net/src/actors/{ => admin}/list_users.rs | 2 +- ng-net/src/actors/admin/mod.rs | 14 + ng-net/src/actors/mod.rs | 17 +- ng-net/src/types.rs | 2 +- ng-repo/src/kcv_storage.rs | 337 +++++++++++++++++- ng-repo/src/types.rs | 12 + ng-verifier/src/user_storage/branch.rs | 5 +- ng-verifier/src/user_storage/mod.rs | 13 - ng-verifier/src/user_storage/repo.rs | 2 +- ngaccount/src/main.rs | 2 +- ngcli/src/main.rs | 2 +- 24 files changed, 588 insertions(+), 234 deletions(-) create mode 100644 ng-broker/src/actors/mod.rs rename ng-net/src/actors/{ => admin}/add_invitation.rs (99%) rename ng-net/src/actors/{ => admin}/add_user.rs (98%) rename ng-net/src/actors/{ => admin}/del_user.rs (98%) rename ng-net/src/actors/{ => admin}/list_invitations.rs (99%) rename ng-net/src/actors/{ => admin}/list_users.rs (98%) create mode 100644 ng-net/src/actors/admin/mod.rs diff --git a/ng-broker/src/actors/mod.rs b/ng-broker/src/actors/mod.rs new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/ng-broker/src/actors/mod.rs @@ -0,0 +1 @@ + diff --git a/ng-broker/src/lib.rs b/ng-broker/src/lib.rs index b38f93e..aa33148 100644 --- a/ng-broker/src/lib.rs +++ b/ng-broker/src/lib.rs @@ -11,3 +11,5 @@ pub mod server_storage; pub mod rocksdb_server_storage; pub mod server_ws; + +pub mod actors; diff --git a/ng-broker/src/server_broker.rs b/ng-broker/src/server_broker.rs index 2ae79cb..47ca602 100644 --- a/ng-broker/src/server_broker.rs +++ b/ng-broker/src/server_broker.rs @@ -22,16 +22,15 @@ use ng_repo::{ use crate::rocksdb_server_storage::RocksDbServerStorage; struct TopicInfo { - /// can be None if the Broker is not currently serving this topic for its clients. - repo: Option, + repo: RepoHash, publisher_advert: Option, - current_heads: Vec, + current_heads: HashSet, expose_outer: bool, - /// indicates which users have subscribed to topic (boolean says if as publisher or not) + /// indicates which users have opened the topic (boolean says if as publisher or not) users: HashMap, } @@ -47,6 +46,8 @@ struct RepoInfo { struct OverlayInfo { inner: Option, + overlay_topic: Option, + topics: HashMap, repos: HashMap, diff --git a/ng-broker/src/server_storage/admin/account.rs b/ng-broker/src/server_storage/admin/account.rs index 4ac40d1..3603d1e 100644 --- a/ng-broker/src/server_storage/admin/account.rs +++ b/ng-broker/src/server_storage/admin/account.rs @@ -24,7 +24,7 @@ use serde_bare::{from_slice, to_vec}; pub struct Account<'a> { /// User ID id: UserId, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, } impl<'a> Account<'a> { @@ -38,10 +38,10 @@ impl<'a> Account<'a> { const ALL_CLIENT_PROPERTIES: [u8; 2] = [Self::INFO, Self::LAST_SEEN]; - pub fn open(id: &UserId, store: &'a dyn KCVStorage) -> Result, StorageError> { + pub fn open(id: &UserId, storage: &'a dyn KCVStorage) -> Result, StorageError> { let opening = Account { id: id.clone(), - store, + storage, }; if !opening.exists() { return Err(StorageError::NotFound); @@ -51,16 +51,16 @@ impl<'a> Account<'a> { pub fn create( id: &UserId, admin: bool, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, ) -> Result, StorageError> { let acc = Account { id: id.clone(), - store, + storage, }; if acc.exists() { return Err(StorageError::AlreadyExists); } - store.put( + storage.put( Self::PREFIX_ACCOUNT, &to_vec(&id)?, None, @@ -73,12 +73,12 @@ impl<'a> Account<'a> { #[allow(deprecated)] pub fn get_all_users( admins: bool, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, ) -> Result, StorageError> { let size = to_vec(&UserId::nil())?.len(); let mut res: Vec = vec![]; for user in - store.get_all_keys_and_values(Self::PREFIX_ACCOUNT, size, vec![], None, &None)? + storage.get_all_keys_and_values(Self::PREFIX_ACCOUNT, size, vec![], None, &None)? { let admin: bool = from_slice(&user.1)?; if admin == admins { @@ -89,7 +89,7 @@ impl<'a> Account<'a> { Ok(res) } pub fn exists(&self) -> bool { - self.store + self.storage .get( Self::PREFIX_ACCOUNT, &to_vec(&self.id).unwrap(), @@ -115,7 +115,7 @@ impl<'a> Account<'a> { let info_ser = to_vec(info)?; - self.store.write_transaction(&mut |tx| { + self.storage.write_transaction(&mut |tx| { let mut id_and_client = to_vec(&self.id)?; id_and_client.append(&mut client_key_ser); if tx @@ -158,7 +158,7 @@ impl<'a> Account<'a> { } // pub fn has_client(&self, client: &ClientId) -> Result<(), StorageError> { - // self.store.has_property_value( + // self.storage.has_property_value( // Self::PREFIX, // &to_vec(&self.id)?, // Some(Self::CLIENT), @@ -170,7 +170,7 @@ impl<'a> Account<'a> { // if !self.exists() { // return Err(StorageError::BackendError); // } - // self.store.put( + // self.storage.put( // Self::PREFIX, // &to_vec(&self.id)?, // Some(Self::OVERLAY), @@ -178,7 +178,7 @@ impl<'a> Account<'a> { // ) // } // pub fn remove_overlay(&self, overlay: &OverlayId) -> Result<(), StorageError> { - // self.store.del_property_value( + // self.storage.del_property_value( // Self::PREFIX, // &to_vec(&self.id)?, // Some(Self::OVERLAY), @@ -187,7 +187,7 @@ impl<'a> Account<'a> { // } // pub fn has_overlay(&self, overlay: &OverlayId) -> Result<(), StorageError> { - // self.store.has_property_value( + // self.storage.has_property_value( // Self::PREFIX, // &to_vec(&self.id)?, // Some(Self::OVERLAY), @@ -197,7 +197,7 @@ impl<'a> Account<'a> { pub fn is_admin(&self) -> Result { if self - .store + .storage .has_property_value( Self::PREFIX_ACCOUNT, &to_vec(&self.id)?, @@ -213,7 +213,7 @@ impl<'a> Account<'a> { } pub fn del(&self) -> Result<(), StorageError> { - self.store.write_transaction(&mut |tx| { + self.storage.write_transaction(&mut |tx| { let id = to_vec(&self.id)?; // let mut id_and_client = to_vec(&self.id)?; // let client_key = (client.clone(), hash); @@ -261,14 +261,14 @@ mod test { let key: [u8; 32] = [0; 32]; fs::create_dir_all(root.path()).unwrap(); println!("{}", root.path().to_str().unwrap()); - let mut store = RocksDbKCVStorage::open(root.path(), key).unwrap(); + let mut storage = RocksDbKCVStorage::open(root.path(), key).unwrap(); let user_id = PubKey::Ed25519PubKey([1; 32]); - let account = Account::create(&user_id, true, &store).unwrap(); + let account = Account::create(&user_id, true, &storage).unwrap(); println!("account created {}", account.id()); - let account2 = Account::open(&user_id, &store).unwrap(); + let account2 = Account::open(&user_id, &storage).unwrap(); println!("account opened {}", account2.id()); // let client_id = PubKey::Ed25519PubKey([56; 32]); diff --git a/ng-broker/src/server_storage/admin/invitation.rs b/ng-broker/src/server_storage/admin/invitation.rs index 7f0ea54..06101da 100644 --- a/ng-broker/src/server_storage/admin/invitation.rs +++ b/ng-broker/src/server_storage/admin/invitation.rs @@ -27,7 +27,7 @@ use serde_bare::to_vec; pub struct Invitation<'a> { /// code id: [u8; 32], - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, } impl<'a> Invitation<'a> { @@ -45,10 +45,13 @@ impl<'a> Invitation<'a> { const SUFFIX_FOR_EXIST_CHECK: u8 = Self::TYPE; - pub fn open(id: &[u8; 32], store: &'a dyn KCVStorage) -> Result, StorageError> { + pub fn open( + id: &[u8; 32], + storage: &'a dyn KCVStorage, + ) -> Result, StorageError> { let opening = Invitation { id: id.clone(), - store, + storage, }; if !opening.exists() { return Err(StorageError::NotFound); @@ -59,7 +62,7 @@ impl<'a> Invitation<'a> { id: &InvitationCode, expiry: u32, memo: &Option, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, ) -> Result, StorageError> { let (code_type, code) = match id { InvitationCode::Unique(c) => (0u8, c.slice()), @@ -68,13 +71,13 @@ impl<'a> Invitation<'a> { }; let acc = Invitation { id: code.clone(), - store, + storage, }; if acc.exists() { return Err(StorageError::BackendError); } let mut value = to_vec(&(code_type, expiry, memo.clone()))?; - store.write_transaction(&mut |tx| { + storage.write_transaction(&mut |tx| { tx.put( Self::PREFIX, &to_vec(code)?, @@ -88,7 +91,7 @@ impl<'a> Invitation<'a> { } pub fn get_all_invitations( - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, mut admin: bool, mut unique: bool, mut multi: bool, @@ -100,7 +103,7 @@ impl<'a> Invitation<'a> { unique = true; multi = true; } - for invite in store.get_all_keys_and_values(Self::PREFIX, size, vec![], None, &None)? { + for invite in storage.get_all_keys_and_values(Self::PREFIX, size, vec![], None, &None)? { if invite.0.len() == size + 2 { let code: [u8; 32] = from_slice(&invite.0[1..invite.0.len() - 1])?; if invite.0[size + 1] == Self::TYPE { @@ -139,7 +142,7 @@ impl<'a> Invitation<'a> { } pub fn exists(&self) -> bool { - self.store + self.storage .get( Self::PREFIX, &to_vec(&self.id).unwrap(), @@ -153,9 +156,9 @@ impl<'a> Invitation<'a> { } pub fn get_type(&self) -> Result { - let type_ser = self - .store - .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::TYPE), &None)?; + let type_ser = + self.storage + .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::TYPE), &None)?; let t: (u8, u32, Option) = from_slice(&type_ser)?; // if t.1 < now_timestamp() { // return Err(ProtocolError::Expired); @@ -165,7 +168,7 @@ impl<'a> Invitation<'a> { pub fn is_expired(&self) -> Result { let expire_ser = - self.store + self.storage .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::TYPE), &None)?; let expire: (u8, u32, Option) = from_slice(&expire_ser)?; if expire.1 < now_timestamp() { @@ -175,7 +178,7 @@ impl<'a> Invitation<'a> { } pub fn del(&self) -> Result<(), StorageError> { - self.store.write_transaction(&mut |tx| { + self.storage.write_transaction(&mut |tx| { tx.del_all( Self::PREFIX, &to_vec(&self.id)?, diff --git a/ng-broker/src/server_storage/admin/wallet.rs b/ng-broker/src/server_storage/admin/wallet.rs index 2ecfb5a..26dc1c6 100644 --- a/ng-broker/src/server_storage/admin/wallet.rs +++ b/ng-broker/src/server_storage/admin/wallet.rs @@ -7,7 +7,7 @@ // notice may not be copied, modified, or distributed except // according to those terms. -//! Broker Wallet, persists to store all the SymKeys needed to open other storages +//! Broker Wallet, persists to storage all the SymKeys needed to open other storages use ng_net::types::*; use ng_repo::errors::StorageError; @@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize}; use serde_bare::{from_slice, to_vec}; pub struct Wallet<'a> { - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, } impl<'a> Wallet<'a> { @@ -39,8 +39,8 @@ impl<'a> Wallet<'a> { const SUFFIX_FOR_EXIST_CHECK: u8 = Self::SYM_KEY; - pub fn open(store: &'a dyn KCVStorage) -> Wallet<'a> { - Wallet { store } + pub fn open(storage: &'a dyn KCVStorage) -> Wallet<'a> { + Wallet { storage } } pub fn get_or_create_single_key( &self, @@ -48,7 +48,7 @@ impl<'a> Wallet<'a> { key: &Vec, ) -> Result { let mut result: Option = None; - self.store.write_transaction(&mut |tx| { + self.storage.write_transaction(&mut |tx| { let got = tx.get(prefix, key, Some(Self::SUFFIX_FOR_EXIST_CHECK), &None); match got { Err(e) => { @@ -92,7 +92,7 @@ impl<'a> Wallet<'a> { Ok(symkey) } pub fn exists_single_key(&self, prefix: u8, key: &Vec) -> bool { - self.store + self.storage .get(prefix, key, Some(Self::SUFFIX_FOR_EXIST_CHECK), &None) .is_ok() } @@ -102,7 +102,7 @@ impl<'a> Wallet<'a> { } pub fn create_accounts_key(&self) -> Result { let mut result: Option = None; - self.store.write_transaction(&mut |tx| { + self.storage.write_transaction(&mut |tx| { let res = Self::create_single_key(tx, Self::PREFIX, &Self::KEY_ACCOUNTS.to_vec())?; result = Some(res); Ok(()) diff --git a/ng-broker/src/server_storage/core/overlay.rs b/ng-broker/src/server_storage/core/overlay.rs index 42f2bbb..28dacc9 100644 --- a/ng-broker/src/server_storage/core/overlay.rs +++ b/ng-broker/src/server_storage/core/overlay.rs @@ -27,7 +27,7 @@ pub struct OverlayMeta { pub struct Overlay<'a> { /// Overlay ID id: OverlayId, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, } impl<'a> Overlay<'a> { @@ -50,10 +50,10 @@ impl<'a> Overlay<'a> { const SUFFIX_FOR_EXIST_CHECK: u8 = Self::SECRET; - pub fn open(id: &OverlayId, store: &'a dyn KCVStorage) -> Result, StorageError> { + pub fn open(id: &OverlayId, storage: &'a dyn KCVStorage) -> Result, StorageError> { let opening = Overlay { id: id.clone(), - store, + storage, }; if !opening.exists() { return Err(StorageError::NotFound); @@ -64,16 +64,16 @@ impl<'a> Overlay<'a> { id: &OverlayId, secret: &SymKey, repo: Option, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, ) -> Result, StorageError> { let acc = Overlay { id: id.clone(), - store, + storage, }; if acc.exists() { return Err(StorageError::BackendError); } - store.write_transaction(&mut |tx| { + storage.write_transaction(&mut |tx| { tx.put( Self::PREFIX, &to_vec(&id)?, @@ -106,7 +106,7 @@ impl<'a> Overlay<'a> { Ok(acc) } pub fn exists(&self) -> bool { - self.store + self.storage .get( Self::PREFIX, &to_vec(&self.id).unwrap(), @@ -122,7 +122,7 @@ impl<'a> Overlay<'a> { if !self.exists() { return Err(StorageError::BackendError); } - self.store.put( + self.storage.put( Self::PREFIX, &to_vec(&self.id)?, Some(Self::PEER), @@ -131,7 +131,7 @@ impl<'a> Overlay<'a> { ) } pub fn remove_peer(&self, peer: &PeerId) -> Result<(), StorageError> { - self.store.del_property_value( + self.storage.del_property_value( Self::PREFIX, &to_vec(&self.id)?, Some(Self::PEER), @@ -141,7 +141,7 @@ impl<'a> Overlay<'a> { } pub fn has_peer(&self, peer: &PeerId) -> Result<(), StorageError> { - self.store.has_property_value( + self.storage.has_property_value( Self::PREFIX, &to_vec(&self.id)?, Some(Self::PEER), @@ -154,7 +154,7 @@ impl<'a> Overlay<'a> { if !self.exists() { return Err(StorageError::BackendError); } - self.store.put( + self.storage.put( Self::PREFIX, &to_vec(&self.id)?, Some(Self::TOPIC), @@ -163,7 +163,7 @@ impl<'a> Overlay<'a> { ) } pub fn remove_topic(&self, topic: &TopicId) -> Result<(), StorageError> { - self.store.del_property_value( + self.storage.del_property_value( Self::PREFIX, &to_vec(&self.id)?, Some(Self::TOPIC), @@ -173,7 +173,7 @@ impl<'a> Overlay<'a> { } pub fn has_topic(&self, topic: &TopicId) -> Result<(), StorageError> { - self.store.has_property_value( + self.storage.has_property_value( Self::PREFIX, &to_vec(&self.id)?, Some(Self::TOPIC), @@ -184,7 +184,7 @@ impl<'a> Overlay<'a> { pub fn secret(&self) -> Result { match self - .store + .storage .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::SECRET), &None) { Ok(secret) => Ok(from_slice::(&secret)?), @@ -194,7 +194,7 @@ impl<'a> Overlay<'a> { pub fn metadata(&self) -> Result { match self - .store + .storage .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::META), &None) { Ok(meta) => Ok(from_slice::(&meta)?), @@ -205,7 +205,7 @@ impl<'a> Overlay<'a> { if !self.exists() { return Err(StorageError::BackendError); } - self.store.replace( + self.storage.replace( Self::PREFIX, &to_vec(&self.id)?, Some(Self::META), @@ -216,7 +216,7 @@ impl<'a> Overlay<'a> { pub fn repo(&self) -> Result { match self - .store + .storage .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::REPO), &None) { Ok(repo) => Ok(from_slice::(&repo)?), @@ -225,7 +225,7 @@ impl<'a> Overlay<'a> { } pub fn del(&self) -> Result<(), StorageError> { - self.store.del_all( + self.storage.del_all( Self::PREFIX, &to_vec(&self.id)?, &Self::ALL_PROPERTIES, diff --git a/ng-broker/src/server_storage/core/peer.rs b/ng-broker/src/server_storage/core/peer.rs index 4724c86..571241f 100644 --- a/ng-broker/src/server_storage/core/peer.rs +++ b/ng-broker/src/server_storage/core/peer.rs @@ -19,7 +19,7 @@ use serde_bare::{from_slice, to_vec}; pub struct Peer<'a> { /// Topic ID id: PeerId, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, } impl<'a> Peer<'a> { @@ -33,10 +33,10 @@ impl<'a> Peer<'a> { const SUFFIX_FOR_EXIST_CHECK: u8 = Self::VERSION; - pub fn open(id: &PeerId, store: &'a dyn KCVStorage) -> Result, StorageError> { + pub fn open(id: &PeerId, storage: &'a dyn KCVStorage) -> Result, StorageError> { let opening = Peer { id: id.clone(), - store, + storage, }; if !opening.exists() { return Err(StorageError::NotFound); @@ -45,13 +45,13 @@ impl<'a> Peer<'a> { } pub fn update_or_create( advert: &PeerAdvert, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, ) -> Result, StorageError> { let id = advert.peer(); - match Self::open(id, store) { + match Self::open(id, storage) { Err(e) => { if e == StorageError::NotFound { - Self::create(advert, store) + Self::create(advert, storage) } else { Err(StorageError::BackendError) } @@ -64,17 +64,17 @@ impl<'a> Peer<'a> { } pub fn create( advert: &PeerAdvert, - store: &'a dyn KCVStorage, + storage: &'a dyn KCVStorage, ) -> Result, StorageError> { let id = advert.peer(); let acc = Peer { id: id.clone(), - store, + storage, }; if acc.exists() { return Err(StorageError::BackendError); } - store.write_transaction(&mut |tx| { + storage.write_transaction(&mut |tx| { tx.put( Self::PREFIX, &to_vec(&id)?, @@ -94,7 +94,7 @@ impl<'a> Peer<'a> { Ok(acc) } pub fn exists(&self) -> bool { - self.store + self.storage .get( Self::PREFIX, &to_vec(&self.id).unwrap(), @@ -108,7 +108,7 @@ impl<'a> Peer<'a> { } pub fn version(&self) -> Result { match self - .store + .storage .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::VERSION), &None) { Ok(ver) => Ok(from_slice::(&ver)?), @@ -119,7 +119,7 @@ impl<'a> Peer<'a> { if !self.exists() { return Err(StorageError::BackendError); } - self.store.replace( + self.storage.replace( Self::PREFIX, &to_vec(&self.id)?, Some(Self::VERSION), @@ -135,7 +135,7 @@ impl<'a> Peer<'a> { if current_advert.version() >= advert.version() { return Ok(()); } - self.store.write_transaction(&mut |tx| { + self.storage.write_transaction(&mut |tx| { tx.replace( Self::PREFIX, &to_vec(&self.id)?, @@ -155,7 +155,7 @@ impl<'a> Peer<'a> { } pub fn advert(&self) -> Result { match self - .store + .storage .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::ADVERT), &None) { Ok(advert) => Ok(from_slice::(&advert)?), @@ -166,7 +166,7 @@ impl<'a> Peer<'a> { if !self.exists() { return Err(StorageError::BackendError); } - self.store.replace( + self.storage.replace( Self::PREFIX, &to_vec(&self.id)?, Some(Self::ADVERT), @@ -176,7 +176,7 @@ impl<'a> Peer<'a> { } pub fn del(&self) -> Result<(), StorageError> { - self.store.del_all( + self.storage.del_all( Self::PREFIX, &to_vec(&self.id)?, &Self::ALL_PROPERTIES, diff --git a/ng-broker/src/server_storage/core/topic.rs b/ng-broker/src/server_storage/core/topic.rs index a347171..5ae624f 100644 --- a/ng-broker/src/server_storage/core/topic.rs +++ b/ng-broker/src/server_storage/core/topic.rs @@ -9,138 +9,151 @@ //! Topic +use std::collections::HashMap; +use std::collections::HashSet; + use ng_net::types::*; use ng_repo::errors::StorageError; -use ng_repo::kcv_storage::KCVStorage; +use ng_repo::kcv_storage::*; use ng_repo::types::*; -use serde::{Deserialize, Serialize}; -use serde_bare::{from_slice, to_vec}; -// TODO: versioning V0 -#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] -pub struct TopicMeta { - pub users: u32, -} +use serde_bare::to_vec; pub struct Topic<'a> { - /// Topic ID - id: TopicId, - store: &'a dyn KCVStorage, + key: Vec, + repo: ExistentialValue, + storage: &'a dyn KCVStorage, +} + +impl<'a> IModel for Topic<'a> { + fn key(&self) -> &Vec { + &self.key + } + fn storage(&self) -> &dyn KCVStorage { + self.storage + } + fn class(&self) -> &Class { + &Self::CLASS + } + fn existential(&mut self) -> &mut dyn IExistentialValue { + &mut self.repo + } } impl<'a> Topic<'a> { - const PREFIX: u8 = b"t"[0]; + const PREFIX: u8 = b't'; - // propertie's suffixes - const ADVERT: u8 = b"a"[0]; - const HEAD: u8 = b"h"[0]; - const META: u8 = b"m"[0]; + // Topic properties + const ADVERT: SingleValueColumn = SingleValueColumn::new(b'a'); + const REPO: ExistentialValueColumn = ExistentialValueColumn::new(b'r'); + const ROOT_COMMIT: SingleValueColumn = SingleValueColumn::new(b'o'); - const ALL_PROPERTIES: [u8; 3] = [Self::ADVERT, Self::HEAD, Self::META]; + // Topic <-> Users who pinned it + pub const USERS: MultiValueColumn = MultiValueColumn::new(b'u'); + // Topic <-> heads + pub const HEADS: MultiValueColumn = MultiValueColumn::new(b'h'); - const SUFFIX_FOR_EXIST_CHECK: u8 = Self::META; + const CLASS: Class<'a> = Class::new( + Self::PREFIX, + &Self::REPO, + vec![&Self::ADVERT, &Self::ROOT_COMMIT], + vec![&Self::USERS, &Self::HEADS], + ); + + pub fn load(&self) -> Result<(), StorageError> { + let props = self.load_props()?; + // let bs = BranchInfo { + // id: id.clone(), + // branch_type: prop(Self::TYPE, &props)?, + // read_cap: prop(Self::READ_CAP, &props)?, + // topic: prop(Self::TOPIC, &props)?, + // topic_priv_key: prop(Self::PUBLISHER, &props).ok(), + // current_heads: Self::get_all_heads(id, storage)?, + // }; + // Ok(bs) + Ok(()) + } - pub fn open(id: &TopicId, store: &'a dyn KCVStorage) -> Result, StorageError> { - let opening = Topic { - id: id.clone(), - store, - }; - if !opening.exists() { - return Err(StorageError::NotFound); + pub fn new(id: &TopicId, overlay: &OverlayId, storage: &'a dyn KCVStorage) -> Self { + let mut key: Vec = Vec::with_capacity(33 + 33); + key.append(&mut to_vec(overlay).unwrap()); + key.append(&mut to_vec(id).unwrap()); + Topic { + key, + repo: ExistentialValue::::new(), + storage, } + } + + pub fn open( + id: &TopicId, + overlay: &OverlayId, + storage: &'a dyn KCVStorage, + ) -> Result, StorageError> { + let mut opening = Topic::new(id, overlay, storage); + opening.check_exists()?; Ok(opening) } - pub fn create(id: &TopicId, store: &'a mut dyn KCVStorage) -> Result, StorageError> { - let acc = Topic { - id: id.clone(), - store, - }; - if acc.exists() { - return Err(StorageError::BackendError); - } - let meta = TopicMeta { users: 0 }; - store.put( - Self::PREFIX, - &to_vec(&id)?, - Some(Self::META), - &to_vec(&meta)?, - &None, - )?; - Ok(acc) - } - pub fn exists(&self) -> bool { - self.store - .get( - Self::PREFIX, - &to_vec(&self.id).unwrap(), - Some(Self::SUFFIX_FOR_EXIST_CHECK), - &None, - ) - .is_ok() - } - pub fn id(&self) -> TopicId { - self.id - } - pub fn add_head(&self, head: &ObjectId) -> Result<(), StorageError> { - if !self.exists() { - return Err(StorageError::BackendError); - } - self.store.put( - Self::PREFIX, - &to_vec(&self.id)?, - Some(Self::HEAD), - &to_vec(head)?, - &None, - ) - } - pub fn remove_head(&self, head: &ObjectId) -> Result<(), StorageError> { - self.store.del_property_value( - Self::PREFIX, - &to_vec(&self.id)?, - Some(Self::HEAD), - &to_vec(head)?, - &None, - ) - } - - pub fn has_head(&self, head: &ObjectId) -> Result<(), StorageError> { - self.store.has_property_value( - Self::PREFIX, - &to_vec(&self.id)?, - Some(Self::HEAD), - &to_vec(head)?, - &None, - ) - } - - pub fn metadata(&self) -> Result { - match self - .store - .get(Self::PREFIX, &to_vec(&self.id)?, Some(Self::META), &None) - { - Ok(meta) => Ok(from_slice::(&meta)?), - Err(e) => Err(e), + pub fn create( + id: &TopicId, + overlay: &OverlayId, + repo: &RepoHash, + storage: &'a mut dyn KCVStorage, + ) -> Result, StorageError> { + let mut topic = Topic::new(id, overlay, storage); + if topic.exists() { + return Err(StorageError::AlreadyExists); } + topic.repo.set(repo, &topic)?; + + Ok(topic) } - pub fn set_metadata(&self, meta: &TopicMeta) -> Result<(), StorageError> { - if !self.exists() { - return Err(StorageError::BackendError); - } - self.store.replace( - Self::PREFIX, - &to_vec(&self.id)?, - Some(Self::META), - &to_vec(meta)?, - &None, - ) - } - - pub fn del(&self) -> Result<(), StorageError> { - self.store.del_all( - Self::PREFIX, - &to_vec(&self.id)?, - &Self::ALL_PROPERTIES, - &None, - ) + + pub fn repo_hash(&self) -> &RepoHash { + self.repo.get().unwrap() + } + + pub fn root_commit(&mut self) -> Result { + Self::ROOT_COMMIT.get(self) + } + pub fn set_root_commit(&mut self, commit: &ObjectId) -> Result<(), StorageError> { + Self::ROOT_COMMIT.set(self, commit) + } + + pub fn publisher_advert(&mut self) -> Result { + Self::ADVERT.get(self) + } + pub fn set_publisher_advert(&mut self, advert: &PublisherAdvert) -> Result<(), StorageError> { + Self::ADVERT.set(self, advert) + } + + pub fn add_head(&mut self, head: &ObjectId) -> Result<(), StorageError> { + Self::HEADS.add(self, head) + } + pub fn remove_head(&mut self, head: &ObjectId) -> Result<(), StorageError> { + Self::HEADS.remove(self, head) + } + + pub fn has_head(&mut self, head: &ObjectId) -> Result<(), StorageError> { + Self::HEADS.has(self, head) + } + + pub fn get_all_heads(&mut self) -> Result, StorageError> { + Self::HEADS.get_all(self) + } + + pub fn add_user(&mut self, user: &UserId) -> Result<(), StorageError> { + Self::USERS.add(self, user) + } + pub fn remove_user(&mut self, user: &UserId) -> Result<(), StorageError> { + Self::USERS.remove(self, user) + } + + pub fn has_user(&mut self, user: &UserId) -> Result<(), StorageError> { + Self::USERS.has(self, user) + } + + pub fn get_all_users(&mut self) -> Result, StorageError> { + Self::USERS.get_all(self) } } diff --git a/ng-net/src/actors/add_invitation.rs b/ng-net/src/actors/admin/add_invitation.rs similarity index 99% rename from ng-net/src/actors/add_invitation.rs rename to ng-net/src/actors/admin/add_invitation.rs index 0b555c4..dc5e6ed 100644 --- a/ng-net/src/actors/add_invitation.rs +++ b/ng-net/src/actors/admin/add_invitation.rs @@ -19,7 +19,7 @@ use ng_repo::types::PubKey; use serde::{Deserialize, Serialize}; use std::sync::Arc; -use super::StartProtocol; +use super::super::StartProtocol; /// Add invitation #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/ng-net/src/actors/add_user.rs b/ng-net/src/actors/admin/add_user.rs similarity index 98% rename from ng-net/src/actors/add_user.rs rename to ng-net/src/actors/admin/add_user.rs index b8a0ca2..9bf1aaa 100644 --- a/ng-net/src/actors/add_user.rs +++ b/ng-net/src/actors/admin/add_user.rs @@ -19,7 +19,7 @@ use ng_repo::types::PubKey; use serde::{Deserialize, Serialize}; use std::sync::Arc; -use super::StartProtocol; +use super::super::StartProtocol; /// Add user account #[derive(Clone, Copy, Debug, Serialize, Deserialize)] diff --git a/ng-net/src/actors/del_user.rs b/ng-net/src/actors/admin/del_user.rs similarity index 98% rename from ng-net/src/actors/del_user.rs rename to ng-net/src/actors/admin/del_user.rs index 695e41e..1f4d316 100644 --- a/ng-net/src/actors/del_user.rs +++ b/ng-net/src/actors/admin/del_user.rs @@ -18,7 +18,7 @@ use ng_repo::types::PubKey; use serde::{Deserialize, Serialize}; use std::sync::Arc; -use super::StartProtocol; +use super::super::StartProtocol; /// Delete user account V0 #[derive(Clone, Copy, Debug, Serialize, Deserialize)] diff --git a/ng-net/src/actors/list_invitations.rs b/ng-net/src/actors/admin/list_invitations.rs similarity index 99% rename from ng-net/src/actors/list_invitations.rs rename to ng-net/src/actors/admin/list_invitations.rs index 5b9a947..1a2f2f8 100644 --- a/ng-net/src/actors/list_invitations.rs +++ b/ng-net/src/actors/admin/list_invitations.rs @@ -19,7 +19,7 @@ use ng_repo::types::PubKey; use serde::{Deserialize, Serialize}; use std::sync::Arc; -use super::StartProtocol; +use super::super::StartProtocol; /// List invitations registered on this broker #[derive(Clone, Copy, Debug, Serialize, Deserialize)] diff --git a/ng-net/src/actors/list_users.rs b/ng-net/src/actors/admin/list_users.rs similarity index 98% rename from ng-net/src/actors/list_users.rs rename to ng-net/src/actors/admin/list_users.rs index 10ff532..11faaf2 100644 --- a/ng-net/src/actors/list_users.rs +++ b/ng-net/src/actors/admin/list_users.rs @@ -19,7 +19,7 @@ use ng_repo::types::PubKey; use serde::{Deserialize, Serialize}; use std::sync::Arc; -use super::StartProtocol; +use super::super::StartProtocol; /// List users registered on this broker #[derive(Clone, Copy, Debug, Serialize, Deserialize)] diff --git a/ng-net/src/actors/admin/mod.rs b/ng-net/src/actors/admin/mod.rs new file mode 100644 index 0000000..76596b5 --- /dev/null +++ b/ng-net/src/actors/admin/mod.rs @@ -0,0 +1,14 @@ +pub mod add_user; +pub use add_user::*; + +pub mod del_user; +pub use del_user::*; + +pub mod list_users; +pub use list_users::*; + +pub mod add_invitation; +pub use add_invitation::*; + +pub mod list_invitations; +pub use list_invitations::*; diff --git a/ng-net/src/actors/mod.rs b/ng-net/src/actors/mod.rs index a377e5c..523308e 100644 --- a/ng-net/src/actors/mod.rs +++ b/ng-net/src/actors/mod.rs @@ -9,22 +9,9 @@ pub use start::*; pub mod probe; pub use probe::*; -pub mod add_user; -pub use add_user::*; - -pub mod del_user; -pub use del_user::*; - -pub mod list_users; -pub use list_users::*; - -pub mod add_invitation; -pub use add_invitation::*; - -pub mod list_invitations; -pub use list_invitations::*; - pub mod connecting; pub use connecting::*; pub mod client; + +pub mod admin; diff --git a/ng-net/src/types.rs b/ng-net/src/types.rs index 2a41254..993951c 100644 --- a/ng-net/src/types.rs +++ b/ng-net/src/types.rs @@ -16,7 +16,7 @@ use crate::utils::{ is_public_ipv4, is_public_ipv6, }; use crate::WS_PORT_ALTERNATE; -use crate::{actor::EActor, actors::*}; +use crate::{actor::EActor, actors::admin::*, actors::*}; use core::fmt; use ng_repo::errors::*; use ng_repo::log::*; diff --git a/ng-repo/src/kcv_storage.rs b/ng-repo/src/kcv_storage.rs index 149438a..b2f4548 100644 --- a/ng-repo/src/kcv_storage.rs +++ b/ng-repo/src/kcv_storage.rs @@ -6,13 +6,346 @@ // notice may not be copied, modified, or distributed except // according to those terms. -//! KeyColumnValue Store abstraction +//! KeyColumnValue Storage abstraction use std::collections::HashMap; +use std::{collections::HashSet, marker::PhantomData}; use crate::errors::StorageError; +use serde::{Deserialize, Serialize}; +use serde_bare::{from_slice, to_vec}; -// TODO:remove mut on self for trait WriteTransaction methods +pub fn prop(prop: u8, props: &HashMap>) -> Result +where + A: for<'a> Deserialize<'a>, +{ + Ok(from_slice( + &props.get(&prop).ok_or(StorageError::PropertyNotFound)?, + )?) +} + +pub struct Class<'a> { + columns: Vec<&'a dyn ISingleValueColumn>, + multi_value_columns: Vec<&'a dyn IMultiValueColumn>, + existential_column: &'a dyn ISingleValueColumn, + prefix: u8, +} + +impl<'a> Class<'a> { + pub fn new( + prefix: u8, + existential_column: &'a dyn ISingleValueColumn, + columns: Vec<&'a dyn ISingleValueColumn>, + multi_value_columns: Vec<&'a dyn IMultiValueColumn>, + ) -> Self { + // check unicity of prefixes and suffixes + #[cfg(test)] + { + let mut prefixes = HashSet::from([prefix]); + let mut suffixes = HashSet::from([existential_column.suffix()]); + for column in columns.iter() { + if !suffixes.insert(column.suffix()) { + panic!("duplicate suffix {} !!! check the code", column.suffix()); + } + } + for mvc in multi_value_columns.iter() { + if !prefixes.insert(mvc.prefix()) { + panic!("duplicate prefix {} !!! check the code", mvc.prefix()); + } + } + } + Self { + columns, + multi_value_columns, + prefix, + existential_column, + } + } + fn suffices(&self) -> Vec { + let mut res: Vec = self.columns.iter().map(|c| c.suffix()).collect(); + res.push(self.existential_column.suffix()); + res + } +} + +pub trait IModel { + fn key(&self) -> &Vec; + fn prefix(&self) -> u8 { + self.class().prefix + } + fn check_exists(&mut self) -> Result<(), StorageError> { + if !self.exists() { + return Err(StorageError::NotFound); + } + Ok(()) + } + fn existential(&mut self) -> &mut dyn IExistentialValue; + fn exists(&mut self) -> bool { + if self.existential().exists() { + return true; + } + let prefix = self.prefix(); + let key = self.key(); + let suffix = self.class().existential_column.suffix(); + match self.storage().get(prefix, key, Some(suffix), &None) { + Ok(res) => { + self.existential().process_exists(res); + true + } + Err(e) => false, + } + } + fn storage(&self) -> &dyn KCVStorage; + fn load_props(&self) -> Result>, StorageError> { + self.storage().get_all_properties_of_key( + self.prefix(), + self.key().to_vec(), + self.class().suffices(), + &None, + ) + } + fn class(&self) -> &Class; + fn del(&self) -> Result<(), StorageError> { + self.storage().write_transaction(&mut |tx| { + tx.del_all(self.prefix(), self.key(), &self.class().suffices(), &None)?; + for mvc in self.class().multi_value_columns.iter() { + let size = mvc.value_size()?; + tx.del_all_values(self.prefix(), self.key(), size, None, &None)?; + } + Ok(()) + })?; + Ok(()) + } +} +use std::hash::Hash; +pub struct MultiValueColumn< + Model: IModel, + Column: Eq + PartialEq + Hash + Serialize + Default + for<'a> Deserialize<'a>, +> { + prefix: u8, + phantom: PhantomData, + model: PhantomData, +} + +impl< + Model: IModel, + Column: Eq + PartialEq + Hash + Serialize + Default + for<'d> Deserialize<'d>, + > MultiValueColumn +{ + pub fn new(prefix: u8) -> Self { + MultiValueColumn { + prefix, + phantom: PhantomData, + model: PhantomData, + } + } + pub fn add(&self, model: &mut Model, column: &Column) -> Result<(), StorageError> { + model.check_exists()?; + model + .storage() + .put(self.prefix, model.key(), None, &to_vec(column)?, &None) + } + pub fn remove(&self, model: &mut Model, column: &Column) -> Result<(), StorageError> { + model.check_exists()?; + model + .storage() + .del_property_value(self.prefix, model.key(), None, &to_vec(column)?, &None) + } + + pub fn has(&self, model: &mut Model, column: &Column) -> Result<(), StorageError> { + model.check_exists()?; + model + .storage() + .has_property_value(self.prefix, model.key(), None, &to_vec(column)?, &None) + } + + pub fn get_all(&self, model: &mut Model) -> Result, StorageError> { + model.check_exists()?; + let key_prefix = model.key(); + let value_size = to_vec(&Column::default())?.len(); + + let mut res: HashSet = HashSet::new(); + let total_size = key_prefix.len() + value_size; + for user in model.storage().get_all_keys_and_values( + self.prefix, + total_size, + key_prefix.to_vec(), + None, + &None, + )? { + if user.0.len() == total_size + 1 { + let user: Column = from_slice(&user.0[1..user.0.len()])?; + res.insert(user); + } + } + Ok(res) + } +} +impl< + Model: IModel, + Column: Eq + PartialEq + Hash + Serialize + Default + for<'d> Deserialize<'d>, + > IMultiValueColumn for MultiValueColumn +{ + fn value_size(&self) -> Result { + Ok(to_vec(&Column::default())?.len()) + } + fn prefix(&self) -> u8 { + self.prefix + } +} + +pub trait ISingleValueColumn { + fn suffix(&self) -> u8; +} + +pub trait IMultiValueColumn { + fn prefix(&self) -> u8; + fn value_size(&self) -> Result; +} + +pub struct SingleValueColumn Deserialize<'a>> { + suffix: u8, + phantom: PhantomData, + model: PhantomData, +} + +impl Deserialize<'d>> ISingleValueColumn + for SingleValueColumn +{ + fn suffix(&self) -> u8 { + self.suffix + } +} + +pub struct ExistentialValueColumn { + suffix: u8, +} + +impl ISingleValueColumn for ExistentialValueColumn { + fn suffix(&self) -> u8 { + self.suffix + } +} + +impl ExistentialValueColumn { + pub fn new(suffix: u8) -> Self { + ExistentialValueColumn { suffix } + } +} + +impl Deserialize<'d>> SingleValueColumn { + pub fn new(suffix: u8) -> Self { + SingleValueColumn { + suffix, + phantom: PhantomData, + model: PhantomData, + } + } + + pub fn set(&self, model: &mut Model, column: &Column) -> Result<(), StorageError> { + model.check_exists()?; + model.storage().replace( + model.prefix(), + model.key(), + Some(self.suffix), + &to_vec(column)?, + &None, + ) + } + pub fn get(&self, model: &mut Model) -> Result { + model.check_exists()?; + match model + .storage() + .get(model.prefix(), model.key(), Some(self.suffix), &None) + { + Ok(res) => Ok(from_slice::(&res)?), + Err(e) => Err(e), + } + } + + pub fn has(&self, model: &mut Model, column: &Column) -> Result<(), StorageError> { + model.check_exists()?; + model.storage().has_property_value( + model.prefix(), + model.key(), + Some(self.suffix), + &to_vec(column)?, + &None, + ) + } + + pub fn del( + &self, + model: &mut Model, + tx: &mut dyn WriteTransaction, + ) -> Result<(), StorageError> { + tx.del(model.prefix(), model.key(), Some(self.suffix), &None) + } +} + +pub struct ExistentialValue Deserialize<'d>> { + value: Option, + value_ser: Vec, +} +pub trait IExistentialValue { + fn process_exists(&mut self, value_ser: Vec); + + fn exists(&self) -> bool; +} + +impl Deserialize<'d>> IExistentialValue for ExistentialValue { + fn exists(&self) -> bool { + self.value.is_some() || self.value_ser.len() > 0 + } + fn process_exists(&mut self, value_ser: Vec) { + self.value_ser = value_ser; + } +} + +impl Deserialize<'d>> ExistentialValue { + pub fn new() -> Self { + ExistentialValue { + value: None, + value_ser: vec![], + } + } + + pub fn set( + &mut self, + value: &Column, + model: &Model, + ) -> Result<(), StorageError> { + if self.value.is_some() { + return Err(StorageError::AlreadyExists); + } + model.storage().replace( + model.prefix(), + model.key(), + Some(model.class().existential_column.suffix()), + &to_vec(value)?, + &None, + )?; + self.value = Some(value.clone()); + Ok(()) + } + + pub fn get(&mut self) -> Result<&Column, StorageError> { + if self.value.is_some() { + return Ok(self.value.as_ref().unwrap()); + } + if self.value_ser.len() == 0 { + return Err(StorageError::BackendError); + } + let value = from_slice::(&self.value_ser); + match value { + Err(_) => return Err(StorageError::InvalidValue), + Ok(val) => { + self.value = Some(val); + return Ok(self.value.as_ref().unwrap()); + } + } + } +} pub trait WriteTransaction: ReadTransaction { /// Save a property value to the store. diff --git a/ng-repo/src/types.rs b/ng-repo/src/types.rs index 86616ac..4ce3535 100644 --- a/ng-repo/src/types.rs +++ b/ng-repo/src/types.rs @@ -137,6 +137,12 @@ pub enum PubKey { X25519PubKey(X25519PubKey), } +impl Default for PubKey { + fn default() -> Self { + Self::nil() + } +} + impl PubKey { pub fn slice(&self) -> &[u8; 32] { match self { @@ -398,6 +404,12 @@ pub struct BlockRef { pub key: BlockKey, } +impl Default for BlockId { + fn default() -> Self { + Self::nil() + } +} + impl BlockId { #[cfg(any(test, feature = "testing"))] pub fn dummy() -> Self { diff --git a/ng-verifier/src/user_storage/branch.rs b/ng-verifier/src/user_storage/branch.rs index 3ca93e9..0396912 100644 --- a/ng-verifier/src/user_storage/branch.rs +++ b/ng-verifier/src/user_storage/branch.rs @@ -19,6 +19,7 @@ use ng_net::types::*; use ng_repo::block_storage::BlockStorage; use ng_repo::errors::ProtocolError; use ng_repo::errors::StorageError; +use ng_repo::kcv_storage::prop; use ng_repo::kcv_storage::KCVStorage; use ng_repo::repo::BranchInfo; use ng_repo::repo::Repo; @@ -36,8 +37,6 @@ use ng_repo::types::TopicId; use serde_bare::from_slice; use serde_bare::to_vec; -use super::prop; - pub struct BranchStorage<'a> { storage: &'a dyn KCVStorage, id: BranchId, @@ -87,6 +86,8 @@ impl<'a> BranchStorage<'a> { ) } + //TODO: save all branch info under the repo_id (key prefix should be repo_id) + pub fn create( id: &BranchId, read_cap: &ReadCap, diff --git a/ng-verifier/src/user_storage/mod.rs b/ng-verifier/src/user_storage/mod.rs index 27616cc..f39d0ef 100644 --- a/ng-verifier/src/user_storage/mod.rs +++ b/ng-verifier/src/user_storage/mod.rs @@ -14,16 +14,3 @@ pub use storage::*; pub mod repo; pub mod branch; - -use ng_repo::errors::StorageError; -use serde::Deserialize; -use serde_bare::from_slice; -use std::collections::HashMap; -pub(crate) fn prop(prop: u8, props: &HashMap>) -> Result -where - A: for<'a> Deserialize<'a>, -{ - Ok(from_slice( - &props.get(&prop).ok_or(StorageError::PropertyNotFound)?, - )?) -} diff --git a/ng-verifier/src/user_storage/repo.rs b/ng-verifier/src/user_storage/repo.rs index a9edf6a..7eb7c63 100644 --- a/ng-verifier/src/user_storage/repo.rs +++ b/ng-verifier/src/user_storage/repo.rs @@ -21,6 +21,7 @@ use ng_net::types::*; use ng_repo::block_storage::BlockStorage; use ng_repo::errors::ProtocolError; use ng_repo::errors::StorageError; +use ng_repo::kcv_storage::prop; use ng_repo::kcv_storage::KCVStorage; use ng_repo::log::*; use ng_repo::repo::BranchInfo; @@ -43,7 +44,6 @@ use serde_bare::to_vec; use std::sync::{Arc, RwLock}; use super::branch::BranchStorage; -use super::prop; pub struct RepoStorage<'a> { storage: &'a dyn KCVStorage, diff --git a/ngaccount/src/main.rs b/ngaccount/src/main.rs index 1f910de..9d02273 100644 --- a/ngaccount/src/main.rs +++ b/ngaccount/src/main.rs @@ -13,7 +13,7 @@ mod types; use duration_str::parse; use ng_client_ws::remote_ws::ConnectionWebSocket; -use ng_net::actors::add_invitation::*; +use ng_net::actors::admin::add_invitation::*; use ng_net::broker::BROKER; use serde::{Deserialize, Serialize}; use warp::http::header::{HeaderMap, HeaderValue}; diff --git a/ngcli/src/main.rs b/ngcli/src/main.rs index 6b7ae96..5a441b8 100644 --- a/ngcli/src/main.rs +++ b/ngcli/src/main.rs @@ -12,7 +12,7 @@ use ed25519_dalek::*; use core::fmt; use duration_str::parse; use futures::{future, pin_mut, stream, SinkExt, StreamExt}; -use ng_net::actors::*; +use ng_net::actors::admin::*; use ng_repo::block_storage::{ store_max_value_size, store_valid_value_size, BlockStorage, HashMapBlockStorage, };