integration test and config work

This commit is contained in:
Christien Rioux 2024-03-02 17:45:26 -05:00
parent 8818e63dc0
commit a04d4e12c5
17 changed files with 521 additions and 304 deletions

76
Cargo.lock generated
View File

@ -1210,6 +1210,29 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "crossbeam-deque"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fca89a0e215bab21874660c67903c5f143333cab1da83d041c7ded6053774751"
dependencies = [
"cfg-if 1.0.0",
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa"
dependencies = [
"autocfg",
"cfg-if 1.0.0",
"crossbeam-utils",
"memoffset 0.9.0",
]
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.19" version = "0.8.19"
@ -2816,9 +2839,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.152" version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]] [[package]]
name = "libc-print" name = "libc-print"
@ -2988,6 +3011,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "memory_units" name = "memory_units"
version = "0.4.0" version = "0.4.0"
@ -4015,6 +4047,26 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
[[package]]
name = "rayon"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1"
dependencies = [
"either",
"rayon-core",
]
[[package]]
name = "rayon-core"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed"
dependencies = [
"crossbeam-deque",
"crossbeam-utils",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.16"
@ -4824,16 +4876,17 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]] [[package]]
name = "sysinfo" name = "sysinfo"
version = "0.29.11" version = "0.30.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" checksum = "6746919caf9f2a85bff759535664c060109f21975c5ac2e8652e60102bd4d196"
dependencies = [ dependencies = [
"cfg-if 1.0.0", "cfg-if 1.0.0",
"core-foundation-sys", "core-foundation-sys",
"libc", "libc",
"ntapi", "ntapi",
"once_cell", "once_cell",
"winapi", "rayon",
"windows 0.52.0",
] ]
[[package]] [[package]]
@ -5670,6 +5723,7 @@ dependencies = [
"socket2 0.5.5", "socket2 0.5.5",
"static_assertions", "static_assertions",
"stop-token", "stop-token",
"sysinfo",
"thiserror", "thiserror",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@ -5696,7 +5750,7 @@ dependencies = [
"webpki-roots 0.25.3", "webpki-roots 0.25.3",
"wee_alloc", "wee_alloc",
"winapi", "winapi",
"windows", "windows 0.51.1",
"windows-permissions", "windows-permissions",
"ws_stream_wasm", "ws_stream_wasm",
"x25519-dalek", "x25519-dalek",
@ -6180,6 +6234,16 @@ dependencies = [
"windows-targets 0.48.5", "windows-targets 0.48.5",
] ]
[[package]]
name = "windows"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be"
dependencies = [
"windows-core 0.52.0",
"windows-targets 0.52.0",
]
[[package]] [[package]]
name = "windows-core" name = "windows-core"
version = "0.51.1" version = "0.51.1"

View File

@ -151,6 +151,7 @@ nix = "0.27.1"
# System # System
async-std = { version = "1.12.0", features = ["unstable"], optional = true } async-std = { version = "1.12.0", features = ["unstable"], optional = true }
sysinfo = { version = "^0.30.6" }
tokio = { version = "1.35.0", features = ["full"], optional = true } tokio = { version = "1.35.0", features = ["full"], optional = true }
tokio-util = { version = "0.7.10", features = ["compat"], optional = true } tokio-util = { version = "0.7.10", features = ["compat"], optional = true }
tokio-stream = { version = "0.1.14", features = ["net"], optional = true } tokio-stream = { version = "0.1.14", features = ["net"], optional = true }

View File

@ -1,7 +1,22 @@
use crate::*; use crate::*;
use directories::ProjectDirs;
use std::path::PathBuf; use std::path::PathBuf;
cfg_if::cfg_if! {
if #[cfg(not(target_arch = "wasm32"))] {
use sysinfo::System;
use lazy_static::*;
use directories::ProjectDirs;
lazy_static! {
static ref SYSTEM:System = {
sysinfo::System::new_with_specifics(
sysinfo::RefreshKind::new().with_memory(sysinfo::MemoryRefreshKind::everything()),
)
};
}
}
}
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
pub type ConfigCallbackReturn = VeilidAPIResult<Box<dyn core::any::Any + Send>>; pub type ConfigCallbackReturn = VeilidAPIResult<Box<dyn core::any::Any + Send>>;
pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send + Sync>; pub type ConfigCallback = Arc<dyn Fn(String) -> ConfigCallbackReturn + Send + Sync>;
@ -103,8 +118,15 @@ pub struct VeilidConfigUDP {
impl Default for VeilidConfigUDP { impl Default for VeilidConfigUDP {
fn default() -> Self { fn default() -> Self {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
let enabled = false;
} else {
let enabled = true;
}
}
Self { Self {
enabled: true, enabled,
socket_pool_size: 0, socket_pool_size: 0,
listen_address: String::from(""), listen_address: String::from(""),
public_address: None, public_address: None,
@ -135,9 +157,18 @@ pub struct VeilidConfigTCP {
impl Default for VeilidConfigTCP { impl Default for VeilidConfigTCP {
fn default() -> Self { fn default() -> Self {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
let connect = false;
let listen = false;
} else {
let connect = true;
let listen = true;
}
}
Self { Self {
connect: true, connect,
listen: true, listen,
max_connections: 32, max_connections: 32,
listen_address: String::from(""), listen_address: String::from(""),
public_address: None, public_address: None,
@ -151,7 +182,7 @@ impl Default for VeilidConfigTCP {
/// ws: /// ws:
/// connect: true /// connect: true
/// listen: true /// listen: true
/// max_connections: 16 /// max_connections: 32
/// listen_address: ':5150' /// listen_address: ':5150'
/// path: 'ws' /// path: 'ws'
/// url: 'ws://localhost:5150/ws' /// url: 'ws://localhost:5150/ws'
@ -171,10 +202,19 @@ pub struct VeilidConfigWS {
impl Default for VeilidConfigWS { impl Default for VeilidConfigWS {
fn default() -> Self { fn default() -> Self {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
let connect = true;
let listen = false;
} else {
let connect = true;
let listen = true;
}
}
Self { Self {
connect: true, connect,
listen: true, listen,
max_connections: 16, max_connections: 32,
listen_address: String::from(""), listen_address: String::from(""),
path: String::from("ws"), path: String::from("ws"),
url: None, url: None,
@ -188,7 +228,7 @@ impl Default for VeilidConfigWS {
/// wss: /// wss:
/// connect: true /// connect: true
/// listen: false /// listen: false
/// max_connections: 16 /// max_connections: 32
/// listen_address: ':5150' /// listen_address: ':5150'
/// path: 'ws' /// path: 'ws'
/// url: '' /// url: ''
@ -211,7 +251,7 @@ impl Default for VeilidConfigWSS {
Self { Self {
connect: true, connect: true,
listen: false, listen: false,
max_connections: 16, max_connections: 32,
listen_address: String::from(""), listen_address: String::from(""),
path: String::from("ws"), path: String::from("ws"),
url: None, url: None,
@ -254,15 +294,22 @@ pub struct VeilidConfigTLS {
impl Default for VeilidConfigTLS { impl Default for VeilidConfigTLS {
fn default() -> Self { fn default() -> Self {
let certificate_path = get_default_ssl_directory("certs/server.crt");
let private_key_path = get_default_ssl_directory("keys/server.key");
Self { Self {
certificate_path: get_default_ssl_directory("certs/server.crt"), certificate_path,
private_key_path: get_default_ssl_directory("keys/server.key"), private_key_path,
connection_initial_timeout_ms: 2000, connection_initial_timeout_ms: 2000,
} }
} }
} }
#[cfg_attr(target_arch = "wasm32", allow(unused_variables))]
pub fn get_default_ssl_directory(sub_path: &str) -> String { pub fn get_default_ssl_directory(sub_path: &str) -> String {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
"".to_owned()
} else {
#[cfg(unix)] #[cfg(unix)]
{ {
let default_path = PathBuf::from("/etc/veilid-server/ssl").join(sub_path); let default_path = PathBuf::from("/etc/veilid-server/ssl").join(sub_path);
@ -270,12 +317,13 @@ pub fn get_default_ssl_directory(sub_path: &str) -> String {
return default_path.to_string_lossy().into(); return default_path.to_string_lossy().into();
} }
} }
ProjectDirs::from("org", "Veilid", "Veilid") ProjectDirs::from("org", "Veilid", "Veilid")
.map(|dirs| dirs.data_local_dir().join("ssl").join(sub_path)) .map(|dirs| dirs.data_local_dir().join("ssl").join(sub_path))
.unwrap_or_else(|| PathBuf::from("./ssl").join(sub_path)) .unwrap_or_else(|| PathBuf::from("./ssl").join(sub_path))
.to_string_lossy() .to_string_lossy()
.into() .into()
}
}
} }
/// Configure the Distributed Hash Table (DHT) /// Configure the Distributed Hash Table (DHT)
@ -309,8 +357,33 @@ pub struct VeilidConfigDHT {
impl Default for VeilidConfigDHT { impl Default for VeilidConfigDHT {
fn default() -> Self { fn default() -> Self {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
let local_subkey_cache_size = 128;
let local_max_subkey_cache_memory_mb = 256;
let remote_subkey_cache_size = 64;
let remote_max_records = 64;
let remote_max_subkey_cache_memory_mb = 256;
let remote_max_storage_space_mb = 128;
} else {
let local_subkey_cache_size = 1024;
let local_max_subkey_cache_memory_mb = if sysinfo::IS_SUPPORTED_SYSTEM {
(SYSTEM.total_memory() / 32u64 / (1024u64 * 1024u64)) as u32
} else {
256
};
let remote_subkey_cache_size = 128;
let remote_max_records = 128;
let remote_max_subkey_cache_memory_mb = if sysinfo::IS_SUPPORTED_SYSTEM {
(SYSTEM.total_memory() / 32u64 / (1024u64 * 1024u64)) as u32
} else {
256
};
let remote_max_storage_space_mb = 256;
}
}
Self { Self {
// Assuming some reasonable defaults
max_find_node_count: 20, max_find_node_count: 20,
resolve_node_timeout_ms: 10000, resolve_node_timeout_ms: 10000,
resolve_node_count: 1, resolve_node_count: 1,
@ -324,12 +397,12 @@ impl Default for VeilidConfigDHT {
min_peer_count: 20, min_peer_count: 20,
min_peer_refresh_time_ms: 60000, min_peer_refresh_time_ms: 60000,
validate_dial_info_receipt_time_ms: 2000, validate_dial_info_receipt_time_ms: 2000,
local_subkey_cache_size: 1024, local_subkey_cache_size,
local_max_subkey_cache_memory_mb: 256, local_max_subkey_cache_memory_mb,
remote_subkey_cache_size: 128, remote_subkey_cache_size,
remote_max_records: 128, remote_max_records,
remote_max_subkey_cache_memory_mb: 256, remote_max_subkey_cache_memory_mb,
remote_max_storage_space_mb: 256, remote_max_storage_space_mb,
public_watch_limit: 32, public_watch_limit: 32,
member_watch_limit: 8, member_watch_limit: 8,
max_watch_expiration_ms: 600000, max_watch_expiration_ms: 600000,
@ -388,10 +461,18 @@ pub struct VeilidConfigRoutingTable {
impl Default for VeilidConfigRoutingTable { impl Default for VeilidConfigRoutingTable {
fn default() -> Self { fn default() -> Self {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
let bootstrap = vec!["ws://bootstrap.veilid.net:5150/ws".to_string()];
} else {
let bootstrap = vec!["bootstrap.veilid.net".to_string()];
}
}
Self { Self {
node_id: TypedKeyGroup::default(), node_id: TypedKeyGroup::default(),
node_id_secret: TypedSecretGroup::default(), node_id_secret: TypedSecretGroup::default(),
bootstrap: vec!["bootstrap.veilid.net".to_string()], bootstrap,
limit_over_attached: 64, limit_over_attached: 64,
limit_fully_attached: 32, limit_fully_attached: 32,
limit_attached_strong: 16, limit_attached_strong: 16,
@ -468,7 +549,12 @@ impl Default for VeilidConfigTableStore {
} }
} }
#[cfg_attr(target_arch = "wasm32", allow(unused_variables))]
fn get_default_store_path(store_type: &str) -> String { fn get_default_store_path(store_type: &str) -> String {
cfg_if::cfg_if! {
if #[cfg(target_arch = "wasm32")] {
"".to_owned()
} else {
#[cfg(unix)] #[cfg(unix)]
{ {
let globalpath = PathBuf::from(format!("/var/db/veilid-server/{}", store_type)); let globalpath = PathBuf::from(format!("/var/db/veilid-server/{}", store_type));
@ -476,13 +562,14 @@ fn get_default_store_path(store_type: &str) -> String {
return globalpath.to_string_lossy().into(); return globalpath.to_string_lossy().into();
} }
} }
ProjectDirs::from("org", "Veilid", "Veilid") ProjectDirs::from("org", "Veilid", "Veilid")
.map(|dirs| dirs.data_local_dir().to_path_buf()) .map(|dirs| dirs.data_local_dir().to_path_buf())
.unwrap_or_else(|| PathBuf::from("./")) .unwrap_or_else(|| PathBuf::from("./"))
.join(store_type) .join(store_type)
.to_string_lossy() .to_string_lossy()
.into() .into()
}
}
} }
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)] #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
@ -520,7 +607,7 @@ impl Default for VeilidConfigProtectedStore {
always_use_insecure_storage: false, always_use_insecure_storage: false,
directory: get_default_store_path("protected_store"), directory: get_default_store_path("protected_store"),
delete: false, delete: false,
device_encryption_key_password: String::from(""), device_encryption_key_password: "".to_owned(),
new_device_encryption_key_password: None, new_device_encryption_key_password: None,
} }
} }

View File

@ -0,0 +1,40 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'fixtures.dart';
import 'test_veilid_config.dart';
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
group('VeilidConfig', () {
final fixture = DefaultFixture();
setUp(fixture.setUp);
tearDown(fixture.tearDown);
test('test VeilidConfig defaults', testVeilidConfigDefaults);
});
// group('end-to-end test', () {
// testWidgets('tap on the floating action button, verify counter',
// (tester) async {
// // Load app widget.
// await tester.pumpWidget(const MyApp());
// // Verify the counter starts at 0.
// expect(find.text('0'), findsOneWidget);
// // Finds the floating action button to tap on.
// final fab = find.byKey(const Key('increment'));
// // Emulate a tap on the floating action button.
// await tester.tap(fab);
// // Trigger a frame.
// await tester.pumpAndSettle();
// // Verify the counter increments by 1.
// expect(find.text('1'), findsOneWidget);
// });
// });
}

View File

@ -0,0 +1,91 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:mutex/mutex.dart';
import 'package:veilid/veilid.dart';
class DefaultFixture {
DefaultFixture();
StreamSubscription<VeilidUpdate>? _updateSubscription;
Stream<VeilidUpdate>? _updateStream;
static final _fixtureMutex = Mutex();
Future<void> setUp() async {
await _fixtureMutex.acquire();
assert(_updateStream == null, 'should not set up fixture twice');
final Map<String, dynamic> platformConfigJson;
if (kIsWeb) {
const platformConfig = VeilidWASMConfig(
logging: VeilidWASMConfigLogging(
performance: VeilidWASMConfigLoggingPerformance(
enabled: true,
level: VeilidConfigLogLevel.debug,
logsInTimings: true,
logsInConsole: false,
),
api: VeilidWASMConfigLoggingApi(
enabled: true,
level: VeilidConfigLogLevel.info,
)));
platformConfigJson = platformConfig.toJson();
} else {
const platformConfig = VeilidFFIConfig(
logging: VeilidFFIConfigLogging(
terminal: VeilidFFIConfigLoggingTerminal(
enabled: false,
level: VeilidConfigLogLevel.debug,
),
otlp: VeilidFFIConfigLoggingOtlp(
enabled: false,
level: VeilidConfigLogLevel.trace,
grpcEndpoint: 'localhost:4317',
serviceName: 'Veilid Tests',
),
api: VeilidFFIConfigLoggingApi(
enabled: true,
level: VeilidConfigLogLevel.info,
)));
platformConfigJson = platformConfig.toJson();
}
Veilid.instance.initializeVeilidCore(platformConfigJson);
final defaultConfig = await getDefaultVeilidConfig(
isWeb: kIsWeb, programName: 'Veilid Tests');
final updateStream =
_updateStream = await Veilid.instance.startupVeilidCore(defaultConfig);
if (_updateStream == null) {
throw Exception('failed to start up veilid core');
}
_updateSubscription = updateStream.listen((update) {
if (update is VeilidLog) {
} else if (update is VeilidUpdateAttachment) {
} else if (update is VeilidUpdateConfig) {
} else if (update is VeilidUpdateNetwork) {
} else if (update is VeilidAppMessage) {
} else if (update is VeilidAppCall) {
} else if (update is VeilidUpdateValueChange) {
} else {
throw Exception('unexpected update: $update');
}
});
}
Future<void> tearDown() async {
assert(_updateStream != null, 'should not tearDown without setUp');
final cancelFut = _updateSubscription?.cancel();
await Veilid.instance.shutdownVeilidCore();
await cancelFut;
_updateSubscription = null;
_updateStream = null;
_fixtureMutex.release();
}
}

View File

@ -0,0 +1,10 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:veilid/default_config.dart';
Future<void> testVeilidConfigDefaults() async {
const programName = 'Veilid Tests';
final defaultConfig =
await getDefaultVeilidConfig(isWeb: kIsWeb, programName: programName);
assert(defaultConfig.programName == programName, 'program name should match');
}

View File

@ -1,6 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:veilid/veilid.dart'; import 'package:veilid/veilid.dart';
import 'package:loggy/loggy.dart'; import 'package:loggy/loggy.dart';
@ -109,7 +110,8 @@ class _MyAppState extends State<MyApp> with UiLoggy {
Future<void> toggleStartup(bool startup) async { Future<void> toggleStartup(bool startup) async {
if (startup && !_startedUp) { if (startup && !_startedUp) {
var config = await getDefaultVeilidConfig("Veilid Plugin Example"); var config = await getDefaultVeilidConfig(
isWeb: kIsWeb, programName: "Veilid Plugin Example");
if (const String.fromEnvironment("DELETE_TABLE_STORE") == "1") { if (const String.fromEnvironment("DELETE_TABLE_STORE") == "1") {
config = config.copyWith( config = config.copyWith(
tableStore: config.tableStore.copyWith(delete: true)); tableStore: config.tableStore.copyWith(delete: true));

View File

@ -11,12 +11,9 @@ void veilidInit() {
enabled: true, enabled: true,
level: VeilidConfigLogLevel.debug, level: VeilidConfigLogLevel.debug,
logsInTimings: true, logsInTimings: true,
logsInConsole: false, logsInConsole: false),
ignoreLogTargets: []),
api: VeilidWASMConfigLoggingApi( api: VeilidWASMConfigLoggingApi(
enabled: true, enabled: true, level: VeilidConfigLogLevel.info)));
level: VeilidConfigLogLevel.info,
ignoreLogTargets: [])));
Veilid.instance.initializeVeilidCore(platformConfig.toJson()); Veilid.instance.initializeVeilidCore(platformConfig.toJson());
} else { } else {
var platformConfig = const VeilidFFIConfig( var platformConfig = const VeilidFFIConfig(
@ -24,17 +21,14 @@ void veilidInit() {
terminal: VeilidFFIConfigLoggingTerminal( terminal: VeilidFFIConfigLoggingTerminal(
enabled: false, enabled: false,
level: VeilidConfigLogLevel.debug, level: VeilidConfigLogLevel.debug,
ignoreLogTargets: []), ),
otlp: VeilidFFIConfigLoggingOtlp( otlp: VeilidFFIConfigLoggingOtlp(
enabled: false, enabled: false,
level: VeilidConfigLogLevel.trace, level: VeilidConfigLogLevel.trace,
grpcEndpoint: "localhost:4317", grpcEndpoint: "localhost:4317",
serviceName: "VeilidExample", serviceName: "VeilidExample"),
ignoreLogTargets: []),
api: VeilidFFIConfigLoggingApi( api: VeilidFFIConfigLoggingApi(
enabled: true, enabled: true, level: VeilidConfigLogLevel.info)));
level: VeilidConfigLogLevel.info,
ignoreLogTargets: [])));
Veilid.instance.initializeVeilidCore(platformConfig.toJson()); Veilid.instance.initializeVeilidCore(platformConfig.toJson());
} }
} }

View File

@ -27,9 +27,9 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663 macos_window_utils: 933f91f64805e2eb91a5bd057cf97cd097276663
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943 path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
veilid: a54f57b7bcf0e4e072fe99272d76ca126b2026d0 veilid: a54f57b7bcf0e4e072fe99272d76ca126b2026d0
PODFILE CHECKSUM: 73d2f470b1d889e27fcfda1d6e6efec66f98af3f PODFILE CHECKSUM: 73d2f470b1d889e27fcfda1d6e6efec66f98af3f
COCOAPODS: 1.12.1 COCOAPODS: 1.15.2

View File

@ -208,7 +208,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 0920; LastSwiftUpdateCheck = 0920;
LastUpgradeCheck = 1430; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = ""; ORGANIZATIONNAME = "";
TargetAttributes = { TargetAttributes = {
33CC10EC2044A3C60003C045 = { 33CC10EC2044A3C60003C045 = {

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1430" LastUpgradeVersion = "1510"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -105,6 +105,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.2"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@ -126,14 +134,19 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.3" version: "1.1.3"
flutter_driver:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
flutter_lints: flutter_lints:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: flutter_lints name: flutter_lints
sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.3" version: "3.0.1"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -152,6 +165,11 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.4.1" version: "2.4.1"
fuchsia_remote_debug_protocol:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
globbing: globbing:
dependency: transitive dependency: transitive
description: description:
@ -160,6 +178,11 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.0" version: "1.0.0"
integration_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
json_annotation: json_annotation:
dependency: transitive dependency: transitive
description: description:
@ -196,10 +219,10 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: lints name: lints
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.1" version: "3.0.0"
loggy: loggy:
dependency: "direct main" dependency: "direct main"
description: description:
@ -240,6 +263,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.11.0" version: "1.11.0"
mutex:
dependency: "direct dev"
description:
name: mutex
sha256: "8827da25de792088eb33e572115a5eb0d61d61a3c01acbc8bcbe76ed78f1a1f2"
url: "https://pub.dev"
source: hosted
version: "3.1.0"
path: path:
dependency: "direct main" dependency: "direct main"
description: description:
@ -304,14 +335,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.4" version: "3.1.4"
platform_info:
dependency: transitive
description:
name: platform_info
sha256: "012e73712166cf0b56d3eb95c0d33491f56b428c169eca385f036448474147e4"
url: "https://pub.dev"
source: hosted
version: "3.2.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
@ -320,6 +343,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.8" version: "2.1.8"
process:
dependency: transitive
description:
name: process
sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32"
url: "https://pub.dev"
source: hosted
version: "5.0.2"
quiver: quiver:
dependency: transitive dependency: transitive
description: description:
@ -365,6 +396,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.0" version: "1.2.0"
sync_http:
dependency: transitive
description:
name: sync_http
sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961"
url: "https://pub.dev"
source: hosted
version: "0.3.1"
system_info2: system_info2:
dependency: transitive dependency: transitive
description: description:
@ -428,6 +467,14 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "13.0.0" version: "13.0.0"
webdriver:
dependency: transitive
description:
name: webdriver
sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e"
url: "https://pub.dev"
source: hosted
version: "3.0.3"
win32: win32:
dependency: transitive dependency: transitive
description: description:
@ -448,10 +495,18 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: xterm name: xterm
sha256: "6a02b15d03152b8186e12790902ff28c8a932fc441e89fa7255a7491661a8e69" sha256: "168dfedca77cba33fdb6f52e2cd001e9fde216e398e89335c19b524bb22da3a2"
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "3.5.0" version: "4.0.0"
zmodem:
dependency: transitive
description:
name: zmodem
sha256: "3b7e5b29f3a7d8aee472029b05165a68438eff2f3f7766edf13daba1e297adbf"
url: "https://pub.dev"
source: hosted
version: "0.0.6"
sdks: sdks:
dart: ">=3.3.0-279.1.beta <4.0.0" dart: ">=3.3.0-279.1.beta <4.0.0"
flutter: ">=3.10.6" flutter: ">=3.19.1"

View File

@ -31,27 +31,21 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.6
loggy: ^2.0.1+1 loggy: ^2.0.3
path_provider: ^2.0.11 path_provider: ^2.1.2
path: ^1.8.1 path: ^1.9.0
xterm: ^3.4.0 xterm: ^4.0.0
flutter_acrylic: ^1.0.0+2 flutter_acrylic: ^1.1.3
ansicolor: ^2.0.1 ansicolor: ^2.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
integration_test:
# The "flutter_lints" package below contains a set of recommended lints to sdk: flutter
# encourage good coding practices. The lint set provided by the package is flutter_lints: ^3.0.1
# activated in the `analysis_options.yaml` file located at the root of your mutex: ^3.1.0
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter. # The following section is specific to Flutter.
flutter: flutter:

View File

@ -1,192 +1,49 @@
import 'dart:io'; import 'dart:convert';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:path/path.dart' as p; import 'package:path/path.dart' as p;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:system_info2/system_info2.dart' as sysinfo;
import 'package:system_info_plus/system_info_plus.dart';
import 'veilid.dart'; import 'veilid.dart';
const int megaByte = 1024 * 1024; Future<VeilidConfig> getDefaultVeilidConfig({
required bool isWeb,
int getLocalSubkeyCacheSize() { required String programName,
if (kIsWeb) { String bootstrap = '',
return 128; String namespace = '',
} String deviceEncryptionKeyPassword = '',
return 1024; String? newDeviceEncryptionKeyPassword,
} String networkKeyPassword = '',
}) async {
Future<int> getLocalMaxSubkeyCacheMemoryMb() async { final defaultConfigStr = Veilid.instance.defaultVeilidConfig();
if (kIsWeb) { final defaultConfig = VeilidConfig.fromJson(jsonDecode(defaultConfigStr));
return 256; return defaultConfig.copyWith(
}
if (Platform.isIOS || Platform.isAndroid) {
return (await SystemInfoPlus.physicalMemory ?? 2048) ~/ 32;
}
return sysinfo.SysInfo.getTotalPhysicalMemory() ~/ 32 ~/ megaByte;
}
int getRemoteSubkeyCacheSize() {
if (kIsWeb) {
return 64;
}
return 128;
}
int getRemoteMaxRecords() {
if (kIsWeb) {
return 64;
}
return 128;
}
Future<int> getRemoteMaxSubkeyCacheMemoryMb() async {
if (kIsWeb) {
return 256;
}
if (Platform.isIOS || Platform.isAndroid) {
return (await SystemInfoPlus.physicalMemory ?? 2048) ~/ 32;
}
return sysinfo.SysInfo.getTotalPhysicalMemory() ~/ 32 ~/ megaByte;
}
int getRemoteMaxStorageSpaceMb() {
if (kIsWeb) {
return 128;
}
return 256;
}
Future<VeilidConfig> getDefaultVeilidConfig(String programName,
{String bootstrap = ''}) async =>
VeilidConfig(
programName: programName, programName: programName,
namespace: '', namespace: namespace,
capabilities: const VeilidConfigCapabilities(disable: []), tableStore: defaultConfig.tableStore.copyWith(
protectedStore: const VeilidConfigProtectedStore( directory: isWeb
allowInsecureFallback: false,
alwaysUseInsecureStorage: false,
directory: '',
delete: false,
deviceEncryptionKeyPassword: '',
),
tableStore: VeilidConfigTableStore(
directory: kIsWeb
? '' ? ''
: p.join((await getApplicationSupportDirectory()).absolute.path, : p.join((await getApplicationSupportDirectory()).absolute.path,
'table_store'), 'table_store'),
delete: false,
), ),
blockStore: VeilidConfigBlockStore( blockStore: defaultConfig.blockStore.copyWith(
directory: kIsWeb directory: isWeb
? '' ? ''
: p.join((await getApplicationSupportDirectory()).absolute.path, : p.join((await getApplicationSupportDirectory()).absolute.path,
'block_store'), 'block_store'),
delete: false,
), ),
network: VeilidConfigNetwork( protectedStore: defaultConfig.protectedStore.copyWith(
connectionInitialTimeoutMs: 2000, directory: isWeb
connectionInactivityTimeoutMs: 60000, ? ''
maxConnectionsPerIp4: 32, : p.join((await getApplicationSupportDirectory()).absolute.path,
maxConnectionsPerIp6Prefix: 32, 'protected_store'),
maxConnectionsPerIp6PrefixSize: 56, deviceEncryptionKeyPassword: deviceEncryptionKeyPassword,
maxConnectionFrequencyPerMin: 128, newDeviceEncryptionKeyPassword: newDeviceEncryptionKeyPassword,
clientAllowlistTimeoutMs: 300000, ),
reverseConnectionReceiptTimeMs: 5000, network: defaultConfig.network.copyWith(
holePunchReceiptTimeMs: 5000, networkKeyPassword: networkKeyPassword,
routingTable: VeilidConfigRoutingTable( routingTable: defaultConfig.network.routingTable.copyWith(
nodeId: [],
nodeIdSecret: [],
bootstrap: bootstrap.isNotEmpty bootstrap: bootstrap.isNotEmpty
? bootstrap.split(',') ? bootstrap.split(',')
: (kIsWeb : defaultConfig.network.routingTable.bootstrap),
? ['ws://bootstrap.veilid.net:5150/ws'] dht: defaultConfig.network.dht.copyWith()));
: ['bootstrap.veilid.net']), }
limitOverAttached: 64,
limitFullyAttached: 32,
limitAttachedStrong: 16,
limitAttachedGood: 8,
limitAttachedWeak: 4,
),
rpc: const VeilidConfigRPC(
concurrency: 0,
queueSize: 1024,
maxTimestampBehindMs: 10000,
maxTimestampAheadMs: 10000,
timeoutMs: 5000,
maxRouteHopCount: 4,
defaultRouteHopCount: 1,
),
dht: VeilidConfigDHT(
maxFindNodeCount: 20,
resolveNodeTimeoutMs: 10000,
resolveNodeCount: 1,
resolveNodeFanout: 4,
getValueTimeoutMs: 10000,
getValueCount: 3,
getValueFanout: 4,
setValueTimeoutMs: 10000,
setValueCount: 5,
setValueFanout: 4,
minPeerCount: 20,
minPeerRefreshTimeMs: 60000,
validateDialInfoReceiptTimeMs: 2000,
localSubkeyCacheSize: getLocalSubkeyCacheSize(),
localMaxSubkeyCacheMemoryMb: await getLocalMaxSubkeyCacheMemoryMb(),
remoteSubkeyCacheSize: getRemoteSubkeyCacheSize(),
remoteMaxRecords: getRemoteMaxRecords(),
remoteMaxSubkeyCacheMemoryMb:
await getRemoteMaxSubkeyCacheMemoryMb(),
remoteMaxStorageSpaceMb: getRemoteMaxStorageSpaceMb(),
publicWatchLimit: 32,
memberWatchLimit: 8,
maxWatchExpirationMs: 600000),
upnp: true,
detectAddressChanges: true,
restrictedNatRetries: 0,
tls: const VeilidConfigTLS(
certificatePath: '',
privateKeyPath: '',
connectionInitialTimeoutMs: 2000,
),
application: const VeilidConfigApplication(
https: VeilidConfigHTTPS(
enabled: false,
listenAddress: '',
path: '',
),
http: VeilidConfigHTTP(
enabled: false,
listenAddress: '',
path: '',
)),
protocol: const VeilidConfigProtocol(
udp: VeilidConfigUDP(
enabled: !kIsWeb,
socketPoolSize: 0,
listenAddress: '',
),
tcp: VeilidConfigTCP(
connect: !kIsWeb,
listen: !kIsWeb,
maxConnections: 32,
listenAddress: '',
),
ws: VeilidConfigWS(
connect: true,
listen: !kIsWeb,
maxConnections: 32,
listenAddress: '',
path: 'ws',
),
wss: VeilidConfigWSS(
connect: true,
listen: false,
maxConnections: 32,
listenAddress: '',
path: 'ws',
),
),
),
);

View File

@ -6,13 +6,16 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized(); TestWidgetsFlutterBinding.ensureInitialized();
setUp(() {}); setUp(() {});
tearDown(() {}); tearDown(() {});
test('testEncodingKnownVectors', testEncodingKnownVectors); group('encoding', () {
test('testEncodeDecodeGarbage', testEncodeDecodeGarbage); test('test encoding known vectors', testEncodingKnownVectors);
test('testEncodeDecodeGarbagePad', testEncodeDecodeGarbagePad); test('test encode/decode garbage', testEncodeDecodeGarbage);
test('test encode/decode garbage with pad', testEncodeDecodeGarbagePad);
});
test('testVSR', testValueSubkeyRange); group('ValueSubkeyRange', () {
test('test ValueSubkeyRange', testValueSubkeyRange);
test('test List<ValueSubkeyRange>', testValueSubkeyRangeList); test('test List<ValueSubkeyRange>', testValueSubkeyRangeList);
});
} }

View File

@ -20,8 +20,8 @@ default-async-std = ["rt-async-std", "veilid-core/default-async-std"]
crypto-test = ["rt-tokio", "veilid-core/crypto-test"] crypto-test = ["rt-tokio", "veilid-core/crypto-test"]
crypto-test-none = ["rt-tokio", "veilid-core/crypto-test-none"] crypto-test-none = ["rt-tokio", "veilid-core/crypto-test-none"]
otlp-tonic = [ "opentelemetry-otlp/grpc-tonic", "opentelemetry-otlp/trace" ] otlp-tonic = ["opentelemetry-otlp/grpc-tonic", "opentelemetry-otlp/trace"]
otlp-grpc = [ "opentelemetry-otlp/grpc-sys", "opentelemetry-otlp/trace" ] otlp-grpc = ["opentelemetry-otlp/grpc-sys", "opentelemetry-otlp/trace"]
rt-async-std = [ rt-async-std = [
"veilid-core/rt-async-std", "veilid-core/rt-async-std",
@ -49,7 +49,7 @@ tracing-appender = "^0"
tracing-opentelemetry = "0.21" tracing-opentelemetry = "0.21"
# Buggy: tracing-error = "^0" # Buggy: tracing-error = "^0"
opentelemetry = { version = "0.20" } opentelemetry = { version = "0.20" }
opentelemetry-otlp = { version = "0.13", default-features = false, optional=true } opentelemetry-otlp = { version = "0.13", default-features = false, optional = true }
opentelemetry-semantic-conventions = "0.12" opentelemetry-semantic-conventions = "0.12"
async-std = { version = "^1", features = ["unstable"], optional = true } async-std = { version = "^1", features = ["unstable"], optional = true }
tokio = { version = "1.35.0", features = ["full", "tracing"], optional = true } tokio = { version = "1.35.0", features = ["full", "tracing"], optional = true }
@ -81,7 +81,7 @@ flume = { version = "^0", features = ["async"] }
rpassword = "^7" rpassword = "^7"
hostname = "^0" hostname = "^0"
stop-token = { version = "^0", default-features = false } stop-token = { version = "^0", default-features = false }
sysinfo = { version = "^0.29.11", default-features = false } sysinfo = { version = "^0.30.6" }
wg = "0.3.2" wg = "0.3.2"
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]

View File

@ -7,11 +7,30 @@ use std::ffi::OsStr;
use std::net::SocketAddr; use std::net::SocketAddr;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::sync::Arc; use std::sync::Arc;
use sysinfo::{DiskExt, SystemExt};
use url::Url; use url::Url;
use veilid_core::tools::*; use veilid_core::tools::*;
use veilid_core::*; use veilid_core::*;
use lazy_static::*;
lazy_static! {
static ref SYSTEM: sysinfo::System = {
sysinfo::System::new_with_specifics(
sysinfo::RefreshKind::new().with_memory(sysinfo::MemoryRefreshKind::everything()),
)
};
static ref DISKS: sysinfo::Disks = {
let mut disks = sysinfo::Disks::new_with_refreshed_list();
disks.sort_by(|a, b| {
b.mount_point()
.to_string_lossy()
.len()
.cmp(&a.mount_point().to_string_lossy().len())
});
disks
};
}
pub fn load_default_config() -> EyreResult<config::Config> { pub fn load_default_config() -> EyreResult<config::Config> {
let mut default_config = String::from( let mut default_config = String::from(
r#"--- r#"---
@ -865,21 +884,19 @@ impl Settings {
} }
pub fn get_default_remote_max_subkey_cache_memory_mb() -> u32 { pub fn get_default_remote_max_subkey_cache_memory_mb() -> u32 {
let sys = sysinfo::System::new_with_specifics(sysinfo::RefreshKind::new().with_memory()); if sysinfo::IS_SUPPORTED_SYSTEM {
((sys.free_memory() / (1024u64 * 1024u64)) / 16) as u32 ((SYSTEM.free_memory() / (1024u64 * 1024u64)) / 16) as u32
} else {
256
}
} }
pub fn get_default_remote_max_storage_space_mb(inner: &SettingsInner) -> u32 { pub fn get_default_remote_max_storage_space_mb(inner: &SettingsInner) -> u32 {
let mut sys = sysinfo::System::new_with_specifics(sysinfo::RefreshKind::new().with_disks());
let dht_storage_path = inner.core.table_store.directory.clone(); let dht_storage_path = inner.core.table_store.directory.clone();
// Sort longer mount point paths first since we want the mount point closest to our table store directory // Sort longer mount point paths first since we want the mount point closest to our table store directory
sys.sort_disks_by(|a, b| {
b.mount_point() if sysinfo::IS_SUPPORTED_SYSTEM {
.to_string_lossy() for disk in DISKS.list() {
.len()
.cmp(&a.mount_point().to_string_lossy().len())
});
for disk in sys.disks() {
if dht_storage_path.starts_with(&*disk.mount_point().to_string_lossy()) { if dht_storage_path.starts_with(&*disk.mount_point().to_string_lossy()) {
let available_mb = disk.available_space() / 1_000_000u64; let available_mb = disk.available_space() / 1_000_000u64;
if available_mb > 40_000 { if available_mb > 40_000 {
@ -890,6 +907,8 @@ impl Settings {
return available_mb as u32; return available_mb as u32;
} }
} }
}
// If we can't figure out our storage path go with 1GB of space and pray // If we can't figure out our storage path go with 1GB of space and pray
1_000 1_000
} }