immutable config

This commit is contained in:
Christien Rioux 2025-09-11 16:59:09 -04:00
parent 45dffe0d9f
commit 681fdf9f7c
79 changed files with 733 additions and 1319 deletions

View file

@ -30,6 +30,8 @@
- Added 'tick lag' detection to check for missed watch updates - Added 'tick lag' detection to check for missed watch updates
- Added 'DHT Widening', separates consensus width (server side dht operation acceptance) from consensus count (client side), fixes [#435](https://gitlab.com/veilid/veilid/-/issues/435) - Added 'DHT Widening', separates consensus width (server side dht operation acceptance) from consensus count (client side), fixes [#435](https://gitlab.com/veilid/veilid/-/issues/435)
- Deprecation of WSS protocol, closes [#487](https://gitlab.com/veilid/veilid/-/issues/487) - Deprecation of WSS protocol, closes [#487](https://gitlab.com/veilid/veilid/-/issues/487)
- Move node id and public key init to routing table
- VeilidConfig is now read-only and no longer requires a lock [#485](https://gitlab.com/veilid/veilid/-/issues/485)
- veilid-python: - veilid-python:
- Migrated to 'uv' from 'poetry' - Migrated to 'uv' from 'poetry'

View file

@ -12,7 +12,16 @@ async fn main() {
} }
Network(msg) => { Network(msg) => {
println!( println!(
"Network: Peers {:}, bytes/sec [{} up] [{} down]", "Network: Node Ids: {}, Peers {}, bytes/sec [{} up] [{} down]",
if msg.node_ids.is_empty() {
"(none assigned)".to_string()
} else {
msg.node_ids
.iter()
.map(|x| x.to_string())
.collect::<Vec<_>>()
.join(",")
},
msg.peers.len(), msg.peers.len(),
msg.bps_up, msg.bps_up,
msg.bps_down msg.bps_down
@ -58,21 +67,12 @@ async fn main() {
let veilid = veilid_core::api_startup(update_callback, config) let veilid = veilid_core::api_startup(update_callback, config)
.await .await
.unwrap(); .unwrap();
println!(
"Node ID: {}",
veilid
.config()
.unwrap()
.get()
.network
.routing_table
.public_keys
);
// Attach to the network // Attach to the network
veilid.attach().await.unwrap(); veilid.attach().await.unwrap();
// Until CTRL+C is pressed, keep running // Until CTRL+C is pressed, keep running
tokio::signal::ctrl_c().await.unwrap(); tokio::signal::ctrl_c().await.unwrap();
veilid.shutdown().await; veilid.shutdown().await;
} }

View file

@ -475,7 +475,7 @@ impl AttachmentManager {
// Calculate new attachment state // Calculate new attachment state
let config = self.config(); let config = self.config();
let routing_table_config = &config.get().network.routing_table; let routing_table_config = &config.network.routing_table;
let next_attachment_state = let next_attachment_state =
AttachmentManager::translate_routing_table_health(&health, routing_table_config); AttachmentManager::translate_routing_table_health(&health, routing_table_config);

View file

@ -25,11 +25,11 @@ pub(crate) trait VeilidComponent:
pub(crate) trait VeilidComponentRegistryAccessor { pub(crate) trait VeilidComponentRegistryAccessor {
fn registry(&self) -> VeilidComponentRegistry; fn registry(&self) -> VeilidComponentRegistry;
fn config(&self) -> VeilidStartupOptions { fn config(&self) -> Arc<VeilidConfig> {
self.registry().config.clone() self.registry().startup_options.config()
} }
fn update_callback(&self) -> UpdateCallback { fn update_callback(&self) -> UpdateCallback {
self.registry().config.update_callback() self.registry().startup_options.update_callback()
} }
fn event_bus(&self) -> EventBus { fn event_bus(&self) -> EventBus {
self.registry().event_bus.clone() self.registry().event_bus.clone()
@ -65,7 +65,7 @@ struct VeilidComponentRegistryInner {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub(crate) struct VeilidComponentRegistry { pub(crate) struct VeilidComponentRegistry {
inner: Arc<Mutex<VeilidComponentRegistryInner>>, inner: Arc<Mutex<VeilidComponentRegistryInner>>,
config: VeilidStartupOptions, startup_options: VeilidStartupOptions,
namespace: &'static str, namespace: &'static str,
program_name: &'static str, program_name: &'static str,
log_key: &'static str, log_key: &'static str,
@ -74,9 +74,9 @@ pub(crate) struct VeilidComponentRegistry {
} }
impl VeilidComponentRegistry { impl VeilidComponentRegistry {
pub fn new(config: VeilidStartupOptions) -> Self { pub fn new(startup_options: VeilidStartupOptions) -> Self {
let (namespace, program_name) = let namespace = startup_options.config().namespace.to_static_str();
config.with(|c| (c.namespace.to_static_str(), c.program_name.to_static_str())); let program_name = startup_options.config().program_name.to_static_str();
let log_key = VeilidLayerFilter::make_veilid_log_key(program_name, namespace); let log_key = VeilidLayerFilter::make_veilid_log_key(program_name, namespace);
@ -86,7 +86,7 @@ impl VeilidComponentRegistry {
init_order: Vec::new(), init_order: Vec::new(),
mock: false, mock: false,
})), })),
config, startup_options,
namespace, namespace,
program_name, program_name,
log_key, log_key,

View file

@ -27,15 +27,18 @@ impl VeilidCoreContext {
#[instrument(level = "trace", target = "core_context", err, skip_all)] #[instrument(level = "trace", target = "core_context", err, skip_all)]
async fn new_with_config( async fn new_with_config(
update_callback: UpdateCallback, update_callback: UpdateCallback,
config_inner: VeilidConfig, config: VeilidConfig,
) -> VeilidAPIResult<VeilidCoreContext> { ) -> VeilidAPIResult<VeilidCoreContext> {
// Set up config from json // Set up config from json
let config = VeilidStartupOptions::new_from_config(config_inner, update_callback); let config = VeilidStartupOptions::try_new(config, update_callback)?;
Self::new_common(config).await Self::new_common(config).await
} }
#[instrument(level = "trace", target = "core_context", err, skip_all)] #[instrument(level = "trace", target = "core_context", err, skip_all)]
async fn new_common(config: VeilidStartupOptions) -> VeilidAPIResult<VeilidCoreContext> { async fn new_common(
startup_options: VeilidStartupOptions,
) -> VeilidAPIResult<VeilidCoreContext> {
cfg_if! { cfg_if! {
if #[cfg(target_os = "android")] { if #[cfg(target_os = "android")] {
if !crate::intf::android::is_android_ready() { if !crate::intf::android::is_android_ready() {
@ -45,11 +48,11 @@ impl VeilidCoreContext {
} }
let (program_name, namespace, update_callback) = { let (program_name, namespace, update_callback) = {
let cfginner = config.get(); let cfginner = startup_options.config();
( (
cfginner.program_name.clone(), cfginner.program_name.clone(),
cfginner.namespace.clone(), cfginner.namespace.clone(),
config.update_callback(), startup_options.update_callback(),
) )
}; };
@ -57,7 +60,7 @@ impl VeilidCoreContext {
ApiTracingLayer::add_callback(log_key, update_callback.clone()).await?; ApiTracingLayer::add_callback(log_key, update_callback.clone()).await?;
// Create component registry // Create component registry
let registry = VeilidComponentRegistry::new(config); let registry = VeilidComponentRegistry::new(startup_options);
veilid_log!(registry info "Veilid API starting up"); veilid_log!(registry info "Veilid API starting up");
if let Some(target) = option_env!("TARGET") { if let Some(target) = option_env!("TARGET") {
@ -114,15 +117,10 @@ impl VeilidCoreContext {
async fn shutdown(self) { async fn shutdown(self) {
veilid_log!(self info "Veilid API shutting down"); veilid_log!(self info "Veilid API shutting down");
let (program_name, namespace, update_callback) = { let config = self.registry.config();
let config = self.registry.config(); let program_name = &config.program_name;
let cfginner = config.get(); let namespace = &config.namespace;
( let update_callback = self.registry().update_callback();
cfginner.program_name.clone(),
cfginner.namespace.clone(),
config.update_callback(),
)
};
// Run pre-termination // Run pre-termination
// This should shut down background processes that may require the existence of // This should shut down background processes that may require the existence of
@ -135,7 +133,7 @@ impl VeilidCoreContext {
veilid_log!(self info "Veilid API shutdown complete"); veilid_log!(self info "Veilid API shutdown complete");
let log_key = VeilidLayerFilter::make_veilid_log_key(&program_name, &namespace).to_string(); let log_key = VeilidLayerFilter::make_veilid_log_key(program_name, namespace).to_string();
if let Err(e) = ApiTracingLayer::remove_callback(log_key).await { if let Err(e) = ApiTracingLayer::remove_callback(log_key).await {
error!("Error removing callback from ApiTracingLayer: {}", e); error!("Error removing callback from ApiTracingLayer: {}", e);
} }
@ -258,8 +256,7 @@ pub(crate) async fn api_shutdown(context: VeilidCoreContext) {
let init_key = { let init_key = {
let registry = context.registry(); let registry = context.registry();
let config = registry.config(); let config = registry.config();
let cfginner = config.get(); (config.program_name.clone(), config.namespace.clone())
(cfginner.program_name.clone(), cfginner.namespace.clone())
}; };
// Only allow one startup/shutdown per program_name+namespace combination simultaneously // Only allow one startup/shutdown per program_name+namespace combination simultaneously

View file

@ -119,32 +119,14 @@ impl Crypto {
// Setup called by table store after it get initialized // Setup called by table store after it get initialized
#[instrument(level = "trace", target = "crypto", skip_all, err)] #[instrument(level = "trace", target = "crypto", skip_all, err)]
pub(crate) async fn table_store_setup(&self, table_store: &TableStore) -> EyreResult<()> { pub(crate) async fn table_store_setup(&self, table_store: &TableStore) -> EyreResult<()> {
// Init node id from config
if let Err(e) = self.setup_public_keys(table_store).await {
return Err(e).wrap_err("init node id failed");
}
// make local copy of node id for easy access
let mut cache_validity_key: Vec<u8> = Vec::new();
self.config().with(|c| {
for ck in VALID_CRYPTO_KINDS {
if let Some(nid) = c.network.routing_table.public_keys.get(ck) {
cache_validity_key.extend_from_slice(nid.ref_value());
}
}
});
// load caches if they are valid for this node id // load caches if they are valid for this node id
let mut db = table_store let caches_valid = {
.open("crypto_caches", 1) let db = table_store
.await .open("crypto_caches", 1)
.wrap_err("failed to open crypto_caches")?; .await
let mut caches_valid = match db.load(0, b"cache_validity_key").await? { .wrap_err("failed to open crypto_caches")?;
Some(v) => v == cache_validity_key,
None => false,
};
if caches_valid { let mut caches_valid = true;
if let Some(b) = db.load(0, b"dh_cache").await? { if let Some(b) = db.load(0, b"dh_cache").await? {
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
if let Ok(dh_cache) = bytes_to_cache(&b) { if let Ok(dh_cache) = bytes_to_cache(&b) {
@ -153,15 +135,14 @@ impl Crypto {
caches_valid = false; caches_valid = false;
} }
} }
}
caches_valid
};
if !caches_valid { if !caches_valid {
drop(db);
table_store.delete("crypto_caches").await?; table_store.delete("crypto_caches").await?;
db = table_store.open("crypto_caches", 1).await?;
db.store(0, b"cache_validity_key", &cache_validity_key)
.await?;
} }
Ok(()) Ok(())
} }
@ -375,142 +356,4 @@ impl Crypto {
} }
Ok(()) Ok(())
} }
#[cfg(not(test))]
async fn setup_public_key(
&self,
vcrypto: AsyncCryptoSystemGuard<'_>,
table_store: &TableStore,
) -> VeilidAPIResult<(PublicKey, SecretKey)> {
let config = self.config();
let ck = vcrypto.kind();
let (mut public_key, mut secret_key) = config.with(|c| {
(
c.network.routing_table.public_keys.get(ck),
c.network.routing_table.secret_keys.get(ck),
)
});
let config_table = table_store.open("__veilid_config", 1).await?;
// Old pre-0.5.0 locations
let table_key_node_id = format!("node_id_{}", ck);
let table_key_node_id_secret = format!("node_id_secret_{}", ck);
// Post-0.5.0 locations
let table_key_public_key = format!("public_key_{}", ck);
let table_key_secret_key = format!("secret_key_{}", ck);
// See if public key was previously stored in the table store
if public_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_public_key);
if let Ok(Some(stored_public_key)) = config_table
.load_json::<PublicKey>(0, table_key_public_key.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_public_key);
public_key = Some(stored_public_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_public_key);
}
}
if public_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_node_id);
if let Ok(Some(stored_public_key)) = config_table
.load_json::<PublicKey>(0, table_key_node_id.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_node_id);
public_key = Some(stored_public_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_node_id);
}
}
// See if secret key was previously stored in the table store
if secret_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_secret_key);
if let Ok(Some(stored_secret_key)) = config_table
.load_json::<SecretKey>(0, table_key_secret_key.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_secret_key);
secret_key = Some(stored_secret_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_secret_key);
}
}
if secret_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_node_id_secret);
if let Ok(Some(stored_secret_key)) = config_table
.load_json::<SecretKey>(0, table_key_node_id_secret.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_node_id_secret);
secret_key = Some(stored_secret_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_node_id_secret);
}
}
// If we have a node id from storage, check it
let (public_key, secret_key) =
if let (Some(public_key), Some(secret_key)) = (public_key, secret_key) {
// Validate node id
if !vcrypto.validate_keypair(&public_key, &secret_key).await? {
apibail_generic!(format!(
"secret_key and public_key don't match:\npublic_key: {}\nsecret_key: {}",
public_key, secret_key
));
}
(public_key, secret_key)
} else {
// If we still don't have a valid keypair, generate one
veilid_log!(self debug "generating new node {} keypair", ck);
vcrypto.generate_keypair().await.into_split()
};
veilid_log!(self info "Public Key: {}", public_key);
// Save the node id / secret in storage
config_table
.store_json(0, table_key_public_key.as_bytes(), &public_key)
.await?;
config_table
.store_json(0, table_key_secret_key.as_bytes(), &secret_key)
.await?;
Ok((public_key, secret_key))
}
/// Get the public keys from config if one is specified.
/// Must be done -after- protected store is initialized, during table store init
#[cfg_attr(test, allow(unused_variables))]
async fn setup_public_keys(&self, table_store: &TableStore) -> VeilidAPIResult<()> {
let mut out_public_keys = PublicKeyGroup::new();
let mut out_secret_keys = SecretKeyGroup::new();
for ck in VALID_CRYPTO_KINDS {
let vcrypto = self
.get_async(ck)
.expect("Valid crypto kind is not actually valid.");
#[cfg(test)]
let (public_key, secret_key) = vcrypto.generate_keypair().await.into_split();
#[cfg(not(test))]
let (public_key, secret_key) = self.setup_public_key(vcrypto, table_store).await?;
// Save for config
out_public_keys.add(public_key);
out_secret_keys.add(secret_key);
}
// Commit back to config
self.config().try_with_mut(|c| {
c.network.routing_table.public_keys = out_public_keys;
c.network.routing_table.secret_keys = out_secret_keys;
Ok(())
})?;
Ok(())
}
} }

View file

@ -52,15 +52,14 @@ impl ProtectedStore {
async fn init_async(&self) -> EyreResult<()> { async fn init_async(&self) -> EyreResult<()> {
let delete = { let delete = {
let config = self.config(); let config = self.config();
let c = config.get();
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
if !c.protected_store.always_use_insecure_storage { if !config.protected_store.always_use_insecure_storage {
// Attempt to open the secure keyring // Attempt to open the secure keyring
cfg_if! { cfg_if! {
if #[cfg(target_os = "android")] { if #[cfg(target_os = "android")] {
let maybe_km = KeyringManager::new_secure(&c.program_name, crate::intf::android::get_android_globals()); let maybe_km = KeyringManager::new_secure(&config.program_name, crate::intf::android::get_android_globals());
} else { } else {
let maybe_km = KeyringManager::new_secure(&c.program_name); let maybe_km = KeyringManager::new_secure(&config.program_name);
} }
} }
@ -72,17 +71,17 @@ impl ProtectedStore {
} }
}; };
} }
if (c.protected_store.always_use_insecure_storage if (config.protected_store.always_use_insecure_storage
|| c.protected_store.allow_insecure_fallback) || config.protected_store.allow_insecure_fallback)
&& inner.keyring_manager.is_none() && inner.keyring_manager.is_none()
{ {
let directory = Path::new(&c.protected_store.directory); let directory = Path::new(&config.protected_store.directory);
let insecure_keyring_file = directory.to_owned().join(format!( let insecure_keyring_file = directory.to_owned().join(format!(
"insecure_keyring{}", "insecure_keyring{}",
if c.namespace.is_empty() { if config.namespace.is_empty() {
"".to_owned() "".to_owned()
} else { } else {
format!("_{}", c.namespace) format!("_{}", config.namespace)
} }
)); ));
@ -91,14 +90,14 @@ impl ProtectedStore {
// Open the insecure keyring // Open the insecure keyring
inner.keyring_manager = Some( inner.keyring_manager = Some(
KeyringManager::new_insecure(&c.program_name, &insecure_keyring_file) KeyringManager::new_insecure(&config.program_name, &insecure_keyring_file)
.wrap_err("failed to create insecure keyring")?, .wrap_err("failed to create insecure keyring")?,
); );
} }
if inner.keyring_manager.is_none() { if inner.keyring_manager.is_none() {
bail!("Could not initialize the protected store."); bail!("Could not initialize the protected store.");
} }
c.protected_store.delete config.protected_store.delete
}; };
if delete { if delete {
@ -123,11 +122,10 @@ impl ProtectedStore {
fn service_name(&self) -> String { fn service_name(&self) -> String {
let config = self.config(); let config = self.config();
let c = config.get(); if config.namespace.is_empty() {
if c.namespace.is_empty() {
"veilid_protected_store".to_owned() "veilid_protected_store".to_owned()
} else { } else {
format!("veilid_protected_store_{}", c.namespace) format!("veilid_protected_store_{}", config.namespace)
} }
} }

View file

@ -35,7 +35,7 @@ impl ProtectedStore {
#[instrument(level = "debug", skip(self), err)] #[instrument(level = "debug", skip(self), err)]
async fn init_async(&self) -> EyreResult<()> { async fn init_async(&self) -> EyreResult<()> {
if self.config().with(|c| c.protected_store.delete) { if self.config().protected_store.delete {
self.delete_all(); self.delete_all();
} }
@ -55,11 +55,10 @@ impl ProtectedStore {
fn browser_key_name(&self, key: &str) -> String { fn browser_key_name(&self, key: &str) -> String {
let config = self.config(); let config = self.config();
let c = config.get(); if config.namespace.is_empty() {
if c.namespace.is_empty() {
format!("__veilid_protected_store_{}", key) format!("__veilid_protected_store_{}", key)
} else { } else {
format!("__veilid_protected_store_{}_{}", c.namespace, key) format!("__veilid_protected_store_{}_{}", config.namespace, key)
} }
} }

View file

@ -71,14 +71,11 @@ impl AddressCheck {
pub fn new(net: Network) -> Self { pub fn new(net: Network) -> Self {
let registry = net.registry(); let registry = net.registry();
let (detect_address_changes, ip6_prefix_size, require_inbound_relay) = let config = registry.config();
registry.config().with(|c| { let detect_address_changes = net.resolved_detect_address_changes();
( let ip6_prefix_size = config.network.max_connections_per_ip6_prefix_size as usize;
net.resolved_detect_address_changes(), let require_inbound_relay = config.network.privacy.require_inbound_relay;
c.network.max_connections_per_ip6_prefix_size as usize,
c.network.privacy.require_inbound_relay,
)
});
let config = AddressCheckConfig { let config = AddressCheckConfig {
detect_address_changes, detect_address_changes,
ip6_prefix_size, ip6_prefix_size,

View file

@ -77,7 +77,6 @@ impl_veilid_component_registry_accessor!(AddressFilter);
impl AddressFilter { impl AddressFilter {
pub fn new(registry: VeilidComponentRegistry) -> Self { pub fn new(registry: VeilidComponentRegistry) -> Self {
let config = registry.config(); let config = registry.config();
let c = config.get();
Self { Self {
registry, registry,
inner: Mutex::new(AddressFilterInner { inner: Mutex::new(AddressFilterInner {
@ -90,11 +89,12 @@ impl AddressFilter {
punishments_by_node_id: BTreeMap::new(), punishments_by_node_id: BTreeMap::new(),
dial_info_failures: BTreeMap::new(), dial_info_failures: BTreeMap::new(),
}), }),
max_connections_per_ip4: c.network.max_connections_per_ip4 as usize, max_connections_per_ip4: config.network.max_connections_per_ip4 as usize,
max_connections_per_ip6_prefix: c.network.max_connections_per_ip6_prefix as usize, max_connections_per_ip6_prefix: config.network.max_connections_per_ip6_prefix as usize,
max_connections_per_ip6_prefix_size: c.network.max_connections_per_ip6_prefix_size max_connections_per_ip6_prefix_size: config.network.max_connections_per_ip6_prefix_size
as usize,
max_connection_frequency_per_min: config.network.max_connection_frequency_per_min
as usize, as usize,
max_connection_frequency_per_min: c.network.max_connection_frequency_per_min as usize,
punishment_duration_min: PUNISHMENT_DURATION_MIN, punishment_duration_min: PUNISHMENT_DURATION_MIN,
dial_info_failure_duration_min: DIAL_INFO_FAILURE_DURATION_MIN, dial_info_failure_duration_min: DIAL_INFO_FAILURE_DURATION_MIN,
} }

View file

@ -12,13 +12,17 @@ impl NetworkManager {
/// If no bootstrap keys are specified, uses the v0 mechanism, otherwise uses the v1 mechanism /// If no bootstrap keys are specified, uses the v0 mechanism, otherwise uses the v1 mechanism
#[instrument(level = "trace", target = "net", err, skip(self))] #[instrument(level = "trace", target = "net", err, skip(self))]
pub async fn direct_bootstrap(&self, dial_info: DialInfo) -> EyreResult<Vec<Arc<PeerInfo>>> { pub async fn direct_bootstrap(&self, dial_info: DialInfo) -> EyreResult<Vec<Arc<PeerInfo>>> {
let direct_boot_version = self.config().with(|c| { let direct_boot_version = if self
if c.network.routing_table.bootstrap_keys.is_empty() { .config()
0 .network
} else { .routing_table
1 .bootstrap_keys
} .is_empty()
}); {
0
} else {
1
};
if direct_boot_version == 0 { if direct_boot_version == 0 {
self.direct_bootstrap_v0(dial_info).await self.direct_bootstrap_v0(dial_info).await
@ -30,7 +34,7 @@ impl NetworkManager {
/// Uses the bootstrap v0 (BOOT) mechanism /// Uses the bootstrap v0 (BOOT) mechanism
#[instrument(level = "trace", target = "net", err, skip(self))] #[instrument(level = "trace", target = "net", err, skip(self))]
async fn direct_bootstrap_v0(&self, dial_info: DialInfo) -> EyreResult<Vec<Arc<PeerInfo>>> { async fn direct_bootstrap_v0(&self, dial_info: DialInfo) -> EyreResult<Vec<Arc<PeerInfo>>> {
let timeout_ms = self.config().with(|c| c.network.rpc.timeout_ms); let timeout_ms = self.config().network.rpc.timeout_ms;
// Send boot magic to requested peer address // Send boot magic to requested peer address
let data = BOOT_MAGIC.to_vec(); let data = BOOT_MAGIC.to_vec();
@ -59,7 +63,7 @@ impl NetworkManager {
/// Uses the bootstrap v1 (B01T) mechanism /// Uses the bootstrap v1 (B01T) mechanism
#[instrument(level = "trace", target = "net", err, skip(self))] #[instrument(level = "trace", target = "net", err, skip(self))]
async fn direct_bootstrap_v1(&self, dial_info: DialInfo) -> EyreResult<Vec<Arc<PeerInfo>>> { async fn direct_bootstrap_v1(&self, dial_info: DialInfo) -> EyreResult<Vec<Arc<PeerInfo>>> {
let timeout_ms = self.config().with(|c| c.network.rpc.timeout_ms); let timeout_ms = self.config().network.rpc.timeout_ms;
// Send boot magic to requested peer address // Send boot magic to requested peer address
let data = B01T_MAGIC.to_vec(); let data = B01T_MAGIC.to_vec();

View file

@ -15,9 +15,7 @@ impl NetworkManager {
/// however this does work over straight UDP and TCP protocols as well. /// however this does work over straight UDP and TCP protocols as well.
#[instrument(level = "trace", target = "net", skip(self), ret, err)] #[instrument(level = "trace", target = "net", skip(self), ret, err)]
pub async fn handle_boot_v1_request(&self, flow: Flow) -> EyreResult<NetworkResult<()>> { pub async fn handle_boot_v1_request(&self, flow: Flow) -> EyreResult<NetworkResult<()>> {
let bootstraps = self let bootstraps = self.config().network.routing_table.bootstrap.clone();
.config()
.with(|c| c.network.routing_table.bootstrap.clone());
// Don't bother if bootstraps aren't configured // Don't bother if bootstraps aren't configured
if bootstraps.is_empty() { if bootstraps.is_empty() {

View file

@ -19,13 +19,17 @@ impl NetworkManager {
// Get the minimum bootstrap version we are supporting // Get the minimum bootstrap version we are supporting
// If no keys are available, allow v0. // If no keys are available, allow v0.
// If bootstrap keys are specified, require at least v1. // If bootstrap keys are specified, require at least v1.
let min_boot_version = self.config().with(|c| { let min_boot_version = if self
if c.network.routing_table.bootstrap_keys.is_empty() { .config()
BOOTSTRAP_TXT_VERSION_0 .network
} else { .routing_table
BOOTSTRAP_TXT_VERSION_1 .bootstrap_keys
} .is_empty()
}); {
BOOTSTRAP_TXT_VERSION_0
} else {
BOOTSTRAP_TXT_VERSION_1
};
// Resolve bootstrap servers and recurse their TXT entries // Resolve bootstrap servers and recurse their TXT entries
// This only operates in the PublicInternet routing domain because DNS is inherently // This only operates in the PublicInternet routing domain because DNS is inherently

View file

@ -13,9 +13,7 @@ impl NetworkManager {
) -> EyreResult<Vec<BootstrapRecord>> { ) -> EyreResult<Vec<BootstrapRecord>> {
veilid_log!(self debug "Parsing v1 bootstraps: {:?}", record_strings); veilid_log!(self debug "Parsing v1 bootstraps: {:?}", record_strings);
let signing_keys = self let signing_keys = self.config().network.routing_table.bootstrap_keys.clone();
.config()
.with(|c| c.network.routing_table.bootstrap_keys.clone());
if signing_keys.is_empty() { if signing_keys.is_empty() {
veilid_log!(self warn "No signing keys in config. Proceeding with UNVERIFIED bootstrap."); veilid_log!(self warn "No signing keys in config. Proceeding with UNVERIFIED bootstrap.");
} }

View file

@ -102,13 +102,8 @@ impl ConnectionManager {
} }
fn new_arc(registry: VeilidComponentRegistry) -> ConnectionManagerArc { fn new_arc(registry: VeilidComponentRegistry) -> ConnectionManagerArc {
let config = registry.config(); let config = registry.config();
let (connection_initial_timeout_ms, connection_inactivity_timeout_ms) = { let connection_initial_timeout_ms = config.network.connection_initial_timeout_ms;
let c = config.get(); let connection_inactivity_timeout_ms = config.network.connection_inactivity_timeout_ms;
(
c.network.connection_initial_timeout_ms,
c.network.connection_inactivity_timeout_ms,
)
};
ConnectionManagerArc { ConnectionManagerArc {
reconnection_processor: DeferredStreamProcessor::new(), reconnection_processor: DeferredStreamProcessor::new(),

View file

@ -61,22 +61,20 @@ impl ConnectionTable {
pub fn new(registry: VeilidComponentRegistry) -> Self { pub fn new(registry: VeilidComponentRegistry) -> Self {
let config = registry.config(); let config = registry.config();
let max_connections = { let max_connections = {
let c = config.get();
let mut max_connections = BTreeMap::<ProtocolType, usize>::new(); let mut max_connections = BTreeMap::<ProtocolType, usize>::new();
max_connections.insert( max_connections.insert(
ProtocolType::TCP, ProtocolType::TCP,
c.network.protocol.tcp.max_connections as usize, config.network.protocol.tcp.max_connections as usize,
); );
max_connections.insert( max_connections.insert(
ProtocolType::WS, ProtocolType::WS,
c.network.protocol.ws.max_connections as usize, config.network.protocol.ws.max_connections as usize,
); );
#[cfg(feature = "enable-protocol-wss")] #[cfg(feature = "enable-protocol-wss")]
max_connections.insert( max_connections.insert(
ProtocolType::WSS, ProtocolType::WSS,
c.network.protocol.wss.max_connections as usize, config.network.protocol.wss.max_connections as usize,
); );
max_connections max_connections

View file

@ -277,8 +277,7 @@ impl NetworkManager {
let config = registry.config(); let config = registry.config();
let crypto = registry.crypto(); let crypto = registry.crypto();
let c = config.get(); let network_key_password = config.network.network_key_password.clone();
let network_key_password = c.network.network_key_password.clone();
let network_key = if let Some(network_key_password) = network_key_password { let network_key = if let Some(network_key_password) = network_key_password {
if !network_key_password.is_empty() { if !network_key_password.is_empty() {
veilid_log!(registry info "Using network key"); veilid_log!(registry info "Using network key");
@ -307,11 +306,10 @@ impl NetworkManager {
// make local copy of node id for easy access // make local copy of node id for easy access
let (concurrency, queue_size) = { let (concurrency, queue_size) = {
let config = registry.config(); let config = registry.config();
let c = config.get();
// set up channel // set up channel
let mut concurrency = c.network.rpc.concurrency; let mut concurrency = config.network.rpc.concurrency;
let queue_size = c.network.rpc.queue_size; let queue_size = config.network.rpc.queue_size;
if concurrency == 0 { if concurrency == 0 {
concurrency = get_concurrency(); concurrency = get_concurrency();
if concurrency == 0 { if concurrency == 0 {
@ -585,9 +583,7 @@ impl NetworkManager {
} }
pub fn purge_client_allowlist(&self) { pub fn purge_client_allowlist(&self) {
let timeout_ms = self let timeout_ms = self.config().network.client_allowlist_timeout_ms;
.config()
.with(|c| c.network.client_allowlist_timeout_ms);
let mut inner = self.inner.lock(); let mut inner = self.inner.lock();
let cutoff_timestamp = let cutoff_timestamp =
Timestamp::now() - TimestampDuration::new((timeout_ms as u64) * 1000u64); Timestamp::now() - TimestampDuration::new((timeout_ms as u64) * 1000u64);
@ -1095,20 +1091,19 @@ impl NetworkManager {
}; };
// Get timestamp range // Get timestamp range
let (tsbehind, tsahead) = self.config().with(|c| { let config = self.config();
( let tsbehind = config
c.network .network
.rpc .rpc
.max_timestamp_behind_ms .max_timestamp_behind_ms
.map(ms_to_us) .map(ms_to_us)
.map(TimestampDuration::new), .map(TimestampDuration::new);
c.network let tsahead = config
.rpc .network
.max_timestamp_ahead_ms .rpc
.map(ms_to_us) .max_timestamp_ahead_ms
.map(TimestampDuration::new), .map(ms_to_us)
) .map(TimestampDuration::new);
});
// Validate timestamp isn't too old // Validate timestamp isn't too old
let ts = Timestamp::now(); let ts = Timestamp::now();
@ -1177,10 +1172,7 @@ impl NetworkManager {
// which only performs a lightweight lookup before passing the packet back out // which only performs a lightweight lookup before passing the packet back out
// If our node has the relay capability disabled, we should not be asked to relay // If our node has the relay capability disabled, we should not be asked to relay
if self if self.config().capabilities.disable.contains(&CAP_RELAY) {
.config()
.with(|c| c.capabilities.disable.contains(&CAP_RELAY))
{
veilid_log!(self debug "node has relay capability disabled, dropping relayed envelope from {} to {}", sender_id, recipient_id); veilid_log!(self debug "node has relay capability disabled, dropping relayed envelope from {} to {}", sender_id, recipient_id);
return Ok(false); return Ok(false);
} }

View file

@ -737,7 +737,7 @@ impl DiscoveryContext {
// NAT Detection // NAT Detection
/////////// ///////////
let retry_count = self.config().with(|c| c.network.restricted_nat_retries); let retry_count = self.config().network.restricted_nat_retries;
// Full Cone NAT Detection // Full Cone NAT Detection
/////////// ///////////
@ -883,10 +883,8 @@ impl DiscoveryContext {
// UPNP Automatic Mapping // UPNP Automatic Mapping
/////////// ///////////
let config = self.config();
let enable_upnp = self let enable_upnp = config.network.upnp && !config.network.privacy.require_inbound_relay;
.config()
.with(|c| c.network.upnp && !c.network.privacy.require_inbound_relay);
if enable_upnp { if enable_upnp {
// Attempt a port mapping via all available and enabled mechanisms // Attempt a port mapping via all available and enabled mechanisms
// Try this before the direct mapping in the event that we are restarting // Try this before the direct mapping in the event that we are restarting

View file

@ -227,26 +227,25 @@ impl Network {
fn load_server_config(&self) -> io::Result<ServerConfig> { fn load_server_config(&self) -> io::Result<ServerConfig> {
let config = self.config(); let config = self.config();
let c = config.get();
// //
veilid_log!(self trace veilid_log!(self trace
"loading certificate from {}", "loading certificate from {}",
c.network.tls.certificate_path config.network.tls.certificate_path
); );
let certs = Self::load_certs(&PathBuf::from(&c.network.tls.certificate_path))?; let certs = Self::load_certs(&PathBuf::from(&config.network.tls.certificate_path))?;
veilid_log!(self trace "loaded {} certificates", certs.len()); veilid_log!(self trace "loaded {} certificates", certs.len());
if certs.is_empty() { if certs.is_empty() {
return Err(io::Error::new(io::ErrorKind::InvalidInput, format!("Certificates at {} could not be loaded.\nEnsure it is in PEM format, beginning with '-----BEGIN CERTIFICATE-----'",c.network.tls.certificate_path))); return Err(io::Error::new(io::ErrorKind::InvalidInput, format!("Certificates at {} could not be loaded.\nEnsure it is in PEM format, beginning with '-----BEGIN CERTIFICATE-----'",config.network.tls.certificate_path)));
} }
// //
veilid_log!(self trace veilid_log!(self trace
"loading private key from {}", "loading private key from {}",
c.network.tls.private_key_path config.network.tls.private_key_path
); );
let mut keys = Self::load_keys(&PathBuf::from(&c.network.tls.private_key_path))?; let mut keys = Self::load_keys(&PathBuf::from(&config.network.tls.private_key_path))?;
veilid_log!(self trace "loaded {} keys", keys.len()); veilid_log!(self trace "loaded {} keys", keys.len());
if keys.is_empty() { if keys.is_empty() {
return Err(io::Error::new(io::ErrorKind::InvalidInput, format!("Private key at {} could not be loaded.\nEnsure it is unencrypted and in RSA or PKCS8 format, beginning with '-----BEGIN RSA PRIVATE KEY-----' or '-----BEGIN PRIVATE KEY-----'",c.network.tls.private_key_path))); return Err(io::Error::new(io::ErrorKind::InvalidInput, format!("Private key at {} could not be loaded.\nEnsure it is unencrypted and in RSA or PKCS8 format, beginning with '-----BEGIN RSA PRIVATE KEY-----' or '-----BEGIN PRIVATE KEY-----'",config.network.tls.private_key_path)));
} }
let config = ServerConfig::builder() let config = ServerConfig::builder()
@ -365,9 +364,7 @@ impl Network {
dial_info.clone(), dial_info.clone(),
async move { async move {
let data_len = data.len(); let data_len = data.len();
let connect_timeout_ms = self let connect_timeout_ms = self.config().network.connection_initial_timeout_ms;
.config()
.with(|c| c.network.connection_initial_timeout_ms);
if self if self
.network_manager() .network_manager()
@ -457,9 +454,7 @@ impl Network {
dial_info.clone(), dial_info.clone(),
async move { async move {
let data_len = data.len(); let data_len = data.len();
let connect_timeout_ms = self let connect_timeout_ms = self.config().network.connection_initial_timeout_ms;
.config()
.with(|c| c.network.connection_initial_timeout_ms);
if self if self
.network_manager() .network_manager()
@ -771,7 +766,7 @@ impl Network {
inner.stop_source = Some(StopSource::new()); inner.stop_source = Some(StopSource::new());
// Process the detect_address_changes 'auto' mode // Process the detect_address_changes 'auto' mode
let detect_address_changes = self.config().with(|c| c.network.detect_address_changes); let detect_address_changes = self.config().network.detect_address_changes;
if let Some(detect_address_changes) = detect_address_changes { if let Some(detect_address_changes) = detect_address_changes {
inner.resolved_detect_address_changes = detect_address_changes; inner.resolved_detect_address_changes = detect_address_changes;
if inner.resolved_detect_address_changes { if inner.resolved_detect_address_changes {
@ -831,9 +826,7 @@ impl Network {
); );
confirmed_public_internet = !resolved_detect_address_changes confirmed_public_internet = !resolved_detect_address_changes
|| self || self.config().network.privacy.require_inbound_relay;
.config()
.with(|c| c.network.privacy.require_inbound_relay);
editor_public_internet editor_public_internet
.set_interface_addresses(network_state.interface_addresses.as_ref().clone()); .set_interface_addresses(network_state.interface_addresses.as_ref().clone());
editor_public_internet.setup_network( editor_public_internet.setup_network(
@ -913,13 +906,7 @@ impl Network {
// enabled, this option intentionally disables publishing any dialinfo. // enabled, this option intentionally disables publishing any dialinfo.
let pi = routing_table.get_current_peer_info(RoutingDomain::PublicInternet); let pi = routing_table.get_current_peer_info(RoutingDomain::PublicInternet);
if !pi.node_info().has_any_dial_info() if !pi.node_info().has_any_dial_info()
&& !self && !self.config().network.privacy.require_inbound_relay
.registry
.config()
.get()
.network
.privacy
.require_inbound_relay
{ {
veilid_log!(self warn veilid_log!(self warn
"This node has no valid public dial info.\nConfigure this node with a static public IP address and correct firewall rules." "This node has no valid public dial info.\nConfigure this node with a static public IP address and correct firewall rules."

View file

@ -87,35 +87,34 @@ impl Network {
// Get protocol config // Get protocol config
let protocol_config = { let protocol_config = {
let config = self.config(); let config = self.config();
let c = config.get();
let mut inbound = ProtocolTypeSet::new(); let mut inbound = ProtocolTypeSet::new();
if c.network.protocol.udp.enabled { if config.network.protocol.udp.enabled {
inbound.insert(ProtocolType::UDP); inbound.insert(ProtocolType::UDP);
} }
if c.network.protocol.tcp.listen { if config.network.protocol.tcp.listen {
inbound.insert(ProtocolType::TCP); inbound.insert(ProtocolType::TCP);
} }
if c.network.protocol.ws.listen { if config.network.protocol.ws.listen {
inbound.insert(ProtocolType::WS); inbound.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")] #[cfg(feature = "enable-protocol-wss")]
if c.network.protocol.wss.listen { if config.network.protocol.wss.listen {
inbound.insert(ProtocolType::WSS); inbound.insert(ProtocolType::WSS);
} }
let mut outbound = ProtocolTypeSet::new(); let mut outbound = ProtocolTypeSet::new();
if c.network.protocol.udp.enabled { if config.network.protocol.udp.enabled {
outbound.insert(ProtocolType::UDP); outbound.insert(ProtocolType::UDP);
} }
if c.network.protocol.tcp.connect { if config.network.protocol.tcp.connect {
outbound.insert(ProtocolType::TCP); outbound.insert(ProtocolType::TCP);
} }
if c.network.protocol.ws.connect { if config.network.protocol.ws.connect {
outbound.insert(ProtocolType::WS); outbound.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")] #[cfg(feature = "enable-protocol-wss")]
if c.network.protocol.wss.connect { if config.network.protocol.wss.connect {
outbound.insert(ProtocolType::WSS); outbound.insert(ProtocolType::WSS);
} }
@ -136,14 +135,14 @@ impl Network {
PUBLIC_INTERNET_CAPABILITIES PUBLIC_INTERNET_CAPABILITIES
.iter() .iter()
.copied() .copied()
.filter(|cap| !c.capabilities.disable.contains(cap)) .filter(|cap| !config.capabilities.disable.contains(cap))
.collect::<Vec<VeilidCapability>>() .collect::<Vec<VeilidCapability>>()
}; };
let local_network_capabilities = { let local_network_capabilities = {
LOCAL_NETWORK_CAPABILITIES LOCAL_NETWORK_CAPABILITIES
.iter() .iter()
.copied() .copied()
.filter(|cap| !c.capabilities.disable.contains(cap)) .filter(|cap| !config.capabilities.disable.contains(cap))
.collect::<Vec<VeilidCapability>>() .collect::<Vec<VeilidCapability>>()
}; };

View file

@ -224,13 +224,9 @@ impl Network {
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
async fn spawn_socket_listener(&self, addr: SocketAddr) -> EyreResult<bool> { async fn spawn_socket_listener(&self, addr: SocketAddr) -> EyreResult<bool> {
// Get config // Get config
let (connection_initial_timeout_ms, tls_connection_initial_timeout_ms) = let config = self.config();
self.config().with(|c| { let connection_initial_timeout_ms = config.network.connection_initial_timeout_ms;
( let tls_connection_initial_timeout_ms = config.network.tls.connection_initial_timeout_ms;
c.network.connection_initial_timeout_ms,
c.network.tls.connection_initial_timeout_ms,
)
});
// Create a shared socket and bind it once we have determined the port is free // Create a shared socket and bind it once we have determined the port is free
let Some(listener) = bind_async_tcp_listener(addr)? else { let Some(listener) = bind_async_tcp_listener(addr)? else {

View file

@ -5,9 +5,7 @@ impl Network {
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
pub(super) async fn create_udp_listener_tasks(&self) -> EyreResult<()> { pub(super) async fn create_udp_listener_tasks(&self) -> EyreResult<()> {
// Spawn socket tasks // Spawn socket tasks
let mut task_count = self let mut task_count = self.config().network.protocol.udp.socket_pool_size;
.config()
.with(|c| c.network.protocol.udp.socket_pool_size);
if task_count == 0 { if task_count == 0 {
task_count = get_concurrency() / 2; task_count = get_concurrency() / 2;
if task_count == 0 { if task_count == 0 {

View file

@ -123,9 +123,7 @@ impl_veilid_component_registry_accessor!(RawTcpProtocolHandler);
impl RawTcpProtocolHandler { impl RawTcpProtocolHandler {
pub fn new(registry: VeilidComponentRegistry) -> Self { pub fn new(registry: VeilidComponentRegistry) -> Self {
let connection_initial_timeout_ms = registry let connection_initial_timeout_ms = registry.config().network.connection_initial_timeout_ms;
.config()
.with(|c| c.network.connection_initial_timeout_ms);
Self { Self {
registry, registry,
connection_initial_timeout_ms, connection_initial_timeout_ms,

View file

@ -102,10 +102,7 @@ where
#[instrument(level = "trace", target = "protocol", err, skip_all)] #[instrument(level = "trace", target = "protocol", err, skip_all)]
pub async fn close(&self) -> io::Result<NetworkResult<()>> { pub async fn close(&self) -> io::Result<NetworkResult<()>> {
let timeout_ms = self let timeout_ms = self.config().network.connection_initial_timeout_ms;
.registry
.config()
.with(|c| c.network.connection_initial_timeout_ms);
// Make an attempt to close the stream normally // Make an attempt to close the stream normally
let mut stream = self.stream.clone(); let mut stream = self.stream.clone();
@ -194,22 +191,24 @@ impl_veilid_component_registry_accessor!(WebsocketProtocolHandler);
impl WebsocketProtocolHandler { impl WebsocketProtocolHandler {
pub fn new(registry: VeilidComponentRegistry, tls: bool) -> Self { pub fn new(registry: VeilidComponentRegistry, tls: bool) -> Self {
let config = registry.config(); let config = registry.config();
let c = config.get();
let path = if tls { let path = if tls {
cfg_if::cfg_if! { cfg_if::cfg_if! {
if #[cfg(feature="enable-protocol-wss")] { if #[cfg(feature="enable-protocol-wss")] {
format!("GET /{}", c.network.protocol.wss.path.trim_end_matches('/')) format!("GET /{}", config.network.protocol.wss.path.trim_end_matches('/'))
} else { } else {
unreachable!("no tls protocols are enabled"); unreachable!("no tls protocols are enabled");
} }
} }
} else { } else {
format!("GET /{}", c.network.protocol.ws.path.trim_end_matches('/')) format!(
"GET /{}",
config.network.protocol.ws.path.trim_end_matches('/')
)
}; };
let connection_initial_timeout_ms = if tls { let connection_initial_timeout_ms = if tls {
c.network.tls.connection_initial_timeout_ms config.network.tls.connection_initial_timeout_ms
} else { } else {
c.network.connection_initial_timeout_ms config.network.connection_initial_timeout_ms
}; };
Self { Self {

View file

@ -140,13 +140,10 @@ impl Network {
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
pub(super) async fn bind_udp_protocol_handlers(&self) -> EyreResult<StartupDisposition> { pub(super) async fn bind_udp_protocol_handlers(&self) -> EyreResult<StartupDisposition> {
veilid_log!(self trace "UDP: binding protocol handlers"); veilid_log!(self trace "UDP: binding protocol handlers");
let (listen_address, public_address, require_inbound_relay) = self.config().with(|c| { let config = self.config();
( let listen_address = config.network.protocol.udp.listen_address.clone();
c.network.protocol.udp.listen_address.clone(), let public_address = config.network.protocol.udp.public_address.clone();
c.network.protocol.udp.public_address.clone(), let require_inbound_relay = config.network.privacy.require_inbound_relay;
c.network.privacy.require_inbound_relay,
)
});
// Get the binding parameters from the user-specified listen address // Get the binding parameters from the user-specified listen address
let bind_set = self let bind_set = self
@ -198,14 +195,10 @@ impl Network {
) -> EyreResult<()> { ) -> EyreResult<()> {
veilid_log!(self trace "UDP: registering dial info"); veilid_log!(self trace "UDP: registering dial info");
let (public_address, resolved_detect_address_changes, require_inbound_relay) = let config = self.config();
self.config().with(|c| { let public_address = config.network.protocol.udp.public_address.clone();
( let resolved_detect_address_changes = self.inner.lock().resolved_detect_address_changes;
c.network.protocol.udp.public_address.clone(), let require_inbound_relay = config.network.privacy.require_inbound_relay;
self.inner.lock().resolved_detect_address_changes,
c.network.privacy.require_inbound_relay,
)
});
let local_dial_info_list = { let local_dial_info_list = {
let mut out = vec![]; let mut out = vec![];
@ -274,13 +267,10 @@ impl Network {
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
pub(super) async fn start_ws_listeners(&self) -> EyreResult<StartupDisposition> { pub(super) async fn start_ws_listeners(&self) -> EyreResult<StartupDisposition> {
veilid_log!(self trace "WS: binding protocol handlers"); veilid_log!(self trace "WS: binding protocol handlers");
let (listen_address, url, require_inbound_relay) = self.config().with(|c| { let config = self.config();
( let listen_address = config.network.protocol.ws.listen_address.clone();
c.network.protocol.ws.listen_address.clone(), let url = config.network.protocol.ws.url.clone();
c.network.protocol.ws.url.clone(), let require_inbound_relay = config.network.privacy.require_inbound_relay;
c.network.privacy.require_inbound_relay,
)
});
// Get the binding parameters from the user-specified listen address // Get the binding parameters from the user-specified listen address
let bind_set = self let bind_set = self
@ -327,15 +317,12 @@ impl Network {
editor_local_network: &mut RoutingDomainEditorLocalNetwork<'_>, editor_local_network: &mut RoutingDomainEditorLocalNetwork<'_>,
) -> EyreResult<()> { ) -> EyreResult<()> {
veilid_log!(self trace "WS: registering dial info"); veilid_log!(self trace "WS: registering dial info");
let (url, path, resolved_detect_address_changes, require_inbound_relay) =
self.config().with(|c| { let config = self.config();
( let url = config.network.protocol.ws.url.clone();
c.network.protocol.ws.url.clone(), let path = config.network.protocol.ws.path.clone();
c.network.protocol.ws.path.clone(), let resolved_detect_address_changes = self.inner.lock().resolved_detect_address_changes;
self.inner.lock().resolved_detect_address_changes, let require_inbound_relay = config.network.privacy.require_inbound_relay;
c.network.privacy.require_inbound_relay,
)
});
let mut registered_addresses: HashSet<IpAddr> = HashSet::new(); let mut registered_addresses: HashSet<IpAddr> = HashSet::new();
@ -424,15 +411,11 @@ impl Network {
pub(super) async fn start_wss_listeners(&self) -> EyreResult<StartupDisposition> { pub(super) async fn start_wss_listeners(&self) -> EyreResult<StartupDisposition> {
veilid_log!(self trace "WSS: binding protocol handlers"); veilid_log!(self trace "WSS: binding protocol handlers");
let (listen_address, url, resolved_detect_address_changes, require_inbound_relay) = let config = self.config();
self.config().with(|c| { let listen_address = config.network.protocol.wss.listen_address.clone();
( let url = config.network.protocol.wss.url.clone();
c.network.protocol.wss.listen_address.clone(), let resolved_detect_address_changes = self.inner.lock().resolved_detect_address_changes;
c.network.protocol.wss.url.clone(), let require_inbound_relay = config.network.privacy.require_inbound_relay;
self.inner.lock().resolved_detect_address_changes,
c.network.privacy.require_inbound_relay,
)
});
// Get the binding parameters from the user-specified listen address // Get the binding parameters from the user-specified listen address
let bind_set = self let bind_set = self
@ -481,13 +464,9 @@ impl Network {
editor_local_network: &mut RoutingDomainEditorLocalNetwork<'_>, editor_local_network: &mut RoutingDomainEditorLocalNetwork<'_>,
) -> EyreResult<()> { ) -> EyreResult<()> {
veilid_log!(self trace "WSS: registering dialinfo"); veilid_log!(self trace "WSS: registering dialinfo");
let config = self.config();
let (url, _detect_address_changes) = self.config().with(|c| { let url = config.network.protocol.wss.url.clone();
( let _detect_address_changes = config.network.detect_address_changes;
c.network.protocol.wss.url.clone(),
c.network.detect_address_changes,
)
});
// NOTE: No interface dial info for WSS, as there is no way to connect to a local dialinfo via TLS // NOTE: No interface dial info for WSS, as there is no way to connect to a local dialinfo via TLS
// If the hostname is specified, it is the public dialinfo via the URL. If no hostname // If the hostname is specified, it is the public dialinfo via the URL. If no hostname
@ -535,19 +514,11 @@ impl Network {
pub(super) async fn start_tcp_listeners(&self) -> EyreResult<StartupDisposition> { pub(super) async fn start_tcp_listeners(&self) -> EyreResult<StartupDisposition> {
veilid_log!(self trace "TCP: binding protocol handlers"); veilid_log!(self trace "TCP: binding protocol handlers");
let ( let config = self.config();
listen_address, let listen_address = config.network.protocol.tcp.listen_address.clone();
public_address, let public_address = config.network.protocol.tcp.public_address.clone();
resolved_detect_address_changes, let resolved_detect_address_changes = self.inner.lock().resolved_detect_address_changes;
require_inbound_relay, let require_inbound_relay = config.network.privacy.require_inbound_relay;
) = self.config().with(|c| {
(
c.network.protocol.tcp.listen_address.clone(),
c.network.protocol.tcp.public_address.clone(),
self.inner.lock().resolved_detect_address_changes,
c.network.privacy.require_inbound_relay,
)
});
// Get the binding parameters from the user-specified listen address // Get the binding parameters from the user-specified listen address
let bind_set = self let bind_set = self
@ -598,14 +569,10 @@ impl Network {
) -> EyreResult<()> { ) -> EyreResult<()> {
veilid_log!(self trace "TCP: registering dialinfo"); veilid_log!(self trace "TCP: registering dialinfo");
let (public_address, resolved_detect_address_changes, require_inbound_relay) = let config = self.config();
self.config().with(|c| { let public_address = config.network.protocol.tcp.public_address.clone();
( let resolved_detect_address_changes = self.inner.lock().resolved_detect_address_changes;
c.network.protocol.tcp.public_address.clone(), let require_inbound_relay = config.network.privacy.require_inbound_relay;
self.inner.lock().resolved_detect_address_changes,
c.network.privacy.require_inbound_relay,
)
});
let mut registered_addresses: HashSet<IpAddr> = HashSet::new(); let mut registered_addresses: HashSet<IpAddr> = HashSet::new();

View file

@ -100,9 +100,11 @@ impl Network {
} }
let (upnp, require_inbound_relay) = { let (upnp, require_inbound_relay) = {
let config = self.network_manager().config(); let config = self.config();
let c = config.get(); (
(c.network.upnp, c.network.privacy.require_inbound_relay) config.network.upnp,
config.network.privacy.require_inbound_relay,
)
}; };
if require_inbound_relay { if require_inbound_relay {

View file

@ -248,15 +248,13 @@ impl Network {
ProtocolType::TCP => DialInfo::tcp(addr), ProtocolType::TCP => DialInfo::tcp(addr),
ProtocolType::WS => DialInfo::try_ws( ProtocolType::WS => DialInfo::try_ws(
addr, addr,
self.config() format!("ws://{}/{}", addr, self.config().network.protocol.ws.path),
.with(|c| format!("ws://{}/{}", addr, c.network.protocol.ws.path)),
) )
.unwrap(), .unwrap(),
#[cfg(feature = "enable-protocol-wss")] #[cfg(feature = "enable-protocol-wss")]
ProtocolType::WSS => DialInfo::try_wss( ProtocolType::WSS => DialInfo::try_wss(
addr, addr,
self.config() format!("wss://{}/{}", addr, self.config().network.protocol.wss.path),
.with(|c| format!("wss://{}/{}", addr, c.network.protocol.wss.path)),
) )
.unwrap(), .unwrap(),
} }

View file

@ -392,11 +392,11 @@ impl NetworkManager {
data data
}; };
let excessive_reverse_connect_duration_us = self.config().with(|c| { let config = self.config();
(c.network.connection_initial_timeout_ms * 2 let excessive_reverse_connect_duration_us =
+ c.network.reverse_connection_receipt_time_ms) as u64 (config.network.connection_initial_timeout_ms * 2
* 1000 + config.network.reverse_connection_receipt_time_ms) as u64
}); * 1000;
let unique_flow = network_result_try!( let unique_flow = network_result_try!(
pin_future!(debug_duration( pin_future!(debug_duration(
@ -448,9 +448,8 @@ impl NetworkManager {
data data
}; };
let hole_punch_receipt_time_us = self let hole_punch_receipt_time_us =
.config() self.config().network.hole_punch_receipt_time_ms as u64 * 1000;
.with(|c| c.network.hole_punch_receipt_time_ms as u64 * 1000);
let unique_flow = network_result_try!( let unique_flow = network_result_try!(
pin_future!(debug_duration( pin_future!(debug_duration(
@ -812,8 +811,7 @@ impl NetworkManager {
// Build a return receipt for the signal // Build a return receipt for the signal
let receipt_timeout = TimestampDuration::new_ms( let receipt_timeout = TimestampDuration::new_ms(
self.config() self.config().network.reverse_connection_receipt_time_ms as u64,
.with(|c| c.network.reverse_connection_receipt_time_ms as u64),
); );
let (receipt, eventual_value) = self.generate_single_shot_receipt(receipt_timeout, [])?; let (receipt, eventual_value) = self.generate_single_shot_receipt(receipt_timeout, [])?;
@ -926,10 +924,8 @@ impl NetworkManager {
); );
// Build a return receipt for the signal // Build a return receipt for the signal
let receipt_timeout = TimestampDuration::new_ms( let receipt_timeout =
self.config() TimestampDuration::new_ms(self.config().network.hole_punch_receipt_time_ms as u64);
.with(|c| c.network.hole_punch_receipt_time_ms as u64),
);
let (receipt, eventual_value) = self.generate_single_shot_receipt(receipt_timeout, [])?; let (receipt, eventual_value) = self.generate_single_shot_receipt(receipt_timeout, [])?;
// Get target routing domain // Get target routing domain

View file

@ -105,6 +105,7 @@ impl NetworkManager {
bps_down: 0.into(), bps_down: 0.into(),
bps_up: 0.into(), bps_up: 0.into(),
peers: Vec::new(), peers: Vec::new(),
node_ids: Vec::new(),
}); });
} }
let routing_table = self.routing_table(); let routing_table = self.routing_table();
@ -136,6 +137,7 @@ impl NetworkManager {
} }
out out
}, },
node_ids: routing_table.node_ids().to_vec(),
}) })
} }

View file

@ -137,9 +137,7 @@ impl Network {
self.record_dial_info_failure(dial_info.clone(), async move { self.record_dial_info_failure(dial_info.clone(), async move {
let data_len = data.len(); let data_len = data.len();
let timeout_ms = self let timeout_ms = self.config().network.connection_initial_timeout_ms;
.config()
.with(|c| c.network.connection_initial_timeout_ms);
if self if self
.network_manager() .network_manager()
@ -204,9 +202,7 @@ impl Network {
self.record_dial_info_failure(dial_info.clone(), async move { self.record_dial_info_failure(dial_info.clone(), async move {
let data_len = data.len(); let data_len = data.len();
let connect_timeout_ms = self let connect_timeout_ms = self.config().network.connection_initial_timeout_ms;
.config()
.with(|c| c.network.connection_initial_timeout_ms);
if self if self
.network_manager() .network_manager()
@ -382,15 +378,14 @@ impl Network {
// get protocol config // get protocol config
let protocol_config = { let protocol_config = {
let config = self.config(); let config = self.config();
let c = config.get();
let inbound = ProtocolTypeSet::new(); let inbound = ProtocolTypeSet::new();
let mut outbound = ProtocolTypeSet::new(); let mut outbound = ProtocolTypeSet::new();
if c.network.protocol.ws.connect { if config.network.protocol.ws.connect {
outbound.insert(ProtocolType::WS); outbound.insert(ProtocolType::WS);
} }
#[cfg(feature = "enable-protocol-wss")] #[cfg(feature = "enable-protocol-wss")]
if c.network.protocol.wss.connect { if config.network.protocol.wss.connect {
outbound.insert(ProtocolType::WSS); outbound.insert(ProtocolType::WSS);
} }
@ -406,7 +401,7 @@ impl Network {
PUBLIC_INTERNET_CAPABILITIES PUBLIC_INTERNET_CAPABILITIES
.iter() .iter()
.copied() .copied()
.filter(|cap| !c.capabilities.disable.contains(cap)) .filter(|cap| !config.capabilities.disable.contains(cap))
.collect::<Vec<VeilidCapability>>() .collect::<Vec<VeilidCapability>>()
}; };

View file

@ -52,10 +52,7 @@ impl WebsocketNetworkConnection {
instrument(level = "trace", err, skip(self)) instrument(level = "trace", err, skip(self))
)] )]
pub async fn close(&self) -> io::Result<NetworkResult<()>> { pub async fn close(&self) -> io::Result<NetworkResult<()>> {
let timeout_ms = self let timeout_ms = self.config().network.connection_initial_timeout_ms;
.registry
.config()
.with(|c| c.network.connection_initial_timeout_ms);
#[allow(unused_variables)] #[allow(unused_variables)]
let x = match timeout(timeout_ms, self.inner.ws_meta.close()).await { let x = match timeout(timeout_ms, self.inner.ws_meta.close()).await {

View file

@ -37,9 +37,7 @@ impl RoutingTable {
) as RoutingTableEntryFilter; ) as RoutingTableEntryFilter;
let filters = VecDeque::from([filter]); let filters = VecDeque::from([filter]);
let node_count = self let node_count = self.config().network.dht.max_find_node_count as usize;
.config()
.with(|c| c.network.dht.max_find_node_count as usize);
let closest_nodes = match self.find_preferred_closest_nodes( let closest_nodes = match self.find_preferred_closest_nodes(
node_count, node_count,
@ -115,9 +113,7 @@ impl RoutingTable {
) as RoutingTableEntryFilter; ) as RoutingTableEntryFilter;
let filters = VecDeque::from([filter]); let filters = VecDeque::from([filter]);
let node_count = self let node_count = self.config().network.dht.max_find_node_count as usize;
.config()
.with(|c| c.network.dht.max_find_node_count as usize);
// //
let closest_nodes = match self.find_preferred_closest_nodes( let closest_nodes = match self.find_preferred_closest_nodes(

View file

@ -129,6 +129,10 @@ pub(crate) struct RoutingTable {
/// Node Ids /// Node Ids
node_ids: RwLock<NodeIdGroup>, node_ids: RwLock<NodeIdGroup>,
/// Public Keys
public_keys: RwLock<PublicKeyGroup>,
/// Secret Keys
secret_keys: RwLock<SecretKeyGroup>,
/// Route spec store /// Route spec store
route_spec_store: RouteSpecStore, route_spec_store: RouteSpecStore,
/// Buckets to kick on our next kick task /// Buckets to kick on our next kick task
@ -182,7 +186,6 @@ impl RoutingTable {
startup_context: RoutingTableStartupContext, startup_context: RoutingTableStartupContext,
) -> Self { ) -> Self {
let config = registry.config(); let config = registry.config();
let c = config.get();
let inner = RwLock::new(RoutingTableInner::new(registry.clone())); let inner = RwLock::new(RoutingTableInner::new(registry.clone()));
let route_spec_store = RouteSpecStore::new(registry.clone()); let route_spec_store = RouteSpecStore::new(registry.clone());
let this = Self { let this = Self {
@ -190,6 +193,8 @@ impl RoutingTable {
inner, inner,
startup_context, startup_context,
node_ids: RwLock::new(NodeIdGroup::new()), node_ids: RwLock::new(NodeIdGroup::new()),
public_keys: RwLock::new(PublicKeyGroup::new()),
secret_keys: RwLock::new(SecretKeyGroup::new()),
route_spec_store, route_spec_store,
kick_queue: Mutex::new(BTreeSet::default()), kick_queue: Mutex::new(BTreeSet::default()),
flush_task: TickTask::new("flush_task", ROUTING_TABLE_FLUSH_INTERVAL_SECS), flush_task: TickTask::new("flush_task", ROUTING_TABLE_FLUSH_INTERVAL_SECS),
@ -210,7 +215,7 @@ impl RoutingTable {
peer_minimum_refresh_task: TickTask::new("peer_minimum_refresh_task", 1), peer_minimum_refresh_task: TickTask::new("peer_minimum_refresh_task", 1),
closest_peers_refresh_task: TickTask::new_ms( closest_peers_refresh_task: TickTask::new_ms(
"closest_peers_refresh_task", "closest_peers_refresh_task",
c.network.dht.min_peer_refresh_time_ms, config.network.dht.min_peer_refresh_time_ms,
), ),
ping_validator_public_internet_task: TickTask::new( ping_validator_public_internet_task: TickTask::new(
"ping_validator_public_internet_task", "ping_validator_public_internet_task",
@ -248,17 +253,8 @@ impl RoutingTable {
async fn init_async(&self) -> EyreResult<()> { async fn init_async(&self) -> EyreResult<()> {
veilid_log!(self debug "starting routing table init"); veilid_log!(self debug "starting routing table init");
// Set up node ids // Set up initial keys and node ids
{ self.setup_public_keys().await?;
let mut node_ids = NodeIdGroup::new();
for pk in self.public_keys().iter() {
let node_id = self
.generate_node_id(pk)
.wrap_err("unable to generate node id for public key")?;
node_ids.add(node_id);
}
*self.node_ids.write() = node_ids;
}
// Set up routing buckets // Set up routing buckets
{ {
@ -376,13 +372,11 @@ impl RoutingTable {
} }
pub fn public_key(&self, kind: CryptoKind) -> PublicKey { pub fn public_key(&self, kind: CryptoKind) -> PublicKey {
self.config() self.public_keys.read().get(kind).unwrap()
.with(|c| c.network.routing_table.public_keys.get(kind).unwrap())
} }
pub fn secret_key(&self, kind: CryptoKind) -> SecretKey { pub fn secret_key(&self, kind: CryptoKind) -> SecretKey {
self.config() self.secret_keys.read().get(kind).unwrap()
.with(|c| c.network.routing_table.secret_keys.get(kind).unwrap())
} }
pub fn node_ids(&self) -> NodeIdGroup { pub fn node_ids(&self) -> NodeIdGroup {
@ -390,8 +384,7 @@ impl RoutingTable {
} }
pub fn public_keys(&self) -> PublicKeyGroup { pub fn public_keys(&self) -> PublicKeyGroup {
self.config() self.public_keys.read().clone()
.with(|c| c.network.routing_table.public_keys.clone())
} }
pub fn signing_key_pairs(&self) -> KeyPairGroup { pub fn signing_key_pairs(&self) -> KeyPairGroup {
@ -427,6 +420,148 @@ impl RoutingTable {
false false
} }
#[cfg(not(test))]
async fn setup_public_key(
&self,
vcrypto: AsyncCryptoSystemGuard<'_>,
) -> VeilidAPIResult<(PublicKey, SecretKey)> {
let config = self.config();
let table_store = self.table_store();
let ck = vcrypto.kind();
let mut public_key = config.network.routing_table.public_keys.get(ck);
let mut secret_key = config.network.routing_table.secret_keys.get(ck);
let config_table = table_store.open("__veilid_config", 1).await?;
// Old pre-0.5.0 locations
let table_key_node_id = format!("node_id_{}", ck);
let table_key_node_id_secret = format!("node_id_secret_{}", ck);
// Post-0.5.0 locations
let table_key_public_key = format!("public_key_{}", ck);
let table_key_secret_key = format!("secret_key_{}", ck);
// See if public key was previously stored in the table store
if public_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_public_key);
if let Ok(Some(stored_public_key)) = config_table
.load_json::<PublicKey>(0, table_key_public_key.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_public_key);
public_key = Some(stored_public_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_public_key);
}
}
if public_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_node_id);
if let Ok(Some(stored_public_key)) = config_table
.load_json::<PublicKey>(0, table_key_node_id.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_node_id);
public_key = Some(stored_public_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_node_id);
}
}
// See if secret key was previously stored in the table store
if secret_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_secret_key);
if let Ok(Some(stored_secret_key)) = config_table
.load_json::<SecretKey>(0, table_key_secret_key.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_secret_key);
secret_key = Some(stored_secret_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_secret_key);
}
}
if secret_key.is_none() {
veilid_log!(self debug "pulling {} from storage", table_key_node_id_secret);
if let Ok(Some(stored_secret_key)) = config_table
.load_json::<SecretKey>(0, table_key_node_id_secret.as_bytes())
.await
{
veilid_log!(self debug "{} found in storage", table_key_node_id_secret);
secret_key = Some(stored_secret_key);
} else {
veilid_log!(self debug "{} not found in storage", table_key_node_id_secret);
}
}
// If we have a public key from storage, check it
let (public_key, secret_key) =
if let (Some(public_key), Some(secret_key)) = (public_key, secret_key) {
// Validate node id
if !vcrypto.validate_keypair(&public_key, &secret_key).await? {
apibail_generic!(format!(
"secret_key and public_key don't match:\npublic_key: {}\nsecret_key: {}",
public_key, secret_key
));
}
(public_key, secret_key)
} else {
// If we still don't have a valid keypair, generate one
veilid_log!(self debug "generating new node {} keypair", ck);
vcrypto.generate_keypair().await.into_split()
};
// Save the public key + secret in storage
config_table
.store_json(0, table_key_public_key.as_bytes(), &public_key)
.await?;
config_table
.store_json(0, table_key_secret_key.as_bytes(), &secret_key)
.await?;
Ok((public_key, secret_key))
}
/// Get the public keys from config if one is specified
#[cfg_attr(test, allow(unused_variables))]
async fn setup_public_keys(&self) -> VeilidAPIResult<()> {
let crypto = self.crypto();
let mut out_public_keys = PublicKeyGroup::new();
let mut out_secret_keys = SecretKeyGroup::new();
for ck in VALID_CRYPTO_KINDS {
let vcrypto = crypto
.get_async(ck)
.expect("Valid crypto kind is not actually valid.");
#[cfg(test)]
let (public_key, secret_key) = vcrypto.generate_keypair().await.into_split();
#[cfg(not(test))]
let (public_key, secret_key) = self.setup_public_key(vcrypto).await?;
// Save for config
out_public_keys.add(public_key);
out_secret_keys.add(secret_key);
}
veilid_log!(self info "Public Keys: {}", out_public_keys);
*self.public_keys.write() = out_public_keys;
*self.secret_keys.write() = out_secret_keys;
// Set up node ids
let mut node_ids = NodeIdGroup::new();
for pk in self.public_keys().iter() {
let node_id = self.generate_node_id(pk)?;
node_ids.add(node_id);
}
veilid_log!(self info "Node Ids: {}", node_ids);
*self.node_ids.write() = node_ids;
Ok(())
}
// Convenience validators // Convenience validators
pub fn check_route_id(&self, route_id: &RouteId) -> VeilidAPIResult<()> { pub fn check_route_id(&self, route_id: &RouteId) -> VeilidAPIResult<()> {
let crypto = self.crypto(); let crypto = self.crypto();
@ -546,17 +681,17 @@ impl RoutingTable {
let mut cache_validity_key: Vec<u8> = Vec::new(); let mut cache_validity_key: Vec<u8> = Vec::new();
{ {
let config = self.config(); let config = self.config();
let c = config.get();
for ck in VALID_CRYPTO_KINDS { for ck in VALID_CRYPTO_KINDS {
if let Some(nid) = c.network.routing_table.public_keys.get(ck) { if let Some(nid) = config.network.routing_table.public_keys.get(ck) {
cache_validity_key.extend_from_slice(nid.ref_value()); cache_validity_key.extend_from_slice(nid.ref_value());
} }
} }
for b in &c.network.routing_table.bootstrap { for b in &config.network.routing_table.bootstrap {
cache_validity_key.extend_from_slice(b.as_bytes()); cache_validity_key.extend_from_slice(b.as_bytes());
} }
cache_validity_key.extend_from_slice( cache_validity_key.extend_from_slice(
c.network config
.network
.network_key_password .network_key_password
.clone() .clone()
.unwrap_or_default() .unwrap_or_default()

View file

@ -54,7 +54,6 @@ impl_veilid_component_registry_accessor!(RouteSpecStore);
impl RouteSpecStore { impl RouteSpecStore {
pub fn new(registry: VeilidComponentRegistry) -> Self { pub fn new(registry: VeilidComponentRegistry) -> Self {
let config = registry.config(); let config = registry.config();
let c = config.get();
Self { Self {
registry: registry.clone(), registry: registry.clone(),
@ -62,8 +61,8 @@ impl RouteSpecStore {
content: RouteSpecStoreContent::default(), content: RouteSpecStoreContent::default(),
cache: RouteSpecStoreCache::new(registry.clone()), cache: RouteSpecStoreCache::new(registry.clone()),
}), }),
max_route_hop_count: c.network.rpc.max_route_hop_count.into(), max_route_hop_count: config.network.rpc.max_route_hop_count.into(),
default_route_hop_count: c.network.rpc.default_route_hop_count.into(), default_route_hop_count: config.network.rpc.default_route_hop_count.into(),
} }
} }
@ -202,10 +201,7 @@ impl RouteSpecStore {
apibail_generic!("safety_spec.preferred_route must be empty when allocating new route"); apibail_generic!("safety_spec.preferred_route must be empty when allocating new route");
} }
let ip6_prefix_size = self let ip6_prefix_size = self.config().network.max_connections_per_ip6_prefix_size as usize;
.registry()
.config()
.with(|c| c.network.max_connections_per_ip6_prefix_size as usize);
if safety_spec.hop_count < 1 { if safety_spec.hop_count < 1 {
apibail_invalid_argument!( apibail_invalid_argument!(

View file

@ -446,9 +446,7 @@ impl RoutingDomainDetail for PublicInternetRoutingDomainDetail {
sequencing: Sequencing, sequencing: Sequencing,
dif_sort: Option<&DialInfoDetailSort>, dif_sort: Option<&DialInfoDetailSort>,
) -> ContactMethod { ) -> ContactMethod {
let ip6_prefix_size = rti let ip6_prefix_size = rti.config().network.max_connections_per_ip6_prefix_size as usize;
.config()
.with(|c| c.network.max_connections_per_ip6_prefix_size as usize);
// Get the nodeinfos for convenience // Get the nodeinfos for convenience
let node_a = peer_a.node_info(); let node_a = peer_a.node_info();

View file

@ -13,9 +13,7 @@ impl RoutingTable {
_last_ts: Timestamp, _last_ts: Timestamp,
_cur_ts: Timestamp, _cur_ts: Timestamp,
) -> EyreResult<()> { ) -> EyreResult<()> {
let bootstraps = self let bootstraps = self.config().network.routing_table.bootstrap.clone();
.config()
.with(|c| c.network.routing_table.bootstrap.clone());
// Don't bother if bootstraps aren't configured // Don't bother if bootstraps aren't configured
if bootstraps.is_empty() { if bootstraps.is_empty() {

View file

@ -185,9 +185,7 @@ impl RoutingTable {
// XXX: eventually this should probably be done per-routingdomain // XXX: eventually this should probably be done per-routingdomain
let mut needs_peer_minimum_refresh = false; let mut needs_peer_minimum_refresh = false;
if !needs_bootstrap { if !needs_bootstrap {
let min_peer_count = self let min_peer_count = self.config().network.dht.min_peer_count as usize;
.config()
.with(|c| c.network.dht.min_peer_count as usize);
for ck in VALID_CRYPTO_KINDS { for ck in VALID_CRYPTO_KINDS {
let eckey = (RoutingDomain::PublicInternet, ck); let eckey = (RoutingDomain::PublicInternet, ck);

View file

@ -22,12 +22,8 @@ impl RoutingTable {
// Get counts by crypto kind // Get counts by crypto kind
let live_entry_counts = self.inner.read().cached_live_entry_counts(); let live_entry_counts = self.inner.read().cached_live_entry_counts();
let (min_peer_count, min_peer_refresh_time_ms) = self.config().with(|c| { let min_peer_count = self.config().network.dht.min_peer_count as usize;
( let min_peer_refresh_time_ms = self.config().network.dht.min_peer_refresh_time_ms;
c.network.dht.min_peer_count as usize,
c.network.dht.min_peer_refresh_time_ms,
)
});
// For the PublicInternet routing domain, get list of all peers we know about // For the PublicInternet routing domain, get list of all peers we know about
// even the unreliable ones, and ask them to find nodes close to our node too // even the unreliable ones, and ask them to find nodes close to our node too

View file

@ -10,13 +10,11 @@ const BACKGROUND_SAFETY_ROUTE_COUNT: usize = 2;
impl RoutingTable { impl RoutingTable {
fn get_background_safety_route_count(&self) -> usize { fn get_background_safety_route_count(&self) -> usize {
self.config().with(|c| { if self.config().capabilities.disable.contains(&CAP_ROUTE) {
if c.capabilities.disable.contains(&CAP_ROUTE) { 0
0 } else {
} else { BACKGROUND_SAFETY_ROUTE_COUNT
BACKGROUND_SAFETY_ROUTE_COUNT }
}
})
} }
/// Fastest routes sort /// Fastest routes sort
fn route_sort_latency_fn(a: &(RouteId, u64), b: &(RouteId, u64)) -> cmp::Ordering { fn route_sort_latency_fn(a: &(RouteId, u64), b: &(RouteId, u64)) -> cmp::Ordering {
@ -47,9 +45,7 @@ impl RoutingTable {
/// If a route doesn't 'need_testing', then we neither test nor drop it /// If a route doesn't 'need_testing', then we neither test nor drop it
#[instrument(level = "trace", skip(self))] #[instrument(level = "trace", skip(self))]
fn get_allocated_routes_to_test(&self, cur_ts: Timestamp) -> Vec<RouteId> { fn get_allocated_routes_to_test(&self, cur_ts: Timestamp) -> Vec<RouteId> {
let default_route_hop_count = self let default_route_hop_count = self.config().network.rpc.default_route_hop_count as usize;
.config()
.with(|c| c.network.rpc.default_route_hop_count as usize);
let mut must_test_routes = Vec::<RouteId>::new(); let mut must_test_routes = Vec::<RouteId>::new();
let mut unpublished_routes = Vec::<(RouteId, u64)>::new(); let mut unpublished_routes = Vec::<(RouteId, u64)>::new();
@ -188,9 +184,7 @@ impl RoutingTable {
} }
// Ensure we have a minimum of N allocated local, unpublished routes with the default number of hops and all our supported crypto kinds // Ensure we have a minimum of N allocated local, unpublished routes with the default number of hops and all our supported crypto kinds
let default_route_hop_count = self let default_route_hop_count = self.config().network.rpc.default_route_hop_count as usize;
.config()
.with(|c| c.network.rpc.default_route_hop_count as usize);
let mut local_unpublished_route_count = 0usize; let mut local_unpublished_route_count = 0usize;
self.route_spec_store().list_allocated_routes(|_k, v| { self.route_spec_store().list_allocated_routes(|_k, v| {

View file

@ -247,9 +247,7 @@ impl RoutingTable {
#[instrument(level = "trace", skip_all)] #[instrument(level = "trace", skip_all)]
pub fn make_public_internet_relay_node_filter(&self) -> impl Fn(&BucketEntryInner) -> bool { pub fn make_public_internet_relay_node_filter(&self) -> impl Fn(&BucketEntryInner) -> bool {
let ip6_prefix_size = self let ip6_prefix_size = self.config().network.max_connections_per_ip6_prefix_size as usize;
.config()
.with(|c| c.network.max_connections_per_ip6_prefix_size as usize);
// Get all our outbound protocol/address types // Get all our outbound protocol/address types
let outbound_dif = self.get_outbound_dial_info_filter(RoutingDomain::PublicInternet); let outbound_dif = self.get_outbound_dial_info_filter(RoutingDomain::PublicInternet);

View file

@ -11,7 +11,7 @@ pub mod mock_registry {
pub async fn init<S: AsRef<str>>(namespace: S) -> VeilidComponentRegistry { pub async fn init<S: AsRef<str>>(namespace: S) -> VeilidComponentRegistry {
let (update_callback, config) = setup_veilid_core_with_namespace(namespace); let (update_callback, config) = setup_veilid_core_with_namespace(namespace);
let startup_options = VeilidStartupOptions::new_from_config(config, update_callback); let startup_options = VeilidStartupOptions::try_new(config, update_callback).unwrap();
let registry = VeilidComponentRegistry::new(startup_options); let registry = VeilidComponentRegistry::new(startup_options);
registry.enable_mock(); registry.enable_mock();
registry.register(ProtectedStore::new); registry.register(ProtectedStore::new);

View file

@ -175,12 +175,11 @@ impl RPCProcessor {
// make local copy of node id for easy access // make local copy of node id for easy access
let (concurrency, queue_size, timeout_us) = { let (concurrency, queue_size, timeout_us) = {
let config = registry.config(); let config = registry.config();
let c = config.get();
// set up channel // set up channel
let mut concurrency = c.network.rpc.concurrency; let mut concurrency = config.network.rpc.concurrency;
let queue_size = c.network.rpc.queue_size; let queue_size = config.network.rpc.queue_size;
let timeout_us = TimestampDuration::new(ms_to_us(c.network.rpc.timeout_ms)); let timeout_us = TimestampDuration::new(ms_to_us(config.network.rpc.timeout_ms));
if concurrency == 0 { if concurrency == 0 {
concurrency = get_concurrency(); concurrency = get_concurrency();
if concurrency == 0 { if concurrency == 0 {
@ -470,14 +469,12 @@ impl RPCProcessor {
} }
// If nobody knows where this node is, ask the DHT for it // If nobody knows where this node is, ask the DHT for it
let (node_count, _consensus_count, fanout, timeout) = this.config().with(|c| { let config = this.config();
( let node_count = config.network.dht.max_find_node_count as usize;
c.network.dht.max_find_node_count as usize, let _consensus_count = config.network.dht.resolve_node_count as usize;
c.network.dht.resolve_node_count as usize, let fanout = config.network.dht.resolve_node_fanout as usize;
c.network.dht.resolve_node_fanout as usize, let timeout =
TimestampDuration::from(ms_to_us(c.network.dht.resolve_node_timeout_ms)), TimestampDuration::from(ms_to_us(config.network.dht.resolve_node_timeout_ms));
)
});
// Search routing domains for peer // Search routing domains for peer
// xxx: Eventually add other routing domains here // xxx: Eventually add other routing domains here

View file

@ -250,9 +250,7 @@ impl RPCProcessor {
} }
// See if this is within the consensus width // See if this is within the consensus width
let consensus_width = self let consensus_width = self.config().network.dht.consensus_width as usize;
.config()
.with(|c| c.network.dht.consensus_width as usize);
let (get_result_value, get_result_descriptor) = let (get_result_value, get_result_descriptor) =
if closer_to_key_peers.len() >= consensus_width { if closer_to_key_peers.len() >= consensus_width {
// Not close enough // Not close enough

View file

@ -235,9 +235,7 @@ impl RPCProcessor {
} }
// See if this is within the consensus width // See if this is within the consensus width
let consensus_width = self let consensus_width = self.config().network.dht.consensus_width as usize;
.config()
.with(|c| c.network.dht.consensus_width as usize);
let (inspect_result_seqs, inspect_result_descriptor) = let (inspect_result_seqs, inspect_result_descriptor) =
if closer_to_key_peers.len() >= consensus_width { if closer_to_key_peers.len() >= consensus_width {

View file

@ -263,9 +263,7 @@ impl RPCProcessor {
veilid_log!(self debug target: "dht", "{}", debug_string); veilid_log!(self debug target: "dht", "{}", debug_string);
// If there are less than 'consensus_width' peers that are closer, then store here too // If there are less than 'consensus_width' peers that are closer, then store here too
let consensus_width = self let consensus_width = self.config().network.dht.consensus_width as usize;
.config()
.with(|c| c.network.dht.consensus_width as usize);
let (set, new_value) = if closer_to_key_peers.len() >= consensus_width { let (set, new_value) = if closer_to_key_peers.len() >= consensus_width {
// Not close enough // Not close enough

View file

@ -25,9 +25,8 @@ impl RPCProcessor {
let network_manager = self.network_manager(); let network_manager = self.network_manager();
let validate_dial_info_receipt_time_ms = self let validate_dial_info_receipt_time_ms =
.config() self.config().network.dht.validate_dial_info_receipt_time_ms as u64;
.with(|c| c.network.dht.validate_dial_info_receipt_time_ms as u64);
let receipt_time = TimestampDuration::new_ms(validate_dial_info_receipt_time_ms); let receipt_time = TimestampDuration::new_ms(validate_dial_info_receipt_time_ms);
@ -132,9 +131,7 @@ impl RPCProcessor {
// an ipv6 address // an ipv6 address
let sender_node_id = detail.envelope.get_sender_id(); let sender_node_id = detail.envelope.get_sender_id();
let routing_domain = detail.routing_domain; let routing_domain = detail.routing_domain;
let node_count = self let node_count = self.config().network.dht.max_find_node_count as usize;
.config()
.with(|c| c.network.dht.max_find_node_count as usize);
// Filter on nodes that can validate dial info, and can reach a specific dial info // Filter on nodes that can validate dial info, and can reach a specific dial info
let outbound_dial_info_entry_filter = let outbound_dial_info_entry_filter =

View file

@ -274,9 +274,7 @@ impl RPCProcessor {
)); ));
// See if this is within the consensus width // See if this is within the consensus width
let consensus_width = self let consensus_width = self.config().network.dht.consensus_width as usize;
.config()
.with(|c| c.network.dht.consensus_width as usize);
let (ret_accepted, ret_expiration, ret_watch_id) = let (ret_accepted, ret_expiration, ret_watch_id) =
if closer_to_key_peers.len() >= consensus_width { if closer_to_key_peers.len() >= consensus_width {

View file

@ -34,16 +34,13 @@ impl StorageManager {
last_get_result: GetResult, last_get_result: GetResult,
) -> VeilidAPIResult<flume::Receiver<VeilidAPIResult<OutboundGetValueResult>>> { ) -> VeilidAPIResult<flume::Receiver<VeilidAPIResult<OutboundGetValueResult>>> {
let routing_domain = RoutingDomain::PublicInternet; let routing_domain = RoutingDomain::PublicInternet;
let config = self.config();
// Get the DHT parameters for 'GetValue' // Get the DHT parameters for 'GetValue'
let (key_count, consensus_count, fanout, timeout_us) = self.config().with(|c| { let key_count = config.network.dht.max_find_node_count as usize;
( let consensus_count = config.network.dht.get_value_count as usize;
c.network.dht.max_find_node_count as usize, let fanout = config.network.dht.get_value_fanout as usize;
c.network.dht.get_value_count as usize, let timeout_us = TimestampDuration::from(ms_to_us(config.network.dht.get_value_timeout_ms));
c.network.dht.get_value_fanout as usize,
TimestampDuration::from(ms_to_us(c.network.dht.get_value_timeout_ms)),
)
});
// Get the nodes we know are caching this value to seed the fanout // Get the nodes we know are caching this value to seed the fanout
let init_fanout_queue = { let init_fanout_queue = {
@ -395,8 +392,7 @@ impl StorageManager {
opaque_record_key.clone(), opaque_record_key.clone(),
core::iter::once((ValueSubkeyRangeSet::single(subkey), result.fanout_result)), core::iter::once((ValueSubkeyRangeSet::single(subkey), result.fanout_result)),
false, false,
self.config() self.config().network.dht.consensus_width as usize,
.with(|c| c.network.dht.consensus_width as usize),
); );
// If we got a new value back then write it to the opened record // If we got a new value back then write it to the opened record

View file

@ -68,23 +68,23 @@ impl StorageManager {
// Get the DHT parameters for 'InspectValue' // Get the DHT parameters for 'InspectValue'
// Can use either 'get scope' or 'set scope' depending on the purpose of the inspection // Can use either 'get scope' or 'set scope' depending on the purpose of the inspection
let (key_count, consensus_count, fanout, timeout_us) = self.config().with(|c| { let (key_count, consensus_count, fanout, timeout_us) = if use_set_scope {
if use_set_scope { let config = self.config();
( (
c.network.dht.max_find_node_count as usize, config.network.dht.max_find_node_count as usize,
c.network.dht.set_value_count as usize, config.network.dht.set_value_count as usize,
c.network.dht.set_value_fanout as usize, config.network.dht.set_value_fanout as usize,
TimestampDuration::from(ms_to_us(c.network.dht.set_value_timeout_ms)), TimestampDuration::from(ms_to_us(config.network.dht.set_value_timeout_ms)),
) )
} else { } else {
( let config = self.config();
c.network.dht.max_find_node_count as usize, (
c.network.dht.get_value_count as usize, config.network.dht.max_find_node_count as usize,
c.network.dht.get_value_fanout as usize, config.network.dht.get_value_count as usize,
TimestampDuration::from(ms_to_us(c.network.dht.get_value_timeout_ms)), config.network.dht.get_value_fanout as usize,
) TimestampDuration::from(ms_to_us(config.network.dht.get_value_timeout_ms)),
} )
}); };
// Get the nodes we know are caching this value to seed the fanout // Get the nodes we know are caching this value to seed the fanout
let init_fanout_queue = { let init_fanout_queue = {

View file

@ -247,8 +247,7 @@ impl StorageManager {
this this
} }
fn local_limits_from_config(config: VeilidStartupOptions) -> RecordStoreLimits { fn local_limits_from_config(c: Arc<VeilidConfig>) -> RecordStoreLimits {
let c = config.get();
RecordStoreLimits { RecordStoreLimits {
subkey_cache_size: c.network.dht.local_subkey_cache_size as usize, subkey_cache_size: c.network.dht.local_subkey_cache_size as usize,
max_subkey_size: MAX_SUBKEY_SIZE, max_subkey_size: MAX_SUBKEY_SIZE,
@ -267,8 +266,7 @@ impl StorageManager {
} }
} }
fn remote_limits_from_config(config: VeilidStartupOptions) -> RecordStoreLimits { fn remote_limits_from_config(c: Arc<VeilidConfig>) -> RecordStoreLimits {
let c = config.get();
RecordStoreLimits { RecordStoreLimits {
subkey_cache_size: c.network.dht.remote_subkey_cache_size as usize, subkey_cache_size: c.network.dht.remote_subkey_cache_size as usize,
max_subkey_size: MAX_SUBKEY_SIZE, max_subkey_size: MAX_SUBKEY_SIZE,
@ -643,9 +641,7 @@ impl StorageManager {
// We had an existing record, so check the network to see if we should // We had an existing record, so check the network to see if we should
// update it with what we have here // update it with what we have here
let set_consensus = self let set_consensus = self.config().network.dht.set_value_count as usize;
.config()
.with(|c| c.network.dht.set_value_count as usize);
self.add_rehydration_request( self.add_rehydration_request(
record_key.opaque(), record_key.opaque(),
@ -1252,9 +1248,8 @@ impl StorageManager {
None None
} else { } else {
// Get the minimum expiration timestamp we will accept // Get the minimum expiration timestamp we will accept
let rpc_timeout_us = self let rpc_timeout_us =
.config() TimestampDuration::from(ms_to_us(self.config().network.rpc.timeout_ms));
.with(|c| TimestampDuration::from(ms_to_us(c.network.rpc.timeout_ms)));
let cur_ts = get_timestamp(); let cur_ts = get_timestamp();
let min_expiration_ts = Timestamp::new(cur_ts + rpc_timeout_us.as_u64()); let min_expiration_ts = Timestamp::new(cur_ts + rpc_timeout_us.as_u64());
let expiration_ts = if expiration.as_u64() == 0 { let expiration_ts = if expiration.as_u64() == 0 {
@ -1481,8 +1476,7 @@ impl StorageManager {
opaque_record_key.clone(), opaque_record_key.clone(),
results_iter, results_iter,
false, false,
self.config() self.config().network.dht.consensus_width as usize,
.with(|c| c.network.dht.consensus_width as usize),
); );
if result.inspect_result.subkeys().is_empty() { if result.inspect_result.subkeys().is_empty() {
@ -1555,9 +1549,7 @@ impl StorageManager {
match fanout_result.kind { match fanout_result.kind {
FanoutResultKind::Incomplete => false, FanoutResultKind::Incomplete => false,
FanoutResultKind::Timeout => { FanoutResultKind::Timeout => {
let get_consensus = self let get_consensus = self.config().network.dht.get_value_count as usize;
.config()
.with(|c| c.network.dht.get_value_count as usize);
let value_node_count = fanout_result.consensus_nodes.len(); let value_node_count = fanout_result.consensus_nodes.len();
if value_node_count < get_consensus { if value_node_count < get_consensus {
veilid_log!(self debug "timeout with insufficient consensus ({}<{}), adding offline subkey: {}:{}", veilid_log!(self debug "timeout with insufficient consensus ({}<{}), adding offline subkey: {}:{}",
@ -1572,9 +1564,7 @@ impl StorageManager {
} }
} }
FanoutResultKind::Exhausted => { FanoutResultKind::Exhausted => {
let get_consensus = self let get_consensus = self.config().network.dht.get_value_count as usize;
.config()
.with(|c| c.network.dht.get_value_count as usize);
let value_node_count = fanout_result.consensus_nodes.len(); let value_node_count = fanout_result.consensus_nodes.len();
if value_node_count < get_consensus { if value_node_count < get_consensus {
veilid_log!(self debug "exhausted with insufficient consensus ({}<{}), adding offline subkey: {}:{}", veilid_log!(self debug "exhausted with insufficient consensus ({}<{}), adding offline subkey: {}:{}",
@ -1616,8 +1606,7 @@ impl StorageManager {
// Verify the dht schema does not contain the node id // Verify the dht schema does not contain the node id
{ {
let config = self.config(); let config = self.config();
let cfg = config.get(); if let Some(node_id) = config.network.routing_table.public_keys.get(kind) {
if let Some(node_id) = cfg.network.routing_table.public_keys.get(kind) {
let node_member_id = BareMemberId::new(node_id.ref_value()); let node_member_id = BareMemberId::new(node_id.ref_value());
if schema.is_member(&node_member_id) { if schema.is_member(&node_member_id) {
apibail_invalid_argument!( apibail_invalid_argument!(

View file

@ -292,8 +292,7 @@ impl StorageManager {
opaque_record_key.clone(), opaque_record_key.clone(),
results_iter, results_iter,
false, false,
self.config() self.config().network.dht.consensus_width as usize,
.with(|c| c.network.dht.consensus_width as usize),
); );
Ok(RehydrateReport { Ok(RehydrateReport {

View file

@ -37,14 +37,11 @@ impl StorageManager {
let routing_domain = RoutingDomain::PublicInternet; let routing_domain = RoutingDomain::PublicInternet;
// Get the DHT parameters for 'SetValue' // Get the DHT parameters for 'SetValue'
let (key_count, consensus_count, fanout, timeout_us) = self.config().with(|c| { let config = self.config();
( let key_count = config.network.dht.max_find_node_count as usize;
c.network.dht.max_find_node_count as usize, let consensus_count = config.network.dht.set_value_count as usize;
c.network.dht.set_value_count as usize, let fanout = config.network.dht.set_value_fanout as usize;
c.network.dht.set_value_fanout as usize, let timeout_us = TimestampDuration::from(ms_to_us(config.network.dht.set_value_timeout_ms));
TimestampDuration::from(ms_to_us(c.network.dht.set_value_timeout_ms)),
)
});
// Get the nodes we know are caching this value to seed the fanout // Get the nodes we know are caching this value to seed the fanout
let init_fanout_queue = { let init_fanout_queue = {
@ -379,8 +376,7 @@ impl StorageManager {
record_key.opaque(), record_key.opaque(),
core::iter::once((ValueSubkeyRangeSet::single(subkey), result.fanout_result)), core::iter::once((ValueSubkeyRangeSet::single(subkey), result.fanout_result)),
true, true,
self.config() self.config().network.dht.consensus_width as usize,
.with(|c| c.network.dht.consensus_width as usize),
); );
// Record the set value locally since it was successfully set online // Record the set value locally since it was successfully set online

View file

@ -170,9 +170,7 @@ impl StorageManager {
// Process all results // Process all results
#[instrument(level = "trace", target = "stor", skip_all)] #[instrument(level = "trace", target = "stor", skip_all)]
async fn process_single_result(&self, result: WorkItemResult) { async fn process_single_result(&self, result: WorkItemResult) {
let consensus_width = self let consensus_width = self.config().network.dht.consensus_width as usize;
.config()
.with(|c| c.network.dht.consensus_width as usize);
let mut inner = self.inner.lock().await; let mut inner = self.inner.lock().await;

View file

@ -166,14 +166,11 @@ impl StorageManager {
let routing_domain = RoutingDomain::PublicInternet; let routing_domain = RoutingDomain::PublicInternet;
// Get the DHT parameters for 'WatchValue', some of which are the same for 'GetValue' operations // Get the DHT parameters for 'WatchValue', some of which are the same for 'GetValue' operations
let (key_count, consensus_count, fanout, timeout_us) = self.config().with(|c| { let config = self.config();
( let key_count = config.network.dht.max_find_node_count as usize;
c.network.dht.max_find_node_count as usize, let consensus_count = config.network.dht.get_value_count as usize;
c.network.dht.get_value_count as usize, let fanout = config.network.dht.get_value_fanout as usize;
c.network.dht.get_value_fanout as usize, let timeout_us = TimestampDuration::from(ms_to_us(config.network.dht.get_value_timeout_ms));
TimestampDuration::from(ms_to_us(c.network.dht.get_value_timeout_ms)),
)
});
// Get the appropriate watcher key, if anonymous use a static anonymous watch key // Get the appropriate watcher key, if anonymous use a static anonymous watch key
// which lives for the duration of the app's runtime // which lives for the duration of the app's runtime
@ -351,8 +348,7 @@ impl StorageManager {
record_key.opaque(), record_key.opaque(),
core::iter::once((ValueSubkeyRangeSet::new(), fanout_result)), core::iter::once((ValueSubkeyRangeSet::new(), fanout_result)),
false, false,
self.config() self.config().network.dht.consensus_width as usize,
.with(|c| c.network.dht.consensus_width as usize),
); );
let owvresult = context.lock().watch_value_result.clone(); let owvresult = context.lock().watch_value_result.clone();
@ -842,9 +838,7 @@ impl StorageManager {
outbound_watch: &mut OutboundWatch, outbound_watch: &mut OutboundWatch,
) -> Option<PinBoxFutureStatic<()>> { ) -> Option<PinBoxFutureStatic<()>> {
let registry = self.registry(); let registry = self.registry();
let consensus_count = self let consensus_count = self.config().network.dht.get_value_count as usize;
.config()
.with(|c| c.network.dht.get_value_count as usize);
// Operate on this watch only if it isn't already being operated on // Operate on this watch only if it isn't already being operated on
let watch_lock = let watch_lock =

View file

@ -97,7 +97,7 @@ pub struct TableStore {
registry: VeilidComponentRegistry, registry: VeilidComponentRegistry,
inner: Mutex<TableStoreInner>, // Sync mutex here because TableDB drops can happen at any time inner: Mutex<TableStoreInner>, // Sync mutex here because TableDB drops can happen at any time
table_store_driver: TableStoreDriver, table_store_driver: TableStoreDriver,
async_lock: Arc<AsyncMutex<()>>, // Async mutex for operations async_lock: Arc<AsyncMutex<()>>,
} }
impl fmt::Debug for TableStore { impl fmt::Debug for TableStore {
@ -158,7 +158,7 @@ impl TableStore {
{ {
apibail_invalid_argument!("table name is invalid", "table", table); apibail_invalid_argument!("table name is invalid", "table", table);
} }
let namespace = self.config().with(|c| c.namespace.clone()); let namespace = self.config().namespace.clone();
Ok(if namespace.is_empty() { Ok(if namespace.is_empty() {
table.to_string() table.to_string()
} else { } else {
@ -375,7 +375,9 @@ impl TableStore {
// Get device encryption key protection password if we have it // Get device encryption key protection password if we have it
let device_encryption_key_password = self let device_encryption_key_password = self
.config() .config()
.with(|c| c.protected_store.device_encryption_key_password.clone()); .protected_store
.device_encryption_key_password
.clone();
Ok(Some( Ok(Some(
self.maybe_unprotect_device_encryption_key(&dek_bytes, &device_encryption_key_password) self.maybe_unprotect_device_encryption_key(&dek_bytes, &device_encryption_key_password)
@ -398,27 +400,23 @@ impl TableStore {
}; };
// Get new device encryption key protection password if we are changing it // Get new device encryption key protection password if we are changing it
let new_device_encryption_key_password = { let new_device_encryption_key_password = self
self.config() .config()
.with(|c| c.protected_store.new_device_encryption_key_password.clone()) .protected_store
}; .new_device_encryption_key_password
.clone();
let device_encryption_key_password = let device_encryption_key_password =
if let Some(new_device_encryption_key_password) = new_device_encryption_key_password { if let Some(new_device_encryption_key_password) = new_device_encryption_key_password {
// Change password // Change password
veilid_log!(self debug "changing dek password"); veilid_log!(self debug "changing dek password");
self.config() new_device_encryption_key_password
.try_with_mut(|c| {
c.protected_store
.device_encryption_key_password
.clone_from(&new_device_encryption_key_password);
Ok(new_device_encryption_key_password)
})
.unwrap()
} else { } else {
// Get device encryption key protection password if we have it // Get device encryption key protection password if we have it
veilid_log!(self debug "saving with existing dek password"); veilid_log!(self debug "saving with existing dek password");
self.config() self.config()
.with(|c| c.protected_store.device_encryption_key_password.clone()) .protected_store
.device_encryption_key_password
.clone()
}; };
let dek_bytes = self let dek_bytes = self
@ -462,11 +460,11 @@ impl TableStore {
} }
// Check for password change // Check for password change
let changing_password = self.config().with(|c| { let changing_password = self
c.protected_store .config()
.new_device_encryption_key_password .protected_store
.is_some() .new_device_encryption_key_password
}); .is_some();
// Save encryption key if it has changed or if the protecting password wants to change // Save encryption key if it has changed or if the protecting password wants to change
if device_encryption_key_changed || changing_password { if device_encryption_key_changed || changing_password {
@ -505,7 +503,7 @@ impl TableStore {
inner.all_tables_db = Some(all_tables_db); inner.all_tables_db = Some(all_tables_db);
} }
let do_delete = self.config().with(|c| c.table_store.delete); let do_delete = self.config().table_store.delete;
if do_delete { if do_delete {
self.delete_all().await; self.delete_all().await;

View file

@ -16,12 +16,11 @@ impl TableStoreDriver {
} }
fn get_dbpath(&self, table: &str) -> VeilidAPIResult<PathBuf> { fn get_dbpath(&self, table: &str) -> VeilidAPIResult<PathBuf> {
let config = self.registry().config(); let config = self.config();
let c = config.get(); let tablestoredir = config.table_store.directory.clone();
let tablestoredir = c.table_store.directory.clone();
std::fs::create_dir_all(&tablestoredir).map_err(VeilidAPIError::from)?; std::fs::create_dir_all(&tablestoredir).map_err(VeilidAPIError::from)?;
let namespace = c.namespace.clone(); let namespace = config.namespace.clone();
let dbpath: PathBuf = if namespace.is_empty() { let dbpath: PathBuf = if namespace.is_empty() {
[tablestoredir, String::from(table)].iter().collect() [tablestoredir, String::from(table)].iter().collect()
} else { } else {

View file

@ -16,8 +16,7 @@ impl TableStoreDriver {
fn get_namespaced_table_name(&self, table: &str) -> String { fn get_namespaced_table_name(&self, table: &str) -> String {
let config = self.registry().config(); let config = self.registry().config();
let c = config.get(); let namespace = config.namespace.clone();
let namespace = c.namespace.clone();
if namespace.is_empty() { if namespace.is_empty() {
table.to_owned() table.to_owned()
} else { } else {

View file

@ -315,7 +315,7 @@ pub fn fix_fake_veilid_config() -> VeilidConfig {
} }
pub fn get_startup_options() -> VeilidStartupOptions { pub fn get_startup_options() -> VeilidStartupOptions {
VeilidStartupOptions::new_from_config(get_config(), Arc::new(update_callback)) VeilidStartupOptions::try_new(get_config(), Arc::new(update_callback)).unwrap()
} }
pub fn get_config() -> VeilidConfig { pub fn get_config() -> VeilidConfig {

View file

@ -79,7 +79,7 @@ impl VeilidAPI {
// Public Accessors // Public Accessors
/// Access the configuration that Veilid was initialized with. /// Access the configuration that Veilid was initialized with.
pub fn config(&self) -> VeilidAPIResult<VeilidStartupOptions> { pub fn config(&self) -> VeilidAPIResult<Arc<VeilidConfig>> {
let inner = self.inner.lock(); let inner = self.inner.lock();
let Some(context) = &inner.context else { let Some(context) = &inner.context else {
return Err(VeilidAPIError::NotInitialized); return Err(VeilidAPIError::NotInitialized);
@ -173,12 +173,13 @@ impl VeilidAPI {
let attachment = attachment_manager.get_veilid_state(); let attachment = attachment_manager.get_veilid_state();
let network = network_manager.get_veilid_state(); let network = network_manager.get_veilid_state();
let config = config.get_veilid_state();
Ok(VeilidState { Ok(VeilidState {
attachment, attachment,
network, network,
config, config: Box::new(VeilidStateConfig {
config: config.as_ref().clone(),
}),
}) })
} }
@ -279,11 +280,8 @@ impl VeilidAPI {
Crypto::validate_crypto_kind(*kind)?; Crypto::validate_crypto_kind(*kind)?;
} }
let default_route_hop_count: usize = { let default_route_hop_count: usize =
let config = self.config()?; self.config()?.network.rpc.default_route_hop_count.into();
let c = config.get();
c.network.rpc.default_route_hop_count.into()
};
let safety_spec = SafetySpec { let safety_spec = SafetySpec {
preferred_route: None, preferred_route: None,

View file

@ -173,9 +173,8 @@ fn get_safety_selection(
registry: VeilidComponentRegistry, registry: VeilidComponentRegistry,
) -> impl Fn(&str) -> Option<SafetySelection> { ) -> impl Fn(&str) -> Option<SafetySelection> {
move |text| { move |text| {
let default_route_hop_count = registry let default_route_hop_count =
.config() registry.config().network.rpc.default_route_hop_count as usize;
.with(|c| c.network.rpc.default_route_hop_count as usize);
if !text.is_empty() && &text[0..1] == "-" { if !text.is_empty() && &text[0..1] == "-" {
// Unsafe // Unsafe
@ -827,11 +826,12 @@ impl VeilidAPI {
Ok(nodeid) Ok(nodeid)
} }
#[expect(clippy::unused_async)]
async fn debug_config(&self, args: String) -> VeilidAPIResult<String> { async fn debug_config(&self, args: String) -> VeilidAPIResult<String> {
let mut args = args.as_str(); let mut args = args.as_str();
let mut config = self.config()?; let mut config = self.config()?;
if !args.starts_with("insecure") { if !args.starts_with("insecure") {
config = config.safe_config(); config = config.safe();
} else { } else {
args = &args[8..]; args = &args[8..];
} }
@ -844,23 +844,11 @@ impl VeilidAPI {
let rest = rest.trim_start().to_owned(); let rest = rest.trim_start().to_owned();
// One argument is 'config get' // One argument is 'config get'
if rest.is_empty() { if !rest.is_empty() {
return config.get_key_json(arg, true); apibail_internal!("too many arguments");
} }
// More than one argument is 'config set' config.get_key_json(arg, true)
// Must be detached
if !matches!(
self.get_state().await?.attachment.state,
AttachmentState::Detached
) {
apibail_internal!("Must be detached to change config");
}
// Change the config key
config.set_key_json(arg, &rest)?;
Ok("Config value set".to_owned())
} }
async fn debug_network(&self, args: String) -> VeilidAPIResult<String> { async fn debug_network(&self, args: String) -> VeilidAPIResult<String> {
@ -1193,11 +1181,7 @@ impl VeilidAPI {
let registry = self.core_context()?.registry(); let registry = self.core_context()?.registry();
let routing_table = registry.routing_table(); let routing_table = registry.routing_table();
let rss = routing_table.route_spec_store(); let rss = routing_table.route_spec_store();
let config = self.config().unwrap(); let default_route_hop_count = self.config()?.network.rpc.default_route_hop_count as usize;
let default_route_hop_count = {
let c = config.get();
c.network.rpc.default_route_hop_count as usize
};
let mut ai = 1; let mut ai = 1;
let mut sequencing = Sequencing::default(); let mut sequencing = Sequencing::default();
@ -2050,11 +2034,8 @@ impl VeilidAPI {
.add_rehydration_request( .add_rehydration_request(
key.opaque(), key.opaque(),
subkeys.unwrap_or_default(), subkeys.unwrap_or_default(),
consensus_count.unwrap_or_else(|| { consensus_count
registry .unwrap_or_else(|| registry.config().network.dht.set_value_count as usize),
.config()
.with(|c| c.network.dht.set_value_count as usize)
}),
) )
.await; .await;

View file

@ -56,14 +56,13 @@ impl RoutingContext {
pub(super) fn try_new(api: VeilidAPI) -> VeilidAPIResult<Self> { pub(super) fn try_new(api: VeilidAPI) -> VeilidAPIResult<Self> {
let config = api.config()?; let config = api.config()?;
let c = config.get();
Ok(Self { Ok(Self {
api, api,
unlocked_inner: Arc::new(RoutingContextUnlockedInner { unlocked_inner: Arc::new(RoutingContextUnlockedInner {
safety_selection: SafetySelection::Safe(SafetySpec { safety_selection: SafetySelection::Safe(SafetySpec {
preferred_route: None, preferred_route: None,
hop_count: c.network.rpc.default_route_hop_count as usize, hop_count: config.network.rpc.default_route_hop_count as usize,
stability: Stability::Reliable, stability: Stability::Reliable,
sequencing: Sequencing::PreferOrdered, sequencing: Sequencing::PreferOrdered,
}), }),
@ -92,11 +91,10 @@ impl RoutingContext {
"RoutingContext::with_default_safety(self: {:?})", self); "RoutingContext::with_default_safety(self: {:?})", self);
let config = self.api.config()?; let config = self.api.config()?;
let c = config.get();
self.with_safety(SafetySelection::Safe(SafetySpec { self.with_safety(SafetySelection::Safe(SafetySpec {
preferred_route: None, preferred_route: None,
hop_count: c.network.rpc.default_route_hop_count as usize, hop_count: config.network.rpc.default_route_hop_count as usize,
stability: Stability::Reliable, stability: Stability::Reliable,
sequencing: Sequencing::PreferOrdered, sequencing: Sequencing::PreferOrdered,
})) }))

View file

@ -236,6 +236,7 @@ pub fn test_veilidstatenetwork() {
bps_down: ByteCount::from(14_400), bps_down: ByteCount::from(14_400),
bps_up: ByteCount::from(1200), bps_up: ByteCount::from(1200),
peers: vec![fix_peertabledata()], peers: vec![fix_peertabledata()],
node_ids: vec![fix_fake_node_id()],
}; };
let copy = deserialize_json(&serialize_json(&orig)).unwrap(); let copy = deserialize_json(&serialize_json(&orig)).unwrap();
@ -289,6 +290,7 @@ pub fn test_veilidstate() {
bps_down: ByteCount::from(14_400), bps_down: ByteCount::from(14_400),
bps_up: ByteCount::from(1200), bps_up: ByteCount::from(1200),
peers: vec![fix_peertabledata()], peers: vec![fix_peertabledata()],
node_ids: vec![fix_fake_node_id()],
}), }),
config: Box::new(VeilidStateConfig { config: Box::new(VeilidStateConfig {
config: fix_fake_veilid_config(), config: fix_fake_veilid_config(),

View file

@ -128,6 +128,13 @@ pub struct VeilidStateNetwork {
/// The list of most recently accessed peers. /// The list of most recently accessed peers.
/// This is not an active connection table, nor is representative of the entire routing table. /// This is not an active connection table, nor is representative of the entire routing table.
pub peers: Vec<PeerTableData>, pub peers: Vec<PeerTableData>,
/// The list of node ids for this node
#[schemars(with = "Vec<String>")]
#[cfg_attr(
all(target_arch = "wasm32", target_os = "unknown"),
tsify(type = "string[]")
)]
pub node_ids: Vec<NodeId>,
} }
/// Describe a private route change that has happened /// Describe a private route change that has happened

View file

@ -954,118 +954,22 @@ impl VeilidConfig {
out out
} }
}
/// The configuration built for each Veilid node during API startup
#[derive(Clone)]
#[must_use]
pub struct VeilidStartupOptions {
update_cb: UpdateCallback,
inner: Arc<RwLock<VeilidConfig>>,
}
impl fmt::Debug for VeilidStartupOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let inner = self.inner.read();
f.debug_struct("VeilidConfig")
.field("inner", &*inner)
.finish()
}
}
impl VeilidStartupOptions {
pub(crate) fn new_from_config(config: VeilidConfig, update_cb: UpdateCallback) -> Self {
Self {
update_cb,
inner: Arc::new(RwLock::new(config)),
}
}
pub(crate) fn get_veilid_state(&self) -> Box<VeilidStateConfig> {
let inner = self.inner.read();
Box::new(VeilidStateConfig {
config: inner.clone(),
})
}
#[must_use] #[must_use]
pub fn update_callback(&self) -> UpdateCallback { pub fn safe(&self) -> Arc<VeilidConfig> {
self.update_cb.clone() let mut safe_cfg = self.clone();
}
pub fn get(&self) -> RwLockReadGuard<'_, VeilidConfig> {
self.inner.read()
}
fn safe_config_inner(&self) -> VeilidConfig {
let mut safe_cfg = self.inner.read().clone();
// Remove secrets // Remove secrets
safe_cfg.network.routing_table.secret_keys = SecretKeyGroup::new(); safe_cfg.network.routing_table.secret_keys = SecretKeyGroup::new();
"".clone_into(&mut safe_cfg.protected_store.device_encryption_key_password); "".clone_into(&mut safe_cfg.protected_store.device_encryption_key_password);
safe_cfg.protected_store.new_device_encryption_key_password = None; safe_cfg.protected_store.new_device_encryption_key_password = None;
safe_cfg Arc::new(safe_cfg)
}
pub fn safe_config(&self) -> VeilidStartupOptions {
let mut safe_cfg = self.inner.read().clone();
// Remove secrets
safe_cfg.network.routing_table.secret_keys = SecretKeyGroup::new();
"".clone_into(&mut safe_cfg.protected_store.device_encryption_key_password);
safe_cfg.protected_store.new_device_encryption_key_password = None;
VeilidStartupOptions {
update_cb: self.update_cb.clone(),
inner: Arc::new(RwLock::new(safe_cfg)),
}
}
pub fn with<F, R>(&self, f: F) -> R
where
F: FnOnce(&VeilidConfig) -> R,
{
let inner = self.inner.read();
f(&inner)
}
pub fn try_with_mut<F, R>(&self, f: F) -> VeilidAPIResult<R>
where
F: FnOnce(&mut VeilidConfig) -> VeilidAPIResult<R>,
{
let out = {
let inner = &mut *self.inner.write();
// Edit a copy
let mut editedinner = inner.clone();
// Make changes
let out = f(&mut editedinner)?;
// Validate
Self::validate(&editedinner)?;
// See if things have changed
if *inner == editedinner {
// No changes, return early
return Ok(out);
}
// Commit changes
*inner = editedinner.clone();
out
};
// Send configuration update to clients
let safe_cfg = self.safe_config_inner();
(self.update_cb)(VeilidUpdate::Config(Box::new(VeilidStateConfig {
config: safe_cfg,
})));
Ok(out)
} }
pub fn get_key_json(&self, key: &str, pretty: bool) -> VeilidAPIResult<String> { pub fn get_key_json(&self, key: &str, pretty: bool) -> VeilidAPIResult<String> {
let c = self.get();
// Generate json from whole config // Generate json from whole config
let jc = serde_json::to_string(&*c).map_err(VeilidAPIError::generic)?; let jc = serde_json::to_string(self).map_err(VeilidAPIError::generic)?;
let jvc = json::parse(&jc).map_err(VeilidAPIError::generic)?; let jvc = json::parse(&jc).map_err(VeilidAPIError::generic)?;
// Find requested subkey // Find requested subkey
@ -1092,42 +996,6 @@ impl VeilidStartupOptions {
}) })
} }
} }
pub fn set_key_json(&self, key: &str, value: &str) -> VeilidAPIResult<()> {
self.try_with_mut(|c| {
// Split key into path parts
let keypath: Vec<&str> = key.split('.').collect();
// Convert value into jsonvalue
let newval = json::parse(value).map_err(VeilidAPIError::generic)?;
// Generate json from whole config
let jc = serde_json::to_string(&*c).map_err(VeilidAPIError::generic)?;
let mut jvc = json::parse(&jc).map_err(VeilidAPIError::generic)?;
// Find requested subkey
let newconfigstring = if let Some((objkeyname, objkeypath)) = keypath.split_last() {
// Replace subkey
let mut out = &mut jvc;
for k in objkeypath {
if !out.has_key(k) {
apibail_parse_error!(format!("invalid subkey in key '{}'", key), k);
}
out = &mut out[*k];
}
if !out.has_key(objkeyname) {
apibail_parse_error!(format!("invalid subkey in key '{}'", key), objkeyname);
}
out[*objkeyname] = newval;
jvc.to_string()
} else {
newval.to_string()
};
// Generate new config
*c = serde_json::from_str(&newconfigstring).map_err(VeilidAPIError::generic)?;
Ok(())
})
}
fn validate_program_name(program_name: &str) -> VeilidAPIResult<()> { fn validate_program_name(program_name: &str) -> VeilidAPIResult<()> {
if program_name.is_empty() { if program_name.is_empty() {
@ -1162,32 +1030,32 @@ impl VeilidStartupOptions {
Ok(()) Ok(())
} }
fn validate(inner: &VeilidConfig) -> VeilidAPIResult<()> { pub fn validate(&self) -> VeilidAPIResult<()> {
Self::validate_program_name(&inner.program_name)?; Self::validate_program_name(&self.program_name)?;
Self::validate_namespace(&inner.namespace)?; Self::validate_namespace(&self.namespace)?;
// if inner.network.protocol.udp.enabled { // if inner.network.protocol.udp.enabled {
// // Validate UDP settings // // Validate UDP settings
// } // }
if inner.network.protocol.tcp.listen { if self.network.protocol.tcp.listen {
// Validate TCP settings // Validate TCP settings
if inner.network.protocol.tcp.max_connections == 0 { if self.network.protocol.tcp.max_connections == 0 {
apibail_generic!("TCP max connections must be > 0 in config key 'network.protocol.tcp.max_connections'"); apibail_generic!("TCP max connections must be > 0 in config key 'network.protocol.tcp.max_connections'");
} }
} }
if inner.network.protocol.ws.listen { if self.network.protocol.ws.listen {
// Validate WS settings // Validate WS settings
if inner.network.protocol.ws.max_connections == 0 { if self.network.protocol.ws.max_connections == 0 {
apibail_generic!("WS max connections must be > 0 in config key 'network.protocol.ws.max_connections'"); apibail_generic!("WS max connections must be > 0 in config key 'network.protocol.ws.max_connections'");
} }
} }
#[cfg(feature = "enable-protocol-wss")] #[cfg(feature = "enable-protocol-wss")]
if inner.network.protocol.wss.listen { if self.network.protocol.wss.listen {
// Validate WSS settings // Validate WSS settings
if inner.network.protocol.wss.max_connections == 0 { if self.network.protocol.wss.max_connections == 0 {
apibail_generic!("WSS max connections must be > 0 in config key 'network.protocol.wss.max_connections'"); apibail_generic!("WSS max connections must be > 0 in config key 'network.protocol.wss.max_connections'");
} }
if inner if self
.network .network
.protocol .protocol
.wss .wss
@ -1201,50 +1069,50 @@ impl VeilidStartupOptions {
); );
} }
} }
if inner.network.rpc.max_route_hop_count == 0 { if self.network.rpc.max_route_hop_count == 0 {
apibail_generic!( apibail_generic!(
"max route hop count must be >= 1 in 'network.rpc.max_route_hop_count'" "max route hop count must be >= 1 in 'network.rpc.max_route_hop_count'"
); );
} }
if inner.network.rpc.max_route_hop_count > 5 { if self.network.rpc.max_route_hop_count > 5 {
apibail_generic!( apibail_generic!(
"max route hop count must be <= 5 in 'network.rpc.max_route_hop_count'" "max route hop count must be <= 5 in 'network.rpc.max_route_hop_count'"
); );
} }
if inner.network.rpc.default_route_hop_count == 0 { if self.network.rpc.default_route_hop_count == 0 {
apibail_generic!( apibail_generic!(
"default route hop count must be >= 1 in 'network.rpc.default_route_hop_count'" "default route hop count must be >= 1 in 'network.rpc.default_route_hop_count'"
); );
} }
if inner.network.rpc.default_route_hop_count > inner.network.rpc.max_route_hop_count { if self.network.rpc.default_route_hop_count > self.network.rpc.max_route_hop_count {
apibail_generic!( apibail_generic!(
"default route hop count must be <= max route hop count in 'network.rpc.default_route_hop_count <= network.rpc.max_route_hop_count'" "default route hop count must be <= max route hop count in 'network.rpc.default_route_hop_count <= network.rpc.max_route_hop_count'"
); );
} }
if inner.network.rpc.queue_size < 256 { if self.network.rpc.queue_size < 256 {
apibail_generic!("rpc queue size must be >= 256 in 'network.rpc.queue_size'"); apibail_generic!("rpc queue size must be >= 256 in 'network.rpc.queue_size'");
} }
if inner.network.rpc.timeout_ms < 1000 { if self.network.rpc.timeout_ms < 1000 {
apibail_generic!("rpc timeout must be >= 1000 in 'network.rpc.timeout_ms'"); apibail_generic!("rpc timeout must be >= 1000 in 'network.rpc.timeout_ms'");
} }
if inner.network.dht.consensus_width < inner.network.dht.set_value_count { if self.network.dht.consensus_width < self.network.dht.set_value_count {
apibail_generic!( apibail_generic!(
"consensus width must be >= set value count in 'network.dht.consensus_width'" "consensus width must be >= set value count in 'network.dht.consensus_width'"
); );
} }
if inner.network.dht.get_value_count <= (inner.network.dht.set_value_count / 2) { if self.network.dht.get_value_count <= (self.network.dht.set_value_count / 2) {
apibail_generic!("get consensus count must be >= (set value count / 2) in 'network.dht.get_value_count'"); apibail_generic!("get consensus count must be >= (set value count / 2) in 'network.dht.get_value_count'");
} }
if inner.network.dht.get_value_fanout < 1 { if self.network.dht.get_value_fanout < 1 {
apibail_generic!("get value fanout must be >= 1 in 'network.dht.get_value_fanout'"); apibail_generic!("get value fanout must be >= 1 in 'network.dht.get_value_fanout'");
} }
if inner.network.dht.set_value_fanout < 1 { if self.network.dht.set_value_fanout < 1 {
apibail_generic!("set value fanout must be >= 1 in 'network.dht.set_value_fanout'"); apibail_generic!("set value fanout must be >= 1 in 'network.dht.set_value_fanout'");
} }
if inner.network.dht.get_value_timeout_ms < (2 * inner.network.rpc.timeout_ms) { if self.network.dht.get_value_timeout_ms < (2 * self.network.rpc.timeout_ms) {
apibail_generic!("get value timeout must be >= (2 * the rpc timeout) in 'network.dht.get_value_timeout_ms'"); apibail_generic!("get value timeout must be >= (2 * the rpc timeout) in 'network.dht.get_value_timeout_ms'");
} }
if inner.network.dht.set_value_timeout_ms < (2 * inner.network.rpc.timeout_ms) { if self.network.dht.set_value_timeout_ms < (2 * self.network.rpc.timeout_ms) {
apibail_generic!("set value timeout must be >= (2 * the rpc timeout) in 'network.dht.set_value_timeout_ms'"); apibail_generic!("set value timeout must be >= (2 * the rpc timeout) in 'network.dht.set_value_timeout_ms'");
} }
@ -1252,6 +1120,46 @@ impl VeilidStartupOptions {
} }
} }
/// The configuration built for each Veilid node during API startup
#[derive(Clone)]
#[must_use]
pub struct VeilidStartupOptions {
update_cb: UpdateCallback,
config: Arc<VeilidConfig>,
}
impl fmt::Debug for VeilidStartupOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VeilidConfig")
.field("config", self.config.as_ref())
.finish()
}
}
impl VeilidStartupOptions {
pub(crate) fn try_new(
config: VeilidConfig,
update_cb: UpdateCallback,
) -> VeilidAPIResult<Self> {
config.validate()?;
Ok(Self {
update_cb,
config: Arc::new(config),
})
}
#[must_use]
pub fn update_callback(&self) -> UpdateCallback {
self.update_cb.clone()
}
#[must_use]
pub fn config(&self) -> Arc<VeilidConfig> {
self.config.clone()
}
}
/// Return the default veilid config as a json object. /// Return the default veilid config as a json object.
#[must_use] #[must_use]
pub fn default_veilid_config() -> String { pub fn default_veilid_config() -> String {

View file

@ -16,8 +16,7 @@ Future<void> testGetCryptoSystems() async {
const CryptoKind invalidCryptoKind = cryptoKindNONE + 1; const CryptoKind invalidCryptoKind = cryptoKindNONE + 1;
Future<void> testGetCryptoSystemInvalid() async { Future<void> testGetCryptoSystemInvalid() async {
await expectLater( await expectLater(() => Veilid.instance.getCryptoSystem(invalidCryptoKind),
() async => Veilid.instance.getCryptoSystem(invalidCryptoKind),
throwsA(isA<VeilidAPIException>())); throwsA(isA<VeilidAPIException>()));
} }

View file

@ -10,8 +10,8 @@ final bogusKey =
Future<void> testGetDHTValueUnopened() async { Future<void> testGetDHTValueUnopened() async {
final rc = await Veilid.instance.routingContext(); final rc = await Veilid.instance.routingContext();
try { try {
await expectLater(() async => rc.getDHTValue(bogusKey, 0), await expectLater(
throwsA(isA<VeilidAPIException>())); () => rc.getDHTValue(bogusKey, 0), throwsA(isA<VeilidAPIException>()));
} finally { } finally {
rc.close(); rc.close();
} }
@ -20,8 +20,8 @@ Future<void> testGetDHTValueUnopened() async {
Future<void> testOpenDHTRecordNonexistentNoWriter() async { Future<void> testOpenDHTRecordNonexistentNoWriter() async {
final rc = await Veilid.instance.routingContext(); final rc = await Veilid.instance.routingContext();
try { try {
await expectLater(() async => rc.openDHTRecord(bogusKey), await expectLater(
throwsA(isA<VeilidAPIException>())); () => rc.openDHTRecord(bogusKey), throwsA(isA<VeilidAPIException>()));
} finally { } finally {
rc.close(); rc.close();
} }
@ -30,8 +30,8 @@ Future<void> testOpenDHTRecordNonexistentNoWriter() async {
Future<void> testCloseDHTRecordNonexistent() async { Future<void> testCloseDHTRecordNonexistent() async {
final rc = await Veilid.instance.routingContext(); final rc = await Veilid.instance.routingContext();
try { try {
await expectLater(() async => rc.closeDHTRecord(bogusKey), await expectLater(
throwsA(isA<VeilidAPIException>())); () => rc.closeDHTRecord(bogusKey), throwsA(isA<VeilidAPIException>()));
} finally { } finally {
rc.close(); rc.close();
} }
@ -40,8 +40,8 @@ Future<void> testCloseDHTRecordNonexistent() async {
Future<void> testDeleteDHTRecordNonexistent() async { Future<void> testDeleteDHTRecordNonexistent() async {
final rc = await Veilid.instance.routingContext(); final rc = await Veilid.instance.routingContext();
try { try {
await expectLater(() async => rc.deleteDHTRecord(bogusKey), await expectLater(
throwsA(isA<VeilidAPIException>())); () => rc.deleteDHTRecord(bogusKey), throwsA(isA<VeilidAPIException>()));
} finally { } finally {
rc.close(); rc.close();
} }

View file

@ -16,7 +16,7 @@ Future<void> testOpenDeleteTableDb() async {
final tdb = await Veilid.instance.openTableDB(testDb, 1); final tdb = await Veilid.instance.openTableDB(testDb, 1);
try { try {
await expectLater(() async => Veilid.instance.deleteTableDB(testDb), await expectLater(() => Veilid.instance.deleteTableDB(testDb),
throwsA(isA<VeilidAPIException>())); throwsA(isA<VeilidAPIException>()));
} finally { } finally {
tdb.close(); tdb.close();
@ -32,11 +32,11 @@ Future<void> testOpenTwiceTableDb() async {
final tdb2 = await Veilid.instance.openTableDB(testDb, 1); final tdb2 = await Veilid.instance.openTableDB(testDb, 1);
// delete should fail because open // delete should fail because open
await expectLater(() async => Veilid.instance.deleteTableDB(testDb), await expectLater(() => Veilid.instance.deleteTableDB(testDb),
throwsA(isA<VeilidAPIException>())); throwsA(isA<VeilidAPIException>()));
tdb.close(); tdb.close();
// delete should fail because open // delete should fail because open
await expectLater(() async => Veilid.instance.deleteTableDB(testDb), await expectLater(() => Veilid.instance.deleteTableDB(testDb),
throwsA(isA<VeilidAPIException>())); throwsA(isA<VeilidAPIException>()));
tdb2.close(); tdb2.close();
@ -100,7 +100,7 @@ Future<void> testResizeTableDb() async {
final tdb = await Veilid.instance.openTableDB(testDb, 1); final tdb = await Veilid.instance.openTableDB(testDb, 1);
try { try {
// reopen the db with more columns should fail if it is already open // reopen the db with more columns should fail if it is already open
await expectLater(() async => Veilid.instance.openTableDB(testDb, 2), await expectLater(() => Veilid.instance.openTableDB(testDb, 2),
throwsA(isA<VeilidAPIException>())); throwsA(isA<VeilidAPIException>()));
} finally { } finally {
tdb.close(); tdb.close();
@ -115,7 +115,7 @@ Future<void> testResizeTableDb() async {
final tdb3 = await Veilid.instance.openTableDB(testDb, 1); final tdb3 = await Veilid.instance.openTableDB(testDb, 1);
try { try {
// Should fail access to second column // Should fail access to second column
await expectLater(() async => tdb3.load(1, utf8.encode('qwer')), await expectLater(() => tdb3.load(1, utf8.encode('qwer')),
throwsA(isA<VeilidAPIException>())); throwsA(isA<VeilidAPIException>()));
// Should succeed with access to second column // Should succeed with access to second column

View file

@ -634,7 +634,7 @@ packages:
path: ".." path: ".."
relative: true relative: true
source: path source: path
version: "0.4.7" version: "0.4.8"
veilid_test: veilid_test:
dependency: "direct dev" dependency: "direct dev"
description: description:

View file

@ -195,23 +195,23 @@ sealed class VeilidConfigWS with _$VeilidConfigWS {
} }
//////////// ////////////
@Deprecated('WSS is disabled by default in veilid-flutter') // @Deprecated('WSS is disabled by default in veilid-flutter')
@freezed // @freezed
sealed class VeilidConfigWSS with _$VeilidConfigWSS { // sealed class VeilidConfigWSS with _$VeilidConfigWSS {
@Deprecated('WSS is disabled by default in veilid-flutter') // @Deprecated('WSS is disabled by default in veilid-flutter')
const factory VeilidConfigWSS({ // const factory VeilidConfigWSS({
required bool connect, // required bool connect,
required bool listen, // required bool listen,
required int maxConnections, // required int maxConnections,
required String listenAddress, // required String listenAddress,
required String path, // required String path,
String? url, // String? url,
}) = _VeilidConfigWSS; // }) = _VeilidConfigWSS;
@Deprecated('WSS is disabled by default in veilid-flutter') // @Deprecated('WSS is disabled by default in veilid-flutter')
factory VeilidConfigWSS.fromJson(dynamic json) => // factory VeilidConfigWSS.fromJson(dynamic json) =>
_$VeilidConfigWSSFromJson(json as Map<String, dynamic>); // _$VeilidConfigWSSFromJson(json as Map<String, dynamic>);
} // }
//////////// ////////////
@ -221,8 +221,7 @@ sealed class VeilidConfigProtocol with _$VeilidConfigProtocol {
required VeilidConfigUDP udp, required VeilidConfigUDP udp,
required VeilidConfigTCP tcp, required VeilidConfigTCP tcp,
required VeilidConfigWS ws, required VeilidConfigWS ws,
@Deprecated('WSS is disabled by default in veilid-flutter') // required VeilidConfigWSS wss,
required VeilidConfigWSS wss,
}) = _VeilidConfigProtocol; }) = _VeilidConfigProtocol;
factory VeilidConfigProtocol.fromJson(dynamic json) => factory VeilidConfigProtocol.fromJson(dynamic json) =>

View file

@ -3776,294 +3776,10 @@ as String?,
} }
/// @nodoc
mixin _$VeilidConfigWSS implements DiagnosticableTreeMixin {
bool get connect; bool get listen; int get maxConnections; String get listenAddress; String get path; String? get url;
/// Create a copy of VeilidConfigWSS
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
$VeilidConfigWSSCopyWith<VeilidConfigWSS> get copyWith => _$VeilidConfigWSSCopyWithImpl<VeilidConfigWSS>(this as VeilidConfigWSS, _$identity);
/// Serializes this VeilidConfigWSS to a JSON map.
Map<String, dynamic> toJson();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'VeilidConfigWSS'))
..add(DiagnosticsProperty('connect', connect))..add(DiagnosticsProperty('listen', listen))..add(DiagnosticsProperty('maxConnections', maxConnections))..add(DiagnosticsProperty('listenAddress', listenAddress))..add(DiagnosticsProperty('path', path))..add(DiagnosticsProperty('url', url));
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidConfigWSS&&(identical(other.connect, connect) || other.connect == connect)&&(identical(other.listen, listen) || other.listen == listen)&&(identical(other.maxConnections, maxConnections) || other.maxConnections == maxConnections)&&(identical(other.listenAddress, listenAddress) || other.listenAddress == listenAddress)&&(identical(other.path, path) || other.path == path)&&(identical(other.url, url) || other.url == url));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,connect,listen,maxConnections,listenAddress,path,url);
@override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'VeilidConfigWSS(connect: $connect, listen: $listen, maxConnections: $maxConnections, listenAddress: $listenAddress, path: $path, url: $url)';
}
}
/// @nodoc
abstract mixin class $VeilidConfigWSSCopyWith<$Res> {
factory $VeilidConfigWSSCopyWith(VeilidConfigWSS value, $Res Function(VeilidConfigWSS) _then) = _$VeilidConfigWSSCopyWithImpl;
@useResult
$Res call({
bool connect, bool listen, int maxConnections, String listenAddress, String path, String? url
});
}
/// @nodoc
class _$VeilidConfigWSSCopyWithImpl<$Res>
implements $VeilidConfigWSSCopyWith<$Res> {
_$VeilidConfigWSSCopyWithImpl(this._self, this._then);
final VeilidConfigWSS _self;
final $Res Function(VeilidConfigWSS) _then;
/// Create a copy of VeilidConfigWSS
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? connect = null,Object? listen = null,Object? maxConnections = null,Object? listenAddress = null,Object? path = null,Object? url = freezed,}) {
return _then(_self.copyWith(
connect: null == connect ? _self.connect : connect // ignore: cast_nullable_to_non_nullable
as bool,listen: null == listen ? _self.listen : listen // ignore: cast_nullable_to_non_nullable
as bool,maxConnections: null == maxConnections ? _self.maxConnections : maxConnections // ignore: cast_nullable_to_non_nullable
as int,listenAddress: null == listenAddress ? _self.listenAddress : listenAddress // ignore: cast_nullable_to_non_nullable
as String,path: null == path ? _self.path : path // ignore: cast_nullable_to_non_nullable
as String,url: freezed == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// Adds pattern-matching-related methods to [VeilidConfigWSS].
extension VeilidConfigWSSPatterns on VeilidConfigWSS {
/// A variant of `map` that fallback to returning `orElse`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _VeilidConfigWSS value)? $default,{required TResult orElse(),}){
final _that = this;
switch (_that) {
case _VeilidConfigWSS() when $default != null:
return $default(_that);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// Callbacks receives the raw object, upcasted.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case final Subclass2 value:
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _VeilidConfigWSS value) $default,){
final _that = this;
switch (_that) {
case _VeilidConfigWSS():
return $default(_that);}
}
/// A variant of `map` that fallback to returning `null`.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case final Subclass value:
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _VeilidConfigWSS value)? $default,){
final _that = this;
switch (_that) {
case _VeilidConfigWSS() when $default != null:
return $default(_that);case _:
return null;
}
}
/// A variant of `when` that fallback to an `orElse` callback.
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return orElse();
/// }
/// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( bool connect, bool listen, int maxConnections, String listenAddress, String path, String? url)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) {
case _VeilidConfigWSS() when $default != null:
return $default(_that.connect,_that.listen,_that.maxConnections,_that.listenAddress,_that.path,_that.url);case _:
return orElse();
}
}
/// A `switch`-like method, using callbacks.
///
/// As opposed to `map`, this offers destructuring.
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case Subclass2(:final field2):
/// return ...;
/// }
/// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( bool connect, bool listen, int maxConnections, String listenAddress, String path, String? url) $default,) {final _that = this;
switch (_that) {
case _VeilidConfigWSS():
return $default(_that.connect,_that.listen,_that.maxConnections,_that.listenAddress,_that.path,_that.url);}
}
/// A variant of `when` that fallback to returning `null`
///
/// It is equivalent to doing:
/// ```dart
/// switch (sealedClass) {
/// case Subclass(:final field):
/// return ...;
/// case _:
/// return null;
/// }
/// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( bool connect, bool listen, int maxConnections, String listenAddress, String path, String? url)? $default,) {final _that = this;
switch (_that) {
case _VeilidConfigWSS() when $default != null:
return $default(_that.connect,_that.listen,_that.maxConnections,_that.listenAddress,_that.path,_that.url);case _:
return null;
}
}
}
/// @nodoc
@JsonSerializable()
@Deprecated('WSS is disabled by default in veilid-flutter')
class _VeilidConfigWSS with DiagnosticableTreeMixin implements VeilidConfigWSS {
const _VeilidConfigWSS({required this.connect, required this.listen, required this.maxConnections, required this.listenAddress, required this.path, this.url});
factory _VeilidConfigWSS.fromJson(Map<String, dynamic> json) => _$VeilidConfigWSSFromJson(json);
@override final bool connect;
@override final bool listen;
@override final int maxConnections;
@override final String listenAddress;
@override final String path;
@override final String? url;
/// Create a copy of VeilidConfigWSS
/// with the given fields replaced by the non-null parameter values.
@override @JsonKey(includeFromJson: false, includeToJson: false)
@pragma('vm:prefer-inline')
_$VeilidConfigWSSCopyWith<_VeilidConfigWSS> get copyWith => __$VeilidConfigWSSCopyWithImpl<_VeilidConfigWSS>(this, _$identity);
@override
Map<String, dynamic> toJson() {
return _$VeilidConfigWSSToJson(this, );
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties
..add(DiagnosticsProperty('type', 'VeilidConfigWSS'))
..add(DiagnosticsProperty('connect', connect))..add(DiagnosticsProperty('listen', listen))..add(DiagnosticsProperty('maxConnections', maxConnections))..add(DiagnosticsProperty('listenAddress', listenAddress))..add(DiagnosticsProperty('path', path))..add(DiagnosticsProperty('url', url));
}
@override
bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VeilidConfigWSS&&(identical(other.connect, connect) || other.connect == connect)&&(identical(other.listen, listen) || other.listen == listen)&&(identical(other.maxConnections, maxConnections) || other.maxConnections == maxConnections)&&(identical(other.listenAddress, listenAddress) || other.listenAddress == listenAddress)&&(identical(other.path, path) || other.path == path)&&(identical(other.url, url) || other.url == url));
}
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType,connect,listen,maxConnections,listenAddress,path,url);
@override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'VeilidConfigWSS(connect: $connect, listen: $listen, maxConnections: $maxConnections, listenAddress: $listenAddress, path: $path, url: $url)';
}
}
/// @nodoc
abstract mixin class _$VeilidConfigWSSCopyWith<$Res> implements $VeilidConfigWSSCopyWith<$Res> {
factory _$VeilidConfigWSSCopyWith(_VeilidConfigWSS value, $Res Function(_VeilidConfigWSS) _then) = __$VeilidConfigWSSCopyWithImpl;
@override @useResult
$Res call({
bool connect, bool listen, int maxConnections, String listenAddress, String path, String? url
});
}
/// @nodoc
class __$VeilidConfigWSSCopyWithImpl<$Res>
implements _$VeilidConfigWSSCopyWith<$Res> {
__$VeilidConfigWSSCopyWithImpl(this._self, this._then);
final _VeilidConfigWSS _self;
final $Res Function(_VeilidConfigWSS) _then;
/// Create a copy of VeilidConfigWSS
/// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? connect = null,Object? listen = null,Object? maxConnections = null,Object? listenAddress = null,Object? path = null,Object? url = freezed,}) {
return _then(_VeilidConfigWSS(
connect: null == connect ? _self.connect : connect // ignore: cast_nullable_to_non_nullable
as bool,listen: null == listen ? _self.listen : listen // ignore: cast_nullable_to_non_nullable
as bool,maxConnections: null == maxConnections ? _self.maxConnections : maxConnections // ignore: cast_nullable_to_non_nullable
as int,listenAddress: null == listenAddress ? _self.listenAddress : listenAddress // ignore: cast_nullable_to_non_nullable
as String,path: null == path ? _self.path : path // ignore: cast_nullable_to_non_nullable
as String,url: freezed == url ? _self.url : url // ignore: cast_nullable_to_non_nullable
as String?,
));
}
}
/// @nodoc /// @nodoc
mixin _$VeilidConfigProtocol implements DiagnosticableTreeMixin { mixin _$VeilidConfigProtocol implements DiagnosticableTreeMixin {
VeilidConfigUDP get udp; VeilidConfigTCP get tcp; VeilidConfigWS get ws;@Deprecated('WSS is disabled by default in veilid-flutter') VeilidConfigWSS get wss; VeilidConfigUDP get udp; VeilidConfigTCP get tcp; VeilidConfigWS get ws;
/// Create a copy of VeilidConfigProtocol /// Create a copy of VeilidConfigProtocol
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@ -4077,21 +3793,21 @@ $VeilidConfigProtocolCopyWith<VeilidConfigProtocol> get copyWith => _$VeilidConf
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties properties
..add(DiagnosticsProperty('type', 'VeilidConfigProtocol')) ..add(DiagnosticsProperty('type', 'VeilidConfigProtocol'))
..add(DiagnosticsProperty('udp', udp))..add(DiagnosticsProperty('tcp', tcp))..add(DiagnosticsProperty('ws', ws))..add(DiagnosticsProperty('wss', wss)); ..add(DiagnosticsProperty('udp', udp))..add(DiagnosticsProperty('tcp', tcp))..add(DiagnosticsProperty('ws', ws));
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidConfigProtocol&&(identical(other.udp, udp) || other.udp == udp)&&(identical(other.tcp, tcp) || other.tcp == tcp)&&(identical(other.ws, ws) || other.ws == ws)&&(identical(other.wss, wss) || other.wss == wss)); return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidConfigProtocol&&(identical(other.udp, udp) || other.udp == udp)&&(identical(other.tcp, tcp) || other.tcp == tcp)&&(identical(other.ws, ws) || other.ws == ws));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@override @override
int get hashCode => Object.hash(runtimeType,udp,tcp,ws,wss); int get hashCode => Object.hash(runtimeType,udp,tcp,ws);
@override @override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'VeilidConfigProtocol(udp: $udp, tcp: $tcp, ws: $ws, wss: $wss)'; return 'VeilidConfigProtocol(udp: $udp, tcp: $tcp, ws: $ws)';
} }
@ -4102,11 +3818,11 @@ abstract mixin class $VeilidConfigProtocolCopyWith<$Res> {
factory $VeilidConfigProtocolCopyWith(VeilidConfigProtocol value, $Res Function(VeilidConfigProtocol) _then) = _$VeilidConfigProtocolCopyWithImpl; factory $VeilidConfigProtocolCopyWith(VeilidConfigProtocol value, $Res Function(VeilidConfigProtocol) _then) = _$VeilidConfigProtocolCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws,@Deprecated('WSS is disabled by default in veilid-flutter') VeilidConfigWSS wss VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws
}); });
$VeilidConfigUDPCopyWith<$Res> get udp;$VeilidConfigTCPCopyWith<$Res> get tcp;$VeilidConfigWSCopyWith<$Res> get ws;$VeilidConfigWSSCopyWith<$Res> get wss; $VeilidConfigUDPCopyWith<$Res> get udp;$VeilidConfigTCPCopyWith<$Res> get tcp;$VeilidConfigWSCopyWith<$Res> get ws;
} }
/// @nodoc /// @nodoc
@ -4119,13 +3835,12 @@ class _$VeilidConfigProtocolCopyWithImpl<$Res>
/// Create a copy of VeilidConfigProtocol /// Create a copy of VeilidConfigProtocol
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @override $Res call({Object? udp = null,Object? tcp = null,Object? ws = null,Object? wss = null,}) { @pragma('vm:prefer-inline') @override $Res call({Object? udp = null,Object? tcp = null,Object? ws = null,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
udp: null == udp ? _self.udp : udp // ignore: cast_nullable_to_non_nullable udp: null == udp ? _self.udp : udp // ignore: cast_nullable_to_non_nullable
as VeilidConfigUDP,tcp: null == tcp ? _self.tcp : tcp // ignore: cast_nullable_to_non_nullable as VeilidConfigUDP,tcp: null == tcp ? _self.tcp : tcp // ignore: cast_nullable_to_non_nullable
as VeilidConfigTCP,ws: null == ws ? _self.ws : ws // ignore: cast_nullable_to_non_nullable as VeilidConfigTCP,ws: null == ws ? _self.ws : ws // ignore: cast_nullable_to_non_nullable
as VeilidConfigWS,wss: null == wss ? _self.wss : wss // ignore: cast_nullable_to_non_nullable as VeilidConfigWS,
as VeilidConfigWSS,
)); ));
} }
/// Create a copy of VeilidConfigProtocol /// Create a copy of VeilidConfigProtocol
@ -4155,15 +3870,6 @@ $VeilidConfigWSCopyWith<$Res> get ws {
return $VeilidConfigWSCopyWith<$Res>(_self.ws, (value) { return $VeilidConfigWSCopyWith<$Res>(_self.ws, (value) {
return _then(_self.copyWith(ws: value)); return _then(_self.copyWith(ws: value));
}); });
}/// Create a copy of VeilidConfigProtocol
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$VeilidConfigWSSCopyWith<$Res> get wss {
return $VeilidConfigWSSCopyWith<$Res>(_self.wss, (value) {
return _then(_self.copyWith(wss: value));
});
} }
} }
@ -4243,10 +3949,10 @@ return $default(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws, @Deprecated('WSS is disabled by default in veilid-flutter') VeilidConfigWSS wss)? $default,{required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case _VeilidConfigProtocol() when $default != null: case _VeilidConfigProtocol() when $default != null:
return $default(_that.udp,_that.tcp,_that.ws,_that.wss);case _: return $default(_that.udp,_that.tcp,_that.ws);case _:
return orElse(); return orElse();
} }
@ -4264,10 +3970,10 @@ return $default(_that.udp,_that.tcp,_that.ws,_that.wss);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws, @Deprecated('WSS is disabled by default in veilid-flutter') VeilidConfigWSS wss) $default,) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws) $default,) {final _that = this;
switch (_that) { switch (_that) {
case _VeilidConfigProtocol(): case _VeilidConfigProtocol():
return $default(_that.udp,_that.tcp,_that.ws,_that.wss);} return $default(_that.udp,_that.tcp,_that.ws);}
} }
/// A variant of `when` that fallback to returning `null` /// A variant of `when` that fallback to returning `null`
/// ///
@ -4281,10 +3987,10 @@ return $default(_that.udp,_that.tcp,_that.ws,_that.wss);}
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws, @Deprecated('WSS is disabled by default in veilid-flutter') VeilidConfigWSS wss)? $default,) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws)? $default,) {final _that = this;
switch (_that) { switch (_that) {
case _VeilidConfigProtocol() when $default != null: case _VeilidConfigProtocol() when $default != null:
return $default(_that.udp,_that.tcp,_that.ws,_that.wss);case _: return $default(_that.udp,_that.tcp,_that.ws);case _:
return null; return null;
} }
@ -4296,13 +4002,12 @@ return $default(_that.udp,_that.tcp,_that.ws,_that.wss);case _:
@JsonSerializable() @JsonSerializable()
class _VeilidConfigProtocol with DiagnosticableTreeMixin implements VeilidConfigProtocol { class _VeilidConfigProtocol with DiagnosticableTreeMixin implements VeilidConfigProtocol {
const _VeilidConfigProtocol({required this.udp, required this.tcp, required this.ws, @Deprecated('WSS is disabled by default in veilid-flutter') required this.wss}); const _VeilidConfigProtocol({required this.udp, required this.tcp, required this.ws});
factory _VeilidConfigProtocol.fromJson(Map<String, dynamic> json) => _$VeilidConfigProtocolFromJson(json); factory _VeilidConfigProtocol.fromJson(Map<String, dynamic> json) => _$VeilidConfigProtocolFromJson(json);
@override final VeilidConfigUDP udp; @override final VeilidConfigUDP udp;
@override final VeilidConfigTCP tcp; @override final VeilidConfigTCP tcp;
@override final VeilidConfigWS ws; @override final VeilidConfigWS ws;
@override@Deprecated('WSS is disabled by default in veilid-flutter') final VeilidConfigWSS wss;
/// Create a copy of VeilidConfigProtocol /// Create a copy of VeilidConfigProtocol
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@ -4318,21 +4023,21 @@ Map<String, dynamic> toJson() {
void debugFillProperties(DiagnosticPropertiesBuilder properties) { void debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties properties
..add(DiagnosticsProperty('type', 'VeilidConfigProtocol')) ..add(DiagnosticsProperty('type', 'VeilidConfigProtocol'))
..add(DiagnosticsProperty('udp', udp))..add(DiagnosticsProperty('tcp', tcp))..add(DiagnosticsProperty('ws', ws))..add(DiagnosticsProperty('wss', wss)); ..add(DiagnosticsProperty('udp', udp))..add(DiagnosticsProperty('tcp', tcp))..add(DiagnosticsProperty('ws', ws));
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is _VeilidConfigProtocol&&(identical(other.udp, udp) || other.udp == udp)&&(identical(other.tcp, tcp) || other.tcp == tcp)&&(identical(other.ws, ws) || other.ws == ws)&&(identical(other.wss, wss) || other.wss == wss)); return identical(this, other) || (other.runtimeType == runtimeType&&other is _VeilidConfigProtocol&&(identical(other.udp, udp) || other.udp == udp)&&(identical(other.tcp, tcp) || other.tcp == tcp)&&(identical(other.ws, ws) || other.ws == ws));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@override @override
int get hashCode => Object.hash(runtimeType,udp,tcp,ws,wss); int get hashCode => Object.hash(runtimeType,udp,tcp,ws);
@override @override
String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) { String toString({ DiagnosticLevel minLevel = DiagnosticLevel.info }) {
return 'VeilidConfigProtocol(udp: $udp, tcp: $tcp, ws: $ws, wss: $wss)'; return 'VeilidConfigProtocol(udp: $udp, tcp: $tcp, ws: $ws)';
} }
@ -4343,11 +4048,11 @@ abstract mixin class _$VeilidConfigProtocolCopyWith<$Res> implements $VeilidConf
factory _$VeilidConfigProtocolCopyWith(_VeilidConfigProtocol value, $Res Function(_VeilidConfigProtocol) _then) = __$VeilidConfigProtocolCopyWithImpl; factory _$VeilidConfigProtocolCopyWith(_VeilidConfigProtocol value, $Res Function(_VeilidConfigProtocol) _then) = __$VeilidConfigProtocolCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws,@Deprecated('WSS is disabled by default in veilid-flutter') VeilidConfigWSS wss VeilidConfigUDP udp, VeilidConfigTCP tcp, VeilidConfigWS ws
}); });
@override $VeilidConfigUDPCopyWith<$Res> get udp;@override $VeilidConfigTCPCopyWith<$Res> get tcp;@override $VeilidConfigWSCopyWith<$Res> get ws;@override $VeilidConfigWSSCopyWith<$Res> get wss; @override $VeilidConfigUDPCopyWith<$Res> get udp;@override $VeilidConfigTCPCopyWith<$Res> get tcp;@override $VeilidConfigWSCopyWith<$Res> get ws;
} }
/// @nodoc /// @nodoc
@ -4360,13 +4065,12 @@ class __$VeilidConfigProtocolCopyWithImpl<$Res>
/// Create a copy of VeilidConfigProtocol /// Create a copy of VeilidConfigProtocol
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@override @pragma('vm:prefer-inline') $Res call({Object? udp = null,Object? tcp = null,Object? ws = null,Object? wss = null,}) { @override @pragma('vm:prefer-inline') $Res call({Object? udp = null,Object? tcp = null,Object? ws = null,}) {
return _then(_VeilidConfigProtocol( return _then(_VeilidConfigProtocol(
udp: null == udp ? _self.udp : udp // ignore: cast_nullable_to_non_nullable udp: null == udp ? _self.udp : udp // ignore: cast_nullable_to_non_nullable
as VeilidConfigUDP,tcp: null == tcp ? _self.tcp : tcp // ignore: cast_nullable_to_non_nullable as VeilidConfigUDP,tcp: null == tcp ? _self.tcp : tcp // ignore: cast_nullable_to_non_nullable
as VeilidConfigTCP,ws: null == ws ? _self.ws : ws // ignore: cast_nullable_to_non_nullable as VeilidConfigTCP,ws: null == ws ? _self.ws : ws // ignore: cast_nullable_to_non_nullable
as VeilidConfigWS,wss: null == wss ? _self.wss : wss // ignore: cast_nullable_to_non_nullable as VeilidConfigWS,
as VeilidConfigWSS,
)); ));
} }
@ -4397,15 +4101,6 @@ $VeilidConfigWSCopyWith<$Res> get ws {
return $VeilidConfigWSCopyWith<$Res>(_self.ws, (value) { return $VeilidConfigWSCopyWith<$Res>(_self.ws, (value) {
return _then(_self.copyWith(ws: value)); return _then(_self.copyWith(ws: value));
}); });
}/// Create a copy of VeilidConfigProtocol
/// with the given fields replaced by the non-null parameter values.
@override
@pragma('vm:prefer-inline')
$VeilidConfigWSSCopyWith<$Res> get wss {
return $VeilidConfigWSSCopyWith<$Res>(_self.wss, (value) {
return _then(_self.copyWith(wss: value));
});
} }
} }

View file

@ -225,33 +225,12 @@ Map<String, dynamic> _$VeilidConfigWSToJson(_VeilidConfigWS instance) =>
'url': instance.url, 'url': instance.url,
}; };
_VeilidConfigWSS _$VeilidConfigWSSFromJson(Map<String, dynamic> json) =>
_VeilidConfigWSS(
connect: json['connect'] as bool,
listen: json['listen'] as bool,
maxConnections: (json['max_connections'] as num).toInt(),
listenAddress: json['listen_address'] as String,
path: json['path'] as String,
url: json['url'] as String?,
);
Map<String, dynamic> _$VeilidConfigWSSToJson(_VeilidConfigWSS instance) =>
<String, dynamic>{
'connect': instance.connect,
'listen': instance.listen,
'max_connections': instance.maxConnections,
'listen_address': instance.listenAddress,
'path': instance.path,
'url': instance.url,
};
_VeilidConfigProtocol _$VeilidConfigProtocolFromJson( _VeilidConfigProtocol _$VeilidConfigProtocolFromJson(
Map<String, dynamic> json, Map<String, dynamic> json,
) => _VeilidConfigProtocol( ) => _VeilidConfigProtocol(
udp: VeilidConfigUDP.fromJson(json['udp']), udp: VeilidConfigUDP.fromJson(json['udp']),
tcp: VeilidConfigTCP.fromJson(json['tcp']), tcp: VeilidConfigTCP.fromJson(json['tcp']),
ws: VeilidConfigWS.fromJson(json['ws']), ws: VeilidConfigWS.fromJson(json['ws']),
wss: VeilidConfigWSS.fromJson(json['wss']),
); );
Map<String, dynamic> _$VeilidConfigProtocolToJson( Map<String, dynamic> _$VeilidConfigProtocolToJson(
@ -260,7 +239,6 @@ Map<String, dynamic> _$VeilidConfigProtocolToJson(
'udp': instance.udp.toJson(), 'udp': instance.udp.toJson(),
'tcp': instance.tcp.toJson(), 'tcp': instance.tcp.toJson(),
'ws': instance.ws.toJson(), 'ws': instance.ws.toJson(),
'wss': instance.wss.toJson(),
}; };
_VeilidConfigPrivacy _$VeilidConfigPrivacyFromJson(Map<String, dynamic> json) => _VeilidConfigPrivacy _$VeilidConfigPrivacyFromJson(Map<String, dynamic> json) =>

View file

@ -188,7 +188,7 @@ sealed class PeerStats with _$PeerStats {
@freezed @freezed
sealed class PeerTableData with _$PeerTableData { sealed class PeerTableData with _$PeerTableData {
const factory PeerTableData({ const factory PeerTableData({
required List<PublicKey> nodeIds, required List<NodeId> nodeIds,
required String peerAddress, required String peerAddress,
required PeerStats peerStats, required PeerStats peerStats,
}) = _PeerTableData; }) = _PeerTableData;
@ -218,20 +218,22 @@ sealed class VeilidUpdate with _$VeilidUpdate {
PublicKey? sender, PublicKey? sender,
String? routeId, String? routeId,
}) = VeilidAppCall; }) = VeilidAppCall;
const factory VeilidUpdate.attachment( const factory VeilidUpdate.attachment({
{required AttachmentState state, required AttachmentState state,
required bool publicInternetReady, required bool publicInternetReady,
required bool localNetworkReady, required bool localNetworkReady,
required TimestampDuration uptime, required TimestampDuration uptime,
required TimestampDuration? attachedUptime}) = VeilidUpdateAttachment; required TimestampDuration? attachedUptime,
const factory VeilidUpdate.network( }) = VeilidUpdateAttachment;
{required bool started, const factory VeilidUpdate.network({
required BigInt bpsDown, required bool started,
required BigInt bpsUp, required BigInt bpsDown,
required List<PeerTableData> peers}) = VeilidUpdateNetwork; required BigInt bpsUp,
const factory VeilidUpdate.config({ required List<PeerTableData> peers,
required VeilidConfig config, required List<NodeId> nodeIds,
}) = VeilidUpdateConfig; }) = VeilidUpdateNetwork;
const factory VeilidUpdate.config({required VeilidConfig config}) =
VeilidUpdateConfig;
const factory VeilidUpdate.routeChange({ const factory VeilidUpdate.routeChange({
required List<String> deadRoutes, required List<String> deadRoutes,
required List<String> deadRemoteRoutes, required List<String> deadRemoteRoutes,
@ -252,12 +254,13 @@ sealed class VeilidUpdate with _$VeilidUpdate {
@freezed @freezed
sealed class VeilidStateAttachment with _$VeilidStateAttachment { sealed class VeilidStateAttachment with _$VeilidStateAttachment {
const factory VeilidStateAttachment( const factory VeilidStateAttachment({
{required AttachmentState state, required AttachmentState state,
required bool publicInternetReady, required bool publicInternetReady,
required bool localNetworkReady, required bool localNetworkReady,
required TimestampDuration uptime, required TimestampDuration uptime,
required TimestampDuration? attachedUptime}) = _VeilidStateAttachment; required TimestampDuration? attachedUptime,
}) = _VeilidStateAttachment;
factory VeilidStateAttachment.fromJson(dynamic json) => factory VeilidStateAttachment.fromJson(dynamic json) =>
_$VeilidStateAttachmentFromJson(json as Map<String, dynamic>); _$VeilidStateAttachmentFromJson(json as Map<String, dynamic>);
@ -268,11 +271,12 @@ sealed class VeilidStateAttachment with _$VeilidStateAttachment {
@freezed @freezed
sealed class VeilidStateNetwork with _$VeilidStateNetwork { sealed class VeilidStateNetwork with _$VeilidStateNetwork {
const factory VeilidStateNetwork( const factory VeilidStateNetwork({
{required bool started, required bool started,
required BigInt bpsDown, required BigInt bpsDown,
required BigInt bpsUp, required BigInt bpsUp,
required List<PeerTableData> peers}) = _VeilidStateNetwork; required List<PeerTableData> peers,
}) = _VeilidStateNetwork;
factory VeilidStateNetwork.fromJson(dynamic json) => factory VeilidStateNetwork.fromJson(dynamic json) =>
_$VeilidStateNetworkFromJson(json as Map<String, dynamic>); _$VeilidStateNetworkFromJson(json as Map<String, dynamic>);
@ -283,9 +287,8 @@ sealed class VeilidStateNetwork with _$VeilidStateNetwork {
@freezed @freezed
sealed class VeilidStateConfig with _$VeilidStateConfig { sealed class VeilidStateConfig with _$VeilidStateConfig {
const factory VeilidStateConfig({ const factory VeilidStateConfig({required VeilidConfig config}) =
required VeilidConfig config, _VeilidStateConfig;
}) = _VeilidStateConfig;
factory VeilidStateConfig.fromJson(dynamic json) => factory VeilidStateConfig.fromJson(dynamic json) =>
_$VeilidStateConfigFromJson(json as Map<String, dynamic>); _$VeilidStateConfigFromJson(json as Map<String, dynamic>);

View file

@ -2371,7 +2371,7 @@ $LatencyStatsCopyWith<$Res>? get latency {
/// @nodoc /// @nodoc
mixin _$PeerTableData { mixin _$PeerTableData {
List<PublicKey> get nodeIds; String get peerAddress; PeerStats get peerStats; List<NodeId> get nodeIds; String get peerAddress; PeerStats get peerStats;
/// Create a copy of PeerTableData /// Create a copy of PeerTableData
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@ -2404,7 +2404,7 @@ abstract mixin class $PeerTableDataCopyWith<$Res> {
factory $PeerTableDataCopyWith(PeerTableData value, $Res Function(PeerTableData) _then) = _$PeerTableDataCopyWithImpl; factory $PeerTableDataCopyWith(PeerTableData value, $Res Function(PeerTableData) _then) = _$PeerTableDataCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
List<PublicKey> nodeIds, String peerAddress, PeerStats peerStats List<NodeId> nodeIds, String peerAddress, PeerStats peerStats
}); });
@ -2424,7 +2424,7 @@ class _$PeerTableDataCopyWithImpl<$Res>
@pragma('vm:prefer-inline') @override $Res call({Object? nodeIds = null,Object? peerAddress = null,Object? peerStats = null,}) { @pragma('vm:prefer-inline') @override $Res call({Object? nodeIds = null,Object? peerAddress = null,Object? peerStats = null,}) {
return _then(_self.copyWith( return _then(_self.copyWith(
nodeIds: null == nodeIds ? _self.nodeIds : nodeIds // ignore: cast_nullable_to_non_nullable nodeIds: null == nodeIds ? _self.nodeIds : nodeIds // ignore: cast_nullable_to_non_nullable
as List<PublicKey>,peerAddress: null == peerAddress ? _self.peerAddress : peerAddress // ignore: cast_nullable_to_non_nullable as List<NodeId>,peerAddress: null == peerAddress ? _self.peerAddress : peerAddress // ignore: cast_nullable_to_non_nullable
as String,peerStats: null == peerStats ? _self.peerStats : peerStats // ignore: cast_nullable_to_non_nullable as String,peerStats: null == peerStats ? _self.peerStats : peerStats // ignore: cast_nullable_to_non_nullable
as PeerStats, as PeerStats,
)); ));
@ -2517,7 +2517,7 @@ return $default(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<PublicKey> nodeIds, String peerAddress, PeerStats peerStats)? $default,{required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( List<NodeId> nodeIds, String peerAddress, PeerStats peerStats)? $default,{required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case _PeerTableData() when $default != null: case _PeerTableData() when $default != null:
return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);case _: return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);case _:
@ -2538,7 +2538,7 @@ return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<PublicKey> nodeIds, String peerAddress, PeerStats peerStats) $default,) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( List<NodeId> nodeIds, String peerAddress, PeerStats peerStats) $default,) {final _that = this;
switch (_that) { switch (_that) {
case _PeerTableData(): case _PeerTableData():
return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);} return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);}
@ -2555,7 +2555,7 @@ return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);}
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<PublicKey> nodeIds, String peerAddress, PeerStats peerStats)? $default,) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( List<NodeId> nodeIds, String peerAddress, PeerStats peerStats)? $default,) {final _that = this;
switch (_that) { switch (_that) {
case _PeerTableData() when $default != null: case _PeerTableData() when $default != null:
return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);case _: return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);case _:
@ -2570,11 +2570,11 @@ return $default(_that.nodeIds,_that.peerAddress,_that.peerStats);case _:
@JsonSerializable() @JsonSerializable()
class _PeerTableData implements PeerTableData { class _PeerTableData implements PeerTableData {
const _PeerTableData({required final List<PublicKey> nodeIds, required this.peerAddress, required this.peerStats}): _nodeIds = nodeIds; const _PeerTableData({required final List<NodeId> nodeIds, required this.peerAddress, required this.peerStats}): _nodeIds = nodeIds;
factory _PeerTableData.fromJson(Map<String, dynamic> json) => _$PeerTableDataFromJson(json); factory _PeerTableData.fromJson(Map<String, dynamic> json) => _$PeerTableDataFromJson(json);
final List<PublicKey> _nodeIds; final List<NodeId> _nodeIds;
@override List<PublicKey> get nodeIds { @override List<NodeId> get nodeIds {
if (_nodeIds is EqualUnmodifiableListView) return _nodeIds; if (_nodeIds is EqualUnmodifiableListView) return _nodeIds;
// ignore: implicit_dynamic_type // ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_nodeIds); return EqualUnmodifiableListView(_nodeIds);
@ -2616,7 +2616,7 @@ abstract mixin class _$PeerTableDataCopyWith<$Res> implements $PeerTableDataCopy
factory _$PeerTableDataCopyWith(_PeerTableData value, $Res Function(_PeerTableData) _then) = __$PeerTableDataCopyWithImpl; factory _$PeerTableDataCopyWith(_PeerTableData value, $Res Function(_PeerTableData) _then) = __$PeerTableDataCopyWithImpl;
@override @useResult @override @useResult
$Res call({ $Res call({
List<PublicKey> nodeIds, String peerAddress, PeerStats peerStats List<NodeId> nodeIds, String peerAddress, PeerStats peerStats
}); });
@ -2636,7 +2636,7 @@ class __$PeerTableDataCopyWithImpl<$Res>
@override @pragma('vm:prefer-inline') $Res call({Object? nodeIds = null,Object? peerAddress = null,Object? peerStats = null,}) { @override @pragma('vm:prefer-inline') $Res call({Object? nodeIds = null,Object? peerAddress = null,Object? peerStats = null,}) {
return _then(_PeerTableData( return _then(_PeerTableData(
nodeIds: null == nodeIds ? _self._nodeIds : nodeIds // ignore: cast_nullable_to_non_nullable nodeIds: null == nodeIds ? _self._nodeIds : nodeIds // ignore: cast_nullable_to_non_nullable
as List<PublicKey>,peerAddress: null == peerAddress ? _self.peerAddress : peerAddress // ignore: cast_nullable_to_non_nullable as List<NodeId>,peerAddress: null == peerAddress ? _self.peerAddress : peerAddress // ignore: cast_nullable_to_non_nullable
as String,peerStats: null == peerStats ? _self.peerStats : peerStats // ignore: cast_nullable_to_non_nullable as String,peerStats: null == peerStats ? _self.peerStats : peerStats // ignore: cast_nullable_to_non_nullable
as PeerStats, as PeerStats,
)); ));
@ -2830,14 +2830,14 @@ return valueChange(_that);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( VeilidLogLevel logLevel, String message, String? backtrace)? log,TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, PublicKey? sender, String? routeId)? appMessage,TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, String callId, PublicKey? sender, String? routeId)? appCall,TResult Function( AttachmentState state, bool publicInternetReady, bool localNetworkReady, TimestampDuration uptime, TimestampDuration? attachedUptime)? attachment,TResult Function( bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers)? network,TResult Function( VeilidConfig config)? config,TResult Function( List<String> deadRoutes, List<String> deadRemoteRoutes)? routeChange,TResult Function( RecordKey key, List<ValueSubkeyRange> subkeys, int count, ValueData? value)? valueChange,required TResult orElse(),}) {final _that = this; @optionalTypeArgs TResult maybeWhen<TResult extends Object?>({TResult Function( VeilidLogLevel logLevel, String message, String? backtrace)? log,TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, PublicKey? sender, String? routeId)? appMessage,TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, String callId, PublicKey? sender, String? routeId)? appCall,TResult Function( AttachmentState state, bool publicInternetReady, bool localNetworkReady, TimestampDuration uptime, TimestampDuration? attachedUptime)? attachment,TResult Function( bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers, List<NodeId> nodeIds)? network,TResult Function( VeilidConfig config)? config,TResult Function( List<String> deadRoutes, List<String> deadRemoteRoutes)? routeChange,TResult Function( RecordKey key, List<ValueSubkeyRange> subkeys, int count, ValueData? value)? valueChange,required TResult orElse(),}) {final _that = this;
switch (_that) { switch (_that) {
case VeilidLog() when log != null: case VeilidLog() when log != null:
return log(_that.logLevel,_that.message,_that.backtrace);case VeilidAppMessage() when appMessage != null: return log(_that.logLevel,_that.message,_that.backtrace);case VeilidAppMessage() when appMessage != null:
return appMessage(_that.message,_that.sender,_that.routeId);case VeilidAppCall() when appCall != null: return appMessage(_that.message,_that.sender,_that.routeId);case VeilidAppCall() when appCall != null:
return appCall(_that.message,_that.callId,_that.sender,_that.routeId);case VeilidUpdateAttachment() when attachment != null: return appCall(_that.message,_that.callId,_that.sender,_that.routeId);case VeilidUpdateAttachment() when attachment != null:
return attachment(_that.state,_that.publicInternetReady,_that.localNetworkReady,_that.uptime,_that.attachedUptime);case VeilidUpdateNetwork() when network != null: return attachment(_that.state,_that.publicInternetReady,_that.localNetworkReady,_that.uptime,_that.attachedUptime);case VeilidUpdateNetwork() when network != null:
return network(_that.started,_that.bpsDown,_that.bpsUp,_that.peers);case VeilidUpdateConfig() when config != null: return network(_that.started,_that.bpsDown,_that.bpsUp,_that.peers,_that.nodeIds);case VeilidUpdateConfig() when config != null:
return config(_that.config);case VeilidUpdateRouteChange() when routeChange != null: return config(_that.config);case VeilidUpdateRouteChange() when routeChange != null:
return routeChange(_that.deadRoutes,_that.deadRemoteRoutes);case VeilidUpdateValueChange() when valueChange != null: return routeChange(_that.deadRoutes,_that.deadRemoteRoutes);case VeilidUpdateValueChange() when valueChange != null:
return valueChange(_that.key,_that.subkeys,_that.count,_that.value);case _: return valueChange(_that.key,_that.subkeys,_that.count,_that.value);case _:
@ -2858,14 +2858,14 @@ return valueChange(_that.key,_that.subkeys,_that.count,_that.value);case _:
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( VeilidLogLevel logLevel, String message, String? backtrace) log,required TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, PublicKey? sender, String? routeId) appMessage,required TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, String callId, PublicKey? sender, String? routeId) appCall,required TResult Function( AttachmentState state, bool publicInternetReady, bool localNetworkReady, TimestampDuration uptime, TimestampDuration? attachedUptime) attachment,required TResult Function( bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers) network,required TResult Function( VeilidConfig config) config,required TResult Function( List<String> deadRoutes, List<String> deadRemoteRoutes) routeChange,required TResult Function( RecordKey key, List<ValueSubkeyRange> subkeys, int count, ValueData? value) valueChange,}) {final _that = this; @optionalTypeArgs TResult when<TResult extends Object?>({required TResult Function( VeilidLogLevel logLevel, String message, String? backtrace) log,required TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, PublicKey? sender, String? routeId) appMessage,required TResult Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, String callId, PublicKey? sender, String? routeId) appCall,required TResult Function( AttachmentState state, bool publicInternetReady, bool localNetworkReady, TimestampDuration uptime, TimestampDuration? attachedUptime) attachment,required TResult Function( bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers, List<NodeId> nodeIds) network,required TResult Function( VeilidConfig config) config,required TResult Function( List<String> deadRoutes, List<String> deadRemoteRoutes) routeChange,required TResult Function( RecordKey key, List<ValueSubkeyRange> subkeys, int count, ValueData? value) valueChange,}) {final _that = this;
switch (_that) { switch (_that) {
case VeilidLog(): case VeilidLog():
return log(_that.logLevel,_that.message,_that.backtrace);case VeilidAppMessage(): return log(_that.logLevel,_that.message,_that.backtrace);case VeilidAppMessage():
return appMessage(_that.message,_that.sender,_that.routeId);case VeilidAppCall(): return appMessage(_that.message,_that.sender,_that.routeId);case VeilidAppCall():
return appCall(_that.message,_that.callId,_that.sender,_that.routeId);case VeilidUpdateAttachment(): return appCall(_that.message,_that.callId,_that.sender,_that.routeId);case VeilidUpdateAttachment():
return attachment(_that.state,_that.publicInternetReady,_that.localNetworkReady,_that.uptime,_that.attachedUptime);case VeilidUpdateNetwork(): return attachment(_that.state,_that.publicInternetReady,_that.localNetworkReady,_that.uptime,_that.attachedUptime);case VeilidUpdateNetwork():
return network(_that.started,_that.bpsDown,_that.bpsUp,_that.peers);case VeilidUpdateConfig(): return network(_that.started,_that.bpsDown,_that.bpsUp,_that.peers,_that.nodeIds);case VeilidUpdateConfig():
return config(_that.config);case VeilidUpdateRouteChange(): return config(_that.config);case VeilidUpdateRouteChange():
return routeChange(_that.deadRoutes,_that.deadRemoteRoutes);case VeilidUpdateValueChange(): return routeChange(_that.deadRoutes,_that.deadRemoteRoutes);case VeilidUpdateValueChange():
return valueChange(_that.key,_that.subkeys,_that.count,_that.value);} return valueChange(_that.key,_that.subkeys,_that.count,_that.value);}
@ -2882,14 +2882,14 @@ return valueChange(_that.key,_that.subkeys,_that.count,_that.value);}
/// } /// }
/// ``` /// ```
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( VeilidLogLevel logLevel, String message, String? backtrace)? log,TResult? Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, PublicKey? sender, String? routeId)? appMessage,TResult? Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, String callId, PublicKey? sender, String? routeId)? appCall,TResult? Function( AttachmentState state, bool publicInternetReady, bool localNetworkReady, TimestampDuration uptime, TimestampDuration? attachedUptime)? attachment,TResult? Function( bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers)? network,TResult? Function( VeilidConfig config)? config,TResult? Function( List<String> deadRoutes, List<String> deadRemoteRoutes)? routeChange,TResult? Function( RecordKey key, List<ValueSubkeyRange> subkeys, int count, ValueData? value)? valueChange,}) {final _that = this; @optionalTypeArgs TResult? whenOrNull<TResult extends Object?>({TResult? Function( VeilidLogLevel logLevel, String message, String? backtrace)? log,TResult? Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, PublicKey? sender, String? routeId)? appMessage,TResult? Function(@Uint8ListJsonConverter.jsIsArray() Uint8List message, String callId, PublicKey? sender, String? routeId)? appCall,TResult? Function( AttachmentState state, bool publicInternetReady, bool localNetworkReady, TimestampDuration uptime, TimestampDuration? attachedUptime)? attachment,TResult? Function( bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers, List<NodeId> nodeIds)? network,TResult? Function( VeilidConfig config)? config,TResult? Function( List<String> deadRoutes, List<String> deadRemoteRoutes)? routeChange,TResult? Function( RecordKey key, List<ValueSubkeyRange> subkeys, int count, ValueData? value)? valueChange,}) {final _that = this;
switch (_that) { switch (_that) {
case VeilidLog() when log != null: case VeilidLog() when log != null:
return log(_that.logLevel,_that.message,_that.backtrace);case VeilidAppMessage() when appMessage != null: return log(_that.logLevel,_that.message,_that.backtrace);case VeilidAppMessage() when appMessage != null:
return appMessage(_that.message,_that.sender,_that.routeId);case VeilidAppCall() when appCall != null: return appMessage(_that.message,_that.sender,_that.routeId);case VeilidAppCall() when appCall != null:
return appCall(_that.message,_that.callId,_that.sender,_that.routeId);case VeilidUpdateAttachment() when attachment != null: return appCall(_that.message,_that.callId,_that.sender,_that.routeId);case VeilidUpdateAttachment() when attachment != null:
return attachment(_that.state,_that.publicInternetReady,_that.localNetworkReady,_that.uptime,_that.attachedUptime);case VeilidUpdateNetwork() when network != null: return attachment(_that.state,_that.publicInternetReady,_that.localNetworkReady,_that.uptime,_that.attachedUptime);case VeilidUpdateNetwork() when network != null:
return network(_that.started,_that.bpsDown,_that.bpsUp,_that.peers);case VeilidUpdateConfig() when config != null: return network(_that.started,_that.bpsDown,_that.bpsUp,_that.peers,_that.nodeIds);case VeilidUpdateConfig() when config != null:
return config(_that.config);case VeilidUpdateRouteChange() when routeChange != null: return config(_that.config);case VeilidUpdateRouteChange() when routeChange != null:
return routeChange(_that.deadRoutes,_that.deadRemoteRoutes);case VeilidUpdateValueChange() when valueChange != null: return routeChange(_that.deadRoutes,_that.deadRemoteRoutes);case VeilidUpdateValueChange() when valueChange != null:
return valueChange(_that.key,_that.subkeys,_that.count,_that.value);case _: return valueChange(_that.key,_that.subkeys,_that.count,_that.value);case _:
@ -3218,7 +3218,7 @@ as TimestampDuration?,
@JsonSerializable() @JsonSerializable()
class VeilidUpdateNetwork implements VeilidUpdate { class VeilidUpdateNetwork implements VeilidUpdate {
const VeilidUpdateNetwork({required this.started, required this.bpsDown, required this.bpsUp, required final List<PeerTableData> peers, final String? $type}): _peers = peers,$type = $type ?? 'Network'; const VeilidUpdateNetwork({required this.started, required this.bpsDown, required this.bpsUp, required final List<PeerTableData> peers, required final List<NodeId> nodeIds, final String? $type}): _peers = peers,_nodeIds = nodeIds,$type = $type ?? 'Network';
factory VeilidUpdateNetwork.fromJson(Map<String, dynamic> json) => _$VeilidUpdateNetworkFromJson(json); factory VeilidUpdateNetwork.fromJson(Map<String, dynamic> json) => _$VeilidUpdateNetworkFromJson(json);
final bool started; final bool started;
@ -3231,6 +3231,13 @@ class VeilidUpdateNetwork implements VeilidUpdate {
return EqualUnmodifiableListView(_peers); return EqualUnmodifiableListView(_peers);
} }
final List<NodeId> _nodeIds;
List<NodeId> get nodeIds {
if (_nodeIds is EqualUnmodifiableListView) return _nodeIds;
// ignore: implicit_dynamic_type
return EqualUnmodifiableListView(_nodeIds);
}
@JsonKey(name: 'kind') @JsonKey(name: 'kind')
final String $type; final String $type;
@ -3249,16 +3256,16 @@ Map<String, dynamic> toJson() {
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidUpdateNetwork&&(identical(other.started, started) || other.started == started)&&(identical(other.bpsDown, bpsDown) || other.bpsDown == bpsDown)&&(identical(other.bpsUp, bpsUp) || other.bpsUp == bpsUp)&&const DeepCollectionEquality().equals(other._peers, _peers)); return identical(this, other) || (other.runtimeType == runtimeType&&other is VeilidUpdateNetwork&&(identical(other.started, started) || other.started == started)&&(identical(other.bpsDown, bpsDown) || other.bpsDown == bpsDown)&&(identical(other.bpsUp, bpsUp) || other.bpsUp == bpsUp)&&const DeepCollectionEquality().equals(other._peers, _peers)&&const DeepCollectionEquality().equals(other._nodeIds, _nodeIds));
} }
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@override @override
int get hashCode => Object.hash(runtimeType,started,bpsDown,bpsUp,const DeepCollectionEquality().hash(_peers)); int get hashCode => Object.hash(runtimeType,started,bpsDown,bpsUp,const DeepCollectionEquality().hash(_peers),const DeepCollectionEquality().hash(_nodeIds));
@override @override
String toString() { String toString() {
return 'VeilidUpdate.network(started: $started, bpsDown: $bpsDown, bpsUp: $bpsUp, peers: $peers)'; return 'VeilidUpdate.network(started: $started, bpsDown: $bpsDown, bpsUp: $bpsUp, peers: $peers, nodeIds: $nodeIds)';
} }
@ -3269,7 +3276,7 @@ abstract mixin class $VeilidUpdateNetworkCopyWith<$Res> implements $VeilidUpdate
factory $VeilidUpdateNetworkCopyWith(VeilidUpdateNetwork value, $Res Function(VeilidUpdateNetwork) _then) = _$VeilidUpdateNetworkCopyWithImpl; factory $VeilidUpdateNetworkCopyWith(VeilidUpdateNetwork value, $Res Function(VeilidUpdateNetwork) _then) = _$VeilidUpdateNetworkCopyWithImpl;
@useResult @useResult
$Res call({ $Res call({
bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers bool started, BigInt bpsDown, BigInt bpsUp, List<PeerTableData> peers, List<NodeId> nodeIds
}); });
@ -3286,13 +3293,14 @@ class _$VeilidUpdateNetworkCopyWithImpl<$Res>
/// Create a copy of VeilidUpdate /// Create a copy of VeilidUpdate
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') $Res call({Object? started = null,Object? bpsDown = null,Object? bpsUp = null,Object? peers = null,}) { @pragma('vm:prefer-inline') $Res call({Object? started = null,Object? bpsDown = null,Object? bpsUp = null,Object? peers = null,Object? nodeIds = null,}) {
return _then(VeilidUpdateNetwork( return _then(VeilidUpdateNetwork(
started: null == started ? _self.started : started // ignore: cast_nullable_to_non_nullable started: null == started ? _self.started : started // ignore: cast_nullable_to_non_nullable
as bool,bpsDown: null == bpsDown ? _self.bpsDown : bpsDown // ignore: cast_nullable_to_non_nullable as bool,bpsDown: null == bpsDown ? _self.bpsDown : bpsDown // ignore: cast_nullable_to_non_nullable
as BigInt,bpsUp: null == bpsUp ? _self.bpsUp : bpsUp // ignore: cast_nullable_to_non_nullable as BigInt,bpsUp: null == bpsUp ? _self.bpsUp : bpsUp // ignore: cast_nullable_to_non_nullable
as BigInt,peers: null == peers ? _self._peers : peers // ignore: cast_nullable_to_non_nullable as BigInt,peers: null == peers ? _self._peers : peers // ignore: cast_nullable_to_non_nullable
as List<PeerTableData>, as List<PeerTableData>,nodeIds: null == nodeIds ? _self._nodeIds : nodeIds // ignore: cast_nullable_to_non_nullable
as List<NodeId>,
)); ));
} }

View file

@ -196,7 +196,7 @@ Map<String, dynamic> _$PeerStatsToJson(_PeerStats instance) =>
_PeerTableData _$PeerTableDataFromJson(Map<String, dynamic> json) => _PeerTableData _$PeerTableDataFromJson(Map<String, dynamic> json) =>
_PeerTableData( _PeerTableData(
nodeIds: (json['node_ids'] as List<dynamic>) nodeIds: (json['node_ids'] as List<dynamic>)
.map(Typed<BarePublicKey>.fromJson) .map(Typed<BareNodeId>.fromJson)
.toList(), .toList(),
peerAddress: json['peer_address'] as String, peerAddress: json['peer_address'] as String,
peerStats: PeerStats.fromJson(json['peer_stats']), peerStats: PeerStats.fromJson(json['peer_stats']),
@ -299,6 +299,9 @@ VeilidUpdateNetwork _$VeilidUpdateNetworkFromJson(Map<String, dynamic> json) =>
peers: (json['peers'] as List<dynamic>) peers: (json['peers'] as List<dynamic>)
.map(PeerTableData.fromJson) .map(PeerTableData.fromJson)
.toList(), .toList(),
nodeIds: (json['node_ids'] as List<dynamic>)
.map(Typed<BareNodeId>.fromJson)
.toList(),
$type: json['kind'] as String?, $type: json['kind'] as String?,
); );
@ -309,6 +312,7 @@ Map<String, dynamic> _$VeilidUpdateNetworkToJson(
'bps_down': instance.bpsDown.toString(), 'bps_down': instance.bpsDown.toString(),
'bps_up': instance.bpsUp.toString(), 'bps_up': instance.bpsUp.toString(),
'peers': instance.peers.map((e) => e.toJson()).toList(), 'peers': instance.peers.map((e) => e.toJson()).toList(),
'node_ids': instance.nodeIds.map((e) => e.toJson()).toList(),
'kind': instance.$type, 'kind': instance.$type,
}; };

View file

@ -16,14 +16,14 @@ async def test_connect(api_connection: veilid.VeilidAPI):
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_get_public_keys(api_connection: veilid.VeilidAPI): async def test_get_node_ids(api_connection: veilid.VeilidAPI):
state = await api_connection.get_state() state = await api_connection.get_state()
public_keys = state.config.config.network.routing_table.public_keys node_ids = state.network.node_ids
assert len(public_keys) >= 1 assert len(node_ids) >= 1
for public_key in public_keys: for node_id in node_ids:
assert public_key[4] == ":" assert node_id[4] == ":"
@pytest.mark.asyncio @pytest.mark.asyncio

2
veilid-python/uv.lock generated
View file

@ -210,7 +210,7 @@ wheels = [
[[package]] [[package]]
name = "veilid" name = "veilid"
version = "0.4.7" version = "0.4.8"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "appdirs" }, { name = "appdirs" },

View file

@ -4758,6 +4758,13 @@
"description": "The total number of bytes per second used by Veilid currently in the upload direction.", "description": "The total number of bytes per second used by Veilid currently in the upload direction.",
"$ref": "#/$defs/ByteCount" "$ref": "#/$defs/ByteCount"
}, },
"node_ids": {
"description": "The list of node ids for this node",
"type": "array",
"items": {
"type": "string"
}
},
"peers": { "peers": {
"description": "The list of most recently accessed peers.\nThis is not an active connection table, nor is representative of the entire routing table.", "description": "The list of most recently accessed peers.\nThis is not an active connection table, nor is representative of the entire routing table.",
"type": "array", "type": "array",
@ -4774,7 +4781,8 @@
"started", "started",
"bps_down", "bps_down",
"bps_up", "bps_up",
"peers" "peers",
"node_ids"
] ]
}, },
"VeilidUpdate": { "VeilidUpdate": {

View file

@ -7,7 +7,7 @@ from .types import (
BareRouteId, BareRouteId,
Timestamp, Timestamp,
TimestampDuration, TimestampDuration,
PublicKey, NodeId,
RecordKey, RecordKey,
ValueData, ValueData,
ValueSubkey, ValueSubkey,
@ -382,11 +382,11 @@ class PeerStats:
class PeerTableData: class PeerTableData:
node_ids: list[str] node_ids: list[NodeId]
peer_address: str peer_address: str
peer_stats: PeerStats peer_stats: PeerStats
def __init__(self, node_ids: list[str], peer_address: str, peer_stats: PeerStats): def __init__(self, node_ids: list[NodeId], peer_address: str, peer_stats: PeerStats):
self.node_ids = node_ids self.node_ids = node_ids
self.peer_address = peer_address self.peer_address = peer_address
self.peer_stats = peer_stats self.peer_stats = peer_stats
@ -394,7 +394,9 @@ class PeerTableData:
@classmethod @classmethod
def from_json(cls, j: dict) -> Self: def from_json(cls, j: dict) -> Self:
"""JSON object hook""" """JSON object hook"""
return cls(j["node_ids"], j["peer_address"], PeerStats.from_json(j["peer_stats"])) return cls([NodeId(node_id) for node_id in j["node_ids"]],
j["peer_address"],
PeerStats.from_json(j["peer_stats"]))
def to_json(self) -> dict: def to_json(self) -> dict:
return self.__dict__ return self.__dict__
@ -405,6 +407,7 @@ class VeilidStateNetwork:
bps_down: ByteCount bps_down: ByteCount
bps_up: ByteCount bps_up: ByteCount
peers: list[PeerTableData] peers: list[PeerTableData]
node_ids: list[NodeId]
def __init__( def __init__(
self, self,
@ -412,11 +415,13 @@ class VeilidStateNetwork:
bps_down: ByteCount, bps_down: ByteCount,
bps_up: ByteCount, bps_up: ByteCount,
peers: list[PeerTableData], peers: list[PeerTableData],
node_ids: list[NodeId],
): ):
self.started = started self.started = started
self.bps_down = bps_down self.bps_down = bps_down
self.bps_up = bps_up self.bps_up = bps_up
self.peers = peers self.peers = peers
self.node_ids = node_ids
@classmethod @classmethod
def from_json(cls, j: dict) -> Self: def from_json(cls, j: dict) -> Self:
@ -426,6 +431,7 @@ class VeilidStateNetwork:
ByteCount(j["bps_down"]), ByteCount(j["bps_down"]),
ByteCount(j["bps_up"]), ByteCount(j["bps_up"]),
[PeerTableData.from_json(peer) for peer in j["peers"]], [PeerTableData.from_json(peer) for peer in j["peers"]],
[NodeId(node_id) for node_id in j["node_ids"]],
) )
def to_json(self) -> dict: def to_json(self) -> dict:
@ -495,11 +501,11 @@ class VeilidLog:
class VeilidAppMessage: class VeilidAppMessage:
sender: Optional[PublicKey] sender: Optional[NodeId]
route_id: Optional[BareRouteId] route_id: Optional[BareRouteId]
message: bytes message: bytes
def __init__(self, sender: Optional[PublicKey], route_id: Optional[BareRouteId], message: bytes): def __init__(self, sender: Optional[NodeId], route_id: Optional[BareRouteId], message: bytes):
self.sender = sender self.sender = sender
self.route_id = route_id self.route_id = route_id
self.message = message self.message = message
@ -508,7 +514,7 @@ class VeilidAppMessage:
def from_json(cls, j: dict) -> Self: def from_json(cls, j: dict) -> Self:
"""JSON object hook""" """JSON object hook"""
return cls( return cls(
None if j["sender"] is None else PublicKey(j["sender"]), None if j["sender"] is None else NodeId(j["sender"]),
None if j["route_id"] is None else BareRouteId(j["route_id"]), None if j["route_id"] is None else BareRouteId(j["route_id"]),
urlsafe_b64decode_no_pad(j["message"]), urlsafe_b64decode_no_pad(j["message"]),
) )
@ -518,12 +524,12 @@ class VeilidAppMessage:
class VeilidAppCall: class VeilidAppCall:
sender: Optional[PublicKey] sender: Optional[NodeId]
route_id: Optional[BareRouteId] route_id: Optional[BareRouteId]
message: bytes message: bytes
call_id: OperationId call_id: OperationId
def __init__(self, sender: Optional[PublicKey], route_id: Optional[BareRouteId], message: bytes, call_id: OperationId): def __init__(self, sender: Optional[NodeId], route_id: Optional[BareRouteId], message: bytes, call_id: OperationId):
self.sender = sender self.sender = sender
self.route_id = route_id self.route_id = route_id
self.message = message self.message = message
@ -533,7 +539,7 @@ class VeilidAppCall:
def from_json(cls, j: dict) -> Self: def from_json(cls, j: dict) -> Self:
"""JSON object hook""" """JSON object hook"""
return cls( return cls(
None if j["sender"] is None else PublicKey(j["sender"]), None if j["sender"] is None else NodeId(j["sender"]),
None if j["route_id"] is None else BareRouteId(j["route_id"]), None if j["route_id"] is None else BareRouteId(j["route_id"]),
urlsafe_b64decode_no_pad(j["message"]), urlsafe_b64decode_no_pad(j["message"]),
OperationId(j["call_id"]), OperationId(j["call_id"]),

View file

@ -21,7 +21,7 @@
}, },
"../pkg": { "../pkg": {
"name": "veilid-wasm", "name": "veilid-wasm",
"version": "0.4.7", "version": "0.4.8",
"dev": true, "dev": true,
"license": "MPL-2.0" "license": "MPL-2.0"
}, },