getting dressed for first release

pull/19/head
Niko PLP 8 months ago
parent 9c43d577dd
commit 481c4a96fd
  1. 15
      nextgraph/examples/in_memory.rs
  2. 13
      nextgraph/examples/open.rs
  3. 19
      nextgraph/examples/persistent.rs
  4. 65
      nextgraph/src/local_broker.rs
  5. 56
      ng-app/src-tauri/src/lib.rs
  6. 14
      ng-app/src/App.svelte
  7. 4
      ng-app/src/lib/Install.svelte
  8. 5
      ng-app/src/lib/Login.svelte
  9. 6
      ng-app/src/lib/Test.svelte
  10. 2
      ng-app/src/routes/Test.svelte
  11. 3
      ng-app/src/routes/User.svelte
  12. 7
      ng-app/src/routes/WalletCreate.svelte
  13. 7
      ng-app/src/routes/WalletLogin.svelte
  14. 58
      ng-broker/src/rocksdb_server_storage.rs
  15. 28
      ng-broker/src/server_broker.rs
  16. 9
      ng-broker/src/server_storage/admin/account.rs
  17. 18
      ng-broker/src/server_storage/admin/invitation.rs
  18. 9
      ng-broker/src/server_storage/admin/wallet.rs
  19. 105
      ng-broker/src/server_storage/config.rs
  20. 12
      ng-broker/src/server_storage/core/commit.rs
  21. 9
      ng-broker/src/server_storage/core/overlay.rs
  22. 9
      ng-broker/src/server_storage/core/peer.rs
  23. 10
      ng-broker/src/server_storage/core/repo.rs
  24. 5
      ng-broker/src/server_storage/core/topic.rs
  25. 2
      ng-broker/src/server_storage/mod.rs
  26. 69
      ng-broker/src/server_ws.rs
  27. 7
      ng-broker/src/types.rs
  28. 47
      ng-client-ws/src/remote_ws.rs
  29. 38
      ng-client-ws/src/remote_ws_wasm.rs
  30. 18
      ng-net/src/actor.rs
  31. 19
      ng-net/src/actors/admin/add_invitation.rs
  32. 18
      ng-net/src/actors/admin/add_user.rs
  33. 16
      ng-net/src/actors/admin/del_user.rs
  34. 20
      ng-net/src/actors/admin/list_invitations.rs
  35. 20
      ng-net/src/actors/admin/list_users.rs
  36. 16
      ng-net/src/actors/client/blocks_exist.rs
  37. 19
      ng-net/src/actors/client/blocks_get.rs
  38. 16
      ng-net/src/actors/client/blocks_put.rs
  39. 19
      ng-net/src/actors/client/commit_get.rs
  40. 28
      ng-net/src/actors/client/event.rs
  41. 17
      ng-net/src/actors/client/pin_repo.rs
  42. 16
      ng-net/src/actors/client/repo_pin_status.rs
  43. 15
      ng-net/src/actors/client/topic_sub.rs
  44. 19
      ng-net/src/actors/client/topic_sync_req.rs
  45. 20
      ng-net/src/actors/connecting.rs
  46. 11
      ng-net/src/actors/noise.rs
  47. 18
      ng-net/src/actors/probe.rs
  48. 31
      ng-net/src/actors/start.rs
  49. 74
      ng-net/src/broker.rs
  50. 37
      ng-net/src/connection.rs
  51. 84
      ng-net/src/errors.rs
  52. 4
      ng-net/src/lib.rs
  53. 3
      ng-net/src/server_broker.rs
  54. 33
      ng-net/src/types.rs
  55. 23
      ng-net/src/utils.rs
  56. 10
      ng-repo/src/block.rs
  57. 13
      ng-repo/src/block_storage.rs
  58. 88
      ng-repo/src/branch.rs
  59. 20
      ng-repo/src/commit.rs
  60. 11
      ng-repo/src/errors.rs
  61. 16
      ng-repo/src/event.rs
  62. 9
      ng-repo/src/file.rs
  63. 67
      ng-repo/src/kcv_storage.rs
  64. 35
      ng-repo/src/object.rs
  65. 11
      ng-repo/src/os_info.rs
  66. 33
      ng-repo/src/repo.rs
  67. 17
      ng-repo/src/store.rs
  68. 23
      ng-repo/src/types.rs
  69. 10
      ng-repo/src/utils.rs
  70. 2
      ng-sdk-js/README.md
  71. 185
      ng-sdk-js/src/lib.rs
  72. 25
      ng-storage-rocksdb/src/block_storage.rs
  73. 33
      ng-storage-rocksdb/src/kcv_storage.rs
  74. 76
      ng-verifier/src/commits/mod.rs
  75. 26
      ng-verifier/src/request_processor.rs
  76. 26
      ng-verifier/src/rocksdb_user_storage.rs
  77. 21
      ng-verifier/src/site.rs
  78. 32
      ng-verifier/src/types.rs
  79. 25
      ng-verifier/src/user_storage/branch.rs
  80. 27
      ng-verifier/src/user_storage/repo.rs
  81. 35
      ng-verifier/src/user_storage/storage.rs
  82. 282
      ng-verifier/src/verifier.rs
  83. 1
      ng-wallet/src/bip39.rs
  84. 4
      ng-wallet/src/emojis.rs
  85. 61
      ng-wallet/src/lib.rs
  86. 20
      ng-wallet/src/types.rs
  87. 37
      ngaccount/src/main.rs
  88. 3
      ngaccount/src/types.rs
  89. 42
      ngcli/src/main.rs
  90. 1
      ngd/src/cli.rs
  91. 67
      ngd/src/main.rs

@ -7,6 +7,9 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use std::fs::read;
#[allow(unused_imports)]
use nextgraph::local_broker::{ use nextgraph::local_broker::{
app_request, app_request_stream, init_local_broker, session_start, session_stop, user_connect, app_request, app_request_stream, init_local_broker, session_start, session_stop, user_connect,
user_disconnect, wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import, user_disconnect, wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import,
@ -19,9 +22,6 @@ use nextgraph::repo::types::PubKey;
use nextgraph::wallet::types::CreateWalletV0; use nextgraph::wallet::types::CreateWalletV0;
use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle}; use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle};
use std::env::current_dir;
use std::fs::read;
#[async_std::main] #[async_std::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
// initialize the local_broker with in-memory config. // initialize the local_broker with in-memory config.
@ -64,7 +64,12 @@ async fn main() -> std::io::Result<()> {
let mut pazzle_words = vec![]; let mut pazzle_words = vec![];
println!("Your pazzle is: {:?}", wallet_result.pazzle); println!("Your pazzle is: {:?}", wallet_result.pazzle);
for emoji in pazzle { for emoji in pazzle {
println!(" {}:\t{}", emoji.0, emoji.1); println!(
"\t{}:\t{}{}",
emoji.0,
if emoji.0.len() > 12 { "" } else { "\t" },
emoji.1
);
pazzle_words.push(emoji.1.to_string()); pazzle_words.push(emoji.1.to_string());
} }
println!("Your mnemonic is:"); println!("Your mnemonic is:");
@ -104,7 +109,7 @@ async fn main() -> std::io::Result<()> {
// if you have saved the wallet locally (which we haven't done in the example above, see `local_save: false`), next time you want to connect, // if you have saved the wallet locally (which we haven't done in the example above, see `local_save: false`), next time you want to connect,
// you can retrieve the wallet, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet // you can retrieve the wallet, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet
// if you haven't saved the wallet, the next line will not work once you restart the LocalBroker. // if you haven't saved the wallet, the next line will not work once you restart the LocalBroker.
let wallet = wallet_get(&wallet_result.wallet_name).await?; let _wallet = wallet_get(&wallet_result.wallet_name).await?;
// at this point, the wallet is kept in the internal memory of the LocalBroker // at this point, the wallet is kept in the internal memory of the LocalBroker
// and it hasn't been opened yet, so it is not usable right away. // and it hasn't been opened yet, so it is not usable right away.

@ -7,21 +7,16 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use std::env::current_dir;
use std::fs::create_dir_all;
#[allow(unused_imports)]
use nextgraph::local_broker::{ use nextgraph::local_broker::{
app_request, app_request_stream, init_local_broker, session_start, session_stop, user_connect, app_request, app_request_stream, init_local_broker, session_start, session_stop, user_connect,
user_disconnect, wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import, user_disconnect, wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import,
wallet_open_with_pazzle, wallet_open_with_pazzle_words, wallet_read_file, wallet_was_opened, wallet_open_with_pazzle, wallet_open_with_pazzle_words, wallet_read_file, wallet_was_opened,
LocalBrokerConfig, SessionConfig, LocalBrokerConfig, SessionConfig,
}; };
use nextgraph::net::types::BootstrapContentV0;
use nextgraph::repo::errors::NgError;
use nextgraph::repo::types::PubKey;
use nextgraph::wallet::types::CreateWalletV0;
use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle};
use std::env::current_dir;
use std::fs::create_dir_all;
use std::fs::read;
#[async_std::main] #[async_std::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {

@ -7,6 +7,11 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use std::env::current_dir;
use std::fs::create_dir_all;
use std::fs::read;
#[allow(unused_imports)]
use nextgraph::local_broker::{ use nextgraph::local_broker::{
app_request, app_request_stream, init_local_broker, session_start, session_stop, user_connect, app_request, app_request_stream, init_local_broker, session_start, session_stop, user_connect,
user_disconnect, wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import, user_disconnect, wallet_close, wallet_create_v0, wallet_get, wallet_get_file, wallet_import,
@ -14,15 +19,10 @@ use nextgraph::local_broker::{
SessionConfig, SessionConfig,
}; };
use nextgraph::net::types::BootstrapContentV0; use nextgraph::net::types::BootstrapContentV0;
use nextgraph::repo::errors::NgError;
use nextgraph::repo::types::PubKey; use nextgraph::repo::types::PubKey;
use nextgraph::wallet::types::CreateWalletV0; use nextgraph::wallet::types::CreateWalletV0;
use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle}; use nextgraph::wallet::{display_mnemonic, emojis::display_pazzle};
use std::env::current_dir;
use std::fs::create_dir_all;
use std::fs::read;
#[async_std::main] #[async_std::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
// get the current working directory // get the current working directory
@ -72,7 +72,12 @@ async fn main() -> std::io::Result<()> {
let mut pazzle_words = vec![]; let mut pazzle_words = vec![];
println!("Your pazzle is: {:?}", wallet_result.pazzle); println!("Your pazzle is: {:?}", wallet_result.pazzle);
for emoji in pazzle { for emoji in pazzle {
println!(" {}:\t{}", emoji.0, emoji.1); println!(
"\t{}:\t{}{}",
emoji.0,
if emoji.0.len() > 12 { "" } else { "\t" },
emoji.1
);
pazzle_words.push(emoji.1.to_string()); pazzle_words.push(emoji.1.to_string());
} }
println!("Your mnemonic is:"); println!("Your mnemonic is:");
@ -111,7 +116,7 @@ async fn main() -> std::io::Result<()> {
// as we have saved the wallet, the next time we want to connect, // as we have saved the wallet, the next time we want to connect,
// we can retrieve the wallet, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet // we can retrieve the wallet, display the security phrase and image to the user, ask for the pazzle or mnemonic, and then open the wallet
let wallet = wallet_get(&wallet_result.wallet_name).await?; let _wallet = wallet_get(&wallet_result.wallet_name).await?;
// at this point, the wallet is kept in the internal memory of the LocalBroker // at this point, the wallet is kept in the internal memory of the LocalBroker
// and it hasn't been opened yet, so it is not usable right away. // and it hasn't been opened yet, so it is not usable right away.

@ -7,34 +7,38 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use async_once_cell::OnceCell;
use async_std::sync::{Arc, Mutex, RwLock, RwLockReadGuard};
use core::fmt; use core::fmt;
use std::collections::HashMap;
use std::fs::{read, remove_file, write};
use std::path::PathBuf;
use async_once_cell::OnceCell;
use async_std::sync::{Arc, Mutex, RwLock};
use futures::channel::mpsc; use futures::channel::mpsc;
use futures::SinkExt; use futures::SinkExt;
use ng_net::actor::EActor;
use ng_net::connection::{ClientConfig, IConnect, NoiseFSM, StartConfig};
use ng_net::types::{ClientInfo, ClientType, ProtocolMessage};
use ng_net::utils::{Receiver, Sender};
use ng_repo::block_storage::HashMapBlockStorage;
use ng_repo::os_info::get_os_info;
use ng_verifier::types::*;
use ng_verifier::verifier::Verifier;
use ng_wallet::emojis::encode_pazzle;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use serde_bare::to_vec; use serde_bare::to_vec;
use serde_json::json; use serde_json::json;
use std::collections::HashMap; use zeroize::Zeroize;
use std::fs::{read, remove_file, write, File, OpenOptions};
use std::path::PathBuf;
use zeroize::{Zeroize, ZeroizeOnDrop};
use ng_net::broker::*;
use ng_repo::block_storage::BlockStorage; use ng_repo::block_storage::BlockStorage;
use ng_repo::block_storage::HashMapBlockStorage;
use ng_repo::errors::{NgError, ProtocolError}; use ng_repo::errors::{NgError, ProtocolError};
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::os_info::get_os_info;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::derive_key; use ng_repo::utils::derive_key;
use ng_net::actor::EActor;
use ng_net::broker::*;
use ng_net::connection::{ClientConfig, IConnect, NoiseFSM, StartConfig};
use ng_net::types::{ClientInfo, ClientType, ProtocolMessage};
use ng_net::utils::{Receiver, Sender};
use ng_verifier::types::*;
use ng_verifier::verifier::Verifier;
use ng_wallet::emojis::encode_pazzle;
use ng_wallet::{create_wallet_first_step_v0, create_wallet_second_step_v0, types::*}; use ng_wallet::{create_wallet_first_step_v0, create_wallet_second_step_v0, types::*};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -192,6 +196,7 @@ impl LocalBrokerConfig {
_ => None, _ => None,
} }
} }
#[cfg(not(target_family = "wasm"))]
fn compute_path(&self, dir: &String) -> Result<PathBuf, NgError> { fn compute_path(&self, dir: &String) -> Result<PathBuf, NgError> {
match self { match self {
Self::BasePath(path) => { Self::BasePath(path) => {
@ -221,6 +226,7 @@ pub enum SessionConfig {
struct Session { struct Session {
config: SessionConfig, config: SessionConfig,
peer_key: PrivKey, peer_key: PrivKey,
#[allow(dead_code)]
last_wallet_nonce: u64, last_wallet_nonce: u64,
verifier: Verifier, verifier: Verifier,
} }
@ -536,6 +542,8 @@ impl LocalBroker {
) -> Result<ClientV0, NgError> { ) -> Result<ClientV0, NgError> {
let broker = self; let broker = self;
//log_info!("wallet_was_opened {}", wallet.id());
match broker.opened_wallets.get(&wallet.id()) { match broker.opened_wallets.get(&wallet.id()) {
Some(opened_wallet) => { Some(opened_wallet) => {
return Ok(opened_wallet.wallet.client().to_owned().unwrap()); return Ok(opened_wallet.wallet.client().to_owned().unwrap());
@ -591,7 +599,7 @@ impl LocalBroker {
wallet, wallet,
block_storage, block_storage,
}; };
//log_info!("inserted wallet_was_opened {}", wallet_id);
broker.opened_wallets.insert(wallet_id, opened_wallet); broker.opened_wallets.insert(wallet_id, opened_wallet);
Ok(client) Ok(client)
} }
@ -845,7 +853,7 @@ impl LocalBroker {
return Err(NgError::IoError); return Err(NgError::IoError);
} }
} }
_ => panic!("wrong LocalBrokerConfig"), _ => return Err(NgError::CannotSaveWhenInMemoryConfig),
} }
Ok(()) Ok(())
} }
@ -1064,6 +1072,7 @@ pub async fn wallets_reload() -> Result<(), NgError> {
base64_url::decode(&wallets_string).map_err(|_| NgError::SerializationError)?; base64_url::decode(&wallets_string).map_err(|_| NgError::SerializationError)?;
let wallets: LocalWalletStorage = serde_bare::from_slice(&map_ser)?; let wallets: LocalWalletStorage = serde_bare::from_slice(&map_ser)?;
let LocalWalletStorage::V0(v0) = wallets; let LocalWalletStorage::V0(v0) = wallets;
//log_info!("adding wallet {:?}", v0);
broker.wallets.extend(v0); broker.wallets.extend(v0);
} }
_ => {} _ => {}
@ -1074,7 +1083,7 @@ pub async fn wallets_reload() -> Result<(), NgError> {
#[doc(hidden)] #[doc(hidden)]
/// This should not be used by programmers. Only here because the JS SDK needs it. /// This should not be used by programmers. Only here because the JS SDK needs it.
/// ///
/// It will throw and error if you use it. /// It will throw an error if you use it.
pub async fn wallet_add(lws: LocalWalletStorageV0) -> Result<(), NgError> { pub async fn wallet_add(lws: LocalWalletStorageV0) -> Result<(), NgError> {
let mut broker = match LOCAL_BROKER.get() { let mut broker = match LOCAL_BROKER.get() {
None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized), None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized),
@ -1210,7 +1219,7 @@ pub async fn wallet_import(
/// this is a separate step because in JS webapp, the opening of a wallet takes time and freezes the GUI. /// this is a separate step because in JS webapp, the opening of a wallet takes time and freezes the GUI.
/// We need to run it in the background in a WebWorker. but there, the LocalBroker cannot access localStorage... /// We need to run it in the background in a WebWorker. but there, the LocalBroker cannot access localStorage...
/// So a separate function must be called, once the WebWorker is done. /// So a separate function must be called, once the WebWorker is done.
pub async fn wallet_was_opened(mut wallet: SensitiveWallet) -> Result<ClientV0, NgError> { pub async fn wallet_was_opened(wallet: SensitiveWallet) -> Result<ClientV0, NgError> {
let mut broker = match LOCAL_BROKER.get() { let mut broker = match LOCAL_BROKER.get() {
None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized), None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized),
Some(Ok(broker)) => broker.write().await, Some(Ok(broker)) => broker.write().await,
@ -1224,7 +1233,7 @@ pub async fn wallet_was_opened(mut wallet: SensitiveWallet) -> Result<ClientV0,
/// The session is valid even if there is no internet. The local data will be used in this case. /// The session is valid even if there is no internet. The local data will be used in this case.
/// wallet_creation_events should be the list of events that was returned by wallet_create_v0 /// wallet_creation_events should be the list of events that was returned by wallet_create_v0
/// Return value is the index of the session, will be used in all the doc_* API calls. /// Return value is the index of the session, will be used in all the doc_* API calls.
pub async fn session_start(mut config: SessionConfig) -> Result<SessionInfo, NgError> { pub async fn session_start(config: SessionConfig) -> Result<SessionInfo, NgError> {
let mut broker = match LOCAL_BROKER.get() { let mut broker = match LOCAL_BROKER.get() {
None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized), None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized),
Some(Ok(broker)) => broker.write().await, Some(Ok(broker)) => broker.write().await,
@ -1324,7 +1333,11 @@ pub async fn user_connect_with_device_info(
let user_id = user.to_string(); let user_id = user.to_string();
let peer_key = &session.peer_key; let peer_key = &session.peer_key;
let peer_id = peer_key.to_pub(); let peer_id = peer_key.to_pub();
log_info!("local peer_id {}", peer_id); log_info!(
"connecting with local peer_id {} for user {}",
peer_id,
user_id
);
let site = wallet.sites.get(&user_id); let site = wallet.sites.get(&user_id);
if site.is_none() { if site.is_none() {
result.push(( result.push((
@ -1363,7 +1376,7 @@ pub async fn user_connect_with_device_info(
//Option<(String, Vec<BindAddress>)> //Option<(String, Vec<BindAddress>)>
if url.is_some() { if url.is_some() {
let url = url.unwrap(); let url = url.unwrap();
if url.1.len() == 0 { if url.1.is_empty() {
// TODO deal with Box(Dyn)Public -> tunnel, and on tauri/forward/CLIs, deal with all Box -> direct connections (when url.1.len is > 0) // TODO deal with Box(Dyn)Public -> tunnel, and on tauri/forward/CLIs, deal with all Box -> direct connections (when url.1.len is > 0)
let res = BROKER let res = BROKER
.write() .write()
@ -1488,16 +1501,14 @@ pub async fn wallet_close(wallet_name: &String) -> Result<(), NgError> {
} }
/// (not implemented yet) /// (not implemented yet)
pub async fn wallet_remove(wallet_name: String) -> Result<(), NgError> { pub async fn wallet_remove(_wallet_name: String) -> Result<(), NgError> {
let mut broker = match LOCAL_BROKER.get() { let _broker = match LOCAL_BROKER.get() {
None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized), None | Some(Err(_)) => return Err(NgError::LocalBrokerNotInitialized),
Some(Ok(broker)) => broker.write().await, Some(Ok(broker)) => broker.write().await,
}; };
todo!(); todo!();
// should close the wallet, then remove all the saved sessions and remove the wallet // should close the wallet, then remove all the saved sessions and remove the wallet
Ok(())
} }
// /// fetches a document's content. // /// fetches a document's content.

@ -6,25 +6,29 @@
// at your option. All files in the project carrying such // at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use std::collections::HashMap;
use std::fs::write;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use nextgraph::local_broker::*; use serde::{Deserialize, Serialize};
use nextgraph::verifier::types::*; use serde_json::Value;
use ng_net::broker::*; use tauri::scope::ipc::RemoteDomainAccessScope;
use ng_net::types::{ClientInfo, CreateAccountBSP, Invitation}; use tauri::utils::config::WindowConfig;
use ng_net::utils::{decode_invitation_string, spawn_and_log_error, Receiver, ResultSend}; use tauri::{path::BaseDirectory, App, Manager};
use ng_repo::errors::NgError; use ng_repo::errors::NgError;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::*; use ng_repo::types::*;
use ng_net::types::{ClientInfo, CreateAccountBSP, Invitation};
use ng_net::utils::{decode_invitation_string, spawn_and_log_error, Receiver, ResultSend};
use ng_wallet::types::*; use ng_wallet::types::*;
use ng_wallet::*; use ng_wallet::*;
use serde::{Deserialize, Serialize};
use serde_json::Value; use nextgraph::local_broker::*;
use std::collections::HashMap; use nextgraph::verifier::types::*;
use std::fs::{read, write, File, OpenOptions};
use std::io::Write;
use tauri::scope::ipc::RemoteDomainAccessScope;
use tauri::utils::config::WindowConfig;
use tauri::{path::BaseDirectory, App, Manager, Window};
#[cfg(mobile)] #[cfg(mobile)]
mod mobile; mod mobile;
@ -43,10 +47,10 @@ async fn test(app: tauri::AppHandle) -> Result<(), ()> {
init_local_broker(Box::new(move || LocalBrokerConfig::BasePath(path.clone()))).await; init_local_broker(Box::new(move || LocalBrokerConfig::BasePath(path.clone()))).await;
//log_debug!("test is {}", BROKER.read().await.test()); //log_debug!("test is {}", BROKER.read().await.test());
let path = app // let path = app
.path() // .path()
.resolve("storage", BaseDirectory::AppLocalData) // .resolve("storage", BaseDirectory::AppLocalData)
.map_err(|_| ())?; // .map_err(|_| ())?;
//BROKER.read().await.test_storage(path); //BROKER.read().await.test_storage(path);
@ -73,7 +77,7 @@ async fn wallet_open_with_pazzle(
wallet: Wallet, wallet: Wallet,
pazzle: Vec<u8>, pazzle: Vec<u8>,
pin: [u8; 4], pin: [u8; 4],
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<SensitiveWallet, String> { ) -> Result<SensitiveWallet, String> {
//log_debug!("wallet_open_with_pazzle from rust {:?}", pazzle); //log_debug!("wallet_open_with_pazzle from rust {:?}", pazzle);
let wallet = nextgraph::local_broker::wallet_open_with_pazzle(&wallet, pazzle, pin) let wallet = nextgraph::local_broker::wallet_open_with_pazzle(&wallet, pazzle, pin)
@ -126,7 +130,7 @@ async fn wallet_create(
} }
#[tauri::command(rename_all = "snake_case")] #[tauri::command(rename_all = "snake_case")]
async fn wallet_read_file(file: Vec<u8>, app: tauri::AppHandle) -> Result<Wallet, String> { async fn wallet_read_file(file: Vec<u8>, _app: tauri::AppHandle) -> Result<Wallet, String> {
nextgraph::local_broker::wallet_read_file(file) nextgraph::local_broker::wallet_read_file(file)
.await .await
.map_err(|e: NgError| e.to_string()) .map_err(|e: NgError| e.to_string())
@ -135,7 +139,7 @@ async fn wallet_read_file(file: Vec<u8>, app: tauri::AppHandle) -> Result<Wallet
#[tauri::command(rename_all = "snake_case")] #[tauri::command(rename_all = "snake_case")]
async fn wallet_was_opened( async fn wallet_was_opened(
opened_wallet: SensitiveWallet, opened_wallet: SensitiveWallet,
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<ClientV0, String> { ) -> Result<ClientV0, String> {
nextgraph::local_broker::wallet_was_opened(opened_wallet) nextgraph::local_broker::wallet_was_opened(opened_wallet)
.await .await
@ -147,7 +151,7 @@ async fn wallet_import(
encrypted_wallet: Wallet, encrypted_wallet: Wallet,
opened_wallet: SensitiveWallet, opened_wallet: SensitiveWallet,
in_memory: bool, in_memory: bool,
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<ClientV0, String> { ) -> Result<ClientV0, String> {
nextgraph::local_broker::wallet_import(encrypted_wallet, opened_wallet, in_memory) nextgraph::local_broker::wallet_import(encrypted_wallet, opened_wallet, in_memory)
.await .await
@ -178,7 +182,7 @@ async fn get_wallets(
async fn session_start( async fn session_start(
wallet_name: String, wallet_name: String,
user: PubKey, user: PubKey,
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<SessionInfo, String> { ) -> Result<SessionInfo, String> {
let config = SessionConfig::new_save(&user, &wallet_name); let config = SessionConfig::new_save(&user, &wallet_name);
nextgraph::local_broker::session_start(config) nextgraph::local_broker::session_start(config)
@ -191,7 +195,7 @@ async fn session_start_remote(
wallet_name: String, wallet_name: String,
user: PubKey, user: PubKey,
peer_id: Option<PubKey>, peer_id: Option<PubKey>,
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<SessionInfo, String> { ) -> Result<SessionInfo, String> {
let config = SessionConfig::new_remote(&user, &wallet_name, peer_id); let config = SessionConfig::new_remote(&user, &wallet_name, peer_id);
nextgraph::local_broker::session_start(config) nextgraph::local_broker::session_start(config)
@ -292,7 +296,7 @@ async fn doc_fetch_private_subscribe() -> Result<AppRequest, String> {
async fn app_request( async fn app_request(
session_id: u64, session_id: u64,
request: AppRequest, request: AppRequest,
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<AppResponse, String> { ) -> Result<AppResponse, String> {
log_debug!("app request {:?}", request); log_debug!("app request {:?}", request);
@ -307,7 +311,7 @@ async fn upload_chunk(
upload_id: u32, upload_id: u32,
chunk: serde_bytes::ByteBuf, chunk: serde_bytes::ByteBuf,
nuri: NuriV0, nuri: NuriV0,
app: tauri::AppHandle, _app: tauri::AppHandle,
) -> Result<AppResponse, String> { ) -> Result<AppResponse, String> {
//log_debug!("upload_chunk {:?}", chunk); //log_debug!("upload_chunk {:?}", chunk);
@ -399,7 +403,7 @@ struct ConnectionInfo {
async fn user_connect( async fn user_connect(
info: ClientInfo, info: ClientInfo,
user_id: UserId, user_id: UserId,
location: Option<String>, _location: Option<String>,
) -> Result<HashMap<String, ConnectionInfo>, String> { ) -> Result<HashMap<String, ConnectionInfo>, String> {
let mut opened_connections: HashMap<String, ConnectionInfo> = HashMap::new(); let mut opened_connections: HashMap<String, ConnectionInfo> = HashMap::new();

@ -161,12 +161,18 @@
break; break;
case "opened": case "opened":
if (!$opened_wallets[event.data.wallet.id]) { if (!$opened_wallets[event.data.wallet.id]) {
await tick();
// console.log( // console.log(
// "ADDING TO OPENED", // "ADDING TO OPENED",
// event.data.wallet.id, // event.data.wallet.id,
// JSON.stringify($opened_wallets), // JSON.stringify($opened_wallets),
// event.data.wallet.wallet // event.data.wallet.wallet
// ); // );
if (event.data.ng_wallets) {
localStorage.setItem("ng_wallets", event.data.ng_wallets);
await ng.wallets_reload();
wallets.set(await ng.get_wallets());
}
try { try {
await ng.wallet_was_opened(event.data.wallet.wallet); await ng.wallet_was_opened(event.data.wallet.wallet);
} catch (e) { } catch (e) {
@ -220,8 +226,14 @@
w[value.id] = value.wallet; w[value.id] = value.wallet;
return w; return w;
}); });
await tick();
//console.log("posting opened");
wallet_channel.postMessage( wallet_channel.postMessage(
{ cmd: "opened", wallet: value }, {
cmd: "opened",
wallet: value,
ng_wallets: localStorage.getItem("ng_wallets"),
},
location.href location.href
); );
} else { } else {

@ -52,7 +52,7 @@
</Alert> </Alert>
{/if} {/if}
<div class="row mt-5"> <div class="row mt-5">
<a href="#"> <a href="#/">
<button <button
tabindex="-1" tabindex="-1"
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2" class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2"
@ -92,7 +92,7 @@
</a> </a>
</div> </div>
<div class="row mt-5"> <div class="row mt-5">
<a href="#"> <a href="#/">
<button <button
tabindex="-1" tabindex="-1"
class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2" class="text-primary-700 bg-primary-100 hover:bg-primary-100/90 focus:ring-4 focus:ring-primary-100/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-100/55 mr-2 mb-2"

@ -503,11 +503,6 @@
margin-left: auto; margin-left: auto;
} }
.pin {
cursor: pointer;
text-align: center;
}
.sel { .sel {
position: absolute; position: absolute;
width: 100%; width: 100%;

@ -263,7 +263,11 @@
{#await get_img(file.V0.File) then url} {#await get_img(file.V0.File) then url}
{#if url} {#if url}
<img src={url} title={"did:ng" + file.V0.File.nuri} /> <img
src={url}
title={"did:ng" + file.V0.File.nuri}
alt={file.V0.File.name}
/>
{/if} {/if}
{/await} {/await}
</p> </p>

@ -11,7 +11,7 @@
<script lang="ts"> <script lang="ts">
import Test from "../lib/Test.svelte"; import Test from "../lib/Test.svelte";
export let params = {};
import { active_session } from "../store"; import { active_session } from "../store";
import { onMount, tick } from "svelte"; import { onMount, tick } from "svelte";
import { link, push } from "svelte-spa-router"; import { link, push } from "svelte-spa-router";

@ -206,6 +206,7 @@
{#if !downloading} {#if !downloading}
<li <li
tabindex="0" tabindex="0"
role="menuitem"
class="flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700" class="flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"
on:keypress={download_wallet} on:keypress={download_wallet}
on:click={download_wallet} on:click={download_wallet}
@ -355,6 +356,7 @@
<SidebarGroup border> <SidebarGroup border>
<li <li
tabindex="0" tabindex="0"
role="menuitem"
class="flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700" class="flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"
on:keypress={donate} on:keypress={donate}
on:click={donate} on:click={donate}
@ -368,6 +370,7 @@
<li <li
tabindex="0" tabindex="0"
role="menuitem"
class="flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700" class="flex items-center p-2 text-base font-normal text-gray-900 clickable rounded-lg dark:text-white hover:bg-gray-200 dark:hover:bg-gray-700"
on:keypress={about} on:keypress={about}
on:click={about} on:click={about}

@ -99,7 +99,8 @@
let phrase; let phrase;
let validate_button; let validate_button;
let animate_bounce; let animate_bounce;
let image_url; let image_url =
"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
let info_options; let info_options;
let options; let options;
let creating = false; let creating = false;
@ -707,7 +708,6 @@
<div class="row mb-20"> <div class="row mb-20">
<button <button
on:click|once={create_wallet} on:click|once={create_wallet}
role="button"
class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2" class="text-white bg-primary-700 hover:bg-primary-700/90 focus:ring-4 focus:ring-primary-700/50 font-medium rounded-lg text-lg px-5 py-2.5 text-center inline-flex items-center dark:focus:ring-primary-700/55 mb-2"
> >
<svg <svg
@ -1323,6 +1323,7 @@
bind:this={img_preview} bind:this={img_preview}
class="max-w-[250px] h-[250px] mx-auto mb-10" class="max-w-[250px] h-[250px] mx-auto mb-10"
src={image_url} src={image_url}
alt="your security"
/> />
{:else} {:else}
<Alert color="red" class="mt-5"> <Alert color="red" class="mt-5">
@ -1375,6 +1376,7 @@
<span <span
style="font-weight: 500;cursor: pointer; color: #646cff;" style="font-weight: 500;cursor: pointer; color: #646cff;"
tabindex="0" tabindex="0"
role="link"
on:keypress={tos} on:keypress={tos}
on:click={tos}>Terms of Service of our cloud</span on:click={tos}>Terms of Service of our cloud</span
>. >.
@ -1410,6 +1412,7 @@
<span <span
style="font-weight: 500;cursor: pointer; color: #646cff;" style="font-weight: 500;cursor: pointer; color: #646cff;"
tabindex="0" tabindex="0"
role="link"
on:keypress={tos} on:keypress={tos}
on:click={tos}>Terms of Service of our cloud</span on:click={tos}>Terms of Service of our cloud</span
>. >.

@ -10,7 +10,7 @@
--> -->
<script lang="ts"> <script lang="ts">
import { onMount, onDestroy } from "svelte"; import { onMount, onDestroy, tick } from "svelte";
import { link, push } from "svelte-spa-router"; import { link, push } from "svelte-spa-router";
import Login from "../lib/Login.svelte"; import Login from "../lib/Login.svelte";
import CenteredLayout from "../lib/CenteredLayout.svelte"; import CenteredLayout from "../lib/CenteredLayout.svelte";
@ -56,6 +56,7 @@
}); });
opened_wallets_unsub = opened_wallets.subscribe(async (value) => { opened_wallets_unsub = opened_wallets.subscribe(async (value) => {
if (!$active_wallet && selected && value[selected]) { if (!$active_wallet && selected && value[selected]) {
await tick();
active_wallet.set({ wallet: value[selected], id: selected }); active_wallet.set({ wallet: value[selected], id: selected });
} }
}); });
@ -136,6 +137,7 @@
let client = await ng.wallet_was_opened(event.detail.wallet); let client = await ng.wallet_was_opened(event.detail.wallet);
event.detail.wallet.V0.client = client; event.detail.wallet.V0.client = client;
} }
await tick();
active_wallet.set(event.detail); active_wallet.set(event.detail);
// { wallet, // { wallet,
// id } // id }
@ -356,8 +358,7 @@
</a> </a>
</div> </div>
</div> </div>
{:else if step == "security"}{:else if step == "qrcode"}{:else if step == "cloud"} <!-- {:else if step == "security"}{:else if step == "qrcode"}{:else if step == "cloud"} -->
{:else if step == "loggedin"} {:else if step == "loggedin"}
You are logged in.<br /> please wait while the app is loading...{/if} You are logged in.<br /> please wait while the app is loading...{/if}
</CenteredLayout> </CenteredLayout>

@ -12,27 +12,27 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fs::{read, File, OpenOptions}; use std::fs::{read, File, OpenOptions};
use std::io::Write; use std::io::Write;
use std::path::{Path, PathBuf}; use std::path::PathBuf;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use crate::server_broker::*;
use crate::server_storage::admin::account::Account;
use crate::server_storage::admin::invitation::Invitation;
use crate::server_storage::admin::wallet::Wallet;
use crate::server_storage::core::*;
use crate::types::*;
use ng_net::types::*;
use ng_repo::block_storage::{BlockStorage, HashMapBlockStorage}; use ng_repo::block_storage::{BlockStorage, HashMapBlockStorage};
use ng_repo::errors::{ProtocolError, ServerError, StorageError}; use ng_repo::errors::{ProtocolError, ServerError, StorageError};
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::object::Object; use ng_repo::object::Object;
use ng_repo::store::Store; use ng_repo::store::Store;
use ng_repo::types::*; use ng_repo::types::*;
use ng_net::types::*;
use ng_storage_rocksdb::block_storage::RocksDbBlockStorage; use ng_storage_rocksdb::block_storage::RocksDbBlockStorage;
use ng_storage_rocksdb::kcv_storage::RocksDbKCVStorage; use ng_storage_rocksdb::kcv_storage::RocksDbKCVStorage;
use crate::server_broker::*;
use crate::server_storage::admin::{account::Account, invitation::Invitation, wallet::Wallet};
use crate::server_storage::core::*;
pub(crate) struct RocksDbServerStorage { pub(crate) struct RocksDbServerStorage {
#[allow(dead_code)]
wallet_storage: RocksDbKCVStorage, wallet_storage: RocksDbKCVStorage,
accounts_storage: RocksDbKCVStorage, accounts_storage: RocksDbKCVStorage,
//peers_storage: RocksDbKCVStorage, //peers_storage: RocksDbKCVStorage,
@ -54,7 +54,7 @@ impl RocksDbServerStorage {
std::fs::create_dir_all(wallet_path.clone()).unwrap(); std::fs::create_dir_all(wallet_path.clone()).unwrap();
log_debug!("opening wallet DB"); log_debug!("opening wallet DB");
//TODO redo the whole key passing mechanism in RKV so it uses zeroize all the way //TODO redo the whole key passing mechanism in RKV so it uses zeroize all the way
let mut wallet_storage = RocksDbKCVStorage::open(&wallet_path, master_key.slice().clone())?; let wallet_storage = RocksDbKCVStorage::open(&wallet_path, master_key.slice().clone())?;
let wallet = Wallet::open(&wallet_storage); let wallet = Wallet::open(&wallet_storage);
// create/open the ACCOUNTS storage // create/open the ACCOUNTS storage
@ -93,7 +93,7 @@ impl RocksDbServerStorage {
log_debug!("opening accounts DB"); log_debug!("opening accounts DB");
std::fs::create_dir_all(accounts_path.clone()).unwrap(); std::fs::create_dir_all(accounts_path.clone()).unwrap();
//TODO redo the whole key passing mechanism in RKV so it uses zeroize all the way //TODO redo the whole key passing mechanism in RKV so it uses zeroize all the way
let mut accounts_storage = let accounts_storage =
RocksDbKCVStorage::open(&accounts_path, accounts_key.slice().clone())?; RocksDbKCVStorage::open(&accounts_path, accounts_key.slice().clone())?;
// create/open the PEERS storage // create/open the PEERS storage
@ -127,7 +127,10 @@ impl RocksDbServerStorage {
core_path.push("core"); core_path.push("core");
std::fs::create_dir_all(core_path.clone()).unwrap(); std::fs::create_dir_all(core_path.clone()).unwrap();
//TODO redo the whole key passing mechanism in RKV so it uses zeroize all the way //TODO redo the whole key passing mechanism in RKV so it uses zeroize all the way
#[cfg(debug_assertions)]
let mut core_storage = RocksDbKCVStorage::open(&core_path, core_key.slice().clone())?; let mut core_storage = RocksDbKCVStorage::open(&core_path, core_key.slice().clone())?;
#[cfg(not(debug_assertions))]
let core_storage = RocksDbKCVStorage::open(&core_path, core_key.slice().clone())?;
// check unicity of class prefixes, by storage // check unicity of class prefixes, by storage
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
@ -167,23 +170,23 @@ impl RocksDbServerStorage {
let file = read(filename.clone()); let file = read(filename.clone());
let mut file_save = match file { let mut file_save = match file {
Ok(ser) => { Ok(ser) => {
let last: u64 = serde_bare::from_slice(&ser).map_err(|e| ServerError::FileError)?; let last: u64 = serde_bare::from_slice(&ser).map_err(|_| ServerError::FileError)?;
if last >= seq { if last >= seq {
return Err(ServerError::SequenceMismatch); return Err(ServerError::SequenceMismatch);
} }
OpenOptions::new() OpenOptions::new()
.write(true) .write(true)
.open(filename) .open(filename)
.map_err(|e| ServerError::FileError)? .map_err(|_| ServerError::FileError)?
} }
Err(_) => File::create(filename).map_err(|e| ServerError::FileError)?, Err(_) => File::create(filename).map_err(|_| ServerError::FileError)?,
}; };
let ser = serde_bare::to_vec(&seq).unwrap(); let ser = serde_bare::to_vec(&seq).unwrap();
file_save file_save
.write_all(&ser) .write_all(&ser)
.map_err(|e| ServerError::FileError)?; .map_err(|_| ServerError::FileError)?;
file_save.sync_data().map_err(|e| ServerError::FileError)?; file_save.sync_data().map_err(|_| ServerError::FileError)?;
Ok(()) Ok(())
} }
@ -261,7 +264,7 @@ impl RocksDbServerStorage {
} }
} }
} }
if topics.len() == 0 { if topics.is_empty() {
return Err(ServerError::False); return Err(ServerError::False);
} }
@ -558,7 +561,7 @@ impl RocksDbServerStorage {
pub(crate) fn save_event( pub(crate) fn save_event(
&self, &self,
overlay: &OverlayId, overlay: &OverlayId,
mut event: Event, event: Event,
user_id: &UserId, user_id: &UserId,
) -> Result<TopicId, ServerError> { ) -> Result<TopicId, ServerError> {
if overlay.is_outer() { if overlay.is_outer() {
@ -609,7 +612,7 @@ impl RocksDbServerStorage {
Arc::new(std::sync::RwLock::new(temp_mini_block_storage)), Arc::new(std::sync::RwLock::new(temp_mini_block_storage)),
); );
let commit_id = extracted_blocks_ids[0]; let commit_id = extracted_blocks_ids[0];
let header = Object::load_header(&first_block_copy, &temp_store).map_err(|e| { let header = Object::load_header(&first_block_copy, &temp_store).map_err(|_e| {
//log_err!("err : {:?}", e); //log_err!("err : {:?}", e);
ServerError::InvalidHeader ServerError::InvalidHeader
})?; })?;
@ -629,17 +632,14 @@ impl RocksDbServerStorage {
&self.core_storage, &self.core_storage,
)?; )?;
let acks = if header.is_some() { let past = if header.is_some() {
HashSet::from_iter(header.unwrap().acks()) HashSet::from_iter(header.unwrap().acks_and_nacks())
} else { } else {
HashSet::new() HashSet::new()
}; };
let head = HashSet::from([commit_id]); let head = HashSet::from([commit_id]);
TopicStorage::HEADS.replace_with_new_set_if_old_set_exists( //TODO: current_heads in TopicInfo in ServerBroker is not updated (but it isn't used so far)
&mut topic_storage, TopicStorage::HEADS.remove_from_set_and_add(&mut topic_storage, past, head)?;
acks,
head,
)?;
} }
} }
@ -656,11 +656,11 @@ impl RocksDbServerStorage {
let overlay = self.check_overlay(overlay)?; let overlay = self.check_overlay(overlay)?;
// quick solution for now using the Branch::sync_req. TODO: use the saved references (ACKS,DEPS) in the server_storage, to have much quicker responses // quick solution for now using the Branch::sync_req. TODO: use the saved references (ACKS,DEPS) in the server_storage, to have much quicker responses
let target_heads = if target_heads.len() == 0 { let target_heads = if target_heads.is_empty() {
// get the current_heads // get the current_heads
let mut topic_storage = TopicStorage::new(topic, &overlay, &self.core_storage); let mut topic_storage = TopicStorage::new(topic, &overlay, &self.core_storage);
let heads = TopicStorage::get_all_heads(&mut topic_storage)?; let heads = TopicStorage::get_all_heads(&mut topic_storage)?;
if heads.len() == 0 { if heads.is_empty() {
return Err(ServerError::TopicNotFound); return Err(ServerError::TopicNotFound);
} }
Box::new(heads.into_iter()) as Box<dyn Iterator<Item = ObjectId>> Box::new(heads.into_iter()) as Box<dyn Iterator<Item = ObjectId>>
@ -676,7 +676,7 @@ impl RocksDbServerStorage {
let mut result = Vec::with_capacity(commits.len()); let mut result = Vec::with_capacity(commits.len());
for commit_id in commits { for commit_id in commits {
let mut commit_storage = CommitStorage::open(&commit_id, &overlay, &self.core_storage)?; let commit_storage = CommitStorage::open(&commit_id, &overlay, &self.core_storage)?;
let mut event_info = commit_storage let mut event_info = commit_storage
.take_event() .take_event()
.left() .left()

@ -14,14 +14,15 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use either::Either; use either::Either;
use ng_net::{server_broker::IServerBroker, types::*}; use serde::{Deserialize, Serialize};
use ng_repo::{ use ng_repo::{
errors::{NgError, ProtocolError, ServerError}, errors::{NgError, ProtocolError, ServerError},
log::*,
types::*, types::*,
}; };
use serde::{Deserialize, Serialize};
use ng_repo::log::*; use ng_net::{server_broker::IServerBroker, types::*};
use crate::rocksdb_server_storage::RocksDbServerStorage; use crate::rocksdb_server_storage::RocksDbServerStorage;
@ -97,8 +98,8 @@ impl From<OverlayAccess> for OverlayType {
OverlayAccess::ReadOnly(_) => { OverlayAccess::ReadOnly(_) => {
panic!("cannot create an OverlayType from a ReadOnly OverlayAccess") panic!("cannot create an OverlayType from a ReadOnly OverlayAccess")
} }
OverlayAccess::ReadWrite((inner, outer)) => OverlayType::Inner(outer), OverlayAccess::ReadWrite((_inner, outer)) => OverlayType::Inner(outer),
OverlayAccess::WriteOnly(inner) => OverlayType::InnerOnly, OverlayAccess::WriteOnly(_inner) => OverlayType::InnerOnly,
} }
} }
} }
@ -113,14 +114,16 @@ pub struct OverlayInfo {
pub struct ServerBroker { pub struct ServerBroker {
storage: RocksDbServerStorage, storage: RocksDbServerStorage,
#[allow(dead_code)]
overlays: HashMap<OverlayId, OverlayInfo>, overlays: HashMap<OverlayId, OverlayInfo>,
#[allow(dead_code)]
inner_overlays: HashMap<OverlayId, Option<OverlayId>>, inner_overlays: HashMap<OverlayId, Option<OverlayId>>,
local_subscriptions: HashMap<(OverlayId, TopicId), HashSet<PubKey>>, local_subscriptions: HashMap<(OverlayId, TopicId), HashSet<PubKey>>,
} }
impl ServerBroker { impl ServerBroker {
pub fn new(storage: RocksDbServerStorage) -> Self { pub(crate) fn new(storage: RocksDbServerStorage) -> Self {
ServerBroker { ServerBroker {
storage: storage, storage: storage,
overlays: HashMap::new(), overlays: HashMap::new(),
@ -157,6 +160,7 @@ impl ServerBroker {
Ok(()) Ok(())
} }
#[allow(dead_code)]
fn remove_subscription( fn remove_subscription(
&mut self, &mut self,
overlay: &OverlayId, overlay: &OverlayId,
@ -317,12 +321,12 @@ impl IServerBroker for ServerBroker {
) -> Result<HashSet<&PubKey>, ServerError> { ) -> Result<HashSet<&PubKey>, ServerError> {
let topic = self.storage.save_event(overlay, event, user_id)?; let topic = self.storage.save_event(overlay, event, user_id)?;
log_debug!( // log_debug!(
"DISPATCH EVENT {} {} {:?}", // "DISPATCH EVENT {} {} {:?}",
overlay, // overlay,
topic, // topic,
self.local_subscriptions // self.local_subscriptions
); // );
let mut set = self let mut set = self
.local_subscriptions .local_subscriptions

@ -14,12 +14,15 @@ use std::hash::Hash;
use std::hash::Hasher; use std::hash::Hasher;
use std::time::SystemTime; use std::time::SystemTime;
use ng_net::types::*; use serde_bare::{from_slice, to_vec};
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::KCVStorage; use ng_repo::kcv_storage::KCVStorage;
#[allow(unused_imports)]
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::UserId; use ng_repo::types::UserId;
use serde_bare::{from_slice, to_vec};
use ng_net::types::*;
pub struct Account<'a> { pub struct Account<'a> {
/// User ID /// User ID
@ -220,7 +223,7 @@ impl<'a> Account<'a> {
// let mut client_key_ser = to_vec(&client_key)?; // let mut client_key_ser = to_vec(&client_key)?;
#[allow(deprecated)] #[allow(deprecated)]
let client_key = (ClientId::nil(), 0u64); let client_key = (ClientId::nil(), 0u64);
let mut client_key_ser = to_vec(&client_key)?; let client_key_ser = to_vec(&client_key)?;
let size = client_key_ser.len() + id.len(); let size = client_key_ser.len() + id.len();
if let Ok(clients) = if let Ok(clients) =

@ -9,20 +9,16 @@
//! User account Storage (Object Key/Col/Value Mapping) //! User account Storage (Object Key/Col/Value Mapping)
use std::collections::hash_map::DefaultHasher; use serde_bare::from_slice;
use std::hash::Hash; use serde_bare::to_vec;
use std::hash::Hasher;
use std::time::SystemTime;
use ng_net::types::*;
use ng_repo::errors::ProtocolError; use ng_repo::errors::ProtocolError;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::KCVStorage; use ng_repo::kcv_storage::KCVStorage;
use ng_repo::types::SymKey; use ng_repo::types::SymKey;
use ng_repo::types::Timestamp;
use ng_repo::utils::now_timestamp; use ng_repo::utils::now_timestamp;
use serde_bare::from_slice;
use serde_bare::to_vec; use ng_net::types::*;
pub struct Invitation<'a> { pub struct Invitation<'a> {
/// code /// code
@ -37,10 +33,6 @@ impl<'a> Invitation<'a> {
const TYPE: u8 = b't'; const TYPE: u8 = b't';
//const EXPIRE: u8 = b'e'; //const EXPIRE: u8 = b'e';
const PREFIX_EXPIRE: u8 = b'e';
// propertie's expiry suffixes
const INVITATION: u8 = b'i';
const ALL_PROPERTIES: [u8; 1] = [Self::TYPE]; const ALL_PROPERTIES: [u8; 1] = [Self::TYPE];
const SUFFIX_FOR_EXIST_CHECK: u8 = Self::TYPE; const SUFFIX_FOR_EXIST_CHECK: u8 = Self::TYPE;
@ -76,7 +68,7 @@ impl<'a> Invitation<'a> {
if acc.exists() { if acc.exists() {
return Err(StorageError::BackendError); return Err(StorageError::BackendError);
} }
let mut value = to_vec(&(code_type, expiry, memo.clone()))?; let value = to_vec(&(code_type, expiry, memo.clone()))?;
storage.write_transaction(&mut |tx| { storage.write_transaction(&mut |tx| {
tx.put( tx.put(
Self::PREFIX, Self::PREFIX,

@ -9,14 +9,13 @@
//! Broker Wallet Storage (Object Key/Col/Value Mapping), persists to storage all the SymKeys needed to open other storages //! Broker Wallet Storage (Object Key/Col/Value Mapping), persists to storage all the SymKeys needed to open other storages
use ng_net::types::*; use serde_bare::to_vec;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::KCVStorage; use ng_repo::kcv_storage::KCVStorage;
use ng_repo::kcv_storage::WriteTransaction; use ng_repo::kcv_storage::WriteTransaction;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::*; use ng_repo::types::*;
use serde::{Deserialize, Serialize};
use serde_bare::{from_slice, to_vec};
pub struct Wallet<'a> { pub struct Wallet<'a> {
storage: &'a dyn KCVStorage, storage: &'a dyn KCVStorage,
@ -28,14 +27,14 @@ impl<'a> Wallet<'a> {
const PREFIX_USER: u8 = b'u'; const PREFIX_USER: u8 = b'u';
const KEY_ACCOUNTS: [u8; 8] = *b"accounts"; const KEY_ACCOUNTS: [u8; 8] = *b"accounts";
const KEY_PEERS: [u8; 5] = *b"peers"; //const KEY_PEERS: [u8; 5] = *b"peers";
const KEY_CORE: [u8; 4] = *b"core"; const KEY_CORE: [u8; 4] = *b"core";
const KEY_BLOCKS: [u8; 6] = *b"blocks"; const KEY_BLOCKS: [u8; 6] = *b"blocks";
// propertie's suffixes // propertie's suffixes
const SYM_KEY: u8 = b"s"[0]; const SYM_KEY: u8 = b"s"[0];
const ALL_PROPERTIES: [u8; 1] = [Self::SYM_KEY]; //const ALL_PROPERTIES: [u8; 1] = [Self::SYM_KEY];
const SUFFIX_FOR_EXIST_CHECK: u8 = Self::SYM_KEY; const SUFFIX_FOR_EXIST_CHECK: u8 = Self::SYM_KEY;

@ -1,105 +0,0 @@
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
//! Broker Config, persisted to store
use ng_net::types::*;
use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::KCVStorage;
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 enum ConfigMode {
Local,
Core,
}
pub struct Config<'a> {
store: &'a dyn KCVStorage,
}
impl<'a> Config<'a> {
const PREFIX: u8 = b"c"[0];
const KEY: [u8; 5] = *b"onfig";
// propertie's suffixes
const MODE: u8 = b"m"[0];
const ALL_PROPERTIES: [u8; 1] = [Self::MODE];
const SUFFIX_FOR_EXIST_CHECK: u8 = Self::MODE;
pub fn open(store: &'a dyn KCVStorage) -> Result<Config<'a>, StorageError> {
let opening = Config { store };
if !opening.exists() {
return Err(StorageError::NotFound);
}
Ok(opening)
}
pub fn get_or_create(
mode: &ConfigMode,
store: &'a dyn KCVStorage,
) -> Result<Config<'a>, StorageError> {
match Self::open(store) {
Err(e) => {
if e == StorageError::NotFound {
Self::create(mode, store)
} else {
Err(StorageError::BackendError)
}
}
Ok(p) => {
if &p.mode().unwrap() != mode {
return Err(StorageError::InvalidValue);
}
Ok(p)
}
}
}
pub fn create(
mode: &ConfigMode,
store: &'a dyn KCVStorage,
) -> Result<Config<'a>, StorageError> {
let acc = Config { store };
if acc.exists() {
return Err(StorageError::BackendError);
}
store.put(
Self::PREFIX,
&to_vec(&Self::KEY)?,
Some(Self::MODE),
&to_vec(&mode)?,
&None,
)?;
Ok(acc)
}
pub fn exists(&self) -> bool {
self.store
.get(
Self::PREFIX,
&to_vec(&Self::KEY).unwrap(),
Some(Self::SUFFIX_FOR_EXIST_CHECK),
&None,
)
.is_ok()
}
pub fn mode(&self) -> Result<ConfigMode, StorageError> {
match self
.store
.get(Self::PREFIX, &to_vec(&Self::KEY)?, Some(Self::MODE), &None)
{
Ok(ver) => Ok(from_slice::<ConfigMode>(&ver)?),
Err(e) => Err(e),
}
}
}

@ -9,22 +9,18 @@
//! Commit Storage (Object Key/Col/Value Mapping) //! Commit Storage (Object Key/Col/Value Mapping)
use std::collections::HashMap; use either::Either;
use std::collections::HashSet; use serde_bare::to_vec;
use ng_net::types::*;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::*; use ng_repo::kcv_storage::*;
use ng_repo::types::*; use ng_repo::types::*;
use either::Either; use super::OverlayStorage;
use serde_bare::to_vec;
use crate::server_broker::CommitInfo; use crate::server_broker::CommitInfo;
use crate::server_broker::EventInfo; use crate::server_broker::EventInfo;
use super::OverlayStorage;
pub struct CommitStorage<'a> { pub struct CommitStorage<'a> {
key: Vec<u8>, key: Vec<u8>,
event: ExistentialValue<Either<EventInfo, TopicId>>, event: ExistentialValue<Either<EventInfo, TopicId>>,
@ -156,7 +152,7 @@ impl<'a> CommitStorage<'a> {
pub fn event(&mut self) -> &Either<EventInfo, TopicId> { pub fn event(&mut self) -> &Either<EventInfo, TopicId> {
self.event.get().unwrap() self.event.get().unwrap()
} }
pub fn take_event(mut self) -> Either<EventInfo, TopicId> { pub fn take_event(self) -> Either<EventInfo, TopicId> {
self.event.take().unwrap() self.event.take().unwrap()
} }
} }

@ -10,15 +10,13 @@
//! Overlay Storage (Object Key/Col/Value Mapping) //! Overlay Storage (Object Key/Col/Value Mapping)
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet;
use ng_net::types::*; use serde_bare::to_vec;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::*; use ng_repo::kcv_storage::*;
use ng_repo::types::*; use ng_repo::types::*;
use serde_bare::to_vec;
use crate::server_broker::OverlayInfo; use crate::server_broker::OverlayInfo;
use crate::server_broker::OverlayType; use crate::server_broker::OverlayType;
@ -41,9 +39,6 @@ impl<'a> IModel for OverlayStorage<'a> {
fn existential(&mut self) -> Option<&mut dyn IExistentialValue> { fn existential(&mut self) -> Option<&mut dyn IExistentialValue> {
Some(&mut self.overlay_type) Some(&mut self.overlay_type)
} }
// fn name(&self) -> String {
// format_type_of(self)
// }
} }
impl<'a> OverlayStorage<'a> { impl<'a> OverlayStorage<'a> {

@ -9,12 +9,13 @@
//! Peer //! Peer
use ng_net::types::*; use serde_bare::{from_slice, to_vec};
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::KCVStorage; use ng_repo::kcv_storage::KCVStorage;
use ng_repo::types::*; use ng_repo::types::*;
use serde::{Deserialize, Serialize};
use serde_bare::{from_slice, to_vec}; use ng_net::types::*;
pub struct Peer<'a> { pub struct Peer<'a> {
/// Topic ID /// Topic ID
@ -131,7 +132,7 @@ impl<'a> Peer<'a> {
if advert.peer() != &self.id { if advert.peer() != &self.id {
return Err(StorageError::InvalidValue); return Err(StorageError::InvalidValue);
} }
let current_advert = self.advert().map_err(|e| StorageError::BackendError)?; let current_advert = self.advert().map_err(|_| StorageError::BackendError)?;
if current_advert.version() >= advert.version() { if current_advert.version() >= advert.version() {
return Ok(()); return Ok(());
} }

@ -9,16 +9,14 @@
//! Repo Storage (Object Key/Col/Value Mapping) //! Repo Storage (Object Key/Col/Value Mapping)
use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use ng_net::types::*; use serde_bare::to_vec;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::*; use ng_repo::kcv_storage::*;
use ng_repo::types::*; use ng_repo::types::*;
use serde_bare::to_vec;
use crate::server_broker::RepoInfo; use crate::server_broker::RepoInfo;
pub struct RepoHashStorage<'a> { pub struct RepoHashStorage<'a> {
@ -111,7 +109,7 @@ impl<'a> RepoHashStorage<'a> {
overlay: &OverlayId, overlay: &OverlayId,
storage: &'a dyn KCVStorage, storage: &'a dyn KCVStorage,
) -> Result<RepoHashStorage<'a>, StorageError> { ) -> Result<RepoHashStorage<'a>, StorageError> {
let mut opening = Self::new(repo, overlay, storage); let opening = Self::new(repo, overlay, storage);
Ok(opening) Ok(opening)
} }
pub fn create( pub fn create(
@ -119,7 +117,7 @@ impl<'a> RepoHashStorage<'a> {
overlay: &OverlayId, overlay: &OverlayId,
storage: &'a dyn KCVStorage, storage: &'a dyn KCVStorage,
) -> Result<RepoHashStorage<'a>, StorageError> { ) -> Result<RepoHashStorage<'a>, StorageError> {
let mut creating = Self::new(repo, overlay, storage); let creating = Self::new(repo, overlay, storage);
Ok(creating) Ok(creating)
} }
} }

@ -12,12 +12,13 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use ng_net::types::*; use serde_bare::to_vec;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::*; use ng_repo::kcv_storage::*;
use ng_repo::types::*; use ng_repo::types::*;
use serde_bare::to_vec; use ng_net::types::*;
use crate::server_broker::TopicInfo; use crate::server_broker::TopicInfo;

@ -1,5 +1,3 @@
pub mod admin; pub mod admin;
pub mod core; pub mod core;
//pub mod config;

@ -11,55 +11,43 @@
//! WebSocket implementation of the Broker //! WebSocket implementation of the Broker
use crate::interfaces::*; use std::collections::HashMap;
use crate::rocksdb_server_storage::RocksDbServerStorage; use std::collections::HashSet;
use crate::server_broker::ServerBroker; use std::net::IpAddr;
use crate::types::*; use std::net::SocketAddr;
use async_std::io::ReadExt; use std::path::PathBuf;
use futures::StreamExt;
use once_cell::sync::OnceCell;
use rust_embed::RustEmbed;
use serde_json::json;
use async_std::net::{TcpListener, TcpStream}; use async_std::net::{TcpListener, TcpStream};
use async_std::sync::Mutex;
use async_std::task;
use async_tungstenite::accept_hdr_async; use async_tungstenite::accept_hdr_async;
use async_tungstenite::tungstenite::handshake::server::{ use async_tungstenite::tungstenite::handshake::server::{
Callback, ErrorResponse, Request, Response, Callback, ErrorResponse, Request, Response,
}; };
use async_tungstenite::tungstenite::http::{ use async_tungstenite::tungstenite::http::{
header::{CONNECTION, HOST, ORIGIN, UPGRADE}, header::{CONNECTION, HOST, ORIGIN},
HeaderValue, Method, StatusCode, Uri, Version, HeaderValue, Method, StatusCode, Uri, Version,
}; };
use async_tungstenite::tungstenite::protocol::Message; use ng_repo::errors::NgError;
use futures::{SinkExt, StreamExt}; use ng_repo::log::*;
use ng_client_ws::remote_ws::ConnectionWebSocket; use ng_repo::types::{PrivKey, PubKey, SymKey};
use ng_net::broker::*; use ng_net::broker::*;
use ng_net::connection::IAccept; use ng_net::connection::IAccept;
use ng_net::types::*; use ng_net::types::*;
use ng_net::utils::get_domain_without_port; use ng_net::utils::{is_private_ip, is_public_ip};
use ng_net::utils::is_private_ip;
use ng_net::utils::is_public_ip;
use ng_net::NG_BOOTSTRAP_LOCAL_PATH; use ng_net::NG_BOOTSTRAP_LOCAL_PATH;
use ng_repo::errors::NgError;
use ng_repo::log::*;
use ng_repo::types::SymKey;
use ng_repo::types::{PrivKey, PubKey};
use ng_repo::utils::generate_keypair;
use once_cell::sync::Lazy;
use once_cell::sync::OnceCell;
use rust_embed::RustEmbed;
use serde_json::json;
use std::collections::HashMap;
use std::collections::HashSet;
use std::fs;
use std::net::SocketAddr;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::num::NonZeroU8;
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::{thread, time};
use tempfile::Builder; use ng_client_ws::remote_ws::ConnectionWebSocket;
use crate::interfaces::*;
use crate::rocksdb_server_storage::RocksDbServerStorage;
use crate::server_broker::ServerBroker;
use crate::types::*;
static LISTENERS_INFO: OnceCell<(HashMap<String, ListenerInfo>, HashMap<BindAddress, String>)> = static LISTENERS_INFO: OnceCell<(HashMap<String, ListenerInfo>, HashMap<BindAddress, String>)> =
OnceCell::new(); OnceCell::new();
@ -575,16 +563,19 @@ pub async fn accept(tcp: TcpStream, peer_priv_key: PrivKey) {
.await .await
.accept(base, remote_bind_address, local_bind_address) .accept(base, remote_bind_address, local_bind_address)
.await; .await;
if res.is_err() {
log_warn!("Accept error: {:?}", res.unwrap_err());
}
} }
pub async fn run_server_accept_one( pub async fn run_server_accept_one(
addr: &str, addr: &str,
port: u16, port: u16,
peer_priv_key: PrivKey, peer_priv_key: PrivKey,
peer_pub_key: PubKey, _peer_pub_key: PubKey,
) -> std::io::Result<()> { ) -> std::io::Result<()> {
let addrs = format!("{}:{}", addr, port); let addrs = format!("{}:{}", addr, port);
let root = tempfile::Builder::new().prefix("ngd").tempdir().unwrap(); let _root = tempfile::Builder::new().prefix("ngd").tempdir().unwrap();
// let master_key: [u8; 32] = [0; 32]; // let master_key: [u8; 32] = [0; 32];
// std::fs::create_dir_all(root.path()).unwrap(); // std::fs::create_dir_all(root.path()).unwrap();
// log_debug!("data directory: {}", root.path().to_str().unwrap()); // log_debug!("data directory: {}", root.path().to_str().unwrap());
@ -689,7 +680,7 @@ pub async fn run_server_v0(
} }
}) })
.collect(); .collect();
if addrs.len() == 0 { if addrs.is_empty() {
return Err(NgError::BrokerConfigError(format!( return Err(NgError::BrokerConfigError(format!(
"The interface {} does not have any IPv4 address.", "The interface {} does not have any IPv4 address.",
listener.interface_name listener.interface_name
@ -752,7 +743,7 @@ pub async fn run_server_v0(
} }
} }
if listeners_addrs.len() == 0 { if listeners_addrs.is_empty() {
return Err(NgError::BrokerConfigErrorStr("No listener configured.")); return Err(NgError::BrokerConfigErrorStr("No listener configured."));
} }

@ -6,10 +6,13 @@
// at your option. All files in the project carrying such // at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use ng_net::types::{BrokerOverlayConfigV0, ListenerV0, RegistrationConfig};
use ng_repo::types::{PrivKey, PubKey};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use ng_repo::types::PubKey;
use ng_net::types::{BrokerOverlayConfigV0, ListenerV0, RegistrationConfig};
/// DaemonConfig Version 0 /// DaemonConfig Version 0
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DaemonConfigV0 { pub struct DaemonConfigV0 {

@ -11,29 +11,23 @@
//! WebSocket Remote Connection to a Broker //! WebSocket Remote Connection to a Broker
use std::sync::Arc; use async_std::task;
use async_tungstenite::{
use async_tungstenite::tungstenite::protocol::frame::coding::CloseCode; async_std::{connect_async, ConnectStream},
use async_tungstenite::tungstenite::protocol::CloseFrame; tungstenite::{protocol::frame::coding::CloseCode, protocol::CloseFrame, Message},
use async_tungstenite::WebSocketStream; WebSocketStream,
};
use async_std::sync::Mutex;
use either::Either; use either::Either;
use futures::io::Close; use futures::{pin_mut, select, StreamExt};
use futures::{future, pin_mut, select, stream, StreamExt};
use futures::{FutureExt, SinkExt}; use futures::{FutureExt, SinkExt};
use async_std::task;
use ng_net::types::*;
use ng_net::utils::{spawn_and_log_error, Receiver, ResultSend, Sender};
use ng_net::{connection::*, WS_PORT};
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::{generate_keypair, now_timestamp};
use async_tungstenite::async_std::{connect_async, ConnectStream}; use ng_net::connection::*;
use async_tungstenite::tungstenite::{Error, Message}; use ng_net::types::*;
use ng_net::utils::{Receiver, Sender};
pub struct ConnectionWebSocket {} pub struct ConnectionWebSocket {}
@ -44,7 +38,7 @@ impl IConnect for ConnectionWebSocket {
&self, &self,
url: String, url: String,
peer_privk: PrivKey, peer_privk: PrivKey,
peer_pubk: PubKey, _peer_pubk: PubKey,
remote_peer: DirectPeerId, remote_peer: DirectPeerId,
config: StartConfig, config: StartConfig,
) -> Result<ConnectionBase, ProtocolError> { ) -> Result<ConnectionBase, ProtocolError> {
@ -53,8 +47,8 @@ impl IConnect for ConnectionWebSocket {
let res = connect_async(url).await; let res = connect_async(url).await;
match res { match res {
Err(e) => { Err(_e) => {
log_debug!("Cannot connect: {:?}", e); log_debug!("Cannot connect: {:?}", _e);
Err(ProtocolError::ConnectionError) Err(ProtocolError::ConnectionError)
} }
Ok((websocket, _)) => { Ok((websocket, _)) => {
@ -64,7 +58,7 @@ impl IConnect for ConnectionWebSocket {
let mut shutdown = cnx.set_shutdown(); let mut shutdown = cnx.set_shutdown();
cnx.release_shutdown(); cnx.release_shutdown();
let join = task::spawn(async move { let _join = task::spawn(async move {
log_debug!("START of WS loop"); log_debug!("START of WS loop");
let res = ws_loop(websocket, s, r).await; let res = ws_loop(websocket, s, r).await;
@ -91,8 +85,8 @@ impl IConnect for ConnectionWebSocket {
let res = connect_async(url).await; let res = connect_async(url).await;
match res { match res {
Err(e) => { Err(_e) => {
log_debug!("Cannot connect: {:?}", e); log_debug!("Cannot connect: {:?}", _e);
Err(ProtocolError::ConnectionError) Err(ProtocolError::ConnectionError)
} }
Ok((websocket, _)) => { Ok((websocket, _)) => {
@ -102,7 +96,7 @@ impl IConnect for ConnectionWebSocket {
let mut shutdown = cnx.set_shutdown(); let mut shutdown = cnx.set_shutdown();
cnx.release_shutdown(); cnx.release_shutdown();
let join = task::spawn(async move { let _join = task::spawn(async move {
log_debug!("START of WS loop"); log_debug!("START of WS loop");
let res = ws_loop(websocket, s, r).await; let res = ws_loop(websocket, s, r).await;
@ -143,7 +137,7 @@ impl IAccept for ConnectionWebSocket {
let r = cnx.take_receiver(); let r = cnx.take_receiver();
let mut shutdown = cnx.set_shutdown(); let mut shutdown = cnx.set_shutdown();
let join = task::spawn(async move { let _join = task::spawn(async move {
log_debug!("START of WS loop"); log_debug!("START of WS loop");
let res = ws_loop(socket, s, r).await; let res = ws_loop(socket, s, r).await;
@ -236,7 +230,7 @@ async fn ws_loop(
.map_err(|_e| NetError::IoError)?; .map_err(|_e| NetError::IoError)?;
} }
}, },
Some(Err(e)) => {log_debug!("GOT ERROR {:?}",e);return Err(NetError::WsError);}, Some(Err(_e)) => {log_debug!("GOT ERROR {:?}",_e);return Err(NetError::WsError);},
None => break None => break
}, },
s = sender.next().fuse() => match s { s = sender.next().fuse() => match s {
@ -301,14 +295,15 @@ mod test {
use crate::remote_ws::*; use crate::remote_ws::*;
use async_std::task; use async_std::task;
use ng_net::broker::*;
use ng_net::types::IP; use ng_net::types::IP;
use ng_net::utils::{spawn_and_log_error, ResultSend}; use ng_net::utils::{spawn_and_log_error, ResultSend};
use ng_net::{broker::*, WS_PORT};
use ng_repo::errors::{NetError, NgError}; use ng_repo::errors::{NetError, NgError};
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::utils::generate_keypair; use ng_repo::utils::generate_keypair;
use std::net::IpAddr; use std::net::IpAddr;
use std::str::FromStr; use std::str::FromStr;
use std::sync::Arc;
#[async_std::test] #[async_std::test]
pub async fn test_ws() -> Result<(), NgError> { pub async fn test_ws() -> Result<(), NgError> {

@ -13,23 +13,21 @@
use either::Either; use either::Either;
use futures::FutureExt; use futures::FutureExt;
use futures::{future, pin_mut, select, stream, SinkExt, StreamExt}; use futures::{select, SinkExt, StreamExt};
use ng_net::connection::*;
use ng_net::types::*;
use ng_net::utils::*;
use ng_net::WS_PORT;
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::*;
use ng_repo::utils::{generate_keypair, now_timestamp};
use std::sync::Arc;
use { use {
pharos::{Filter, Observable, ObserveConfig}, pharos::{Observable, ObserveConfig},
wasm_bindgen::UnwrapThrowExt, wasm_bindgen::UnwrapThrowExt,
ws_stream_wasm::*, ws_stream_wasm::*,
}; };
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::*;
use ng_net::connection::*;
use ng_net::types::*;
use ng_net::utils::*;
pub struct ConnectionWebSocket {} pub struct ConnectionWebSocket {}
#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
@ -39,20 +37,20 @@ impl IConnect for ConnectionWebSocket {
&self, &self,
url: String, url: String,
peer_privk: PrivKey, peer_privk: PrivKey,
peer_pubk: PubKey, _peer_pubk: PubKey,
remote_peer: DirectPeerId, remote_peer: DirectPeerId,
config: StartConfig, config: StartConfig,
) -> Result<ConnectionBase, ProtocolError> { ) -> Result<ConnectionBase, ProtocolError> {
log_debug!("url {}", url); log_debug!("url {}", url);
let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS); let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS);
let (mut ws, wsio) = WsMeta::connect(url, None).await.map_err(|e| { let (ws, wsio) = WsMeta::connect(url, None).await.map_err(|_e| {
//log_debug!("{:?}", e); //log_debug!("{:?}", _e);
ProtocolError::ConnectionError ProtocolError::ConnectionError
})?; })?;
cnx.start_read_loop(None, Some(peer_privk), Some(remote_peer)); cnx.start_read_loop(None, Some(peer_privk), Some(remote_peer));
let mut shutdown = cnx.set_shutdown(); let shutdown = cnx.set_shutdown();
spawn_and_log_error(ws_loop( spawn_and_log_error(ws_loop(
ws, ws,
@ -70,13 +68,13 @@ impl IConnect for ConnectionWebSocket {
let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS); let mut cnx = ConnectionBase::new(ConnectionDir::Client, TransportProtocol::WS);
let url = format!("ws://{}:{}", ip, port); let url = format!("ws://{}:{}", ip, port);
let (mut ws, wsio) = WsMeta::connect(url, None).await.map_err(|e| { let (ws, wsio) = WsMeta::connect(url, None).await.map_err(|_e| {
//log_debug!("{:?}", e); //log_debug!("{:?}", _e);
ProtocolError::ConnectionError ProtocolError::ConnectionError
})?; })?;
cnx.start_read_loop(None, None, None); cnx.start_read_loop(None, None, None);
let mut shutdown = cnx.set_shutdown(); let shutdown = cnx.set_shutdown();
spawn_and_log_error(ws_loop( spawn_and_log_error(ws_loop(
ws, ws,
@ -124,7 +122,7 @@ async fn ws_loop(
match msg { match msg {
ConnectionCommand::Msg(m) => { ConnectionCommand::Msg(m) => {
stream.send(WsMessage::Binary(serde_bare::to_vec(&m)?)).await.map_err(|e| { log_debug!("{:?}",e); return NetError::IoError;})?; stream.send(WsMessage::Binary(serde_bare::to_vec(&m)?)).await.map_err(|_e| { log_debug!("{:?}",_e); return NetError::IoError;})?;
}, },
ConnectionCommand::Error(e) => { ConnectionCommand::Error(e) => {

@ -11,17 +11,19 @@
//! Actor handles messages in the Protocol. common types are here //! Actor handles messages in the Protocol. common types are here
use std::any::TypeId;
use std::marker::PhantomData;
use std::sync::Arc;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use async_std::sync::Mutex; use async_std::sync::Mutex;
use futures::{channel::mpsc, SinkExt}; use futures::{channel::mpsc, SinkExt};
use ng_repo::errors::{NgError, ProtocolError, ServerError};
use ng_repo::log::*; use ng_repo::log::*;
use std::any::TypeId;
use std::sync::Arc;
use crate::utils::{spawn_and_log_error, Receiver, ResultSend, Sender}; use crate::utils::{spawn_and_log_error, Receiver, ResultSend, Sender};
use crate::{connection::*, types::ProtocolMessage}; use crate::{connection::*, types::ProtocolMessage};
use ng_repo::errors::{NgError, ProtocolError, ServerError};
use std::marker::PhantomData;
impl TryFrom<ProtocolMessage> for () { impl TryFrom<ProtocolMessage> for () {
type Error = ProtocolError; type Error = ProtocolError;
@ -38,7 +40,7 @@ pub trait EActor: Send + Sync + std::fmt::Debug {
fsm: Arc<Mutex<NoiseFSM>>, fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError>; ) -> Result<(), ProtocolError>;
fn set_id(&mut self, id: i64) {} fn set_id(&mut self, _id: i64) {}
} }
#[derive(Debug)] #[derive(Debug)]
@ -52,7 +54,7 @@ pub struct Actor<
phantom_b: PhantomData<&'a B>, phantom_b: PhantomData<&'a B>,
receiver: Option<Receiver<ConnectionCommand>>, receiver: Option<Receiver<ConnectionCommand>>,
receiver_tx: Sender<ConnectionCommand>, receiver_tx: Sender<ConnectionCommand>,
initiator: bool, //initiator: bool,
} }
pub enum SoS<B> { pub enum SoS<B> {
@ -94,7 +96,7 @@ impl<
B: TryFrom<ProtocolMessage, Error = ProtocolError> + Sync + Send + std::fmt::Debug + 'static, B: TryFrom<ProtocolMessage, Error = ProtocolError> + Sync + Send + std::fmt::Debug + 'static,
> Actor<'_, A, B> > Actor<'_, A, B>
{ {
pub fn new(id: i64, initiator: bool) -> Self { pub fn new(id: i64, _initiator: bool) -> Self {
let (receiver_tx, receiver) = mpsc::unbounded::<ConnectionCommand>(); let (receiver_tx, receiver) = mpsc::unbounded::<ConnectionCommand>();
Self { Self {
id, id,
@ -102,7 +104,7 @@ impl<
receiver_tx, receiver_tx,
phantom_a: PhantomData, phantom_a: PhantomData,
phantom_b: PhantomData, phantom_b: PhantomData,
initiator, //initiator,
} }
} }

@ -8,19 +8,22 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use super::super::StartProtocol; use super::super::StartProtocol;
use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
/// Add invitation /// Add invitation
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AddInvitationV0 { pub struct AddInvitationV0 {
@ -79,7 +82,7 @@ impl TryFrom<ProtocolMessage> for AddInvitation {
} }
impl From<AddInvitation> for ProtocolMessage { impl From<AddInvitation> for ProtocolMessage {
fn from(msg: AddInvitation) -> ProtocolMessage { fn from(_msg: AddInvitation) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }

@ -8,19 +8,23 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::PubKey; use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use super::super::StartProtocol; use super::super::StartProtocol;
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
/// Add user account /// Add user account
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct AddUserV0 { pub struct AddUserV0 {
@ -69,7 +73,7 @@ impl TryFrom<ProtocolMessage> for AddUser {
} }
impl From<AddUser> for ProtocolMessage { impl From<AddUser> for ProtocolMessage {
fn from(msg: AddUser) -> ProtocolMessage { fn from(_msg: AddUser) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }

@ -8,15 +8,19 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use std::sync::Arc;
use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*;
use ng_repo::types::PubKey;
use crate::broker::BROKER; use crate::broker::BROKER;
use crate::connection::NoiseFSM; use crate::connection::NoiseFSM;
use crate::types::*; use crate::types::*;
use crate::{actor::*, types::ProtocolMessage}; use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex;
use ng_repo::errors::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use super::super::StartProtocol; use super::super::StartProtocol;
@ -60,7 +64,7 @@ impl TryFrom<ProtocolMessage> for DelUser {
} }
impl From<DelUser> for ProtocolMessage { impl From<DelUser> for ProtocolMessage {
fn from(msg: DelUser) -> ProtocolMessage { fn from(_msg: DelUser) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }

@ -8,19 +8,23 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::BROKER;
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*; use ng_repo::errors::*;
#[allow(unused_imports)]
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use super::super::StartProtocol; use super::super::StartProtocol;
use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
/// List invitations registered on this broker /// List invitations registered on this broker
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ListInvitationsV0 { pub struct ListInvitationsV0 {
@ -76,7 +80,7 @@ impl TryFrom<ProtocolMessage> for ListInvitations {
} }
impl From<ListInvitations> for ProtocolMessage { impl From<ListInvitations> for ProtocolMessage {
fn from(msg: ListInvitations) -> ProtocolMessage { fn from(_msg: ListInvitations) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }

@ -8,19 +8,21 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::BROKER;
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc;
use ng_repo::errors::*;
use super::super::StartProtocol; use super::super::StartProtocol;
use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
/// List users registered on this broker /// List users registered on this broker
#[derive(Clone, Copy, Debug, Serialize, Deserialize)] #[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub struct ListUsersV0 { pub struct ListUsersV0 {
@ -62,7 +64,7 @@ impl TryFrom<ProtocolMessage> for ListUsers {
} }
impl From<ListUsers> for ProtocolMessage { impl From<ListUsers> for ProtocolMessage {
fn from(msg: ListUsers) -> ProtocolMessage { fn from(_msg: ListUsers) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }

@ -8,16 +8,18 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize}; use crate::broker::BROKER;
use std::sync::Arc; use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl BlocksExist { impl BlocksExist {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {

@ -8,18 +8,21 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::server_broker::IServerBroker;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_recursion::async_recursion; use async_recursion::async_recursion;
use async_std::sync::{Mutex, MutexGuard}; use async_std::sync::{Mutex, MutexGuard};
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::{Block, BlockId, OverlayId, PubKey}; use ng_repo::types::{Block, BlockId, OverlayId};
use serde::{Deserialize, Serialize};
use std::sync::Arc; use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::server_broker::IServerBroker;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl BlocksGet { impl BlocksGet {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {

@ -8,16 +8,18 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize}; use crate::broker::BROKER;
use std::sync::Arc; use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl BlocksPut { impl BlocksPut {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {

@ -8,16 +8,19 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::{Block, OverlayId, PubKey}; use ng_repo::types::{Block, OverlayId};
use serde::{Deserialize, Serialize};
use std::sync::Arc; use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl CommitGet { impl CommitGet {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {
@ -94,7 +97,7 @@ impl EActor for Actor<'_, CommitGet, Block> {
// IF NEEDED, the get_commit could be changed to return a stream, and then the send_in_reply_to would be also totally async // IF NEEDED, the get_commit could be changed to return a stream, and then the send_in_reply_to would be also totally async
match blocks_res { match blocks_res {
Ok(blocks) => { Ok(blocks) => {
if blocks.len() == 0 { if blocks.is_empty() {
let re: Result<(), ServerError> = Err(ServerError::EmptyStream); let re: Result<(), ServerError> = Err(ServerError::EmptyStream);
fsm.lock() fsm.lock()
.await .await

@ -8,18 +8,20 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::repo::{BranchInfo, Repo};
use ng_repo::store::Store;
use ng_repo::types::*; use ng_repo::types::*;
use serde::{Deserialize, Serialize};
use std::sync::Arc; #[cfg(not(target_arch = "wasm32"))]
use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl PublishEvent { impl PublishEvent {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {
@ -70,12 +72,12 @@ impl Actor<'_, PublishEvent, ()> {}
impl EActor for Actor<'_, PublishEvent, ()> { impl EActor for Actor<'_, PublishEvent, ()> {
async fn respond( async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, _msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, _fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
{ {
let req = PublishEvent::try_from(msg)?; let req = PublishEvent::try_from(_msg)?;
// send a ProtocolError if invalid signatures (will disconnect the client) // send a ProtocolError if invalid signatures (will disconnect the client)
req.event().verify()?; req.event().verify()?;
@ -83,7 +85,7 @@ impl EActor for Actor<'_, PublishEvent, ()> {
let broker = BROKER.read().await; let broker = BROKER.read().await;
let overlay = req.overlay().clone(); let overlay = req.overlay().clone();
let (user_id, remote_peer) = { let (user_id, remote_peer) = {
let fsm = fsm.lock().await; let fsm = _fsm.lock().await;
( (
fsm.user_id()?, fsm.user_id()?,
fsm.remote_peer().ok_or(ProtocolError::ActorError)?, fsm.remote_peer().ok_or(ProtocolError::ActorError)?,
@ -93,7 +95,7 @@ impl EActor for Actor<'_, PublishEvent, ()> {
.dispatch_event(&overlay, req.take_event(), &user_id, &remote_peer) .dispatch_event(&overlay, req.take_event(), &user_id, &remote_peer)
.await; .await;
fsm.lock() _fsm.lock()
.await .await
.send_in_reply_to(res.into(), self.id()) .send_in_reply_to(res.into(), self.id())
.await?; .await?;

@ -8,17 +8,20 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::repo::Repo; use ng_repo::repo::Repo;
use ng_repo::types::*; use ng_repo::types::*;
use serde::{Deserialize, Serialize};
use std::sync::Arc; use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl PinRepo { impl PinRepo {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {
@ -145,7 +148,7 @@ impl EActor for Actor<'_, PinRepo, RepoOpened> {
if req.overlay() != w if req.overlay() != w
|| !w.is_inner() || !w.is_inner()
|| r.is_inner() || r.is_inner()
|| req.expose_outer() && req.rw_topics().len() == 0 || req.expose_outer() && req.rw_topics().is_empty()
{ {
// we do not allow to expose_outer if not a publisher for at least one topic // we do not allow to expose_outer if not a publisher for at least one topic
// TODO add a check on "|| overlay_root_topic.is_none()" because it should be mandatory to have one (not sent by client at the moment) // TODO add a check on "|| overlay_root_topic.is_none()" because it should be mandatory to have one (not sent by client at the moment)

@ -8,16 +8,18 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize}; use crate::broker::BROKER;
use std::sync::Arc; use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl RepoPinStatusReq { impl RepoPinStatusReq {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {

@ -8,17 +8,20 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::repo::{BranchInfo, Repo}; use ng_repo::repo::{BranchInfo, Repo};
use ng_repo::types::*; use ng_repo::types::*;
use serde::{Deserialize, Serialize};
use std::sync::Arc; use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl TopicSub { impl TopicSub {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {

@ -8,17 +8,20 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::repo::{BranchInfo, Repo}; use ng_repo::repo::Repo;
use ng_repo::types::*; use ng_repo::types::*;
use serde::{Deserialize, Serialize};
use std::sync::Arc; use crate::broker::BROKER;
use crate::connection::NoiseFSM;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
impl TopicSyncReq { impl TopicSyncReq {
pub fn get_actor(&self, id: i64) -> Box<dyn EActor> { pub fn get_actor(&self, id: i64) -> Box<dyn EActor> {
@ -113,7 +116,7 @@ impl EActor for Actor<'_, TopicSyncReq, TopicSyncRes> {
// IF NEEDED, the topic_sync_req could be changed to return a stream, and then the send_in_reply_to would be also totally async // IF NEEDED, the topic_sync_req could be changed to return a stream, and then the send_in_reply_to would be also totally async
match res { match res {
Ok(blocks) => { Ok(blocks) => {
if blocks.len() == 0 { if blocks.is_empty() {
let re: Result<(), ServerError> = Err(ServerError::EmptyStream); let re: Result<(), ServerError> = Err(ServerError::EmptyStream);
fsm.lock() fsm.lock()
.await .await

@ -8,22 +8,22 @@
* notice may not be copied, modified, or distributed except * notice may not be copied, modified, or distributed except
* according to those terms. * according to those terms.
*/ */
use crate::broker::{ServerConfig, BROKER};
use crate::connection::NoiseFSM; use std::sync::Arc;
use crate::types::*;
use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::PubKey;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::sync::Arc;
use ng_repo::errors::*;
use crate::connection::NoiseFSM;
use crate::{actor::*, types::ProtocolMessage};
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Connecting(); pub struct Connecting();
impl From<Connecting> for ProtocolMessage { impl From<Connecting> for ProtocolMessage {
fn from(msg: Connecting) -> ProtocolMessage { fn from(_msg: Connecting) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }
@ -34,7 +34,7 @@ impl Actor<'_, Connecting, ()> {}
impl EActor for Actor<'_, Connecting, ()> { impl EActor for Actor<'_, Connecting, ()> {
async fn respond( async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, _msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
fsm.lock().await.remove_actor(0).await; fsm.lock().await.remove_actor(0).await;

@ -11,11 +11,12 @@
use std::sync::Arc; use std::sync::Arc;
use crate::{actor::*, connection::NoiseFSM, types::ProtocolMessage};
use async_std::sync::Mutex; use async_std::sync::Mutex;
use ng_repo::errors::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::any::{Any, TypeId};
use ng_repo::errors::*;
use crate::{actor::*, connection::NoiseFSM, types::ProtocolMessage};
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct NoiseV0 { pub struct NoiseV0 {
@ -60,8 +61,8 @@ impl Actor<'_, Noise, Noise> {}
impl EActor for Actor<'_, Noise, Noise> { impl EActor for Actor<'_, Noise, Noise> {
async fn respond( async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, _msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, _fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
Ok(()) Ok(())
} }

@ -9,14 +9,16 @@
* according to those terms. * according to those terms.
*/ */
use std::sync::Arc;
use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*;
use crate::connection::NoiseFSM; use crate::connection::NoiseFSM;
use crate::types::{ProbeResponse, MAGIC_NG_REQUEST}; use crate::types::{ProbeResponse, MAGIC_NG_REQUEST};
use crate::{actor::*, types::ProtocolMessage}; use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex;
use ng_repo::errors::*;
use serde::{Deserialize, Serialize};
use std::any::{Any, TypeId};
use std::sync::Arc;
/// Send to probe if the server is a NextGraph broker. /// Send to probe if the server is a NextGraph broker.
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
@ -49,7 +51,7 @@ impl TryFrom<ProtocolMessage> for Probe {
} }
impl From<Probe> for ProtocolMessage { impl From<Probe> for ProtocolMessage {
fn from(msg: Probe) -> ProtocolMessage { fn from(_msg: Probe) -> ProtocolMessage {
ProtocolMessage::Probe(MAGIC_NG_REQUEST) ProtocolMessage::Probe(MAGIC_NG_REQUEST)
} }
} }
@ -61,9 +63,9 @@ impl EActor for Actor<'_, Probe, ProbeResponse> {
async fn respond( async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, _fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
let req = Probe::try_from(msg)?; let _req = Probe::try_from(msg)?;
//let res = ProbeResponse() //let res = ProbeResponse()
//fsm.lock().await.send(res.into()).await?; //fsm.lock().await.send(res.into()).await?;
Ok(()) Ok(())

@ -9,19 +9,22 @@
* according to those terms. * according to those terms.
*/ */
use std::any::{Any, TypeId};
use std::sync::Arc;
use async_std::sync::Mutex;
use serde::{Deserialize, Serialize};
use ng_repo::errors::*;
use ng_repo::log::*;
use crate::actors::noise::Noise; use crate::actors::noise::Noise;
use crate::connection::NoiseFSM; use crate::connection::NoiseFSM;
use crate::types::{ use crate::types::{
AdminRequest, CoreBrokerConnect, CoreBrokerConnectResponse, CoreBrokerConnectResponseV0, AdminRequest, CoreBrokerConnect, CoreBrokerConnectResponse, CoreMessage, CoreMessageV0,
CoreMessage, CoreMessageV0, CoreResponse, CoreResponseContentV0, CoreResponseV0, ExtResponse, CoreResponse, CoreResponseContentV0, CoreResponseV0, ExtResponse,
}; };
use crate::{actor::*, types::ProtocolMessage}; use crate::{actor::*, types::ProtocolMessage};
use async_std::sync::Mutex;
use ng_repo::errors::*;
use ng_repo::log::*;
use serde::{Deserialize, Serialize};
use std::any::{Any, TypeId};
use std::sync::Arc;
// pub struct Noise3(Noise); // pub struct Noise3(Noise);
@ -102,7 +105,7 @@ impl From<CoreHello> for ProtocolMessage {
} }
impl From<CoreBrokerConnect> for ProtocolMessage { impl From<CoreBrokerConnect> for ProtocolMessage {
fn from(msg: CoreBrokerConnect) -> ProtocolMessage { fn from(_msg: CoreBrokerConnect) -> ProtocolMessage {
unimplemented!(); unimplemented!();
} }
} }
@ -113,8 +116,8 @@ impl Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> {}
impl EActor for Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> { impl EActor for Actor<'_, CoreBrokerConnect, CoreBrokerConnectResponse> {
async fn respond( async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, _msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, _fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
//let req = CoreBrokerConnect::try_from(msg)?; //let req = CoreBrokerConnect::try_from(msg)?;
// let res = CoreBrokerConnectResponse::V0(CoreBrokerConnectResponseV0 { // let res = CoreBrokerConnectResponse::V0(CoreBrokerConnectResponseV0 {
@ -234,7 +237,7 @@ impl EActor for Actor<'_, ClientHello, ServerHello> {
msg: ProtocolMessage, msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
let req = ClientHello::try_from(msg)?; let _req = ClientHello::try_from(msg)?;
let res = ServerHello::V0(ServerHelloV0 { nonce: vec![] }); let res = ServerHello::V0(ServerHelloV0 { nonce: vec![] });
fsm.lock().await.send(res.into()).await?; fsm.lock().await.send(res.into()).await?;
Ok(()) Ok(())
@ -247,8 +250,8 @@ impl Actor<'_, ExtHello, ExtResponse> {}
impl EActor for Actor<'_, ExtHello, ExtResponse> { impl EActor for Actor<'_, ExtHello, ExtResponse> {
async fn respond( async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, _msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, _fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
Ok(()) Ok(())
} }

@ -11,26 +11,28 @@
//! Broker singleton present in every instance of NextGraph (Client, Server, Core node) //! Broker singleton present in every instance of NextGraph (Client, Server, Core node)
use crate::actor::EActor; use std::collections::HashMap;
use crate::actor::SoS; #[cfg(not(target_arch = "wasm32"))]
use crate::connection::*; use std::collections::HashSet;
use crate::server_broker::IServerBroker;
use crate::types::*;
use crate::utils::spawn_and_log_error;
use crate::utils::{Receiver, ResultSend, Sender};
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use async_std::sync::{Arc, RwLock}; use async_std::sync::{Arc, RwLock};
use either::Either; use either::Either;
use futures::channel::mpsc; use futures::channel::mpsc;
use futures::SinkExt; use futures::SinkExt;
use once_cell::sync::Lazy;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::object::Object;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::generate_keypair;
use once_cell::sync::Lazy; use crate::actor::EActor;
use std::collections::{HashMap, HashSet}; use crate::actor::SoS;
use std::path::PathBuf; use crate::connection::*;
use crate::server_broker::IServerBroker;
use crate::types::*;
use crate::utils::spawn_and_log_error;
use crate::utils::{Receiver, ResultSend, Sender};
#[derive(Debug)] #[derive(Debug)]
pub enum PeerConnection { pub enum PeerConnection {
@ -41,11 +43,13 @@ pub enum PeerConnection {
#[derive(Debug)] #[derive(Debug)]
pub struct BrokerPeerInfo { pub struct BrokerPeerInfo {
lastPeerAdvert: Option<PeerAdvert>, //FIXME: remove Option #[allow(dead_code)]
last_peer_advert: Option<PeerAdvert>, //FIXME: remove Option
connected: PeerConnection, connected: PeerConnection,
} }
#[derive(Debug)] #[derive(Debug)]
#[allow(dead_code)]
pub struct DirectConnection { pub struct DirectConnection {
addr: BindAddress, addr: BindAddress,
remote_peer_id: X25519PrivKey, remote_peer_id: X25519PrivKey,
@ -80,9 +84,7 @@ pub struct Broker {
peers: HashMap<(Option<PubKey>, X25519PubKey), BrokerPeerInfo>, peers: HashMap<(Option<PubKey>, X25519PubKey), BrokerPeerInfo>,
/// (local,remote) -> ConnectionBase /// (local,remote) -> ConnectionBase
anonymous_connections: HashMap<(BindAddress, BindAddress), ConnectionBase>, anonymous_connections: HashMap<(BindAddress, BindAddress), ConnectionBase>,
#[cfg(not(target_arch = "wasm32"))]
listeners: HashMap<String, ListenerInfo>,
bind_addresses: HashMap<BindAddress, String>,
config: Option<ServerConfig>, config: Option<ServerConfig>,
shutdown: Option<Receiver<ProtocolError>>, shutdown: Option<Receiver<ProtocolError>>,
shutdown_sender: Sender<ProtocolError>, shutdown_sender: Sender<ProtocolError>,
@ -92,6 +94,11 @@ pub struct Broker {
//local_broker: Option<Box<dyn ILocalBroker + Send + Sync + 'a>>, //local_broker: Option<Box<dyn ILocalBroker + Send + Sync + 'a>>,
local_broker: Option<Arc<RwLock<dyn ILocalBroker>>>, local_broker: Option<Arc<RwLock<dyn ILocalBroker>>>,
#[cfg(not(target_arch = "wasm32"))]
listeners: HashMap<String, ListenerInfo>,
#[cfg(not(target_arch = "wasm32"))]
bind_addresses: HashMap<BindAddress, String>,
#[cfg(not(target_arch = "wasm32"))]
users_peers: HashMap<UserId, HashSet<X25519PubKey>>, users_peers: HashMap<UserId, HashSet<X25519PubKey>>,
} }
@ -304,7 +311,7 @@ impl Broker {
match peerinfo { match peerinfo {
Some(info) => match &info.connected { Some(info) => match &info.connected {
PeerConnection::NONE => {} PeerConnection::NONE => {}
PeerConnection::Client(cb) => { PeerConnection::Client(_cb) => {
info.connected = PeerConnection::NONE; info.connected = PeerConnection::NONE;
} }
PeerConnection::Core(ip) => { PeerConnection::Core(ip) => {
@ -320,11 +327,11 @@ impl Broker {
match removed { match removed {
Some(info) => match info.connected { Some(info) => match info.connected {
PeerConnection::NONE => {} PeerConnection::NONE => {}
PeerConnection::Client(cb) => { PeerConnection::Client(_cb) => {
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
if user.is_none() { if user.is_none() {
// server side // server side
if let Some(fsm) = cb.fsm { if let Some(fsm) = _cb.fsm {
if let Ok(user) = fsm.lock().await.user_id() { if let Ok(user) = fsm.lock().await.user_id() {
let _ = self.remove_user_peer(&user, &peer_id); let _ = self.remove_user_peer(&user, &peer_id);
} }
@ -375,9 +382,6 @@ impl Broker {
Broker { Broker {
anonymous_connections: HashMap::new(), anonymous_connections: HashMap::new(),
#[cfg(not(target_arch = "wasm32"))]
listeners: HashMap::new(),
bind_addresses: HashMap::new(),
config: None, config: None,
shutdown: Some(shutdown_receiver), shutdown: Some(shutdown_receiver),
shutdown_sender, shutdown_sender,
@ -386,6 +390,12 @@ impl Broker {
closing: false, closing: false,
server_broker: None, server_broker: None,
local_broker: None, local_broker: None,
#[cfg(not(target_arch = "wasm32"))]
listeners: HashMap::new(),
#[cfg(not(target_arch = "wasm32"))]
bind_addresses: HashMap::new(),
#[cfg(not(target_arch = "wasm32"))]
users_peers: HashMap::new(), users_peers: HashMap::new(),
} }
} }
@ -524,8 +534,8 @@ impl Broker {
let res = join.next().await; let res = join.next().await;
match res { match res {
Some(Either::Right(remote_peer_id)) => { Some(Either::Right(remote_peer_id)) => {
let res = join.next().await; let _res = join.next().await;
log_debug!("SOCKET IS CLOSED {:?} peer_id: {:?}", res, remote_peer_id); log_debug!("SOCKET IS CLOSED {:?} peer_id: {:?}", _res, remote_peer_id);
BROKER BROKER
.write() .write()
.await .await
@ -660,7 +670,7 @@ impl Broker {
PeerConnection::Core(remote_bind_address) PeerConnection::Core(remote_bind_address)
}; };
let bpi = BrokerPeerInfo { let bpi = BrokerPeerInfo {
lastPeerAdvert: None, last_peer_advert: None,
connected, connected,
}; };
self.peers.insert((None, remote_peer_id), bpi); self.peers.insert((None, remote_peer_id), bpi);
@ -782,7 +792,7 @@ impl Broker {
}; };
let bpi = BrokerPeerInfo { let bpi = BrokerPeerInfo {
lastPeerAdvert: None, last_peer_advert: None,
connected, connected,
}; };
@ -791,9 +801,9 @@ impl Broker {
async fn watch_close( async fn watch_close(
mut join: Receiver<Either<NetError, X25519PrivKey>>, mut join: Receiver<Either<NetError, X25519PrivKey>>,
cnx: Arc<Box<dyn IConnect>>, _cnx: Arc<Box<dyn IConnect>>,
peer_privk: PrivKey, _peer_privk: PrivKey,
peer_pubkey: PubKey, _peer_pubkey: PubKey,
remote_peer_id: [u8; 32], remote_peer_id: [u8; 32],
config: StartConfig, config: StartConfig,
local_broker: Arc<async_std::sync::RwLock<dyn ILocalBroker>>, local_broker: Arc<async_std::sync::RwLock<dyn ILocalBroker>>,
@ -884,16 +894,16 @@ impl Broker {
remote_peer, remote_peer,
)?; )?;
log_debug!("dispatch_event {:?}", peers_for_local_dispatch); //log_debug!("dispatch_event {:?}", peers_for_local_dispatch);
for peer in peers_for_local_dispatch { for peer in peers_for_local_dispatch {
log_debug!("dispatch_event peer {:?}", peer); //log_debug!("dispatch_event peer {:?}", peer);
if let Some(BrokerPeerInfo { if let Some(BrokerPeerInfo {
connected: PeerConnection::Client(ConnectionBase { fsm: Some(fsm), .. }), connected: PeerConnection::Client(ConnectionBase { fsm: Some(fsm), .. }),
.. ..
}) = self.peers.get(&(None, peer.to_owned().to_dh())) }) = self.peers.get(&(None, peer.to_owned().to_dh()))
{ {
log_debug!("ForwardedEvent peer {:?}", peer); //log_debug!("ForwardedEvent peer {:?}", peer);
let _ = fsm let _ = fsm
.lock() .lock()
.await .await

@ -18,20 +18,10 @@ use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use crate::actor::{Actor, SoS};
use crate::actors::*;
use crate::broker::BROKER;
use crate::types::*;
use crate::utils::*;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use async_std::sync::Mutex; use async_std::sync::Mutex;
use either::Either; use either::Either;
use futures::{channel::mpsc, select, FutureExt, SinkExt}; use futures::{channel::mpsc, select, FutureExt, SinkExt};
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::{DirectPeerId, PrivKey, PubKey, UserId, X25519PrivKey};
use ng_repo::utils::{sign, verify};
use noise_protocol::{patterns::noise_xk, CipherState, HandshakeState}; use noise_protocol::{patterns::noise_xk, CipherState, HandshakeState};
use noise_rust_crypto::*; use noise_rust_crypto::*;
use serde_bare::from_slice; use serde_bare::from_slice;
@ -39,6 +29,19 @@ use unique_id::sequence::SequenceGenerator;
use unique_id::Generator; use unique_id::Generator;
use unique_id::GeneratorFromSeed; use unique_id::GeneratorFromSeed;
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::types::{DirectPeerId, PrivKey, PubKey, UserId, X25519PrivKey};
use ng_repo::utils::sign;
#[cfg(not(target_arch = "wasm32"))]
use ng_repo::utils::verify;
use crate::actor::{Actor, SoS};
use crate::actors::*;
use crate::broker::BROKER;
use crate::types::*;
use crate::utils::*;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ConnectionCommand { pub enum ConnectionCommand {
Msg(ProtocolMessage), Msg(ProtocolMessage),
@ -123,6 +126,7 @@ pub struct NoiseFSM {
sender: Sender<ConnectionCommand>, sender: Sender<ConnectionCommand>,
/// first is local, second is remote /// first is local, second is remote
#[allow(dead_code)]
bind_addresses: Option<(BindAddress, BindAddress)>, bind_addresses: Option<(BindAddress, BindAddress)>,
actors: Arc<Mutex<HashMap<i64, Sender<ConnectionCommand>>>>, actors: Arc<Mutex<HashMap<i64, Sender<ConnectionCommand>>>>,
@ -268,6 +272,7 @@ impl NoiseFSM {
&self.remote &self.remote
} }
#[cfg(not(target_arch = "wasm32"))]
pub(crate) fn set_user_id(&mut self, user: UserId) { pub(crate) fn set_user_id(&mut self, user: UserId) {
if self.user.is_none() { if self.user.is_none() {
self.user = Some(user); self.user = Some(user);
@ -362,13 +367,13 @@ impl NoiseFSM {
None, None,
); );
let mut payload = handshake.read_message_vec(noise.data()).map_err(|e| { let mut payload = handshake.read_message_vec(noise.data()).map_err(|_e| {
log_debug!("{:?}", e); log_debug!("{:?}", _e);
ProtocolError::NoiseHandshakeFailed ProtocolError::NoiseHandshakeFailed
})?; })?;
payload = handshake.write_message_vec(&payload).map_err(|e| { payload = handshake.write_message_vec(&payload).map_err(|_e| {
log_debug!("{:?}", e); log_debug!("{:?}", _e);
ProtocolError::NoiseHandshakeFailed ProtocolError::NoiseHandshakeFailed
})?; })?;
@ -580,8 +585,8 @@ impl NoiseFSM {
.read_message_vec(noise.data()) .read_message_vec(noise.data())
.map_err(|_e| ProtocolError::NoiseHandshakeFailed)?; .map_err(|_e| ProtocolError::NoiseHandshakeFailed)?;
payload = handshake.write_message_vec(&payload).map_err(|e| { payload = handshake.write_message_vec(&payload).map_err(|_e| {
log_debug!("{:?}", e); log_debug!("{:?}", _e);
ProtocolError::NoiseHandshakeFailed ProtocolError::NoiseHandshakeFailed
})?; })?;

@ -1,84 +0,0 @@
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use core::fmt;
use ng_repo::errors::{ObjectParseError, StorageError};
use std::convert::From;
use std::error::Error;
// impl From<BrokerMessage> for Result<(), ProtocolError> {
// fn from(msg: BrokerMessage) -> Self {
// if !msg.is_response() {
// panic!("BrokerMessage is not a response");
// }
// match msg.result() {
// 0 => Ok(()),
// err => Err(ProtocolError::try_from(err).unwrap()),
// }
// }
// }
// impl From<BrokerMessage> for Result<ObjectId, ProtocolError> {
// fn from(msg: BrokerMessage) -> Self {
// if !msg.is_response() {
// panic!("BrokerMessage is not a response");
// }
// match msg.result() {
// 0 => Ok(msg.response_object_id()),
// err => Err(ProtocolError::try_from(err).unwrap()),
// }
// }
// }
// /// Option represents if a Block is available. cannot be returned here. call BrokerMessage.response_block() to get a reference to it.
// impl From<BrokerMessage> for Result<Option<u16>, ProtocolError> {
// fn from(msg: BrokerMessage) -> Self {
// if !msg.is_response() {
// panic!("BrokerMessage is not a response");
// }
// //let partial: u16 = ProtocolError::PartialContent.into();
// let res = msg.result();
// if res == 0 || ProtocolError::try_from(res).unwrap().is_stream() {
// if msg.is_overlay() {
// match msg.response_block() {
// Some(_) => Ok(Some(res)),
// None => Ok(None),
// }
// } else {
// Ok(None)
// }
// } else {
// Err(ProtocolError::try_from(res).unwrap())
// }
// }
// }
// /// Option represents if a Block is available. returns a clone.
// impl From<BrokerMessage> for Result<Option<Block>, ProtocolError> {
// fn from(msg: BrokerMessage) -> Self {
// if !msg.is_response() {
// panic!("BrokerMessage is not a response");
// }
// //let partial: u16 = ProtocolError::PartialContent.into();
// let res = msg.result();
// if res == 0 || ProtocolError::try_from(res).unwrap().is_stream() {
// if msg.is_overlay() {
// match msg.response_block() {
// Some(b) => Ok(Some(b.clone())),
// None => Ok(None),
// }
// } else {
// Ok(None)
// }
// } else {
// Err(ProtocolError::try_from(res).unwrap())
// }
// }
// }

@ -11,10 +11,6 @@
pub mod types; pub mod types;
pub mod errors;
//pub mod broker_connection;
pub mod broker; pub mod broker;
pub mod server_broker; pub mod server_broker;

@ -13,10 +13,11 @@
use std::collections::HashSet; use std::collections::HashSet;
use crate::types::*;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::types::*; use ng_repo::types::*;
use crate::types::*;
pub trait IServerBroker: Send + Sync { pub trait IServerBroker: Send + Sync {
fn put_block(&self, overlay_id: &OverlayId, block: Block) -> Result<(), ServerError>; fn put_block(&self, overlay_id: &OverlayId, block: Block) -> Result<(), ServerError>;
fn has_block(&self, overlay_id: &OverlayId, block_id: &BlockId) -> Result<(), ServerError>; fn has_block(&self, overlay_id: &OverlayId, block_id: &BlockId) -> Result<(), ServerError>;

@ -11,26 +11,29 @@
//! //!
//! Corresponds to the BARE schema //! Corresponds to the BARE schema
use crate::utils::{
get_domain_without_port_443, is_ipv4_private, is_ipv6_private, is_private_ip, is_public_ip,
is_public_ipv4, is_public_ipv6,
};
use crate::WS_PORT_ALTERNATE;
use crate::{actor::EActor, actors::admin::*, actors::*};
use core::fmt; use core::fmt;
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::store::Store;
use ng_repo::types::*;
use ng_repo::utils::{sign, verify};
use serde::{Deserialize, Serialize};
use std::collections::HashSet; use std::collections::HashSet;
use std::{ use std::{
any::{Any, TypeId}, any::{Any, TypeId},
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}, net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
}; };
use serde::{Deserialize, Serialize};
use web_time::SystemTime; use web_time::SystemTime;
use ng_repo::errors::*;
use ng_repo::log::*;
use ng_repo::store::Store;
use ng_repo::types::*;
use ng_repo::utils::{sign, verify};
use crate::utils::{
get_domain_without_port_443, is_ipv4_private, is_ipv6_private, is_private_ip, is_public_ip,
is_public_ipv4, is_public_ipv6,
};
use crate::WS_PORT_ALTERNATE;
use crate::{actor::EActor, actors::admin::*, actors::*};
// //
// Network common types // Network common types
// //
@ -1276,7 +1279,7 @@ impl OverlayAccess {
pub fn overlay_id_for_client_protocol_purpose(&self) -> &OverlayId { pub fn overlay_id_for_client_protocol_purpose(&self) -> &OverlayId {
match self { match self {
Self::ReadOnly(ro) => ro, Self::ReadOnly(ro) => ro,
Self::ReadWrite((inner, outer)) => inner, Self::ReadWrite((inner, _outer)) => inner,
Self::WriteOnly(wo) => wo, Self::WriteOnly(wo) => wo,
} }
} }
@ -3255,7 +3258,7 @@ impl ClientRequestContentV0 {
match self { match self {
ClientRequestContentV0::RepoPinStatusReq(a) => a.set_overlay(overlay), ClientRequestContentV0::RepoPinStatusReq(a) => a.set_overlay(overlay),
ClientRequestContentV0::TopicSub(a) => a.set_overlay(overlay), ClientRequestContentV0::TopicSub(a) => a.set_overlay(overlay),
ClientRequestContentV0::PinRepo(a) => {} ClientRequestContentV0::PinRepo(_a) => {}
ClientRequestContentV0::PublishEvent(a) => a.set_overlay(overlay), ClientRequestContentV0::PublishEvent(a) => a.set_overlay(overlay),
ClientRequestContentV0::CommitGet(a) => a.set_overlay(overlay), ClientRequestContentV0::CommitGet(a) => a.set_overlay(overlay),
ClientRequestContentV0::TopicSyncReq(a) => a.set_overlay(overlay), ClientRequestContentV0::TopicSyncReq(a) => a.set_overlay(overlay),
@ -3536,7 +3539,7 @@ impl TryFrom<ProtocolMessage> for ClientResponseContentV0 {
if let ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 { if let ProtocolMessage::ClientMessage(ClientMessage::V0(ClientMessageV0 {
content: content:
ClientMessageContentV0::ClientResponse(ClientResponse::V0(ClientResponseV0 { ClientMessageContentV0::ClientResponse(ClientResponse::V0(ClientResponseV0 {
content: content, content,
result: res, result: res,
.. ..
})), })),

@ -9,23 +9,26 @@
* according to those terms. * according to those terms.
*/ */
use crate::types::*; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
#[cfg(target_arch = "wasm32")]
use crate::NG_BOOTSTRAP_LOCAL_PATH;
use async_std::task; use async_std::task;
use ed25519_dalek::*; use ed25519_dalek::*;
use futures::{channel::mpsc, Future}; use futures::{channel::mpsc, Future};
#[cfg(target_arch = "wasm32")]
use ng_repo::errors::*;
use ng_repo::types::PubKey;
use ng_repo::{log::*, types::PrivKey};
use noise_protocol::U8Array; use noise_protocol::U8Array;
use noise_protocol::DH; use noise_protocol::DH;
use noise_rust_crypto::sensitive::Sensitive; use noise_rust_crypto::sensitive::Sensitive;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use url::Host; use url::Host;
use url::Url; use url::Url;
#[cfg(target_arch = "wasm32")]
use ng_repo::errors::*;
use ng_repo::types::PubKey;
use ng_repo::{log::*, types::PrivKey};
use crate::types::*;
#[cfg(target_arch = "wasm32")]
use crate::NG_BOOTSTRAP_LOCAL_PATH;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
pub fn spawn_and_log_error<F>(fut: F) -> task::JoinHandle<()> pub fn spawn_and_log_error<F>(fut: F) -> task::JoinHandle<()>
where where
@ -119,7 +122,7 @@ pub fn check_is_local_url(bootstrap: &BrokerServerV0, location: &String) -> Opti
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
async fn retrieve_ng_bootstrap(location: &String) -> Option<LocalBootstrapInfo> { async fn retrieve_ng_bootstrap(location: &String) -> Option<LocalBootstrapInfo> {
let prefix = if (APP_PREFIX == "") { let prefix = if APP_PREFIX == "" {
let url = Url::parse(location).unwrap(); let url = Url::parse(location).unwrap();
url.origin().unicode_serialization() url.origin().unicode_serialization()
} else { } else {
@ -177,7 +180,7 @@ pub async fn retrieve_local_bootstrap(
if info.is_none() { if info.is_none() {
None None
} else { } else {
let mut inv: Invitation = info.unwrap().into(); let inv: Invitation = info.unwrap().into();
Some(inv) Some(inv)
} }
}; };

@ -9,13 +9,13 @@
//! Immutable Block, used to store and exchange File and Commit //! Immutable Block, used to store and exchange File and Commit
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::ChaCha20;
use crate::errors::*; use crate::errors::*;
use crate::log::*; use crate::log::*;
use crate::types::*; use crate::types::*;
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::ChaCha20;
impl BlockV0 { impl BlockV0 {
pub fn new( pub fn new(
children: Vec<BlockId>, children: Vec<BlockId>,
@ -245,8 +245,8 @@ impl Block {
let content: ChunkContentV0; let content: ChunkContentV0;
match serde_bare::from_slice(content_dec.as_slice()) { match serde_bare::from_slice(content_dec.as_slice()) {
Ok(c) => content = c, Ok(c) => content = c,
Err(e) => { Err(_e) => {
log_debug!("Block deserialize error: {}", e); //log_debug!("Block deserialize error: {}", e);
return Err(ObjectParseError::BlockDeserializeError); return Err(ObjectParseError::BlockDeserializeError);
} }
} }

@ -9,11 +9,6 @@
//! Storage of Blocks //! Storage of Blocks
use futures::StreamExt;
use crate::errors::*;
use crate::types::*;
use crate::utils::Receiver;
use std::sync::RwLock; use std::sync::RwLock;
use std::{ use std::{
cmp::{max, min}, cmp::{max, min},
@ -21,6 +16,12 @@ use std::{
mem::size_of_val, mem::size_of_val,
}; };
use futures::StreamExt;
use crate::errors::*;
use crate::types::*;
use crate::utils::Receiver;
pub trait BlockStorage: Send + Sync { pub trait BlockStorage: Send + Sync {
/// Load a block from the storage. /// Load a block from the storage.
fn get(&self, overlay: &OverlayId, id: &BlockId) -> Result<Block, StorageError>; fn get(&self, overlay: &OverlayId, id: &BlockId) -> Result<Block, StorageError>;
@ -165,7 +166,7 @@ impl BlockStorage for HashMapBlockStorage {
Ok(id) Ok(id)
} }
fn del(&self, overlay: &OverlayId, id: &BlockId) -> Result<usize, StorageError> { fn del(&self, _overlay: &OverlayId, id: &BlockId) -> Result<usize, StorageError> {
let block = self let block = self
.blocks .blocks
.write() .write()

@ -12,12 +12,12 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::fmt; use std::fmt;
use zeroize::{Zeroize, ZeroizeOnDrop};
use zeroize::Zeroize;
// use fastbloom_rs::{BloomFilter as Filter, Membership}; // use fastbloom_rs::{BloomFilter as Filter, Membership};
use crate::block_storage::*;
use crate::errors::*; use crate::errors::*;
#[allow(unused_imports)]
use crate::log::*; use crate::log::*;
use crate::object::*; use crate::object::*;
use crate::store::Store; use crate::store::Store;
@ -49,7 +49,7 @@ impl BranchV0 {
} }
#[derive(Debug)] #[derive(Debug)]
struct DagNode { pub struct DagNode {
pub future: HashSet<ObjectId>, pub future: HashSet<ObjectId>,
} }
@ -152,40 +152,25 @@ impl Branch {
)) ))
} }
/// Branch sync request from another peer
///
/// `target_heads` represents the list of heads the requester would like to reach. this list should not be empty.
/// if the requester doesn't know what to reach, the responder should fill this list with their own current local head.
/// `known_heads` represents the list of current heads at the requester replica at the moment of request.
/// an empty list means the requester has an empty branch locally
///
/// Return ObjectIds to send, ordered in respect of causal partial order
pub fn sync_req(
target_heads: impl Iterator<Item = ObjectId>,
known_heads: &[ObjectId],
//their_filter: &BloomFilter,
store: &Store,
) -> Result<Vec<ObjectId>, ObjectParseError> {
//log_debug!(">> sync_req");
//log_debug!(" target_heads: {:?}", target_heads);
//log_debug!(" known_heads: {:?}", known_heads);
/// Load causal past of a Commit `cobj` in a `Branch` from the `Store`, /// Load causal past of a Commit `cobj` in a `Branch` from the `Store`,
///
/// and collect in `visited` the ObjectIds encountered on the way, stopping at any commit already belonging to `theirs` or the root of DAG. /// and collect in `visited` the ObjectIds encountered on the way, stopping at any commit already belonging to `theirs` or the root of DAG.
/// optionally collecting the missing objects/blocks that couldn't be found locally on the way /// optionally collecting the missing objects/blocks that couldn't be found locally on the way,
fn load_causal_past( /// and also optionally, collecting the commits of theirs found on the way
pub fn load_causal_past(
cobj: &Object, cobj: &Object,
store: &Store, store: &Store,
theirs: &HashMap<ObjectId, DagNode>, theirs: &HashSet<ObjectId>,
visited: &mut HashMap<ObjectId, DagNode>, visited: &mut HashMap<ObjectId, DagNode>,
missing: &mut Option<&mut HashSet<ObjectId>>, missing: &mut Option<&mut HashSet<ObjectId>>,
future: Option<ObjectId>, future: Option<ObjectId>,
theirs_found: &mut Option<&mut HashSet<ObjectId>>,
) -> Result<(), ObjectParseError> { ) -> Result<(), ObjectParseError> {
let id = cobj.id(); let id = cobj.id();
// check if this commit object is present in theirs or has already been visited in the current walk // check if this commit object is present in theirs or has already been visited in the current walk
// load deps, stop at the root(including it in visited) or if this is a commit object from known_heads // load deps, stop at the root(including it in visited) or if this is a commit object from known_heads
if !theirs.contains_key(&id) { if !theirs.contains(&id) {
if let Some(past) = visited.get_mut(&id) { if let Some(past) = visited.get_mut(&id) {
// we update the future // we update the future
if let Some(f) = future { if let Some(f) = future {
@ -200,7 +185,15 @@ impl Branch {
for past_id in cobj.acks_and_nacks() { for past_id in cobj.acks_and_nacks() {
match Object::load(past_id, None, store) { match Object::load(past_id, None, store) {
Ok(o) => { Ok(o) => {
load_causal_past(&o, store, theirs, visited, missing, Some(id))?; Self::load_causal_past(
&o,
store,
theirs,
visited,
missing,
Some(id),
theirs_found,
)?;
} }
Err(ObjectParseError::MissingBlocks(blocks)) => { Err(ObjectParseError::MissingBlocks(blocks)) => {
missing.as_mut().map(|m| m.extend(blocks)); missing.as_mut().map(|m| m.extend(blocks));
@ -209,27 +202,66 @@ impl Branch {
} }
} }
} }
} else if theirs_found.is_some() {
theirs_found.as_mut().unwrap().insert(id);
} }
Ok(()) Ok(())
} }
/// Branch sync request from another peer
///
/// `target_heads` represents the list of heads the requester would like to reach. this list should not be empty.
/// if the requester doesn't know what to reach, the responder should fill this list with their own current local head.
/// `known_heads` represents the list of current heads at the requester replica at the moment of request.
/// an empty list means the requester has an empty branch locally
///
/// Return ObjectIds to send, ordered in respect of causal partial order
pub fn sync_req(
target_heads: impl Iterator<Item = ObjectId>,
known_heads: &[ObjectId],
//their_filter: &BloomFilter,
store: &Store,
) -> Result<Vec<ObjectId>, ObjectParseError> {
//log_debug!(">> sync_req");
//log_debug!(" target_heads: {:?}", target_heads);
//log_debug!(" known_heads: {:?}", known_heads);
// their commits // their commits
let mut theirs: HashMap<ObjectId, DagNode> = HashMap::new(); let mut theirs: HashMap<ObjectId, DagNode> = HashMap::new();
// collect causal past of known_heads // collect causal past of known_heads
for id in known_heads { for id in known_heads {
if let Ok(cobj) = Object::load(*id, None, store) { if let Ok(cobj) = Object::load(*id, None, store) {
load_causal_past(&cobj, store, &HashMap::new(), &mut theirs, &mut None, None)?; Self::load_causal_past(
&cobj,
store,
&HashSet::new(),
&mut theirs,
&mut None,
None,
&mut None,
)?;
} }
// we silently discard any load error on the known_heads as the responder might not know them (yet). // we silently discard any load error on the known_heads as the responder might not know them (yet).
} }
let mut visited = HashMap::new(); let mut visited = HashMap::new();
let theirs: HashSet<ObjectId> = theirs.keys().into_iter().cloned().collect();
// collect all commits reachable from target_heads // collect all commits reachable from target_heads
// up to the root or until encountering a commit from theirs // up to the root or until encountering a commit from theirs
for id in target_heads { for id in target_heads {
if let Ok(cobj) = Object::load(id, None, store) { if let Ok(cobj) = Object::load(id, None, store) {
load_causal_past(&cobj, store, &theirs, &mut visited, &mut None, None)?; Self::load_causal_past(
&cobj,
store,
&theirs,
&mut visited,
&mut None,
None,
&mut None,
)?;
} }
// we silently discard any load error on the target_heads as they can be wrong if the requester is confused about what the responder has locally. // we silently discard any load error on the target_heads as they can be wrong if the requester is confused about what the responder has locally.
} }

@ -10,21 +10,18 @@
//! Commit that composes the DAG of a Branch //! Commit that composes the DAG of a Branch
use core::fmt; use core::fmt;
use std::collections::HashSet;
use std::iter::FromIterator;
use ed25519_dalek::{PublicKey, Signature}; use ed25519_dalek::{PublicKey, Signature};
use once_cell::sync::OnceCell; use once_cell::sync::OnceCell;
use crate::errors::NgError;
use crate::block_storage::*;
use crate::errors::*; use crate::errors::*;
use crate::log::*;
use crate::object::*; use crate::object::*;
use crate::repo::Repo; use crate::repo::Repo;
use crate::store::Store; use crate::store::Store;
use crate::types::*; use crate::types::*;
use crate::utils::*; use crate::utils::*;
use std::collections::HashSet;
use std::iter::FromIterator;
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
pub enum CommitLoadError { pub enum CommitLoadError {
@ -486,7 +483,7 @@ impl Commit {
CommitBody::V0(CommitBodyV0::RootBranch(_)) => { CommitBody::V0(CommitBodyV0::RootBranch(_)) => {
let deps = self.deps(); let deps = self.deps();
let acks = self.acks(); let acks = self.acks();
if deps.len() == 0 && acks.len() == 1 { if deps.is_empty() && acks.len() == 1 {
// we check that the ACK is the repository singleton commit. in this case, it means we are dealing with the first RootBranch commit, which is fine to have no deps. // we check that the ACK is the repository singleton commit. in this case, it means we are dealing with the first RootBranch commit, which is fine to have no deps.
let causal_past = Commit::load(acks[0].clone(), store, true)?; let causal_past = Commit::load(acks[0].clone(), store, true)?;
if causal_past.body().unwrap().is_repository_singleton_commit() { if causal_past.body().unwrap().is_repository_singleton_commit() {
@ -567,7 +564,7 @@ impl Commit {
res res
} }
/// Get all commits that are in the direct causal past of the commit (`deps`, `acks`, `nacks`) /// Get all commits that are in the direct causal past of the commit (`acks` and `nacks`)
/// only returns objectRefs that have both an ID from header and a KEY from header_keys (they all have a key) /// only returns objectRefs that have both an ID from header and a KEY from header_keys (they all have a key)
pub fn direct_causal_past(&self) -> Vec<ObjectRef> { pub fn direct_causal_past(&self) -> Vec<ObjectRef> {
let mut res: Vec<ObjectRef> = vec![]; let mut res: Vec<ObjectRef> = vec![];
@ -580,12 +577,6 @@ impl Commit {
for nack in header_v0.nacks.iter().zip(hk_v0.nacks.iter()) { for nack in header_v0.nacks.iter().zip(hk_v0.nacks.iter()) {
res.push(nack.into()); res.push(nack.into());
} }
for dep in header_v0.deps.iter().zip(hk_v0.deps.iter()) {
let obj_ref: ObjectRef = dep.into();
if !res.contains(&obj_ref) {
res.push(obj_ref);
}
}
} }
_ => {} _ => {}
}, },
@ -1178,6 +1169,7 @@ impl CommitHeader {
} }
impl CommitHeaderV0 { impl CommitHeaderV0 {
#[allow(dead_code)]
fn new_empty() -> Self { fn new_empty() -> Self {
Self { Self {
id: None, id: None,

@ -9,15 +9,16 @@
//! Errors //! Errors
pub use crate::commit::{CommitLoadError, CommitVerifyError}; use core::fmt;
use crate::file::FileError; use std::error::Error;
use crate::object::Object;
use num_enum::IntoPrimitive; use num_enum::IntoPrimitive;
use num_enum::TryFromPrimitive; use num_enum::TryFromPrimitive;
pub use crate::commit::{CommitLoadError, CommitVerifyError};
use crate::file::FileError;
use crate::object::Object;
use crate::types::BlockId; use crate::types::BlockId;
use core::fmt;
use std::error::Error;
#[derive(Debug, Eq, PartialEq, Clone)] #[derive(Debug, Eq, PartialEq, Clone)]
#[repr(u16)] #[repr(u16)]

@ -8,22 +8,18 @@
//! Event, a message sent in the PUB/SUB //! Event, a message sent in the PUB/SUB
use core::fmt;
use std::sync::Arc;
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::ChaCha20;
use zeroize::Zeroize; use zeroize::Zeroize;
use crate::block_storage::*;
use crate::errors::*; use crate::errors::*;
use crate::object::*; use crate::repo::{BranchInfo, Repo};
use crate::repo::BranchInfo;
use crate::repo::Repo;
use crate::store::Store; use crate::store::Store;
use crate::types::*; use crate::types::*;
use crate::utils::*; use crate::utils::*;
use core::fmt;
use std::sync::Arc;
use std::sync::RwLockWriteGuard;
use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::ChaCha20;
impl fmt::Display for Event { impl fmt::Display for Event {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

@ -20,6 +20,7 @@ use zeroize::Zeroize;
use crate::block_storage::*; use crate::block_storage::*;
use crate::errors::*; use crate::errors::*;
#[allow(unused_imports)]
use crate::log::*; use crate::log::*;
use crate::object::*; use crate::object::*;
use crate::store::Store; use crate::store::Store;
@ -203,7 +204,7 @@ impl ReadFile for RandomAccessFile {
if level > 0 { if level > 0 {
let tree_block = store.get(&current_block_id_key.0)?; let tree_block = store.get(&current_block_id_key.0)?;
let (children, content) = tree_block.read(&current_block_id_key.1)?; let (children, content) = tree_block.read(&current_block_id_key.1)?;
if children.len() == 0 || content.len() > 0 { if children.is_empty() || content.len() > 0 {
return Err(FileError::BlockDeserializeError); return Err(FileError::BlockDeserializeError);
} }
@ -238,7 +239,7 @@ impl ReadFile for RandomAccessFile {
for level in 0..depth { for level in 0..depth {
let tree_block = self.store.get(&current_block_id_key.0)?; let tree_block = self.store.get(&current_block_id_key.0)?;
let (children, content) = tree_block.read(&current_block_id_key.1)?; let (children, content) = tree_block.read(&current_block_id_key.1)?;
if children.len() == 0 || content.len() > 0 { if children.is_empty() || content.len() > 0 {
return Err(FileError::BlockDeserializeError); return Err(FileError::BlockDeserializeError);
} }
let factor = (arity as usize).pow(depth as u32 - level as u32 - 1) let factor = (arity as usize).pow(depth as u32 - level as u32 - 1)
@ -256,7 +257,7 @@ impl ReadFile for RandomAccessFile {
let (children, content) = content_block.read(&current_block_id_key.1)?; let (children, content) = content_block.read(&current_block_id_key.1)?;
if children.len() == 0 && content.len() > 0 { if children.is_empty() && content.len() > 0 {
//log_debug!("CONTENT SIZE {}", content.len()); //log_debug!("CONTENT SIZE {}", content.len());
if level_pos >= content.len() { if level_pos >= content.len() {
@ -289,7 +290,7 @@ impl ReadFile for RandomAccessFile {
let block = &self.blocks[index]; let block = &self.blocks[index];
let content_block = self.store.get(&block.0)?; let content_block = self.store.get(&block.0)?;
let (children, content) = content_block.read(&block.1)?; let (children, content) = content_block.read(&block.1)?;
if children.len() == 0 && content.len() > 0 { if children.is_empty() && content.len() > 0 {
//log_debug!("CONTENT SIZE {}", content.len()); //log_debug!("CONTENT SIZE {}", content.len());
if level_pos >= content.len() { if level_pos >= content.len() {

@ -8,14 +8,18 @@
//! KeyColumnValue Storage abstraction //! KeyColumnValue Storage abstraction
use std::collections::HashMap; use std::{
use std::{collections::HashSet, marker::PhantomData}; collections::{HashMap, HashSet},
marker::PhantomData,
};
use crate::errors::StorageError;
use crate::log::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_bare::{from_slice, to_vec}; use serde_bare::{from_slice, to_vec};
use crate::errors::StorageError;
#[allow(unused_imports)]
use crate::log::*;
pub fn prop<A>(prop: u8, props: &HashMap<u8, Vec<u8>>) -> Result<A, StorageError> pub fn prop<A>(prop: u8, props: &HashMap<u8, Vec<u8>>) -> Result<A, StorageError>
where where
A: for<'a> Deserialize<'a>, A: for<'a> Deserialize<'a>,
@ -168,7 +172,7 @@ pub trait IModel {
self.existential().as_mut().unwrap().process_exists(res); self.existential().as_mut().unwrap().process_exists(res);
true true
} }
Err(e) => false, Err(_e) => false,
} }
} }
fn storage(&self) -> &dyn KCVStorage; fn storage(&self) -> &dyn KCVStorage;
@ -266,6 +270,51 @@ impl<
.has_property_value(self.prefix, &key, None, &vec![], &None) .has_property_value(self.prefix, &key, None, &vec![], &None)
} }
pub fn remove_from_set_and_add(
&self,
model: &mut Model,
mut remove_set: HashSet<Column>,
add_set: HashSet<Column>,
) -> Result<(), StorageError> {
// if existing_set.len() == 0 {
// return Err(StorageError::InvalidValue);
// }
model.check_exists()?;
let key_prefix = model.key();
let key_prefix_len = key_prefix.len();
let total_size = key_prefix_len + self.value_size()?;
//log_debug!("REPLACE HEAD {:?} with {:?}", existing_set, replace_with);
model.storage().write_transaction(&mut |tx| {
for found in tx.get_all_keys_and_values(
self.prefix,
total_size,
key_prefix.to_vec(),
None,
&None,
)? {
if found.0.len() == total_size + 1 {
let val: Column = from_slice(&found.0[1 + key_prefix_len..total_size + 1])?;
if remove_set.remove(&val) {
tx.del(self.prefix, &found.0[1..].to_vec(), None, &None)?;
}
}
}
for add in add_set.iter() {
let mut new = Vec::with_capacity(total_size);
new.extend(key_prefix);
let mut val = to_vec(add)?;
new.append(&mut val);
//log_debug!("PUTTING HEAD {} {:?}", self.prefix as char, new);
tx.put(self.prefix, &new, None, &vec![], &None)?;
}
return Ok(());
})
}
pub fn replace_with_new_set_if_old_set_exists( pub fn replace_with_new_set_if_old_set_exists(
&self, &self,
model: &mut Model, model: &mut Model,
@ -281,7 +330,7 @@ impl<
let key_prefix_len = key_prefix.len(); let key_prefix_len = key_prefix.len();
let total_size = key_prefix_len + self.value_size()?; let total_size = key_prefix_len + self.value_size()?;
let empty_existing = existing_set.len() == 0; let empty_existing = existing_set.is_empty();
//log_debug!("REPLACE HEAD {:?} with {:?}", existing_set, replace_with); //log_debug!("REPLACE HEAD {:?} with {:?}", existing_set, replace_with);
@ -295,7 +344,7 @@ impl<
)? { )? {
if found.0.len() == total_size + 1 { if found.0.len() == total_size + 1 {
let val: Column = from_slice(&found.0[1 + key_prefix_len..total_size + 1])?; let val: Column = from_slice(&found.0[1 + key_prefix_len..total_size + 1])?;
if (empty_existing) { if empty_existing {
return Err(StorageError::NotEmpty); return Err(StorageError::NotEmpty);
} }
if existing_set.remove(&val) { if existing_set.remove(&val) {
@ -303,7 +352,7 @@ impl<
} }
} }
} }
if existing_set.len() == 0 { if existing_set.is_empty() {
for add in replace_with.iter() { for add in replace_with.iter() {
let mut new = Vec::with_capacity(total_size); let mut new = Vec::with_capacity(total_size);
new.extend(key_prefix); new.extend(key_prefix);
@ -781,7 +830,7 @@ impl<Column: Clone + Serialize + for<'d> Deserialize<'d>> ExistentialValue<Colum
if self.value.is_some() { if self.value.is_some() {
return Ok(self.value.as_ref().unwrap()); return Ok(self.value.as_ref().unwrap());
} }
if self.value_ser.len() == 0 { if self.value_ser.is_empty() {
return Err(StorageError::BackendError); return Err(StorageError::BackendError);
} }
let value = from_slice::<Column>(&self.value_ser); let value = from_slice::<Column>(&self.value_ser);

@ -10,8 +10,6 @@
//! Object: Merkle hash tree of Blocks //! Object: Merkle hash tree of Blocks
use core::fmt; use core::fmt;
use std::borrow::BorrowMut;
use std::cmp::max;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use chacha20::cipher::{KeyIvInit, StreamCipher}; use chacha20::cipher::{KeyIvInit, StreamCipher};
@ -37,7 +35,6 @@ pub const BLOCK_KEY_SIZE: usize = 33;
pub const BIG_VARINT_EXTRA: usize = 2; pub const BIG_VARINT_EXTRA: usize = 2;
/// Varint extra bytes when reaching the maximum size of data byte arrays. /// Varint extra bytes when reaching the maximum size of data byte arrays.
pub const DATA_VARINT_EXTRA: usize = 4; pub const DATA_VARINT_EXTRA: usize = 4;
pub const BLOCK_MAX_DATA_EXTRA: usize = 4; pub const BLOCK_MAX_DATA_EXTRA: usize = 4;
#[derive(Debug, PartialEq, Eq, Clone)] #[derive(Debug, PartialEq, Eq, Clone)]
@ -367,7 +364,8 @@ impl Object {
} else { } else {
// chunk content and create leaf nodes // chunk content and create leaf nodes
let mut i = 0; let mut i = 0;
let total = max(1, content_len / (valid_block_size - BLOCK_EXTRA)); #[cfg(not(target_arch = "wasm32"))]
let _total = std::cmp::max(1, content_len / (valid_block_size - BLOCK_EXTRA));
for chunk in content_ser.chunks(valid_block_size - BLOCK_EXTRA) { for chunk in content_ser.chunks(valid_block_size - BLOCK_EXTRA) {
let data_chunk = ChunkContentV0::DataChunk(chunk.to_vec()); let data_chunk = ChunkContentV0::DataChunk(chunk.to_vec());
let chunk_ser = serde_bare::to_vec(&data_chunk).unwrap(); let chunk_ser = serde_bare::to_vec(&data_chunk).unwrap();
@ -377,7 +375,8 @@ impl Object {
&mut block_contents, &mut block_contents,
&mut already_existing, &mut already_existing,
); );
log_debug!("make_block {} of {} - {}%", i, total + 1, i * 100 / total); #[cfg(not(target_arch = "wasm32"))]
log_debug!("make_block {} of {} - {}%", i, _total + 1, i * 100 / _total);
i = i + 1; i = i + 1;
} }
@ -465,7 +464,7 @@ impl Object {
Ok(ObjectContent::V0(ObjectContentV0::CommitHeader(commit_header))) => { Ok(ObjectContent::V0(ObjectContentV0::CommitHeader(commit_header))) => {
Ok((Some(commit_header), vec![])) Ok((Some(commit_header), vec![]))
} }
Err(e) => { Err(_e) => {
return Err(ObjectParseError::InvalidHeader); return Err(ObjectParseError::InvalidHeader);
} }
_ => { _ => {
@ -582,7 +581,7 @@ impl Object {
let root_id = self.id(); let root_id = self.id();
let mut blocks = vec![root_id]; let mut blocks = vec![root_id];
deduplicated.remove(&root_id); deduplicated.remove(&root_id);
let mut list = deduplicated.drain(); let list = deduplicated.drain();
blocks.append(&mut list.collect()); blocks.append(&mut list.collect());
deduplicated.shrink_to(0); deduplicated.shrink_to(0);
Ok(blocks) Ok(blocks)
@ -758,8 +757,8 @@ impl Object {
let content: ChunkContentV0; let content: ChunkContentV0;
match serde_bare::from_slice(content_dec.as_slice()) { match serde_bare::from_slice(content_dec.as_slice()) {
Ok(c) => content = c, Ok(c) => content = c,
Err(e) => { Err(_e) => {
log_debug!("Block deserialize error: {}", e); //log_debug!("Block deserialize error: {}", e);
return Err(ObjectParseError::BlockDeserializeError); return Err(ObjectParseError::BlockDeserializeError);
} }
} }
@ -850,8 +849,8 @@ impl Object {
) { ) {
Ok(_) => match serde_bare::from_slice(obj_content.as_slice()) { Ok(_) => match serde_bare::from_slice(obj_content.as_slice()) {
Ok(c) => Ok(c), Ok(c) => Ok(c),
Err(e) => { Err(_e) => {
log_debug!("Object deserialize error: {}", e); //log_debug!("Object deserialize error: {}", e);
Err(ObjectParseError::ObjectDeserializeError) Err(ObjectParseError::ObjectDeserializeError)
} }
}, },
@ -899,7 +898,7 @@ impl IObject for Object {
let root_id = self.id(); let root_id = self.id();
let mut blocks = vec![root_id]; let mut blocks = vec![root_id];
deduplicated.remove(&root_id); deduplicated.remove(&root_id);
let mut list = deduplicated.drain(); let list = deduplicated.drain();
blocks.append(&mut list.collect()); blocks.append(&mut list.collect());
deduplicated.shrink_to(0); deduplicated.shrink_to(0);
blocks blocks
@ -984,14 +983,14 @@ impl fmt::Display for ObjectContent {
ObjectContentV0::Commit(c) => ("Commit", format!("{}", c)), ObjectContentV0::Commit(c) => ("Commit", format!("{}", c)),
ObjectContentV0::CommitBody(c) => ("CommitBody", format!("{}", c)), ObjectContentV0::CommitBody(c) => ("CommitBody", format!("{}", c)),
ObjectContentV0::CommitHeader(c) => ("CommitHeader", format!("{}", c)), ObjectContentV0::CommitHeader(c) => ("CommitHeader", format!("{}", c)),
ObjectContentV0::Quorum(c) => ("Quorum", format!("{}", "")), ObjectContentV0::Quorum(_c) => ("Quorum", format!("{}", "")),
ObjectContentV0::Signature(c) => ("Signature", format!("{}", "")), ObjectContentV0::Signature(_c) => ("Signature", format!("{}", "")),
ObjectContentV0::Certificate(c) => ("Certificate", format!("{}", "")), ObjectContentV0::Certificate(_c) => ("Certificate", format!("{}", "")),
ObjectContentV0::SmallFile(c) => ("SmallFile", format!("{}", "")), ObjectContentV0::SmallFile(_c) => ("SmallFile", format!("{}", "")),
ObjectContentV0::RandomAccessFileMeta(c) => { ObjectContentV0::RandomAccessFileMeta(_c) => {
("RandomAccessFileMeta", format!("{}", "")) ("RandomAccessFileMeta", format!("{}", ""))
} }
ObjectContentV0::RefreshCap(c) => ("RefreshCap", format!("{}", "")), ObjectContentV0::RefreshCap(_c) => ("RefreshCap", format!("{}", "")),
}, },
), ),
}; };

@ -1,5 +1,14 @@
// Copyright (c) 2022-2024 Niko Bonnieure, Par le Peuple, NextGraph.org developers
// All rights reserved.
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
// or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use os_info; use os_info;
use serde_json::{json, to_string_pretty, Value}; use serde_json::{json, Value};
pub fn get_os_info() -> Value { pub fn get_os_info() -> Value {
let arch = std::env::consts::ARCH; let arch = std::env::consts::ARCH;

@ -9,21 +9,17 @@
//! Repository //! Repository
use crate::block_storage::*;
use crate::errors::*;
use crate::event::*;
use crate::log::*;
use crate::object::Object;
use crate::store::Store;
use crate::types::*;
use crate::utils::generate_keypair;
use crate::utils::sign;
use core::fmt; use core::fmt;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::sync::Arc; use std::sync::Arc;
use crate::errors::*;
#[allow(unused_imports)]
use crate::log::*;
use crate::store::Store;
use crate::types::*;
impl RepositoryV0 { impl RepositoryV0 {
pub fn new_with_meta(id: &PubKey, metadata: &Vec<u8>) -> RepositoryV0 { pub fn new_with_meta(id: &PubKey, metadata: &Vec<u8>) -> RepositoryV0 {
RepositoryV0 { RepositoryV0 {
@ -163,19 +159,24 @@ impl Repo {
Self::new_with_member(&pub_key, &pub_key, perms, OverlayId::dummy(), store) Self::new_with_member(&pub_key, &pub_key, perms, OverlayId::dummy(), store)
} }
pub fn update_branch_current_head( pub fn update_branch_current_heads(
&mut self, &mut self,
branch: &BranchId, branch: &BranchId,
commit_ref: ObjectRef, commit_ref: ObjectRef,
) -> Option<Vec<ObjectRef>> { past: Vec<ObjectRef>,
) -> Result<Vec<ObjectRef>, VerifierError> {
//log_info!("from branch {} HEAD UPDATED TO {}", branch, commit_ref.id); //log_info!("from branch {} HEAD UPDATED TO {}", branch, commit_ref.id);
if let Some(branch) = self.branches.get_mut(branch) { if let Some(branch) = self.branches.get_mut(branch) {
// FIXME: this is very wrong. the DAG is not always linear let mut set: HashSet<&ObjectRef> = HashSet::from_iter(branch.current_heads.iter());
branch.current_heads = vec![commit_ref]; for p in past {
set.remove(&p);
}
branch.current_heads = set.into_iter().cloned().collect();
branch.current_heads.push(commit_ref);
// we return the new current heads // we return the new current heads
Some(branch.current_heads.to_vec()) Ok(branch.current_heads.to_vec())
} else { } else {
None Err(VerifierError::BranchNotFound)
} }
} }

@ -12,20 +12,19 @@
//! Store of a Site, or of a Group or Dialog //! Store of a Site, or of a Group or Dialog
use core::fmt; use core::fmt;
use std::collections::{HashMap, HashSet}; use std::collections::HashMap;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use threshold_crypto::SecretKeySet;
use crate::block_storage::{BlockStorage, HashMapBlockStorage}; use crate::block_storage::{BlockStorage, HashMapBlockStorage};
use crate::errors::{NgError, StorageError}; use crate::errors::{NgError, StorageError};
#[allow(unused_imports)]
use crate::log::*;
use crate::object::Object; use crate::object::Object;
use crate::repo::{BranchInfo, Repo}; use crate::repo::{BranchInfo, Repo};
use crate::types::*; use crate::types::*;
use crate::utils::{generate_keypair, sign, verify}; use crate::utils::{generate_keypair, sign};
use crate::log::*;
use rand::prelude::*;
use threshold_crypto::{SecretKeySet, SecretKeyShare};
pub struct Store { pub struct Store {
//TODO: store_repo, store_readcap and store_overlay_branch_readcap could be empty, if we have only an outer access to the store. should be Options //TODO: store_repo, store_readcap and store_overlay_branch_readcap could be empty, if we have only an outer access to the store. should be Options
@ -140,7 +139,7 @@ impl Store {
} }
/// fetch a block from broker or core overlay /// fetch a block from broker or core overlay
pub async fn fetch(&self, id: &BlockId) -> Result<Block, StorageError> { pub async fn fetch(&self, _id: &BlockId) -> Result<Block, StorageError> {
todo!(); todo!();
} }
@ -367,7 +366,7 @@ impl Store {
// creating the main branch // creating the main branch
let (main_branch_commit, main_add_branch_commit, mut main_branch_info) = let (main_branch_commit, main_add_branch_commit, main_branch_info) =
self.as_ref().create_branch( self.as_ref().create_branch(
BranchType::Main, BranchType::Main,
creator, creator,

@ -11,19 +11,20 @@
//! //!
//! Corresponds to the BARE schema //! Corresponds to the BARE schema
use core::fmt;
use std::hash::Hash;
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use threshold_crypto::serde_impl::SerdeSecret;
use zeroize::{Zeroize, ZeroizeOnDrop};
use crate::errors::NgError; use crate::errors::NgError;
use crate::store::Store;
use crate::utils::{ use crate::utils::{
decode_key, decode_priv_key, dh_pubkey_array_from_ed_pubkey_slice, decode_key, decode_priv_key, dh_pubkey_array_from_ed_pubkey_slice,
dh_pubkey_from_ed_pubkey_slice, ed_privkey_to_ed_pubkey, from_ed_privkey_to_dh_privkey, dh_pubkey_from_ed_pubkey_slice, ed_privkey_to_ed_pubkey, from_ed_privkey_to_dh_privkey,
random_key, random_key,
}; };
use core::fmt;
use once_cell::sync::OnceCell;
use serde::{Deserialize, Serialize};
use std::hash::Hash;
use threshold_crypto::serde_impl::SerdeSecret;
use zeroize::{Zeroize, ZeroizeOnDrop};
// //
// COMMON TYPES // COMMON TYPES
@ -770,10 +771,10 @@ impl StoreRepo {
pub fn overlay_id_for_storage_purpose(&self) -> OverlayId { pub fn overlay_id_for_storage_purpose(&self) -> OverlayId {
match self { match self {
Self::V0(StoreRepoV0::PublicStore(id)) Self::V0(StoreRepoV0::PublicStore(_id))
| Self::V0(StoreRepoV0::ProtectedStore(id)) | Self::V0(StoreRepoV0::ProtectedStore(_id))
| Self::V0(StoreRepoV0::Group(id)) | Self::V0(StoreRepoV0::Group(_id))
| Self::V0(StoreRepoV0::PrivateStore(id)) => self.overlay_id_for_read_purpose(), | Self::V0(StoreRepoV0::PrivateStore(_id)) => self.overlay_id_for_read_purpose(),
Self::V0(StoreRepoV0::Dialog(d)) => OverlayId::Inner(d.1.clone()), Self::V0(StoreRepoV0::Dialog(d)) => OverlayId::Inner(d.1.clone()),
} }
} }

@ -7,10 +7,6 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use crate::errors::*;
use crate::log::*;
use crate::types::*;
use chacha20::cipher::{KeyIvInit, StreamCipher}; use chacha20::cipher::{KeyIvInit, StreamCipher};
use chacha20::ChaCha20; use chacha20::ChaCha20;
use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint}; use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
@ -18,10 +14,16 @@ use ed25519_dalek::*;
use futures::channel::mpsc; use futures::channel::mpsc;
use rand::rngs::OsRng; use rand::rngs::OsRng;
use rand::RngCore; use rand::RngCore;
#[cfg(not(target_arch = "wasm32"))]
use time::OffsetDateTime; use time::OffsetDateTime;
use web_time::{Duration, SystemTime, UNIX_EPOCH}; use web_time::{Duration, SystemTime, UNIX_EPOCH};
use zeroize::Zeroize; use zeroize::Zeroize;
use crate::errors::*;
#[allow(unused_imports)]
use crate::log::*;
use crate::types::*;
pub fn derive_key(context: &str, key_material: &[u8]) -> [u8; 32] { pub fn derive_key(context: &str, key_material: &[u8]) -> [u8; 32] {
blake3::derive_key(context, key_material) blake3::derive_key(context, key_material)
} }

@ -1,6 +1,6 @@
# ng-sdk-js # ng-sdk-js
JS/WASM crate containing the SDK of NextGraph JS/WASM package containing the SDK of NextGraph
## NextGraph ## NextGraph

@ -9,43 +9,41 @@
* according to those terms. * according to those terms.
*/ */
use async_std::task; use std::collections::HashMap;
use std::net::IpAddr;
use std::str::FromStr;
use std::sync::Arc;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};
#[allow(unused_imports)]
use serde_json::json;
// #[cfg(target_arch = "wasm32")] // #[cfg(target_arch = "wasm32")]
// use js_sys::Reflect; // use js_sys::Reflect;
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use js_sys::Uint8Array; use wasm_bindgen_futures::JsFuture;
#[cfg(target_arch = "wasm32")]
use ng_client_ws::remote_ws_wasm::ConnectionWebSocket; use ng_repo::errors::NgError;
use ng_repo::log::*;
use ng_repo::types::*;
use ng_net::broker::*; use ng_net::broker::*;
use ng_net::connection::{ClientConfig, StartConfig}; use ng_net::types::{ClientInfo, ClientInfoV0, ClientType, CreateAccountBSP, IP};
use ng_net::types::{ use ng_net::utils::{decode_invitation_string, spawn_and_log_error, Receiver, ResultSend};
BootstrapContent, BootstrapContentV0, ClientId, ClientInfo, ClientInfoV0, ClientType,
CreateAccountBSP, IP,
};
use ng_net::utils::{decode_invitation_string, spawn_and_log_error, Receiver, ResultSend, Sender};
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
use ng_net::utils::{retrieve_local_bootstrap, retrieve_local_url}; use ng_net::utils::{retrieve_local_bootstrap, retrieve_local_url};
use ng_net::WS_PORT;
#[cfg(target_arch = "wasm32")]
use ng_client_ws::remote_ws_wasm::ConnectionWebSocket;
use ng_wallet::types::*; use ng_wallet::types::*;
use ng_wallet::*; use ng_wallet::*;
use nextgraph::local_broker::*; use nextgraph::local_broker::*;
use nextgraph::verifier::types::*; use nextgraph::verifier::types::*;
use ng_net::WS_PORT;
use ng_repo::errors::NgError;
use ng_repo::log::*;
use ng_repo::types::*;
use ng_repo::utils::generate_keypair;
use serde::{Deserialize, Serialize};
use serde_json::json;
use std::collections::HashMap;
use std::net::IpAddr;
use std::str::FromStr;
use std::sync::Arc;
use wasm_bindgen::prelude::*;
#[cfg(target_arch = "wasm32")]
use wasm_bindgen_futures::{future_to_promise, JsFuture};
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[wasm_bindgen] #[wasm_bindgen]
@ -124,7 +122,7 @@ pub fn wallet_open_with_pazzle(
) -> Result<JsValue, JsValue> { ) -> Result<JsValue, JsValue> {
let encrypted_wallet = serde_wasm_bindgen::from_value::<Wallet>(js_wallet) let encrypted_wallet = serde_wasm_bindgen::from_value::<Wallet>(js_wallet)
.map_err(|_| "Deserialization error of wallet")?; .map_err(|_| "Deserialization error of wallet")?;
let mut pin = serde_wasm_bindgen::from_value::<[u8; 4]>(js_pin) let pin = serde_wasm_bindgen::from_value::<[u8; 4]>(js_pin)
.map_err(|_| "Deserialization error of pin")?; .map_err(|_| "Deserialization error of pin")?;
let res = nextgraph::local_broker::wallet_open_with_pazzle(&encrypted_wallet, pazzle, pin); let res = nextgraph::local_broker::wallet_open_with_pazzle(&encrypted_wallet, pazzle, pin);
match res { match res {
@ -138,9 +136,9 @@ pub fn wallet_open_with_pazzle(
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[wasm_bindgen] #[wasm_bindgen]
pub fn wallet_update(js_wallet_id: JsValue, js_operations: JsValue) -> Result<JsValue, JsValue> { pub fn wallet_update(js_wallet_id: JsValue, js_operations: JsValue) -> Result<JsValue, JsValue> {
let wallet = serde_wasm_bindgen::from_value::<WalletId>(js_wallet_id) let _wallet = serde_wasm_bindgen::from_value::<WalletId>(js_wallet_id)
.map_err(|_| "Deserialization error of WalletId")?; .map_err(|_| "Deserialization error of WalletId")?;
let operations = serde_wasm_bindgen::from_value::<Vec<WalletOperation>>(js_operations) let _operations = serde_wasm_bindgen::from_value::<Vec<WalletOperation>>(js_operations)
.map_err(|_| "Deserialization error of operations")?; .map_err(|_| "Deserialization error of operations")?;
unimplemented!(); unimplemented!();
// match res { // match res {
@ -326,7 +324,7 @@ pub async fn wallet_get_file(wallet_name: String) -> Result<JsValue, JsValue> {
#[wasm_bindgen] #[wasm_bindgen]
pub async fn wallet_read_file(js_file: JsValue) -> Result<JsValue, String> { pub async fn wallet_read_file(js_file: JsValue) -> Result<JsValue, String> {
init_local_broker_with_lazy(&INIT_LOCAL_BROKER).await; init_local_broker_with_lazy(&INIT_LOCAL_BROKER).await;
let mut file = serde_wasm_bindgen::from_value::<serde_bytes::ByteBuf>(js_file) let file = serde_wasm_bindgen::from_value::<serde_bytes::ByteBuf>(js_file)
.map_err(|_| "Deserialization error of file".to_string())?; .map_err(|_| "Deserialization error of file".to_string())?;
let wallet = nextgraph::local_broker::wallet_read_file(file.into_vec()) let wallet = nextgraph::local_broker::wallet_read_file(file.into_vec())
@ -341,7 +339,7 @@ pub async fn wallet_read_file(js_file: JsValue) -> Result<JsValue, String> {
pub async fn wallet_was_opened( pub async fn wallet_was_opened(
js_opened_wallet: JsValue, //SensitiveWallet js_opened_wallet: JsValue, //SensitiveWallet
) -> Result<JsValue, String> { ) -> Result<JsValue, String> {
let mut opened_wallet = serde_wasm_bindgen::from_value::<SensitiveWallet>(js_opened_wallet) let opened_wallet = serde_wasm_bindgen::from_value::<SensitiveWallet>(js_opened_wallet)
.map_err(|_| "Deserialization error of SensitiveWallet".to_string())?; .map_err(|_| "Deserialization error of SensitiveWallet".to_string())?;
let client = nextgraph::local_broker::wallet_was_opened(opened_wallet) let client = nextgraph::local_broker::wallet_was_opened(opened_wallet)
@ -360,7 +358,7 @@ pub async fn wallet_import(
) -> Result<JsValue, String> { ) -> Result<JsValue, String> {
let encrypted_wallet = serde_wasm_bindgen::from_value::<Wallet>(js_encrypted_wallet) let encrypted_wallet = serde_wasm_bindgen::from_value::<Wallet>(js_encrypted_wallet)
.map_err(|_| "Deserialization error of Wallet".to_string())?; .map_err(|_| "Deserialization error of Wallet".to_string())?;
let mut opened_wallet = serde_wasm_bindgen::from_value::<SensitiveWallet>(js_opened_wallet) let opened_wallet = serde_wasm_bindgen::from_value::<SensitiveWallet>(js_opened_wallet)
.map_err(|_| "Deserialization error of SensitiveWallet".to_string())?; .map_err(|_| "Deserialization error of SensitiveWallet".to_string())?;
let client = nextgraph::local_broker::wallet_import(encrypted_wallet, opened_wallet, in_memory) let client = nextgraph::local_broker::wallet_import(encrypted_wallet, opened_wallet, in_memory)
@ -370,24 +368,6 @@ pub async fn wallet_import(
Ok(serde_wasm_bindgen::to_value(&client).unwrap()) Ok(serde_wasm_bindgen::to_value(&client).unwrap())
} }
#[cfg(target_arch = "wasm32")]
#[wasm_bindgen]
pub fn test_create_wallet() -> JsValue {
let pin = [5, 2, 9, 1];
let r = CreateWalletV0::new(
vec![50u8; 20],
" know yourself ".to_string(),
pin,
9,
false,
false,
BootstrapContentV0::new_empty(),
None,
None,
);
serde_wasm_bindgen::to_value(&r).unwrap()
}
#[cfg(wasmpack_target = "nodejs")] #[cfg(wasmpack_target = "nodejs")]
#[wasm_bindgen(module = "/js/node.js")] #[wasm_bindgen(module = "/js/node.js")]
extern "C" { extern "C" {
@ -484,6 +464,7 @@ pub fn client_info() -> JsValue {
pub async fn test() { pub async fn test() {
init_local_broker_with_lazy(&INIT_LOCAL_BROKER).await; init_local_broker_with_lazy(&INIT_LOCAL_BROKER).await;
//log_debug!("test is {}", BROKER.read().await.test()); //log_debug!("test is {}", BROKER.read().await.test());
#[cfg(debug_assertions)]
let client_info = client_info(); let client_info = client_info();
log_debug!("{:?}", client_info); log_debug!("{:?}", client_info);
} }
@ -498,36 +479,26 @@ pub async fn app_request_stream(
let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(js_session_id) let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(js_session_id)
.map_err(|_| "Deserialization error of session_id".to_string())?; .map_err(|_| "Deserialization error of session_id".to_string())?;
let mut request = serde_wasm_bindgen::from_value::<AppRequest>(js_request) let request = serde_wasm_bindgen::from_value::<AppRequest>(js_request)
.map_err(|_| "Deserialization error of AppRequest".to_string())?; .map_err(|_| "Deserialization error of AppRequest".to_string())?;
let vec: Vec<u8> = vec![2; 10]; let (reader, cancel) = nextgraph::local_broker::app_request_stream(session_id, request)
let view = unsafe { Uint8Array::view(&vec) };
let x = JsValue::from(Uint8Array::new(view.as_ref()));
let mut reader;
let mut cancel;
{
(reader, cancel) = nextgraph::local_broker::app_request_stream(session_id, request)
.await .await
.map_err(|e: NgError| e.to_string())?; .map_err(|e: NgError| e.to_string())?;
}
async fn inner_task( async fn inner_task(
mut reader: Receiver<AppResponse>, mut reader: Receiver<AppResponse>,
callback: js_sys::Function, callback: js_sys::Function,
) -> ResultSend<()> { ) -> ResultSend<()> {
while let Some(app_response) = reader.next().await { while let Some(app_response) = reader.next().await {
let xx = serde_wasm_bindgen::to_value(&app_response).unwrap(); let response_js = serde_wasm_bindgen::to_value(&app_response).unwrap();
//let xx = JsValue::from(json!(commit).to_string());
//let _ = callback.call1(&this, &xx);
let this = JsValue::null(); let this = JsValue::null();
match callback.call1(&this, &xx) { match callback.call1(&this, &response_js) {
Ok(jsval) => { Ok(jsval) => {
let promise_res: Result<js_sys::Promise, JsValue> = jsval.dyn_into(); let promise_res: Result<js_sys::Promise, JsValue> = jsval.dyn_into();
match promise_res { match promise_res {
Ok(promise) => { Ok(promise) => {
JsFuture::from(promise).await; let _ = JsFuture::from(promise).await;
} }
Err(_) => {} Err(_) => {}
} }
@ -559,7 +530,7 @@ pub async fn app_request_stream(
pub async fn app_request(js_session_id: JsValue, js_request: JsValue) -> Result<JsValue, String> { pub async fn app_request(js_session_id: JsValue, js_request: JsValue) -> Result<JsValue, String> {
let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(js_session_id) let session_id: u64 = serde_wasm_bindgen::from_value::<u64>(js_session_id)
.map_err(|_| "Deserialization error of session_id".to_string())?; .map_err(|_| "Deserialization error of session_id".to_string())?;
let mut request = serde_wasm_bindgen::from_value::<AppRequest>(js_request) let request = serde_wasm_bindgen::from_value::<AppRequest>(js_request)
.map_err(|_| "Deserialization error of AppRequest".to_string())?; .map_err(|_| "Deserialization error of AppRequest".to_string())?;
let response = nextgraph::local_broker::app_request(session_id, request) let response = nextgraph::local_broker::app_request(session_id, request)
@ -625,28 +596,24 @@ pub async fn doc_fetch_private_subscribe() -> Result<JsValue, String> {
#[wasm_bindgen] #[wasm_bindgen]
pub async fn disconnections_subscribe(callback: &js_sys::Function) -> Result<JsValue, JsValue> { pub async fn disconnections_subscribe(callback: &js_sys::Function) -> Result<JsValue, JsValue> {
init_local_broker_with_lazy(&INIT_LOCAL_BROKER).await; init_local_broker_with_lazy(&INIT_LOCAL_BROKER).await;
let vec: Vec<u8> = vec![2; 10];
let view = unsafe { Uint8Array::view(&vec) }; let reader = nextgraph::local_broker::take_disconnections_receiver()
let x = JsValue::from(Uint8Array::new(view.as_ref()));
let mut reader;
{
reader = nextgraph::local_broker::take_disconnections_receiver()
.await .await
.map_err(|e: NgError| false)?; .map_err(|_e: NgError| false)?;
}
async fn inner_task( async fn inner_task(
mut reader: Receiver<String>, mut reader: Receiver<String>,
callback: js_sys::Function, callback: js_sys::Function,
) -> ResultSend<()> { ) -> ResultSend<()> {
while let Some(user_id) = reader.next().await { while let Some(user_id) = reader.next().await {
let this = JsValue::null(); let this = JsValue::null();
let xx = serde_wasm_bindgen::to_value(&user_id).unwrap(); let user_id_js = serde_wasm_bindgen::to_value(&user_id).unwrap();
match callback.call1(&this, &xx) { match callback.call1(&this, &user_id_js) {
Ok(jsval) => { Ok(jsval) => {
let promise_res: Result<js_sys::Promise, JsValue> = jsval.dyn_into(); let promise_res: Result<js_sys::Promise, JsValue> = jsval.dyn_into();
match promise_res { match promise_res {
Ok(promise) => { Ok(promise) => {
JsFuture::from(promise).await; let _ = JsFuture::from(promise).await;
} }
Err(_) => {} Err(_) => {}
} }
@ -670,7 +637,7 @@ pub async fn disconnections_subscribe(callback: &js_sys::Function) -> Result<JsV
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[wasm_bindgen] #[wasm_bindgen]
pub async fn probe() { pub async fn probe() {
let res = BROKER let _res = BROKER
.write() .write()
.await .await
.probe( .probe(
@ -679,75 +646,15 @@ pub async fn probe() {
WS_PORT, WS_PORT,
) )
.await; .await;
log_debug!("broker.probe : {:?}", res); log_debug!("broker.probe : {:?}", _res);
Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(5)).await; let _ = Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(5)).await;
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[wasm_bindgen] #[wasm_bindgen]
pub async fn start() { pub async fn start() {
async fn inner_task() -> ResultSend<()> { async fn inner_task() -> ResultSend<()> {
let server_key: PubKey = "X0nh-gOTGKSx0yL0LYJviOWRNacyqIzjQW_LKdK6opU".try_into()?;
log_debug!("server_key:{}", server_key);
//let keys = ng_net::utils::gen_dh_keys();
//let pub_key = PubKey::Ed25519PubKey(keys.1);
let keys = generate_keypair();
let x_from_ed = keys.1.to_dh_from_ed();
log_debug!("Pub from X {}", x_from_ed);
let (client_priv, client) = generate_keypair();
let (user_priv, user) = generate_keypair();
log_debug!("start connecting");
let res = BROKER
.write()
.await
.connect(
Arc::new(Box::new(ConnectionWebSocket {})),
keys.0,
keys.1,
server_key,
StartConfig::Client(ClientConfig {
url: format!("ws://127.0.0.1:{}", WS_PORT),
name: None,
user_priv,
client_priv,
info: ClientInfo::V0(client_info_()),
registration: None,
}),
)
.await;
log_debug!("broker.connect : {:?}", res);
if res.is_err() {
return Ok(());
//panic!("Cannot connect");
}
BROKER.read().await.print_status();
//res.expect_throw("assume the connection succeeds");
async fn timer_close(remote_peer_id: DirectPeerId, user: Option<PubKey>) -> ResultSend<()> {
async move {
sleep!(std::time::Duration::from_secs(3));
log_debug!("timeout");
BROKER
.write()
.await
.close_peer_connection(&remote_peer_id, user)
.await;
}
.await;
Ok(())
}
spawn_and_log_error(timer_close(server_key, Some(user)));
//Broker::graceful_shutdown().await;
Broker::join_shutdown_with_timeout(std::time::Duration::from_secs(5)).await;
Ok(()) Ok(())
} }
spawn_and_log_error(inner_task()).await; spawn_and_log_error(inner_task()).await;
@ -813,7 +720,7 @@ pub async fn user_connect(
log_debug!("{:?}", results); log_debug!("{:?}", results);
for result in results { for result in results {
let mut date = js_sys::Date::new_0(); let date = js_sys::Date::new_0();
date.set_time(result.4); date.set_time(result.4);
opened_connections.insert( opened_connections.insert(
result.0, result.0,

@ -7,26 +7,21 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use ng_repo::block_storage::BlockStorage;
use ng_repo::errors::StorageError;
use ng_repo::types::*;
use ng_repo::utils::*;
use ng_repo::log::*;
use rocksdb::BlockBasedOptions;
use rocksdb::DBCompressionType;
use std::path::Path; use std::path::Path;
use std::sync::{Arc, RwLock};
use std::thread::available_parallelism; use std::thread::available_parallelism;
use serde::{Deserialize, Serialize}; #[allow(unused_imports)]
use serde_bare::error::Error;
use rocksdb::{ use rocksdb::{
ColumnFamily, ColumnFamilyDescriptor, Direction, Env, ErrorKind, IteratorMode, Options, BlockBasedOptions, ColumnFamily, ColumnFamilyDescriptor, DBCompressionType, Direction, Env,
SingleThreaded, TransactionDB, TransactionDBOptions, DB, ErrorKind, IteratorMode, Options, TransactionDB, TransactionDBOptions,
}; };
use ng_repo::block_storage::BlockStorage;
use ng_repo::errors::StorageError;
use ng_repo::log::*;
use ng_repo::types::*;
#[allow(dead_code)]
pub struct RocksDbBlockStorage { pub struct RocksDbBlockStorage {
/// the main store where all the properties of keys are stored /// the main store where all the properties of keys are stored
db: TransactionDB, db: TransactionDB,
@ -133,7 +128,7 @@ impl BlockStorage for RocksDbBlockStorage {
let ser = serde_bare::to_vec(block)?; let ser = serde_bare::to_vec(block)?;
let tx = self.db.transaction(); let tx = self.db.transaction();
let key = Self::compute_key(overlay, &block_id); let key = Self::compute_key(overlay, &block_id);
if (lazy) { if lazy {
if let Some(block_ser) = tx if let Some(block_ser) = tx
.get(key.clone()) .get(key.clone())
.map_err(|_e| StorageError::BackendError)? .map_err(|_e| StorageError::BackendError)?

@ -7,22 +7,23 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use ng_repo::kcv_storage::*; use std::collections::HashMap;
use std::path::Path;
use std::path::PathBuf;
use std::thread::available_parallelism;
use ng_repo::errors::*;
use ng_repo::log::*;
use rocksdb::BlockBasedOptions; use rocksdb::BlockBasedOptions;
use rocksdb::Cache; use rocksdb::Cache;
use rocksdb::DBIteratorWithThreadMode; use rocksdb::DBIteratorWithThreadMode;
use std::collections::HashMap; use ng_repo::errors::*;
use std::path::Path; use ng_repo::kcv_storage::*;
use std::path::PathBuf; use ng_repo::log::*;
use std::thread::available_parallelism;
#[allow(unused_imports)]
use rocksdb::{ use rocksdb::{
ColumnFamily, ColumnFamilyDescriptor, Direction, Env, ErrorKind, IteratorMode, Options, ColumnFamily, ColumnFamilyDescriptor, Direction, Env, ErrorKind, IteratorMode, Options,
SingleThreaded, TransactionDB, TransactionDBOptions, DB, TransactionDB, TransactionDBOptions,
}; };
pub struct RocksdbTransaction<'a> { pub struct RocksdbTransaction<'a> {
@ -119,10 +120,10 @@ impl<'a> ReadTransaction for RocksdbTransaction<'a> {
/// Load all the values of a property from the store. /// Load all the values of a property from the store.
fn get_all( fn get_all(
&self, &self,
prefix: u8, _prefix: u8,
key: &Vec<u8>, _key: &Vec<u8>,
suffix: Option<u8>, _suffix: Option<u8>,
family: &Option<String>, _family: &Option<String>,
) -> Result<Vec<Vec<u8>>, StorageError> { ) -> Result<Vec<Vec<u8>>, StorageError> {
unimplemented!(); unimplemented!();
} }
@ -387,10 +388,10 @@ impl ReadTransaction for RocksDbKCVStorage {
/// Load all the values of a property from the store. /// Load all the values of a property from the store.
fn get_all( fn get_all(
&self, &self,
prefix: u8, _prefix: u8,
key: &Vec<u8>, _key: &Vec<u8>,
suffix: Option<u8>, _suffix: Option<u8>,
family: &Option<String>, _family: &Option<String>,
) -> Result<Vec<Vec<u8>>, StorageError> { ) -> Result<Vec<Vec<u8>>, StorageError> {
unimplemented!(); unimplemented!();
} }

@ -9,16 +9,19 @@
//! Verifiers for each Commit type //! Verifiers for each Commit type
use crate::types::*; use std::collections::HashMap;
use crate::verifier::Verifier; use std::sync::Arc;
use ng_repo::errors::VerifierError; use ng_repo::errors::VerifierError;
#[allow(unused_imports)]
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::object::Object; use ng_repo::object::Object;
use ng_repo::repo::{BranchInfo, Repo}; use ng_repo::repo::{BranchInfo, Repo};
use ng_repo::store::Store; use ng_repo::store::Store;
use ng_repo::types::*; use ng_repo::types::*;
use std::collections::HashMap;
use std::sync::Arc; use crate::types::*;
use crate::verifier::Verifier;
#[async_trait::async_trait] #[async_trait::async_trait]
pub trait CommitVerifier { pub trait CommitVerifier {
@ -63,8 +66,8 @@ impl CommitVerifier for RootBranch {
&self, &self,
commit: &Commit, commit: &Commit,
verifier: &mut Verifier, verifier: &mut Verifier,
branch_id: &BranchId, _branch_id: &BranchId,
repo_id: &RepoId, _repo_id: &RepoId,
store: Arc<Store>, store: Arc<Store>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
match self { match self {
@ -136,8 +139,8 @@ impl CommitVerifier for Branch {
&self, &self,
commit: &Commit, commit: &Commit,
verifier: &mut Verifier, verifier: &mut Verifier,
branch_id: &BranchId, _branch_id: &BranchId,
repo_id: &RepoId, _repo_id: &RepoId,
store: Arc<Store>, store: Arc<Store>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
match self { match self {
@ -199,7 +202,7 @@ impl CommitVerifier for SyncSignature {
SyncSignature::V0(signature_ref) => { SyncSignature::V0(signature_ref) => {
let sign = Object::load_ref(signature_ref, &store)?; let sign = Object::load_ref(signature_ref, &store)?;
match sign.content_v0()? { match sign.content_v0()? {
ObjectContentV0::Signature(sig) => { ObjectContentV0::Signature(_sig) => {
//TODO: verify signature //TODO: verify signature
} }
_ => return Err(VerifierError::InvalidSignatureObject), _ => return Err(VerifierError::InvalidSignatureObject),
@ -231,8 +234,8 @@ impl CommitVerifier for AddBranch {
&self, &self,
commit: &Commit, commit: &Commit,
verifier: &mut Verifier, verifier: &mut Verifier,
branch_id: &BranchId, _branch_id: &BranchId,
repo_id: &RepoId, _repo_id: &RepoId,
store: Arc<Store>, store: Arc<Store>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
match self { match self {
@ -240,10 +243,6 @@ impl CommitVerifier for AddBranch {
if v0.branch_type == BranchType::Root { if v0.branch_type == BranchType::Root {
return Err(VerifierError::InvalidBranch); return Err(VerifierError::InvalidBranch);
} }
// let _ = verifier.topics.insert(
// (store.inner_overlay(), v0.topic_id),
// (*commit.branch(), v0.branch_id),
// );
let branch_info = BranchInfo { let branch_info = BranchInfo {
id: v0.branch_id, id: v0.branch_id,
@ -268,11 +267,11 @@ impl CommitVerifier for AddBranch {
impl CommitVerifier for Repository { impl CommitVerifier for Repository {
async fn verify( async fn verify(
&self, &self,
commit: &Commit, _commit: &Commit,
verifier: &mut Verifier, _verifier: &mut Verifier,
branch_id: &BranchId, _branch_id: &BranchId,
repo_id: &RepoId, _repo_id: &RepoId,
store: Arc<Store>, _store: Arc<Store>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
// left empty intentionally // left empty intentionally
Ok(()) Ok(())
@ -282,11 +281,11 @@ impl CommitVerifier for Repository {
impl CommitVerifier for StoreUpdate { impl CommitVerifier for StoreUpdate {
async fn verify( async fn verify(
&self, &self,
commit: &Commit, _commit: &Commit,
verifier: &mut Verifier, verifier: &mut Verifier,
branch_id: &BranchId, _branch_id: &BranchId,
repo_id: &RepoId, _repo_id: &RepoId,
store: Arc<Store>, _store: Arc<Store>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
verifier.new_store_from_update(self) verifier.new_store_from_update(self)
} }
@ -295,11 +294,11 @@ impl CommitVerifier for StoreUpdate {
impl CommitVerifier for AddSignerCap { impl CommitVerifier for AddSignerCap {
async fn verify( async fn verify(
&self, &self,
commit: &Commit, _commit: &Commit,
verifier: &mut Verifier, verifier: &mut Verifier,
branch_id: &BranchId, _branch_id: &BranchId,
repo_id: &RepoId, _repo_id: &RepoId,
store: Arc<Store>, _store: Arc<Store>,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
match self { match self {
AddSignerCap::V0(v0) => verifier.update_signer_cap(&v0.cap), AddSignerCap::V0(v0) => verifier.update_signer_cap(&v0.cap),
@ -308,6 +307,7 @@ impl CommitVerifier for AddSignerCap {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AddMember { impl CommitVerifier for AddMember {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -321,6 +321,7 @@ impl CommitVerifier for AddMember {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveMember { impl CommitVerifier for RemoveMember {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -334,6 +335,7 @@ impl CommitVerifier for RemoveMember {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AddPermission { impl CommitVerifier for AddPermission {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -347,6 +349,7 @@ impl CommitVerifier for AddPermission {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemovePermission { impl CommitVerifier for RemovePermission {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -360,6 +363,7 @@ impl CommitVerifier for RemovePermission {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveBranch { impl CommitVerifier for RemoveBranch {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -373,6 +377,7 @@ impl CommitVerifier for RemoveBranch {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AddName { impl CommitVerifier for AddName {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -386,6 +391,7 @@ impl CommitVerifier for AddName {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveName { impl CommitVerifier for RemoveName {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -399,6 +405,7 @@ impl CommitVerifier for RemoveName {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for () { impl CommitVerifier for () {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -412,6 +419,7 @@ impl CommitVerifier for () {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for Snapshot { impl CommitVerifier for Snapshot {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -425,6 +433,7 @@ impl CommitVerifier for Snapshot {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AddFile { impl CommitVerifier for AddFile {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -459,6 +468,7 @@ impl CommitVerifier for AddFile {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveFile { impl CommitVerifier for RemoveFile {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -472,6 +482,7 @@ impl CommitVerifier for RemoveFile {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for Compact { impl CommitVerifier for Compact {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -485,6 +496,7 @@ impl CommitVerifier for Compact {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AsyncSignature { impl CommitVerifier for AsyncSignature {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -498,6 +510,7 @@ impl CommitVerifier for AsyncSignature {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RootCapRefresh { impl CommitVerifier for RootCapRefresh {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -511,6 +524,7 @@ impl CommitVerifier for RootCapRefresh {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for BranchCapRefresh { impl CommitVerifier for BranchCapRefresh {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -524,6 +538,7 @@ impl CommitVerifier for BranchCapRefresh {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AddRepo { impl CommitVerifier for AddRepo {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -537,6 +552,7 @@ impl CommitVerifier for AddRepo {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveRepo { impl CommitVerifier for RemoveRepo {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -550,6 +566,7 @@ impl CommitVerifier for RemoveRepo {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for AddLink { impl CommitVerifier for AddLink {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -563,6 +580,7 @@ impl CommitVerifier for AddLink {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveLink { impl CommitVerifier for RemoveLink {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -576,6 +594,7 @@ impl CommitVerifier for RemoveLink {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for RemoveSignerCap { impl CommitVerifier for RemoveSignerCap {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,
@ -589,6 +608,7 @@ impl CommitVerifier for RemoveSignerCap {
} }
#[async_trait::async_trait] #[async_trait::async_trait]
impl CommitVerifier for WalletUpdate { impl CommitVerifier for WalletUpdate {
#[allow(unused_variables)]
async fn verify( async fn verify(
&self, &self,
commit: &Commit, commit: &Commit,

@ -9,32 +9,32 @@
//! Processor for each type of AppRequest //! Processor for each type of AppRequest
use std::sync::Arc;
use futures::channel::mpsc; use futures::channel::mpsc;
use futures::SinkExt; use futures::SinkExt;
use futures::StreamExt; use futures::StreamExt;
use ng_net::utils::ResultSend;
use std::sync::Arc;
use crate::types::*;
use crate::verifier::*;
use ng_net::utils::{spawn_and_log_error, Receiver, Sender};
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::file::{RandomAccessFile, ReadFile}; use ng_repo::file::{RandomAccessFile, ReadFile};
#[allow(unused_imports)]
use ng_repo::log::*;
use ng_repo::types::BranchId; use ng_repo::types::BranchId;
use ng_repo::types::StoreRepo;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::log::*; use ng_net::utils::ResultSend;
use ng_repo::types::StoreRepo; use ng_net::utils::{spawn_and_log_error, Receiver, Sender};
use crate::types::*;
use crate::verifier::*;
impl AppRequestCommandV0 { impl AppRequestCommandV0 {
pub(crate) async fn process_stream( pub(crate) async fn process_stream(
&self, &self,
verifier: &mut Verifier, verifier: &mut Verifier,
nuri: &NuriV0, nuri: &NuriV0,
payload: &Option<AppRequestPayload>, _payload: &Option<AppRequestPayload>,
) -> Result<(Receiver<AppResponse>, CancelFn), NgError> { ) -> Result<(Receiver<AppResponse>, CancelFn), NgError> {
match self { match self {
Self::Fetch(fetch) => match fetch { Self::Fetch(fetch) => match fetch {
@ -184,7 +184,9 @@ impl AppRequestCommandV0 {
) )
.await?; .await?;
} }
AppRequestPayloadV0::SmallFilePut(small) => {} AppRequestPayloadV0::SmallFilePut(_small) => {
unimplemented!();
}
AppRequestPayloadV0::RandomAccessFilePut(content_type) => { AppRequestPayloadV0::RandomAccessFilePut(content_type) => {
let (repo_id, _, store_repo) = let (repo_id, _, store_repo) =
Self::resolve_target(verifier, &nuri.target)?; Self::resolve_target(verifier, &nuri.target)?;

@ -9,24 +9,24 @@
//! RocksDb Backend for UserStorage trait //! RocksDb Backend for UserStorage trait
use crate::types::*; use std::collections::HashMap;
use crate::user_storage::branch::*; use std::path::PathBuf;
use crate::user_storage::repo::*; use std::sync::{Arc, RwLock};
use crate::user_storage::*;
use either::Either::{Left, Right}; use either::Either::{Left, Right};
use ng_repo::block_storage::BlockStorage; use ng_repo::block_storage::BlockStorage;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::repo::{BranchInfo, Repo}; use ng_repo::repo::{BranchInfo, Repo};
use ng_repo::store::Store; use ng_repo::store::Store;
use ng_repo::{errors::StorageError, types::*}; use ng_repo::{errors::StorageError, types::*};
use ng_storage_rocksdb::kcv_storage::RocksDbKCVStorage; use ng_storage_rocksdb::kcv_storage::RocksDbKCVStorage;
use std::path::PathBuf;
use std::sync::{Arc, RwLock}; use crate::types::*;
use std::{ use crate::user_storage::branch::*;
cmp::{max, min}, use crate::user_storage::repo::*;
collections::HashMap, use crate::user_storage::*;
mem::size_of_val,
};
pub(crate) struct RocksDbUserStorage { pub(crate) struct RocksDbUserStorage {
user_storage: RocksDbKCVStorage, user_storage: RocksDbKCVStorage,
@ -78,9 +78,9 @@ impl UserStorage for RocksDbUserStorage {
RepoStorage::update_signer_cap(signer_cap, &self.user_storage) RepoStorage::update_signer_cap(signer_cap, &self.user_storage)
} }
fn update_branch_current_head( fn update_branch_current_heads(
&self, &self,
repo_id: &RepoId, _repo_id: &RepoId,
branch_id: &BranchId, branch_id: &BranchId,
new_heads: Vec<ObjectRef>, new_heads: Vec<ObjectRef>,
) -> Result<(), StorageError> { ) -> Result<(), StorageError> {

@ -11,13 +11,13 @@
//! A Site of an Individual or Org (with 3P stores: Public, Protected, Private) //! A Site of an Individual or Org (with 3P stores: Public, Protected, Private)
use crate::types::*; use serde::{Deserialize, Serialize};
use crate::verifier::Verifier;
use ng_repo::errors::NgError; use ng_repo::errors::NgError;
use ng_repo::store::*;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::{generate_keypair, sign, verify}; use ng_repo::utils::generate_keypair;
use serde::{Deserialize, Serialize};
use crate::verifier::Verifier;
/// Site V0 /// Site V0
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
@ -183,7 +183,6 @@ impl SiteV0 {
let private_repo_id = private_repo.id; let private_repo_id = private_repo.id;
let private_store_repo = private_repo.store.get_store_repo().clone(); let private_store_repo = private_repo.store.get_store_repo().clone();
let private_repo_read_cap = private_repo.read_cap.to_owned().unwrap(); let private_repo_read_cap = private_repo.read_cap.to_owned().unwrap();
let user_branch_id = user_branch.id;
// Creating the AddSignerCap for each store // Creating the AddSignerCap for each store
let mut commits = Vec::with_capacity(5); let mut commits = Vec::with_capacity(5);
@ -254,13 +253,15 @@ impl SiteV0 {
} }
pub async fn create_org(name: String) -> Result<Self, NgError> { pub async fn create_org(name: String) -> Result<Self, NgError> {
let (site_privkey, site_pubkey) = generate_keypair(); // TODO: implement correctly. see create_personal/create_individual
let (public_store_privkey, public_store_pubkey) = generate_keypair(); let (_site_privkey, site_pubkey) = generate_keypair();
let (protected_store_privkey, protected_store_pubkey) = generate_keypair(); let (_public_store_privkey, public_store_pubkey) = generate_keypair();
let (private_store_privkey, private_store_pubkey) = generate_keypair(); let (_protected_store_privkey, protected_store_pubkey) = generate_keypair();
let (_private_store_privkey, private_store_pubkey) = generate_keypair();
let public = SiteStore { let public = SiteStore {
id: public_store_pubkey, id: public_store_pubkey,

@ -10,31 +10,18 @@
//! Types for Verifier //! Types for Verifier
use core::fmt; use core::fmt;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
//use oxigraph::io::{RdfFormat, RdfParser, RdfSerializer}; //use oxigraph::io::{RdfFormat, RdfParser, RdfSerializer};
//use oxigraph::store::Store; //use oxigraph::store::Store;
//use oxigraph::model::GroundQuad; //use oxigraph::model::GroundQuad;
#[cfg(not(target_family = "wasm"))]
use crate::rocksdb_user_storage::RocksDbUserStorage;
use crate::user_storage::UserStorage;
use async_std::sync::Mutex;
use std::{collections::HashMap, path::PathBuf, sync::Arc};
use ng_net::{
connection::NoiseFSM,
types::*,
utils::{Receiver, Sender},
};
use ng_repo::{
block_storage::BlockStorage,
errors::{NgError, ProtocolError, StorageError},
file::RandomAccessFile,
store::Store,
types::*,
};
use serde::{Deserialize, Serialize};
use web_time::SystemTime;
//use yrs::{StateVector, Update}; //use yrs::{StateVector, Update};
use ng_repo::{errors::NgError, types::*};
use ng_net::types::*;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub enum SessionPeerLastSeq { pub enum SessionPeerLastSeq {
V0(u64), V0(u64),
@ -132,6 +119,7 @@ impl VerifierConfigType {
} }
} }
#[allow(dead_code)]
pub(crate) fn is_in_memory(&self) -> bool { pub(crate) fn is_in_memory(&self) -> bool {
match self { match self {
Self::Memory | Self::JsSaveSession(_) => true, Self::Memory | Self::JsSaveSession(_) => true,
@ -245,8 +233,8 @@ impl NuriV0 {
locator: vec![], locator: vec![],
} }
} }
pub fn new(from: String) -> Self { pub fn new(_from: String) -> Self {
unimplemented!(); todo!();
} }
} }

@ -9,33 +9,14 @@
//! Branch Storage (Object Key/Col/Value Mapping) //! Branch Storage (Object Key/Col/Value Mapping)
use std::collections::hash_map::DefaultHasher; use serde_bare::from_slice;
use std::collections::HashMap; use serde_bare::to_vec;
use std::hash::Hash;
use std::hash::Hasher;
use std::time::SystemTime;
use ng_net::types::*;
use ng_repo::block_storage::BlockStorage;
use ng_repo::errors::ProtocolError;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::prop; use ng_repo::kcv_storage::prop;
use ng_repo::kcv_storage::KCVStorage; use ng_repo::kcv_storage::KCVStorage;
use ng_repo::repo::BranchInfo; use ng_repo::repo::BranchInfo;
use ng_repo::repo::Repo; use ng_repo::types::*;
use ng_repo::store::Store;
use ng_repo::types::BranchId;
use ng_repo::types::BranchType;
use ng_repo::types::BranchWriteCapSecret;
use ng_repo::types::ObjectId;
use ng_repo::types::ObjectRef;
use ng_repo::types::ReadCap;
use ng_repo::types::RepoId;
use ng_repo::types::SymKey;
use ng_repo::types::Timestamp;
use ng_repo::types::TopicId;
use serde_bare::from_slice;
use serde_bare::to_vec;
use crate::types::FileName; use crate::types::FileName;

@ -9,39 +9,24 @@
//! Repo Storage (Object Key/Col/Value Mapping) //! Repo Storage (Object Key/Col/Value Mapping)
use std::collections::hash_map::DefaultHasher;
use std::collections::HashMap; use std::collections::HashMap;
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::Hash; use std::sync::{Arc, RwLock};
use std::hash::Hasher;
use std::time::SystemTime;
use either::{Either, Left, Right}; use either::{Either, Left, Right};
use ng_net::types::*; use serde_bare::from_slice;
use serde_bare::to_vec;
use ng_repo::block_storage::BlockStorage; use ng_repo::block_storage::BlockStorage;
use ng_repo::errors::ProtocolError;
use ng_repo::errors::StorageError; use ng_repo::errors::StorageError;
use ng_repo::kcv_storage::prop; use ng_repo::kcv_storage::prop;
use ng_repo::kcv_storage::KCVStorage; use ng_repo::kcv_storage::KCVStorage;
#[allow(unused_imports)]
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::repo::BranchInfo; use ng_repo::repo::BranchInfo;
use ng_repo::repo::Repo; use ng_repo::repo::Repo;
use ng_repo::store::Store; use ng_repo::store::Store;
use ng_repo::types::BranchId; use ng_repo::types::*;
use ng_repo::types::BranchType;
use ng_repo::types::ReadCap;
use ng_repo::types::RepoId;
use ng_repo::types::RepoWriteCapSecret;
use ng_repo::types::Repository;
use ng_repo::types::SignerCap;
use ng_repo::types::StoreRepo;
use ng_repo::types::SymKey;
use ng_repo::types::Timestamp;
use ng_repo::utils::now_timestamp;
use serde::Deserialize;
use serde_bare::from_slice;
use serde_bare::to_vec;
use std::sync::{Arc, RwLock};
use super::branch::BranchStorage; use super::branch::BranchStorage;

@ -9,6 +9,11 @@
//! Storage of user application data (RDF, content of rich-text document, etc) //! Storage of user application data (RDF, content of rich-text document, etc)
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
use ng_repo::{ use ng_repo::{
block_storage::BlockStorage, block_storage::BlockStorage,
errors::StorageError, errors::StorageError,
@ -18,12 +23,6 @@ use ng_repo::{
}; };
use crate::types::*; use crate::types::*;
use std::{
cmp::{max, min},
collections::HashMap,
mem::size_of_val,
sync::{Arc, RwLock},
};
pub trait UserStorage: Send + Sync { pub trait UserStorage: Send + Sync {
//fn repo_id_to_store_overlay(&self, id: &RepoId) -> Result<StoreOverlay, StorageError>; //fn repo_id_to_store_overlay(&self, id: &RepoId) -> Result<StoreOverlay, StorageError>;
@ -53,7 +52,7 @@ pub trait UserStorage: Send + Sync {
fn branch_get_all_files(&self, branch: &BranchId) -> Result<Vec<FileName>, StorageError>; fn branch_get_all_files(&self, branch: &BranchId) -> Result<Vec<FileName>, StorageError>;
fn update_branch_current_head( fn update_branch_current_heads(
&self, &self,
repo_id: &RepoId, repo_id: &RepoId,
branch_id: &BranchId, branch_id: &BranchId,
@ -76,7 +75,7 @@ impl InMemoryUserStorage {
impl UserStorage for InMemoryUserStorage { impl UserStorage for InMemoryUserStorage {
fn branch_add_file( fn branch_add_file(
&self, &self,
commit_id: ObjectId, _commit_id: ObjectId,
branch: BranchId, branch: BranchId,
file: FileName, file: FileName,
) -> Result<(), StorageError> { ) -> Result<(), StorageError> {
@ -101,32 +100,32 @@ impl UserStorage for InMemoryUserStorage {
fn load_store( fn load_store(
&self, &self,
store_repo: &StoreRepo, _store_repo: &StoreRepo,
block_storage: Arc<RwLock<dyn BlockStorage + Send + Sync>>, _block_storage: Arc<RwLock<dyn BlockStorage + Send + Sync>>,
) -> Result<Repo, StorageError> { ) -> Result<Repo, StorageError> {
unimplemented!(); unimplemented!();
} }
fn load_repo(&self, repo_id: &RepoId, store: Arc<Store>) -> Result<Repo, StorageError> { fn load_repo(&self, _repo_id: &RepoId, _store: Arc<Store>) -> Result<Repo, StorageError> {
unimplemented!(); unimplemented!();
} }
fn save_repo(&self, repo: &Repo) -> Result<(), StorageError> { fn save_repo(&self, _repo: &Repo) -> Result<(), StorageError> {
unimplemented!(); unimplemented!();
} }
fn add_branch(&self, repo_id: &RepoId, branch_info: &BranchInfo) -> Result<(), StorageError> { fn add_branch(&self, _repo_id: &RepoId, _branch_info: &BranchInfo) -> Result<(), StorageError> {
unimplemented!(); unimplemented!();
} }
fn update_signer_cap(&self, signer_cap: &SignerCap) -> Result<(), StorageError> { fn update_signer_cap(&self, _signer_cap: &SignerCap) -> Result<(), StorageError> {
unimplemented!(); unimplemented!();
} }
fn update_branch_current_head( fn update_branch_current_heads(
&self, &self,
repo_id: &RepoId, _repo_id: &RepoId,
branch_id: &BranchId, _branch_id: &BranchId,
new_heads: Vec<ObjectRef>, _new_heads: Vec<ObjectRef>,
) -> Result<(), StorageError> { ) -> Result<(), StorageError> {
unimplemented!(); unimplemented!();
} }

@ -8,53 +8,57 @@
// according to those terms. // according to those terms.
//! Repo object (on heap) to handle a Repository //! Repo object (on heap) to handle a Repository
use crate::commits::*;
use crate::types::*; use core::fmt;
use crate::user_storage::InMemoryUserStorage; use std::cmp::max;
use std::collections::BTreeMap;
use std::collections::HashSet;
#[cfg(not(target_arch = "wasm32"))]
use std::fs::create_dir_all;
use std::fs::{read, File, OpenOptions};
use std::io::Write;
use std::{collections::HashMap, sync::Arc};
use async_std::stream::StreamExt; use async_std::stream::StreamExt;
use async_std::sync::{Mutex, RwLockReadGuard};
use futures::channel::mpsc; use futures::channel::mpsc;
use futures::SinkExt; use futures::SinkExt;
use ng_net::actor::SoS; use ng_repo::object::Object;
use ng_net::broker::{Broker, BROKER}; use serde::{Deserialize, Serialize};
use ng_repo::block_storage::store_max_value_size; use web_time::SystemTime;
//use oxigraph::io::{RdfFormat, RdfParser, RdfSerializer};
//use oxigraph::store::Store;
//use oxigraph::model::GroundQuad;
//use yrs::{StateVector, Update};
use ng_repo::file::ReadFile; use ng_repo::file::ReadFile;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::object::Object; #[cfg(any(test, feature = "testing"))]
use ng_repo::repo::BranchInfo; use ng_repo::utils::generate_keypair;
use ng_repo::{ use ng_repo::{
block_storage::{BlockStorage, HashMapBlockStorage}, block_storage::{store_max_value_size, BlockStorage, HashMapBlockStorage},
errors::{NgError, ProtocolError, ServerError, StorageError, VerifierError}, errors::{NgError, ProtocolError, ServerError, StorageError, VerifierError},
file::RandomAccessFile, file::RandomAccessFile,
repo::Repo, repo::{BranchInfo, Repo},
store::Store, store::Store,
types::*, types::*,
utils::{generate_keypair, sign},
}; };
use std::cmp::max;
use std::collections::BTreeMap;
use std::collections::HashSet;
use std::fs::{create_dir_all, read, write, File, OpenOptions};
use std::io::Write;
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::UserStorage;
use async_std::sync::{Mutex, RwLockReadGuard, RwLockWriteGuard};
use std::{collections::HashMap, path::PathBuf, sync::Arc};
use ng_net::actor::SoS;
use ng_net::broker::{Broker, BROKER};
use ng_net::{ use ng_net::{
connection::NoiseFSM, connection::NoiseFSM,
types::*, types::*,
utils::{Receiver, Sender}, utils::{Receiver, Sender},
}; };
use serde::{Deserialize, Serialize}; use crate::commits::*;
use web_time::SystemTime; #[cfg(not(target_family = "wasm"))]
//use yrs::{StateVector, Update}; use crate::rocksdb_user_storage::RocksDbUserStorage;
use crate::types::*;
use crate::user_storage::InMemoryUserStorage;
use crate::user_storage::UserStorage;
// pub trait IVerifier { // pub trait IVerifier {
// fn add_branch_and_save( // fn add_branch_and_save(
@ -72,6 +76,7 @@ use web_time::SystemTime;
pub struct Verifier { pub struct Verifier {
pub config: VerifierConfig, pub config: VerifierConfig,
pub connected_server_id: Option<PubKey>, pub connected_server_id: Option<PubKey>,
#[allow(dead_code)]
graph_dataset: Option<oxigraph::store::Store>, graph_dataset: Option<oxigraph::store::Store>,
pub(crate) user_storage: Option<Arc<Box<dyn UserStorage>>>, pub(crate) user_storage: Option<Arc<Box<dyn UserStorage>>>,
block_storage: Option<Arc<std::sync::RwLock<dyn BlockStorage + Send + Sync>>>, block_storage: Option<Arc<std::sync::RwLock<dyn BlockStorage + Send + Sync>>>,
@ -150,7 +155,7 @@ impl Verifier {
.uploads .uploads
.remove(&upload_id) .remove(&upload_id)
.ok_or(NgError::WrongUploadId)?; .ok_or(NgError::WrongUploadId)?;
let id = file.save()?; let _id = file.save()?;
Ok(file.reference().unwrap()) Ok(file.reference().unwrap())
} }
@ -198,15 +203,6 @@ impl Verifier {
&mut self, &mut self,
branch: BranchId, branch: BranchId,
) -> Result<(Receiver<AppResponse>, CancelFn), VerifierError> { ) -> Result<(Receiver<AppResponse>, CancelFn), VerifierError> {
// async fn send(mut tx: Sender<AppResponse>, msg: AppResponse) -> ResultSend<()> {
// while let Ok(_) = tx.send(msg.clone()).await {
// log_debug!("sending AppResponse");
// sleep!(std::time::Duration::from_secs(3));
// }
// log_debug!("end of sending");
// Ok(())
// }
// spawn_and_log_error(send(tx.clone(), commit));
//log_info!("#### create_branch_subscription {}", branch); //log_info!("#### create_branch_subscription {}", branch);
let (tx, rx) = mpsc::unbounded::<AppResponse>(); let (tx, rx) = mpsc::unbounded::<AppResponse>();
//log_info!("SUBSCRIBE"); //log_info!("SUBSCRIBE");
@ -313,12 +309,13 @@ impl Verifier {
self.config.config_type.is_persistent() self.config.config_type.is_persistent()
} }
#[allow(dead_code)]
fn is_in_memory(&self) -> bool { fn is_in_memory(&self) -> bool {
self.config.config_type.is_in_memory() self.config.config_type.is_in_memory()
} }
fn need_bootstrap(&self) -> bool { fn need_bootstrap(&self) -> bool {
self.stores.len() == 0 self.stores.is_empty()
} }
fn get_arc_block_storage( fn get_arc_block_storage(
@ -431,9 +428,9 @@ impl Verifier {
pub fn get_repo_mut( pub fn get_repo_mut(
&mut self, &mut self,
id: &RepoId, id: &RepoId,
store_repo: &StoreRepo, _store_repo: &StoreRepo,
) -> Result<&mut Repo, VerifierError> { ) -> Result<&mut Repo, VerifierError> {
let store = self.get_store(store_repo); //let store = self.get_store(store_repo);
let repo_ref = self.repos.get_mut(id).ok_or(VerifierError::RepoNotFound); let repo_ref = self.repos.get_mut(id).ok_or(VerifierError::RepoNotFound);
// .or_insert_with(|| { // .or_insert_with(|| {
// // load from storage // // load from storage
@ -518,8 +515,10 @@ impl Verifier {
let repo = self.get_repo(&repo_id, store_repo)?; let repo = self.get_repo(&repo_id, store_repo)?;
let event = Event::new(&publisher, seq_num, commit, additional_blocks, repo)?; let event = Event::new(&publisher, seq_num, commit, additional_blocks, repo)?;
let past = commit.direct_causal_past();
self.send_or_save_event_to_outbox( self.send_or_save_event_to_outbox(
commit.reference().unwrap(), commit.reference().unwrap(),
past,
event, event,
repo.store.inner_overlay(), repo.store.inner_overlay(),
) )
@ -540,6 +539,7 @@ impl Verifier {
let event = Event::new(&publisher, seq_num, commit, additional_blocks, repo)?; let event = Event::new(&publisher, seq_num, commit, additional_blocks, repo)?;
self.send_or_save_event_to_outbox( self.send_or_save_event_to_outbox(
commit.reference().unwrap(), commit.reference().unwrap(),
commit.direct_causal_past(),
event, event,
repo.store.inner_overlay(), repo.store.inner_overlay(),
) )
@ -547,6 +547,7 @@ impl Verifier {
Ok(()) Ok(())
} }
#[allow(dead_code)]
pub(crate) fn last_seq_number(&mut self) -> Result<u64, NgError> { pub(crate) fn last_seq_number(&mut self) -> Result<u64, NgError> {
if self.available_seq_nums() <= 1 { if self.available_seq_nums() <= 1 {
self.reserve_more(1)?; self.reserve_more(1)?;
@ -584,7 +585,7 @@ impl Verifier {
0, 0,
&repo.store, &repo.store,
)?; )?;
self.verify_commit(&commit, branch_id, repo_id, Arc::clone(&repo.store)) self.verify_commit_(&commit, branch_id, repo_id, Arc::clone(&repo.store), true)
.await?; .await?;
commit commit
}; };
@ -594,6 +595,7 @@ impl Verifier {
.await .await
} }
#[allow(dead_code)]
pub(crate) async fn new_commit_simple( pub(crate) async fn new_commit_simple(
&mut self, &mut self,
commit_body: CommitBodyV0, commit_body: CommitBodyV0,
@ -614,6 +616,7 @@ impl Verifier {
.await .await
} }
#[allow(dead_code)]
pub(crate) async fn new_events_with_repo( pub(crate) async fn new_events_with_repo(
&mut self, &mut self,
events: Vec<(Commit, Vec<Digest>)>, events: Vec<(Commit, Vec<Digest>)>,
@ -724,6 +727,7 @@ impl Verifier {
async fn send_or_save_event_to_outbox<'a>( async fn send_or_save_event_to_outbox<'a>(
&'a mut self, &'a mut self,
commit_ref: ObjectRef, commit_ref: ObjectRef,
past: Vec<ObjectRef>,
event: Event, event: Event,
overlay: OverlayId, overlay: OverlayId,
) -> Result<(), NgError> { ) -> Result<(), NgError> {
@ -735,7 +739,7 @@ impl Verifier {
.ok_or(NgError::TopicNotFound)? .ok_or(NgError::TopicNotFound)?
.to_owned(); .to_owned();
self.update_branch_current_head(&repo_id, &branch_id, commit_ref); self.update_branch_current_heads(&repo_id, &branch_id, past, commit_ref);
if self.connected_server_id.is_some() { if self.connected_server_id.is_some() {
// send the event to the server already // send the event to the server already
@ -800,22 +804,24 @@ impl Verifier {
return Err(e); return Err(e);
} }
let res = self.send_outbox().await;
log_info!("SENDING EVENTS FROM OUTBOX RETURNED: {:?}", res);
let mut branches = vec![]; let mut branches = vec![];
{ {
for (id, repo) in self.repos.iter() { for (id, repo) in self.repos.iter_mut() {
for (branch, publisher) in repo.opened_branches.iter() { for (branch, publisher) in repo.opened_branches.iter() {
branches.push((*id, *branch, *publisher)); branches.push((*id, *branch, *publisher));
} }
repo.opened_branches = HashMap::new();
} }
} }
let res = self.send_outbox().await;
log_info!("SENDING EVENTS FROM OUTBOX RETURNED: {:?}", res);
let user = self.config.user_priv_key.to_pub(); let user = self.config.user_priv_key.to_pub();
let broker = BROKER.read().await; let broker = BROKER.read().await;
for (repo, branch, publisher) in branches { for (repo, branch, publisher) in branches {
let _ = self let _ = self
.open_branch_(&repo, &branch, publisher, &broker, &user, &peer, true) .open_branch_(&repo, &branch, publisher, &broker, &user, &peer, false)
.await; .await;
// discarding error. // discarding error.
} }
@ -915,7 +921,7 @@ impl Verifier {
} else { } else {
match repo.opened_branches.get(branch) { match repo.opened_branches.get(branch) {
Some(val) => (false, as_publisher && !val, overlay), Some(val) => (false, as_publisher && !val, overlay),
None => (repo.opened_branches.len() == 0, true, overlay), None => (repo.opened_branches.is_empty(), true, overlay),
} }
} }
}; };
@ -1118,6 +1124,18 @@ impl Verifier {
branch_id: &BranchId, branch_id: &BranchId,
repo_id: &RepoId, repo_id: &RepoId,
store: Arc<Store>, store: Arc<Store>,
) -> Result<(), VerifierError> {
self.verify_commit_(commit, branch_id, repo_id, store, false)
.await
}
async fn verify_commit_(
&mut self,
commit: &Commit,
branch_id: &BranchId,
repo_id: &RepoId,
store: Arc<Store>,
skip_heads_update: bool,
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
//let quorum_type = commit.quorum_type(); //let quorum_type = commit.quorum_type();
// log_info!( // log_info!(
@ -1146,32 +1164,32 @@ impl Verifier {
}, },
}; };
let res = res.await; let res = res.await;
if res.is_ok() { if res.is_ok() && !skip_heads_update {
let commit_ref = commit.reference().unwrap(); let commit_ref = commit.reference().unwrap();
self.update_branch_current_head(repo_id, branch_id, commit_ref); let past = commit.direct_causal_past();
self.update_branch_current_heads(repo_id, branch_id, past, commit_ref);
Ok(()) Ok(())
} else { } else {
res res
} }
} }
fn update_branch_current_head( fn update_branch_current_heads(
&mut self, &mut self,
repo_id: &RepoId, repo_id: &RepoId,
branch: &BranchId, branch: &BranchId,
direct_past: Vec<ObjectRef>,
commit_ref: ObjectRef, commit_ref: ObjectRef,
) { ) -> Result<(), VerifierError> {
if let Some(repo) = self.repos.get_mut(repo_id) { if let Some(repo) = self.repos.get_mut(repo_id) {
let new_heads = repo.update_branch_current_head(branch, commit_ref); let new_heads = repo.update_branch_current_heads(branch, commit_ref, direct_past)?;
if new_heads.is_none() {
return;
}
let new_heads = new_heads.unwrap();
//log_info!("NEW HEADS {} {:?}", branch, new_heads); //log_info!("NEW HEADS {} {:?}", branch, new_heads);
if let Some(user_storage) = self.user_storage_if_persistent() { if let Some(user_storage) = self.user_storage_if_persistent() {
let _ = user_storage.update_branch_current_head(repo_id, branch, new_heads); let _ = user_storage.update_branch_current_heads(repo_id, branch, new_heads);
} }
} }
Ok(())
} }
fn user_storage_if_persistent(&self) -> Option<Arc<Box<dyn UserStorage>>> { fn user_storage_if_persistent(&self) -> Option<Arc<Box<dyn UserStorage>>> {
@ -1244,7 +1262,7 @@ impl Verifier {
pub(crate) fn get_repo( pub(crate) fn get_repo(
&self, &self,
id: &RepoId, id: &RepoId,
store_repo: &StoreRepo, _store_repo: &StoreRepo,
) -> Result<&Repo, VerifierError> { ) -> Result<&Repo, VerifierError> {
//let store = self.get_store(store_repo); //let store = self.get_store(store_repo);
let repo_ref: Result<&Repo, VerifierError> = let repo_ref: Result<&Repo, VerifierError> =
@ -1284,7 +1302,7 @@ impl Verifier {
let ours_set: HashSet<Digest> = HashSet::from_iter(ours.clone()); let ours_set: HashSet<Digest> = HashSet::from_iter(ours.clone());
let theirs = HashSet::from_iter(remote_heads.clone().into_iter()); let theirs = HashSet::from_iter(remote_heads.clone().into_iter());
if theirs.len() == 0 { if theirs.is_empty() {
log_info!("branch is new on the broker. doing nothing"); log_info!("branch is new on the broker. doing nothing");
return Ok(()); return Ok(());
} }
@ -1292,14 +1310,39 @@ impl Verifier {
&& theirs.difference(&ours_set).count() == 0 && theirs.difference(&ours_set).count() == 0
{ {
// no need to sync // no need to sync
// log_info!("branch is up to date"); log_info!("branch {} is up to date", branch_id);
return Ok(());
}
let mut theirs_found = HashSet::new();
let mut visited = HashMap::new();
for our in ours_set.iter() {
if let Ok(cobj) = Object::load(*our, None, &repo.store) {
let _ = Branch::load_causal_past(
&cobj,
&repo.store,
&theirs,
&mut visited,
&mut None,
None,
&mut Some(&mut theirs_found),
);
}
}
let theirs_not_found: Vec<ObjectId> =
theirs.difference(&theirs_found).cloned().collect();
if theirs_not_found.is_empty() {
return Ok(()); return Ok(());
} else {
// prepare bloom filter
} }
let msg = TopicSyncReq::V0(TopicSyncReqV0 { let msg = TopicSyncReq::V0(TopicSyncReqV0 {
topic: branch_info.topic, topic: branch_info.topic,
known_heads: ours.collect(), known_heads: ours_set.union(&theirs_found).into_iter().cloned().collect(),
target_heads: remote_heads.clone(), target_heads: theirs_not_found,
overlay: Some(store.overlay_for_read_on_client_protocol()), overlay: Some(store.overlay_for_read_on_client_protocol()),
}); });
(store, msg, branch_info.read_cap.key.clone()) (store, msg, branch_info.read_cap.key.clone())
@ -1580,41 +1623,6 @@ impl Verifier {
); );
let private_store = self.create_private_store_from_credentials()?; let private_store = self.create_private_store_from_credentials()?;
// let storage = self.block_storage.as_ref().unwrap().write().unwrap();
// for e in events {
// if e.overlay == private_inner_overlay_id {
// // it is an event about the private store
// // we will load only the commits on the root branch.
// let load = if let Ok(repo) =
// self.get_repo(private_store.id(), private_store.get_store_repo())
// {
// if let Some(root) = repo.root_branch() {
// root.topic == *e.event.topic_id()
// } else {
// true
// }
// } else {
// true
// };
// if !load {
// continue;
// }
// let commit = e.event.open(
// &private_store,
// private_store.id(),
// private_store.id(),
// private_store.get_store_readcap_secret(),
// )?;
// self.verify_commit(commit, Arc::clone(&private_store))?;
// }
// }
// let repo = self.get_repo(private_store.id(), private_store.get_store_repo())?;
// let root_topic = repo
// .root_branch()
// .ok_or(VerifierError::RootBranchNotFound)?
// .topic;
// 2nd pass: load all the other branches of the private store repo. // 2nd pass: load all the other branches of the private store repo.
@ -1662,34 +1670,6 @@ impl Verifier {
} }
} }
// for e in events {
// if e.overlay == private_inner_overlay_id {
// // it is an event about the private store
// // we will load only the commits that are not on the root branch.
// if root_topic == *e.event.topic_id() {
// continue;
// }
// let repo = self.get_repo(private_store.id(), private_store.get_store_repo())?;
// let (_, branch_id) = self
// .topics
// .get(&(e.overlay, *e.event.topic_id()))
// .ok_or(VerifierError::TopicNotFound)?;
// let branch = repo.branch(branch_id)?;
// let commit = e.event.open_with_info(repo, branch)?;
// if commit
// .body()
// .ok_or(VerifierError::CommitBodyNotFound)?
// .is_add_signer_cap()
// {
// postponed_signer_caps.push(commit);
// } else {
// self.verify_commit(commit, Arc::clone(&private_store))?;
// }
// }
// }
//log_info!("{:?}\n{:?}\n{:?}", self.repos, self.stores, self.topics); //log_info!("{:?}\n{:?}\n{:?}", self.repos, self.stores, self.topics);
//log_info!("SECOND PASS"); //log_info!("SECOND PASS");
// 2nd pass : load the other events (that are not from private store) // 2nd pass : load the other events (that are not from private store)
@ -1737,18 +1717,6 @@ impl Verifier {
} }
} }
} }
// let list: Vec<(OverlayId, StoreRepo)> = self
// .stores
// .iter()
// .map(|(o, s)| (o.clone(), s.get_store_repo().clone()))
// .collect();
// for (overlay, store_repo) in list {
// if overlay == private_inner_overlay_id {
// continue;
// // we skip the private store, as we already loaded it
// }
// self.complete_site_store_already_inserted(store_repo)?;
// }
// finally, ingest the signer_caps. // finally, ingest the signer_caps.
for signer_cap in postponed_signer_caps { for signer_cap in postponed_signer_caps {
@ -1764,16 +1732,16 @@ impl Verifier {
Ok(()) Ok(())
} }
fn display(heads: &Vec<ObjectRef>) -> String { // fn display(heads: &Vec<ObjectRef>) -> String {
let mut ret = String::new(); // let mut ret = String::new();
if heads.len() == 0 { // if heads.len() == 0 {
ret = "0".to_string(); // ret = "0".to_string();
} // }
for head in heads { // for head in heads {
ret.push_str(&format!("{} ", head.id)); // ret.push_str(&format!("{} ", head.id));
} // }
ret // ret
} // }
pub async fn send_outbox(&mut self) -> Result<(), NgError> { pub async fn send_outbox(&mut self) -> Result<(), NgError> {
let ret = self.take_events_from_outbox(); let ret = self.take_events_from_outbox();
@ -1781,7 +1749,7 @@ impl Verifier {
// log_err!("send_outbox {:}", ret.as_ref().unwrap_err()); // log_err!("send_outbox {:}", ret.as_ref().unwrap_err());
// } // }
let events: Vec<EventOutboxStorage> = ret.unwrap_or(vec![]); let events: Vec<EventOutboxStorage> = ret.unwrap_or(vec![]);
if events.len() == 0 { if events.is_empty() {
return Ok(()); return Ok(());
} }
let broker = BROKER.read().await; let broker = BROKER.read().await;
@ -1800,7 +1768,7 @@ impl Verifier {
match self.topics.get(&(e.overlay, *e.event.topic_id())) { match self.topics.get(&(e.overlay, *e.event.topic_id())) {
Some((repo_id, branch_id)) => match self.repos.get(repo_id) { Some((repo_id, branch_id)) => match self.repos.get(repo_id) {
Some(repo) => match repo.branches.get(branch_id) { Some(repo) => match repo.branches.get(branch_id) {
Some(branch) => { Some(_branch) => {
// let commit = e.event.open_with_info(repo, branch)?; // let commit = e.event.open_with_info(repo, branch)?;
// let acks = commit.acks(); // let acks = commit.acks();
// match branch_heads.get(branch_id) { // match branch_heads.get(branch_id) {
@ -1877,7 +1845,7 @@ impl Verifier {
let store_repo = repo.store.get_store_repo().clone(); let store_repo = repo.store.get_store_repo().clone();
self.open_branch_(&repo_id, &branch_id, true, &broker, &user, &remote, true) self.open_branch_(&repo_id, &branch_id, true, &broker, &user, &remote, false)
.await?; .await?;
for file in commit.files() { for file in commit.files() {
@ -2029,8 +1997,8 @@ impl Verifier {
pub async fn respond( pub async fn respond(
&mut self, &mut self,
msg: ProtocolMessage, _msg: ProtocolMessage,
fsm: Arc<Mutex<NoiseFSM>>, _fsm: Arc<Mutex<NoiseFSM>>,
) -> Result<(), ProtocolError> { ) -> Result<(), ProtocolError> {
unimplemented!(); unimplemented!();
} }
@ -2045,7 +2013,7 @@ impl Verifier {
let topic_id = info.topic.clone(); let topic_id = info.topic.clone();
let repo_id = repo.id.clone(); let repo_id = repo.id.clone();
let branch_id = branch_id.clone(); let branch_id = branch_id.clone();
let res = self let _res = self
.topics .topics
.insert((overlay_id, topic_id), (repo_id, branch_id)); .insert((overlay_id, topic_id), (repo_id, branch_id));
} }
@ -2103,7 +2071,7 @@ impl Verifier {
) -> Result<(), VerifierError> { ) -> Result<(), VerifierError> {
let store = Store::new_from(update, self.get_arc_block_storage()?); let store = Store::new_from(update, self.get_arc_block_storage()?);
let overlay_id = store.get_store_repo().overlay_id_for_storage_purpose(); let overlay_id = store.get_store_repo().overlay_id_for_storage_purpose();
let store = self let _store = self
.stores .stores
.entry(overlay_id) .entry(overlay_id)
.or_insert_with(|| Arc::new(store)); .or_insert_with(|| Arc::new(store));

@ -1,3 +1,4 @@
#[allow(non_upper_case_globals)]
pub const bip39_wordlist: [&str; 2048] = [ pub const bip39_wordlist: [&str; 2048] = [
"abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd",
"abuse", "access", "accident", "account", "accuse", "achieve", "acid", "acoustic", "acquire", "abuse", "access", "accident", "account", "accuse", "achieve", "acid", "acoustic", "acquire",

@ -7,8 +7,10 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use ng_repo::errors::NgError;
use std::collections::HashMap; use std::collections::HashMap;
use ng_repo::errors::NgError;
pub struct EmojiDef<'a> { pub struct EmojiDef<'a> {
pub hexcode: &'a str, pub hexcode: &'a str,
pub shortcode: &'a str, pub shortcode: &'a str,

@ -7,9 +7,6 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
// #[macro_use]
// extern crate slice_as_array;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -19,29 +16,31 @@ pub mod bip39;
pub mod emojis; pub mod emojis;
use ng_verifier::{site::SiteV0, verifier::Verifier}; use std::{collections::HashMap, io::Cursor};
use rand::distributions::{Distribution, Uniform};
use std::{collections::HashMap, io::Cursor, sync::Arc};
use crate::bip39::bip39_wordlist;
use crate::types::*;
use aes_gcm_siv::{ use aes_gcm_siv::{
aead::{heapless::Vec as HeaplessVec, AeadInPlace, KeyInit}, aead::{heapless::Vec as HeaplessVec, AeadInPlace, KeyInit},
Aes256GcmSiv, Nonce, Aes256GcmSiv, Nonce,
}; };
use argon2::{Algorithm, Argon2, AssociatedData, ParamsBuilder, Version}; use argon2::{Algorithm, Argon2, AssociatedData, ParamsBuilder, Version};
use chacha20poly1305::XChaCha20Poly1305; use chacha20poly1305::XChaCha20Poly1305;
use zeroize::{Zeroize, ZeroizeOnDrop};
use image::{imageops::FilterType, io::Reader as ImageReader, ImageOutputFormat}; use image::{imageops::FilterType, io::Reader as ImageReader, ImageOutputFormat};
use rand::distributions::{Distribution, Uniform};
use rand::prelude::*;
use safe_transmute::transmute_to_bytes; use safe_transmute::transmute_to_bytes;
use serde_bare::{from_slice, to_vec};
#[cfg(debug_assertions)]
use web_time::Instant;
use zeroize::Zeroize;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::{generate_keypair, now_timestamp, sign, verify}; use ng_repo::utils::{generate_keypair, now_timestamp, sign, verify};
use ng_repo::{log::*, types::PrivKey}; use ng_repo::{log::*, types::PrivKey};
use rand::prelude::*;
use serde_bare::{from_slice, to_vec}; use ng_verifier::{site::SiteV0, verifier::Verifier};
use web_time::Instant;
use crate::bip39::bip39_wordlist;
use crate::types::*;
impl Wallet { impl Wallet {
pub fn id(&self) -> WalletId { pub fn id(&self) -> WalletId {
@ -150,7 +149,7 @@ pub fn enc_master_key(
// Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext // Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext
cipher cipher
.encrypt_in_place(nonce, &to_vec(&wallet_id).unwrap(), &mut buffer) .encrypt_in_place(nonce, &to_vec(&wallet_id).unwrap(), &mut buffer)
.map_err(|e| NgWalletError::EncryptionError)?; .map_err(|_e| NgWalletError::EncryptionError)?;
// `buffer` now contains the encrypted master key // `buffer` now contains the encrypted master key
// log_debug!("cipher {:?}", buffer); // log_debug!("cipher {:?}", buffer);
@ -173,7 +172,7 @@ pub fn dec_master_key(
// Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext // Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext
cipher cipher
.decrypt_in_place(nonce, &to_vec(&wallet_id).unwrap(), &mut buffer) .decrypt_in_place(nonce, &to_vec(&wallet_id).unwrap(), &mut buffer)
.map_err(|e| NgWalletError::DecryptionError)?; .map_err(|_e| NgWalletError::DecryptionError)?;
Ok(buffer.into_array::<32>().unwrap()) Ok(buffer.into_array::<32>().unwrap())
} }
@ -197,7 +196,7 @@ pub fn enc_wallet_log(
timestamp: Timestamp, timestamp: Timestamp,
wallet_id: WalletId, wallet_id: WalletId,
) -> Result<Vec<u8>, NgWalletError> { ) -> Result<Vec<u8>, NgWalletError> {
let ser_log = to_vec(log).map_err(|e| NgWalletError::InternalError)?; let ser_log = to_vec(log).map_err(|_e| NgWalletError::InternalError)?;
let nonce_buffer: [u8; 24] = gen_nonce(peer_id, nonce); let nonce_buffer: [u8; 24] = gen_nonce(peer_id, nonce);
@ -213,7 +212,7 @@ pub fn enc_wallet_log(
&gen_associated_data(timestamp, wallet_id), &gen_associated_data(timestamp, wallet_id),
&mut buffer, &mut buffer,
) )
.map_err(|e| NgWalletError::EncryptionError)?; .map_err(|_e| NgWalletError::EncryptionError)?;
// `buffer` now contains the message ciphertext // `buffer` now contains the message ciphertext
// log_debug!("encrypted_block ciphertext {:?}", buffer); // log_debug!("encrypted_block ciphertext {:?}", buffer);
@ -268,10 +267,10 @@ pub fn dec_encrypted_block(
&gen_associated_data(timestamp, wallet_id), &gen_associated_data(timestamp, wallet_id),
&mut ciphertext, &mut ciphertext,
) )
.map_err(|e| NgWalletError::DecryptionError)?; .map_err(|_e| NgWalletError::DecryptionError)?;
let decrypted_log = let decrypted_log =
from_slice::<WalletLog>(&ciphertext).map_err(|e| NgWalletError::DecryptionError)?; from_slice::<WalletLog>(&ciphertext).map_err(|_e| NgWalletError::DecryptionError)?;
//master_key.zeroize(); // this is now done in the SensitiveWalletV0 //master_key.zeroize(); // this is now done in the SensitiveWalletV0
@ -296,8 +295,8 @@ pub fn dec_encrypted_block(
// we haven't test it yet. https://community.bitwarden.com/t/recommended-settings-for-argon2/50901/16?page=4 // we haven't test it yet. https://community.bitwarden.com/t/recommended-settings-for-argon2/50901/16?page=4
pub fn derive_key_from_pass(mut pass: Vec<u8>, salt: [u8; 16], wallet_id: WalletId) -> [u8; 32] { pub fn derive_key_from_pass(mut pass: Vec<u8>, salt: [u8; 16], wallet_id: WalletId) -> [u8; 32] {
let params = ParamsBuilder::new() let params = ParamsBuilder::new()
.m_cost(20 * 1024) .m_cost(30 * 1024)
.t_cost(30) .t_cost(40)
.p_cost(1) .p_cost(1)
.data(AssociatedData::new(wallet_id.slice()).unwrap()) .data(AssociatedData::new(wallet_id.slice()).unwrap())
.output_len(32) .output_len(32)
@ -322,10 +321,11 @@ pub fn open_wallet_with_pazzle(
//log_info!("pazzle={:?}", pazzle); //log_info!("pazzle={:?}", pazzle);
#[cfg(debug_assertions)]
let opening_pazzle = Instant::now(); let opening_pazzle = Instant::now();
verify(&wallet.content_as_bytes(), wallet.sig(), wallet.id()) verify(&wallet.content_as_bytes(), wallet.sig(), wallet.id())
.map_err(|e| NgWalletError::InvalidSignature)?; .map_err(|_e| NgWalletError::InvalidSignature)?;
match wallet { match wallet {
Wallet::V0(v0) => { Wallet::V0(v0) => {
@ -366,7 +366,7 @@ pub fn open_wallet_with_mnemonic(
mut pin: [u8; 4], mut pin: [u8; 4],
) -> Result<SensitiveWallet, NgWalletError> { ) -> Result<SensitiveWallet, NgWalletError> {
verify(&wallet.content_as_bytes(), wallet.sig(), wallet.id()) verify(&wallet.content_as_bytes(), wallet.sig(), wallet.id())
.map_err(|e| NgWalletError::InvalidSignature)?; .map_err(|_e| NgWalletError::InvalidSignature)?;
match wallet { match wallet {
Wallet::V0(v0) => { Wallet::V0(v0) => {
@ -519,9 +519,9 @@ pub fn create_wallet_first_step_v0(
// check validity of image // check validity of image
let decoded_img = ImageReader::new(Cursor::new(&params.security_img)) let decoded_img = ImageReader::new(Cursor::new(&params.security_img))
.with_guessed_format() .with_guessed_format()
.map_err(|e| NgWalletError::InvalidSecurityImage)? .map_err(|_e| NgWalletError::InvalidSecurityImage)?
.decode() .decode()
.map_err(|e| NgWalletError::InvalidSecurityImage)?; .map_err(|_e| NgWalletError::InvalidSecurityImage)?;
if decoded_img.height() < 150 || decoded_img.width() < 150 { if decoded_img.height() < 150 || decoded_img.width() < 150 {
return Err(NgWalletError::InvalidSecurityImage); return Err(NgWalletError::InvalidSecurityImage);
@ -537,7 +537,7 @@ pub fn create_wallet_first_step_v0(
let mut cursor = Cursor::new(buffer); let mut cursor = Cursor::new(buffer);
resized_img resized_img
.write_to(&mut cursor, ImageOutputFormat::Jpeg(72)) .write_to(&mut cursor, ImageOutputFormat::Jpeg(72))
.map_err(|e| NgWalletError::InvalidSecurityImage)?; .map_err(|_e| NgWalletError::InvalidSecurityImage)?;
// creating the wallet keys // creating the wallet keys
@ -581,6 +581,7 @@ pub async fn create_wallet_second_step_v0(
), ),
NgWalletError, NgWalletError,
> { > {
#[cfg(debug_assertions)]
let creating_pazzle = Instant::now(); let creating_pazzle = Instant::now();
let mut site = SiteV0::create_personal(params.user_privkey.clone(), verifier) let mut site = SiteV0::create_personal(params.user_privkey.clone(), verifier)
@ -684,12 +685,12 @@ pub async fn create_wallet_second_step_v0(
} }
let mut master_key = [0u8; 32]; let mut master_key = [0u8; 32];
getrandom::getrandom(&mut master_key).map_err(|e| NgWalletError::InternalError)?; getrandom::getrandom(&mut master_key).map_err(|_e| NgWalletError::InternalError)?;
let mut salt_pazzle = [0u8; 16]; let mut salt_pazzle = [0u8; 16];
let mut enc_master_key_pazzle = [0u8; 48]; let mut enc_master_key_pazzle = [0u8; 48];
if params.pazzle_length > 0 { if params.pazzle_length > 0 {
getrandom::getrandom(&mut salt_pazzle).map_err(|e| NgWalletError::InternalError)?; getrandom::getrandom(&mut salt_pazzle).map_err(|_e| NgWalletError::InternalError)?;
let mut pazzle_key = derive_key_from_pass( let mut pazzle_key = derive_key_from_pass(
[pazzle.clone(), params.pin.to_vec()].concat(), [pazzle.clone(), params.pin.to_vec()].concat(),
@ -702,7 +703,7 @@ pub async fn create_wallet_second_step_v0(
} }
let mut salt_mnemonic = [0u8; 16]; let mut salt_mnemonic = [0u8; 16];
getrandom::getrandom(&mut salt_mnemonic).map_err(|e| NgWalletError::InternalError)?; getrandom::getrandom(&mut salt_mnemonic).map_err(|_e| NgWalletError::InternalError)?;
//log_debug!("salt_pazzle {:?}", salt_pazzle); //log_debug!("salt_pazzle {:?}", salt_pazzle);
//log_debug!("salt_mnemonic {:?}", salt_mnemonic); //log_debug!("salt_mnemonic {:?}", salt_mnemonic);
@ -888,6 +889,7 @@ mod test {
assert_eq!(v0.content.security_img, generated_security_image_compare); assert_eq!(v0.content.security_img, generated_security_image_compare);
#[cfg(debug_assertions)]
let opening_mnemonic = Instant::now(); let opening_mnemonic = Instant::now();
let w = open_wallet_with_mnemonic(Wallet::V0(v0.clone()), res.mnemonic, pin.clone()) let w = open_wallet_with_mnemonic(Wallet::V0(v0.clone()), res.mnemonic, pin.clone())
@ -900,6 +902,7 @@ mod test {
); );
if v0.content.pazzle_length > 0 { if v0.content.pazzle_length > 0 {
#[cfg(debug_assertions)]
let opening_pazzle = Instant::now(); let opening_pazzle = Instant::now();
let w = open_wallet_with_pazzle(&Wallet::V0(v0.clone()), res.pazzle.clone(), pin) let w = open_wallet_with_pazzle(&Wallet::V0(v0.clone()), res.pazzle.clone(), pin)
.expect("open with pazzle"); .expect("open with pazzle");

@ -7,19 +7,22 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use ng_repo::log::*; use serde::{Deserialize, Serialize};
use serde_big_array::BigArray;
use std::collections::hash_map::{DefaultHasher, Keys};
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::{collections::HashMap, fmt}; use std::{collections::HashMap, fmt};
use web_time::SystemTime; use web_time::SystemTime;
use zeroize::{Zeroize, ZeroizeOnDrop}; use zeroize::{Zeroize, ZeroizeOnDrop};
use serde::{Deserialize, Serialize};
use serde_big_array::BigArray;
use ng_net::types::*;
use ng_repo::errors::NgError; use ng_repo::errors::NgError;
#[allow(unused_imports)]
use ng_repo::log::*;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::{encrypt_in_place, generate_keypair, now_timestamp, sign}; use ng_repo::utils::{encrypt_in_place, generate_keypair};
use ng_net::types::*;
use ng_verifier::site::SiteV0; use ng_verifier::site::SiteV0;
/// WalletId is a PubKey /// WalletId is a PubKey
@ -910,13 +913,12 @@ pub enum WalletOperation {
//SetSiteRBDRefV0((PubKey, SiteStoreType, ObjectRef)), //SetSiteRBDRefV0((PubKey, SiteStoreType, ObjectRef)),
//SetSiteRepoSecretV0((PubKey, SiteStoreType, RepoWriteCapSecret)), //SetSiteRepoSecretV0((PubKey, SiteStoreType, RepoWriteCapSecret)),
} }
use std::collections::hash_map::{DefaultHasher, Iter, Keys};
impl WalletOperation { impl WalletOperation {
pub fn hash(&self) -> (u64, &str) { pub fn hash(&self) -> (u64, &str) {
let mut s = DefaultHasher::new(); let mut s = DefaultHasher::new();
match self { match self {
Self::CreateWalletV0(t) => (0, "CreateWalletV0"), Self::CreateWalletV0(_t) => (0, "CreateWalletV0"),
Self::AddSiteV0(t) => { Self::AddSiteV0(t) => {
t.id.hash(&mut s); t.id.hash(&mut s);
(s.finish(), "AddSiteV0") (s.finish(), "AddSiteV0")
@ -933,7 +935,7 @@ impl WalletOperation {
t.hash(&mut s); t.hash(&mut s);
(s.finish(), "RemoveBrokerServerV0") (s.finish(), "RemoveBrokerServerV0")
} }
Self::SetSaveToNGOneV0(t) => (0, "SetSaveToNGOneV0"), Self::SetSaveToNGOneV0(_t) => (0, "SetSaveToNGOneV0"),
Self::SetBrokerCoreV0(t) => { Self::SetBrokerCoreV0(t) => {
t.peer_id.hash(&mut s); t.peer_id.hash(&mut s);
(s.finish(), "SetBrokerCoreV0") (s.finish(), "SetBrokerCoreV0")

@ -11,33 +11,32 @@ extern crate anyhow;
mod types; mod types;
use std::convert::Infallible;
use std::net::IpAddr;
use std::str::FromStr;
use std::sync::Arc;
use std::{env};
use duration_str::parse; use duration_str::parse;
use ng_client_ws::remote_ws::ConnectionWebSocket;
use ng_net::actors::admin::add_invitation::*;
use ng_net::broker::BROKER;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use warp::http::header::{HeaderMap, HeaderValue}; use warp::http::header::{HeaderMap, HeaderValue};
use warp::reply::Response; use warp::reply::Response;
use warp::{Filter, Reply}; use warp::{Filter, Reply};
use rust_embed::RustEmbed; use rust_embed::RustEmbed;
use serde_bare::{from_slice, to_vec};
use serde_json::json;
use std::convert::Infallible;
use std::net::IpAddr;
use std::str::FromStr;
use std::sync::Arc;
use std::{env, fs};
use crate::types::*; use ng_repo::log::*;
use ng_wallet::types::*; use ng_repo::types::*;
use ng_repo::utils::timestamp_after;
use ng_net::actors::admin::add_invitation::*;
use ng_net::broker::BROKER;
use ng_net::types::{ use ng_net::types::{
AdminResponseContentV0, BindAddress, CreateAccountBSP, Invitation, InvitationCode, AdminResponseContentV0, BindAddress, CreateAccountBSP, Invitation, InvitationCode,
InvitationV0, APP_ACCOUNT_REGISTERED_SUFFIX, APP_NG_ONE_URL, NG_ONE_URL, APP_ACCOUNT_REGISTERED_SUFFIX,
}; };
use ng_repo::log::*;
use ng_repo::types::*; use ng_client_ws::remote_ws::ConnectionWebSocket;
use ng_repo::utils::{generate_keypair, sign, timestamp_after, verify};
#[derive(RustEmbed)] #[derive(RustEmbed)]
#[folder = "web/dist"] #[folder = "web/dist"]
@ -71,7 +70,7 @@ impl Server {
url: None, url: None,
}; };
} }
let mut cabsp = cabsp.unwrap(); let cabsp = cabsp.unwrap();
log_debug!("{:?}", cabsp); log_debug!("{:?}", cabsp);
@ -156,7 +155,7 @@ impl Server {
Ok(response) Ok(response)
} }
RegisterResponse { RegisterResponse {
error: Some(e), error: Some(_e),
url: redirect_url, url: redirect_url,
.. ..
} => { } => {

@ -9,6 +9,7 @@
use warp::{reply::Response, Reply}; use warp::{reply::Response, Reply};
#[allow(dead_code)]
pub enum NgHttpError { pub enum NgHttpError {
InvalidParams, InvalidParams,
NotFound, NotFound,
@ -18,7 +19,7 @@ pub enum NgHttpError {
impl Reply for NgHttpError { impl Reply for NgHttpError {
fn into_response(self) -> Response { fn into_response(self) -> Response {
match (self) { match self {
NgHttpError::NotFound => warp::http::StatusCode::NOT_FOUND.into_response(), NgHttpError::NotFound => warp::http::StatusCode::NOT_FOUND.into_response(),
NgHttpError::InvalidParams => { NgHttpError::InvalidParams => {
let response = Response::new("Invalid params".into()); let response = Response::new("Invalid params".into());

@ -7,39 +7,29 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use ed25519_dalek::*;
use core::fmt; use core::fmt;
use duration_str::parse;
use futures::{future, pin_mut, stream, SinkExt, StreamExt};
use ng_net::actors::admin::*;
use ng_repo::block_storage::{
store_max_value_size, store_valid_value_size, BlockStorage, HashMapBlockStorage,
};
use rand::rngs::OsRng;
use serde::{Deserialize, Serialize};
use serde_json::{from_str, to_string_pretty};
use std::collections::HashMap;
use std::error::Error; use std::error::Error;
use std::fs::{read_to_string, write}; use std::fs::{read_to_string, write};
use std::io::ErrorKind; use std::net::IpAddr;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use clap::{arg, command, value_parser, Command};
use duration_str::parse;
use serde::{Deserialize, Serialize};
use serde_json::{from_str, to_string_pretty};
use zeroize::Zeroize; use zeroize::Zeroize;
use ng_client_ws::remote_ws::ConnectionWebSocket;
use ng_net::broker::BROKER;
use ng_net::types::*;
use ng_repo::errors::*; use ng_repo::errors::*;
use ng_repo::log::*; use ng_repo::log::*;
use ng_repo::types::*; use ng_repo::types::*;
use ng_repo::utils::{ use ng_repo::utils::{decode_priv_key, display_timestamp, generate_keypair, timestamp_after};
decode_priv_key, display_timestamp, generate_keypair, now_timestamp, timestamp_after,
}; use ng_net::actors::admin::*;
use ng_net::broker::BROKER;
use ng_net::types::*;
use clap::{arg, command, value_parser, ArgAction, Command}; use ng_client_ws::remote_ws::ConnectionWebSocket;
/// CliConfig Version 0 /// CliConfig Version 0
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
@ -249,7 +239,7 @@ async fn main_inner() -> Result<(), NgcliError> {
} }
env_logger::init(); env_logger::init();
if let Some(matches) = matches.subcommand_matches("gen-key") { if let Some(_matches) = matches.subcommand_matches("gen-key") {
let (privkey, pubkey) = generate_keypair(); let (privkey, pubkey) = generate_keypair();
println!("Your UserId is: {pubkey}"); println!("Your UserId is: {pubkey}");
println!("Your Private key is: {privkey}"); println!("Your Private key is: {privkey}");
@ -286,7 +276,7 @@ async fn main_inner() -> Result<(), NgcliError> {
} }
}; };
let mut keys: [[u8; 32]; 4] = match matches.get_one::<String>("key") { let keys: [[u8; 32]; 4] = match matches.get_one::<String>("key") {
Some(key_string) => { Some(key_string) => {
if key_from_file.is_some() { if key_from_file.is_some() {
log_err!("provided --key option or NG_CLIENT_KEY var env will not be used as a key file is already present"); log_err!("provided --key option or NG_CLIENT_KEY var env will not be used as a key file is already present");
@ -458,7 +448,7 @@ async fn main_inner() -> Result<(), NgcliError> {
Some(("admin", sub_matches)) => match sub_matches.subcommand() { Some(("admin", sub_matches)) => match sub_matches.subcommand() {
Some(("add-user", sub2_matches)) => { Some(("add-user", sub2_matches)) => {
log_debug!("add-user"); log_debug!("add-user");
let res = do_admin_call( let _res = do_admin_call(
keys[1], keys[1],
config_v0, config_v0,
AddUser::V0(AddUserV0 { AddUser::V0(AddUserV0 {
@ -480,7 +470,7 @@ async fn main_inner() -> Result<(), NgcliError> {
} }
Some(("del-user", sub2_matches)) => { Some(("del-user", sub2_matches)) => {
log_debug!("add-user"); log_debug!("add-user");
let res = do_admin_call( let _res = do_admin_call(
keys[1], keys[1],
config_v0, config_v0,
DelUser::V0(DelUserV0 { DelUser::V0(DelUserV0 {

@ -7,7 +7,6 @@
// notice may not be copied, modified, or distributed except // notice may not be copied, modified, or distributed except
// according to those terms. // according to those terms.
use clap::builder::OsStr;
use clap::Parser; use clap::Parser;
use crate::DEFAULT_PORT; use crate::DEFAULT_PORT;

@ -11,44 +11,42 @@ pub mod types;
mod cli; mod cli;
use crate::cli::*;
use crate::types::*;
use clap::Parser;
use core::fmt; use core::fmt;
use ng_broker::interfaces::*;
use ng_broker::server_ws::run_server_v0;
use ng_broker::types::*;
use ng_broker::utils::*;
use ng_net::types::*;
use ng_net::utils::is_private_ip;
use ng_net::utils::is_public_ip;
use ng_net::utils::is_public_ipv4;
use ng_net::utils::is_public_ipv6;
use ng_net::utils::{
gen_dh_keys, is_ipv4_global, is_ipv4_private, is_ipv6_global, is_ipv6_private,
};
use ng_net::{WS_PORT, WS_PORT_REVERSE_PROXY};
use ng_repo::errors::NgError;
use ng_repo::log::*;
use ng_repo::types::Sig;
use ng_repo::types::SymKey;
use ng_repo::utils::ed_keypair_from_priv_bytes;
use ng_repo::{
types::{PrivKey, PubKey},
utils::{decode_key, decode_priv_key, generate_keypair, sign, verify},
};
use serde_json::{from_str, to_string_pretty};
use std::error::Error; use std::error::Error;
use std::fs::{read_to_string, write}; use std::fs::{read_to_string, write};
use std::io::ErrorKind;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::path::PathBuf; use std::path::PathBuf;
use zeroize::Zeroize;
use addr::parser::DnsName; use addr::parser::DnsName;
use addr::psl::List; use addr::psl::List;
use clap::Parser;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use regex::Regex; use regex::Regex;
use serde_json::{from_str, to_string_pretty};
use zeroize::Zeroize;
use ng_repo::errors::NgError;
use ng_repo::log::*;
use ng_repo::types::{Sig, SymKey};
use ng_repo::utils::ed_keypair_from_priv_bytes;
use ng_repo::{
types::PrivKey,
utils::{decode_key, decode_priv_key, sign, verify},
};
use ng_net::types::*;
use ng_net::utils::is_private_ip;
use ng_net::utils::is_public_ip;
use ng_net::utils::is_public_ipv4;
use ng_net::utils::is_public_ipv6;
use ng_net::{WS_PORT, WS_PORT_REVERSE_PROXY};
use ng_broker::interfaces::*;
use ng_broker::server_ws::run_server_v0;
use ng_broker::types::*;
use ng_broker::utils::*;
use crate::cli::*;
//For windows: {846EE342-7039-11DE-9D20-806E6F6E6963} //For windows: {846EE342-7039-11DE-9D20-806E6F6E6963}
//For the other OSes: en0 lo ... //For the other OSes: en0 lo ...
@ -223,6 +221,7 @@ fn parse_triple_interface_and_port_for(
parts[1].to_string(), parts[1].to_string(),
&format!("public IPv6 (middle) part of the {}", for_option), &format!("public IPv6 (middle) part of the {}", for_option),
)?; )?;
middle_part = Some(middle_part_res);
} }
let last_part = parse_ipv4_and_port_for( let last_part = parse_ipv4_and_port_for(
@ -274,7 +273,7 @@ fn parse_domain_and_port(
} else { } else {
default_port default_port
}; };
let mut domain_with_port = parts[0].clone().to_string(); let mut domain_with_port = parts[0].to_string();
if port != default_port { if port != default_port {
domain_with_port.push_str(&format!(":{}", port)); domain_with_port.push_str(&format!(":{}", port));
} }
@ -459,7 +458,7 @@ async fn main_inner() -> Result<(), NgdError> {
gen_broker_keys(key_from_file) gen_broker_keys(key_from_file)
} else { } else {
let res = gen_broker_keys(None); let res = gen_broker_keys(None);
let key = PrivKey::Ed25519PrivKey((res[0])); let key = PrivKey::Ed25519PrivKey(res[0]);
let mut master_key = key.to_string(); let mut master_key = key.to_string();
if args.save_key { if args.save_key {
write(key_path.clone(), &master_key) write(key_path.clone(), &master_key)
@ -484,7 +483,7 @@ async fn main_inner() -> Result<(), NgdError> {
let mut sign_path = path.clone(); let mut sign_path = path.clone();
sign_path.push("sign"); sign_path.push("sign");
let sign_from_file: Option<[u8; 32]>; //let sign_from_file: Option<[u8; 32]>;
let privkey: PrivKey = keys[3].into(); let privkey: PrivKey = keys[3].into();
let pubkey = privkey.to_pub(); let pubkey = privkey.to_pub();
@ -502,7 +501,7 @@ async fn main_inner() -> Result<(), NgdError> {
.map_err(|e| NgdError::CannotSaveSignature(e.to_string()))?; .map_err(|e| NgdError::CannotSaveSignature(e.to_string()))?;
let sig_ser = serde_bare::to_vec(&sig).unwrap(); let sig_ser = serde_bare::to_vec(&sig).unwrap();
let res = std::fs::write(sign_path, sig_ser) std::fs::write(sign_path, sig_ser)
.map_err(|e| NgdError::CannotSaveSignature(e.to_string()))?; .map_err(|e| NgdError::CannotSaveSignature(e.to_string()))?;
} }
@ -966,8 +965,8 @@ async fn main_inner() -> Result<(), NgdError> {
.unwrap() .unwrap()
.as_str() .as_str()
.try_into() .try_into()
.map_err(|e| { .map_err(|_e| {
log_warn!("The admin UserId supplied is invalid. no admin user configured."); log_warn!("The supplied admin UserId is invalid. no admin user configured.");
}) })
.ok() .ok()
} else { } else {

Loading…
Cancel
Save