From e12280b88ea199691062da0ee8fb0fcbac31725e Mon Sep 17 00:00:00 2001 From: Sun Date: Thu, 24 Feb 2022 22:27:26 +0800 Subject: [PATCH] refactor --- Cargo.toml | 13 +- lib/global.dart | 4 +- lib/rpc.dart | 25 +- lib/security.dart | 3 - macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 231 ++- pubspec.yaml | 4 - src/account.rs | 70 +- src/apps.rs | 78 +- src/apps/device/mod.rs | 4 +- src/apps/device/models.rs | 40 +- src/apps/device/rpc.rs | 10 +- src/daemon.rs | 7 +- src/global.rs | 92 + src/group.rs | 1630 ++++++++--------- src/group/running.rs | 42 +- src/layer.rs | 742 ++++---- src/lib.rs | 7 +- src/migrate.rs | 2 +- src/migrate/account.rs | 2 +- src/migrate/consensus.rs | 2 +- src/migrate/session.rs | 3 +- src/rpc.rs | 785 ++++---- src/server.rs | 265 +-- src/session.rs | 37 +- src/storage.rs | 106 +- types/cloud/Cargo.toml | 1 - types/cloud/src/lib.rs | 5 +- types/dao/src/lib.rs | 15 +- types/domain/Cargo.toml | 1 - types/domain/src/lib.rs | 13 +- types/group/Cargo.toml | 1 - types/group/src/lib.rs | 5 +- types/primitives/src/lib.rs | 4 +- .../flutter/generated_plugin_registrant.cc | 9 +- windows/flutter/generated_plugins.cmake | 1 + 36 files changed, 2146 insertions(+), 2115 deletions(-) create mode 100644 src/global.rs diff --git a/Cargo.toml b/Cargo.toml index 582361b..adc15a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,9 +34,9 @@ panic = 'abort' anyhow = "1.0" log = "0.4" rand = "0.8" -once_cell = "1.8" +once_cell = "1.9" simplelog = "0.11" -image = "0.23" +image = "0.24" base64 = "0.13" hex = "0.4" sha2 = "0.10" @@ -44,13 +44,14 @@ argon2 = "0.3" blake3 = "1.3" bincode = "1.3" aes-gcm = "0.9" -sysinfo = "0.21" +sysinfo = "0.23" serde = { version = "1", features = ["derive"] } tokio = { version = "1", features = ["full"] } -web3 = { version = "0.17", default-features = false, features = ["http-tls", "signing"] } -tdn = { version = "0.7", default-features = false, features = ["full"] } +web3 = { version = "0.18", default-features = false, features = ["http-tls", "signing"] } +tdn = { version = "0.7", default-features = false, features = ["std"] } tdn_did = { version = "0.7" } tdn_storage = { git = "https://github.com/cympletech/tdn", branch="main" } +esse_primitives = { version = "0.1", path = "./types/primitives" } chat_types = { version = "0.1", path = "./types/chat" } group_types = { version = "0.1", path = "./types/group" } cloud_types = { version = "0.1", path = "./types/cloud" } @@ -66,6 +67,8 @@ jni = { version = "0.19", default-features = false } # DEBUG patch. [patch.crates-io] +chamomile = { git = "https://github.com/cympletech/chamomile" } +chamomile_types = { git = "https://github.com/cympletech/chamomile" } tdn = { git = "https://github.com/cympletech/tdn" } tdn_types = { git = "https://github.com/cympletech/tdn" } tdn_did = { git = "https://github.com/cympletech/tdn" } diff --git a/lib/global.dart b/lib/global.dart index c26a935..ad6e49b 100644 --- a/lib/global.dart +++ b/lib/global.dart @@ -1,8 +1,8 @@ class Global { static String version = 'v0.5.0'; static String gid = '0000000000000000000000000000000000000000000000000000000000000000'; - static String httpRpc = '127.0.0.1:8000'; - static String wsRpc = '127.0.0.1:8080'; + static String httpRpc = '127.0.0.1:7365'; + static String wsRpc = '127.0.0.1:7366'; //static String httpRpc = '192.168.2.148:8001'; // test code //static String wsRpc = '192.168.2.148:8081'; // test code //static String httpRpc = '192.168.50.250:8001'; // test code diff --git a/lib/rpc.dart b/lib/rpc.dart index 516872f..6b27213 100644 --- a/lib/rpc.dart +++ b/lib/rpc.dart @@ -10,7 +10,6 @@ import 'package:esse/global.dart'; Map jsonrpc = { "jsonrpc": "2.0", "id": 1, - "gid": Global.gid, "method": "", "params": [], }; @@ -111,7 +110,6 @@ class WebSocketsNotifications { send(String method, List params) { jsonrpc["method"] = method; jsonrpc["params"] = params; - jsonrpc["gid"] = Global.gid; if (_channel != null) { _channel!.sink.add(json.encode(jsonrpc)); @@ -134,23 +132,16 @@ class WebSocketsNotifications { Map response = json.decode(message); print(response); - if (response["result"] != null && - response["method"] != null && - response["gid"] != null - ) { - String method = response["method"]; - List params = response["result"]; - String gid = response["gid"]; + if (response["result"] != null && response["method"] != null) { + String method = response["method"]; + List params = response["result"]; + if (_listeners[method] != null) { final callbacks = _listeners[method]!; - if (gid == Global.gid || method.startsWith('account')) { - try { - callbacks[0](params); - } catch (e) { - print('function is unvalid'); - } - } else if (callbacks[1] != null && callbacks[1]) { - _notice!(gid); + try { + callbacks[0](params); + } catch (e) { + print('function is unvalid'); } } else { print("has no this " + method); diff --git a/lib/security.dart b/lib/security.dart index c3fcea3..b62ad94 100644 --- a/lib/security.dart +++ b/lib/security.dart @@ -175,9 +175,6 @@ class _SecurityPageState extends State { await rpc.init(Global.wsRpc); } - // init system info. - rpc.send('account-system-info', []); - // check if has logined. final loginedAccounts = await getLogined(); if (loginedAccounts.length != 0) { diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 1136c38..cfd2ffa 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,6 +6,7 @@ import FlutterMacOS import Foundation import audio_session +import device_info_plus_macos import esse_core import file_selector_macos import just_audio @@ -15,6 +16,7 @@ import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) + DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) EsseCorePlugin.register(with: registry.registrar(forPlugin: "EsseCorePlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 1be3b9e..ef98561 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -15,13 +15,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.8.0" - ansicolor: - dependency: transitive - description: - name: ansicolor - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" archive: dependency: transitive description: @@ -78,6 +71,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.1" + cli_dialog: + dependency: transitive + description: + name: cli_dialog + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.0" cli_util: dependency: transitive description: @@ -141,6 +141,55 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.17.1" + dart_console: + dependency: transitive + description: + name: dart_console + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + device_info_plus: + dependency: transitive + description: + name: device_info_plus + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.2" + device_info_plus_linux: + dependency: transitive + description: + name: device_info_plus_linux + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + device_info_plus_macos: + dependency: transitive + description: + name: device_info_plus_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" + device_info_plus_platform_interface: + dependency: transitive + description: + name: device_info_plus_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0+1" + device_info_plus_web: + dependency: transitive + description: + name: device_info_plus_web + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + device_info_plus_windows: + dependency: transitive + description: + name: device_info_plus_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" diff_match_patch: dependency: transitive description: @@ -189,20 +238,20 @@ packages: name: file_picker url: "https://pub.dartlang.org" source: hosted - version: "4.3.0" + version: "4.4.0" file_selector: dependency: "direct main" description: name: file_selector url: "https://pub.dartlang.org" source: hosted - version: "0.8.2+1" + version: "0.8.3" file_selector_linux: dependency: "direct main" description: path: "plugins/file_selector/file_selector_linux" ref: HEAD - resolved-ref: c339fe7dd2e17a80f7bb839bfad89d21a6e084ba + resolved-ref: "89c350f787e1d7bff12b3517e5671146211ee70e" url: "git://github.com/google/flutter-desktop-embedding.git" source: git version: "0.0.2+1" @@ -211,7 +260,7 @@ packages: description: path: "plugins/file_selector/file_selector_macos" ref: HEAD - resolved-ref: c339fe7dd2e17a80f7bb839bfad89d21a6e084ba + resolved-ref: "89c350f787e1d7bff12b3517e5671146211ee70e" url: "git://github.com/google/flutter-desktop-embedding.git" source: git version: "0.0.4+1" @@ -221,23 +270,21 @@ packages: name: file_selector_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.4" file_selector_web: dependency: transitive description: name: file_selector_web url: "https://pub.dartlang.org" source: hosted - version: "0.8.1+2" + version: "0.8.1+3" file_selector_windows: - dependency: "direct main" + dependency: transitive description: - path: "plugins/file_selector/file_selector_windows" - ref: HEAD - resolved-ref: c339fe7dd2e17a80f7bb839bfad89d21a6e084ba - url: "git://github.com/google/flutter-desktop-embedding.git" - source: git - version: "0.0.2+1" + name: file_selector_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.2" flutter: dependency: "direct main" description: flutter @@ -268,7 +315,7 @@ packages: name: flutter_keyboard_visibility url: "https://pub.dartlang.org" source: hosted - version: "5.1.0" + version: "5.2.0" flutter_keyboard_visibility_platform_interface: dependency: transitive description: @@ -315,7 +362,7 @@ packages: name: flutter_native_splash url: "https://pub.dartlang.org" source: hosted - version: "1.3.3" + version: "2.0.5" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -329,7 +376,7 @@ packages: name: flutter_quill url: "https://pub.dartlang.org" source: hosted - version: "3.2.0" + version: "4.0.5" flutter_test: dependency: "direct dev" description: flutter @@ -352,6 +399,13 @@ packages: description: flutter source: sdk version: "0.0.0" + gallery_saver: + dependency: transitive + description: + name: gallery_saver + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.2" gettext_parser: dependency: transitive description: @@ -400,28 +454,28 @@ packages: name: image url: "https://pub.dartlang.org" source: hosted - version: "3.1.0" + version: "3.1.3" image_picker: dependency: "direct main" description: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.8.4+4" + version: "0.8.4+9" image_picker_for_web: dependency: transitive description: name: image_picker_for_web url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.6" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.4.2" + version: "2.4.4" image_save: dependency: "direct main" description: @@ -429,13 +483,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "5.0.0" - injector: - dependency: transitive - description: - name: injector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" integration_test: dependency: "direct dev" description: flutter @@ -461,21 +508,21 @@ packages: name: just_audio url: "https://pub.dartlang.org" source: hosted - version: "0.9.18" + version: "0.9.20" just_audio_platform_interface: dependency: transitive description: name: just_audio_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "4.0.0" + version: "4.1.0" just_audio_web: dependency: transitive description: name: just_audio_web url: "https://pub.dartlang.org" source: hosted - version: "0.4.2" + version: "0.4.4" lints: dependency: transitive description: @@ -490,6 +537,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -503,7 +557,7 @@ packages: name: msix url: "https://pub.dartlang.org" source: hosted - version: "2.8.0" + version: "3.2.0" nested: dependency: transitive description: @@ -538,7 +592,7 @@ packages: name: path_provider url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.9" path_provider_android: dependency: transitive description: @@ -559,28 +613,28 @@ packages: name: path_provider_linux url: "https://pub.dartlang.org" source: hosted - version: "2.1.4" + version: "2.1.5" path_provider_macos: dependency: transitive description: name: path_provider_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" path_provider_windows: dependency: transitive description: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" pedantic: dependency: transitive description: @@ -594,14 +648,28 @@ packages: name: percent_indicator url: "https://pub.dartlang.org" source: hosted - version: "3.4.0" + version: "4.0.0" permission_handler: dependency: "direct main" description: name: permission_handler url: "https://pub.dartlang.org" source: hosted - version: "8.3.0" + version: "9.2.0" + permission_handler_android: + dependency: transitive + description: + name: permission_handler_android + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.2" + permission_handler_apple: + dependency: transitive + description: + name: permission_handler_apple + url: "https://pub.dartlang.org" + source: hosted + version: "9.0.2" permission_handler_platform_interface: dependency: transitive description: @@ -609,6 +677,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.7.0" + permission_handler_windows: + dependency: transitive + description: + name: permission_handler_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" petitparser: dependency: transitive description: @@ -629,14 +704,14 @@ packages: name: platform url: "https://pub.dartlang.org" source: hosted - version: "3.0.2" + version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.2" process: dependency: transitive description: @@ -671,7 +746,7 @@ packages: name: qr_code_scanner url: "https://pub.dartlang.org" source: hosted - version: "0.6.1" + version: "0.7.0" qr_flutter: dependency: "direct main" description: @@ -720,35 +795,35 @@ packages: name: shared_preferences url: "https://pub.dartlang.org" source: hosted - version: "2.0.11" + version: "2.0.13" shared_preferences_android: dependency: transitive description: name: shared_preferences_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.9" + version: "2.0.11" shared_preferences_ios: dependency: transitive description: name: shared_preferences_ios url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.1.0" shared_preferences_macos: dependency: transitive description: name: shared_preferences_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shared_preferences_platform_interface: dependency: transitive description: @@ -762,14 +837,14 @@ packages: name: shared_preferences_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.3" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.1.0" sky_engine: dependency: transitive description: flutter @@ -837,7 +912,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" tuple: dependency: transitive description: @@ -872,35 +947,35 @@ packages: name: url_launcher url: "https://pub.dartlang.org" source: hosted - version: "6.0.17" + version: "6.0.20" url_launcher_android: dependency: transitive description: name: url_launcher_android url: "https://pub.dartlang.org" source: hosted - version: "6.0.13" + version: "6.0.15" url_launcher_ios: dependency: transitive description: name: url_launcher_ios url: "https://pub.dartlang.org" source: hosted - version: "6.0.13" + version: "6.0.15" url_launcher_linux: dependency: transitive description: name: url_launcher_linux url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "3.0.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "3.0.0" url_launcher_platform_interface: dependency: transitive description: @@ -914,21 +989,21 @@ packages: name: url_launcher_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.8" url_launcher_windows: dependency: transitive description: name: url_launcher_windows url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "3.0.0" uuid: dependency: transitive description: name: uuid url: "https://pub.dartlang.org" source: hosted - version: "3.0.5" + version: "3.0.6" vector_math: dependency: transitive description: @@ -942,28 +1017,42 @@ packages: name: video_player url: "https://pub.dartlang.org" source: hosted - version: "2.2.10" + version: "2.2.18" + video_player_android: + dependency: transitive + description: + name: video_player_android + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + video_player_avfoundation: + dependency: transitive + description: + name: video_player_avfoundation + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "5.0.1" + version: "5.1.0" video_player_web: dependency: transitive description: name: video_player_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.7" vm_service: dependency: transitive description: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "7.3.0" + version: "7.5.0" watcher: dependency: transitive description: @@ -991,14 +1080,14 @@ packages: name: win32 url: "https://pub.dartlang.org" source: hosted - version: "2.3.3" + version: "2.4.1" xdg_directories: dependency: transitive description: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0" + version: "0.2.0+1" xml: dependency: transitive description: @@ -1022,4 +1111,4 @@ packages: version: "8.0.0" sdks: dart: ">=2.15.1 <3.0.0" - flutter: ">=2.5.3" + flutter: ">=2.10.0" diff --git a/pubspec.yaml b/pubspec.yaml index b3d6963..5d125fc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,10 +35,6 @@ dependencies: git: url: git://github.com/google/flutter-desktop-embedding.git path: plugins/file_selector/file_selector_macos - file_selector_windows: - git: - url: git://github.com/google/flutter-desktop-embedding.git - path: plugins/file_selector/file_selector_windows open_file: any # open file in mobile. crop: any unorm_dart: any diff --git a/src/account.rs b/src/account.rs index c1d2d72..be5ac5d 100644 --- a/src/account.rs +++ b/src/account.rs @@ -2,12 +2,14 @@ use rand::Rng; use serde::{Deserialize, Serialize}; use std::time::{SystemTime, UNIX_EPOCH}; use tdn::types::{ - group::{EventId, GroupId}, - primitive::{PeerId, Result}, + group::EventId, + primitives::{PeerId, PeerKey, Result}, }; -use tdn_did::{generate_id, Keypair, Language}; +use tdn_did::{generate_peer, Language}; use tdn_storage::local::{DStorage, DsValue}; +use esse_primitives::{id_from_str, id_to_str}; + use crate::utils::crypto::{ check_pin, decrypt, decrypt_key, encrypt_key, encrypt_multiple, hash_pin, }; @@ -45,7 +47,7 @@ pub fn lang_from_i64(u: i64) -> Language { pub(crate) struct Account { pub id: i64, - pub gid: GroupId, + pub pid: PeerId, pub index: i64, pub lang: i64, pub mnemonic: Vec, // encrypted value. @@ -56,7 +58,7 @@ pub(crate) struct Account { pub secret: Vec, // encrypted value. pub encrypt: Vec, // encrypted encrypt key. pub wallet: String, // main wallet info. - pub pub_height: i64, // public information height. + pub pub_height: u64, // public information height. pub own_height: u64, // own data consensus height. pub event: EventId, pub datetime: i64, @@ -65,7 +67,7 @@ pub(crate) struct Account { impl Account { pub fn new( - gid: GroupId, + pid: PeerId, index: i64, lang: i64, pass: String, @@ -89,7 +91,7 @@ impl Account { own_height: 0, wallet: String::new(), event: EventId::default(), - gid, + pid, index, lang, pass, @@ -117,8 +119,8 @@ impl Account { name: &str, lock: &str, avatar: Vec, - ) -> Result<(Account, Keypair)> { - let (gid, sk) = generate_id( + ) -> Result<(Account, PeerKey)> { + let sk = generate_peer( lang_from_i64(lang), mnemonic, index, @@ -128,15 +130,19 @@ impl Account { let key = rand::thread_rng().gen::<[u8; 32]>(); let ckey = encrypt_key(salt, lock, &key)?; - let mut ebytes = - encrypt_multiple(salt, lock, &ckey, vec![&sk.to_bytes(), mnemonic.as_bytes()])?; + let mut ebytes = encrypt_multiple( + salt, + lock, + &ckey, + vec![&sk.to_db_bytes(), mnemonic.as_bytes()], + )?; let mnemonic = ebytes.pop().unwrap_or(vec![]); let secret = ebytes.pop().unwrap_or(vec![]); let index = index as i64; Ok(( Account::new( - gid, + sk.peer_id(), index, lang, pass.to_string(), @@ -186,10 +192,10 @@ impl Account { String::from_utf8(pbytes).or(Err(anyhow!("mnemonic unlock invalid."))) } - pub fn secret(&self, salt: &[u8], lock: &str) -> Result { + pub fn secret(&self, salt: &[u8], lock: &str) -> Result { self.check_lock(lock)?; let pbytes = decrypt(salt, lock, &self.encrypt, &self.secret)?; - Keypair::from_bytes(&pbytes).or(Err(anyhow!("secret unlock invalid."))) + PeerKey::from_db_bytes(&pbytes).or(Err(anyhow!("secret unlock invalid."))) } /// here is zero-copy and unwrap is safe. checked. @@ -198,7 +204,7 @@ impl Account { datetime: v.pop().unwrap().as_i64(), event: EventId::from_hex(v.pop().unwrap().as_str()).unwrap_or(EventId::default()), own_height: v.pop().unwrap().as_i64() as u64, - pub_height: v.pop().unwrap().as_i64(), + pub_height: v.pop().unwrap().as_i64() as u64, wallet: v.pop().unwrap().as_string(), avatar: base64::decode(v.pop().unwrap().as_str()).unwrap_or(vec![]), encrypt: base64::decode(v.pop().unwrap().as_str()).unwrap_or(vec![]), @@ -209,16 +215,16 @@ impl Account { pass: v.pop().unwrap().as_string(), lang: v.pop().unwrap().as_i64(), index: v.pop().unwrap().as_i64(), - gid: GroupId::from_hex(v.pop().unwrap().as_str()).unwrap_or(GroupId::default()), + pid: id_from_str(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()), id: v.pop().unwrap().as_i64(), plainkey: vec![], } } - pub fn get(db: &DStorage, gid: &GroupId) -> Result { + pub fn get(db: &DStorage, pid: &PeerId) -> Result { let sql = format!( - "SELECT id, gid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts WHERE gid = '{}'", - gid.to_hex() + "SELECT id, pid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts WHERE pid = '{}'", + id_to_str(pid) ); let mut matrix = db.query(&sql)?; if matrix.len() > 0 { @@ -231,7 +237,7 @@ impl Account { pub fn all(db: &DStorage) -> Result> { let matrix = db.query( - "SELECT id, gid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts ORDER BY datetime DESC", + "SELECT id, pid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime FROM accounts ORDER BY datetime DESC", )?; let mut accounts = vec![]; for values in matrix { @@ -242,16 +248,16 @@ impl Account { pub fn insert(&mut self, db: &DStorage) -> Result<()> { let mut unique_check = db.query(&format!( - "SELECT id from accounts WHERE gid = '{}'", - self.gid.to_hex() + "SELECT id from accounts WHERE pid = '{}'", + id_to_str(&self.pid) ))?; if unique_check.len() > 0 { let id = unique_check.pop().unwrap().pop().unwrap().as_i64(); self.id = id; self.update(db)?; } else { - let sql = format!("INSERT INTO accounts (gid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime) VALUES ('{}', {}, {}, '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', {}, {}, '{}', {})", - self.gid.to_hex(), + let sql = format!("INSERT INTO accounts (pid, indx, lang, pass, name, lock, mnemonic, secret, encrypt, avatar, wallet, pub_height, own_height, event, datetime) VALUES ('{}', {}, {}, '{}', '{}', '{}', '{}', '{}', '{}', '{}', '{}', {}, {}, '{}', {})", + id_to_str(&self.pid), self.index, self.lang, self.pass, @@ -321,8 +327,7 @@ impl Account { #[derive(Serialize, Deserialize, Clone)] pub(crate) struct User { - pub id: GroupId, - pub addr: PeerId, + pub id: PeerId, pub name: String, pub wallet: String, pub height: i64, @@ -330,17 +335,9 @@ pub(crate) struct User { } impl User { - pub fn new( - id: GroupId, - addr: PeerId, - name: String, - avatar: Vec, - wallet: String, - height: i64, - ) -> Self { + pub fn new(id: PeerId, name: String, avatar: Vec, wallet: String, height: i64) -> Self { Self { id, - addr, name, avatar, wallet, @@ -350,8 +347,7 @@ impl User { pub fn info(name: String, wallet: String, height: i64, avatar: Vec) -> Self { Self { - id: GroupId::default(), - addr: PeerId::default(), + id: PeerId::default(), name, wallet, height, diff --git a/src/apps.rs b/src/apps.rs index 98e8a32..fac8f52 100644 --- a/src/apps.rs +++ b/src/apps.rs @@ -2,56 +2,56 @@ use std::sync::Arc; use tdn::types::{ group::GroupId, message::RecvType, - primitive::{HandleResult, Result}, + primitives::{HandleResult, Result}, rpc::RpcHandler, }; use tokio::sync::RwLock; +use crate::global::Global; use crate::layer::Layer; -use crate::rpc::RpcState; -pub(crate) mod chat; -pub(crate) mod cloud; +//pub(crate) mod chat; +//pub(crate) mod cloud; pub(crate) mod device; -pub(crate) mod domain; -pub(crate) mod file; -pub(crate) mod group; -pub(crate) mod jarvis; +//pub(crate) mod domain; +//pub(crate) mod file; +//pub(crate) mod group; +//pub(crate) mod jarvis; //pub(crate) mod dao; -pub(crate) mod wallet; +//pub(crate) mod wallet; -pub(crate) fn app_rpc_inject(handler: &mut RpcHandler) { - device::new_rpc_handler(handler); - chat::new_rpc_handler(handler); - jarvis::new_rpc_handler(handler); - domain::new_rpc_handler(handler); - file::new_rpc_handler(handler); - group::new_rpc_handler(handler); - wallet::new_rpc_handler(handler); +pub(crate) fn app_rpc_inject(handler: &mut RpcHandler) { + //device::new_rpc_handler(handler); + //chat::new_rpc_handler(handler); + //jarvis::new_rpc_handler(handler); + //domain::new_rpc_handler(handler); + //file::new_rpc_handler(handler); + //group::new_rpc_handler(handler); + //wallet::new_rpc_handler(handler); //dao::new_rpc_handler(handler); - cloud::new_rpc_handler(handler); + //cloud::new_rpc_handler(handler); } -pub(crate) async fn app_layer_handle( - layer: &Arc>, - fgid: GroupId, - mgid: GroupId, - msg: RecvType, -) -> Result { - match (fgid, mgid) { - (group::GROUP_ID, _) => group::handle_peer(layer, mgid, msg).await, - (_, group::GROUP_ID) => group::handle_server(layer, fgid, msg).await, - //(dao::GROUP_ID, _) => dao::handle(layer, fgid, mgid, false, msg).await, - (domain::GROUP_ID, _) => domain::handle(layer, mgid, msg).await, - (cloud::GROUP_ID, _) => cloud::handle(layer, mgid, msg).await, - _ => chat::handle(layer, fgid, mgid, msg).await, - } -} +// pub(crate) async fn app_layer_handle( +// layer: &Arc>, +// fgid: GroupId, +// mgid: GroupId, +// msg: RecvType, +// ) -> Result { +// match (fgid, mgid) { +// (group::GROUP_ID, _) => group::handle_peer(layer, mgid, msg).await, +// (_, group::GROUP_ID) => group::handle_server(layer, fgid, msg).await, +// (dao::GROUP_ID, _) => dao::handle(layer, fgid, mgid, false, msg).await, +// (domain::GROUP_ID, _) => domain::handle(layer, mgid, msg).await, +// (cloud::GROUP_ID, _) => cloud::handle(layer, mgid, msg).await, +// _ => chat::handle(layer, fgid, mgid, msg).await, +// } +// } -pub(crate) fn _app_group_handle() -> Result { - todo!() -} +// pub(crate) fn _app_group_handle() -> Result { +// todo!() +// } -pub(crate) fn _app_migrate() -> Result<()> { - todo!() -} +// pub(crate) fn _app_migrate() -> Result<()> { +// todo!() +// } diff --git a/src/apps/device/mod.rs b/src/apps/device/mod.rs index 32f135b..d1076b0 100644 --- a/src/apps/device/mod.rs +++ b/src/apps/device/mod.rs @@ -1,5 +1,5 @@ mod models; -pub(crate) mod rpc; +//pub(crate) mod rpc; pub(crate) use models::Device; -pub(crate) use rpc::new_rpc_handler; +//pub(crate) use rpc::new_rpc_handler; diff --git a/src/apps/device/models.rs b/src/apps/device/models.rs index f86c2d0..21705c2 100644 --- a/src/apps/device/models.rs +++ b/src/apps/device/models.rs @@ -1,6 +1,5 @@ -use std::collections::HashMap; use std::time::{SystemTime, UNIX_EPOCH}; -use tdn::types::primitive::{Peer, PeerId, Result}; +use tdn::types::primitives::{Peer, Result}; use tdn::types::rpc::{json, RpcParam}; use tdn_storage::local::{DStorage, DsValue}; @@ -8,13 +7,13 @@ pub(crate) struct Device { pub id: i64, pub name: String, pub info: String, - pub addr: PeerId, + pub peer: Peer, pub lasttime: i64, pub online: bool, } impl Device { - pub fn new(name: String, info: String, addr: PeerId) -> Self { + pub fn new(name: String, info: String, peer: Peer) -> Self { let start = SystemTime::now(); let lasttime = start .duration_since(UNIX_EPOCH) @@ -22,10 +21,10 @@ impl Device { .unwrap_or(0) as i64; // safe for all life. Self { - addr, lasttime, info, name, + peer, id: 0, online: true, } @@ -35,7 +34,7 @@ impl Device { fn from_values(mut v: Vec) -> Device { Device { lasttime: v.pop().unwrap().as_i64(), - addr: PeerId::from_hex(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()), + peer: Peer::from_string(v.pop().unwrap().as_str()).unwrap_or(Peer::default()), info: v.pop().unwrap().as_string(), name: v.pop().unwrap().as_string(), id: v.pop().unwrap().as_i64(), @@ -48,7 +47,7 @@ impl Device { self.id, self.name, self.info, - self.addr.to_hex(), + self.peer.to_string(), self.lasttime, if self.online { "1" } else { "0" }, ]) @@ -56,25 +55,22 @@ impl Device { /// load account devices. pub fn list(db: &DStorage) -> Result> { - let matrix = db.query("SELECT id, name, info, addr, lasttime FROM devices")?; + let matrix = db.query("SELECT id, name, info, peer, lasttime FROM devices")?; let mut devices = vec![]; for values in matrix { - if values.len() == 5 { - devices.push(Device::from_values(values)); - } + devices.push(Device::from_values(values)); } Ok(devices) } - pub fn distributes(db: &DStorage) -> Result> { - let matrix = db.query("SELECT id, addr FROM devices")?; - let mut devices = HashMap::new(); - for mut values in matrix { - if values.len() == 2 { - let addr = - PeerId::from_hex(values.pop().unwrap().as_str()).unwrap_or(PeerId::default()); - let id = values.pop().unwrap().as_i64(); - devices.insert(addr, (Peer::peer(addr), id, false)); + pub fn distributes(db: &DStorage) -> Result> { + let matrix = db.query("SELECT id, peer FROM devices")?; + let mut devices = vec![]; + for mut v in matrix { + if v.len() == 3 { + let peer = Peer::from_string(v.pop().unwrap().as_str()).unwrap_or(Peer::default()); + let id = v.pop().unwrap().as_i64(); + devices.push((peer, id, false)); } } Ok(devices) @@ -95,10 +91,10 @@ impl Device { pub fn insert(&mut self, db: &DStorage) -> Result<()> { let sql = format!( - "INSERT INTO devices (name, info, addr, lasttime) VALUES ('{}', '{}', '{}', {})", + "INSERT INTO devices (name, info, peer, lasttime) VALUES ('{}', '{}', '{}', {})", self.name, self.info, - self.addr.to_hex(), + self.peer.to_string(), self.lasttime, ); let id = db.insert(&sql)?; diff --git a/src/apps/device/rpc.rs b/src/apps/device/rpc.rs index 4341e46..a1f30d5 100644 --- a/src/apps/device/rpc.rs +++ b/src/apps/device/rpc.rs @@ -12,28 +12,28 @@ use crate::utils::device_status::device_status as local_device_status; use super::Device; #[inline] -pub(crate) fn device_create(mgid: GroupId, device: &Device) -> RpcParam { +pub(crate) fn device_create(mgid: PeerId, device: &Device) -> RpcParam { rpc_response(0, "device-create", json!(device.to_rpc()), mgid) } #[inline] -pub(crate) fn _device_remove(mgid: GroupId, id: i64) -> RpcParam { +pub(crate) fn _device_remove(mgid: PeerId, id: i64) -> RpcParam { rpc_response(0, "device-remove", json!([id]), mgid) } #[inline] -pub(crate) fn device_online(mgid: GroupId, id: i64) -> RpcParam { +pub(crate) fn device_online(mgid: PeerId, id: i64) -> RpcParam { rpc_response(0, "device-online", json!([id]), mgid) } #[inline] -pub(crate) fn device_offline(mgid: GroupId, id: i64) -> RpcParam { +pub(crate) fn device_offline(mgid: PeerId, id: i64) -> RpcParam { rpc_response(0, "device-offline", json!([id]), mgid) } #[inline] pub(crate) fn device_status( - mgid: GroupId, + mgid: PeerId, cpu: u32, memory: u32, swap: u32, diff --git a/src/daemon.rs b/src/daemon.rs index 1fb67da..f0212df 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -8,15 +8,16 @@ use std::env::args; mod account; mod apps; -mod consensus; -mod event; +//mod consensus; +//mod event; mod group; mod layer; mod migrate; mod primitives; mod rpc; mod server; -mod session; +//mod session; +mod global; mod storage; mod utils; diff --git a/src/global.rs b/src/global.rs new file mode 100644 index 0000000..849fa81 --- /dev/null +++ b/src/global.rs @@ -0,0 +1,92 @@ +use std::collections::HashMap; +use std::path::PathBuf; +use std::sync::Arc; +use tdn::prelude::{GroupId, PeerId, SendMessage}; +use tokio::{sync::mpsc::Sender, sync::RwLock}; + +use crate::account::Account; +use crate::group::Group; +use crate::layer::Layer; + +/// global status. +pub(crate) struct Global { + /// current running account. + pub peer_id: RwLock, + /// current account public height. + pub peer_pub_height: RwLock, + /// current account own height. + pub peer_own_height: RwLock, + /// current group. + pub group: RwLock, + /// current layer. + pub layer: RwLock, + /// TDN network sender. + pub sender: RwLock>, + /// message delivery tracking. uuid, me_gid, db_id. + pub _delivery: RwLock>, + /// storage base path. + pub base: PathBuf, + /// random secret seed. + pub secret: [u8; 32], +} + +impl Global { + pub fn init( + accounts: HashMap, + tdn_send: Sender, + base: PathBuf, + secret: [u8; 32], + ) -> Self { + Global { + base, + secret, + peer_id: RwLock::new(PeerId::default()), + peer_pub_height: RwLock::new(0), + peer_own_height: RwLock::new(0), + group: RwLock::new(Group::init(accounts)), + layer: RwLock::new(Layer::init()), + sender: RwLock::new(tdn_send), + _delivery: RwLock::new(HashMap::new()), + } + } + + pub async fn pid(&self) -> PeerId { + self.peer_id.read().await.clone() + } + + pub async fn send(&self, msg: SendMessage) -> anyhow::Result<()> { + self.sender + .read() + .await + .send(msg) + .await + .map_err(|_e| anyhow!("network lost!")) + } + + pub async fn clear(&self) { + *self.peer_id.write().await = PeerId::default(); + self.layer.write().await.clear(); + } + + pub async fn reset(&self, pid: &PeerId, lock: &str) -> anyhow::Result { + if *self.peer_id.read().await == *pid { + return Ok(false); + } + + let (pheight, oheight) = + self.group + .write() + .await + .reset(pid, lock, &self.base, &self.secret)?; + self.layer.write().await.clear(); + + *self.peer_id.write().await = *pid; + *self.peer_pub_height.write().await = pheight; + *self.peer_own_height.write().await = oheight; + self._delivery.write().await.clear(); + + // TODO change sender. + + Ok(true) + } +} diff --git a/src/group.rs b/src/group.rs index c435b1e..d18cf79 100644 --- a/src/group.rs +++ b/src/group.rs @@ -1,57 +1,50 @@ +use esse_primitives::id_to_str; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; +use std::time::{SystemTime, UNIX_EPOCH}; use tdn::types::{ group::{EventId, GroupId}, message::{RecvType, SendMessage, SendType}, - primitive::{HandleResult, Peer, PeerId, Result}, + primitives::{HandleResult, Peer, PeerId, PeerKey, Result}, }; -use tdn_did::Proof; -use tokio::sync::{mpsc::Sender, RwLock}; - use tdn_storage::local::DStorage; +use tokio::sync::{mpsc::Sender, RwLock}; use crate::account::{Account, User}; -use crate::apps::device::rpc as device_rpc; +use crate::global::Global; +//use crate::apps::device::rpc as device_rpc; use crate::apps::device::Device; -use crate::consensus::Event; -use crate::event::{InnerEvent, StatusEvent, SyncEvent}; -use crate::layer::Layer; -use crate::migrate::{ - ACCOUNT_DB, CHAT_DB, CLOUD_DB, CONSENSUS_DB, DAO_DB, DOMAIN_DB, FILE_DB, GROUP_DB, JARVIS_DB, - SERVICE_DB, SESSION_DB, WALLET_DB, -}; -use crate::rpc; -use crate::storage::{account_init, write_avatar}; +//use crate::consensus::Event; +//use crate::event::{InnerEvent, StatusEvent, SyncEvent}; +//use crate::layer::Layer; +//use crate::rpc; +use crate::storage::{account_db, account_init, consensus_db, write_avatar}; use crate::utils::crypto::{decrypt, encrypt}; use crate::utils::device_status::{device_info, device_status as local_device_status}; -pub(crate) mod running; - -use running::RunningAccount; - /// Esse group. pub(crate) struct Group { - /// storage base path. - base: PathBuf, - /// random secret seed. - secret: [u8; 32], - /// TDN network sender. - sender: Sender, - /// current address. - addr: PeerId, /// all accounts. - accounts: HashMap, - /// distributed devices. - runnings: HashMap, + pub accounts: HashMap, + /// current account secret keypair. + pub keypair: PeerKey, + /// current account device's name. + pub device_name: String, + /// current account device's info. + pub device_info: String, + /// current account distribute connected devices. + pub distributes: Vec<(Peer, i64, bool)>, + /// current account uptime + pub uptime: u32, } /// Request for make distributed. #[derive(Serialize, Deserialize)] enum GroupConnect { /// Params: User, consensus height, event_id, remote_name, remote_info, other_devices addr. - Create(Proof, User, u64, EventId, String, String, Vec), + Create(User, u64, EventId, String, String, Vec), /// connected. Connect(u64, EventId), } @@ -60,13 +53,15 @@ enum GroupConnect { #[derive(Serialize, Deserialize)] pub(crate) enum GroupEvent { /// Sync event. - Event(u64, EventId, EventId, InnerEvent), + Event(u64, EventId, EventId), + //Event(u64, EventId, EventId, InnerEvent), /// Sync infomations. - Status(StatusEvent), + Status, + //Status(StatusEvent), /// device's info update. - DeviceUpdate(PeerId, String), + DeviceUpdate(String), /// device deleted. - DeviceDelete(PeerId), + DeviceDelete, /// offline. DeviceOffline, /// Device status request. @@ -79,386 +74,394 @@ pub(crate) enum GroupEvent { /// Sync height from..to request. SyncRequest(u64, u64), /// Sync height from..last_to, to, response. - SyncResponse(u64, u64, u64, Vec), + SyncResponse(u64, u64, u64), + //SyncResponse(u64, u64, u64, Vec), } -impl Group { - pub async fn handle( - &mut self, - gid: GroupId, - msg: RecvType, - layer: &Arc>, - uid: u64, - ) -> Result { - let mut results = HandleResult::new(); - - // 1. check account is online, if not online, nothing. - if !self.runnings.contains_key(&gid) { - return Ok(results); - } +/// handle inner-group message. +pub(crate) async fn handle(msg: RecvType, global: &Arc) -> Result { + let mut results = HandleResult::new(); - match msg { - RecvType::Connect(addr, data) => { - self.hanlde_connect(&mut results, &gid, addr, data, true)?; - } - RecvType::Leave(addr) => { - for (_, account) in &mut self.runnings { - if let Some(device) = account.distributes.get_mut(&addr) { - device.2 = false; - results.rpcs.push(device_rpc::device_offline(gid, device.1)); - } - } - } - RecvType::Result(addr, is_ok, data) => { - if is_ok { - self.hanlde_connect(&mut results, &gid, addr, data, false)?; - } - } - RecvType::ResultConnect(addr, data) => { - self.hanlde_connect(&mut results, &gid, addr, data, true)?; - } - RecvType::Event(addr, bytes) => { - let event: GroupEvent = bincode::deserialize(&bytes)?; - return GroupEvent::handle(self, event, gid, addr, layer, uid).await; - } - RecvType::Stream(_uid, _stream, _bytes) => { - todo!(); - // TODO stream - } - RecvType::Delivery(_t, _tid, _is_ok) => {} + match msg { + RecvType::Connect(peer, data) => { + //self.hanlde_connect(&mut results, peer, data, true)?; } - - Ok(results) - } - - fn hanlde_connect( - &mut self, - results: &mut HandleResult, - gid: &GroupId, - addr: Peer, - data: Vec, - is_connect: bool, - ) -> Result<()> { - let connect = bincode::deserialize(&data)?; - let peer_id = addr.id; - - let (remote_height, remote_event, others) = match connect { - GroupConnect::Create( - proof, - remote, - remote_height, - remote_event, - device_name, - device_info, - others, - ) => { - // check remote addr is receive addr. - if remote.addr != peer_id { - return Err(anyhow!("Address is invalid.")); - } - proof.verify(gid, &peer_id, &self.addr)?; - if is_connect { - results - .groups - .push((*gid, self.agree_message(gid, addr.clone())?)); - } - - // first init sync. - if remote.avatar.len() > 0 { - let account_db = self.account_db()?; - if let Some(u) = self.accounts.get_mut(gid) { - if u.avatar.len() == 0 { - u.name = remote.name; - u.avatar = remote.avatar; - u.update(&account_db)?; - account_db.close()?; - results.rpcs.push(rpc::account_update( - *gid, - &u.name, - base64::encode(&u.avatar), - )); - } - } - } - - let db = self.consensus_db(gid)?; - let running = self.runnings.get_mut(gid).unwrap(); // safe unwrap. checked. - let mut new_addrs = vec![]; - for a in others { - if a != peer_id && a != self.addr && !running.distributes.contains_key(&a) { - new_addrs.push(a); - } - } - - if let Some(v) = running.distributes.get_mut(&peer_id) { - v.2 = true; - results.rpcs.push(device_rpc::device_online(*gid, v.1)); - (remote_height, remote_event, new_addrs) - } else { - let mut device = Device::new(device_name, device_info, peer_id); - device.insert(&db)?; - db.close()?; - running - .distributes - .insert(peer_id, (addr.clone(), device.id, true)); - results.rpcs.push(device_rpc::device_create(*gid, &device)); - results - .rpcs - .push(device_rpc::device_online(*gid, device.id)); - (remote_height, remote_event, new_addrs) - } - } - GroupConnect::Connect(remote_height, remote_event) => { - if self - .runnings - .get(gid) - .unwrap() // safe, checked - .distributes - .contains_key(&peer_id) - { - if is_connect { - results.groups.push((*gid, self.connect_result(gid, addr)?)); - } - } else { - if is_connect { - results.groups.push((*gid, self.create_message(gid, addr)?)); - } - return Ok(()); - } - - let v = self.running_mut(gid)?; - let did = v.add_online(&peer_id)?; - results.rpcs.push(device_rpc::device_online(*gid, did)); - (remote_height, remote_event, vec![]) + RecvType::Leave(peer) => { + // check device leave. + //if let Ok(id) = account.offline(&peer) { + //results.rpcs.push(device_rpc::device_offline(peer.id, id)); + //} + } + RecvType::Result(peer, is_ok, data) => { + if is_ok { + //self.hanlde_connect(&mut results, peer, data, false)?; } - }; - - let account = self.account(gid)?; - if account.own_height != remote_height || account.event != remote_event { - results.groups.push(( - *gid, - self.sync_message(gid, peer_id, 1, account.own_height)?, - )); } - - // connect to others. - for addr in others { - results - .groups - .push((*gid, self.create_message(gid, Peer::peer(addr))?)); + RecvType::ResultConnect(peer, data) => { + //self.hanlde_connect(&mut results, peer, data, true)?; } - - Ok(()) + RecvType::Event(addr, bytes) => { + //let event: GroupEvent = bincode::deserialize(&bytes)?; + //return GroupEvent::handle(self, event, pid, addr, uid).await; + } + RecvType::Stream(_uid, _stream, _bytes) => { + todo!(); + // TODO stream + } + RecvType::Delivery(_t, _tid, _is_ok) => {} } + + Ok(results) } +// fn hanlde_connect( +// &mut self, +// results: &mut HandleResult, +// peer: Peer, +// data: Vec, +// is_connect: bool, +// ) -> Result<()> { +// let connect = bincode::deserialize(&data)?; +// let pid = peer.id; + +// let (remote_height, remote_event, others) = match connect { +// GroupConnect::Create( +// remote, +// remote_height, +// remote_event, +// device_name, +// device_info, +// others, +// ) => { +// // check remote addr is receive addr. +// if remote.addr != pid { +// return Err(anyhow!("Address is invalid.")); +// } + +// if is_connect { +// results +// .groups +// .push((pid, self.agree_message(peer.clone())?)); +// } + +// // first init sync. +// if remote.avatar.len() > 0 { +// let account_db = self.account_db()?; +// if let Some(u) = self.accounts.get_mut(pid) { +// if u.avatar.len() == 0 { +// u.name = remote.name; +// u.avatar = remote.avatar; +// u.update(&account_db)?; +// account_db.close()?; +// results.rpcs.push(rpc::account_update( +// *pid, +// &u.name, +// base64::encode(&u.avatar), +// )); +// } +// } +// } + +// let db = self.consensus_db(pid)?; +// let running = self.runnings.get_mut(pid).unwrap(); // safe unwrap. checked. +// let mut new_addrs = vec![]; +// for a in others { +// if a != peer_id && a != self.addr && !running.distributes.contains_key(&a) { +// new_addrs.push(a); +// } +// } + +// if let Some(v) = running.distributes.get_mut(&peer_id) { +// v.2 = true; +// results.rpcs.push(device_rpc::device_online(*pid, v.1)); +// (remote_height, remote_event, new_addrs) +// } else { +// let mut device = Device::new(device_name, device_info, peer_id); +// device.insert(&db)?; +// db.close()?; +// running +// .distributes +// .insert(peer_id, (addr.clone(), device.id, true)); +// results.rpcs.push(device_rpc::device_create(*pid, &device)); +// results +// .rpcs +// .push(device_rpc::device_online(*pid, device.id)); +// (remote_height, remote_event, new_addrs) +// } +// } +// GroupConnect::Connect(remote_height, remote_event) => { +// if self +// .runnings +// .get(pid) +// .unwrap() // safe, checked +// .distributes +// .contains_key(&peer_id) +// { +// if is_connect { +// results.groups.push((*pid, self.connect_result(pid, addr)?)); +// } +// } else { +// if is_connect { +// results.groups.push((*pid, self.create_message(pid, addr)?)); +// } +// return Ok(()); +// } + +// let v = self.running_mut(pid)?; +// let did = v.add_online(&peer_id)?; +// results.rpcs.push(device_rpc::device_online(*pid, did)); +// (remote_height, remote_event, vec![]) +// } +// }; + +// let account = self.account(pid)?; +// if account.own_height != remote_height || account.event != remote_event { +// results.groups.push(( +// *pid, +// self.sync_message(pid, peer_id, 1, account.own_height)?, +// )); +// } + +// // connect to others. +// for addr in others { +// results +// .groups +// .push((*pid, self.create_message(pid, Peer::peer(addr))?)); +// } + +// Ok(()) +// } +// } + impl Group { - pub async fn init( - secret: [u8; 32], - sender: Sender, - addr: PeerId, - accounts: HashMap, - base: PathBuf, - ) -> Result { - Ok(Group { - secret, - sender, - addr, + pub fn init(accounts: HashMap) -> Group { + Group { accounts, - base, - runnings: HashMap::new(), - }) + keypair: PeerKey::default(), + device_name: String::new(), + device_info: String::new(), + distributes: vec![], + uptime: 0, + } } - pub fn addr(&self) -> &PeerId { - &self.addr + pub fn db_key(&self, pid: &PeerId) -> Result { + Ok(self.account(pid)?.plainkey()) } - pub fn base(&self) -> &PathBuf { - &self.base + pub fn online(&mut self, peer: &Peer) -> Result { + for i in self.distributes.iter_mut() { + if &i.0 == peer { + i.2 = true; + return Ok(i.1); + } + } + Err(anyhow!("missing distribute device")) } - pub fn sender(&self) -> Sender { - self.sender.clone() + pub fn offline(&mut self, peer: &Peer) -> Result { + for i in self.distributes.iter_mut() { + if &i.0 == peer { + i.2 = false; + return Ok(i.1); + } + } + Err(anyhow!("missing distribute device")) } - pub fn check_lock(&self, gid: &GroupId, lock: &str) -> bool { - if let Some(account) = self.accounts.get(gid) { + pub fn check_lock(&self, pid: &PeerId, lock: &str) -> bool { + if let Some(account) = self.accounts.get(pid) { account.check_lock(lock).is_ok() } else { false } } - pub fn account(&self, gid: &GroupId) -> Result<&Account> { - if let Some(account) = self.accounts.get(gid) { + pub fn account(&self, pid: &PeerId) -> Result<&Account> { + if let Some(account) = self.accounts.get(pid) { Ok(account) } else { - Err(anyhow!("user missing")) + Err(anyhow!("account missing")) } } - pub fn account_mut(&mut self, gid: &GroupId) -> Result<&mut Account> { - if let Some(account) = self.accounts.get_mut(gid) { + pub fn account_mut(&mut self, pid: &PeerId) -> Result<&mut Account> { + if let Some(account) = self.accounts.get_mut(pid) { Ok(account) } else { - Err(anyhow!("user missing")) - } - } - - pub fn running(&self, gid: &GroupId) -> Result<&RunningAccount> { - if let Some(running) = self.runnings.get(gid) { - Ok(running) - } else { - Err(anyhow!("user missing")) - } - } - - pub fn running_mut(&mut self, gid: &GroupId) -> Result<&mut RunningAccount> { - if let Some(running) = self.runnings.get_mut(gid) { - Ok(running) - } else { - Err(anyhow!("user missing")) - } - } - - pub fn prove_addr(&self, mgid: &GroupId, raddr: &PeerId) -> Result { - let running = self.running(mgid)?; - Ok(Proof::prove(&running.keypair, &self.addr, raddr)) - } - - pub fn uptime(&self, gid: &GroupId) -> Result { - self.running(gid).map(|v| v.uptime) - } - - pub fn list_running_user(&self) -> Vec { - self.runnings.keys().map(|d| *d).collect() - } - - pub fn distribute_conns(&self, gid: &GroupId) -> Vec { - let mut vecs = vec![]; - if let Some(running) = &self.runnings.get(gid) { - for (addr, (peer, _, _)) in &running.distributes { - if addr != &self.addr { - if let Ok(s) = self.connect_message(gid, peer.clone()) { - vecs.push(s); - } - } - } + Err(anyhow!("account missing")) } - vecs } - pub fn all_distribute_conns(&self) -> HashMap> { - let mut conns = HashMap::new(); - for (mgid, running) in &self.runnings { - let mut vecs = vec![]; - for (addr, (peer, _, _)) in &running.distributes { - if addr != &self.addr { - if let Ok(s) = self.connect_message(mgid, peer.clone()) { - vecs.push(s); - } - } - } - conns.insert(*mgid, vecs); - } - conns - } - - pub fn online_devices(&self, gid: &GroupId, mut devices: Vec) -> Vec { - if let Some(running) = self.runnings.get(gid) { - for (addr, (_peer, _id, online)) in &running.distributes { - if *online { - for device in devices.iter_mut() { - if device.addr == *addr { - device.online = true; - } - } - } - } - } - - devices - } - - pub fn remove_all_running(&mut self) -> HashMap { - let mut addrs: HashMap = HashMap::new(); - for (_, running) in self.runnings.drain() { - for (addr, (_peer, _id, online)) in running.distributes { - if addr != self.addr && online { - addrs.insert(addr, ()); - } - } - } - addrs - } - - pub fn remove_running(&mut self, gid: &GroupId) -> HashMap { - // check close the stable connection. - let mut addrs: HashMap = HashMap::new(); - if let Some(running) = self.runnings.remove(gid) { - for (addr, (_peer, _id, online)) in running.distributes { - if addr != self.addr && online { - addrs.insert(addr, ()); - } - } - - // check if other stable connection. - for other_running in self.runnings.values() { - for (addr, (_peer, _id, online)) in &other_running.distributes { - if *online && addrs.contains_key(addr) { - addrs.remove(addr); - } - } - } - } - - addrs - } - - pub fn add_running(&mut self, gid: &GroupId, lock: &str) -> Result<(i64, bool)> { - let (keypair, id, key) = if let Some(u) = self.accounts.get_mut(gid) { - let keypair = u.secret(&self.secret, lock)?; - u.cache_plainkey(&self.secret, lock)?; - (keypair, u.id, u.plainkey()) + // pub fn running(&self, pid: &PeerId) -> Result<&RunningAccount> { + // if let Some(running) = self.runnings.get(pid) { + // Ok(running) + // } else { + // Err(anyhow!("user missing")) + // } + // } + + // pub fn running_mut(&mut self, pid: &PeerId) -> Result<&mut RunningAccount> { + // if let Some(running) = self.runnings.get_mut(pid) { + // Ok(running) + // } else { + // Err(anyhow!("user missing")) + // } + // } + + // pub fn prove_addr(&self, mpid: &PeerId, raddr: &PeerId) -> Result { + // let running = self.running(mpid)?; + // Ok(Proof::prove(&running.keypair, &self.addr, raddr)) + // } + + // pub fn uptime(&self, pid: &PeerId) -> Result { + // self.running(pid).map(|v| v.uptime) + // } + + // pub fn list_running_user(&self) -> Vec { + // self.runnings.keys().map(|d| *d).collect() + // } + + // pub fn distribute_conns(&self, pid: &PeerId) -> Vec { + // let mut vecs = vec![]; + // if let Some(running) = &self.runnings.get(pid) { + // for (addr, (peer, _, _)) in &running.distributes { + // if addr != &self.addr { + // if let Ok(s) = self.connect_message(pid, peer.clone()) { + // vecs.push(s); + // } + // } + // } + // } + // vecs + // } + + // pub fn all_distribute_conns(&self) -> HashMap> { + // let mut conns = HashMap::new(); + // for (mpid, running) in &self.runnings { + // let mut vecs = vec![]; + // for (addr, (peer, _, _)) in &running.distributes { + // if addr != &self.addr { + // if let Ok(s) = self.connect_message(mpid, peer.clone()) { + // vecs.push(s); + // } + // } + // } + // conns.insert(*mpid, vecs); + // } + // conns + // } + + // pub fn online_devices(&self, pid: &PeerId, mut devices: Vec) -> Vec { + // if let Some(running) = self.runnings.get(pid) { + // for (addr, (_peer, _id, online)) in &running.distributes { + // if *online { + // for device in devices.iter_mut() { + // if device.addr == *addr { + // device.online = true; + // } + // } + // } + // } + // } + + // devices + // } + + // pub fn remove_all_running(&mut self) -> HashMap { + // let mut addrs: HashMap = HashMap::new(); + // for (_, running) in self.runnings.drain() { + // for (addr, (_peer, _id, online)) in running.distributes { + // if addr != self.addr && online { + // addrs.insert(addr, ()); + // } + // } + // } + // addrs + // } + + // pub fn remove_running(&mut self, pid: &PeerId) -> HashMap { + // // check close the stable connection. + // let mut addrs: HashMap = HashMap::new(); + // if let Some(running) = self.runnings.remove(pid) { + // for (addr, (_peer, _id, online)) in running.distributes { + // if addr != self.addr && online { + // addrs.insert(addr, ()); + // } + // } + + // // check if other stable connection. + // for other_running in self.runnings.values() { + // for (addr, (_peer, _id, online)) in &other_running.distributes { + // if *online && addrs.contains_key(addr) { + // addrs.remove(addr); + // } + // } + // } + // } + + // addrs + // } + + /// reset group info when change account. + pub fn reset( + &mut self, + pid: &PeerId, + lock: &str, + base: &PathBuf, + secret: &[u8], + ) -> Result<(u64, u64)> { + let (keypair, pheight, oheight, key) = if let Some(u) = self.accounts.get_mut(pid) { + let keypair = u.secret(secret, lock)?; + u.cache_plainkey(secret, lock)?; + (keypair, u.pub_height, u.own_height, u.plainkey()) } else { return Err(anyhow!("user missing.")); }; - if !self.runnings.contains_key(gid) { - // load devices to runnings. - let running = RunningAccount::init(keypair, &self.base, &key, gid)?; - self.runnings.insert(gid.clone(), running); - Ok((id, false)) - } else { - Ok((id, true)) - } - } - - pub fn clone_user(&self, gid: &GroupId) -> Result { - if let Some(u) = self.accounts.get(gid) { - Ok(User::new( - u.gid, - self.addr, - u.name.clone(), - u.avatar.clone(), - u.wallet.clone(), - u.pub_height, - )) - } else { - Err(anyhow!("user missing.")) - } - } + self.keypair = keypair; - pub fn username(&self, gid: &GroupId) -> Result { - if let Some(u) = self.accounts.get(gid) { - Ok(u.name.clone()) - } else { - Err(anyhow!("user missing.")) - } - } + let db = consensus_db(base, pid, &self.db_key(pid)?)?; + self.distributes = Device::distributes(&db)?; - pub fn list_users(&self) -> &HashMap { + let (device_name, device_info) = Device::device_info(&db)?; + db.close()?; + self.device_name = device_name; + self.device_info = device_info; + + let start = SystemTime::now(); + self.uptime = start + .duration_since(UNIX_EPOCH) + .map(|s| s.as_secs()) + .unwrap_or(0) as u32; // safe for all life. + + Ok((pheight, oheight)) + } + + // pub fn clone_user(&self, pid: &PeerId) -> Result { + // if let Some(u) = self.accounts.get(pid) { + // Ok(User::new( + // u.pid, + // self.addr, + // u.name.clone(), + // u.avatar.clone(), + // u.wallet.clone(), + // u.pub_height, + // )) + // } else { + // Err(anyhow!("user missing.")) + // } + // } + + // pub fn username(&self, pid: &PeerId) -> Result { + // if let Some(u) = self.accounts.get(pid) { + // Ok(u.name.clone()) + // } else { + // Err(anyhow!("user missing.")) + // } + // } + + pub fn list_accounts(&self) -> &HashMap { &self.accounts } @@ -470,11 +473,13 @@ impl Group { name: &str, lock: &str, avatar_bytes: Vec, - ) -> Result<(i64, GroupId)> { + base: &PathBuf, + secret: &[u8], + ) -> Result<(i64, PeerId)> { let account_index = self.accounts.len() as u32; let (mut account, sk) = Account::generate( account_index, - &self.secret, + secret, lang, seed, pass, @@ -482,41 +487,41 @@ impl Group { lock, avatar_bytes, )?; - let account_id = account.gid; + let account_id = account.pid; if let Some(u) = self.accounts.get(&account_id) { - let running = RunningAccount::init(sk, &self.base, &account.plainkey(), &account_id)?; - self.runnings.insert(account_id, running); return Ok((u.id, account_id)); } - account_init(&self.base, &account.plainkey(), &account.gid).await?; + account_init(base, &account.plainkey(), &account.pid).await?; - let account_db = self.account_db()?; + let account_db = account_db(base, secret)?; account.insert(&account_db)?; account_db.close()?; let account_did = account.id; let key = account.plainkey(); - let _ = write_avatar(&self.base, &account_id, &account_id, &account.avatar).await; - self.accounts.insert(account.gid, account); + let _ = write_avatar(base, &account_id, &account_id, &account.avatar).await; + self.accounts.insert(account.pid, account); let (device_name, device_info) = device_info(); - let mut device = Device::new(device_name, device_info, self.addr); - let db = self.consensus_db(&account_id)?; + let mut device = Device::new(device_name, device_info, Peer::peer(account_id)); + let db = consensus_db(base, &account_id, &self.db_key(&account_id)?)?; device.insert(&db)?; db.close()?; - self.runnings.insert( - account_id, - RunningAccount::init(sk, &self.base, &key, &account_id)?, - ); - Ok((account_did, account_id)) } - pub fn update_account(&mut self, gid: GroupId, name: &str, avatar: Vec) -> Result<()> { - let account_db = self.account_db()?; - let account = self.account_mut(&gid)?; + pub fn update_account( + &mut self, + pid: PeerId, + name: &str, + avatar: Vec, + base: &PathBuf, + secret: &[u8], + ) -> Result<()> { + let account_db = account_db(base, secret)?; + let account = self.account_mut(&pid)?; account.name = name.to_owned(); if avatar.len() > 0 { account.avatar = avatar; @@ -526,446 +531,425 @@ impl Group { account_db.close() } - pub fn mnemonic(&self, gid: &GroupId, lock: &str) -> Result { - if let Some(u) = self.accounts.get(gid) { - u.mnemonic(&self.secret, lock) - } else { - Err(anyhow!("user missing.")) - } - } - - pub fn pin(&mut self, gid: &GroupId, lock: &str, new: &str) -> Result<()> { - let account_db = self.account_db()?; - if let Some(u) = self.accounts.get_mut(gid) { - u.pin(&self.secret, lock, new)?; - u.update(&account_db)?; - account_db.close() - } else { - Err(anyhow!("user missing.")) - } - } - - pub fn encrypt(&self, gid: &GroupId, lock: &str, bytes: &[u8]) -> Result> { - let ckey = &self.account(gid)?.encrypt; - encrypt(&self.secret, lock, ckey, bytes) - } - pub fn decrypt(&self, gid: &GroupId, lock: &str, bytes: &[u8]) -> Result> { - let ckey = &self.account(gid)?.encrypt; - decrypt(&self.secret, lock, ckey, bytes) - } - - pub fn create_message(&self, gid: &GroupId, addr: Peer) -> Result { - let user = self.clone_user(gid)?; - let account = self.account(gid)?; - let height = account.own_height; - let event = account.event; - let proof = self.prove_addr(gid, &addr.id)?; - let running = self.running(gid)?; - - Ok(SendType::Connect( - 0, - addr, - bincode::serialize(&GroupConnect::Create( - proof, - user, - height, - event, - running.device_name.clone(), - running.device_info.clone(), - running.distributes.keys().cloned().collect(), - )) - .unwrap_or(vec![]), - )) + pub fn mnemonic(&self, pid: &PeerId, lock: &str, secret: &[u8]) -> Result { + let account = self.account(pid)?; + account.mnemonic(secret, lock) } - pub fn connect_message(&self, gid: &GroupId, addr: Peer) -> Result { - let account = self.account(gid)?; - let height = account.own_height; - let event = account.event; - let data = bincode::serialize(&GroupConnect::Connect(height, event)).unwrap_or(vec![]); - Ok(SendType::Connect(0, addr, data)) - } - - pub fn connect_result(&self, gid: &GroupId, addr: Peer) -> Result { - let account = self.account(gid)?; - let height = account.own_height; - let event = account.event; - let data = bincode::serialize(&GroupConnect::Connect(height, event)).unwrap_or(vec![]); - Ok(SendType::Result(0, addr, true, false, data)) - } - - pub fn agree_message(&self, gid: &GroupId, addr: Peer) -> Result { - let account = self.account(gid)?; - let height = account.own_height; - let event = account.event; - let me = self.clone_user(gid)?; - let proof = self.prove_addr(gid, &addr.id)?; - let running = self.running(gid)?; - - Ok(SendType::Result( - 0, - addr, - true, - false, - bincode::serialize(&GroupConnect::Create( - proof, - me, - height, - event, - running.device_name.clone(), - running.device_info.clone(), - running.distributes.keys().cloned().collect(), - )) - .unwrap_or(vec![]), - )) - } - - fn ancestor(from: u64, to: u64) -> (Vec, bool) { - let space = to - from; - let step = space / 8; - if step == 0 { - ((from..to + 1).map(|i| i).collect(), true) - } else { - let mut vec: Vec = (1..8).map(|i| step * i + from).collect(); - vec.push(to); - (vec, false) - } - } - - pub fn sync_message( - &self, - gid: &GroupId, - addr: PeerId, - from: u64, - to: u64, - ) -> Result { - let (ancestors, hashes, is_min) = if to >= from { - let (ancestors, is_min) = Self::ancestor(from, to); - let db = self.consensus_db(gid)?; - let hashes = crate::consensus::Event::get_assign_hash(&db, &ancestors)?; - db.close()?; - (ancestors, hashes, is_min) - } else { - (vec![], vec![], true) - }; - - let event = GroupEvent::SyncCheck(ancestors, hashes, is_min); - let data = bincode::serialize(&event).unwrap_or(vec![]); - Ok(SendType::Event(0, addr, data)) - } - - pub fn event_message(&self, addr: PeerId, event: &GroupEvent) -> Result { - let data = bincode::serialize(event).unwrap_or(vec![]); - Ok(SendType::Event(0, addr, data)) - } - - pub fn broadcast( + pub fn pin( &mut self, - gid: &GroupId, - event: InnerEvent, - path: i64, - row: i64, - results: &mut HandleResult, + pid: &PeerId, + lock: &str, + new: &str, + base: &PathBuf, + secret: &[u8], ) -> Result<()> { - let db = self.consensus_db(gid)?; - let account_db = self.account_db()?; - - let account = self.account_mut(gid)?; - let pre_event = account.event; - let eheight = account.own_height + 1; - let eid = event.generate_event_id(); - - Event::merge(&db, eid, path, row, eheight)?; - drop(db); - - account.update_consensus(&account_db, eheight, eid)?; - account_db.close()?; - drop(account); - - let e = GroupEvent::Event(eheight, eid, pre_event, event); - let data = bincode::serialize(&e).unwrap_or(vec![]); - let running = self.running(gid)?; - for (addr, (_peer, _id, online)) in &running.distributes { - if *online { - let msg = SendType::Event(0, *addr, data.clone()); - results.groups.push((*gid, msg)) - } - } - Ok(()) + let account_db = account_db(base, secret)?; + let account = self.account_mut(pid)?; + account.pin(secret, lock, new)?; + account.update(&account_db)?; + account_db.close() } - pub fn _status( - &mut self, - gid: &GroupId, - event: StatusEvent, - results: &mut HandleResult, - ) -> Result<()> { - let running = self.running(gid)?; - let data = bincode::serialize(&GroupEvent::Status(event)).unwrap_or(vec![]); - for (addr, (_peer, _id, online)) in &running.distributes { - if *online { - let msg = SendType::Event(0, *addr, data.clone()); - results.groups.push((*gid, msg)) - } - } - Ok(()) - } + // pub fn encrypt(&self, pid: &PeerId, lock: &str, bytes: &[u8]) -> Result> { + // let ckey = &self.account(pid)?.encrypt; + // encrypt(&self.secret, lock, ckey, bytes) + // } + // pub fn decrypt(&self, pid: &PeerId, lock: &str, bytes: &[u8]) -> Result> { + // let ckey = &self.account(pid)?.encrypt; + // decrypt(&self.secret, lock, ckey, bytes) + // } + + // pub fn create_message(&self, pid: &PeerId, addr: Peer) -> Result { + // let user = self.clone_user(pid)?; + // let account = self.account(pid)?; + // let height = account.own_height; + // let event = account.event; + // let proof = self.prove_addr(pid, &addr.id)?; + // let running = self.running(pid)?; + + // Ok(SendType::Connect( + // 0, + // addr, + // bincode::serialize(&GroupConnect::Create( + // proof, + // user, + // height, + // event, + // running.device_name.clone(), + // running.device_info.clone(), + // running.distributes.keys().cloned().collect(), + // )) + // .unwrap_or(vec![]), + // )) + // } + + // pub fn connect_message(&self, pid: &PeerId, addr: Peer) -> Result { + // let account = self.account(pid)?; + // let height = account.own_height; + // let event = account.event; + // let data = bincode::serialize(&GroupConnect::Connect(height, event)).unwrap_or(vec![]); + // Ok(SendType::Connect(0, addr, data)) + // } + + // pub fn connect_result(&self, pid: &PeerId, addr: Peer) -> Result { + // let account = self.account(pid)?; + // let height = account.own_height; + // let event = account.event; + // let data = bincode::serialize(&GroupConnect::Connect(height, event)).unwrap_or(vec![]); + // Ok(SendType::Result(0, addr, true, false, data)) + // } + + // pub fn agree_message(&self, pid: &PeerId, addr: Peer) -> Result { + // let account = self.account(pid)?; + // let height = account.own_height; + // let event = account.event; + // let me = self.clone_user(pid)?; + // let proof = self.prove_addr(pid, &addr.id)?; + // let running = self.running(pid)?; + + // Ok(SendType::Result( + // 0, + // addr, + // true, + // false, + // bincode::serialize(&GroupConnect::Create( + // proof, + // me, + // height, + // event, + // running.device_name.clone(), + // running.device_info.clone(), + // running.distributes.keys().cloned().collect(), + // )) + // .unwrap_or(vec![]), + // )) + // } + + // fn ancestor(from: u64, to: u64) -> (Vec, bool) { + // let space = to - from; + // let step = space / 8; + // if step == 0 { + // ((from..to + 1).map(|i| i).collect(), true) + // } else { + // let mut vec: Vec = (1..8).map(|i| step * i + from).collect(); + // vec.push(to); + // (vec, false) + // } + // } + + // pub fn sync_message(&self, pid: &PeerId, addr: PeerId, from: u64, to: u64) -> Result { + // let (ancestors, hashes, is_min) = if to >= from { + // let (ancestors, is_min) = Self::ancestor(from, to); + // let db = self.consensus_db(pid)?; + // let hashes = crate::consensus::Event::get_assign_hash(&db, &ancestors)?; + // db.close()?; + // (ancestors, hashes, is_min) + // } else { + // (vec![], vec![], true) + // }; + + // let event = GroupEvent::SyncCheck(ancestors, hashes, is_min); + // let data = bincode::serialize(&event).unwrap_or(vec![]); + // Ok(SendType::Event(0, addr, data)) + // } + + // pub fn event_message(&self, addr: PeerId, event: &GroupEvent) -> Result { + // let data = bincode::serialize(event).unwrap_or(vec![]); + // Ok(SendType::Event(0, addr, data)) + // } + + // pub fn broadcast( + // &mut self, + // pid: &PeerId, + // event: InnerEvent, + // path: i64, + // row: i64, + // results: &mut HandleResult, + // ) -> Result<()> { + // let db = self.consensus_db(pid)?; + // let account_db = self.account_db()?; + + // let account = self.account_mut(pid)?; + // let pre_event = account.event; + // let eheight = account.own_height + 1; + // let eid = event.generate_event_id(); + + // Event::merge(&db, eid, path, row, eheight)?; + // drop(db); + + // account.update_consensus(&account_db, eheight, eid)?; + // account_db.close()?; + // drop(account); + + // let e = GroupEvent::Event(eheight, eid, pre_event, event); + // let data = bincode::serialize(&e).unwrap_or(vec![]); + // let running = self.running(pid)?; + // for (addr, (_peer, _id, online)) in &running.distributes { + // if *online { + // let msg = SendType::Event(0, *addr, data.clone()); + // results.groups.push((*pid, msg)) + // } + // } + // Ok(()) + // } + + // pub fn _status( + // &mut self, + // pid: &PeerId, + // event: StatusEvent, + // results: &mut HandleResult, + // ) -> Result<()> { + // let running = self.running(pid)?; + // let data = bincode::serialize(&GroupEvent::Status(event)).unwrap_or(vec![]); + // for (addr, (_peer, _id, online)) in &running.distributes { + // if *online { + // let msg = SendType::Event(0, *addr, data.clone()); + // results.groups.push((*pid, msg)) + // } + // } + // Ok(()) + // } } impl Group { - fn db_key(&self, gid: &GroupId) -> Result { - Ok(self.account(gid)?.plainkey()) - } - - pub(crate) fn account_db(&self) -> Result { - let mut db_path = self.base.clone(); - db_path.push(ACCOUNT_DB); - DStorage::open(db_path, &hex::encode(&self.secret)) - } - - pub(crate) fn consensus_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(CONSENSUS_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn session_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(SESSION_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn chat_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(CHAT_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn file_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(FILE_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn _service_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(SERVICE_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn jarvis_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(JARVIS_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn group_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(GROUP_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn _dao_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(DAO_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn domain_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(DOMAIN_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn wallet_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(WALLET_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } - - pub(crate) fn _cloud_db(&self, gid: &GroupId) -> Result { - let mut db_path = self.base.clone(); - db_path.push(gid.to_hex()); - db_path.push(CLOUD_DB); - DStorage::open(db_path, &self.db_key(gid)?) - } + // pub(crate) fn session_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(SESSION_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn chat_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(CHAT_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn file_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(FILE_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn _service_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(SERVICE_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn jarvis_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(JARVIS_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn group_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(GROUP_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn _dao_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(DAO_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn domain_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(DOMAIN_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn wallet_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(WALLET_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } + + // pub(crate) fn _cloud_db(&self, pid: &PeerId) -> Result { + // let mut db_path = self.base.clone(); + // db_path.push(pid.to_hex()); + // db_path.push(CLOUD_DB); + // DStorage::open(db_path, &self.db_key(pid)?) + // } } -impl GroupEvent { - pub async fn handle( - group: &mut Group, - event: GroupEvent, - gid: GroupId, - addr: PeerId, - layer: &Arc>, - uid: u64, - ) -> Result { - let mut results = HandleResult::new(); - match event { - GroupEvent::DeviceUpdate(_at, _name) => { - // TODO - } - GroupEvent::DeviceDelete(_at) => { - // TODO - } - GroupEvent::DeviceOffline => { - let v = group.running_mut(&gid)?; - let did = v.offline(&addr)?; - results.rpcs.push(device_rpc::device_offline(gid, did)); - } - GroupEvent::StatusRequest => { - let (cpu_n, mem_s, swap_s, disk_s, cpu_p, mem_p, swap_p, disk_p) = - local_device_status(); - results.groups.push(( - gid, - SendType::Event( - 0, - addr, - bincode::serialize(&GroupEvent::StatusResponse( - cpu_n, - mem_s, - swap_s, - disk_s, - cpu_p, - mem_p, - swap_p, - disk_p, - group.uptime(&gid)?, - )) - .unwrap_or(vec![]), - ), - )) - } - GroupEvent::StatusResponse( - cpu_n, - mem_s, - swap_s, - disk_s, - cpu_p, - mem_p, - swap_p, - disk_p, - uptime, - ) => results.rpcs.push(device_rpc::device_status( - gid, cpu_n, mem_s, swap_s, disk_s, cpu_p, mem_p, swap_p, disk_p, uptime, - )), - GroupEvent::Event(eheight, eid, pre, inner_event) => { - inner_event.handle(group, gid, addr, eheight, eid, pre, &mut results, layer)?; - } - GroupEvent::Status(status_event) => { - status_event.handle(group, gid, addr, &mut results, layer, uid)?; - } - GroupEvent::SyncCheck(ancestors, hashes, is_min) => { - println!("sync check: {:?}", ancestors); - let account = group.account(&gid)?; - if ancestors.len() == 0 || hashes.len() == 0 { - return Ok(results); - } - - // remote is new need it handle. - if hashes[0] == EventId::default() { - return Ok(results); - } - - let remote_height = ancestors.last().map(|v| *v).unwrap_or(0); - let remote_event = hashes.last().map(|v| *v).unwrap_or(EventId::default()); - if account.own_height != remote_height || account.event != remote_event { - // check ancestor and merge. - let db = group.consensus_db(&gid)?; - let ours = crate::consensus::Event::get_assign_hash(&db, &ancestors)?; - drop(db); - - if ours.len() == 0 { - let event = GroupEvent::SyncRequest(1, remote_height); - let data = bincode::serialize(&event).unwrap_or(vec![]); - results.groups.push((gid, SendType::Event(0, addr, data))); - return Ok(results); - } - - let mut ancestor = 0u64; - for i in 0..ancestors.len() { - if hashes[i] != ours[i] { - if i == 0 { - ancestor = ancestors[0]; - break; - } - - if ancestors[i - 1] == ancestors[i] + 1 { - ancestor = ancestors[i - 1]; - } else { - if is_min { - ancestor = ancestors[i - 1]; - } else { - results.groups.push(( - gid, - group.sync_message( - &gid, - addr, - ancestors[i - 1], - ancestors[i], - )?, - )); - return Ok(results); - } - } - - break; - } - } - - if ancestor != 0 { - let event = GroupEvent::SyncRequest(ancestor, remote_height); - let data = bincode::serialize(&event).unwrap_or(vec![]); - results.groups.push((gid, SendType::Event(0, addr, data))); - } else { - results.groups.push(( - gid, - group.sync_message(&gid, addr, remote_height, account.own_height)?, - )); - } - } - } - GroupEvent::SyncRequest(from, to) => { - println!("====== DEBUG Sync Request: from: {} to {}", from, to); - // every time sync MAX is 100. - let last_to = if to - from > 100 { to - 100 } else { to }; - let sync_events = SyncEvent::sync( - &group, - &group.base, - &gid, - group.account(&gid)?, - from, - last_to, - ) - .await?; - let event = GroupEvent::SyncResponse(from, last_to, to, sync_events); - let data = bincode::serialize(&event).unwrap_or(vec![]); - results.groups.push((gid, SendType::Event(0, addr, data))); - } - GroupEvent::SyncResponse(from, last_to, to, events) => { - println!( - "====== DEBUG Sync Response: from: {} last {}, to {}", - from, last_to, to - ); - if last_to < to { - let event = GroupEvent::SyncRequest(last_to + 1, to); - let data = bincode::serialize(&event).unwrap_or(vec![]); - results.groups.push((gid, SendType::Event(0, addr, data))); - } - SyncEvent::handle(gid, from, last_to, events, group, layer, &mut results, addr)?; - } - } - - Ok(results) - } -} +// impl GroupEvent { +// pub async fn handle( +// group: &mut Group, +// event: GroupEvent, +// pid: PeerId, +// addr: PeerId, +// //layer: &Arc>, +// uid: u64, +// ) -> Result { +// let mut results = HandleResult::new(); +// match event { +// GroupEvent::DeviceUpdate(_at, _name) => { +// // TODO +// } +// GroupEvent::DeviceDelete(_at) => { +// // TODO +// } +// GroupEvent::DeviceOffline => { +// let v = group.running_mut(&pid)?; +// let did = v.offline(&addr)?; +// results.rpcs.push(device_rpc::device_offline(pid, did)); +// } +// GroupEvent::StatusRequest => { +// let (cpu_n, mem_s, swap_s, disk_s, cpu_p, mem_p, swap_p, disk_p) = +// local_device_status(); +// results.groups.push(( +// pid, +// SendType::Event( +// 0, +// addr, +// bincode::serialize(&GroupEvent::StatusResponse( +// cpu_n, +// mem_s, +// swap_s, +// disk_s, +// cpu_p, +// mem_p, +// swap_p, +// disk_p, +// group.uptime(&pid)?, +// )) +// .unwrap_or(vec![]), +// ), +// )) +// } +// GroupEvent::StatusResponse( +// cpu_n, +// mem_s, +// swap_s, +// disk_s, +// cpu_p, +// mem_p, +// swap_p, +// disk_p, +// uptime, +// ) => results.rpcs.push(device_rpc::device_status( +// pid, cpu_n, mem_s, swap_s, disk_s, cpu_p, mem_p, swap_p, disk_p, uptime, +// )), +// GroupEvent::Event(eheight, eid, pre) => { +// //inner_event.handle(group, pid, addr, eheight, eid, pre, &mut results, layer)?; +// } +// GroupEvent::Status => { +// //status_event.handle(group, pid, addr, &mut results, layer, uid)?; +// } +// GroupEvent::SyncCheck(ancestors, hashes, is_min) => { +// println!("sync check: {:?}", ancestors); +// let account = group.account(&pid)?; +// if ancestors.len() == 0 || hashes.len() == 0 { +// return Ok(results); +// } + +// // remote is new need it handle. +// if hashes[0] == EventId::default() { +// return Ok(results); +// } + +// let remote_height = ancestors.last().map(|v| *v).unwrap_or(0); +// let remote_event = hashes.last().map(|v| *v).unwrap_or(EventId::default()); +// if account.own_height != remote_height || account.event != remote_event { +// // check ancestor and merge. +// let db = group.consensus_db(&pid)?; +// let ours = vec![]; +// //let ours = crate::consensus::Event::get_assign_hash(&db, &ancestors)?; +// drop(db); + +// if ours.len() == 0 { +// let event = GroupEvent::SyncRequest(1, remote_height); +// let data = bincode::serialize(&event).unwrap_or(vec![]); +// results.groups.push((pid, SendType::Event(0, addr, data))); +// return Ok(results); +// } + +// let mut ancestor = 0u64; +// for i in 0..ancestors.len() { +// if hashes[i] != ours[i] { +// if i == 0 { +// ancestor = ancestors[0]; +// break; +// } + +// if ancestors[i - 1] == ancestors[i] + 1 { +// ancestor = ancestors[i - 1]; +// } else { +// if is_min { +// ancestor = ancestors[i - 1]; +// } else { +// results.groups.push(( +// pid, +// group.sync_message( +// &pid, +// addr, +// ancestors[i - 1], +// ancestors[i], +// )?, +// )); +// return Ok(results); +// } +// } + +// break; +// } +// } + +// if ancestor != 0 { +// let event = GroupEvent::SyncRequest(ancestor, remote_height); +// let data = bincode::serialize(&event).unwrap_or(vec![]); +// results.groups.push((pid, SendType::Event(0, addr, data))); +// } else { +// results.groups.push(( +// pid, +// group.sync_message(&pid, addr, remote_height, account.own_height)?, +// )); +// } +// } +// } +// GroupEvent::SyncRequest(from, to) => { +// println!("====== DEBUG Sync Request: from: {} to {}", from, to); +// // every time sync MAX is 100. +// let last_to = if to - from > 100 { to - 100 } else { to }; +// // let sync_events = SyncEvent::sync( +// // &group, +// // &group.base, +// // &pid, +// // group.account(&pid)?, +// // from, +// // last_to, +// // ) +// // .await?; +// let event = GroupEvent::SyncResponse(from, last_to, to); +// let data = bincode::serialize(&event).unwrap_or(vec![]); +// results.groups.push((pid, SendType::Event(0, addr, data))); +// } +// GroupEvent::SyncResponse(from, last_to, to) => { +// println!( +// "====== DEBUG Sync Response: from: {} last {}, to {}", +// from, last_to, to +// ); +// if last_to < to { +// let event = GroupEvent::SyncRequest(last_to + 1, to); +// let data = bincode::serialize(&event).unwrap_or(vec![]); +// results.groups.push((pid, SendType::Event(0, addr, data))); +// } +// //SyncEvent::handle(pid, from, last_to, events, group, layer, &mut results, addr)?; +// } +// } + +// Ok(results) +// } +// } diff --git a/src/group/running.rs b/src/group/running.rs index 0e20a36..a9a4f3b 100644 --- a/src/group/running.rs +++ b/src/group/running.rs @@ -1,11 +1,7 @@ -use std::collections::HashMap; +use esse_primitives::id_to_str; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; -use tdn::types::{ - group::GroupId, - primitive::{Peer, PeerId, Result}, -}; -use tdn_did::Keypair; +use tdn::types::primitives::{Peer, PeerId, PeerKey, Result}; use tdn_storage::local::DStorage; use crate::apps::device::Device; @@ -13,21 +9,21 @@ use crate::migrate::CONSENSUS_DB; pub(crate) struct RunningAccount { /// secret keypair. - pub keypair: Keypair, + pub keypair: PeerKey, /// device's name. pub device_name: String, /// device's info. pub device_info: String, /// distribute connected devices. - pub distributes: HashMap, + pub distributes: Vec<(Peer, i64, bool)>, /// uptime pub uptime: u32, } impl RunningAccount { - pub fn init(keypair: Keypair, base: &PathBuf, key: &str, gid: &GroupId) -> Result { + pub fn init(keypair: PeerKey, base: &PathBuf, key: &str, pid: &PeerId) -> Result { let mut db_path = base.clone(); - db_path.push(gid.to_hex()); + db_path.push(id_to_str(&pid)); db_path.push(CONSENSUS_DB); let db = DStorage::open(db_path, key)?; let distributes = Device::distributes(&db)?; @@ -49,21 +45,23 @@ impl RunningAccount { }) } - pub fn add_online(&mut self, addr: &PeerId) -> Result { - if let Some(v) = self.distributes.get_mut(addr) { - v.2 = true; - Ok(v.1) - } else { - Err(anyhow!("device missing")) + pub fn online(&mut self, peer: &Peer) -> Result { + for i in self.distributes.iter_mut() { + if &i.0 == peer { + i.2 = true; + return Ok(i.1); + } } + Err(anyhow!("missing distribute device")) } - pub fn offline(&mut self, addr: &PeerId) -> Result { - if let Some(v) = self.distributes.get_mut(addr) { - v.2 = false; - Ok(v.1) - } else { - Err(anyhow!("device missing")) + pub fn offline(&mut self, peer: &Peer) -> Result { + for i in self.distributes.iter_mut() { + if &i.0 == peer { + i.2 = false; + return Ok(i.1); + } } + Err(anyhow!("missing distribute device")) } } diff --git a/src/layer.rs b/src/layer.rs index b44e79b..88c243e 100644 --- a/src/layer.rs +++ b/src/layer.rs @@ -5,15 +5,15 @@ use std::sync::Arc; use tdn::types::{ group::GroupId, message::SendType, - primitive::{HandleResult, Peer, PeerId, Result}, + primitives::{HandleResult, Peer, PeerId, Result}, }; use tokio::sync::RwLock; use crate::account::User; -use crate::apps::chat::{chat_conn, LayerEvent as ChatLayerEvent}; -use crate::apps::group::{group_conn, GROUP_ID}; +//use crate::apps::chat::{chat_conn, LayerEvent as ChatLayerEvent}; +//use crate::apps::group::{group_conn, GROUP_ID}; use crate::group::Group; -use crate::session::{Session, SessionType}; +//use crate::session::{Session, SessionType}; /// ESSE app's `BaseLayerEvent`. /// EVERY LAYER APP MUST EQUAL THE FIRST THREE FIELDS. @@ -29,157 +29,126 @@ pub(crate) enum LayerEvent { /// ESSE layers. pub(crate) struct Layer { - /// layer_gid (include account id, group chat id) => running_layer. - pub runnings: HashMap, - /// message delivery tracking. uuid, me_gid, db_id. - pub delivery: HashMap, - /// storage base path. - pub base: PathBuf, - /// self peer addr. - pub addr: PeerId, - /// group info. - pub group: Arc>, + /// running layers: (Layer_gid, layer sessions) + pub sessions: HashMap>, } impl Layer { - pub async fn init(base: PathBuf, addr: PeerId, group: Arc>) -> Result { - Ok(Layer { - base, - group, - addr, - runnings: HashMap::new(), - delivery: HashMap::new(), - }) - } - - pub fn base(&self) -> &PathBuf { - &self.base - } - - pub fn running(&self, gid: &GroupId) -> Result<&RunningLayer> { - self.runnings.get(gid).ok_or(anyhow!("not online")) - } - - pub fn running_mut(&mut self, gid: &GroupId) -> Result<&mut RunningLayer> { - self.runnings.get_mut(gid).ok_or(anyhow!("not online")) - } - - pub fn add_running( - &mut self, - gid: &GroupId, - owner: GroupId, - id: i64, - consensus: i64, - ) -> Result<()> { - if !self.runnings.contains_key(gid) { - self.runnings - .insert(*gid, RunningLayer::init(owner, id, consensus)); - } - - Ok(()) - } - - pub fn remove_running(&mut self, gid: &GroupId) -> HashMap { - // check close the stable connection. - let mut addrs: HashMap = HashMap::new(); - if let Some(running) = self.runnings.remove(gid) { - for (addr, fgid) in running.remove_onlines() { - addrs.insert(addr, fgid); - } - } - - let mut need_keep = vec![]; - for (_, running) in &self.runnings { - for addr in addrs.keys() { - if running.check_addr_online(addr) { - need_keep.push(*addr); - } - } - } - for i in need_keep { - addrs.remove(&i); - } - - addrs - } - - pub fn remove_all_running(&mut self) -> HashMap { - let mut addrs: HashMap = HashMap::new(); - for (_, running) in self.runnings.drain() { - for (addr, fgid) in running.remove_onlines() { - addrs.insert(addr, fgid); - } - } - addrs - } - - pub fn get_running_remote_id(&self, mgid: &GroupId, fgid: &GroupId) -> Result<(i64, i64)> { - debug!("onlines: {:?}, find: {:?}", self.runnings.keys(), mgid); - self.running(mgid)?.get_online_id(fgid) - } - - pub fn remove_online(&mut self, gid: &GroupId, fgid: &GroupId) -> Option { - self.running_mut(gid).ok()?.remove_online(fgid) - } - - pub async fn all_layer_conns(&self) -> Result>> { - let mut conns = HashMap::new(); - let group_lock = self.group.read().await; - for mgid in self.runnings.keys() { - let mut vecs = vec![]; - - let db = group_lock.session_db(&mgid)?; - let sessions = Session::list(&db)?; - drop(db); - - for s in sessions { - match s.s_type { - SessionType::Chat => { - let proof = group_lock.prove_addr(mgid, &s.addr)?; - vecs.push((s.gid, chat_conn(proof, Peer::peer(s.addr)))); - } - SessionType::Group => { - let proof = group_lock.prove_addr(mgid, &s.addr)?; - vecs.push((GROUP_ID, group_conn(proof, Peer::peer(s.addr), s.gid))); - } - _ => {} - } - } - - conns.insert(*mgid, vecs); - } - - Ok(conns) - } - - pub fn is_addr_online(&self, faddr: &PeerId) -> bool { - for (_, running) in &self.runnings { - if running.check_addr_online(faddr) { - return true; - } - } - return false; - } - - pub fn is_online(&self, gid: &GroupId, fgid: &GroupId) -> bool { - if let Some(running) = self.runnings.get(gid) { - running.is_online(fgid) - } else { - false - } - } - - pub fn broadcast(&self, user: User, results: &mut HandleResult) { - let gid = user.id; - let info = ChatLayerEvent::InfoRes(user); - let data = bincode::serialize(&info).unwrap_or(vec![]); - if let Some(running) = self.runnings.get(&gid) { - for (fgid, online) in &running.sessions { - let msg = SendType::Event(0, *online.online.addr(), data.clone()); - results.layers.push((gid, *fgid, msg)); - } - } - } + pub fn init() -> Layer { + // add all inner-service layers + // add all third-service layers + let mut sessions = HashMap::new(); + + // runnings.insert(CHAT_GROUP_ID, RunningLayer::init()); + + Layer { sessions } + } + + pub fn clear(&mut self) { + let _ = self.sessions.iter_mut().map(|(_, s)| s.clear()); + } + + // pub fn remove_running(&mut self, gid: &GroupId) -> HashMap { + // // check close the stable connection. + // let mut addrs: HashMap = HashMap::new(); + // if let Some(running) = self.runnings.remove(gid) { + // for (addr, fgid) in running.remove_onlines() { + // addrs.insert(addr, fgid); + // } + // } + + // let mut need_keep = vec![]; + // for (_, running) in &self.runnings { + // for addr in addrs.keys() { + // if running.check_addr_online(addr) { + // need_keep.push(*addr); + // } + // } + // } + // for i in need_keep { + // addrs.remove(&i); + // } + + // addrs + // } + + // pub fn remove_all_running(&mut self) -> HashMap { + // let mut addrs: HashMap = HashMap::new(); + // for (_, running) in self.runnings.drain() { + // for (addr, fgid) in running.remove_onlines() { + // addrs.insert(addr, fgid); + // } + // } + // addrs + // } + + // pub fn get_running_remote_id(&self, mgid: &GroupId, fgid: &GroupId) -> Result<(i64, i64)> { + // debug!("onlines: {:?}, find: {:?}", self.runnings.keys(), mgid); + // self.running(mgid)?.get_online_id(fgid) + // } + + // pub fn remove_online(&mut self, gid: &GroupId, fgid: &GroupId) -> Option { + // self.running_mut(gid).ok()?.remove_online(fgid) + // } + + // pub async fn all_layer_conns(&self) -> Result>> { + // let mut conns = HashMap::new(); + // let group_lock = self.group.read().await; + // for mgid in self.runnings.keys() { + // let mut vecs = vec![]; + + // let db = group_lock.session_db(&mgid)?; + // let sessions = Session::list(&db)?; + // drop(db); + + // for s in sessions { + // match s.s_type { + // SessionType::Chat => { + // let proof = group_lock.prove_addr(mgid, &s.addr)?; + // vecs.push((s.gid, chat_conn(proof, Peer::peer(s.addr)))); + // } + // SessionType::Group => { + // let proof = group_lock.prove_addr(mgid, &s.addr)?; + // vecs.push((GROUP_ID, group_conn(proof, Peer::peer(s.addr), s.gid))); + // } + // _ => {} + // } + // } + + // conns.insert(*mgid, vecs); + // } + + // Ok(conns) + // } + + // pub fn is_addr_online(&self, faddr: &PeerId) -> bool { + // for (_, running) in &self.runnings { + // if running.check_addr_online(faddr) { + // return true; + // } + // } + // return false; + // } + + // pub fn is_online(&self, gid: &GroupId, fgid: &GroupId) -> bool { + // if let Some(running) = self.runnings.get(gid) { + // running.is_online(fgid) + // } else { + // false + // } + // } + + // pub fn broadcast(&self, user: User, results: &mut HandleResult) { + // let gid = user.id; + // let info = ChatLayerEvent::InfoRes(user); + // let data = bincode::serialize(&info).unwrap_or(vec![]); + // if let Some(running) = self.runnings.get(&gid) { + // for (fgid, online) in &running.sessions { + // let msg = SendType::Event(0, *online.online.addr(), data.clone()); + // results.layers.push((gid, *fgid, msg)); + // } + // } + // } } /// online info. @@ -188,13 +157,13 @@ pub(crate) enum Online { /// connected to this device. Direct(PeerId), /// connected to other device. - _Relay(PeerId), + Relay(PeerId), } impl Online { fn addr(&self) -> &PeerId { match self { - Online::Direct(ref addr) | Online::_Relay(ref addr) => addr, + Online::Direct(ref addr) | Online::Relay(ref addr) => addr, } } } @@ -210,241 +179,236 @@ pub(crate) struct OnlineSession { pub remain: u16, // keep-alive remain minutes } -impl OnlineSession { - fn new(online: Online, db_id: i64, db_fid: i64) -> Self { - Self { - online, - db_id, - db_fid, - suspend_me: false, - suspend_remote: false, - remain: 0, - } - } - - fn close_suspend(&mut self) -> bool { - if self.suspend_me && self.suspend_remote { - if self.remain == 0 { - true - } else { - self.remain -= 1; - false - } - } else { - false - } - } -} - -pub(crate) struct RunningLayer { - owner: GroupId, // if is service it has owner account. - /// layer current database id. - id: i64, - /// layer current consensus height. - consensus: i64, - /// online group (friends/services) => (group's address, group's db id) - sessions: HashMap, +// impl OnlineSession { +// fn new(online: Online, db_id: i64, db_fid: i64) -> Self { +// Self { +// online, +// db_id, +// db_fid, +// suspend_me: false, +// suspend_remote: false, +// remain: 0, +// } +// } + +// fn close_suspend(&mut self) -> bool { +// if self.suspend_me && self.suspend_remote { +// if self.remain == 0 { +// true +// } else { +// self.remain -= 1; +// false +// } +// } else { +// false +// } +// } +// } + +/// online connected layer session. +pub(crate) struct LayerSession { + /// session online type. + pub online: Online, + /// current layer consensus(height). + pub consensus: i64, + /// session database id. + pub s_id: i64, + /// layer database id. + pub db_id: i64, + /// if session is suspend by me. + pub suspend_me: bool, + /// if session is suspend by remote. + pub suspend_remote: bool, + /// keep alive remain minutes. + pub remain: u16, } -impl RunningLayer { - pub fn init(owner: GroupId, id: i64, consensus: i64) -> Self { - RunningLayer { - owner, - id, - consensus, - sessions: HashMap::new(), - } - } - - pub fn owner_height_id(&self) -> (GroupId, i64, i64) { - (self.owner, self.consensus, self.id) - } - - pub fn increased(&mut self) -> i64 { - self.consensus += 1; - self.consensus - } - - pub fn active(&mut self, gid: &GroupId, is_me: bool) -> Option { - if let Some(online) = self.sessions.get_mut(gid) { - if is_me { - online.suspend_me = false; - } else { - online.suspend_remote = false; - } - - online.remain = 0; - Some(*online.online.addr()) - } else { - None - } - } - - pub fn suspend(&mut self, gid: &GroupId, is_me: bool, must: bool) -> Result { - if let Some(online) = self.sessions.get_mut(gid) { - if must { - online.suspend_me = true; - online.suspend_remote = true; - } - - if is_me { - online.suspend_me = true; - } else { - online.suspend_remote = true; - } - - if online.suspend_remote && online.suspend_me { - online.remain = 6; // keep-alive 10~11 minutes 120s/time - Ok(true) - } else { - Ok(false) - } - } else { - Err(anyhow!("remote not online")) - } - } - - pub fn get_online_id(&self, gid: &GroupId) -> Result<(i64, i64)> { - debug!("onlines: {:?}, find: {:?}", self.sessions.keys(), gid); - self.sessions - .get(gid) - .map(|online| (online.db_id, online.db_fid)) - .ok_or(anyhow!("remote not online")) - } - - /// get online peer's addr. - pub fn online(&self, gid: &GroupId) -> Result { - self.sessions - .get(gid) - .map(|online| *online.online.addr()) - .ok_or(anyhow!("remote not online")) - } - - pub fn online_direct(&self, gid: &GroupId) -> Result { - if let Some(online) = self.sessions.get(gid) { - match online.online { - Online::Direct(addr) => return Ok(addr), - _ => {} - } - } - Err(anyhow!("no direct online")) - } - - /// get all online peer. - pub fn onlines(&self) -> Vec<(&GroupId, &PeerId)> { - self.sessions - .iter() - .map(|(fgid, online)| (fgid, online.online.addr())) - .collect() - } - - pub fn is_online(&self, gid: &GroupId) -> bool { - self.sessions.contains_key(gid) - } - - /// check add online. - pub fn check_add_online( - &mut self, - gid: GroupId, - online: Online, - id: i64, - fid: i64, - ) -> Result<()> { - if let Some(o) = self.sessions.get(&gid) { - match (&o.online, &online) { - (Online::_Relay(..), Online::Direct(..)) => { - self.sessions - .insert(gid, OnlineSession::new(online, id, fid)); - Ok(()) - } - _ => Err(anyhow!("remote had online")), - } - } else { - self.sessions - .insert(gid, OnlineSession::new(online, id, fid)); - Ok(()) - } - } - - /// check offline, and return is direct. - pub fn check_offline(&mut self, gid: &GroupId, addr: &PeerId) -> bool { - if let Some(online) = self.sessions.remove(gid) { - if online.online.addr() != addr { - return false; - } - - match online.online { - Online::Direct(..) => { - return true; - } - _ => {} - } - } - false - } - - pub fn remove_online(&mut self, gid: &GroupId) -> Option { - self.sessions - .remove(gid) - .map(|online| *online.online.addr()) - } - - /// remove all onlines peer. - pub fn remove_onlines(self) -> Vec<(PeerId, GroupId)> { - let mut peers = vec![]; - for (fgid, online) in self.sessions { - match online.online { - Online::Direct(addr) => peers.push((addr, fgid)), - _ => {} - } - } - peers - } - - /// check if addr is online. - pub fn check_addr_online(&self, addr: &PeerId) -> bool { - for (_, online) in &self.sessions { - if online.online.addr() == addr { - return true; - } - } - false - } - - /// peer leave, remove online peer. - pub fn peer_leave(&mut self, addr: &PeerId) -> Vec { - let mut peers = vec![]; - let mut deletes = vec![]; - for (fgid, online) in &self.sessions { - if online.online.addr() == addr { - peers.push(online.db_id); - deletes.push(*fgid); - } - } - for i in &deletes { - self.sessions.remove(&i); - } - - peers - } - - /// list all onlines groups. - pub fn close_suspend(&mut self, self_addr: &PeerId) -> Vec<(GroupId, PeerId, i64)> { - let mut needed = vec![]; - for (fgid, online) in &mut self.sessions { - // when online is self. skip. - if online.online == Online::Direct(*self_addr) { - continue; - } - - if online.close_suspend() { - needed.push((*fgid, *online.online.addr(), online.db_id)); - } - } - - for (gid, _, _) in needed.iter() { - self.sessions.remove(gid); - } - needed - } +impl LayerSession { + // pub fn increased(&mut self) -> i64 { + // self.consensus += 1; + // self.consensus + // } + + // pub fn active(&mut self, gid: &GroupId, is_me: bool) -> Option { + // if let Some(online) = self.sessions.get_mut(gid) { + // if is_me { + // online.suspend_me = false; + // } else { + // online.suspend_remote = false; + // } + + // online.remain = 0; + // Some(*online.online.addr()) + // } else { + // None + // } + // } + + // pub fn suspend(&mut self, gid: &GroupId, is_me: bool, must: bool) -> Result { + // if let Some(online) = self.sessions.get_mut(gid) { + // if must { + // online.suspend_me = true; + // online.suspend_remote = true; + // } + + // if is_me { + // online.suspend_me = true; + // } else { + // online.suspend_remote = true; + // } + + // if online.suspend_remote && online.suspend_me { + // online.remain = 6; // keep-alive 10~11 minutes 120s/time + // Ok(true) + // } else { + // Ok(false) + // } + // } else { + // Err(anyhow!("remote not online")) + // } + // } + + // pub fn get_online_id(&self, gid: &GroupId) -> Result<(i64, i64)> { + // debug!("onlines: {:?}, find: {:?}", self.sessions.keys(), gid); + // self.sessions + // .get(gid) + // .map(|online| (online.db_id, online.db_fid)) + // .ok_or(anyhow!("remote not online")) + // } + + // /// get online peer's addr. + // pub fn online(&self, gid: &GroupId) -> Result { + // self.sessions + // .get(gid) + // .map(|online| *online.online.addr()) + // .ok_or(anyhow!("remote not online")) + // } + + // pub fn online_direct(&self, gid: &GroupId) -> Result { + // if let Some(online) = self.sessions.get(gid) { + // match online.online { + // Online::Direct(addr) => return Ok(addr), + // _ => {} + // } + // } + // Err(anyhow!("no direct online")) + // } + + // /// get all online peer. + // pub fn onlines(&self) -> Vec<(&GroupId, &PeerId)> { + // self.sessions + // .iter() + // .map(|(fgid, online)| (fgid, online.online.addr())) + // .collect() + // } + + // pub fn is_online(&self, gid: &GroupId) -> bool { + // self.sessions.contains_key(gid) + // } + + // /// check add online. + // pub fn check_add_online( + // &mut self, + // gid: GroupId, + // online: Online, + // id: i64, + // fid: i64, + // ) -> Result<()> { + // if let Some(o) = self.sessions.get(&gid) { + // match (&o.online, &online) { + // (Online::_Relay(..), Online::Direct(..)) => { + // self.sessions + // .insert(gid, OnlineSession::new(online, id, fid)); + // Ok(()) + // } + // _ => Err(anyhow!("remote had online")), + // } + // } else { + // self.sessions + // .insert(gid, OnlineSession::new(online, id, fid)); + // Ok(()) + // } + // } + + // /// check offline, and return is direct. + // pub fn check_offline(&mut self, gid: &GroupId, addr: &PeerId) -> bool { + // if let Some(online) = self.sessions.remove(gid) { + // if online.online.addr() != addr { + // return false; + // } + + // match online.online { + // Online::Direct(..) => { + // return true; + // } + // _ => {} + // } + // } + // false + // } + + // pub fn remove_online(&mut self, gid: &GroupId) -> Option { + // self.sessions + // .remove(gid) + // .map(|online| *online.online.addr()) + // } + + // /// remove all onlines peer. + // pub fn remove_onlines(self) -> Vec<(PeerId, GroupId)> { + // let mut peers = vec![]; + // for (fgid, online) in self.sessions { + // match online.online { + // Online::Direct(addr) => peers.push((addr, fgid)), + // _ => {} + // } + // } + // peers + // } + + // /// check if addr is online. + // pub fn check_addr_online(&self, addr: &PeerId) -> bool { + // for (_, online) in &self.sessions { + // if online.online.addr() == addr { + // return true; + // } + // } + // false + // } + + // /// peer leave, remove online peer. + // pub fn peer_leave(&mut self, addr: &PeerId) -> Vec { + // let mut peers = vec![]; + // let mut deletes = vec![]; + // for (fgid, online) in &self.sessions { + // if online.online.addr() == addr { + // peers.push(online.db_id); + // deletes.push(*fgid); + // } + // } + // for i in &deletes { + // self.sessions.remove(&i); + // } + + // peers + // } + + // /// list all onlines groups. + // pub fn close_suspend(&mut self, self_addr: &PeerId) -> Vec<(GroupId, PeerId, i64)> { + // let mut needed = vec![]; + // for (fgid, online) in &mut self.sessions { + // // when online is self. skip. + // if online.online == Online::Direct(*self_addr) { + // continue; + // } + + // if online.close_suspend() { + // needed.push((*fgid, *online.online.addr(), online.db_id)); + // } + // } + + // for (gid, _, _) in needed.iter() { + // self.sessions.remove(gid); + // } + // needed + // } } diff --git a/src/lib.rs b/src/lib.rs index 7127f4f..cdf4d76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -9,15 +9,16 @@ use std::os::raw::c_char; mod account; mod apps; -mod consensus; -mod event; +//mod consensus; +//mod event; mod group; mod layer; mod migrate; mod primitives; mod rpc; mod server; -mod session; +//mod session; +mod global; mod storage; mod utils; diff --git a/src/migrate.rs b/src/migrate.rs index 1c10bb5..31659d2 100644 --- a/src/migrate.rs +++ b/src/migrate.rs @@ -1,5 +1,5 @@ use std::path::PathBuf; -use tdn::types::primitive::Result; +use tdn::types::primitives::Result; use tdn_storage::local::DStorage; pub mod consensus; diff --git a/src/migrate/account.rs b/src/migrate/account.rs index edd5892..dbae9f9 100644 --- a/src/migrate/account.rs +++ b/src/migrate/account.rs @@ -2,7 +2,7 @@ pub(super) const ACCOUNT_VERSIONS: [&str; 13] = [ "CREATE TABLE IF NOT EXISTS accounts( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - gid TEXT NOT NULL, + pid TEXT NOT NULL, indx INTEGER NOT NULL, lang INTEGER NOT NULL, pass TEXT NOT NULL, diff --git a/src/migrate/consensus.rs b/src/migrate/consensus.rs index b1a9391..57dac53 100644 --- a/src/migrate/consensus.rs +++ b/src/migrate/consensus.rs @@ -10,7 +10,7 @@ pub(super) const CONSENSUS_VERSIONS: [&str; 9] = [ id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TEXT NOT NULL, info TEXT NOT NULL, - addr TEXT NOT NULL, + peer TEXT NOT NULL, lasttime INTEGER NOT NULL);", "CREATE TABLE IF NOT EXISTS db_tables( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, diff --git a/src/migrate/session.rs b/src/migrate/session.rs index 138df89..b3dd81a 100644 --- a/src/migrate/session.rs +++ b/src/migrate/session.rs @@ -3,7 +3,6 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [ "CREATE TABLE IF NOT EXISTS sessions( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, fid INTEGER NOT NULL, - gid TEXT NOT NULL, addr TEXT NOT NULL, s_type INTEGER NOT NULL, name TEXT NOT NULL, @@ -12,5 +11,5 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [ last_datetime INTEGER, last_content TEXT, last_readed INTEGER);", - "INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES (0, '', '', 3, '', 0, 0, 0, '', 1);", // Jarvis. + "INSERT INTO sessions (fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES (0, '', 3, '', 0, 0, 0, '', 1);", // Jarvis. ]; diff --git a/src/rpc.rs b/src/rpc.rs index 85d5e8f..88b00e1 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -1,10 +1,11 @@ +use esse_primitives::{id_from_str, id_to_str}; use std::collections::HashMap; use std::net::SocketAddr; use std::sync::Arc; use tdn::types::{ group::GroupId, message::{NetworkType, SendMessage, SendType, StateRequest, StateResponse}, - primitive::{HandleResult, Peer, PeerId, Result}, + primitives::{HandleResult, Peer, PeerId, Result}, rpc::{json, rpc_response, RpcError, RpcHandler, RpcParam}, }; use tdn_did::{generate_mnemonic, Count}; @@ -15,28 +16,20 @@ use tokio::sync::{ use crate::account::lang_from_i64; use crate::apps::app_rpc_inject; -use crate::apps::chat::chat_conn; -use crate::apps::group::{add_layer, group_conn, GroupChat}; -use crate::event::InnerEvent; +use crate::global::Global; +//use crate::apps::chat::chat_conn; +//use crate::apps::group::{add_layer, group_conn, GroupChat}; +//use crate::event::InnerEvent; use crate::group::Group; use crate::layer::{Layer, LayerEvent, Online}; -use crate::session::{connect_session, Session, SessionType}; - -pub(crate) fn init_rpc( - addr: PeerId, - group: Arc>, - layer: Arc>, -) -> RpcHandler { - let mut handler = new_rpc_handler(addr, group, layer); +//use crate::session::{connect_session, Session, SessionType}; + +pub(crate) fn init_rpc(global: Arc) -> RpcHandler { + let mut handler = new_rpc_handler(global); app_rpc_inject(&mut handler); handler } -pub(crate) struct RpcState { - pub group: Arc>, - pub layer: Arc>, -} - #[inline] pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam { let s_peers: Vec> = peers @@ -50,100 +43,95 @@ pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam { vec![p.to_hex(), d] }) .collect(); - rpc_response(0, "network-stable", json!(s_peers), GroupId::default()) + rpc_response(0, "network-stable", json!(s_peers)) } #[inline] pub(crate) fn network_dht(peers: Vec) -> RpcParam { let s_peers: Vec = peers.iter().map(|p| p.to_hex()).collect(); - rpc_response(0, "network-dht", json!(s_peers), GroupId::default()) -} - -#[inline] -pub(crate) fn account_update(mgid: GroupId, name: &str, avatar: String) -> RpcParam { - rpc_response( - 0, - "account-update", - json!([mgid.to_hex(), name, avatar]), - mgid, - ) -} - -#[inline] -pub(crate) fn session_create(mgid: GroupId, session: &Session) -> RpcParam { - rpc_response(0, "session-create", session.to_rpc(), mgid) -} - -#[inline] -pub(crate) fn session_last( - mgid: GroupId, - id: &i64, - time: &i64, - content: &str, - readed: bool, -) -> RpcParam { - rpc_response(0, "session-last", json!([id, time, content, readed]), mgid) -} - -#[inline] -pub(crate) fn notice_menu(mgid: GroupId, t: &SessionType) -> RpcParam { - rpc_response(0, "notice-menu", json!([t.to_int()]), mgid) -} - -#[inline] -pub(crate) fn session_update_name(mgid: GroupId, id: &i64, name: &str) -> RpcParam { - rpc_response(0, "session-update", json!([id, "", name, false]), mgid) -} - -#[inline] -pub(crate) fn session_update( - mgid: GroupId, - id: &i64, - addr: &PeerId, - name: &str, - is_top: bool, -) -> RpcParam { - rpc_response( - 0, - "session-update", - json!([id, addr.to_hex(), name, is_top]), - mgid, - ) -} - -#[inline] -pub(crate) fn session_connect(mgid: GroupId, id: &i64, addr: &PeerId) -> RpcParam { - rpc_response(0, "session-connect", json!([id, addr.to_hex()]), mgid) -} - -#[inline] -pub(crate) fn session_suspend(mgid: GroupId, id: &i64) -> RpcParam { - rpc_response(0, "session-suspend", json!([id]), mgid) -} - -#[inline] -pub(crate) fn session_lost(mgid: GroupId, id: &i64) -> RpcParam { - rpc_response(0, "session-lost", json!([id]), mgid) + rpc_response(0, "network-dht", json!(s_peers)) } #[inline] -pub(crate) fn session_delete(mgid: GroupId, id: &i64) -> RpcParam { - rpc_response(0, "session-delete", json!([id]), mgid) +pub(crate) fn account_update(pid: &PeerId, name: &str, avatar: String) -> RpcParam { + rpc_response(0, "account-update", json!([id_to_str(pid), name, avatar])) } -#[inline] -pub(crate) fn session_close(mgid: GroupId, id: &i64) -> RpcParam { - rpc_response(0, "session-close", json!([id]), mgid) -} - -#[inline] -fn session_list(sessions: Vec) -> RpcParam { - let mut results = vec![]; - for session in sessions { - results.push(session.to_rpc()); - } - json!(results) -} +// #[inline] +// pub(crate) fn session_create(mgid: GroupId, session: &Session) -> RpcParam { +// rpc_response(0, "session-create", session.to_rpc(), mgid) +// } + +// #[inline] +// pub(crate) fn session_last( +// mgid: GroupId, +// id: &i64, +// time: &i64, +// content: &str, +// readed: bool, +// ) -> RpcParam { +// rpc_response(0, "session-last", json!([id, time, content, readed]), mgid) +// } + +// #[inline] +// pub(crate) fn notice_menu(mgid: GroupId, t: &SessionType) -> RpcParam { +// rpc_response(0, "notice-menu", json!([t.to_int()]), mgid) +// } + +// #[inline] +// pub(crate) fn session_update_name(mgid: GroupId, id: &i64, name: &str) -> RpcParam { +// rpc_response(0, "session-update", json!([id, "", name, false]), mgid) +// } + +// #[inline] +// pub(crate) fn session_update( +// mgid: GroupId, +// id: &i64, +// addr: &PeerId, +// name: &str, +// is_top: bool, +// ) -> RpcParam { +// rpc_response( +// 0, +// "session-update", +// json!([id, addr.to_hex(), name, is_top]), +// mgid, +// ) +// } + +// #[inline] +// pub(crate) fn session_connect(mgid: GroupId, id: &i64, addr: &PeerId) -> RpcParam { +// rpc_response(0, "session-connect", json!([id, addr.to_hex()]), mgid) +// } + +// #[inline] +// pub(crate) fn session_suspend(mgid: GroupId, id: &i64) -> RpcParam { +// rpc_response(0, "session-suspend", json!([id]), mgid) +// } + +// #[inline] +// pub(crate) fn session_lost(mgid: GroupId, id: &i64) -> RpcParam { +// rpc_response(0, "session-lost", json!([id]), mgid) +// } + +// #[inline] +// pub(crate) fn session_delete(mgid: GroupId, id: &i64) -> RpcParam { +// rpc_response(0, "session-delete", json!([id]), mgid) +// } + +// #[inline] +// pub(crate) fn session_close(mgid: GroupId, id: &i64) -> RpcParam { +// rpc_response(0, "session-close", json!([id]), mgid) +// } + +// #[inline] +// fn session_list(sessions: Vec) -> RpcParam { +// let mut results = vec![]; +// for session in sessions { +// results.push(session.to_rpc()); +// } +// json!(results) +// } #[inline] pub(crate) async fn sleep_waiting_close_stable( @@ -154,20 +142,13 @@ pub(crate) async fn sleep_waiting_close_stable( tokio::time::sleep(std::time::Duration::from_secs(10)).await; for (addr, _) in groups { sender - .send(SendMessage::Group( - Default::default(), - SendType::Disconnect(addr), - )) + .send(SendMessage::Group(SendType::Disconnect(addr))) .await?; } for (faddr, fgid) in layers { sender - .send(SendMessage::Layer( - Default::default(), - fgid, - SendType::Disconnect(faddr), - )) + .send(SendMessage::Layer(fgid, SendType::Disconnect(faddr))) .await?; } @@ -175,7 +156,7 @@ pub(crate) async fn sleep_waiting_close_stable( } #[inline] -pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender) -> Result<()> { +pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc) -> Result<()> { // Inner network default rpc method. only use in http-rpc. if method == "network-stable" || method == "network-dht" { let req = match method { @@ -185,7 +166,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender(128); - let _ = sender + let _ = global + .sender + .read() + .await .send(SendMessage::Network(NetworkType::NetworkState(req, s))) .await .expect("TDN channel closed"); @@ -198,7 +182,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender>, - layer: Arc>, -) -> RpcHandler { - let mut handler = RpcHandler::new(RpcState { group, layer }); +fn new_rpc_handler(global: Arc) -> RpcHandler { + let mut handler = RpcHandler::new_with_state(global); - handler.add_method("echo", |_, params, _| async move { + handler.add_method("echo", |params, _| async move { Ok(HandleResult::rpc(json!(params))) }); - handler.add_method("account-system-info", move |_, _, _| async move { - Ok(HandleResult::rpc(json!(vec![addr.to_hex()]))) + handler.add_method("add-bootstrap", |params: Vec, _| async move { + let socket = params[0].as_str().ok_or(RpcError::ParseError)?; + let transport = params[1].as_str().ok_or(RpcError::ParseError)?; + + if let Ok(addr) = socket.parse::() { + Ok(HandleResult::network(NetworkType::Connect( + Peer::socket_transport(addr, transport), + ))) + } else { + Err(RpcError::InvalidRequest) + } }); - handler.add_method( - "add-bootstrap", - |_gid, params: Vec, _| async move { - let socket = params[0].as_str().ok_or(RpcError::ParseError)?; - let transport = params[1].as_str().ok_or(RpcError::ParseError)?; - - if let Ok(addr) = socket.parse::() { - Ok(HandleResult::network(NetworkType::Connect( - Peer::socket_transport(addr, transport), - ))) - } else { - Err(RpcError::InvalidRequest) - } - }, - ); - - handler.add_method( - "account-list", - |_gid, _params: Vec, state: Arc| async move { - let mut users: Vec> = vec![]; - let group_lock = state.group.read().await; - for (gid, user) in group_lock.list_users().iter() { - users.push(vec![ - gid.to_hex(), - user.name.clone(), - base64::encode(&user.avatar), - ]); - } - drop(group_lock); - - Ok(HandleResult::rpc(json!(users))) - }, - ); + handler.add_method("account-list", |_, state: Arc| async move { + let mut accounts: Vec> = vec![]; + let group_lock = state.group.read().await; + for (pid, account) in group_lock.list_accounts().iter() { + accounts.push(vec![ + id_to_str(pid), + account.name.clone(), + base64::encode(&account.avatar), + ]); + } + drop(group_lock); + + Ok(HandleResult::rpc(json!(accounts))) + }); handler.add_method( "account-generate", - |_gid, params: Vec, _state: Arc| async move { + |params: Vec, _state: Arc| async move { let lang = params[0].as_i64().ok_or(RpcError::ParseError)?; let language = lang_from_i64(lang); let words = generate_mnemonic(language, Count::Words12); @@ -270,7 +243,7 @@ fn new_rpc_handler( handler.add_method( "account-create", - |_gid, params: Vec, state: Arc| async move { + |params: Vec, state: Arc| async move { let lang = params[0].as_i64().ok_or(RpcError::ParseError)?; let seed = params[1].as_str().ok_or(RpcError::ParseError)?; let pass = params[2].as_str().ok_or(RpcError::ParseError)?; @@ -280,26 +253,29 @@ fn new_rpc_handler( let avatar = params[5].as_str().ok_or(RpcError::ParseError)?; let avatar_bytes = base64::decode(avatar).unwrap_or(vec![]); - let (id, gid) = state + let (_id, pid) = state .group .write() .await - .add_account(lang, seed, pass, name, lock, avatar_bytes) + .add_account( + lang, + seed, + pass, + name, + lock, + avatar_bytes, + &state.base, + &state.secret, + ) .await?; - state.layer.write().await.add_running(&gid, gid, id, 0)?; - - let mut results = HandleResult::rpc(json!(vec![gid.to_hex()])); - results.networks.push(NetworkType::AddGroup(gid)); // add AddGroup to TDN. - debug!("Account Logined: {}.", gid.to_hex()); - - Ok(results) + Ok(HandleResult::rpc(json!(vec![id_to_str(&pid)]))) }, ); handler.add_method( "account-restore", - |_gid, params: Vec, state: Arc| async move { + |params: Vec, state: Arc| async move { let lang = params[0].as_i64().ok_or(RpcError::ParseError)?; let seed = params[1].as_str().ok_or(RpcError::ParseError)?; let pass = params[2].as_str().ok_or(RpcError::ParseError)?; @@ -307,60 +283,55 @@ fn new_rpc_handler( let name = params[3].as_str().ok_or(RpcError::ParseError)?; let lock = params[4].as_str().ok_or(RpcError::ParseError)?; - let some_addr = PeerId::from_hex(params[5].as_str().ok_or(RpcError::ParseError)?).ok(); - - let (id, gid) = state + let (_id, pid) = state .group .write() .await - .add_account(lang, seed, pass, name, lock, vec![]) + .add_account( + lang, + seed, + pass, + name, + lock, + vec![], + &state.base, + &state.secret, + ) .await?; - state.layer.write().await.add_running(&gid, gid, id, 0)?; - - let mut results = HandleResult::rpc(json!(vec![gid.to_hex()])); - results.networks.push(NetworkType::AddGroup(gid)); // add AddGroup to TDN. - - debug!("Account Logined: {}.", gid.to_hex()); - - if let Some(addr) = some_addr { - let group_lock = state.group.read().await; - let sender = group_lock.sender(); - let msg = group_lock.create_message(&gid, Peer::peer(addr))?; - drop(group_lock); - tokio::spawn(async move { - tokio::time::sleep(std::time::Duration::from_secs(2)).await; - let _ = sender.send(SendMessage::Group(gid, msg)).await; - }); - } - Ok(results) + // TODO auto search online account info. + + Ok(HandleResult::rpc(json!(vec![id_to_str(&pid)]))) }, ); handler.add_method( "account-update", - |gid: GroupId, params: Vec, state: Arc| async move { + |params: Vec, state: Arc| async move { let name = params[0].as_str().ok_or(RpcError::ParseError)?; let avatar = params[1].as_str().ok_or(RpcError::ParseError)?; let avatar_bytes = base64::decode(avatar).unwrap_or(vec![]); + let pid = state.pid().await; let mut group_lock = state.group.write().await; - group_lock.update_account(gid, name, avatar_bytes.clone())?; - let user = group_lock.clone_user(&gid)?; - - let mut results = HandleResult::new(); - group_lock.broadcast( - &gid, - InnerEvent::UserInfo(name.to_owned(), avatar_bytes.clone()), - 0, - 0, - &mut results, + group_lock.update_account( + pid, + name, + avatar_bytes.clone(), + &state.base, + &state.secret, )?; drop(group_lock); - // broadcast all friends. - state.layer.read().await.broadcast(user, &mut results); + let results = HandleResult::new(); + + // TODO broadcast to all devices. + //let user = group_lock.clone_user(&pid)?; + //group_lock.broadcast(&pid, &mut results)?; + + // TODO broadcast to all layers. + //state.layer.read().await.broadcast(user, &mut results); Ok(results) }, @@ -368,81 +339,84 @@ fn new_rpc_handler( handler.add_method( "account-pin-check", - |_gid: GroupId, params: Vec, state: Arc| async move { - let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?; + |params: Vec, state: Arc| async move { + let pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?; let lock = params[1].as_str().ok_or(RpcError::ParseError)?; - let res = state.group.read().await.check_lock(&gid, lock); + let res = state.group.read().await.check_lock(&pid, lock); Ok(HandleResult::rpc(json!([res]))) }, ); handler.add_method( - "account-pin", - |gid: GroupId, params: Vec, state: Arc| async move { + "account-pin-change", + |params: Vec, state: Arc| async move { let old = params[0].as_str().ok_or(RpcError::ParseError)?; let new = params[1].as_str().ok_or(RpcError::ParseError)?; + let pid = state.pid().await; let result = HandleResult::rpc(json!([new])); - state.group.write().await.pin(&gid, old, new)?; + state + .group + .write() + .await + .pin(&pid, old, new, &state.base, &state.secret)?; Ok(result) }, ); handler.add_method( "account-mnemonic", - |gid: GroupId, params: Vec, state: Arc| async move { + |params: Vec, state: Arc| async move { let lock = params[0].as_str().ok_or(RpcError::ParseError)?; - - let mnemonic = state.group.read().await.mnemonic(&gid, lock)?; + let pid = state.pid().await; + let mnemonic = state + .group + .read() + .await + .mnemonic(&pid, lock, &state.secret)?; Ok(HandleResult::rpc(json!([mnemonic]))) }, ); handler.add_method( "account-login", - |_gid: GroupId, params: Vec, state: Arc| async move { - let ogid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?; + |params: Vec, state: Arc| async move { + let pid = id_from_str(params[0].as_str().ok_or(RpcError::ParseError)?)?; let me_lock = params[1].as_str().ok_or(RpcError::ParseError)?; - let mut results = HandleResult::rpc(json!([ogid.to_hex()])); + let mut results = HandleResult::rpc(json!([id_to_str(&pid)])); - let (id, running) = state.group.write().await.add_running(&ogid, me_lock)?; + let running = state.reset(&pid, me_lock).await?; if running { return Ok(results); } - // add AddGroup to TDN. - results.networks.push(NetworkType::AddGroup(ogid)); - - let mut layer_lock = state.layer.write().await; - layer_lock.add_running(&ogid, ogid, id, 0)?; // TODO account current state height. - - // load all services layer created by this account. + // TODO load all local services created by this account. // 1. group chat. - let self_addr = layer_lock.addr.clone(); - let group_lock = state.group.read().await; - let group_db = group_lock.group_db(&ogid)?; - let s_db = group_lock.session_db(&ogid)?; - drop(group_lock); - let group_chats = GroupChat::local(&group_db)?; - for g in group_chats { - layer_lock.add_running(&g.g_id, ogid, g.id, g.height)?; - results.networks.push(NetworkType::AddGroup(g.g_id)); - - // 2. online group to self group onlines. - if let Some(session) = - connect_session(&s_db, &SessionType::Group, &g.id, &self_addr)? - { - layer_lock.running_mut(&ogid)?.check_add_online( - g.g_id, - Online::Direct(self_addr), - session.id, - g.id, - )?; - } - } - drop(layer_lock); - - debug!("Account Logined: {}.", ogid.to_hex()); + // let self_addr = layer_lock.addr.clone(); + // let group_lock = state.group.read().await; + // let group_db = group_lock.group_db(&ogid)?; + // let s_db = group_lock.session_db(&ogid)?; + // drop(group_lock); + // let group_chats = GroupChat::local(&group_db)?; + // for g in group_chats { + // layer_lock.add_running(&g.g_id, ogid, g.id, g.height)?; + // results.networks.push(NetworkType::AddGroup(g.g_id)); + + // // 2. online group to self group onlines. + // if let Some(session) = + // connect_session(&s_db, &SessionType::Group, &g.id, &self_addr)? + // { + // layer_lock.running_mut(&ogid)?.check_add_online( + // g.g_id, + // Online::Direct(self_addr), + // session.id, + // g.id, + // )?; + // } + // } + // drop(layer_lock); + + debug!("Account Logined: {}.", id_to_str(&pid)); Ok(results) }, @@ -450,209 +424,152 @@ fn new_rpc_handler( handler.add_method( "account-logout", - |_gid: GroupId, _params: Vec, state: Arc| async move { + |_params: Vec, state: Arc| async move { let mut results = HandleResult::new(); + // TODO broadcast to inner-group. let group_lock = state.group.read().await; - let layer_lock = state.layer.read().await; - let keys = group_lock.list_running_user(); - - for gid in keys { - for (fgid, addr) in layer_lock.running(&gid)?.onlines() { - // send a event that is offline. - let data = bincode::serialize(&LayerEvent::Offline(*fgid))?; - let msg = SendType::Event(0, *addr, data); - results.layers.push((gid, *fgid, msg)); - } - - debug!("Account Offline: {}.", gid.to_hex()); - // add Remove Group to TDN. - results.networks.push(NetworkType::DelGroup(gid)); - } - drop(group_lock); - drop(layer_lock); - - let mut layer_lock = state.layer.write().await; - let layers = layer_lock.remove_all_running(); - drop(layer_lock); - - let mut group_lock = state.group.write().await; - let groups = group_lock.remove_all_running(); - let sender = group_lock.sender(); - drop(group_lock); - tokio::spawn(sleep_waiting_close_stable(sender, groups, layers)); - - Ok(results) - }, - ); - - handler.add_method( - "account-online", - |_gid: GroupId, params: Vec, state: Arc| async move { - let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?; - - let mut results = HandleResult::new(); - - let group_lock = state.group.read().await; - let devices = group_lock.distribute_conns(&gid); - for device in devices { - results.groups.push((gid, device)); - } - drop(group_lock); - debug!("Account Online: {}.", gid.to_hex()); - - Ok(results) - }, - ); - - handler.add_method( - "account-offline", - |_gid: GroupId, params: Vec, state: Arc| async move { - let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?; - let mut results = HandleResult::new(); + // TODO broadcast to layers. let layer_lock = state.layer.read().await; - for (fgid, addr) in layer_lock.running(&gid)?.onlines() { - // send a event that is offline. - let data = bincode::serialize(&LayerEvent::Offline(*fgid))?; - let msg = SendType::Event(0, *addr, data); - results.layers.push((gid, *fgid, msg)); - } - drop(layer_lock); - - let layers = state.layer.write().await.remove_running(&gid); - let mut group_lock = state.group.write().await; - let groups = group_lock.remove_running(&gid); - let sender = group_lock.sender(); - drop(group_lock); - tokio::spawn(sleep_waiting_close_stable(sender, groups, layers)); - - debug!("Account Offline: {}.", gid.to_hex()); - // add Remove Group to TDN. - results.networks.push(NetworkType::DelGroup(gid)); - - Ok(results) - }, - ); - - handler.add_method( - "session-list", - |gid: GroupId, _params: Vec, state: Arc| async move { - let db = state.group.read().await.session_db(&gid)?; - Ok(HandleResult::rpc(session_list(Session::list(&db)?))) - }, - ); - - handler.add_method( - "session-connect", - |gid: GroupId, params: Vec, state: Arc| async move { - let id = params[0].as_i64().ok_or(RpcError::ParseError)?; - let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?; - - let group_lock = state.group.read().await; - let db = group_lock.session_db(&gid)?; - Session::readed(&db, &id)?; - - let mut layer_lock = state.layer.write().await; - let online = layer_lock.running_mut(&gid)?.active(&remote, true); - drop(layer_lock); - if let Some(addr) = online { - return Ok(HandleResult::rpc(json!([id, addr.to_hex()]))); - } - - let s = Session::get(&db, &id)?; - drop(db); - - let mut results = HandleResult::new(); - match s.s_type { - SessionType::Chat => { - let proof = group_lock.prove_addr(&gid, &s.addr)?; - results - .layers - .push((gid, s.gid, chat_conn(proof, Peer::peer(s.addr)))); - } - SessionType::Group => { - let proof = group_lock.prove_addr(&gid, &s.addr)?; - add_layer( - &mut results, - gid, - group_conn(proof, Peer::peer(s.addr), s.gid), - ); + for (gid, sessions) in layer_lock.sessions.iter() { + for (pid, _) in sessions { + // send a event that is offline. + let data = bincode::serialize(&LayerEvent::Offline(*gid))?; + let msg = SendType::Event(0, *pid, data); + results.layers.push((*gid, msg)); } - _ => {} } - Ok(results) - }, - ); - - handler.add_method( - "session-suspend", - |gid: GroupId, params: Vec, state: Arc| async move { - let id = params[0].as_i64().ok_or(RpcError::ParseError)?; - let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?; - let must = params[2].as_bool().ok_or(RpcError::ParseError)?; // if need must suspend. - - let db = state.group.read().await.session_db(&gid)?; - let s = Session::get(&db, &id)?; - drop(db); - - let msg = match s.s_type { - SessionType::Chat | SessionType::Group => { - let event = LayerEvent::Suspend(s.gid); - let data = bincode::serialize(&event)?; - SendType::Event(0, s.addr, data) - } - _ => { - return Ok(HandleResult::new()); // others has no online. - } - }; - - let mut layer_lock = state.layer.write().await; - let suspend = layer_lock.running_mut(&gid)?.suspend(&remote, true, must)?; drop(layer_lock); - let mut results = HandleResult::new(); - if suspend { - results.rpcs.push(json!([id])) - } + debug!("Account Offline: {}.", id_to_str(&state.pid().await)); - match s.s_type { - SessionType::Chat => { - results.layers.push((gid, s.gid, msg)); - } - SessionType::Group => { - add_layer(&mut results, gid, msg); - } - _ => {} - } + //let sender = state.sender.read().await.clone(); + state.clear().await; + //tokio::spawn(sleep_waiting_close_stable(sender, groups, layers)); Ok(results) }, ); - handler.add_method( - "session-readed", - |gid: GroupId, params: Vec, state: Arc| async move { - let id = params[0].as_i64().ok_or(RpcError::ParseError)?; - let db = state.group.read().await.session_db(&gid)?; - Session::readed(&db, &id)?; - Ok(HandleResult::new()) - }, - ); - - handler.add_method( - "session-update", - |gid: GroupId, params: Vec, state: Arc| async move { - let id = params[0].as_i64().ok_or(RpcError::ParseError)?; - let is_top = params[1].as_bool().ok_or(RpcError::ParseError)?; - let is_close = params[2].as_bool().ok_or(RpcError::ParseError)?; - - let db = state.group.read().await.session_db(&gid)?; - Session::update(&db, &id, is_top, is_close)?; - Ok(HandleResult::new()) - }, - ); + // handler.add_method( + // "session-list", + // |gid: GroupId, _params: Vec, state: Arc| async move { + // let db = state.group.read().await.session_db(&gid)?; + // Ok(HandleResult::rpc(session_list(Session::list(&db)?))) + // }, + // ); + + // handler.add_method( + // "session-connect", + // |gid: GroupId, params: Vec, state: Arc| async move { + // let id = params[0].as_i64().ok_or(RpcError::ParseError)?; + // let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?; + + // let group_lock = state.group.read().await; + // let db = group_lock.session_db(&gid)?; + // Session::readed(&db, &id)?; + + // let mut layer_lock = state.layer.write().await; + // let online = layer_lock.running_mut(&gid)?.active(&remote, true); + // drop(layer_lock); + // if let Some(addr) = online { + // return Ok(HandleResult::rpc(json!([id, addr.to_hex()]))); + // } + + // let s = Session::get(&db, &id)?; + // drop(db); + + // let mut results = HandleResult::new(); + // match s.s_type { + // SessionType::Chat => { + // let proof = group_lock.prove_addr(&gid, &s.addr)?; + // results + // .layers + // .push((gid, s.gid, chat_conn(proof, Peer::peer(s.addr)))); + // } + // SessionType::Group => { + // let proof = group_lock.prove_addr(&gid, &s.addr)?; + // add_layer( + // &mut results, + // gid, + // group_conn(proof, Peer::peer(s.addr), s.gid), + // ); + // } + // _ => {} + // } + // Ok(results) + // }, + // ); + + // handler.add_method( + // "session-suspend", + // |gid: GroupId, params: Vec, state: Arc| async move { + // let id = params[0].as_i64().ok_or(RpcError::ParseError)?; + // let remote = GroupId::from_hex(params[1].as_str().ok_or(RpcError::ParseError)?)?; + // let must = params[2].as_bool().ok_or(RpcError::ParseError)?; // if need must suspend. + + // let db = state.group.read().await.session_db(&gid)?; + // let s = Session::get(&db, &id)?; + // drop(db); + + // let msg = match s.s_type { + // SessionType::Chat | SessionType::Group => { + // let event = LayerEvent::Suspend(s.gid); + // let data = bincode::serialize(&event)?; + // SendType::Event(0, s.addr, data) + // } + // _ => { + // return Ok(HandleResult::new()); // others has no online. + // } + // }; + + // let mut layer_lock = state.layer.write().await; + // let suspend = layer_lock.running_mut(&gid)?.suspend(&remote, true, must)?; + // drop(layer_lock); + + // let mut results = HandleResult::new(); + // if suspend { + // results.rpcs.push(json!([id])) + // } + + // match s.s_type { + // SessionType::Chat => { + // results.layers.push((gid, s.gid, msg)); + // } + // SessionType::Group => { + // add_layer(&mut results, gid, msg); + // } + // _ => {} + // } + + // Ok(results) + // }, + // ); + + // handler.add_method( + // "session-readed", + // |gid: GroupId, params: Vec, state: Arc| async move { + // let id = params[0].as_i64().ok_or(RpcError::ParseError)?; + // let db = state.group.read().await.session_db(&gid)?; + // Session::readed(&db, &id)?; + // Ok(HandleResult::new()) + // }, + // ); + + // handler.add_method( + // "session-update", + // |gid: GroupId, params: Vec, state: Arc| async move { + // let id = params[0].as_i64().ok_or(RpcError::ParseError)?; + // let is_top = params[1].as_bool().ok_or(RpcError::ParseError)?; + // let is_close = params[2].as_bool().ok_or(RpcError::ParseError)?; + + // let db = state.group.read().await.session_db(&gid)?; + // Session::update(&db, &id, is_top, is_close)?; + // Ok(HandleResult::new()) + // }, + // ); handler } diff --git a/src/server.rs b/src/server.rs index 25ff2ea..1c83eba 100644 --- a/src/server.rs +++ b/src/server.rs @@ -5,7 +5,10 @@ use std::path::PathBuf; use std::sync::Arc; use tdn::{ prelude::*, - types::primitive::{HandleResult, Result}, + types::{ + message::RpcSendMessage, + primitives::{HandleResult, Result}, + }, }; use tokio::{ sync::mpsc::{error::SendError, Sender}, @@ -15,14 +18,15 @@ use tokio::{ use tdn_storage::local::DStorage; use crate::account::Account; -use crate::apps::app_layer_handle; +//use crate::apps::app_layer_handle; +use crate::global::Global; use crate::group::Group; use crate::layer::Layer; use crate::migrate::{main_migrate, ACCOUNT_DB}; use crate::primitives::network_seeds; use crate::rpc::{init_rpc, inner_rpc}; -pub const DEFAULT_WS_ADDR: &'static str = "127.0.0.1:8080"; +pub const DEFAULT_WS_ADDR: &'static str = "127.0.0.1:7366"; pub const DEFAULT_LOG_FILE: &'static str = "esse.log.txt"; pub static RPC_WS_UID: OnceCell = OnceCell::new(); @@ -61,49 +65,54 @@ pub async fn start(db_path: String) -> Result<()> { let account_db = DStorage::open(account_db_path, &hex::encode(&rand_secret))?; let accounts = Account::all(&account_db)?; account_db.close()?; - let mut me: HashMap = HashMap::new(); + let mut me: HashMap = HashMap::new(); for account in accounts { - me.insert(account.gid, account); + me.insert(account.pid, account); } - config.group_ids = me.keys().cloned().collect(); + let gids: Vec = vec![]; // TODO add apps inject GROUP_ID + let peer_id = PeerId::default(); - let (peer_id, sender, mut recver) = start_with_config(config).await?; - info!("Network Peer id : {}", peer_id.to_hex()); + let (_, _, p2p_config, rpc_config) = config.split(); + let (tdn_send, tdn_recv) = new_send_channel(); + let (self_send, mut self_recv) = new_receive_channel(); + let rpc_send = start_rpc(rpc_config, self_send).await?; - let group = Arc::new(RwLock::new( - Group::init(rand_secret, sender.clone(), peer_id, me, db_path.clone()).await?, - )); - let layer = Arc::new(RwLock::new( - Layer::init(db_path, peer_id, group.clone()).await?, - )); + let global = Arc::new(Global::init(me, tdn_send, db_path, rand_secret)); - let rpc = init_rpc(peer_id, group.clone(), layer.clone()); - //let mut group_rpcs: HashMap = HashMap::new(); + //let peer_id = start_main(gids, p2p_config, self_send, tdn_recv, rpc_send, Some(key)).await; + // TODO CHECK peer_id is equal. + + // info!("Network Peer id : {}", peer_id.to_hex()); + + // let group = Arc::new(RwLock::new( + // Group::init(rand_secret, sender.clone(), peer_id, me, db_path.clone()).await?, + // )); + // let layer = Arc::new(RwLock::new( + // Layer::init(db_path, peer_id, group.clone()).await?, + // )); + + let rpc = init_rpc(global.clone()); + // //let mut group_rpcs: HashMap = HashMap::new(); let mut now_rpc_uid = 0; - // running session remain task. - tokio::spawn(session_remain(peer_id, layer.clone(), sender.clone())); + // // running session remain task. + // tokio::spawn(session_remain(peer_id, layer.clone(), sender.clone())); - while let Some(message) = recver.recv().await { + while let Some(message) = self_recv.recv().await { match message { - ReceiveMessage::Group(fgid, g_msg) => { - if let Ok(handle_result) = group - .write() - .await - .handle(fgid, g_msg, &layer, now_rpc_uid) - .await - { - handle(handle_result, now_rpc_uid, true, &sender).await; - } + ReceiveMessage::Group(g_msg) => { + //if let Ok(handle_result) = group.write().await.handle(g_msg, now_rpc_uid).await { + //handle(handle_result, now_rpc_uid, true, &sender).await; + //} } - ReceiveMessage::Layer(fgid, tgid, l_msg) => { - if let Ok(handle_result) = app_layer_handle(&layer, fgid, tgid, l_msg).await { - handle(handle_result, now_rpc_uid, true, &sender).await; - } + ReceiveMessage::Layer(fgid, l_msg) => { + // if let Ok(handle_result) = app_layer_handle(&layer, fgid, tgid, l_msg).await { + // handle(handle_result, now_rpc_uid, true, &sender).await; + // } } ReceiveMessage::Rpc(uid, params, is_ws) => { if !is_ws { - if inner_rpc(uid, params["method"].as_str().unwrap(), &sender) + if inner_rpc(uid, params["method"].as_str().unwrap(), &global) .await .is_ok() { @@ -117,23 +126,22 @@ pub async fn start(db_path: String) -> Result<()> { } if let Ok(handle_result) = rpc.handle(params).await { - handle(handle_result, uid, is_ws, &sender).await; + handle(handle_result, uid, is_ws, &global, &rpc_send).await; } } ReceiveMessage::NetworkLost => { - sender + global .send(SendMessage::Network(NetworkType::NetworkReboot)) - .await - .expect("TDN channel closed"); - let t_sender = sender.clone(); - let g_conns = group.read().await.all_distribute_conns(); - let l_conns = layer - .read() - .await - .all_layer_conns() - .await - .unwrap_or(HashMap::new()); - tokio::spawn(sleep_waiting_reboot(t_sender, g_conns, l_conns)); + .await?; + // let t_sender = tdn_send.clone(); + // let g_conns = group.read().await.all_distribute_conns(); + // let l_conns = layer + // .read() + // .await + // .all_layer_conns() + // .await + // .unwrap_or(HashMap::new()); + // tokio::spawn(sleep_waiting_reboot(t_sender, g_conns, l_conns)); } } } @@ -141,81 +149,87 @@ pub async fn start(db_path: String) -> Result<()> { Ok(()) } -#[inline] -async fn sleep_waiting_reboot( - sender: Sender, - groups: HashMap>, - layers: HashMap>, -) -> std::result::Result<(), SendError> { - tokio::time::sleep(std::time::Duration::from_secs(10)).await; - - for (gid, conns) in groups { - for conn in conns { - sender.send(SendMessage::Group(gid, conn)).await?; - } - } - - for (fgid, conns) in layers { - for (tgid, conn) in conns { - sender.send(SendMessage::Layer(fgid, tgid, conn)).await?; - } - } - - Ok(()) -} - -async fn session_remain( - self_addr: PeerId, - layer: Arc>, - sender: Sender, -) -> Result<()> { - loop { - tokio::time::sleep(std::time::Duration::from_secs(120)).await; - if let Some(uid) = RPC_WS_UID.get() { - let mut layer_lock = layer.write().await; - let mut rpcs = vec![]; - let mut addrs = HashMap::new(); - - for (_, running) in layer_lock.runnings.iter_mut() { - let closed = running.close_suspend(&self_addr); - for (gid, addr, sid) in closed { - addrs.insert(addr, false); - rpcs.push(crate::rpc::session_lost(gid, &sid)); - } - } - drop(layer_lock); - - let layer_lock = layer.read().await; - for (_, running) in layer_lock.runnings.iter() { - for (addr, keep) in addrs.iter_mut() { - if running.check_addr_online(addr) { - *keep = true; - } - } - } - drop(layer_lock); - - for rpc in rpcs { - let _ = sender.send(SendMessage::Rpc(*uid, rpc, true)).await; - } - - for (addr, keep) in addrs { - if !keep { - let _ = sender - .send(SendMessage::Layer( - GroupId::default(), - GroupId::default(), - SendType::Disconnect(addr), - )) - .await; - } - } - } - } -} +// #[inline] +// async fn sleep_waiting_reboot( +// sender: Sender, +// groups: HashMap>, +// layers: HashMap>, +// ) -> std::result::Result<(), SendError> { +// tokio::time::sleep(std::time::Duration::from_secs(10)).await; + +// for (gid, conns) in groups { +// for conn in conns { +// sender.send(SendMessage::Group(gid, conn)).await?; +// } +// } + +// for (fgid, conns) in layers { +// for (tgid, conn) in conns { +// sender.send(SendMessage::Layer(fgid, tgid, conn)).await?; +// } +// } + +// Ok(()) +// } + +// async fn session_remain( +// self_addr: PeerId, +// layer: Arc>, +// sender: Sender, +// ) -> Result<()> { +// loop { +// tokio::time::sleep(std::time::Duration::from_secs(120)).await; +// if let Some(uid) = RPC_WS_UID.get() { +// let mut layer_lock = layer.write().await; +// let mut rpcs = vec![]; +// let mut addrs = HashMap::new(); + +// for (_, running) in layer_lock.runnings.iter_mut() { +// let closed = running.close_suspend(&self_addr); +// for (gid, addr, sid) in closed { +// addrs.insert(addr, false); +// rpcs.push(crate::rpc::session_lost(gid, &sid)); +// } +// } +// drop(layer_lock); + +// let layer_lock = layer.read().await; +// for (_, running) in layer_lock.runnings.iter() { +// for (addr, keep) in addrs.iter_mut() { +// if running.check_addr_online(addr) { +// *keep = true; +// } +// } +// } +// drop(layer_lock); + +// for rpc in rpcs { +// let _ = sender.send(SendMessage::Rpc(*uid, rpc, true)).await; +// } + +// for (addr, keep) in addrs { +// if !keep { +// let _ = sender +// .send(SendMessage::Layer( +// GroupId::default(), +// GroupId::default(), +// SendType::Disconnect(addr), +// )) +// .await; +// } +// } +// } +// } +// } #[inline] -async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sender) { +async fn handle( + handle_result: HandleResult, + uid: u64, + is_ws: bool, + global: &Arc, + rpc_sender: &Sender, +) { let HandleResult { mut rpcs, mut groups, @@ -226,8 +240,8 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen loop { if rpcs.len() != 0 { let msg = rpcs.remove(0); - sender - .send(SendMessage::Rpc(uid, msg, is_ws)) + rpc_sender + .send(RpcSendMessage(uid, msg, is_ws)) .await .expect("TDN channel closed"); } else { @@ -235,6 +249,7 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen } } + let sender = global.sender.read().await; loop { if networks.len() != 0 { let msg = networks.remove(0); @@ -249,9 +264,9 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen loop { if groups.len() != 0 { - let (gid, msg) = groups.remove(0); + let msg = groups.remove(0); sender - .send(SendMessage::Group(gid, msg)) + .send(SendMessage::Group(msg)) .await .expect("TDN channel closed"); } else { @@ -261,9 +276,9 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen loop { if layers.len() != 0 { - let (fgid, tgid, msg) = layers.remove(0); + let (tgid, msg) = layers.remove(0); sender - .send(SendMessage::Layer(fgid, tgid, msg)) + .send(SendMessage::Layer(tgid, msg)) .await .expect("TDN channel closed"); } else { diff --git a/src/session.rs b/src/session.rs index c7abdef..a43b13e 100644 --- a/src/session.rs +++ b/src/session.rs @@ -1,6 +1,6 @@ +use esse_primitives::{id_from_str, id_to_string}; use tdn::types::{ - group::GroupId, - primitive::{PeerId, Result}, + primitives::{PeerId, Result}, rpc::{json, RpcParam}, }; use tdn_storage::local::{DStorage, DsValue}; @@ -36,7 +36,6 @@ impl SessionType { pub(crate) struct Session { pub id: i64, fid: i64, - pub gid: GroupId, pub addr: PeerId, pub s_type: SessionType, name: String, @@ -48,17 +47,9 @@ pub(crate) struct Session { } impl Session { - pub fn new( - fid: i64, - gid: GroupId, - addr: PeerId, - s_type: SessionType, - name: String, - datetime: i64, - ) -> Self { + pub fn new(fid: i64, addr: PeerId, s_type: SessionType, name: String, datetime: i64) -> Self { Self { fid, - gid, addr, s_type, name, @@ -75,8 +66,7 @@ impl Session { json!([ self.id, self.fid, - self.gid.to_hex(), - self.addr.to_hex(), + id_to_string(&self.addr), self.s_type.to_int(), self.name, self.is_top, @@ -96,8 +86,7 @@ impl Session { is_top: v.pop().unwrap().as_bool(), name: v.pop().unwrap().as_string(), s_type: SessionType::from_int(v.pop().unwrap().as_i64()), - addr: PeerId::from_hex(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()), - gid: GroupId::from_hex(v.pop().unwrap().as_str()).unwrap_or(GroupId::default()), + addr: id_from_str(v.pop().unwrap().as_str()).unwrap_or(PeerId::default()), fid: v.pop().unwrap().as_i64(), id: v.pop().unwrap().as_i64(), } @@ -113,19 +102,17 @@ impl Session { let id = unique_check.pop().unwrap().pop().unwrap().as_i64(); self.id = id; - let sql = format!("UPDATE sessions SET gid = '{}', addr='{}', name = '{}', is_top = '{}', is_close = false WHERE id = {}", - self.gid.to_hex(), - self.addr.to_hex(), + let sql = format!("UPDATE sessions SET addr='{}', name = '{}', is_top = '{}', is_close = false WHERE id = {}", + id_to_string(&self.addr), self.name, self.is_top, self.id, ); db.update(&sql)?; } else { - let sql = format!("INSERT INTO sessions (fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES ({}, '{}', '{}', {}, '{}', {}, {}, {}, '{}', {})", + let sql = format!("INSERT INTO sessions (fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed) VALUES ({}, '{}', {}, '{}', {}, {}, {}, '{}', {})", self.fid, - self.gid.to_hex(), - self.addr.to_hex(), + id_to_string(&self.addr), self.s_type.to_int(), self.name, self.is_top, @@ -142,7 +129,7 @@ impl Session { } pub fn get(db: &DStorage, id: &i64) -> Result { - let sql = format!("SELECT id, fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id); + let sql = format!("SELECT id, fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE id = {}", id); let mut matrix = db.query(&sql)?; if matrix.len() > 0 { Ok(Session::from_values(matrix.pop().unwrap())) // safe unwrap() @@ -152,7 +139,7 @@ impl Session { } pub fn list(db: &DStorage) -> Result> { - let matrix = db.query("SELECT id, fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?; + let matrix = db.query("SELECT id, fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions ORDER BY last_datetime DESC")?; let mut sessions = vec![]; for values in matrix { sessions.push(Session::from_values(values)); @@ -268,7 +255,7 @@ pub(crate) fn connect_session( fid: &i64, addr: &PeerId, ) -> Result> { - let sql = format!("SELECT id, fid, gid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE s_type = {} AND fid = {}", s_type.to_int(), fid); + let sql = format!("SELECT id, fid, addr, s_type, name, is_top, is_close, last_datetime, last_content, last_readed FROM sessions WHERE s_type = {} AND fid = {}", s_type.to_int(), fid); let mut matrix = db.query(&sql)?; if matrix.len() > 0 { diff --git a/src/storage.rs b/src/storage.rs index e2fc140..c95a262 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,12 +1,17 @@ +use esse_primitives::id_to_str; use image::{load_from_memory, DynamicImage, GenericImageView}; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use std::path::PathBuf; use std::time::{SystemTime, UNIX_EPOCH}; +use tdn::types::primitives::{PeerId, Result}; +use tdn_storage::local::DStorage; use tokio::fs; -use tdn::types::{group::GroupId, primitive::Result}; - use crate::migrate::account_init_migrate; +use crate::migrate::{ + ACCOUNT_DB, CHAT_DB, CLOUD_DB, CONSENSUS_DB, DAO_DB, DOMAIN_DB, FILE_DB, GROUP_DB, JARVIS_DB, + SERVICE_DB, SESSION_DB, WALLET_DB, +}; const FILES_DIR: &'static str = "files"; const IMAGE_DIR: &'static str = "images"; @@ -56,11 +61,11 @@ pub(crate) async fn read_file(base: &PathBuf) -> Result> { pub(crate) async fn copy_file( target: &PathBuf, base: &PathBuf, - gid: &GroupId, + pid: &PeerId, name: &str, ) -> Result<()> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(FILES_DIR); path.push(name); fs::copy(target, path).await?; @@ -69,12 +74,12 @@ pub(crate) async fn copy_file( pub(crate) async fn write_file( base: &PathBuf, - gid: &GroupId, + pid: &PeerId, name: &str, bytes: &[u8], ) -> Result { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(FILES_DIR); path.push(name); fs::write(path, bytes).await?; @@ -83,12 +88,12 @@ pub(crate) async fn write_file( pub(crate) fn write_file_sync( base: &PathBuf, - gid: &GroupId, + pid: &PeerId, name: &str, bytes: Vec, ) -> Result { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(FILES_DIR); path.push(name); tokio::spawn(async move { fs::write(path, bytes).await }); @@ -96,9 +101,9 @@ pub(crate) fn write_file_sync( Ok(name.to_owned()) } -pub(crate) async fn read_db_file(base: &PathBuf, gid: &GroupId, name: &str) -> Result> { +pub(crate) async fn read_db_file(base: &PathBuf, pid: &PeerId, name: &str) -> Result> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(FILES_DIR); path.push(name); if path.exists() { @@ -108,9 +113,9 @@ pub(crate) async fn read_db_file(base: &PathBuf, gid: &GroupId, name: &str) -> R } } -pub(crate) async fn read_image(base: &PathBuf, gid: &GroupId, name: &str) -> Result> { +pub(crate) async fn read_image(base: &PathBuf, pid: &PeerId, name: &str) -> Result> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(IMAGE_DIR); path.push(name); if path.exists() { @@ -143,9 +148,9 @@ fn image_thumb(bytes: &[u8]) -> Result { } } -pub(crate) fn write_image_sync(base: &PathBuf, gid: &GroupId, bytes: Vec) -> Result { +pub(crate) fn write_image_sync(base: &PathBuf, pid: &PeerId, bytes: Vec) -> Result { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); let thumb = image_thumb(&bytes)?; let name = image_name(); @@ -164,9 +169,9 @@ pub(crate) fn write_image_sync(base: &PathBuf, gid: &GroupId, bytes: Vec) -> Ok(name) } -pub(crate) async fn write_image(base: &PathBuf, gid: &GroupId, bytes: &[u8]) -> Result { +pub(crate) async fn write_image(base: &PathBuf, pid: &PeerId, bytes: &[u8]) -> Result { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); let thumb = image_thumb(bytes)?; let name = image_name(); @@ -186,19 +191,15 @@ pub(crate) async fn write_image(base: &PathBuf, gid: &GroupId, bytes: &[u8]) -> } #[inline] -fn avatar_png(gid: &GroupId) -> String { - let mut gs = gid.to_hex(); +fn avatar_png(pid: &PeerId) -> String { + let mut gs = id_to_str(pid); gs.push_str(".png"); gs } -pub(crate) async fn read_avatar( - base: &PathBuf, - gid: &GroupId, - remote: &GroupId, -) -> Result> { +pub(crate) async fn read_avatar(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(AVATAR_DIR); path.push(avatar_png(remote)); if path.exists() { @@ -208,9 +209,9 @@ pub(crate) async fn read_avatar( } } -pub(crate) fn read_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result> { +pub(crate) fn read_avatar_sync(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(AVATAR_DIR); path.push(avatar_png(remote)); if path.exists() { @@ -222,15 +223,15 @@ pub(crate) fn read_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId) pub(crate) async fn write_avatar( base: &PathBuf, - gid: &GroupId, - remote: &GroupId, + pid: &PeerId, + remote: &PeerId, bytes: &[u8], ) -> Result<()> { if bytes.len() < 1 { return Ok(()); } let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(AVATAR_DIR); path.push(avatar_png(remote)); Ok(fs::write(path, bytes).await?) @@ -238,24 +239,24 @@ pub(crate) async fn write_avatar( pub(crate) fn write_avatar_sync( base: &PathBuf, - gid: &GroupId, - remote: &GroupId, + pid: &PeerId, + remote: &PeerId, bytes: Vec, ) -> Result<()> { if bytes.len() < 1 { return Ok(()); } let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(AVATAR_DIR); path.push(avatar_png(remote)); tokio::spawn(async move { fs::write(path, bytes).await }); Ok(()) } -pub(crate) async fn delete_avatar(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result<()> { +pub(crate) async fn delete_avatar(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<()> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(AVATAR_DIR); path.push(avatar_png(remote)); if path.exists() { @@ -265,9 +266,9 @@ pub(crate) async fn delete_avatar(base: &PathBuf, gid: &GroupId, remote: &GroupI } } -pub(crate) fn delete_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result<()> { +pub(crate) fn delete_avatar_sync(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<()> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(AVATAR_DIR); path.push(avatar_png(remote)); if path.exists() { @@ -276,9 +277,9 @@ pub(crate) fn delete_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId Ok(()) } -pub(crate) async fn read_record(base: &PathBuf, gid: &GroupId, name: &str) -> Result> { +pub(crate) async fn read_record(base: &PathBuf, pid: &PeerId, name: &str) -> Result> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(RECORD_DIR); path.push(name); if path.exists() { @@ -290,7 +291,7 @@ pub(crate) async fn read_record(base: &PathBuf, gid: &GroupId, name: &str) -> Re pub(crate) fn write_record_sync( base: &PathBuf, - gid: &GroupId, + pid: &PeerId, t: u32, bytes: Vec, ) -> Result { @@ -301,7 +302,7 @@ pub(crate) fn write_record_sync( .unwrap_or(0u128); let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(RECORD_DIR); path.push(format!("{}.m4a", datetime)); tokio::spawn(async move { fs::write(path, bytes).await }); @@ -309,27 +310,40 @@ pub(crate) fn write_record_sync( Ok(format!("{}_{}.m4a", t, datetime)) } -pub(crate) async fn _delete_record(base: &PathBuf, gid: &GroupId, name: &str) -> Result<()> { +pub(crate) async fn _delete_record(base: &PathBuf, pid: &PeerId, name: &str) -> Result<()> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(RECORD_DIR); path.push(name); Ok(fs::remove_file(path).await?) } -pub(crate) fn _write_emoji(base: &PathBuf, gid: &GroupId) -> Result<()> { +pub(crate) fn _write_emoji(base: &PathBuf, pid: &PeerId) -> Result<()> { let mut path = base.clone(); - path.push(gid.to_hex()); + path.push(id_to_str(pid)); path.push(EMOJI_DIR); Ok(()) } /// account independent db and storage directory. -pub(crate) async fn account_init(base: &PathBuf, key: &str, gid: &GroupId) -> Result<()> { +pub(crate) async fn account_init(base: &PathBuf, key: &str, pid: &PeerId) -> Result<()> { let mut db_path = base.clone(); - db_path.push(gid.to_hex()); + db_path.push(id_to_str(pid)); init_local_files(&db_path).await?; // Inner Database. account_init_migrate(&db_path, key) } + +pub(crate) fn account_db(base: &PathBuf, secret: &[u8]) -> Result { + let mut db_path = base.clone(); + db_path.push(ACCOUNT_DB); + DStorage::open(db_path, &hex::encode(secret)) +} + +pub(crate) fn consensus_db(base: &PathBuf, pid: &PeerId, db_key: &str) -> Result { + let mut db_path = base.clone(); + db_path.push(id_to_str(pid)); + db_path.push(CONSENSUS_DB); + DStorage::open(db_path, db_key) +} diff --git a/types/cloud/Cargo.toml b/types/cloud/Cargo.toml index 403599c..0831f88 100644 --- a/types/cloud/Cargo.toml +++ b/types/cloud/Cargo.toml @@ -12,4 +12,3 @@ license = "MIT/Apache-2.0" [dependencies] serde = { version = "1", features = ["derive"] } tdn_types = { version = "0.7", default-features = false } -tdn_did = { version = "0.7", default-features = false } diff --git a/types/cloud/src/lib.rs b/types/cloud/src/lib.rs index 5f4e037..703b364 100644 --- a/types/cloud/src/lib.rs +++ b/types/cloud/src/lib.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use tdn_did::Proof; use tdn_types::group::GroupId; /// Personal data cloud service default TDN GROUP ID. @@ -7,11 +6,11 @@ pub const CLOUD_ID: GroupId = 5; /// ESSE service to peer layer Event. #[derive(Serialize, Deserialize)] -pub struct LayerServerEvent(pub ServerEvent, pub Proof); +pub struct LayerServerEvent(pub ServerEvent); /// ESSE peer to layer Event. #[derive(Serialize, Deserialize)] -pub struct LayerPeerEvent(pub PeerEvent, pub Proof); +pub struct LayerPeerEvent(pub PeerEvent); /// ESSE service to peer Event. #[derive(Serialize, Deserialize)] diff --git a/types/dao/src/lib.rs b/types/dao/src/lib.rs index 970fd3b..698564a 100644 --- a/types/dao/src/lib.rs +++ b/types/dao/src/lib.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use tdn_did::Proof; use tdn_types::{group::GroupId, primitives::PeerId}; use chat_types::NetworkMessage; @@ -91,10 +90,10 @@ pub struct LayerResult(pub DaoId, pub i64); pub enum ConnectProof { /// when is joined in group chat, can only use had to join (connect). /// params: proof. - Common(Proof), + Common, /// zero-knowledge-proof. not has account id. /// verify(proof, key_hash, current_peer_addr). - Zkp(Proof), // TODO MOCK-PROOF + Zkp, // TODO MOCK-PROOF } /// Dao chat join proof. @@ -104,11 +103,11 @@ pub enum JoinProof { /// params: member name, member avatar. Open(String, Vec), /// when is invate, it will take group_manager's proof for invate. - /// params: invite_by_account, invite_proof, member name, member avatar. - Invite(PeerId, Proof, String, Vec), + /// params: invite_by_account, member name, member avatar. + Invite(PeerId, String, Vec), /// zero-knowledge-proof. not has account id. /// verify(proof, key_hash, current_peer_addr). - Zkp(Proof), // TODO MOCK-PROOF + Zkp, // TODO MOCK-PROOF } /// check result type. @@ -150,8 +149,8 @@ pub enum LayerEvent { /// params: check type, provider name, remain, supported_group_types. CheckResult(CheckType, String, i64, Vec), /// create a Group Chat. - /// params: group_info, proof. - Create(DaoInfo, Proof), + /// params: group_info. + Create(DaoInfo), /// result create group success. /// params: Group ID, is_ok. CreateResult(DaoId, bool), diff --git a/types/domain/Cargo.toml b/types/domain/Cargo.toml index d5548a4..d972d1f 100644 --- a/types/domain/Cargo.toml +++ b/types/domain/Cargo.toml @@ -12,4 +12,3 @@ license = "MIT/Apache-2.0" [dependencies] serde = { version = "1", features = ["derive"] } tdn_types = { version = "0.7", default-features = false } -tdn_did = { version = "0.7", default-features = false } diff --git a/types/domain/src/lib.rs b/types/domain/src/lib.rs index 473770b..409a6cd 100644 --- a/types/domain/src/lib.rs +++ b/types/domain/src/lib.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use tdn_did::Proof; use tdn_types::{group::GroupId, primitives::PeerId}; // Same ID can has many name !. @@ -7,17 +6,9 @@ use tdn_types::{group::GroupId, primitives::PeerId}; /// Group chat app(service) default TDN GROUP ID. pub const DOMAIN_ID: GroupId = 4; -/// ESSE domain service layer Event. -#[derive(Serialize, Deserialize)] -pub struct LayerServerEvent(pub ServerEvent, pub Proof); - -/// ESSE domain service layer Event. -#[derive(Serialize, Deserialize)] -pub struct LayerPeerEvent(pub PeerEvent, pub Proof); - /// ESSE domain service to peer layer Event. #[derive(Serialize, Deserialize)] -pub enum ServerEvent { +pub enum LayerServerEvent { /// check result status. /// params: provider name, is support request proxy. Status(String, bool), @@ -42,7 +33,7 @@ pub enum ServerEvent { /// ESSE domain peer to service layer Event. #[derive(Serialize, Deserialize)] -pub enum PeerEvent { +pub enum LayerPeerEvent { /// check service status is ok. Check, /// register new unique identity to service. diff --git a/types/group/Cargo.toml b/types/group/Cargo.toml index a93cbe0..ad0a699 100644 --- a/types/group/Cargo.toml +++ b/types/group/Cargo.toml @@ -13,4 +13,3 @@ license = "MIT/Apache-2.0" chat_types = { path = "../chat", version = "0.1" } serde = { version = "1", features = ["derive"] } tdn_types = { version = "0.7", default-features = false } -tdn_did = { version = "0.7", default-features = false } diff --git a/types/group/src/lib.rs b/types/group/src/lib.rs index bd6250e..e6fa28d 100644 --- a/types/group/src/lib.rs +++ b/types/group/src/lib.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use tdn_did::Proof; use tdn_types::{group::GroupId, primitives::PeerId}; use chat_types::NetworkMessage; @@ -11,9 +10,9 @@ pub const GROUP_CHAT_ID: GroupId = 2; pub type GroupChatId = u64; /// Group chat connect data structure. -/// params: Group Chat ID, join_proof. +/// params: Group Chat ID. #[derive(Serialize, Deserialize)] -pub struct LayerConnect(pub GroupChatId, pub Proof); +pub struct LayerConnect(pub GroupChatId); /// Group chat connect success result data structure. /// params: Group ID, group name, group current height. diff --git a/types/primitives/src/lib.rs b/types/primitives/src/lib.rs index 0209250..39aab94 100644 --- a/types/primitives/src/lib.rs +++ b/types/primitives/src/lib.rs @@ -77,11 +77,11 @@ pub mod bs32 { use tdn_types::primitives::{new_io_error, PeerId, PEER_ID_LENGTH}; -pub fn id_to_string(peer: &PeerId) -> String { +pub fn id_to_str(peer: &PeerId) -> String { bs32::encode(&peer.0) } -pub fn id_from_string(s: &str) -> std::io::Result { +pub fn id_from_str(s: &str) -> std::io::Result { let data = bs32::decode(s).ok_or(new_io_error("id from string is failure."))?; if data.len() != PEER_ID_LENGTH { return Err(new_io_error("id from string is failure.")); diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index a7402be..d52ab30 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -7,14 +7,17 @@ #include "generated_plugin_registrant.h" #include -#include +#include +#include #include void RegisterPlugins(flutter::PluginRegistry* registry) { EsseCorePluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("EsseCorePlugin")); - FileSelectorPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FileSelectorPlugin")); + FileSelectorWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FileSelectorWindows")); + PermissionHandlerWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); } diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 1dccebe..66b79ea 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -5,6 +5,7 @@ list(APPEND FLUTTER_PLUGIN_LIST esse_core file_selector_windows + permission_handler_windows url_launcher_windows )