Browse Source

Merge branch 'dev' of github.com:CympleTech/esse into dev

pull/18/head
Sun 4 years ago
parent
commit
d2bcf6b9d3
  1. 13
      Cargo.toml
  2. 4
      lib/global.dart
  3. 25
      lib/rpc.dart
  4. 3
      lib/security.dart
  5. 2
      macos/Flutter/GeneratedPluginRegistrant.swift
  6. 231
      pubspec.lock
  7. 4
      pubspec.yaml
  8. 70
      src/account.rs
  9. 78
      src/apps.rs
  10. 4
      src/apps/device/mod.rs
  11. 40
      src/apps/device/models.rs
  12. 10
      src/apps/device/rpc.rs
  13. 7
      src/daemon.rs
  14. 92
      src/global.rs
  15. 1630
      src/group.rs
  16. 42
      src/group/running.rs
  17. 742
      src/layer.rs
  18. 7
      src/lib.rs
  19. 2
      src/migrate.rs
  20. 2
      src/migrate/account.rs
  21. 2
      src/migrate/consensus.rs
  22. 3
      src/migrate/session.rs
  23. 785
      src/rpc.rs
  24. 265
      src/server.rs
  25. 37
      src/session.rs
  26. 106
      src/storage.rs
  27. 1
      types/cloud/Cargo.toml
  28. 5
      types/cloud/src/lib.rs
  29. 15
      types/dao/src/lib.rs
  30. 1
      types/domain/Cargo.toml
  31. 13
      types/domain/src/lib.rs
  32. 1
      types/group/Cargo.toml
  33. 5
      types/group/src/lib.rs
  34. 4
      types/primitives/src/lib.rs
  35. 9
      windows/flutter/generated_plugin_registrant.cc
  36. 1
      windows/flutter/generated_plugins.cmake

13
Cargo.toml

@ -34,9 +34,9 @@ panic = 'abort' @@ -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" @@ -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 } @@ -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" }

4
lib/global.dart

@ -1,8 +1,8 @@ @@ -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

25
lib/rpc.dart

@ -10,7 +10,6 @@ import 'package:esse/global.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 { @@ -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 { @@ -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);

3
lib/security.dart

@ -175,9 +175,6 @@ class _SecurityPageState extends State<SecurityPage> { @@ -175,9 +175,6 @@ class _SecurityPageState extends State<SecurityPage> {
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) {

2
macos/Flutter/GeneratedPluginRegistrant.swift

@ -6,6 +6,7 @@ import FlutterMacOS @@ -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 @@ -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"))

231
pubspec.lock

@ -15,13 +15,6 @@ packages: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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: @@ -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"

4
pubspec.yaml

@ -35,10 +35,6 @@ dependencies: @@ -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

70
src/account.rs

@ -2,12 +2,14 @@ use rand::Rng; @@ -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 { @@ -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<u8>, // encrypted value.
@ -56,7 +58,7 @@ pub(crate) struct Account { @@ -56,7 +58,7 @@ pub(crate) struct Account {
pub secret: Vec<u8>, // encrypted value.
pub encrypt: Vec<u8>, // 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 { @@ -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 { @@ -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 { @@ -117,8 +119,8 @@ impl Account {
name: &str,
lock: &str,
avatar: Vec<u8>,
) -> 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 { @@ -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 { @@ -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<Keypair> {
pub fn secret(&self, salt: &[u8], lock: &str) -> Result<PeerKey> {
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 { @@ -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 { @@ -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<Account> {
pub fn get(db: &DStorage, pid: &PeerId) -> Result<Account> {
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 { @@ -231,7 +237,7 @@ impl Account {
pub fn all(db: &DStorage) -> Result<Vec<Account>> {
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 { @@ -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 { @@ -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 { @@ -330,17 +335,9 @@ pub(crate) struct User {
}
impl User {
pub fn new(
id: GroupId,
addr: PeerId,
name: String,
avatar: Vec<u8>,
wallet: String,
height: i64,
) -> Self {
pub fn new(id: PeerId, name: String, avatar: Vec<u8>, wallet: String, height: i64) -> Self {
Self {
id,
addr,
name,
avatar,
wallet,
@ -350,8 +347,7 @@ impl User { @@ -350,8 +347,7 @@ impl User {
pub fn info(name: String, wallet: String, height: i64, avatar: Vec<u8>) -> Self {
Self {
id: GroupId::default(),
addr: PeerId::default(),
id: PeerId::default(),
name,
wallet,
height,

78
src/apps.rs

@ -2,56 +2,56 @@ use std::sync::Arc; @@ -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<RpcState>) {
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<Global>) {
//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<RwLock<Layer>>,
fgid: GroupId,
mgid: GroupId,
msg: RecvType,
) -> Result<HandleResult> {
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<RwLock<Layer>>,
// fgid: GroupId,
// mgid: GroupId,
// msg: RecvType,
// ) -> Result<HandleResult> {
// 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<HandleResult> {
todo!()
}
// pub(crate) fn _app_group_handle() -> Result<HandleResult> {
// todo!()
// }
pub(crate) fn _app_migrate() -> Result<()> {
todo!()
}
// pub(crate) fn _app_migrate() -> Result<()> {
// todo!()
// }

4
src/apps/device/mod.rs

@ -1,5 +1,5 @@ @@ -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;

40
src/apps/device/models.rs

@ -1,6 +1,5 @@ @@ -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 { @@ -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 { @@ -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 { @@ -35,7 +34,7 @@ impl Device {
fn from_values(mut v: Vec<DsValue>) -> 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 { @@ -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 { @@ -56,25 +55,22 @@ impl Device {
/// load account devices.
pub fn list(db: &DStorage) -> Result<Vec<Device>> {
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<HashMap<PeerId, (Peer, i64, bool)>> {
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<Vec<(Peer, i64, bool)>> {
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 { @@ -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)?;

10
src/apps/device/rpc.rs

@ -12,28 +12,28 @@ use crate::utils::device_status::device_status as local_device_status; @@ -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,

7
src/daemon.rs

@ -8,15 +8,16 @@ use std::env::args; @@ -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;

92
src/global.rs

@ -0,0 +1,92 @@ @@ -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<PeerId>,
/// current account public height.
pub peer_pub_height: RwLock<u64>,
/// current account own height.
pub peer_own_height: RwLock<u64>,
/// current group.
pub group: RwLock<Group>,
/// current layer.
pub layer: RwLock<Layer>,
/// TDN network sender.
pub sender: RwLock<Sender<SendMessage>>,
/// message delivery tracking. uuid, me_gid, db_id.
pub _delivery: RwLock<HashMap<u64, (GroupId, i64)>>,
/// storage base path.
pub base: PathBuf,
/// random secret seed.
pub secret: [u8; 32],
}
impl Global {
pub fn init(
accounts: HashMap<PeerId, Account>,
tdn_send: Sender<SendMessage>,
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<bool> {
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)
}
}

1630
src/group.rs

File diff suppressed because it is too large Load Diff

42
src/group/running.rs

@ -1,11 +1,7 @@ @@ -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; @@ -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<PeerId, (Peer, i64, bool)>,
pub distributes: Vec<(Peer, i64, bool)>,
/// uptime
pub uptime: u32,
}
impl RunningAccount {
pub fn init(keypair: Keypair, base: &PathBuf, key: &str, gid: &GroupId) -> Result<Self> {
pub fn init(keypair: PeerKey, base: &PathBuf, key: &str, pid: &PeerId) -> Result<Self> {
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 { @@ -49,21 +45,23 @@ impl RunningAccount {
})
}
pub fn add_online(&mut self, addr: &PeerId) -> Result<i64> {
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<i64> {
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<i64> {
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<i64> {
for i in self.distributes.iter_mut() {
if &i.0 == peer {
i.2 = false;
return Ok(i.1);
}
}
Err(anyhow!("missing distribute device"))
}
}

742
src/layer.rs

@ -5,15 +5,15 @@ use std::sync::Arc; @@ -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 { @@ -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<GroupId, RunningLayer>,
/// message delivery tracking. uuid, me_gid, db_id.
pub delivery: HashMap<u64, (GroupId, i64)>,
/// storage base path.
pub base: PathBuf,
/// self peer addr.
pub addr: PeerId,
/// group info.
pub group: Arc<RwLock<Group>>,
/// running layers: (Layer_gid, layer sessions)
pub sessions: HashMap<GroupId, HashMap<PeerId, LayerSession>>,
}
impl Layer {
pub async fn init(base: PathBuf, addr: PeerId, group: Arc<RwLock<Group>>) -> Result<Layer> {
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<PeerId, GroupId> {
// check close the stable connection.
let mut addrs: HashMap<PeerId, GroupId> = 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<PeerId, GroupId> {
let mut addrs: HashMap<PeerId, GroupId> = 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<PeerId> {
self.running_mut(gid).ok()?.remove_online(fgid)
}
pub async fn all_layer_conns(&self) -> Result<HashMap<GroupId, Vec<(GroupId, SendType)>>> {
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<PeerId, GroupId> {
// // check close the stable connection.
// let mut addrs: HashMap<PeerId, GroupId> = 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<PeerId, GroupId> {
// let mut addrs: HashMap<PeerId, GroupId> = 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<PeerId> {
// self.running_mut(gid).ok()?.remove_online(fgid)
// }
// pub async fn all_layer_conns(&self) -> Result<HashMap<GroupId, Vec<(GroupId, SendType)>>> {
// 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 { @@ -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 { @@ -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<GroupId, OnlineSession>,
// 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<PeerId> {
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<bool> {
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<PeerId> {
self.sessions
.get(gid)
.map(|online| *online.online.addr())
.ok_or(anyhow!("remote not online"))
}
pub fn online_direct(&self, gid: &GroupId) -> Result<PeerId> {
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<PeerId> {
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<i64> {
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<PeerId> {
// 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<bool> {
// 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<PeerId> {
// self.sessions
// .get(gid)
// .map(|online| *online.online.addr())
// .ok_or(anyhow!("remote not online"))
// }
// pub fn online_direct(&self, gid: &GroupId) -> Result<PeerId> {
// 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<PeerId> {
// 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<i64> {
// 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
// }
}

7
src/lib.rs

@ -9,15 +9,16 @@ use std::os::raw::c_char; @@ -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;

2
src/migrate.rs

@ -1,5 +1,5 @@ @@ -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;

2
src/migrate/account.rs

@ -2,7 +2,7 @@ @@ -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,

2
src/migrate/consensus.rs

@ -10,7 +10,7 @@ pub(super) const CONSENSUS_VERSIONS: [&str; 9] = [ @@ -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,

3
src/migrate/session.rs

@ -3,7 +3,6 @@ pub(super) const SESSION_VERSIONS: [&str; 2] = [ @@ -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] = [ @@ -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.
];

785
src/rpc.rs

@ -1,10 +1,11 @@ @@ -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::{ @@ -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<RwLock<Group>>,
layer: Arc<RwLock<Layer>>,
) -> RpcHandler<RpcState> {
let mut handler = new_rpc_handler(addr, group, layer);
//use crate::session::{connect_session, Session, SessionType};
pub(crate) fn init_rpc(global: Arc<Global>) -> RpcHandler<Global> {
let mut handler = new_rpc_handler(global);
app_rpc_inject(&mut handler);
handler
}
pub(crate) struct RpcState {
pub group: Arc<RwLock<Group>>,
pub layer: Arc<RwLock<Layer>>,
}
#[inline]
pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam {
let s_peers: Vec<Vec<String>> = peers
@ -50,100 +43,95 @@ pub(crate) fn network_stable(peers: Vec<(PeerId, bool)>) -> RpcParam { @@ -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<PeerId>) -> RpcParam {
let s_peers: Vec<String> = 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<Session>) -> 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<Session>) -> 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( @@ -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( @@ -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<SendMessage>) -> Result<()> {
pub(crate) async fn inner_rpc(uid: u64, method: &str, global: &Arc<Global>) -> 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<SendMessag @@ -185,7 +166,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag
};
let (s, mut r) = mpsc::channel::<StateResponse>(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<SendMessag @@ -198,7 +182,10 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag
}
};
sender
global
.sender
.read()
.await
.send(SendMessage::Rpc(uid, param, false))
.await
.expect("TDN channel closed");
@ -209,58 +196,44 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag @@ -209,58 +196,44 @@ pub(crate) async fn inner_rpc(uid: u64, method: &str, sender: &Sender<SendMessag
Err(anyhow!("not found"))
}
fn new_rpc_handler(
addr: PeerId,
group: Arc<RwLock<Group>>,
layer: Arc<RwLock<Layer>>,
) -> RpcHandler<RpcState> {
let mut handler = RpcHandler::new(RpcState { group, layer });
fn new_rpc_handler(global: Arc<Global>) -> RpcHandler<Global> {
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<RpcParam>, _| 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::<SocketAddr>() {
Ok(HandleResult::network(NetworkType::Connect(
Peer::socket_transport(addr, transport),
)))
} else {
Err(RpcError::InvalidRequest)
}
});
handler.add_method(
"add-bootstrap",
|_gid, params: Vec<RpcParam>, _| 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::<SocketAddr>() {
Ok(HandleResult::network(NetworkType::Connect(
Peer::socket_transport(addr, transport),
)))
} else {
Err(RpcError::InvalidRequest)
}
},
);
handler.add_method(
"account-list",
|_gid, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let mut users: Vec<Vec<String>> = 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<Global>| async move {
let mut accounts: Vec<Vec<String>> = 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<RpcParam>, _state: Arc<RpcState>| async move {
|params: Vec<RpcParam>, _state: Arc<Global>| 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( @@ -270,7 +243,7 @@ fn new_rpc_handler(
handler.add_method(
"account-create",
|_gid, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
|params: Vec<RpcParam>, state: Arc<Global>| 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( @@ -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<RpcParam>, state: Arc<RpcState>| async move {
|params: Vec<RpcParam>, state: Arc<Global>| 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( @@ -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<RpcParam>, state: Arc<RpcState>| async move {
|params: Vec<RpcParam>, state: Arc<Global>| 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( @@ -368,81 +339,84 @@ fn new_rpc_handler(
handler.add_method(
"account-pin-check",
|_gid: GroupId, params: Vec<RpcParam>, state: Arc<RpcState>| async move {
let gid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?;
|params: Vec<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<RpcState>| async move {
"account-pin-change",
|params: Vec<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<RpcState>| async move {
|params: Vec<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<RpcState>| async move {
let ogid = GroupId::from_hex(params[0].as_str().ok_or(RpcError::ParseError)?)?;
|params: Vec<RpcParam>, state: Arc<Global>| 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( @@ -450,209 +424,152 @@ fn new_rpc_handler(
handler.add_method(
"account-logout",
|_gid: GroupId, _params: Vec<RpcParam>, state: Arc<RpcState>| async move {
|_params: Vec<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<RpcState>| 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<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<Global>| 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<RpcParam>, state: Arc<Global>| 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
}

265
src/server.rs

@ -5,7 +5,10 @@ use std::path::PathBuf; @@ -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::{ @@ -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<u64> = OnceCell::new();
@ -61,49 +65,54 @@ pub async fn start(db_path: String) -> Result<()> { @@ -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<GroupId, Account> = HashMap::new();
let mut me: HashMap<PeerId, Account> = 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<GroupId> = 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<u64, GroupId> = 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<u64, GroupId> = 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<()> { @@ -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<()> { @@ -141,81 +149,87 @@ pub async fn start(db_path: String) -> Result<()> {
Ok(())
}
#[inline]
async fn sleep_waiting_reboot(
sender: Sender<SendMessage>,
groups: HashMap<GroupId, Vec<SendType>>,
layers: HashMap<GroupId, Vec<(GroupId, SendType)>>,
) -> std::result::Result<(), SendError<SendMessage>> {
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<RwLock<Layer>>,
sender: Sender<SendMessage>,
) -> 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<SendMessage>,
// groups: HashMap<GroupId, Vec<SendType>>,
// layers: HashMap<GroupId, Vec<(GroupId, SendType)>>,
// ) -> std::result::Result<(), SendError<SendMessage>> {
// 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<RwLock<Layer>>,
// sender: Sender<SendMessage>,
// ) -> 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<SendMessage>) {
async fn handle(
handle_result: HandleResult,
uid: u64,
is_ws: bool,
global: &Arc<Global>,
rpc_sender: &Sender<RpcSendMessage>,
) {
let HandleResult {
mut rpcs,
mut groups,
@ -226,8 +240,8 @@ async fn handle(handle_result: HandleResult, uid: u64, is_ws: bool, sender: &Sen @@ -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 @@ -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 @@ -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 @@ -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 {

37
src/session.rs

@ -1,6 +1,6 @@ @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -142,7 +129,7 @@ impl Session {
}
pub fn get(db: &DStorage, id: &i64) -> Result<Session> {
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 { @@ -152,7 +139,7 @@ impl Session {
}
pub fn list(db: &DStorage) -> Result<Vec<Session>> {
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( @@ -268,7 +255,7 @@ pub(crate) fn connect_session(
fid: &i64,
addr: &PeerId,
) -> Result<Option<Session>> {
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 {

106
src/storage.rs

@ -1,12 +1,17 @@ @@ -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<Vec<u8>> { @@ -56,11 +61,11 @@ pub(crate) async fn read_file(base: &PathBuf) -> Result<Vec<u8>> {
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( @@ -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<String> {
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( @@ -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<u8>,
) -> Result<String> {
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( @@ -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<Vec<u8>> {
pub(crate) async fn read_db_file(base: &PathBuf, pid: &PeerId, name: &str) -> Result<Vec<u8>> {
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 @@ -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<Vec<u8>> {
pub(crate) async fn read_image(base: &PathBuf, pid: &PeerId, name: &str) -> Result<Vec<u8>> {
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<DynamicImage> { @@ -143,9 +148,9 @@ fn image_thumb(bytes: &[u8]) -> Result<DynamicImage> {
}
}
pub(crate) fn write_image_sync(base: &PathBuf, gid: &GroupId, bytes: Vec<u8>) -> Result<String> {
pub(crate) fn write_image_sync(base: &PathBuf, pid: &PeerId, bytes: Vec<u8>) -> Result<String> {
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<u8>) -> @@ -164,9 +169,9 @@ pub(crate) fn write_image_sync(base: &PathBuf, gid: &GroupId, bytes: Vec<u8>) ->
Ok(name)
}
pub(crate) async fn write_image(base: &PathBuf, gid: &GroupId, bytes: &[u8]) -> Result<String> {
pub(crate) async fn write_image(base: &PathBuf, pid: &PeerId, bytes: &[u8]) -> Result<String> {
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]) -> @@ -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<Vec<u8>> {
pub(crate) async fn read_avatar(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<Vec<u8>> {
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( @@ -208,9 +209,9 @@ pub(crate) async fn read_avatar(
}
}
pub(crate) fn read_avatar_sync(base: &PathBuf, gid: &GroupId, remote: &GroupId) -> Result<Vec<u8>> {
pub(crate) fn read_avatar_sync(base: &PathBuf, pid: &PeerId, remote: &PeerId) -> Result<Vec<u8>> {
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) @@ -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( @@ -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<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));
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 @@ -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 @@ -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<Vec<u8>> {
pub(crate) async fn read_record(base: &PathBuf, pid: &PeerId, name: &str) -> Result<Vec<u8>> {
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 @@ -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<u8>,
) -> Result<String> {
@ -301,7 +302,7 @@ pub(crate) fn write_record_sync( @@ -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( @@ -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<DStorage> {
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<DStorage> {
let mut db_path = base.clone();
db_path.push(id_to_str(pid));
db_path.push(CONSENSUS_DB);
DStorage::open(db_path, db_key)
}

1
types/cloud/Cargo.toml

@ -12,4 +12,3 @@ license = "MIT/Apache-2.0" @@ -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 }

5
types/cloud/src/lib.rs

@ -1,5 +1,4 @@ @@ -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; @@ -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)]

15
types/dao/src/lib.rs

@ -1,5 +1,4 @@ @@ -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); @@ -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 { @@ -104,11 +103,11 @@ pub enum JoinProof {
/// params: member name, member avatar.
Open(String, Vec<u8>),
/// 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<u8>),
/// params: invite_by_account, member name, member avatar.
Invite(PeerId, String, Vec<u8>),
/// 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 { @@ -150,8 +149,8 @@ pub enum LayerEvent {
/// params: check type, provider name, remain, supported_group_types.
CheckResult(CheckType, String, i64, Vec<GroupType>),
/// 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),

1
types/domain/Cargo.toml

@ -12,4 +12,3 @@ license = "MIT/Apache-2.0" @@ -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 }

13
types/domain/src/lib.rs

@ -1,5 +1,4 @@ @@ -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}; @@ -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 { @@ -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.

1
types/group/Cargo.toml

@ -13,4 +13,3 @@ license = "MIT/Apache-2.0" @@ -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 }

5
types/group/src/lib.rs

@ -1,5 +1,4 @@ @@ -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; @@ -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.

4
types/primitives/src/lib.rs

@ -77,11 +77,11 @@ pub mod bs32 { @@ -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<PeerId> {
pub fn id_from_str(s: &str) -> std::io::Result<PeerId> {
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."));

9
windows/flutter/generated_plugin_registrant.cc

@ -7,14 +7,17 @@ @@ -7,14 +7,17 @@
#include "generated_plugin_registrant.h"
#include <esse_core/esse_core_plugin.h>
#include <file_selector_windows/file_selector_plugin.h>
#include <file_selector_windows/file_selector_windows.h>
#include <permission_handler_windows/permission_handler_windows_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>
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"));
}

1
windows/flutter/generated_plugins.cmake

@ -5,6 +5,7 @@ @@ -5,6 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
esse_core
file_selector_windows
permission_handler_windows
url_launcher_windows
)

Loading…
Cancel
Save