From 70e256a25a9f26a660194494af2f5cecc91a445d Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 19 Nov 2023 21:14:58 -0500 Subject: [PATCH 01/67] checkpoint --- doc/config/sample.config | 3 + doc/config/veilid-server-config.md | 3 + veilid-core/proto/veilid.capnp | 4 +- .../operations/operation_watch_value.rs | 94 ++++--- .../src/rpc_processor/rpc_get_value.rs | 2 +- .../src/rpc_processor/rpc_watch_value.rs | 162 ++++++++++++ veilid-core/src/storage_manager/get_value.rs | 65 +++-- veilid-core/src/storage_manager/mod.rs | 129 +++++++--- veilid-core/src/storage_manager/set_value.rs | 51 ++-- .../storage_manager/storage_manager_inner.rs | 62 ++++- .../types/local_record_detail.rs | 3 + .../src/storage_manager/types/record.rs | 6 +- .../src/storage_manager/watch_value.rs | 236 ++++++++++++++++++ veilid-core/src/veilid_api/routing_context.rs | 22 +- veilid-core/src/veilid_api/tests/fixtures.rs | 2 + veilid-core/src/veilid_config.rs | 4 + veilid-flutter/lib/default_config.dart | 4 +- veilid-flutter/lib/veilid_config.dart | 43 ++-- veilid-python/veilid/config.py | 3 + veilid-server/src/settings.rs | 13 +- veilid-wasm/tests/src/utils/veilid-config.ts | 2 + 21 files changed, 765 insertions(+), 148 deletions(-) create mode 100644 veilid-core/src/storage_manager/watch_value.rs diff --git a/doc/config/sample.config b/doc/config/sample.config index 53b8d996..fe324081 100644 --- a/doc/config/sample.config +++ b/doc/config/sample.config @@ -88,6 +88,9 @@ core: remote_max_records: 65536 remote_max_subkey_cache_memory_mb: %REMOTE_MAX_SUBKEY_CACHE_MEMORY_MB% remote_max_storage_space_mb: 0 + public_watch_limit: 32 + member_watch_limit: 8 + upnp: true detect_address_changes: true restricted_nat_retries: 0 diff --git a/doc/config/veilid-server-config.md b/doc/config/veilid-server-config.md index e099da63..69b44c10 100644 --- a/doc/config/veilid-server-config.md +++ b/doc/config/veilid-server-config.md @@ -255,6 +255,9 @@ dht: remote_max_records: 65536 remote_max_subkey_cache_memory_mb: %REMOTE_MAX_SUBKEY_CACHE_MEMORY_MB% remote_max_storage_space_mb: 0 + public_watch_limit: 32 + member_watch_limit: 8 + ``` #### core:network:tls diff --git a/veilid-core/proto/veilid.capnp b/veilid-core/proto/veilid.capnp index 8fabe0f7..d4f1a9b1 100644 --- a/veilid-core/proto/veilid.capnp +++ b/veilid-core/proto/veilid.capnp @@ -356,8 +356,8 @@ struct OperationWatchValueQ @0xf9a5a6c547b9b228 { subkeys @1 :List(SubkeyRange); # subkey range to watch (up to 512 subranges), if empty, watch everything expiration @2 :UInt64; # requested timestamp when this watch will expire in usec since epoch (can be return less, 0 for max) count @3 :UInt32; # requested number of changes to watch for (0 = cancel, 1 = single shot, 2+ = counter, UINT32_MAX = continuous) - watcher @4 :PublicKey; # the watcher performing the watch, can be the owner or a schema member - signature @5 :Signature; # signature of the watcher, must be one of the schema members or the key owner. signature covers: key, subkeys, expiration, count + watcher @4 :PublicKey; # optional: the watcher performing the watch, can be the owner or a schema member + signature @5 :Signature; # optional: signature of the watcher, must be one of the schema members or the key owner. signature covers: key, subkeys, expiration, count } struct OperationWatchValueA @0xa726cab7064ba893 { diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index bf79f20d..666f358f 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -9,8 +9,7 @@ pub(in crate::rpc_processor) struct RPCOperationWatchValueQ { subkeys: ValueSubkeyRangeSet, expiration: u64, count: u32, - watcher: PublicKey, - signature: Signature, + opt_watch_signature: Option<(PublicKey, Signature)>, } impl RPCOperationWatchValueQ { @@ -20,8 +19,8 @@ impl RPCOperationWatchValueQ { subkeys: ValueSubkeyRangeSet, expiration: u64, count: u32, - watcher: PublicKey, - signature: Signature, + opt_watcher: Option, + vcrypto: CryptoSystemVersion, ) -> Result { // Needed because RangeSetBlaze uses different types here all the time #[allow(clippy::unnecessary_cast)] @@ -30,31 +29,46 @@ impl RPCOperationWatchValueQ { if subkeys_len > MAX_WATCH_VALUE_Q_SUBKEYS_LEN { return Err(RPCError::protocol("WatchValueQ subkeys length too long")); } + + let opt_watch_signature = if let Some(watcher) = opt_watcher { + let signature_data = Self::make_signature_data(&key, &subkeys, expiration, count); + let signature = vcrypto + .sign(&watcher.key, &watcher.secret, &signature_data) + .map_err(RPCError::protocol)?; + Some((watcher.key, signature)) + } else { + None + }; + Ok(Self { key, subkeys, expiration, count, - watcher, - signature, + opt_watch_signature, }) } // signature covers: key, subkeys, expiration, count, using watcher key - fn make_signature_data(&self) -> Vec { + fn make_signature_data( + key: &TypedKey, + subkeys: &ValueSubkeyRangeSet, + expiration: u64, + count: u32, + ) -> Vec { // Needed because RangeSetBlaze uses different types here all the time #[allow(clippy::unnecessary_cast)] - let subkeys_len = self.subkeys.len() as usize; + let subkeys_len = subkeys.len() as usize; let mut sig_data = Vec::with_capacity(PUBLIC_KEY_LENGTH + 4 + (subkeys_len * 8) + 8 + 4); - sig_data.extend_from_slice(&self.key.kind.0); - sig_data.extend_from_slice(&self.key.value.bytes); - for sk in self.subkeys.ranges() { + sig_data.extend_from_slice(&key.kind.0); + sig_data.extend_from_slice(&key.value.bytes); + for sk in subkeys.ranges() { sig_data.extend_from_slice(&sk.start().to_le_bytes()); sig_data.extend_from_slice(&sk.end().to_le_bytes()); } - sig_data.extend_from_slice(&self.expiration.to_le_bytes()); - sig_data.extend_from_slice(&self.count.to_le_bytes()); + sig_data.extend_from_slice(&expiration.to_le_bytes()); + sig_data.extend_from_slice(&count.to_le_bytes()); sig_data } @@ -63,11 +77,13 @@ impl RPCOperationWatchValueQ { return Err(RPCError::protocol("unsupported cryptosystem")); }; - let sig_data = self.make_signature_data(); - vcrypto - .verify(&self.watcher, &sig_data, &self.signature) - .map_err(RPCError::protocol)?; - + if let Some(watch_signature) = self.opt_watch_signature { + let sig_data = + Self::make_signature_data(&self.key, &self.subkeys, self.expiration, self.count); + vcrypto + .verify(&watch_signature.0, &sig_data, &watch_signature.1) + .map_err(RPCError::protocol)?; + } Ok(()) } @@ -92,13 +108,8 @@ impl RPCOperationWatchValueQ { } #[allow(dead_code)] - pub fn watcher(&self) -> &PublicKey { - &self.watcher - } - - #[allow(dead_code)] - pub fn signature(&self) -> &Signature { - &self.signature + pub fn opt_watch_signature(&self) -> Option<&(PublicKey, Signature)> { + self.opt_watch_signature.as_ref() } #[allow(dead_code)] @@ -109,16 +120,14 @@ impl RPCOperationWatchValueQ { ValueSubkeyRangeSet, u64, u32, - PublicKey, - Signature, + Option<(PublicKey, Signature)>, ) { ( self.key, self.subkeys, self.expiration, self.count, - self.watcher, - self.signature, + self.opt_watch_signature, ) } @@ -151,19 +160,24 @@ impl RPCOperationWatchValueQ { let expiration = reader.get_expiration(); let count = reader.get_count(); - let w_reader = reader.get_watcher().map_err(RPCError::protocol)?; - let watcher = decode_key256(&w_reader); + let opt_watch_signature = if reader.has_watcher() { + let w_reader = reader.get_watcher().map_err(RPCError::protocol)?; + let watcher = decode_key256(&w_reader); - let s_reader = reader.get_signature().map_err(RPCError::protocol)?; - let signature = decode_signature512(&s_reader); + let s_reader = reader.get_signature().map_err(RPCError::protocol)?; + let signature = decode_signature512(&s_reader); + + Some((watcher, signature)) + } else { + None + }; Ok(Self { key, subkeys, expiration, count, - watcher, - signature, + opt_watch_signature, }) } @@ -188,11 +202,13 @@ impl RPCOperationWatchValueQ { builder.set_expiration(self.expiration); builder.set_count(self.count); - let mut w_builder = builder.reborrow().init_watcher(); - encode_key256(&self.watcher, &mut w_builder); + if let Some(watch_signature) = self.opt_watch_signature { + let mut w_builder = builder.reborrow().init_watcher(); + encode_key256(&watch_signature.0, &mut w_builder); - let mut s_builder = builder.reborrow().init_signature(); - encode_signature512(&self.signature, &mut s_builder); + let mut s_builder = builder.reborrow().init_signature(); + encode_signature512(&watch_signature.1, &mut s_builder); + } Ok(()) } diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index 055aaa45..d45d211f 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -37,7 +37,7 @@ impl RPCProcessor { // and get the target noderef so we can validate the response let Some(target) = dest.target() else { return Err(RPCError::internal( - "Never send set value requests over private routes", + "Never send get value requests over private routes", )); }; diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 7ec9d69a..b22960f1 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -1,6 +1,168 @@ use super::*; +#[derive(Clone, Debug)] +pub struct WatchValueAnswer { + pub expiration_ts: Option, +} + impl RPCProcessor { + /// Sends a watch value request and wait for response + /// Can be sent via all methods including relays + /// Safety routes may be used, but never private routes. + /// Because this leaks information about the identity of the node itself, + /// replying to this request received over a private route will leak + /// the identity of the node and defeat the private route. + + #[cfg_attr( + feature = "verbose-tracing", + instrument(level = "trace", skip(self), + fields(ret.expiration_ts, + ret.latency + ),err) + )] + pub async fn rpc_call_watch_value( + self, + dest: Destination, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + opt_watcher: Option, + ) -> RPCNetworkResult> { + // Ensure destination never has a private route + // and get the target noderef so we can validate the response + let Some(target) = dest.target() else { + return Err(RPCError::internal( + "Never send watch value requests over private routes", + )); + }; + + // Get the target node id + let Some(vcrypto) = self.crypto.get(key.kind) else { + return Err(RPCError::internal("unsupported cryptosystem")); + }; + let Some(target_node_id) = target.node_ids().get(key.kind) else { + return Err(RPCError::internal("No node id for crypto kind")); + }; + + let debug_string = format!( + "OUT ==> WatchValueQ({} {}#{:?}@{}+{}) => {}", + key, + if opt_watcher.is_some() { "+W " } else { "" }, + subkeys, + expiration, + count, + dest + ); + + // Send the watchvalue question + let watch_value_q = RPCOperationWatchValueQ::new( + key, + subkeys, + expiration.as_u64(), + count, + opt_watcher, + vcrypto, + )?; + let question = RPCQuestion::new( + network_result_try!(self.get_destination_respond_to(&dest)?), + RPCQuestionDetail::WatchValueQ(Box::new(watch_value_q)), + ); + + #[cfg(feature = "debug-dht")] + log_rpc!(debug "{}", debug_string); + + let waitable_reply = + network_result_try!(self.question(dest.clone(), question, None).await?); +xxxxx continue here + // Wait for reply + let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { + TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), + TimeoutOr::Value(v) => v, + }; + + // Get the right answer type + let (_, _, _, kind) = msg.operation.destructure(); + let get_value_a = match kind { + RPCOperationKind::Answer(a) => match a.destructure() { + RPCAnswerDetail::GetValueA(a) => a, + _ => return Ok(NetworkResult::invalid_message("not a getvalue answer")), + }, + _ => return Ok(NetworkResult::invalid_message("not an answer")), + }; + + let (value, peers, descriptor) = get_value_a.destructure(); + #[cfg(feature = "debug-dht")] + { + let debug_string_value = value + .as_ref() + .map(|v| { + format!( + " len={} seq={} writer={}", + v.value_data().data().len(), + v.value_data().seq(), + v.value_data().writer(), + ) + }) + .unwrap_or_default(); + + let debug_string_answer = format!( + "OUT <== GetValueA({} #{}{}{} peers={}) <= {}", + key, + subkey, + debug_string_value, + if descriptor.is_some() { " +desc" } else { "" }, + peers.len(), + dest + ); + + log_rpc!(debug "{}", debug_string_answer); + + let peer_ids: Vec = peers + .iter() + .filter_map(|p| p.node_ids().get(key.kind).map(|k| k.to_string())) + .collect(); + log_rpc!(debug "Peers: {:#?}", peer_ids); + } + + // Validate peers returned are, in fact, closer to the key than the node we sent this to + let valid = match RoutingTable::verify_peers_closer(vcrypto, target_node_id, key, &peers) { + Ok(v) => v, + Err(e) => { + return Ok(NetworkResult::invalid_message(format!( + "missing cryptosystem in peers node ids: {}", + e + ))); + } + }; + if !valid { + return Ok(NetworkResult::invalid_message("non-closer peers returned")); + } + + #[cfg(feature = "verbose-tracing")] + tracing::Span::current().record("ret.latency", latency.as_u64()); + #[cfg(feature = "verbose-tracing")] + if let Some(value) = &value { + tracing::Span::current().record("ret.value.data.len", value.value_data().data().len()); + tracing::Span::current().record("ret.value.data.seq", value.value_data().seq()); + tracing::Span::current().record( + "ret.value.data.writer", + value.value_data().writer().to_string(), + ); + } + #[cfg(feature = "verbose-tracing")] + tracing::Span::current().record("ret.peers.len", peers.len()); + + Ok(NetworkResult::value(Answer::new( + latency, + GetValueAnswer { + value, + peers, + descriptor, + }, + ))) + } + #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] pub(crate) async fn process_watch_value_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { // Ignore if disabled diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index 3fcb4b0c..abfe0272 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -4,14 +4,22 @@ use super::*; struct OutboundGetValueContext { /// The latest value of the subkey, may be the value passed in pub value: Option, - /// The consensus count for the value we have received - pub value_count: usize, + /// The nodes that have returned the value so far (up to the consensus count) + pub value_nodes: Vec, /// The descriptor if we got a fresh one or empty if no descriptor was needed pub descriptor: Option, /// The parsed schema from the descriptor if we have one pub schema: Option, } +/// The result of the outbound_get_value operation +struct OutboundGetValueResult { + /// The subkey that was retrieved + pub subkey_result: SubkeyResult, + /// And where it was retrieved from + pub value_nodes: Vec, +} + impl StorageManager { /// Perform a 'get value' query on the network pub async fn outbound_get_value( @@ -21,7 +29,7 @@ impl StorageManager { subkey: ValueSubkey, safety_selection: SafetySelection, last_subkey_result: SubkeyResult, - ) -> VeilidAPIResult { + ) -> VeilidAPIResult { let routing_table = rpc_processor.routing_table(); // Get the DHT parameters for 'GetValue' @@ -43,7 +51,7 @@ impl StorageManager { }; let context = Arc::new(Mutex::new(OutboundGetValueContext { value: last_subkey_result.value, - value_count: 0, + value_nodes: vec![], descriptor: last_subkey_result.descriptor.clone(), schema, })); @@ -116,12 +124,12 @@ impl StorageManager { return Ok(NetworkResult::invalid_message("value data mismatch")); } // Increase the consensus count for the existing value - ctx.value_count += 1; + ctx.value_nodes.push(next_node); } else if new_seq > prior_seq { // If the sequence number is greater, start over with the new value ctx.value = Some(value); // One node has shown us this value so far - ctx.value_count = 1; + ctx.value_nodes = vec![next_node]; } else { // If the sequence number is older, ignore it } @@ -129,7 +137,7 @@ impl StorageManager { // If we have no prior value, keep it ctx.value = Some(value); // One node has shown us this value so far - ctx.value_count = 1; + ctx.value_nodes = vec![next_node]; } } @@ -145,7 +153,9 @@ impl StorageManager { let check_done = |_closest_nodes: &[NodeRef]| { // If we have reached sufficient consensus, return done let ctx = context.lock(); - if ctx.value.is_some() && ctx.descriptor.is_some() && ctx.value_count >= consensus_count + if ctx.value.is_some() + && ctx.descriptor.is_some() + && ctx.value_nodes.len() >= consensus_count { return Some(()); } @@ -169,42 +179,51 @@ impl StorageManager { TimeoutOr::Timeout => { // Return the best answer we've got let ctx = context.lock(); - if ctx.value_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { log_stor!(debug "GetValue Fanout Timeout Consensus"); } else { - log_stor!(debug "GetValue Fanout Timeout Non-Consensus: {}", ctx.value_count); + log_stor!(debug "GetValue Fanout Timeout Non-Consensus: {}", ctx.value_nodes.len()); } - Ok(SubkeyResult { - value: ctx.value.clone(), - descriptor: ctx.descriptor.clone(), + Ok(OutboundGetValueResult { + subkey_result: SubkeyResult { + value: ctx.value.clone(), + descriptor: ctx.descriptor.clone(), + }, + value_nodes: ctx.value_nodes.clone(), }) } // If we finished with consensus (enough nodes returning the same value) TimeoutOr::Value(Ok(Some(()))) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.value_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { log_stor!(debug "GetValue Fanout Consensus"); } else { - log_stor!(debug "GetValue Fanout Non-Consensus: {}", ctx.value_count); + log_stor!(debug "GetValue Fanout Non-Consensus: {}", ctx.value_nodes.len()); } - Ok(SubkeyResult { - value: ctx.value.clone(), - descriptor: ctx.descriptor.clone(), + Ok(OutboundGetValueResult { + subkey_result: SubkeyResult { + value: ctx.value.clone(), + descriptor: ctx.descriptor.clone(), + }, + value_nodes: ctx.value_nodes.clone(), }) } // If we finished without consensus (ran out of nodes before getting consensus) TimeoutOr::Value(Ok(None)) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.value_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { log_stor!(debug "GetValue Fanout Exhausted Consensus"); } else { - log_stor!(debug "GetValue Fanout Exhausted Non-Consensus: {}", ctx.value_count); + log_stor!(debug "GetValue Fanout Exhausted Non-Consensus: {}", ctx.value_nodes.len()); } - Ok(SubkeyResult { - value: ctx.value.clone(), - descriptor: ctx.descriptor.clone(), + Ok(OutboundGetValueResult { + subkey_result: SubkeyResult { + value: ctx.value.clone(), + descriptor: ctx.descriptor.clone(), + }, + value_nodes: ctx.value_nodes.clone(), }) } // Failed diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 378420c5..aa2ad095 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -8,6 +8,7 @@ mod set_value; mod storage_manager_inner; mod tasks; mod types; +mod watch_value; use keys::*; use limited_size::*; @@ -186,9 +187,7 @@ impl StorageManager { .map(|r| r.unwrap()) } - /// Open an existing local record if it exists, - /// and if it doesnt exist locally, try to pull it from the network and - /// open it and return the opened descriptor + /// Open an existing local record if it exists, and if it doesnt exist locally, try to pull it from the network and open it and return the opened descriptor pub async fn open_record( &self, key: TypedKey, @@ -218,7 +217,7 @@ impl StorageManager { // No last descriptor, no last value // Use the safety selection we opened the record with let subkey: ValueSubkey = 0; - let subkey_result = self + let result = self .outbound_get_value( rpc_processor, key, @@ -229,7 +228,7 @@ impl StorageManager { .await?; // If we got nothing back, the key wasn't found - if subkey_result.value.is_none() && subkey_result.descriptor.is_none() { + if result.subkey_result.value.is_none() && result.subkey_result.descriptor.is_none() { // No result apibail_key_not_found!(key); }; @@ -250,7 +249,7 @@ impl StorageManager { // Open the new record inner - .open_new_record(key, writer, subkey, subkey_result, safety_selection) + .open_new_record(key, writer, subkey, result.subkey_result, safety_selection) .await } @@ -278,9 +277,6 @@ impl StorageManager { } /// Get the value of a subkey from an opened local record - /// may refresh the record, and will if it is forced to or the subkey is not available locally yet - /// Returns Ok(None) if no value was found - /// Returns Ok(Some(value)) is a value was found online or locally pub async fn get_value( &self, key: TypedKey, @@ -325,7 +321,7 @@ impl StorageManager { .value .as_ref() .map(|v| v.value_data().seq()); - let subkey_result = self + let result = self .outbound_get_value( rpc_processor, key, @@ -336,14 +332,17 @@ impl StorageManager { .await?; // See if we got a value back - let Some(subkey_result_value) = subkey_result.value else { + let Some(subkey_result_value) = result.subkey_result.value else { // If we got nothing back then we also had nothing beforehand, return nothing return Ok(None); }; + // Keep the list of nodes that returned a value for later reference + let mut inner = self.lock().await?; + inner.set_value_nodes(key, result.value_nodes)?; + // If we got a new value back then write it to the opened record if Some(subkey_result_value.value_data().seq()) != opt_last_seq { - let mut inner = self.lock().await?; inner .handle_set_local_value(key, subkey, subkey_result_value.clone()) .await?; @@ -352,9 +351,6 @@ impl StorageManager { } /// Set the value of a subkey on an opened local record - /// Puts changes to the network immediately and may refresh the record if the there is a newer subkey available online - /// Returns Ok(None) if the value was set - /// Returns Ok(Some(newer value)) if a newer value was found online pub async fn set_value( &self, key: TypedKey, @@ -450,7 +446,7 @@ impl StorageManager { drop(inner); // Use the safety selection we opened the record with - let final_signed_value_data = self + let result = self .outbound_set_value( rpc_processor, key, @@ -464,35 +460,102 @@ impl StorageManager { // Whatever record we got back, store it locally, might be newer than the one we asked to save let mut inner = self.lock().await?; inner - .handle_set_local_value(key, subkey, final_signed_value_data.clone()) + .handle_set_local_value(key, subkey, result.signed_value_data.clone()) .await?; // Return the new value if it differs from what was asked to set - if final_signed_value_data.value_data() != signed_value_data.value_data() { - return Ok(Some(final_signed_value_data.into_value_data())); + if result.signed_value_data.value_data() != signed_value_data.value_data() { + return Ok(Some(result.signed_value_data.into_value_data())); } // If the original value was set, return None Ok(None) } + /// Add a watch to a DHT value pub async fn watch_values( &self, - _key: TypedKey, - _subkeys: ValueSubkeyRangeSet, - _expiration: Timestamp, - _count: u32, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, ) -> VeilidAPIResult { - let _inner = self.lock().await?; - unimplemented!(); + let inner = self.lock().await?; + + // Get the safety selection and the writer we opened this record with + let (safety_selection, opt_writer) = { + let Some(opened_record) = inner.opened_records.get(&key) else { + apibail_generic!("record not open"); + }; + ( + opened_record.safety_selection(), + opened_record.writer().cloned(), + ) + }; + + // Get rpc processor and drop mutex so we don't block while requesting the watch from the network + let Some(rpc_processor) = inner.rpc_processor.clone() else { + apibail_try_again!("offline, try again later"); + }; + + // Drop the lock for network access + drop(inner); + + // Use the safety selection we opened the record with + let expiration_ts = self + .outbound_watch_value( + rpc_processor, + key, + subkeys, + expiration, + count, + safety_selection, + opt_writer, + ) + .await?; + + Ok(expiration_ts) } - pub async fn cancel_watch_values( - &self, - _key: TypedKey, - _subkeys: ValueSubkeyRangeSet, - ) -> VeilidAPIResult { - let _inner = self.lock().await?; - unimplemented!(); - } + // pub async fn cancel_watch_values( + // &self, + // key: TypedKey, + // subkeys: ValueSubkeyRangeSet, + // ) -> VeilidAPIResult { + // let inner = self.lock().await?; + + // // // Get the safety selection and the writer we opened this record with + // // let (safety_selection, opt_writer) = { + // // let Some(opened_record) = inner.opened_records.get(&key) else { + // // apibail_generic!("record not open"); + // // }; + // // ( + // // opened_record.safety_selection(), + // // opened_record.writer().cloned(), + // // ) + // // }; + + // // // Get rpc processor and drop mutex so we don't block while requesting the watch from the network + // // let Some(rpc_processor) = inner.rpc_processor.clone() else { + // // apibail_try_again!("offline, try again later"); + // // }; + + // // // Drop the lock for network access + // // drop(inner); + + // // // Use the safety selection we opened the record with + // // let expiration_ts = self + // // .outbound_watch_value( + // // rpc_processor, + // // key, + // // subkeys, + // // expiration, + // // count, + // // safety_selection, + // // opt_writer, + // // ) + // // .await?; + + // // Ok(expiration_ts) + // } } diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index e7742fac..b2bae1c5 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -4,14 +4,22 @@ use super::*; struct OutboundSetValueContext { /// The latest value of the subkey, may be the value passed in pub value: SignedValueData, - /// The consensus count for the value we have received - pub set_count: usize, + /// The nodes that have set the value so far (up to the consensus count) + pub value_nodes: Vec, /// The number of non-sets since the last set we have received pub missed_since_last_set: usize, /// The parsed schema from the descriptor if we have one pub schema: DHTSchema, } +/// The result of the outbound_set_value operation +struct OutboundSetValueResult { + /// The value that was set + pub signed_value_data: SignedValueData, + /// And where it was set to + pub value_nodes: Vec, +} + impl StorageManager { /// Perform a 'set value' query on the network pub async fn outbound_set_value( @@ -22,7 +30,7 @@ impl StorageManager { safety_selection: SafetySelection, value: SignedValueData, descriptor: SignedValueDescriptor, - ) -> VeilidAPIResult { + ) -> VeilidAPIResult { let routing_table = rpc_processor.routing_table(); // Get the DHT parameters for 'SetValue' @@ -40,7 +48,7 @@ impl StorageManager { let schema = descriptor.schema()?; let context = Arc::new(Mutex::new(OutboundSetValueContext { value, - set_count: 0, + value_nodes: vec![], missed_since_last_set: 0, schema, })); @@ -99,7 +107,7 @@ impl StorageManager { // If the sequence number is greater, keep it ctx.value = value; // One node has shown us this value so far - ctx.set_count = 1; + ctx.value_nodes = vec![next_node]; ctx.missed_since_last_set = 0; } else { // If the sequence number is older, or an equal sequence number, @@ -110,7 +118,7 @@ impl StorageManager { } else { // It was set on this node and no newer value was found and returned, // so increase our consensus count - ctx.set_count += 1; + ctx.value_nodes.push(next_node); ctx.missed_since_last_set = 0; } } else { @@ -131,13 +139,13 @@ impl StorageManager { let ctx = context.lock(); // If we have reached sufficient consensus, return done - if ctx.set_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { return Some(()); } // If we have missed more than our consensus count since our last set, return done // This keeps the traversal from searching too many nodes when we aren't converging // Only do this if we have gotten at least half our desired sets. - if ctx.set_count >= ((consensus_count + 1) / 2) + if ctx.value_nodes.len() >= ((consensus_count + 1) / 2) && ctx.missed_since_last_set >= consensus_count { return Some(()); @@ -162,35 +170,44 @@ impl StorageManager { TimeoutOr::Timeout => { // Return the best answer we've got let ctx = context.lock(); - if ctx.set_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { log_stor!(debug "SetValue Fanout Timeout Consensus"); } else { - log_stor!(debug "SetValue Fanout Timeout Non-Consensus: {}", ctx.set_count); + log_stor!(debug "SetValue Fanout Timeout Non-Consensus: {}", ctx.value_nodes.len()); } - Ok(ctx.value.clone()) + Ok(OutboundSetValueResult { + signed_value_data: ctx.value.clone(), + value_nodes: ctx.value_nodes.clone(), + }) } // If we finished with or without consensus (enough nodes returning the same value) TimeoutOr::Value(Ok(Some(()))) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.set_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { log_stor!(debug "SetValue Fanout Consensus"); } else { - log_stor!(debug "SetValue Fanout Non-Consensus: {}", ctx.set_count); + log_stor!(debug "SetValue Fanout Non-Consensus: {}", ctx.value_nodes.len()); } - Ok(ctx.value.clone()) + Ok(OutboundSetValueResult { + signed_value_data: ctx.value.clone(), + value_nodes: ctx.value_nodes.clone(), + }) } // If we ran out of nodes before getting consensus) TimeoutOr::Value(Ok(None)) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.set_count >= consensus_count { + if ctx.value_nodes.len() >= consensus_count { log_stor!(debug "SetValue Fanout Exhausted Consensus"); } else { - log_stor!(debug "SetValue Fanout Exhausted Non-Consensus: {}", ctx.set_count); + log_stor!(debug "SetValue Fanout Exhausted Non-Consensus: {}", ctx.value_nodes.len()); } - Ok(ctx.value.clone()) + Ok(OutboundSetValueResult { + signed_value_data: ctx.value.clone(), + value_nodes: ctx.value_nodes.clone(), + }) } // Failed TimeoutOr::Value(Err(e)) => { diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index 8eb8c0b6..4aa3008a 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -204,7 +204,10 @@ impl StorageManagerInner { // Add new local value record let cur_ts = get_aligned_timestamp(); - let local_record_detail = LocalRecordDetail { safety_selection }; + let local_record_detail = LocalRecordDetail { + safety_selection, + value_nodes: vec![], + }; let record = Record::::new(cur_ts, signed_value_descriptor, local_record_detail)?; @@ -243,7 +246,10 @@ impl StorageManagerInner { let local_record = Record::new( cur_ts, remote_record.descriptor().clone(), - LocalRecordDetail { safety_selection }, + LocalRecordDetail { + safety_selection, + value_nodes: vec![], + }, )?; local_record_store.new_record(key, local_record).await?; @@ -379,7 +385,10 @@ impl StorageManagerInner { let record = Record::::new( get_aligned_timestamp(), signed_value_descriptor, - LocalRecordDetail { safety_selection }, + LocalRecordDetail { + safety_selection, + value_nodes: vec![], + }, )?; local_record_store.new_record(key, record).await?; @@ -400,6 +409,53 @@ impl StorageManagerInner { Ok(descriptor) } + pub fn get_value_nodes(&mut self, key: TypedKey) -> VeilidAPIResult>> { + // Get local record store + let Some(local_record_store) = self.local_record_store.as_mut() else { + apibail_not_initialized!(); + }; + + // Get routing table to see if we still know about these nodes + let Some(routing_table) = self.rpc_processor.map(|r| r.routing_table()) else { + apibail_try_again!("offline, try again later"); + }; + + let opt_value_nodes = local_record_store.with_record(key, |r| { + let d = r.detail(); + d.value_nodes + .iter() + .copied() + .filter_map(|x| { + routing_table + .lookup_node_ref(TypedKey::new(key.kind, x)) + .ok() + .flatten() + }) + .collect() + }); + + Ok(opt_value_nodes) + } + + pub fn set_value_nodes( + &mut self, + key: TypedKey, + value_nodes: Vec, + ) -> VeilidAPIResult<()> { + // Get local record store + let Some(local_record_store) = self.local_record_store.as_mut() else { + apibail_not_initialized!(); + }; + local_record_store.with_record_mut(key, |r| { + let d = r.detail_mut(); + d.value_nodes = value_nodes + .into_iter() + .filter_map(|x| x.node_ids().get(key.kind).map(|k| k.value)) + .collect(); + }); + Ok(()) + } + pub fn close_record(&mut self, key: TypedKey) -> VeilidAPIResult<()> { let Some(_opened_record) = self.opened_records.remove(&key) else { apibail_generic!("record not open"); diff --git a/veilid-core/src/storage_manager/types/local_record_detail.rs b/veilid-core/src/storage_manager/types/local_record_detail.rs index 64e1f8d7..50987428 100644 --- a/veilid-core/src/storage_manager/types/local_record_detail.rs +++ b/veilid-core/src/storage_manager/types/local_record_detail.rs @@ -6,4 +6,7 @@ pub struct LocalRecordDetail { /// The last 'safety selection' used when creating/opening this record. /// Even when closed, this safety selection applies to re-publication attempts by the system. pub safety_selection: SafetySelection, + /// The nodes that we have seen this record cached on recently + #[serde(default)] + pub value_nodes: Vec, } diff --git a/veilid-core/src/storage_manager/types/record.rs b/veilid-core/src/storage_manager/types/record.rs index d8ca49ee..21d5cd79 100644 --- a/veilid-core/src/storage_manager/types/record.rs +++ b/veilid-core/src/storage_manager/types/record.rs @@ -79,9 +79,9 @@ where + self.record_data_size } - // pub fn detail(&self) -> &D { - // &self.detail - // } + pub fn detail(&self) -> &D { + &self.detail + } pub fn detail_mut(&mut self) -> &mut D { &mut self.detail } diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs new file mode 100644 index 00000000..fc276be8 --- /dev/null +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -0,0 +1,236 @@ +use super::*; + +/// The context of the outbound_watch_value operation +struct OutboundWatchValueContext { + /// The timestamp for the expiration of the watch we successfully got + pub opt_expiration_ts: Option, +} + +impl StorageManager { + + /// Perform a 'watch value' query on the network + pub async fn outbound_watch_value( + &self, + rpc_processor: RPCProcessor, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + safety_selection: SafetySelection, + opt_writer: Option, + ) -> VeilidAPIResult { + let routing_table = rpc_processor.routing_table(); + + // Get the DHT parameters for 'GetValue', some of which are the same for 'WatchValue' operations + let (key_count, fanout, timeout_us) = { + let c = self.unlocked_inner.config.get(); + ( + c.network.dht.max_find_node_count as usize, + c.network.dht.get_value_fanout as usize, + TimestampDuration::from(ms_to_us(c.network.dht.get_value_timeout_ms)), + ) + }; + + // Make do-watch-value answer context + let schema = if let Some(d) = &last_subkey_result.descriptor { + Some(d.schema()?) + } else { + None + }; + let context = Arc::new(Mutex::new(OutboundWatchValueContext { + opt_expiration_ts: None, + })); + + // Routine to call to generate fanout + let call_routine = |next_node: NodeRef| { + let rpc_processor = rpc_processor.clone(); + let context = context.clone(); + let last_descriptor = last_subkey_result.descriptor.clone(); + async move { + let gva = network_result_try!( + rpc_processor + .clone() + .rpc_call_watch_value( + Destination::direct(next_node.clone()).with_safety(safety_selection), + key, + subkey, + last_descriptor, + ) + .await? + ); + + // Keep the descriptor if we got one. If we had a last_descriptor it will + // already be validated by rpc_call_get_value + if let Some(descriptor) = gva.answer.descriptor { + let mut ctx = context.lock(); + if ctx.descriptor.is_none() && ctx.schema.is_none() { + ctx.schema = Some(descriptor.schema().map_err(RPCError::invalid_format)?); + ctx.descriptor = Some(descriptor); + } + } + + // Keep the value if we got one and it is newer and it passes schema validation + if let Some(value) = gva.answer.value { + log_stor!(debug "Got value back: len={} seq={}", value.value_data().data().len(), value.value_data().seq()); + let mut ctx = context.lock(); + + // Ensure we have a schema and descriptor + let (Some(descriptor), Some(schema)) = (&ctx.descriptor, &ctx.schema) else { + // Got a value but no descriptor for it + // Move to the next node + return Ok(NetworkResult::invalid_message( + "Got value with no descriptor", + )); + }; + + // Validate with schema + if !schema.check_subkey_value_data( + descriptor.owner(), + subkey, + value.value_data(), + ) { + // Validation failed, ignore this value + // Move to the next node + return Ok(NetworkResult::invalid_message(format!( + "Schema validation failed on subkey {}", + subkey + ))); + } + + // If we have a prior value, see if this is a newer sequence number + if let Some(prior_value) = &ctx.value { + let prior_seq = prior_value.value_data().seq(); + let new_seq = value.value_data().seq(); + + if new_seq == prior_seq { + // If sequence number is the same, the data should be the same + if prior_value.value_data() != value.value_data() { + // Move to the next node + return Ok(NetworkResult::invalid_message("value data mismatch")); + } + // Increase the consensus count for the existing value + ctx.value_count += 1; + } else if new_seq > prior_seq { + // If the sequence number is greater, start over with the new value + ctx.value = Some(value); + // One node has shown us this value so far + ctx.value_count = 1; + } else { + // If the sequence number is older, ignore it + } + } else { + // If we have no prior value, keep it + ctx.value = Some(value); + // One node has shown us this value so far + ctx.value_count = 1; + } + } + + // Return peers if we have some + #[cfg(feature = "network-result-extra")] + log_stor!(debug "GetValue fanout call returned peers {}", gva.answer.peers.len()); + + Ok(NetworkResult::value(gva.answer.peers)) + } + }; + + // Routine to call to check if we're done at each step + let check_done = |_closest_nodes: &[NodeRef]| { + // If we have reached sufficient consensus, return done + let ctx = context.lock(); + if ctx.value.is_some() && ctx.descriptor.is_some() && ctx.value_count >= consensus_count + { + return Some(()); + } + None + }; + + // Call the fanout + let fanout_call = FanoutCall::new( + routing_table.clone(), + key, + key_count, + fanout, + timeout_us, + capability_fanout_node_info_filter(vec![CAP_DHT]), + call_routine, + check_done, + ); + + match fanout_call.run().await { + // If we don't finish in the timeout (too much time passed checking for consensus) + TimeoutOr::Timeout => { + // Return the best answer we've got + let ctx = context.lock(); + if ctx.value_count >= consensus_count { + log_stor!(debug "GetValue Fanout Timeout Consensus"); + } else { + log_stor!(debug "GetValue Fanout Timeout Non-Consensus: {}", ctx.value_count); + } + Ok(SubkeyResult { + value: ctx.value.clone(), + descriptor: ctx.descriptor.clone(), + }) + } + // If we finished with consensus (enough nodes returning the same value) + TimeoutOr::Value(Ok(Some(()))) => { + // Return the best answer we've got + let ctx = context.lock(); + if ctx.value_count >= consensus_count { + log_stor!(debug "GetValue Fanout Consensus"); + } else { + log_stor!(debug "GetValue Fanout Non-Consensus: {}", ctx.value_count); + } + Ok(SubkeyResult { + value: ctx.value.clone(), + descriptor: ctx.descriptor.clone(), + }) + } + // If we finished without consensus (ran out of nodes before getting consensus) + TimeoutOr::Value(Ok(None)) => { + // Return the best answer we've got + let ctx = context.lock(); + if ctx.value_count >= consensus_count { + log_stor!(debug "GetValue Fanout Exhausted Consensus"); + } else { + log_stor!(debug "GetValue Fanout Exhausted Non-Consensus: {}", ctx.value_count); + } + Ok(SubkeyResult { + value: ctx.value.clone(), + descriptor: ctx.descriptor.clone(), + }) + } + // Failed + TimeoutOr::Value(Err(e)) => { + // If we finished with an error, return that + log_stor!(debug "GetValue Fanout Error: {}", e); + Err(e.into()) + } + } + } + + /// Handle a received 'Get Value' query + // pub async fn inbound_get_value( + // &self, + // key: TypedKey, + // subkey: ValueSubkey, + // want_descriptor: bool, + // ) -> VeilidAPIResult> { + // let mut inner = self.lock().await?; + // let res = match inner + // .handle_get_remote_value(key, subkey, want_descriptor) + // .await + // { + // Ok(res) => res, + // Err(VeilidAPIError::Internal { message }) => { + // apibail_internal!(message); + // } + // Err(e) => { + // return Ok(NetworkResult::invalid_message(e)); + // } + // }; + // Ok(NetworkResult::value(res)) + // } +} + + diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index b4eeb620..37f1e207 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -314,13 +314,25 @@ impl RoutingContext { storage_manager.set_value(key, subkey, data).await } - /// Watches changes to an opened or created value + /// Add a watch to a DHT value that informs the user via an VeilidUpdate::ValueChange callback when the record has subkeys change. + /// One remote node will be selected to perform the watch and it will offer an expiration time based on a suggestion, and make an attempt to + /// continue to report changes via the callback. Nodes that agree to doing watches will be put on our 'ping' list to ensure they are still around + /// otherwise the watch will be cancelled and will have to be re-watched. /// - /// Changes to subkeys within the subkey range are returned via a ValueChanged callback - /// If the subkey range is empty, all subkey changes are considered - /// Expiration can be infinite to keep the watch for the maximum amount of time + /// There is only one watch permitted per record. If a change to a watch is desired, the first one must will be overwritten. + /// * `key` is the record key to watch. it must first be opened for reading or writing. + /// * `subkeys` is the the range of subkeys to watch. The range must not exceed 512 discrete non-overlapping or adjacent subranges. If no range is specified, this is equivalent to watching the entire range of subkeys. + /// * `expiration` is the desired timestamp of when to automatically terminate the watch, in microseconds. If this value is less than `network.rpc.timeout_ms` milliseconds in the future, this function will return an error immediately. + /// * `count` is the number of times the watch will be sent, maximum. A zero value here is equivalent to a cancellation. /// - /// Return value upon success is the amount of time allowed for the watch + /// Returns a timestamp of when the watch will expire. All watches are guaranteed to expire at some point in the future, and the returned timestamp will + /// be no later than the requested expiration, but -may- be before the requested expiration. + /// + /// DHT watches are accepted with the following conditions: + /// * First-come first-served basis for arbitrary unauthenticated readers, up to network.dht.public_watch_limit per record + /// * If a member (either the owner or a SMPL schema member) has opened the key for writing (even if no writing is performed) then the watch will be signed and guaranteed network.dht.member_watch_limit per writer + /// + /// Members can be specified via the SMPL schema and do not need to allocate writable subkeys in order to offer a member watch capability. pub async fn watch_dht_values( &self, key: TypedKey, diff --git a/veilid-core/src/veilid_api/tests/fixtures.rs b/veilid-core/src/veilid_api/tests/fixtures.rs index 738a34f7..44540407 100644 --- a/veilid-core/src/veilid_api/tests/fixtures.rs +++ b/veilid-core/src/veilid_api/tests/fixtures.rs @@ -144,6 +144,8 @@ pub fn fix_veilidconfiginner() -> VeilidConfigInner { remote_max_records: 17, remote_max_subkey_cache_memory_mb: 18, remote_max_storage_space_mb: 19, + public_watch_limit: 20, + member_watch_limit: 21, }, upnp: true, detect_address_changes: false, diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index ec3ea1f7..91f8be7c 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -301,6 +301,8 @@ pub struct VeilidConfigDHT { pub remote_max_records: u32, pub remote_max_subkey_cache_memory_mb: u32, pub remote_max_storage_space_mb: u32, + pub public_watch_limit: u32, + pub member_watch_limit: u32, } impl Default for VeilidConfigDHT { @@ -758,6 +760,8 @@ impl VeilidConfig { get_config!(inner.network.dht.remote_max_records); get_config!(inner.network.dht.remote_max_subkey_cache_memory_mb); get_config!(inner.network.dht.remote_max_storage_space_mb); + get_config!(inner.network.dht.public_watch_limit); + get_config!(inner.network.dht.member_watch_limit); get_config!(inner.network.rpc.concurrency); get_config!(inner.network.rpc.queue_size); get_config!(inner.network.rpc.max_timestamp_behind_ms); diff --git a/veilid-flutter/lib/default_config.dart b/veilid-flutter/lib/default_config.dart index 9d11c91f..906ac498 100644 --- a/veilid-flutter/lib/default_config.dart +++ b/veilid-flutter/lib/default_config.dart @@ -138,7 +138,9 @@ Future getDefaultVeilidConfig(String programName) async { remoteSubkeyCacheSize: getRemoteSubkeyCacheSize(), remoteMaxRecords: getRemoteMaxRecords(), remoteMaxSubkeyCacheMemoryMb: await getRemoteMaxSubkeyCacheMemoryMb(), - remoteMaxStorageSpaceMb: getRemoteMaxStorageSpaceMb()), + remoteMaxStorageSpaceMb: getRemoteMaxStorageSpaceMb(), + publicWatchLimit: 32, + memberWatchLimit: 8), upnp: true, detectAddressChanges: true, restrictedNatRetries: 0, diff --git a/veilid-flutter/lib/veilid_config.dart b/veilid-flutter/lib/veilid_config.dart index d5b2469f..058b6cd5 100644 --- a/veilid-flutter/lib/veilid_config.dart +++ b/veilid-flutter/lib/veilid_config.dart @@ -263,26 +263,29 @@ class VeilidConfigTLS with _$VeilidConfigTLS { //////////// @freezed class VeilidConfigDHT with _$VeilidConfigDHT { - const factory VeilidConfigDHT( - {required int resolveNodeTimeoutMs, - required int resolveNodeCount, - required int resolveNodeFanout, - required int maxFindNodeCount, - required int getValueTimeoutMs, - required int getValueCount, - required int getValueFanout, - required int setValueTimeoutMs, - required int setValueCount, - required int setValueFanout, - required int minPeerCount, - required int minPeerRefreshTimeMs, - required int validateDialInfoReceiptTimeMs, - required int localSubkeyCacheSize, - required int localMaxSubkeyCacheMemoryMb, - required int remoteSubkeyCacheSize, - required int remoteMaxRecords, - required int remoteMaxSubkeyCacheMemoryMb, - required int remoteMaxStorageSpaceMb}) = _VeilidConfigDHT; + const factory VeilidConfigDHT({ + required int resolveNodeTimeoutMs, + required int resolveNodeCount, + required int resolveNodeFanout, + required int maxFindNodeCount, + required int getValueTimeoutMs, + required int getValueCount, + required int getValueFanout, + required int setValueTimeoutMs, + required int setValueCount, + required int setValueFanout, + required int minPeerCount, + required int minPeerRefreshTimeMs, + required int validateDialInfoReceiptTimeMs, + required int localSubkeyCacheSize, + required int localMaxSubkeyCacheMemoryMb, + required int remoteSubkeyCacheSize, + required int remoteMaxRecords, + required int remoteMaxSubkeyCacheMemoryMb, + required int remoteMaxStorageSpaceMb, + required int publicWatchLimit, + required int memberWatchLimit, + }) = _VeilidConfigDHT; factory VeilidConfigDHT.fromJson(dynamic json) => _$VeilidConfigDHTFromJson(json as Map); diff --git a/veilid-python/veilid/config.py b/veilid-python/veilid/config.py index c4649ba1..02644495 100644 --- a/veilid-python/veilid/config.py +++ b/veilid-python/veilid/config.py @@ -110,6 +110,9 @@ class VeilidConfigDHT(ConfigBase): remote_max_records: int remote_max_subkey_cache_memory_mb: int remote_max_storage_space_mb: int + public_watch_limit: int + member_watch_limit: int + @dataclass diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 6c498fb3..9973a4a1 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -109,6 +109,8 @@ core: remote_max_records: 65536 remote_max_subkey_cache_memory_mb: %REMOTE_MAX_SUBKEY_CACHE_MEMORY_MB% remote_max_storage_space_mb: 0 + public_watch_limit: 32 + member_watch_limit: 8 upnp: true detect_address_changes: true restricted_nat_retries: 0 @@ -562,6 +564,8 @@ pub struct Dht { pub remote_max_records: u32, pub remote_max_subkey_cache_memory_mb: u32, pub remote_max_storage_space_mb: u32, + pub public_watch_limit: u32, + pub member_watch_limit: u32, } #[derive(Debug, Deserialize, Serialize)] @@ -948,6 +952,8 @@ impl Settings { value ); set_config_value!(inner.core.network.dht.remote_max_storage_space_mb, value); + set_config_value!(inner.core.network.dht.public_watch_limit, value); + set_config_value!(inner.core.network.dht.member_watch_limit, value); set_config_value!(inner.core.network.upnp, value); set_config_value!(inner.core.network.detect_address_changes, value); set_config_value!(inner.core.network.restricted_nat_retries, value); @@ -1189,7 +1195,12 @@ impl Settings { "network.dht.remote_max_storage_space_mb" => { Ok(Box::new(inner.core.network.dht.remote_max_storage_space_mb)) } - + "network.dht.public_watch_limit" => { + Ok(Box::new(inner.core.network.dht.public_watch_limit)) + } + "network.dht.member_watch_limit" => { + Ok(Box::new(inner.core.network.dht.member_watch_limit)) + } "network.upnp" => Ok(Box::new(inner.core.network.upnp)), "network.detect_address_changes" => { Ok(Box::new(inner.core.network.detect_address_changes)) diff --git a/veilid-wasm/tests/src/utils/veilid-config.ts b/veilid-wasm/tests/src/utils/veilid-config.ts index d3d718f2..3ebdc777 100644 --- a/veilid-wasm/tests/src/utils/veilid-config.ts +++ b/veilid-wasm/tests/src/utils/veilid-config.ts @@ -88,6 +88,8 @@ export const veilidCoreStartupConfig = { remote_max_records: 65536, remote_max_subkey_cache_memory_mb: 256, remote_max_storage_space_mb: 0, + public_watch_limit: 32, + member_watch_limit: 8, }, upnp: true, detect_address_changes: true, From 9d9a76e45c63f47ab7182ce281e5ebd78e278750 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Mon, 20 Nov 2023 08:58:14 -0500 Subject: [PATCH 02/67] more watch value --- .../src/rpc_processor/rpc_watch_value.rs | 56 ++--- .../src/storage_manager/watch_value.rs | 197 ++++++------------ 2 files changed, 83 insertions(+), 170 deletions(-) diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index b22960f1..8ec66489 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -2,7 +2,8 @@ use super::*; #[derive(Clone, Debug)] pub struct WatchValueAnswer { - pub expiration_ts: Option, + pub expiration_ts: Timestamp, + pub peers: Vec, } impl RPCProcessor { @@ -16,8 +17,9 @@ impl RPCProcessor { #[cfg_attr( feature = "verbose-tracing", instrument(level = "trace", skip(self), - fields(ret.expiration_ts, - ret.latency + fields(ret.expiration, + ret.latency, + ret.peers.len ),err) )] pub async fn rpc_call_watch_value( @@ -62,7 +64,7 @@ impl RPCProcessor { expiration.as_u64(), count, opt_watcher, - vcrypto, + vcrypto.clone(), )?; let question = RPCQuestion::new( network_result_try!(self.get_destination_respond_to(&dest)?), @@ -74,7 +76,7 @@ impl RPCProcessor { let waitable_reply = network_result_try!(self.question(dest.clone(), question, None).await?); -xxxxx continue here + // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), @@ -83,36 +85,24 @@ xxxxx continue here // Get the right answer type let (_, _, _, kind) = msg.operation.destructure(); - let get_value_a = match kind { + let watch_value_a = match kind { RPCOperationKind::Answer(a) => match a.destructure() { - RPCAnswerDetail::GetValueA(a) => a, - _ => return Ok(NetworkResult::invalid_message("not a getvalue answer")), + RPCAnswerDetail::WatchValueA(a) => a, + _ => return Ok(NetworkResult::invalid_message("not a watchvalue answer")), }, _ => return Ok(NetworkResult::invalid_message("not an answer")), }; - let (value, peers, descriptor) = get_value_a.destructure(); + let (expiration, peers) = watch_value_a.destructure(); #[cfg(feature = "debug-dht")] { - let debug_string_value = value - .as_ref() - .map(|v| { - format!( - " len={} seq={} writer={}", - v.value_data().data().len(), - v.value_data().seq(), - v.value_data().writer(), - ) - }) - .unwrap_or_default(); - let debug_string_answer = format!( - "OUT <== GetValueA({} #{}{}{} peers={}) <= {}", + "OUT <== WatchValueA({} {}#{:?}@{} peers={}) <= {}", key, - subkey, - debug_string_value, - if descriptor.is_some() { " +desc" } else { "" }, - peers.len(), + if opt_watcher.is_some() { "+W " } else { "" }, + subkeys, + expiration, + peer.len() dest ); @@ -142,23 +132,15 @@ xxxxx continue here #[cfg(feature = "verbose-tracing")] tracing::Span::current().record("ret.latency", latency.as_u64()); #[cfg(feature = "verbose-tracing")] - if let Some(value) = &value { - tracing::Span::current().record("ret.value.data.len", value.value_data().data().len()); - tracing::Span::current().record("ret.value.data.seq", value.value_data().seq()); - tracing::Span::current().record( - "ret.value.data.writer", - value.value_data().writer().to_string(), - ); - } + tracing::Span::current().record("ret.expiration", latency.as_u64()); #[cfg(feature = "verbose-tracing")] tracing::Span::current().record("ret.peers.len", peers.len()); Ok(NetworkResult::value(Answer::new( latency, - GetValueAnswer { - value, + WatchValueAnswer { + expiration_ts: Timestamp::new(expiration), peers, - descriptor, }, ))) } diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index fc276be8..b1062b9e 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -7,7 +7,6 @@ struct OutboundWatchValueContext { } impl StorageManager { - /// Perform a 'watch value' query on the network pub async fn outbound_watch_value( &self, @@ -17,26 +16,25 @@ impl StorageManager { expiration: Timestamp, count: u32, safety_selection: SafetySelection, - opt_writer: Option, + opt_watcher: Option, ) -> VeilidAPIResult { let routing_table = rpc_processor.routing_table(); - // Get the DHT parameters for 'GetValue', some of which are the same for 'WatchValue' operations - let (key_count, fanout, timeout_us) = { + // Get the DHT parameters for 'WatchValue', some of which are the same for 'WatchValue' operations + let (key_count, timeout_us, rpc_timeout_us) = { let c = self.unlocked_inner.config.get(); ( c.network.dht.max_find_node_count as usize, - c.network.dht.get_value_fanout as usize, TimestampDuration::from(ms_to_us(c.network.dht.get_value_timeout_ms)), + TimestampDuration::from(ms_to_us(c.network.rpc.timeout_ms)), ) }; + // Get the minimum expiration timestamp we will accept + let cur_ts = get_timestamp(); + let min_expiration_ts = cur_ts + rpc_timeout_us.as_u64(); + // Make do-watch-value answer context - let schema = if let Some(d) = &last_subkey_result.descriptor { - Some(d.schema()?) - } else { - None - }; let context = Arc::new(Mutex::new(OutboundWatchValueContext { opt_expiration_ts: None, })); @@ -45,112 +43,54 @@ impl StorageManager { let call_routine = |next_node: NodeRef| { let rpc_processor = rpc_processor.clone(); let context = context.clone(); - let last_descriptor = last_subkey_result.descriptor.clone(); + let subkeys = subkeys.clone(); async move { - let gva = network_result_try!( + let wva = network_result_try!( rpc_processor .clone() .rpc_call_watch_value( Destination::direct(next_node.clone()).with_safety(safety_selection), key, - subkey, - last_descriptor, + subkeys, + expiration, + count, + opt_watcher ) .await? ); - // Keep the descriptor if we got one. If we had a last_descriptor it will - // already be validated by rpc_call_get_value - if let Some(descriptor) = gva.answer.descriptor { + // Keep the expiration_ts if we got one + if wva.answer.expiration_ts.as_u64() >= min_expiration_ts { + log_stor!(debug "Got expiration back: expiration_ts={}", wva.answer.expiration_ts); let mut ctx = context.lock(); - if ctx.descriptor.is_none() && ctx.schema.is_none() { - ctx.schema = Some(descriptor.schema().map_err(RPCError::invalid_format)?); - ctx.descriptor = Some(descriptor); - } - } - - // Keep the value if we got one and it is newer and it passes schema validation - if let Some(value) = gva.answer.value { - log_stor!(debug "Got value back: len={} seq={}", value.value_data().data().len(), value.value_data().seq()); - let mut ctx = context.lock(); - - // Ensure we have a schema and descriptor - let (Some(descriptor), Some(schema)) = (&ctx.descriptor, &ctx.schema) else { - // Got a value but no descriptor for it - // Move to the next node - return Ok(NetworkResult::invalid_message( - "Got value with no descriptor", - )); - }; - - // Validate with schema - if !schema.check_subkey_value_data( - descriptor.owner(), - subkey, - value.value_data(), - ) { - // Validation failed, ignore this value - // Move to the next node - return Ok(NetworkResult::invalid_message(format!( - "Schema validation failed on subkey {}", - subkey - ))); - } - - // If we have a prior value, see if this is a newer sequence number - if let Some(prior_value) = &ctx.value { - let prior_seq = prior_value.value_data().seq(); - let new_seq = value.value_data().seq(); - - if new_seq == prior_seq { - // If sequence number is the same, the data should be the same - if prior_value.value_data() != value.value_data() { - // Move to the next node - return Ok(NetworkResult::invalid_message("value data mismatch")); - } - // Increase the consensus count for the existing value - ctx.value_count += 1; - } else if new_seq > prior_seq { - // If the sequence number is greater, start over with the new value - ctx.value = Some(value); - // One node has shown us this value so far - ctx.value_count = 1; - } else { - // If the sequence number is older, ignore it - } - } else { - // If we have no prior value, keep it - ctx.value = Some(value); - // One node has shown us this value so far - ctx.value_count = 1; - } + ctx.opt_expiration_ts = Some(wva.answer.expiration_ts); } // Return peers if we have some #[cfg(feature = "network-result-extra")] - log_stor!(debug "GetValue fanout call returned peers {}", gva.answer.peers.len()); + log_stor!(debug "WatchValue fanout call returned peers {}", wva.answer.peers.len()); - Ok(NetworkResult::value(gva.answer.peers)) + Ok(NetworkResult::value(wva.answer.peers)) } }; // Routine to call to check if we're done at each step let check_done = |_closest_nodes: &[NodeRef]| { - // If we have reached sufficient consensus, return done + // If a watch has succeeded, return done let ctx = context.lock(); - if ctx.value.is_some() && ctx.descriptor.is_some() && ctx.value_count >= consensus_count - { + if ctx.opt_expiration_ts.is_some() { return Some(()); } None }; // Call the fanout + // Use a fixed fanout concurrency of 1 because we only want one watch let fanout_call = FanoutCall::new( routing_table.clone(), key, key_count, - fanout, + 1, timeout_us, capability_fanout_node_info_filter(vec![CAP_DHT]), call_routine, @@ -158,79 +98,70 @@ impl StorageManager { ); match fanout_call.run().await { - // If we don't finish in the timeout (too much time passed checking for consensus) + // If we don't finish in the timeout (too much time passed without a successful watch) TimeoutOr::Timeout => { // Return the best answer we've got let ctx = context.lock(); - if ctx.value_count >= consensus_count { - log_stor!(debug "GetValue Fanout Timeout Consensus"); + if ctx.opt_expiration_ts.is_some() { + log_stor!(debug "WatchValue Fanout Timeout Success"); } else { - log_stor!(debug "GetValue Fanout Timeout Non-Consensus: {}", ctx.value_count); + log_stor!(debug "WatchValue Fanout Timeout Failure"); } - Ok(SubkeyResult { - value: ctx.value.clone(), - descriptor: ctx.descriptor.clone(), - }) + Ok(ctx.opt_expiration_ts.unwrap_or_default()) } - // If we finished with consensus (enough nodes returning the same value) + // If we finished with done TimeoutOr::Value(Ok(Some(()))) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.value_count >= consensus_count { - log_stor!(debug "GetValue Fanout Consensus"); + if ctx.opt_expiration_ts.is_some() { + log_stor!(debug "WatchValue Fanout Success"); } else { - log_stor!(debug "GetValue Fanout Non-Consensus: {}", ctx.value_count); + log_stor!(debug "WatchValue Fanout Failure"); } - Ok(SubkeyResult { - value: ctx.value.clone(), - descriptor: ctx.descriptor.clone(), - }) + Ok(ctx.opt_expiration_ts.unwrap_or_default()) } - // If we finished without consensus (ran out of nodes before getting consensus) + // If we ran out of nodes TimeoutOr::Value(Ok(None)) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.value_count >= consensus_count { - log_stor!(debug "GetValue Fanout Exhausted Consensus"); + if ctx.opt_expiration_ts.is_some() { + log_stor!(debug "WatchValue Fanout Exhausted Success"); } else { - log_stor!(debug "GetValue Fanout Exhausted Non-Consensus: {}", ctx.value_count); + log_stor!(debug "WatchValue Fanout Exhausted Failure"); } - Ok(SubkeyResult { - value: ctx.value.clone(), - descriptor: ctx.descriptor.clone(), - }) + Ok(ctx.opt_expiration_ts.unwrap_or_default()) } // Failed TimeoutOr::Value(Err(e)) => { // If we finished with an error, return that - log_stor!(debug "GetValue Fanout Error: {}", e); + log_stor!(debug "WatchValue Fanout Error: {}", e); Err(e.into()) } } } - /// Handle a received 'Get Value' query - // pub async fn inbound_get_value( - // &self, - // key: TypedKey, - // subkey: ValueSubkey, - // want_descriptor: bool, - // ) -> VeilidAPIResult> { - // let mut inner = self.lock().await?; - // let res = match inner - // .handle_get_remote_value(key, subkey, want_descriptor) - // .await - // { - // Ok(res) => res, - // Err(VeilidAPIError::Internal { message }) => { - // apibail_internal!(message); - // } - // Err(e) => { - // return Ok(NetworkResult::invalid_message(e)); - // } - // }; - // Ok(NetworkResult::value(res)) - // } + /// Handle a received 'Watch Value' query + pub async fn inbound_watch_value( + &self, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + // xxx more here + ) -> VeilidAPIResult> { + let mut inner = self.lock().await?; + let res = match inner + .handle_watch_remote_value(key, subkeys, expiration, count) + .await + { + Ok(res) => res, + Err(VeilidAPIError::Internal { message }) => { + apibail_internal!(message); + } + Err(e) => { + return Ok(NetworkResult::invalid_message(e)); + } + }; + Ok(NetworkResult::value(res)) + } } - - From 248f8dad067f43376f3725ad147d86e02756f15c Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Tue, 21 Nov 2023 19:39:27 -0500 Subject: [PATCH 03/67] watchvalue recordkeeping --- veilid-core/proto/veilid.capnp | 2 +- .../route_spec_store_content.rs | 2 +- veilid-core/src/rpc_processor/fanout_call.rs | 9 +- veilid-core/src/rpc_processor/mod.rs | 14 +- veilid-core/src/rpc_processor/rpc_app_call.rs | 9 +- .../src/rpc_processor/rpc_find_node.rs | 9 +- .../src/rpc_processor/rpc_get_value.rs | 4 + .../src/rpc_processor/rpc_set_value.rs | 3 + veilid-core/src/rpc_processor/rpc_status.rs | 9 +- .../src/rpc_processor/rpc_watch_value.rs | 4 + veilid-core/src/storage_manager/get_value.rs | 2 +- veilid-core/src/storage_manager/mod.rs | 187 +++++++++++++----- veilid-core/src/storage_manager/set_value.rs | 2 +- .../storage_manager/storage_manager_inner.rs | 10 +- .../storage_manager/types/opened_record.rs | 30 +++ .../src/storage_manager/watch_value.rs | 67 +++++-- veilid-core/src/veilid_api/routing_context.rs | 2 + .../types/dht/value_subkey_range_set.rs | 22 +++ 18 files changed, 300 insertions(+), 87 deletions(-) diff --git a/veilid-core/proto/veilid.capnp b/veilid-core/proto/veilid.capnp index d4f1a9b1..6202a29e 100644 --- a/veilid-core/proto/veilid.capnp +++ b/veilid-core/proto/veilid.capnp @@ -361,7 +361,7 @@ struct OperationWatchValueQ @0xf9a5a6c547b9b228 { } struct OperationWatchValueA @0xa726cab7064ba893 { - expiration @0 :UInt64; # timestamp when this watch will expire in usec since epoch (0 if watch failed) + expiration @0 :UInt64; # timestamp when this watch will expire in usec since epoch (0 if watch was rejected). if watch is being cancelled (with count = 0), this will be the non-zero former expiration time. peers @1 :List(PeerInfo); # returned list of other nodes to ask that could propagate watches } diff --git a/veilid-core/src/routing_table/route_spec_store/route_spec_store_content.rs b/veilid-core/src/routing_table/route_spec_store/route_spec_store_content.rs index 604ac9a2..9127f00d 100644 --- a/veilid-core/src/routing_table/route_spec_store/route_spec_store_content.rs +++ b/veilid-core/src/routing_table/route_spec_store/route_spec_store_content.rs @@ -3,7 +3,7 @@ use super::*; /// The core representation of the RouteSpecStore that can be serialized #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub(super) struct RouteSpecStoreContent { - /// All of the route sets we have allocated so far indexed by key + /// All of the route sets we have allocated so far indexed by key (many to one) id_by_key: HashMap, /// All of the route sets we have allocated so far details: HashMap, diff --git a/veilid-core/src/rpc_processor/fanout_call.rs b/veilid-core/src/rpc_processor/fanout_call.rs index efa7f7f2..4cc2c64f 100644 --- a/veilid-core/src/rpc_processor/fanout_call.rs +++ b/veilid-core/src/rpc_processor/fanout_call.rs @@ -219,7 +219,10 @@ where Ok(()) } - pub async fn run(self: Arc) -> TimeoutOr, RPCError>> { + pub async fn run( + self: Arc, + opt_init_fanout_queue: Option>, + ) -> TimeoutOr, RPCError>> { // Get timeout in milliseconds let timeout_ms = match us_to_ms(self.timeout_us.as_u64()).map_err(RPCError::internal) { Ok(v) => v, @@ -229,7 +232,9 @@ where }; // Initialize closest nodes list - if let Err(e) = self.clone().init_closest_nodes() { + if let Some(init_fanout_queue) = opt_init_fanout_queue { + self.clone().add_to_fanout_queue(&init_fanout_queue); + } else if let Err(e) = self.clone().init_closest_nodes() { return TimeoutOr::value(Err(e)); } diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 009559ed..7c623409 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -196,12 +196,16 @@ struct WaitableReply { #[derive(Clone, Debug, Default)] pub struct Answer { - pub latency: TimestampDuration, // how long it took to get this answer - pub answer: T, // the answer itself + /// Hpw long it took to get this answer + pub latency: TimestampDuration, + /// The private route requested to receive the reply + pub reply_private_route: Option, + /// The answer itself + pub answer: T, } impl Answer { - pub fn new(latency: TimestampDuration, answer: T) -> Self { - Self { latency, answer } + pub fn new(latency: TimestampDuration, reply_private_route: Option, answer: T) -> Self { + Self { latency, reply_private_route, answer } } } @@ -512,7 +516,7 @@ impl RPCProcessor { check_done, ); - fanout_call.run().await + fanout_call.run(None).await } /// Search the DHT for a specific node corresponding to a key unless we have that node in our routing table already, and return the node reference diff --git a/veilid-core/src/rpc_processor/rpc_app_call.rs b/veilid-core/src/rpc_processor/rpc_app_call.rs index 239768ca..f82588ac 100644 --- a/veilid-core/src/rpc_processor/rpc_app_call.rs +++ b/veilid-core/src/rpc_processor/rpc_app_call.rs @@ -23,6 +23,9 @@ impl RPCProcessor { // Send the app call question let waitable_reply = network_result_try!(self.question(dest, question, None).await?); + // Keep the reply private route that was used to return with the answer + let reply_private_route = waitable_reply.reply_private_route.clone(); + // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), @@ -45,7 +48,11 @@ impl RPCProcessor { tracing::Span::current().record("ret.latency", latency.as_u64()); #[cfg(feature = "verbose-tracing")] tracing::Span::current().record("ret.len", a_message.len()); - Ok(NetworkResult::value(Answer::new(latency, a_message))) + Ok(NetworkResult::value(Answer::new( + latency, + reply_private_route, + a_message, + ))) } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] diff --git a/veilid-core/src/rpc_processor/rpc_find_node.rs b/veilid-core/src/rpc_processor/rpc_find_node.rs index ded13285..3db9e39e 100644 --- a/veilid-core/src/rpc_processor/rpc_find_node.rs +++ b/veilid-core/src/rpc_processor/rpc_find_node.rs @@ -43,6 +43,9 @@ impl RPCProcessor { // Send the find_node request let waitable_reply = network_result_try!(self.question(dest, find_node_q, None).await?); + // Keep the reply private route that was used to return with the answer + let reply_private_route = waitable_reply.reply_private_route.clone(); + // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), @@ -74,7 +77,11 @@ impl RPCProcessor { } } - Ok(NetworkResult::value(Answer::new(latency, peers))) + Ok(NetworkResult::value(Answer::new( + latency, + reply_private_route, + peers, + ))) } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index d45d211f..b251e97e 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -82,6 +82,9 @@ impl RPCProcessor { .await? ); + // Keep the reply private route that was used to return with the answer + let reply_private_route = waitable_reply.reply_private_route.clone(); + // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), @@ -156,6 +159,7 @@ impl RPCProcessor { Ok(NetworkResult::value(Answer::new( latency, + reply_private_route, GetValueAnswer { value, peers, diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index b507b73e..397f3b03 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -96,6 +96,8 @@ impl RPCProcessor { .await? ); + // Keep the reply private route that was used to return with the answer + let reply_private_route = waitable_reply.reply_private_route.clone(); // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { @@ -174,6 +176,7 @@ impl RPCProcessor { Ok(NetworkResult::value(Answer::new( latency, + reply_private_route, SetValueAnswer { set, value, peers }, ))) } diff --git a/veilid-core/src/rpc_processor/rpc_status.rs b/veilid-core/src/rpc_processor/rpc_status.rs index ae03778d..51832682 100644 --- a/veilid-core/src/rpc_processor/rpc_status.rs +++ b/veilid-core/src/rpc_processor/rpc_status.rs @@ -113,6 +113,9 @@ impl RPCProcessor { // Note what kind of ping this was and to what peer scope let send_data_method = waitable_reply.send_data_method.clone(); + // Keep the reply private route that was used to return with the answer + let reply_private_route = waitable_reply.reply_private_route.clone(); + // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), @@ -190,7 +193,11 @@ impl RPCProcessor { // sender info is irrelevant over relays and routes } }; - Ok(NetworkResult::value(Answer::new(latency, opt_sender_info))) + Ok(NetworkResult::value(Answer::new( + latency, + reply_private_route, + opt_sender_info, + ))) } #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 8ec66489..7781398e 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -77,6 +77,9 @@ impl RPCProcessor { let waitable_reply = network_result_try!(self.question(dest.clone(), question, None).await?); + // Keep the reply private route that was used to return with the answer + let reply_private_route = waitable_reply.reply_private_route.clone(); + // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { TimeoutOr::Timeout => return Ok(NetworkResult::Timeout), @@ -138,6 +141,7 @@ impl RPCProcessor { Ok(NetworkResult::value(Answer::new( latency, + reply_private_route, WatchValueAnswer { expiration_ts: Timestamp::new(expiration), peers, diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index abfe0272..2243af42 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -174,7 +174,7 @@ impl StorageManager { check_done, ); - match fanout_call.run().await { + match fanout_call.run(None).await { // If we don't finish in the timeout (too much time passed checking for consensus) TimeoutOr::Timeout => { // Return the best answer we've got diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index aa2ad095..0db2f0b0 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -255,19 +255,52 @@ impl StorageManager { /// Close an opened local record pub async fn close_record(&self, key: TypedKey) -> VeilidAPIResult<()> { - let mut inner = self.lock().await?; - inner.close_record(key) + let (opened_record, opt_rpc_processor) = { + let mut inner = self.lock().await?; + (inner.close_record(key)?, inner.rpc_processor.clone()) + }; + + // Send a one-time cancel request for the watch if we have one and we're online + if let Some(active_watch) = opened_record.active_watch() { + if let Some(rpc_processor) = opt_rpc_processor { + // Use the safety selection we opened the record with + // Use the writer we opened with as the 'watcher' as well + let opt_owvresult = self + .outbound_watch_value( + rpc_processor, + key, + ValueSubkeyRangeSet::full(), + Timestamp::new(0), + 0, + opened_record.safety_selection(), + opened_record.writer().cloned(), + Some(active_watch.watch_node), + ) + .await?; + if let Some(owvresult) = opt_owvresult { + if owvresult.expiration_ts.as_u64() != 0 { + log_stor!(debug + "close record watch cancel got unexpected expiration: {}", + owvresult.expiration_ts + ); + } + } else { + log_stor!(debug "close record watch cancel unsuccessful"); + } + } else { + log_stor!(debug "skipping last-ditch watch cancel because we are offline"); + } + } + + Ok(()) } /// Delete a local record pub async fn delete_record(&self, key: TypedKey) -> VeilidAPIResult<()> { - let mut inner = self.lock().await?; - // Ensure the record is closed - if inner.opened_records.contains_key(&key) { - inner.close_record(key)?; - } + self.close_record(key).await?; + let mut inner = self.lock().await?; let Some(local_record_store) = inner.local_record_store.as_mut() else { apibail_not_initialized!(); }; @@ -482,14 +515,22 @@ impl StorageManager { ) -> VeilidAPIResult { let inner = self.lock().await?; + // Rewrite subkey range if empty to full + let subkeys = if subkeys.is_empty() { + ValueSubkeyRangeSet::full() + } else { + subkeys + }; + // Get the safety selection and the writer we opened this record with - let (safety_selection, opt_writer) = { + let (safety_selection, opt_writer, opt_watch_node) = { let Some(opened_record) = inner.opened_records.get(&key) else { apibail_generic!("record not open"); }; ( opened_record.safety_selection(), opened_record.writer().cloned(), + opened_record.active_watch().map(|aw| aw.watch_node.clone()), ) }; @@ -502,60 +543,112 @@ impl StorageManager { drop(inner); // Use the safety selection we opened the record with - let expiration_ts = self + // Use the writer we opened with as the 'watcher' as well + let opt_owvresult = self .outbound_watch_value( rpc_processor, key, - subkeys, + subkeys.clone(), expiration, count, safety_selection, opt_writer, + opt_watch_node, ) .await?; - Ok(expiration_ts) + // If we did not get a valid response return a zero timestamp + let Some(owvresult) = opt_owvresult else { + return Ok(Timestamp::new(0)); + }; + + // Clear any existing watch if the watch succeeded or got cancelled + let mut inner = self.lock().await?; + let Some(opened_record) = inner.opened_records.get_mut(&key) else { + apibail_generic!("record not open"); + }; + opened_record.clear_active_watch(); + + // Get the minimum expiration timestamp we will accept + let rpc_timeout_us = { + let c = self.unlocked_inner.config.get(); + TimestampDuration::from(ms_to_us(c.network.rpc.timeout_ms)) + }; + let cur_ts = get_timestamp(); + let min_expiration_ts = cur_ts + rpc_timeout_us.as_u64(); + + // If the expiration time is less than our minimum expiration time or greater than the requested time, consider this watch cancelled + if owvresult.expiration_ts.as_u64() < min_expiration_ts + || owvresult.expiration_ts.as_u64() > expiration.as_u64() + { + // Don't set the watch so we ignore any stray valuechanged messages + return Ok(Timestamp::new(0)); + } + + // If we requested a cancellation, then consider this watch cancelled + if count == 0 { + return Ok(Timestamp::new(0)); + } + + // Keep a record of the watch + opened_record.set_active_watch(ActiveWatch { + expiration_ts: owvresult.expiration_ts, + watch_node: owvresult.watch_node, + opt_value_changed_route: owvresult.opt_value_changed_route, + subkeys, + count, + }); + + Ok(owvresult.expiration_ts) } - // pub async fn cancel_watch_values( - // &self, - // key: TypedKey, - // subkeys: ValueSubkeyRangeSet, - // ) -> VeilidAPIResult { - // let inner = self.lock().await?; + pub async fn cancel_watch_values( + &self, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + ) -> VeilidAPIResult { + let (subkeys, active_watch) = { + let inner = self.lock().await?; + let Some(opened_record) = inner.opened_records.get(&key) else { + apibail_generic!("record not open"); + }; - // // // Get the safety selection and the writer we opened this record with - // // let (safety_selection, opt_writer) = { - // // let Some(opened_record) = inner.opened_records.get(&key) else { - // // apibail_generic!("record not open"); - // // }; - // // ( - // // opened_record.safety_selection(), - // // opened_record.writer().cloned(), - // // ) - // // }; + // See what watch we have currently if any + let Some(active_watch) = opened_record.active_watch() else { + // If we didn't have an active watch, then we can just return false because there's nothing to do here + return Ok(false); + }; - // // // Get rpc processor and drop mutex so we don't block while requesting the watch from the network - // // let Some(rpc_processor) = inner.rpc_processor.clone() else { - // // apibail_try_again!("offline, try again later"); - // // }; + // Rewrite subkey range if empty to full + let subkeys = if subkeys.is_empty() { + ValueSubkeyRangeSet::full() + } else { + subkeys + }; - // // // Drop the lock for network access - // // drop(inner); + // Reduce the subkey range + let new_subkeys = active_watch.subkeys.difference(&subkeys); - // // // Use the safety selection we opened the record with - // // let expiration_ts = self - // // .outbound_watch_value( - // // rpc_processor, - // // key, - // // subkeys, - // // expiration, - // // count, - // // safety_selection, - // // opt_writer, - // // ) - // // .await?; + (new_subkeys, active_watch) + }; - // // Ok(expiration_ts) - // } + // If we have no subkeys left, then set the count to zero to indicate a full cancellation + let count = if subkeys.is_empty() { + 0 + } else { + active_watch.count + }; + + // Update the watch + let expiration_ts = self + .watch_values(key, subkeys, active_watch.expiration_ts, count) + .await?; + + // A zero expiration time means the watch is done or nothing is left, and the watch is no longer active + if expiration_ts.as_u64() == 0 { + return Ok(false); + } + + Ok(true) + } } diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index b2bae1c5..ce9d6de1 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -165,7 +165,7 @@ impl StorageManager { check_done, ); - match fanout_call.run().await { + match fanout_call.run(None).await { // If we don't finish in the timeout (too much time passed checking for consensus) TimeoutOr::Timeout => { // Return the best answer we've got diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index 4aa3008a..bf78b593 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -409,9 +409,9 @@ impl StorageManagerInner { Ok(descriptor) } - pub fn get_value_nodes(&mut self, key: TypedKey) -> VeilidAPIResult>> { + pub fn get_value_nodes(&self, key: TypedKey) -> VeilidAPIResult>> { // Get local record store - let Some(local_record_store) = self.local_record_store.as_mut() else { + let Some(local_record_store) = self.local_record_store.as_ref() else { apibail_not_initialized!(); }; @@ -456,11 +456,11 @@ impl StorageManagerInner { Ok(()) } - pub fn close_record(&mut self, key: TypedKey) -> VeilidAPIResult<()> { - let Some(_opened_record) = self.opened_records.remove(&key) else { + pub fn close_record(&mut self, key: TypedKey) -> VeilidAPIResult { + let Some(opened_record) = self.opened_records.remove(&key) else { apibail_generic!("record not open"); }; - Ok(()) + Ok(opened_record) } pub async fn handle_get_local_value( diff --git a/veilid-core/src/storage_manager/types/opened_record.rs b/veilid-core/src/storage_manager/types/opened_record.rs index 8f47786c..e2a0a4a4 100644 --- a/veilid-core/src/storage_manager/types/opened_record.rs +++ b/veilid-core/src/storage_manager/types/opened_record.rs @@ -1,5 +1,19 @@ use super::*; +#[derive(Clone, Debug)] +pub struct ActiveWatch { + /// The expiration of a successful watch + pub expiration_ts: Timestamp, + /// Which node accepted the watch + pub watch_node: NodeRef, + /// Which private route is responsible for receiving ValueChanged notifications + pub opt_value_changed_route: Option, + /// Which subkeys we are watching + pub subkeys: ValueSubkeyRangeSet, + /// How many notifications are left + pub count: u32, +} + /// The state associated with a local record when it is opened /// This is not serialized to storage as it is ephemeral for the lifetime of the opened record #[derive(Clone, Debug, Default)] @@ -11,6 +25,9 @@ pub struct OpenedRecord { /// The safety selection in current use safety_selection: SafetySelection, + + /// Active watch we have on this record + active_watch: Option, } impl OpenedRecord { @@ -18,6 +35,7 @@ impl OpenedRecord { Self { writer, safety_selection, + active_watch: None, } } @@ -28,4 +46,16 @@ impl OpenedRecord { pub fn safety_selection(&self) -> SafetySelection { self.safety_selection } + + pub fn set_active_watch(&mut self, active_watch: ActiveWatch) { + self.active_watch = Some(active_watch); + } + + pub fn clear_active_watch(&mut self) { + self.active_watch = None; + } + + pub fn active_watch(&self) -> Option { + self.active_watch.clone() + } } diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index b1062b9e..c9424ee5 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -2,8 +2,19 @@ use super::*; /// The context of the outbound_watch_value operation struct OutboundWatchValueContext { - /// The timestamp for the expiration of the watch we successfully got - pub opt_expiration_ts: Option, + /// A successful watch + pub opt_watch_value_result: Option, +} + +/// The result of the outbound_watch_value operation +#[derive(Debug, Clone)] +struct OutboundWatchValueResult { + /// The expiration of a successful watch + pub expiration_ts: Timestamp, + /// Which node accepted the watch + pub watch_node: NodeRef, + /// Which private route is responsible for receiving ValueChanged notifications + pub opt_value_changed_route: Option, } impl StorageManager { @@ -17,26 +28,30 @@ impl StorageManager { count: u32, safety_selection: SafetySelection, opt_watcher: Option, - ) -> VeilidAPIResult { + opt_watch_node: Option, + ) -> VeilidAPIResult> { let routing_table = rpc_processor.routing_table(); // Get the DHT parameters for 'WatchValue', some of which are the same for 'WatchValue' operations - let (key_count, timeout_us, rpc_timeout_us) = { + let (key_count, timeout_us) = { let c = self.unlocked_inner.config.get(); ( c.network.dht.max_find_node_count as usize, TimestampDuration::from(ms_to_us(c.network.dht.get_value_timeout_ms)), - TimestampDuration::from(ms_to_us(c.network.rpc.timeout_ms)), ) }; - // Get the minimum expiration timestamp we will accept - let cur_ts = get_timestamp(); - let min_expiration_ts = cur_ts + rpc_timeout_us.as_u64(); + // Get the nodes we know are caching this value to seed the fanout + let opt_init_fanout_queue = if let Some(watch_node) = opt_watch_node { + Some(vec![watch_node]) + } else { + let inner = self.inner.lock().await; + inner.get_value_nodes(key)? + }; // Make do-watch-value answer context let context = Arc::new(Mutex::new(OutboundWatchValueContext { - opt_expiration_ts: None, + opt_watch_value_result: None, })); // Routine to call to generate fanout @@ -59,11 +74,21 @@ impl StorageManager { .await? ); - // Keep the expiration_ts if we got one - if wva.answer.expiration_ts.as_u64() >= min_expiration_ts { - log_stor!(debug "Got expiration back: expiration_ts={}", wva.answer.expiration_ts); + // Keep answer if we got one + if wva.answer.expiration_ts.as_u64() > 0 { + if count > 0 { + // If we asked for a nonzero notification count, then this is an accepted watch + log_stor!(debug "Watch accepted: expiration_ts={}", wva.answer.expiration_ts); + } else { + // If we asked for a zero notification count, then this is a cancelled watch + log_stor!(debug "Watch cancelled"); + } let mut ctx = context.lock(); - ctx.opt_expiration_ts = Some(wva.answer.expiration_ts); + ctx.opt_watch_value_result = Some(OutboundWatchValueResult { + expiration_ts: wva.answer.expiration_ts, + watch_node: next_node.clone(), + opt_value_changed_route: wva.reply_private_route, + }); } // Return peers if we have some @@ -78,7 +103,7 @@ impl StorageManager { let check_done = |_closest_nodes: &[NodeRef]| { // If a watch has succeeded, return done let ctx = context.lock(); - if ctx.opt_expiration_ts.is_some() { + if ctx.opt_watch_value_result.is_some() { return Some(()); } None @@ -97,39 +122,39 @@ impl StorageManager { check_done, ); - match fanout_call.run().await { + match fanout_call.run(opt_init_fanout_queue).await { // If we don't finish in the timeout (too much time passed without a successful watch) TimeoutOr::Timeout => { // Return the best answer we've got let ctx = context.lock(); - if ctx.opt_expiration_ts.is_some() { + if ctx.opt_watch_value_result.is_some() { log_stor!(debug "WatchValue Fanout Timeout Success"); } else { log_stor!(debug "WatchValue Fanout Timeout Failure"); } - Ok(ctx.opt_expiration_ts.unwrap_or_default()) + Ok(ctx.opt_watch_value_result.clone()) } // If we finished with done TimeoutOr::Value(Ok(Some(()))) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.opt_expiration_ts.is_some() { + if ctx.opt_watch_value_result.is_some() { log_stor!(debug "WatchValue Fanout Success"); } else { log_stor!(debug "WatchValue Fanout Failure"); } - Ok(ctx.opt_expiration_ts.unwrap_or_default()) + Ok(ctx.opt_watch_value_result.clone()) } // If we ran out of nodes TimeoutOr::Value(Ok(None)) => { // Return the best answer we've got let ctx = context.lock(); - if ctx.opt_expiration_ts.is_some() { + if ctx.opt_watch_value_result.is_some() { log_stor!(debug "WatchValue Fanout Exhausted Success"); } else { log_stor!(debug "WatchValue Fanout Exhausted Failure"); } - Ok(ctx.opt_expiration_ts.unwrap_or_default()) + Ok(ctx.opt_watch_value_result.clone()) } // Failed TimeoutOr::Value(Err(e)) => { diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index 37f1e207..5520c6e7 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -350,6 +350,8 @@ impl RoutingContext { /// Cancels a watch early /// /// This is a convenience function that cancels watching all subkeys in a range + /// Returns Ok(true) if there is any remaining watch for this record + /// Returns Ok(false) if the entire watch has been cancelled pub async fn cancel_dht_watch( &self, key: TypedKey, diff --git a/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs b/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs index 99ba294b..62d75fd9 100644 --- a/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs +++ b/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs @@ -16,6 +16,11 @@ impl ValueSubkeyRangeSet { data: Default::default(), } } + pub fn full() -> Self { + let mut data = RangeSetBlaze::new(); + data.ranges_insert(u32::MIN..=u32::MAX); + Self { data } + } pub fn new_with_data(data: RangeSetBlaze) -> Self { Self { data } } @@ -24,6 +29,23 @@ impl ValueSubkeyRangeSet { data.insert(value); Self { data } } + + pub fn interset(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { + Self::new_with_data(self.data & other.data) + } + pub fn difference(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { + Self::new_with_data(self.data - other.data) + } + pub fn union(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { + Self::new_with_data(self.data | other.data) + } + + pub fn data(&self) -> RangeSetBlaze { + self.data().clone() + } + pub fn into_data(self) -> RangeSetBlaze { + self.data() + } } impl FromStr for ValueSubkeyRangeSet { From a211c7cce34258612428df1bfae31b913005f032 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Wed, 22 Nov 2023 21:39:21 -0500 Subject: [PATCH 04/67] more watchvalue --- veilid-core/src/rpc_processor/destination.rs | 104 ++++++++++++++---- veilid-core/src/rpc_processor/mod.rs | 10 +- .../src/rpc_processor/rpc_get_value.rs | 2 +- .../src/rpc_processor/rpc_set_value.rs | 2 +- veilid-core/src/rpc_processor/rpc_status.rs | 8 +- .../src/rpc_processor/rpc_value_changed.rs | 66 ++++++++++- .../src/rpc_processor/rpc_watch_value.rs | 93 +++++++++++++++- veilid-core/src/storage_manager/get_value.rs | 30 +++-- .../src/storage_manager/watch_value.rs | 44 +++++--- veilid-core/src/veilid_api/debug.rs | 4 +- veilid-core/src/veilid_api/routing_context.rs | 42 ++----- 11 files changed, 303 insertions(+), 102 deletions(-) diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 8d58e6d8..42e9a3cb 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -6,7 +6,7 @@ pub(crate) enum Destination { /// Send to node directly Direct { /// The node to send to - target: NodeRef, + node: NodeRef, /// Require safety route or not safety_selection: SafetySelection, }, @@ -15,7 +15,7 @@ pub(crate) enum Destination { /// The relay to send to relay: NodeRef, /// The final destination the relay should send to - target: NodeRef, + node: NodeRef, /// Require safety route or not safety_selection: SafetySelection, }, @@ -29,15 +29,15 @@ pub(crate) enum Destination { } impl Destination { - pub fn target(&self) -> Option { + pub fn node(&self) -> Option { match self { Destination::Direct { - target, + node: target, safety_selection: _, } => Some(target.clone()), Destination::Relay { relay: _, - target, + node: target, safety_selection: _, } => Some(target.clone()), Destination::PrivateRoute { @@ -46,18 +46,18 @@ impl Destination { } => None, } } - pub fn direct(target: NodeRef) -> Self { - let sequencing = target.sequencing(); + pub fn direct(node: NodeRef) -> Self { + let sequencing = node.sequencing(); Self::Direct { - target, + node, safety_selection: SafetySelection::Unsafe(sequencing), } } - pub fn relay(relay: NodeRef, target: NodeRef) -> Self { - let sequencing = relay.sequencing().max(target.sequencing()); + pub fn relay(relay: NodeRef, node: NodeRef) -> Self { + let sequencing = relay.sequencing().max(node.sequencing()); Self::Relay { relay, - target, + node, safety_selection: SafetySelection::Unsafe(sequencing), } } @@ -71,19 +71,19 @@ impl Destination { pub fn with_safety(self, safety_selection: SafetySelection) -> Self { match self { Destination::Direct { - target, + node, safety_selection: _, } => Self::Direct { - target, + node, safety_selection, }, Destination::Relay { relay, - target, + node, safety_selection: _, } => Self::Relay { relay, - target, + node, safety_selection, }, Destination::PrivateRoute { @@ -99,12 +99,12 @@ impl Destination { pub fn get_safety_selection(&self) -> &SafetySelection { match self { Destination::Direct { - target: _, + node: _, safety_selection, } => safety_selection, Destination::Relay { relay: _, - target: _, + node: _, safety_selection, } => safety_selection, Destination::PrivateRoute { @@ -113,13 +113,31 @@ impl Destination { } => safety_selection, } } + + pub fn get_target(&self) -> Target { + match self { + Destination::Direct { + node, + safety_selection: _, + } + | Destination::Relay { + relay: _, + node, + safety_selection: _, + } => Target::NodeId(node.best_node_id()), + Destination::PrivateRoute { + private_route, + safety_selection: _, + } => Target::PrivateRoute(private_route.public_key.value), + } + } } impl fmt::Display for Destination { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Destination::Direct { - target, + node, safety_selection, } => { let sr = if matches!(safety_selection, SafetySelection::Safe(_)) { @@ -128,11 +146,11 @@ impl fmt::Display for Destination { "" }; - write!(f, "{}{}", target, sr) + write!(f, "{}{}", node, sr) } Destination::Relay { relay, - target, + node, safety_selection, } => { let sr = if matches!(safety_selection, SafetySelection::Safe(_)) { @@ -141,7 +159,7 @@ impl fmt::Display for Destination { "" }; - write!(f, "{}@{}{}", target, relay, sr) + write!(f, "{}@{}{}", node, relay, sr) } Destination::PrivateRoute { private_route, @@ -160,6 +178,46 @@ impl fmt::Display for Destination { } impl RPCProcessor { + /// Convert a 'Target' into a 'Destination' + pub async fn resolve_target_to_destination( + &self, + target: Target, + safety_selection: SafetySelection, + sequencing: Sequencing, + ) -> Result { + match target { + Target::NodeId(node_id) => { + // Resolve node + let mut nr = match self.resolve_node(node_id, safety_selection).await? { + Some(nr) => nr, + None => { + return Err(RPCError::network("could not resolve node id")); + } + }; + // Apply sequencing to match safety selection + nr.set_sequencing(sequencing); + + Ok(rpc_processor::Destination::Direct { + node: nr, + safety_selection, + }) + } + Target::PrivateRoute(rsid) => { + // Get remote private route + let rss = self.routing_table().route_spec_store(); + + let Some(private_route) = rss.best_remote_private_route(&rsid) else { + return Err(RPCError::network("could not get remote private route")); + }; + + Ok(rpc_processor::Destination::PrivateRoute { + private_route, + safety_selection, + }) + } + } + } + /// Convert the 'Destination' into a 'RespondTo' for a response pub(super) fn get_destination_respond_to( &self, @@ -170,7 +228,7 @@ impl RPCProcessor { match dest { Destination::Direct { - target, + node: target, safety_selection, } => match safety_selection { SafetySelection::Unsafe(_) => { @@ -198,7 +256,7 @@ impl RPCProcessor { }, Destination::Relay { relay, - target, + node: target, safety_selection, } => match safety_selection { SafetySelection::Unsafe(_) => { diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 7c623409..db07a467 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -732,12 +732,12 @@ impl RPCProcessor { // To where are we sending the request match dest { Destination::Direct { - target: ref node_ref, + node: ref node_ref, safety_selection, } | Destination::Relay { relay: ref node_ref, - target: _, + node: _, safety_selection, } => { // Send to a node without a private route @@ -746,7 +746,7 @@ impl RPCProcessor { // Get the actual destination node id accounting for relays let (node_ref, destination_node_ref) = if let Destination::Relay { relay: _, - ref target, + node: ref target, safety_selection: _, } = dest { @@ -854,12 +854,12 @@ impl RPCProcessor { let routing_table = self.routing_table(); let target = match dest { Destination::Direct { - target, + node: target, safety_selection: _, } => target.clone(), Destination::Relay { relay: _, - target, + node: target, safety_selection: _, } => target.clone(), Destination::PrivateRoute { diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index b251e97e..148c10f4 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -35,7 +35,7 @@ impl RPCProcessor { ) ->RPCNetworkResult> { // Ensure destination never has a private route // and get the target noderef so we can validate the response - let Some(target) = dest.target() else { + let Some(target) = dest.node() else { return Err(RPCError::internal( "Never send get value requests over private routes", )); diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index 397f3b03..5c9201ab 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -39,7 +39,7 @@ impl RPCProcessor { ) ->RPCNetworkResult> { // Ensure destination never has a private route // and get the target noderef so we can validate the response - let Some(target) = dest.target() else { + let Some(target) = dest.node() else { return Err(RPCError::internal( "Never send set value requests over private routes", )); diff --git a/veilid-core/src/rpc_processor/rpc_status.rs b/veilid-core/src/rpc_processor/rpc_status.rs index 51832682..e8b48975 100644 --- a/veilid-core/src/rpc_processor/rpc_status.rs +++ b/veilid-core/src/rpc_processor/rpc_status.rs @@ -27,7 +27,7 @@ impl RPCProcessor { SafetySelection::Unsafe(_) => { let (opt_target_nr, routing_domain) = match &dest { Destination::Direct { - target, + node: target, safety_selection: _, } => { let routing_domain = match target.best_routing_domain() { @@ -52,7 +52,7 @@ impl RPCProcessor { } Destination::Relay { relay, - target, + node: target, safety_selection: _, } => { let routing_domain = match relay.best_routing_domain() { @@ -147,7 +147,7 @@ impl RPCProcessor { let mut opt_sender_info = None; match dest { Destination::Direct { - target, + node: target, safety_selection, } => { if matches!(safety_selection, SafetySelection::Unsafe(_)) { @@ -183,7 +183,7 @@ impl RPCProcessor { } Destination::Relay { relay: _, - target: _, + node: _, safety_selection: _, } | Destination::PrivateRoute { diff --git a/veilid-core/src/rpc_processor/rpc_value_changed.rs b/veilid-core/src/rpc_processor/rpc_value_changed.rs index 96c1b1fc..18b31c36 100644 --- a/veilid-core/src/rpc_processor/rpc_value_changed.rs +++ b/veilid-core/src/rpc_processor/rpc_value_changed.rs @@ -2,13 +2,67 @@ use super::*; impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), err))] + // Sends a high level app message + // Can be sent via all methods including relays and routes + #[cfg_attr( + feature = "verbose-tracing", + instrument(level = "trace", skip(self, message), fields(message.len = message.len()), err) + )] + pub async fn rpc_call_value_changed( + self, + dest: Destination, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + count: u32, + value: SignedValueData, + ) -> RPCNetworkResult<()> { + let value_changed = RPCOperationValueChanged::new(key, subkeys, count, value); + let statement = + RPCStatement::new(RPCStatementDetail::ValueChanged(Box::new(value_changed))); + + // Send the value changed request + self.statement(dest, statement).await + } + pub(crate) async fn process_value_changed(&self, msg: RPCMessage) -> RPCNetworkResult<()> { - // Ignore if disabled - let routing_table = self.routing_table(); - let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); - if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { - return Ok(NetworkResult::service_unavailable("dht is not available")); + // Get the statement + let (_, _, _, kind) = msg.operation.destructure(); + let (key, subkeys, count, value) = match kind { + RPCOperationKind::Statement(s) => match s.destructure() { + RPCStatementDetail::ValueChanged(s) => s.destructure(), + _ => panic!("not a value changed statement"), + }, + _ => panic!("not a statement"), + }; + + #[cfg(feature = "debug-dht")] + { + let debug_string_value = format!( + " len={} seq={} writer={}", + value.value_data().data().len(), + value.value_data().seq(), + value.value_data().writer(), + ); + + let debug_string_stmt = format!( + "IN <== ValueChanged({} #{:?}+{}{}) <= {}", + key, + subkeys, + count, + debug_string_value, + msg.header.direct_sender_node_id() + ); + + log_rpc!(debug "{}", debug_string_stmt); } - Err(RPCError::unimplemented("process_value_changed")) + + // Save the subkey, creating a new record if necessary + let storage_manager = self.storage_manager(); + storage_manager + .inbound_value_changed(key, subkeys, count, value) + .await + .map_err(RPCError::internal)?; + + Ok(NetworkResult::value(())) } } diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 7781398e..2861bb67 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -33,7 +33,7 @@ impl RPCProcessor { ) -> RPCNetworkResult> { // Ensure destination never has a private route // and get the target noderef so we can validate the response - let Some(target) = dest.target() else { + let Some(target) = dest.node() else { return Err(RPCError::internal( "Never send watch value requests over private routes", )); @@ -151,12 +151,101 @@ impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] pub(crate) async fn process_watch_value_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { + // Ensure this never came over a private route, safety route is okay though + match &msg.header.detail { + RPCMessageHeaderDetail::Direct(_) | RPCMessageHeaderDetail::SafetyRouted(_) => {} + RPCMessageHeaderDetail::PrivateRouted(_) => { + return Ok(NetworkResult::invalid_message( + "not processing watch value request over private route", + )) + } + } + // Ignore if disabled let routing_table = self.routing_table(); let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { return Ok(NetworkResult::service_unavailable("dht is not available")); } - Err(RPCError::unimplemented("process_watch_value_q")) + + // Get the question + let kind = msg.operation.kind().clone(); + let watch_value_q = match kind { + RPCOperationKind::Question(q) => match q.destructure() { + (_, RPCQuestionDetail::WatchValueQ(q)) => q, + _ => panic!("not a watchvalue question"), + }, + _ => panic!("not a question"), + }; + + // Destructure + let (key, subkeys, expiration, count, opt_watch_signature) = watch_value_q.destructure(); + let opt_watcher = opt_watch_signature.map(|ws| ws.0); + + // Get target for ValueChanged notifications + let dest = network_result_try!(self.get_respond_to_destination(&msg)); + let target = dest.get_target(); + + #[cfg(feature = "debug-dht")] + { + let debug_string = format!( + "IN <=== WatchValueQ({} {}#{:?}@{}+{}) <== {}", + key, + if opt_watcher.is_some() { "+W " } else { "" }, + subkeys, + expiration, + count, + msg.header.direct_sender_node_id() + ); + + log_rpc!(debug "{}", debug_string); + } + + // See if we have this record ourselves, if so, accept the watch + let storage_manager = self.storage_manager(); + let ret_expiration = network_result_try!(storage_manager + .inbound_watch_value( + key, + subkeys, + Timestamp::new(expiration), + count, + target, + opt_watcher + ) + .await + .map_err(RPCError::internal)?); + + // Get the nodes that we know about that are closer to the the key than our own node + let routing_table = self.routing_table(); + let closer_to_key_peers = if ret_expiration.as_u64() == 0 { + network_result_try!(routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT])) + } else { + vec![] + }; + + #[cfg(feature = "debug-dht")] + { + let debug_string_answer = format!( + "IN ===> WatchValueA({} #{} expiration={} peers={}) ==> {}", + key, + subkeys, + ret_expiration, + closer_to_key_peers.len(), + msg.header.direct_sender_node_id() + ); + + log_rpc!(debug "{}", debug_string_answer); + } + + // Make WatchValue answer + let watch_value_a = + RPCOperationWatchValueA::new(ret_expiration.as_u64(), closer_to_key_peers)?; + + // Send GetValue answer + self.answer( + msg, + RPCAnswer::new(RPCAnswerDetail::WatchValueA(Box::new(watch_value_a))), + ) + .await } } diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index 2243af42..7917938b 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -243,18 +243,26 @@ impl StorageManager { want_descriptor: bool, ) -> VeilidAPIResult> { let mut inner = self.lock().await?; - let res = match inner - .handle_get_remote_value(key, subkey, want_descriptor) - .await - { - Ok(res) => res, - Err(VeilidAPIError::Internal { message }) => { - apibail_internal!(message); - } - Err(e) => { - return Ok(NetworkResult::invalid_message(e)); + + // See if this is a remote or local value + let (_is_local, last_subkey_result) = { + // See if the subkey we are getting has a last known local value + let mut last_subkey_result = inner.handle_get_local_value(key, subkey, true).await?; + // If this is local, it must have a descriptor already + if last_subkey_result.descriptor.is_some() { + if !want_descriptor { + last_subkey_result.descriptor = None; + } + (true, last_subkey_result) + } else { + // See if the subkey we are getting has a last known remote value + let last_subkey_result = inner + .handle_get_remote_value(key, subkey, want_descriptor) + .await?; + (false, last_subkey_result) } }; - Ok(NetworkResult::value(res)) + + Ok(NetworkResult::value(last_subkey_result)) } } diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index c9424ee5..db9e718c 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -172,21 +172,39 @@ impl StorageManager { subkeys: ValueSubkeyRangeSet, expiration: Timestamp, count: u32, - // xxx more here - ) -> VeilidAPIResult> { + target: Target, + opt_watcher: Option, + ) -> VeilidAPIResult> { let mut inner = self.lock().await?; - let res = match inner - .handle_watch_remote_value(key, subkeys, expiration, count) - .await - { - Ok(res) => res, - Err(VeilidAPIError::Internal { message }) => { - apibail_internal!(message); - } - Err(e) => { - return Ok(NetworkResult::invalid_message(e)); + + // See if this is a remote or local value + let (_is_local, opt_expiration_ts) = { + // See if the subkey we are watching has a local value + let opt_expiration_ts = inner + .handle_watch_local_value(key, subkeys, expiration, count, target, opt_watcher) + .await?; + if opt_expiration_ts.is_some() { + (true, opt_expiration_ts) + } else { + // See if the subkey we are watching is a remote value + let opt_expiration_ts = inner + .handle_watch_remote_value(key, subkeys, expiration, count, target, opt_watcher) + .await?; + (false, opt_expiration_ts) } }; - Ok(NetworkResult::value(res)) + + Ok(NetworkResult::value(opt_expiration_ts.unwrap_or_default())) + } + + /// Handle a received 'Value Changed' statement + pub async fn inbound_value_changed( + &self, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + count: u32, + value: SignedValueData, + ) -> VeilidAPIResult<()> { + // } } diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 08eaf1dd..305fbb9e 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -888,7 +888,7 @@ impl VeilidAPI { match &dest { Destination::Direct { - target, + node: target, safety_selection: _, } => Ok(format!( "Destination: {:#?}\nTarget Entry:\n{}\n", @@ -897,7 +897,7 @@ impl VeilidAPI { )), Destination::Relay { relay, - target, + node: target, safety_selection: _, } => Ok(format!( "Destination: {:#?}\nTarget Entry:\n{}\nRelay Entry:\n{}\n", diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index 5520c6e7..a40df864 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -123,40 +123,14 @@ impl RoutingContext { async fn get_destination(&self, target: Target) -> VeilidAPIResult { let rpc_processor = self.api.rpc_processor()?; - - match target { - Target::NodeId(node_id) => { - // Resolve node - let mut nr = match rpc_processor - .resolve_node(node_id, self.unlocked_inner.safety_selection) - .await - { - Ok(Some(nr)) => nr, - Ok(None) => apibail_invalid_target!("could not resolve node id"), - Err(e) => return Err(e.into()), - }; - // Apply sequencing to match safety selection - nr.set_sequencing(self.sequencing()); - - Ok(rpc_processor::Destination::Direct { - target: nr, - safety_selection: self.unlocked_inner.safety_selection, - }) - } - Target::PrivateRoute(rsid) => { - // Get remote private route - let rss = self.api.routing_table()?.route_spec_store(); - - let Some(private_route) = rss.best_remote_private_route(&rsid) else { - apibail_invalid_target!("could not get remote private route"); - }; - - Ok(rpc_processor::Destination::PrivateRoute { - private_route, - safety_selection: self.unlocked_inner.safety_selection, - }) - } - } + rpc_processor + .resolve_target_to_destination( + target, + self.unlocked_inner.safety_selection, + self.sequencing(), + ) + .await + .map_err(VeilidAPIError::invalid_target) } //////////////////////////////////////////////////////////////// From 4a76353f338ef802a1585c3626cb8dc9c6330fb2 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 23 Nov 2023 09:49:25 -0500 Subject: [PATCH 05/67] ensure get_value doesn't try to pull values unless they are close enough --- .../src/rpc_processor/rpc_get_value.rs | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index 148c10f4..f8832772 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -230,16 +230,29 @@ impl RPCProcessor { log_rpc!(debug "{}", debug_string); } - // See if we have this record ourselves - let storage_manager = self.storage_manager(); - let subkey_result = network_result_try!(storage_manager - .inbound_get_value(key, subkey, want_descriptor) - .await - .map_err(RPCError::internal)?); - + // See if we would have accepted this as a set + let set_value_count = { + let c = self.config.get(); + c.network.dht.set_value_count as usize + }; + let (subkey_result_value, subkey_result_descriptor) = if closer_to_key_peers.len() >= set_value_count { + // Not close enough + (None, None) + } else { + // Close enough, lets get it + + // See if we have this record ourselves + let storage_manager = self.storage_manager(); + let subkey_result = network_result_try!(storage_manager + .inbound_get_value(key, subkey, want_descriptor) + .await + .map_err(RPCError::internal)?); + (subkey_result.value, subkey_result.descriptor) + }; + #[cfg(feature="debug-dht")] { - let debug_string_value = subkey_result.value.as_ref().map(|v| { + let debug_string_value = subkey_result_value.as_ref().map(|v| { format!(" len={} seq={} writer={}", v.value_data().data().len(), v.value_data().seq(), @@ -252,7 +265,7 @@ impl RPCProcessor { key, subkey, debug_string_value, - if subkey_result.descriptor.is_some() { + if subkey_result_descriptor.is_some() { " +desc" } else { "" @@ -266,9 +279,9 @@ impl RPCProcessor { // Make GetValue answer let get_value_a = RPCOperationGetValueA::new( - subkey_result.value, + subkey_result_value, closer_to_key_peers, - subkey_result.descriptor, + subkey_result_descriptor, )?; // Send GetValue answer From 077a1808a5b255f36cd55a5220d2c628c252a381 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 23 Nov 2023 10:00:19 -0500 Subject: [PATCH 06/67] propagate set logic to watch logic --- .../src/rpc_processor/rpc_watch_value.rs | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 2861bb67..f3dda723 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -201,26 +201,36 @@ impl RPCProcessor { log_rpc!(debug "{}", debug_string); } - // See if we have this record ourselves, if so, accept the watch - let storage_manager = self.storage_manager(); - let ret_expiration = network_result_try!(storage_manager - .inbound_watch_value( - key, - subkeys, - Timestamp::new(expiration), - count, - target, - opt_watcher - ) - .await - .map_err(RPCError::internal)?); - // Get the nodes that we know about that are closer to the the key than our own node let routing_table = self.routing_table(); - let closer_to_key_peers = if ret_expiration.as_u64() == 0 { - network_result_try!(routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT])) + let closer_to_key_peers = network_result_try!( + routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT]) + ); + + // See if we would have accepted this as a set + let set_value_count = { + let c = self.config.get(); + c.network.dht.set_value_count as usize + }; + let ret_expiration = if closer_to_key_peers.len() >= set_value_count { + // Not close enough + Timestamp::default() } else { - vec![] + // Close enough, lets watch it + + // See if we have this record ourselves, if so, accept the watch + let storage_manager = self.storage_manager(); + network_result_try!(storage_manager + .inbound_watch_value( + key, + subkeys, + Timestamp::new(expiration), + count, + target, + opt_watcher + ) + .await + .map_err(RPCError::internal)?) }; #[cfg(feature = "debug-dht")] @@ -238,8 +248,14 @@ impl RPCProcessor { } // Make WatchValue answer - let watch_value_a = - RPCOperationWatchValueA::new(ret_expiration.as_u64(), closer_to_key_peers)?; + let watch_value_a = RPCOperationWatchValueA::new( + ret_expiration.as_u64(), + if ret_expiration.as_u64() == 0 { + closer_to_key_peers + } else { + vec![] + }, + )?; // Send GetValue answer self.answer( From 8efa2de82ce6923f23a716b000b9d31c68945340 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 23 Nov 2023 19:00:33 -0500 Subject: [PATCH 07/67] config -> record store --- .../src/storage_manager/record_store.rs | 46 +++++++++++++++++-- .../storage_manager/record_store_limits.rs | 4 ++ .../storage_manager/storage_manager_inner.rs | 40 ++++++++++++++++ .../src/storage_manager/watch_value.rs | 9 +++- 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index c7a9da80..bc199b1c 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -13,15 +13,34 @@ struct DeadRecord where D: fmt::Debug + Clone + Serialize + for<'d> Deserialize<'d>, { - // The key used in the record_index + /// The key used in the record_index key: RecordTableKey, - // The actual record + /// The actual record record: Record, - // True if this record is accounted for in the total storage - // and needs to have the statistics updated or not when purged + /// True if this record is accounted for in the total storage + /// and needs to have the statistics updated or not when purged in_total_storage: bool, } +/// An individual watch +#[derive(Debug, Clone)] +struct WatchedRecordWatch { + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + target: Target, + opt_watcher: Option, +} + +#[derive(Debug, Clone)] +/// A record being watched for changes +struct WatchedRecord { + /// Number of watchers that are anonymous + anon_count: usize, + /// The list of active watchers + watchers: Vec, +} + pub struct RecordStore where D: fmt::Debug + Clone + Serialize + for<'d> Deserialize<'d>, @@ -46,6 +65,8 @@ where dead_records: Vec>, /// The list of records that have changed since last flush to disk (optimization for batched writes) changed_records: HashSet, + /// The list of records being watched for changes + watched_records: HashMap, /// A mutex to ensure we handle this concurrently purge_dead_records_mutex: Arc>, @@ -93,6 +114,7 @@ where ), dead_records: Vec::new(), changed_records: HashSet::new(), + watched_records: HashMap::new(), purge_dead_records_mutex: Arc::new(AsyncMutex::new(())), } } @@ -675,6 +697,22 @@ where Ok(()) } + /// Add a record watch for changes + pub async fn watch_subkeys( + &mut self, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + target: Target, + opt_watcher: Option, + ) -> VeilidAPIResult> { + + // If we have a watcher and it is in the record's schema + // then we have a guaranteed watch slot for it + xxx continue here + } + /// LRU out some records until we reclaim the amount of space requested /// This will force a garbage collection of the space immediately /// If zero is passed in here, a garbage collection will be performed of dead records diff --git a/veilid-core/src/storage_manager/record_store_limits.rs b/veilid-core/src/storage_manager/record_store_limits.rs index 5dfb25d4..6e03c713 100644 --- a/veilid-core/src/storage_manager/record_store_limits.rs +++ b/veilid-core/src/storage_manager/record_store_limits.rs @@ -13,4 +13,8 @@ pub struct RecordStoreLimits { pub max_subkey_cache_memory_mb: Option, /// Limit on the amount of storage space to use for subkey data and record data pub max_storage_space_mb: Option, + /// Max number of anonymous watches + pub public_watch_limit: u32, + /// Max number of watches per schema member + pub member_watch_limit: u32, } diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index bf78b593..09a935fb 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -39,6 +39,8 @@ fn local_limits_from_config(config: VeilidConfig) -> RecordStoreLimits { max_records: None, max_subkey_cache_memory_mb: Some(c.network.dht.local_max_subkey_cache_memory_mb as usize), max_storage_space_mb: None, + public_watch_limit: c.network.dht.public_watch_limit, + member_watch_limit: c.network.dht.member_watch_limit, } } @@ -51,6 +53,8 @@ fn remote_limits_from_config(config: VeilidConfig) -> RecordStoreLimits { max_records: Some(c.network.dht.remote_max_records as usize), max_subkey_cache_memory_mb: Some(c.network.dht.remote_max_subkey_cache_memory_mb as usize), max_storage_space_mb: Some(c.network.dht.remote_max_storage_space_mb as usize), + public_watch_limit: c.network.dht.public_watch_limit, + member_watch_limit: c.network.dht.member_watch_limit, } } @@ -505,6 +509,24 @@ impl StorageManagerInner { Ok(()) } + pub async fn handle_watch_local_value( + &mut self, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + target: Target, + opt_watcher: Option, + ) -> VeilidAPIResult> { + // See if it's in the local record store + let Some(local_record_store) = self.local_record_store.as_mut() else { + apibail_not_initialized!(); + }; + local_record_store + .watch_subkeys(key, subkeys, expiration, count, target, opt_watcher) + .await + } + pub async fn handle_get_remote_value( &mut self, key: TypedKey, @@ -561,6 +583,24 @@ impl StorageManagerInner { Ok(()) } + pub async fn handle_watch_remote_value( + &mut self, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + expiration: Timestamp, + count: u32, + target: Target, + opt_watcher: Option, + ) -> VeilidAPIResult> { + // See if it's in the remote record store + let Some(remote_record_store) = self.remote_record_store.as_mut() else { + apibail_not_initialized!(); + }; + remote_record_store + .watch_subkeys(key, subkeys, expiration, count, target, opt_watcher) + .await + } + /// # DHT Key = Hash(ownerKeyKind) of: [ ownerKeyValue, schema ] fn get_key(vcrypto: CryptoSystemVersion, record: &Record) -> TypedKey where diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index db9e718c..d4982b22 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -181,7 +181,14 @@ impl StorageManager { let (_is_local, opt_expiration_ts) = { // See if the subkey we are watching has a local value let opt_expiration_ts = inner - .handle_watch_local_value(key, subkeys, expiration, count, target, opt_watcher) + .handle_watch_local_value( + key, + subkeys.clone(), + expiration, + count, + target.clone(), + opt_watcher, + ) .await?; if opt_expiration_ts.is_some() { (true, opt_expiration_ts) From 7917dadd30ec2b1b6fde8023f6adaa65782bcf13 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 24 Nov 2023 08:03:00 -0500 Subject: [PATCH 08/67] merge --- Earthfile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Earthfile b/Earthfile index 85c56494..8d4cb1c4 100644 --- a/Earthfile +++ b/Earthfile @@ -105,6 +105,8 @@ code-linux: ARG BASE=local IF [ "$BASE" = "local" ] FROM +build-linux-cache + ELSE IF [ "$BASE" = "uncached" ] + FROM +deps-linux ELSE ARG CI_REGISTRY_IMAGE=registry.gitlab.com/veilid/veilid FROM $CI_REGISTRY_IMAGE/build-cache:latest @@ -128,12 +130,12 @@ clippy: build-release: FROM +code-linux RUN cargo build --release -p veilid-server -p veilid-cli -p veilid-tools -p veilid-core - SAVE ARTIFACT ./target/release AS LOCAL ./target/release + SAVE ARTIFACT ./target/release AS LOCAL ./target/earthly/release build: FROM +code-linux RUN cargo build -p veilid-server -p veilid-cli -p veilid-tools -p veilid-core - SAVE ARTIFACT ./target/debug AS LOCAL ./target/debug + SAVE ARTIFACT ./target/debug AS LOCAL ./target/earthly/debug build-linux-amd64: FROM +code-linux From 9b8420d288cc45651aa6d3dc1e8735aa07a122fe Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 25 Nov 2023 15:59:43 -0800 Subject: [PATCH 09/67] more watchvalue --- .../operations/operation_watch_value.rs | 75 +- .../src/rpc_processor/rpc_watch_value.rs | 24 +- veilid-core/src/storage_manager/mod.rs | 12 + .../src/storage_manager/record_store.rs | 133 +- .../storage_manager/record_store_limits.rs | 10 +- .../storage_manager/storage_manager_inner.rs | 24 +- .../src/storage_manager/watch_value.rs | 17 +- veilid-core/src/veilid_api/routing_context.rs | 3 +- .../src/veilid_api/types/dht/schema/dflt.rs | 5 + .../src/veilid_api/types/dht/schema/mod.rs | 8 + .../src/veilid_api/types/dht/schema/smpl.rs | 10 + veilid-core/src/veilid_config.rs | 1 + veilid-flutter/example/pubspec.lock | 26 +- veilid-flutter/lib/default_config.dart | 3 +- .../lib/routing_context.freezed.dart | 344 +++-- veilid-flutter/lib/routing_context.g.dart | 52 +- veilid-flutter/lib/veilid_config.dart | 1 + veilid-flutter/lib/veilid_config.freezed.dart | 1320 +++++++++-------- veilid-flutter/lib/veilid_config.g.dart | 231 ++- veilid-flutter/lib/veilid_state.freezed.dart | 785 +++++----- veilid-flutter/lib/veilid_state.g.dart | 127 +- veilid-python/veilid/config.py | 3 +- veilid-server/src/settings.rs | 9 + 23 files changed, 1693 insertions(+), 1530 deletions(-) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index 666f358f..c114c4c7 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -9,7 +9,8 @@ pub(in crate::rpc_processor) struct RPCOperationWatchValueQ { subkeys: ValueSubkeyRangeSet, expiration: u64, count: u32, - opt_watch_signature: Option<(PublicKey, Signature)>, + watcher: PublicKey, + signature: Signature, } impl RPCOperationWatchValueQ { @@ -19,7 +20,7 @@ impl RPCOperationWatchValueQ { subkeys: ValueSubkeyRangeSet, expiration: u64, count: u32, - opt_watcher: Option, + watcher: KeyPair, vcrypto: CryptoSystemVersion, ) -> Result { // Needed because RangeSetBlaze uses different types here all the time @@ -30,22 +31,18 @@ impl RPCOperationWatchValueQ { return Err(RPCError::protocol("WatchValueQ subkeys length too long")); } - let opt_watch_signature = if let Some(watcher) = opt_watcher { - let signature_data = Self::make_signature_data(&key, &subkeys, expiration, count); - let signature = vcrypto - .sign(&watcher.key, &watcher.secret, &signature_data) - .map_err(RPCError::protocol)?; - Some((watcher.key, signature)) - } else { - None - }; + let signature_data = Self::make_signature_data(&key, &subkeys, expiration, count); + let signature = vcrypto + .sign(&watcher.key, &watcher.secret, &signature_data) + .map_err(RPCError::protocol)?; Ok(Self { key, subkeys, expiration, count, - opt_watch_signature, + watcher: watcher.key, + signature, }) } @@ -77,13 +74,11 @@ impl RPCOperationWatchValueQ { return Err(RPCError::protocol("unsupported cryptosystem")); }; - if let Some(watch_signature) = self.opt_watch_signature { - let sig_data = - Self::make_signature_data(&self.key, &self.subkeys, self.expiration, self.count); - vcrypto - .verify(&watch_signature.0, &sig_data, &watch_signature.1) - .map_err(RPCError::protocol)?; - } + let sig_data = + Self::make_signature_data(&self.key, &self.subkeys, self.expiration, self.count); + vcrypto + .verify(&self.watcher, &sig_data, &self.signature) + .map_err(RPCError::protocol)?; Ok(()) } @@ -108,10 +103,13 @@ impl RPCOperationWatchValueQ { } #[allow(dead_code)] - pub fn opt_watch_signature(&self) -> Option<&(PublicKey, Signature)> { - self.opt_watch_signature.as_ref() + pub fn watcher(&self) -> &PublicKey { + &self.watcher + } + #[allow(dead_code)] + pub fn signature(&self) -> &Signature { + &self.signature } - #[allow(dead_code)] pub fn destructure( self, @@ -120,14 +118,16 @@ impl RPCOperationWatchValueQ { ValueSubkeyRangeSet, u64, u32, - Option<(PublicKey, Signature)>, + PublicKey, + Signature, ) { ( self.key, self.subkeys, self.expiration, self.count, - self.opt_watch_signature, + self.watcher, + self.signature, ) } @@ -160,24 +160,19 @@ impl RPCOperationWatchValueQ { let expiration = reader.get_expiration(); let count = reader.get_count(); - let opt_watch_signature = if reader.has_watcher() { - let w_reader = reader.get_watcher().map_err(RPCError::protocol)?; - let watcher = decode_key256(&w_reader); + let w_reader = reader.get_watcher().map_err(RPCError::protocol)?; + let watcher = decode_key256(&w_reader); - let s_reader = reader.get_signature().map_err(RPCError::protocol)?; - let signature = decode_signature512(&s_reader); - - Some((watcher, signature)) - } else { - None - }; + let s_reader = reader.get_signature().map_err(RPCError::protocol)?; + let signature = decode_signature512(&s_reader); Ok(Self { key, subkeys, expiration, count, - opt_watch_signature, + watcher, + signature, }) } @@ -202,13 +197,11 @@ impl RPCOperationWatchValueQ { builder.set_expiration(self.expiration); builder.set_count(self.count); - if let Some(watch_signature) = self.opt_watch_signature { - let mut w_builder = builder.reborrow().init_watcher(); - encode_key256(&watch_signature.0, &mut w_builder); + let mut w_builder = builder.reborrow().init_watcher(); + encode_key256(&self.watcher, &mut w_builder); - let mut s_builder = builder.reborrow().init_signature(); - encode_signature512(&watch_signature.1, &mut s_builder); - } + let mut s_builder = builder.reborrow().init_signature(); + encode_signature512(&self.signature, &mut s_builder); Ok(()) } diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index f3dda723..0c619055 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -29,7 +29,7 @@ impl RPCProcessor { subkeys: ValueSubkeyRangeSet, expiration: Timestamp, count: u32, - opt_watcher: Option, + watcher: KeyPair, ) -> RPCNetworkResult> { // Ensure destination never has a private route // and get the target noderef so we can validate the response @@ -48,13 +48,8 @@ impl RPCProcessor { }; let debug_string = format!( - "OUT ==> WatchValueQ({} {}#{:?}@{}+{}) => {}", - key, - if opt_watcher.is_some() { "+W " } else { "" }, - subkeys, - expiration, - count, - dest + "OUT ==> WatchValueQ({} {}@{}+{}) => {} (watcher={})", + key, subkeys, expiration, count, dest, watcher.key ); // Send the watchvalue question @@ -63,7 +58,7 @@ impl RPCProcessor { subkeys, expiration.as_u64(), count, - opt_watcher, + watcher, vcrypto.clone(), )?; let question = RPCQuestion::new( @@ -179,8 +174,7 @@ impl RPCProcessor { }; // Destructure - let (key, subkeys, expiration, count, opt_watch_signature) = watch_value_q.destructure(); - let opt_watcher = opt_watch_signature.map(|ws| ws.0); + let (key, subkeys, expiration, count, watcher, signature) = watch_value_q.destructure(); // Get target for ValueChanged notifications let dest = network_result_try!(self.get_respond_to_destination(&msg)); @@ -189,13 +183,13 @@ impl RPCProcessor { #[cfg(feature = "debug-dht")] { let debug_string = format!( - "IN <=== WatchValueQ({} {}#{:?}@{}+{}) <== {}", + "IN <=== WatchValueQ({} {}@{}+{}) <== {} (watcher={})", key, - if opt_watcher.is_some() { "+W " } else { "" }, subkeys, expiration, count, - msg.header.direct_sender_node_id() + msg.header.direct_sender_node_id(), + watcher ); log_rpc!(debug "{}", debug_string); @@ -227,7 +221,7 @@ impl RPCProcessor { Timestamp::new(expiration), count, target, - opt_watcher + watcher ) .await .map_err(RPCError::internal)?) diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 0db2f0b0..e1082d5f 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -42,6 +42,9 @@ struct StorageManagerUnlockedInner { // Background processes flush_record_stores_task: TickTask, offline_subkey_writes_task: TickTask, + + // Anonymous watch keys + anonymous_watch_keys: TypedKeyPairGroup, } #[derive(Clone)] @@ -57,6 +60,14 @@ impl StorageManager { table_store: TableStore, #[cfg(feature = "unstable-blockstore")] block_store: BlockStore, ) -> StorageManagerUnlockedInner { + // Generate keys to use for anonymous watches + let mut anonymous_watch_keys = TypedKeyPairGroup::new(); + for ck in VALID_CRYPTO_KINDS { + let vcrypto = crypto.get(ck).unwrap(); + let kp = vcrypto.generate_keypair(); + anonymous_watch_keys.add(TypedKeyPair::new(ck, kp)); + } + StorageManagerUnlockedInner { config, crypto, @@ -65,6 +76,7 @@ impl StorageManager { block_store, flush_record_stores_task: TickTask::new(FLUSH_RECORD_STORES_INTERVAL_SECS), offline_subkey_writes_task: TickTask::new(OFFLINE_SUBKEY_WRITES_INTERVAL_SECS), + anonymous_watch_keys, } } fn new_inner(unlocked_inner: Arc) -> StorageManagerInner { diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index bc199b1c..245d7642 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -29,14 +29,12 @@ struct WatchedRecordWatch { expiration: Timestamp, count: u32, target: Target, - opt_watcher: Option, + watcher: CryptoKey, } -#[derive(Debug, Clone)] +#[derive(Debug, Default, Clone)] /// A record being watched for changes struct WatchedRecord { - /// Number of watchers that are anonymous - anon_count: usize, /// The list of active watchers watchers: Vec, } @@ -698,19 +696,136 @@ where } /// Add a record watch for changes - pub async fn watch_subkeys( + pub async fn watch_record( &mut self, key: TypedKey, subkeys: ValueSubkeyRangeSet, expiration: Timestamp, count: u32, target: Target, - opt_watcher: Option, + watcher: CryptoKey, ) -> VeilidAPIResult> { + // If subkeys is empty or count is zero then we're cancelling a watch completely + if subkeys.is_empty() || count == 0 { + return self.cancel_watch(key, target, watcher).await; + } - // If we have a watcher and it is in the record's schema - // then we have a guaranteed watch slot for it - xxx continue here + // See if expiration timestamp is too far in the future or not enough in the future + let cur_ts = get_timestamp(); + let max_ts = cur_ts + self.limits.max_watch_expiration.as_u64(); + let min_ts = cur_ts + self.limits.min_watch_expiration.as_u64(); + if expiration.as_u64() < min_ts || expiration.as_u64() > max_ts { + return Ok(None); + } + + // Get the record being watched + let Some(is_member) = self.with_record_mut(key, |record| { + // Check if the watcher specified is a schema member + let schema = record.schema(); + (*record.owner()) == watcher || schema.is_member(&watcher) + }) else { + // Record not found + return Ok(None); + }; + + // See if we are updating an existing watch + // with the watcher matched on target + let mut watch_count = 0; + let rtk = RecordTableKey { key }; + if let Some(watch) = self.watched_records.get_mut(&rtk) { + for w in &mut watch.watchers { + if w.watcher == watcher { + watch_count += 1; + + // Only one watch for an anonymous watcher + // Allow members to have one watch per target + if !is_member || w.target == target { + // Updating an existing watch + w.subkeys = subkeys; + w.expiration = expiration; + w.count = count; + return Ok(Some(expiration)); + } + } + } + } + + // Adding a new watcher to a watch + // Check watch table for limits + if is_member { + // Member watch + if watch_count >= self.limits.member_watch_limit { + // Too many watches + return Ok(None); + } + } else { + // Public watch + if watch_count >= self.limits.public_watch_limit { + // Too many watches + return Ok(None); + } + } + + // Ok this is an acceptable new watch, add it + let watch = self.watched_records.entry(rtk).or_default(); + watch.watchers.push(WatchedRecordWatch { + subkeys, + expiration, + count, + target, + watcher, + }); + Ok(Some(expiration)) + } + + /// Add a record watch for changes + async fn cancel_watch( + &mut self, + key: TypedKey, + target: Target, + watcher: CryptoKey, + ) -> VeilidAPIResult> { + // Get the record being watched + let Some(is_member) = self.with_record_mut(key, |record| { + // Check if the watcher specified is a schema member + let schema = record.schema(); + (*record.owner()) == watcher || schema.is_member(&watcher) + }) else { + // Record not found + return Ok(None); + }; + + // See if we are cancelling an existing watch + // with the watcher matched on target + let rtk = RecordTableKey { key }; + let mut is_empty = false; + let mut ret_timestamp = None; + if let Some(watch) = self.watched_records.get_mut(&rtk) { + let mut dead_watcher = None; + for (wn, w) in watch.watchers.iter_mut().enumerate() { + if w.watcher == watcher { + // Only one watch for an anonymous watcher + // Allow members to have one watch per target + if !is_member || w.target == target { + // Canceling an existing watch + dead_watcher = Some(wn); + ret_timestamp = Some(w.expiration); + break; + } + } + } + if let Some(dw) = dead_watcher { + watch.watchers.remove(dw); + if watch.watchers.len() == 0 { + is_empty = true; + } + } + } + if is_empty { + self.watched_records.remove(&rtk); + } + + Ok(ret_timestamp) } /// LRU out some records until we reclaim the amount of space requested diff --git a/veilid-core/src/storage_manager/record_store_limits.rs b/veilid-core/src/storage_manager/record_store_limits.rs index 6e03c713..7b273ed6 100644 --- a/veilid-core/src/storage_manager/record_store_limits.rs +++ b/veilid-core/src/storage_manager/record_store_limits.rs @@ -1,3 +1,5 @@ +use super::*; + /// Configuration for the record store #[derive(Debug, Default, Copy, Clone)] pub struct RecordStoreLimits { @@ -14,7 +16,11 @@ pub struct RecordStoreLimits { /// Limit on the amount of storage space to use for subkey data and record data pub max_storage_space_mb: Option, /// Max number of anonymous watches - pub public_watch_limit: u32, + pub public_watch_limit: usize, /// Max number of watches per schema member - pub member_watch_limit: u32, + pub member_watch_limit: usize, + /// Max expiration duration per watch + pub max_watch_expiration: TimestampDuration, + /// Min expiration duration per watch + pub min_watch_expiration: TimestampDuration, } diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index 09a935fb..03c192da 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -39,8 +39,12 @@ fn local_limits_from_config(config: VeilidConfig) -> RecordStoreLimits { max_records: None, max_subkey_cache_memory_mb: Some(c.network.dht.local_max_subkey_cache_memory_mb as usize), max_storage_space_mb: None, - public_watch_limit: c.network.dht.public_watch_limit, - member_watch_limit: c.network.dht.member_watch_limit, + public_watch_limit: c.network.dht.public_watch_limit as usize, + member_watch_limit: c.network.dht.member_watch_limit as usize, + max_watch_expiration: TimestampDuration::new(ms_to_us( + c.network.dht.max_watch_expiration_ms, + )), + min_watch_expiration: TimestampDuration::new(ms_to_us(c.network.rpc.timeout_ms)), } } @@ -53,8 +57,12 @@ fn remote_limits_from_config(config: VeilidConfig) -> RecordStoreLimits { max_records: Some(c.network.dht.remote_max_records as usize), max_subkey_cache_memory_mb: Some(c.network.dht.remote_max_subkey_cache_memory_mb as usize), max_storage_space_mb: Some(c.network.dht.remote_max_storage_space_mb as usize), - public_watch_limit: c.network.dht.public_watch_limit, - member_watch_limit: c.network.dht.member_watch_limit, + public_watch_limit: c.network.dht.public_watch_limit as usize, + member_watch_limit: c.network.dht.member_watch_limit as usize, + max_watch_expiration: TimestampDuration::new(ms_to_us( + c.network.dht.max_watch_expiration_ms, + )), + min_watch_expiration: TimestampDuration::new(ms_to_us(c.network.rpc.timeout_ms)), } } @@ -516,14 +524,14 @@ impl StorageManagerInner { expiration: Timestamp, count: u32, target: Target, - opt_watcher: Option, + watcher: CryptoKey, ) -> VeilidAPIResult> { // See if it's in the local record store let Some(local_record_store) = self.local_record_store.as_mut() else { apibail_not_initialized!(); }; local_record_store - .watch_subkeys(key, subkeys, expiration, count, target, opt_watcher) + .watch_record(key, subkeys, expiration, count, target, watcher) .await } @@ -590,14 +598,14 @@ impl StorageManagerInner { expiration: Timestamp, count: u32, target: Target, - opt_watcher: Option, + watcher: CryptoKey, ) -> VeilidAPIResult> { // See if it's in the remote record store let Some(remote_record_store) = self.remote_record_store.as_mut() else { apibail_not_initialized!(); }; remote_record_store - .watch_subkeys(key, subkeys, expiration, count, target, opt_watcher) + .watch_record(key, subkeys, expiration, count, target, watcher) .await } diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index d4982b22..9eabe7bc 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -49,6 +49,15 @@ impl StorageManager { inner.get_value_nodes(key)? }; + // Get the appropriate watcher key + let watcher = opt_watcher.unwrap_or_else(|| { + self.unlocked_inner + .anonymous_watch_keys + .get(key.kind) + .unwrap() + .value + }); + // Make do-watch-value answer context let context = Arc::new(Mutex::new(OutboundWatchValueContext { opt_watch_value_result: None, @@ -69,7 +78,7 @@ impl StorageManager { subkeys, expiration, count, - opt_watcher + watcher ) .await? ); @@ -173,7 +182,7 @@ impl StorageManager { expiration: Timestamp, count: u32, target: Target, - opt_watcher: Option, + watcher: CryptoKey, ) -> VeilidAPIResult> { let mut inner = self.lock().await?; @@ -187,7 +196,7 @@ impl StorageManager { expiration, count, target.clone(), - opt_watcher, + watcher, ) .await?; if opt_expiration_ts.is_some() { @@ -195,7 +204,7 @@ impl StorageManager { } else { // See if the subkey we are watching is a remote value let opt_expiration_ts = inner - .handle_watch_remote_value(key, subkeys, expiration, count, target, opt_watcher) + .handle_watch_remote_value(key, subkeys, expiration, count, target, watcher) .await?; (false, opt_expiration_ts) } diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index a40df864..a1373b82 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -1,10 +1,9 @@ use super::*; -use routing_table::NodeRefBase; /////////////////////////////////////////////////////////////////////////////////////// /// Valid destinations for a message sent over a routing context -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Eq, PartialEq)] pub enum Target { /// Node by its public key NodeId(TypedKey), diff --git a/veilid-core/src/veilid_api/types/dht/schema/dflt.rs b/veilid-core/src/veilid_api/types/dht/schema/dflt.rs index a6a5aee5..9ff10b8e 100644 --- a/veilid-core/src/veilid_api/types/dht/schema/dflt.rs +++ b/veilid-core/src/veilid_api/types/dht/schema/dflt.rs @@ -53,6 +53,11 @@ impl DHTSchemaDFLT { // Subkey out of range false } + + /// Check if a key is a schema member + pub fn is_member(&self, key: &PublicKey) -> bool { + false + } } impl TryFrom<&[u8]> for DHTSchemaDFLT { diff --git a/veilid-core/src/veilid_api/types/dht/schema/mod.rs b/veilid-core/src/veilid_api/types/dht/schema/mod.rs index 1b9bf4c3..42213240 100644 --- a/veilid-core/src/veilid_api/types/dht/schema/mod.rs +++ b/veilid-core/src/veilid_api/types/dht/schema/mod.rs @@ -59,6 +59,14 @@ impl DHTSchema { DHTSchema::SMPL(s) => s.check_subkey_value_data(owner, subkey, value_data), } } + + /// Check if a key is a schema member + pub fn is_member(&self, key: &PublicKey) -> bool { + match self { + DHTSchema::DFLT(d) => d.is_member(key), + DHTSchema::SMPL(s) => s.is_member(key), + } + } } impl Default for DHTSchema { diff --git a/veilid-core/src/veilid_api/types/dht/schema/smpl.rs b/veilid-core/src/veilid_api/types/dht/schema/smpl.rs index 21163bc1..93093eec 100644 --- a/veilid-core/src/veilid_api/types/dht/schema/smpl.rs +++ b/veilid-core/src/veilid_api/types/dht/schema/smpl.rs @@ -93,6 +93,16 @@ impl DHTSchemaSMPL { // Subkey out of range false } + + /// Check if a key is a schema member + pub fn is_member(&self, key: &PublicKey) -> bool { + for m in &self.members { + if m.m_key == *key { + return true; + } + } + false + } } impl TryFrom<&[u8]> for DHTSchemaSMPL { diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index 91f8be7c..19830002 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -303,6 +303,7 @@ pub struct VeilidConfigDHT { pub remote_max_storage_space_mb: u32, pub public_watch_limit: u32, pub member_watch_limit: u32, + pub max_watch_expiration_ms: u32, } impl Default for VeilidConfigDHT { diff --git a/veilid-flutter/example/pubspec.lock b/veilid-flutter/example/pubspec.lock index 28671d7b..73fc4fc6 100644 --- a/veilid-flutter/example/pubspec.lock +++ b/veilid-flutter/example/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.2" convert: dependency: transitive description: @@ -220,10 +220,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" path: dependency: "direct main" description: @@ -329,18 +329,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" string_scanner: dependency: transitive description: @@ -377,10 +377,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.6.0" typed_data: dependency: transitive description: @@ -408,10 +408,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.1.4-beta" win32: dependency: transitive description: @@ -437,5 +437,5 @@ packages: source: hosted version: "3.5.0" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.1.0-185.0.dev <4.0.0" flutter: ">=3.10.6" diff --git a/veilid-flutter/lib/default_config.dart b/veilid-flutter/lib/default_config.dart index 906ac498..eeb1833a 100644 --- a/veilid-flutter/lib/default_config.dart +++ b/veilid-flutter/lib/default_config.dart @@ -140,7 +140,8 @@ Future getDefaultVeilidConfig(String programName) async { remoteMaxSubkeyCacheMemoryMb: await getRemoteMaxSubkeyCacheMemoryMb(), remoteMaxStorageSpaceMb: getRemoteMaxStorageSpaceMb(), publicWatchLimit: 32, - memberWatchLimit: 8), + memberWatchLimit: 8, + maxWatchExpirationMs: 600000), upnp: true, detectAddressChanges: true, restrictedNatRetries: 0, diff --git a/veilid-flutter/lib/routing_context.freezed.dart b/veilid-flutter/lib/routing_context.freezed.dart index 57ba287d..af4f4aab 100644 --- a/veilid-flutter/lib/routing_context.freezed.dart +++ b/veilid-flutter/lib/routing_context.freezed.dart @@ -107,22 +107,22 @@ class _$DHTSchemaCopyWithImpl<$Res, $Val extends DHTSchema> } /// @nodoc -abstract class _$$DHTSchemaDFLTImplCopyWith<$Res> +abstract class _$$DHTSchemaDFLTCopyWith<$Res> implements $DHTSchemaCopyWith<$Res> { - factory _$$DHTSchemaDFLTImplCopyWith( - _$DHTSchemaDFLTImpl value, $Res Function(_$DHTSchemaDFLTImpl) then) = - __$$DHTSchemaDFLTImplCopyWithImpl<$Res>; + factory _$$DHTSchemaDFLTCopyWith( + _$DHTSchemaDFLT value, $Res Function(_$DHTSchemaDFLT) then) = + __$$DHTSchemaDFLTCopyWithImpl<$Res>; @override @useResult $Res call({int oCnt}); } /// @nodoc -class __$$DHTSchemaDFLTImplCopyWithImpl<$Res> - extends _$DHTSchemaCopyWithImpl<$Res, _$DHTSchemaDFLTImpl> - implements _$$DHTSchemaDFLTImplCopyWith<$Res> { - __$$DHTSchemaDFLTImplCopyWithImpl( - _$DHTSchemaDFLTImpl _value, $Res Function(_$DHTSchemaDFLTImpl) _then) +class __$$DHTSchemaDFLTCopyWithImpl<$Res> + extends _$DHTSchemaCopyWithImpl<$Res, _$DHTSchemaDFLT> + implements _$$DHTSchemaDFLTCopyWith<$Res> { + __$$DHTSchemaDFLTCopyWithImpl( + _$DHTSchemaDFLT _value, $Res Function(_$DHTSchemaDFLT) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -130,7 +130,7 @@ class __$$DHTSchemaDFLTImplCopyWithImpl<$Res> $Res call({ Object? oCnt = null, }) { - return _then(_$DHTSchemaDFLTImpl( + return _then(_$DHTSchemaDFLT( oCnt: null == oCnt ? _value.oCnt : oCnt // ignore: cast_nullable_to_non_nullable @@ -141,12 +141,12 @@ class __$$DHTSchemaDFLTImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$DHTSchemaDFLTImpl implements DHTSchemaDFLT { - const _$DHTSchemaDFLTImpl({required this.oCnt, final String? $type}) +class _$DHTSchemaDFLT implements DHTSchemaDFLT { + const _$DHTSchemaDFLT({required this.oCnt, final String? $type}) : $type = $type ?? 'DFLT'; - factory _$DHTSchemaDFLTImpl.fromJson(Map json) => - _$$DHTSchemaDFLTImplFromJson(json); + factory _$DHTSchemaDFLT.fromJson(Map json) => + _$$DHTSchemaDFLTFromJson(json); @override final int oCnt; @@ -163,7 +163,7 @@ class _$DHTSchemaDFLTImpl implements DHTSchemaDFLT { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DHTSchemaDFLTImpl && + other is _$DHTSchemaDFLT && (identical(other.oCnt, oCnt) || other.oCnt == oCnt)); } @@ -174,8 +174,8 @@ class _$DHTSchemaDFLTImpl implements DHTSchemaDFLT { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$DHTSchemaDFLTImplCopyWith<_$DHTSchemaDFLTImpl> get copyWith => - __$$DHTSchemaDFLTImplCopyWithImpl<_$DHTSchemaDFLTImpl>(this, _$identity); + _$$DHTSchemaDFLTCopyWith<_$DHTSchemaDFLT> get copyWith => + __$$DHTSchemaDFLTCopyWithImpl<_$DHTSchemaDFLT>(this, _$identity); @override @optionalTypeArgs @@ -241,43 +241,43 @@ class _$DHTSchemaDFLTImpl implements DHTSchemaDFLT { @override Map toJson() { - return _$$DHTSchemaDFLTImplToJson( + return _$$DHTSchemaDFLTToJson( this, ); } } abstract class DHTSchemaDFLT implements DHTSchema { - const factory DHTSchemaDFLT({required final int oCnt}) = _$DHTSchemaDFLTImpl; + const factory DHTSchemaDFLT({required final int oCnt}) = _$DHTSchemaDFLT; factory DHTSchemaDFLT.fromJson(Map json) = - _$DHTSchemaDFLTImpl.fromJson; + _$DHTSchemaDFLT.fromJson; @override int get oCnt; @override @JsonKey(ignore: true) - _$$DHTSchemaDFLTImplCopyWith<_$DHTSchemaDFLTImpl> get copyWith => + _$$DHTSchemaDFLTCopyWith<_$DHTSchemaDFLT> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$DHTSchemaSMPLImplCopyWith<$Res> +abstract class _$$DHTSchemaSMPLCopyWith<$Res> implements $DHTSchemaCopyWith<$Res> { - factory _$$DHTSchemaSMPLImplCopyWith( - _$DHTSchemaSMPLImpl value, $Res Function(_$DHTSchemaSMPLImpl) then) = - __$$DHTSchemaSMPLImplCopyWithImpl<$Res>; + factory _$$DHTSchemaSMPLCopyWith( + _$DHTSchemaSMPL value, $Res Function(_$DHTSchemaSMPL) then) = + __$$DHTSchemaSMPLCopyWithImpl<$Res>; @override @useResult $Res call({int oCnt, List members}); } /// @nodoc -class __$$DHTSchemaSMPLImplCopyWithImpl<$Res> - extends _$DHTSchemaCopyWithImpl<$Res, _$DHTSchemaSMPLImpl> - implements _$$DHTSchemaSMPLImplCopyWith<$Res> { - __$$DHTSchemaSMPLImplCopyWithImpl( - _$DHTSchemaSMPLImpl _value, $Res Function(_$DHTSchemaSMPLImpl) _then) +class __$$DHTSchemaSMPLCopyWithImpl<$Res> + extends _$DHTSchemaCopyWithImpl<$Res, _$DHTSchemaSMPL> + implements _$$DHTSchemaSMPLCopyWith<$Res> { + __$$DHTSchemaSMPLCopyWithImpl( + _$DHTSchemaSMPL _value, $Res Function(_$DHTSchemaSMPL) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -286,7 +286,7 @@ class __$$DHTSchemaSMPLImplCopyWithImpl<$Res> Object? oCnt = null, Object? members = null, }) { - return _then(_$DHTSchemaSMPLImpl( + return _then(_$DHTSchemaSMPL( oCnt: null == oCnt ? _value.oCnt : oCnt // ignore: cast_nullable_to_non_nullable @@ -301,16 +301,16 @@ class __$$DHTSchemaSMPLImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$DHTSchemaSMPLImpl implements DHTSchemaSMPL { - const _$DHTSchemaSMPLImpl( +class _$DHTSchemaSMPL implements DHTSchemaSMPL { + const _$DHTSchemaSMPL( {required this.oCnt, required final List members, final String? $type}) : _members = members, $type = $type ?? 'SMPL'; - factory _$DHTSchemaSMPLImpl.fromJson(Map json) => - _$$DHTSchemaSMPLImplFromJson(json); + factory _$DHTSchemaSMPL.fromJson(Map json) => + _$$DHTSchemaSMPLFromJson(json); @override final int oCnt; @@ -334,7 +334,7 @@ class _$DHTSchemaSMPLImpl implements DHTSchemaSMPL { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DHTSchemaSMPLImpl && + other is _$DHTSchemaSMPL && (identical(other.oCnt, oCnt) || other.oCnt == oCnt) && const DeepCollectionEquality().equals(other._members, _members)); } @@ -347,8 +347,8 @@ class _$DHTSchemaSMPLImpl implements DHTSchemaSMPL { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$DHTSchemaSMPLImplCopyWith<_$DHTSchemaSMPLImpl> get copyWith => - __$$DHTSchemaSMPLImplCopyWithImpl<_$DHTSchemaSMPLImpl>(this, _$identity); + _$$DHTSchemaSMPLCopyWith<_$DHTSchemaSMPL> get copyWith => + __$$DHTSchemaSMPLCopyWithImpl<_$DHTSchemaSMPL>(this, _$identity); @override @optionalTypeArgs @@ -414,7 +414,7 @@ class _$DHTSchemaSMPLImpl implements DHTSchemaSMPL { @override Map toJson() { - return _$$DHTSchemaSMPLImplToJson( + return _$$DHTSchemaSMPLToJson( this, ); } @@ -423,17 +423,17 @@ class _$DHTSchemaSMPLImpl implements DHTSchemaSMPL { abstract class DHTSchemaSMPL implements DHTSchema { const factory DHTSchemaSMPL( {required final int oCnt, - required final List members}) = _$DHTSchemaSMPLImpl; + required final List members}) = _$DHTSchemaSMPL; factory DHTSchemaSMPL.fromJson(Map json) = - _$DHTSchemaSMPLImpl.fromJson; + _$DHTSchemaSMPL.fromJson; @override int get oCnt; List get members; @override @JsonKey(ignore: true) - _$$DHTSchemaSMPLImplCopyWith<_$DHTSchemaSMPLImpl> get copyWith => + _$$DHTSchemaSMPLCopyWith<_$DHTSchemaSMPL> get copyWith => throw _privateConstructorUsedError; } @@ -491,22 +491,22 @@ class _$DHTSchemaMemberCopyWithImpl<$Res, $Val extends DHTSchemaMember> } /// @nodoc -abstract class _$$DHTSchemaMemberImplCopyWith<$Res> +abstract class _$$_DHTSchemaMemberCopyWith<$Res> implements $DHTSchemaMemberCopyWith<$Res> { - factory _$$DHTSchemaMemberImplCopyWith(_$DHTSchemaMemberImpl value, - $Res Function(_$DHTSchemaMemberImpl) then) = - __$$DHTSchemaMemberImplCopyWithImpl<$Res>; + factory _$$_DHTSchemaMemberCopyWith( + _$_DHTSchemaMember value, $Res Function(_$_DHTSchemaMember) then) = + __$$_DHTSchemaMemberCopyWithImpl<$Res>; @override @useResult $Res call({FixedEncodedString43 mKey, int mCnt}); } /// @nodoc -class __$$DHTSchemaMemberImplCopyWithImpl<$Res> - extends _$DHTSchemaMemberCopyWithImpl<$Res, _$DHTSchemaMemberImpl> - implements _$$DHTSchemaMemberImplCopyWith<$Res> { - __$$DHTSchemaMemberImplCopyWithImpl( - _$DHTSchemaMemberImpl _value, $Res Function(_$DHTSchemaMemberImpl) _then) +class __$$_DHTSchemaMemberCopyWithImpl<$Res> + extends _$DHTSchemaMemberCopyWithImpl<$Res, _$_DHTSchemaMember> + implements _$$_DHTSchemaMemberCopyWith<$Res> { + __$$_DHTSchemaMemberCopyWithImpl( + _$_DHTSchemaMember _value, $Res Function(_$_DHTSchemaMember) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -515,7 +515,7 @@ class __$$DHTSchemaMemberImplCopyWithImpl<$Res> Object? mKey = null, Object? mCnt = null, }) { - return _then(_$DHTSchemaMemberImpl( + return _then(_$_DHTSchemaMember( mKey: null == mKey ? _value.mKey : mKey // ignore: cast_nullable_to_non_nullable @@ -530,12 +530,12 @@ class __$$DHTSchemaMemberImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$DHTSchemaMemberImpl implements _DHTSchemaMember { - const _$DHTSchemaMemberImpl({required this.mKey, required this.mCnt}) +class _$_DHTSchemaMember implements _DHTSchemaMember { + const _$_DHTSchemaMember({required this.mKey, required this.mCnt}) : assert(mCnt > 0 && mCnt <= 65535, 'value out of range'); - factory _$DHTSchemaMemberImpl.fromJson(Map json) => - _$$DHTSchemaMemberImplFromJson(json); + factory _$_DHTSchemaMember.fromJson(Map json) => + _$$_DHTSchemaMemberFromJson(json); @override final FixedEncodedString43 mKey; @@ -551,7 +551,7 @@ class _$DHTSchemaMemberImpl implements _DHTSchemaMember { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DHTSchemaMemberImpl && + other is _$_DHTSchemaMember && (identical(other.mKey, mKey) || other.mKey == mKey) && (identical(other.mCnt, mCnt) || other.mCnt == mCnt)); } @@ -563,13 +563,12 @@ class _$DHTSchemaMemberImpl implements _DHTSchemaMember { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$DHTSchemaMemberImplCopyWith<_$DHTSchemaMemberImpl> get copyWith => - __$$DHTSchemaMemberImplCopyWithImpl<_$DHTSchemaMemberImpl>( - this, _$identity); + _$$_DHTSchemaMemberCopyWith<_$_DHTSchemaMember> get copyWith => + __$$_DHTSchemaMemberCopyWithImpl<_$_DHTSchemaMember>(this, _$identity); @override Map toJson() { - return _$$DHTSchemaMemberImplToJson( + return _$$_DHTSchemaMemberToJson( this, ); } @@ -578,10 +577,10 @@ class _$DHTSchemaMemberImpl implements _DHTSchemaMember { abstract class _DHTSchemaMember implements DHTSchemaMember { const factory _DHTSchemaMember( {required final FixedEncodedString43 mKey, - required final int mCnt}) = _$DHTSchemaMemberImpl; + required final int mCnt}) = _$_DHTSchemaMember; factory _DHTSchemaMember.fromJson(Map json) = - _$DHTSchemaMemberImpl.fromJson; + _$_DHTSchemaMember.fromJson; @override FixedEncodedString43 get mKey; @@ -589,7 +588,7 @@ abstract class _DHTSchemaMember implements DHTSchemaMember { int get mCnt; @override @JsonKey(ignore: true) - _$$DHTSchemaMemberImplCopyWith<_$DHTSchemaMemberImpl> get copyWith => + _$$_DHTSchemaMemberCopyWith<_$_DHTSchemaMember> get copyWith => throw _privateConstructorUsedError; } @@ -673,11 +672,11 @@ class _$DHTRecordDescriptorCopyWithImpl<$Res, $Val extends DHTRecordDescriptor> } /// @nodoc -abstract class _$$DHTRecordDescriptorImplCopyWith<$Res> +abstract class _$$_DHTRecordDescriptorCopyWith<$Res> implements $DHTRecordDescriptorCopyWith<$Res> { - factory _$$DHTRecordDescriptorImplCopyWith(_$DHTRecordDescriptorImpl value, - $Res Function(_$DHTRecordDescriptorImpl) then) = - __$$DHTRecordDescriptorImplCopyWithImpl<$Res>; + factory _$$_DHTRecordDescriptorCopyWith(_$_DHTRecordDescriptor value, + $Res Function(_$_DHTRecordDescriptor) then) = + __$$_DHTRecordDescriptorCopyWithImpl<$Res>; @override @useResult $Res call( @@ -691,11 +690,11 @@ abstract class _$$DHTRecordDescriptorImplCopyWith<$Res> } /// @nodoc -class __$$DHTRecordDescriptorImplCopyWithImpl<$Res> - extends _$DHTRecordDescriptorCopyWithImpl<$Res, _$DHTRecordDescriptorImpl> - implements _$$DHTRecordDescriptorImplCopyWith<$Res> { - __$$DHTRecordDescriptorImplCopyWithImpl(_$DHTRecordDescriptorImpl _value, - $Res Function(_$DHTRecordDescriptorImpl) _then) +class __$$_DHTRecordDescriptorCopyWithImpl<$Res> + extends _$DHTRecordDescriptorCopyWithImpl<$Res, _$_DHTRecordDescriptor> + implements _$$_DHTRecordDescriptorCopyWith<$Res> { + __$$_DHTRecordDescriptorCopyWithImpl(_$_DHTRecordDescriptor _value, + $Res Function(_$_DHTRecordDescriptor) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -706,7 +705,7 @@ class __$$DHTRecordDescriptorImplCopyWithImpl<$Res> Object? schema = null, Object? ownerSecret = freezed, }) { - return _then(_$DHTRecordDescriptorImpl( + return _then(_$_DHTRecordDescriptor( key: null == key ? _value.key : key // ignore: cast_nullable_to_non_nullable @@ -729,15 +728,15 @@ class __$$DHTRecordDescriptorImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$DHTRecordDescriptorImpl implements _DHTRecordDescriptor { - const _$DHTRecordDescriptorImpl( +class _$_DHTRecordDescriptor implements _DHTRecordDescriptor { + const _$_DHTRecordDescriptor( {required this.key, required this.owner, required this.schema, this.ownerSecret}); - factory _$DHTRecordDescriptorImpl.fromJson(Map json) => - _$$DHTRecordDescriptorImplFromJson(json); + factory _$_DHTRecordDescriptor.fromJson(Map json) => + _$$_DHTRecordDescriptorFromJson(json); @override final Typed key; @@ -757,7 +756,7 @@ class _$DHTRecordDescriptorImpl implements _DHTRecordDescriptor { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$DHTRecordDescriptorImpl && + other is _$_DHTRecordDescriptor && (identical(other.key, key) || other.key == key) && (identical(other.owner, owner) || other.owner == owner) && (identical(other.schema, schema) || other.schema == schema) && @@ -772,13 +771,13 @@ class _$DHTRecordDescriptorImpl implements _DHTRecordDescriptor { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$DHTRecordDescriptorImplCopyWith<_$DHTRecordDescriptorImpl> get copyWith => - __$$DHTRecordDescriptorImplCopyWithImpl<_$DHTRecordDescriptorImpl>( + _$$_DHTRecordDescriptorCopyWith<_$_DHTRecordDescriptor> get copyWith => + __$$_DHTRecordDescriptorCopyWithImpl<_$_DHTRecordDescriptor>( this, _$identity); @override Map toJson() { - return _$$DHTRecordDescriptorImplToJson( + return _$$_DHTRecordDescriptorToJson( this, ); } @@ -789,10 +788,10 @@ abstract class _DHTRecordDescriptor implements DHTRecordDescriptor { {required final Typed key, required final FixedEncodedString43 owner, required final DHTSchema schema, - final FixedEncodedString43? ownerSecret}) = _$DHTRecordDescriptorImpl; + final FixedEncodedString43? ownerSecret}) = _$_DHTRecordDescriptor; factory _DHTRecordDescriptor.fromJson(Map json) = - _$DHTRecordDescriptorImpl.fromJson; + _$_DHTRecordDescriptor.fromJson; @override Typed get key; @@ -804,7 +803,7 @@ abstract class _DHTRecordDescriptor implements DHTRecordDescriptor { FixedEncodedString43? get ownerSecret; @override @JsonKey(ignore: true) - _$$DHTRecordDescriptorImplCopyWith<_$DHTRecordDescriptorImpl> get copyWith => + _$$_DHTRecordDescriptorCopyWith<_$_DHTRecordDescriptor> get copyWith => throw _privateConstructorUsedError; } @@ -862,22 +861,22 @@ class _$ValueSubkeyRangeCopyWithImpl<$Res, $Val extends ValueSubkeyRange> } /// @nodoc -abstract class _$$ValueSubkeyRangeImplCopyWith<$Res> +abstract class _$$_ValueSubkeyRangeCopyWith<$Res> implements $ValueSubkeyRangeCopyWith<$Res> { - factory _$$ValueSubkeyRangeImplCopyWith(_$ValueSubkeyRangeImpl value, - $Res Function(_$ValueSubkeyRangeImpl) then) = - __$$ValueSubkeyRangeImplCopyWithImpl<$Res>; + factory _$$_ValueSubkeyRangeCopyWith( + _$_ValueSubkeyRange value, $Res Function(_$_ValueSubkeyRange) then) = + __$$_ValueSubkeyRangeCopyWithImpl<$Res>; @override @useResult $Res call({int low, int high}); } /// @nodoc -class __$$ValueSubkeyRangeImplCopyWithImpl<$Res> - extends _$ValueSubkeyRangeCopyWithImpl<$Res, _$ValueSubkeyRangeImpl> - implements _$$ValueSubkeyRangeImplCopyWith<$Res> { - __$$ValueSubkeyRangeImplCopyWithImpl(_$ValueSubkeyRangeImpl _value, - $Res Function(_$ValueSubkeyRangeImpl) _then) +class __$$_ValueSubkeyRangeCopyWithImpl<$Res> + extends _$ValueSubkeyRangeCopyWithImpl<$Res, _$_ValueSubkeyRange> + implements _$$_ValueSubkeyRangeCopyWith<$Res> { + __$$_ValueSubkeyRangeCopyWithImpl( + _$_ValueSubkeyRange _value, $Res Function(_$_ValueSubkeyRange) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -886,7 +885,7 @@ class __$$ValueSubkeyRangeImplCopyWithImpl<$Res> Object? low = null, Object? high = null, }) { - return _then(_$ValueSubkeyRangeImpl( + return _then(_$_ValueSubkeyRange( low: null == low ? _value.low : low // ignore: cast_nullable_to_non_nullable @@ -901,13 +900,13 @@ class __$$ValueSubkeyRangeImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$ValueSubkeyRangeImpl implements _ValueSubkeyRange { - const _$ValueSubkeyRangeImpl({required this.low, required this.high}) +class _$_ValueSubkeyRange implements _ValueSubkeyRange { + const _$_ValueSubkeyRange({required this.low, required this.high}) : assert(low < 0 || low > high, 'low out of range'), assert(high < 0, 'high out of range'); - factory _$ValueSubkeyRangeImpl.fromJson(Map json) => - _$$ValueSubkeyRangeImplFromJson(json); + factory _$_ValueSubkeyRange.fromJson(Map json) => + _$$_ValueSubkeyRangeFromJson(json); @override final int low; @@ -923,7 +922,7 @@ class _$ValueSubkeyRangeImpl implements _ValueSubkeyRange { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$ValueSubkeyRangeImpl && + other is _$_ValueSubkeyRange && (identical(other.low, low) || other.low == low) && (identical(other.high, high) || other.high == high)); } @@ -935,13 +934,12 @@ class _$ValueSubkeyRangeImpl implements _ValueSubkeyRange { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$ValueSubkeyRangeImplCopyWith<_$ValueSubkeyRangeImpl> get copyWith => - __$$ValueSubkeyRangeImplCopyWithImpl<_$ValueSubkeyRangeImpl>( - this, _$identity); + _$$_ValueSubkeyRangeCopyWith<_$_ValueSubkeyRange> get copyWith => + __$$_ValueSubkeyRangeCopyWithImpl<_$_ValueSubkeyRange>(this, _$identity); @override Map toJson() { - return _$$ValueSubkeyRangeImplToJson( + return _$$_ValueSubkeyRangeToJson( this, ); } @@ -949,11 +947,10 @@ class _$ValueSubkeyRangeImpl implements _ValueSubkeyRange { abstract class _ValueSubkeyRange implements ValueSubkeyRange { const factory _ValueSubkeyRange( - {required final int low, - required final int high}) = _$ValueSubkeyRangeImpl; + {required final int low, required final int high}) = _$_ValueSubkeyRange; factory _ValueSubkeyRange.fromJson(Map json) = - _$ValueSubkeyRangeImpl.fromJson; + _$_ValueSubkeyRange.fromJson; @override int get low; @@ -961,7 +958,7 @@ abstract class _ValueSubkeyRange implements ValueSubkeyRange { int get high; @override @JsonKey(ignore: true) - _$$ValueSubkeyRangeImplCopyWith<_$ValueSubkeyRangeImpl> get copyWith => + _$$_ValueSubkeyRangeCopyWith<_$_ValueSubkeyRange> get copyWith => throw _privateConstructorUsedError; } @@ -1028,11 +1025,10 @@ class _$ValueDataCopyWithImpl<$Res, $Val extends ValueData> } /// @nodoc -abstract class _$$ValueDataImplCopyWith<$Res> - implements $ValueDataCopyWith<$Res> { - factory _$$ValueDataImplCopyWith( - _$ValueDataImpl value, $Res Function(_$ValueDataImpl) then) = - __$$ValueDataImplCopyWithImpl<$Res>; +abstract class _$$_ValueDataCopyWith<$Res> implements $ValueDataCopyWith<$Res> { + factory _$$_ValueDataCopyWith( + _$_ValueData value, $Res Function(_$_ValueData) then) = + __$$_ValueDataCopyWithImpl<$Res>; @override @useResult $Res call( @@ -1042,11 +1038,11 @@ abstract class _$$ValueDataImplCopyWith<$Res> } /// @nodoc -class __$$ValueDataImplCopyWithImpl<$Res> - extends _$ValueDataCopyWithImpl<$Res, _$ValueDataImpl> - implements _$$ValueDataImplCopyWith<$Res> { - __$$ValueDataImplCopyWithImpl( - _$ValueDataImpl _value, $Res Function(_$ValueDataImpl) _then) +class __$$_ValueDataCopyWithImpl<$Res> + extends _$ValueDataCopyWithImpl<$Res, _$_ValueData> + implements _$$_ValueDataCopyWith<$Res> { + __$$_ValueDataCopyWithImpl( + _$_ValueData _value, $Res Function(_$_ValueData) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1056,7 +1052,7 @@ class __$$ValueDataImplCopyWithImpl<$Res> Object? data = null, Object? writer = null, }) { - return _then(_$ValueDataImpl( + return _then(_$_ValueData( seq: null == seq ? _value.seq : seq // ignore: cast_nullable_to_non_nullable @@ -1075,15 +1071,15 @@ class __$$ValueDataImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$ValueDataImpl implements _ValueData { - const _$ValueDataImpl( +class _$_ValueData implements _ValueData { + const _$_ValueData( {required this.seq, @Uint8ListJsonConverter.jsIsArray() required this.data, required this.writer}) : assert(seq >= 0, 'seq out of range'); - factory _$ValueDataImpl.fromJson(Map json) => - _$$ValueDataImplFromJson(json); + factory _$_ValueData.fromJson(Map json) => + _$$_ValueDataFromJson(json); @override final int seq; @@ -1102,7 +1098,7 @@ class _$ValueDataImpl implements _ValueData { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$ValueDataImpl && + other is _$_ValueData && (identical(other.seq, seq) || other.seq == seq) && const DeepCollectionEquality().equals(other.data, data) && (identical(other.writer, writer) || other.writer == writer)); @@ -1116,12 +1112,12 @@ class _$ValueDataImpl implements _ValueData { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$ValueDataImplCopyWith<_$ValueDataImpl> get copyWith => - __$$ValueDataImplCopyWithImpl<_$ValueDataImpl>(this, _$identity); + _$$_ValueDataCopyWith<_$_ValueData> get copyWith => + __$$_ValueDataCopyWithImpl<_$_ValueData>(this, _$identity); @override Map toJson() { - return _$$ValueDataImplToJson( + return _$$_ValueDataToJson( this, ); } @@ -1131,10 +1127,10 @@ abstract class _ValueData implements ValueData { const factory _ValueData( {required final int seq, @Uint8ListJsonConverter.jsIsArray() required final Uint8List data, - required final FixedEncodedString43 writer}) = _$ValueDataImpl; + required final FixedEncodedString43 writer}) = _$_ValueData; factory _ValueData.fromJson(Map json) = - _$ValueDataImpl.fromJson; + _$_ValueData.fromJson; @override int get seq; @@ -1145,7 +1141,7 @@ abstract class _ValueData implements ValueData { FixedEncodedString43 get writer; @override @JsonKey(ignore: true) - _$$ValueDataImplCopyWith<_$ValueDataImpl> get copyWith => + _$$_ValueDataCopyWith<_$_ValueData> get copyWith => throw _privateConstructorUsedError; } @@ -1219,11 +1215,11 @@ class _$SafetySpecCopyWithImpl<$Res, $Val extends SafetySpec> } /// @nodoc -abstract class _$$SafetySpecImplCopyWith<$Res> +abstract class _$$_SafetySpecCopyWith<$Res> implements $SafetySpecCopyWith<$Res> { - factory _$$SafetySpecImplCopyWith( - _$SafetySpecImpl value, $Res Function(_$SafetySpecImpl) then) = - __$$SafetySpecImplCopyWithImpl<$Res>; + factory _$$_SafetySpecCopyWith( + _$_SafetySpec value, $Res Function(_$_SafetySpec) then) = + __$$_SafetySpecCopyWithImpl<$Res>; @override @useResult $Res call( @@ -1234,11 +1230,11 @@ abstract class _$$SafetySpecImplCopyWith<$Res> } /// @nodoc -class __$$SafetySpecImplCopyWithImpl<$Res> - extends _$SafetySpecCopyWithImpl<$Res, _$SafetySpecImpl> - implements _$$SafetySpecImplCopyWith<$Res> { - __$$SafetySpecImplCopyWithImpl( - _$SafetySpecImpl _value, $Res Function(_$SafetySpecImpl) _then) +class __$$_SafetySpecCopyWithImpl<$Res> + extends _$SafetySpecCopyWithImpl<$Res, _$_SafetySpec> + implements _$$_SafetySpecCopyWith<$Res> { + __$$_SafetySpecCopyWithImpl( + _$_SafetySpec _value, $Res Function(_$_SafetySpec) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1249,7 +1245,7 @@ class __$$SafetySpecImplCopyWithImpl<$Res> Object? sequencing = null, Object? preferredRoute = freezed, }) { - return _then(_$SafetySpecImpl( + return _then(_$_SafetySpec( hopCount: null == hopCount ? _value.hopCount : hopCount // ignore: cast_nullable_to_non_nullable @@ -1272,15 +1268,15 @@ class __$$SafetySpecImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$SafetySpecImpl implements _SafetySpec { - const _$SafetySpecImpl( +class _$_SafetySpec implements _SafetySpec { + const _$_SafetySpec( {required this.hopCount, required this.stability, required this.sequencing, this.preferredRoute}); - factory _$SafetySpecImpl.fromJson(Map json) => - _$$SafetySpecImplFromJson(json); + factory _$_SafetySpec.fromJson(Map json) => + _$$_SafetySpecFromJson(json); @override final int hopCount; @@ -1300,7 +1296,7 @@ class _$SafetySpecImpl implements _SafetySpec { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$SafetySpecImpl && + other is _$_SafetySpec && (identical(other.hopCount, hopCount) || other.hopCount == hopCount) && (identical(other.stability, stability) || @@ -1319,12 +1315,12 @@ class _$SafetySpecImpl implements _SafetySpec { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$SafetySpecImplCopyWith<_$SafetySpecImpl> get copyWith => - __$$SafetySpecImplCopyWithImpl<_$SafetySpecImpl>(this, _$identity); + _$$_SafetySpecCopyWith<_$_SafetySpec> get copyWith => + __$$_SafetySpecCopyWithImpl<_$_SafetySpec>(this, _$identity); @override Map toJson() { - return _$$SafetySpecImplToJson( + return _$$_SafetySpecToJson( this, ); } @@ -1335,10 +1331,10 @@ abstract class _SafetySpec implements SafetySpec { {required final int hopCount, required final Stability stability, required final Sequencing sequencing, - final String? preferredRoute}) = _$SafetySpecImpl; + final String? preferredRoute}) = _$_SafetySpec; factory _SafetySpec.fromJson(Map json) = - _$SafetySpecImpl.fromJson; + _$_SafetySpec.fromJson; @override int get hopCount; @@ -1350,7 +1346,7 @@ abstract class _SafetySpec implements SafetySpec { String? get preferredRoute; @override @JsonKey(ignore: true) - _$$SafetySpecImplCopyWith<_$SafetySpecImpl> get copyWith => + _$$_SafetySpecCopyWith<_$_SafetySpec> get copyWith => throw _privateConstructorUsedError; } @@ -1408,22 +1404,21 @@ class _$RouteBlobCopyWithImpl<$Res, $Val extends RouteBlob> } /// @nodoc -abstract class _$$RouteBlobImplCopyWith<$Res> - implements $RouteBlobCopyWith<$Res> { - factory _$$RouteBlobImplCopyWith( - _$RouteBlobImpl value, $Res Function(_$RouteBlobImpl) then) = - __$$RouteBlobImplCopyWithImpl<$Res>; +abstract class _$$_RouteBlobCopyWith<$Res> implements $RouteBlobCopyWith<$Res> { + factory _$$_RouteBlobCopyWith( + _$_RouteBlob value, $Res Function(_$_RouteBlob) then) = + __$$_RouteBlobCopyWithImpl<$Res>; @override @useResult $Res call({String routeId, @Uint8ListJsonConverter() Uint8List blob}); } /// @nodoc -class __$$RouteBlobImplCopyWithImpl<$Res> - extends _$RouteBlobCopyWithImpl<$Res, _$RouteBlobImpl> - implements _$$RouteBlobImplCopyWith<$Res> { - __$$RouteBlobImplCopyWithImpl( - _$RouteBlobImpl _value, $Res Function(_$RouteBlobImpl) _then) +class __$$_RouteBlobCopyWithImpl<$Res> + extends _$RouteBlobCopyWithImpl<$Res, _$_RouteBlob> + implements _$$_RouteBlobCopyWith<$Res> { + __$$_RouteBlobCopyWithImpl( + _$_RouteBlob _value, $Res Function(_$_RouteBlob) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1432,7 +1427,7 @@ class __$$RouteBlobImplCopyWithImpl<$Res> Object? routeId = null, Object? blob = null, }) { - return _then(_$RouteBlobImpl( + return _then(_$_RouteBlob( routeId: null == routeId ? _value.routeId : routeId // ignore: cast_nullable_to_non_nullable @@ -1447,12 +1442,12 @@ class __$$RouteBlobImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$RouteBlobImpl implements _RouteBlob { - const _$RouteBlobImpl( +class _$_RouteBlob implements _RouteBlob { + const _$_RouteBlob( {required this.routeId, @Uint8ListJsonConverter() required this.blob}); - factory _$RouteBlobImpl.fromJson(Map json) => - _$$RouteBlobImplFromJson(json); + factory _$_RouteBlob.fromJson(Map json) => + _$$_RouteBlobFromJson(json); @override final String routeId; @@ -1469,7 +1464,7 @@ class _$RouteBlobImpl implements _RouteBlob { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$RouteBlobImpl && + other is _$_RouteBlob && (identical(other.routeId, routeId) || other.routeId == routeId) && const DeepCollectionEquality().equals(other.blob, blob)); } @@ -1482,12 +1477,12 @@ class _$RouteBlobImpl implements _RouteBlob { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$RouteBlobImplCopyWith<_$RouteBlobImpl> get copyWith => - __$$RouteBlobImplCopyWithImpl<_$RouteBlobImpl>(this, _$identity); + _$$_RouteBlobCopyWith<_$_RouteBlob> get copyWith => + __$$_RouteBlobCopyWithImpl<_$_RouteBlob>(this, _$identity); @override Map toJson() { - return _$$RouteBlobImplToJson( + return _$$_RouteBlobToJson( this, ); } @@ -1495,12 +1490,11 @@ class _$RouteBlobImpl implements _RouteBlob { abstract class _RouteBlob implements RouteBlob { const factory _RouteBlob( - {required final String routeId, - @Uint8ListJsonConverter() required final Uint8List blob}) = - _$RouteBlobImpl; + {required final String routeId, + @Uint8ListJsonConverter() required final Uint8List blob}) = _$_RouteBlob; factory _RouteBlob.fromJson(Map json) = - _$RouteBlobImpl.fromJson; + _$_RouteBlob.fromJson; @override String get routeId; @@ -1509,6 +1503,6 @@ abstract class _RouteBlob implements RouteBlob { Uint8List get blob; @override @JsonKey(ignore: true) - _$$RouteBlobImplCopyWith<_$RouteBlobImpl> get copyWith => + _$$_RouteBlobCopyWith<_$_RouteBlob> get copyWith => throw _privateConstructorUsedError; } diff --git a/veilid-flutter/lib/routing_context.g.dart b/veilid-flutter/lib/routing_context.g.dart index 79ff0310..d76ff703 100644 --- a/veilid-flutter/lib/routing_context.g.dart +++ b/veilid-flutter/lib/routing_context.g.dart @@ -6,20 +6,20 @@ part of 'routing_context.dart'; // JsonSerializableGenerator // ************************************************************************** -_$DHTSchemaDFLTImpl _$$DHTSchemaDFLTImplFromJson(Map json) => - _$DHTSchemaDFLTImpl( +_$DHTSchemaDFLT _$$DHTSchemaDFLTFromJson(Map json) => + _$DHTSchemaDFLT( oCnt: json['o_cnt'] as int, $type: json['kind'] as String?, ); -Map _$$DHTSchemaDFLTImplToJson(_$DHTSchemaDFLTImpl instance) => +Map _$$DHTSchemaDFLTToJson(_$DHTSchemaDFLT instance) => { 'o_cnt': instance.oCnt, 'kind': instance.$type, }; -_$DHTSchemaSMPLImpl _$$DHTSchemaSMPLImplFromJson(Map json) => - _$DHTSchemaSMPLImpl( +_$DHTSchemaSMPL _$$DHTSchemaSMPLFromJson(Map json) => + _$DHTSchemaSMPL( oCnt: json['o_cnt'] as int, members: (json['members'] as List) .map(DHTSchemaMember.fromJson) @@ -27,30 +27,28 @@ _$DHTSchemaSMPLImpl _$$DHTSchemaSMPLImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$DHTSchemaSMPLImplToJson(_$DHTSchemaSMPLImpl instance) => +Map _$$DHTSchemaSMPLToJson(_$DHTSchemaSMPL instance) => { 'o_cnt': instance.oCnt, 'members': instance.members.map((e) => e.toJson()).toList(), 'kind': instance.$type, }; -_$DHTSchemaMemberImpl _$$DHTSchemaMemberImplFromJson( - Map json) => - _$DHTSchemaMemberImpl( +_$_DHTSchemaMember _$$_DHTSchemaMemberFromJson(Map json) => + _$_DHTSchemaMember( mKey: FixedEncodedString43.fromJson(json['m_key']), mCnt: json['m_cnt'] as int, ); -Map _$$DHTSchemaMemberImplToJson( - _$DHTSchemaMemberImpl instance) => +Map _$$_DHTSchemaMemberToJson(_$_DHTSchemaMember instance) => { 'm_key': instance.mKey.toJson(), 'm_cnt': instance.mCnt, }; -_$DHTRecordDescriptorImpl _$$DHTRecordDescriptorImplFromJson( +_$_DHTRecordDescriptor _$$_DHTRecordDescriptorFromJson( Map json) => - _$DHTRecordDescriptorImpl( + _$_DHTRecordDescriptor( key: Typed.fromJson(json['key']), owner: FixedEncodedString43.fromJson(json['owner']), schema: DHTSchema.fromJson(json['schema']), @@ -59,8 +57,8 @@ _$DHTRecordDescriptorImpl _$$DHTRecordDescriptorImplFromJson( : FixedEncodedString43.fromJson(json['owner_secret']), ); -Map _$$DHTRecordDescriptorImplToJson( - _$DHTRecordDescriptorImpl instance) => +Map _$$_DHTRecordDescriptorToJson( + _$_DHTRecordDescriptor instance) => { 'key': instance.key.toJson(), 'owner': instance.owner.toJson(), @@ -68,43 +66,40 @@ Map _$$DHTRecordDescriptorImplToJson( 'owner_secret': instance.ownerSecret?.toJson(), }; -_$ValueSubkeyRangeImpl _$$ValueSubkeyRangeImplFromJson( - Map json) => - _$ValueSubkeyRangeImpl( +_$_ValueSubkeyRange _$$_ValueSubkeyRangeFromJson(Map json) => + _$_ValueSubkeyRange( low: json['low'] as int, high: json['high'] as int, ); -Map _$$ValueSubkeyRangeImplToJson( - _$ValueSubkeyRangeImpl instance) => +Map _$$_ValueSubkeyRangeToJson(_$_ValueSubkeyRange instance) => { 'low': instance.low, 'high': instance.high, }; -_$ValueDataImpl _$$ValueDataImplFromJson(Map json) => - _$ValueDataImpl( +_$_ValueData _$$_ValueDataFromJson(Map json) => _$_ValueData( seq: json['seq'] as int, data: const Uint8ListJsonConverter.jsIsArray().fromJson(json['data']), writer: FixedEncodedString43.fromJson(json['writer']), ); -Map _$$ValueDataImplToJson(_$ValueDataImpl instance) => +Map _$$_ValueDataToJson(_$_ValueData instance) => { 'seq': instance.seq, 'data': const Uint8ListJsonConverter.jsIsArray().toJson(instance.data), 'writer': instance.writer.toJson(), }; -_$SafetySpecImpl _$$SafetySpecImplFromJson(Map json) => - _$SafetySpecImpl( +_$_SafetySpec _$$_SafetySpecFromJson(Map json) => + _$_SafetySpec( hopCount: json['hop_count'] as int, stability: Stability.fromJson(json['stability']), sequencing: Sequencing.fromJson(json['sequencing']), preferredRoute: json['preferred_route'] as String?, ); -Map _$$SafetySpecImplToJson(_$SafetySpecImpl instance) => +Map _$$_SafetySpecToJson(_$_SafetySpec instance) => { 'hop_count': instance.hopCount, 'stability': instance.stability.toJson(), @@ -112,13 +107,12 @@ Map _$$SafetySpecImplToJson(_$SafetySpecImpl instance) => 'preferred_route': instance.preferredRoute, }; -_$RouteBlobImpl _$$RouteBlobImplFromJson(Map json) => - _$RouteBlobImpl( +_$_RouteBlob _$$_RouteBlobFromJson(Map json) => _$_RouteBlob( routeId: json['route_id'] as String, blob: const Uint8ListJsonConverter().fromJson(json['blob']), ); -Map _$$RouteBlobImplToJson(_$RouteBlobImpl instance) => +Map _$$_RouteBlobToJson(_$_RouteBlob instance) => { 'route_id': instance.routeId, 'blob': const Uint8ListJsonConverter().toJson(instance.blob), diff --git a/veilid-flutter/lib/veilid_config.dart b/veilid-flutter/lib/veilid_config.dart index 058b6cd5..cc34e6b5 100644 --- a/veilid-flutter/lib/veilid_config.dart +++ b/veilid-flutter/lib/veilid_config.dart @@ -285,6 +285,7 @@ class VeilidConfigDHT with _$VeilidConfigDHT { required int remoteMaxStorageSpaceMb, required int publicWatchLimit, required int memberWatchLimit, + required int maxWatchExpirationMs, }) = _VeilidConfigDHT; factory VeilidConfigDHT.fromJson(dynamic json) => diff --git a/veilid-flutter/lib/veilid_config.freezed.dart b/veilid-flutter/lib/veilid_config.freezed.dart index 592da1c4..0f74d2d4 100644 --- a/veilid-flutter/lib/veilid_config.freezed.dart +++ b/veilid-flutter/lib/veilid_config.freezed.dart @@ -72,25 +72,25 @@ class _$VeilidFFIConfigLoggingTerminalCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidFFIConfigLoggingTerminalImplCopyWith<$Res> +abstract class _$$_VeilidFFIConfigLoggingTerminalCopyWith<$Res> implements $VeilidFFIConfigLoggingTerminalCopyWith<$Res> { - factory _$$VeilidFFIConfigLoggingTerminalImplCopyWith( - _$VeilidFFIConfigLoggingTerminalImpl value, - $Res Function(_$VeilidFFIConfigLoggingTerminalImpl) then) = - __$$VeilidFFIConfigLoggingTerminalImplCopyWithImpl<$Res>; + factory _$$_VeilidFFIConfigLoggingTerminalCopyWith( + _$_VeilidFFIConfigLoggingTerminal value, + $Res Function(_$_VeilidFFIConfigLoggingTerminal) then) = + __$$_VeilidFFIConfigLoggingTerminalCopyWithImpl<$Res>; @override @useResult $Res call({bool enabled, VeilidConfigLogLevel level}); } /// @nodoc -class __$$VeilidFFIConfigLoggingTerminalImplCopyWithImpl<$Res> +class __$$_VeilidFFIConfigLoggingTerminalCopyWithImpl<$Res> extends _$VeilidFFIConfigLoggingTerminalCopyWithImpl<$Res, - _$VeilidFFIConfigLoggingTerminalImpl> - implements _$$VeilidFFIConfigLoggingTerminalImplCopyWith<$Res> { - __$$VeilidFFIConfigLoggingTerminalImplCopyWithImpl( - _$VeilidFFIConfigLoggingTerminalImpl _value, - $Res Function(_$VeilidFFIConfigLoggingTerminalImpl) _then) + _$_VeilidFFIConfigLoggingTerminal> + implements _$$_VeilidFFIConfigLoggingTerminalCopyWith<$Res> { + __$$_VeilidFFIConfigLoggingTerminalCopyWithImpl( + _$_VeilidFFIConfigLoggingTerminal _value, + $Res Function(_$_VeilidFFIConfigLoggingTerminal) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -99,7 +99,7 @@ class __$$VeilidFFIConfigLoggingTerminalImplCopyWithImpl<$Res> Object? enabled = null, Object? level = null, }) { - return _then(_$VeilidFFIConfigLoggingTerminalImpl( + return _then(_$_VeilidFFIConfigLoggingTerminal( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -114,15 +114,15 @@ class __$$VeilidFFIConfigLoggingTerminalImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidFFIConfigLoggingTerminalImpl +class _$_VeilidFFIConfigLoggingTerminal with DiagnosticableTreeMixin implements _VeilidFFIConfigLoggingTerminal { - const _$VeilidFFIConfigLoggingTerminalImpl( + const _$_VeilidFFIConfigLoggingTerminal( {required this.enabled, required this.level}); - factory _$VeilidFFIConfigLoggingTerminalImpl.fromJson( + factory _$_VeilidFFIConfigLoggingTerminal.fromJson( Map json) => - _$$VeilidFFIConfigLoggingTerminalImplFromJson(json); + _$$_VeilidFFIConfigLoggingTerminalFromJson(json); @override final bool enabled; @@ -147,7 +147,7 @@ class _$VeilidFFIConfigLoggingTerminalImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidFFIConfigLoggingTerminalImpl && + other is _$_VeilidFFIConfigLoggingTerminal && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.level, level) || other.level == level)); } @@ -159,14 +159,13 @@ class _$VeilidFFIConfigLoggingTerminalImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidFFIConfigLoggingTerminalImplCopyWith< - _$VeilidFFIConfigLoggingTerminalImpl> - get copyWith => __$$VeilidFFIConfigLoggingTerminalImplCopyWithImpl< - _$VeilidFFIConfigLoggingTerminalImpl>(this, _$identity); + _$$_VeilidFFIConfigLoggingTerminalCopyWith<_$_VeilidFFIConfigLoggingTerminal> + get copyWith => __$$_VeilidFFIConfigLoggingTerminalCopyWithImpl< + _$_VeilidFFIConfigLoggingTerminal>(this, _$identity); @override Map toJson() { - return _$$VeilidFFIConfigLoggingTerminalImplToJson( + return _$$_VeilidFFIConfigLoggingTerminalToJson( this, ); } @@ -177,10 +176,10 @@ abstract class _VeilidFFIConfigLoggingTerminal const factory _VeilidFFIConfigLoggingTerminal( {required final bool enabled, required final VeilidConfigLogLevel level}) = - _$VeilidFFIConfigLoggingTerminalImpl; + _$_VeilidFFIConfigLoggingTerminal; factory _VeilidFFIConfigLoggingTerminal.fromJson(Map json) = - _$VeilidFFIConfigLoggingTerminalImpl.fromJson; + _$_VeilidFFIConfigLoggingTerminal.fromJson; @override bool get enabled; @@ -188,8 +187,7 @@ abstract class _VeilidFFIConfigLoggingTerminal VeilidConfigLogLevel get level; @override @JsonKey(ignore: true) - _$$VeilidFFIConfigLoggingTerminalImplCopyWith< - _$VeilidFFIConfigLoggingTerminalImpl> + _$$_VeilidFFIConfigLoggingTerminalCopyWith<_$_VeilidFFIConfigLoggingTerminal> get copyWith => throw _privateConstructorUsedError; } @@ -266,12 +264,12 @@ class _$VeilidFFIConfigLoggingOtlpCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidFFIConfigLoggingOtlpImplCopyWith<$Res> +abstract class _$$_VeilidFFIConfigLoggingOtlpCopyWith<$Res> implements $VeilidFFIConfigLoggingOtlpCopyWith<$Res> { - factory _$$VeilidFFIConfigLoggingOtlpImplCopyWith( - _$VeilidFFIConfigLoggingOtlpImpl value, - $Res Function(_$VeilidFFIConfigLoggingOtlpImpl) then) = - __$$VeilidFFIConfigLoggingOtlpImplCopyWithImpl<$Res>; + factory _$$_VeilidFFIConfigLoggingOtlpCopyWith( + _$_VeilidFFIConfigLoggingOtlp value, + $Res Function(_$_VeilidFFIConfigLoggingOtlp) then) = + __$$_VeilidFFIConfigLoggingOtlpCopyWithImpl<$Res>; @override @useResult $Res call( @@ -282,13 +280,13 @@ abstract class _$$VeilidFFIConfigLoggingOtlpImplCopyWith<$Res> } /// @nodoc -class __$$VeilidFFIConfigLoggingOtlpImplCopyWithImpl<$Res> +class __$$_VeilidFFIConfigLoggingOtlpCopyWithImpl<$Res> extends _$VeilidFFIConfigLoggingOtlpCopyWithImpl<$Res, - _$VeilidFFIConfigLoggingOtlpImpl> - implements _$$VeilidFFIConfigLoggingOtlpImplCopyWith<$Res> { - __$$VeilidFFIConfigLoggingOtlpImplCopyWithImpl( - _$VeilidFFIConfigLoggingOtlpImpl _value, - $Res Function(_$VeilidFFIConfigLoggingOtlpImpl) _then) + _$_VeilidFFIConfigLoggingOtlp> + implements _$$_VeilidFFIConfigLoggingOtlpCopyWith<$Res> { + __$$_VeilidFFIConfigLoggingOtlpCopyWithImpl( + _$_VeilidFFIConfigLoggingOtlp _value, + $Res Function(_$_VeilidFFIConfigLoggingOtlp) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -299,7 +297,7 @@ class __$$VeilidFFIConfigLoggingOtlpImplCopyWithImpl<$Res> Object? grpcEndpoint = null, Object? serviceName = null, }) { - return _then(_$VeilidFFIConfigLoggingOtlpImpl( + return _then(_$_VeilidFFIConfigLoggingOtlp( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -322,18 +320,17 @@ class __$$VeilidFFIConfigLoggingOtlpImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidFFIConfigLoggingOtlpImpl +class _$_VeilidFFIConfigLoggingOtlp with DiagnosticableTreeMixin implements _VeilidFFIConfigLoggingOtlp { - const _$VeilidFFIConfigLoggingOtlpImpl( + const _$_VeilidFFIConfigLoggingOtlp( {required this.enabled, required this.level, required this.grpcEndpoint, required this.serviceName}); - factory _$VeilidFFIConfigLoggingOtlpImpl.fromJson( - Map json) => - _$$VeilidFFIConfigLoggingOtlpImplFromJson(json); + factory _$_VeilidFFIConfigLoggingOtlp.fromJson(Map json) => + _$$_VeilidFFIConfigLoggingOtlpFromJson(json); @override final bool enabled; @@ -364,7 +361,7 @@ class _$VeilidFFIConfigLoggingOtlpImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidFFIConfigLoggingOtlpImpl && + other is _$_VeilidFFIConfigLoggingOtlp && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.level, level) || other.level == level) && (identical(other.grpcEndpoint, grpcEndpoint) || @@ -381,13 +378,13 @@ class _$VeilidFFIConfigLoggingOtlpImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidFFIConfigLoggingOtlpImplCopyWith<_$VeilidFFIConfigLoggingOtlpImpl> - get copyWith => __$$VeilidFFIConfigLoggingOtlpImplCopyWithImpl< - _$VeilidFFIConfigLoggingOtlpImpl>(this, _$identity); + _$$_VeilidFFIConfigLoggingOtlpCopyWith<_$_VeilidFFIConfigLoggingOtlp> + get copyWith => __$$_VeilidFFIConfigLoggingOtlpCopyWithImpl< + _$_VeilidFFIConfigLoggingOtlp>(this, _$identity); @override Map toJson() { - return _$$VeilidFFIConfigLoggingOtlpImplToJson( + return _$$_VeilidFFIConfigLoggingOtlpToJson( this, ); } @@ -399,10 +396,10 @@ abstract class _VeilidFFIConfigLoggingOtlp {required final bool enabled, required final VeilidConfigLogLevel level, required final String grpcEndpoint, - required final String serviceName}) = _$VeilidFFIConfigLoggingOtlpImpl; + required final String serviceName}) = _$_VeilidFFIConfigLoggingOtlp; factory _VeilidFFIConfigLoggingOtlp.fromJson(Map json) = - _$VeilidFFIConfigLoggingOtlpImpl.fromJson; + _$_VeilidFFIConfigLoggingOtlp.fromJson; @override bool get enabled; @@ -414,7 +411,7 @@ abstract class _VeilidFFIConfigLoggingOtlp String get serviceName; @override @JsonKey(ignore: true) - _$$VeilidFFIConfigLoggingOtlpImplCopyWith<_$VeilidFFIConfigLoggingOtlpImpl> + _$$_VeilidFFIConfigLoggingOtlpCopyWith<_$_VeilidFFIConfigLoggingOtlp> get copyWith => throw _privateConstructorUsedError; } @@ -474,25 +471,25 @@ class _$VeilidFFIConfigLoggingApiCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidFFIConfigLoggingApiImplCopyWith<$Res> +abstract class _$$_VeilidFFIConfigLoggingApiCopyWith<$Res> implements $VeilidFFIConfigLoggingApiCopyWith<$Res> { - factory _$$VeilidFFIConfigLoggingApiImplCopyWith( - _$VeilidFFIConfigLoggingApiImpl value, - $Res Function(_$VeilidFFIConfigLoggingApiImpl) then) = - __$$VeilidFFIConfigLoggingApiImplCopyWithImpl<$Res>; + factory _$$_VeilidFFIConfigLoggingApiCopyWith( + _$_VeilidFFIConfigLoggingApi value, + $Res Function(_$_VeilidFFIConfigLoggingApi) then) = + __$$_VeilidFFIConfigLoggingApiCopyWithImpl<$Res>; @override @useResult $Res call({bool enabled, VeilidConfigLogLevel level}); } /// @nodoc -class __$$VeilidFFIConfigLoggingApiImplCopyWithImpl<$Res> +class __$$_VeilidFFIConfigLoggingApiCopyWithImpl<$Res> extends _$VeilidFFIConfigLoggingApiCopyWithImpl<$Res, - _$VeilidFFIConfigLoggingApiImpl> - implements _$$VeilidFFIConfigLoggingApiImplCopyWith<$Res> { - __$$VeilidFFIConfigLoggingApiImplCopyWithImpl( - _$VeilidFFIConfigLoggingApiImpl _value, - $Res Function(_$VeilidFFIConfigLoggingApiImpl) _then) + _$_VeilidFFIConfigLoggingApi> + implements _$$_VeilidFFIConfigLoggingApiCopyWith<$Res> { + __$$_VeilidFFIConfigLoggingApiCopyWithImpl( + _$_VeilidFFIConfigLoggingApi _value, + $Res Function(_$_VeilidFFIConfigLoggingApi) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -501,7 +498,7 @@ class __$$VeilidFFIConfigLoggingApiImplCopyWithImpl<$Res> Object? enabled = null, Object? level = null, }) { - return _then(_$VeilidFFIConfigLoggingApiImpl( + return _then(_$_VeilidFFIConfigLoggingApi( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -516,14 +513,14 @@ class __$$VeilidFFIConfigLoggingApiImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidFFIConfigLoggingApiImpl +class _$_VeilidFFIConfigLoggingApi with DiagnosticableTreeMixin implements _VeilidFFIConfigLoggingApi { - const _$VeilidFFIConfigLoggingApiImpl( + const _$_VeilidFFIConfigLoggingApi( {required this.enabled, required this.level}); - factory _$VeilidFFIConfigLoggingApiImpl.fromJson(Map json) => - _$$VeilidFFIConfigLoggingApiImplFromJson(json); + factory _$_VeilidFFIConfigLoggingApi.fromJson(Map json) => + _$$_VeilidFFIConfigLoggingApiFromJson(json); @override final bool enabled; @@ -548,7 +545,7 @@ class _$VeilidFFIConfigLoggingApiImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidFFIConfigLoggingApiImpl && + other is _$_VeilidFFIConfigLoggingApi && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.level, level) || other.level == level)); } @@ -560,13 +557,13 @@ class _$VeilidFFIConfigLoggingApiImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidFFIConfigLoggingApiImplCopyWith<_$VeilidFFIConfigLoggingApiImpl> - get copyWith => __$$VeilidFFIConfigLoggingApiImplCopyWithImpl< - _$VeilidFFIConfigLoggingApiImpl>(this, _$identity); + _$$_VeilidFFIConfigLoggingApiCopyWith<_$_VeilidFFIConfigLoggingApi> + get copyWith => __$$_VeilidFFIConfigLoggingApiCopyWithImpl< + _$_VeilidFFIConfigLoggingApi>(this, _$identity); @override Map toJson() { - return _$$VeilidFFIConfigLoggingApiImplToJson( + return _$$_VeilidFFIConfigLoggingApiToJson( this, ); } @@ -576,10 +573,10 @@ abstract class _VeilidFFIConfigLoggingApi implements VeilidFFIConfigLoggingApi { const factory _VeilidFFIConfigLoggingApi( {required final bool enabled, required final VeilidConfigLogLevel level}) = - _$VeilidFFIConfigLoggingApiImpl; + _$_VeilidFFIConfigLoggingApi; factory _VeilidFFIConfigLoggingApi.fromJson(Map json) = - _$VeilidFFIConfigLoggingApiImpl.fromJson; + _$_VeilidFFIConfigLoggingApi.fromJson; @override bool get enabled; @@ -587,7 +584,7 @@ abstract class _VeilidFFIConfigLoggingApi implements VeilidFFIConfigLoggingApi { VeilidConfigLogLevel get level; @override @JsonKey(ignore: true) - _$$VeilidFFIConfigLoggingApiImplCopyWith<_$VeilidFFIConfigLoggingApiImpl> + _$$_VeilidFFIConfigLoggingApiCopyWith<_$_VeilidFFIConfigLoggingApi> get copyWith => throw _privateConstructorUsedError; } @@ -686,12 +683,11 @@ class _$VeilidFFIConfigLoggingCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidFFIConfigLoggingImplCopyWith<$Res> +abstract class _$$_VeilidFFIConfigLoggingCopyWith<$Res> implements $VeilidFFIConfigLoggingCopyWith<$Res> { - factory _$$VeilidFFIConfigLoggingImplCopyWith( - _$VeilidFFIConfigLoggingImpl value, - $Res Function(_$VeilidFFIConfigLoggingImpl) then) = - __$$VeilidFFIConfigLoggingImplCopyWithImpl<$Res>; + factory _$$_VeilidFFIConfigLoggingCopyWith(_$_VeilidFFIConfigLogging value, + $Res Function(_$_VeilidFFIConfigLogging) then) = + __$$_VeilidFFIConfigLoggingCopyWithImpl<$Res>; @override @useResult $Res call( @@ -708,13 +704,12 @@ abstract class _$$VeilidFFIConfigLoggingImplCopyWith<$Res> } /// @nodoc -class __$$VeilidFFIConfigLoggingImplCopyWithImpl<$Res> +class __$$_VeilidFFIConfigLoggingCopyWithImpl<$Res> extends _$VeilidFFIConfigLoggingCopyWithImpl<$Res, - _$VeilidFFIConfigLoggingImpl> - implements _$$VeilidFFIConfigLoggingImplCopyWith<$Res> { - __$$VeilidFFIConfigLoggingImplCopyWithImpl( - _$VeilidFFIConfigLoggingImpl _value, - $Res Function(_$VeilidFFIConfigLoggingImpl) _then) + _$_VeilidFFIConfigLogging> + implements _$$_VeilidFFIConfigLoggingCopyWith<$Res> { + __$$_VeilidFFIConfigLoggingCopyWithImpl(_$_VeilidFFIConfigLogging _value, + $Res Function(_$_VeilidFFIConfigLogging) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -724,7 +719,7 @@ class __$$VeilidFFIConfigLoggingImplCopyWithImpl<$Res> Object? otlp = null, Object? api = null, }) { - return _then(_$VeilidFFIConfigLoggingImpl( + return _then(_$_VeilidFFIConfigLogging( terminal: null == terminal ? _value.terminal : terminal // ignore: cast_nullable_to_non_nullable @@ -743,14 +738,14 @@ class __$$VeilidFFIConfigLoggingImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidFFIConfigLoggingImpl +class _$_VeilidFFIConfigLogging with DiagnosticableTreeMixin implements _VeilidFFIConfigLogging { - const _$VeilidFFIConfigLoggingImpl( + const _$_VeilidFFIConfigLogging( {required this.terminal, required this.otlp, required this.api}); - factory _$VeilidFFIConfigLoggingImpl.fromJson(Map json) => - _$$VeilidFFIConfigLoggingImplFromJson(json); + factory _$_VeilidFFIConfigLogging.fromJson(Map json) => + _$$_VeilidFFIConfigLoggingFromJson(json); @override final VeilidFFIConfigLoggingTerminal terminal; @@ -778,7 +773,7 @@ class _$VeilidFFIConfigLoggingImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidFFIConfigLoggingImpl && + other is _$_VeilidFFIConfigLogging && (identical(other.terminal, terminal) || other.terminal == terminal) && (identical(other.otlp, otlp) || other.otlp == otlp) && @@ -792,13 +787,13 @@ class _$VeilidFFIConfigLoggingImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidFFIConfigLoggingImplCopyWith<_$VeilidFFIConfigLoggingImpl> - get copyWith => __$$VeilidFFIConfigLoggingImplCopyWithImpl< - _$VeilidFFIConfigLoggingImpl>(this, _$identity); + _$$_VeilidFFIConfigLoggingCopyWith<_$_VeilidFFIConfigLogging> get copyWith => + __$$_VeilidFFIConfigLoggingCopyWithImpl<_$_VeilidFFIConfigLogging>( + this, _$identity); @override Map toJson() { - return _$$VeilidFFIConfigLoggingImplToJson( + return _$$_VeilidFFIConfigLoggingToJson( this, ); } @@ -809,10 +804,10 @@ abstract class _VeilidFFIConfigLogging implements VeilidFFIConfigLogging { {required final VeilidFFIConfigLoggingTerminal terminal, required final VeilidFFIConfigLoggingOtlp otlp, required final VeilidFFIConfigLoggingApi api}) = - _$VeilidFFIConfigLoggingImpl; + _$_VeilidFFIConfigLogging; factory _VeilidFFIConfigLogging.fromJson(Map json) = - _$VeilidFFIConfigLoggingImpl.fromJson; + _$_VeilidFFIConfigLogging.fromJson; @override VeilidFFIConfigLoggingTerminal get terminal; @@ -822,8 +817,8 @@ abstract class _VeilidFFIConfigLogging implements VeilidFFIConfigLogging { VeilidFFIConfigLoggingApi get api; @override @JsonKey(ignore: true) - _$$VeilidFFIConfigLoggingImplCopyWith<_$VeilidFFIConfigLoggingImpl> - get copyWith => throw _privateConstructorUsedError; + _$$_VeilidFFIConfigLoggingCopyWith<_$_VeilidFFIConfigLogging> get copyWith => + throw _privateConstructorUsedError; } VeilidFFIConfig _$VeilidFFIConfigFromJson(Map json) { @@ -884,11 +879,11 @@ class _$VeilidFFIConfigCopyWithImpl<$Res, $Val extends VeilidFFIConfig> } /// @nodoc -abstract class _$$VeilidFFIConfigImplCopyWith<$Res> +abstract class _$$_VeilidFFIConfigCopyWith<$Res> implements $VeilidFFIConfigCopyWith<$Res> { - factory _$$VeilidFFIConfigImplCopyWith(_$VeilidFFIConfigImpl value, - $Res Function(_$VeilidFFIConfigImpl) then) = - __$$VeilidFFIConfigImplCopyWithImpl<$Res>; + factory _$$_VeilidFFIConfigCopyWith( + _$_VeilidFFIConfig value, $Res Function(_$_VeilidFFIConfig) then) = + __$$_VeilidFFIConfigCopyWithImpl<$Res>; @override @useResult $Res call({VeilidFFIConfigLogging logging}); @@ -898,11 +893,11 @@ abstract class _$$VeilidFFIConfigImplCopyWith<$Res> } /// @nodoc -class __$$VeilidFFIConfigImplCopyWithImpl<$Res> - extends _$VeilidFFIConfigCopyWithImpl<$Res, _$VeilidFFIConfigImpl> - implements _$$VeilidFFIConfigImplCopyWith<$Res> { - __$$VeilidFFIConfigImplCopyWithImpl( - _$VeilidFFIConfigImpl _value, $Res Function(_$VeilidFFIConfigImpl) _then) +class __$$_VeilidFFIConfigCopyWithImpl<$Res> + extends _$VeilidFFIConfigCopyWithImpl<$Res, _$_VeilidFFIConfig> + implements _$$_VeilidFFIConfigCopyWith<$Res> { + __$$_VeilidFFIConfigCopyWithImpl( + _$_VeilidFFIConfig _value, $Res Function(_$_VeilidFFIConfig) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -910,7 +905,7 @@ class __$$VeilidFFIConfigImplCopyWithImpl<$Res> $Res call({ Object? logging = null, }) { - return _then(_$VeilidFFIConfigImpl( + return _then(_$_VeilidFFIConfig( logging: null == logging ? _value.logging : logging // ignore: cast_nullable_to_non_nullable @@ -921,13 +916,13 @@ class __$$VeilidFFIConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidFFIConfigImpl +class _$_VeilidFFIConfig with DiagnosticableTreeMixin implements _VeilidFFIConfig { - const _$VeilidFFIConfigImpl({required this.logging}); + const _$_VeilidFFIConfig({required this.logging}); - factory _$VeilidFFIConfigImpl.fromJson(Map json) => - _$$VeilidFFIConfigImplFromJson(json); + factory _$_VeilidFFIConfig.fromJson(Map json) => + _$$_VeilidFFIConfigFromJson(json); @override final VeilidFFIConfigLogging logging; @@ -949,7 +944,7 @@ class _$VeilidFFIConfigImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidFFIConfigImpl && + other is _$_VeilidFFIConfig && (identical(other.logging, logging) || other.logging == logging)); } @@ -960,13 +955,12 @@ class _$VeilidFFIConfigImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidFFIConfigImplCopyWith<_$VeilidFFIConfigImpl> get copyWith => - __$$VeilidFFIConfigImplCopyWithImpl<_$VeilidFFIConfigImpl>( - this, _$identity); + _$$_VeilidFFIConfigCopyWith<_$_VeilidFFIConfig> get copyWith => + __$$_VeilidFFIConfigCopyWithImpl<_$_VeilidFFIConfig>(this, _$identity); @override Map toJson() { - return _$$VeilidFFIConfigImplToJson( + return _$$_VeilidFFIConfigToJson( this, ); } @@ -974,16 +968,16 @@ class _$VeilidFFIConfigImpl abstract class _VeilidFFIConfig implements VeilidFFIConfig { const factory _VeilidFFIConfig( - {required final VeilidFFIConfigLogging logging}) = _$VeilidFFIConfigImpl; + {required final VeilidFFIConfigLogging logging}) = _$_VeilidFFIConfig; factory _VeilidFFIConfig.fromJson(Map json) = - _$VeilidFFIConfigImpl.fromJson; + _$_VeilidFFIConfig.fromJson; @override VeilidFFIConfigLogging get logging; @override @JsonKey(ignore: true) - _$$VeilidFFIConfigImplCopyWith<_$VeilidFFIConfigImpl> get copyWith => + _$$_VeilidFFIConfigCopyWith<_$_VeilidFFIConfig> get copyWith => throw _privateConstructorUsedError; } @@ -1062,12 +1056,12 @@ class _$VeilidWASMConfigLoggingPerformanceCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidWASMConfigLoggingPerformanceImplCopyWith<$Res> +abstract class _$$_VeilidWASMConfigLoggingPerformanceCopyWith<$Res> implements $VeilidWASMConfigLoggingPerformanceCopyWith<$Res> { - factory _$$VeilidWASMConfigLoggingPerformanceImplCopyWith( - _$VeilidWASMConfigLoggingPerformanceImpl value, - $Res Function(_$VeilidWASMConfigLoggingPerformanceImpl) then) = - __$$VeilidWASMConfigLoggingPerformanceImplCopyWithImpl<$Res>; + factory _$$_VeilidWASMConfigLoggingPerformanceCopyWith( + _$_VeilidWASMConfigLoggingPerformance value, + $Res Function(_$_VeilidWASMConfigLoggingPerformance) then) = + __$$_VeilidWASMConfigLoggingPerformanceCopyWithImpl<$Res>; @override @useResult $Res call( @@ -1078,13 +1072,13 @@ abstract class _$$VeilidWASMConfigLoggingPerformanceImplCopyWith<$Res> } /// @nodoc -class __$$VeilidWASMConfigLoggingPerformanceImplCopyWithImpl<$Res> +class __$$_VeilidWASMConfigLoggingPerformanceCopyWithImpl<$Res> extends _$VeilidWASMConfigLoggingPerformanceCopyWithImpl<$Res, - _$VeilidWASMConfigLoggingPerformanceImpl> - implements _$$VeilidWASMConfigLoggingPerformanceImplCopyWith<$Res> { - __$$VeilidWASMConfigLoggingPerformanceImplCopyWithImpl( - _$VeilidWASMConfigLoggingPerformanceImpl _value, - $Res Function(_$VeilidWASMConfigLoggingPerformanceImpl) _then) + _$_VeilidWASMConfigLoggingPerformance> + implements _$$_VeilidWASMConfigLoggingPerformanceCopyWith<$Res> { + __$$_VeilidWASMConfigLoggingPerformanceCopyWithImpl( + _$_VeilidWASMConfigLoggingPerformance _value, + $Res Function(_$_VeilidWASMConfigLoggingPerformance) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1095,7 +1089,7 @@ class __$$VeilidWASMConfigLoggingPerformanceImplCopyWithImpl<$Res> Object? logsInTimings = null, Object? logsInConsole = null, }) { - return _then(_$VeilidWASMConfigLoggingPerformanceImpl( + return _then(_$_VeilidWASMConfigLoggingPerformance( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -1118,18 +1112,18 @@ class __$$VeilidWASMConfigLoggingPerformanceImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidWASMConfigLoggingPerformanceImpl +class _$_VeilidWASMConfigLoggingPerformance with DiagnosticableTreeMixin implements _VeilidWASMConfigLoggingPerformance { - const _$VeilidWASMConfigLoggingPerformanceImpl( + const _$_VeilidWASMConfigLoggingPerformance( {required this.enabled, required this.level, required this.logsInTimings, required this.logsInConsole}); - factory _$VeilidWASMConfigLoggingPerformanceImpl.fromJson( + factory _$_VeilidWASMConfigLoggingPerformance.fromJson( Map json) => - _$$VeilidWASMConfigLoggingPerformanceImplFromJson(json); + _$$_VeilidWASMConfigLoggingPerformanceFromJson(json); @override final bool enabled; @@ -1160,7 +1154,7 @@ class _$VeilidWASMConfigLoggingPerformanceImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidWASMConfigLoggingPerformanceImpl && + other is _$_VeilidWASMConfigLoggingPerformance && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.level, level) || other.level == level) && (identical(other.logsInTimings, logsInTimings) || @@ -1177,14 +1171,14 @@ class _$VeilidWASMConfigLoggingPerformanceImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidWASMConfigLoggingPerformanceImplCopyWith< - _$VeilidWASMConfigLoggingPerformanceImpl> - get copyWith => __$$VeilidWASMConfigLoggingPerformanceImplCopyWithImpl< - _$VeilidWASMConfigLoggingPerformanceImpl>(this, _$identity); + _$$_VeilidWASMConfigLoggingPerformanceCopyWith< + _$_VeilidWASMConfigLoggingPerformance> + get copyWith => __$$_VeilidWASMConfigLoggingPerformanceCopyWithImpl< + _$_VeilidWASMConfigLoggingPerformance>(this, _$identity); @override Map toJson() { - return _$$VeilidWASMConfigLoggingPerformanceImplToJson( + return _$$_VeilidWASMConfigLoggingPerformanceToJson( this, ); } @@ -1197,11 +1191,11 @@ abstract class _VeilidWASMConfigLoggingPerformance required final VeilidConfigLogLevel level, required final bool logsInTimings, required final bool logsInConsole}) = - _$VeilidWASMConfigLoggingPerformanceImpl; + _$_VeilidWASMConfigLoggingPerformance; factory _VeilidWASMConfigLoggingPerformance.fromJson( Map json) = - _$VeilidWASMConfigLoggingPerformanceImpl.fromJson; + _$_VeilidWASMConfigLoggingPerformance.fromJson; @override bool get enabled; @@ -1213,8 +1207,8 @@ abstract class _VeilidWASMConfigLoggingPerformance bool get logsInConsole; @override @JsonKey(ignore: true) - _$$VeilidWASMConfigLoggingPerformanceImplCopyWith< - _$VeilidWASMConfigLoggingPerformanceImpl> + _$$_VeilidWASMConfigLoggingPerformanceCopyWith< + _$_VeilidWASMConfigLoggingPerformance> get copyWith => throw _privateConstructorUsedError; } @@ -1275,25 +1269,25 @@ class _$VeilidWASMConfigLoggingApiCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidWASMConfigLoggingApiImplCopyWith<$Res> +abstract class _$$_VeilidWASMConfigLoggingApiCopyWith<$Res> implements $VeilidWASMConfigLoggingApiCopyWith<$Res> { - factory _$$VeilidWASMConfigLoggingApiImplCopyWith( - _$VeilidWASMConfigLoggingApiImpl value, - $Res Function(_$VeilidWASMConfigLoggingApiImpl) then) = - __$$VeilidWASMConfigLoggingApiImplCopyWithImpl<$Res>; + factory _$$_VeilidWASMConfigLoggingApiCopyWith( + _$_VeilidWASMConfigLoggingApi value, + $Res Function(_$_VeilidWASMConfigLoggingApi) then) = + __$$_VeilidWASMConfigLoggingApiCopyWithImpl<$Res>; @override @useResult $Res call({bool enabled, VeilidConfigLogLevel level}); } /// @nodoc -class __$$VeilidWASMConfigLoggingApiImplCopyWithImpl<$Res> +class __$$_VeilidWASMConfigLoggingApiCopyWithImpl<$Res> extends _$VeilidWASMConfigLoggingApiCopyWithImpl<$Res, - _$VeilidWASMConfigLoggingApiImpl> - implements _$$VeilidWASMConfigLoggingApiImplCopyWith<$Res> { - __$$VeilidWASMConfigLoggingApiImplCopyWithImpl( - _$VeilidWASMConfigLoggingApiImpl _value, - $Res Function(_$VeilidWASMConfigLoggingApiImpl) _then) + _$_VeilidWASMConfigLoggingApi> + implements _$$_VeilidWASMConfigLoggingApiCopyWith<$Res> { + __$$_VeilidWASMConfigLoggingApiCopyWithImpl( + _$_VeilidWASMConfigLoggingApi _value, + $Res Function(_$_VeilidWASMConfigLoggingApi) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1302,7 +1296,7 @@ class __$$VeilidWASMConfigLoggingApiImplCopyWithImpl<$Res> Object? enabled = null, Object? level = null, }) { - return _then(_$VeilidWASMConfigLoggingApiImpl( + return _then(_$_VeilidWASMConfigLoggingApi( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -1317,15 +1311,14 @@ class __$$VeilidWASMConfigLoggingApiImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidWASMConfigLoggingApiImpl +class _$_VeilidWASMConfigLoggingApi with DiagnosticableTreeMixin implements _VeilidWASMConfigLoggingApi { - const _$VeilidWASMConfigLoggingApiImpl( + const _$_VeilidWASMConfigLoggingApi( {required this.enabled, required this.level}); - factory _$VeilidWASMConfigLoggingApiImpl.fromJson( - Map json) => - _$$VeilidWASMConfigLoggingApiImplFromJson(json); + factory _$_VeilidWASMConfigLoggingApi.fromJson(Map json) => + _$$_VeilidWASMConfigLoggingApiFromJson(json); @override final bool enabled; @@ -1350,7 +1343,7 @@ class _$VeilidWASMConfigLoggingApiImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidWASMConfigLoggingApiImpl && + other is _$_VeilidWASMConfigLoggingApi && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.level, level) || other.level == level)); } @@ -1362,13 +1355,13 @@ class _$VeilidWASMConfigLoggingApiImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidWASMConfigLoggingApiImplCopyWith<_$VeilidWASMConfigLoggingApiImpl> - get copyWith => __$$VeilidWASMConfigLoggingApiImplCopyWithImpl< - _$VeilidWASMConfigLoggingApiImpl>(this, _$identity); + _$$_VeilidWASMConfigLoggingApiCopyWith<_$_VeilidWASMConfigLoggingApi> + get copyWith => __$$_VeilidWASMConfigLoggingApiCopyWithImpl< + _$_VeilidWASMConfigLoggingApi>(this, _$identity); @override Map toJson() { - return _$$VeilidWASMConfigLoggingApiImplToJson( + return _$$_VeilidWASMConfigLoggingApiToJson( this, ); } @@ -1379,10 +1372,10 @@ abstract class _VeilidWASMConfigLoggingApi const factory _VeilidWASMConfigLoggingApi( {required final bool enabled, required final VeilidConfigLogLevel level}) = - _$VeilidWASMConfigLoggingApiImpl; + _$_VeilidWASMConfigLoggingApi; factory _VeilidWASMConfigLoggingApi.fromJson(Map json) = - _$VeilidWASMConfigLoggingApiImpl.fromJson; + _$_VeilidWASMConfigLoggingApi.fromJson; @override bool get enabled; @@ -1390,7 +1383,7 @@ abstract class _VeilidWASMConfigLoggingApi VeilidConfigLogLevel get level; @override @JsonKey(ignore: true) - _$$VeilidWASMConfigLoggingApiImplCopyWith<_$VeilidWASMConfigLoggingApiImpl> + _$$_VeilidWASMConfigLoggingApiCopyWith<_$_VeilidWASMConfigLoggingApi> get copyWith => throw _privateConstructorUsedError; } @@ -1473,12 +1466,11 @@ class _$VeilidWASMConfigLoggingCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidWASMConfigLoggingImplCopyWith<$Res> +abstract class _$$_VeilidWASMConfigLoggingCopyWith<$Res> implements $VeilidWASMConfigLoggingCopyWith<$Res> { - factory _$$VeilidWASMConfigLoggingImplCopyWith( - _$VeilidWASMConfigLoggingImpl value, - $Res Function(_$VeilidWASMConfigLoggingImpl) then) = - __$$VeilidWASMConfigLoggingImplCopyWithImpl<$Res>; + factory _$$_VeilidWASMConfigLoggingCopyWith(_$_VeilidWASMConfigLogging value, + $Res Function(_$_VeilidWASMConfigLogging) then) = + __$$_VeilidWASMConfigLoggingCopyWithImpl<$Res>; @override @useResult $Res call( @@ -1492,13 +1484,12 @@ abstract class _$$VeilidWASMConfigLoggingImplCopyWith<$Res> } /// @nodoc -class __$$VeilidWASMConfigLoggingImplCopyWithImpl<$Res> +class __$$_VeilidWASMConfigLoggingCopyWithImpl<$Res> extends _$VeilidWASMConfigLoggingCopyWithImpl<$Res, - _$VeilidWASMConfigLoggingImpl> - implements _$$VeilidWASMConfigLoggingImplCopyWith<$Res> { - __$$VeilidWASMConfigLoggingImplCopyWithImpl( - _$VeilidWASMConfigLoggingImpl _value, - $Res Function(_$VeilidWASMConfigLoggingImpl) _then) + _$_VeilidWASMConfigLogging> + implements _$$_VeilidWASMConfigLoggingCopyWith<$Res> { + __$$_VeilidWASMConfigLoggingCopyWithImpl(_$_VeilidWASMConfigLogging _value, + $Res Function(_$_VeilidWASMConfigLogging) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1507,7 +1498,7 @@ class __$$VeilidWASMConfigLoggingImplCopyWithImpl<$Res> Object? performance = null, Object? api = null, }) { - return _then(_$VeilidWASMConfigLoggingImpl( + return _then(_$_VeilidWASMConfigLogging( performance: null == performance ? _value.performance : performance // ignore: cast_nullable_to_non_nullable @@ -1522,14 +1513,14 @@ class __$$VeilidWASMConfigLoggingImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidWASMConfigLoggingImpl +class _$_VeilidWASMConfigLogging with DiagnosticableTreeMixin implements _VeilidWASMConfigLogging { - const _$VeilidWASMConfigLoggingImpl( + const _$_VeilidWASMConfigLogging( {required this.performance, required this.api}); - factory _$VeilidWASMConfigLoggingImpl.fromJson(Map json) => - _$$VeilidWASMConfigLoggingImplFromJson(json); + factory _$_VeilidWASMConfigLogging.fromJson(Map json) => + _$$_VeilidWASMConfigLoggingFromJson(json); @override final VeilidWASMConfigLoggingPerformance performance; @@ -1554,7 +1545,7 @@ class _$VeilidWASMConfigLoggingImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidWASMConfigLoggingImpl && + other is _$_VeilidWASMConfigLogging && (identical(other.performance, performance) || other.performance == performance) && (identical(other.api, api) || other.api == api)); @@ -1567,13 +1558,14 @@ class _$VeilidWASMConfigLoggingImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidWASMConfigLoggingImplCopyWith<_$VeilidWASMConfigLoggingImpl> - get copyWith => __$$VeilidWASMConfigLoggingImplCopyWithImpl< - _$VeilidWASMConfigLoggingImpl>(this, _$identity); + _$$_VeilidWASMConfigLoggingCopyWith<_$_VeilidWASMConfigLogging> + get copyWith => + __$$_VeilidWASMConfigLoggingCopyWithImpl<_$_VeilidWASMConfigLogging>( + this, _$identity); @override Map toJson() { - return _$$VeilidWASMConfigLoggingImplToJson( + return _$$_VeilidWASMConfigLoggingToJson( this, ); } @@ -1583,10 +1575,10 @@ abstract class _VeilidWASMConfigLogging implements VeilidWASMConfigLogging { const factory _VeilidWASMConfigLogging( {required final VeilidWASMConfigLoggingPerformance performance, required final VeilidWASMConfigLoggingApi api}) = - _$VeilidWASMConfigLoggingImpl; + _$_VeilidWASMConfigLogging; factory _VeilidWASMConfigLogging.fromJson(Map json) = - _$VeilidWASMConfigLoggingImpl.fromJson; + _$_VeilidWASMConfigLogging.fromJson; @override VeilidWASMConfigLoggingPerformance get performance; @@ -1594,7 +1586,7 @@ abstract class _VeilidWASMConfigLogging implements VeilidWASMConfigLogging { VeilidWASMConfigLoggingApi get api; @override @JsonKey(ignore: true) - _$$VeilidWASMConfigLoggingImplCopyWith<_$VeilidWASMConfigLoggingImpl> + _$$_VeilidWASMConfigLoggingCopyWith<_$_VeilidWASMConfigLogging> get copyWith => throw _privateConstructorUsedError; } @@ -1656,11 +1648,11 @@ class _$VeilidWASMConfigCopyWithImpl<$Res, $Val extends VeilidWASMConfig> } /// @nodoc -abstract class _$$VeilidWASMConfigImplCopyWith<$Res> +abstract class _$$_VeilidWASMConfigCopyWith<$Res> implements $VeilidWASMConfigCopyWith<$Res> { - factory _$$VeilidWASMConfigImplCopyWith(_$VeilidWASMConfigImpl value, - $Res Function(_$VeilidWASMConfigImpl) then) = - __$$VeilidWASMConfigImplCopyWithImpl<$Res>; + factory _$$_VeilidWASMConfigCopyWith( + _$_VeilidWASMConfig value, $Res Function(_$_VeilidWASMConfig) then) = + __$$_VeilidWASMConfigCopyWithImpl<$Res>; @override @useResult $Res call({VeilidWASMConfigLogging logging}); @@ -1670,11 +1662,11 @@ abstract class _$$VeilidWASMConfigImplCopyWith<$Res> } /// @nodoc -class __$$VeilidWASMConfigImplCopyWithImpl<$Res> - extends _$VeilidWASMConfigCopyWithImpl<$Res, _$VeilidWASMConfigImpl> - implements _$$VeilidWASMConfigImplCopyWith<$Res> { - __$$VeilidWASMConfigImplCopyWithImpl(_$VeilidWASMConfigImpl _value, - $Res Function(_$VeilidWASMConfigImpl) _then) +class __$$_VeilidWASMConfigCopyWithImpl<$Res> + extends _$VeilidWASMConfigCopyWithImpl<$Res, _$_VeilidWASMConfig> + implements _$$_VeilidWASMConfigCopyWith<$Res> { + __$$_VeilidWASMConfigCopyWithImpl( + _$_VeilidWASMConfig _value, $Res Function(_$_VeilidWASMConfig) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1682,7 +1674,7 @@ class __$$VeilidWASMConfigImplCopyWithImpl<$Res> $Res call({ Object? logging = null, }) { - return _then(_$VeilidWASMConfigImpl( + return _then(_$_VeilidWASMConfig( logging: null == logging ? _value.logging : logging // ignore: cast_nullable_to_non_nullable @@ -1693,13 +1685,13 @@ class __$$VeilidWASMConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidWASMConfigImpl +class _$_VeilidWASMConfig with DiagnosticableTreeMixin implements _VeilidWASMConfig { - const _$VeilidWASMConfigImpl({required this.logging}); + const _$_VeilidWASMConfig({required this.logging}); - factory _$VeilidWASMConfigImpl.fromJson(Map json) => - _$$VeilidWASMConfigImplFromJson(json); + factory _$_VeilidWASMConfig.fromJson(Map json) => + _$$_VeilidWASMConfigFromJson(json); @override final VeilidWASMConfigLogging logging; @@ -1721,7 +1713,7 @@ class _$VeilidWASMConfigImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidWASMConfigImpl && + other is _$_VeilidWASMConfig && (identical(other.logging, logging) || other.logging == logging)); } @@ -1732,13 +1724,12 @@ class _$VeilidWASMConfigImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidWASMConfigImplCopyWith<_$VeilidWASMConfigImpl> get copyWith => - __$$VeilidWASMConfigImplCopyWithImpl<_$VeilidWASMConfigImpl>( - this, _$identity); + _$$_VeilidWASMConfigCopyWith<_$_VeilidWASMConfig> get copyWith => + __$$_VeilidWASMConfigCopyWithImpl<_$_VeilidWASMConfig>(this, _$identity); @override Map toJson() { - return _$$VeilidWASMConfigImplToJson( + return _$$_VeilidWASMConfigToJson( this, ); } @@ -1746,17 +1737,16 @@ class _$VeilidWASMConfigImpl abstract class _VeilidWASMConfig implements VeilidWASMConfig { const factory _VeilidWASMConfig( - {required final VeilidWASMConfigLogging logging}) = - _$VeilidWASMConfigImpl; + {required final VeilidWASMConfigLogging logging}) = _$_VeilidWASMConfig; factory _VeilidWASMConfig.fromJson(Map json) = - _$VeilidWASMConfigImpl.fromJson; + _$_VeilidWASMConfig.fromJson; @override VeilidWASMConfigLogging get logging; @override @JsonKey(ignore: true) - _$$VeilidWASMConfigImplCopyWith<_$VeilidWASMConfigImpl> get copyWith => + _$$_VeilidWASMConfigCopyWith<_$_VeilidWASMConfig> get copyWith => throw _privateConstructorUsedError; } @@ -1826,22 +1816,22 @@ class _$VeilidConfigHTTPSCopyWithImpl<$Res, $Val extends VeilidConfigHTTPS> } /// @nodoc -abstract class _$$VeilidConfigHTTPSImplCopyWith<$Res> +abstract class _$$_VeilidConfigHTTPSCopyWith<$Res> implements $VeilidConfigHTTPSCopyWith<$Res> { - factory _$$VeilidConfigHTTPSImplCopyWith(_$VeilidConfigHTTPSImpl value, - $Res Function(_$VeilidConfigHTTPSImpl) then) = - __$$VeilidConfigHTTPSImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigHTTPSCopyWith(_$_VeilidConfigHTTPS value, + $Res Function(_$_VeilidConfigHTTPS) then) = + __$$_VeilidConfigHTTPSCopyWithImpl<$Res>; @override @useResult $Res call({bool enabled, String listenAddress, String path, String? url}); } /// @nodoc -class __$$VeilidConfigHTTPSImplCopyWithImpl<$Res> - extends _$VeilidConfigHTTPSCopyWithImpl<$Res, _$VeilidConfigHTTPSImpl> - implements _$$VeilidConfigHTTPSImplCopyWith<$Res> { - __$$VeilidConfigHTTPSImplCopyWithImpl(_$VeilidConfigHTTPSImpl _value, - $Res Function(_$VeilidConfigHTTPSImpl) _then) +class __$$_VeilidConfigHTTPSCopyWithImpl<$Res> + extends _$VeilidConfigHTTPSCopyWithImpl<$Res, _$_VeilidConfigHTTPS> + implements _$$_VeilidConfigHTTPSCopyWith<$Res> { + __$$_VeilidConfigHTTPSCopyWithImpl( + _$_VeilidConfigHTTPS _value, $Res Function(_$_VeilidConfigHTTPS) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1852,7 +1842,7 @@ class __$$VeilidConfigHTTPSImplCopyWithImpl<$Res> Object? path = null, Object? url = freezed, }) { - return _then(_$VeilidConfigHTTPSImpl( + return _then(_$_VeilidConfigHTTPS( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -1875,17 +1865,17 @@ class __$$VeilidConfigHTTPSImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigHTTPSImpl +class _$_VeilidConfigHTTPS with DiagnosticableTreeMixin implements _VeilidConfigHTTPS { - const _$VeilidConfigHTTPSImpl( + const _$_VeilidConfigHTTPS( {required this.enabled, required this.listenAddress, required this.path, this.url}); - factory _$VeilidConfigHTTPSImpl.fromJson(Map json) => - _$$VeilidConfigHTTPSImplFromJson(json); + factory _$_VeilidConfigHTTPS.fromJson(Map json) => + _$$_VeilidConfigHTTPSFromJson(json); @override final bool enabled; @@ -1916,7 +1906,7 @@ class _$VeilidConfigHTTPSImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigHTTPSImpl && + other is _$_VeilidConfigHTTPS && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.listenAddress, listenAddress) || other.listenAddress == listenAddress) && @@ -1932,13 +1922,13 @@ class _$VeilidConfigHTTPSImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigHTTPSImplCopyWith<_$VeilidConfigHTTPSImpl> get copyWith => - __$$VeilidConfigHTTPSImplCopyWithImpl<_$VeilidConfigHTTPSImpl>( + _$$_VeilidConfigHTTPSCopyWith<_$_VeilidConfigHTTPS> get copyWith => + __$$_VeilidConfigHTTPSCopyWithImpl<_$_VeilidConfigHTTPS>( this, _$identity); @override Map toJson() { - return _$$VeilidConfigHTTPSImplToJson( + return _$$_VeilidConfigHTTPSToJson( this, ); } @@ -1949,10 +1939,10 @@ abstract class _VeilidConfigHTTPS implements VeilidConfigHTTPS { {required final bool enabled, required final String listenAddress, required final String path, - final String? url}) = _$VeilidConfigHTTPSImpl; + final String? url}) = _$_VeilidConfigHTTPS; factory _VeilidConfigHTTPS.fromJson(Map json) = - _$VeilidConfigHTTPSImpl.fromJson; + _$_VeilidConfigHTTPS.fromJson; @override bool get enabled; @@ -1964,7 +1954,7 @@ abstract class _VeilidConfigHTTPS implements VeilidConfigHTTPS { String? get url; @override @JsonKey(ignore: true) - _$$VeilidConfigHTTPSImplCopyWith<_$VeilidConfigHTTPSImpl> get copyWith => + _$$_VeilidConfigHTTPSCopyWith<_$_VeilidConfigHTTPS> get copyWith => throw _privateConstructorUsedError; } @@ -2034,22 +2024,22 @@ class _$VeilidConfigHTTPCopyWithImpl<$Res, $Val extends VeilidConfigHTTP> } /// @nodoc -abstract class _$$VeilidConfigHTTPImplCopyWith<$Res> +abstract class _$$_VeilidConfigHTTPCopyWith<$Res> implements $VeilidConfigHTTPCopyWith<$Res> { - factory _$$VeilidConfigHTTPImplCopyWith(_$VeilidConfigHTTPImpl value, - $Res Function(_$VeilidConfigHTTPImpl) then) = - __$$VeilidConfigHTTPImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigHTTPCopyWith( + _$_VeilidConfigHTTP value, $Res Function(_$_VeilidConfigHTTP) then) = + __$$_VeilidConfigHTTPCopyWithImpl<$Res>; @override @useResult $Res call({bool enabled, String listenAddress, String path, String? url}); } /// @nodoc -class __$$VeilidConfigHTTPImplCopyWithImpl<$Res> - extends _$VeilidConfigHTTPCopyWithImpl<$Res, _$VeilidConfigHTTPImpl> - implements _$$VeilidConfigHTTPImplCopyWith<$Res> { - __$$VeilidConfigHTTPImplCopyWithImpl(_$VeilidConfigHTTPImpl _value, - $Res Function(_$VeilidConfigHTTPImpl) _then) +class __$$_VeilidConfigHTTPCopyWithImpl<$Res> + extends _$VeilidConfigHTTPCopyWithImpl<$Res, _$_VeilidConfigHTTP> + implements _$$_VeilidConfigHTTPCopyWith<$Res> { + __$$_VeilidConfigHTTPCopyWithImpl( + _$_VeilidConfigHTTP _value, $Res Function(_$_VeilidConfigHTTP) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2060,7 +2050,7 @@ class __$$VeilidConfigHTTPImplCopyWithImpl<$Res> Object? path = null, Object? url = freezed, }) { - return _then(_$VeilidConfigHTTPImpl( + return _then(_$_VeilidConfigHTTP( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -2083,17 +2073,17 @@ class __$$VeilidConfigHTTPImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigHTTPImpl +class _$_VeilidConfigHTTP with DiagnosticableTreeMixin implements _VeilidConfigHTTP { - const _$VeilidConfigHTTPImpl( + const _$_VeilidConfigHTTP( {required this.enabled, required this.listenAddress, required this.path, this.url}); - factory _$VeilidConfigHTTPImpl.fromJson(Map json) => - _$$VeilidConfigHTTPImplFromJson(json); + factory _$_VeilidConfigHTTP.fromJson(Map json) => + _$$_VeilidConfigHTTPFromJson(json); @override final bool enabled; @@ -2124,7 +2114,7 @@ class _$VeilidConfigHTTPImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigHTTPImpl && + other is _$_VeilidConfigHTTP && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.listenAddress, listenAddress) || other.listenAddress == listenAddress) && @@ -2140,13 +2130,12 @@ class _$VeilidConfigHTTPImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigHTTPImplCopyWith<_$VeilidConfigHTTPImpl> get copyWith => - __$$VeilidConfigHTTPImplCopyWithImpl<_$VeilidConfigHTTPImpl>( - this, _$identity); + _$$_VeilidConfigHTTPCopyWith<_$_VeilidConfigHTTP> get copyWith => + __$$_VeilidConfigHTTPCopyWithImpl<_$_VeilidConfigHTTP>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigHTTPImplToJson( + return _$$_VeilidConfigHTTPToJson( this, ); } @@ -2157,10 +2146,10 @@ abstract class _VeilidConfigHTTP implements VeilidConfigHTTP { {required final bool enabled, required final String listenAddress, required final String path, - final String? url}) = _$VeilidConfigHTTPImpl; + final String? url}) = _$_VeilidConfigHTTP; factory _VeilidConfigHTTP.fromJson(Map json) = - _$VeilidConfigHTTPImpl.fromJson; + _$_VeilidConfigHTTP.fromJson; @override bool get enabled; @@ -2172,7 +2161,7 @@ abstract class _VeilidConfigHTTP implements VeilidConfigHTTP { String? get url; @override @JsonKey(ignore: true) - _$$VeilidConfigHTTPImplCopyWith<_$VeilidConfigHTTPImpl> get copyWith => + _$$_VeilidConfigHTTPCopyWith<_$_VeilidConfigHTTP> get copyWith => throw _privateConstructorUsedError; } @@ -2251,12 +2240,11 @@ class _$VeilidConfigApplicationCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigApplicationImplCopyWith<$Res> +abstract class _$$_VeilidConfigApplicationCopyWith<$Res> implements $VeilidConfigApplicationCopyWith<$Res> { - factory _$$VeilidConfigApplicationImplCopyWith( - _$VeilidConfigApplicationImpl value, - $Res Function(_$VeilidConfigApplicationImpl) then) = - __$$VeilidConfigApplicationImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigApplicationCopyWith(_$_VeilidConfigApplication value, + $Res Function(_$_VeilidConfigApplication) then) = + __$$_VeilidConfigApplicationCopyWithImpl<$Res>; @override @useResult $Res call({VeilidConfigHTTPS https, VeilidConfigHTTP http}); @@ -2268,13 +2256,12 @@ abstract class _$$VeilidConfigApplicationImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigApplicationImplCopyWithImpl<$Res> +class __$$_VeilidConfigApplicationCopyWithImpl<$Res> extends _$VeilidConfigApplicationCopyWithImpl<$Res, - _$VeilidConfigApplicationImpl> - implements _$$VeilidConfigApplicationImplCopyWith<$Res> { - __$$VeilidConfigApplicationImplCopyWithImpl( - _$VeilidConfigApplicationImpl _value, - $Res Function(_$VeilidConfigApplicationImpl) _then) + _$_VeilidConfigApplication> + implements _$$_VeilidConfigApplicationCopyWith<$Res> { + __$$_VeilidConfigApplicationCopyWithImpl(_$_VeilidConfigApplication _value, + $Res Function(_$_VeilidConfigApplication) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2283,7 +2270,7 @@ class __$$VeilidConfigApplicationImplCopyWithImpl<$Res> Object? https = null, Object? http = null, }) { - return _then(_$VeilidConfigApplicationImpl( + return _then(_$_VeilidConfigApplication( https: null == https ? _value.https : https // ignore: cast_nullable_to_non_nullable @@ -2298,14 +2285,13 @@ class __$$VeilidConfigApplicationImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigApplicationImpl +class _$_VeilidConfigApplication with DiagnosticableTreeMixin implements _VeilidConfigApplication { - const _$VeilidConfigApplicationImpl( - {required this.https, required this.http}); + const _$_VeilidConfigApplication({required this.https, required this.http}); - factory _$VeilidConfigApplicationImpl.fromJson(Map json) => - _$$VeilidConfigApplicationImplFromJson(json); + factory _$_VeilidConfigApplication.fromJson(Map json) => + _$$_VeilidConfigApplicationFromJson(json); @override final VeilidConfigHTTPS https; @@ -2330,7 +2316,7 @@ class _$VeilidConfigApplicationImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigApplicationImpl && + other is _$_VeilidConfigApplication && (identical(other.https, https) || other.https == https) && (identical(other.http, http) || other.http == http)); } @@ -2342,13 +2328,14 @@ class _$VeilidConfigApplicationImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigApplicationImplCopyWith<_$VeilidConfigApplicationImpl> - get copyWith => __$$VeilidConfigApplicationImplCopyWithImpl< - _$VeilidConfigApplicationImpl>(this, _$identity); + _$$_VeilidConfigApplicationCopyWith<_$_VeilidConfigApplication> + get copyWith => + __$$_VeilidConfigApplicationCopyWithImpl<_$_VeilidConfigApplication>( + this, _$identity); @override Map toJson() { - return _$$VeilidConfigApplicationImplToJson( + return _$$_VeilidConfigApplicationToJson( this, ); } @@ -2357,10 +2344,10 @@ class _$VeilidConfigApplicationImpl abstract class _VeilidConfigApplication implements VeilidConfigApplication { const factory _VeilidConfigApplication( {required final VeilidConfigHTTPS https, - required final VeilidConfigHTTP http}) = _$VeilidConfigApplicationImpl; + required final VeilidConfigHTTP http}) = _$_VeilidConfigApplication; factory _VeilidConfigApplication.fromJson(Map json) = - _$VeilidConfigApplicationImpl.fromJson; + _$_VeilidConfigApplication.fromJson; @override VeilidConfigHTTPS get https; @@ -2368,7 +2355,7 @@ abstract class _VeilidConfigApplication implements VeilidConfigApplication { VeilidConfigHTTP get http; @override @JsonKey(ignore: true) - _$$VeilidConfigApplicationImplCopyWith<_$VeilidConfigApplicationImpl> + _$$_VeilidConfigApplicationCopyWith<_$_VeilidConfigApplication> get copyWith => throw _privateConstructorUsedError; } @@ -2442,11 +2429,11 @@ class _$VeilidConfigUDPCopyWithImpl<$Res, $Val extends VeilidConfigUDP> } /// @nodoc -abstract class _$$VeilidConfigUDPImplCopyWith<$Res> +abstract class _$$_VeilidConfigUDPCopyWith<$Res> implements $VeilidConfigUDPCopyWith<$Res> { - factory _$$VeilidConfigUDPImplCopyWith(_$VeilidConfigUDPImpl value, - $Res Function(_$VeilidConfigUDPImpl) then) = - __$$VeilidConfigUDPImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigUDPCopyWith( + _$_VeilidConfigUDP value, $Res Function(_$_VeilidConfigUDP) then) = + __$$_VeilidConfigUDPCopyWithImpl<$Res>; @override @useResult $Res call( @@ -2457,11 +2444,11 @@ abstract class _$$VeilidConfigUDPImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigUDPImplCopyWithImpl<$Res> - extends _$VeilidConfigUDPCopyWithImpl<$Res, _$VeilidConfigUDPImpl> - implements _$$VeilidConfigUDPImplCopyWith<$Res> { - __$$VeilidConfigUDPImplCopyWithImpl( - _$VeilidConfigUDPImpl _value, $Res Function(_$VeilidConfigUDPImpl) _then) +class __$$_VeilidConfigUDPCopyWithImpl<$Res> + extends _$VeilidConfigUDPCopyWithImpl<$Res, _$_VeilidConfigUDP> + implements _$$_VeilidConfigUDPCopyWith<$Res> { + __$$_VeilidConfigUDPCopyWithImpl( + _$_VeilidConfigUDP _value, $Res Function(_$_VeilidConfigUDP) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2472,7 +2459,7 @@ class __$$VeilidConfigUDPImplCopyWithImpl<$Res> Object? listenAddress = null, Object? publicAddress = freezed, }) { - return _then(_$VeilidConfigUDPImpl( + return _then(_$_VeilidConfigUDP( enabled: null == enabled ? _value.enabled : enabled // ignore: cast_nullable_to_non_nullable @@ -2495,17 +2482,17 @@ class __$$VeilidConfigUDPImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigUDPImpl +class _$_VeilidConfigUDP with DiagnosticableTreeMixin implements _VeilidConfigUDP { - const _$VeilidConfigUDPImpl( + const _$_VeilidConfigUDP( {required this.enabled, required this.socketPoolSize, required this.listenAddress, this.publicAddress}); - factory _$VeilidConfigUDPImpl.fromJson(Map json) => - _$$VeilidConfigUDPImplFromJson(json); + factory _$_VeilidConfigUDP.fromJson(Map json) => + _$$_VeilidConfigUDPFromJson(json); @override final bool enabled; @@ -2536,7 +2523,7 @@ class _$VeilidConfigUDPImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigUDPImpl && + other is _$_VeilidConfigUDP && (identical(other.enabled, enabled) || other.enabled == enabled) && (identical(other.socketPoolSize, socketPoolSize) || other.socketPoolSize == socketPoolSize) && @@ -2554,13 +2541,12 @@ class _$VeilidConfigUDPImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigUDPImplCopyWith<_$VeilidConfigUDPImpl> get copyWith => - __$$VeilidConfigUDPImplCopyWithImpl<_$VeilidConfigUDPImpl>( - this, _$identity); + _$$_VeilidConfigUDPCopyWith<_$_VeilidConfigUDP> get copyWith => + __$$_VeilidConfigUDPCopyWithImpl<_$_VeilidConfigUDP>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigUDPImplToJson( + return _$$_VeilidConfigUDPToJson( this, ); } @@ -2571,10 +2557,10 @@ abstract class _VeilidConfigUDP implements VeilidConfigUDP { {required final bool enabled, required final int socketPoolSize, required final String listenAddress, - final String? publicAddress}) = _$VeilidConfigUDPImpl; + final String? publicAddress}) = _$_VeilidConfigUDP; factory _VeilidConfigUDP.fromJson(Map json) = - _$VeilidConfigUDPImpl.fromJson; + _$_VeilidConfigUDP.fromJson; @override bool get enabled; @@ -2586,7 +2572,7 @@ abstract class _VeilidConfigUDP implements VeilidConfigUDP { String? get publicAddress; @override @JsonKey(ignore: true) - _$$VeilidConfigUDPImplCopyWith<_$VeilidConfigUDPImpl> get copyWith => + _$$_VeilidConfigUDPCopyWith<_$_VeilidConfigUDP> get copyWith => throw _privateConstructorUsedError; } @@ -2667,11 +2653,11 @@ class _$VeilidConfigTCPCopyWithImpl<$Res, $Val extends VeilidConfigTCP> } /// @nodoc -abstract class _$$VeilidConfigTCPImplCopyWith<$Res> +abstract class _$$_VeilidConfigTCPCopyWith<$Res> implements $VeilidConfigTCPCopyWith<$Res> { - factory _$$VeilidConfigTCPImplCopyWith(_$VeilidConfigTCPImpl value, - $Res Function(_$VeilidConfigTCPImpl) then) = - __$$VeilidConfigTCPImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigTCPCopyWith( + _$_VeilidConfigTCP value, $Res Function(_$_VeilidConfigTCP) then) = + __$$_VeilidConfigTCPCopyWithImpl<$Res>; @override @useResult $Res call( @@ -2683,11 +2669,11 @@ abstract class _$$VeilidConfigTCPImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigTCPImplCopyWithImpl<$Res> - extends _$VeilidConfigTCPCopyWithImpl<$Res, _$VeilidConfigTCPImpl> - implements _$$VeilidConfigTCPImplCopyWith<$Res> { - __$$VeilidConfigTCPImplCopyWithImpl( - _$VeilidConfigTCPImpl _value, $Res Function(_$VeilidConfigTCPImpl) _then) +class __$$_VeilidConfigTCPCopyWithImpl<$Res> + extends _$VeilidConfigTCPCopyWithImpl<$Res, _$_VeilidConfigTCP> + implements _$$_VeilidConfigTCPCopyWith<$Res> { + __$$_VeilidConfigTCPCopyWithImpl( + _$_VeilidConfigTCP _value, $Res Function(_$_VeilidConfigTCP) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2699,7 +2685,7 @@ class __$$VeilidConfigTCPImplCopyWithImpl<$Res> Object? listenAddress = null, Object? publicAddress = freezed, }) { - return _then(_$VeilidConfigTCPImpl( + return _then(_$_VeilidConfigTCP( connect: null == connect ? _value.connect : connect // ignore: cast_nullable_to_non_nullable @@ -2726,18 +2712,18 @@ class __$$VeilidConfigTCPImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigTCPImpl +class _$_VeilidConfigTCP with DiagnosticableTreeMixin implements _VeilidConfigTCP { - const _$VeilidConfigTCPImpl( + const _$_VeilidConfigTCP( {required this.connect, required this.listen, required this.maxConnections, required this.listenAddress, this.publicAddress}); - factory _$VeilidConfigTCPImpl.fromJson(Map json) => - _$$VeilidConfigTCPImplFromJson(json); + factory _$_VeilidConfigTCP.fromJson(Map json) => + _$$_VeilidConfigTCPFromJson(json); @override final bool connect; @@ -2771,7 +2757,7 @@ class _$VeilidConfigTCPImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigTCPImpl && + other is _$_VeilidConfigTCP && (identical(other.connect, connect) || other.connect == connect) && (identical(other.listen, listen) || other.listen == listen) && (identical(other.maxConnections, maxConnections) || @@ -2790,13 +2776,12 @@ class _$VeilidConfigTCPImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigTCPImplCopyWith<_$VeilidConfigTCPImpl> get copyWith => - __$$VeilidConfigTCPImplCopyWithImpl<_$VeilidConfigTCPImpl>( - this, _$identity); + _$$_VeilidConfigTCPCopyWith<_$_VeilidConfigTCP> get copyWith => + __$$_VeilidConfigTCPCopyWithImpl<_$_VeilidConfigTCP>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigTCPImplToJson( + return _$$_VeilidConfigTCPToJson( this, ); } @@ -2808,10 +2793,10 @@ abstract class _VeilidConfigTCP implements VeilidConfigTCP { required final bool listen, required final int maxConnections, required final String listenAddress, - final String? publicAddress}) = _$VeilidConfigTCPImpl; + final String? publicAddress}) = _$_VeilidConfigTCP; factory _VeilidConfigTCP.fromJson(Map json) = - _$VeilidConfigTCPImpl.fromJson; + _$_VeilidConfigTCP.fromJson; @override bool get connect; @@ -2825,7 +2810,7 @@ abstract class _VeilidConfigTCP implements VeilidConfigTCP { String? get publicAddress; @override @JsonKey(ignore: true) - _$$VeilidConfigTCPImplCopyWith<_$VeilidConfigTCPImpl> get copyWith => + _$$_VeilidConfigTCPCopyWith<_$_VeilidConfigTCP> get copyWith => throw _privateConstructorUsedError; } @@ -2913,11 +2898,11 @@ class _$VeilidConfigWSCopyWithImpl<$Res, $Val extends VeilidConfigWS> } /// @nodoc -abstract class _$$VeilidConfigWSImplCopyWith<$Res> +abstract class _$$_VeilidConfigWSCopyWith<$Res> implements $VeilidConfigWSCopyWith<$Res> { - factory _$$VeilidConfigWSImplCopyWith(_$VeilidConfigWSImpl value, - $Res Function(_$VeilidConfigWSImpl) then) = - __$$VeilidConfigWSImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigWSCopyWith( + _$_VeilidConfigWS value, $Res Function(_$_VeilidConfigWS) then) = + __$$_VeilidConfigWSCopyWithImpl<$Res>; @override @useResult $Res call( @@ -2930,11 +2915,11 @@ abstract class _$$VeilidConfigWSImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigWSImplCopyWithImpl<$Res> - extends _$VeilidConfigWSCopyWithImpl<$Res, _$VeilidConfigWSImpl> - implements _$$VeilidConfigWSImplCopyWith<$Res> { - __$$VeilidConfigWSImplCopyWithImpl( - _$VeilidConfigWSImpl _value, $Res Function(_$VeilidConfigWSImpl) _then) +class __$$_VeilidConfigWSCopyWithImpl<$Res> + extends _$VeilidConfigWSCopyWithImpl<$Res, _$_VeilidConfigWS> + implements _$$_VeilidConfigWSCopyWith<$Res> { + __$$_VeilidConfigWSCopyWithImpl( + _$_VeilidConfigWS _value, $Res Function(_$_VeilidConfigWS) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2947,7 +2932,7 @@ class __$$VeilidConfigWSImplCopyWithImpl<$Res> Object? path = null, Object? url = freezed, }) { - return _then(_$VeilidConfigWSImpl( + return _then(_$_VeilidConfigWS( connect: null == connect ? _value.connect : connect // ignore: cast_nullable_to_non_nullable @@ -2978,10 +2963,10 @@ class __$$VeilidConfigWSImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigWSImpl +class _$_VeilidConfigWS with DiagnosticableTreeMixin implements _VeilidConfigWS { - const _$VeilidConfigWSImpl( + const _$_VeilidConfigWS( {required this.connect, required this.listen, required this.maxConnections, @@ -2989,8 +2974,8 @@ class _$VeilidConfigWSImpl required this.path, this.url}); - factory _$VeilidConfigWSImpl.fromJson(Map json) => - _$$VeilidConfigWSImplFromJson(json); + factory _$_VeilidConfigWS.fromJson(Map json) => + _$$_VeilidConfigWSFromJson(json); @override final bool connect; @@ -3027,7 +3012,7 @@ class _$VeilidConfigWSImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigWSImpl && + other is _$_VeilidConfigWS && (identical(other.connect, connect) || other.connect == connect) && (identical(other.listen, listen) || other.listen == listen) && (identical(other.maxConnections, maxConnections) || @@ -3046,13 +3031,12 @@ class _$VeilidConfigWSImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigWSImplCopyWith<_$VeilidConfigWSImpl> get copyWith => - __$$VeilidConfigWSImplCopyWithImpl<_$VeilidConfigWSImpl>( - this, _$identity); + _$$_VeilidConfigWSCopyWith<_$_VeilidConfigWS> get copyWith => + __$$_VeilidConfigWSCopyWithImpl<_$_VeilidConfigWS>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigWSImplToJson( + return _$$_VeilidConfigWSToJson( this, ); } @@ -3065,10 +3049,10 @@ abstract class _VeilidConfigWS implements VeilidConfigWS { required final int maxConnections, required final String listenAddress, required final String path, - final String? url}) = _$VeilidConfigWSImpl; + final String? url}) = _$_VeilidConfigWS; factory _VeilidConfigWS.fromJson(Map json) = - _$VeilidConfigWSImpl.fromJson; + _$_VeilidConfigWS.fromJson; @override bool get connect; @@ -3084,7 +3068,7 @@ abstract class _VeilidConfigWS implements VeilidConfigWS { String? get url; @override @JsonKey(ignore: true) - _$$VeilidConfigWSImplCopyWith<_$VeilidConfigWSImpl> get copyWith => + _$$_VeilidConfigWSCopyWith<_$_VeilidConfigWS> get copyWith => throw _privateConstructorUsedError; } @@ -3172,11 +3156,11 @@ class _$VeilidConfigWSSCopyWithImpl<$Res, $Val extends VeilidConfigWSS> } /// @nodoc -abstract class _$$VeilidConfigWSSImplCopyWith<$Res> +abstract class _$$_VeilidConfigWSSCopyWith<$Res> implements $VeilidConfigWSSCopyWith<$Res> { - factory _$$VeilidConfigWSSImplCopyWith(_$VeilidConfigWSSImpl value, - $Res Function(_$VeilidConfigWSSImpl) then) = - __$$VeilidConfigWSSImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigWSSCopyWith( + _$_VeilidConfigWSS value, $Res Function(_$_VeilidConfigWSS) then) = + __$$_VeilidConfigWSSCopyWithImpl<$Res>; @override @useResult $Res call( @@ -3189,11 +3173,11 @@ abstract class _$$VeilidConfigWSSImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigWSSImplCopyWithImpl<$Res> - extends _$VeilidConfigWSSCopyWithImpl<$Res, _$VeilidConfigWSSImpl> - implements _$$VeilidConfigWSSImplCopyWith<$Res> { - __$$VeilidConfigWSSImplCopyWithImpl( - _$VeilidConfigWSSImpl _value, $Res Function(_$VeilidConfigWSSImpl) _then) +class __$$_VeilidConfigWSSCopyWithImpl<$Res> + extends _$VeilidConfigWSSCopyWithImpl<$Res, _$_VeilidConfigWSS> + implements _$$_VeilidConfigWSSCopyWith<$Res> { + __$$_VeilidConfigWSSCopyWithImpl( + _$_VeilidConfigWSS _value, $Res Function(_$_VeilidConfigWSS) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3206,7 +3190,7 @@ class __$$VeilidConfigWSSImplCopyWithImpl<$Res> Object? path = null, Object? url = freezed, }) { - return _then(_$VeilidConfigWSSImpl( + return _then(_$_VeilidConfigWSS( connect: null == connect ? _value.connect : connect // ignore: cast_nullable_to_non_nullable @@ -3237,10 +3221,10 @@ class __$$VeilidConfigWSSImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigWSSImpl +class _$_VeilidConfigWSS with DiagnosticableTreeMixin implements _VeilidConfigWSS { - const _$VeilidConfigWSSImpl( + const _$_VeilidConfigWSS( {required this.connect, required this.listen, required this.maxConnections, @@ -3248,8 +3232,8 @@ class _$VeilidConfigWSSImpl required this.path, this.url}); - factory _$VeilidConfigWSSImpl.fromJson(Map json) => - _$$VeilidConfigWSSImplFromJson(json); + factory _$_VeilidConfigWSS.fromJson(Map json) => + _$$_VeilidConfigWSSFromJson(json); @override final bool connect; @@ -3286,7 +3270,7 @@ class _$VeilidConfigWSSImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigWSSImpl && + other is _$_VeilidConfigWSS && (identical(other.connect, connect) || other.connect == connect) && (identical(other.listen, listen) || other.listen == listen) && (identical(other.maxConnections, maxConnections) || @@ -3305,13 +3289,12 @@ class _$VeilidConfigWSSImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigWSSImplCopyWith<_$VeilidConfigWSSImpl> get copyWith => - __$$VeilidConfigWSSImplCopyWithImpl<_$VeilidConfigWSSImpl>( - this, _$identity); + _$$_VeilidConfigWSSCopyWith<_$_VeilidConfigWSS> get copyWith => + __$$_VeilidConfigWSSCopyWithImpl<_$_VeilidConfigWSS>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigWSSImplToJson( + return _$$_VeilidConfigWSSToJson( this, ); } @@ -3324,10 +3307,10 @@ abstract class _VeilidConfigWSS implements VeilidConfigWSS { required final int maxConnections, required final String listenAddress, required final String path, - final String? url}) = _$VeilidConfigWSSImpl; + final String? url}) = _$_VeilidConfigWSS; factory _VeilidConfigWSS.fromJson(Map json) = - _$VeilidConfigWSSImpl.fromJson; + _$_VeilidConfigWSS.fromJson; @override bool get connect; @@ -3343,7 +3326,7 @@ abstract class _VeilidConfigWSS implements VeilidConfigWSS { String? get url; @override @JsonKey(ignore: true) - _$$VeilidConfigWSSImplCopyWith<_$VeilidConfigWSSImpl> get copyWith => + _$$_VeilidConfigWSSCopyWith<_$_VeilidConfigWSS> get copyWith => throw _privateConstructorUsedError; } @@ -3455,11 +3438,11 @@ class _$VeilidConfigProtocolCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigProtocolImplCopyWith<$Res> +abstract class _$$_VeilidConfigProtocolCopyWith<$Res> implements $VeilidConfigProtocolCopyWith<$Res> { - factory _$$VeilidConfigProtocolImplCopyWith(_$VeilidConfigProtocolImpl value, - $Res Function(_$VeilidConfigProtocolImpl) then) = - __$$VeilidConfigProtocolImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigProtocolCopyWith(_$_VeilidConfigProtocol value, + $Res Function(_$_VeilidConfigProtocol) then) = + __$$_VeilidConfigProtocolCopyWithImpl<$Res>; @override @useResult $Res call( @@ -3479,11 +3462,11 @@ abstract class _$$VeilidConfigProtocolImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigProtocolImplCopyWithImpl<$Res> - extends _$VeilidConfigProtocolCopyWithImpl<$Res, _$VeilidConfigProtocolImpl> - implements _$$VeilidConfigProtocolImplCopyWith<$Res> { - __$$VeilidConfigProtocolImplCopyWithImpl(_$VeilidConfigProtocolImpl _value, - $Res Function(_$VeilidConfigProtocolImpl) _then) +class __$$_VeilidConfigProtocolCopyWithImpl<$Res> + extends _$VeilidConfigProtocolCopyWithImpl<$Res, _$_VeilidConfigProtocol> + implements _$$_VeilidConfigProtocolCopyWith<$Res> { + __$$_VeilidConfigProtocolCopyWithImpl(_$_VeilidConfigProtocol _value, + $Res Function(_$_VeilidConfigProtocol) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3494,7 +3477,7 @@ class __$$VeilidConfigProtocolImplCopyWithImpl<$Res> Object? ws = null, Object? wss = null, }) { - return _then(_$VeilidConfigProtocolImpl( + return _then(_$_VeilidConfigProtocol( udp: null == udp ? _value.udp : udp // ignore: cast_nullable_to_non_nullable @@ -3517,17 +3500,17 @@ class __$$VeilidConfigProtocolImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigProtocolImpl +class _$_VeilidConfigProtocol with DiagnosticableTreeMixin implements _VeilidConfigProtocol { - const _$VeilidConfigProtocolImpl( + const _$_VeilidConfigProtocol( {required this.udp, required this.tcp, required this.ws, required this.wss}); - factory _$VeilidConfigProtocolImpl.fromJson(Map json) => - _$$VeilidConfigProtocolImplFromJson(json); + factory _$_VeilidConfigProtocol.fromJson(Map json) => + _$$_VeilidConfigProtocolFromJson(json); @override final VeilidConfigUDP udp; @@ -3558,7 +3541,7 @@ class _$VeilidConfigProtocolImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigProtocolImpl && + other is _$_VeilidConfigProtocol && (identical(other.udp, udp) || other.udp == udp) && (identical(other.tcp, tcp) || other.tcp == tcp) && (identical(other.ws, ws) || other.ws == ws) && @@ -3572,14 +3555,13 @@ class _$VeilidConfigProtocolImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigProtocolImplCopyWith<_$VeilidConfigProtocolImpl> - get copyWith => - __$$VeilidConfigProtocolImplCopyWithImpl<_$VeilidConfigProtocolImpl>( - this, _$identity); + _$$_VeilidConfigProtocolCopyWith<_$_VeilidConfigProtocol> get copyWith => + __$$_VeilidConfigProtocolCopyWithImpl<_$_VeilidConfigProtocol>( + this, _$identity); @override Map toJson() { - return _$$VeilidConfigProtocolImplToJson( + return _$$_VeilidConfigProtocolToJson( this, ); } @@ -3590,10 +3572,10 @@ abstract class _VeilidConfigProtocol implements VeilidConfigProtocol { {required final VeilidConfigUDP udp, required final VeilidConfigTCP tcp, required final VeilidConfigWS ws, - required final VeilidConfigWSS wss}) = _$VeilidConfigProtocolImpl; + required final VeilidConfigWSS wss}) = _$_VeilidConfigProtocol; factory _VeilidConfigProtocol.fromJson(Map json) = - _$VeilidConfigProtocolImpl.fromJson; + _$_VeilidConfigProtocol.fromJson; @override VeilidConfigUDP get udp; @@ -3605,8 +3587,8 @@ abstract class _VeilidConfigProtocol implements VeilidConfigProtocol { VeilidConfigWSS get wss; @override @JsonKey(ignore: true) - _$$VeilidConfigProtocolImplCopyWith<_$VeilidConfigProtocolImpl> - get copyWith => throw _privateConstructorUsedError; + _$$_VeilidConfigProtocolCopyWith<_$_VeilidConfigProtocol> get copyWith => + throw _privateConstructorUsedError; } VeilidConfigTLS _$VeilidConfigTLSFromJson(Map json) { @@ -3672,11 +3654,11 @@ class _$VeilidConfigTLSCopyWithImpl<$Res, $Val extends VeilidConfigTLS> } /// @nodoc -abstract class _$$VeilidConfigTLSImplCopyWith<$Res> +abstract class _$$_VeilidConfigTLSCopyWith<$Res> implements $VeilidConfigTLSCopyWith<$Res> { - factory _$$VeilidConfigTLSImplCopyWith(_$VeilidConfigTLSImpl value, - $Res Function(_$VeilidConfigTLSImpl) then) = - __$$VeilidConfigTLSImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigTLSCopyWith( + _$_VeilidConfigTLS value, $Res Function(_$_VeilidConfigTLS) then) = + __$$_VeilidConfigTLSCopyWithImpl<$Res>; @override @useResult $Res call( @@ -3686,11 +3668,11 @@ abstract class _$$VeilidConfigTLSImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigTLSImplCopyWithImpl<$Res> - extends _$VeilidConfigTLSCopyWithImpl<$Res, _$VeilidConfigTLSImpl> - implements _$$VeilidConfigTLSImplCopyWith<$Res> { - __$$VeilidConfigTLSImplCopyWithImpl( - _$VeilidConfigTLSImpl _value, $Res Function(_$VeilidConfigTLSImpl) _then) +class __$$_VeilidConfigTLSCopyWithImpl<$Res> + extends _$VeilidConfigTLSCopyWithImpl<$Res, _$_VeilidConfigTLS> + implements _$$_VeilidConfigTLSCopyWith<$Res> { + __$$_VeilidConfigTLSCopyWithImpl( + _$_VeilidConfigTLS _value, $Res Function(_$_VeilidConfigTLS) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3700,7 +3682,7 @@ class __$$VeilidConfigTLSImplCopyWithImpl<$Res> Object? privateKeyPath = null, Object? connectionInitialTimeoutMs = null, }) { - return _then(_$VeilidConfigTLSImpl( + return _then(_$_VeilidConfigTLS( certificatePath: null == certificatePath ? _value.certificatePath : certificatePath // ignore: cast_nullable_to_non_nullable @@ -3719,16 +3701,16 @@ class __$$VeilidConfigTLSImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigTLSImpl +class _$_VeilidConfigTLS with DiagnosticableTreeMixin implements _VeilidConfigTLS { - const _$VeilidConfigTLSImpl( + const _$_VeilidConfigTLS( {required this.certificatePath, required this.privateKeyPath, required this.connectionInitialTimeoutMs}); - factory _$VeilidConfigTLSImpl.fromJson(Map json) => - _$$VeilidConfigTLSImplFromJson(json); + factory _$_VeilidConfigTLS.fromJson(Map json) => + _$$_VeilidConfigTLSFromJson(json); @override final String certificatePath; @@ -3757,7 +3739,7 @@ class _$VeilidConfigTLSImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigTLSImpl && + other is _$_VeilidConfigTLS && (identical(other.certificatePath, certificatePath) || other.certificatePath == certificatePath) && (identical(other.privateKeyPath, privateKeyPath) || @@ -3776,13 +3758,12 @@ class _$VeilidConfigTLSImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigTLSImplCopyWith<_$VeilidConfigTLSImpl> get copyWith => - __$$VeilidConfigTLSImplCopyWithImpl<_$VeilidConfigTLSImpl>( - this, _$identity); + _$$_VeilidConfigTLSCopyWith<_$_VeilidConfigTLS> get copyWith => + __$$_VeilidConfigTLSCopyWithImpl<_$_VeilidConfigTLS>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigTLSImplToJson( + return _$$_VeilidConfigTLSToJson( this, ); } @@ -3792,10 +3773,10 @@ abstract class _VeilidConfigTLS implements VeilidConfigTLS { const factory _VeilidConfigTLS( {required final String certificatePath, required final String privateKeyPath, - required final int connectionInitialTimeoutMs}) = _$VeilidConfigTLSImpl; + required final int connectionInitialTimeoutMs}) = _$_VeilidConfigTLS; factory _VeilidConfigTLS.fromJson(Map json) = - _$VeilidConfigTLSImpl.fromJson; + _$_VeilidConfigTLS.fromJson; @override String get certificatePath; @@ -3805,7 +3786,7 @@ abstract class _VeilidConfigTLS implements VeilidConfigTLS { int get connectionInitialTimeoutMs; @override @JsonKey(ignore: true) - _$$VeilidConfigTLSImplCopyWith<_$VeilidConfigTLSImpl> get copyWith => + _$$_VeilidConfigTLSCopyWith<_$_VeilidConfigTLS> get copyWith => throw _privateConstructorUsedError; } @@ -3834,6 +3815,9 @@ mixin _$VeilidConfigDHT { int get remoteMaxRecords => throw _privateConstructorUsedError; int get remoteMaxSubkeyCacheMemoryMb => throw _privateConstructorUsedError; int get remoteMaxStorageSpaceMb => throw _privateConstructorUsedError; + int get publicWatchLimit => throw _privateConstructorUsedError; + int get memberWatchLimit => throw _privateConstructorUsedError; + int get maxWatchExpirationMs => throw _privateConstructorUsedError; Map toJson() => throw _privateConstructorUsedError; @JsonKey(ignore: true) @@ -3866,7 +3850,10 @@ abstract class $VeilidConfigDHTCopyWith<$Res> { int remoteSubkeyCacheSize, int remoteMaxRecords, int remoteMaxSubkeyCacheMemoryMb, - int remoteMaxStorageSpaceMb}); + int remoteMaxStorageSpaceMb, + int publicWatchLimit, + int memberWatchLimit, + int maxWatchExpirationMs}); } /// @nodoc @@ -3901,6 +3888,9 @@ class _$VeilidConfigDHTCopyWithImpl<$Res, $Val extends VeilidConfigDHT> Object? remoteMaxRecords = null, Object? remoteMaxSubkeyCacheMemoryMb = null, Object? remoteMaxStorageSpaceMb = null, + Object? publicWatchLimit = null, + Object? memberWatchLimit = null, + Object? maxWatchExpirationMs = null, }) { return _then(_value.copyWith( resolveNodeTimeoutMs: null == resolveNodeTimeoutMs @@ -3979,16 +3969,28 @@ class _$VeilidConfigDHTCopyWithImpl<$Res, $Val extends VeilidConfigDHT> ? _value.remoteMaxStorageSpaceMb : remoteMaxStorageSpaceMb // ignore: cast_nullable_to_non_nullable as int, + publicWatchLimit: null == publicWatchLimit + ? _value.publicWatchLimit + : publicWatchLimit // ignore: cast_nullable_to_non_nullable + as int, + memberWatchLimit: null == memberWatchLimit + ? _value.memberWatchLimit + : memberWatchLimit // ignore: cast_nullable_to_non_nullable + as int, + maxWatchExpirationMs: null == maxWatchExpirationMs + ? _value.maxWatchExpirationMs + : maxWatchExpirationMs // ignore: cast_nullable_to_non_nullable + as int, ) as $Val); } } /// @nodoc -abstract class _$$VeilidConfigDHTImplCopyWith<$Res> +abstract class _$$_VeilidConfigDHTCopyWith<$Res> implements $VeilidConfigDHTCopyWith<$Res> { - factory _$$VeilidConfigDHTImplCopyWith(_$VeilidConfigDHTImpl value, - $Res Function(_$VeilidConfigDHTImpl) then) = - __$$VeilidConfigDHTImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigDHTCopyWith( + _$_VeilidConfigDHT value, $Res Function(_$_VeilidConfigDHT) then) = + __$$_VeilidConfigDHTCopyWithImpl<$Res>; @override @useResult $Res call( @@ -4010,15 +4012,18 @@ abstract class _$$VeilidConfigDHTImplCopyWith<$Res> int remoteSubkeyCacheSize, int remoteMaxRecords, int remoteMaxSubkeyCacheMemoryMb, - int remoteMaxStorageSpaceMb}); + int remoteMaxStorageSpaceMb, + int publicWatchLimit, + int memberWatchLimit, + int maxWatchExpirationMs}); } /// @nodoc -class __$$VeilidConfigDHTImplCopyWithImpl<$Res> - extends _$VeilidConfigDHTCopyWithImpl<$Res, _$VeilidConfigDHTImpl> - implements _$$VeilidConfigDHTImplCopyWith<$Res> { - __$$VeilidConfigDHTImplCopyWithImpl( - _$VeilidConfigDHTImpl _value, $Res Function(_$VeilidConfigDHTImpl) _then) +class __$$_VeilidConfigDHTCopyWithImpl<$Res> + extends _$VeilidConfigDHTCopyWithImpl<$Res, _$_VeilidConfigDHT> + implements _$$_VeilidConfigDHTCopyWith<$Res> { + __$$_VeilidConfigDHTCopyWithImpl( + _$_VeilidConfigDHT _value, $Res Function(_$_VeilidConfigDHT) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4043,8 +4048,11 @@ class __$$VeilidConfigDHTImplCopyWithImpl<$Res> Object? remoteMaxRecords = null, Object? remoteMaxSubkeyCacheMemoryMb = null, Object? remoteMaxStorageSpaceMb = null, + Object? publicWatchLimit = null, + Object? memberWatchLimit = null, + Object? maxWatchExpirationMs = null, }) { - return _then(_$VeilidConfigDHTImpl( + return _then(_$_VeilidConfigDHT( resolveNodeTimeoutMs: null == resolveNodeTimeoutMs ? _value.resolveNodeTimeoutMs : resolveNodeTimeoutMs // ignore: cast_nullable_to_non_nullable @@ -4121,16 +4129,28 @@ class __$$VeilidConfigDHTImplCopyWithImpl<$Res> ? _value.remoteMaxStorageSpaceMb : remoteMaxStorageSpaceMb // ignore: cast_nullable_to_non_nullable as int, + publicWatchLimit: null == publicWatchLimit + ? _value.publicWatchLimit + : publicWatchLimit // ignore: cast_nullable_to_non_nullable + as int, + memberWatchLimit: null == memberWatchLimit + ? _value.memberWatchLimit + : memberWatchLimit // ignore: cast_nullable_to_non_nullable + as int, + maxWatchExpirationMs: null == maxWatchExpirationMs + ? _value.maxWatchExpirationMs + : maxWatchExpirationMs // ignore: cast_nullable_to_non_nullable + as int, )); } } /// @nodoc @JsonSerializable() -class _$VeilidConfigDHTImpl +class _$_VeilidConfigDHT with DiagnosticableTreeMixin implements _VeilidConfigDHT { - const _$VeilidConfigDHTImpl( + const _$_VeilidConfigDHT( {required this.resolveNodeTimeoutMs, required this.resolveNodeCount, required this.resolveNodeFanout, @@ -4149,10 +4169,13 @@ class _$VeilidConfigDHTImpl required this.remoteSubkeyCacheSize, required this.remoteMaxRecords, required this.remoteMaxSubkeyCacheMemoryMb, - required this.remoteMaxStorageSpaceMb}); + required this.remoteMaxStorageSpaceMb, + required this.publicWatchLimit, + required this.memberWatchLimit, + required this.maxWatchExpirationMs}); - factory _$VeilidConfigDHTImpl.fromJson(Map json) => - _$$VeilidConfigDHTImplFromJson(json); + factory _$_VeilidConfigDHT.fromJson(Map json) => + _$$_VeilidConfigDHTFromJson(json); @override final int resolveNodeTimeoutMs; @@ -4192,10 +4215,16 @@ class _$VeilidConfigDHTImpl final int remoteMaxSubkeyCacheMemoryMb; @override final int remoteMaxStorageSpaceMb; + @override + final int publicWatchLimit; + @override + final int memberWatchLimit; + @override + final int maxWatchExpirationMs; @override String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { - return 'VeilidConfigDHT(resolveNodeTimeoutMs: $resolveNodeTimeoutMs, resolveNodeCount: $resolveNodeCount, resolveNodeFanout: $resolveNodeFanout, maxFindNodeCount: $maxFindNodeCount, getValueTimeoutMs: $getValueTimeoutMs, getValueCount: $getValueCount, getValueFanout: $getValueFanout, setValueTimeoutMs: $setValueTimeoutMs, setValueCount: $setValueCount, setValueFanout: $setValueFanout, minPeerCount: $minPeerCount, minPeerRefreshTimeMs: $minPeerRefreshTimeMs, validateDialInfoReceiptTimeMs: $validateDialInfoReceiptTimeMs, localSubkeyCacheSize: $localSubkeyCacheSize, localMaxSubkeyCacheMemoryMb: $localMaxSubkeyCacheMemoryMb, remoteSubkeyCacheSize: $remoteSubkeyCacheSize, remoteMaxRecords: $remoteMaxRecords, remoteMaxSubkeyCacheMemoryMb: $remoteMaxSubkeyCacheMemoryMb, remoteMaxStorageSpaceMb: $remoteMaxStorageSpaceMb)'; + return 'VeilidConfigDHT(resolveNodeTimeoutMs: $resolveNodeTimeoutMs, resolveNodeCount: $resolveNodeCount, resolveNodeFanout: $resolveNodeFanout, maxFindNodeCount: $maxFindNodeCount, getValueTimeoutMs: $getValueTimeoutMs, getValueCount: $getValueCount, getValueFanout: $getValueFanout, setValueTimeoutMs: $setValueTimeoutMs, setValueCount: $setValueCount, setValueFanout: $setValueFanout, minPeerCount: $minPeerCount, minPeerRefreshTimeMs: $minPeerRefreshTimeMs, validateDialInfoReceiptTimeMs: $validateDialInfoReceiptTimeMs, localSubkeyCacheSize: $localSubkeyCacheSize, localMaxSubkeyCacheMemoryMb: $localMaxSubkeyCacheMemoryMb, remoteSubkeyCacheSize: $remoteSubkeyCacheSize, remoteMaxRecords: $remoteMaxRecords, remoteMaxSubkeyCacheMemoryMb: $remoteMaxSubkeyCacheMemoryMb, remoteMaxStorageSpaceMb: $remoteMaxStorageSpaceMb, publicWatchLimit: $publicWatchLimit, memberWatchLimit: $memberWatchLimit, maxWatchExpirationMs: $maxWatchExpirationMs)'; } @override @@ -4225,14 +4254,17 @@ class _$VeilidConfigDHTImpl ..add(DiagnosticsProperty( 'remoteMaxSubkeyCacheMemoryMb', remoteMaxSubkeyCacheMemoryMb)) ..add(DiagnosticsProperty( - 'remoteMaxStorageSpaceMb', remoteMaxStorageSpaceMb)); + 'remoteMaxStorageSpaceMb', remoteMaxStorageSpaceMb)) + ..add(DiagnosticsProperty('publicWatchLimit', publicWatchLimit)) + ..add(DiagnosticsProperty('memberWatchLimit', memberWatchLimit)) + ..add(DiagnosticsProperty('maxWatchExpirationMs', maxWatchExpirationMs)); } @override bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigDHTImpl && + other is _$_VeilidConfigDHT && (identical(other.resolveNodeTimeoutMs, resolveNodeTimeoutMs) || other.resolveNodeTimeoutMs == resolveNodeTimeoutMs) && (identical(other.resolveNodeCount, resolveNodeCount) || @@ -4275,9 +4307,14 @@ class _$VeilidConfigDHTImpl remoteMaxSubkeyCacheMemoryMb) || other.remoteMaxSubkeyCacheMemoryMb == remoteMaxSubkeyCacheMemoryMb) && - (identical( - other.remoteMaxStorageSpaceMb, remoteMaxStorageSpaceMb) || - other.remoteMaxStorageSpaceMb == remoteMaxStorageSpaceMb)); + (identical(other.remoteMaxStorageSpaceMb, remoteMaxStorageSpaceMb) || + other.remoteMaxStorageSpaceMb == remoteMaxStorageSpaceMb) && + (identical(other.publicWatchLimit, publicWatchLimit) || + other.publicWatchLimit == publicWatchLimit) && + (identical(other.memberWatchLimit, memberWatchLimit) || + other.memberWatchLimit == memberWatchLimit) && + (identical(other.maxWatchExpirationMs, maxWatchExpirationMs) || + other.maxWatchExpirationMs == maxWatchExpirationMs)); } @JsonKey(ignore: true) @@ -4302,19 +4339,21 @@ class _$VeilidConfigDHTImpl remoteSubkeyCacheSize, remoteMaxRecords, remoteMaxSubkeyCacheMemoryMb, - remoteMaxStorageSpaceMb + remoteMaxStorageSpaceMb, + publicWatchLimit, + memberWatchLimit, + maxWatchExpirationMs ]); @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigDHTImplCopyWith<_$VeilidConfigDHTImpl> get copyWith => - __$$VeilidConfigDHTImplCopyWithImpl<_$VeilidConfigDHTImpl>( - this, _$identity); + _$$_VeilidConfigDHTCopyWith<_$_VeilidConfigDHT> get copyWith => + __$$_VeilidConfigDHTCopyWithImpl<_$_VeilidConfigDHT>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigDHTImplToJson( + return _$$_VeilidConfigDHTToJson( this, ); } @@ -4340,10 +4379,13 @@ abstract class _VeilidConfigDHT implements VeilidConfigDHT { required final int remoteSubkeyCacheSize, required final int remoteMaxRecords, required final int remoteMaxSubkeyCacheMemoryMb, - required final int remoteMaxStorageSpaceMb}) = _$VeilidConfigDHTImpl; + required final int remoteMaxStorageSpaceMb, + required final int publicWatchLimit, + required final int memberWatchLimit, + required final int maxWatchExpirationMs}) = _$_VeilidConfigDHT; factory _VeilidConfigDHT.fromJson(Map json) = - _$VeilidConfigDHTImpl.fromJson; + _$_VeilidConfigDHT.fromJson; @override int get resolveNodeTimeoutMs; @@ -4384,8 +4426,14 @@ abstract class _VeilidConfigDHT implements VeilidConfigDHT { @override int get remoteMaxStorageSpaceMb; @override + int get publicWatchLimit; + @override + int get memberWatchLimit; + @override + int get maxWatchExpirationMs; + @override @JsonKey(ignore: true) - _$$VeilidConfigDHTImplCopyWith<_$VeilidConfigDHTImpl> get copyWith => + _$$_VeilidConfigDHTCopyWith<_$_VeilidConfigDHT> get copyWith => throw _privateConstructorUsedError; } @@ -4480,11 +4528,11 @@ class _$VeilidConfigRPCCopyWithImpl<$Res, $Val extends VeilidConfigRPC> } /// @nodoc -abstract class _$$VeilidConfigRPCImplCopyWith<$Res> +abstract class _$$_VeilidConfigRPCCopyWith<$Res> implements $VeilidConfigRPCCopyWith<$Res> { - factory _$$VeilidConfigRPCImplCopyWith(_$VeilidConfigRPCImpl value, - $Res Function(_$VeilidConfigRPCImpl) then) = - __$$VeilidConfigRPCImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigRPCCopyWith( + _$_VeilidConfigRPC value, $Res Function(_$_VeilidConfigRPC) then) = + __$$_VeilidConfigRPCCopyWithImpl<$Res>; @override @useResult $Res call( @@ -4498,11 +4546,11 @@ abstract class _$$VeilidConfigRPCImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigRPCImplCopyWithImpl<$Res> - extends _$VeilidConfigRPCCopyWithImpl<$Res, _$VeilidConfigRPCImpl> - implements _$$VeilidConfigRPCImplCopyWith<$Res> { - __$$VeilidConfigRPCImplCopyWithImpl( - _$VeilidConfigRPCImpl _value, $Res Function(_$VeilidConfigRPCImpl) _then) +class __$$_VeilidConfigRPCCopyWithImpl<$Res> + extends _$VeilidConfigRPCCopyWithImpl<$Res, _$_VeilidConfigRPC> + implements _$$_VeilidConfigRPCCopyWith<$Res> { + __$$_VeilidConfigRPCCopyWithImpl( + _$_VeilidConfigRPC _value, $Res Function(_$_VeilidConfigRPC) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4516,7 +4564,7 @@ class __$$VeilidConfigRPCImplCopyWithImpl<$Res> Object? maxTimestampBehindMs = freezed, Object? maxTimestampAheadMs = freezed, }) { - return _then(_$VeilidConfigRPCImpl( + return _then(_$_VeilidConfigRPC( concurrency: null == concurrency ? _value.concurrency : concurrency // ignore: cast_nullable_to_non_nullable @@ -4551,10 +4599,10 @@ class __$$VeilidConfigRPCImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigRPCImpl +class _$_VeilidConfigRPC with DiagnosticableTreeMixin implements _VeilidConfigRPC { - const _$VeilidConfigRPCImpl( + const _$_VeilidConfigRPC( {required this.concurrency, required this.queueSize, required this.timeoutMs, @@ -4563,8 +4611,8 @@ class _$VeilidConfigRPCImpl this.maxTimestampBehindMs, this.maxTimestampAheadMs}); - factory _$VeilidConfigRPCImpl.fromJson(Map json) => - _$$VeilidConfigRPCImplFromJson(json); + factory _$_VeilidConfigRPC.fromJson(Map json) => + _$$_VeilidConfigRPCFromJson(json); @override final int concurrency; @@ -4604,7 +4652,7 @@ class _$VeilidConfigRPCImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigRPCImpl && + other is _$_VeilidConfigRPC && (identical(other.concurrency, concurrency) || other.concurrency == concurrency) && (identical(other.queueSize, queueSize) || @@ -4636,13 +4684,12 @@ class _$VeilidConfigRPCImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigRPCImplCopyWith<_$VeilidConfigRPCImpl> get copyWith => - __$$VeilidConfigRPCImplCopyWithImpl<_$VeilidConfigRPCImpl>( - this, _$identity); + _$$_VeilidConfigRPCCopyWith<_$_VeilidConfigRPC> get copyWith => + __$$_VeilidConfigRPCCopyWithImpl<_$_VeilidConfigRPC>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigRPCImplToJson( + return _$$_VeilidConfigRPCToJson( this, ); } @@ -4656,10 +4703,10 @@ abstract class _VeilidConfigRPC implements VeilidConfigRPC { required final int maxRouteHopCount, required final int defaultRouteHopCount, final int? maxTimestampBehindMs, - final int? maxTimestampAheadMs}) = _$VeilidConfigRPCImpl; + final int? maxTimestampAheadMs}) = _$_VeilidConfigRPC; factory _VeilidConfigRPC.fromJson(Map json) = - _$VeilidConfigRPCImpl.fromJson; + _$_VeilidConfigRPC.fromJson; @override int get concurrency; @@ -4677,7 +4724,7 @@ abstract class _VeilidConfigRPC implements VeilidConfigRPC { int? get maxTimestampAheadMs; @override @JsonKey(ignore: true) - _$$VeilidConfigRPCImplCopyWith<_$VeilidConfigRPCImpl> get copyWith => + _$$_VeilidConfigRPCCopyWith<_$_VeilidConfigRPC> get copyWith => throw _privateConstructorUsedError; } @@ -4783,12 +4830,12 @@ class _$VeilidConfigRoutingTableCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigRoutingTableImplCopyWith<$Res> +abstract class _$$_VeilidConfigRoutingTableCopyWith<$Res> implements $VeilidConfigRoutingTableCopyWith<$Res> { - factory _$$VeilidConfigRoutingTableImplCopyWith( - _$VeilidConfigRoutingTableImpl value, - $Res Function(_$VeilidConfigRoutingTableImpl) then) = - __$$VeilidConfigRoutingTableImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigRoutingTableCopyWith( + _$_VeilidConfigRoutingTable value, + $Res Function(_$_VeilidConfigRoutingTable) then) = + __$$_VeilidConfigRoutingTableCopyWithImpl<$Res>; @override @useResult $Res call( @@ -4803,13 +4850,12 @@ abstract class _$$VeilidConfigRoutingTableImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigRoutingTableImplCopyWithImpl<$Res> +class __$$_VeilidConfigRoutingTableCopyWithImpl<$Res> extends _$VeilidConfigRoutingTableCopyWithImpl<$Res, - _$VeilidConfigRoutingTableImpl> - implements _$$VeilidConfigRoutingTableImplCopyWith<$Res> { - __$$VeilidConfigRoutingTableImplCopyWithImpl( - _$VeilidConfigRoutingTableImpl _value, - $Res Function(_$VeilidConfigRoutingTableImpl) _then) + _$_VeilidConfigRoutingTable> + implements _$$_VeilidConfigRoutingTableCopyWith<$Res> { + __$$_VeilidConfigRoutingTableCopyWithImpl(_$_VeilidConfigRoutingTable _value, + $Res Function(_$_VeilidConfigRoutingTable) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4824,7 +4870,7 @@ class __$$VeilidConfigRoutingTableImplCopyWithImpl<$Res> Object? limitAttachedGood = null, Object? limitAttachedWeak = null, }) { - return _then(_$VeilidConfigRoutingTableImpl( + return _then(_$_VeilidConfigRoutingTable( nodeId: null == nodeId ? _value._nodeId : nodeId // ignore: cast_nullable_to_non_nullable @@ -4863,10 +4909,10 @@ class __$$VeilidConfigRoutingTableImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigRoutingTableImpl +class _$_VeilidConfigRoutingTable with DiagnosticableTreeMixin implements _VeilidConfigRoutingTable { - const _$VeilidConfigRoutingTableImpl( + const _$_VeilidConfigRoutingTable( {required final List> nodeId, required final List> nodeIdSecret, required final List bootstrap, @@ -4879,8 +4925,8 @@ class _$VeilidConfigRoutingTableImpl _nodeIdSecret = nodeIdSecret, _bootstrap = bootstrap; - factory _$VeilidConfigRoutingTableImpl.fromJson(Map json) => - _$$VeilidConfigRoutingTableImplFromJson(json); + factory _$_VeilidConfigRoutingTable.fromJson(Map json) => + _$$_VeilidConfigRoutingTableFromJson(json); final List> _nodeId; @override @@ -4941,7 +4987,7 @@ class _$VeilidConfigRoutingTableImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigRoutingTableImpl && + other is _$_VeilidConfigRoutingTable && const DeepCollectionEquality().equals(other._nodeId, _nodeId) && const DeepCollectionEquality() .equals(other._nodeIdSecret, _nodeIdSecret) && @@ -4975,13 +5021,13 @@ class _$VeilidConfigRoutingTableImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigRoutingTableImplCopyWith<_$VeilidConfigRoutingTableImpl> - get copyWith => __$$VeilidConfigRoutingTableImplCopyWithImpl< - _$VeilidConfigRoutingTableImpl>(this, _$identity); + _$$_VeilidConfigRoutingTableCopyWith<_$_VeilidConfigRoutingTable> + get copyWith => __$$_VeilidConfigRoutingTableCopyWithImpl< + _$_VeilidConfigRoutingTable>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigRoutingTableImplToJson( + return _$$_VeilidConfigRoutingTableToJson( this, ); } @@ -4996,10 +5042,10 @@ abstract class _VeilidConfigRoutingTable implements VeilidConfigRoutingTable { required final int limitFullyAttached, required final int limitAttachedStrong, required final int limitAttachedGood, - required final int limitAttachedWeak}) = _$VeilidConfigRoutingTableImpl; + required final int limitAttachedWeak}) = _$_VeilidConfigRoutingTable; factory _VeilidConfigRoutingTable.fromJson(Map json) = - _$VeilidConfigRoutingTableImpl.fromJson; + _$_VeilidConfigRoutingTable.fromJson; @override List> get nodeId; @@ -5019,7 +5065,7 @@ abstract class _VeilidConfigRoutingTable implements VeilidConfigRoutingTable { int get limitAttachedWeak; @override @JsonKey(ignore: true) - _$$VeilidConfigRoutingTableImplCopyWith<_$VeilidConfigRoutingTableImpl> + _$$_VeilidConfigRoutingTableCopyWith<_$_VeilidConfigRoutingTable> get copyWith => throw _privateConstructorUsedError; } @@ -5255,11 +5301,11 @@ class _$VeilidConfigNetworkCopyWithImpl<$Res, $Val extends VeilidConfigNetwork> } /// @nodoc -abstract class _$$VeilidConfigNetworkImplCopyWith<$Res> +abstract class _$$_VeilidConfigNetworkCopyWith<$Res> implements $VeilidConfigNetworkCopyWith<$Res> { - factory _$$VeilidConfigNetworkImplCopyWith(_$VeilidConfigNetworkImpl value, - $Res Function(_$VeilidConfigNetworkImpl) then) = - __$$VeilidConfigNetworkImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigNetworkCopyWith(_$_VeilidConfigNetwork value, + $Res Function(_$_VeilidConfigNetwork) then) = + __$$_VeilidConfigNetworkCopyWithImpl<$Res>; @override @useResult $Res call( @@ -5298,11 +5344,11 @@ abstract class _$$VeilidConfigNetworkImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigNetworkImplCopyWithImpl<$Res> - extends _$VeilidConfigNetworkCopyWithImpl<$Res, _$VeilidConfigNetworkImpl> - implements _$$VeilidConfigNetworkImplCopyWith<$Res> { - __$$VeilidConfigNetworkImplCopyWithImpl(_$VeilidConfigNetworkImpl _value, - $Res Function(_$VeilidConfigNetworkImpl) _then) +class __$$_VeilidConfigNetworkCopyWithImpl<$Res> + extends _$VeilidConfigNetworkCopyWithImpl<$Res, _$_VeilidConfigNetwork> + implements _$$_VeilidConfigNetworkCopyWith<$Res> { + __$$_VeilidConfigNetworkCopyWithImpl(_$_VeilidConfigNetwork _value, + $Res Function(_$_VeilidConfigNetwork) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -5328,7 +5374,7 @@ class __$$VeilidConfigNetworkImplCopyWithImpl<$Res> Object? protocol = null, Object? networkKeyPassword = freezed, }) { - return _then(_$VeilidConfigNetworkImpl( + return _then(_$_VeilidConfigNetwork( connectionInitialTimeoutMs: null == connectionInitialTimeoutMs ? _value.connectionInitialTimeoutMs : connectionInitialTimeoutMs // ignore: cast_nullable_to_non_nullable @@ -5411,10 +5457,10 @@ class __$$VeilidConfigNetworkImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigNetworkImpl +class _$_VeilidConfigNetwork with DiagnosticableTreeMixin implements _VeilidConfigNetwork { - const _$VeilidConfigNetworkImpl( + const _$_VeilidConfigNetwork( {required this.connectionInitialTimeoutMs, required this.connectionInactivityTimeoutMs, required this.maxConnectionsPerIp4, @@ -5435,8 +5481,8 @@ class _$VeilidConfigNetworkImpl required this.protocol, this.networkKeyPassword}); - factory _$VeilidConfigNetworkImpl.fromJson(Map json) => - _$$VeilidConfigNetworkImplFromJson(json); + factory _$_VeilidConfigNetwork.fromJson(Map json) => + _$$_VeilidConfigNetworkFromJson(json); @override final int connectionInitialTimeoutMs; @@ -5520,7 +5566,7 @@ class _$VeilidConfigNetworkImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigNetworkImpl && + other is _$_VeilidConfigNetwork && (identical(other.connectionInitialTimeoutMs, connectionInitialTimeoutMs) || other.connectionInitialTimeoutMs == connectionInitialTimeoutMs) && @@ -5592,13 +5638,13 @@ class _$VeilidConfigNetworkImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigNetworkImplCopyWith<_$VeilidConfigNetworkImpl> get copyWith => - __$$VeilidConfigNetworkImplCopyWithImpl<_$VeilidConfigNetworkImpl>( + _$$_VeilidConfigNetworkCopyWith<_$_VeilidConfigNetwork> get copyWith => + __$$_VeilidConfigNetworkCopyWithImpl<_$_VeilidConfigNetwork>( this, _$identity); @override Map toJson() { - return _$$VeilidConfigNetworkImplToJson( + return _$$_VeilidConfigNetworkToJson( this, ); } @@ -5624,10 +5670,10 @@ abstract class _VeilidConfigNetwork implements VeilidConfigNetwork { required final VeilidConfigTLS tls, required final VeilidConfigApplication application, required final VeilidConfigProtocol protocol, - final String? networkKeyPassword}) = _$VeilidConfigNetworkImpl; + final String? networkKeyPassword}) = _$_VeilidConfigNetwork; factory _VeilidConfigNetwork.fromJson(Map json) = - _$VeilidConfigNetworkImpl.fromJson; + _$_VeilidConfigNetwork.fromJson; @override int get connectionInitialTimeoutMs; @@ -5669,7 +5715,7 @@ abstract class _VeilidConfigNetwork implements VeilidConfigNetwork { String? get networkKeyPassword; @override @JsonKey(ignore: true) - _$$VeilidConfigNetworkImplCopyWith<_$VeilidConfigNetworkImpl> get copyWith => + _$$_VeilidConfigNetworkCopyWith<_$_VeilidConfigNetwork> get copyWith => throw _privateConstructorUsedError; } @@ -5729,25 +5775,23 @@ class _$VeilidConfigTableStoreCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigTableStoreImplCopyWith<$Res> +abstract class _$$_VeilidConfigTableStoreCopyWith<$Res> implements $VeilidConfigTableStoreCopyWith<$Res> { - factory _$$VeilidConfigTableStoreImplCopyWith( - _$VeilidConfigTableStoreImpl value, - $Res Function(_$VeilidConfigTableStoreImpl) then) = - __$$VeilidConfigTableStoreImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigTableStoreCopyWith(_$_VeilidConfigTableStore value, + $Res Function(_$_VeilidConfigTableStore) then) = + __$$_VeilidConfigTableStoreCopyWithImpl<$Res>; @override @useResult $Res call({String directory, bool delete}); } /// @nodoc -class __$$VeilidConfigTableStoreImplCopyWithImpl<$Res> +class __$$_VeilidConfigTableStoreCopyWithImpl<$Res> extends _$VeilidConfigTableStoreCopyWithImpl<$Res, - _$VeilidConfigTableStoreImpl> - implements _$$VeilidConfigTableStoreImplCopyWith<$Res> { - __$$VeilidConfigTableStoreImplCopyWithImpl( - _$VeilidConfigTableStoreImpl _value, - $Res Function(_$VeilidConfigTableStoreImpl) _then) + _$_VeilidConfigTableStore> + implements _$$_VeilidConfigTableStoreCopyWith<$Res> { + __$$_VeilidConfigTableStoreCopyWithImpl(_$_VeilidConfigTableStore _value, + $Res Function(_$_VeilidConfigTableStore) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -5756,7 +5800,7 @@ class __$$VeilidConfigTableStoreImplCopyWithImpl<$Res> Object? directory = null, Object? delete = null, }) { - return _then(_$VeilidConfigTableStoreImpl( + return _then(_$_VeilidConfigTableStore( directory: null == directory ? _value.directory : directory // ignore: cast_nullable_to_non_nullable @@ -5771,14 +5815,14 @@ class __$$VeilidConfigTableStoreImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigTableStoreImpl +class _$_VeilidConfigTableStore with DiagnosticableTreeMixin implements _VeilidConfigTableStore { - const _$VeilidConfigTableStoreImpl( + const _$_VeilidConfigTableStore( {required this.directory, required this.delete}); - factory _$VeilidConfigTableStoreImpl.fromJson(Map json) => - _$$VeilidConfigTableStoreImplFromJson(json); + factory _$_VeilidConfigTableStore.fromJson(Map json) => + _$$_VeilidConfigTableStoreFromJson(json); @override final String directory; @@ -5803,7 +5847,7 @@ class _$VeilidConfigTableStoreImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigTableStoreImpl && + other is _$_VeilidConfigTableStore && (identical(other.directory, directory) || other.directory == directory) && (identical(other.delete, delete) || other.delete == delete)); @@ -5816,13 +5860,13 @@ class _$VeilidConfigTableStoreImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigTableStoreImplCopyWith<_$VeilidConfigTableStoreImpl> - get copyWith => __$$VeilidConfigTableStoreImplCopyWithImpl< - _$VeilidConfigTableStoreImpl>(this, _$identity); + _$$_VeilidConfigTableStoreCopyWith<_$_VeilidConfigTableStore> get copyWith => + __$$_VeilidConfigTableStoreCopyWithImpl<_$_VeilidConfigTableStore>( + this, _$identity); @override Map toJson() { - return _$$VeilidConfigTableStoreImplToJson( + return _$$_VeilidConfigTableStoreToJson( this, ); } @@ -5831,10 +5875,10 @@ class _$VeilidConfigTableStoreImpl abstract class _VeilidConfigTableStore implements VeilidConfigTableStore { const factory _VeilidConfigTableStore( {required final String directory, - required final bool delete}) = _$VeilidConfigTableStoreImpl; + required final bool delete}) = _$_VeilidConfigTableStore; factory _VeilidConfigTableStore.fromJson(Map json) = - _$VeilidConfigTableStoreImpl.fromJson; + _$_VeilidConfigTableStore.fromJson; @override String get directory; @@ -5842,8 +5886,8 @@ abstract class _VeilidConfigTableStore implements VeilidConfigTableStore { bool get delete; @override @JsonKey(ignore: true) - _$$VeilidConfigTableStoreImplCopyWith<_$VeilidConfigTableStoreImpl> - get copyWith => throw _privateConstructorUsedError; + _$$_VeilidConfigTableStoreCopyWith<_$_VeilidConfigTableStore> get copyWith => + throw _privateConstructorUsedError; } VeilidConfigBlockStore _$VeilidConfigBlockStoreFromJson( @@ -5902,25 +5946,23 @@ class _$VeilidConfigBlockStoreCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigBlockStoreImplCopyWith<$Res> +abstract class _$$_VeilidConfigBlockStoreCopyWith<$Res> implements $VeilidConfigBlockStoreCopyWith<$Res> { - factory _$$VeilidConfigBlockStoreImplCopyWith( - _$VeilidConfigBlockStoreImpl value, - $Res Function(_$VeilidConfigBlockStoreImpl) then) = - __$$VeilidConfigBlockStoreImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigBlockStoreCopyWith(_$_VeilidConfigBlockStore value, + $Res Function(_$_VeilidConfigBlockStore) then) = + __$$_VeilidConfigBlockStoreCopyWithImpl<$Res>; @override @useResult $Res call({String directory, bool delete}); } /// @nodoc -class __$$VeilidConfigBlockStoreImplCopyWithImpl<$Res> +class __$$_VeilidConfigBlockStoreCopyWithImpl<$Res> extends _$VeilidConfigBlockStoreCopyWithImpl<$Res, - _$VeilidConfigBlockStoreImpl> - implements _$$VeilidConfigBlockStoreImplCopyWith<$Res> { - __$$VeilidConfigBlockStoreImplCopyWithImpl( - _$VeilidConfigBlockStoreImpl _value, - $Res Function(_$VeilidConfigBlockStoreImpl) _then) + _$_VeilidConfigBlockStore> + implements _$$_VeilidConfigBlockStoreCopyWith<$Res> { + __$$_VeilidConfigBlockStoreCopyWithImpl(_$_VeilidConfigBlockStore _value, + $Res Function(_$_VeilidConfigBlockStore) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -5929,7 +5971,7 @@ class __$$VeilidConfigBlockStoreImplCopyWithImpl<$Res> Object? directory = null, Object? delete = null, }) { - return _then(_$VeilidConfigBlockStoreImpl( + return _then(_$_VeilidConfigBlockStore( directory: null == directory ? _value.directory : directory // ignore: cast_nullable_to_non_nullable @@ -5944,14 +5986,14 @@ class __$$VeilidConfigBlockStoreImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigBlockStoreImpl +class _$_VeilidConfigBlockStore with DiagnosticableTreeMixin implements _VeilidConfigBlockStore { - const _$VeilidConfigBlockStoreImpl( + const _$_VeilidConfigBlockStore( {required this.directory, required this.delete}); - factory _$VeilidConfigBlockStoreImpl.fromJson(Map json) => - _$$VeilidConfigBlockStoreImplFromJson(json); + factory _$_VeilidConfigBlockStore.fromJson(Map json) => + _$$_VeilidConfigBlockStoreFromJson(json); @override final String directory; @@ -5976,7 +6018,7 @@ class _$VeilidConfigBlockStoreImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigBlockStoreImpl && + other is _$_VeilidConfigBlockStore && (identical(other.directory, directory) || other.directory == directory) && (identical(other.delete, delete) || other.delete == delete)); @@ -5989,13 +6031,13 @@ class _$VeilidConfigBlockStoreImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigBlockStoreImplCopyWith<_$VeilidConfigBlockStoreImpl> - get copyWith => __$$VeilidConfigBlockStoreImplCopyWithImpl< - _$VeilidConfigBlockStoreImpl>(this, _$identity); + _$$_VeilidConfigBlockStoreCopyWith<_$_VeilidConfigBlockStore> get copyWith => + __$$_VeilidConfigBlockStoreCopyWithImpl<_$_VeilidConfigBlockStore>( + this, _$identity); @override Map toJson() { - return _$$VeilidConfigBlockStoreImplToJson( + return _$$_VeilidConfigBlockStoreToJson( this, ); } @@ -6004,10 +6046,10 @@ class _$VeilidConfigBlockStoreImpl abstract class _VeilidConfigBlockStore implements VeilidConfigBlockStore { const factory _VeilidConfigBlockStore( {required final String directory, - required final bool delete}) = _$VeilidConfigBlockStoreImpl; + required final bool delete}) = _$_VeilidConfigBlockStore; factory _VeilidConfigBlockStore.fromJson(Map json) = - _$VeilidConfigBlockStoreImpl.fromJson; + _$_VeilidConfigBlockStore.fromJson; @override String get directory; @@ -6015,8 +6057,8 @@ abstract class _VeilidConfigBlockStore implements VeilidConfigBlockStore { bool get delete; @override @JsonKey(ignore: true) - _$$VeilidConfigBlockStoreImplCopyWith<_$VeilidConfigBlockStoreImpl> - get copyWith => throw _privateConstructorUsedError; + _$$_VeilidConfigBlockStoreCopyWith<_$_VeilidConfigBlockStore> get copyWith => + throw _privateConstructorUsedError; } VeilidConfigProtectedStore _$VeilidConfigProtectedStoreFromJson( @@ -6107,12 +6149,12 @@ class _$VeilidConfigProtectedStoreCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigProtectedStoreImplCopyWith<$Res> +abstract class _$$_VeilidConfigProtectedStoreCopyWith<$Res> implements $VeilidConfigProtectedStoreCopyWith<$Res> { - factory _$$VeilidConfigProtectedStoreImplCopyWith( - _$VeilidConfigProtectedStoreImpl value, - $Res Function(_$VeilidConfigProtectedStoreImpl) then) = - __$$VeilidConfigProtectedStoreImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigProtectedStoreCopyWith( + _$_VeilidConfigProtectedStore value, + $Res Function(_$_VeilidConfigProtectedStore) then) = + __$$_VeilidConfigProtectedStoreCopyWithImpl<$Res>; @override @useResult $Res call( @@ -6125,13 +6167,13 @@ abstract class _$$VeilidConfigProtectedStoreImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigProtectedStoreImplCopyWithImpl<$Res> +class __$$_VeilidConfigProtectedStoreCopyWithImpl<$Res> extends _$VeilidConfigProtectedStoreCopyWithImpl<$Res, - _$VeilidConfigProtectedStoreImpl> - implements _$$VeilidConfigProtectedStoreImplCopyWith<$Res> { - __$$VeilidConfigProtectedStoreImplCopyWithImpl( - _$VeilidConfigProtectedStoreImpl _value, - $Res Function(_$VeilidConfigProtectedStoreImpl) _then) + _$_VeilidConfigProtectedStore> + implements _$$_VeilidConfigProtectedStoreCopyWith<$Res> { + __$$_VeilidConfigProtectedStoreCopyWithImpl( + _$_VeilidConfigProtectedStore _value, + $Res Function(_$_VeilidConfigProtectedStore) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -6144,7 +6186,7 @@ class __$$VeilidConfigProtectedStoreImplCopyWithImpl<$Res> Object? deviceEncryptionKeyPassword = null, Object? newDeviceEncryptionKeyPassword = freezed, }) { - return _then(_$VeilidConfigProtectedStoreImpl( + return _then(_$_VeilidConfigProtectedStore( allowInsecureFallback: null == allowInsecureFallback ? _value.allowInsecureFallback : allowInsecureFallback // ignore: cast_nullable_to_non_nullable @@ -6175,10 +6217,10 @@ class __$$VeilidConfigProtectedStoreImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigProtectedStoreImpl +class _$_VeilidConfigProtectedStore with DiagnosticableTreeMixin implements _VeilidConfigProtectedStore { - const _$VeilidConfigProtectedStoreImpl( + const _$_VeilidConfigProtectedStore( {required this.allowInsecureFallback, required this.alwaysUseInsecureStorage, required this.directory, @@ -6186,9 +6228,8 @@ class _$VeilidConfigProtectedStoreImpl required this.deviceEncryptionKeyPassword, this.newDeviceEncryptionKeyPassword}); - factory _$VeilidConfigProtectedStoreImpl.fromJson( - Map json) => - _$$VeilidConfigProtectedStoreImplFromJson(json); + factory _$_VeilidConfigProtectedStore.fromJson(Map json) => + _$$_VeilidConfigProtectedStoreFromJson(json); @override final bool allowInsecureFallback; @@ -6228,7 +6269,7 @@ class _$VeilidConfigProtectedStoreImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigProtectedStoreImpl && + other is _$_VeilidConfigProtectedStore && (identical(other.allowInsecureFallback, allowInsecureFallback) || other.allowInsecureFallback == allowInsecureFallback) && (identical( @@ -6261,13 +6302,13 @@ class _$VeilidConfigProtectedStoreImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigProtectedStoreImplCopyWith<_$VeilidConfigProtectedStoreImpl> - get copyWith => __$$VeilidConfigProtectedStoreImplCopyWithImpl< - _$VeilidConfigProtectedStoreImpl>(this, _$identity); + _$$_VeilidConfigProtectedStoreCopyWith<_$_VeilidConfigProtectedStore> + get copyWith => __$$_VeilidConfigProtectedStoreCopyWithImpl< + _$_VeilidConfigProtectedStore>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigProtectedStoreImplToJson( + return _$$_VeilidConfigProtectedStoreToJson( this, ); } @@ -6282,10 +6323,10 @@ abstract class _VeilidConfigProtectedStore required final bool delete, required final String deviceEncryptionKeyPassword, final String? newDeviceEncryptionKeyPassword}) = - _$VeilidConfigProtectedStoreImpl; + _$_VeilidConfigProtectedStore; factory _VeilidConfigProtectedStore.fromJson(Map json) = - _$VeilidConfigProtectedStoreImpl.fromJson; + _$_VeilidConfigProtectedStore.fromJson; @override bool get allowInsecureFallback; @@ -6301,7 +6342,7 @@ abstract class _VeilidConfigProtectedStore String? get newDeviceEncryptionKeyPassword; @override @JsonKey(ignore: true) - _$$VeilidConfigProtectedStoreImplCopyWith<_$VeilidConfigProtectedStoreImpl> + _$$_VeilidConfigProtectedStoreCopyWith<_$_VeilidConfigProtectedStore> get copyWith => throw _privateConstructorUsedError; } @@ -6355,25 +6396,24 @@ class _$VeilidConfigCapabilitiesCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidConfigCapabilitiesImplCopyWith<$Res> +abstract class _$$_VeilidConfigCapabilitiesCopyWith<$Res> implements $VeilidConfigCapabilitiesCopyWith<$Res> { - factory _$$VeilidConfigCapabilitiesImplCopyWith( - _$VeilidConfigCapabilitiesImpl value, - $Res Function(_$VeilidConfigCapabilitiesImpl) then) = - __$$VeilidConfigCapabilitiesImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigCapabilitiesCopyWith( + _$_VeilidConfigCapabilities value, + $Res Function(_$_VeilidConfigCapabilities) then) = + __$$_VeilidConfigCapabilitiesCopyWithImpl<$Res>; @override @useResult $Res call({List disable}); } /// @nodoc -class __$$VeilidConfigCapabilitiesImplCopyWithImpl<$Res> +class __$$_VeilidConfigCapabilitiesCopyWithImpl<$Res> extends _$VeilidConfigCapabilitiesCopyWithImpl<$Res, - _$VeilidConfigCapabilitiesImpl> - implements _$$VeilidConfigCapabilitiesImplCopyWith<$Res> { - __$$VeilidConfigCapabilitiesImplCopyWithImpl( - _$VeilidConfigCapabilitiesImpl _value, - $Res Function(_$VeilidConfigCapabilitiesImpl) _then) + _$_VeilidConfigCapabilities> + implements _$$_VeilidConfigCapabilitiesCopyWith<$Res> { + __$$_VeilidConfigCapabilitiesCopyWithImpl(_$_VeilidConfigCapabilities _value, + $Res Function(_$_VeilidConfigCapabilities) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -6381,7 +6421,7 @@ class __$$VeilidConfigCapabilitiesImplCopyWithImpl<$Res> $Res call({ Object? disable = null, }) { - return _then(_$VeilidConfigCapabilitiesImpl( + return _then(_$_VeilidConfigCapabilities( disable: null == disable ? _value._disable : disable // ignore: cast_nullable_to_non_nullable @@ -6392,14 +6432,14 @@ class __$$VeilidConfigCapabilitiesImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigCapabilitiesImpl +class _$_VeilidConfigCapabilities with DiagnosticableTreeMixin implements _VeilidConfigCapabilities { - const _$VeilidConfigCapabilitiesImpl({required final List disable}) + const _$_VeilidConfigCapabilities({required final List disable}) : _disable = disable; - factory _$VeilidConfigCapabilitiesImpl.fromJson(Map json) => - _$$VeilidConfigCapabilitiesImplFromJson(json); + factory _$_VeilidConfigCapabilities.fromJson(Map json) => + _$$_VeilidConfigCapabilitiesFromJson(json); final List _disable; @override @@ -6426,7 +6466,7 @@ class _$VeilidConfigCapabilitiesImpl bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigCapabilitiesImpl && + other is _$_VeilidConfigCapabilities && const DeepCollectionEquality().equals(other._disable, _disable)); } @@ -6438,13 +6478,13 @@ class _$VeilidConfigCapabilitiesImpl @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigCapabilitiesImplCopyWith<_$VeilidConfigCapabilitiesImpl> - get copyWith => __$$VeilidConfigCapabilitiesImplCopyWithImpl< - _$VeilidConfigCapabilitiesImpl>(this, _$identity); + _$$_VeilidConfigCapabilitiesCopyWith<_$_VeilidConfigCapabilities> + get copyWith => __$$_VeilidConfigCapabilitiesCopyWithImpl< + _$_VeilidConfigCapabilities>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigCapabilitiesImplToJson( + return _$$_VeilidConfigCapabilitiesToJson( this, ); } @@ -6452,16 +6492,16 @@ class _$VeilidConfigCapabilitiesImpl abstract class _VeilidConfigCapabilities implements VeilidConfigCapabilities { const factory _VeilidConfigCapabilities( - {required final List disable}) = _$VeilidConfigCapabilitiesImpl; + {required final List disable}) = _$_VeilidConfigCapabilities; factory _VeilidConfigCapabilities.fromJson(Map json) = - _$VeilidConfigCapabilitiesImpl.fromJson; + _$_VeilidConfigCapabilities.fromJson; @override List get disable; @override @JsonKey(ignore: true) - _$$VeilidConfigCapabilitiesImplCopyWith<_$VeilidConfigCapabilitiesImpl> + _$$_VeilidConfigCapabilitiesCopyWith<_$_VeilidConfigCapabilities> get copyWith => throw _privateConstructorUsedError; } @@ -6606,11 +6646,11 @@ class _$VeilidConfigCopyWithImpl<$Res, $Val extends VeilidConfig> } /// @nodoc -abstract class _$$VeilidConfigImplCopyWith<$Res> +abstract class _$$_VeilidConfigCopyWith<$Res> implements $VeilidConfigCopyWith<$Res> { - factory _$$VeilidConfigImplCopyWith( - _$VeilidConfigImpl value, $Res Function(_$VeilidConfigImpl) then) = - __$$VeilidConfigImplCopyWithImpl<$Res>; + factory _$$_VeilidConfigCopyWith( + _$_VeilidConfig value, $Res Function(_$_VeilidConfig) then) = + __$$_VeilidConfigCopyWithImpl<$Res>; @override @useResult $Res call( @@ -6635,11 +6675,11 @@ abstract class _$$VeilidConfigImplCopyWith<$Res> } /// @nodoc -class __$$VeilidConfigImplCopyWithImpl<$Res> - extends _$VeilidConfigCopyWithImpl<$Res, _$VeilidConfigImpl> - implements _$$VeilidConfigImplCopyWith<$Res> { - __$$VeilidConfigImplCopyWithImpl( - _$VeilidConfigImpl _value, $Res Function(_$VeilidConfigImpl) _then) +class __$$_VeilidConfigCopyWithImpl<$Res> + extends _$VeilidConfigCopyWithImpl<$Res, _$_VeilidConfig> + implements _$$_VeilidConfigCopyWith<$Res> { + __$$_VeilidConfigCopyWithImpl( + _$_VeilidConfig _value, $Res Function(_$_VeilidConfig) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -6653,7 +6693,7 @@ class __$$VeilidConfigImplCopyWithImpl<$Res> Object? blockStore = null, Object? network = null, }) { - return _then(_$VeilidConfigImpl( + return _then(_$_VeilidConfig( programName: null == programName ? _value.programName : programName // ignore: cast_nullable_to_non_nullable @@ -6688,8 +6728,8 @@ class __$$VeilidConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidConfigImpl with DiagnosticableTreeMixin implements _VeilidConfig { - const _$VeilidConfigImpl( +class _$_VeilidConfig with DiagnosticableTreeMixin implements _VeilidConfig { + const _$_VeilidConfig( {required this.programName, required this.namespace, required this.capabilities, @@ -6698,8 +6738,8 @@ class _$VeilidConfigImpl with DiagnosticableTreeMixin implements _VeilidConfig { required this.blockStore, required this.network}); - factory _$VeilidConfigImpl.fromJson(Map json) => - _$$VeilidConfigImplFromJson(json); + factory _$_VeilidConfig.fromJson(Map json) => + _$$_VeilidConfigFromJson(json); @override final String programName; @@ -6739,7 +6779,7 @@ class _$VeilidConfigImpl with DiagnosticableTreeMixin implements _VeilidConfig { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidConfigImpl && + other is _$_VeilidConfig && (identical(other.programName, programName) || other.programName == programName) && (identical(other.namespace, namespace) || @@ -6763,12 +6803,12 @@ class _$VeilidConfigImpl with DiagnosticableTreeMixin implements _VeilidConfig { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidConfigImplCopyWith<_$VeilidConfigImpl> get copyWith => - __$$VeilidConfigImplCopyWithImpl<_$VeilidConfigImpl>(this, _$identity); + _$$_VeilidConfigCopyWith<_$_VeilidConfig> get copyWith => + __$$_VeilidConfigCopyWithImpl<_$_VeilidConfig>(this, _$identity); @override Map toJson() { - return _$$VeilidConfigImplToJson( + return _$$_VeilidConfigToJson( this, ); } @@ -6782,10 +6822,10 @@ abstract class _VeilidConfig implements VeilidConfig { required final VeilidConfigProtectedStore protectedStore, required final VeilidConfigTableStore tableStore, required final VeilidConfigBlockStore blockStore, - required final VeilidConfigNetwork network}) = _$VeilidConfigImpl; + required final VeilidConfigNetwork network}) = _$_VeilidConfig; factory _VeilidConfig.fromJson(Map json) = - _$VeilidConfigImpl.fromJson; + _$_VeilidConfig.fromJson; @override String get programName; @@ -6803,6 +6843,6 @@ abstract class _VeilidConfig implements VeilidConfig { VeilidConfigNetwork get network; @override @JsonKey(ignore: true) - _$$VeilidConfigImplCopyWith<_$VeilidConfigImpl> get copyWith => + _$$_VeilidConfigCopyWith<_$_VeilidConfig> get copyWith => throw _privateConstructorUsedError; } diff --git a/veilid-flutter/lib/veilid_config.g.dart b/veilid-flutter/lib/veilid_config.g.dart index b6079785..08170e0a 100644 --- a/veilid-flutter/lib/veilid_config.g.dart +++ b/veilid-flutter/lib/veilid_config.g.dart @@ -6,31 +6,31 @@ part of 'veilid_config.dart'; // JsonSerializableGenerator // ************************************************************************** -_$VeilidFFIConfigLoggingTerminalImpl - _$$VeilidFFIConfigLoggingTerminalImplFromJson(Map json) => - _$VeilidFFIConfigLoggingTerminalImpl( - enabled: json['enabled'] as bool, - level: VeilidConfigLogLevel.fromJson(json['level']), - ); +_$_VeilidFFIConfigLoggingTerminal _$$_VeilidFFIConfigLoggingTerminalFromJson( + Map json) => + _$_VeilidFFIConfigLoggingTerminal( + enabled: json['enabled'] as bool, + level: VeilidConfigLogLevel.fromJson(json['level']), + ); -Map _$$VeilidFFIConfigLoggingTerminalImplToJson( - _$VeilidFFIConfigLoggingTerminalImpl instance) => +Map _$$_VeilidFFIConfigLoggingTerminalToJson( + _$_VeilidFFIConfigLoggingTerminal instance) => { 'enabled': instance.enabled, 'level': instance.level.toJson(), }; -_$VeilidFFIConfigLoggingOtlpImpl _$$VeilidFFIConfigLoggingOtlpImplFromJson( +_$_VeilidFFIConfigLoggingOtlp _$$_VeilidFFIConfigLoggingOtlpFromJson( Map json) => - _$VeilidFFIConfigLoggingOtlpImpl( + _$_VeilidFFIConfigLoggingOtlp( enabled: json['enabled'] as bool, level: VeilidConfigLogLevel.fromJson(json['level']), grpcEndpoint: json['grpc_endpoint'] as String, serviceName: json['service_name'] as String, ); -Map _$$VeilidFFIConfigLoggingOtlpImplToJson( - _$VeilidFFIConfigLoggingOtlpImpl instance) => +Map _$$_VeilidFFIConfigLoggingOtlpToJson( + _$_VeilidFFIConfigLoggingOtlp instance) => { 'enabled': instance.enabled, 'level': instance.level.toJson(), @@ -38,60 +38,57 @@ Map _$$VeilidFFIConfigLoggingOtlpImplToJson( 'service_name': instance.serviceName, }; -_$VeilidFFIConfigLoggingApiImpl _$$VeilidFFIConfigLoggingApiImplFromJson( +_$_VeilidFFIConfigLoggingApi _$$_VeilidFFIConfigLoggingApiFromJson( Map json) => - _$VeilidFFIConfigLoggingApiImpl( + _$_VeilidFFIConfigLoggingApi( enabled: json['enabled'] as bool, level: VeilidConfigLogLevel.fromJson(json['level']), ); -Map _$$VeilidFFIConfigLoggingApiImplToJson( - _$VeilidFFIConfigLoggingApiImpl instance) => +Map _$$_VeilidFFIConfigLoggingApiToJson( + _$_VeilidFFIConfigLoggingApi instance) => { 'enabled': instance.enabled, 'level': instance.level.toJson(), }; -_$VeilidFFIConfigLoggingImpl _$$VeilidFFIConfigLoggingImplFromJson( +_$_VeilidFFIConfigLogging _$$_VeilidFFIConfigLoggingFromJson( Map json) => - _$VeilidFFIConfigLoggingImpl( + _$_VeilidFFIConfigLogging( terminal: VeilidFFIConfigLoggingTerminal.fromJson(json['terminal']), otlp: VeilidFFIConfigLoggingOtlp.fromJson(json['otlp']), api: VeilidFFIConfigLoggingApi.fromJson(json['api']), ); -Map _$$VeilidFFIConfigLoggingImplToJson( - _$VeilidFFIConfigLoggingImpl instance) => +Map _$$_VeilidFFIConfigLoggingToJson( + _$_VeilidFFIConfigLogging instance) => { 'terminal': instance.terminal.toJson(), 'otlp': instance.otlp.toJson(), 'api': instance.api.toJson(), }; -_$VeilidFFIConfigImpl _$$VeilidFFIConfigImplFromJson( - Map json) => - _$VeilidFFIConfigImpl( +_$_VeilidFFIConfig _$$_VeilidFFIConfigFromJson(Map json) => + _$_VeilidFFIConfig( logging: VeilidFFIConfigLogging.fromJson(json['logging']), ); -Map _$$VeilidFFIConfigImplToJson( - _$VeilidFFIConfigImpl instance) => +Map _$$_VeilidFFIConfigToJson(_$_VeilidFFIConfig instance) => { 'logging': instance.logging.toJson(), }; -_$VeilidWASMConfigLoggingPerformanceImpl - _$$VeilidWASMConfigLoggingPerformanceImplFromJson( - Map json) => - _$VeilidWASMConfigLoggingPerformanceImpl( +_$_VeilidWASMConfigLoggingPerformance + _$$_VeilidWASMConfigLoggingPerformanceFromJson(Map json) => + _$_VeilidWASMConfigLoggingPerformance( enabled: json['enabled'] as bool, level: VeilidConfigLogLevel.fromJson(json['level']), logsInTimings: json['logs_in_timings'] as bool, logsInConsole: json['logs_in_console'] as bool, ); -Map _$$VeilidWASMConfigLoggingPerformanceImplToJson( - _$VeilidWASMConfigLoggingPerformanceImpl instance) => +Map _$$_VeilidWASMConfigLoggingPerformanceToJson( + _$_VeilidWASMConfigLoggingPerformance instance) => { 'enabled': instance.enabled, 'level': instance.level.toJson(), @@ -99,58 +96,55 @@ Map _$$VeilidWASMConfigLoggingPerformanceImplToJson( 'logs_in_console': instance.logsInConsole, }; -_$VeilidWASMConfigLoggingApiImpl _$$VeilidWASMConfigLoggingApiImplFromJson( +_$_VeilidWASMConfigLoggingApi _$$_VeilidWASMConfigLoggingApiFromJson( Map json) => - _$VeilidWASMConfigLoggingApiImpl( + _$_VeilidWASMConfigLoggingApi( enabled: json['enabled'] as bool, level: VeilidConfigLogLevel.fromJson(json['level']), ); -Map _$$VeilidWASMConfigLoggingApiImplToJson( - _$VeilidWASMConfigLoggingApiImpl instance) => +Map _$$_VeilidWASMConfigLoggingApiToJson( + _$_VeilidWASMConfigLoggingApi instance) => { 'enabled': instance.enabled, 'level': instance.level.toJson(), }; -_$VeilidWASMConfigLoggingImpl _$$VeilidWASMConfigLoggingImplFromJson( +_$_VeilidWASMConfigLogging _$$_VeilidWASMConfigLoggingFromJson( Map json) => - _$VeilidWASMConfigLoggingImpl( + _$_VeilidWASMConfigLogging( performance: VeilidWASMConfigLoggingPerformance.fromJson(json['performance']), api: VeilidWASMConfigLoggingApi.fromJson(json['api']), ); -Map _$$VeilidWASMConfigLoggingImplToJson( - _$VeilidWASMConfigLoggingImpl instance) => +Map _$$_VeilidWASMConfigLoggingToJson( + _$_VeilidWASMConfigLogging instance) => { 'performance': instance.performance.toJson(), 'api': instance.api.toJson(), }; -_$VeilidWASMConfigImpl _$$VeilidWASMConfigImplFromJson( - Map json) => - _$VeilidWASMConfigImpl( +_$_VeilidWASMConfig _$$_VeilidWASMConfigFromJson(Map json) => + _$_VeilidWASMConfig( logging: VeilidWASMConfigLogging.fromJson(json['logging']), ); -Map _$$VeilidWASMConfigImplToJson( - _$VeilidWASMConfigImpl instance) => +Map _$$_VeilidWASMConfigToJson(_$_VeilidWASMConfig instance) => { 'logging': instance.logging.toJson(), }; -_$VeilidConfigHTTPSImpl _$$VeilidConfigHTTPSImplFromJson( - Map json) => - _$VeilidConfigHTTPSImpl( +_$_VeilidConfigHTTPS _$$_VeilidConfigHTTPSFromJson(Map json) => + _$_VeilidConfigHTTPS( enabled: json['enabled'] as bool, listenAddress: json['listen_address'] as String, path: json['path'] as String, url: json['url'] as String?, ); -Map _$$VeilidConfigHTTPSImplToJson( - _$VeilidConfigHTTPSImpl instance) => +Map _$$_VeilidConfigHTTPSToJson( + _$_VeilidConfigHTTPS instance) => { 'enabled': instance.enabled, 'listen_address': instance.listenAddress, @@ -158,17 +152,15 @@ Map _$$VeilidConfigHTTPSImplToJson( 'url': instance.url, }; -_$VeilidConfigHTTPImpl _$$VeilidConfigHTTPImplFromJson( - Map json) => - _$VeilidConfigHTTPImpl( +_$_VeilidConfigHTTP _$$_VeilidConfigHTTPFromJson(Map json) => + _$_VeilidConfigHTTP( enabled: json['enabled'] as bool, listenAddress: json['listen_address'] as String, path: json['path'] as String, url: json['url'] as String?, ); -Map _$$VeilidConfigHTTPImplToJson( - _$VeilidConfigHTTPImpl instance) => +Map _$$_VeilidConfigHTTPToJson(_$_VeilidConfigHTTP instance) => { 'enabled': instance.enabled, 'listen_address': instance.listenAddress, @@ -176,31 +168,29 @@ Map _$$VeilidConfigHTTPImplToJson( 'url': instance.url, }; -_$VeilidConfigApplicationImpl _$$VeilidConfigApplicationImplFromJson( +_$_VeilidConfigApplication _$$_VeilidConfigApplicationFromJson( Map json) => - _$VeilidConfigApplicationImpl( + _$_VeilidConfigApplication( https: VeilidConfigHTTPS.fromJson(json['https']), http: VeilidConfigHTTP.fromJson(json['http']), ); -Map _$$VeilidConfigApplicationImplToJson( - _$VeilidConfigApplicationImpl instance) => +Map _$$_VeilidConfigApplicationToJson( + _$_VeilidConfigApplication instance) => { 'https': instance.https.toJson(), 'http': instance.http.toJson(), }; -_$VeilidConfigUDPImpl _$$VeilidConfigUDPImplFromJson( - Map json) => - _$VeilidConfigUDPImpl( +_$_VeilidConfigUDP _$$_VeilidConfigUDPFromJson(Map json) => + _$_VeilidConfigUDP( enabled: json['enabled'] as bool, socketPoolSize: json['socket_pool_size'] as int, listenAddress: json['listen_address'] as String, publicAddress: json['public_address'] as String?, ); -Map _$$VeilidConfigUDPImplToJson( - _$VeilidConfigUDPImpl instance) => +Map _$$_VeilidConfigUDPToJson(_$_VeilidConfigUDP instance) => { 'enabled': instance.enabled, 'socket_pool_size': instance.socketPoolSize, @@ -208,9 +198,8 @@ Map _$$VeilidConfigUDPImplToJson( 'public_address': instance.publicAddress, }; -_$VeilidConfigTCPImpl _$$VeilidConfigTCPImplFromJson( - Map json) => - _$VeilidConfigTCPImpl( +_$_VeilidConfigTCP _$$_VeilidConfigTCPFromJson(Map json) => + _$_VeilidConfigTCP( connect: json['connect'] as bool, listen: json['listen'] as bool, maxConnections: json['max_connections'] as int, @@ -218,8 +207,7 @@ _$VeilidConfigTCPImpl _$$VeilidConfigTCPImplFromJson( publicAddress: json['public_address'] as String?, ); -Map _$$VeilidConfigTCPImplToJson( - _$VeilidConfigTCPImpl instance) => +Map _$$_VeilidConfigTCPToJson(_$_VeilidConfigTCP instance) => { 'connect': instance.connect, 'listen': instance.listen, @@ -228,8 +216,8 @@ Map _$$VeilidConfigTCPImplToJson( 'public_address': instance.publicAddress, }; -_$VeilidConfigWSImpl _$$VeilidConfigWSImplFromJson(Map json) => - _$VeilidConfigWSImpl( +_$_VeilidConfigWS _$$_VeilidConfigWSFromJson(Map json) => + _$_VeilidConfigWS( connect: json['connect'] as bool, listen: json['listen'] as bool, maxConnections: json['max_connections'] as int, @@ -238,8 +226,7 @@ _$VeilidConfigWSImpl _$$VeilidConfigWSImplFromJson(Map json) => url: json['url'] as String?, ); -Map _$$VeilidConfigWSImplToJson( - _$VeilidConfigWSImpl instance) => +Map _$$_VeilidConfigWSToJson(_$_VeilidConfigWS instance) => { 'connect': instance.connect, 'listen': instance.listen, @@ -249,9 +236,8 @@ Map _$$VeilidConfigWSImplToJson( 'url': instance.url, }; -_$VeilidConfigWSSImpl _$$VeilidConfigWSSImplFromJson( - Map json) => - _$VeilidConfigWSSImpl( +_$_VeilidConfigWSS _$$_VeilidConfigWSSFromJson(Map json) => + _$_VeilidConfigWSS( connect: json['connect'] as bool, listen: json['listen'] as bool, maxConnections: json['max_connections'] as int, @@ -260,8 +246,7 @@ _$VeilidConfigWSSImpl _$$VeilidConfigWSSImplFromJson( url: json['url'] as String?, ); -Map _$$VeilidConfigWSSImplToJson( - _$VeilidConfigWSSImpl instance) => +Map _$$_VeilidConfigWSSToJson(_$_VeilidConfigWSS instance) => { 'connect': instance.connect, 'listen': instance.listen, @@ -271,17 +256,17 @@ Map _$$VeilidConfigWSSImplToJson( 'url': instance.url, }; -_$VeilidConfigProtocolImpl _$$VeilidConfigProtocolImplFromJson( +_$_VeilidConfigProtocol _$$_VeilidConfigProtocolFromJson( Map json) => - _$VeilidConfigProtocolImpl( + _$_VeilidConfigProtocol( udp: VeilidConfigUDP.fromJson(json['udp']), tcp: VeilidConfigTCP.fromJson(json['tcp']), ws: VeilidConfigWS.fromJson(json['ws']), wss: VeilidConfigWSS.fromJson(json['wss']), ); -Map _$$VeilidConfigProtocolImplToJson( - _$VeilidConfigProtocolImpl instance) => +Map _$$_VeilidConfigProtocolToJson( + _$_VeilidConfigProtocol instance) => { 'udp': instance.udp.toJson(), 'tcp': instance.tcp.toJson(), @@ -289,25 +274,22 @@ Map _$$VeilidConfigProtocolImplToJson( 'wss': instance.wss.toJson(), }; -_$VeilidConfigTLSImpl _$$VeilidConfigTLSImplFromJson( - Map json) => - _$VeilidConfigTLSImpl( +_$_VeilidConfigTLS _$$_VeilidConfigTLSFromJson(Map json) => + _$_VeilidConfigTLS( certificatePath: json['certificate_path'] as String, privateKeyPath: json['private_key_path'] as String, connectionInitialTimeoutMs: json['connection_initial_timeout_ms'] as int, ); -Map _$$VeilidConfigTLSImplToJson( - _$VeilidConfigTLSImpl instance) => +Map _$$_VeilidConfigTLSToJson(_$_VeilidConfigTLS instance) => { 'certificate_path': instance.certificatePath, 'private_key_path': instance.privateKeyPath, 'connection_initial_timeout_ms': instance.connectionInitialTimeoutMs, }; -_$VeilidConfigDHTImpl _$$VeilidConfigDHTImplFromJson( - Map json) => - _$VeilidConfigDHTImpl( +_$_VeilidConfigDHT _$$_VeilidConfigDHTFromJson(Map json) => + _$_VeilidConfigDHT( resolveNodeTimeoutMs: json['resolve_node_timeout_ms'] as int, resolveNodeCount: json['resolve_node_count'] as int, resolveNodeFanout: json['resolve_node_fanout'] as int, @@ -330,10 +312,12 @@ _$VeilidConfigDHTImpl _$$VeilidConfigDHTImplFromJson( remoteMaxSubkeyCacheMemoryMb: json['remote_max_subkey_cache_memory_mb'] as int, remoteMaxStorageSpaceMb: json['remote_max_storage_space_mb'] as int, + publicWatchLimit: json['public_watch_limit'] as int, + memberWatchLimit: json['member_watch_limit'] as int, + maxWatchExpirationMs: json['max_watch_expiration_ms'] as int, ); -Map _$$VeilidConfigDHTImplToJson( - _$VeilidConfigDHTImpl instance) => +Map _$$_VeilidConfigDHTToJson(_$_VeilidConfigDHT instance) => { 'resolve_node_timeout_ms': instance.resolveNodeTimeoutMs, 'resolve_node_count': instance.resolveNodeCount, @@ -356,11 +340,13 @@ Map _$$VeilidConfigDHTImplToJson( 'remote_max_subkey_cache_memory_mb': instance.remoteMaxSubkeyCacheMemoryMb, 'remote_max_storage_space_mb': instance.remoteMaxStorageSpaceMb, + 'public_watch_limit': instance.publicWatchLimit, + 'member_watch_limit': instance.memberWatchLimit, + 'max_watch_expiration_ms': instance.maxWatchExpirationMs, }; -_$VeilidConfigRPCImpl _$$VeilidConfigRPCImplFromJson( - Map json) => - _$VeilidConfigRPCImpl( +_$_VeilidConfigRPC _$$_VeilidConfigRPCFromJson(Map json) => + _$_VeilidConfigRPC( concurrency: json['concurrency'] as int, queueSize: json['queue_size'] as int, timeoutMs: json['timeout_ms'] as int, @@ -370,8 +356,7 @@ _$VeilidConfigRPCImpl _$$VeilidConfigRPCImplFromJson( maxTimestampAheadMs: json['max_timestamp_ahead_ms'] as int?, ); -Map _$$VeilidConfigRPCImplToJson( - _$VeilidConfigRPCImpl instance) => +Map _$$_VeilidConfigRPCToJson(_$_VeilidConfigRPC instance) => { 'concurrency': instance.concurrency, 'queue_size': instance.queueSize, @@ -382,9 +367,9 @@ Map _$$VeilidConfigRPCImplToJson( 'max_timestamp_ahead_ms': instance.maxTimestampAheadMs, }; -_$VeilidConfigRoutingTableImpl _$$VeilidConfigRoutingTableImplFromJson( +_$_VeilidConfigRoutingTable _$$_VeilidConfigRoutingTableFromJson( Map json) => - _$VeilidConfigRoutingTableImpl( + _$_VeilidConfigRoutingTable( nodeId: (json['node_id'] as List) .map(Typed.fromJson) .toList(), @@ -400,8 +385,8 @@ _$VeilidConfigRoutingTableImpl _$$VeilidConfigRoutingTableImplFromJson( limitAttachedWeak: json['limit_attached_weak'] as int, ); -Map _$$VeilidConfigRoutingTableImplToJson( - _$VeilidConfigRoutingTableImpl instance) => +Map _$$_VeilidConfigRoutingTableToJson( + _$_VeilidConfigRoutingTable instance) => { 'node_id': instance.nodeId.map((e) => e.toJson()).toList(), 'node_id_secret': instance.nodeIdSecret.map((e) => e.toJson()).toList(), @@ -413,9 +398,9 @@ Map _$$VeilidConfigRoutingTableImplToJson( 'limit_attached_weak': instance.limitAttachedWeak, }; -_$VeilidConfigNetworkImpl _$$VeilidConfigNetworkImplFromJson( +_$_VeilidConfigNetwork _$$_VeilidConfigNetworkFromJson( Map json) => - _$VeilidConfigNetworkImpl( + _$_VeilidConfigNetwork( connectionInitialTimeoutMs: json['connection_initial_timeout_ms'] as int, connectionInactivityTimeoutMs: json['connection_inactivity_timeout_ms'] as int, @@ -441,8 +426,8 @@ _$VeilidConfigNetworkImpl _$$VeilidConfigNetworkImplFromJson( networkKeyPassword: json['network_key_password'] as String?, ); -Map _$$VeilidConfigNetworkImplToJson( - _$VeilidConfigNetworkImpl instance) => +Map _$$_VeilidConfigNetworkToJson( + _$_VeilidConfigNetwork instance) => { 'connection_initial_timeout_ms': instance.connectionInitialTimeoutMs, 'connection_inactivity_timeout_ms': @@ -468,37 +453,37 @@ Map _$$VeilidConfigNetworkImplToJson( 'network_key_password': instance.networkKeyPassword, }; -_$VeilidConfigTableStoreImpl _$$VeilidConfigTableStoreImplFromJson( +_$_VeilidConfigTableStore _$$_VeilidConfigTableStoreFromJson( Map json) => - _$VeilidConfigTableStoreImpl( + _$_VeilidConfigTableStore( directory: json['directory'] as String, delete: json['delete'] as bool, ); -Map _$$VeilidConfigTableStoreImplToJson( - _$VeilidConfigTableStoreImpl instance) => +Map _$$_VeilidConfigTableStoreToJson( + _$_VeilidConfigTableStore instance) => { 'directory': instance.directory, 'delete': instance.delete, }; -_$VeilidConfigBlockStoreImpl _$$VeilidConfigBlockStoreImplFromJson( +_$_VeilidConfigBlockStore _$$_VeilidConfigBlockStoreFromJson( Map json) => - _$VeilidConfigBlockStoreImpl( + _$_VeilidConfigBlockStore( directory: json['directory'] as String, delete: json['delete'] as bool, ); -Map _$$VeilidConfigBlockStoreImplToJson( - _$VeilidConfigBlockStoreImpl instance) => +Map _$$_VeilidConfigBlockStoreToJson( + _$_VeilidConfigBlockStore instance) => { 'directory': instance.directory, 'delete': instance.delete, }; -_$VeilidConfigProtectedStoreImpl _$$VeilidConfigProtectedStoreImplFromJson( +_$_VeilidConfigProtectedStore _$$_VeilidConfigProtectedStoreFromJson( Map json) => - _$VeilidConfigProtectedStoreImpl( + _$_VeilidConfigProtectedStore( allowInsecureFallback: json['allow_insecure_fallback'] as bool, alwaysUseInsecureStorage: json['always_use_insecure_storage'] as bool, directory: json['directory'] as String, @@ -509,8 +494,8 @@ _$VeilidConfigProtectedStoreImpl _$$VeilidConfigProtectedStoreImplFromJson( json['new_device_encryption_key_password'] as String?, ); -Map _$$VeilidConfigProtectedStoreImplToJson( - _$VeilidConfigProtectedStoreImpl instance) => +Map _$$_VeilidConfigProtectedStoreToJson( + _$_VeilidConfigProtectedStore instance) => { 'allow_insecure_fallback': instance.allowInsecureFallback, 'always_use_insecure_storage': instance.alwaysUseInsecureStorage, @@ -521,21 +506,21 @@ Map _$$VeilidConfigProtectedStoreImplToJson( instance.newDeviceEncryptionKeyPassword, }; -_$VeilidConfigCapabilitiesImpl _$$VeilidConfigCapabilitiesImplFromJson( +_$_VeilidConfigCapabilities _$$_VeilidConfigCapabilitiesFromJson( Map json) => - _$VeilidConfigCapabilitiesImpl( + _$_VeilidConfigCapabilities( disable: (json['disable'] as List).map((e) => e as String).toList(), ); -Map _$$VeilidConfigCapabilitiesImplToJson( - _$VeilidConfigCapabilitiesImpl instance) => +Map _$$_VeilidConfigCapabilitiesToJson( + _$_VeilidConfigCapabilities instance) => { 'disable': instance.disable, }; -_$VeilidConfigImpl _$$VeilidConfigImplFromJson(Map json) => - _$VeilidConfigImpl( +_$_VeilidConfig _$$_VeilidConfigFromJson(Map json) => + _$_VeilidConfig( programName: json['program_name'] as String, namespace: json['namespace'] as String, capabilities: VeilidConfigCapabilities.fromJson(json['capabilities']), @@ -546,7 +531,7 @@ _$VeilidConfigImpl _$$VeilidConfigImplFromJson(Map json) => network: VeilidConfigNetwork.fromJson(json['network']), ); -Map _$$VeilidConfigImplToJson(_$VeilidConfigImpl instance) => +Map _$$_VeilidConfigToJson(_$_VeilidConfig instance) => { 'program_name': instance.programName, 'namespace': instance.namespace, diff --git a/veilid-flutter/lib/veilid_state.freezed.dart b/veilid-flutter/lib/veilid_state.freezed.dart index dddf627f..ca6d13af 100644 --- a/veilid-flutter/lib/veilid_state.freezed.dart +++ b/veilid-flutter/lib/veilid_state.freezed.dart @@ -77,11 +77,11 @@ class _$LatencyStatsCopyWithImpl<$Res, $Val extends LatencyStats> } /// @nodoc -abstract class _$$LatencyStatsImplCopyWith<$Res> +abstract class _$$_LatencyStatsCopyWith<$Res> implements $LatencyStatsCopyWith<$Res> { - factory _$$LatencyStatsImplCopyWith( - _$LatencyStatsImpl value, $Res Function(_$LatencyStatsImpl) then) = - __$$LatencyStatsImplCopyWithImpl<$Res>; + factory _$$_LatencyStatsCopyWith( + _$_LatencyStats value, $Res Function(_$_LatencyStats) then) = + __$$_LatencyStatsCopyWithImpl<$Res>; @override @useResult $Res call( @@ -91,11 +91,11 @@ abstract class _$$LatencyStatsImplCopyWith<$Res> } /// @nodoc -class __$$LatencyStatsImplCopyWithImpl<$Res> - extends _$LatencyStatsCopyWithImpl<$Res, _$LatencyStatsImpl> - implements _$$LatencyStatsImplCopyWith<$Res> { - __$$LatencyStatsImplCopyWithImpl( - _$LatencyStatsImpl _value, $Res Function(_$LatencyStatsImpl) _then) +class __$$_LatencyStatsCopyWithImpl<$Res> + extends _$LatencyStatsCopyWithImpl<$Res, _$_LatencyStats> + implements _$$_LatencyStatsCopyWith<$Res> { + __$$_LatencyStatsCopyWithImpl( + _$_LatencyStats _value, $Res Function(_$_LatencyStats) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -105,7 +105,7 @@ class __$$LatencyStatsImplCopyWithImpl<$Res> Object? average = null, Object? slowest = null, }) { - return _then(_$LatencyStatsImpl( + return _then(_$_LatencyStats( fastest: null == fastest ? _value.fastest : fastest // ignore: cast_nullable_to_non_nullable @@ -124,12 +124,12 @@ class __$$LatencyStatsImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$LatencyStatsImpl implements _LatencyStats { - const _$LatencyStatsImpl( +class _$_LatencyStats implements _LatencyStats { + const _$_LatencyStats( {required this.fastest, required this.average, required this.slowest}); - factory _$LatencyStatsImpl.fromJson(Map json) => - _$$LatencyStatsImplFromJson(json); + factory _$_LatencyStats.fromJson(Map json) => + _$$_LatencyStatsFromJson(json); @override final TimestampDuration fastest; @@ -147,7 +147,7 @@ class _$LatencyStatsImpl implements _LatencyStats { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LatencyStatsImpl && + other is _$_LatencyStats && (identical(other.fastest, fastest) || other.fastest == fastest) && (identical(other.average, average) || other.average == average) && (identical(other.slowest, slowest) || other.slowest == slowest)); @@ -160,12 +160,12 @@ class _$LatencyStatsImpl implements _LatencyStats { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LatencyStatsImplCopyWith<_$LatencyStatsImpl> get copyWith => - __$$LatencyStatsImplCopyWithImpl<_$LatencyStatsImpl>(this, _$identity); + _$$_LatencyStatsCopyWith<_$_LatencyStats> get copyWith => + __$$_LatencyStatsCopyWithImpl<_$_LatencyStats>(this, _$identity); @override Map toJson() { - return _$$LatencyStatsImplToJson( + return _$$_LatencyStatsToJson( this, ); } @@ -175,10 +175,10 @@ abstract class _LatencyStats implements LatencyStats { const factory _LatencyStats( {required final TimestampDuration fastest, required final TimestampDuration average, - required final TimestampDuration slowest}) = _$LatencyStatsImpl; + required final TimestampDuration slowest}) = _$_LatencyStats; factory _LatencyStats.fromJson(Map json) = - _$LatencyStatsImpl.fromJson; + _$_LatencyStats.fromJson; @override TimestampDuration get fastest; @@ -188,7 +188,7 @@ abstract class _LatencyStats implements LatencyStats { TimestampDuration get slowest; @override @JsonKey(ignore: true) - _$$LatencyStatsImplCopyWith<_$LatencyStatsImpl> get copyWith => + _$$_LatencyStatsCopyWith<_$_LatencyStats> get copyWith => throw _privateConstructorUsedError; } @@ -258,22 +258,22 @@ class _$TransferStatsCopyWithImpl<$Res, $Val extends TransferStats> } /// @nodoc -abstract class _$$TransferStatsImplCopyWith<$Res> +abstract class _$$_TransferStatsCopyWith<$Res> implements $TransferStatsCopyWith<$Res> { - factory _$$TransferStatsImplCopyWith( - _$TransferStatsImpl value, $Res Function(_$TransferStatsImpl) then) = - __$$TransferStatsImplCopyWithImpl<$Res>; + factory _$$_TransferStatsCopyWith( + _$_TransferStats value, $Res Function(_$_TransferStats) then) = + __$$_TransferStatsCopyWithImpl<$Res>; @override @useResult $Res call({BigInt total, BigInt maximum, BigInt average, BigInt minimum}); } /// @nodoc -class __$$TransferStatsImplCopyWithImpl<$Res> - extends _$TransferStatsCopyWithImpl<$Res, _$TransferStatsImpl> - implements _$$TransferStatsImplCopyWith<$Res> { - __$$TransferStatsImplCopyWithImpl( - _$TransferStatsImpl _value, $Res Function(_$TransferStatsImpl) _then) +class __$$_TransferStatsCopyWithImpl<$Res> + extends _$TransferStatsCopyWithImpl<$Res, _$_TransferStats> + implements _$$_TransferStatsCopyWith<$Res> { + __$$_TransferStatsCopyWithImpl( + _$_TransferStats _value, $Res Function(_$_TransferStats) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -284,7 +284,7 @@ class __$$TransferStatsImplCopyWithImpl<$Res> Object? average = null, Object? minimum = null, }) { - return _then(_$TransferStatsImpl( + return _then(_$_TransferStats( total: null == total ? _value.total : total // ignore: cast_nullable_to_non_nullable @@ -307,15 +307,15 @@ class __$$TransferStatsImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$TransferStatsImpl implements _TransferStats { - const _$TransferStatsImpl( +class _$_TransferStats implements _TransferStats { + const _$_TransferStats( {required this.total, required this.maximum, required this.average, required this.minimum}); - factory _$TransferStatsImpl.fromJson(Map json) => - _$$TransferStatsImplFromJson(json); + factory _$_TransferStats.fromJson(Map json) => + _$$_TransferStatsFromJson(json); @override final BigInt total; @@ -335,7 +335,7 @@ class _$TransferStatsImpl implements _TransferStats { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$TransferStatsImpl && + other is _$_TransferStats && (identical(other.total, total) || other.total == total) && (identical(other.maximum, maximum) || other.maximum == maximum) && (identical(other.average, average) || other.average == average) && @@ -350,12 +350,12 @@ class _$TransferStatsImpl implements _TransferStats { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$TransferStatsImplCopyWith<_$TransferStatsImpl> get copyWith => - __$$TransferStatsImplCopyWithImpl<_$TransferStatsImpl>(this, _$identity); + _$$_TransferStatsCopyWith<_$_TransferStats> get copyWith => + __$$_TransferStatsCopyWithImpl<_$_TransferStats>(this, _$identity); @override Map toJson() { - return _$$TransferStatsImplToJson( + return _$$_TransferStatsToJson( this, ); } @@ -366,10 +366,10 @@ abstract class _TransferStats implements TransferStats { {required final BigInt total, required final BigInt maximum, required final BigInt average, - required final BigInt minimum}) = _$TransferStatsImpl; + required final BigInt minimum}) = _$_TransferStats; factory _TransferStats.fromJson(Map json) = - _$TransferStatsImpl.fromJson; + _$_TransferStats.fromJson; @override BigInt get total; @@ -381,7 +381,7 @@ abstract class _TransferStats implements TransferStats { BigInt get minimum; @override @JsonKey(ignore: true) - _$$TransferStatsImplCopyWith<_$TransferStatsImpl> get copyWith => + _$$_TransferStatsCopyWith<_$_TransferStats> get copyWith => throw _privateConstructorUsedError; } @@ -458,11 +458,11 @@ class _$TransferStatsDownUpCopyWithImpl<$Res, $Val extends TransferStatsDownUp> } /// @nodoc -abstract class _$$TransferStatsDownUpImplCopyWith<$Res> +abstract class _$$_TransferStatsDownUpCopyWith<$Res> implements $TransferStatsDownUpCopyWith<$Res> { - factory _$$TransferStatsDownUpImplCopyWith(_$TransferStatsDownUpImpl value, - $Res Function(_$TransferStatsDownUpImpl) then) = - __$$TransferStatsDownUpImplCopyWithImpl<$Res>; + factory _$$_TransferStatsDownUpCopyWith(_$_TransferStatsDownUp value, + $Res Function(_$_TransferStatsDownUp) then) = + __$$_TransferStatsDownUpCopyWithImpl<$Res>; @override @useResult $Res call({TransferStats down, TransferStats up}); @@ -474,11 +474,11 @@ abstract class _$$TransferStatsDownUpImplCopyWith<$Res> } /// @nodoc -class __$$TransferStatsDownUpImplCopyWithImpl<$Res> - extends _$TransferStatsDownUpCopyWithImpl<$Res, _$TransferStatsDownUpImpl> - implements _$$TransferStatsDownUpImplCopyWith<$Res> { - __$$TransferStatsDownUpImplCopyWithImpl(_$TransferStatsDownUpImpl _value, - $Res Function(_$TransferStatsDownUpImpl) _then) +class __$$_TransferStatsDownUpCopyWithImpl<$Res> + extends _$TransferStatsDownUpCopyWithImpl<$Res, _$_TransferStatsDownUp> + implements _$$_TransferStatsDownUpCopyWith<$Res> { + __$$_TransferStatsDownUpCopyWithImpl(_$_TransferStatsDownUp _value, + $Res Function(_$_TransferStatsDownUp) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -487,7 +487,7 @@ class __$$TransferStatsDownUpImplCopyWithImpl<$Res> Object? down = null, Object? up = null, }) { - return _then(_$TransferStatsDownUpImpl( + return _then(_$_TransferStatsDownUp( down: null == down ? _value.down : down // ignore: cast_nullable_to_non_nullable @@ -502,11 +502,11 @@ class __$$TransferStatsDownUpImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$TransferStatsDownUpImpl implements _TransferStatsDownUp { - const _$TransferStatsDownUpImpl({required this.down, required this.up}); +class _$_TransferStatsDownUp implements _TransferStatsDownUp { + const _$_TransferStatsDownUp({required this.down, required this.up}); - factory _$TransferStatsDownUpImpl.fromJson(Map json) => - _$$TransferStatsDownUpImplFromJson(json); + factory _$_TransferStatsDownUp.fromJson(Map json) => + _$$_TransferStatsDownUpFromJson(json); @override final TransferStats down; @@ -522,7 +522,7 @@ class _$TransferStatsDownUpImpl implements _TransferStatsDownUp { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$TransferStatsDownUpImpl && + other is _$_TransferStatsDownUp && (identical(other.down, down) || other.down == down) && (identical(other.up, up) || other.up == up)); } @@ -534,13 +534,13 @@ class _$TransferStatsDownUpImpl implements _TransferStatsDownUp { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$TransferStatsDownUpImplCopyWith<_$TransferStatsDownUpImpl> get copyWith => - __$$TransferStatsDownUpImplCopyWithImpl<_$TransferStatsDownUpImpl>( + _$$_TransferStatsDownUpCopyWith<_$_TransferStatsDownUp> get copyWith => + __$$_TransferStatsDownUpCopyWithImpl<_$_TransferStatsDownUp>( this, _$identity); @override Map toJson() { - return _$$TransferStatsDownUpImplToJson( + return _$$_TransferStatsDownUpToJson( this, ); } @@ -549,10 +549,10 @@ class _$TransferStatsDownUpImpl implements _TransferStatsDownUp { abstract class _TransferStatsDownUp implements TransferStatsDownUp { const factory _TransferStatsDownUp( {required final TransferStats down, - required final TransferStats up}) = _$TransferStatsDownUpImpl; + required final TransferStats up}) = _$_TransferStatsDownUp; factory _TransferStatsDownUp.fromJson(Map json) = - _$TransferStatsDownUpImpl.fromJson; + _$_TransferStatsDownUp.fromJson; @override TransferStats get down; @@ -560,7 +560,7 @@ abstract class _TransferStatsDownUp implements TransferStatsDownUp { TransferStats get up; @override @JsonKey(ignore: true) - _$$TransferStatsDownUpImplCopyWith<_$TransferStatsDownUpImpl> get copyWith => + _$$_TransferStatsDownUpCopyWith<_$_TransferStatsDownUp> get copyWith => throw _privateConstructorUsedError; } @@ -661,11 +661,10 @@ class _$RPCStatsCopyWithImpl<$Res, $Val extends RPCStats> } /// @nodoc -abstract class _$$RPCStatsImplCopyWith<$Res> - implements $RPCStatsCopyWith<$Res> { - factory _$$RPCStatsImplCopyWith( - _$RPCStatsImpl value, $Res Function(_$RPCStatsImpl) then) = - __$$RPCStatsImplCopyWithImpl<$Res>; +abstract class _$$_RPCStatsCopyWith<$Res> implements $RPCStatsCopyWith<$Res> { + factory _$$_RPCStatsCopyWith( + _$_RPCStats value, $Res Function(_$_RPCStats) then) = + __$$_RPCStatsCopyWithImpl<$Res>; @override @useResult $Res call( @@ -680,11 +679,11 @@ abstract class _$$RPCStatsImplCopyWith<$Res> } /// @nodoc -class __$$RPCStatsImplCopyWithImpl<$Res> - extends _$RPCStatsCopyWithImpl<$Res, _$RPCStatsImpl> - implements _$$RPCStatsImplCopyWith<$Res> { - __$$RPCStatsImplCopyWithImpl( - _$RPCStatsImpl _value, $Res Function(_$RPCStatsImpl) _then) +class __$$_RPCStatsCopyWithImpl<$Res> + extends _$RPCStatsCopyWithImpl<$Res, _$_RPCStats> + implements _$$_RPCStatsCopyWith<$Res> { + __$$_RPCStatsCopyWithImpl( + _$_RPCStats _value, $Res Function(_$_RPCStats) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -699,7 +698,7 @@ class __$$RPCStatsImplCopyWithImpl<$Res> Object? recentLostAnswers = null, Object? failedToSend = null, }) { - return _then(_$RPCStatsImpl( + return _then(_$_RPCStats( messagesSent: null == messagesSent ? _value.messagesSent : messagesSent // ignore: cast_nullable_to_non_nullable @@ -738,8 +737,8 @@ class __$$RPCStatsImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$RPCStatsImpl implements _RPCStats { - const _$RPCStatsImpl( +class _$_RPCStats implements _RPCStats { + const _$_RPCStats( {required this.messagesSent, required this.messagesRcvd, required this.questionsInFlight, @@ -749,8 +748,8 @@ class _$RPCStatsImpl implements _RPCStats { required this.recentLostAnswers, required this.failedToSend}); - factory _$RPCStatsImpl.fromJson(Map json) => - _$$RPCStatsImplFromJson(json); + factory _$_RPCStats.fromJson(Map json) => + _$$_RPCStatsFromJson(json); @override final int messagesSent; @@ -778,7 +777,7 @@ class _$RPCStatsImpl implements _RPCStats { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$RPCStatsImpl && + other is _$_RPCStats && (identical(other.messagesSent, messagesSent) || other.messagesSent == messagesSent) && (identical(other.messagesRcvd, messagesRcvd) || @@ -813,12 +812,12 @@ class _$RPCStatsImpl implements _RPCStats { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$RPCStatsImplCopyWith<_$RPCStatsImpl> get copyWith => - __$$RPCStatsImplCopyWithImpl<_$RPCStatsImpl>(this, _$identity); + _$$_RPCStatsCopyWith<_$_RPCStats> get copyWith => + __$$_RPCStatsCopyWithImpl<_$_RPCStats>(this, _$identity); @override Map toJson() { - return _$$RPCStatsImplToJson( + return _$$_RPCStatsToJson( this, ); } @@ -833,10 +832,9 @@ abstract class _RPCStats implements RPCStats { required final Timestamp? lastSeenTs, required final Timestamp? firstConsecutiveSeenTs, required final int recentLostAnswers, - required final int failedToSend}) = _$RPCStatsImpl; + required final int failedToSend}) = _$_RPCStats; - factory _RPCStats.fromJson(Map json) = - _$RPCStatsImpl.fromJson; + factory _RPCStats.fromJson(Map json) = _$_RPCStats.fromJson; @override int get messagesSent; @@ -856,7 +854,7 @@ abstract class _RPCStats implements RPCStats { int get failedToSend; @override @JsonKey(ignore: true) - _$$RPCStatsImplCopyWith<_$RPCStatsImpl> get copyWith => + _$$_RPCStatsCopyWith<_$_RPCStats> get copyWith => throw _privateConstructorUsedError; } @@ -961,11 +959,10 @@ class _$PeerStatsCopyWithImpl<$Res, $Val extends PeerStats> } /// @nodoc -abstract class _$$PeerStatsImplCopyWith<$Res> - implements $PeerStatsCopyWith<$Res> { - factory _$$PeerStatsImplCopyWith( - _$PeerStatsImpl value, $Res Function(_$PeerStatsImpl) then) = - __$$PeerStatsImplCopyWithImpl<$Res>; +abstract class _$$_PeerStatsCopyWith<$Res> implements $PeerStatsCopyWith<$Res> { + factory _$$_PeerStatsCopyWith( + _$_PeerStats value, $Res Function(_$_PeerStats) then) = + __$$_PeerStatsCopyWithImpl<$Res>; @override @useResult $Res call( @@ -983,11 +980,11 @@ abstract class _$$PeerStatsImplCopyWith<$Res> } /// @nodoc -class __$$PeerStatsImplCopyWithImpl<$Res> - extends _$PeerStatsCopyWithImpl<$Res, _$PeerStatsImpl> - implements _$$PeerStatsImplCopyWith<$Res> { - __$$PeerStatsImplCopyWithImpl( - _$PeerStatsImpl _value, $Res Function(_$PeerStatsImpl) _then) +class __$$_PeerStatsCopyWithImpl<$Res> + extends _$PeerStatsCopyWithImpl<$Res, _$_PeerStats> + implements _$$_PeerStatsCopyWith<$Res> { + __$$_PeerStatsCopyWithImpl( + _$_PeerStats _value, $Res Function(_$_PeerStats) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -998,7 +995,7 @@ class __$$PeerStatsImplCopyWithImpl<$Res> Object? transfer = null, Object? latency = freezed, }) { - return _then(_$PeerStatsImpl( + return _then(_$_PeerStats( timeAdded: null == timeAdded ? _value.timeAdded : timeAdded // ignore: cast_nullable_to_non_nullable @@ -1021,15 +1018,15 @@ class __$$PeerStatsImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$PeerStatsImpl implements _PeerStats { - const _$PeerStatsImpl( +class _$_PeerStats implements _PeerStats { + const _$_PeerStats( {required this.timeAdded, required this.rpcStats, required this.transfer, this.latency}); - factory _$PeerStatsImpl.fromJson(Map json) => - _$$PeerStatsImplFromJson(json); + factory _$_PeerStats.fromJson(Map json) => + _$$_PeerStatsFromJson(json); @override final Timestamp timeAdded; @@ -1049,7 +1046,7 @@ class _$PeerStatsImpl implements _PeerStats { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PeerStatsImpl && + other is _$_PeerStats && (identical(other.timeAdded, timeAdded) || other.timeAdded == timeAdded) && (identical(other.rpcStats, rpcStats) || @@ -1067,12 +1064,12 @@ class _$PeerStatsImpl implements _PeerStats { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$PeerStatsImplCopyWith<_$PeerStatsImpl> get copyWith => - __$$PeerStatsImplCopyWithImpl<_$PeerStatsImpl>(this, _$identity); + _$$_PeerStatsCopyWith<_$_PeerStats> get copyWith => + __$$_PeerStatsCopyWithImpl<_$_PeerStats>(this, _$identity); @override Map toJson() { - return _$$PeerStatsImplToJson( + return _$$_PeerStatsToJson( this, ); } @@ -1083,10 +1080,10 @@ abstract class _PeerStats implements PeerStats { {required final Timestamp timeAdded, required final RPCStats rpcStats, required final TransferStatsDownUp transfer, - final LatencyStats? latency}) = _$PeerStatsImpl; + final LatencyStats? latency}) = _$_PeerStats; factory _PeerStats.fromJson(Map json) = - _$PeerStatsImpl.fromJson; + _$_PeerStats.fromJson; @override Timestamp get timeAdded; @@ -1098,7 +1095,7 @@ abstract class _PeerStats implements PeerStats { LatencyStats? get latency; @override @JsonKey(ignore: true) - _$$PeerStatsImplCopyWith<_$PeerStatsImpl> get copyWith => + _$$_PeerStatsCopyWith<_$_PeerStats> get copyWith => throw _privateConstructorUsedError; } @@ -1176,11 +1173,11 @@ class _$PeerTableDataCopyWithImpl<$Res, $Val extends PeerTableData> } /// @nodoc -abstract class _$$PeerTableDataImplCopyWith<$Res> +abstract class _$$_PeerTableDataCopyWith<$Res> implements $PeerTableDataCopyWith<$Res> { - factory _$$PeerTableDataImplCopyWith( - _$PeerTableDataImpl value, $Res Function(_$PeerTableDataImpl) then) = - __$$PeerTableDataImplCopyWithImpl<$Res>; + factory _$$_PeerTableDataCopyWith( + _$_PeerTableData value, $Res Function(_$_PeerTableData) then) = + __$$_PeerTableDataCopyWithImpl<$Res>; @override @useResult $Res call( @@ -1193,11 +1190,11 @@ abstract class _$$PeerTableDataImplCopyWith<$Res> } /// @nodoc -class __$$PeerTableDataImplCopyWithImpl<$Res> - extends _$PeerTableDataCopyWithImpl<$Res, _$PeerTableDataImpl> - implements _$$PeerTableDataImplCopyWith<$Res> { - __$$PeerTableDataImplCopyWithImpl( - _$PeerTableDataImpl _value, $Res Function(_$PeerTableDataImpl) _then) +class __$$_PeerTableDataCopyWithImpl<$Res> + extends _$PeerTableDataCopyWithImpl<$Res, _$_PeerTableData> + implements _$$_PeerTableDataCopyWith<$Res> { + __$$_PeerTableDataCopyWithImpl( + _$_PeerTableData _value, $Res Function(_$_PeerTableData) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1207,7 +1204,7 @@ class __$$PeerTableDataImplCopyWithImpl<$Res> Object? peerAddress = null, Object? peerStats = null, }) { - return _then(_$PeerTableDataImpl( + return _then(_$_PeerTableData( nodeIds: null == nodeIds ? _value._nodeIds : nodeIds // ignore: cast_nullable_to_non_nullable @@ -1226,15 +1223,15 @@ class __$$PeerTableDataImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$PeerTableDataImpl implements _PeerTableData { - const _$PeerTableDataImpl( +class _$_PeerTableData implements _PeerTableData { + const _$_PeerTableData( {required final List> nodeIds, required this.peerAddress, required this.peerStats}) : _nodeIds = nodeIds; - factory _$PeerTableDataImpl.fromJson(Map json) => - _$$PeerTableDataImplFromJson(json); + factory _$_PeerTableData.fromJson(Map json) => + _$$_PeerTableDataFromJson(json); final List> _nodeIds; @override @@ -1258,7 +1255,7 @@ class _$PeerTableDataImpl implements _PeerTableData { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PeerTableDataImpl && + other is _$_PeerTableData && const DeepCollectionEquality().equals(other._nodeIds, _nodeIds) && (identical(other.peerAddress, peerAddress) || other.peerAddress == peerAddress) && @@ -1274,12 +1271,12 @@ class _$PeerTableDataImpl implements _PeerTableData { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$PeerTableDataImplCopyWith<_$PeerTableDataImpl> get copyWith => - __$$PeerTableDataImplCopyWithImpl<_$PeerTableDataImpl>(this, _$identity); + _$$_PeerTableDataCopyWith<_$_PeerTableData> get copyWith => + __$$_PeerTableDataCopyWithImpl<_$_PeerTableData>(this, _$identity); @override Map toJson() { - return _$$PeerTableDataImplToJson( + return _$$_PeerTableDataToJson( this, ); } @@ -1289,10 +1286,10 @@ abstract class _PeerTableData implements PeerTableData { const factory _PeerTableData( {required final List> nodeIds, required final String peerAddress, - required final PeerStats peerStats}) = _$PeerTableDataImpl; + required final PeerStats peerStats}) = _$_PeerTableData; factory _PeerTableData.fromJson(Map json) = - _$PeerTableDataImpl.fromJson; + _$_PeerTableData.fromJson; @override List> get nodeIds; @@ -1302,7 +1299,7 @@ abstract class _PeerTableData implements PeerTableData { PeerStats get peerStats; @override @JsonKey(ignore: true) - _$$PeerTableDataImplCopyWith<_$PeerTableDataImpl> get copyWith => + _$$_PeerTableDataCopyWith<_$_PeerTableData> get copyWith => throw _privateConstructorUsedError; } @@ -1469,20 +1466,20 @@ class _$VeilidUpdateCopyWithImpl<$Res, $Val extends VeilidUpdate> } /// @nodoc -abstract class _$$VeilidLogImplCopyWith<$Res> { - factory _$$VeilidLogImplCopyWith( - _$VeilidLogImpl value, $Res Function(_$VeilidLogImpl) then) = - __$$VeilidLogImplCopyWithImpl<$Res>; +abstract class _$$VeilidLogCopyWith<$Res> { + factory _$$VeilidLogCopyWith( + _$VeilidLog value, $Res Function(_$VeilidLog) then) = + __$$VeilidLogCopyWithImpl<$Res>; @useResult $Res call({VeilidLogLevel logLevel, String message, String? backtrace}); } /// @nodoc -class __$$VeilidLogImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidLogImpl> - implements _$$VeilidLogImplCopyWith<$Res> { - __$$VeilidLogImplCopyWithImpl( - _$VeilidLogImpl _value, $Res Function(_$VeilidLogImpl) _then) +class __$$VeilidLogCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidLog> + implements _$$VeilidLogCopyWith<$Res> { + __$$VeilidLogCopyWithImpl( + _$VeilidLog _value, $Res Function(_$VeilidLog) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1492,7 +1489,7 @@ class __$$VeilidLogImplCopyWithImpl<$Res> Object? message = null, Object? backtrace = freezed, }) { - return _then(_$VeilidLogImpl( + return _then(_$VeilidLog( logLevel: null == logLevel ? _value.logLevel : logLevel // ignore: cast_nullable_to_non_nullable @@ -1511,16 +1508,16 @@ class __$$VeilidLogImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidLogImpl implements VeilidLog { - const _$VeilidLogImpl( +class _$VeilidLog implements VeilidLog { + const _$VeilidLog( {required this.logLevel, required this.message, this.backtrace, final String? $type}) : $type = $type ?? 'Log'; - factory _$VeilidLogImpl.fromJson(Map json) => - _$$VeilidLogImplFromJson(json); + factory _$VeilidLog.fromJson(Map json) => + _$$VeilidLogFromJson(json); @override final VeilidLogLevel logLevel; @@ -1541,7 +1538,7 @@ class _$VeilidLogImpl implements VeilidLog { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidLogImpl && + other is _$VeilidLog && (identical(other.logLevel, logLevel) || other.logLevel == logLevel) && (identical(other.message, message) || other.message == message) && @@ -1556,8 +1553,8 @@ class _$VeilidLogImpl implements VeilidLog { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidLogImplCopyWith<_$VeilidLogImpl> get copyWith => - __$$VeilidLogImplCopyWithImpl<_$VeilidLogImpl>(this, _$identity); + _$$VeilidLogCopyWith<_$VeilidLog> get copyWith => + __$$VeilidLogCopyWithImpl<_$VeilidLog>(this, _$identity); @override @optionalTypeArgs @@ -1699,7 +1696,7 @@ class _$VeilidLogImpl implements VeilidLog { @override Map toJson() { - return _$$VeilidLogImplToJson( + return _$$VeilidLogToJson( this, ); } @@ -1709,24 +1706,23 @@ abstract class VeilidLog implements VeilidUpdate { const factory VeilidLog( {required final VeilidLogLevel logLevel, required final String message, - final String? backtrace}) = _$VeilidLogImpl; + final String? backtrace}) = _$VeilidLog; - factory VeilidLog.fromJson(Map json) = - _$VeilidLogImpl.fromJson; + factory VeilidLog.fromJson(Map json) = _$VeilidLog.fromJson; VeilidLogLevel get logLevel; String get message; String? get backtrace; @JsonKey(ignore: true) - _$$VeilidLogImplCopyWith<_$VeilidLogImpl> get copyWith => + _$$VeilidLogCopyWith<_$VeilidLog> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidAppMessageImplCopyWith<$Res> { - factory _$$VeilidAppMessageImplCopyWith(_$VeilidAppMessageImpl value, - $Res Function(_$VeilidAppMessageImpl) then) = - __$$VeilidAppMessageImplCopyWithImpl<$Res>; +abstract class _$$VeilidAppMessageCopyWith<$Res> { + factory _$$VeilidAppMessageCopyWith( + _$VeilidAppMessage value, $Res Function(_$VeilidAppMessage) then) = + __$$VeilidAppMessageCopyWithImpl<$Res>; @useResult $Res call( {@Uint8ListJsonConverter() Uint8List message, @@ -1734,11 +1730,11 @@ abstract class _$$VeilidAppMessageImplCopyWith<$Res> { } /// @nodoc -class __$$VeilidAppMessageImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidAppMessageImpl> - implements _$$VeilidAppMessageImplCopyWith<$Res> { - __$$VeilidAppMessageImplCopyWithImpl(_$VeilidAppMessageImpl _value, - $Res Function(_$VeilidAppMessageImpl) _then) +class __$$VeilidAppMessageCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidAppMessage> + implements _$$VeilidAppMessageCopyWith<$Res> { + __$$VeilidAppMessageCopyWithImpl( + _$VeilidAppMessage _value, $Res Function(_$VeilidAppMessage) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1747,7 +1743,7 @@ class __$$VeilidAppMessageImplCopyWithImpl<$Res> Object? message = null, Object? sender = freezed, }) { - return _then(_$VeilidAppMessageImpl( + return _then(_$VeilidAppMessage( message: null == message ? _value.message : message // ignore: cast_nullable_to_non_nullable @@ -1762,15 +1758,15 @@ class __$$VeilidAppMessageImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidAppMessageImpl implements VeilidAppMessage { - const _$VeilidAppMessageImpl( +class _$VeilidAppMessage implements VeilidAppMessage { + const _$VeilidAppMessage( {@Uint8ListJsonConverter() required this.message, this.sender, final String? $type}) : $type = $type ?? 'AppMessage'; - factory _$VeilidAppMessageImpl.fromJson(Map json) => - _$$VeilidAppMessageImplFromJson(json); + factory _$VeilidAppMessage.fromJson(Map json) => + _$$VeilidAppMessageFromJson(json); @override @Uint8ListJsonConverter() @@ -1790,7 +1786,7 @@ class _$VeilidAppMessageImpl implements VeilidAppMessage { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidAppMessageImpl && + other is _$VeilidAppMessage && const DeepCollectionEquality().equals(other.message, message) && (identical(other.sender, sender) || other.sender == sender)); } @@ -1803,9 +1799,8 @@ class _$VeilidAppMessageImpl implements VeilidAppMessage { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidAppMessageImplCopyWith<_$VeilidAppMessageImpl> get copyWith => - __$$VeilidAppMessageImplCopyWithImpl<_$VeilidAppMessageImpl>( - this, _$identity); + _$$VeilidAppMessageCopyWith<_$VeilidAppMessage> get copyWith => + __$$VeilidAppMessageCopyWithImpl<_$VeilidAppMessage>(this, _$identity); @override @optionalTypeArgs @@ -1947,7 +1942,7 @@ class _$VeilidAppMessageImpl implements VeilidAppMessage { @override Map toJson() { - return _$$VeilidAppMessageImplToJson( + return _$$VeilidAppMessageToJson( this, ); } @@ -1956,24 +1951,24 @@ class _$VeilidAppMessageImpl implements VeilidAppMessage { abstract class VeilidAppMessage implements VeilidUpdate { const factory VeilidAppMessage( {@Uint8ListJsonConverter() required final Uint8List message, - final Typed? sender}) = _$VeilidAppMessageImpl; + final Typed? sender}) = _$VeilidAppMessage; factory VeilidAppMessage.fromJson(Map json) = - _$VeilidAppMessageImpl.fromJson; + _$VeilidAppMessage.fromJson; @Uint8ListJsonConverter() Uint8List get message; Typed? get sender; @JsonKey(ignore: true) - _$$VeilidAppMessageImplCopyWith<_$VeilidAppMessageImpl> get copyWith => + _$$VeilidAppMessageCopyWith<_$VeilidAppMessage> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidAppCallImplCopyWith<$Res> { - factory _$$VeilidAppCallImplCopyWith( - _$VeilidAppCallImpl value, $Res Function(_$VeilidAppCallImpl) then) = - __$$VeilidAppCallImplCopyWithImpl<$Res>; +abstract class _$$VeilidAppCallCopyWith<$Res> { + factory _$$VeilidAppCallCopyWith( + _$VeilidAppCall value, $Res Function(_$VeilidAppCall) then) = + __$$VeilidAppCallCopyWithImpl<$Res>; @useResult $Res call( {@Uint8ListJsonConverter() Uint8List message, @@ -1982,11 +1977,11 @@ abstract class _$$VeilidAppCallImplCopyWith<$Res> { } /// @nodoc -class __$$VeilidAppCallImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidAppCallImpl> - implements _$$VeilidAppCallImplCopyWith<$Res> { - __$$VeilidAppCallImplCopyWithImpl( - _$VeilidAppCallImpl _value, $Res Function(_$VeilidAppCallImpl) _then) +class __$$VeilidAppCallCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidAppCall> + implements _$$VeilidAppCallCopyWith<$Res> { + __$$VeilidAppCallCopyWithImpl( + _$VeilidAppCall _value, $Res Function(_$VeilidAppCall) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1996,7 +1991,7 @@ class __$$VeilidAppCallImplCopyWithImpl<$Res> Object? callId = null, Object? sender = freezed, }) { - return _then(_$VeilidAppCallImpl( + return _then(_$VeilidAppCall( message: null == message ? _value.message : message // ignore: cast_nullable_to_non_nullable @@ -2015,16 +2010,16 @@ class __$$VeilidAppCallImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidAppCallImpl implements VeilidAppCall { - const _$VeilidAppCallImpl( +class _$VeilidAppCall implements VeilidAppCall { + const _$VeilidAppCall( {@Uint8ListJsonConverter() required this.message, required this.callId, this.sender, final String? $type}) : $type = $type ?? 'AppCall'; - factory _$VeilidAppCallImpl.fromJson(Map json) => - _$$VeilidAppCallImplFromJson(json); + factory _$VeilidAppCall.fromJson(Map json) => + _$$VeilidAppCallFromJson(json); @override @Uint8ListJsonConverter() @@ -2046,7 +2041,7 @@ class _$VeilidAppCallImpl implements VeilidAppCall { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidAppCallImpl && + other is _$VeilidAppCall && const DeepCollectionEquality().equals(other.message, message) && (identical(other.callId, callId) || other.callId == callId) && (identical(other.sender, sender) || other.sender == sender)); @@ -2060,8 +2055,8 @@ class _$VeilidAppCallImpl implements VeilidAppCall { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidAppCallImplCopyWith<_$VeilidAppCallImpl> get copyWith => - __$$VeilidAppCallImplCopyWithImpl<_$VeilidAppCallImpl>(this, _$identity); + _$$VeilidAppCallCopyWith<_$VeilidAppCall> get copyWith => + __$$VeilidAppCallCopyWithImpl<_$VeilidAppCall>(this, _$identity); @override @optionalTypeArgs @@ -2203,7 +2198,7 @@ class _$VeilidAppCallImpl implements VeilidAppCall { @override Map toJson() { - return _$$VeilidAppCallImplToJson( + return _$$VeilidAppCallToJson( this, ); } @@ -2213,26 +2208,25 @@ abstract class VeilidAppCall implements VeilidUpdate { const factory VeilidAppCall( {@Uint8ListJsonConverter() required final Uint8List message, required final String callId, - final Typed? sender}) = _$VeilidAppCallImpl; + final Typed? sender}) = _$VeilidAppCall; factory VeilidAppCall.fromJson(Map json) = - _$VeilidAppCallImpl.fromJson; + _$VeilidAppCall.fromJson; @Uint8ListJsonConverter() Uint8List get message; String get callId; Typed? get sender; @JsonKey(ignore: true) - _$$VeilidAppCallImplCopyWith<_$VeilidAppCallImpl> get copyWith => + _$$VeilidAppCallCopyWith<_$VeilidAppCall> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidUpdateAttachmentImplCopyWith<$Res> { - factory _$$VeilidUpdateAttachmentImplCopyWith( - _$VeilidUpdateAttachmentImpl value, - $Res Function(_$VeilidUpdateAttachmentImpl) then) = - __$$VeilidUpdateAttachmentImplCopyWithImpl<$Res>; +abstract class _$$VeilidUpdateAttachmentCopyWith<$Res> { + factory _$$VeilidUpdateAttachmentCopyWith(_$VeilidUpdateAttachment value, + $Res Function(_$VeilidUpdateAttachment) then) = + __$$VeilidUpdateAttachmentCopyWithImpl<$Res>; @useResult $Res call( {AttachmentState state, @@ -2241,12 +2235,11 @@ abstract class _$$VeilidUpdateAttachmentImplCopyWith<$Res> { } /// @nodoc -class __$$VeilidUpdateAttachmentImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateAttachmentImpl> - implements _$$VeilidUpdateAttachmentImplCopyWith<$Res> { - __$$VeilidUpdateAttachmentImplCopyWithImpl( - _$VeilidUpdateAttachmentImpl _value, - $Res Function(_$VeilidUpdateAttachmentImpl) _then) +class __$$VeilidUpdateAttachmentCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateAttachment> + implements _$$VeilidUpdateAttachmentCopyWith<$Res> { + __$$VeilidUpdateAttachmentCopyWithImpl(_$VeilidUpdateAttachment _value, + $Res Function(_$VeilidUpdateAttachment) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2256,7 +2249,7 @@ class __$$VeilidUpdateAttachmentImplCopyWithImpl<$Res> Object? publicInternetReady = null, Object? localNetworkReady = null, }) { - return _then(_$VeilidUpdateAttachmentImpl( + return _then(_$VeilidUpdateAttachment( state: null == state ? _value.state : state // ignore: cast_nullable_to_non_nullable @@ -2275,16 +2268,16 @@ class __$$VeilidUpdateAttachmentImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidUpdateAttachmentImpl implements VeilidUpdateAttachment { - const _$VeilidUpdateAttachmentImpl( +class _$VeilidUpdateAttachment implements VeilidUpdateAttachment { + const _$VeilidUpdateAttachment( {required this.state, required this.publicInternetReady, required this.localNetworkReady, final String? $type}) : $type = $type ?? 'Attachment'; - factory _$VeilidUpdateAttachmentImpl.fromJson(Map json) => - _$$VeilidUpdateAttachmentImplFromJson(json); + factory _$VeilidUpdateAttachment.fromJson(Map json) => + _$$VeilidUpdateAttachmentFromJson(json); @override final AttachmentState state; @@ -2305,7 +2298,7 @@ class _$VeilidUpdateAttachmentImpl implements VeilidUpdateAttachment { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidUpdateAttachmentImpl && + other is _$VeilidUpdateAttachment && (identical(other.state, state) || other.state == state) && (identical(other.publicInternetReady, publicInternetReady) || other.publicInternetReady == publicInternetReady) && @@ -2321,9 +2314,9 @@ class _$VeilidUpdateAttachmentImpl implements VeilidUpdateAttachment { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidUpdateAttachmentImplCopyWith<_$VeilidUpdateAttachmentImpl> - get copyWith => __$$VeilidUpdateAttachmentImplCopyWithImpl< - _$VeilidUpdateAttachmentImpl>(this, _$identity); + _$$VeilidUpdateAttachmentCopyWith<_$VeilidUpdateAttachment> get copyWith => + __$$VeilidUpdateAttachmentCopyWithImpl<_$VeilidUpdateAttachment>( + this, _$identity); @override @optionalTypeArgs @@ -2465,7 +2458,7 @@ class _$VeilidUpdateAttachmentImpl implements VeilidUpdateAttachment { @override Map toJson() { - return _$$VeilidUpdateAttachmentImplToJson( + return _$$VeilidUpdateAttachmentToJson( this, ); } @@ -2475,35 +2468,35 @@ abstract class VeilidUpdateAttachment implements VeilidUpdate { const factory VeilidUpdateAttachment( {required final AttachmentState state, required final bool publicInternetReady, - required final bool localNetworkReady}) = _$VeilidUpdateAttachmentImpl; + required final bool localNetworkReady}) = _$VeilidUpdateAttachment; factory VeilidUpdateAttachment.fromJson(Map json) = - _$VeilidUpdateAttachmentImpl.fromJson; + _$VeilidUpdateAttachment.fromJson; AttachmentState get state; bool get publicInternetReady; bool get localNetworkReady; @JsonKey(ignore: true) - _$$VeilidUpdateAttachmentImplCopyWith<_$VeilidUpdateAttachmentImpl> - get copyWith => throw _privateConstructorUsedError; + _$$VeilidUpdateAttachmentCopyWith<_$VeilidUpdateAttachment> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidUpdateNetworkImplCopyWith<$Res> { - factory _$$VeilidUpdateNetworkImplCopyWith(_$VeilidUpdateNetworkImpl value, - $Res Function(_$VeilidUpdateNetworkImpl) then) = - __$$VeilidUpdateNetworkImplCopyWithImpl<$Res>; +abstract class _$$VeilidUpdateNetworkCopyWith<$Res> { + factory _$$VeilidUpdateNetworkCopyWith(_$VeilidUpdateNetwork value, + $Res Function(_$VeilidUpdateNetwork) then) = + __$$VeilidUpdateNetworkCopyWithImpl<$Res>; @useResult $Res call( {bool started, BigInt bpsDown, BigInt bpsUp, List peers}); } /// @nodoc -class __$$VeilidUpdateNetworkImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateNetworkImpl> - implements _$$VeilidUpdateNetworkImplCopyWith<$Res> { - __$$VeilidUpdateNetworkImplCopyWithImpl(_$VeilidUpdateNetworkImpl _value, - $Res Function(_$VeilidUpdateNetworkImpl) _then) +class __$$VeilidUpdateNetworkCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateNetwork> + implements _$$VeilidUpdateNetworkCopyWith<$Res> { + __$$VeilidUpdateNetworkCopyWithImpl( + _$VeilidUpdateNetwork _value, $Res Function(_$VeilidUpdateNetwork) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2514,7 +2507,7 @@ class __$$VeilidUpdateNetworkImplCopyWithImpl<$Res> Object? bpsUp = null, Object? peers = null, }) { - return _then(_$VeilidUpdateNetworkImpl( + return _then(_$VeilidUpdateNetwork( started: null == started ? _value.started : started // ignore: cast_nullable_to_non_nullable @@ -2537,8 +2530,8 @@ class __$$VeilidUpdateNetworkImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidUpdateNetworkImpl implements VeilidUpdateNetwork { - const _$VeilidUpdateNetworkImpl( +class _$VeilidUpdateNetwork implements VeilidUpdateNetwork { + const _$VeilidUpdateNetwork( {required this.started, required this.bpsDown, required this.bpsUp, @@ -2547,8 +2540,8 @@ class _$VeilidUpdateNetworkImpl implements VeilidUpdateNetwork { : _peers = peers, $type = $type ?? 'Network'; - factory _$VeilidUpdateNetworkImpl.fromJson(Map json) => - _$$VeilidUpdateNetworkImplFromJson(json); + factory _$VeilidUpdateNetwork.fromJson(Map json) => + _$$VeilidUpdateNetworkFromJson(json); @override final bool started; @@ -2576,7 +2569,7 @@ class _$VeilidUpdateNetworkImpl implements VeilidUpdateNetwork { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidUpdateNetworkImpl && + other is _$VeilidUpdateNetwork && (identical(other.started, started) || other.started == started) && (identical(other.bpsDown, bpsDown) || other.bpsDown == bpsDown) && (identical(other.bpsUp, bpsUp) || other.bpsUp == bpsUp) && @@ -2591,8 +2584,8 @@ class _$VeilidUpdateNetworkImpl implements VeilidUpdateNetwork { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidUpdateNetworkImplCopyWith<_$VeilidUpdateNetworkImpl> get copyWith => - __$$VeilidUpdateNetworkImplCopyWithImpl<_$VeilidUpdateNetworkImpl>( + _$$VeilidUpdateNetworkCopyWith<_$VeilidUpdateNetwork> get copyWith => + __$$VeilidUpdateNetworkCopyWithImpl<_$VeilidUpdateNetwork>( this, _$identity); @override @@ -2735,7 +2728,7 @@ class _$VeilidUpdateNetworkImpl implements VeilidUpdateNetwork { @override Map toJson() { - return _$$VeilidUpdateNetworkImplToJson( + return _$$VeilidUpdateNetworkToJson( this, ); } @@ -2746,25 +2739,25 @@ abstract class VeilidUpdateNetwork implements VeilidUpdate { {required final bool started, required final BigInt bpsDown, required final BigInt bpsUp, - required final List peers}) = _$VeilidUpdateNetworkImpl; + required final List peers}) = _$VeilidUpdateNetwork; factory VeilidUpdateNetwork.fromJson(Map json) = - _$VeilidUpdateNetworkImpl.fromJson; + _$VeilidUpdateNetwork.fromJson; bool get started; BigInt get bpsDown; BigInt get bpsUp; List get peers; @JsonKey(ignore: true) - _$$VeilidUpdateNetworkImplCopyWith<_$VeilidUpdateNetworkImpl> get copyWith => + _$$VeilidUpdateNetworkCopyWith<_$VeilidUpdateNetwork> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidUpdateConfigImplCopyWith<$Res> { - factory _$$VeilidUpdateConfigImplCopyWith(_$VeilidUpdateConfigImpl value, - $Res Function(_$VeilidUpdateConfigImpl) then) = - __$$VeilidUpdateConfigImplCopyWithImpl<$Res>; +abstract class _$$VeilidUpdateConfigCopyWith<$Res> { + factory _$$VeilidUpdateConfigCopyWith(_$VeilidUpdateConfig value, + $Res Function(_$VeilidUpdateConfig) then) = + __$$VeilidUpdateConfigCopyWithImpl<$Res>; @useResult $Res call({VeilidConfig config}); @@ -2772,11 +2765,11 @@ abstract class _$$VeilidUpdateConfigImplCopyWith<$Res> { } /// @nodoc -class __$$VeilidUpdateConfigImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateConfigImpl> - implements _$$VeilidUpdateConfigImplCopyWith<$Res> { - __$$VeilidUpdateConfigImplCopyWithImpl(_$VeilidUpdateConfigImpl _value, - $Res Function(_$VeilidUpdateConfigImpl) _then) +class __$$VeilidUpdateConfigCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateConfig> + implements _$$VeilidUpdateConfigCopyWith<$Res> { + __$$VeilidUpdateConfigCopyWithImpl( + _$VeilidUpdateConfig _value, $Res Function(_$VeilidUpdateConfig) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2784,7 +2777,7 @@ class __$$VeilidUpdateConfigImplCopyWithImpl<$Res> $Res call({ Object? config = null, }) { - return _then(_$VeilidUpdateConfigImpl( + return _then(_$VeilidUpdateConfig( config: null == config ? _value.config : config // ignore: cast_nullable_to_non_nullable @@ -2803,12 +2796,12 @@ class __$$VeilidUpdateConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidUpdateConfigImpl implements VeilidUpdateConfig { - const _$VeilidUpdateConfigImpl({required this.config, final String? $type}) +class _$VeilidUpdateConfig implements VeilidUpdateConfig { + const _$VeilidUpdateConfig({required this.config, final String? $type}) : $type = $type ?? 'Config'; - factory _$VeilidUpdateConfigImpl.fromJson(Map json) => - _$$VeilidUpdateConfigImplFromJson(json); + factory _$VeilidUpdateConfig.fromJson(Map json) => + _$$VeilidUpdateConfigFromJson(json); @override final VeilidConfig config; @@ -2825,7 +2818,7 @@ class _$VeilidUpdateConfigImpl implements VeilidUpdateConfig { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidUpdateConfigImpl && + other is _$VeilidUpdateConfig && (identical(other.config, config) || other.config == config)); } @@ -2836,8 +2829,8 @@ class _$VeilidUpdateConfigImpl implements VeilidUpdateConfig { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidUpdateConfigImplCopyWith<_$VeilidUpdateConfigImpl> get copyWith => - __$$VeilidUpdateConfigImplCopyWithImpl<_$VeilidUpdateConfigImpl>( + _$$VeilidUpdateConfigCopyWith<_$VeilidUpdateConfig> get copyWith => + __$$VeilidUpdateConfigCopyWithImpl<_$VeilidUpdateConfig>( this, _$identity); @override @@ -2980,7 +2973,7 @@ class _$VeilidUpdateConfigImpl implements VeilidUpdateConfig { @override Map toJson() { - return _$$VeilidUpdateConfigImplToJson( + return _$$VeilidUpdateConfigToJson( this, ); } @@ -2988,34 +2981,32 @@ class _$VeilidUpdateConfigImpl implements VeilidUpdateConfig { abstract class VeilidUpdateConfig implements VeilidUpdate { const factory VeilidUpdateConfig({required final VeilidConfig config}) = - _$VeilidUpdateConfigImpl; + _$VeilidUpdateConfig; factory VeilidUpdateConfig.fromJson(Map json) = - _$VeilidUpdateConfigImpl.fromJson; + _$VeilidUpdateConfig.fromJson; VeilidConfig get config; @JsonKey(ignore: true) - _$$VeilidUpdateConfigImplCopyWith<_$VeilidUpdateConfigImpl> get copyWith => + _$$VeilidUpdateConfigCopyWith<_$VeilidUpdateConfig> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidUpdateRouteChangeImplCopyWith<$Res> { - factory _$$VeilidUpdateRouteChangeImplCopyWith( - _$VeilidUpdateRouteChangeImpl value, - $Res Function(_$VeilidUpdateRouteChangeImpl) then) = - __$$VeilidUpdateRouteChangeImplCopyWithImpl<$Res>; +abstract class _$$VeilidUpdateRouteChangeCopyWith<$Res> { + factory _$$VeilidUpdateRouteChangeCopyWith(_$VeilidUpdateRouteChange value, + $Res Function(_$VeilidUpdateRouteChange) then) = + __$$VeilidUpdateRouteChangeCopyWithImpl<$Res>; @useResult $Res call({List deadRoutes, List deadRemoteRoutes}); } /// @nodoc -class __$$VeilidUpdateRouteChangeImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateRouteChangeImpl> - implements _$$VeilidUpdateRouteChangeImplCopyWith<$Res> { - __$$VeilidUpdateRouteChangeImplCopyWithImpl( - _$VeilidUpdateRouteChangeImpl _value, - $Res Function(_$VeilidUpdateRouteChangeImpl) _then) +class __$$VeilidUpdateRouteChangeCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateRouteChange> + implements _$$VeilidUpdateRouteChangeCopyWith<$Res> { + __$$VeilidUpdateRouteChangeCopyWithImpl(_$VeilidUpdateRouteChange _value, + $Res Function(_$VeilidUpdateRouteChange) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3024,7 +3015,7 @@ class __$$VeilidUpdateRouteChangeImplCopyWithImpl<$Res> Object? deadRoutes = null, Object? deadRemoteRoutes = null, }) { - return _then(_$VeilidUpdateRouteChangeImpl( + return _then(_$VeilidUpdateRouteChange( deadRoutes: null == deadRoutes ? _value._deadRoutes : deadRoutes // ignore: cast_nullable_to_non_nullable @@ -3039,8 +3030,8 @@ class __$$VeilidUpdateRouteChangeImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidUpdateRouteChangeImpl implements VeilidUpdateRouteChange { - const _$VeilidUpdateRouteChangeImpl( +class _$VeilidUpdateRouteChange implements VeilidUpdateRouteChange { + const _$VeilidUpdateRouteChange( {required final List deadRoutes, required final List deadRemoteRoutes, final String? $type}) @@ -3048,8 +3039,8 @@ class _$VeilidUpdateRouteChangeImpl implements VeilidUpdateRouteChange { _deadRemoteRoutes = deadRemoteRoutes, $type = $type ?? 'RouteChange'; - factory _$VeilidUpdateRouteChangeImpl.fromJson(Map json) => - _$$VeilidUpdateRouteChangeImplFromJson(json); + factory _$VeilidUpdateRouteChange.fromJson(Map json) => + _$$VeilidUpdateRouteChangeFromJson(json); final List _deadRoutes; @override @@ -3080,7 +3071,7 @@ class _$VeilidUpdateRouteChangeImpl implements VeilidUpdateRouteChange { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidUpdateRouteChangeImpl && + other is _$VeilidUpdateRouteChange && const DeepCollectionEquality() .equals(other._deadRoutes, _deadRoutes) && const DeepCollectionEquality() @@ -3097,9 +3088,9 @@ class _$VeilidUpdateRouteChangeImpl implements VeilidUpdateRouteChange { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidUpdateRouteChangeImplCopyWith<_$VeilidUpdateRouteChangeImpl> - get copyWith => __$$VeilidUpdateRouteChangeImplCopyWithImpl< - _$VeilidUpdateRouteChangeImpl>(this, _$identity); + _$$VeilidUpdateRouteChangeCopyWith<_$VeilidUpdateRouteChange> get copyWith => + __$$VeilidUpdateRouteChangeCopyWithImpl<_$VeilidUpdateRouteChange>( + this, _$identity); @override @optionalTypeArgs @@ -3241,7 +3232,7 @@ class _$VeilidUpdateRouteChangeImpl implements VeilidUpdateRouteChange { @override Map toJson() { - return _$$VeilidUpdateRouteChangeImplToJson( + return _$$VeilidUpdateRouteChangeToJson( this, ); } @@ -3251,24 +3242,23 @@ abstract class VeilidUpdateRouteChange implements VeilidUpdate { const factory VeilidUpdateRouteChange( {required final List deadRoutes, required final List deadRemoteRoutes}) = - _$VeilidUpdateRouteChangeImpl; + _$VeilidUpdateRouteChange; factory VeilidUpdateRouteChange.fromJson(Map json) = - _$VeilidUpdateRouteChangeImpl.fromJson; + _$VeilidUpdateRouteChange.fromJson; List get deadRoutes; List get deadRemoteRoutes; @JsonKey(ignore: true) - _$$VeilidUpdateRouteChangeImplCopyWith<_$VeilidUpdateRouteChangeImpl> - get copyWith => throw _privateConstructorUsedError; + _$$VeilidUpdateRouteChangeCopyWith<_$VeilidUpdateRouteChange> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$VeilidUpdateValueChangeImplCopyWith<$Res> { - factory _$$VeilidUpdateValueChangeImplCopyWith( - _$VeilidUpdateValueChangeImpl value, - $Res Function(_$VeilidUpdateValueChangeImpl) then) = - __$$VeilidUpdateValueChangeImplCopyWithImpl<$Res>; +abstract class _$$VeilidUpdateValueChangeCopyWith<$Res> { + factory _$$VeilidUpdateValueChangeCopyWith(_$VeilidUpdateValueChange value, + $Res Function(_$VeilidUpdateValueChange) then) = + __$$VeilidUpdateValueChangeCopyWithImpl<$Res>; @useResult $Res call( {Typed key, @@ -3280,12 +3270,11 @@ abstract class _$$VeilidUpdateValueChangeImplCopyWith<$Res> { } /// @nodoc -class __$$VeilidUpdateValueChangeImplCopyWithImpl<$Res> - extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateValueChangeImpl> - implements _$$VeilidUpdateValueChangeImplCopyWith<$Res> { - __$$VeilidUpdateValueChangeImplCopyWithImpl( - _$VeilidUpdateValueChangeImpl _value, - $Res Function(_$VeilidUpdateValueChangeImpl) _then) +class __$$VeilidUpdateValueChangeCopyWithImpl<$Res> + extends _$VeilidUpdateCopyWithImpl<$Res, _$VeilidUpdateValueChange> + implements _$$VeilidUpdateValueChangeCopyWith<$Res> { + __$$VeilidUpdateValueChangeCopyWithImpl(_$VeilidUpdateValueChange _value, + $Res Function(_$VeilidUpdateValueChange) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3296,7 +3285,7 @@ class __$$VeilidUpdateValueChangeImplCopyWithImpl<$Res> Object? count = null, Object? valueData = null, }) { - return _then(_$VeilidUpdateValueChangeImpl( + return _then(_$VeilidUpdateValueChange( key: null == key ? _value.key : key // ignore: cast_nullable_to_non_nullable @@ -3327,8 +3316,8 @@ class __$$VeilidUpdateValueChangeImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidUpdateValueChangeImpl implements VeilidUpdateValueChange { - const _$VeilidUpdateValueChangeImpl( +class _$VeilidUpdateValueChange implements VeilidUpdateValueChange { + const _$VeilidUpdateValueChange( {required this.key, required final List subkeys, required this.count, @@ -3337,8 +3326,8 @@ class _$VeilidUpdateValueChangeImpl implements VeilidUpdateValueChange { : _subkeys = subkeys, $type = $type ?? 'ValueChange'; - factory _$VeilidUpdateValueChangeImpl.fromJson(Map json) => - _$$VeilidUpdateValueChangeImplFromJson(json); + factory _$VeilidUpdateValueChange.fromJson(Map json) => + _$$VeilidUpdateValueChangeFromJson(json); @override final Typed key; @@ -3367,7 +3356,7 @@ class _$VeilidUpdateValueChangeImpl implements VeilidUpdateValueChange { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidUpdateValueChangeImpl && + other is _$VeilidUpdateValueChange && (identical(other.key, key) || other.key == key) && const DeepCollectionEquality().equals(other._subkeys, _subkeys) && (identical(other.count, count) || other.count == count) && @@ -3383,9 +3372,9 @@ class _$VeilidUpdateValueChangeImpl implements VeilidUpdateValueChange { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidUpdateValueChangeImplCopyWith<_$VeilidUpdateValueChangeImpl> - get copyWith => __$$VeilidUpdateValueChangeImplCopyWithImpl< - _$VeilidUpdateValueChangeImpl>(this, _$identity); + _$$VeilidUpdateValueChangeCopyWith<_$VeilidUpdateValueChange> get copyWith => + __$$VeilidUpdateValueChangeCopyWithImpl<_$VeilidUpdateValueChange>( + this, _$identity); @override @optionalTypeArgs @@ -3527,7 +3516,7 @@ class _$VeilidUpdateValueChangeImpl implements VeilidUpdateValueChange { @override Map toJson() { - return _$$VeilidUpdateValueChangeImplToJson( + return _$$VeilidUpdateValueChangeToJson( this, ); } @@ -3538,18 +3527,18 @@ abstract class VeilidUpdateValueChange implements VeilidUpdate { {required final Typed key, required final List subkeys, required final int count, - required final ValueData valueData}) = _$VeilidUpdateValueChangeImpl; + required final ValueData valueData}) = _$VeilidUpdateValueChange; factory VeilidUpdateValueChange.fromJson(Map json) = - _$VeilidUpdateValueChangeImpl.fromJson; + _$VeilidUpdateValueChange.fromJson; Typed get key; List get subkeys; int get count; ValueData get valueData; @JsonKey(ignore: true) - _$$VeilidUpdateValueChangeImplCopyWith<_$VeilidUpdateValueChangeImpl> - get copyWith => throw _privateConstructorUsedError; + _$$VeilidUpdateValueChangeCopyWith<_$VeilidUpdateValueChange> get copyWith => + throw _privateConstructorUsedError; } VeilidStateAttachment _$VeilidStateAttachmentFromJson( @@ -3617,12 +3606,11 @@ class _$VeilidStateAttachmentCopyWithImpl<$Res, } /// @nodoc -abstract class _$$VeilidStateAttachmentImplCopyWith<$Res> +abstract class _$$_VeilidStateAttachmentCopyWith<$Res> implements $VeilidStateAttachmentCopyWith<$Res> { - factory _$$VeilidStateAttachmentImplCopyWith( - _$VeilidStateAttachmentImpl value, - $Res Function(_$VeilidStateAttachmentImpl) then) = - __$$VeilidStateAttachmentImplCopyWithImpl<$Res>; + factory _$$_VeilidStateAttachmentCopyWith(_$_VeilidStateAttachment value, + $Res Function(_$_VeilidStateAttachment) then) = + __$$_VeilidStateAttachmentCopyWithImpl<$Res>; @override @useResult $Res call( @@ -3632,12 +3620,11 @@ abstract class _$$VeilidStateAttachmentImplCopyWith<$Res> } /// @nodoc -class __$$VeilidStateAttachmentImplCopyWithImpl<$Res> - extends _$VeilidStateAttachmentCopyWithImpl<$Res, - _$VeilidStateAttachmentImpl> - implements _$$VeilidStateAttachmentImplCopyWith<$Res> { - __$$VeilidStateAttachmentImplCopyWithImpl(_$VeilidStateAttachmentImpl _value, - $Res Function(_$VeilidStateAttachmentImpl) _then) +class __$$_VeilidStateAttachmentCopyWithImpl<$Res> + extends _$VeilidStateAttachmentCopyWithImpl<$Res, _$_VeilidStateAttachment> + implements _$$_VeilidStateAttachmentCopyWith<$Res> { + __$$_VeilidStateAttachmentCopyWithImpl(_$_VeilidStateAttachment _value, + $Res Function(_$_VeilidStateAttachment) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3647,7 +3634,7 @@ class __$$VeilidStateAttachmentImplCopyWithImpl<$Res> Object? publicInternetReady = null, Object? localNetworkReady = null, }) { - return _then(_$VeilidStateAttachmentImpl( + return _then(_$_VeilidStateAttachment( state: null == state ? _value.state : state // ignore: cast_nullable_to_non_nullable @@ -3666,14 +3653,14 @@ class __$$VeilidStateAttachmentImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidStateAttachmentImpl implements _VeilidStateAttachment { - const _$VeilidStateAttachmentImpl( +class _$_VeilidStateAttachment implements _VeilidStateAttachment { + const _$_VeilidStateAttachment( {required this.state, required this.publicInternetReady, required this.localNetworkReady}); - factory _$VeilidStateAttachmentImpl.fromJson(Map json) => - _$$VeilidStateAttachmentImplFromJson(json); + factory _$_VeilidStateAttachment.fromJson(Map json) => + _$$_VeilidStateAttachmentFromJson(json); @override final AttachmentState state; @@ -3691,7 +3678,7 @@ class _$VeilidStateAttachmentImpl implements _VeilidStateAttachment { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidStateAttachmentImpl && + other is _$_VeilidStateAttachment && (identical(other.state, state) || other.state == state) && (identical(other.publicInternetReady, publicInternetReady) || other.publicInternetReady == publicInternetReady) && @@ -3707,13 +3694,13 @@ class _$VeilidStateAttachmentImpl implements _VeilidStateAttachment { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidStateAttachmentImplCopyWith<_$VeilidStateAttachmentImpl> - get copyWith => __$$VeilidStateAttachmentImplCopyWithImpl< - _$VeilidStateAttachmentImpl>(this, _$identity); + _$$_VeilidStateAttachmentCopyWith<_$_VeilidStateAttachment> get copyWith => + __$$_VeilidStateAttachmentCopyWithImpl<_$_VeilidStateAttachment>( + this, _$identity); @override Map toJson() { - return _$$VeilidStateAttachmentImplToJson( + return _$$_VeilidStateAttachmentToJson( this, ); } @@ -3723,10 +3710,10 @@ abstract class _VeilidStateAttachment implements VeilidStateAttachment { const factory _VeilidStateAttachment( {required final AttachmentState state, required final bool publicInternetReady, - required final bool localNetworkReady}) = _$VeilidStateAttachmentImpl; + required final bool localNetworkReady}) = _$_VeilidStateAttachment; factory _VeilidStateAttachment.fromJson(Map json) = - _$VeilidStateAttachmentImpl.fromJson; + _$_VeilidStateAttachment.fromJson; @override AttachmentState get state; @@ -3736,8 +3723,8 @@ abstract class _VeilidStateAttachment implements VeilidStateAttachment { bool get localNetworkReady; @override @JsonKey(ignore: true) - _$$VeilidStateAttachmentImplCopyWith<_$VeilidStateAttachmentImpl> - get copyWith => throw _privateConstructorUsedError; + _$$_VeilidStateAttachmentCopyWith<_$_VeilidStateAttachment> get copyWith => + throw _privateConstructorUsedError; } VeilidStateNetwork _$VeilidStateNetworkFromJson(Map json) { @@ -3807,11 +3794,11 @@ class _$VeilidStateNetworkCopyWithImpl<$Res, $Val extends VeilidStateNetwork> } /// @nodoc -abstract class _$$VeilidStateNetworkImplCopyWith<$Res> +abstract class _$$_VeilidStateNetworkCopyWith<$Res> implements $VeilidStateNetworkCopyWith<$Res> { - factory _$$VeilidStateNetworkImplCopyWith(_$VeilidStateNetworkImpl value, - $Res Function(_$VeilidStateNetworkImpl) then) = - __$$VeilidStateNetworkImplCopyWithImpl<$Res>; + factory _$$_VeilidStateNetworkCopyWith(_$_VeilidStateNetwork value, + $Res Function(_$_VeilidStateNetwork) then) = + __$$_VeilidStateNetworkCopyWithImpl<$Res>; @override @useResult $Res call( @@ -3819,11 +3806,11 @@ abstract class _$$VeilidStateNetworkImplCopyWith<$Res> } /// @nodoc -class __$$VeilidStateNetworkImplCopyWithImpl<$Res> - extends _$VeilidStateNetworkCopyWithImpl<$Res, _$VeilidStateNetworkImpl> - implements _$$VeilidStateNetworkImplCopyWith<$Res> { - __$$VeilidStateNetworkImplCopyWithImpl(_$VeilidStateNetworkImpl _value, - $Res Function(_$VeilidStateNetworkImpl) _then) +class __$$_VeilidStateNetworkCopyWithImpl<$Res> + extends _$VeilidStateNetworkCopyWithImpl<$Res, _$_VeilidStateNetwork> + implements _$$_VeilidStateNetworkCopyWith<$Res> { + __$$_VeilidStateNetworkCopyWithImpl( + _$_VeilidStateNetwork _value, $Res Function(_$_VeilidStateNetwork) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3834,7 +3821,7 @@ class __$$VeilidStateNetworkImplCopyWithImpl<$Res> Object? bpsUp = null, Object? peers = null, }) { - return _then(_$VeilidStateNetworkImpl( + return _then(_$_VeilidStateNetwork( started: null == started ? _value.started : started // ignore: cast_nullable_to_non_nullable @@ -3857,16 +3844,16 @@ class __$$VeilidStateNetworkImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidStateNetworkImpl implements _VeilidStateNetwork { - const _$VeilidStateNetworkImpl( +class _$_VeilidStateNetwork implements _VeilidStateNetwork { + const _$_VeilidStateNetwork( {required this.started, required this.bpsDown, required this.bpsUp, required final List peers}) : _peers = peers; - factory _$VeilidStateNetworkImpl.fromJson(Map json) => - _$$VeilidStateNetworkImplFromJson(json); + factory _$_VeilidStateNetwork.fromJson(Map json) => + _$$_VeilidStateNetworkFromJson(json); @override final bool started; @@ -3891,7 +3878,7 @@ class _$VeilidStateNetworkImpl implements _VeilidStateNetwork { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidStateNetworkImpl && + other is _$_VeilidStateNetwork && (identical(other.started, started) || other.started == started) && (identical(other.bpsDown, bpsDown) || other.bpsDown == bpsDown) && (identical(other.bpsUp, bpsUp) || other.bpsUp == bpsUp) && @@ -3906,13 +3893,13 @@ class _$VeilidStateNetworkImpl implements _VeilidStateNetwork { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidStateNetworkImplCopyWith<_$VeilidStateNetworkImpl> get copyWith => - __$$VeilidStateNetworkImplCopyWithImpl<_$VeilidStateNetworkImpl>( + _$$_VeilidStateNetworkCopyWith<_$_VeilidStateNetwork> get copyWith => + __$$_VeilidStateNetworkCopyWithImpl<_$_VeilidStateNetwork>( this, _$identity); @override Map toJson() { - return _$$VeilidStateNetworkImplToJson( + return _$$_VeilidStateNetworkToJson( this, ); } @@ -3923,10 +3910,10 @@ abstract class _VeilidStateNetwork implements VeilidStateNetwork { {required final bool started, required final BigInt bpsDown, required final BigInt bpsUp, - required final List peers}) = _$VeilidStateNetworkImpl; + required final List peers}) = _$_VeilidStateNetwork; factory _VeilidStateNetwork.fromJson(Map json) = - _$VeilidStateNetworkImpl.fromJson; + _$_VeilidStateNetwork.fromJson; @override bool get started; @@ -3938,7 +3925,7 @@ abstract class _VeilidStateNetwork implements VeilidStateNetwork { List get peers; @override @JsonKey(ignore: true) - _$$VeilidStateNetworkImplCopyWith<_$VeilidStateNetworkImpl> get copyWith => + _$$_VeilidStateNetworkCopyWith<_$_VeilidStateNetwork> get copyWith => throw _privateConstructorUsedError; } @@ -4000,11 +3987,11 @@ class _$VeilidStateConfigCopyWithImpl<$Res, $Val extends VeilidStateConfig> } /// @nodoc -abstract class _$$VeilidStateConfigImplCopyWith<$Res> +abstract class _$$_VeilidStateConfigCopyWith<$Res> implements $VeilidStateConfigCopyWith<$Res> { - factory _$$VeilidStateConfigImplCopyWith(_$VeilidStateConfigImpl value, - $Res Function(_$VeilidStateConfigImpl) then) = - __$$VeilidStateConfigImplCopyWithImpl<$Res>; + factory _$$_VeilidStateConfigCopyWith(_$_VeilidStateConfig value, + $Res Function(_$_VeilidStateConfig) then) = + __$$_VeilidStateConfigCopyWithImpl<$Res>; @override @useResult $Res call({VeilidConfig config}); @@ -4014,11 +4001,11 @@ abstract class _$$VeilidStateConfigImplCopyWith<$Res> } /// @nodoc -class __$$VeilidStateConfigImplCopyWithImpl<$Res> - extends _$VeilidStateConfigCopyWithImpl<$Res, _$VeilidStateConfigImpl> - implements _$$VeilidStateConfigImplCopyWith<$Res> { - __$$VeilidStateConfigImplCopyWithImpl(_$VeilidStateConfigImpl _value, - $Res Function(_$VeilidStateConfigImpl) _then) +class __$$_VeilidStateConfigCopyWithImpl<$Res> + extends _$VeilidStateConfigCopyWithImpl<$Res, _$_VeilidStateConfig> + implements _$$_VeilidStateConfigCopyWith<$Res> { + __$$_VeilidStateConfigCopyWithImpl( + _$_VeilidStateConfig _value, $Res Function(_$_VeilidStateConfig) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4026,7 +4013,7 @@ class __$$VeilidStateConfigImplCopyWithImpl<$Res> $Res call({ Object? config = null, }) { - return _then(_$VeilidStateConfigImpl( + return _then(_$_VeilidStateConfig( config: null == config ? _value.config : config // ignore: cast_nullable_to_non_nullable @@ -4037,11 +4024,11 @@ class __$$VeilidStateConfigImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidStateConfigImpl implements _VeilidStateConfig { - const _$VeilidStateConfigImpl({required this.config}); +class _$_VeilidStateConfig implements _VeilidStateConfig { + const _$_VeilidStateConfig({required this.config}); - factory _$VeilidStateConfigImpl.fromJson(Map json) => - _$$VeilidStateConfigImplFromJson(json); + factory _$_VeilidStateConfig.fromJson(Map json) => + _$$_VeilidStateConfigFromJson(json); @override final VeilidConfig config; @@ -4055,7 +4042,7 @@ class _$VeilidStateConfigImpl implements _VeilidStateConfig { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidStateConfigImpl && + other is _$_VeilidStateConfig && (identical(other.config, config) || other.config == config)); } @@ -4066,13 +4053,13 @@ class _$VeilidStateConfigImpl implements _VeilidStateConfig { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidStateConfigImplCopyWith<_$VeilidStateConfigImpl> get copyWith => - __$$VeilidStateConfigImplCopyWithImpl<_$VeilidStateConfigImpl>( + _$$_VeilidStateConfigCopyWith<_$_VeilidStateConfig> get copyWith => + __$$_VeilidStateConfigCopyWithImpl<_$_VeilidStateConfig>( this, _$identity); @override Map toJson() { - return _$$VeilidStateConfigImplToJson( + return _$$_VeilidStateConfigToJson( this, ); } @@ -4080,16 +4067,16 @@ class _$VeilidStateConfigImpl implements _VeilidStateConfig { abstract class _VeilidStateConfig implements VeilidStateConfig { const factory _VeilidStateConfig({required final VeilidConfig config}) = - _$VeilidStateConfigImpl; + _$_VeilidStateConfig; factory _VeilidStateConfig.fromJson(Map json) = - _$VeilidStateConfigImpl.fromJson; + _$_VeilidStateConfig.fromJson; @override VeilidConfig get config; @override @JsonKey(ignore: true) - _$$VeilidStateConfigImplCopyWith<_$VeilidStateConfigImpl> get copyWith => + _$$_VeilidStateConfigCopyWith<_$_VeilidStateConfig> get copyWith => throw _privateConstructorUsedError; } @@ -4184,11 +4171,11 @@ class _$VeilidStateCopyWithImpl<$Res, $Val extends VeilidState> } /// @nodoc -abstract class _$$VeilidStateImplCopyWith<$Res> +abstract class _$$_VeilidStateCopyWith<$Res> implements $VeilidStateCopyWith<$Res> { - factory _$$VeilidStateImplCopyWith( - _$VeilidStateImpl value, $Res Function(_$VeilidStateImpl) then) = - __$$VeilidStateImplCopyWithImpl<$Res>; + factory _$$_VeilidStateCopyWith( + _$_VeilidState value, $Res Function(_$_VeilidState) then) = + __$$_VeilidStateCopyWithImpl<$Res>; @override @useResult $Res call( @@ -4205,11 +4192,11 @@ abstract class _$$VeilidStateImplCopyWith<$Res> } /// @nodoc -class __$$VeilidStateImplCopyWithImpl<$Res> - extends _$VeilidStateCopyWithImpl<$Res, _$VeilidStateImpl> - implements _$$VeilidStateImplCopyWith<$Res> { - __$$VeilidStateImplCopyWithImpl( - _$VeilidStateImpl _value, $Res Function(_$VeilidStateImpl) _then) +class __$$_VeilidStateCopyWithImpl<$Res> + extends _$VeilidStateCopyWithImpl<$Res, _$_VeilidState> + implements _$$_VeilidStateCopyWith<$Res> { + __$$_VeilidStateCopyWithImpl( + _$_VeilidState _value, $Res Function(_$_VeilidState) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4219,7 +4206,7 @@ class __$$VeilidStateImplCopyWithImpl<$Res> Object? network = null, Object? config = null, }) { - return _then(_$VeilidStateImpl( + return _then(_$_VeilidState( attachment: null == attachment ? _value.attachment : attachment // ignore: cast_nullable_to_non_nullable @@ -4238,12 +4225,12 @@ class __$$VeilidStateImplCopyWithImpl<$Res> /// @nodoc @JsonSerializable() -class _$VeilidStateImpl implements _VeilidState { - const _$VeilidStateImpl( +class _$_VeilidState implements _VeilidState { + const _$_VeilidState( {required this.attachment, required this.network, required this.config}); - factory _$VeilidStateImpl.fromJson(Map json) => - _$$VeilidStateImplFromJson(json); + factory _$_VeilidState.fromJson(Map json) => + _$$_VeilidStateFromJson(json); @override final VeilidStateAttachment attachment; @@ -4261,7 +4248,7 @@ class _$VeilidStateImpl implements _VeilidState { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$VeilidStateImpl && + other is _$_VeilidState && (identical(other.attachment, attachment) || other.attachment == attachment) && (identical(other.network, network) || other.network == network) && @@ -4275,12 +4262,12 @@ class _$VeilidStateImpl implements _VeilidState { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$VeilidStateImplCopyWith<_$VeilidStateImpl> get copyWith => - __$$VeilidStateImplCopyWithImpl<_$VeilidStateImpl>(this, _$identity); + _$$_VeilidStateCopyWith<_$_VeilidState> get copyWith => + __$$_VeilidStateCopyWithImpl<_$_VeilidState>(this, _$identity); @override Map toJson() { - return _$$VeilidStateImplToJson( + return _$$_VeilidStateToJson( this, ); } @@ -4290,10 +4277,10 @@ abstract class _VeilidState implements VeilidState { const factory _VeilidState( {required final VeilidStateAttachment attachment, required final VeilidStateNetwork network, - required final VeilidStateConfig config}) = _$VeilidStateImpl; + required final VeilidStateConfig config}) = _$_VeilidState; factory _VeilidState.fromJson(Map json) = - _$VeilidStateImpl.fromJson; + _$_VeilidState.fromJson; @override VeilidStateAttachment get attachment; @@ -4303,6 +4290,6 @@ abstract class _VeilidState implements VeilidState { VeilidStateConfig get config; @override @JsonKey(ignore: true) - _$$VeilidStateImplCopyWith<_$VeilidStateImpl> get copyWith => + _$$_VeilidStateCopyWith<_$_VeilidState> get copyWith => throw _privateConstructorUsedError; } diff --git a/veilid-flutter/lib/veilid_state.g.dart b/veilid-flutter/lib/veilid_state.g.dart index 6cc9fcfb..8ed1eb66 100644 --- a/veilid-flutter/lib/veilid_state.g.dart +++ b/veilid-flutter/lib/veilid_state.g.dart @@ -6,29 +6,29 @@ part of 'veilid_state.dart'; // JsonSerializableGenerator // ************************************************************************** -_$LatencyStatsImpl _$$LatencyStatsImplFromJson(Map json) => - _$LatencyStatsImpl( +_$_LatencyStats _$$_LatencyStatsFromJson(Map json) => + _$_LatencyStats( fastest: TimestampDuration.fromJson(json['fastest']), average: TimestampDuration.fromJson(json['average']), slowest: TimestampDuration.fromJson(json['slowest']), ); -Map _$$LatencyStatsImplToJson(_$LatencyStatsImpl instance) => +Map _$$_LatencyStatsToJson(_$_LatencyStats instance) => { 'fastest': instance.fastest.toJson(), 'average': instance.average.toJson(), 'slowest': instance.slowest.toJson(), }; -_$TransferStatsImpl _$$TransferStatsImplFromJson(Map json) => - _$TransferStatsImpl( +_$_TransferStats _$$_TransferStatsFromJson(Map json) => + _$_TransferStats( total: BigInt.parse(json['total'] as String), maximum: BigInt.parse(json['maximum'] as String), average: BigInt.parse(json['average'] as String), minimum: BigInt.parse(json['minimum'] as String), ); -Map _$$TransferStatsImplToJson(_$TransferStatsImpl instance) => +Map _$$_TransferStatsToJson(_$_TransferStats instance) => { 'total': instance.total.toString(), 'maximum': instance.maximum.toString(), @@ -36,22 +36,21 @@ Map _$$TransferStatsImplToJson(_$TransferStatsImpl instance) => 'minimum': instance.minimum.toString(), }; -_$TransferStatsDownUpImpl _$$TransferStatsDownUpImplFromJson( +_$_TransferStatsDownUp _$$_TransferStatsDownUpFromJson( Map json) => - _$TransferStatsDownUpImpl( + _$_TransferStatsDownUp( down: TransferStats.fromJson(json['down']), up: TransferStats.fromJson(json['up']), ); -Map _$$TransferStatsDownUpImplToJson( - _$TransferStatsDownUpImpl instance) => +Map _$$_TransferStatsDownUpToJson( + _$_TransferStatsDownUp instance) => { 'down': instance.down.toJson(), 'up': instance.up.toJson(), }; -_$RPCStatsImpl _$$RPCStatsImplFromJson(Map json) => - _$RPCStatsImpl( +_$_RPCStats _$$_RPCStatsFromJson(Map json) => _$_RPCStats( messagesSent: json['messages_sent'] as int, messagesRcvd: json['messages_rcvd'] as int, questionsInFlight: json['questions_in_flight'] as int, @@ -68,7 +67,7 @@ _$RPCStatsImpl _$$RPCStatsImplFromJson(Map json) => failedToSend: json['failed_to_send'] as int, ); -Map _$$RPCStatsImplToJson(_$RPCStatsImpl instance) => +Map _$$_RPCStatsToJson(_$_RPCStats instance) => { 'messages_sent': instance.messagesSent, 'messages_rcvd': instance.messagesRcvd, @@ -80,8 +79,7 @@ Map _$$RPCStatsImplToJson(_$RPCStatsImpl instance) => 'failed_to_send': instance.failedToSend, }; -_$PeerStatsImpl _$$PeerStatsImplFromJson(Map json) => - _$PeerStatsImpl( +_$_PeerStats _$$_PeerStatsFromJson(Map json) => _$_PeerStats( timeAdded: Timestamp.fromJson(json['time_added']), rpcStats: RPCStats.fromJson(json['rpc_stats']), transfer: TransferStatsDownUp.fromJson(json['transfer']), @@ -90,7 +88,7 @@ _$PeerStatsImpl _$$PeerStatsImplFromJson(Map json) => : LatencyStats.fromJson(json['latency']), ); -Map _$$PeerStatsImplToJson(_$PeerStatsImpl instance) => +Map _$$_PeerStatsToJson(_$_PeerStats instance) => { 'time_added': instance.timeAdded.toJson(), 'rpc_stats': instance.rpcStats.toJson(), @@ -98,8 +96,8 @@ Map _$$PeerStatsImplToJson(_$PeerStatsImpl instance) => 'latency': instance.latency?.toJson(), }; -_$PeerTableDataImpl _$$PeerTableDataImplFromJson(Map json) => - _$PeerTableDataImpl( +_$_PeerTableData _$$_PeerTableDataFromJson(Map json) => + _$_PeerTableData( nodeIds: (json['node_ids'] as List) .map(Typed.fromJson) .toList(), @@ -107,22 +105,21 @@ _$PeerTableDataImpl _$$PeerTableDataImplFromJson(Map json) => peerStats: PeerStats.fromJson(json['peer_stats']), ); -Map _$$PeerTableDataImplToJson(_$PeerTableDataImpl instance) => +Map _$$_PeerTableDataToJson(_$_PeerTableData instance) => { 'node_ids': instance.nodeIds.map((e) => e.toJson()).toList(), 'peer_address': instance.peerAddress, 'peer_stats': instance.peerStats.toJson(), }; -_$VeilidLogImpl _$$VeilidLogImplFromJson(Map json) => - _$VeilidLogImpl( +_$VeilidLog _$$VeilidLogFromJson(Map json) => _$VeilidLog( logLevel: VeilidLogLevel.fromJson(json['log_level']), message: json['message'] as String, backtrace: json['backtrace'] as String?, $type: json['kind'] as String?, ); -Map _$$VeilidLogImplToJson(_$VeilidLogImpl instance) => +Map _$$VeilidLogToJson(_$VeilidLog instance) => { 'log_level': instance.logLevel.toJson(), 'message': instance.message, @@ -130,9 +127,8 @@ Map _$$VeilidLogImplToJson(_$VeilidLogImpl instance) => 'kind': instance.$type, }; -_$VeilidAppMessageImpl _$$VeilidAppMessageImplFromJson( - Map json) => - _$VeilidAppMessageImpl( +_$VeilidAppMessage _$$VeilidAppMessageFromJson(Map json) => + _$VeilidAppMessage( message: const Uint8ListJsonConverter().fromJson(json['message']), sender: json['sender'] == null ? null @@ -140,16 +136,15 @@ _$VeilidAppMessageImpl _$$VeilidAppMessageImplFromJson( $type: json['kind'] as String?, ); -Map _$$VeilidAppMessageImplToJson( - _$VeilidAppMessageImpl instance) => +Map _$$VeilidAppMessageToJson(_$VeilidAppMessage instance) => { 'message': const Uint8ListJsonConverter().toJson(instance.message), 'sender': instance.sender?.toJson(), 'kind': instance.$type, }; -_$VeilidAppCallImpl _$$VeilidAppCallImplFromJson(Map json) => - _$VeilidAppCallImpl( +_$VeilidAppCall _$$VeilidAppCallFromJson(Map json) => + _$VeilidAppCall( message: const Uint8ListJsonConverter().fromJson(json['message']), callId: json['call_id'] as String, sender: json['sender'] == null @@ -158,7 +153,7 @@ _$VeilidAppCallImpl _$$VeilidAppCallImplFromJson(Map json) => $type: json['kind'] as String?, ); -Map _$$VeilidAppCallImplToJson(_$VeilidAppCallImpl instance) => +Map _$$VeilidAppCallToJson(_$VeilidAppCall instance) => { 'message': const Uint8ListJsonConverter().toJson(instance.message), 'call_id': instance.callId, @@ -166,17 +161,17 @@ Map _$$VeilidAppCallImplToJson(_$VeilidAppCallImpl instance) => 'kind': instance.$type, }; -_$VeilidUpdateAttachmentImpl _$$VeilidUpdateAttachmentImplFromJson( +_$VeilidUpdateAttachment _$$VeilidUpdateAttachmentFromJson( Map json) => - _$VeilidUpdateAttachmentImpl( + _$VeilidUpdateAttachment( state: AttachmentState.fromJson(json['state']), publicInternetReady: json['public_internet_ready'] as bool, localNetworkReady: json['local_network_ready'] as bool, $type: json['kind'] as String?, ); -Map _$$VeilidUpdateAttachmentImplToJson( - _$VeilidUpdateAttachmentImpl instance) => +Map _$$VeilidUpdateAttachmentToJson( + _$VeilidUpdateAttachment instance) => { 'state': instance.state.toJson(), 'public_internet_ready': instance.publicInternetReady, @@ -184,9 +179,9 @@ Map _$$VeilidUpdateAttachmentImplToJson( 'kind': instance.$type, }; -_$VeilidUpdateNetworkImpl _$$VeilidUpdateNetworkImplFromJson( +_$VeilidUpdateNetwork _$$VeilidUpdateNetworkFromJson( Map json) => - _$VeilidUpdateNetworkImpl( + _$VeilidUpdateNetwork( started: json['started'] as bool, bpsDown: BigInt.parse(json['bps_down'] as String), bpsUp: BigInt.parse(json['bps_up'] as String), @@ -195,8 +190,8 @@ _$VeilidUpdateNetworkImpl _$$VeilidUpdateNetworkImplFromJson( $type: json['kind'] as String?, ); -Map _$$VeilidUpdateNetworkImplToJson( - _$VeilidUpdateNetworkImpl instance) => +Map _$$VeilidUpdateNetworkToJson( + _$VeilidUpdateNetwork instance) => { 'started': instance.started, 'bps_down': instance.bpsDown.toString(), @@ -205,23 +200,22 @@ Map _$$VeilidUpdateNetworkImplToJson( 'kind': instance.$type, }; -_$VeilidUpdateConfigImpl _$$VeilidUpdateConfigImplFromJson( - Map json) => - _$VeilidUpdateConfigImpl( +_$VeilidUpdateConfig _$$VeilidUpdateConfigFromJson(Map json) => + _$VeilidUpdateConfig( config: VeilidConfig.fromJson(json['config']), $type: json['kind'] as String?, ); -Map _$$VeilidUpdateConfigImplToJson( - _$VeilidUpdateConfigImpl instance) => +Map _$$VeilidUpdateConfigToJson( + _$VeilidUpdateConfig instance) => { 'config': instance.config.toJson(), 'kind': instance.$type, }; -_$VeilidUpdateRouteChangeImpl _$$VeilidUpdateRouteChangeImplFromJson( +_$VeilidUpdateRouteChange _$$VeilidUpdateRouteChangeFromJson( Map json) => - _$VeilidUpdateRouteChangeImpl( + _$VeilidUpdateRouteChange( deadRoutes: (json['dead_routes'] as List) .map((e) => e as String) .toList(), @@ -231,17 +225,17 @@ _$VeilidUpdateRouteChangeImpl _$$VeilidUpdateRouteChangeImplFromJson( $type: json['kind'] as String?, ); -Map _$$VeilidUpdateRouteChangeImplToJson( - _$VeilidUpdateRouteChangeImpl instance) => +Map _$$VeilidUpdateRouteChangeToJson( + _$VeilidUpdateRouteChange instance) => { 'dead_routes': instance.deadRoutes, 'dead_remote_routes': instance.deadRemoteRoutes, 'kind': instance.$type, }; -_$VeilidUpdateValueChangeImpl _$$VeilidUpdateValueChangeImplFromJson( +_$VeilidUpdateValueChange _$$VeilidUpdateValueChangeFromJson( Map json) => - _$VeilidUpdateValueChangeImpl( + _$VeilidUpdateValueChange( key: Typed.fromJson(json['key']), subkeys: (json['subkeys'] as List) .map(ValueSubkeyRange.fromJson) @@ -251,8 +245,8 @@ _$VeilidUpdateValueChangeImpl _$$VeilidUpdateValueChangeImplFromJson( $type: json['kind'] as String?, ); -Map _$$VeilidUpdateValueChangeImplToJson( - _$VeilidUpdateValueChangeImpl instance) => +Map _$$VeilidUpdateValueChangeToJson( + _$VeilidUpdateValueChange instance) => { 'key': instance.key.toJson(), 'subkeys': instance.subkeys.map((e) => e.toJson()).toList(), @@ -261,25 +255,25 @@ Map _$$VeilidUpdateValueChangeImplToJson( 'kind': instance.$type, }; -_$VeilidStateAttachmentImpl _$$VeilidStateAttachmentImplFromJson( +_$_VeilidStateAttachment _$$_VeilidStateAttachmentFromJson( Map json) => - _$VeilidStateAttachmentImpl( + _$_VeilidStateAttachment( state: AttachmentState.fromJson(json['state']), publicInternetReady: json['public_internet_ready'] as bool, localNetworkReady: json['local_network_ready'] as bool, ); -Map _$$VeilidStateAttachmentImplToJson( - _$VeilidStateAttachmentImpl instance) => +Map _$$_VeilidStateAttachmentToJson( + _$_VeilidStateAttachment instance) => { 'state': instance.state.toJson(), 'public_internet_ready': instance.publicInternetReady, 'local_network_ready': instance.localNetworkReady, }; -_$VeilidStateNetworkImpl _$$VeilidStateNetworkImplFromJson( +_$_VeilidStateNetwork _$$_VeilidStateNetworkFromJson( Map json) => - _$VeilidStateNetworkImpl( + _$_VeilidStateNetwork( started: json['started'] as bool, bpsDown: BigInt.parse(json['bps_down'] as String), bpsUp: BigInt.parse(json['bps_up'] as String), @@ -287,8 +281,8 @@ _$VeilidStateNetworkImpl _$$VeilidStateNetworkImplFromJson( (json['peers'] as List).map(PeerTableData.fromJson).toList(), ); -Map _$$VeilidStateNetworkImplToJson( - _$VeilidStateNetworkImpl instance) => +Map _$$_VeilidStateNetworkToJson( + _$_VeilidStateNetwork instance) => { 'started': instance.started, 'bps_down': instance.bpsDown.toString(), @@ -296,26 +290,25 @@ Map _$$VeilidStateNetworkImplToJson( 'peers': instance.peers.map((e) => e.toJson()).toList(), }; -_$VeilidStateConfigImpl _$$VeilidStateConfigImplFromJson( - Map json) => - _$VeilidStateConfigImpl( +_$_VeilidStateConfig _$$_VeilidStateConfigFromJson(Map json) => + _$_VeilidStateConfig( config: VeilidConfig.fromJson(json['config']), ); -Map _$$VeilidStateConfigImplToJson( - _$VeilidStateConfigImpl instance) => +Map _$$_VeilidStateConfigToJson( + _$_VeilidStateConfig instance) => { 'config': instance.config.toJson(), }; -_$VeilidStateImpl _$$VeilidStateImplFromJson(Map json) => - _$VeilidStateImpl( +_$_VeilidState _$$_VeilidStateFromJson(Map json) => + _$_VeilidState( attachment: VeilidStateAttachment.fromJson(json['attachment']), network: VeilidStateNetwork.fromJson(json['network']), config: VeilidStateConfig.fromJson(json['config']), ); -Map _$$VeilidStateImplToJson(_$VeilidStateImpl instance) => +Map _$$_VeilidStateToJson(_$_VeilidState instance) => { 'attachment': instance.attachment.toJson(), 'network': instance.network.toJson(), diff --git a/veilid-python/veilid/config.py b/veilid-python/veilid/config.py index 02644495..8cfa04fb 100644 --- a/veilid-python/veilid/config.py +++ b/veilid-python/veilid/config.py @@ -112,8 +112,7 @@ class VeilidConfigDHT(ConfigBase): remote_max_storage_space_mb: int public_watch_limit: int member_watch_limit: int - - + max_watch_expiration_ms: int @dataclass class VeilidConfigTLS(ConfigBase): diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 9973a4a1..03fc4423 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -111,6 +111,7 @@ core: remote_max_storage_space_mb: 0 public_watch_limit: 32 member_watch_limit: 8 + max_watch_expiration_ms: 600000 upnp: true detect_address_changes: true restricted_nat_retries: 0 @@ -566,6 +567,7 @@ pub struct Dht { pub remote_max_storage_space_mb: u32, pub public_watch_limit: u32, pub member_watch_limit: u32, + pub max_watch_expiration_ms: u32, } #[derive(Debug, Deserialize, Serialize)] @@ -954,6 +956,7 @@ impl Settings { set_config_value!(inner.core.network.dht.remote_max_storage_space_mb, value); set_config_value!(inner.core.network.dht.public_watch_limit, value); set_config_value!(inner.core.network.dht.member_watch_limit, value); + set_config_value!(inner.core.network.dht.max_watch_expiration_ms, value); set_config_value!(inner.core.network.upnp, value); set_config_value!(inner.core.network.detect_address_changes, value); set_config_value!(inner.core.network.restricted_nat_retries, value); @@ -1201,6 +1204,9 @@ impl Settings { "network.dht.member_watch_limit" => { Ok(Box::new(inner.core.network.dht.member_watch_limit)) } + "network.dht.max_watch_expiration_ms" => { + Ok(Box::new(inner.core.network.dht.max_watch_expiration_ms)) + } "network.upnp" => Ok(Box::new(inner.core.network.upnp)), "network.detect_address_changes" => { Ok(Box::new(inner.core.network.detect_address_changes)) @@ -1526,6 +1532,9 @@ mod tests { s.core.network.dht.validate_dial_info_receipt_time_ms, 2_000u32 ); + assert_eq!(s.core.network.dht.public_watch_limit, 32u32); + assert_eq!(s.core.network.dht.member_watch_limit, 8u32); + assert_eq!(s.core.network.dht.max_watch_expiration_ms, 600_000u32); // assert!(s.core.network.upnp); assert!(s.core.network.detect_address_changes); From d1dad8de610b27b74aba7e8f05985473e00f8f0b Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 26 Nov 2023 15:02:15 -0800 Subject: [PATCH 10/67] checkpoint --- veilid-core/Cargo.toml | 2 +- .../src/rpc_processor/rpc_watch_value.rs | 2 +- veilid-core/src/storage_manager/mod.rs | 5 + .../src/storage_manager/record_store.rs | 116 +++++++++++++++--- .../storage_manager/storage_manager_inner.rs | 4 +- .../tasks/flush_record_stores.rs | 6 +- veilid-core/src/storage_manager/tasks/mod.rs | 46 +++++-- .../tasks/send_value_changes.rs | 50 ++++++++ .../src/storage_manager/types/record.rs | 6 +- .../src/storage_manager/types/record_data.rs | 10 +- veilid-core/src/veilid_api/tests/fixtures.rs | 1 + 11 files changed, 211 insertions(+), 37 deletions(-) create mode 100644 veilid-core/src/storage_manager/tasks/send_value_changes.rs diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index c12abb15..79e9bcab 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -129,7 +129,7 @@ enum-as-inner = "=0.6.0" # temporary fix for # Serialization capnp = { version = "0.18.1", default-features = false, features = ["alloc"] } -serde = { version = "1.0.188", features = ["derive"] } +serde = { version = "1.0.188", features = ["derive", "rc"] } serde_json = { version = "1.0.107" } serde-big-array = "0.5.1" json = "0.12.4" diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 0c619055..2ef35d6c 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -174,7 +174,7 @@ impl RPCProcessor { }; // Destructure - let (key, subkeys, expiration, count, watcher, signature) = watch_value_q.destructure(); + let (key, subkeys, expiration, count, watcher, _signature) = watch_value_q.destructure(); // Get target for ValueChanged notifications let dest = network_result_try!(self.get_respond_to_destination(&msg)); diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index e1082d5f..a048f204 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -31,6 +31,8 @@ const MAX_RECORD_DATA_SIZE: usize = 1_048_576; const FLUSH_RECORD_STORES_INTERVAL_SECS: u32 = 1; /// Frequency to check for offline subkeys writes to send to the network const OFFLINE_SUBKEY_WRITES_INTERVAL_SECS: u32 = 1; +/// Frequency to send ValueChanged notifications to the network +const SEND_VALUE_CHANGES_INTERVAL_SECS: u32 = 1; struct StorageManagerUnlockedInner { config: VeilidConfig, @@ -42,6 +44,7 @@ struct StorageManagerUnlockedInner { // Background processes flush_record_stores_task: TickTask, offline_subkey_writes_task: TickTask, + send_value_changes_task: TickTask, // Anonymous watch keys anonymous_watch_keys: TypedKeyPairGroup, @@ -76,6 +79,8 @@ impl StorageManager { block_store, flush_record_stores_task: TickTask::new(FLUSH_RECORD_STORES_INTERVAL_SECS), offline_subkey_writes_task: TickTask::new(OFFLINE_SUBKEY_WRITES_INTERVAL_SECS), + send_value_changes_task: TickTask::new(SEND_VALUE_CHANGES_INTERVAL_SECS), + anonymous_watch_keys, } } diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index 245d7642..c415e589 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -30,6 +30,7 @@ struct WatchedRecordWatch { count: u32, target: Target, watcher: CryptoKey, + changed: ValueSubkeyRangeSet, } #[derive(Debug, Default, Clone)] @@ -39,6 +40,16 @@ struct WatchedRecord { watchers: Vec, } +#[derive(Debug, Clone)] +/// A single 'value changed' message to send +pub struct ValueChangedInfo { + target: Target, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + count: u32, + value: SignedValueData, +} + pub struct RecordStore where D: fmt::Debug + Clone + Serialize + for<'d> Deserialize<'d>, @@ -65,6 +76,8 @@ where changed_records: HashSet, /// The list of records being watched for changes watched_records: HashMap, + /// The list of watched records that have changed values since last notification + changed_watched_values: HashSet, /// A mutex to ensure we handle this concurrently purge_dead_records_mutex: Arc>, @@ -74,9 +87,9 @@ where #[derive(Default, Debug)] pub struct SubkeyResult { /// The subkey value if we got one - pub value: Option, + pub value: Option>, /// The descriptor if we got a fresh one or empty if no descriptor was needed - pub descriptor: Option, + pub descriptor: Option>, } impl RecordStore @@ -114,6 +127,7 @@ where changed_records: HashSet::new(), watched_records: HashMap::new(), purge_dead_records_mutex: Arc::new(AsyncMutex::new(())), + changed_watched_values: HashSet::new(), } } @@ -194,10 +208,6 @@ where }); } - fn mark_record_changed(&mut self, key: RecordTableKey) { - self.changed_records.insert(key); - } - fn add_to_subkey_cache(&mut self, key: SubkeyTableKey, record_data: RecordData) { let record_data_total_size = record_data.total_size(); // Write to subkey cache @@ -312,7 +322,6 @@ where } async fn flush_changed_records(&mut self) { - // touch records if self.changed_records.is_empty() { return; } @@ -334,7 +343,7 @@ where } } - pub async fn tick(&mut self) -> EyreResult<()> { + pub async fn flush(&mut self) -> EyreResult<()> { self.flush_changed_records().await; self.purge_dead_records(true).await; Ok(()) @@ -416,7 +425,9 @@ where record.touch(get_aligned_timestamp()); } if out.is_some() { - self.mark_record_changed(rtk); + // Marks as changed because the record was touched and we want to keep the + // LRU ordering serialized + self.changed_records.insert(rtk); } out @@ -451,16 +462,14 @@ where record.touch(get_aligned_timestamp()); } if out.is_some() { - self.mark_record_changed(rtk); + // Marks as changed because the record was touched and we want to keep the + // LRU ordering serialized + self.changed_records.insert(rtk); } out } - // pub fn get_descriptor(&mut self, key: TypedKey) -> Option { - // self.with_record(key, |record| record.descriptor().clone()) - // } - pub async fn get_subkey( &mut self, key: TypedKey, @@ -600,6 +609,24 @@ where })) } + async fn update_watched_value(&mut self, key: TypedKey, subkey: ValueSubkey) { + let rtk = RecordTableKey { key }; + let Some(wr) = self.watched_records.get_mut(&rtk) else { + return; + }; + // Update all watchers + let mut changed = false; + for w in &mut wr.watchers { + // If this watcher is watching the changed subkey then add to the watcher's changed list + if w.subkeys.contains(subkey) && w.changed.insert(subkey) { + changed = true; + } + } + if changed { + self.changed_watched_values.insert(rtk); + } + } + pub async fn set_subkey( &mut self, key: TypedKey, @@ -692,6 +719,9 @@ where // Update storage space self.total_storage_space.commit().unwrap(); + // Update watched value + self.update_watched_value(key, subkey).await; + Ok(()) } @@ -719,7 +749,7 @@ where } // Get the record being watched - let Some(is_member) = self.with_record_mut(key, |record| { + let Some(is_member) = self.with_record(key, |record| { // Check if the watcher specified is a schema member let schema = record.schema(); (*record.owner()) == watcher || schema.is_member(&watcher) @@ -774,6 +804,7 @@ where count, target, watcher, + changed: ValueSubkeyRangeSet::new(), }); Ok(Some(expiration)) } @@ -786,7 +817,7 @@ where watcher: CryptoKey, ) -> VeilidAPIResult> { // Get the record being watched - let Some(is_member) = self.with_record_mut(key, |record| { + let Some(is_member) = self.with_record(key, |record| { // Check if the watcher specified is a schema member let schema = record.schema(); (*record.owner()) == watcher || schema.is_member(&watcher) @@ -828,6 +859,59 @@ where Ok(ret_timestamp) } + pub async fn take_value_changes(&mut self, changes: &mut Vec) { + for rtk in self.changed_watched_values.drain() { + if let Some(watch) = self.watched_records.get_mut(&rtk) { + // Process watch notifications + let mut dead_watchers = vec![]; + for (wn, w) in watch.watchers.iter_mut().enumerate() { + // Get the subkeys that have changed + let subkeys = w.changed.clone(); + w.changed.clear(); + + // Reduce the count of changes sent + // if count goes to zero mark this watcher dead + w.count -= 1; + let count = w.count; + if count == 0 { + dead_watchers.push(wn); + } + + // Get the first subkey data + let Some(first_subkey) = subkeys.first() else { + log_stor!(error "first subkey should exist for value change notification"); + continue; + }; + let subkey_result = match self.get_subkey(rtk.key, first_subkey, false).await { + Ok(Some(skr)) => skr, + Ok(None) => { + log_stor!(error "subkey should have data for value change notification"); + continue; + } + Err(e) => { + log_stor!(error "error getting subkey data for value change notification: {}", e); + continue; + } + }; + let Some(value) = subkey_result.value else { + log_stor!(error "first subkey should have had value for value change notification"); + continue; + }; + + let vci = ValueChangedInfo { + target: w.target.clone(), + key: rtk.key, + subkeys, + count, + value, + }; + + changes.push(vci); + } + } + } + } + /// LRU out some records until we reclaim the amount of space requested /// This will force a garbage collection of the space immediately /// If zero is passed in here, a garbage collection will be performed of dead records diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index 03c192da..da9b76b2 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -136,12 +136,12 @@ impl StorageManagerInner { // Final flush on record stores if let Some(mut local_record_store) = self.local_record_store.take() { - if let Err(e) = local_record_store.tick().await { + if let Err(e) = local_record_store.flush().await { log_stor!(error "termination local record store tick failed: {}", e); } } if let Some(mut remote_record_store) = self.remote_record_store.take() { - if let Err(e) = remote_record_store.tick().await { + if let Err(e) = remote_record_store.flush().await { log_stor!(error "termination remote record store tick failed: {}", e); } } diff --git a/veilid-core/src/storage_manager/tasks/flush_record_stores.rs b/veilid-core/src/storage_manager/tasks/flush_record_stores.rs index c2fb1b0d..af76ef28 100644 --- a/veilid-core/src/storage_manager/tasks/flush_record_stores.rs +++ b/veilid-core/src/storage_manager/tasks/flush_record_stores.rs @@ -1,7 +1,7 @@ use super::*; impl StorageManager { - // Flush records stores to disk and remove dead records + // Flush records stores to disk and remove dead records and send watch notifications #[instrument(level = "trace", skip(self), err)] pub(crate) async fn flush_record_stores_task_routine( self, @@ -11,10 +11,10 @@ impl StorageManager { ) -> EyreResult<()> { let mut inner = self.inner.lock().await; if let Some(local_record_store) = &mut inner.local_record_store { - local_record_store.tick().await?; + local_record_store.flush().await?; } if let Some(remote_record_store) = &mut inner.remote_record_store { - remote_record_store.tick().await?; + remote_record_store.flush().await?; } Ok(()) } diff --git a/veilid-core/src/storage_manager/tasks/mod.rs b/veilid-core/src/storage_manager/tasks/mod.rs index 36171b80..ac8c52ca 100644 --- a/veilid-core/src/storage_manager/tasks/mod.rs +++ b/veilid-core/src/storage_manager/tasks/mod.rs @@ -1,5 +1,6 @@ pub mod flush_record_stores; pub mod offline_subkey_writes; +pub mod send_value_changes; use super::*; @@ -47,23 +48,54 @@ impl StorageManager { ) }); } + // Set send value changes tick task + debug!("starting send value changes task"); + { + let this = self.clone(); + self.unlocked_inner + .send_value_changes_task + .set_routine(move |s, l, t| { + Box::pin( + this.clone() + .send_value_changes_task_routine( + s, + Timestamp::new(l), + Timestamp::new(t), + ) + .instrument(trace_span!( + parent: None, + "StorageManager send value changes task routine" + )), + ) + }); + } } pub async fn tick(&self) -> EyreResult<()> { - // Run the rolling transfers task + // Run the flush stores task self.unlocked_inner.flush_record_stores_task.tick().await?; - // Run offline subkey writes task if there's work to be done - if self.online_writes_ready().await?.is_some() && self.has_offline_subkey_writes().await? { - self.unlocked_inner - .offline_subkey_writes_task - .tick() - .await?; + // Run online-only tasks + if self.online_writes_ready().await?.is_some() { + // Run offline subkey writes task if there's work to be done + if self.has_offline_subkey_writes().await? { + self.unlocked_inner + .offline_subkey_writes_task + .tick() + .await?; + } + + // Send value changed notifications + self.unlocked_inner.send_value_changes_task.tick().await?; } Ok(()) } pub(crate) async fn cancel_tasks(&self) { + debug!("stopping send value changes task"); + if let Err(e) = self.unlocked_inner.send_value_changes_task.stop().await { + warn!("send_value_changes_task not stopped: {}", e); + } debug!("stopping flush record stores task"); if let Err(e) = self.unlocked_inner.flush_record_stores_task.stop().await { warn!("flush_record_stores_task not stopped: {}", e); diff --git a/veilid-core/src/storage_manager/tasks/send_value_changes.rs b/veilid-core/src/storage_manager/tasks/send_value_changes.rs new file mode 100644 index 00000000..a9bbd75a --- /dev/null +++ b/veilid-core/src/storage_manager/tasks/send_value_changes.rs @@ -0,0 +1,50 @@ +use super::*; +use futures_util::StreamExt; +use stop_token::future::FutureExt; + +impl StorageManager { + // Flush records stores to disk and remove dead records and send watch notifications + #[instrument(level = "trace", skip(self), err)] + pub(crate) async fn send_value_changes_task_routine( + self, + stop_token: StopToken, + _last_ts: Timestamp, + _cur_ts: Timestamp, + ) -> EyreResult<()> { + let mut value_changes: Vec = vec![]; + + let mut inner = self.inner.lock().await; + if let Some(local_record_store) = &mut inner.local_record_store { + local_record_store + .take_value_changes(&mut value_changes) + .await?; + } + if let Some(remote_record_store) = &mut inner.remote_record_store { + remote_record_store + .take_value_changes(&mut value_changes) + .await?; + } + + // Send all value changes in parallel + let mut unord = FuturesUnordered::new(); + + // xxx + + while !unord.is_empty() { + match unord.next().timeout_at(stop_token.clone()).await { + Ok(Some(_)) => { + // Some ValueChanged completed + } + Ok(None) => { + // We're empty + } + Err(_) => { + // Timeout means we drop the rest because we were asked to stop + return Ok(()); + } + } + } + + Ok(()) + } +} diff --git a/veilid-core/src/storage_manager/types/record.rs b/veilid-core/src/storage_manager/types/record.rs index 21d5cd79..d680dd7a 100644 --- a/veilid-core/src/storage_manager/types/record.rs +++ b/veilid-core/src/storage_manager/types/record.rs @@ -1,9 +1,9 @@ use super::*; -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct Record where - D: fmt::Debug + Clone + Serialize, + D: fmt::Debug + Serialize, { descriptor: SignedValueDescriptor, subkey_count: usize, @@ -15,7 +15,7 @@ where impl Record where - D: fmt::Debug + Clone + Serialize, + D: fmt::Debug + Serialize, { pub fn new( cur_ts: Timestamp, diff --git a/veilid-core/src/storage_manager/types/record_data.rs b/veilid-core/src/storage_manager/types/record_data.rs index 8b646c7a..5f84e7bb 100644 --- a/veilid-core/src/storage_manager/types/record_data.rs +++ b/veilid-core/src/storage_manager/types/record_data.rs @@ -2,15 +2,17 @@ use super::*; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct RecordData { - signed_value_data: SignedValueData, + signed_value_data: Arc, } +xxx continue here, use arc everywhere to avoid copies + impl RecordData { - pub fn new(signed_value_data: SignedValueData) -> Self { + pub fn new(signed_value_data: Arc) -> Self { Self { signed_value_data } } - pub fn signed_value_data(&self) -> &SignedValueData { - &self.signed_value_data + pub fn signed_value_data(&self) -> Arc { + self.signed_value_data.clone() } pub fn data_size(&self) -> usize { self.signed_value_data.data_size() diff --git a/veilid-core/src/veilid_api/tests/fixtures.rs b/veilid-core/src/veilid_api/tests/fixtures.rs index 44540407..1330ac3e 100644 --- a/veilid-core/src/veilid_api/tests/fixtures.rs +++ b/veilid-core/src/veilid_api/tests/fixtures.rs @@ -146,6 +146,7 @@ pub fn fix_veilidconfiginner() -> VeilidConfigInner { remote_max_storage_space_mb: 19, public_watch_limit: 20, member_watch_limit: 21, + max_watch_expiration_ms: 22, }, upnp: true, detect_address_changes: false, From a67bfde1f786ecc6936217c761ec22dfea4ec101 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Mon, 4 Dec 2023 22:01:50 -0500 Subject: [PATCH 11/67] send valuechanged --- veilid-core/src/core_context.rs | 4 +- veilid-core/src/rpc_processor/destination.rs | 3 +- veilid-core/src/rpc_processor/rpc_app_call.rs | 2 +- .../src/rpc_processor/rpc_find_node.rs | 2 +- .../src/rpc_processor/rpc_get_value.rs | 6 +- .../src/rpc_processor/rpc_set_value.rs | 6 +- veilid-core/src/rpc_processor/rpc_status.rs | 2 +- .../src/rpc_processor/rpc_value_changed.rs | 2 +- .../src/rpc_processor/rpc_watch_value.rs | 2 +- veilid-core/src/storage_manager/get_value.rs | 16 +-- veilid-core/src/storage_manager/mod.rs | 55 +++++++++-- .../src/storage_manager/record_store.rs | 98 ++++++++++--------- veilid-core/src/storage_manager/set_value.rs | 24 ++--- .../storage_manager/storage_manager_inner.rs | 42 +++++--- .../tasks/send_value_changes.rs | 35 ++++--- .../types/local_record_detail.rs | 2 +- veilid-core/src/storage_manager/types/mod.rs | 10 +- .../storage_manager/types/opened_record.rs | 4 +- .../src/storage_manager/types/record.rs | 16 +-- .../src/storage_manager/types/record_data.rs | 4 +- .../types/remote_record_detail.rs | 2 +- .../types/signed_value_data.rs | 4 - .../src/storage_manager/watch_value.rs | 31 +++++- veilid-core/src/veilid_api/routing_context.rs | 6 +- veilid-core/src/veilid_api/tests/fixtures.rs | 2 +- .../src/veilid_api/types/dht/schema/dflt.rs | 2 +- .../types/dht/value_subkey_range_set.rs | 14 +-- .../src/veilid_api/types/veilid_state.rs | 2 +- veilid-flutter/example/pubspec.lock | 26 ++--- veilid-tools/src/tick_task.rs | 28 +++++- 30 files changed, 277 insertions(+), 175 deletions(-) diff --git a/veilid-core/src/core_context.rs b/veilid-core/src/core_context.rs index c77bed93..1dc4dc22 100644 --- a/veilid-core/src/core_context.rs +++ b/veilid-core/src/core_context.rs @@ -120,6 +120,8 @@ impl ServicesContext { // Set up storage manager trace!("init storage manager"); + let update_callback = self.update_callback.clone(); + let storage_manager = StorageManager::new( self.config.clone(), self.crypto.clone().unwrap(), @@ -127,7 +129,7 @@ impl ServicesContext { #[cfg(feature = "unstable-blockstore")] self.block_store.clone().unwrap(), ); - if let Err(e) = storage_manager.init().await { + if let Err(e) = storage_manager.init(update_callback).await { error!("failed to init storage manager: {}", e); self.shutdown().await; return Err(e); diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 42e9a3cb..13f40a63 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -183,7 +183,6 @@ impl RPCProcessor { &self, target: Target, safety_selection: SafetySelection, - sequencing: Sequencing, ) -> Result { match target { Target::NodeId(node_id) => { @@ -195,7 +194,7 @@ impl RPCProcessor { } }; // Apply sequencing to match safety selection - nr.set_sequencing(sequencing); + nr.set_sequencing(safety_selection.get_sequencing()); Ok(rpc_processor::Destination::Direct { node: nr, diff --git a/veilid-core/src/rpc_processor/rpc_app_call.rs b/veilid-core/src/rpc_processor/rpc_app_call.rs index f82588ac..925516ff 100644 --- a/veilid-core/src/rpc_processor/rpc_app_call.rs +++ b/veilid-core/src/rpc_processor/rpc_app_call.rs @@ -24,7 +24,7 @@ impl RPCProcessor { let waitable_reply = network_result_try!(self.question(dest, question, None).await?); // Keep the reply private route that was used to return with the answer - let reply_private_route = waitable_reply.reply_private_route.clone(); + let reply_private_route = waitable_reply.reply_private_route; // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { diff --git a/veilid-core/src/rpc_processor/rpc_find_node.rs b/veilid-core/src/rpc_processor/rpc_find_node.rs index 3db9e39e..3eeeea34 100644 --- a/veilid-core/src/rpc_processor/rpc_find_node.rs +++ b/veilid-core/src/rpc_processor/rpc_find_node.rs @@ -44,7 +44,7 @@ impl RPCProcessor { let waitable_reply = network_result_try!(self.question(dest, find_node_q, None).await?); // Keep the reply private route that was used to return with the answer - let reply_private_route = waitable_reply.reply_private_route.clone(); + let reply_private_route = waitable_reply.reply_private_route; // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index f8832772..679f0423 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -83,7 +83,7 @@ impl RPCProcessor { ); // Keep the reply private route that was used to return with the answer - let reply_private_route = waitable_reply.reply_private_route.clone(); + let reply_private_route = waitable_reply.reply_private_route; // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { @@ -279,9 +279,9 @@ impl RPCProcessor { // Make GetValue answer let get_value_a = RPCOperationGetValueA::new( - subkey_result_value, + subkey_result_value.map(|x| (*x).clone()), closer_to_key_peers, - subkey_result_descriptor, + subkey_result_descriptor.map(|x| (*x).clone()), )?; // Send GetValue answer diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index 5c9201ab..a3bc6d67 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -97,7 +97,7 @@ impl RPCProcessor { ); // Keep the reply private route that was used to return with the answer - let reply_private_route = waitable_reply.reply_private_route.clone(); + let reply_private_route = waitable_reply.reply_private_route; // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { @@ -257,7 +257,7 @@ impl RPCProcessor { // Save the subkey, creating a new record if necessary let storage_manager = self.storage_manager(); let new_value = network_result_try!(storage_manager - .inbound_set_value(key, subkey, value, descriptor) + .inbound_set_value(key, subkey, Arc::new(value), descriptor.map(Arc::new)) .await .map_err(RPCError::internal)?); @@ -292,7 +292,7 @@ impl RPCProcessor { } // Make SetValue answer - let set_value_a = RPCOperationSetValueA::new(set, new_value, closer_to_key_peers)?; + let set_value_a = RPCOperationSetValueA::new(set, new_value.map(|x| (*x).clone()), closer_to_key_peers)?; // Send SetValue answer self.answer(msg, RPCAnswer::new(RPCAnswerDetail::SetValueA(Box::new(set_value_a)))) diff --git a/veilid-core/src/rpc_processor/rpc_status.rs b/veilid-core/src/rpc_processor/rpc_status.rs index e8b48975..9a203cb9 100644 --- a/veilid-core/src/rpc_processor/rpc_status.rs +++ b/veilid-core/src/rpc_processor/rpc_status.rs @@ -114,7 +114,7 @@ impl RPCProcessor { let send_data_method = waitable_reply.send_data_method.clone(); // Keep the reply private route that was used to return with the answer - let reply_private_route = waitable_reply.reply_private_route.clone(); + let reply_private_route = waitable_reply.reply_private_route; // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { diff --git a/veilid-core/src/rpc_processor/rpc_value_changed.rs b/veilid-core/src/rpc_processor/rpc_value_changed.rs index 18b31c36..555dd104 100644 --- a/veilid-core/src/rpc_processor/rpc_value_changed.rs +++ b/veilid-core/src/rpc_processor/rpc_value_changed.rs @@ -59,7 +59,7 @@ impl RPCProcessor { // Save the subkey, creating a new record if necessary let storage_manager = self.storage_manager(); storage_manager - .inbound_value_changed(key, subkeys, count, value) + .inbound_value_changed(key, subkeys, count, Arc::new(value)) .await .map_err(RPCError::internal)?; diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 2ef35d6c..562cde83 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -73,7 +73,7 @@ impl RPCProcessor { network_result_try!(self.question(dest.clone(), question, None).await?); // Keep the reply private route that was used to return with the answer - let reply_private_route = waitable_reply.reply_private_route.clone(); + let reply_private_route = waitable_reply.reply_private_route; // Wait for reply let (msg, latency) = match self.wait_for_reply(waitable_reply, debug_string).await? { diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index 7917938b..e9bdad5a 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -3,17 +3,17 @@ use super::*; /// The context of the outbound_get_value operation struct OutboundGetValueContext { /// The latest value of the subkey, may be the value passed in - pub value: Option, + pub value: Option>, /// The nodes that have returned the value so far (up to the consensus count) pub value_nodes: Vec, /// The descriptor if we got a fresh one or empty if no descriptor was needed - pub descriptor: Option, + pub descriptor: Option>, /// The parsed schema from the descriptor if we have one pub schema: Option, } /// The result of the outbound_get_value operation -struct OutboundGetValueResult { +pub(super) struct OutboundGetValueResult { /// The subkey that was retrieved pub subkey_result: SubkeyResult, /// And where it was retrieved from @@ -22,7 +22,7 @@ struct OutboundGetValueResult { impl StorageManager { /// Perform a 'get value' query on the network - pub async fn outbound_get_value( + pub(super) async fn outbound_get_value( &self, rpc_processor: RPCProcessor, key: TypedKey, @@ -69,7 +69,7 @@ impl StorageManager { Destination::direct(next_node.clone()).with_safety(safety_selection), key, subkey, - last_descriptor, + last_descriptor.map(|x| (*x).clone()), ) .await? ); @@ -80,7 +80,7 @@ impl StorageManager { let mut ctx = context.lock(); if ctx.descriptor.is_none() && ctx.schema.is_none() { ctx.schema = Some(descriptor.schema().map_err(RPCError::invalid_format)?); - ctx.descriptor = Some(descriptor); + ctx.descriptor = Some(Arc::new(descriptor)); } } @@ -127,7 +127,7 @@ impl StorageManager { ctx.value_nodes.push(next_node); } else if new_seq > prior_seq { // If the sequence number is greater, start over with the new value - ctx.value = Some(value); + ctx.value = Some(Arc::new(value)); // One node has shown us this value so far ctx.value_nodes = vec![next_node]; } else { @@ -135,7 +135,7 @@ impl StorageManager { } } else { // If we have no prior value, keep it - ctx.value = Some(value); + ctx.value = Some(Arc::new(value)); // One node has shown us this value so far ctx.value_nodes = vec![next_node]; } diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index a048f204..bb65ebc9 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -34,6 +34,16 @@ const OFFLINE_SUBKEY_WRITES_INTERVAL_SECS: u32 = 1; /// Frequency to send ValueChanged notifications to the network const SEND_VALUE_CHANGES_INTERVAL_SECS: u32 = 1; +#[derive(Debug, Clone)] +/// A single 'value changed' message to send +struct ValueChangedInfo { + target: Target, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + count: u32, + value: Arc, +} + struct StorageManagerUnlockedInner { config: VeilidConfig, crypto: Crypto, @@ -112,11 +122,11 @@ impl StorageManager { } #[instrument(level = "debug", skip_all, err)] - pub async fn init(&self) -> EyreResult<()> { + pub async fn init(&self, update_callback: UpdateCallback) -> EyreResult<()> { debug!("startup storage manager"); let mut inner = self.inner.lock().await; - inner.init(self.clone()).await?; + inner.init(self.clone(), update_callback).await?; Ok(()) } @@ -347,7 +357,7 @@ impl StorageManager { // Return the existing value if we have one unless we are forcing a refresh if !force_refresh { if let Some(last_subkey_result_value) = last_subkey_result.value { - return Ok(Some(last_subkey_result_value.into_value_data())); + return Ok(Some(last_subkey_result_value.value_data().clone())); } } @@ -357,7 +367,7 @@ impl StorageManager { let Some(rpc_processor) = inner.rpc_processor.clone() else { // Return the existing value if we have one if we aren't online if let Some(last_subkey_result_value) = last_subkey_result.value { - return Ok(Some(last_subkey_result_value.into_value_data())); + return Ok(Some(last_subkey_result_value.value_data().clone())); } apibail_try_again!("offline, try again later"); }; @@ -397,7 +407,7 @@ impl StorageManager { .handle_set_local_value(key, subkey, subkey_result_value.clone()) .await?; } - Ok(Some(subkey_result_value.into_value_data())) + Ok(Some(subkey_result_value.value_data().clone())) } /// Set the value of a subkey on an opened local record @@ -460,13 +470,13 @@ impl StorageManager { } // Sign the new value data with the writer - let signed_value_data = SignedValueData::make_signature( + let signed_value_data = Arc::new(SignedValueData::make_signature( value_data, descriptor.owner(), subkey, vcrypto, writer.secret, - )?; + )?); // Get rpc processor and drop mutex so we don't block while getting the value from the network let Some(rpc_processor) = Self::online_writes_ready_inner(&inner) else { @@ -515,7 +525,7 @@ impl StorageManager { // Return the new value if it differs from what was asked to set if result.signed_value_data.value_data() != signed_value_data.value_data() { - return Ok(Some(result.signed_value_data.into_value_data())); + return Ok(Some(result.signed_value_data.value_data().clone())); } // If the original value was set, return None @@ -668,4 +678,33 @@ impl StorageManager { Ok(true) } + + // Send single value change out to the network + #[instrument(level = "trace", skip(self), err)] + async fn send_value_change(&self, vc: ValueChangedInfo) -> VeilidAPIResult<()> { + let rpc_processor = { + let inner = self.inner.lock().await; + if let Some(rpc_processor) = &inner.rpc_processor { + rpc_processor.clone() + } else { + apibail_try_again!("network is not available"); + } + }; + + let dest = rpc_processor + .resolve_target_to_destination( + vc.target, + SafetySelection::Unsafe(Sequencing::NoPreference), + ) + .await + .map_err(VeilidAPIError::from)?; + + network_result_value_or_log!(rpc_processor + .rpc_call_value_changed(dest, vc.key, vc.subkeys, vc.count, (*vc.value).clone()) + .await + .map_err(VeilidAPIError::from)? => [format!(": dest={:?} vc={:?}", dest, vc)] { + }); + + Ok(()) + } } diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index c415e589..a67b2ba1 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -40,17 +40,7 @@ struct WatchedRecord { watchers: Vec, } -#[derive(Debug, Clone)] -/// A single 'value changed' message to send -pub struct ValueChangedInfo { - target: Target, - key: TypedKey, - subkeys: ValueSubkeyRangeSet, - count: u32, - value: SignedValueData, -} - -pub struct RecordStore +pub(super) struct RecordStore where D: fmt::Debug + Clone + Serialize + for<'d> Deserialize<'d>, { @@ -631,7 +621,7 @@ where &mut self, key: TypedKey, subkey: ValueSubkey, - signed_value_data: SignedValueData, + signed_value_data: Arc, ) -> VeilidAPIResult<()> { // Check size limit for data if signed_value_data.value_data().data().len() > self.limits.max_subkey_size { @@ -847,7 +837,7 @@ where } if let Some(dw) = dead_watcher { watch.watchers.remove(dw); - if watch.watchers.len() == 0 { + if watch.watchers.is_empty() { is_empty = true; } } @@ -860,6 +850,16 @@ where } pub async fn take_value_changes(&mut self, changes: &mut Vec) { + // ValueChangedInfo but without the subkey data that requires a double mutable borrow to get + struct EarlyValueChangedInfo { + target: Target, + key: TypedKey, + subkeys: ValueSubkeyRangeSet, + count: u32, + } + + let mut evcis = vec![]; + for rtk in self.changed_watched_values.drain() { if let Some(watch) = self.watched_records.get_mut(&rtk) { // Process watch notifications @@ -877,39 +877,51 @@ where dead_watchers.push(wn); } - // Get the first subkey data - let Some(first_subkey) = subkeys.first() else { - log_stor!(error "first subkey should exist for value change notification"); - continue; - }; - let subkey_result = match self.get_subkey(rtk.key, first_subkey, false).await { - Ok(Some(skr)) => skr, - Ok(None) => { - log_stor!(error "subkey should have data for value change notification"); - continue; - } - Err(e) => { - log_stor!(error "error getting subkey data for value change notification: {}", e); - continue; - } - }; - let Some(value) = subkey_result.value else { - log_stor!(error "first subkey should have had value for value change notification"); - continue; - }; - - let vci = ValueChangedInfo { + evcis.push(EarlyValueChangedInfo { target: w.target.clone(), key: rtk.key, subkeys, count, - value, - }; + }); + } - changes.push(vci); + // Remove in reverse so we don't have to offset the index to remove the right key + for dw in dead_watchers.iter().rev().copied() { + watch.watchers.remove(dw); } } } + + for evci in evcis { + // Get the first subkey data + let Some(first_subkey) = evci.subkeys.first() else { + log_stor!(error "first subkey should exist for value change notification"); + continue; + }; + let subkey_result = match self.get_subkey(evci.key, first_subkey, false).await { + Ok(Some(skr)) => skr, + Ok(None) => { + log_stor!(error "subkey should have data for value change notification"); + continue; + } + Err(e) => { + log_stor!(error "error getting subkey data for value change notification: {}", e); + continue; + } + }; + let Some(value) = subkey_result.value else { + log_stor!(error "first subkey should have had value for value change notification"); + continue; + }; + + changes.push(ValueChangedInfo { + target: evci.target, + key: evci.key, + subkeys: evci.subkeys, + count: evci.count, + value, + }); + } } /// LRU out some records until we reclaim the amount of space requested @@ -931,7 +943,7 @@ where reclaimed } - pub(super) fn debug_records(&self) -> String { + pub fn debug_records(&self) -> String { // Dump fields in an abbreviated way let mut out = String::new(); @@ -963,16 +975,12 @@ where out } - pub(super) fn debug_record_info(&self, key: TypedKey) -> String { + pub fn debug_record_info(&self, key: TypedKey) -> String { self.peek_record(key, |r| format!("{:#?}", r)) .unwrap_or("Not found".to_owned()) } - pub(super) async fn debug_record_subkey_info( - &self, - key: TypedKey, - subkey: ValueSubkey, - ) -> String { + pub async fn debug_record_subkey_info(&self, key: TypedKey, subkey: ValueSubkey) -> String { match self.peek_subkey(key, subkey, true).await { Ok(Some(v)) => { format!("{:#?}", v) diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index ce9d6de1..cab6f225 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -3,7 +3,7 @@ use super::*; /// The context of the outbound_set_value operation struct OutboundSetValueContext { /// The latest value of the subkey, may be the value passed in - pub value: SignedValueData, + pub value: Arc, /// The nodes that have set the value so far (up to the consensus count) pub value_nodes: Vec, /// The number of non-sets since the last set we have received @@ -13,23 +13,23 @@ struct OutboundSetValueContext { } /// The result of the outbound_set_value operation -struct OutboundSetValueResult { +pub(super) struct OutboundSetValueResult { /// The value that was set - pub signed_value_data: SignedValueData, + pub signed_value_data: Arc, /// And where it was set to pub value_nodes: Vec, } impl StorageManager { /// Perform a 'set value' query on the network - pub async fn outbound_set_value( + pub(super) async fn outbound_set_value( &self, rpc_processor: RPCProcessor, key: TypedKey, subkey: ValueSubkey, safety_selection: SafetySelection, - value: SignedValueData, - descriptor: SignedValueDescriptor, + value: Arc, + descriptor: Arc, ) -> VeilidAPIResult { let routing_table = rpc_processor.routing_table(); @@ -75,8 +75,8 @@ impl StorageManager { Destination::direct(next_node.clone()).with_safety(safety_selection), key, subkey, - value, - descriptor.clone(), + (*value).clone(), + (*descriptor).clone(), send_descriptor, ) .await? @@ -105,7 +105,7 @@ impl StorageManager { let new_seq = value.value_data().seq(); if new_seq > prior_seq { // If the sequence number is greater, keep it - ctx.value = value; + ctx.value = Arc::new(value); // One node has shown us this value so far ctx.value_nodes = vec![next_node]; ctx.missed_since_last_set = 0; @@ -225,9 +225,9 @@ impl StorageManager { &self, key: TypedKey, subkey: ValueSubkey, - value: SignedValueData, - descriptor: Option, - ) -> VeilidAPIResult>> { + value: Arc, + descriptor: Option>, + ) -> VeilidAPIResult>>> { let mut inner = self.lock().await?; // See if this is a remote or local value diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index da9b76b2..ad872c4e 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -28,6 +28,8 @@ pub(super) struct StorageManagerInner { pub rpc_processor: Option, /// Background processing task (not part of attachment manager tick tree so it happens when detached too) pub tick_future: Option>, + /// Update callback to send ValueChanged notification to + pub update_callback: Option, } fn local_limits_from_config(config: VeilidConfig) -> RecordStoreLimits { @@ -78,10 +80,15 @@ impl StorageManagerInner { metadata_db: Default::default(), rpc_processor: Default::default(), tick_future: Default::default(), + update_callback: None, } } - pub async fn init(&mut self, outer_self: StorageManager) -> EyreResult<()> { + pub async fn init( + &mut self, + outer_self: StorageManager, + update_callback: UpdateCallback, + ) -> EyreResult<()> { let metadata_db = self .unlocked_inner .table_store @@ -121,13 +128,15 @@ impl StorageManagerInner { } }); self.tick_future = Some(tick_future); - + self.update_callback = Some(update_callback); self.initialized = true; Ok(()) } pub async fn terminate(&mut self) { + self.update_callback = None; + // Stop ticker let tick_future = self.tick_future.take(); if let Some(f) = tick_future { @@ -207,12 +216,12 @@ impl StorageManagerInner { let owner = vcrypto.generate_keypair(); // Make a signed value descriptor for this dht value - let signed_value_descriptor = SignedValueDescriptor::make_signature( + let signed_value_descriptor = Arc::new(SignedValueDescriptor::make_signature( owner.key, schema_data, vcrypto.clone(), owner.secret, - )?; + )?); // Add new local value record let cur_ts = get_aligned_timestamp(); @@ -428,11 +437,11 @@ impl StorageManagerInner { }; // Get routing table to see if we still know about these nodes - let Some(routing_table) = self.rpc_processor.map(|r| r.routing_table()) else { + let Some(routing_table) = self.rpc_processor.as_ref().map(|r| r.routing_table()) else { apibail_try_again!("offline, try again later"); }; - let opt_value_nodes = local_record_store.with_record(key, |r| { + let opt_value_nodes = local_record_store.peek_record(key, |r| { let d = r.detail(); d.value_nodes .iter() @@ -475,7 +484,7 @@ impl StorageManagerInner { Ok(opened_record) } - pub async fn handle_get_local_value( + pub(super) async fn handle_get_local_value( &mut self, key: TypedKey, subkey: ValueSubkey, @@ -498,11 +507,11 @@ impl StorageManagerInner { }) } - pub async fn handle_set_local_value( + pub(super) async fn handle_set_local_value( &mut self, key: TypedKey, subkey: ValueSubkey, - signed_value_data: SignedValueData, + signed_value_data: Arc, ) -> VeilidAPIResult<()> { // See if it's in the local record store let Some(local_record_store) = self.local_record_store.as_mut() else { @@ -517,7 +526,7 @@ impl StorageManagerInner { Ok(()) } - pub async fn handle_watch_local_value( + pub(super) async fn handle_watch_local_value( &mut self, key: TypedKey, subkeys: ValueSubkeyRangeSet, @@ -535,7 +544,7 @@ impl StorageManagerInner { .await } - pub async fn handle_get_remote_value( + pub(super) async fn handle_get_remote_value( &mut self, key: TypedKey, subkey: ValueSubkey, @@ -558,12 +567,12 @@ impl StorageManagerInner { }) } - pub async fn handle_set_remote_value( + pub(super) async fn handle_set_remote_value( &mut self, key: TypedKey, subkey: ValueSubkey, - signed_value_data: SignedValueData, - signed_value_descriptor: SignedValueDescriptor, + signed_value_data: Arc, + signed_value_descriptor: Arc, ) -> VeilidAPIResult<()> { // See if it's in the remote record store let Some(remote_record_store) = self.remote_record_store.as_mut() else { @@ -591,7 +600,7 @@ impl StorageManagerInner { Ok(()) } - pub async fn handle_watch_remote_value( + pub(super) async fn handle_watch_remote_value( &mut self, key: TypedKey, subkeys: ValueSubkeyRangeSet, @@ -614,7 +623,8 @@ impl StorageManagerInner { where D: fmt::Debug + Clone + Serialize, { - let compiled = record.descriptor().schema_data(); + let descriptor = record.descriptor(); + let compiled = descriptor.schema_data(); let mut hash_data = Vec::::with_capacity(PUBLIC_KEY_LENGTH + 4 + compiled.len()); hash_data.extend_from_slice(&vcrypto.kind().0); hash_data.extend_from_slice(&record.owner().bytes); diff --git a/veilid-core/src/storage_manager/tasks/send_value_changes.rs b/veilid-core/src/storage_manager/tasks/send_value_changes.rs index a9bbd75a..ed054c00 100644 --- a/veilid-core/src/storage_manager/tasks/send_value_changes.rs +++ b/veilid-core/src/storage_manager/tasks/send_value_changes.rs @@ -5,7 +5,7 @@ use stop_token::future::FutureExt; impl StorageManager { // Flush records stores to disk and remove dead records and send watch notifications #[instrument(level = "trace", skip(self), err)] - pub(crate) async fn send_value_changes_task_routine( + pub(super) async fn send_value_changes_task_routine( self, stop_token: StopToken, _last_ts: Timestamp, @@ -13,22 +13,31 @@ impl StorageManager { ) -> EyreResult<()> { let mut value_changes: Vec = vec![]; - let mut inner = self.inner.lock().await; - if let Some(local_record_store) = &mut inner.local_record_store { - local_record_store - .take_value_changes(&mut value_changes) - .await?; + { + let mut inner = self.inner.lock().await; + if let Some(local_record_store) = &mut inner.local_record_store { + local_record_store + .take_value_changes(&mut value_changes) + .await; + } + if let Some(remote_record_store) = &mut inner.remote_record_store { + remote_record_store + .take_value_changes(&mut value_changes) + .await; + } } - if let Some(remote_record_store) = &mut inner.remote_record_store { - remote_record_store - .take_value_changes(&mut value_changes) - .await?; - } - // Send all value changes in parallel let mut unord = FuturesUnordered::new(); - // xxx + // Add a future for each value change + for vc in value_changes { + let this = self.clone(); + unord.push(async move { + if let Err(e) = this.send_value_change(vc).await { + log_stor!(debug "Failed to send value change: {}", e); + } + }); + } while !unord.is_empty() { match unord.next().timeout_at(stop_token.clone()).await { diff --git a/veilid-core/src/storage_manager/types/local_record_detail.rs b/veilid-core/src/storage_manager/types/local_record_detail.rs index 50987428..f456f38f 100644 --- a/veilid-core/src/storage_manager/types/local_record_detail.rs +++ b/veilid-core/src/storage_manager/types/local_record_detail.rs @@ -2,7 +2,7 @@ use super::*; /// Information required to handle locally opened records #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct LocalRecordDetail { +pub(in crate::storage_manager) struct LocalRecordDetail { /// The last 'safety selection' used when creating/opening this record. /// Even when closed, this safety selection applies to re-publication attempts by the system. pub safety_selection: SafetySelection, diff --git a/veilid-core/src/storage_manager/types/mod.rs b/veilid-core/src/storage_manager/types/mod.rs index a295241b..71c1e84c 100644 --- a/veilid-core/src/storage_manager/types/mod.rs +++ b/veilid-core/src/storage_manager/types/mod.rs @@ -8,10 +8,10 @@ mod signed_value_descriptor; use super::*; -pub use local_record_detail::*; -pub use opened_record::*; -pub use record::*; -pub use record_data::*; -pub use remote_record_detail::*; +pub(super) use local_record_detail::*; +pub(super) use opened_record::*; +pub(super) use record::*; +pub(super) use record_data::*; +pub(super) use remote_record_detail::*; pub use signed_value_data::*; pub use signed_value_descriptor::*; diff --git a/veilid-core/src/storage_manager/types/opened_record.rs b/veilid-core/src/storage_manager/types/opened_record.rs index e2a0a4a4..831b74fc 100644 --- a/veilid-core/src/storage_manager/types/opened_record.rs +++ b/veilid-core/src/storage_manager/types/opened_record.rs @@ -1,7 +1,7 @@ use super::*; #[derive(Clone, Debug)] -pub struct ActiveWatch { +pub(in crate::storage_manager) struct ActiveWatch { /// The expiration of a successful watch pub expiration_ts: Timestamp, /// Which node accepted the watch @@ -17,7 +17,7 @@ pub struct ActiveWatch { /// The state associated with a local record when it is opened /// This is not serialized to storage as it is ephemeral for the lifetime of the opened record #[derive(Clone, Debug, Default)] -pub struct OpenedRecord { +pub(in crate::storage_manager) struct OpenedRecord { /// The key pair used to perform writes to subkey on this opened record /// Without this, set_value() will fail regardless of which key or subkey is being written to /// as all writes are signed diff --git a/veilid-core/src/storage_manager/types/record.rs b/veilid-core/src/storage_manager/types/record.rs index d680dd7a..8dc78bb1 100644 --- a/veilid-core/src/storage_manager/types/record.rs +++ b/veilid-core/src/storage_manager/types/record.rs @@ -1,11 +1,11 @@ use super::*; -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct Record +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub(in crate::storage_manager) struct Record where - D: fmt::Debug + Serialize, + D: fmt::Debug + Serialize + Clone, { - descriptor: SignedValueDescriptor, + descriptor: Arc, subkey_count: usize, stored_subkeys: ValueSubkeyRangeSet, last_touched_ts: Timestamp, @@ -15,11 +15,11 @@ where impl Record where - D: fmt::Debug + Serialize, + D: fmt::Debug + Serialize + Clone, { pub fn new( cur_ts: Timestamp, - descriptor: SignedValueDescriptor, + descriptor: Arc, detail: D, ) -> VeilidAPIResult { let schema = descriptor.schema()?; @@ -34,8 +34,8 @@ where }) } - pub fn descriptor(&self) -> &SignedValueDescriptor { - &self.descriptor + pub fn descriptor(&self) -> Arc { + self.descriptor.clone() } pub fn owner(&self) -> &PublicKey { self.descriptor.owner() diff --git a/veilid-core/src/storage_manager/types/record_data.rs b/veilid-core/src/storage_manager/types/record_data.rs index 5f84e7bb..86c9f9b7 100644 --- a/veilid-core/src/storage_manager/types/record_data.rs +++ b/veilid-core/src/storage_manager/types/record_data.rs @@ -1,12 +1,10 @@ use super::*; #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] -pub struct RecordData { +pub(in crate::storage_manager) struct RecordData { signed_value_data: Arc, } -xxx continue here, use arc everywhere to avoid copies - impl RecordData { pub fn new(signed_value_data: Arc) -> Self { Self { signed_value_data } diff --git a/veilid-core/src/storage_manager/types/remote_record_detail.rs b/veilid-core/src/storage_manager/types/remote_record_detail.rs index f17a474d..c1bb5b3e 100644 --- a/veilid-core/src/storage_manager/types/remote_record_detail.rs +++ b/veilid-core/src/storage_manager/types/remote_record_detail.rs @@ -1,4 +1,4 @@ use super::*; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct RemoteRecordDetail {} +pub(in crate::storage_manager) struct RemoteRecordDetail {} diff --git a/veilid-core/src/storage_manager/types/signed_value_data.rs b/veilid-core/src/storage_manager/types/signed_value_data.rs index 8a8fb0d5..ed766389 100644 --- a/veilid-core/src/storage_manager/types/signed_value_data.rs +++ b/veilid-core/src/storage_manager/types/signed_value_data.rs @@ -48,10 +48,6 @@ impl SignedValueData { &self.value_data } - pub fn into_value_data(self) -> ValueData { - self.value_data - } - pub fn signature(&self) -> &Signature { &self.signature } diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index 9eabe7bc..a65ad547 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -8,7 +8,7 @@ struct OutboundWatchValueContext { /// The result of the outbound_watch_value operation #[derive(Debug, Clone)] -struct OutboundWatchValueResult { +pub(super) struct OutboundWatchValueResult { /// The expiration of a successful watch pub expiration_ts: Timestamp, /// Which node accepted the watch @@ -19,7 +19,8 @@ struct OutboundWatchValueResult { impl StorageManager { /// Perform a 'watch value' query on the network - pub async fn outbound_watch_value( + #[allow(clippy::too_many_arguments)] + pub(super) async fn outbound_watch_value( &self, rpc_processor: RPCProcessor, key: TypedKey, @@ -219,8 +220,30 @@ impl StorageManager { key: TypedKey, subkeys: ValueSubkeyRangeSet, count: u32, - value: SignedValueData, + value: Arc, ) -> VeilidAPIResult<()> { - // + // Update local record store with new value + let (res, opt_update_callback) = { + let mut inner = self.lock().await?; + + let res = if let Some(first_subkey) = subkeys.first() { + inner + .handle_set_local_value(key, first_subkey, value.clone()) + .await + } else { + VeilidAPIResult::Ok(()) + }; + (res, inner.update_callback.clone()) + }; + // Announce ValueChanged VeilidUpdate + if let Some(update_callback) = opt_update_callback { + update_callback(VeilidUpdate::ValueChange(Box::new(VeilidValueChange { + key, + subkeys, + count, + value: value.value_data().clone(), + }))); + } + res } } diff --git a/veilid-core/src/veilid_api/routing_context.rs b/veilid-core/src/veilid_api/routing_context.rs index a1373b82..59ca2a46 100644 --- a/veilid-core/src/veilid_api/routing_context.rs +++ b/veilid-core/src/veilid_api/routing_context.rs @@ -123,11 +123,7 @@ impl RoutingContext { async fn get_destination(&self, target: Target) -> VeilidAPIResult { let rpc_processor = self.api.rpc_processor()?; rpc_processor - .resolve_target_to_destination( - target, - self.unlocked_inner.safety_selection, - self.sequencing(), - ) + .resolve_target_to_destination(target, self.unlocked_inner.safety_selection) .await .map_err(VeilidAPIError::invalid_target) } diff --git a/veilid-core/src/veilid_api/tests/fixtures.rs b/veilid-core/src/veilid_api/tests/fixtures.rs index 1330ac3e..c85e5109 100644 --- a/veilid-core/src/veilid_api/tests/fixtures.rs +++ b/veilid-core/src/veilid_api/tests/fixtures.rs @@ -208,7 +208,7 @@ pub fn fix_veilidconfiginner() -> VeilidConfigInner { pub fn fix_veilidvaluechange() -> VeilidValueChange { VeilidValueChange { key: fix_typedkey(), - subkeys: vec![1, 2, 3, 4], + subkeys: ValueSubkeyRangeSet::new(), count: 5, value: ValueData::new_with_seq(23, b"ValueData".to_vec(), fix_cryptokey()).unwrap(), } diff --git a/veilid-core/src/veilid_api/types/dht/schema/dflt.rs b/veilid-core/src/veilid_api/types/dht/schema/dflt.rs index 9ff10b8e..25c5bf9b 100644 --- a/veilid-core/src/veilid_api/types/dht/schema/dflt.rs +++ b/veilid-core/src/veilid_api/types/dht/schema/dflt.rs @@ -55,7 +55,7 @@ impl DHTSchemaDFLT { } /// Check if a key is a schema member - pub fn is_member(&self, key: &PublicKey) -> bool { + pub fn is_member(&self, _key: &PublicKey) -> bool { false } } diff --git a/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs b/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs index 62d75fd9..c769826a 100644 --- a/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs +++ b/veilid-core/src/veilid_api/types/dht/value_subkey_range_set.rs @@ -30,21 +30,21 @@ impl ValueSubkeyRangeSet { Self { data } } - pub fn interset(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { - Self::new_with_data(self.data & other.data) + pub fn intersect(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { + Self::new_with_data(&self.data & &other.data) } pub fn difference(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { - Self::new_with_data(self.data - other.data) + Self::new_with_data(&self.data - &other.data) } pub fn union(&self, other: &ValueSubkeyRangeSet) -> ValueSubkeyRangeSet { - Self::new_with_data(self.data | other.data) + Self::new_with_data(&self.data | &other.data) } - pub fn data(&self) -> RangeSetBlaze { - self.data().clone() + pub fn data(&self) -> &RangeSetBlaze { + &self.data } pub fn into_data(self) -> RangeSetBlaze { - self.data() + self.data } } diff --git a/veilid-core/src/veilid_api/types/veilid_state.rs b/veilid-core/src/veilid_api/types/veilid_state.rs index 4f2d441d..b6947690 100644 --- a/veilid-core/src/veilid_api/types/veilid_state.rs +++ b/veilid-core/src/veilid_api/types/veilid_state.rs @@ -99,7 +99,7 @@ pub struct VeilidStateConfig { pub struct VeilidValueChange { #[schemars(with = "String")] pub key: TypedKey, - pub subkeys: Vec, + pub subkeys: ValueSubkeyRangeSet, pub count: u32, pub value: ValueData, } diff --git a/veilid-flutter/example/pubspec.lock b/veilid-flutter/example/pubspec.lock index 73fc4fc6..28671d7b 100644 --- a/veilid-flutter/example/pubspec.lock +++ b/veilid-flutter/example/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" convert: dependency: transitive description: @@ -220,10 +220,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" path: dependency: "direct main" description: @@ -329,18 +329,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -377,10 +377,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" typed_data: dependency: transitive description: @@ -408,10 +408,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" win32: dependency: transitive description: @@ -437,5 +437,5 @@ packages: source: hosted version: "3.5.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0-194.0.dev <4.0.0" flutter: ">=3.10.6" diff --git a/veilid-tools/src/tick_task.rs b/veilid-tools/src/tick_task.rs index 1d6bc5d7..4c2b5a5a 100644 --- a/veilid-tools/src/tick_task.rs +++ b/veilid-tools/src/tick_task.rs @@ -61,6 +61,17 @@ impl TickTask { self.running.load(core::sync::atomic::Ordering::Acquire) } + pub fn last_timestamp_us(&self) -> Option { + let ts = self + .last_timestamp_us + .load(core::sync::atomic::Ordering::Acquire); + if ts == 0 { + None + } else { + Some(ts) + } + } + pub async fn stop(&self) -> Result<(), E> { // drop the stop source if we have one let opt_stop_source = &mut *self.stop_source.lock().await; @@ -89,6 +100,17 @@ impl TickTask { return Ok(()); } + self.internal_tick(now, last_timestamp_us).await.map(drop) + } + + pub async fn try_tick_now(&self) -> Result { + let now = get_timestamp(); + let last_timestamp_us = self.last_timestamp_us.load(Ordering::Acquire); + + self.internal_tick(now, last_timestamp_us).await + } + + async fn internal_tick(&self, now: u64, last_timestamp_us: u64) -> Result { // Lock the stop source, tells us if we have ever started this future let opt_stop_source = &mut *self.stop_source.lock().await; if opt_stop_source.is_some() { @@ -104,12 +126,12 @@ impl TickTask { Ok(None) => { // No prior result to return which means things are still running // We can just return now, since the singlefuture will not run a second time - return Ok(()); + return Ok(false); } Err(()) => { // If we get this, it's because we are joining the singlefuture already // Don't bother running but this is not an error in this case - return Ok(()); + return Ok(false); } }; } @@ -134,7 +156,7 @@ impl TickTask { self.last_timestamp_us.store(now, Ordering::Release); // Save new stopper *opt_stop_source = Some(stop_source); - Ok(()) + Ok(true) } // All other conditions should not be reachable _ => { From b46fd7690f2e649c727332de999fdf072830d751 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Tue, 5 Dec 2023 20:00:08 -0500 Subject: [PATCH 12/67] watch maintenance tasks --- veilid-core/src/routing_table/mod.rs | 12 ++++ veilid-core/src/storage_manager/mod.rs | 23 +++++-- .../src/storage_manager/record_store.rs | 8 ++- .../storage_manager/storage_manager_inner.rs | 9 ++- .../tasks/check_active_watches.rs | 66 +++++++++++++++++++ .../tasks/flush_record_stores.rs | 2 +- veilid-core/src/storage_manager/tasks/mod.rs | 29 ++++++++ .../tasks/send_value_changes.rs | 2 +- .../src/storage_manager/watch_value.rs | 35 +++++++++- 9 files changed, 172 insertions(+), 14 deletions(-) create mode 100644 veilid-core/src/storage_manager/tasks/check_active_watches.rs diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index 8d0a9f00..729f22c1 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -276,6 +276,12 @@ impl RoutingTable { inner.route_spec_store = Some(route_spec_store); } + // Inform storage manager we are up + self.network_manager + .storage_manager() + .set_routing_table(Some(self.clone())) + .await; + debug!("finished routing table init"); Ok(()) } @@ -284,6 +290,12 @@ impl RoutingTable { pub async fn terminate(&self) { debug!("starting routing table terminate"); + // Stop storage manager from using us + self.network_manager + .storage_manager() + .set_routing_table(None) + .await; + // Stop tasks self.cancel_tasks().await; diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index bb65ebc9..36ee21b7 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -33,6 +33,8 @@ const FLUSH_RECORD_STORES_INTERVAL_SECS: u32 = 1; const OFFLINE_SUBKEY_WRITES_INTERVAL_SECS: u32 = 1; /// Frequency to send ValueChanged notifications to the network const SEND_VALUE_CHANGES_INTERVAL_SECS: u32 = 1; +/// Frequence to check for dead nodes and routes for active watches +const CHECK_ACTIVE_WATCHES_INTERVAL_SECS: u32 = 1; #[derive(Debug, Clone)] /// A single 'value changed' message to send @@ -55,6 +57,7 @@ struct StorageManagerUnlockedInner { flush_record_stores_task: TickTask, offline_subkey_writes_task: TickTask, send_value_changes_task: TickTask, + check_active_watches_task: TickTask, // Anonymous watch keys anonymous_watch_keys: TypedKeyPairGroup, @@ -90,6 +93,7 @@ impl StorageManager { flush_record_stores_task: TickTask::new(FLUSH_RECORD_STORES_INTERVAL_SECS), offline_subkey_writes_task: TickTask::new(OFFLINE_SUBKEY_WRITES_INTERVAL_SECS), send_value_changes_task: TickTask::new(SEND_VALUE_CHANGES_INTERVAL_SECS), + check_active_watches_task: TickTask::new(CHECK_ACTIVE_WATCHES_INTERVAL_SECS), anonymous_watch_keys, } @@ -149,7 +153,12 @@ impl StorageManager { pub async fn set_rpc_processor(&self, opt_rpc_processor: Option) { let mut inner = self.inner.lock().await; - inner.rpc_processor = opt_rpc_processor + inner.opt_rpc_processor = opt_rpc_processor + } + + pub async fn set_routing_table(&self, opt_routing_table: Option) { + let mut inner = self.inner.lock().await; + inner.opt_routing_table = opt_routing_table } async fn lock(&self) -> VeilidAPIResult> { @@ -161,7 +170,7 @@ impl StorageManager { } fn online_writes_ready_inner(inner: &StorageManagerInner) -> Option { - if let Some(rpc_processor) = { inner.rpc_processor.clone() } { + if let Some(rpc_processor) = { inner.opt_rpc_processor.clone() } { if let Some(network_class) = rpc_processor .routing_table() .get_network_class(RoutingDomain::PublicInternet) @@ -234,7 +243,7 @@ impl StorageManager { // No record yet, try to get it from the network // Get rpc processor and drop mutex so we don't block while getting the value from the network - let Some(rpc_processor) = inner.rpc_processor.clone() else { + let Some(rpc_processor) = inner.opt_rpc_processor.clone() else { apibail_try_again!("offline, try again later"); }; @@ -284,7 +293,7 @@ impl StorageManager { pub async fn close_record(&self, key: TypedKey) -> VeilidAPIResult<()> { let (opened_record, opt_rpc_processor) = { let mut inner = self.lock().await?; - (inner.close_record(key)?, inner.rpc_processor.clone()) + (inner.close_record(key)?, inner.opt_rpc_processor.clone()) }; // Send a one-time cancel request for the watch if we have one and we're online @@ -364,7 +373,7 @@ impl StorageManager { // Refresh if we can // Get rpc processor and drop mutex so we don't block while getting the value from the network - let Some(rpc_processor) = inner.rpc_processor.clone() else { + let Some(rpc_processor) = inner.opt_rpc_processor.clone() else { // Return the existing value if we have one if we aren't online if let Some(last_subkey_result_value) = last_subkey_result.value { return Ok(Some(last_subkey_result_value.value_data().clone())); @@ -562,7 +571,7 @@ impl StorageManager { }; // Get rpc processor and drop mutex so we don't block while requesting the watch from the network - let Some(rpc_processor) = inner.rpc_processor.clone() else { + let Some(rpc_processor) = inner.opt_rpc_processor.clone() else { apibail_try_again!("offline, try again later"); }; @@ -684,7 +693,7 @@ impl StorageManager { async fn send_value_change(&self, vc: ValueChangedInfo) -> VeilidAPIResult<()> { let rpc_processor = { let inner = self.inner.lock().await; - if let Some(rpc_processor) = &inner.rpc_processor { + if let Some(rpc_processor) = &inner.opt_rpc_processor { rpc_processor.clone() } else { apibail_try_again!("network is not available"); diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index a67b2ba1..58c56a90 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -859,7 +859,7 @@ where } let mut evcis = vec![]; - + let mut empty_watched_records = vec![]; for rtk in self.changed_watched_values.drain() { if let Some(watch) = self.watched_records.get_mut(&rtk) { // Process watch notifications @@ -888,9 +888,15 @@ where // Remove in reverse so we don't have to offset the index to remove the right key for dw in dead_watchers.iter().rev().copied() { watch.watchers.remove(dw); + if watch.watchers.is_empty() { + empty_watched_records.push(rtk); + } } } } + for ewr in empty_watched_records { + self.watched_records.remove(&ewr); + } for evci in evcis { // Get the first subkey data diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index ad872c4e..198a4628 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -25,7 +25,9 @@ pub(super) struct StorageManagerInner { /// Storage manager metadata that is persistent, including copy of offline subkey writes pub metadata_db: Option, /// RPC processor if it is available - pub rpc_processor: Option, + pub opt_rpc_processor: Option, + /// Routing table if it is available + pub opt_routing_table: Option, /// Background processing task (not part of attachment manager tick tree so it happens when detached too) pub tick_future: Option>, /// Update callback to send ValueChanged notification to @@ -78,7 +80,8 @@ impl StorageManagerInner { remote_record_store: Default::default(), offline_subkey_writes: Default::default(), metadata_db: Default::default(), - rpc_processor: Default::default(), + opt_rpc_processor: Default::default(), + opt_routing_table: Default::default(), tick_future: Default::default(), update_callback: None, } @@ -437,7 +440,7 @@ impl StorageManagerInner { }; // Get routing table to see if we still know about these nodes - let Some(routing_table) = self.rpc_processor.as_ref().map(|r| r.routing_table()) else { + let Some(routing_table) = self.opt_rpc_processor.as_ref().map(|r| r.routing_table()) else { apibail_try_again!("offline, try again later"); }; diff --git a/veilid-core/src/storage_manager/tasks/check_active_watches.rs b/veilid-core/src/storage_manager/tasks/check_active_watches.rs new file mode 100644 index 00000000..5ce1917c --- /dev/null +++ b/veilid-core/src/storage_manager/tasks/check_active_watches.rs @@ -0,0 +1,66 @@ +use super::*; + +impl StorageManager { + // Flush records stores to disk and remove dead records and send watch notifications + #[instrument(level = "trace", skip(self), err)] + pub(super) async fn check_active_watches_task_routine( + self, + stop_token: StopToken, + _last_ts: Timestamp, + _cur_ts: Timestamp, + ) -> EyreResult<()> { + { + let mut inner = self.inner.lock().await; + let Some(routing_table) = inner.opt_routing_table.clone() else { + return Ok(()); + }; + let rss = routing_table.route_spec_store(); + + let opt_update_callback = inner.update_callback.clone(); + + let cur_ts = get_aligned_timestamp(); + for (k, v) in inner.opened_records.iter_mut() { + // If no active watch, then skip this + let Some(active_watch) = v.active_watch() else { + continue; + }; + + // See if the active watch's node is dead + let mut is_dead = false; + if matches!( + active_watch.watch_node.state(cur_ts), + BucketEntryState::Dead + ) { + // Watched node is dead + is_dead = true; + } + + // See if the private route we're using is dead + if !is_dead { + if let Some(value_changed_route) = active_watch.opt_value_changed_route { + if rss.get_route_id_for_key(&value_changed_route).is_none() { + // Route we would receive value changes on is dead + is_dead = true; + } + } + } + + if is_dead { + if let Some(update_callback) = opt_update_callback.clone() { + // Send valuechange with dead count and no subkeys + update_callback(VeilidUpdate::ValueChange(Box::new(VeilidValueChange { + key: *k, + subkeys: ValueSubkeyRangeSet::new(), + count: 0, + value: ValueData::default(), + }))); + } + + v.clear_active_watch(); + } + } + } + + Ok(()) + } +} diff --git a/veilid-core/src/storage_manager/tasks/flush_record_stores.rs b/veilid-core/src/storage_manager/tasks/flush_record_stores.rs index af76ef28..a596baec 100644 --- a/veilid-core/src/storage_manager/tasks/flush_record_stores.rs +++ b/veilid-core/src/storage_manager/tasks/flush_record_stores.rs @@ -1,7 +1,7 @@ use super::*; impl StorageManager { - // Flush records stores to disk and remove dead records and send watch notifications + // Flush records stores to disk and remove dead records #[instrument(level = "trace", skip(self), err)] pub(crate) async fn flush_record_stores_task_routine( self, diff --git a/veilid-core/src/storage_manager/tasks/mod.rs b/veilid-core/src/storage_manager/tasks/mod.rs index ac8c52ca..e87e66a0 100644 --- a/veilid-core/src/storage_manager/tasks/mod.rs +++ b/veilid-core/src/storage_manager/tasks/mod.rs @@ -1,3 +1,4 @@ +pub mod check_active_watches; pub mod flush_record_stores; pub mod offline_subkey_writes; pub mod send_value_changes; @@ -69,12 +70,36 @@ impl StorageManager { ) }); } + // Set check active watches tick task + debug!("starting check active watches task"); + { + let this = self.clone(); + self.unlocked_inner + .check_active_watches_task + .set_routine(move |s, l, t| { + Box::pin( + this.clone() + .check_active_watches_task_routine( + s, + Timestamp::new(l), + Timestamp::new(t), + ) + .instrument(trace_span!( + parent: None, + "StorageManager check active watches task routine" + )), + ) + }); + } } pub async fn tick(&self) -> EyreResult<()> { // Run the flush stores task self.unlocked_inner.flush_record_stores_task.tick().await?; + // Check active watches + self.unlocked_inner.check_active_watches_task.tick().await?; + // Run online-only tasks if self.online_writes_ready().await?.is_some() { // Run offline subkey writes task if there's work to be done @@ -92,6 +117,10 @@ impl StorageManager { } pub(crate) async fn cancel_tasks(&self) { + debug!("stopping check active watches task"); + if let Err(e) = self.unlocked_inner.check_active_watches_task.stop().await { + warn!("check_active_watches_task not stopped: {}", e); + } debug!("stopping send value changes task"); if let Err(e) = self.unlocked_inner.send_value_changes_task.stop().await { warn!("send_value_changes_task not stopped: {}", e); diff --git a/veilid-core/src/storage_manager/tasks/send_value_changes.rs b/veilid-core/src/storage_manager/tasks/send_value_changes.rs index ed054c00..5fe7866e 100644 --- a/veilid-core/src/storage_manager/tasks/send_value_changes.rs +++ b/veilid-core/src/storage_manager/tasks/send_value_changes.rs @@ -3,7 +3,7 @@ use futures_util::StreamExt; use stop_token::future::FutureExt; impl StorageManager { - // Flush records stores to disk and remove dead records and send watch notifications + // Send value change notifications across the network #[instrument(level = "trace", skip(self), err)] pub(super) async fn send_value_changes_task_routine( self, diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index a65ad547..5ab0f516 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -219,7 +219,7 @@ impl StorageManager { &self, key: TypedKey, subkeys: ValueSubkeyRangeSet, - count: u32, + mut count: u32, value: Arc, ) -> VeilidAPIResult<()> { // Update local record store with new value @@ -233,8 +233,40 @@ impl StorageManager { } else { VeilidAPIResult::Ok(()) }; + + let Some(opened_record) = inner.opened_records.get_mut(&key) else { + // Don't send update or update the ActiveWatch if this record is closed + return res; + }; + let Some(mut active_watch) = opened_record.active_watch() else { + // No active watch means no callback + return res; + }; + + if count > active_watch.count { + // If count is greater than our requested count then this is invalid, cancel the watch + log_stor!(debug "watch count went backward: {}: {}/{}", key, count, active_watch.count); + // Force count to zero + count = 0; + opened_record.clear_active_watch(); + } else if count == 0 { + // If count is zero, we're done, cancel the watch and the app can renew it if it wants + log_stor!(debug "watch count finished: {}", key); + opened_record.clear_active_watch(); + } else { + log_stor!( + "watch count decremented: {}: {}/{}", + key, + count, + active_watch.count + ); + active_watch.count = count; + opened_record.set_active_watch(active_watch); + } + (res, inner.update_callback.clone()) }; + // Announce ValueChanged VeilidUpdate if let Some(update_callback) = opt_update_callback { update_callback(VeilidUpdate::ValueChange(Box::new(VeilidValueChange { @@ -244,6 +276,7 @@ impl StorageManager { value: value.value_data().clone(), }))); } + res } } From 05f89e070cc83147dfaff3a444b9191a0125f3d3 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Tue, 5 Dec 2023 21:07:42 -0500 Subject: [PATCH 13/67] fix tests --- veilid-core/src/storage_manager/mod.rs | 60 ++++++++++--------- .../storage_manager/storage_manager_inner.rs | 12 ++-- .../src/storage_manager/types/record_data.rs | 3 +- .../src/tests/common/test_veilid_config.rs | 3 + 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 36ee21b7..d9c62019 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -291,40 +291,42 @@ impl StorageManager { /// Close an opened local record pub async fn close_record(&self, key: TypedKey) -> VeilidAPIResult<()> { - let (opened_record, opt_rpc_processor) = { + let (opt_opened_record, opt_rpc_processor) = { let mut inner = self.lock().await?; (inner.close_record(key)?, inner.opt_rpc_processor.clone()) }; // Send a one-time cancel request for the watch if we have one and we're online - if let Some(active_watch) = opened_record.active_watch() { - if let Some(rpc_processor) = opt_rpc_processor { - // Use the safety selection we opened the record with - // Use the writer we opened with as the 'watcher' as well - let opt_owvresult = self - .outbound_watch_value( - rpc_processor, - key, - ValueSubkeyRangeSet::full(), - Timestamp::new(0), - 0, - opened_record.safety_selection(), - opened_record.writer().cloned(), - Some(active_watch.watch_node), - ) - .await?; - if let Some(owvresult) = opt_owvresult { - if owvresult.expiration_ts.as_u64() != 0 { - log_stor!(debug - "close record watch cancel got unexpected expiration: {}", - owvresult.expiration_ts - ); + if let Some(opened_record) = opt_opened_record { + if let Some(active_watch) = opened_record.active_watch() { + if let Some(rpc_processor) = opt_rpc_processor { + // Use the safety selection we opened the record with + // Use the writer we opened with as the 'watcher' as well + let opt_owvresult = self + .outbound_watch_value( + rpc_processor, + key, + ValueSubkeyRangeSet::full(), + Timestamp::new(0), + 0, + opened_record.safety_selection(), + opened_record.writer().cloned(), + Some(active_watch.watch_node), + ) + .await?; + if let Some(owvresult) = opt_owvresult { + if owvresult.expiration_ts.as_u64() != 0 { + log_stor!(debug + "close record watch cancel got unexpected expiration: {}", + owvresult.expiration_ts + ); + } + } else { + log_stor!(debug "close record watch cancel unsuccessful"); } } else { - log_stor!(debug "close record watch cancel unsuccessful"); + log_stor!(debug "skipping last-ditch watch cancel because we are offline"); } - } else { - log_stor!(debug "skipping last-ditch watch cancel because we are offline"); } } @@ -336,6 +338,7 @@ impl StorageManager { // Ensure the record is closed self.close_record(key).await?; + // Get record from the local store let mut inner = self.lock().await?; let Some(local_record_store) = inner.local_record_store.as_mut() else { apibail_not_initialized!(); @@ -526,8 +529,11 @@ impl StorageManager { ) .await?; - // Whatever record we got back, store it locally, might be newer than the one we asked to save + // Keep the list of nodes that returned a value for later reference let mut inner = self.lock().await?; + inner.set_value_nodes(key, result.value_nodes)?; + + // Whatever record we got back, store it locally, might be newer than the one we asked to save inner .handle_set_local_value(key, subkey, result.signed_value_data.clone()) .await?; diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index 198a4628..90c3cfd1 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -480,11 +480,15 @@ impl StorageManagerInner { Ok(()) } - pub fn close_record(&mut self, key: TypedKey) -> VeilidAPIResult { - let Some(opened_record) = self.opened_records.remove(&key) else { - apibail_generic!("record not open"); + pub fn close_record(&mut self, key: TypedKey) -> VeilidAPIResult> { + let Some(local_record_store) = self.local_record_store.as_mut() else { + apibail_not_initialized!(); }; - Ok(opened_record) + if local_record_store.peek_record(key, |_| {}).is_none() { + return Err(VeilidAPIError::key_not_found(key)); + } + + Ok(self.opened_records.remove(&key)) } pub(super) async fn handle_get_local_value( diff --git a/veilid-core/src/storage_manager/types/record_data.rs b/veilid-core/src/storage_manager/types/record_data.rs index 86c9f9b7..69b47837 100644 --- a/veilid-core/src/storage_manager/types/record_data.rs +++ b/veilid-core/src/storage_manager/types/record_data.rs @@ -16,7 +16,6 @@ impl RecordData { self.signed_value_data.data_size() } pub fn total_size(&self) -> usize { - (mem::size_of::() - mem::size_of::()) - + self.signed_value_data.total_size() + mem::size_of::() + self.signed_value_data.total_size() } } diff --git a/veilid-core/src/tests/common/test_veilid_config.rs b/veilid-core/src/tests/common/test_veilid_config.rs index 8f16f206..43515cbd 100644 --- a/veilid-core/src/tests/common/test_veilid_config.rs +++ b/veilid-core/src/tests/common/test_veilid_config.rs @@ -229,6 +229,9 @@ pub fn config_callback(key: String) -> ConfigCallbackReturn { "network.dht.remote_max_records" => Ok(Box::new(4096u32)), "network.dht.remote_max_subkey_cache_memory_mb" => Ok(Box::new(64u32)), "network.dht.remote_max_storage_space_mb" => Ok(Box::new(64u32)), + "network.dht.public_watch_limit" => Ok(Box::new(32u32)), + "network.dht.member_watch_limit" => Ok(Box::new(8u32)), + "network.dht.max_watch_expiration_ms" => Ok(Box::new(600_000u32)), "network.upnp" => Ok(Box::new(false)), "network.detect_address_changes" => Ok(Box::new(true)), "network.restricted_nat_retries" => Ok(Box::new(0u32)), From 96ead7dba57e200ceb439f2629ab1dc3f199b304 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Wed, 6 Dec 2023 17:32:11 -0500 Subject: [PATCH 14/67] fix address in use error and don't send valuechanged to node that sets value --- .../src/network_manager/connection_manager.rs | 10 ++++-- .../src/rpc_processor/rpc_set_value.rs | 6 +++- veilid-core/src/storage_manager/mod.rs | 21 ++++++++++-- .../src/storage_manager/record_store.rs | 32 +++++++++++++++++-- veilid-core/src/storage_manager/set_value.rs | 13 ++++++-- .../storage_manager/storage_manager_inner.rs | 10 +++--- .../src/storage_manager/watch_value.rs | 7 +++- 7 files changed, 83 insertions(+), 16 deletions(-) diff --git a/veilid-core/src/network_manager/connection_manager.rs b/veilid-core/src/network_manager/connection_manager.rs index 9ae3e63a..cb1b1808 100644 --- a/veilid-core/src/network_manager/connection_manager.rs +++ b/veilid-core/src/network_manager/connection_manager.rs @@ -331,7 +331,7 @@ impl ConnectionManager { } // Attempt new connection - let mut retry_count = 0; // Someday, if we need this + let mut retry_count = 1; let prot_conn = network_result_try!(loop { let result_net_res = ProtocolNetworkConnection::connect( @@ -350,12 +350,18 @@ impl ConnectionManager { } Err(e) => { if retry_count == 0 { - return Err(e).wrap_err("failed to connect"); + return Err(e).wrap_err(format!( + "failed to connect: {:?} -> {:?}", + preferred_local_address, dial_info + )); } } }; log_net!(debug "get_or_create_connection retries left: {}", retry_count); retry_count -= 1; + + // Release the preferred local address if things can't connect due to a low-level collision we dont have a record of + preferred_local_address = None; sleep(500).await; }); diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index a3bc6d67..2e7f7f12 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -222,6 +222,10 @@ impl RPCProcessor { // Destructure let (key, subkey, value, descriptor) = set_value_q.destructure(); + // Get target for ValueChanged notifications + let dest = network_result_try!(self.get_respond_to_destination(&msg)); + let target = dest.get_target(); + // Get the nodes that we know about that are closer to the the key than our own node let routing_table = self.routing_table(); let closer_to_key_peers = network_result_try!(routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT])); @@ -257,7 +261,7 @@ impl RPCProcessor { // Save the subkey, creating a new record if necessary let storage_manager = self.storage_manager(); let new_value = network_result_try!(storage_manager - .inbound_set_value(key, subkey, Arc::new(value), descriptor.map(Arc::new)) + .inbound_set_value(key, subkey, Arc::new(value), descriptor.map(Arc::new), target) .await .map_err(RPCError::internal)?); diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index d9c62019..25d2b858 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -416,7 +416,12 @@ impl StorageManager { // If we got a new value back then write it to the opened record if Some(subkey_result_value.value_data().seq()) != opt_last_seq { inner - .handle_set_local_value(key, subkey, subkey_result_value.clone()) + .handle_set_local_value( + key, + subkey, + subkey_result_value.clone(), + WatchUpdateMode::UpdateAll, + ) .await?; } Ok(Some(subkey_result_value.value_data().clone())) @@ -496,7 +501,12 @@ impl StorageManager { // Offline, just write it locally and return immediately inner - .handle_set_local_value(key, subkey, signed_value_data.clone()) + .handle_set_local_value( + key, + subkey, + signed_value_data.clone(), + WatchUpdateMode::UpdateAll, + ) .await?; log_stor!(debug "Writing subkey offline: {}:{} len={}", key, subkey, signed_value_data.value_data().data().len() ); @@ -535,7 +545,12 @@ impl StorageManager { // Whatever record we got back, store it locally, might be newer than the one we asked to save inner - .handle_set_local_value(key, subkey, result.signed_value_data.clone()) + .handle_set_local_value( + key, + subkey, + result.signed_value_data.clone(), + WatchUpdateMode::UpdateAll, + ) .await?; // Return the new value if it differs from what was asked to set diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index 58c56a90..8e3a8712 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -40,6 +40,12 @@ struct WatchedRecord { watchers: Vec, } +pub(super) enum WatchUpdateMode { + NoUpdate, + UpdateAll, + ExcludeTarget(Target), +} + pub(super) struct RecordStore where D: fmt::Debug + Clone + Serialize + for<'d> Deserialize<'d>, @@ -599,7 +605,12 @@ where })) } - async fn update_watched_value(&mut self, key: TypedKey, subkey: ValueSubkey) { + async fn update_watched_value( + &mut self, + key: TypedKey, + subkey: ValueSubkey, + opt_ignore_target: Option, + ) { let rtk = RecordTableKey { key }; let Some(wr) = self.watched_records.get_mut(&rtk) else { return; @@ -608,7 +619,12 @@ where let mut changed = false; for w in &mut wr.watchers { // If this watcher is watching the changed subkey then add to the watcher's changed list - if w.subkeys.contains(subkey) && w.changed.insert(subkey) { + // Don't bother marking changes for value sets coming from the same watching node/target because they + // are already going to be aware of the changes in that case + if Some(&w.target) != opt_ignore_target.as_ref() + && w.subkeys.contains(subkey) + && w.changed.insert(subkey) + { changed = true; } } @@ -622,6 +638,7 @@ where key: TypedKey, subkey: ValueSubkey, signed_value_data: Arc, + watch_update_mode: WatchUpdateMode, ) -> VeilidAPIResult<()> { // Check size limit for data if signed_value_data.value_data().data().len() > self.limits.max_subkey_size { @@ -710,7 +727,16 @@ where self.total_storage_space.commit().unwrap(); // Update watched value - self.update_watched_value(key, subkey).await; + + let (do_update, opt_ignore_target) = match watch_update_mode { + WatchUpdateMode::NoUpdate => (false, None), + WatchUpdateMode::UpdateAll => (true, None), + WatchUpdateMode::ExcludeTarget(target) => (true, Some(target)), + }; + if do_update { + self.update_watched_value(key, subkey, opt_ignore_target) + .await; + } Ok(()) } diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index cab6f225..43970b9f 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -227,6 +227,7 @@ impl StorageManager { subkey: ValueSubkey, value: Arc, descriptor: Option>, + target: Target, ) -> VeilidAPIResult>>> { let mut inner = self.lock().await?; @@ -290,10 +291,18 @@ impl StorageManager { // Do the set and return no new value let res = if is_local { - inner.handle_set_local_value(key, subkey, value).await + inner + .handle_set_local_value(key, subkey, value, WatchUpdateMode::ExcludeTarget(target)) + .await } else { inner - .handle_set_remote_value(key, subkey, value, actual_descriptor) + .handle_set_remote_value( + key, + subkey, + value, + actual_descriptor, + WatchUpdateMode::ExcludeTarget(target), + ) .await }; match res { diff --git a/veilid-core/src/storage_manager/storage_manager_inner.rs b/veilid-core/src/storage_manager/storage_manager_inner.rs index 90c3cfd1..0d78a90a 100644 --- a/veilid-core/src/storage_manager/storage_manager_inner.rs +++ b/veilid-core/src/storage_manager/storage_manager_inner.rs @@ -291,7 +291,7 @@ impl StorageManagerInner { continue; }; local_record_store - .set_subkey(key, subkey, subkey_data) + .set_subkey(key, subkey, subkey_data, WatchUpdateMode::NoUpdate) .await?; } @@ -420,7 +420,7 @@ impl StorageManagerInner { if let Some(signed_value_data) = subkey_result.value { // Write subkey to local store local_record_store - .set_subkey(key, subkey, signed_value_data) + .set_subkey(key, subkey, signed_value_data, WatchUpdateMode::NoUpdate) .await?; } @@ -519,6 +519,7 @@ impl StorageManagerInner { key: TypedKey, subkey: ValueSubkey, signed_value_data: Arc, + watch_update_mode: WatchUpdateMode, ) -> VeilidAPIResult<()> { // See if it's in the local record store let Some(local_record_store) = self.local_record_store.as_mut() else { @@ -527,7 +528,7 @@ impl StorageManagerInner { // Write subkey to local store local_record_store - .set_subkey(key, subkey, signed_value_data) + .set_subkey(key, subkey, signed_value_data, watch_update_mode) .await?; Ok(()) @@ -580,6 +581,7 @@ impl StorageManagerInner { subkey: ValueSubkey, signed_value_data: Arc, signed_value_descriptor: Arc, + watch_update_mode: WatchUpdateMode, ) -> VeilidAPIResult<()> { // See if it's in the remote record store let Some(remote_record_store) = self.remote_record_store.as_mut() else { @@ -601,7 +603,7 @@ impl StorageManagerInner { // Write subkey to remote store remote_record_store - .set_subkey(key, subkey, signed_value_data) + .set_subkey(key, subkey, signed_value_data, watch_update_mode) .await?; Ok(()) diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index 5ab0f516..b49aef25 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -228,7 +228,12 @@ impl StorageManager { let res = if let Some(first_subkey) = subkeys.first() { inner - .handle_set_local_value(key, first_subkey, value.clone()) + .handle_set_local_value( + key, + first_subkey, + value.clone(), + WatchUpdateMode::NoUpdate, + ) .await } else { VeilidAPIResult::Ok(()) From ac6aa8f2eb430c0b3482612a17212341c918e7fa Mon Sep 17 00:00:00 2001 From: John Smith Date: Wed, 6 Dec 2023 19:47:42 -0500 Subject: [PATCH 15/67] fix overflow --- veilid-core/src/storage_manager/types/record.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veilid-core/src/storage_manager/types/record.rs b/veilid-core/src/storage_manager/types/record.rs index 8dc78bb1..5e33d508 100644 --- a/veilid-core/src/storage_manager/types/record.rs +++ b/veilid-core/src/storage_manager/types/record.rs @@ -74,7 +74,7 @@ where } pub fn total_size(&self) -> usize { - (mem::size_of::() - mem::size_of::()) + (mem::size_of::() - mem::size_of::>()) + self.descriptor.total_size() + self.record_data_size } From 99fb135b5b32fa4d00c370b8247b7037c97d0ece Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 7 Dec 2023 10:28:26 -0500 Subject: [PATCH 16/67] fix invalid nodeinfo check --- veilid-core/src/routing_table/bucket_entry.rs | 5 +++++ veilid-core/src/routing_table/routing_table_inner.rs | 5 ++++- veilid-core/src/storage_manager/mod.rs | 4 ++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/veilid-core/src/routing_table/bucket_entry.rs b/veilid-core/src/routing_table/bucket_entry.rs index 28a666c6..eba6a8cf 100644 --- a/veilid-core/src/routing_table/bucket_entry.rs +++ b/veilid-core/src/routing_table/bucket_entry.rs @@ -647,6 +647,11 @@ impl BucketEntryInner { return false; } + // If we have had any lost answers recently, this is not reliable + if self.peer_stats.rpc_stats.recent_lost_answers > 0 { + return false; + } + match self.peer_stats.rpc_stats.first_consecutive_seen_ts { // If we have not seen seen a node consecutively, it can't be reliable None => false, diff --git a/veilid-core/src/routing_table/routing_table_inner.rs b/veilid-core/src/routing_table/routing_table_inner.rs index 855e1321..1af08ccf 100644 --- a/veilid-core/src/routing_table/routing_table_inner.rs +++ b/veilid-core/src/routing_table/routing_table_inner.rs @@ -962,7 +962,10 @@ impl RoutingTableInner { None => has_valid_own_node_info, Some(entry) => entry.with_inner(|e| { e.signed_node_info(routing_domain) - .map(|sni| sni.has_any_signature()) + .map(|sni| { + sni.has_any_signature() + && !matches!(sni.node_info().network_class(), NetworkClass::Invalid) + }) .unwrap_or(false) }), } diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 25d2b858..4abe128d 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -723,14 +723,14 @@ impl StorageManager { let dest = rpc_processor .resolve_target_to_destination( - vc.target, + vc.target.clone(), SafetySelection::Unsafe(Sequencing::NoPreference), ) .await .map_err(VeilidAPIError::from)?; network_result_value_or_log!(rpc_processor - .rpc_call_value_changed(dest, vc.key, vc.subkeys, vc.count, (*vc.value).clone()) + .rpc_call_value_changed(dest, vc.key, vc.subkeys.clone(), vc.count, (*vc.value).clone()) .await .map_err(VeilidAPIError::from)? => [format!(": dest={:?} vc={:?}", dest, vc)] { }); From cdf823c1cc030b72228fd790421cb2cab1f2886b Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 8 Dec 2023 10:57:58 -0500 Subject: [PATCH 17/67] better debug commands for dht --- .../routing_table/routing_domain_editor.rs | 6 +- .../src/rpc_processor/rpc_watch_value.rs | 2 +- veilid-core/src/veilid_api/debug.rs | 288 ++++++++++++------ veilid-tools/src/timestamp.rs | 31 ++ 4 files changed, 222 insertions(+), 105 deletions(-) diff --git a/veilid-core/src/routing_table/routing_domain_editor.rs b/veilid-core/src/routing_table/routing_domain_editor.rs index d5ff715f..f7976faf 100644 --- a/veilid-core/src/routing_table/routing_domain_editor.rs +++ b/veilid-core/src/routing_table/routing_domain_editor.rs @@ -137,10 +137,8 @@ impl RoutingDomainEditor { None }; - // Debug print - log_rtab!(debug "[{:?}] COMMIT: {:?}", self.routing_domain, self.changes); - // Apply changes + log_rtab!("[{:?}] COMMIT: {:?}", self.routing_domain, self.changes); let mut peer_info_changed = false; { let mut inner = self.routing_table.inner.write(); @@ -181,7 +179,7 @@ impl RoutingDomainEditor { peer_info_changed = true; } RoutingDomainChange::SetRelayNodeKeepalive { ts } => { - debug!("[{:?}] relay node keepalive: {:?}", self.routing_domain, ts); + trace!("[{:?}] relay node keepalive: {:?}", self.routing_domain, ts); detail.common_mut().set_relay_node_last_keepalive(ts); } RoutingDomainChange::AddDialInfoDetail { dial_info_detail } => { diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 562cde83..8196ff01 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -100,7 +100,7 @@ impl RPCProcessor { if opt_watcher.is_some() { "+W " } else { "" }, subkeys, expiration, - peer.len() + peer.len(), dest ); diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 305fbb9e..ffb01b74 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -3,16 +3,20 @@ use super::*; use data_encoding::BASE64URL_NOPAD; +use hashlink::LinkedHashMap; use network_manager::*; +use once_cell::sync::Lazy; use routing_table::*; -#[derive(Default, Debug)] +#[derive(Default)] struct DebugCache { imported_routes: Vec, + opened_record_contexts: Lazy>, } static DEBUG_CACHE: Mutex = Mutex::new(DebugCache { imported_routes: Vec::new(), + opened_record_contexts: Lazy::new(LinkedHashMap::new), }); fn format_opt_ts(ts: Option) -> String { @@ -283,6 +287,7 @@ fn get_destination( fn get_number(text: &str) -> Option { usize::from_str(text).ok() } + fn get_typed_key(text: &str) -> Option { TypedKey::from_str(text).ok() } @@ -301,6 +306,18 @@ fn get_crypto_system_version(crypto: Crypto) -> impl FnOnce(&str) -> Option Option { + let key = if let Some(key) = get_public_key(text) { + TypedKey::new(best_crypto_kind(), key) + } else if let Some(key) = get_typed_key(text) { + key + } else { + return None; + }; + + Some(key) +} + fn get_dht_key( routing_table: RoutingTable, ) -> impl FnOnce(&str) -> Option<(TypedKey, Option)> { @@ -515,6 +532,34 @@ async fn async_get_debug_argument_at SendPinBoxFuture VeilidAPIResult<(TypedKey, RoutingContext)> { + let dc = DEBUG_CACHE.lock(); + + let key = match get_debug_argument_at(args, arg, context, key, get_dht_key_no_safety) + .ok() + .or_else(|| { + // If unspecified, use the most recent key opened or created + dc.opened_record_contexts.back().map(|kv| kv.0).copied() + }) { + Some(k) => k, + None => { + apibail_missing_argument!("no keys are opened", "key"); + } + }; + + // Get routing context for record + let Some(rc) = dc.opened_record_contexts.get(&key).cloned() else { + apibail_missing_argument!("key is not opened", "key"); + }; + + Ok((key, rc)) +} + pub fn print_data(data: &[u8], truncate_len: Option) -> String { // check if message body is ascii printable let mut printable = true; @@ -1410,25 +1455,88 @@ impl VeilidAPI { Err(e) => return Ok(format!("Can't open DHT record: {}", e)), Ok(v) => v, }; - match rc.close_dht_record(*record.key()).await { - Err(e) => return Ok(format!("Can't close DHT record: {}", e)), - Ok(v) => v, - }; + + // Save routing context for record + let mut dc = DEBUG_CACHE.lock(); + dc.opened_record_contexts.insert(*record.key(), rc); + debug!("DHT Record Created:\n{:#?}", record); - Ok(format!("{:?}", record)) + Ok(format!("Created: {:?}", record)) } - async fn debug_record_get(&self, args: Vec) -> VeilidAPIResult { + async fn debug_record_open(&self, args: Vec) -> VeilidAPIResult { let netman = self.network_manager()?; let routing_table = netman.routing_table(); let (key, ss) = get_debug_argument_at( &args, 1, - "debug_record_get", + "debug_record_open", "key", get_dht_key(routing_table), )?; + let writer = + get_debug_argument_at(&args, 2, "debug_record_open", "writer", get_keypair).ok(); + + // Get routing context with optional safety + let rc = self.routing_context()?; + let rc = if let Some(ss) = ss { + match rc.with_safety(ss) { + Err(e) => return Ok(format!("Can't use safety selection: {}", e)), + Ok(v) => v, + } + } else { + rc + }; + + // Do a record open + let record = match rc.open_dht_record(key, writer).await { + Err(e) => return Ok(format!("Can't open DHT record: {}", e)), + Ok(v) => v, + }; + + // Save routing context for record + let mut dc = DEBUG_CACHE.lock(); + dc.opened_record_contexts.insert(*record.key(), rc); + + debug!("DHT Record Opened:\n{:#?}", record); + Ok(format!("Opened: {:?}", record)) + } + + async fn debug_record_close(&self, args: Vec) -> VeilidAPIResult { + let (key, rc) = get_opened_dht_record_context(&args, "debug_record_close", "key", 1)?; + + // Do a record close + if let Err(e) = rc.close_dht_record(key).await { + return Ok(format!("Can't close DHT record: {}", e)); + }; + + debug!("DHT Record Closed:\n{:#?}", key); + Ok(format!("Closed: {:?}", key)) + } + + async fn debug_record_set(&self, args: Vec) -> VeilidAPIResult { + let (key, rc) = get_opened_dht_record_context(&args, "debug_record_set", "key", 1)?; + let subkey = get_debug_argument_at(&args, 2, "debug_record_set", "subkey", get_number)?; + let data = get_debug_argument_at(&args, 3, "debug_record_set", "data", get_data)?; + + // Do a record set + let value = match rc.set_dht_value(key, subkey as ValueSubkey, data).await { + Err(e) => { + return Ok(format!("Can't set DHT value: {}", e)); + } + Ok(v) => v, + }; + let out = if let Some(value) = value { + format!("{:?}", value) + } else { + "No value data returned".to_owned() + }; + Ok(out) + } + + async fn debug_record_get(&self, args: Vec) -> VeilidAPIResult { + let (key, rc) = get_opened_dht_record_context(&args, "debug_record_get", "key", 1)?; let subkey = get_debug_argument_at(&args, 2, "debug_record_get", "subkey", get_number)?; let force_refresh = if args.len() >= 4 { Some(get_debug_argument_at( @@ -1452,36 +1560,12 @@ impl VeilidAPI { false }; - // Get routing context with optional privacy - let rc = self.routing_context()?; - let rc = if let Some(ss) = ss { - match rc.with_safety(ss) { - Err(e) => return Ok(format!("Can't use safety selection: {}", e)), - Ok(v) => v, - } - } else { - rc - }; - // Do a record get - let _record = match rc.open_dht_record(key, None).await { - Err(e) => return Ok(format!("Can't open DHT record: {}", e)), - Ok(v) => v, - }; let value = match rc .get_dht_value(key, subkey as ValueSubkey, force_refresh) .await { Err(e) => { - match rc.close_dht_record(key).await { - Err(e) => { - return Ok(format!( - "Can't get DHT value and can't close DHT record: {}", - e - )) - } - Ok(v) => v, - }; return Ok(format!("Can't get DHT value: {}", e)); } Ok(v) => v, @@ -1491,75 +1575,19 @@ impl VeilidAPI { } else { "No value data returned".to_owned() }; - match rc.close_dht_record(key).await { - Err(e) => return Ok(format!("Can't close DHT record: {}", e)), - Ok(v) => v, - }; - Ok(out) - } - - async fn debug_record_set(&self, args: Vec) -> VeilidAPIResult { - let netman = self.network_manager()?; - let routing_table = netman.routing_table(); - - let (key, ss) = get_debug_argument_at( - &args, - 1, - "debug_record_set", - "key", - get_dht_key(routing_table), - )?; - let subkey = get_debug_argument_at(&args, 2, "debug_record_set", "subkey", get_number)?; - let writer = get_debug_argument_at(&args, 3, "debug_record_set", "writer", get_keypair)?; - let data = get_debug_argument_at(&args, 4, "debug_record_set", "data", get_data)?; - - // Get routing context with optional privacy - let rc = self.routing_context()?; - let rc = if let Some(ss) = ss { - match rc.with_safety(ss) { - Err(e) => return Ok(format!("Can't use safety selection: {}", e)), - Ok(v) => v, - } - } else { - rc - }; - - // Do a record get - let _record = match rc.open_dht_record(key, Some(writer)).await { - Err(e) => return Ok(format!("Can't open DHT record: {}", e)), - Ok(v) => v, - }; - let value = match rc.set_dht_value(key, subkey as ValueSubkey, data).await { - Err(e) => { - match rc.close_dht_record(key).await { - Err(e) => { - return Ok(format!( - "Can't set DHT value and can't close DHT record: {}", - e - )) - } - Ok(v) => v, - }; - return Ok(format!("Can't set DHT value: {}", e)); - } - Ok(v) => v, - }; - let out = if let Some(value) = value { - format!("{:?}", value) - } else { - "No value data returned".to_owned() - }; - match rc.close_dht_record(key).await { - Err(e) => return Ok(format!("Can't close DHT record: {}", e)), - Ok(v) => v, - }; Ok(out) } async fn debug_record_delete(&self, args: Vec) -> VeilidAPIResult { - let key = get_debug_argument_at(&args, 1, "debug_record_delete", "key", get_typed_key)?; + let key = get_debug_argument_at( + &args, + 1, + "debug_record_delete", + "key", + get_dht_key_no_safety, + )?; - // Do a record delete + // Do a record delete (can use any routing context here) let rc = self.routing_context()?; match rc.delete_dht_record(key).await { Err(e) => return Ok(format!("Can't delete DHT record: {}", e)), @@ -1571,7 +1599,8 @@ impl VeilidAPI { async fn debug_record_info(&self, args: Vec) -> VeilidAPIResult { let storage_manager = self.storage_manager()?; - let key = get_debug_argument_at(&args, 1, "debug_record_info", "key", get_typed_key)?; + let key = + get_debug_argument_at(&args, 1, "debug_record_info", "key", get_dht_key_no_safety)?; let subkey = get_debug_argument_at(&args, 2, "debug_record_info", "subkey", get_number).ok(); @@ -1595,6 +1624,53 @@ impl VeilidAPI { Ok(out) } + async fn debug_record_watch(&self, args: Vec) -> VeilidAPIResult { + let (key, rc) = get_opened_dht_record_context(&args, "debug_record_watch", "key", 1)?; + let subkeys = get_debug_argument_at(&args, 2, "debug_record_watch", "subkeys", get_subkeys) + .ok() + .unwrap_or_default(); + let expiration = + get_debug_argument_at(&args, 3, "debug_record_watch", "expiration", parse_duration) + .ok() + .unwrap_or_default(); + let count = get_debug_argument_at(&args, 4, "debug_record_watch", "count", get_number) + .ok() + .unwrap_or(usize::MAX) as u32; + + // Do a record watch + let ts = match rc + .watch_dht_values(key, subkeys, Timestamp::new(expiration), count) + .await + { + Err(e) => { + return Ok(format!("Can't watch DHT value: {}", e)); + } + Ok(v) => v, + }; + + Ok(format!("Expiration at: {:?}", debug_ts(ts.as_u64()))) + } + + async fn debug_record_cancel(&self, args: Vec) -> VeilidAPIResult { + let (key, rc) = get_opened_dht_record_context(&args, "debug_record_watch", "key", 1)?; + let subkeys = get_debug_argument_at(&args, 2, "debug_record_watch", "subkeys", get_subkeys) + .ok() + .unwrap_or_default(); + + // Do a record watch cancel + let still_active = match rc.cancel_dht_watch(key, subkeys).await { + Err(e) => { + return Ok(format!("Can't cancel DHT watch: {}", e)); + } + Ok(v) => v, + }; + + Ok(format!( + "Still Active: {:?}", + if still_active { "true" } else { "false" } + )) + } + async fn debug_record(&self, args: String) -> VeilidAPIResult { let args: Vec = shell_words::split(&args).map_err(|e| VeilidAPIError::parse_error(e, args))?; @@ -1607,6 +1683,10 @@ impl VeilidAPI { self.debug_record_purge(args).await } else if command == "create" { self.debug_record_create(args).await + } else if command == "open" { + self.debug_record_open(args).await + } else if command == "close" { + self.debug_record_close(args).await } else if command == "get" { self.debug_record_get(args).await } else if command == "set" { @@ -1615,6 +1695,10 @@ impl VeilidAPI { self.debug_record_delete(args).await } else if command == "info" { self.debug_record_info(args).await + } else if command == "watch" { + self.debug_record_info(args).await + } else if command == "cancel" { + self.debug_record_info(args).await } else { Ok(">>> Unknown command\n".to_owned()) } @@ -1676,10 +1760,14 @@ route allocate [ord|*ord] [rel] [] [in|out] record list purge [bytes] create [ []] - set [+] - get [+] [force] + open [+] [] + close [] + set [] + get [] [force] delete - info [subkey] + info [] [subkey] + watch [] [] [] [] + cancel [] [] -------------------------------------------------------------------- is: VLD0:GsgXCRPrzSK6oBNgxhNpm-rTYFd02R0ySx6j9vbQBG4 * also , , , diff --git a/veilid-tools/src/timestamp.rs b/veilid-tools/src/timestamp.rs index 2d995180..ada1a925 100644 --- a/veilid-tools/src/timestamp.rs +++ b/veilid-tools/src/timestamp.rs @@ -142,3 +142,34 @@ pub fn debug_duration(dur: u64) -> String { msecs ) } + +pub fn parse_duration(s: &str) -> Option { + let mut dur_total: u64 = 0; + let mut dur: u64 = 0; + for c in s.as_bytes() { + match c { + b'0'..=b'9' => { + dur *= 10; + dur += (c - b'0') as u64; + } + b'h' => { + dur *= 3_600_000u64; + dur_total += dur; + dur = 0; + } + b'm' => { + dur *= 60_000u64; + dur_total += dur; + dur = 0; + } + b's' => { + dur *= 1_000u64; + dur_total += dur; + dur = 0; + } + _ => return None, + } + } + dur_total += dur; + Some(dur_total * 1_000u64) +} From d7783e27dd651205a6f36cd0c892306a0325b47b Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 8 Dec 2023 11:32:18 -0500 Subject: [PATCH 18/67] fix bugs --- veilid-core/src/rpc_processor/rpc_watch_value.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 8196ff01..4d22bb70 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -55,7 +55,7 @@ impl RPCProcessor { // Send the watchvalue question let watch_value_q = RPCOperationWatchValueQ::new( key, - subkeys, + subkeys.clone(), expiration.as_u64(), count, watcher, @@ -95,12 +95,11 @@ impl RPCProcessor { #[cfg(feature = "debug-dht")] { let debug_string_answer = format!( - "OUT <== WatchValueA({} {}#{:?}@{} peers={}) <= {}", + "OUT <== WatchValueA({} #{:?}@{} peers={}) <= {}", key, - if opt_watcher.is_some() { "+W " } else { "" }, subkeys, expiration, - peer.len(), + peers.len(), dest ); @@ -217,7 +216,7 @@ impl RPCProcessor { network_result_try!(storage_manager .inbound_watch_value( key, - subkeys, + subkeys.clone(), Timestamp::new(expiration), count, target, From 88d13d36c9f2405e2f862e24859aa1ee1351e704 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 8 Dec 2023 13:50:02 -0500 Subject: [PATCH 19/67] cleanup --- veilid-core/src/veilid_api/debug.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index ffb01b74..415d1ea0 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -1461,7 +1461,7 @@ impl VeilidAPI { dc.opened_record_contexts.insert(*record.key(), rc); debug!("DHT Record Created:\n{:#?}", record); - Ok(format!("Created: {:?}", record)) + Ok(format!("Created: {:?} : {:?}", record.key(), record)) } async fn debug_record_open(&self, args: Vec) -> VeilidAPIResult { @@ -1528,9 +1528,9 @@ impl VeilidAPI { Ok(v) => v, }; let out = if let Some(value) = value { - format!("{:?}", value) + format!("Newer value found: {:?}", value) } else { - "No value data returned".to_owned() + "Success".to_owned() }; Ok(out) } @@ -1696,9 +1696,9 @@ impl VeilidAPI { } else if command == "info" { self.debug_record_info(args).await } else if command == "watch" { - self.debug_record_info(args).await + self.debug_record_watch(args).await } else if command == "cancel" { - self.debug_record_info(args).await + self.debug_record_cancel(args).await } else { Ok(">>> Unknown command\n".to_owned()) } From 8ed3f0672ea6ef9c0396a0a7712cf00aaa834d79 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 9 Dec 2023 12:27:44 -0500 Subject: [PATCH 20/67] fix clear screen --- Cargo.lock | 42 ++-- veilid-cli/Cargo.toml | 5 +- veilid-cli/src/command_processor.rs | 8 +- veilid-cli/src/main.rs | 6 +- veilid-cli/src/ui.rs | 193 ++++++++++++++---- .../src/network_manager/native/igd_manager.rs | 2 +- veilid-core/src/veilid_api/debug.rs | 15 +- veilid-tools/src/network_interfaces/apple.rs | 2 +- 8 files changed, 196 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05f41c32..f97f6045 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,12 +242,6 @@ dependencies = [ "password-hash", ] -[[package]] -name = "arraydeque" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0ffd3d69bd89910509a5d31d1f1353f38ccffdd116dd0099bbd6627f7bd8ad8" - [[package]] name = "arrayref" version = "0.3.7" @@ -1300,20 +1294,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "cursive-flexi-logger-view" -version = "0.5.0" -source = "git+https://gitlab.com/veilid/cursive-flexi-logger-view.git#7c931536b8c57339011bbe2ee604e431c91c0aa8" -dependencies = [ - "arraydeque", - "cursive_core", - "flexi_logger", - "lazy_static", - "log", - "time", - "unicode-width", -] - [[package]] name = "cursive-macros" version = "0.1.0" @@ -2233,6 +2213,15 @@ dependencies = [ "ahash 0.7.7", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.6", +] + [[package]] name = "hashbrown" version = "0.14.2" @@ -2835,6 +2824,15 @@ dependencies = [ "value-bag", ] +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + [[package]] name = "lru-cache" version = "0.1.2" @@ -5491,7 +5489,6 @@ dependencies = [ "config", "crossbeam-channel", "cursive", - "cursive-flexi-logger-view", "cursive_buffered_backend", "cursive_table_view", "data-encoding", @@ -5503,6 +5500,8 @@ dependencies = [ "indent", "json", "log", + "lru", + "owning_ref", "parking_lot 0.12.1", "serde", "serde_derive", @@ -5511,6 +5510,7 @@ dependencies = [ "thiserror", "tokio", "tokio-util", + "unicode-width", "veilid-bugsalot", "veilid-tools", ] diff --git a/veilid-cli/Cargo.toml b/veilid-cli/Cargo.toml index 10f08a55..0c0a606a 100644 --- a/veilid-cli/Cargo.toml +++ b/veilid-cli/Cargo.toml @@ -34,7 +34,7 @@ cursive = { git = "https://gitlab.com/veilid/cursive.git", default-features = fa "toml", "ansi", ] } -cursive-flexi-logger-view = { git = "https://gitlab.com/veilid/cursive-flexi-logger-view.git" } + cursive_buffered_backend = { git = "https://gitlab.com/veilid/cursive-buffered-backend.git" } # cursive-multiplex = "0.6.0" # cursive_tree_view = "0.6.0" @@ -64,6 +64,9 @@ data-encoding = { version = "^2" } indent = { version = "0.1.1" } chrono = "0.4.26" +owning_ref = "0.4.1" +unicode-width = "0.1.10" +lru = "0.10.0" [dev-dependencies] serial_test = "^2" diff --git a/veilid-cli/src/command_processor.rs b/veilid-cli/src/command_processor.rs index 0fc1e2f8..7da88877 100644 --- a/veilid-cli/src/command_processor.rs +++ b/veilid-cli/src/command_processor.rs @@ -189,7 +189,7 @@ Server Debug Commands: ui.send_callback(callback); } Err(e) => { - ui.add_node_event(Level::Error, e.to_string()); + ui.add_node_event(Level::Error, format!("{}\n", e)); ui.send_callback(callback); } } @@ -424,7 +424,7 @@ Server Debug Commands: self.inner().ui_sender.add_node_event( log_level, format!( - "{}: {}{}", + "{}: {}{}\n", log["log_level"].as_str().unwrap_or("???"), log["message"].as_str().unwrap_or("???"), if let Some(bt) = log["backtrace"].as_str() { @@ -466,7 +466,7 @@ Server Debug Commands: self.inner().ui_sender.add_node_event( Level::Info, format!( - "AppMessage ({:?}): {}{}", + "AppMessage ({:?}): {}{}\n", msg["sender"], strmsg, if truncated { "..." } else { "" } @@ -506,7 +506,7 @@ Server Debug Commands: self.inner().ui_sender.add_node_event( Level::Info, format!( - "AppCall ({:?}) id = {:016x} : {}{}", + "AppCall ({:?}) id = {:016x} : {}{}\n", call["sender"], id, strmsg, diff --git a/veilid-cli/src/main.rs b/veilid-cli/src/main.rs index 4f46cfdd..35e00e88 100644 --- a/veilid-cli/src/main.rs +++ b/veilid-cli/src/main.rs @@ -9,6 +9,7 @@ use clap::{Parser, ValueEnum}; use flexi_logger::*; use std::{net::ToSocketAddrs, path::PathBuf}; +mod cached_text_view; mod client_api_connection; mod command_processor; mod peers_table_view; @@ -91,7 +92,6 @@ fn main() -> Result<(), String> { let logger = Logger::with(specbuilder.build()); if settings.logging.terminal.enabled { - let flv = sivui.cursive_flexi_logger(); if settings.logging.file.enabled { std::fs::create_dir_all(settings.logging.file.directory.clone()) .map_err(map_to_string)?; @@ -100,13 +100,13 @@ fn main() -> Result<(), String> { FileSpec::default() .directory(settings.logging.file.directory.clone()) .suppress_timestamp(), - flv, + Box::new(uisender.clone()), ) .start() .expect("failed to initialize logger!"); } else { logger - .log_to_writer(flv) + .log_to_writer(Box::new(uisender.clone())) .start() .expect("failed to initialize logger!"); } diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index d8f07351..95d1b60a 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -7,13 +7,16 @@ use cursive::align::*; use cursive::event::*; use cursive::theme::*; use cursive::traits::*; +use cursive::utils::markup::ansi; use cursive::utils::markup::StyledString; use cursive::view::SizeConstraint; use cursive::views::*; use cursive::Cursive; use cursive::CursiveRunnable; -use cursive_flexi_logger_view::{CursiveLogWriter, FlexiLoggerView}; +use flexi_logger::writers::LogWriter; +use flexi_logger::DeferredNow; // use cursive_multiplex::*; +use crate::cached_text_view::*; use chrono::{Datelike, Timelike}; use std::collections::{HashMap, VecDeque}; use std::io::Write; @@ -50,6 +53,7 @@ impl Dirty { } pub type UICallback = Box; +pub type NodeEventsPanel = Panel>>>; static START_TIME: AtomicU64 = AtomicU64::new(0); @@ -219,12 +223,25 @@ impl UI { }); } fn clear_handler(siv: &mut Cursive) { - cursive_flexi_logger_view::clear_log(); + Self::node_events_view(siv).set_content(""); UI::update_cb(siv); } - fn node_events_panel(s: &mut Cursive) -> ViewRef>> { + + //////////////////////////////////////////////////////////////////////////////////////////////// + // Selectors + + // fn main_layout(s: &mut Cursive) -> ViewRef { + // s.find_name("main-layout").unwrap() + // } + fn node_events_panel(s: &mut Cursive) -> ViewRef { s.find_name("node-events-panel").unwrap() } + fn node_events_view(s: &mut Cursive) -> ViewRef { + s.find_name("node-events-view").unwrap() + } + // fn node_events_scroll_view(s: &mut Cursive) -> ViewRef> { + // s.find_name("node-events-scroll-view").unwrap() + // } fn command_line(s: &mut Cursive) -> ViewRef { s.find_name("command-line").unwrap() } @@ -237,6 +254,27 @@ impl UI { fn peers(s: &mut Cursive) -> ViewRef { s.find_name("peers").unwrap() } + fn connection_address(s: &mut Cursive) -> ViewRef { + s.find_name("connection-address").unwrap() + } + fn connection_dialog(s: &mut Cursive) -> ViewRef { + s.find_name("connection-dialog").unwrap() + } + //////////////////////////////////////////////////////////////////////////////////////////////// + + pub fn push_styled(s: &mut Cursive, styled_string: StyledString) { + let mut ctv = UI::node_events_view(s); + ctv.append(styled_string) + } + + pub fn push_ansi_lines(s: &mut Cursive, starting_style: Style, lines: String) { + let mut ctv = UI::node_events_view(s); + let (spanned_string, _end_style) = ansi::parse_with_starting_style(starting_style, lines); + ctv.append(spanned_string); + } + + //////////////////////////////////////////////////////////////////////////////////////////////// + fn render_attachment_state(inner: &mut UIInner) -> String { let att = match inner.ui_state.attachment_state.get().as_str() { "Detached" => "[----]", @@ -351,16 +389,17 @@ impl UI { return; } // run command - - cursive_flexi_logger_view::parse_lines_to_log( + UI::push_ansi_lines( + s, ColorStyle::primary().into(), - format!("> {} {}", UI::cli_ts(Self::get_start_time()), text), + format!("{}> {}\n", UI::cli_ts(Self::get_start_time()), text), ); match Self::run_command(s, text) { Ok(_) => {} Err(e) => { let color = *Self::inner_mut(s).log_colors.get(&Level::Error).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log( + UI::push_ansi_lines( + s, color.into(), format!(" {} Error: {}", UI::cli_ts(Self::get_start_time()), e), ); @@ -446,7 +485,7 @@ impl UI { } fn submit_connection_address(s: &mut Cursive) { - let edit = s.find_name::("connection-address").unwrap(); + let edit = Self::connection_address(s); let addr = (*edit.get_content()).clone(); let sa = match addr.parse::() { Ok(sa) => Some(sa), @@ -475,7 +514,8 @@ impl UI { && std::io::stdout().flush().is_ok() { let color = *Self::inner_mut(s).log_colors.get(&Level::Info).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log( + UI::push_ansi_lines( + s, color.into(), format!( ">> {} Copied: {}", @@ -491,7 +531,8 @@ impl UI { // X11/Wayland/other system copy if clipboard.set_text(text.as_ref()).is_ok() { let color = *Self::inner_mut(s).log_colors.get(&Level::Info).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log( + UI::push_ansi_lines( + s, color.into(), format!( ">> {} Copied: {}", @@ -501,7 +542,8 @@ impl UI { ); } else { let color = *Self::inner_mut(s).log_colors.get(&Level::Warn).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log( + UI::push_ansi_lines( + s, color.into(), format!( ">> {} Could not copy to clipboard", @@ -622,7 +664,7 @@ impl UI { return true; } if reset { - let mut dlg = s.find_name::("connection-dialog").unwrap(); + let mut dlg = Self::connection_dialog(s); dlg.clear_buttons(); return true; } @@ -644,20 +686,20 @@ impl UI { Some(addr) => addr.to_string(), }; debug!("address is {}", addr); - let mut edit = s.find_name::("connection-address").unwrap(); + let mut edit = Self::connection_address(s); edit.set_content(addr); edit.set_enabled(true); - let mut dlg = s.find_name::("connection-dialog").unwrap(); + let mut dlg = Self::connection_dialog(s); dlg.add_button("Connect", Self::submit_connection_address); } ConnectionState::Connected(_, _) => {} ConnectionState::Retrying(addr, _) => { // - let mut edit = s.find_name::("connection-address").unwrap(); + let mut edit = Self::connection_address(s); debug!("address is {}", addr); edit.set_content(addr.to_string()); edit.set_enabled(false); - let mut dlg = s.find_name::("connection-dialog").unwrap(); + let mut dlg = Self::connection_dialog(s); dlg.add_button("Cancel", |s| { Self::command_processor(s).cancel_reconnect(); }); @@ -837,9 +879,23 @@ impl UI { START_TIME.load(Ordering::Relaxed) } - pub fn new(node_log_scrollback: usize, settings: &Settings) -> (Self, UISender) { - cursive_flexi_logger_view::resize(node_log_scrollback); + fn make_node_events_panel( + node_log_scrollback: usize, + ) -> ResizedView> { + Panel::new( + CachedTextView::new("", node_log_scrollback) + .with_name("node-events-view") + .scrollable() + .scroll_strategy(cursive::view::ScrollStrategy::StickToBottom) + .with_name("node-events-scroll-view"), + ) + .title_position(HAlign::Left) + .title("Node Events") + .with_name("node-events-panel") + .full_screen() + } + pub fn new(node_log_scrollback: usize, settings: &Settings) -> (Self, UISender) { UI::set_start_time(); // Instantiate the cursive runnable let runnable = CursiveRunnable::new( @@ -874,6 +930,7 @@ impl UI { let ui_sender = UISender { inner: this.inner.clone(), cb_sink, + colors: default_log_colors(), }; let mut inner = this.inner.lock(); @@ -882,13 +939,7 @@ impl UI { this.siv.set_user_data(this.inner.clone()); // Create layouts - - let node_events_view = Panel::new(FlexiLoggerView::new_scrollable()) - .title_position(HAlign::Left) - .title("Node Events") - .with_name("node-events-panel") - .full_screen(); - + let node_events_view = Self::make_node_events_panel(node_log_scrollback); let mut peers_table_view = PeersTableView::new() .column(PeerTableColumn::NodeId, "Node Id", |c| c.width(48)) .column(PeerTableColumn::Address, "Address", |c| c) @@ -967,7 +1018,8 @@ impl UI { .child(TextView::new(version)), ); - this.siv.add_fullscreen_layer(mainlayout); + this.siv + .add_fullscreen_layer(mainlayout.with_name("main-layout")); UI::setup_colors(&mut this.siv, &mut inner, settings); UI::setup_quit_handler(&mut this.siv); @@ -978,11 +1030,7 @@ impl UI { (this, ui_sender) } - pub fn cursive_flexi_logger(&self) -> Box { - let mut flv = cursive_flexi_logger_view::cursive_flexi_logger(self.siv.cb_sink().clone()); - flv.set_colors(self.inner.lock().log_colors.clone()); - flv - } + pub fn set_command_processor(&mut self, cmdproc: CommandProcessor) { let mut inner = self.inner.lock(); inner.cmdproc = Some(cmdproc); @@ -999,10 +1047,22 @@ impl UI { type CallbackSink = Box; +/// Default log colors +fn default_log_colors() -> HashMap { + let mut colors = HashMap::::new(); + colors.insert(Level::Trace, Color::Dark(BaseColor::Green)); + colors.insert(Level::Debug, Color::Dark(BaseColor::Cyan)); + colors.insert(Level::Info, Color::Dark(BaseColor::Blue)); + colors.insert(Level::Warn, Color::Dark(BaseColor::Yellow)); + colors.insert(Level::Error, Color::Dark(BaseColor::Red)); + colors +} + #[derive(Clone)] pub struct UISender { inner: Arc>, cb_sink: Sender, + colors: HashMap, } impl UISender { @@ -1094,14 +1154,71 @@ impl UISender { } pub fn add_node_event(&self, log_color: Level, event: String) { - { + let color = { let inner = self.inner.lock(); - let color = *inner.log_colors.get(&log_color).unwrap(); - cursive_flexi_logger_view::parse_lines_to_log( - color.into(), - format!("{}: {}", UI::cli_ts(UI::get_start_time()), event), - ); + *inner.log_colors.get(&log_color).unwrap() + }; + + let _ = self.push_styled_lines( + color.into(), + format!("{}: {}\n", UI::cli_ts(UI::get_start_time()), event), + ); + } + + pub fn push_styled(&self, styled_string: StyledString) -> std::io::Result<()> { + let res = self.cb_sink.send(Box::new(move |s| { + UI::push_styled(s, styled_string); + })); + if res.is_err() { + return Err(std::io::Error::from(std::io::ErrorKind::BrokenPipe)); } - let _ = self.cb_sink.send(Box::new(UI::update_cb)); + Ok(()) + } + + pub fn push_styled_lines(&self, starting_style: Style, lines: String) -> std::io::Result<()> { + let res = self.cb_sink.send(Box::new(move |s| { + UI::push_ansi_lines(s, starting_style, lines); + })); + if res.is_err() { + return Err(std::io::Error::from(std::io::ErrorKind::BrokenPipe)); + } + Ok(()) + } +} +impl LogWriter for UISender { + fn write(&self, _now: &mut DeferredNow, record: &Record) -> std::io::Result<()> { + let color = *self.colors.get(&record.level()).unwrap(); + + let args = format!("{}", &record.args()); + + let mut line = StyledString::new(); + let mut indent = 0; + let levstr = format!("{}: ", record.level()); + indent += levstr.len(); + line.append_styled(levstr, color); + let filestr = format!( + "{}:{} ", + record.file().unwrap_or("(unnamed)"), + record.line().unwrap_or(0), + ); + indent += filestr.len(); + line.append_plain(filestr); + + for argline in args.lines() { + line.append_styled(argline, color); + self.push_styled(line)?; + line = StyledString::new(); + line.append_plain(" ".repeat(indent)); + } + Ok(()) + } + + fn flush(&self) -> std::io::Result<()> { + // we are not buffering + Ok(()) + } + + fn max_log_level(&self) -> log::LevelFilter { + log::LevelFilter::max() } } diff --git a/veilid-core/src/network_manager/native/igd_manager.rs b/veilid-core/src/network_manager/native/igd_manager.rs index 302dba33..19c9f519 100644 --- a/veilid-core/src/network_manager/native/igd_manager.rs +++ b/veilid-core/src/network_manager/native/igd_manager.rs @@ -401,7 +401,7 @@ impl IGDManager { let desc = this.get_description(k.llpt, k.local_port); match gw.add_port(convert_llpt(k.llpt), v.mapped_port, SocketAddr::new(local_ip, k.local_port), (UPNP_MAPPING_LIFETIME_MS + 999) / 1000, &desc) { Ok(()) => { - log_net!(debug "renewed mapped port {:?} -> {:?}", v, k); + log_net!("renewed mapped port {:?} -> {:?}", v, k); inner.port_maps.insert(k, PortMapValue { ext_ip: v.ext_ip, diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 415d1ea0..2d0ece6e 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -1499,8 +1499,7 @@ impl VeilidAPI { let mut dc = DEBUG_CACHE.lock(); dc.opened_record_contexts.insert(*record.key(), rc); - debug!("DHT Record Opened:\n{:#?}", record); - Ok(format!("Opened: {:?}", record)) + Ok(format!("Opened: {} : {:?}", key, record)) } async fn debug_record_close(&self, args: Vec) -> VeilidAPIResult { @@ -1511,7 +1510,6 @@ impl VeilidAPI { return Ok(format!("Can't close DHT record: {}", e)); }; - debug!("DHT Record Closed:\n{:#?}", key); Ok(format!("Closed: {:?}", key)) } @@ -1648,7 +1646,7 @@ impl VeilidAPI { Ok(v) => v, }; - Ok(format!("Expiration at: {:?}", debug_ts(ts.as_u64()))) + Ok(format!("Success: expiration={:?}", debug_ts(ts.as_u64()))) } async fn debug_record_cancel(&self, args: Vec) -> VeilidAPIResult { @@ -1665,10 +1663,11 @@ impl VeilidAPI { Ok(v) => v, }; - Ok(format!( - "Still Active: {:?}", - if still_active { "true" } else { "false" } - )) + Ok(if still_active { + "Watch partially cancelled".to_owned() + } else { + "Watch cancelled".to_owned() + }) } async fn debug_record(&self, args: String) -> VeilidAPIResult { diff --git a/veilid-tools/src/network_interfaces/apple.rs b/veilid-tools/src/network_interfaces/apple.rs index 1a7d5a75..95f8e42b 100644 --- a/veilid-tools/src/network_interfaces/apple.rs +++ b/veilid-tools/src/network_interfaces/apple.rs @@ -485,7 +485,7 @@ impl PlatformSupportApple { ) { Ok(v) => v, Err(e) => { - log_net!(error "failed to get address flags: {}", e); + log_net!(debug "failed to get address flags for ifname={}, ifaddr={:?} : {}", ifname, ifaddr.ifa_addr, e); continue; } }; From 6232355cddda45889127577227317fd942205956 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 9 Dec 2023 12:33:18 -0500 Subject: [PATCH 21/67] cleanup output --- veilid-cli/src/command_processor.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/veilid-cli/src/command_processor.rs b/veilid-cli/src/command_processor.rs index 7da88877..0fc1e2f8 100644 --- a/veilid-cli/src/command_processor.rs +++ b/veilid-cli/src/command_processor.rs @@ -189,7 +189,7 @@ Server Debug Commands: ui.send_callback(callback); } Err(e) => { - ui.add_node_event(Level::Error, format!("{}\n", e)); + ui.add_node_event(Level::Error, e.to_string()); ui.send_callback(callback); } } @@ -424,7 +424,7 @@ Server Debug Commands: self.inner().ui_sender.add_node_event( log_level, format!( - "{}: {}{}\n", + "{}: {}{}", log["log_level"].as_str().unwrap_or("???"), log["message"].as_str().unwrap_or("???"), if let Some(bt) = log["backtrace"].as_str() { @@ -466,7 +466,7 @@ Server Debug Commands: self.inner().ui_sender.add_node_event( Level::Info, format!( - "AppMessage ({:?}): {}{}\n", + "AppMessage ({:?}): {}{}", msg["sender"], strmsg, if truncated { "..." } else { "" } @@ -506,7 +506,7 @@ Server Debug Commands: self.inner().ui_sender.add_node_event( Level::Info, format!( - "AppCall ({:?}) id = {:016x} : {}{}\n", + "AppCall ({:?}) id = {:016x} : {}{}", call["sender"], id, strmsg, From 4acb760c10f33cd737dc2fc59563df90ecc80340 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 9 Dec 2023 13:17:57 -0500 Subject: [PATCH 22/67] missing file --- veilid-cli/src/cached_text_view.rs | 565 +++++++++++++++++++++++++++++ 1 file changed, 565 insertions(+) create mode 100644 veilid-cli/src/cached_text_view.rs diff --git a/veilid-cli/src/cached_text_view.rs b/veilid-cli/src/cached_text_view.rs new file mode 100644 index 00000000..f944e05a --- /dev/null +++ b/veilid-cli/src/cached_text_view.rs @@ -0,0 +1,565 @@ +use std::ops::Deref; +use std::sync::Arc; +use std::sync::{Mutex, MutexGuard}; + +use cursive::align::*; +use cursive::theme::StyleType; +use cursive::utils::lines::spans::{LinesIterator, Row}; +use cursive::utils::markup::StyledString; +use cursive::view::{SizeCache, View}; +use cursive::{Printer, Vec2, With, XY}; +use owning_ref::{ArcRef, OwningHandle}; +use unicode_width::UnicodeWidthStr; + +// Content type used internally for caching and storage +type InnerContentType = Arc; + +/// Provides access to the content of a [`TextView`]. +/// +/// [`TextView`]: struct.TextView.html +/// +/// Cloning this object will still point to the same content. +/// +/// # Examples +/// +/// ```rust +/// # use cursive::views::{TextView, TextContent}; +/// let mut content = TextContent::new("content"); +/// let view = TextView::new_with_content(content.clone()); +/// +/// // Later, possibly in a different thread +/// content.set_content("new content"); +/// assert!(view.get_content().source().contains("new")); +/// ``` +#[derive(Clone)] +pub struct TextContent { + content: Arc>, +} + +impl TextContent { + /// Creates a new text content around the given value. + /// + /// Parses the given value. + pub fn new(content: S) -> Self + where + S: Into, + { + let content = Arc::new(content.into()); + + TextContent { + content: Arc::new(Mutex::new(TextContentInner { + content_value: content, + content_cache: Arc::new(StyledString::default()), + size_cache: None, + })), + } + } +} + +/// A reference to the text content. +/// +/// This can be deref'ed into a [`StyledString`]. +/// +/// [`StyledString`]: ../utils/markup/type.StyledString.html +/// +/// This keeps the content locked. Do not store this! +pub struct TextContentRef { + _handle: OwningHandle>, MutexGuard<'static, TextContentInner>>, + // We also need to keep a copy of Arc so `deref` can return + // a reference to the `StyledString` + data: Arc, +} + +impl Deref for TextContentRef { + type Target = StyledString; + + fn deref(&self) -> &StyledString { + self.data.as_ref() + } +} + +#[allow(dead_code)] +impl TextContent { + /// Replaces the content with the given value. + pub fn set_content(&self, content: S) + where + S: Into, + { + self.with_content(|c| { + *c = content.into(); + }); + } + + /// Append `content` to the end of a `TextView`. + pub fn append(&self, content: S) + where + S: Into, + { + self.with_content(|c| { + // This will only clone content if content_cached and content_value + // are sharing the same underlying Rc. + c.append(content); + }) + } + + /// Returns a reference to the content. + /// + /// This locks the data while the returned value is alive, + /// so don't keep it too long. + pub fn get_content(&self) -> TextContentRef { + TextContentInner::get_content(&self.content) + } + + /// Apply the given closure to the inner content, and bust the cache afterward. + pub fn with_content(&self, f: F) -> O + where + F: FnOnce(&mut StyledString) -> O, + { + self.with_content_inner(|c| f(Arc::make_mut(&mut c.content_value))) + } + + /// Apply the given closure to the inner content, and bust the cache afterward. + fn with_content_inner(&self, f: F) -> O + where + F: FnOnce(&mut TextContentInner) -> O, + { + let mut content = self.content.lock().unwrap(); + + let out = f(&mut content); + + content.size_cache = None; + + out + } +} + +/// Internel representation of the content for a `TextView`. +/// +/// This is mostly just a `StyledString`. +/// +/// Can be shared (through a `Arc`). +struct TextContentInner { + // content: String, + content_value: InnerContentType, + content_cache: InnerContentType, + + // We keep the cache here so it can be busted when we change the content. + size_cache: Option>, +} + +impl TextContentInner { + /// From a shareable content (Arc + Mutex), return a + fn get_content(content: &Arc>) -> TextContentRef { + let arc_ref: ArcRef> = ArcRef::new(Arc::clone(content)); + + let _handle = + OwningHandle::new_with_fn(arc_ref, |mutex| unsafe { (*mutex).lock().unwrap() }); + + let data = Arc::clone(&_handle.content_value); + + TextContentRef { _handle, data } + } + + fn is_cache_valid(&self, size: Vec2) -> bool { + match self.size_cache { + None => false, + Some(ref last) => last.x.accept(size.x) && last.y.accept(size.y), + } + } + + fn get_cache(&self) -> &InnerContentType { + &self.content_cache + } +} + +/// A simple view showing a fixed text. +/// +/// # Examples +/// +/// ```rust +/// use cursive::Cursive; +/// use cursive_cached_text_view::CachedTextView; +/// let mut siv = Cursive::new(); +/// +/// siv.add_layer(CachedTextView::new("Hello world!", 5)); +/// ``` +pub struct CachedTextView { + cache: TinyCache>, + content: TextContent, + + align: Align, + + style: StyleType, + + // True if we can wrap long lines. + wrap: bool, + + // ScrollBase make many scrolling-related things easier + width: Option, +} + +#[allow(dead_code)] +impl CachedTextView { + /// Creates a new TextView with the given content. + pub fn new(content: S, cache_size: usize) -> Self + where + S: Into, + { + Self::new_with_content(TextContent::new(content), cache_size) + } + + /// Creates a new TextView using the given `TextContent`. + /// + /// If you kept a clone of the given content, you'll be able to update it + /// remotely. + /// + /// # Examples + /// + /// ```rust + /// # use cursive_cached_text_view::{TextContent, CachedTextView}; + /// let mut content = TextContent::new("content"); + /// let view = CachedTextView::new_with_content(content.clone(), 5); + /// + /// // Later, possibly in a different thread + /// content.set_content("new content"); + /// assert!(view.get_content().source().contains("new")); + /// ``` + pub fn new_with_content(content: TextContent, cache_size: usize) -> Self { + CachedTextView { + cache: TinyCache::new(cache_size), + content, + style: StyleType::default(), + wrap: true, + align: Align::top_left(), + width: None, + } + } + + /// Creates a new empty `TextView`. + pub fn empty() -> Self { + CachedTextView::new("", 5) + } + + /// Sets the style for the content. + pub fn set_style>(&mut self, style: S) { + self.cache.clear(); + self.style = style.into(); + } + + /// Sets the style for the entire content. + /// + /// Chainable variant. + #[must_use] + pub fn style>(self, style: S) -> Self { + self.with(|s| s.set_style(style)) + } + + /// Disables content wrap for this view. + /// + /// This may be useful if you want horizontal scrolling. + #[must_use] + pub fn no_wrap(self) -> Self { + self.with(|s| s.set_content_wrap(false)) + } + + /// Controls content wrap for this view. + /// + /// If `true` (the default), text will wrap long lines when needed. + pub fn set_content_wrap(&mut self, wrap: bool) { + self.cache.clear(); + self.wrap = wrap; + } + + /// Sets the horizontal alignment for this view. + #[must_use] + pub fn h_align(mut self, h: HAlign) -> Self { + self.align.h = h; + + self + } + + /// Sets the vertical alignment for this view. + #[must_use] + pub fn v_align(mut self, v: VAlign) -> Self { + self.align.v = v; + + self + } + + /// Sets the alignment for this view. + #[must_use] + pub fn align(mut self, a: Align) -> Self { + self.align = a; + + self + } + + /// Center the text horizontally and vertically inside the view. + #[must_use] + pub fn center(mut self) -> Self { + self.align = Align::center(); + self + } + + /// Replace the text in this view. + /// + /// Chainable variant. + #[must_use] + pub fn content(self, content: S) -> Self + where + S: Into, + { + self.with(|s| s.set_content(content)) + } + + /// Replace the text in this view. + pub fn set_content(&mut self, content: S) + where + S: Into, + { + self.cache.clear(); + self.content.set_content(content); + } + + /// Append `content` to the end of a `TextView`. + pub fn append(&mut self, content: S) + where + S: Into, + { + self.cache.clear(); + self.content.append(content); + } + + /// Returns the current text in this view. + pub fn get_content(&self) -> TextContentRef { + TextContentInner::get_content(&self.content.content) + } + + /// Returns a shared reference to the content, allowing content mutation. + pub fn get_shared_content(&mut self) -> TextContent { + // We take &mut here without really needing it, + // because it sort of "makes sense". + TextContent { + content: Arc::clone(&self.content.content), + } + } + + // This must be non-destructive, as it may be called + // multiple times during layout. + fn compute_rows(&mut self, size: Vec2) { + let size = if self.wrap { size } else { Vec2::max_value() }; + + let mut content = self.content.content.lock().unwrap(); + if content.is_cache_valid(size) { + return; + } + + // Completely bust the cache + // Just in case we fail, we don't want to leave a bad cache. + content.size_cache = None; + content.content_cache = Arc::clone(&content.content_value); + + let rows = self.cache.compute(size.x, || { + LinesIterator::new(content.get_cache().as_ref(), size.x).collect() + }); + + // Desired width + self.width = if rows.iter().any(|row| row.is_wrapped) { + // If any rows are wrapped, then require the full width. + Some(size.x) + } else { + rows.iter().map(|row| row.width).max() + } + } +} + +impl View for CachedTextView { + fn draw(&self, printer: &Printer) { + let rows = if let Some(rows) = self.cache.last() { + rows + } else { + return; + }; + let h = rows.len(); + // If the content is smaller than the view, align it somewhere. + let offset = self.align.v.get_offset(h, printer.size.y); + let printer = &printer.offset((0, offset)); + + let content = self.content.content.lock().unwrap(); + + printer.with_style(self.style, |printer| { + for (y, row) in rows + .iter() + .enumerate() + .skip(printer.content_offset.y) + .take(printer.output_size.y) + { + let l = row.width; + let mut x = self.align.h.get_offset(l, printer.size.x); + + for span in row.resolve_stream(content.get_cache().as_ref()) { + printer.with_style(*span.attr, |printer| { + printer.print((x, y), span.content); + x += span.content.width(); + }); + } + } + }); + } + + fn layout(&mut self, size: Vec2) { + // Compute the text rows. + self.compute_rows(size); + + let num_rows = self.cache.last().map(|rows| rows.len()).unwrap_or(0); + + // The entire "virtual" size (includes all rows) + let my_size = Vec2::new(self.width.unwrap_or(0), num_rows); + + // Build a fresh cache. + let mut content = self.content.content.lock().unwrap(); + content.size_cache = Some(SizeCache::build(my_size, size)); + } + + fn needs_relayout(&self) -> bool { + let content = self.content.content.lock().unwrap(); + content.size_cache.is_none() + } + + fn required_size(&mut self, size: Vec2) -> Vec2 { + self.compute_rows(size); + + let num_rows = self.cache.last().map(|rows| rows.len()).unwrap_or(0); + + Vec2::new(self.width.unwrap_or(0), num_rows) + } +} + +struct TinyCache { + size: usize, + data: Vec<(usize, K, V)>, +} + +impl TinyCache { + fn new(size: usize) -> Self { + TinyCache { + size, + data: Vec::with_capacity(size), + } + } + + fn get_key_index(&self, key: &K) -> Option + where + K: Eq, + { + self.data.iter().rposition(|(_, k, _)| k == key) + } + + fn compute(&mut self, key: K, f: impl FnOnce() -> V) -> &V + where + K: Eq, + { + if let Some(index) = self.get_key_index(&key) { + self.data[index].0 += 1; + return &self.data[index].2; + } + + let v = f(); + self.clean(); + self.data.push((0, key, v)); + &self.data.last().as_ref().unwrap().2 + } + + fn clean(&mut self) { + if self.data.len() < self.size { + return; + } + let index = self + .data + .iter() + .enumerate() + .min_by_key(|(_, (count, _, _))| *count) + .map(|(i, _)| i); + + if let Some(index) = index { + self.data.swap_remove(index); + } + } + + fn clear(&mut self) { + self.data.clear(); + } + + fn last(&self) -> Option<&V> { + self.data.last().map(|(_, _, v)| v) + } + + #[cfg(test)] + fn len(&self) -> usize { + self.data.len() + } + + #[cfg(test)] + fn is_empty(&self) -> bool { + self.data.is_empty() + } + + #[cfg(test)] + fn keys(&self) -> Vec<(&K, usize)> { + self.data + .iter() + .map(|(count, key, _)| (key, *count)) + .collect() + } +} + +#[cfg(test)] +mod tests { + use cursive::theme::Style; + use cursive::Vec2; + + use super::*; + + #[test] + fn sanity() { + let text_view = CachedTextView::new("", 5); + assert_eq!(text_view.get_content().data.spans().len(), 1); + } + + #[test] + fn test_cache() { + let mut text_view = CachedTextView::new("sample", 3); + assert!(text_view.cache.is_empty()); + + text_view.compute_rows(Vec2::new(0, 0)); + assert_eq!(text_view.cache.len(), 1); + text_view.compute_rows(Vec2::new(0, 0)); + assert_eq!(text_view.cache.len(), 1); + + text_view.compute_rows(Vec2::new(1, 0)); + assert_eq!(text_view.cache.len(), 2); + + text_view.compute_rows(Vec2::new(2, 0)); + assert_eq!(text_view.cache.len(), 3); + + text_view.compute_rows(Vec2::new(3, 0)); + assert_eq!(text_view.cache.len(), 3); + + assert_eq!(text_view.cache.keys(), [(&0, 1), (&2, 0), (&3, 0)]); + + text_view.set_content(""); + assert_eq!(text_view.cache.len(), 0); + text_view.compute_rows(Vec2::new(0, 0)); + + text_view.append("sample"); + assert_eq!(text_view.cache.len(), 0); + text_view.compute_rows(Vec2::new(0, 0)); + + text_view.set_content_wrap(false); + assert_eq!(text_view.cache.len(), 0); + text_view.compute_rows(Vec2::new(0, 0)); + + text_view.set_style(Style::view()); + assert_eq!(text_view.cache.len(), 0); + } +} From b791a82ec61e39aa2e88433363b4f72a63f9a427 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 9 Dec 2023 16:47:43 -0500 Subject: [PATCH 23/67] cap scrollback --- veilid-cli/src/cached_text_view.rs | 169 ++++++++++++++++++++--------- veilid-cli/src/settings.rs | 2 +- veilid-cli/src/ui.rs | 24 ++-- 3 files changed, 133 insertions(+), 62 deletions(-) diff --git a/veilid-cli/src/cached_text_view.rs b/veilid-cli/src/cached_text_view.rs index f944e05a..7f9b6d6c 100644 --- a/veilid-cli/src/cached_text_view.rs +++ b/veilid-cli/src/cached_text_view.rs @@ -1,3 +1,4 @@ +use std::collections::VecDeque; use std::ops::Deref; use std::sync::Arc; use std::sync::{Mutex, MutexGuard}; @@ -12,7 +13,32 @@ use owning_ref::{ArcRef, OwningHandle}; use unicode_width::UnicodeWidthStr; // Content type used internally for caching and storage -type InnerContentType = Arc; +type ContentType = VecDeque; +type InnerContentType = Arc; +type CacheType = StyledString; +type InnerCacheType = Arc; + +/// A reference to the text content. +/// +/// This can be deref'ed into a [`StyledString`]. +/// +/// [`StyledString`]: ../utils/markup/type.StyledString.html +/// +/// This keeps the content locked. Do not store this! +pub struct TextContentRef { + _handle: OwningHandle>, MutexGuard<'static, TextContentInner>>, + // We also need to keep a copy of Arc so `deref` can return + // a reference to the `StyledString` + data: Arc>, +} + +impl Deref for TextContentRef { + type Target = VecDeque; + + fn deref(&self) -> &VecDeque { + self.data.as_ref() + } +} /// Provides access to the content of a [`TextView`]. /// @@ -36,69 +62,75 @@ pub struct TextContent { content: Arc>, } +#[allow(dead_code)] + impl TextContent { /// Creates a new text content around the given value. /// /// Parses the given value. pub fn new(content: S) -> Self where - S: Into, + S: Into, { let content = Arc::new(content.into()); TextContent { content: Arc::new(Mutex::new(TextContentInner { content_value: content, - content_cache: Arc::new(StyledString::default()), + content_cache: Arc::new(CacheType::default()), size_cache: None, })), } } -} -/// A reference to the text content. -/// -/// This can be deref'ed into a [`StyledString`]. -/// -/// [`StyledString`]: ../utils/markup/type.StyledString.html -/// -/// This keeps the content locked. Do not store this! -pub struct TextContentRef { - _handle: OwningHandle>, MutexGuard<'static, TextContentInner>>, - // We also need to keep a copy of Arc so `deref` can return - // a reference to the `StyledString` - data: Arc, -} - -impl Deref for TextContentRef { - type Target = StyledString; - - fn deref(&self) -> &StyledString { - self.data.as_ref() - } -} - -#[allow(dead_code)] -impl TextContent { /// Replaces the content with the given value. pub fn set_content(&self, content: S) where - S: Into, + S: Into, { self.with_content(|c| { *c = content.into(); }); } - /// Append `content` to the end of a `TextView`. - pub fn append(&self, content: S) + /// Append `line` to the end of a `TextView`. + pub fn append_line(&self, line: S) where S: Into, { self.with_content(|c| { - // This will only clone content if content_cached and content_value - // are sharing the same underlying Rc. - c.append(content); + c.push_back(line.into()); + }) + } + + /// Append `lines` to the end of a `TextView`. + pub fn append_lines(&self, lines: S) + where + S: Iterator, + I: Into, + { + self.with_content(|c| { + for line in lines { + c.push_back(line.into()); + } + }) + } + + /// Remove lines from the beginning until we have no more than 'count' from the end + pub fn resize_back(&self, count: usize) { + self.with_content(|c| { + while c.len() > count { + c.remove(0); + } + }) + } + + /// Remove lines from the end until we have no more than 'count' from the beginning + pub fn resize_front(&self, count: usize) { + self.with_content(|c| { + while c.len() > count { + c.remove(c.len() - 1); + } }) } @@ -113,7 +145,7 @@ impl TextContent { /// Apply the given closure to the inner content, and bust the cache afterward. pub fn with_content(&self, f: F) -> O where - F: FnOnce(&mut StyledString) -> O, + F: FnOnce(&mut ContentType) -> O, { self.with_content_inner(|c| f(Arc::make_mut(&mut c.content_value))) } @@ -141,7 +173,7 @@ impl TextContent { struct TextContentInner { // content: String, content_value: InnerContentType, - content_cache: InnerContentType, + content_cache: InnerCacheType, // We keep the cache here so it can be busted when we change the content. size_cache: Option>, @@ -167,7 +199,7 @@ impl TextContentInner { } } - fn get_cache(&self) -> &InnerContentType { + fn get_cache(&self) -> &InnerCacheType { &self.content_cache } } @@ -194,6 +226,9 @@ pub struct CachedTextView { // True if we can wrap long lines. wrap: bool, + // Maximum number of lines to keep while appending + max_lines: Option, + // ScrollBase make many scrolling-related things easier width: Option, } @@ -201,11 +236,11 @@ pub struct CachedTextView { #[allow(dead_code)] impl CachedTextView { /// Creates a new TextView with the given content. - pub fn new(content: S, cache_size: usize) -> Self + pub fn new(content: S, cache_size: usize, max_lines: Option) -> Self where - S: Into, + S: Into, { - Self::new_with_content(TextContent::new(content), cache_size) + Self::new_with_content(TextContent::new(content), cache_size, max_lines) } /// Creates a new TextView using the given `TextContent`. @@ -224,7 +259,11 @@ impl CachedTextView { /// content.set_content("new content"); /// assert!(view.get_content().source().contains("new")); /// ``` - pub fn new_with_content(content: TextContent, cache_size: usize) -> Self { + pub fn new_with_content( + content: TextContent, + cache_size: usize, + max_lines: Option, + ) -> Self { CachedTextView { cache: TinyCache::new(cache_size), content, @@ -232,12 +271,13 @@ impl CachedTextView { wrap: true, align: Align::top_left(), width: None, + max_lines, } } /// Creates a new empty `TextView`. - pub fn empty() -> Self { - CachedTextView::new("", 5) + pub fn empty(cache_size: usize, max_lines: Option) -> Self { + CachedTextView::new(ContentType::default(), cache_size, max_lines) } /// Sets the style for the content. @@ -307,7 +347,7 @@ impl CachedTextView { #[must_use] pub fn content(self, content: S) -> Self where - S: Into, + S: Into, { self.with(|s| s.set_content(content)) } @@ -315,19 +355,35 @@ impl CachedTextView { /// Replace the text in this view. pub fn set_content(&mut self, content: S) where - S: Into, + S: Into, { self.cache.clear(); self.content.set_content(content); } /// Append `content` to the end of a `TextView`. - pub fn append(&mut self, content: S) + pub fn append_line(&mut self, content: S) where S: Into, { self.cache.clear(); - self.content.append(content); + self.content.append_line(content); + if let Some(max_lines) = self.max_lines { + self.content.resize_back(max_lines); + } + } + + /// Append `content` lines to the end of a `TextView`. + pub fn append_lines(&mut self, content: I) + where + I: Iterator, + S: Into, + { + self.cache.clear(); + self.content.append_lines(content); + if let Some(max_lines) = self.max_lines { + self.content.resize_back(max_lines); + } } /// Returns the current text in this view. @@ -357,7 +413,13 @@ impl CachedTextView { // Completely bust the cache // Just in case we fail, we don't want to leave a bad cache. content.size_cache = None; - content.content_cache = Arc::clone(&content.content_value); + content.content_cache = Arc::new(StyledString::from_iter( + content.content_value.iter().map(|s| { + let mut s = s.clone(); + s.append_plain("\n"); + s + }), + )); let rows = self.cache.compute(size.x, || { LinesIterator::new(content.get_cache().as_ref(), size.x).collect() @@ -522,13 +584,14 @@ mod tests { #[test] fn sanity() { - let text_view = CachedTextView::new("", 5); - assert_eq!(text_view.get_content().data.spans().len(), 1); + let text_view = CachedTextView::new(ContentType::default(), 5, None); + assert_eq!(text_view.get_content().data.len(), 0); } #[test] fn test_cache() { - let mut text_view = CachedTextView::new("sample", 3); + let mut text_view = + CachedTextView::new(VecDeque::from([StyledString::from("sample")]), 3, None); assert!(text_view.cache.is_empty()); text_view.compute_rows(Vec2::new(0, 0)); @@ -547,11 +610,11 @@ mod tests { assert_eq!(text_view.cache.keys(), [(&0, 1), (&2, 0), (&3, 0)]); - text_view.set_content(""); + text_view.set_content(VecDeque::new()); assert_eq!(text_view.cache.len(), 0); text_view.compute_rows(Vec2::new(0, 0)); - text_view.append("sample"); + text_view.append_line("sample"); assert_eq!(text_view.cache.len(), 0); text_view.compute_rows(Vec2::new(0, 0)); diff --git a/veilid-cli/src/settings.rs b/veilid-cli/src/settings.rs index 73ecb29d..2014ab37 100644 --- a/veilid-cli/src/settings.rs +++ b/veilid-cli/src/settings.rs @@ -20,7 +20,7 @@ logging: append: true interface: node_log: - scrollback: 2048 + scrollback: 10000 command_line: history_size: 2048 theme: diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index 95d1b60a..10685c97 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -223,7 +223,7 @@ impl UI { }); } fn clear_handler(siv: &mut Cursive) { - Self::node_events_view(siv).set_content(""); + Self::node_events_view(siv).set_content([]); UI::update_cb(siv); } @@ -262,15 +262,22 @@ impl UI { } //////////////////////////////////////////////////////////////////////////////////////////////// - pub fn push_styled(s: &mut Cursive, styled_string: StyledString) { + fn push_styled_line(s: &mut Cursive, styled_string: StyledString) { let mut ctv = UI::node_events_view(s); - ctv.append(styled_string) + ctv.append_line(styled_string) } - pub fn push_ansi_lines(s: &mut Cursive, starting_style: Style, lines: String) { + fn push_ansi_lines(s: &mut Cursive, mut starting_style: Style, lines: String) { let mut ctv = UI::node_events_view(s); - let (spanned_string, _end_style) = ansi::parse_with_starting_style(starting_style, lines); - ctv.append(spanned_string); + + let mut sslines: Vec = vec![]; + for line in lines.lines() { + let (spanned_string, end_style) = ansi::parse_with_starting_style(starting_style, line); + sslines.push(spanned_string); + starting_style = end_style; + } + + ctv.append_lines(sslines.into_iter()); } //////////////////////////////////////////////////////////////////////////////////////////////// @@ -883,7 +890,7 @@ impl UI { node_log_scrollback: usize, ) -> ResizedView> { Panel::new( - CachedTextView::new("", node_log_scrollback) + CachedTextView::new([], node_log_scrollback, Some(node_log_scrollback)) .with_name("node-events-view") .scrollable() .scroll_strategy(cursive::view::ScrollStrategy::StickToBottom) @@ -1167,7 +1174,7 @@ impl UISender { pub fn push_styled(&self, styled_string: StyledString) -> std::io::Result<()> { let res = self.cb_sink.send(Box::new(move |s| { - UI::push_styled(s, styled_string); + UI::push_styled_line(s, styled_string); })); if res.is_err() { return Err(std::io::Error::from(std::io::ErrorKind::BrokenPipe)); @@ -1206,6 +1213,7 @@ impl LogWriter for UISender { for argline in args.lines() { line.append_styled(argline, color); + line.append_plain("\n"); self.push_styled(line)?; line = StyledString::new(); line.append_plain(" ".repeat(indent)); From 2ffba2c528eb9bb52f96fbdd700a58a4bf030fb5 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 9 Dec 2023 19:04:59 -0500 Subject: [PATCH 24/67] bug fixes --- veilid-cli/src/cached_text_view.rs | 7 ++++++- veilid-cli/src/ui.rs | 12 +++++++++--- veilid-core/src/veilid_api/debug.rs | 4 +++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/veilid-cli/src/cached_text_view.rs b/veilid-cli/src/cached_text_view.rs index 7f9b6d6c..d6137c88 100644 --- a/veilid-cli/src/cached_text_view.rs +++ b/veilid-cli/src/cached_text_view.rs @@ -118,6 +118,9 @@ impl TextContent { /// Remove lines from the beginning until we have no more than 'count' from the end pub fn resize_back(&self, count: usize) { + if self.get_content().len() <= count { + return; + } self.with_content(|c| { while c.len() > count { c.remove(0); @@ -127,13 +130,15 @@ impl TextContent { /// Remove lines from the end until we have no more than 'count' from the beginning pub fn resize_front(&self, count: usize) { + if self.get_content().len() <= count { + return; + } self.with_content(|c| { while c.len() > count { c.remove(c.len() - 1); } }) } - /// Returns a reference to the content. /// /// This locks the data while the returned value is alive, diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index 10685c97..f54d5f5a 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -239,9 +239,9 @@ impl UI { fn node_events_view(s: &mut Cursive) -> ViewRef { s.find_name("node-events-view").unwrap() } - // fn node_events_scroll_view(s: &mut Cursive) -> ViewRef> { - // s.find_name("node-events-scroll-view").unwrap() - // } + fn node_events_scroll_view(s: &mut Cursive) -> ViewRef>> { + s.find_name("node-events-scroll-view").unwrap() + } fn command_line(s: &mut Cursive) -> ViewRef { s.find_name("command-line").unwrap() } @@ -894,6 +894,12 @@ impl UI { .with_name("node-events-view") .scrollable() .scroll_strategy(cursive::view::ScrollStrategy::StickToBottom) + .on_scroll(|s, _r| { + let mut sv = UI::node_events_scroll_view(s); + if sv.is_at_bottom() { + sv.set_scroll_strategy(cursive::view::ScrollStrategy::StickToBottom); + } + }) .with_name("node-events-scroll-view"), ) .title_position(HAlign::Left) diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 2d0ece6e..901fe9b6 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -1645,7 +1645,9 @@ impl VeilidAPI { } Ok(v) => v, }; - + if ts.as_u64() == 0 { + return Ok("Failed to watch value".to_owned()); + } Ok(format!("Success: expiration={:?}", debug_ts(ts.as_u64()))) } From 1e1faa3c1ab87d79e85eb2f1df7480148a9cd760 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 9 Dec 2023 19:44:52 -0500 Subject: [PATCH 25/67] debug --- veilid-core/src/rpc_processor/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index db07a467..3448f3ad 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -1501,7 +1501,7 @@ impl RPCProcessor { ) { address_filter.punish_node_id(sender_node_id); return Ok(NetworkResult::invalid_message( - "sender peerinfo has invalid peer scope", + format!("sender peerinfo has invalid peer scope: {:?}",sender_peer_info.signed_node_info()) )); } opt_sender_nr = match self.routing_table().register_node_with_peer_info( From a0760827631d85bea5d653b26760edc1417c45b4 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 9 Dec 2023 20:43:38 -0500 Subject: [PATCH 26/67] punish clear --- veilid-core/src/network_manager/address_filter.rs | 7 +++++++ veilid-core/src/veilid_api/debug.rs | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/veilid-core/src/network_manager/address_filter.rs b/veilid-core/src/network_manager/address_filter.rs index 15775e02..2eb104a6 100644 --- a/veilid-core/src/network_manager/address_filter.rs +++ b/veilid-core/src/network_manager/address_filter.rs @@ -268,6 +268,13 @@ impl AddressFilter { .or_insert(ts); } + pub fn clear_punishments(&self) { + let mut inner = self.inner.lock(); + inner.punishments_by_ip4.clear(); + inner.punishments_by_ip6_prefix.clear(); + inner.punishments_by_node_id.clear(); + } + pub fn punish_ip_addr(&self, addr: IpAddr) { log_net!(debug ">>> PUNISHED: {}", addr); let ts = get_aligned_timestamp(); diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index 901fe9b6..f67ca339 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -1710,10 +1710,20 @@ impl VeilidAPI { let network_manager = self.network_manager()?; let address_filter = network_manager.address_filter(); - let out = format!("Address Filter Punishments:\n{:#?}", address_filter); + let out = format!("Address filter punishments:\n{:#?}", address_filter); Ok(out) } + async fn debug_punish_clear(&self, _args: Vec) -> VeilidAPIResult { + // + let network_manager = self.network_manager()?; + let address_filter = network_manager.address_filter(); + + address_filter.clear_punishments(); + + Ok("Address Filter punishments cleared\n".to_owned()) + } + async fn debug_punish(&self, args: String) -> VeilidAPIResult { let args: Vec = shell_words::split(&args).map_err(|e| VeilidAPIError::parse_error(e, args))?; @@ -1750,6 +1760,7 @@ appcall appreply [#id] relay [public|local] punish list + clear route allocate [ord|*ord] [rel] [] [in|out] release publish [full] From 0411055aed8aac5d49c7ba0e076e312b3736c288 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 9 Dec 2023 21:41:49 -0500 Subject: [PATCH 27/67] fixes for init nodes --- veilid-core/src/rpc_processor/fanout_call.rs | 10 ++++++---- veilid-core/src/rpc_processor/mod.rs | 2 +- veilid-core/src/storage_manager/get_value.rs | 2 +- veilid-core/src/storage_manager/set_value.rs | 2 +- veilid-core/src/storage_manager/watch_value.rs | 8 ++++---- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/veilid-core/src/rpc_processor/fanout_call.rs b/veilid-core/src/rpc_processor/fanout_call.rs index 4cc2c64f..70813534 100644 --- a/veilid-core/src/rpc_processor/fanout_call.rs +++ b/veilid-core/src/rpc_processor/fanout_call.rs @@ -221,7 +221,7 @@ where pub async fn run( self: Arc, - opt_init_fanout_queue: Option>, + init_fanout_queue: Vec, ) -> TimeoutOr, RPCError>> { // Get timeout in milliseconds let timeout_ms = match us_to_ms(self.timeout_us.as_u64()).map_err(RPCError::internal) { @@ -232,10 +232,12 @@ where }; // Initialize closest nodes list - if let Some(init_fanout_queue) = opt_init_fanout_queue { + if init_fanout_queue.is_empty() { + if let Err(e) = self.clone().init_closest_nodes() { + return TimeoutOr::value(Err(e)); + } + } else { self.clone().add_to_fanout_queue(&init_fanout_queue); - } else if let Err(e) = self.clone().init_closest_nodes() { - return TimeoutOr::value(Err(e)); } // Do a quick check to see if we're already done diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index 3448f3ad..6994f2d1 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -516,7 +516,7 @@ impl RPCProcessor { check_done, ); - fanout_call.run(None).await + fanout_call.run(vec![]).await } /// Search the DHT for a specific node corresponding to a key unless we have that node in our routing table already, and return the node reference diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index e9bdad5a..239fe20f 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -174,7 +174,7 @@ impl StorageManager { check_done, ); - match fanout_call.run(None).await { + match fanout_call.run(vec![]).await { // If we don't finish in the timeout (too much time passed checking for consensus) TimeoutOr::Timeout => { // Return the best answer we've got diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index 43970b9f..50aa8dc7 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -165,7 +165,7 @@ impl StorageManager { check_done, ); - match fanout_call.run(None).await { + match fanout_call.run(vec![]).await { // If we don't finish in the timeout (too much time passed checking for consensus) TimeoutOr::Timeout => { // Return the best answer we've got diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index b49aef25..c448ebc2 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -43,11 +43,11 @@ impl StorageManager { }; // Get the nodes we know are caching this value to seed the fanout - let opt_init_fanout_queue = if let Some(watch_node) = opt_watch_node { - Some(vec![watch_node]) + let init_fanout_queue = if let Some(watch_node) = opt_watch_node { + vec![watch_node] } else { let inner = self.inner.lock().await; - inner.get_value_nodes(key)? + inner.get_value_nodes(key)?.unwrap_or_default() }; // Get the appropriate watcher key @@ -132,7 +132,7 @@ impl StorageManager { check_done, ); - match fanout_call.run(opt_init_fanout_queue).await { + match fanout_call.run(init_fanout_queue).await { // If we don't finish in the timeout (too much time passed without a successful watch) TimeoutOr::Timeout => { // Return the best answer we've got From 448267217e509d3aee1f28019d886cd17c15fc85 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 9 Dec 2023 22:14:10 -0500 Subject: [PATCH 28/67] ranges --- .../rpc_processor/coders/operations/operation_watch_value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index c114c4c7..d58c3198 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -25,7 +25,7 @@ impl RPCOperationWatchValueQ { ) -> Result { // Needed because RangeSetBlaze uses different types here all the time #[allow(clippy::unnecessary_cast)] - let subkeys_len = subkeys.len() as usize; + let subkeys_len = subkeys.ranges_len() as usize; if subkeys_len > MAX_WATCH_VALUE_Q_SUBKEYS_LEN { return Err(RPCError::protocol("WatchValueQ subkeys length too long")); From 827a3443b0c4b9aae13fd295e25a3404d4e20675 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 10:50:20 -0500 Subject: [PATCH 29/67] fix lengths --- .../operations/operation_value_changed.rs | 20 ++++++++++++++++--- .../operations/operation_watch_value.rs | 2 +- .../src/rpc_processor/rpc_value_changed.rs | 2 +- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs b/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs index 36880e96..1fecc143 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_value_changed.rs @@ -1,6 +1,8 @@ use super::*; use crate::storage_manager::SignedValueData; +const MAX_VALUE_CHANGED_SUBKEYS_LEN: usize = 512; + #[derive(Debug, Clone)] pub(in crate::rpc_processor) struct RPCOperationValueChanged { key: TypedKey, @@ -16,13 +18,21 @@ impl RPCOperationValueChanged { subkeys: ValueSubkeyRangeSet, count: u32, value: SignedValueData, - ) -> Self { - Self { + ) -> Result { + // Needed because RangeSetBlaze uses different types here all the time + #[allow(clippy::unnecessary_cast)] + let subkeys_len = subkeys.ranges_len() as usize; + + if subkeys_len > MAX_VALUE_CHANGED_SUBKEYS_LEN { + return Err(RPCError::protocol("ValueChanged subkeys length too long")); + } + + Ok(Self { key, subkeys, count, value, - } + }) } pub fn validate(&mut self, _validate_context: &RPCValidateContext) -> Result<(), RPCError> { @@ -62,6 +72,10 @@ impl RPCOperationValueChanged { let key = decode_typed_key(&k_reader)?; let sk_reader = reader.get_subkeys().map_err(RPCError::protocol)?; + if sk_reader.len() as usize > MAX_VALUE_CHANGED_SUBKEYS_LEN { + return Err(RPCError::protocol("ValueChanged subkeys length too long")); + } + let mut subkeys = ValueSubkeyRangeSet::new(); for skr in sk_reader.iter() { let vskr = (skr.get_start(), skr.get_end()); diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index d58c3198..de35c662 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -185,7 +185,7 @@ impl RPCOperationWatchValueQ { let mut sk_builder = builder.reborrow().init_subkeys( self.subkeys - .len() + .ranges_len() .try_into() .map_err(RPCError::map_internal("invalid subkey range list length"))?, ); diff --git a/veilid-core/src/rpc_processor/rpc_value_changed.rs b/veilid-core/src/rpc_processor/rpc_value_changed.rs index 555dd104..b0ba8c15 100644 --- a/veilid-core/src/rpc_processor/rpc_value_changed.rs +++ b/veilid-core/src/rpc_processor/rpc_value_changed.rs @@ -16,7 +16,7 @@ impl RPCProcessor { count: u32, value: SignedValueData, ) -> RPCNetworkResult<()> { - let value_changed = RPCOperationValueChanged::new(key, subkeys, count, value); + let value_changed = RPCOperationValueChanged::new(key, subkeys, count, value)?; let statement = RPCStatement::new(RPCStatementDetail::ValueChanged(Box::new(value_changed))); From 5f5515af5e1095253c011f2381da2f68e3d65be6 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 13:26:21 -0500 Subject: [PATCH 30/67] oops --- .../rpc_processor/coders/operations/operation_watch_value.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs index de35c662..bc137b74 100644 --- a/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs +++ b/veilid-core/src/rpc_processor/coders/operations/operation_watch_value.rs @@ -55,7 +55,7 @@ impl RPCOperationWatchValueQ { ) -> Vec { // Needed because RangeSetBlaze uses different types here all the time #[allow(clippy::unnecessary_cast)] - let subkeys_len = subkeys.len() as usize; + let subkeys_len = subkeys.ranges_len() as usize; let mut sig_data = Vec::with_capacity(PUBLIC_KEY_LENGTH + 4 + (subkeys_len * 8) + 8 + 4); sig_data.extend_from_slice(&key.kind.0); From d269b25a237239aa41b002432f4621a8a0887fe4 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 13:40:47 -0500 Subject: [PATCH 31/67] make ctrl-k clear screen everywhere --- veilid-cli/src/ui.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index f54d5f5a..c42be9ce 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -205,6 +205,11 @@ impl UI { siv.set_global_callback(cursive::event::Event::Key(Key::Esc), UI::quit_handler); } + fn setup_clear_handler(siv: &mut Cursive) { + siv.clear_global_callbacks(cursive::event::Event::CtrlChar('k')); + siv.set_on_pre_event(cursive::event::Event::CtrlChar('k'), UI::clear_handler); + } + fn quit_handler(siv: &mut Cursive) { siv.add_layer( Dialog::text("Do you want to exit?") @@ -1036,8 +1041,7 @@ impl UI { UI::setup_colors(&mut this.siv, &mut inner, settings); UI::setup_quit_handler(&mut this.siv); - this.siv - .set_global_callback(cursive::event::Event::CtrlChar('k'), UI::clear_handler); + UI::setup_clear_handler(&mut this.siv); drop(inner); From b6f1e706f73a3b7d8eed0068508b86281783a2ba Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 14:25:04 -0500 Subject: [PATCH 32/67] fix expiration --- veilid-core/src/rpc_processor/rpc_watch_value.rs | 4 ++++ veilid-core/src/storage_manager/record_store.rs | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 4d22bb70..84bc900d 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -207,6 +207,10 @@ impl RPCProcessor { }; let ret_expiration = if closer_to_key_peers.len() >= set_value_count { // Not close enough + + #[cfg(feature = "debug-dht")] + log_rpc!(debug "Not close enough for watch value"); + Timestamp::default() } else { // Close enough, lets watch it diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index 8e3a8712..bca8266f 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -746,7 +746,7 @@ where &mut self, key: TypedKey, subkeys: ValueSubkeyRangeSet, - expiration: Timestamp, + mut expiration: Timestamp, count: u32, target: Target, watcher: CryptoKey, @@ -760,7 +760,9 @@ where let cur_ts = get_timestamp(); let max_ts = cur_ts + self.limits.max_watch_expiration.as_u64(); let min_ts = cur_ts + self.limits.min_watch_expiration.as_u64(); - if expiration.as_u64() < min_ts || expiration.as_u64() > max_ts { + if expiration.as_u64() == 0 { + expiration = Timestamp::new(max_ts); + } else if expiration.as_u64() < min_ts || expiration.as_u64() > max_ts { return Ok(None); } From 064661f20d9ff6e7144638de0172a7c5937a54e3 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 14:55:44 -0500 Subject: [PATCH 33/67] expiration work --- veilid-core/src/storage_manager/mod.rs | 16 ++++++++++++---- veilid-core/src/storage_manager/watch_value.rs | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 4abe128d..31b5e48f 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -627,16 +627,24 @@ impl StorageManager { opened_record.clear_active_watch(); // Get the minimum expiration timestamp we will accept - let rpc_timeout_us = { + let (rpc_timeout_us, max_watch_expiration_us) = { let c = self.unlocked_inner.config.get(); - TimestampDuration::from(ms_to_us(c.network.rpc.timeout_ms)) + ( + TimestampDuration::from(ms_to_us(c.network.rpc.timeout_ms)), + TimestampDuration::from(ms_to_us(c.network.dht.max_watch_expiration_ms)), + ) }; let cur_ts = get_timestamp(); let min_expiration_ts = cur_ts + rpc_timeout_us.as_u64(); + let max_expiration_ts = if expiration.as_u64() == 0 { + cur_ts + max_watch_expiration_us.as_u64() + } else { + expiration.as_u64() + }; - // If the expiration time is less than our minimum expiration time or greater than the requested time, consider this watch cancelled + // If the expiration time is less than our minimum expiration time or greater than the maximum time, consider this watch cancelled if owvresult.expiration_ts.as_u64() < min_expiration_ts - || owvresult.expiration_ts.as_u64() > expiration.as_u64() + || owvresult.expiration_ts.as_u64() > max_expiration_ts { // Don't set the watch so we ignore any stray valuechanged messages return Ok(Timestamp::new(0)); diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index c448ebc2..f945c781 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -88,7 +88,7 @@ impl StorageManager { if wva.answer.expiration_ts.as_u64() > 0 { if count > 0 { // If we asked for a nonzero notification count, then this is an accepted watch - log_stor!(debug "Watch accepted: expiration_ts={}", wva.answer.expiration_ts); + log_stor!(debug "Watch accepted: expiration_ts={}", debug_ts(wva.answer.expiration_ts.as_u64())); } else { // If we asked for a zero notification count, then this is a cancelled watch log_stor!(debug "Watch cancelled"); From 9c0c7cf0b2d386eb8c0d13069382d8110a5a6ced Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 15:40:38 -0500 Subject: [PATCH 34/67] config oops --- doc/config/sample.config | 2 +- doc/config/veilid-server-config.md | 2 +- veilid-core/src/intf/native/protected_store.rs | 2 +- veilid-core/src/veilid_config.rs | 1 + veilid-wasm/tests/src/utils/veilid-config.ts | 1 + 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/config/sample.config b/doc/config/sample.config index fe324081..5d930075 100644 --- a/doc/config/sample.config +++ b/doc/config/sample.config @@ -90,7 +90,7 @@ core: remote_max_storage_space_mb: 0 public_watch_limit: 32 member_watch_limit: 8 - + max_watch_expiration_ms: 600000 upnp: true detect_address_changes: true restricted_nat_retries: 0 diff --git a/doc/config/veilid-server-config.md b/doc/config/veilid-server-config.md index 69b44c10..9489a6bb 100644 --- a/doc/config/veilid-server-config.md +++ b/doc/config/veilid-server-config.md @@ -257,7 +257,7 @@ dht: remote_max_storage_space_mb: 0 public_watch_limit: 32 member_watch_limit: 8 - + max_watch_expiration_ms: 600000 ``` #### core:network:tls diff --git a/veilid-core/src/intf/native/protected_store.rs b/veilid-core/src/intf/native/protected_store.rs index c952d9c5..06851411 100644 --- a/veilid-core/src/intf/native/protected_store.rs +++ b/veilid-core/src/intf/native/protected_store.rs @@ -57,7 +57,7 @@ impl ProtectedStore { inner.keyring_manager = match maybe_km { Ok(v) => Some(v), Err(e) => { - log_pstore!(error "Failed to create secure keyring manager: {}", e); + info!("Secure key storage service unavailable, falling back to direct disk-based storage: {}", e); None } }; diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index 19830002..0e1a9f4d 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -763,6 +763,7 @@ impl VeilidConfig { get_config!(inner.network.dht.remote_max_storage_space_mb); get_config!(inner.network.dht.public_watch_limit); get_config!(inner.network.dht.member_watch_limit); + get_config!(inner.network.dht.max_watch_expiration_ms); get_config!(inner.network.rpc.concurrency); get_config!(inner.network.rpc.queue_size); get_config!(inner.network.rpc.max_timestamp_behind_ms); diff --git a/veilid-wasm/tests/src/utils/veilid-config.ts b/veilid-wasm/tests/src/utils/veilid-config.ts index 3ebdc777..44eed767 100644 --- a/veilid-wasm/tests/src/utils/veilid-config.ts +++ b/veilid-wasm/tests/src/utils/veilid-config.ts @@ -90,6 +90,7 @@ export const veilidCoreStartupConfig = { remote_max_storage_space_mb: 0, public_watch_limit: 32, member_watch_limit: 8, + max_watch_expiration_ms: 600000, }, upnp: true, detect_address_changes: true, From c33b00fe32ed2e403406ba1389bfae8316a921d3 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 16:29:52 -0500 Subject: [PATCH 35/67] clamp instead of reject max expiration time --- veilid-core/src/storage_manager/mod.rs | 15 +++++++++------ veilid-core/src/storage_manager/record_store.rs | 7 +++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/veilid-core/src/storage_manager/mod.rs b/veilid-core/src/storage_manager/mod.rs index 31b5e48f..45749c24 100644 --- a/veilid-core/src/storage_manager/mod.rs +++ b/veilid-core/src/storage_manager/mod.rs @@ -642,14 +642,17 @@ impl StorageManager { expiration.as_u64() }; - // If the expiration time is less than our minimum expiration time or greater than the maximum time, consider this watch cancelled - if owvresult.expiration_ts.as_u64() < min_expiration_ts - || owvresult.expiration_ts.as_u64() > max_expiration_ts - { - // Don't set the watch so we ignore any stray valuechanged messages + // If the expiration time is less than our minimum expiration time consider this watch cancelled + let mut expiration_ts = owvresult.expiration_ts; + if expiration_ts.as_u64() < min_expiration_ts { return Ok(Timestamp::new(0)); } + // If the expiration time is greated than our maximum expiration time, clamp our local watch so we ignore extra valuechanged messages + if expiration_ts.as_u64() > max_expiration_ts { + expiration_ts = Timestamp::new(max_expiration_ts); + } + // If we requested a cancellation, then consider this watch cancelled if count == 0 { return Ok(Timestamp::new(0)); @@ -657,7 +660,7 @@ impl StorageManager { // Keep a record of the watch opened_record.set_active_watch(ActiveWatch { - expiration_ts: owvresult.expiration_ts, + expiration_ts, watch_node: owvresult.watch_node, opt_value_changed_route: owvresult.opt_value_changed_route, subkeys, diff --git a/veilid-core/src/storage_manager/record_store.rs b/veilid-core/src/storage_manager/record_store.rs index bca8266f..256107c4 100644 --- a/veilid-core/src/storage_manager/record_store.rs +++ b/veilid-core/src/storage_manager/record_store.rs @@ -760,9 +760,12 @@ where let cur_ts = get_timestamp(); let max_ts = cur_ts + self.limits.max_watch_expiration.as_u64(); let min_ts = cur_ts + self.limits.min_watch_expiration.as_u64(); - if expiration.as_u64() == 0 { + + if expiration.as_u64() == 0 || expiration.as_u64() > max_ts { + // Clamp expiration max time (or set zero expiration to max) expiration = Timestamp::new(max_ts); - } else if expiration.as_u64() < min_ts || expiration.as_u64() > max_ts { + } else if expiration.as_u64() < min_ts { + // Don't add watches with too low of an expiration time return Ok(None); } From 277aed5d40d6cb78357fadcb245a5b6acfea29f8 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 18:25:50 -0500 Subject: [PATCH 36/67] private route respondto fix --- .../src/routing_table/route_spec_store/mod.rs | 44 ++++++++++++++++++- veilid-core/src/rpc_processor/destination.rs | 31 +++++++++++-- .../src/rpc_processor/rpc_set_value.rs | 4 +- .../src/rpc_processor/rpc_watch_value.rs | 6 ++- veilid-core/src/veilid_api/api.rs | 2 +- veilid-core/src/veilid_api/debug.rs | 2 +- 6 files changed, 79 insertions(+), 10 deletions(-) diff --git a/veilid-core/src/routing_table/route_spec_store/mod.rs b/veilid-core/src/routing_table/route_spec_store/mod.rs index 11410b74..32fd3d79 100644 --- a/veilid-core/src/routing_table/route_spec_store/mod.rs +++ b/veilid-core/src/routing_table/route_spec_store/mod.rs @@ -1462,14 +1462,14 @@ impl RouteSpecStore { Ok(out) } - /// Import a remote private route for compilation + /// Import a remote private route set blob for compilation /// It is safe to import the same route more than once and it will return the same route id /// Returns a route set id #[cfg_attr( feature = "verbose-tracing", instrument(level = "trace", skip(self, blob), ret, err) )] - pub fn import_remote_private_route(&self, blob: Vec) -> VeilidAPIResult { + pub fn import_remote_private_route_blob(&self, blob: Vec) -> VeilidAPIResult { let cur_ts = get_aligned_timestamp(); // decode the pr blob @@ -1502,6 +1502,46 @@ impl RouteSpecStore { Ok(id) } + /// Add a single remote private route for compilation + /// It is safe to add the same route more than once and it will return the same route id + /// Returns a route set id + #[cfg_attr( + feature = "verbose-tracing", + instrument(level = "trace", skip(self, blob), ret, err) + )] + pub fn add_remote_private_route( + &self, + private_route: PrivateRoute, + ) -> VeilidAPIResult { + let cur_ts = get_aligned_timestamp(); + + // Make a single route set + let private_routes = vec![private_route]; + + // make the route id + let id = self.generate_remote_route_id(&private_routes)?; + + // validate the private routes + let inner = &mut *self.inner.lock(); + for private_route in &private_routes { + // ensure private route has first hop + if !matches!(private_route.hops, PrivateRouteHops::FirstHop(_)) { + apibail_generic!("private route must have first hop"); + } + + // ensure this isn't also an allocated route + // if inner.content.get_id_by_key(&private_route.public_key.value).is_some() { + // bail!("should not import allocated route"); + // } + } + + inner + .cache + .cache_remote_private_route(cur_ts, id, private_routes); + + Ok(id) + } + /// Release a remote private route that is no longer in use #[cfg_attr( feature = "verbose-tracing", diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 13f40a63..808b7cb4 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -114,7 +114,7 @@ impl Destination { } } - pub fn get_target(&self) -> Target { + pub fn get_target(&self, rss: RouteSpecStore) -> Result { match self { Destination::Direct { node, @@ -124,11 +124,36 @@ impl Destination { relay: _, node, safety_selection: _, - } => Target::NodeId(node.best_node_id()), + } => Ok(Target::NodeId(node.best_node_id())), Destination::PrivateRoute { private_route, safety_selection: _, - } => Target::PrivateRoute(private_route.public_key.value), + } => { + // Add the remote private route if we're going to keep the id + let route_id = rss + .add_remote_private_route(private_route.clone()) + .map_err(RPCError::protocol)?; + + Ok(Target::PrivateRoute(route_id)) + } + } + } + + pub fn get_private_route(&self) -> Option { + match self { + Destination::Direct { + node: _, + safety_selection: _, + } + | Destination::Relay { + relay: _, + node: _, + safety_selection: _, + } => None, + Destination::PrivateRoute { + private_route, + safety_selection: _, + } => Some(private_route.clone()), } } } diff --git a/veilid-core/src/rpc_processor/rpc_set_value.rs b/veilid-core/src/rpc_processor/rpc_set_value.rs index 2e7f7f12..36bead3a 100644 --- a/veilid-core/src/rpc_processor/rpc_set_value.rs +++ b/veilid-core/src/rpc_processor/rpc_set_value.rs @@ -188,6 +188,8 @@ impl RPCProcessor { ) ->RPCNetworkResult<()> { // Ignore if disabled let routing_table = self.routing_table(); + let rss = routing_table.route_spec_store(); + let opi = routing_table.get_own_peer_info(msg.header.routing_domain()); if !opi .signed_node_info() @@ -224,7 +226,7 @@ impl RPCProcessor { // Get target for ValueChanged notifications let dest = network_result_try!(self.get_respond_to_destination(&msg)); - let target = dest.get_target(); + let target = dest.get_target(rss)?; // Get the nodes that we know about that are closer to the the key than our own node let routing_table = self.routing_table(); diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 84bc900d..77351cc8 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -145,6 +145,9 @@ impl RPCProcessor { #[cfg_attr(feature="verbose-tracing", instrument(level = "trace", skip(self, msg), fields(msg.operation.op_id), ret, err))] pub(crate) async fn process_watch_value_q(&self, msg: RPCMessage) -> RPCNetworkResult<()> { + let routing_table = self.routing_table(); + let rss = routing_table.route_spec_store(); + // Ensure this never came over a private route, safety route is okay though match &msg.header.detail { RPCMessageHeaderDetail::Direct(_) | RPCMessageHeaderDetail::SafetyRouted(_) => {} @@ -177,7 +180,7 @@ impl RPCProcessor { // Get target for ValueChanged notifications let dest = network_result_try!(self.get_respond_to_destination(&msg)); - let target = dest.get_target(); + let target = dest.get_target(rss)?; #[cfg(feature = "debug-dht")] { @@ -195,7 +198,6 @@ impl RPCProcessor { } // Get the nodes that we know about that are closer to the the key than our own node - let routing_table = self.routing_table(); let closer_to_key_peers = network_result_try!( routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT]) ); diff --git a/veilid-core/src/veilid_api/api.rs b/veilid-core/src/veilid_api/api.rs index 4e202853..12e282a5 100644 --- a/veilid-core/src/veilid_api/api.rs +++ b/veilid-core/src/veilid_api/api.rs @@ -295,7 +295,7 @@ impl VeilidAPI { /// Returns a route id that can be used to send private messages to the node creating this route. pub fn import_remote_private_route(&self, blob: Vec) -> VeilidAPIResult { let rss = self.routing_table()?.route_spec_store(); - rss.import_remote_private_route(blob) + rss.import_remote_private_route_blob(blob) } /// Release either a locally allocated or remotely imported private route diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index f67ca339..e7a4f10a 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -1307,7 +1307,7 @@ impl VeilidAPI { .map_err(VeilidAPIError::generic)?; let rss = self.routing_table()?.route_spec_store(); let route_id = rss - .import_remote_private_route(blob_dec) + .import_remote_private_route_blob(blob_dec) .map_err(VeilidAPIError::generic)?; let mut dc = DEBUG_CACHE.lock(); From cfd7a319d268e9fe1e3527ae4c2bdf55926695d1 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 18:27:57 -0500 Subject: [PATCH 37/67] remove unused function --- veilid-core/src/rpc_processor/destination.rs | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 808b7cb4..62fc5e69 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -138,24 +138,6 @@ impl Destination { } } } - - pub fn get_private_route(&self) -> Option { - match self { - Destination::Direct { - node: _, - safety_selection: _, - } - | Destination::Relay { - relay: _, - node: _, - safety_selection: _, - } => None, - Destination::PrivateRoute { - private_route, - safety_selection: _, - } => Some(private_route.clone()), - } - } } impl fmt::Display for Destination { From f96e23b0f652a0fb611fae7598ee1cdddfa645e2 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 19:09:42 -0500 Subject: [PATCH 38/67] better display --- veilid-cli/src/command_processor.rs | 35 +++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/veilid-cli/src/command_processor.rs b/veilid-cli/src/command_processor.rs index 0fc1e2f8..fae1a43f 100644 --- a/veilid-cli/src/command_processor.rs +++ b/veilid-cli/src/command_processor.rs @@ -414,7 +414,19 @@ Server Debug Commands: } } pub fn update_value_change(&self, value_change: &json::JsonValue) { - let out = format!("Value change: {:?}", value_change.as_str().unwrap_or("???")); + let data = json_str_vec_u8(&value_change["value"]["data"]); + let (datastr, truncated) = Self::print_json_str_vec_u8(&data); + + let out = format!( + "Value change: key={} subkeys={} count={} value.seq={} value.writer={} value.data={}{}", + value_change["key"].dump(), + value_change["subkeys"].dump(), + value_change["count"].dump(), + value_change["value"]["seq"].dump(), + value_change["value"]["writer"].dump(), + datastr, + if truncated { "..." } else { "" } + ); self.inner().ui_sender.add_node_event(Level::Info, out); } @@ -436,16 +448,10 @@ Server Debug Commands: ); } - pub fn update_app_message(&self, msg: &json::JsonValue) { - if !self.inner.lock().enable_app_messages { - return; - } - - let message = json_str_vec_u8(&msg["message"]); - + fn print_json_str_vec_u8(message: &[u8]) -> (String, bool) { // check if message body is ascii printable let mut printable = true; - for c in &message { + for c in message { if *c < 32 || *c > 126 { printable = false; } @@ -463,6 +469,17 @@ Server Debug Commands: hex::encode(message) }; + (strmsg, truncated) + } + + pub fn update_app_message(&self, msg: &json::JsonValue) { + if !self.inner.lock().enable_app_messages { + return; + } + + let message = json_str_vec_u8(&msg["message"]); + let (strmsg, truncated) = Self::print_json_str_vec_u8(&message); + self.inner().ui_sender.add_node_event( Level::Info, format!( From 2e2f3b0bc4dbb791a4469c8fb77e82bda0dcbcf7 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 19:25:49 -0500 Subject: [PATCH 39/67] clippy lint --- veilid-cli/src/command_processor.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/veilid-cli/src/command_processor.rs b/veilid-cli/src/command_processor.rs index fae1a43f..cc5d13e1 100644 --- a/veilid-cli/src/command_processor.rs +++ b/veilid-cli/src/command_processor.rs @@ -460,7 +460,7 @@ Server Debug Commands: let (message, truncated) = if message.len() > 64 { (&message[0..64], true) } else { - (&message[..], false) + (message, false) }; let strmsg = if printable { From 97a9a8d3afd2df01db986899f14f4b93c39a74f5 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 10 Dec 2023 19:28:09 -0500 Subject: [PATCH 40/67] python update --- veilid-python/veilid/schema/RecvMessage.json | 36 ++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/veilid-python/veilid/schema/RecvMessage.json b/veilid-python/veilid/schema/RecvMessage.json index 7b32d392..cdd9bf60 100644 --- a/veilid-python/veilid/schema/RecvMessage.json +++ b/veilid-python/veilid/schema/RecvMessage.json @@ -2588,9 +2588,21 @@ "subkeys": { "type": "array", "items": { - "type": "integer", - "format": "uint32", - "minimum": 0.0 + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 } }, "value": { @@ -3362,8 +3374,11 @@ "local_max_subkey_cache_memory_mb", "local_subkey_cache_size", "max_find_node_count", + "max_watch_expiration_ms", + "member_watch_limit", "min_peer_count", "min_peer_refresh_time_ms", + "public_watch_limit", "remote_max_records", "remote_max_storage_space_mb", "remote_max_subkey_cache_memory_mb", @@ -3407,6 +3422,16 @@ "format": "uint32", "minimum": 0.0 }, + "max_watch_expiration_ms": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "member_watch_limit": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, "min_peer_count": { "type": "integer", "format": "uint32", @@ -3417,6 +3442,11 @@ "format": "uint32", "minimum": 0.0 }, + "public_watch_limit": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, "remote_max_records": { "type": "integer", "format": "uint32", From 7129343ea18493a1814563c55fd501f7f0231d11 Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 12 Dec 2023 16:13:56 -0500 Subject: [PATCH 41/67] some debugging for bootstrap and route purge --- veilid-core/src/network_manager/mod.rs | 2 +- veilid-core/src/routing_table/mod.rs | 3 +++ veilid-core/src/routing_table/route_spec_store/mod.rs | 4 ++++ veilid-core/src/routing_table/tasks/bootstrap.rs | 3 ++- veilid-core/src/routing_table/tasks/mod.rs | 2 +- .../src/routing_table/tasks/private_route_management.rs | 7 +++---- veilid-core/src/veilid_api/debug.rs | 2 +- veilid-python/tests/test_routing_context.py | 6 +++--- veilid-server/Cargo.toml | 1 + veilid-server/src/client_api.rs | 6 ++++++ 10 files changed, 25 insertions(+), 11 deletions(-) diff --git a/veilid-core/src/network_manager/mod.rs b/veilid-core/src/network_manager/mod.rs index 9c0f951a..9415512a 100644 --- a/veilid-core/src/network_manager/mod.rs +++ b/veilid-core/src/network_manager/mod.rs @@ -1096,7 +1096,7 @@ impl NetworkManager { Ok(true) } - pub fn debug_restart_network(&self) { + pub fn restart_network(&self) { self.net().restart_network(); } } diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index 729f22c1..10574d80 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -38,6 +38,9 @@ pub use types::*; ////////////////////////////////////////////////////////////////////////// +/// How many nodes in our routing table we require for a functional PublicInternet RoutingDomain +pub const MIN_PUBLIC_INTERNET_ROUTING_DOMAIN_NODE_COUNT: usize = 4; + /// How frequently we tick the relay management routine pub const RELAY_MANAGEMENT_INTERVAL_SECS: u32 = 1; diff --git a/veilid-core/src/routing_table/route_spec_store/mod.rs b/veilid-core/src/routing_table/route_spec_store/mod.rs index 32fd3d79..81b58933 100644 --- a/veilid-core/src/routing_table/route_spec_store/mod.rs +++ b/veilid-core/src/routing_table/route_spec_store/mod.rs @@ -152,6 +152,10 @@ impl RouteSpecStore { /// Purge the route spec store pub async fn purge(&self) -> VeilidAPIResult<()> { + // Briefly pause routing table ticker while changes are made + let _tick_guard = self.unlocked_inner.routing_table.pause_tasks().await; + self.unlocked_inner.routing_table.cancel_tasks().await; + { let inner = &mut *self.inner.lock(); inner.content = Default::default(); diff --git a/veilid-core/src/routing_table/tasks/bootstrap.rs b/veilid-core/src/routing_table/tasks/bootstrap.rs index ceebe7a8..1cb9f43e 100644 --- a/veilid-core/src/routing_table/tasks/bootstrap.rs +++ b/veilid-core/src/routing_table/tasks/bootstrap.rs @@ -285,7 +285,8 @@ impl RoutingTable { { Ok(NodeContactMethod::Direct(v)) => v, Ok(v) => { - log_rtab!(warn "invalid contact method for bootstrap: {:?}", v); + log_rtab!(warn "invalid contact method for bootstrap, restarting network: {:?}", v); + routing_table.network_manager().restart_network(); return; } Err(e) => { diff --git a/veilid-core/src/routing_table/tasks/mod.rs b/veilid-core/src/routing_table/tasks/mod.rs index 0a599b26..a61e5194 100644 --- a/veilid-core/src/routing_table/tasks/mod.rs +++ b/veilid-core/src/routing_table/tasks/mod.rs @@ -157,7 +157,7 @@ impl RoutingTable { for ck in VALID_CRYPTO_KINDS { let eckey = (RoutingDomain::PublicInternet, ck); let cnt = entry_counts.get(&eckey).copied().unwrap_or_default(); - if cnt == 0 { + if cnt < MIN_PUBLIC_INTERNET_ROUTING_DOMAIN_NODE_COUNT { needs_bootstrap = true; } else if cnt < min_peer_count { needs_peer_minimum_refresh = true; diff --git a/veilid-core/src/routing_table/tasks/private_route_management.rs b/veilid-core/src/routing_table/tasks/private_route_management.rs index 467a7856..f0cf4420 100644 --- a/veilid-core/src/routing_table/tasks/private_route_management.rs +++ b/veilid-core/src/routing_table/tasks/private_route_management.rs @@ -2,7 +2,6 @@ use super::*; use futures_util::stream::{FuturesUnordered, StreamExt}; use futures_util::FutureExt; -use stop_token::future::FutureExt as StopFutureExt; const BACKGROUND_SAFETY_ROUTE_COUNT: usize = 2; @@ -103,10 +102,10 @@ impl RoutingTable { } /// Test set of routes and remove the ones that don't test clean - #[instrument(level = "trace", skip(self, stop_token), err)] + #[instrument(level = "trace", skip(self, _stop_token), err)] async fn test_route_set( &self, - stop_token: StopToken, + _stop_token: StopToken, routes_needing_testing: Vec, ) -> EyreResult<()> { if routes_needing_testing.is_empty() { @@ -158,7 +157,7 @@ impl RoutingTable { } // Wait for test_route futures to complete in parallel - while let Ok(Some(_)) = unord.next().timeout_at(stop_token.clone()).await {} + while unord.next().await.is_some() {} } // Process failed routes diff --git a/veilid-core/src/veilid_api/debug.rs b/veilid-core/src/veilid_api/debug.rs index e7a4f10a..0fc13136 100644 --- a/veilid-core/src/veilid_api/debug.rs +++ b/veilid-core/src/veilid_api/debug.rs @@ -809,7 +809,7 @@ impl VeilidAPI { } let netman = self.network_manager()?; - netman.debug_restart_network(); + netman.restart_network(); Ok("Network restarted".to_owned()) } else { diff --git a/veilid-python/tests/test_routing_context.py b/veilid-python/tests/test_routing_context.py index 3266e4bb..0dca6319 100644 --- a/veilid-python/tests/test_routing_context.py +++ b/veilid-python/tests/test_routing_context.py @@ -166,8 +166,8 @@ async def test_routing_context_app_message_loopback_big_packets(): # import it as a remote route as well so we can send to it prr = await api.import_remote_private_route(blob) - # do this test 1000 times - for _ in range(1000): + # do this test 100 times + for _ in range(100): # send a random sized random app message to our own private route message = random.randbytes(random.randint(0, 32768)) await rc.app_message(prr, message) @@ -230,7 +230,7 @@ async def test_routing_context_app_call_loopback_big_packets(): # import it as a remote route as well so we can send to it prr = await api.import_remote_private_route(blob) - + # do this test 10 times for _ in range(10): # send a random sized random app message to our own private route diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index 2dde4fc9..b983835f 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -35,6 +35,7 @@ rt-tokio = [ tracking = ["veilid-core/tracking"] network-result-extra = ["veilid-core/network-result-extra"] verbose-tracing = ["veilid-core/verbose-tracing"] +debug-json-api = [] [dependencies] veilid-core = { path = "../veilid-core", default-features = false } diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 403cf957..4eb9c39e 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -217,6 +217,9 @@ impl ClientApi { // (trim all whitespace around input lines just to make things more permissive for API users) let request: json_api::Request = deserialize_json(&sanitized_line)?; + #[cfg(feature = "debug-json-api")] + debug!("JSONAPI: Request: {:?}", request); + // See if this is a control message or a veilid-core message let response = if let json_api::RequestOp::Control { args } = request.op { // Process control messages @@ -231,6 +234,9 @@ impl ClientApi { jrp.clone().process_request(request).await }; + #[cfg(feature = "debug-json-api")] + debug!("JSONAPI: Response: {:?}", response); + // Marshal json + newline => NDJSON let response_string = serialize_json(json_api::RecvMessage::Response(response)) + "\n"; if let Err(e) = responses_tx.send_async(response_string).await { From 6d2119f32e44fb9bdf0d294e1970a77cbf6ecb5b Mon Sep 17 00:00:00 2001 From: John Smith Date: Tue, 12 Dec 2023 16:45:57 -0500 Subject: [PATCH 42/67] fix #347 and #349 --- veilid-server/src/settings.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 03fc4423..575a9c9f 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -384,7 +384,7 @@ impl serde::Serialize for NamedSocketAddrs { } impl NamedSocketAddrs { - pub fn offset_port(&mut self, offset: u16) -> EyreResult<()> { + pub fn offset_port(&mut self, offset: u16) -> EyreResult { // Bump port on name if let Some(split) = self.name.rfind(':') { let hoststr = &self.name[0..split]; @@ -393,7 +393,7 @@ impl NamedSocketAddrs { self.name = format!("{}:{}", hoststr, port); } else { - bail!("no port specified to offset"); + return Ok(false); } // Bump port on addresses @@ -401,7 +401,7 @@ impl NamedSocketAddrs { addr.set_port(addr.port() + offset); } - Ok(()) + Ok(true) } } From 37979277b5dbb6268fa1139770924342c385adf9 Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 14 Dec 2023 17:23:43 -0500 Subject: [PATCH 43/67] IPC to server --- Cargo.lock | 1 + veilid-cli/src/client_api_connection.rs | 112 ++++++--- veilid-cli/src/command_processor.rs | 124 +++++++--- veilid-cli/src/main.rs | 72 ++++-- veilid-cli/src/settings.rs | 48 +++- veilid-cli/src/ui.rs | 220 ++++++++++++++---- veilid-server/Cargo.toml | 6 +- veilid-server/src/client_api.rs | 190 ++++++++++----- veilid-server/src/server.rs | 28 ++- veilid-server/src/settings.rs | 75 +++--- veilid-tools/Cargo.toml | 2 + veilid-tools/src/ipc/ipc_async_std/mod.rs | 11 + veilid-tools/src/ipc/ipc_async_std/unix.rs | 0 veilid-tools/src/ipc/ipc_async_std/windows.rs | 0 veilid-tools/src/ipc/ipc_tokio/mod.rs | 11 + veilid-tools/src/ipc/ipc_tokio/unix.rs | 114 +++++++++ veilid-tools/src/ipc/ipc_tokio/windows.rs | 0 veilid-tools/src/ipc/mod.rs | 11 + veilid-tools/src/lib.rs | 3 + veilid-tools/src/tools.rs | 28 ++- 20 files changed, 817 insertions(+), 239 deletions(-) create mode 100644 veilid-tools/src/ipc/ipc_async_std/mod.rs create mode 100644 veilid-tools/src/ipc/ipc_async_std/unix.rs create mode 100644 veilid-tools/src/ipc/ipc_async_std/windows.rs create mode 100644 veilid-tools/src/ipc/ipc_tokio/mod.rs create mode 100644 veilid-tools/src/ipc/ipc_tokio/unix.rs create mode 100644 veilid-tools/src/ipc/ipc_tokio/windows.rs create mode 100644 veilid-tools/src/ipc/mod.rs diff --git a/Cargo.lock b/Cargo.lock index f97f6045..637488ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5769,6 +5769,7 @@ dependencies = [ "stop-token", "thiserror", "tokio", + "tokio-stream", "tokio-util", "tracing", "tracing-oslog", diff --git a/veilid-cli/src/client_api_connection.rs b/veilid-cli/src/client_api_connection.rs index cb39e5de..6abf0cab 100644 --- a/veilid-cli/src/client_api_connection.rs +++ b/veilid-cli/src/client_api_connection.rs @@ -3,6 +3,7 @@ use crate::tools::*; use futures::stream::FuturesUnordered; use futures::StreamExt; use std::net::SocketAddr; +use std::path::PathBuf; use std::time::SystemTime; use stop_token::{future::FutureExt as _, StopSource}; @@ -20,7 +21,6 @@ cfg_if! { struct ClientApiConnectionInner { comproc: CommandProcessor, - connect_addr: Option, request_sender: Option>, disconnector: Option, disconnect_requested: bool, @@ -38,7 +38,6 @@ impl ClientApiConnection { Self { inner: Arc::new(Mutex::new(ClientApiConnectionInner { comproc, - connect_addr: None, request_sender: None, disconnector: None, disconnect_requested: false, @@ -117,33 +116,15 @@ impl ClientApiConnection { } } - async fn handle_connection(&self, connect_addr: SocketAddr) -> Result<(), String> { - trace!("ClientApiConnection::handle_connection"); - - // Connect the TCP socket - let stream = TcpStream::connect(connect_addr) - .await - .map_err(map_to_string)?; - - // If it succeed, disable nagle algorithm - stream.set_nodelay(true).map_err(map_to_string)?; - - // State we connected - let comproc = self.inner.lock().comproc.clone(); - comproc.set_connection_state(ConnectionState::Connected(connect_addr, SystemTime::now())); - - // Split the stream - cfg_if! { - if #[cfg(feature="rt-async-std")] { - use futures::AsyncReadExt; - let (reader, mut writer) = stream.split(); - let mut reader = BufReader::new(reader); - } else if #[cfg(feature="rt-tokio")] { - let (reader, mut writer) = stream.into_split(); - let mut reader = BufReader::new(reader); - } - } - + pub async fn run_json_api_processor( + self, + mut reader: R, + mut writer: W, + ) -> Result<(), String> + where + R: AsyncBufReadExt + Unpin + Send, + W: AsyncWriteExt + Unpin + Send, + { // Requests to send let (requests_tx, requests_rx) = flume::unbounded(); @@ -152,7 +133,6 @@ impl ClientApiConnection { let stop_source = StopSource::new(); let token = stop_source.token(); let mut inner = self.inner.lock(); - inner.connect_addr = Some(connect_addr); inner.disconnector = Some(stop_source); inner.request_sender = Some(requests_tx); token @@ -231,7 +211,6 @@ impl ClientApiConnection { inner.request_sender = None; inner.disconnector = None; inner.disconnect_requested = false; - inner.connect_addr = None; // Connection finished if disconnect_requested { @@ -241,6 +220,66 @@ impl ClientApiConnection { } } + async fn handle_tcp_connection(&self, connect_addr: SocketAddr) -> Result<(), String> { + trace!("ClientApiConnection::handle_tcp_connection"); + + // Connect the TCP socket + let stream = TcpStream::connect(connect_addr) + .await + .map_err(map_to_string)?; + + // If it succeed, disable nagle algorithm + stream.set_nodelay(true).map_err(map_to_string)?; + + // State we connected + let comproc = self.inner.lock().comproc.clone(); + comproc.set_connection_state(ConnectionState::ConnectedTCP( + connect_addr, + SystemTime::now(), + )); + + // Split into reader and writer halves + // with line buffering on the reader + cfg_if! { + if #[cfg(feature="rt-async-std")] { + use futures::AsyncReadExt; + let (reader, mut writer) = stream.split(); + let reader = BufReader::new(reader); + } else { + let (reader, writer) = stream.into_split(); + let reader = BufReader::new(reader); + } + } + + self.clone().run_json_api_processor(reader, writer).await + } + + async fn handle_ipc_connection(&self, ipc_path: PathBuf) -> Result<(), String> { + trace!("ClientApiConnection::handle_ipc_connection"); + + // Connect the IPC socket + let stream = IpcStream::connect(&ipc_path).await.map_err(map_to_string)?; + + // State we connected + let comproc = self.inner.lock().comproc.clone(); + comproc.set_connection_state(ConnectionState::ConnectedIPC(ipc_path, SystemTime::now())); + + // Split into reader and writer halves + // with line buffering on the reader + use futures::AsyncReadExt; + let (reader, writer) = stream.split(); + cfg_if! { + if #[cfg(feature = "rt-tokio")] { + use tokio_util::compat::{FuturesAsyncReadCompatExt, FuturesAsyncWriteCompatExt}; + let reader = reader.compat(); + let writer = writer.compat_write(); + } + } + let reader = BufReader::new(reader); + + self.clone().run_json_api_processor(reader, writer).await + } + async fn perform_request(&self, mut req: json::JsonValue) -> Option { let (sender, reply_rx) = { let mut inner = self.inner.lock(); @@ -358,10 +397,15 @@ impl ClientApiConnection { } // Start Client API connection - pub async fn connect(&self, connect_addr: SocketAddr) -> Result<(), String> { - trace!("ClientApiConnection::connect"); + pub async fn ipc_connect(&self, ipc_path: PathBuf) -> Result<(), String> { + trace!("ClientApiConnection::ipc_connect"); + // Save the pathto connect to + self.handle_ipc_connection(ipc_path).await + } + pub async fn tcp_connect(&self, connect_addr: SocketAddr) -> Result<(), String> { + trace!("ClientApiConnection::tcp_connect"); // Save the address to connect to - self.handle_connection(connect_addr).await + self.handle_tcp_connection(connect_addr).await } // End Client API connection diff --git a/veilid-cli/src/command_processor.rs b/veilid-cli/src/command_processor.rs index cc5d13e1..0438367d 100644 --- a/veilid-cli/src/command_processor.rs +++ b/veilid-cli/src/command_processor.rs @@ -4,6 +4,7 @@ use crate::tools::*; use crate::ui::*; use indent::indent_all_by; use std::net::SocketAddr; +use std::path::PathBuf; use std::time::SystemTime; use veilid_tools::*; @@ -22,18 +23,20 @@ pub fn convert_loglevel(s: &str) -> Result { #[derive(PartialEq, Clone)] pub enum ConnectionState { Disconnected, - Connected(SocketAddr, SystemTime), - Retrying(SocketAddr, SystemTime), + ConnectedTCP(SocketAddr, SystemTime), + RetryingTCP(SocketAddr, SystemTime), + ConnectedIPC(PathBuf, SystemTime), + RetryingIPC(PathBuf, SystemTime), } impl ConnectionState { pub fn is_disconnected(&self) -> bool { matches!(*self, Self::Disconnected) } pub fn is_connected(&self) -> bool { - matches!(*self, Self::Connected(_, _)) + matches!(*self, Self::ConnectedTCP(_, _) | Self::ConnectedIPC(_, _)) } pub fn is_retrying(&self) -> bool { - matches!(*self, Self::Retrying(_, _)) + matches!(*self, Self::RetryingTCP(_, _) | Self::RetryingIPC(_, _)) } } @@ -44,7 +47,8 @@ struct CommandProcessorInner { finished: bool, autoconnect: bool, autoreconnect: bool, - server_addr: Option, + ipc_path: Option, + network_addr: Option, connection_waker: Eventual, last_call_id: Option, enable_app_messages: bool, @@ -65,7 +69,8 @@ impl CommandProcessor { finished: false, autoconnect: settings.autoconnect, autoreconnect: settings.autoreconnect, - server_addr: None, + ipc_path: None, + network_addr: None, connection_waker: Eventual::new(), last_call_id: None, enable_app_messages: false, @@ -306,38 +311,75 @@ Server Debug Commands: // Loop while we want to keep the connection let mut first = true; while self.inner().reconnect { - let server_addr_opt = self.inner_mut().server_addr; - let server_addr = match server_addr_opt { - None => break, - Some(addr) => addr, - }; - if first { - info!("Connecting to server at {}", server_addr); - self.set_connection_state(ConnectionState::Retrying( - server_addr, + // IPC + let ipc_path_opt = self.inner_mut().ipc_path.clone(); + if let Some(ipc_path) = ipc_path_opt { + if first { + info!( + "Connecting to server at {}", + ipc_path.to_string_lossy().to_string() + ); + self.set_connection_state(ConnectionState::RetryingIPC( + ipc_path.clone(), + SystemTime::now(), + )); + } else { + debug!( + "Retrying connection to {}", + ipc_path.to_string_lossy().to_string() + ); + } + let capi = self.capi(); + let res = capi.ipc_connect(ipc_path.clone()).await; + if res.is_ok() { + info!( + "Connection to server at {} terminated normally", + ipc_path.to_string_lossy().to_string() + ); + break; + } + if !self.inner().autoreconnect { + info!("Connection to server lost."); + break; + } + + self.set_connection_state(ConnectionState::RetryingIPC( + ipc_path, SystemTime::now(), )); - } else { - debug!("Retrying connection to {}", server_addr); - } - let capi = self.capi(); - let res = capi.connect(server_addr).await; - if res.is_ok() { - info!( - "Connection to server at {} terminated normally", - server_addr - ); - break; - } - if !self.inner().autoreconnect { - info!("Connection to server lost."); - break; } - self.set_connection_state(ConnectionState::Retrying( - server_addr, - SystemTime::now(), - )); + // TCP + let network_addr_opt = self.inner_mut().network_addr; + if let Some(network_addr) = network_addr_opt { + if first { + info!("Connecting to server at {}", network_addr); + self.set_connection_state(ConnectionState::RetryingTCP( + network_addr, + SystemTime::now(), + )); + } else { + debug!("Retrying connection to {}", network_addr); + } + let capi = self.capi(); + let res = capi.tcp_connect(network_addr).await; + if res.is_ok() { + info!( + "Connection to server at {} terminated normally", + network_addr + ); + break; + } + if !self.inner().autoreconnect { + info!("Connection to server lost."); + break; + } + + self.set_connection_state(ConnectionState::RetryingTCP( + network_addr, + SystemTime::now(), + )); + } debug!("Connection lost, retrying in 2 seconds"); { @@ -355,11 +397,17 @@ Server Debug Commands: // called by ui //////////////////////////////////////////// - pub fn set_server_address(&self, server_addr: Option) { - self.inner_mut().server_addr = server_addr; + pub fn set_ipc_path(&self, ipc_path: Option) { + self.inner_mut().ipc_path = ipc_path; } - pub fn get_server_address(&self) -> Option { - self.inner().server_addr + pub fn get_ipc_path(&self) -> Option { + self.inner().ipc_path.clone() + } + pub fn set_network_address(&self, network_addr: Option) { + self.inner_mut().network_addr = network_addr; + } + pub fn get_network_address(&self) -> Option { + self.inner().network_addr } // called by client_api_connection // calls into ui diff --git a/veilid-cli/src/main.rs b/veilid-cli/src/main.rs index 35e00e88..39a3577a 100644 --- a/veilid-cli/src/main.rs +++ b/veilid-cli/src/main.rs @@ -3,11 +3,11 @@ #![deny(unused_must_use)] #![recursion_limit = "256"] -use crate::tools::*; +use crate::{settings::NamedSocketAddrs, tools::*}; use clap::{Parser, ValueEnum}; use flexi_logger::*; -use std::{net::ToSocketAddrs, path::PathBuf}; +use std::path::PathBuf; mod cached_text_view; mod client_api_connection; @@ -28,14 +28,20 @@ enum LogLevel { #[derive(Parser, Debug)] #[command(author, version, about = "Veilid Console Client")] struct CmdlineArgs { + /// IPC socket to connect to + #[arg(long, short = 'p')] + ipc_path: Option, + /// IPC socket to connect to + #[arg(long, short = 'i', default_value = "0")] + subnode_index: usize, /// Address to connect to - #[arg(long)] + #[arg(long, short = 'a')] address: Option, /// Wait for debugger to attach #[arg(long)] wait_for_debug: bool, /// Specify a configuration file to use - #[arg(short, long, value_name = "FILE")] + #[arg(short = 'c', long, value_name = "FILE")] config_file: Option, /// log level #[arg(value_enum)] @@ -123,16 +129,48 @@ fn main() -> Result<(), String> { .expect("failed to initialize logger!"); } } + // Get client address - let server_addrs = if let Some(address_arg) = args.address { - address_arg - .to_socket_addrs() - .map_err(|e| format!("Invalid server address '{}'", e))? - .collect() - } else { - settings.address.addrs.clone() - }; - let server_addr = server_addrs.first().cloned(); + let enable_ipc = settings.enable_ipc; + let mut enable_network = settings.enable_network; + + // Determine IPC path to try + let mut client_api_ipc_path = None; + if enable_ipc { + if let Some(ipc_path) = args.ipc_path.or(settings.ipc_path.clone()) { + if ipc_path.exists() && !ipc_path.is_dir() { + // try direct path + enable_network = false; + client_api_ipc_path = Some(ipc_path); + } else if ipc_path.exists() && ipc_path.is_dir() { + // try subnode index inside path + let ipc_path = ipc_path.join(args.subnode_index.to_string()); + if ipc_path.exists() && !ipc_path.is_dir() { + // subnode indexed path exists + enable_network = false; + client_api_ipc_path = Some(ipc_path); + } + } + } + } + let mut client_api_network_addresses = None; + if enable_network { + let args_address = if let Some(args_address) = args.address { + match NamedSocketAddrs::try_from(args_address) { + Ok(v) => Some(v), + Err(e) => { + return Err(format!("Invalid server address: {}", e)); + } + } + } else { + None + }; + if let Some(address_arg) = args_address.or(settings.address.clone()) { + client_api_network_addresses = Some(address_arg.addrs); + } else if let Some(address) = settings.address.clone() { + client_api_network_addresses = Some(address.addrs.clone()); + } + } // Create command processor debug!("Creating Command Processor "); @@ -147,7 +185,13 @@ fn main() -> Result<(), String> { comproc.set_client_api_connection(capi.clone()); // Keep a connection to the server - comproc.set_server_address(server_addr); + if let Some(client_api_ipc_path) = client_api_ipc_path { + comproc.set_ipc_path(Some(client_api_ipc_path)); + } else if let Some(client_api_network_address) = client_api_network_addresses { + let network_addr = client_api_network_address.first().cloned(); + comproc.set_network_address(network_addr); + } + let comproc2 = comproc.clone(); let connection_future = comproc.connection_manager(); diff --git a/veilid-cli/src/settings.rs b/veilid-cli/src/settings.rs index 2014ab37..5aeea7e9 100644 --- a/veilid-cli/src/settings.rs +++ b/veilid-cli/src/settings.rs @@ -7,6 +7,9 @@ use std::path::{Path, PathBuf}; pub fn load_default_config() -> Result { let default_config = r#"--- +enable_ipc: true +local_socket_path: '%LOCAL_SOCKET_DIRECTORY%' +enable_network: true address: "localhost:5959" autoconnect: true autoreconnect: true @@ -45,6 +48,10 @@ interface: warn : "light yellow" error : "light red" "# + .replace( + "%LOCAL_SOCKET_DIRECTORY%", + &Settings::get_default_local_socket_path().to_string_lossy(), + ) .replace( "%LOGGING_FILE_DIRECTORY%", &Settings::get_default_log_directory().to_string_lossy(), @@ -111,11 +118,22 @@ pub fn convert_loglevel(log_level: LogLevel) -> log::LevelFilter { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct NamedSocketAddrs { pub name: String, pub addrs: Vec, } + +impl TryFrom for NamedSocketAddrs { + type Error = std::io::Error; + + fn try_from(value: String) -> Result { + let addrs = value.to_socket_addrs()?.collect(); + let name = value; + Ok(NamedSocketAddrs { name, addrs }) + } +} + impl<'de> serde::Deserialize<'de> for NamedSocketAddrs { fn deserialize(deserializer: D) -> Result where @@ -200,7 +218,10 @@ pub struct Interface { #[derive(Debug, Deserialize)] pub struct Settings { - pub address: NamedSocketAddrs, + pub enable_ipc: bool, + pub ipc_path: Option, + pub enable_network: bool, + pub address: Option, pub autoconnect: bool, pub autoreconnect: bool, pub logging: Logging, @@ -208,6 +229,29 @@ pub struct Settings { } impl Settings { + fn get_server_default_directory(subpath: &str) -> PathBuf { + #[cfg(unix)] + { + let globalpath = PathBuf::from("/var/db/veilid-server").join(subpath); + if globalpath.is_dir() { + return globalpath; + } + } + + let mut ts_path = if let Some(my_proj_dirs) = ProjectDirs::from("org", "Veilid", "Veilid") { + PathBuf::from(my_proj_dirs.data_local_dir()) + } else { + PathBuf::from("./") + }; + ts_path.push(subpath); + + ts_path + } + + pub fn get_default_local_socket_path() -> PathBuf { + Self::get_server_default_directory("local_sockets") + } + pub fn get_default_config_path() -> PathBuf { // Get default configuration file location let mut default_config_path = diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index c42be9ce..c723269d 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -20,6 +20,7 @@ use crate::cached_text_view::*; use chrono::{Datelike, Timelike}; use std::collections::{HashMap, VecDeque}; use std::io::Write; +use std::path::PathBuf; use std::sync::atomic::{AtomicU64, Ordering}; use std::time::{SystemTime, UNIX_EPOCH}; use thiserror::Error; @@ -259,8 +260,17 @@ impl UI { fn peers(s: &mut Cursive) -> ViewRef { s.find_name("peers").unwrap() } - fn connection_address(s: &mut Cursive) -> ViewRef { - s.find_name("connection-address").unwrap() + fn ipc_path(s: &mut Cursive) -> ViewRef { + s.find_name("ipc-path").unwrap() + } + fn ipc_path_radio(s: &mut Cursive) -> ViewRef> { + s.find_name("ipc-path-radio").unwrap() + } + fn network_address(s: &mut Cursive) -> ViewRef { + s.find_name("network-address").unwrap() + } + fn network_address_radio(s: &mut Cursive) -> ViewRef> { + s.find_name("network-address-radio").unwrap() } fn connection_dialog(s: &mut Cursive) -> ViewRef { s.find_name("connection-dialog").unwrap() @@ -321,7 +331,7 @@ impl UI { } } fn render_button_attach<'a>(inner: &mut UIInner) -> (&'a str, bool) { - if let ConnectionState::Connected(_, _) = inner.ui_state.connection_state.get() { + if let ConnectionState::ConnectedTCP(_, _) = inner.ui_state.connection_state.get() { match inner.ui_state.attachment_state.get().as_str() { "Detached" => ("Attach", true), "Attaching" => ("Detach", true), @@ -496,19 +506,39 @@ impl UI { button_attach.set_enabled(button_enable); } - fn submit_connection_address(s: &mut Cursive) { - let edit = Self::connection_address(s); + fn submit_ipc_path(s: &mut Cursive) { + let edit = Self::ipc_path(s); let addr = (*edit.get_content()).clone(); - let sa = match addr.parse::() { - Ok(sa) => Some(sa), + let ipc_path = match addr.parse::() { + Ok(sa) => sa, Err(_) => { - s.add_layer(Dialog::text("Invalid address").button("Close", |s| { + s.add_layer(Dialog::text("Invalid IPC path").button("Close", |s| { s.pop_layer(); })); return; } }; - Self::command_processor(s).set_server_address(sa); + Self::command_processor(s).set_ipc_path(Some(ipc_path)); + Self::command_processor(s).set_network_address(None); + Self::command_processor(s).start_connection(); + } + + fn submit_network_address(s: &mut Cursive) { + let edit = Self::network_address(s); + let addr = (*edit.get_content()).clone(); + let sa = match addr.parse::() { + Ok(sa) => sa, + Err(_) => { + s.add_layer( + Dialog::text("Invalid network address").button("Close", |s| { + s.pop_layer(); + }), + ); + return; + } + }; + Self::command_processor(s).set_ipc_path(None); + Self::command_processor(s).set_network_address(Some(sa)); Self::command_processor(s).start_connection(); } @@ -589,8 +619,19 @@ impl UI { } fn show_connection_dialog(s: &mut Cursive, state: ConnectionState) -> bool { + let is_ipc = Self::command_processor(s).get_ipc_path().is_some(); let mut inner = Self::inner_mut(s); + let mut connection_type_group: RadioGroup = RadioGroup::new().on_change(|s, v| { + if *v == 0 { + Self::ipc_path(s).enable(); + Self::network_address(s).disable(); + } else if *v == 1 { + Self::ipc_path(s).disable(); + Self::network_address(s).enable(); + } + }); + let mut show: bool = false; let mut hide: bool = false; let mut reset: bool = false; @@ -613,7 +654,7 @@ impl UI { reset = true; } } - ConnectionState::Connected(_, _) => { + ConnectionState::ConnectedTCP(_, _) | ConnectionState::ConnectedIPC(_, _) => { if inner.connection_dialog_state.is_some() && !inner .connection_dialog_state @@ -624,7 +665,7 @@ impl UI { hide = true; } } - ConnectionState::Retrying(_, _) => { + ConnectionState::RetryingTCP(_, _) | ConnectionState::RetryingIPC(_, _) => { if inner.connection_dialog_state.is_none() || inner .connection_dialog_state @@ -655,15 +696,42 @@ impl UI { ResizedView::with_full_screen(DummyView {}), ColorStyle::new(PaletteColor::Background, PaletteColor::Background), )); + s.add_layer( Dialog::around( LinearLayout::vertical().child( LinearLayout::horizontal() - .child(TextView::new("Address:")) + .child( + if is_ipc { + connection_type_group.button(0, "IPC Path").selected() + } else { + connection_type_group.button(0, "IPC Path") + } + .with_name("ipc-path-radio"), + ) .child( EditView::new() - .on_submit(|s, _| Self::submit_connection_address(s)) - .with_name("connection-address") + .with_enabled(is_ipc) + .on_submit(|s, _| Self::submit_ipc_path(s)) + .with_name("ipc-path") + .fixed_height(1) + .min_width(40), + ) + .child( + if is_ipc { + connection_type_group.button(1, "Network Address") + } else { + connection_type_group + .button(1, "Network Address") + .selected() + } + .with_name("network-address-radio"), + ) + .child( + EditView::new() + .with_enabled(!is_ipc) + .on_submit(|s, _| Self::submit_network_address(s)) + .with_name("network-address") .fixed_height(1) .min_width(40), ), @@ -693,24 +761,57 @@ impl UI { match new_state { ConnectionState::Disconnected => { - let addr = match Self::command_processor(s).get_server_address() { - None => "".to_owned(), - Some(addr) => addr.to_string(), + Self::ipc_path_radio(s).set_enabled(true); + Self::network_address_radio(s).set_enabled(true); + + let (network_address, network_address_enabled) = + match Self::command_processor(s).get_network_address() { + None => ("".to_owned(), false), + Some(addr) => (addr.to_string(), true), + }; + let mut edit = Self::network_address(s); + edit.set_content(network_address); + edit.set_enabled(network_address_enabled); + + let (ipc_path, ipc_path_enabled) = match Self::command_processor(s).get_ipc_path() { + None => ("".to_owned(), false), + Some(ipc_path) => (ipc_path.to_string_lossy().to_string(), true), }; - debug!("address is {}", addr); - let mut edit = Self::connection_address(s); - edit.set_content(addr); - edit.set_enabled(true); + let mut edit = Self::ipc_path(s); + edit.set_content(ipc_path); + edit.set_enabled(ipc_path_enabled); + let mut dlg = Self::connection_dialog(s); - dlg.add_button("Connect", Self::submit_connection_address); + dlg.add_button("Connect", Self::submit_network_address); } - ConnectionState::Connected(_, _) => {} - ConnectionState::Retrying(addr, _) => { + ConnectionState::ConnectedTCP(_, _) | ConnectionState::ConnectedIPC(_, _) => {} + ConnectionState::RetryingTCP(addr, _) => { + Self::ipc_path_radio(s).set_enabled(false); + Self::network_address_radio(s).set_enabled(false); + // - let mut edit = Self::connection_address(s); - debug!("address is {}", addr); + let mut edit = Self::network_address(s); edit.set_content(addr.to_string()); edit.set_enabled(false); + + Self::ipc_path(s).set_enabled(false); + + let mut dlg = Self::connection_dialog(s); + dlg.add_button("Cancel", |s| { + Self::command_processor(s).cancel_reconnect(); + }); + } + ConnectionState::RetryingIPC(ipc_path, _) => { + Self::ipc_path_radio(s).set_enabled(false); + Self::network_address_radio(s).set_enabled(false); + + // + let mut edit = Self::ipc_path(s); + edit.set_content(ipc_path.to_string_lossy().to_string()); + edit.set_enabled(false); + + Self::network_address(s).set_enabled(false); + let mut dlg = Self::connection_dialog(s); dlg.add_button("Cancel", |s| { Self::command_processor(s).cancel_reconnect(); @@ -732,6 +833,8 @@ impl UI { let mut status = StyledString::new(); + let mut enable_status_fields = false; + match inner.ui_state.connection_state.get() { ConnectionState::Disconnected => { status.append_styled( @@ -740,35 +843,64 @@ impl UI { ); status.append_styled("|", ColorStyle::highlight_inactive()); } - ConnectionState::Retrying(addr, _) => { + ConnectionState::RetryingTCP(addr, _) => { status.append_styled( format!("Reconnecting to {} ", addr), ColorStyle::highlight_inactive(), ); status.append_styled("|", ColorStyle::highlight_inactive()); } - ConnectionState::Connected(addr, _) => { + ConnectionState::RetryingIPC(path, _) => { + status.append_styled( + format!( + "Reconnecting to IPC#{} ", + path.file_name() + .unwrap_or_default() + .to_string_lossy() + .into_owned() + ), + ColorStyle::highlight_inactive(), + ); + status.append_styled("|", ColorStyle::highlight_inactive()); + } + ConnectionState::ConnectedTCP(addr, _) => { status.append_styled( format!("Connected to {} ", addr), ColorStyle::highlight_inactive(), ); - status.append_styled("|", ColorStyle::highlight_inactive()); - // Add attachment state - status.append_styled( - format!(" {} ", UI::render_attachment_state(&mut inner)), - ColorStyle::highlight_inactive(), - ); - status.append_styled("|", ColorStyle::highlight_inactive()); - // Add bandwidth status - status.append_styled( - format!(" {} ", UI::render_network_status(&mut inner)), - ColorStyle::highlight_inactive(), - ); - status.append_styled("|", ColorStyle::highlight_inactive()); - // Add tunnel status - status.append_styled(" No Tunnels ", ColorStyle::highlight_inactive()); - status.append_styled("|", ColorStyle::highlight_inactive()); + enable_status_fields = true; } + ConnectionState::ConnectedIPC(path, _) => { + status.append_styled( + format!( + "Connected to IPC#{} ", + path.file_name() + .unwrap_or_default() + .to_string_lossy() + .into_owned() + ), + ColorStyle::highlight_inactive(), + ); + enable_status_fields = true; + } + } + if enable_status_fields { + status.append_styled("|", ColorStyle::highlight_inactive()); + // Add attachment state + status.append_styled( + format!(" {} ", UI::render_attachment_state(&mut inner)), + ColorStyle::highlight_inactive(), + ); + status.append_styled("|", ColorStyle::highlight_inactive()); + // Add bandwidth status + status.append_styled( + format!(" {} ", UI::render_network_status(&mut inner)), + ColorStyle::highlight_inactive(), + ); + status.append_styled("|", ColorStyle::highlight_inactive()); + // Add tunnel status + status.append_styled(" No Tunnels ", ColorStyle::highlight_inactive()); + status.append_styled("|", ColorStyle::highlight_inactive()); }; statusbar.set_content(status); diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index b983835f..08cadf60 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -48,10 +48,10 @@ opentelemetry = { version = "0.20" } opentelemetry-otlp = { version = "0.13" } opentelemetry-semantic-conventions = "0.12" async-std = { version = "^1", features = ["unstable"], optional = true } -tokio = { version = "^1", features = ["full", "tracing"], optional = true } +tokio = { version = "1.32.0", features = ["full", "tracing"], optional = true } +tokio-stream = { version = "0.1.14", features = ["net"], optional = true } +tokio-util = { version = "0.7.8", features = ["compat"], optional = true } console-subscriber = { version = "^0", optional = true } -tokio-stream = { version = "^0", features = ["net"], optional = true } -tokio-util = { version = "^0", features = ["compat"], optional = true } async-tungstenite = { package = "veilid-async-tungstenite", version = "^0", features = [ "async-tls", ] } diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 4eb9c39e..3f137b74 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -6,6 +6,7 @@ use futures_util::{future::join_all, stream::FuturesUnordered, StreamExt}; use parking_lot::Mutex; use std::collections::HashMap; use std::net::SocketAddr; +use std::path::PathBuf; use std::sync::Arc; use stop_token::future::FutureExt as _; use stop_token::*; @@ -46,7 +47,7 @@ struct ClientApiInner { settings: Settings, stop: Option, join_handle: Option, - update_channels: HashMap<(SocketAddr, SocketAddr), flume::Sender>, + update_channels: HashMap>, } #[derive(Clone)] @@ -108,9 +109,40 @@ impl ClientApi { trace!("ClientApi::stop: stopped"); } - async fn handle_incoming(self, bind_addr: SocketAddr) -> std::io::Result<()> { + async fn handle_ipc_incoming(self, ipc_path: PathBuf) -> std::io::Result<()> { + let listener = IpcListener::bind(ipc_path.clone()).await?; + debug!("IPC Client API listening on: {:?}", ipc_path); + + // Process the incoming accept stream + let mut incoming_stream = listener.incoming(); + + // Make wait group for all incoming connections + let awg = AsyncWaitGroup::new(); + + let stop_token = self.inner.lock().stop.as_ref().unwrap().token(); + while let Ok(Some(stream_result)) = + incoming_stream.next().timeout_at(stop_token.clone()).await + { + // Get the stream to process + let stream = stream_result?; + + // Increment wait group + awg.add(1); + let t_awg = awg.clone(); + + // Process the connection + spawn(self.clone().handle_ipc_connection(stream, t_awg)).detach(); + } + + // Wait for all connections to terminate + awg.wait().await; + + Ok(()) + } + + async fn handle_tcp_incoming(self, bind_addr: SocketAddr) -> std::io::Result<()> { let listener = TcpListener::bind(bind_addr).await?; - debug!("Client API listening on: {:?}", bind_addr); + debug!("TCPClient API listening on: {:?}", bind_addr); // Process the incoming accept stream cfg_if! { @@ -137,7 +169,7 @@ impl ClientApi { let t_awg = awg.clone(); // Process the connection - spawn(self.clone().handle_connection(stream, t_awg)).detach(); + spawn(self.clone().handle_tcp_connection(stream, t_awg)).detach(); } // Wait for all connections to terminate @@ -300,47 +332,11 @@ impl ClientApi { VeilidAPIResult::Ok(None) } - pub async fn handle_connection(self, stream: TcpStream, awg: AsyncWaitGroup) { - // Get address of peer - let peer_addr = match stream.peer_addr() { - Ok(v) => v, - Err(e) => { - eprintln!("can't get peer address: {}", e); - return; - } - }; - // Get local address - let local_addr = match stream.local_addr() { - Ok(v) => v, - Err(e) => { - eprintln!("can't get local address: {}", e); - return; - } - }; - // Get connection tuple - let conn_tuple = (local_addr, peer_addr); - - debug!( - "Accepted Client API Connection: {:?} -> {:?}", - peer_addr, local_addr - ); - - // Make stop token to quit when stop() is requested externally - let stop_token = self.inner.lock().stop.as_ref().unwrap().token(); - - // Split into reader and writer halves - // with line buffering on the reader - cfg_if! { - if #[cfg(feature="rt-async-std")] { - use futures_util::AsyncReadExt; - let (reader, mut writer) = stream.split(); - let reader = BufReader::new(reader); - } else { - let (reader, writer) = stream.into_split(); - let reader = BufReader::new(reader); - } - } - + pub async fn run_json_request_processor(self, reader: R, writer: W, stop_token: StopToken) + where + R: AsyncBufReadExt + Unpin + Send, + W: AsyncWriteExt + Unpin + Send, + { // Make request processor for this connection let api = self.inner.lock().veilid_api.clone(); let jrp = json_api::JsonRequestProcessor::new(api); @@ -354,10 +350,11 @@ impl ClientApi { let (responses_tx, responses_rx) = flume::unbounded(); // Start sending updates + let id = get_timestamp(); self.inner .lock() .update_channels - .insert(conn_tuple, responses_tx.clone()); + .insert(id, responses_tx.clone()); // Request receive processor future // Receives from socket and enqueues RequestLines @@ -407,7 +404,50 @@ impl ClientApi { } // Stop sending updates - self.inner.lock().update_channels.remove(&conn_tuple); + self.inner.lock().update_channels.remove(&id); + } + + pub async fn handle_tcp_connection(self, stream: TcpStream, awg: AsyncWaitGroup) { + // Get address of peer + let peer_addr = match stream.peer_addr() { + Ok(v) => v, + Err(e) => { + eprintln!("can't get peer address: {}", e); + return; + } + }; + // Get local address + let local_addr = match stream.local_addr() { + Ok(v) => v, + Err(e) => { + eprintln!("can't get local address: {}", e); + return; + } + }; + // Get connection tuple + debug!( + "Accepted TCP Client API Connection: {:?} -> {:?}", + peer_addr, local_addr + ); + + // Make stop token to quit when stop() is requested externally + let stop_token = self.inner.lock().stop.as_ref().unwrap().token(); + + // Split into reader and writer halves + // with line buffering on the reader + cfg_if! { + if #[cfg(feature="rt-async-std")] { + use futures_util::AsyncReadExt; + let (reader, mut writer) = stream.split(); + let reader = BufReader::new(reader); + } else { + let (reader, writer) = stream.into_split(); + let reader = BufReader::new(reader); + } + } + + self.run_json_request_processor(reader, writer, stop_token) + .await; debug!( "Closed Client API Connection: {:?} -> {:?}", @@ -417,6 +457,34 @@ impl ClientApi { awg.done(); } + pub async fn handle_ipc_connection(self, stream: IpcStream, awg: AsyncWaitGroup) { + // Get connection tuple + debug!("Accepted IPC Client API Connection"); + + // Make stop token to quit when stop() is requested externally + let stop_token = self.inner.lock().stop.as_ref().unwrap().token(); + + // Split into reader and writer halves + // with line buffering on the reader + use futures_util::AsyncReadExt; + let (reader, writer) = stream.split(); + cfg_if! { + if #[cfg(feature = "rt-tokio")] { + use tokio_util::compat::{FuturesAsyncReadCompatExt, FuturesAsyncWriteCompatExt}; + let reader = reader.compat(); + let writer = writer.compat_write(); + } + } + let reader = BufReader::new(reader); + + self.run_json_request_processor(reader, writer, stop_token) + .await; + + debug!("Closed Client API Connection",); + + awg.done(); + } + pub fn handle_update(&self, veilid_update: veilid_core::VeilidUpdate) { // serialize update to NDJSON let veilid_update = serialize_json(json_api::RecvMessage::Update(veilid_update)) + "\n"; @@ -431,15 +499,29 @@ impl ClientApi { } #[instrument(level = "trace", skip(self))] - pub fn run(&self, bind_addrs: Vec) { - let bind_futures = bind_addrs.iter().copied().map(|addr| { + pub fn run(&self, ipc_path: Option, tcp_bind_addrs: Vec) { + let mut bind_futures: Vec> = Vec::new(); + + // Local IPC + if let Some(ipc_path) = ipc_path { let this = self.clone(); - async move { - if let Err(e) = this.handle_incoming(addr).await { - warn!("Not binding client API to {}: {}", addr, e); + bind_futures.push(Box::pin(async move { + if let Err(e) = this.handle_ipc_incoming(ipc_path.clone()).await { + warn!("Not binding IPC client API to {:?}: {}", ipc_path, e); } - } - }); + })); + } + + // Network sockets + for addr in tcp_bind_addrs.iter().copied() { + let this = self.clone(); + bind_futures.push(Box::pin(async move { + if let Err(e) = this.handle_tcp_incoming(addr).await { + warn!("Not binding TCP client API to {}: {}", addr, e); + } + })); + } + let bind_futures_join = join_all(bind_futures); self.inner.lock().join_handle = Some(spawn(bind_futures_join)); } diff --git a/veilid-server/src/server.rs b/veilid-server/src/server.rs index 8cfbe032..c84e0723 100644 --- a/veilid-server/src/server.rs +++ b/veilid-server/src/server.rs @@ -50,15 +50,21 @@ pub async fn run_veilid_server_internal( let ( settings_auto_attach, - settings_client_api_enabled, + settings_client_api_ipc_enabled, + settings_client_api_network_enabled, + settings_client_api_ipc_directory, settings_client_api_listen_address_addrs, + subnode_index, ) = { let settingsr = settings.read(); ( settingsr.auto_attach, - settingsr.client_api.enabled, + settingsr.client_api.ipc_enabled, + settingsr.client_api.network_enabled, + settingsr.client_api.ipc_directory.clone(), settingsr.client_api.listen_address.addrs.clone(), + settingsr.testing.subnode_index, ) }; @@ -84,12 +90,22 @@ pub async fn run_veilid_server_internal( .wrap_err("VeilidCore startup failed")?; // Start client api if one is requested - let mut capi = if settings_client_api_enabled && matches!(server_mode, ServerMode::Normal) { + let capi_enabled = settings_client_api_ipc_enabled || settings_client_api_network_enabled; + let mut capi = if capi_enabled && matches!(server_mode, ServerMode::Normal) { let some_capi = client_api::ClientApi::new(veilid_api.clone(), veilid_logs.clone(), settings.clone()); - some_capi - .clone() - .run(settings_client_api_listen_address_addrs); + some_capi.clone().run( + if settings_client_api_ipc_enabled { + Some(settings_client_api_ipc_directory.join(subnode_index.to_string())) + } else { + None + }, + if settings_client_api_network_enabled { + settings_client_api_listen_address_addrs + } else { + vec![] + }, + ); Some(some_capi) } else { None diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 575a9c9f..95b3bc6f 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -18,7 +18,9 @@ pub fn load_default_config() -> EyreResult { daemon: enabled: false client_api: - enabled: true + ipc_enabled: false + ipc_directory: '%IPC_DIRECTORY%' + network_enabled: false listen_address: 'localhost:5959' auto_attach: true logging: @@ -158,6 +160,10 @@ core: # url: '' "#, ) + .replace( + "%IPC_DIRECTORY%", + &Settings::get_default_ipc_directory().to_string_lossy(), + ) .replace( "%TABLE_STORE_DIRECTORY%", &VeilidConfigTableStore::default().directory, @@ -172,11 +178,11 @@ core: ) .replace( "%CERTIFICATE_PATH%", - &VeilidConfigTLS::default().certificate_path + &VeilidConfigTLS::default().certificate_path, ) .replace( "%PRIVATE_KEY_PATH%", - &VeilidConfigTLS::default().private_key_path + &VeilidConfigTLS::default().private_key_path, ) .replace( "%REMOTE_MAX_SUBKEY_CACHE_MEMORY_MB%", @@ -445,7 +451,9 @@ pub struct Otlp { #[derive(Debug, Deserialize, Serialize)] pub struct ClientApi { - pub enabled: bool, + pub ipc_enabled: bool, + pub ipc_directory: PathBuf, + pub network_enabled: bool, pub listen_address: NamedSocketAddrs, } @@ -798,6 +806,10 @@ impl Settings { .unwrap_or_else(|| PathBuf::from("./veilid-server.conf")) } + pub fn get_default_ipc_directory() -> PathBuf { + Self::get_or_create_default_directory("ipc") + } + pub fn get_default_remote_max_subkey_cache_memory_mb() -> u32 { let sys = sysinfo::System::new_with_specifics(sysinfo::RefreshKind::new().with_memory()); ((sys.free_memory() / (1024u64 * 1024u64)) / 16) as u32 @@ -854,7 +866,9 @@ impl Settings { } set_config_value!(inner.daemon.enabled, value); - set_config_value!(inner.client_api.enabled, value); + set_config_value!(inner.client_api.ipc_enabled, value); + set_config_value!(inner.client_api.ipc_directory, value); + set_config_value!(inner.client_api.network_enabled, value); set_config_value!(inner.client_api.listen_address, value); set_config_value!(inner.auto_attach, value); set_config_value!(inner.logging.system.enabled, value); @@ -1021,13 +1035,9 @@ impl Settings { "protected_store.always_use_insecure_storage" => Ok(Box::new( inner.core.protected_store.always_use_insecure_storage, )), - "protected_store.directory" => Ok(Box::new( - inner - .core - .protected_store - .directory - .clone(), - )), + "protected_store.directory" => { + Ok(Box::new(inner.core.protected_store.directory.clone())) + } "protected_store.delete" => Ok(Box::new(inner.core.protected_store.delete)), "protected_store.device_encryption_key_password" => Ok(Box::new( inner @@ -1044,22 +1054,10 @@ impl Settings { .clone(), )), - "table_store.directory" => Ok(Box::new( - inner - .core - .table_store - .directory - .clone(), - )), + "table_store.directory" => Ok(Box::new(inner.core.table_store.directory.clone())), "table_store.delete" => Ok(Box::new(inner.core.table_store.delete)), - "block_store.directory" => Ok(Box::new( - inner - .core - .block_store - .directory - .clone(), - )), + "block_store.directory" => Ok(Box::new(inner.core.block_store.directory.clone())), "block_store.delete" => Ok(Box::new(inner.core.block_store.delete)), "network.connection_initial_timeout_ms" => { @@ -1214,22 +1212,12 @@ impl Settings { "network.restricted_nat_retries" => { Ok(Box::new(inner.core.network.restricted_nat_retries)) } - "network.tls.certificate_path" => Ok(Box::new( - inner - .core - .network - .tls - .certificate_path - .clone(), - )), - "network.tls.private_key_path" => Ok(Box::new( - inner - .core - .network - .tls - .private_key_path - .clone(), - )), + "network.tls.certificate_path" => { + Ok(Box::new(inner.core.network.tls.certificate_path.clone())) + } + "network.tls.private_key_path" => { + Ok(Box::new(inner.core.network.tls.private_key_path.clone())) + } "network.tls.connection_initial_timeout_ms" => Ok(Box::new( inner.core.network.tls.connection_initial_timeout_ms, )), @@ -1439,7 +1427,8 @@ mod tests { assert_eq!(s.daemon.group, None); assert_eq!(s.daemon.stdout_file, None); assert_eq!(s.daemon.stderr_file, None); - assert!(s.client_api.enabled); + assert!(s.client_api.ipc_enabled); + assert!(!s.client_api.network_enabled); assert_eq!(s.client_api.listen_address.name, "localhost:5959"); assert_eq!( s.client_api.listen_address.addrs, diff --git a/veilid-tools/Cargo.toml b/veilid-tools/Cargo.toml index a54dc939..46dbda0f 100644 --- a/veilid-tools/Cargo.toml +++ b/veilid-tools/Cargo.toml @@ -23,6 +23,7 @@ rt-async-std = [ rt-tokio = [ "tokio", "tokio-util", + "tokio-stream", "rtnetlink/tokio_socket", "async_executors/tokio_tp", "async_executors/tokio_io", @@ -66,6 +67,7 @@ flume = { version = "0.11.0", features = ["async"] } async-std = { version = "1.12.0", features = ["unstable"], optional = true } tokio = { version = "1.32.0", features = ["full"], optional = true } tokio-util = { version = "0.7.8", features = ["compat"], optional = true } +tokio-stream = { version = "0.1.14", features = ["net"], optional = true } futures-util = { version = "0.3.28", default-features = false, features = [ "async-await", "sink", diff --git a/veilid-tools/src/ipc/ipc_async_std/mod.rs b/veilid-tools/src/ipc/ipc_async_std/mod.rs new file mode 100644 index 00000000..a07114e9 --- /dev/null +++ b/veilid-tools/src/ipc/ipc_async_std/mod.rs @@ -0,0 +1,11 @@ +use cfg_if::*; + +cfg_if! { + if #[cfg(unix)] { + mod unix; + pub use unix::*; + } else if #[cfg(windows)] { + mod windows; + pub use windows::*; + } +} diff --git a/veilid-tools/src/ipc/ipc_async_std/unix.rs b/veilid-tools/src/ipc/ipc_async_std/unix.rs new file mode 100644 index 00000000..e69de29b diff --git a/veilid-tools/src/ipc/ipc_async_std/windows.rs b/veilid-tools/src/ipc/ipc_async_std/windows.rs new file mode 100644 index 00000000..e69de29b diff --git a/veilid-tools/src/ipc/ipc_tokio/mod.rs b/veilid-tools/src/ipc/ipc_tokio/mod.rs new file mode 100644 index 00000000..a07114e9 --- /dev/null +++ b/veilid-tools/src/ipc/ipc_tokio/mod.rs @@ -0,0 +1,11 @@ +use cfg_if::*; + +cfg_if! { + if #[cfg(unix)] { + mod unix; + pub use unix::*; + } else if #[cfg(windows)] { + mod windows; + pub use windows::*; + } +} diff --git a/veilid-tools/src/ipc/ipc_tokio/unix.rs b/veilid-tools/src/ipc/ipc_tokio/unix.rs new file mode 100644 index 00000000..39246332 --- /dev/null +++ b/veilid-tools/src/ipc/ipc_tokio/unix.rs @@ -0,0 +1,114 @@ +use futures_util::AsyncRead as FuturesAsyncRead; +use futures_util::AsyncWrite as FuturesAsyncWrite; +use futures_util::Stream; +use std::{io, path::Path}; +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tokio::net::{UnixListener, UnixStream}; +use tokio_stream::wrappers::UnixListenerStream; +///////////////////////////////////////////////////////////// + +pub struct IpcStream { + internal: UnixStream, +} + +impl IpcStream { + pub async fn connect>(path: P) -> io::Result { + Ok(IpcStream { + internal: UnixStream::connect(path).await?, + }) + } +} + +impl FuturesAsyncRead for IpcStream { + fn poll_read( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut [u8], + ) -> std::task::Poll> { + let mut rb = ReadBuf::new(buf); + match ::poll_read( + std::pin::Pin::new(&mut self.internal), + cx, + &mut rb, + ) { + std::task::Poll::Ready(r) => std::task::Poll::Ready(r.map(|_| rb.filled().len())), + std::task::Poll::Pending => std::task::Poll::Pending, + } + } +} + +impl FuturesAsyncWrite for IpcStream { + fn poll_write( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &[u8], + ) -> std::task::Poll> { + ::poll_write(std::pin::Pin::new(&mut self.internal), cx, buf) + } + + fn poll_flush( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + ::poll_flush(std::pin::Pin::new(&mut self.internal), cx) + } + + fn poll_close( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + ::poll_shutdown(std::pin::Pin::new(&mut self.internal), cx) + } +} + +///////////////////////////////////////////////////////////// + +pub struct IpcIncoming { + internal: UnixListenerStream, +} + +impl Stream for IpcIncoming { + type Item = io::Result; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + match ::poll_next(std::pin::Pin::new(&mut self.internal), cx) + { + std::task::Poll::Ready(ro) => { + std::task::Poll::Ready(ro.map(|rr| rr.map(|s| IpcStream { internal: s }))) + } + std::task::Poll::Pending => std::task::Poll::Pending, + } + } +} + +///////////////////////////////////////////////////////////// + +pub struct IpcListener { + internal: UnixListener, +} + +impl IpcListener { + /// Creates a new `IpcListener` bound to the specified path. + pub async fn bind>(path: P) -> io::Result { + Ok(Self { + internal: UnixListener::bind(path)?, + }) + } + + /// Accepts a new incoming connection to this listener. + pub async fn accept(&self) -> io::Result { + Ok(IpcStream { + internal: self.internal.accept().await?.0, + }) + } + + /// Returns a stream of incoming connections. + pub fn incoming(self) -> IpcIncoming { + IpcIncoming { + internal: UnixListenerStream::new(self.internal), + } + } +} diff --git a/veilid-tools/src/ipc/ipc_tokio/windows.rs b/veilid-tools/src/ipc/ipc_tokio/windows.rs new file mode 100644 index 00000000..e69de29b diff --git a/veilid-tools/src/ipc/mod.rs b/veilid-tools/src/ipc/mod.rs new file mode 100644 index 00000000..ec24eb5d --- /dev/null +++ b/veilid-tools/src/ipc/mod.rs @@ -0,0 +1,11 @@ +use cfg_if::*; + +cfg_if! { + if #[cfg(feature="rt-tokio")] { + mod ipc_tokio; + pub use ipc_tokio::*; + } else if #[cfg(feature="rt-async-std")] { + mod ipc_async_std; + pub use ipc_async_std::*; + } +} diff --git a/veilid-tools/src/lib.rs b/veilid-tools/src/lib.rs index 9f6836ac..c0a5b2a6 100644 --- a/veilid-tools/src/lib.rs +++ b/veilid-tools/src/lib.rs @@ -36,6 +36,7 @@ pub mod eventual_value_clone; pub mod interval; pub mod ip_addr_port; pub mod ip_extra; +pub mod ipc; pub mod log_thru; pub mod must_join_handle; pub mod must_join_single_future; @@ -176,6 +177,8 @@ pub use ip_addr_port::*; #[doc(inline)] pub use ip_extra::*; #[doc(inline)] +pub use ipc::*; +#[doc(inline)] pub use log_thru::*; #[doc(inline)] pub use must_join_handle::*; diff --git a/veilid-tools/src/tools.rs b/veilid-tools/src/tools.rs index 1d8017c7..e86ca492 100644 --- a/veilid-tools/src/tools.rs +++ b/veilid-tools/src/tools.rs @@ -314,7 +314,7 @@ cfg_if::cfg_if! { pub fn ensure_file_private_owner>(path: P) -> Result<(), String> { let path = path.as_ref(); - if !path.exists() { + if !path.is_file() { return Ok(()); } @@ -330,6 +330,32 @@ cfg_if::cfg_if! { } Ok(()) } + + pub fn ensure_directory_private_owner>(path: P, group_read: bool) -> Result<(), String> + { + let path = path.as_ref(); + if !path.is_dir() { + return Ok(()); + } + + let uid = Uid::effective(); + let gid = Gid::effective(); + let meta = std::fs::metadata(path).map_err(|e| format!("unable to get metadata for path: {}", e))?; + + let perm = if group_read { + 0o750 + } else { + 0o700 + }; + + if meta.mode() != perm { + std::fs::set_permissions(path,std::fs::Permissions::from_mode(perm)).map_err(|e| format!("unable to set correct permissions on path: {}", e))?; + } + if meta.uid() != uid.as_raw() || meta.gid() != gid.as_raw() { + return Err("path has incorrect owner/group".to_owned()); + } + Ok(()) + } } else if #[cfg(windows)] { //use std::os::windows::fs::MetadataExt; //use windows_permissions::*; From caa274611060c4d7e2098b0ea97a57d00bb8cbfe Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 14 Dec 2023 21:28:02 -0500 Subject: [PATCH 44/67] ipc works --- veilid-cli/src/main.rs | 2 +- veilid-cli/src/settings.rs | 10 +-- veilid-cli/src/ui.rs | 153 +++++++++++++++++--------------- veilid-server/src/client_api.rs | 12 +++ veilid-server/src/main.rs | 3 - veilid-server/src/settings.rs | 2 +- 6 files changed, 100 insertions(+), 82 deletions(-) diff --git a/veilid-cli/src/main.rs b/veilid-cli/src/main.rs index 39a3577a..6e03990e 100644 --- a/veilid-cli/src/main.rs +++ b/veilid-cli/src/main.rs @@ -31,7 +31,7 @@ struct CmdlineArgs { /// IPC socket to connect to #[arg(long, short = 'p')] ipc_path: Option, - /// IPC socket to connect to + /// Subnode index to use when connecting #[arg(long, short = 'i', default_value = "0")] subnode_index: usize, /// Address to connect to diff --git a/veilid-cli/src/settings.rs b/veilid-cli/src/settings.rs index 5aeea7e9..992f325a 100644 --- a/veilid-cli/src/settings.rs +++ b/veilid-cli/src/settings.rs @@ -8,7 +8,7 @@ use std::path::{Path, PathBuf}; pub fn load_default_config() -> Result { let default_config = r#"--- enable_ipc: true -local_socket_path: '%LOCAL_SOCKET_DIRECTORY%' +ipc_path: '%IPC_DIRECTORY%' enable_network: true address: "localhost:5959" autoconnect: true @@ -49,8 +49,8 @@ interface: error : "light red" "# .replace( - "%LOCAL_SOCKET_DIRECTORY%", - &Settings::get_default_local_socket_path().to_string_lossy(), + "%IPC_DIRECTORY%", + &Settings::get_default_ipc_directory().to_string_lossy(), ) .replace( "%LOGGING_FILE_DIRECTORY%", @@ -248,8 +248,8 @@ impl Settings { ts_path } - pub fn get_default_local_socket_path() -> PathBuf { - Self::get_server_default_directory("local_sockets") + pub fn get_default_ipc_directory() -> PathBuf { + Self::get_server_default_directory("ipc") } pub fn get_default_config_path() -> PathBuf { diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index c723269d..85bf5c85 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -27,18 +27,24 @@ use thiserror::Error; ////////////////////////////////////////////////////////////// /// -struct Dirty { +struct Dirty +where + T: PartialEq, +{ value: T, dirty: bool, } -impl Dirty { +impl Dirty +where + T: PartialEq, +{ pub fn new(value: T) -> Self { Self { value, dirty: true } } pub fn set(&mut self, value: T) { + self.dirty = self.value != value; self.value = value; - self.dirty = true; } pub fn get(&self) -> &T { &self.value @@ -266,6 +272,9 @@ impl UI { fn ipc_path_radio(s: &mut Cursive) -> ViewRef> { s.find_name("ipc-path-radio").unwrap() } + fn connecting_text(s: &mut Cursive) -> ViewRef { + s.find_name("connecting-text").unwrap() + } fn network_address(s: &mut Cursive) -> ViewRef { s.find_name("network-address").unwrap() } @@ -618,7 +627,7 @@ impl UI { EventResult::Ignored } - fn show_connection_dialog(s: &mut Cursive, state: ConnectionState) -> bool { + fn draw_connection_dialog(s: &mut Cursive, state: ConnectionState) -> bool { let is_ipc = Self::command_processor(s).get_ipc_path().is_some(); let mut inner = Self::inner_mut(s); @@ -634,7 +643,7 @@ impl UI { let mut show: bool = false; let mut hide: bool = false; - let mut reset: bool = false; + let mut connecting: bool = false; match state { ConnectionState::Disconnected => { if inner.connection_dialog_state.is_none() @@ -651,7 +660,8 @@ impl UI { .unwrap() .is_retrying() { - reset = true; + hide = true; + show = true } } ConnectionState::ConnectedTCP(_, _) | ConnectionState::ConnectedIPC(_, _) => { @@ -680,8 +690,10 @@ impl UI { .unwrap() .is_disconnected() { - reset = true; + hide = true; + show = true; } + connecting = true; } } inner.connection_dialog_state = Some(state); @@ -689,7 +701,6 @@ impl UI { if hide { s.pop_layer(); s.pop_layer(); - return true; } if show { s.add_fullscreen_layer(Layer::with_color( @@ -698,56 +709,68 @@ impl UI { )); s.add_layer( - Dialog::around( - LinearLayout::vertical().child( - LinearLayout::horizontal() - .child( - if is_ipc { - connection_type_group.button(0, "IPC Path").selected() - } else { - connection_type_group.button(0, "IPC Path") - } - .with_name("ipc-path-radio"), - ) - .child( - EditView::new() - .with_enabled(is_ipc) - .on_submit(|s, _| Self::submit_ipc_path(s)) - .with_name("ipc-path") - .fixed_height(1) - .min_width(40), - ) - .child( - if is_ipc { - connection_type_group.button(1, "Network Address") - } else { - connection_type_group - .button(1, "Network Address") - .selected() - } - .with_name("network-address-radio"), - ) - .child( - EditView::new() - .with_enabled(!is_ipc) - .on_submit(|s, _| Self::submit_network_address(s)) - .with_name("network-address") - .fixed_height(1) - .min_width(40), - ), - ), - ) - .title("Connect to server") + Dialog::around(if connecting { + LinearLayout::vertical() + .child(TextView::new(" ")) + .child( + TextView::new(if is_ipc { + "Connecting to IPC:" + } else { + "Connecting to TCP:" + }) + .min_width(40), + ) + .child(TextView::new("").with_name("connecting-text")) + } else { + LinearLayout::vertical() + .child(TextView::new(" ")) + .child( + if is_ipc { + connection_type_group.button(0, "IPC Path").selected() + } else { + connection_type_group.button(0, "IPC Path") + } + .with_name("ipc-path-radio"), + ) + .child( + EditView::new() + .with_enabled(is_ipc) + .on_submit(|s, _| Self::submit_ipc_path(s)) + .with_name("ipc-path") + .fixed_height(1) + .min_width(40), + ) + .child(TextView::new(" ")) + .child( + if is_ipc { + connection_type_group.button(1, "Network Address") + } else { + connection_type_group + .button(1, "Network Address") + .selected() + } + .with_name("network-address-radio"), + ) + .child( + EditView::new() + .with_enabled(!is_ipc) + .on_submit(|s, _| Self::submit_network_address(s)) + .with_name("network-address") + .fixed_height(1) + .min_width(40), + ) + .child(TextView::new(" ")) + }) + .title(if connecting { + "Connecting to server..." + } else { + "Connect to server" + }) .with_name("connection-dialog"), ); return true; } - if reset { - let mut dlg = Self::connection_dialog(s); - dlg.clear_buttons(); - return true; - } false } @@ -755,7 +778,7 @@ impl UI { fn refresh_connection_dialog(s: &mut Cursive) { let new_state = Self::inner(s).ui_state.connection_state.get().clone(); - if !Self::show_connection_dialog(s, new_state.clone()) { + if !Self::draw_connection_dialog(s, new_state.clone()) { return; } @@ -786,15 +809,8 @@ impl UI { } ConnectionState::ConnectedTCP(_, _) | ConnectionState::ConnectedIPC(_, _) => {} ConnectionState::RetryingTCP(addr, _) => { - Self::ipc_path_radio(s).set_enabled(false); - Self::network_address_radio(s).set_enabled(false); - - // - let mut edit = Self::network_address(s); - edit.set_content(addr.to_string()); - edit.set_enabled(false); - - Self::ipc_path(s).set_enabled(false); + let mut text = Self::connecting_text(s); + text.set_content(addr.to_string()); let mut dlg = Self::connection_dialog(s); dlg.add_button("Cancel", |s| { @@ -802,15 +818,8 @@ impl UI { }); } ConnectionState::RetryingIPC(ipc_path, _) => { - Self::ipc_path_radio(s).set_enabled(false); - Self::network_address_radio(s).set_enabled(false); - - // - let mut edit = Self::ipc_path(s); - edit.set_content(ipc_path.to_string_lossy().to_string()); - edit.set_enabled(false); - - Self::network_address(s).set_enabled(false); + let mut text = Self::connecting_text(s); + text.set_content(ipc_path.to_string_lossy().to_string()); let mut dlg = Self::connection_dialog(s); dlg.add_button("Cancel", |s| { diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 3f137b74..6c914be4 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -110,6 +110,12 @@ impl ClientApi { } async fn handle_ipc_incoming(self, ipc_path: PathBuf) -> std::io::Result<()> { + if ipc_path.exists() { + if let Err(e) = std::fs::remove_file(&ipc_path) { + error!("Binding failed because IPC path is in use: {}\nAnother copy of this application may be using the same IPC path.", e); + return Err(e); + } + } let listener = IpcListener::bind(ipc_path.clone()).await?; debug!("IPC Client API listening on: {:?}", ipc_path); @@ -137,6 +143,12 @@ impl ClientApi { // Wait for all connections to terminate awg.wait().await; + // Clean up IPC path + if let Err(e) = std::fs::remove_file(&ipc_path) { + warn!("Unable to remove IPC socket: {}", e); + return Err(e); + } + Ok(()) } diff --git a/veilid-server/src/main.rs b/veilid-server/src/main.rs index 252ba2d4..03c94e63 100644 --- a/veilid-server/src/main.rs +++ b/veilid-server/src/main.rs @@ -180,9 +180,6 @@ fn main() -> EyreResult<()> { settingsrw.daemon.enabled = false; } if let Some(subnode_index) = args.subnode_index { - if subnode_index == 0 { - bail!("value of subnode_index should be between 1 and 65535"); - } settingsrw.testing.subnode_index = subnode_index; }; diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 95b3bc6f..f2f69434 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -18,7 +18,7 @@ pub fn load_default_config() -> EyreResult { daemon: enabled: false client_api: - ipc_enabled: false + ipc_enabled: true ipc_directory: '%IPC_DIRECTORY%' network_enabled: false listen_address: 'localhost:5959' From eecbb1477439185653116c74b3ff4abcd027e89e Mon Sep 17 00:00:00 2001 From: John Smith Date: Thu, 14 Dec 2023 21:42:58 -0500 Subject: [PATCH 45/67] defer to specified command line mode --- veilid-cli/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/veilid-cli/src/main.rs b/veilid-cli/src/main.rs index 6e03990e..c50f6d32 100644 --- a/veilid-cli/src/main.rs +++ b/veilid-cli/src/main.rs @@ -131,8 +131,8 @@ fn main() -> Result<(), String> { } // Get client address - let enable_ipc = settings.enable_ipc; - let mut enable_network = settings.enable_network; + let enable_ipc = settings.enable_ipc && args.address.is_none(); + let mut enable_network = settings.enable_network && args.ipc_path.is_none(); // Determine IPC path to try let mut client_api_ipc_path = None; From bdb64a96ea6862ae362158d5816ba681778b25a7 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 15 Dec 2023 11:30:53 -0500 Subject: [PATCH 46/67] cleanup a bit --- veilid-python/poetry.lock | 226 +++++++++++++++++++------ veilid-python/pyproject.toml | 1 + veilid-python/tests/api.py | 40 ++++- veilid-python/veilid/json_api.py | 18 ++ veilid-server/src/client_api.rs | 6 - veilid-tools/src/ipc/ipc_tokio/unix.rs | 36 +++- 6 files changed, 256 insertions(+), 71 deletions(-) diff --git a/veilid-python/poetry.lock b/veilid-python/poetry.lock index 85a37c9b..94643712 100644 --- a/veilid-python/poetry.lock +++ b/veilid-python/poetry.lock @@ -1,5 +1,16 @@ # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. +[[package]] +name = "appdirs" +version = "1.4.4" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = "*" +files = [ + {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, + {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +] + [[package]] name = "attrs" version = "23.1.0" @@ -42,94 +53,74 @@ files = [ [[package]] name = "jsonschema" -version = "4.17.3" +version = "4.20.0" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, + {file = "jsonschema-4.20.0-py3-none-any.whl", hash = "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3"}, + {file = "jsonschema-4.20.0.tar.gz", hash = "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa"}, ] [package.dependencies] -attrs = ">=17.4.0" -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +attrs = ">=22.2.0" +jsonschema-specifications = ">=2023.03.6" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +[[package]] +name = "jsonschema-specifications" +version = "2023.11.2" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.11.2-py3-none-any.whl", hash = "sha256:e74ba7c0a65e8cb49dc26837d6cfe576557084a8b423ed16a420984228104f93"}, + {file = "jsonschema_specifications-2023.11.2.tar.gz", hash = "sha256:9472fc4fea474cd74bea4a2b190daeccb5a9e4db2ea80efcf7a1b582fc9a81b8"}, +] + +[package.dependencies] +referencing = ">=0.31.0" + [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] name = "pluggy" -version = "1.0.0" +version = "1.3.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, + {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"}, + {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"}, ] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] - [[package]] name = "pytest" -version = "7.3.2" +version = "7.4.3" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.3.2-py3-none-any.whl", hash = "sha256:cdcbd012c9312258922f8cd3f1b62a6580fdced17db6014896053d47cddf9295"}, - {file = "pytest-7.3.2.tar.gz", hash = "sha256:ee990a3cc55ba808b80795a79944756f315c67c12b56abd3ac993a7b8c17030b"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] @@ -143,13 +134,13 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no [[package]] name = "pytest-asyncio" -version = "0.21.0" +version = "0.21.1" description = "Pytest support for asyncio" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-asyncio-0.21.0.tar.gz", hash = "sha256:2b38a496aef56f56b0e87557ec313e11e1ab9276fc3863f6a7be0f1d0e415e1b"}, - {file = "pytest_asyncio-0.21.0-py3-none-any.whl", hash = "sha256:f2b3366b7cd501a4056858bd39349d5af19742aed2d81660b7998b6341c7eb9c"}, + {file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"}, + {file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"}, ] [package.dependencies] @@ -159,7 +150,130 @@ pytest = ">=7.0.0" docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] +[[package]] +name = "referencing" +version = "0.32.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.32.0-py3-none-any.whl", hash = "sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99"}, + {file = "referencing-0.32.0.tar.gz", hash = "sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "rpds-py" +version = "0.13.2" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.13.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:1ceebd0ae4f3e9b2b6b553b51971921853ae4eebf3f54086be0565d59291e53d"}, + {file = "rpds_py-0.13.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:46e1ed994a0920f350a4547a38471217eb86f57377e9314fbaaa329b71b7dfe3"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee353bb51f648924926ed05e0122b6a0b1ae709396a80eb583449d5d477fcdf7"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:530190eb0cd778363bbb7596612ded0bb9fef662daa98e9d92a0419ab27ae914"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29d311e44dd16d2434d5506d57ef4d7036544fc3c25c14b6992ef41f541b10fb"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e72f750048b32d39e87fc85c225c50b2a6715034848dbb196bf3348aa761fa1"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db09b98c7540df69d4b47218da3fbd7cb466db0fb932e971c321f1c76f155266"}, + {file = "rpds_py-0.13.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2ac26f50736324beb0282c819668328d53fc38543fa61eeea2c32ea8ea6eab8d"}, + {file = "rpds_py-0.13.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:12ecf89bd54734c3c2c79898ae2021dca42750c7bcfb67f8fb3315453738ac8f"}, + {file = "rpds_py-0.13.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a44c8440183b43167fd1a0819e8356692bf5db1ad14ce140dbd40a1485f2dea"}, + {file = "rpds_py-0.13.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bcef4f2d3dc603150421de85c916da19471f24d838c3c62a4f04c1eb511642c1"}, + {file = "rpds_py-0.13.2-cp310-none-win32.whl", hash = "sha256:ee6faebb265e28920a6f23a7d4c362414b3f4bb30607141d718b991669e49ddc"}, + {file = "rpds_py-0.13.2-cp310-none-win_amd64.whl", hash = "sha256:ac96d67b37f28e4b6ecf507c3405f52a40658c0a806dffde624a8fcb0314d5fd"}, + {file = "rpds_py-0.13.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:b5f6328e8e2ae8238fc767703ab7b95785521c42bb2b8790984e3477d7fa71ad"}, + {file = "rpds_py-0.13.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:729408136ef8d45a28ee9a7411917c9e3459cf266c7e23c2f7d4bb8ef9e0da42"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65cfed9c807c27dee76407e8bb29e6f4e391e436774bcc769a037ff25ad8646e"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:aefbdc934115d2f9278f153952003ac52cd2650e7313750390b334518c589568"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d48db29bd47814671afdd76c7652aefacc25cf96aad6daefa82d738ee87461e2"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c55d7f2d817183d43220738270efd3ce4e7a7b7cbdaefa6d551ed3d6ed89190"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6aadae3042f8e6db3376d9e91f194c606c9a45273c170621d46128f35aef7cd0"}, + {file = "rpds_py-0.13.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5feae2f9aa7270e2c071f488fab256d768e88e01b958f123a690f1cc3061a09c"}, + {file = "rpds_py-0.13.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51967a67ea0d7b9b5cd86036878e2d82c0b6183616961c26d825b8c994d4f2c8"}, + {file = "rpds_py-0.13.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d0c10d803549427f427085ed7aebc39832f6e818a011dcd8785e9c6a1ba9b3e"}, + {file = "rpds_py-0.13.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:603d5868f7419081d616dab7ac3cfa285296735e7350f7b1e4f548f6f953ee7d"}, + {file = "rpds_py-0.13.2-cp311-none-win32.whl", hash = "sha256:b8996ffb60c69f677245f5abdbcc623e9442bcc91ed81b6cd6187129ad1fa3e7"}, + {file = "rpds_py-0.13.2-cp311-none-win_amd64.whl", hash = "sha256:5379e49d7e80dca9811b36894493d1c1ecb4c57de05c36f5d0dd09982af20211"}, + {file = "rpds_py-0.13.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:8a776a29b77fe0cc28fedfd87277b0d0f7aa930174b7e504d764e0b43a05f381"}, + {file = "rpds_py-0.13.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2a1472956c5bcc49fb0252b965239bffe801acc9394f8b7c1014ae9258e4572b"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f252dfb4852a527987a9156cbcae3022a30f86c9d26f4f17b8c967d7580d65d2"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f0d320e70b6b2300ff6029e234e79fe44e9dbbfc7b98597ba28e054bd6606a57"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ade2ccb937060c299ab0dfb2dea3d2ddf7e098ed63ee3d651ebfc2c8d1e8632a"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9d121be0217787a7d59a5c6195b0842d3f701007333426e5154bf72346aa658"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fa6bd071ec6d90f6e7baa66ae25820d57a8ab1b0a3c6d3edf1834d4b26fafa2"}, + {file = "rpds_py-0.13.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c918621ee0a3d1fe61c313f2489464f2ae3d13633e60f520a8002a5e910982ee"}, + {file = "rpds_py-0.13.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:25b28b3d33ec0a78e944aaaed7e5e2a94ac811bcd68b557ca48a0c30f87497d2"}, + {file = "rpds_py-0.13.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:31e220a040b89a01505128c2f8a59ee74732f666439a03e65ccbf3824cdddae7"}, + {file = "rpds_py-0.13.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:15253fff410873ebf3cfba1cc686a37711efcd9b8cb30ea21bb14a973e393f60"}, + {file = "rpds_py-0.13.2-cp312-none-win32.whl", hash = "sha256:b981a370f8f41c4024c170b42fbe9e691ae2dbc19d1d99151a69e2c84a0d194d"}, + {file = "rpds_py-0.13.2-cp312-none-win_amd64.whl", hash = "sha256:4c4e314d36d4f31236a545696a480aa04ea170a0b021e9a59ab1ed94d4c3ef27"}, + {file = "rpds_py-0.13.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:80e5acb81cb49fd9f2d5c08f8b74ffff14ee73b10ca88297ab4619e946bcb1e1"}, + {file = "rpds_py-0.13.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:efe093acc43e869348f6f2224df7f452eab63a2c60a6c6cd6b50fd35c4e075ba"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c2a61c0e4811012b0ba9f6cdcb4437865df5d29eab5d6018ba13cee1c3064a0"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:751758d9dd04d548ec679224cc00e3591f5ebf1ff159ed0d4aba6a0746352452"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ba8858933f0c1a979781272a5f65646fca8c18c93c99c6ddb5513ad96fa54b1"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bfdfbe6a36bc3059fff845d64c42f2644cf875c65f5005db54f90cdfdf1df815"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa0379c1935c44053c98826bc99ac95f3a5355675a297ac9ce0dfad0ce2d50ca"}, + {file = "rpds_py-0.13.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d5593855b5b2b73dd8413c3fdfa5d95b99d657658f947ba2c4318591e745d083"}, + {file = "rpds_py-0.13.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2a7bef6977043673750a88da064fd513f89505111014b4e00fbdd13329cd4e9a"}, + {file = "rpds_py-0.13.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:3ab96754d23372009638a402a1ed12a27711598dd49d8316a22597141962fe66"}, + {file = "rpds_py-0.13.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:e06cfea0ece444571d24c18ed465bc93afb8c8d8d74422eb7026662f3d3f779b"}, + {file = "rpds_py-0.13.2-cp38-none-win32.whl", hash = "sha256:5493569f861fb7b05af6d048d00d773c6162415ae521b7010197c98810a14cab"}, + {file = "rpds_py-0.13.2-cp38-none-win_amd64.whl", hash = "sha256:b07501b720cf060c5856f7b5626e75b8e353b5f98b9b354a21eb4bfa47e421b1"}, + {file = "rpds_py-0.13.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:881df98f0a8404d32b6de0fd33e91c1b90ed1516a80d4d6dc69d414b8850474c"}, + {file = "rpds_py-0.13.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d79c159adea0f1f4617f54aa156568ac69968f9ef4d1e5fefffc0a180830308e"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38d4f822ee2f338febcc85aaa2547eb5ba31ba6ff68d10b8ec988929d23bb6b4"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5d75d6d220d55cdced2f32cc22f599475dbe881229aeddba6c79c2e9df35a2b3"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5d97e9ae94fb96df1ee3cb09ca376c34e8a122f36927230f4c8a97f469994bff"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:67a429520e97621a763cf9b3ba27574779c4e96e49a27ff8a1aa99ee70beb28a"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:188435794405c7f0573311747c85a96b63c954a5f2111b1df8018979eca0f2f0"}, + {file = "rpds_py-0.13.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:38f9bf2ad754b4a45b8210a6c732fe876b8a14e14d5992a8c4b7c1ef78740f53"}, + {file = "rpds_py-0.13.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a6ba2cb7d676e9415b9e9ac7e2aae401dc1b1e666943d1f7bc66223d3d73467b"}, + {file = "rpds_py-0.13.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:eaffbd8814bb1b5dc3ea156a4c5928081ba50419f9175f4fc95269e040eff8f0"}, + {file = "rpds_py-0.13.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a4c1058cdae6237d97af272b326e5f78ee7ee3bbffa6b24b09db4d828810468"}, + {file = "rpds_py-0.13.2-cp39-none-win32.whl", hash = "sha256:b5267feb19070bef34b8dea27e2b504ebd9d31748e3ecacb3a4101da6fcb255c"}, + {file = "rpds_py-0.13.2-cp39-none-win_amd64.whl", hash = "sha256:ddf23960cb42b69bce13045d5bc66f18c7d53774c66c13f24cf1b9c144ba3141"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:97163a1ab265a1073a6372eca9f4eeb9f8c6327457a0b22ddfc4a17dcd613e74"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:25ea41635d22b2eb6326f58e608550e55d01df51b8a580ea7e75396bafbb28e9"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d59d4d451ba77f08cb4cd9268dec07be5bc65f73666302dbb5061989b17198"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e7c564c58cf8f248fe859a4f0fe501b050663f3d7fbc342172f259124fb59933"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61dbc1e01dc0c5875da2f7ae36d6e918dc1b8d2ce04e871793976594aad8a57a"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdb82eb60d31b0c033a8e8ee9f3fc7dfbaa042211131c29da29aea8531b4f18f"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d204957169f0b3511fb95395a9da7d4490fb361763a9f8b32b345a7fe119cb45"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c45008ca79bad237cbc03c72bc5205e8c6f66403773929b1b50f7d84ef9e4d07"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:79bf58c08f0756adba691d480b5a20e4ad23f33e1ae121584cf3a21717c36dfa"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e86593bf8637659e6a6ed58854b6c87ec4e9e45ee8a4adfd936831cef55c2d21"}, + {file = "rpds_py-0.13.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:d329896c40d9e1e5c7715c98529e4a188a1f2df51212fd65102b32465612b5dc"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4a5375c5fff13f209527cd886dc75394f040c7d1ecad0a2cb0627f13ebe78a12"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:06d218e4464d31301e943b65b2c6919318ea6f69703a351961e1baaf60347276"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1f41d32a2ddc5a94df4b829b395916a4b7f103350fa76ba6de625fcb9e773ac"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6bc568b05e02cd612be53900c88aaa55012e744930ba2eeb56279db4c6676eb3"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d94d78418203904730585efa71002286ac4c8ac0689d0eb61e3c465f9e608ff"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bed0252c85e21cf73d2d033643c945b460d6a02fc4a7d644e3b2d6f5f2956c64"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244e173bb6d8f3b2f0c4d7370a1aa341f35da3e57ffd1798e5b2917b91731fd3"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7f55cd9cf1564b7b03f238e4c017ca4794c05b01a783e9291065cb2858d86ce4"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:f03a1b3a4c03e3e0161642ac5367f08479ab29972ea0ffcd4fa18f729cd2be0a"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:f5f4424cb87a20b016bfdc157ff48757b89d2cc426256961643d443c6c277007"}, + {file = "rpds_py-0.13.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c82bbf7e03748417c3a88c1b0b291288ce3e4887a795a3addaa7a1cfd9e7153e"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c0095b8aa3e432e32d372e9a7737e65b58d5ed23b9620fea7cb81f17672f1fa1"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:4c2d26aa03d877c9730bf005621c92da263523a1e99247590abbbe252ccb7824"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:96f2975fb14f39c5fe75203f33dd3010fe37d1c4e33177feef1107b5ced750e3"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4dcc5ee1d0275cb78d443fdebd0241e58772a354a6d518b1d7af1580bbd2c4e8"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61d42d2b08430854485135504f672c14d4fc644dd243a9c17e7c4e0faf5ed07e"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d3a61e928feddc458a55110f42f626a2a20bea942ccedb6fb4cee70b4830ed41"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7de12b69d95072394998c622cfd7e8cea8f560db5fca6a62a148f902a1029f8b"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87a90f5545fd61f6964e65eebde4dc3fa8660bb7d87adb01d4cf17e0a2b484ad"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:9c95a1a290f9acf7a8f2ebbdd183e99215d491beea52d61aa2a7a7d2c618ddc6"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:35f53c76a712e323c779ca39b9a81b13f219a8e3bc15f106ed1e1462d56fcfe9"}, + {file = "rpds_py-0.13.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:96fb0899bb2ab353f42e5374c8f0789f54e0a94ef2f02b9ac7149c56622eaf31"}, + {file = "rpds_py-0.13.2.tar.gz", hash = "sha256:f8eae66a1304de7368932b42d801c67969fd090ddb1a7a24f27b435ed4bed68f"}, +] + [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "03a349f63b3d28e64191b6dd845333914827806332b52f5c52ccbd2863c93b4b" +content-hash = "a7ed29c103fe92e0aff96ea5bb601e6e10e651c5c9806d87d2b05a675edaf2ec" diff --git a/veilid-python/pyproject.toml b/veilid-python/pyproject.toml index 0e00d993..4b58dbbe 100644 --- a/veilid-python/pyproject.toml +++ b/veilid-python/pyproject.toml @@ -15,6 +15,7 @@ jsonschema = "^4.17.3" [tool.poetry.group.dev.dependencies] pytest = "^7.3.2" pytest-asyncio = "^0.21.0" +appdirs = "^1.4.4" [build-system] requires = ["poetry-core"] diff --git a/veilid-python/tests/api.py b/veilid-python/tests/api.py index d6c44ecb..a6855375 100644 --- a/veilid-python/tests/api.py +++ b/veilid-python/tests/api.py @@ -1,5 +1,8 @@ +import appdirs import errno import os +import socket +import sys import re from collections.abc import Callable from functools import cache @@ -20,15 +23,38 @@ class VeilidTestConnectionError(Exception): @cache def server_info() -> tuple[str, int]: """Return the hostname and port of the test server.""" - VEILID_SERVER = os.getenv("VEILID_SERVER") - if VEILID_SERVER is None: + VEILID_SERVER_NETWORK = os.getenv("VEILID_SERVER_NETWORK") + if VEILID_SERVER_NETWORK is None: return "localhost", 5959 - hostname, *rest = VEILID_SERVER.split(":") + hostname, *rest = VEILID_SERVER_NETWORK.split(":") if rest: return hostname, int(rest[0]) return hostname, 5959 +@cache +def ipc_info() -> str: + """Return the path of the ipc socket of the test server.""" + VEILID_SERVER_IPC = os.getenv("VEILID_SERVER_IPC") + if VEILID_SERVER_IPC is not None: + return VEILID_SERVER_IPC + + if os.name == 'nt': + return '\\\\.\\PIPE\\veilid-server\\ipc\\0' + + if os.name == 'posix': + ipc_0_path = "/var/db/veilid-server/ipc/0" + if os.path.exists(ipc_0_path): + return ipc_0_path + + # hack to deal with rust's 'directories' crate case-inconsistency + if sys.platform.startswith('darwin'): + data_dir = appdirs.user_data_dir("Veilid","Veilid") + else: + data_dir = appdirs.user_data_dir("veilid","veilid") + ipc_0_path = os.path.join(data_dir, "ipc", "0") + return ipc_0_path + async def api_connector(callback: Callable) -> _JsonVeilidAPI: """Return an API connection if possible. @@ -37,9 +63,15 @@ async def api_connector(callback: Callable) -> _JsonVeilidAPI: server's socket, raise an easy-to-catch VeilidTestConnectionError. """ + ipc_path = ipc_info() hostname, port = server_info() + try: - return await veilid.json_api_connect(hostname, port, callback) + print(f"ipc_path: {ipc_path}") + if os.path.exists(ipc_path): + return await veilid.json_api_connect_ipc(ipc_path, callback) + else: + return await veilid.json_api_connect(hostname, port, callback) except OSError as exc: # This is a little goofy. The underlying Python library handles # connection errors in 2 ways, depending on how many connections diff --git a/veilid-python/veilid/json_api.py b/veilid-python/veilid/json_api.py index af79d894..16cb20be 100644 --- a/veilid-python/veilid/json_api.py +++ b/veilid-python/veilid/json_api.py @@ -1,6 +1,8 @@ import asyncio import importlib.resources as importlib_resources import json +import os +import socket from typing import Awaitable, Callable, Optional, Self from jsonschema import exceptions, validators @@ -149,6 +151,17 @@ class _JsonVeilidAPI(VeilidAPI): ) return veilid_api + @classmethod + async def connect_ipc( + cls, ipc_path: str, update_callback: Callable[[VeilidUpdate], Awaitable] + ) -> Self: + reader, writer = await asyncio.open_unix_connection(ipc_path) + veilid_api = cls(reader, writer, update_callback) + veilid_api.handle_recv_messages_task = asyncio.create_task( + veilid_api.handle_recv_messages(), name="JsonVeilidAPI.handle_recv_messages" + ) + return veilid_api + async def handle_recv_message_response(self, j: dict): id = j["id"] await self.lock.acquire() @@ -1173,3 +1186,8 @@ async def json_api_connect( host: str, port: int, update_callback: Callable[[VeilidUpdate], Awaitable] ) -> _JsonVeilidAPI: return await _JsonVeilidAPI.connect(host, port, update_callback) + +async def json_api_connect_ipc( + ipc_path: str, update_callback: Callable[[VeilidUpdate], Awaitable] +) -> _JsonVeilidAPI: + return await _JsonVeilidAPI.connect_ipc(ipc_path, update_callback) diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 6c914be4..5bc3cf56 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -143,12 +143,6 @@ impl ClientApi { // Wait for all connections to terminate awg.wait().await; - // Clean up IPC path - if let Err(e) = std::fs::remove_file(&ipc_path) { - warn!("Unable to remove IPC socket: {}", e); - return Err(e); - } - Ok(()) } diff --git a/veilid-tools/src/ipc/ipc_tokio/unix.rs b/veilid-tools/src/ipc/ipc_tokio/unix.rs index 39246332..461220b5 100644 --- a/veilid-tools/src/ipc/ipc_tokio/unix.rs +++ b/veilid-tools/src/ipc/ipc_tokio/unix.rs @@ -1,6 +1,8 @@ +use crate::*; use futures_util::AsyncRead as FuturesAsyncRead; use futures_util::AsyncWrite as FuturesAsyncWrite; use futures_util::Stream; +use std::path::PathBuf; use std::{io, path::Path}; use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; use tokio::net::{UnixListener, UnixStream}; @@ -64,6 +66,7 @@ impl FuturesAsyncWrite for IpcStream { ///////////////////////////////////////////////////////////// pub struct IpcIncoming { + path: PathBuf, internal: UnixListenerStream, } @@ -84,31 +87,54 @@ impl Stream for IpcIncoming { } } +impl Drop for IpcIncoming { + fn drop(&mut self) { + // Clean up IPC path + if let Err(e) = std::fs::remove_file(&self.path) { + warn!("Unable to remove IPC socket: {}", e); + } + } +} + ///////////////////////////////////////////////////////////// pub struct IpcListener { - internal: UnixListener, + path: Option, + internal: Option, } impl IpcListener { /// Creates a new `IpcListener` bound to the specified path. pub async fn bind>(path: P) -> io::Result { Ok(Self { - internal: UnixListener::bind(path)?, + path: Some(path.as_ref().to_path_buf()), + internal: Some(UnixListener::bind(path)?), }) } /// Accepts a new incoming connection to this listener. pub async fn accept(&self) -> io::Result { Ok(IpcStream { - internal: self.internal.accept().await?.0, + internal: self.internal.as_ref().unwrap().accept().await?.0, }) } /// Returns a stream of incoming connections. - pub fn incoming(self) -> IpcIncoming { + pub fn incoming(mut self) -> IpcIncoming { IpcIncoming { - internal: UnixListenerStream::new(self.internal), + path: self.path.take().unwrap(), + internal: UnixListenerStream::new(self.internal.take().unwrap()), + } + } +} + +impl Drop for IpcListener { + fn drop(&mut self) { + // Clean up IPC path + if let Some(path) = &self.path { + if let Err(e) = std::fs::remove_file(path) { + warn!("Unable to remove IPC socket: {}", e); + } } } } From d454f9fdf9845662954ab94dcb0d93e4c68d772c Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 15 Dec 2023 13:49:10 -0500 Subject: [PATCH 47/67] update deps --- Cargo.lock | 431 ++++++++++++++++------------ veilid-cli/Cargo.toml | 8 +- veilid-core/Cargo.toml | 80 +++--- veilid-core/src/intf/wasm/system.rs | 2 +- veilid-flutter/rust/Cargo.toml | 18 +- veilid-server/Cargo.toml | 6 +- veilid-tools/Cargo.toml | 30 +- veilid-wasm/Cargo.toml | 2 +- veilid-wasm/tests/package-lock.json | 2 +- 9 files changed, 328 insertions(+), 251 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 637488ec..eb42d578 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -213,9 +213,9 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arboard" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac57f2b058a76363e357c056e4f74f1945bf734d37b8b3ef49066c4787dde0fc" +checksum = "aafb29b107435aa276664c1db8954ac27a6e105cdad3c88287a199eb0e313c08" dependencies = [ "clipboard-win", "core-graphics", @@ -349,7 +349,7 @@ dependencies = [ "futures-lite 2.0.1", "parking", "polling 3.3.0", - "rustix 0.38.21", + "rustix 0.38.28", "slab", "tracing", "waker-fn", @@ -389,7 +389,7 @@ dependencies = [ "cfg-if 1.0.0", "event-listener 3.0.1", "futures-lite 1.13.0", - "rustix 0.38.21", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -405,7 +405,7 @@ dependencies = [ "cfg-if 1.0.0", "futures-core", "futures-io", - "rustix 0.38.21", + "rustix 0.38.28", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -473,7 +473,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -490,7 +490,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -718,7 +718,7 @@ checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -812,9 +812,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "capnp" -version = "0.18.3" +version = "0.18.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "499cea1db22c19b7a823fa4876330700077b388cc7de2c5477028df00bcb4ae4" +checksum = "0e78424967d6d4c8e295a3b5114ae6d849052e9dbbed3e62589a76acda54e3f0" dependencies = [ "embedded-io", ] @@ -980,7 +980,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1055,9 +1055,9 @@ dependencies = [ [[package]] name = "config" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +checksum = "23738e11972c7643e4ec947840fc463b6a571afcd3e735bdfce7d03c7a784aca" dependencies = [ "async-trait", "json5", @@ -1201,9 +1201,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" dependencies = [ "cfg-if 1.0.0", ] @@ -1256,12 +1256,12 @@ dependencies = [ [[package]] name = "ctor" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e366bff8cd32dd8754b0991fb66b279dc48f598c3a18914852a6673deef583" +checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" dependencies = [ "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1377,7 +1377,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1433,7 +1433,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1455,7 +1455,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1473,9 +1473,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" [[package]] name = "der" @@ -1572,9 +1572,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" dependencies = [ "curve25519-dalek", "ed25519", @@ -1582,6 +1582,7 @@ dependencies = [ "serde", "sha2 0.10.8", "signature", + "subtle", "zeroize", ] @@ -1606,7 +1607,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1626,7 +1627,7 @@ checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1669,7 +1670,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -1703,12 +1704,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1750,9 +1751,9 @@ dependencies = [ [[package]] name = "eyre" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2b6b5a29c02cdc822728b7d7b8ae1bab3e3b05d44522770ddd49722eeac7eb" +checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" dependencies = [ "indenter", "once_cell", @@ -1812,14 +1813,14 @@ checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" [[package]] name = "filetime" -version = "0.2.22" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.3.5", - "windows-sys 0.48.0", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", ] [[package]] @@ -1891,9 +1892,9 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ "percent-encoding", ] @@ -1904,7 +1905,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -1989,7 +1990,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -2068,9 +2069,9 @@ dependencies = [ [[package]] name = "gethostname" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177" dependencies = [ "libc", "winapi", @@ -2078,9 +2079,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.10" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2448,6 +2449,16 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "ifstructs" version = "0.1.1" @@ -2572,9 +2583,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" [[package]] name = "jni" @@ -2606,9 +2617,9 @@ checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] @@ -2632,9 +2643,9 @@ dependencies = [ [[package]] name = "keyring-manager" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c023f807de9a2f26e86c6ec3b5a3e0ea5681301999dcda9e262069ab3efb63e" +checksum = "9aed4aad1a5c0ae5cfd990fd8cb7e1e31d1742e04c964a62b6928962838c766d" dependencies = [ "byteorder", "cfg-if 1.0.0", @@ -2730,9 +2741,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libc-print" @@ -2801,9 +2812,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.10" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" [[package]] name = "lock_api" @@ -2893,6 +2904,15 @@ dependencies = [ "autocfg", ] +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + [[package]] name = "memory_units" version = "0.4.0" @@ -3096,19 +3116,7 @@ dependencies = [ "cc", "cfg-if 1.0.0", "libc", - "memoffset", -] - -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if 1.0.0", - "libc", - "memoffset", + "memoffset 0.6.5", ] [[package]] @@ -3120,6 +3128,7 @@ dependencies = [ "bitflags 1.3.2", "cfg-if 1.0.0", "libc", + "memoffset 0.7.1", ] [[package]] @@ -3328,9 +3337,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -3589,9 +3598,9 @@ checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "percent-encoding" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" @@ -3624,7 +3633,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -3665,7 +3674,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -3751,7 +3760,7 @@ dependencies = [ "cfg-if 1.0.0", "concurrent-queue", "pin-project-lite", - "rustix 0.38.21", + "rustix 0.38.28", "tracing", "windows-sys 0.48.0", ] @@ -3800,9 +3809,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -3847,10 +3856,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", - "itertools 0.11.0", + "itertools 0.10.5", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -3915,12 +3924,12 @@ dependencies = [ [[package]] name = "range-set-blaze" -version = "0.1.9" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf36131a8443d1cda3cd66eeac16d60ce46aa7c415f71e12c28d95c195e3ff23" +checksum = "113937773e2f2211b7b9816e54e3e3cf433549c10af0f9ab966a43aa8098188c" dependencies = [ "gen_ops", - "itertools 0.10.5", + "itertools 0.11.0", "num-integer", "num-traits", ] @@ -3940,15 +3949,6 @@ dependencies = [ "bitflags 1.3.2", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.4.1" @@ -4025,9 +4025,9 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.5" +version = "0.17.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb0205304757e5d899b9c2e448b867ffd03ae7f988002e47cd24954391394d0b" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" dependencies = [ "cc", "getrandom", @@ -4149,22 +4149,22 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.21" +version = "0.38.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" dependencies = [ "bitflags 2.4.1", "errno", "libc", - "linux-raw-sys 0.4.10", - "windows-sys 0.48.0", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", ] [[package]] name = "rustls" -version = "0.21.8" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", "ring", @@ -4174,9 +4174,9 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ "base64 0.21.5", ] @@ -4199,9 +4199,9 @@ checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" [[package]] name = "same-file" @@ -4214,9 +4214,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f7b0ce13155372a76ee2e1c5ffba1fe61ede73fbea5630d61eee6fac4929c0c" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -4226,9 +4226,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.15" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e85e2a16b12bdb763244c69ab79363d71db2b4b918a2def53f80b02e0574b13c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -4324,9 +4324,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" dependencies = [ "serde_derive", ] @@ -4353,9 +4353,9 @@ dependencies = [ [[package]] name = "serde-wasm-bindgen" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ba92964781421b6cef36bf0d7da26d201e96d84e1b10e7ae6ed416e516906d" +checksum = "b9b713f70513ae1f8d92665bbbbda5c295c2cf1da5542881ae5eefe20c9af132" dependencies = [ "js-sys", "serde", @@ -4383,13 +4383,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.193" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4411,7 +4411,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4433,7 +4433,7 @@ checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4480,7 +4480,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4732,9 +4732,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.39" +version = "2.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a" +checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" dependencies = [ "proc-macro2", "quote", @@ -4749,9 +4749,9 @@ checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] name = "sysinfo" -version = "0.29.10" +version = "0.29.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5" +checksum = "cd727fc423c2060f6c92d9534cef765c65a6ed3f428a03d7def74a8c4348e666" dependencies = [ "cfg-if 1.0.0", "core-foundation-sys", @@ -4776,7 +4776,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.21", + "rustix 0.38.28", "windows-sys 0.48.0", ] @@ -4806,7 +4806,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -4878,9 +4878,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.33.0" +version = "1.35.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653" +checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" dependencies = [ "backtrace", "bytes", @@ -4908,13 +4908,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5104,7 +5104,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5149,6 +5149,17 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + [[package]] name = "tracing-opentelemetry" version = "0.21.0" @@ -5161,7 +5172,7 @@ dependencies = [ "smallvec", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.1.4", "tracing-subscriber", ] @@ -5183,9 +5194,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "matchers", "nu-ansi-term", @@ -5196,7 +5207,7 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", ] [[package]] @@ -5233,7 +5244,7 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "idna", + "idna 0.4.0", "ipnet", "once_cell", "rand", @@ -5295,7 +5306,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5331,9 +5342,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-bidi" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" [[package]] name = "unicode-ident" @@ -5392,12 +5403,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" dependencies = [ "form_urlencoded", - "idna", + "idna 0.5.0", "percent-encoding", ] @@ -5502,7 +5513,7 @@ dependencies = [ "log", "lru", "owning_ref", - "parking_lot 0.12.1", + "parking_lot 0.11.2", "serde", "serde_derive", "serial_test", @@ -5576,7 +5587,7 @@ dependencies = [ "send_wrapper 0.6.0", "serde", "serde-big-array", - "serde-wasm-bindgen 0.6.1", + "serde-wasm-bindgen 0.6.3", "serde_bytes", "serde_json", "serial_test", @@ -5609,7 +5620,7 @@ dependencies = [ "weak-table", "web-sys", "webpki", - "webpki-roots 0.25.2", + "webpki-roots 0.25.3", "wee_alloc", "winapi", "windows", @@ -5699,7 +5710,7 @@ dependencies = [ "opentelemetry", "opentelemetry-otlp", "opentelemetry-semantic-conventions", - "parking_lot 0.12.1", + "parking_lot 0.11.2", "rpassword", "serde", "serde_derive", @@ -5797,7 +5808,7 @@ dependencies = [ "parking_lot 0.12.1", "send_wrapper 0.6.0", "serde", - "serde-wasm-bindgen 0.6.1", + "serde-wasm-bindgen 0.6.3", "serde_bytes", "serde_json", "tracing", @@ -5856,9 +5867,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if 1.0.0", "serde", @@ -5868,24 +5879,24 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afec9963e3d0994cac82455b2b3502b81a7f40f9a0d32181f7528d9f4b43e02" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -5895,9 +5906,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5905,28 +5916,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "wasm-bindgen-test" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6433b7c56db97397842c46b67e11873eda263170afeb3a2dc74a7cb370fee0d" +checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" dependencies = [ "console_error_panic_hook", "js-sys", @@ -5938,13 +5949,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.38" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "493fcbab756bb764fa37e6bee8cec2dd709eb4273d06d0c282a5e74275ded735" +checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -5966,9 +5977,9 @@ checksum = "323f4da9523e9a669e1eaf9c6e763892769b1d38c623913647bfdc1532fe4549" [[package]] name = "web-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5db499c5f66323272151db0e666cd34f78617522fb0c1604d31a27c50c206a85" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" dependencies = [ "js-sys", "wasm-bindgen", @@ -5995,9 +6006,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.2" +version = "0.25.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" [[package]] name = "wee_alloc" @@ -6037,7 +6048,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.21", + "rustix 0.38.28", ] [[package]] @@ -6144,6 +6155,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -6174,6 +6194,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -6186,6 +6221,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -6198,6 +6239,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -6210,6 +6257,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -6222,6 +6275,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -6234,6 +6293,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -6246,6 +6311,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -6258,6 +6329,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "winnow" version = "0.5.19" @@ -6298,12 +6375,12 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.10.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" dependencies = [ "gethostname", - "nix 0.24.3", + "nix 0.26.4", "winapi", "winapi-wsapoll", "x11rb-protocol", @@ -6311,11 +6388,11 @@ dependencies = [ [[package]] name = "x11rb-protocol" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc" dependencies = [ - "nix 0.24.3", + "nix 0.26.4", ] [[package]] @@ -6412,7 +6489,7 @@ checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] @@ -6432,7 +6509,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.39", + "syn 2.0.41", ] [[package]] diff --git a/veilid-cli/Cargo.toml b/veilid-cli/Cargo.toml index 0c0a606a..f96a708a 100644 --- a/veilid-cli/Cargo.toml +++ b/veilid-cli/Cargo.toml @@ -39,7 +39,7 @@ cursive_buffered_backend = { git = "https://gitlab.com/veilid/cursive-buffered-b # cursive-multiplex = "0.6.0" # cursive_tree_view = "0.6.0" cursive_table_view = "0.14.0" -arboard = "3.2.1" +arboard = "3.3.0" # cursive-tabs = "0.5.0" clap = { version = "4", features = ["derive"] } directories = "^5" @@ -63,10 +63,10 @@ flume = { version = "^0", features = ["async"] } data-encoding = { version = "^2" } indent = { version = "0.1.1" } -chrono = "0.4.26" +chrono = "0.4.31" owning_ref = "0.4.1" -unicode-width = "0.1.10" -lru = "0.10.0" +unicode-width = "0.1.11" +lru = "0.10.1" [dev-dependencies] serial_test = "^2" diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index 79e9bcab..795e565a 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -63,10 +63,10 @@ veilid-tools = { version = "0.2.5", path = "../veilid-tools", features = [ "tracing", ], default-features = false } paste = "1.0.14" -once_cell = "1.18.0" +once_cell = "1.19.0" owning_ref = "0.4.1" backtrace = "0.3.69" -num-traits = "0.2.16" +num-traits = "0.2.17" shell-words = "1.1.0" static_assertions = "1.1.0" cfg-if = "1.0.0" @@ -75,32 +75,32 @@ lazy_static = "1.4.0" directories = "5.0.1" # Logging -tracing = { version = "0.1.37", features = ["log", "attributes"] } -tracing-subscriber = "0.3.17" +tracing = { version = "0.1.40", features = ["log", "attributes"] } +tracing-subscriber = "0.3.18" tracing-error = "0.2.0" -eyre = "0.6.8" -thiserror = "1.0.48" +eyre = "0.6.11" +thiserror = "1.0.50" # Data structures -enumset = { version = "1.1.2", features = ["serde"] } +enumset = { version = "1.1.3", features = ["serde"] } keyvaluedb = "0.1.1" -range-set-blaze = "0.1.9" +range-set-blaze = "0.1.13" weak-table = "0.3.2" hashlink = { package = "veilid-hashlink", version = "0.1.0", features = [ "serde_impl", ] } # System -futures-util = { version = "0.3.28", default-features = false, features = [ +futures-util = { version = "0.3.29", default-features = false, features = [ "alloc", ] } flume = { version = "0.11.0", features = ["async"] } parking_lot = "0.12.1" -lock_api = "0.4.10" +lock_api = "0.4.11" stop-token = { version = "0.7.0", default-features = false } # Crypto -ed25519-dalek = { version = "2.0.0", default-features = false, features = [ +ed25519-dalek = { version = "2.1.0", default-features = false, features = [ "alloc", "rand_core", "digest", @@ -112,29 +112,29 @@ x25519-dalek = { version = "2.0.0", default-features = false, features = [ "zeroize", "precomputed-tables", ] } -curve25519-dalek = { version = "4.1.0", default-features = false, features = [ +curve25519-dalek = { version = "4.1.1", default-features = false, features = [ "alloc", "zeroize", "precomputed-tables", ] } -blake3 = { version = "1.4.1" } +blake3 = { version = "1.5.0" } chacha20poly1305 = "0.10.1" chacha20 = "0.9.1" argon2 = "0.5.2" # Network -async-std-resolver = { version = "0.23.0", optional = true } -trust-dns-resolver = { version = "0.23.0", optional = true } +async-std-resolver = { version = "0.23.2", optional = true } +trust-dns-resolver = { version = "0.23.2", optional = true } enum-as-inner = "=0.6.0" # temporary fix for trust-dns-resolver v0.22.0 # Serialization -capnp = { version = "0.18.1", default-features = false, features = ["alloc"] } -serde = { version = "1.0.188", features = ["derive", "rc"] } -serde_json = { version = "1.0.107" } +capnp = { version = "0.18.10", default-features = false, features = ["alloc"] } +serde = { version = "1.0.193", features = ["derive", "rc"] } +serde_json = { version = "1.0.108" } serde-big-array = "0.5.1" json = "0.12.4" -data-encoding = { version = "2.4.0" } -schemars = "0.8.13" +data-encoding = { version = "2.5.0" } +schemars = "0.8.16" lz4_flex = { version = "0.11.1", default-features = false, features = [ "safe-encode", "safe-decode", @@ -145,19 +145,19 @@ lz4_flex = { version = "0.11.1", default-features = false, features = [ [target.'cfg(not(target_arch = "wasm32"))'.dependencies] # Tools -config = { version = "0.13.3", features = ["yaml"] } +config = { version = "0.13.4", features = ["yaml"] } bugsalot = { package = "veilid-bugsalot", version = "0.1.0" } chrono = "0.4.31" -libc = "0.2.148" +libc = "0.2.151" nix = "0.27.1" # System async-std = { version = "1.12.0", features = ["unstable"], optional = true } -tokio = { version = "1.32.0", features = ["full"], optional = true } -tokio-util = { version = "0.7.8", features = ["compat"], optional = true } +tokio = { version = "1.35.0", features = ["full"], optional = true } +tokio-util = { version = "0.7.10", features = ["compat"], optional = true } tokio-stream = { version = "0.1.14", features = ["net"], optional = true } async-io = { version = "1.13.0" } -futures-util = { version = "0.3.28", default-features = false, features = [ +futures-util = { version = "0.3.29", default-features = false, features = [ "async-await", "sink", "std", @@ -165,7 +165,7 @@ futures-util = { version = "0.3.28", default-features = false, features = [ ] } # Data structures -keyring-manager = "0.5.0" +keyring-manager = "0.5.1" keyvaluedb-sqlite = "0.1.1" # Network @@ -174,11 +174,11 @@ async-tungstenite = { package = "veilid-async-tungstenite", version = "0.23.0", ] } igd = { package = "veilid-igd", version = "0.1.1" } async-tls = { package = "veilid-async-tls", version = "0.12.0" } -webpki = "0.22.1" -webpki-roots = "0.25.2" -rustls = "0.21.8" -rustls-pemfile = "1.0.3" -socket2 = { version = "0.5.4", features = ["all"] } +webpki = "0.22.4" +webpki-roots = "0.25.3" +rustls = "0.21.10" +rustls-pemfile = "1.0.4" +socket2 = { version = "0.5.5", features = ["all"] } # Dependencies for WASM builds only [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -188,7 +188,7 @@ veilid-tools = { version = "0.2.5", path = "../veilid-tools", default-features = ] } # Tools -getrandom = { version = "0.2.10", features = ["js"] } +getrandom = { version = "0.2.11", features = ["js"] } # System async_executors = { version = "0.7.0", default-features = false, features = [ @@ -196,15 +196,15 @@ async_executors = { version = "0.7.0", default-features = false, features = [ "timer", ] } async-lock = "2.8.0" -wasm-bindgen = "0.2.87" -js-sys = "0.3.64" -wasm-bindgen-futures = "0.4.37" +wasm-bindgen = "0.2.89" +js-sys = "0.3.66" +wasm-bindgen-futures = "0.4.39" send_wrapper = { version = "0.6.0", features = ["futures"] } serde_bytes = { version = "0.11", default_features = false, features = [ "alloc", ] } tsify = { version = "0.4.5", features = ["js"] } -serde-wasm-bindgen = "0.6.0" +serde-wasm-bindgen = "0.6.3" # Network ws_stream_wasm = "0.7.4" @@ -218,7 +218,7 @@ keyvaluedb-web = "0.1.1" ### Configuration for WASM32 'web-sys' crate [target.'cfg(target_arch = "wasm32")'.dependencies.web-sys] -version = "0.3.64" +version = "0.3.66" features = [ 'Document', 'HtmlDocument', @@ -258,13 +258,13 @@ tracing-oslog = { version = "0.1.2", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] simplelog = { version = "0.12.1", features = ["test"] } serial_test = "2.0.0" -tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } [target.'cfg(target_arch = "wasm32")'.dev-dependencies] serial_test = { version = "2.0.0", default-features = false, features = [ "async", ] } -wasm-bindgen-test = "0.3.37" +wasm-bindgen-test = "0.3.39" console_error_panic_hook = "0.1.7" wee_alloc = "0.4.5" wasm-logger = "0.2.0" @@ -274,7 +274,7 @@ wasm-logger = "0.2.0" [build-dependencies] capnpc = "0.18.0" glob = "0.3.1" -filetime = "0.2.22" +filetime = "0.2.23" [package.metadata.wasm-pack.profile.release] wasm-opt = ["-O", "--enable-mutable-globals"] diff --git a/veilid-core/src/intf/wasm/system.rs b/veilid-core/src/intf/wasm/system.rs index e6aaf286..727244e3 100644 --- a/veilid-core/src/intf/wasm/system.rs +++ b/veilid-core/src/intf/wasm/system.rs @@ -40,6 +40,6 @@ pub async fn ptr_lookup(_ip_addr: IpAddr) -> EyreResult { bail!("wasm does not support ptr lookup") } -pub fn env_variable_is_defined>(s: S) -> bool { +pub fn env_variable_is_defined>(_s: S) -> bool { false } diff --git a/veilid-flutter/rust/Cargo.toml b/veilid-flutter/rust/Cargo.toml index e8b2e359..e7b3e2d2 100644 --- a/veilid-flutter/rust/Cargo.toml +++ b/veilid-flutter/rust/Cargo.toml @@ -31,17 +31,17 @@ debug-load = ["dep:ctor", "dep:libc-print", "dep:android_log-sys", "dep:oslog"] [dependencies] veilid-core = { path = "../../veilid-core", default-features = false } -tracing = { version = "0.1.37", features = ["log", "attributes"] } -tracing-subscriber = "0.3.17" +tracing = { version = "0.1.40", features = ["log", "attributes"] } +tracing-subscriber = "0.3.18" parking_lot = "0.12.1" backtrace = "0.3.69" -serde_json = "1.0.107" -serde = "1.0.188" -futures-util = { version = "0.3.28", default-features = false, features = [ +serde_json = "1.0.108" +serde = "1.0.193" +futures-util = { version = "0.3.29", default-features = false, features = [ "alloc", ] } cfg-if = "1.0.0" -data-encoding = { version = "2.4.0" } +data-encoding = { version = "2.5.0" } # Dependencies for native builds only # Linux, Windows, Mac, iOS, Android @@ -51,14 +51,14 @@ opentelemetry = { version = "0.20" } opentelemetry-otlp = { version = "0.13" } opentelemetry-semantic-conventions = "0.12" async-std = { version = "1.12.0", features = ["unstable"], optional = true } -tokio = { version = "1.32.0", features = ["full"], optional = true } +tokio = { version = "1.35.0", features = ["full"], optional = true } tokio-stream = { version = "0.1.14", features = ["net"], optional = true } -tokio-util = { version = "0.7.8", features = ["compat"], optional = true } +tokio-util = { version = "0.7.10", features = ["compat"], optional = true } allo-isolate = "0.1.20" ffi-support = "0.4.4" lazy_static = "1.4.0" hostname = "0.3.1" -ctor = { version = "0.2.5", optional = true } +ctor = { version = "0.2.6", optional = true } libc-print = { version = "0.1.22", optional = true } diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index 08cadf60..5e52288f 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -48,9 +48,9 @@ opentelemetry = { version = "0.20" } opentelemetry-otlp = { version = "0.13" } opentelemetry-semantic-conventions = "0.12" async-std = { version = "^1", features = ["unstable"], optional = true } -tokio = { version = "1.32.0", features = ["full", "tracing"], optional = true } +tokio = { version = "1.35.0", features = ["full", "tracing"], optional = true } tokio-stream = { version = "0.1.14", features = ["net"], optional = true } -tokio-util = { version = "0.7.8", features = ["compat"], optional = true } +tokio-util = { version = "0.7.10", features = ["compat"], optional = true } console-subscriber = { version = "^0", optional = true } async-tungstenite = { package = "veilid-async-tungstenite", version = "^0", features = [ "async-tls", @@ -77,7 +77,7 @@ flume = { version = "^0", features = ["async"] } rpassword = "^7" hostname = "^0" stop-token = { version = "^0", default-features = false } -sysinfo = { version = "^0.29.10", default-features = false } +sysinfo = { version = "^0.29.11", default-features = false } wg = "0.3.2" [target.'cfg(windows)'.dependencies] diff --git a/veilid-tools/Cargo.toml b/veilid-tools/Cargo.toml index 46dbda0f..f0722dcd 100644 --- a/veilid-tools/Cargo.toml +++ b/veilid-tools/Cargo.toml @@ -38,37 +38,37 @@ network-result-extra = [] network-result-info = [] [dependencies] -tracing = { version = "0.1.37", features = [ +tracing = { version = "0.1.40", features = [ "log", "attributes", ], optional = true } -tracing-subscriber = { version = "0.3.17", optional = true } +tracing-subscriber = { version = "0.3.18", optional = true } log = { version = "0.4.20" } -eyre = "0.6.8" +eyre = "0.6.11" static_assertions = "1.1.0" cfg-if = "1.0.0" -thiserror = "1.0.48" -futures-util = { version = "0.3.28", default-features = false, features = [ +thiserror = "1.0.50" +futures-util = { version = "0.3.29", default-features = false, features = [ "alloc", ] } parking_lot = "0.12.1" -once_cell = "1.18.0" +once_cell = "1.19.0" stop-token = { version = "0.7.0", default-features = false } rand = "0.8.5" rand_core = "0.6.4" backtrace = "0.3.69" fn_name = "0.1.0" -range-set-blaze = "0.1.9" +range-set-blaze = "0.1.13" flume = { version = "0.11.0", features = ["async"] } # Dependencies for native builds only # Linux, Windows, Mac, iOS, Android [target.'cfg(not(target_arch = "wasm32"))'.dependencies] async-std = { version = "1.12.0", features = ["unstable"], optional = true } -tokio = { version = "1.32.0", features = ["full"], optional = true } -tokio-util = { version = "0.7.8", features = ["compat"], optional = true } +tokio = { version = "1.35.0", features = ["full"], optional = true } +tokio-util = { version = "0.7.10", features = ["compat"], optional = true } tokio-stream = { version = "0.1.14", features = ["net"], optional = true } -futures-util = { version = "0.3.28", default-features = false, features = [ +futures-util = { version = "0.3.29", default-features = false, features = [ "async-await", "sink", "std", @@ -76,14 +76,14 @@ futures-util = { version = "0.3.28", default-features = false, features = [ ] } chrono = "0.4.31" -libc = "0.2.148" +libc = "0.2.151" nix = { version = "0.27.1", features = ["user"] } # Dependencies for WASM builds only [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen = "0.2.87" -js-sys = "0.3.64" -wasm-bindgen-futures = "0.4.37" +wasm-bindgen = "0.2.89" +js-sys = "0.3.66" +wasm-bindgen-futures = "0.4.39" async_executors = { version = "0.7.0", default-features = false } getrandom = { version = "0.2", features = ["js"] } @@ -130,7 +130,7 @@ serial_test = { version = "2.0.0", default-features = false, features = [ "async", ] } console_error_panic_hook = "0.1.7" -wasm-bindgen-test = "0.3.37" +wasm-bindgen-test = "0.3.39" wee_alloc = "0.4.5" wasm-logger = "0.2.0" tracing-wasm = { version = "0.2.1" } diff --git a/veilid-wasm/Cargo.toml b/veilid-wasm/Cargo.toml index 75cb67d4..646d4ece 100644 --- a/veilid-wasm/Cargo.toml +++ b/veilid-wasm/Cargo.toml @@ -39,7 +39,7 @@ futures-util = { version = "^0" } data-encoding = { version = "^2" } gloo-utils = { version = "^0", features = ["serde"] } tsify = { version = "0.4.5", features = ["js"] } -serde-wasm-bindgen = "0.6.0" +serde-wasm-bindgen = "0.6.3" [dev-dependencies] wasm-bindgen-test = "^0" diff --git a/veilid-wasm/tests/package-lock.json b/veilid-wasm/tests/package-lock.json index 47c16c66..34ec1655 100644 --- a/veilid-wasm/tests/package-lock.json +++ b/veilid-wasm/tests/package-lock.json @@ -21,7 +21,7 @@ }, "../pkg": { "name": "veilid-wasm", - "version": "0.2.4", + "version": "0.2.5", "dev": true, "license": "MPL-2.0" }, From f47adfa03f9b8cf0fedb5c66a508cb1750495c65 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 15 Dec 2023 16:56:31 -0500 Subject: [PATCH 48/67] change signature of accept function --- veilid-server/src/client_api.rs | 4 ++-- veilid-tools/src/ipc/ipc_tokio/unix.rs | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 5bc3cf56..6ddc1ec4 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -456,7 +456,7 @@ impl ClientApi { .await; debug!( - "Closed Client API Connection: {:?} -> {:?}", + "Closed TCP Client API Connection: {:?} -> {:?}", peer_addr, local_addr ); @@ -486,7 +486,7 @@ impl ClientApi { self.run_json_request_processor(reader, writer, stop_token) .await; - debug!("Closed Client API Connection",); + debug!("Closed IPC Client API Connection",); awg.done(); } diff --git a/veilid-tools/src/ipc/ipc_tokio/unix.rs b/veilid-tools/src/ipc/ipc_tokio/unix.rs index 461220b5..8abc434b 100644 --- a/veilid-tools/src/ipc/ipc_tokio/unix.rs +++ b/veilid-tools/src/ipc/ipc_tokio/unix.rs @@ -100,7 +100,7 @@ impl Drop for IpcIncoming { pub struct IpcListener { path: Option, - internal: Option, + internal: Option>, } impl IpcListener { @@ -108,14 +108,20 @@ impl IpcListener { pub async fn bind>(path: P) -> io::Result { Ok(Self { path: Some(path.as_ref().to_path_buf()), - internal: Some(UnixListener::bind(path)?), + internal: Some(Arc::new(UnixListener::bind(path)?)), }) } /// Accepts a new incoming connection to this listener. - pub async fn accept(&self) -> io::Result { - Ok(IpcStream { - internal: self.internal.as_ref().unwrap().accept().await?.0, + pub fn accept(&self) -> SendPinBoxFuture> { + let this = IpcListener { + path: self.path.clone(), + internal: self.internal.clone(), + }; + Box::pin(async move { + Ok(IpcStream { + internal: this.internal.as_ref().unwrap().accept().await?.0, + }) }) } @@ -123,7 +129,9 @@ impl IpcListener { pub fn incoming(mut self) -> IpcIncoming { IpcIncoming { path: self.path.take().unwrap(), - internal: UnixListenerStream::new(self.internal.take().unwrap()), + internal: UnixListenerStream::new( + Arc::into_inner(self.internal.take().unwrap()).unwrap(), + ), } } } From d1aa4888831753b0d63e491db9d245b5aaf49d91 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 15 Dec 2023 18:24:53 -0500 Subject: [PATCH 49/67] windows specific ipc logic --- veilid-cli/src/main.rs | 45 +++-- veilid-cli/src/settings.rs | 9 +- veilid-cli/src/ui.rs | 8 +- veilid-flutter/example/pubspec.lock | 26 +-- veilid-server/src/settings.rs | 8 +- veilid-tools/src/ipc/ipc_tokio/windows.rs | 192 ++++++++++++++++++++++ veilid-tools/src/ipc/mod.rs | 21 +++ veilid-tools/src/tools.rs | 28 +++- 8 files changed, 307 insertions(+), 30 deletions(-) diff --git a/veilid-cli/src/main.rs b/veilid-cli/src/main.rs index c50f6d32..d0156a89 100644 --- a/veilid-cli/src/main.rs +++ b/veilid-cli/src/main.rs @@ -8,7 +8,6 @@ use crate::{settings::NamedSocketAddrs, tools::*}; use clap::{Parser, ValueEnum}; use flexi_logger::*; use std::path::PathBuf; - mod cached_text_view; mod client_api_connection; mod command_processor; @@ -137,18 +136,38 @@ fn main() -> Result<(), String> { // Determine IPC path to try let mut client_api_ipc_path = None; if enable_ipc { - if let Some(ipc_path) = args.ipc_path.or(settings.ipc_path.clone()) { - if ipc_path.exists() && !ipc_path.is_dir() { - // try direct path - enable_network = false; - client_api_ipc_path = Some(ipc_path); - } else if ipc_path.exists() && ipc_path.is_dir() { - // try subnode index inside path - let ipc_path = ipc_path.join(args.subnode_index.to_string()); - if ipc_path.exists() && !ipc_path.is_dir() { - // subnode indexed path exists - enable_network = false; - client_api_ipc_path = Some(ipc_path); + cfg_if::cfg_if! { + if #[cfg(windows)] { + if let Some(ipc_path) = args.ipc_path.or(settings.ipc_path.clone()) { + if is_ipc_socket_path(&ipc_path) { + // try direct path + enable_network = false; + client_api_ipc_path = Some(ipc_path); + } else { + // try subnode index inside path + let ipc_path = ipc_path.join(args.subnode_index.to_string()); + if is_ipc_socket_path(&ipc_path) { + // subnode indexed path exists + enable_network = false; + client_api_ipc_path = Some(ipc_path); + } + } + } + } else { + if let Some(ipc_path) = args.ipc_path.or(settings.ipc_path.clone()) { + if is_ipc_socket_path(&ipc_path) { + // try direct path + enable_network = false; + client_api_ipc_path = Some(ipc_path); + } else if ipc_path.exists() && ipc_path.is_dir() { + // try subnode index inside path + let ipc_path = ipc_path.join(args.subnode_index.to_string()); + if is_ipc_socket_path(&ipc_path) { + // subnode indexed path exists + enable_network = false; + client_api_ipc_path = Some(ipc_path); + } + } } } } diff --git a/veilid-cli/src/settings.rs b/veilid-cli/src/settings.rs index 992f325a..c1c55b79 100644 --- a/veilid-cli/src/settings.rs +++ b/veilid-cli/src/settings.rs @@ -229,6 +229,7 @@ pub struct Settings { } impl Settings { + #[allow(dead_code)] fn get_server_default_directory(subpath: &str) -> PathBuf { #[cfg(unix)] { @@ -249,7 +250,13 @@ impl Settings { } pub fn get_default_ipc_directory() -> PathBuf { - Self::get_server_default_directory("ipc") + cfg_if::cfg_if! { + if #[cfg(windows)] { + PathBuf::from(r"\\.\PIPE\veilid-server") + } else { + Self::get_server_default_directory("ipc") + } + } } pub fn get_default_config_path() -> PathBuf { diff --git a/veilid-cli/src/ui.rs b/veilid-cli/src/ui.rs index 85bf5c85..95b6fb53 100644 --- a/veilid-cli/src/ui.rs +++ b/veilid-cli/src/ui.rs @@ -805,7 +805,13 @@ impl UI { edit.set_enabled(ipc_path_enabled); let mut dlg = Self::connection_dialog(s); - dlg.add_button("Connect", Self::submit_network_address); + dlg.add_button("Connect", |s| { + if Self::ipc_path_radio(s).is_selected() { + Self::submit_ipc_path(s); + } else { + Self::submit_network_address(s); + } + }); } ConnectionState::ConnectedTCP(_, _) | ConnectionState::ConnectedIPC(_, _) => {} ConnectionState::RetryingTCP(addr, _) => { diff --git a/veilid-flutter/example/pubspec.lock b/veilid-flutter/example/pubspec.lock index 28671d7b..73fc4fc6 100644 --- a/veilid-flutter/example/pubspec.lock +++ b/veilid-flutter/example/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.18.0" + version: "1.17.2" convert: dependency: transitive description: @@ -220,10 +220,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.9.1" path: dependency: "direct main" description: @@ -329,18 +329,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.1" string_scanner: dependency: transitive description: @@ -377,10 +377,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.6.0" typed_data: dependency: transitive description: @@ -408,10 +408,10 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.1.4-beta" win32: dependency: transitive description: @@ -437,5 +437,5 @@ packages: source: hosted version: "3.5.0" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.1.0-185.0.dev <4.0.0" flutter: ">=3.10.6" diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index f2f69434..f2f2c3bc 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -807,7 +807,13 @@ impl Settings { } pub fn get_default_ipc_directory() -> PathBuf { - Self::get_or_create_default_directory("ipc") + cfg_if! { + if #[cfg(windows)] { + PathBuf::from(r"\\.\PIPE\veilid-server") + } else { + Self::get_or_create_default_directory("ipc") + } + } } pub fn get_default_remote_max_subkey_cache_memory_mb() -> u32 { diff --git a/veilid-tools/src/ipc/ipc_tokio/windows.rs b/veilid-tools/src/ipc/ipc_tokio/windows.rs index e69de29b..5e4ecdbe 100644 --- a/veilid-tools/src/ipc/ipc_tokio/windows.rs +++ b/veilid-tools/src/ipc/ipc_tokio/windows.rs @@ -0,0 +1,192 @@ +use crate::*; +use futures_util::stream::FuturesUnordered; +use futures_util::AsyncRead as FuturesAsyncRead; +use futures_util::AsyncWrite as FuturesAsyncWrite; +use futures_util::Stream; +use std::path::PathBuf; +use std::{io, path::Path}; +use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; +use tokio::net::windows::named_pipe::{ + ClientOptions, NamedPipeClient, NamedPipeServer, ServerOptions, +}; +///////////////////////////////////////////////////////////// + +enum IpcStreamInternal { + Client(NamedPipeClient), + Server(NamedPipeServer), +} + +pub struct IpcStream { + internal: IpcStreamInternal, +} + +impl IpcStream { + pub async fn connect>(path: P) -> io::Result { + Ok(IpcStream { + internal: IpcStreamInternal::Client( + ClientOptions::new().open(path.as_ref().to_path_buf().as_os_str())?, + ), + }) + } +} + +impl FuturesAsyncRead for IpcStream { + fn poll_read( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut [u8], + ) -> std::task::Poll> { + match &mut self.internal { + IpcStreamInternal::Client(client) => { + let mut rb = ReadBuf::new(buf); + match ::poll_read( + std::pin::Pin::new(client), + cx, + &mut rb, + ) { + std::task::Poll::Ready(r) => { + std::task::Poll::Ready(r.map(|_| rb.filled().len())) + } + std::task::Poll::Pending => std::task::Poll::Pending, + } + } + IpcStreamInternal::Server(server) => { + let mut rb = ReadBuf::new(buf); + match ::poll_read( + std::pin::Pin::new(server), + cx, + &mut rb, + ) { + std::task::Poll::Ready(r) => { + std::task::Poll::Ready(r.map(|_| rb.filled().len())) + } + std::task::Poll::Pending => std::task::Poll::Pending, + } + } + } + } +} + +impl FuturesAsyncWrite for IpcStream { + fn poll_write( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &[u8], + ) -> std::task::Poll> { + match &mut self.internal { + IpcStreamInternal::Client(client) => { + ::poll_write(std::pin::Pin::new(client), cx, buf) + } + IpcStreamInternal::Server(server) => { + ::poll_write(std::pin::Pin::new(server), cx, buf) + } + } + } + + fn poll_flush( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + match &mut self.internal { + IpcStreamInternal::Client(client) => { + ::poll_flush(std::pin::Pin::new(client), cx) + } + IpcStreamInternal::Server(server) => { + ::poll_flush(std::pin::Pin::new(server), cx) + } + } + } + + fn poll_close( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + match &mut self.internal { + IpcStreamInternal::Client(client) => { + ::poll_shutdown(std::pin::Pin::new(client), cx) + } + IpcStreamInternal::Server(server) => { + ::poll_shutdown(std::pin::Pin::new(server), cx) + } + } + } +} + +///////////////////////////////////////////////////////////// + +pub struct IpcIncoming { + listener: Arc, + unord: FuturesUnordered>>, +} + +impl Stream for IpcIncoming { + type Item = io::Result; + + fn poll_next<'a>( + mut self: std::pin::Pin<&'a mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + if self.unord.is_empty() { + self.unord.push(Box::pin(self.listener.accept())); + } + match Pin::new(&mut self.unord).poll_next(cx) { + task::Poll::Ready(ro) => { + self.unord.push(Box::pin(self.listener.accept())); + std::task::Poll::Ready(ro) + } + task::Poll::Pending => std::task::Poll::Pending, + } + } +} + +///////////////////////////////////////////////////////////// + +pub struct IpcListener { + path: Option, + internal: Mutex>, +} + +impl IpcListener { + /// Creates a new `IpcListener` bound to the specified path. + pub async fn bind>(path: P) -> io::Result { + let path = path.as_ref().to_path_buf(); + let server = ServerOptions::new() + .first_pipe_instance(true) + .create(&path)?; + Ok(Self { + path: Some(path), + internal: Mutex::new(Some(server)), + }) + } + + /// Accepts a new incoming connection to this listener. + pub fn accept(&self) -> SendPinBoxFuture> { + let mut opt_server = self.internal.lock(); + let Some(server) = opt_server.take() else { + return Box::pin(std::future::ready(Err(io::Error::from( + io::ErrorKind::BrokenPipe, + )))); + }; + let path = self.path.clone().unwrap(); + *opt_server = match ServerOptions::new().create(path) { + Ok(v) => Some(v), + Err(e) => return Box::pin(std::future::ready(Err(e))), + }; + + Box::pin(async move { + server.connect().await?; + + Ok(IpcStream { + internal: IpcStreamInternal::Server(server), + }) + }) + } + + /// Returns a stream of incoming connections. + pub fn incoming(self) -> IpcIncoming { + IpcIncoming { + listener: Arc::new(self), + unord: FuturesUnordered::new(), + } + } +} diff --git a/veilid-tools/src/ipc/mod.rs b/veilid-tools/src/ipc/mod.rs index ec24eb5d..27f81639 100644 --- a/veilid-tools/src/ipc/mod.rs +++ b/veilid-tools/src/ipc/mod.rs @@ -1,4 +1,5 @@ use cfg_if::*; +use std::path::Path; cfg_if! { if #[cfg(feature="rt-tokio")] { @@ -9,3 +10,23 @@ cfg_if! { pub use ipc_async_std::*; } } + +pub fn is_ipc_socket_path>(path: P) -> bool { + cfg_if! { + if #[cfg(windows)] { + let p = path.as_ref().to_path_buf().to_string_lossy().to_string().to_lowercase(); + p.starts_with(r"\\.\pipe") && path.as_ref().exists() + } else if #[cfg(unix)] { + use std::os::unix::fs::FileTypeExt; + let meta = match std::fs::metadata(path) { + Ok(v) => v, + Err(_) => { + return false; + } + }; + meta.file_type().is_socket() + } else { + false + } + } +} diff --git a/veilid-tools/src/tools.rs b/veilid-tools/src/tools.rs index e86ca492..ffb552ba 100644 --- a/veilid-tools/src/tools.rs +++ b/veilid-tools/src/tools.rs @@ -363,15 +363,41 @@ cfg_if::cfg_if! { pub fn ensure_file_private_owner>(path: P) -> Result<(), String> { let path = path.as_ref(); - if !path.exists() { + if !path.is_file() { return Ok(()); } Ok(()) } + + pub fn ensure_directory_private_owner>(path: P, _group_read: bool) -> Result<(), String> + { + let path = path.as_ref(); + if !path.is_dir() { + return Ok(()); + } + + Ok(()) + } + } else { pub fn ensure_file_private_owner>(_path: P) -> Result<(), String> { + let path = path.as_ref(); + if !path.is_file() { + return Ok(()); + } + + Ok(()) + } + + pub fn ensure_directory_private_owner>(path: P, _group_read: bool) -> Result<(), String> + { + let path = path.as_ref(); + if !path.is_dir() { + return Ok(()); + } + Ok(()) } } From 6bfe9a023644f6376148096c7138ff0f98dcb614 Mon Sep 17 00:00:00 2001 From: John Smith Date: Fri, 15 Dec 2023 19:22:06 -0500 Subject: [PATCH 50/67] default to ipc only --- veilid-cli/src/main.rs | 7 +++++-- veilid-cli/src/settings.rs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/veilid-cli/src/main.rs b/veilid-cli/src/main.rs index d0156a89..e1c5a8e3 100644 --- a/veilid-cli/src/main.rs +++ b/veilid-cli/src/main.rs @@ -130,8 +130,9 @@ fn main() -> Result<(), String> { } // Get client address - let enable_ipc = settings.enable_ipc && args.address.is_none(); - let mut enable_network = settings.enable_network && args.ipc_path.is_none(); + let enable_ipc = (settings.enable_ipc && args.address.is_none()) || args.ipc_path.is_some(); + let mut enable_network = + (settings.enable_network && args.ipc_path.is_none()) || args.address.is_some(); // Determine IPC path to try let mut client_api_ipc_path = None; @@ -209,6 +210,8 @@ fn main() -> Result<(), String> { } else if let Some(client_api_network_address) = client_api_network_addresses { let network_addr = client_api_network_address.first().cloned(); comproc.set_network_address(network_addr); + } else { + return Err("veilid-server could not be reached".to_owned()); } let comproc2 = comproc.clone(); diff --git a/veilid-cli/src/settings.rs b/veilid-cli/src/settings.rs index c1c55b79..023e7e68 100644 --- a/veilid-cli/src/settings.rs +++ b/veilid-cli/src/settings.rs @@ -9,7 +9,7 @@ pub fn load_default_config() -> Result { let default_config = r#"--- enable_ipc: true ipc_path: '%IPC_DIRECTORY%' -enable_network: true +enable_network: false address: "localhost:5959" autoconnect: true autoreconnect: true From 4e36524778eac2441c306e94c1eb938c4be11a60 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 16 Dec 2023 12:46:57 -0500 Subject: [PATCH 51/67] windows named pipe support for python --- veilid-python/tests/api.py | 23 +++++++++++++++-------- veilid-python/veilid/json_api.py | 23 +++++++++++++++++++++-- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/veilid-python/tests/api.py b/veilid-python/tests/api.py index a6855375..d3ad9a57 100644 --- a/veilid-python/tests/api.py +++ b/veilid-python/tests/api.py @@ -32,6 +32,15 @@ def server_info() -> tuple[str, int]: return hostname, int(rest[0]) return hostname, 5959 +def ipc_path_exists(path: str) -> bool: + """Determine if an IPC socket exists in a platform independent way.""" + if os.name == 'nt': + if not path.upper().startswith("\\\\.\\PIPE\\"): + return False + return path[9:] in os.listdir("\\\\.\\PIPE") + else: + return os.path.exists(path) + @cache def ipc_info() -> str: """Return the path of the ipc socket of the test server.""" @@ -40,12 +49,11 @@ def ipc_info() -> str: return VEILID_SERVER_IPC if os.name == 'nt': - return '\\\\.\\PIPE\\veilid-server\\ipc\\0' - - if os.name == 'posix': - ipc_0_path = "/var/db/veilid-server/ipc/0" - if os.path.exists(ipc_0_path): - return ipc_0_path + return '\\\\.\\PIPE\\veilid-server\\0' + + ipc_0_path = "/var/db/veilid-server/ipc/0" + if os.path.exists(ipc_0_path): + return ipc_0_path # hack to deal with rust's 'directories' crate case-inconsistency if sys.platform.startswith('darwin'): @@ -67,8 +75,7 @@ async def api_connector(callback: Callable) -> _JsonVeilidAPI: hostname, port = server_info() try: - print(f"ipc_path: {ipc_path}") - if os.path.exists(ipc_path): + if ipc_path_exists(ipc_path): return await veilid.json_api_connect_ipc(ipc_path, callback) else: return await veilid.json_api_connect(hostname, port, callback) diff --git a/veilid-python/veilid/json_api.py b/veilid-python/veilid/json_api.py index 16cb20be..045fd60d 100644 --- a/veilid-python/veilid/json_api.py +++ b/veilid-python/veilid/json_api.py @@ -155,11 +155,30 @@ class _JsonVeilidAPI(VeilidAPI): async def connect_ipc( cls, ipc_path: str, update_callback: Callable[[VeilidUpdate], Awaitable] ) -> Self: - reader, writer = await asyncio.open_unix_connection(ipc_path) + print("opening pipe") + + if os.name=='nt': + async def open_windows_pipe(path=None, *, + limit=65536, **kwds): + """Similar to `open_unix_connection` but works with Windows Named Pipes.""" + loop = asyncio.events.get_running_loop() + + reader = asyncio.StreamReader(limit=limit, loop=loop) + protocol = asyncio.StreamReaderProtocol(reader, loop=loop) + transport, _ = await loop.create_pipe_connection( + lambda: protocol, path, **kwds) + writer = asyncio.StreamWriter(transport, protocol, reader, loop) + return reader, writer + reader, writer = await open_windows_pipe(ipc_path) + else: + reader, writer = await asyncio.open_unix_connection(ipc_path) + + print(f"reader: {vars(reader)}\nwriter: {vars(writer)}\n") + veilid_api = cls(reader, writer, update_callback) veilid_api.handle_recv_messages_task = asyncio.create_task( veilid_api.handle_recv_messages(), name="JsonVeilidAPI.handle_recv_messages" - ) + ) return veilid_api async def handle_recv_message_response(self, j: dict): From b11f404d3f7d5d84f62a74b3ce11858b2b5a8434 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 16 Dec 2023 15:49:53 -0500 Subject: [PATCH 52/67] async-std support --- Cargo.lock | 1 - veilid-cli/Cargo.toml | 2 +- veilid-cli/src/client_api_connection.rs | 5 +- veilid-core/Cargo.toml | 1 - veilid-server/Cargo.toml | 1 + veilid-server/src/client_api.rs | 9 +- veilid-tools/src/ipc/ipc_async_std/unix.rs | 141 +++++++++++++++++++++ veilid-tools/src/ipc/ipc_tokio/unix.rs | 17 ++- 8 files changed, 160 insertions(+), 17 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb42d578..d6d1edbb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5576,7 +5576,6 @@ dependencies = [ "nix 0.27.1", "num-traits", "once_cell", - "owning_ref", "paranoid-android", "parking_lot 0.12.1", "paste", diff --git a/veilid-cli/Cargo.toml b/veilid-cli/Cargo.toml index f96a708a..7cb24732 100644 --- a/veilid-cli/Cargo.toml +++ b/veilid-cli/Cargo.toml @@ -55,7 +55,7 @@ flexi_logger = { version = "^0", features = ["use_chrono_for_offset"] } thiserror = "^1" crossbeam-channel = "^0" hex = "^0" -veilid-tools = { version = "0.2.5", path = "../veilid-tools" } +veilid-tools = { version = "0.2.5", path = "../veilid-tools", default-features = false} json = "^0" stop-token = { version = "^0", default-features = false } diff --git a/veilid-cli/src/client_api_connection.rs b/veilid-cli/src/client_api_connection.rs index 6abf0cab..d507f5ee 100644 --- a/veilid-cli/src/client_api_connection.rs +++ b/veilid-cli/src/client_api_connection.rs @@ -9,8 +9,7 @@ use stop_token::{future::FutureExt as _, StopSource}; cfg_if! { if #[cfg(feature="rt-async-std")] { - use async_std::io::prelude::BufReadExt; - use async_std::io::WriteExt; + use futures::{AsyncBufReadExt, AsyncWriteExt}; use async_std::io::BufReader; } else if #[cfg(feature="rt-tokio")] { use tokio::io::AsyncBufReadExt; @@ -243,7 +242,7 @@ impl ClientApiConnection { cfg_if! { if #[cfg(feature="rt-async-std")] { use futures::AsyncReadExt; - let (reader, mut writer) = stream.split(); + let (reader, writer) = stream.split(); let reader = BufReader::new(reader); } else { let (reader, writer) = stream.into_split(); diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index 795e565a..7bab4989 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -64,7 +64,6 @@ veilid-tools = { version = "0.2.5", path = "../veilid-tools", features = [ ], default-features = false } paste = "1.0.14" once_cell = "1.19.0" -owning_ref = "0.4.1" backtrace = "0.3.69" num-traits = "0.2.17" shell-words = "1.1.0" diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index 5e52288f..edb0292b 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -15,6 +15,7 @@ path = "src/main.rs" [features] default = ["rt-tokio", "veilid-core/default"] +default-async-std = ["rt-async-std", "veilid-core/default-async-std"] crypto-test = ["rt-tokio", "veilid-core/crypto-test"] crypto-test-none = ["rt-tokio", "veilid-core/crypto-test-none"] diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 6ddc1ec4..8933444a 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -20,8 +20,7 @@ const MAX_NON_JSON_LOGGING: usize = 50; cfg_if! { if #[cfg(feature="rt-async-std")] { - use async_std::io::prelude::BufReadExt; - use async_std::io::WriteExt; + use futures_util::{AsyncBufReadExt, AsyncWriteExt}; } else if #[cfg(feature="rt-tokio")] { use tokio::io::AsyncBufReadExt; use tokio::io::AsyncWriteExt; @@ -116,11 +115,11 @@ impl ClientApi { return Err(e); } } - let listener = IpcListener::bind(ipc_path.clone()).await?; + let mut listener = IpcListener::bind(ipc_path.clone()).await?; debug!("IPC Client API listening on: {:?}", ipc_path); // Process the incoming accept stream - let mut incoming_stream = listener.incoming(); + let mut incoming_stream = listener.incoming()?; // Make wait group for all incoming connections let awg = AsyncWaitGroup::new(); @@ -444,7 +443,7 @@ impl ClientApi { cfg_if! { if #[cfg(feature="rt-async-std")] { use futures_util::AsyncReadExt; - let (reader, mut writer) = stream.split(); + let (reader, writer) = stream.split(); let reader = BufReader::new(reader); } else { let (reader, writer) = stream.into_split(); diff --git a/veilid-tools/src/ipc/ipc_async_std/unix.rs b/veilid-tools/src/ipc/ipc_async_std/unix.rs index e69de29b..0bbe2565 100644 --- a/veilid-tools/src/ipc/ipc_async_std/unix.rs +++ b/veilid-tools/src/ipc/ipc_async_std/unix.rs @@ -0,0 +1,141 @@ +use crate::*; +use async_std::io::Read as AsyncRead; +use async_std::io::Write as AsyncWrite; +use async_std::os::unix::net::{Incoming, UnixListener, UnixStream}; +use futures_util::AsyncRead as FuturesAsyncRead; +use futures_util::AsyncWrite as FuturesAsyncWrite; +use futures_util::Stream; +use std::path::PathBuf; +use std::{io, path::Path}; + +///////////////////////////////////////////////////////////// + +pub struct IpcStream { + internal: UnixStream, +} + +impl IpcStream { + pub async fn connect>(path: P) -> io::Result { + Ok(IpcStream { + internal: UnixStream::connect(path.as_ref()).await?, + }) + } +} + +impl FuturesAsyncRead for IpcStream { + fn poll_read( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &mut [u8], + ) -> std::task::Poll> { + ::poll_read(std::pin::Pin::new(&mut self.internal), cx, buf) + } +} + +impl FuturesAsyncWrite for IpcStream { + fn poll_write( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + buf: &[u8], + ) -> std::task::Poll> { + ::poll_write(std::pin::Pin::new(&mut self.internal), cx, buf) + } + + fn poll_flush( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + ::poll_flush(std::pin::Pin::new(&mut self.internal), cx) + } + + fn poll_close( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + ::poll_close(std::pin::Pin::new(&mut self.internal), cx) + } +} + +///////////////////////////////////////////////////////////// + +pub struct IpcIncoming<'a> { + path: PathBuf, + internal: Incoming<'a>, +} + +impl<'a> Drop for IpcIncoming<'a> { + fn drop(&mut self) { + // Clean up IPC path + if let Err(e) = std::fs::remove_file(&self.path) { + warn!("Unable to remove IPC socket: {}", e); + } + } +} + +impl<'a> Stream for IpcIncoming<'a> { + type Item = io::Result; + + fn poll_next( + mut self: std::pin::Pin<&mut Self>, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + match ::poll_next(std::pin::Pin::new(&mut self.internal), cx) { + std::task::Poll::Ready(ro) => { + std::task::Poll::Ready(ro.map(|rr| rr.map(|s| IpcStream { internal: s }))) + } + std::task::Poll::Pending => std::task::Poll::Pending, + } + } +} + +///////////////////////////////////////////////////////////// + +pub struct IpcListener { + path: Option, + internal: Option>, +} + +impl IpcListener { + /// Creates a new `IpcListener` bound to the specified path. + pub async fn bind>(path: P) -> io::Result { + Ok(Self { + path: Some(path.as_ref().to_path_buf()), + internal: Some(Arc::new(UnixListener::bind(path.as_ref()).await?)), + }) + } + + /// Accepts a new incoming connection to this listener. + pub fn accept(&self) -> SendPinBoxFuture> { + let this = IpcListener { + path: self.path.clone(), + internal: self.internal.clone(), + }; + Box::pin(async move { + Ok(IpcStream { + internal: this.internal.as_ref().unwrap().accept().await?.0, + }) + }) + } + + /// Returns a stream of incoming connections. + pub fn incoming<'a>(&'a mut self) -> io::Result> { + if self.path.is_none() { + return Err(io::Error::from(io::ErrorKind::NotConnected)); + } + Ok(IpcIncoming { + path: self.path.take().unwrap(), + internal: self.internal.as_ref().unwrap().incoming(), + }) + } +} + +impl Drop for IpcListener { + fn drop(&mut self) { + // Clean up IPC path + if let Some(path) = &self.path { + if let Err(e) = std::fs::remove_file(path) { + warn!("Unable to remove IPC socket: {}", e); + } + } + } +} diff --git a/veilid-tools/src/ipc/ipc_tokio/unix.rs b/veilid-tools/src/ipc/ipc_tokio/unix.rs index 8abc434b..7606ec13 100644 --- a/veilid-tools/src/ipc/ipc_tokio/unix.rs +++ b/veilid-tools/src/ipc/ipc_tokio/unix.rs @@ -65,12 +65,13 @@ impl FuturesAsyncWrite for IpcStream { ///////////////////////////////////////////////////////////// -pub struct IpcIncoming { +pub struct IpcIncoming<'a> { path: PathBuf, internal: UnixListenerStream, + phantom: std::marker::PhantomData<&'a ()>, } -impl Stream for IpcIncoming { +impl<'a> Stream for IpcIncoming<'a> { type Item = io::Result; fn poll_next( @@ -87,7 +88,7 @@ impl Stream for IpcIncoming { } } -impl Drop for IpcIncoming { +impl<'a> Drop for IpcIncoming<'a> { fn drop(&mut self) { // Clean up IPC path if let Err(e) = std::fs::remove_file(&self.path) { @@ -126,13 +127,17 @@ impl IpcListener { } /// Returns a stream of incoming connections. - pub fn incoming(mut self) -> IpcIncoming { - IpcIncoming { + pub fn incoming(&mut self) -> io::Result> { + if self.path.is_none() { + return Err(io::Error::from(io::ErrorKind::NotConnected)); + } + Ok(IpcIncoming { path: self.path.take().unwrap(), internal: UnixListenerStream::new( Arc::into_inner(self.internal.take().unwrap()).unwrap(), ), - } + phantom: std::marker::PhantomData, + }) } } From 633c0394c9d2963ddb981cec63fd5bf62fcb920f Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 16 Dec 2023 16:11:53 -0500 Subject: [PATCH 53/67] fix windows tokio signature --- veilid-tools/src/ipc/ipc_async_std/unix.rs | 5 +++ veilid-tools/src/ipc/ipc_tokio/unix.rs | 5 +++ veilid-tools/src/ipc/ipc_tokio/windows.rs | 36 ++++++++++++++-------- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/veilid-tools/src/ipc/ipc_async_std/unix.rs b/veilid-tools/src/ipc/ipc_async_std/unix.rs index 0bbe2565..4d6c1bbd 100644 --- a/veilid-tools/src/ipc/ipc_async_std/unix.rs +++ b/veilid-tools/src/ipc/ipc_async_std/unix.rs @@ -106,6 +106,11 @@ impl IpcListener { /// Accepts a new incoming connection to this listener. pub fn accept(&self) -> SendPinBoxFuture> { + if self.path.is_none() { + return Box::pin(std::future::ready(Err(io::Error::from( + io::ErrorKind::NotConnected, + )))); + } let this = IpcListener { path: self.path.clone(), internal: self.internal.clone(), diff --git a/veilid-tools/src/ipc/ipc_tokio/unix.rs b/veilid-tools/src/ipc/ipc_tokio/unix.rs index 7606ec13..0a2f1a44 100644 --- a/veilid-tools/src/ipc/ipc_tokio/unix.rs +++ b/veilid-tools/src/ipc/ipc_tokio/unix.rs @@ -115,6 +115,11 @@ impl IpcListener { /// Accepts a new incoming connection to this listener. pub fn accept(&self) -> SendPinBoxFuture> { + if self.path.is_none() { + return Box::pin(std::future::ready(Err(io::Error::from( + io::ErrorKind::NotConnected, + )))); + } let this = IpcListener { path: self.path.clone(), internal: self.internal.clone(), diff --git a/veilid-tools/src/ipc/ipc_tokio/windows.rs b/veilid-tools/src/ipc/ipc_tokio/windows.rs index 5e4ecdbe..406b050e 100644 --- a/veilid-tools/src/ipc/ipc_tokio/windows.rs +++ b/veilid-tools/src/ipc/ipc_tokio/windows.rs @@ -114,12 +114,13 @@ impl FuturesAsyncWrite for IpcStream { ///////////////////////////////////////////////////////////// -pub struct IpcIncoming { - listener: Arc, +pub struct IpcIncoming<'a> { + listener: IpcListener, unord: FuturesUnordered>>, + phantom: std::marker::PhantomData<&'a ()>, } -impl Stream for IpcIncoming { +impl<'t> Stream for IpcIncoming<'t> { type Item = io::Result; fn poll_next<'a>( @@ -143,7 +144,7 @@ impl Stream for IpcIncoming { pub struct IpcListener { path: Option, - internal: Mutex>, + internal: Option>>, } impl IpcListener { @@ -155,18 +156,20 @@ impl IpcListener { .create(&path)?; Ok(Self { path: Some(path), - internal: Mutex::new(Some(server)), + internal: Some(Mutex::new(Some(server))), }) } /// Accepts a new incoming connection to this listener. pub fn accept(&self) -> SendPinBoxFuture> { - let mut opt_server = self.internal.lock(); - let Some(server) = opt_server.take() else { + if self.path.is_none() { return Box::pin(std::future::ready(Err(io::Error::from( - io::ErrorKind::BrokenPipe, + io::ErrorKind::NotConnected, )))); - }; + } + let internal = self.internal.as_ref().unwrap(); + let mut opt_server = internal.lock(); + let server = opt_server.take().unwrap(); let path = self.path.clone().unwrap(); *opt_server = match ServerOptions::new().create(path) { Ok(v) => Some(v), @@ -183,10 +186,17 @@ impl IpcListener { } /// Returns a stream of incoming connections. - pub fn incoming(self) -> IpcIncoming { - IpcIncoming { - listener: Arc::new(self), - unord: FuturesUnordered::new(), + pub fn incoming(&mut self) -> io::Result> { + if self.path.is_none() { + return Err(io::Error::from(io::ErrorKind::NotConnected)); } + Ok(IpcIncoming { + listener: IpcListener { + path: self.path.take(), + internal: self.internal.take(), + }, + unord: FuturesUnordered::new(), + phantom: std::marker::PhantomData, + }) } } From 25637e5ff531f8cdfb2c1e9cbdf999b7f5e6ed48 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 17 Dec 2023 09:52:10 -0500 Subject: [PATCH 54/67] disable async-std+windows build --- Cargo.lock | 19 +++++++++---------- veilid-python/veilid/json_api.py | 3 --- veilid-server/Cargo.toml | 9 ++++++--- veilid-server/src/client_api.rs | 4 +++- veilid-server/src/veilid_logs.rs | 13 ++++++++++--- veilid-tools/src/ipc/ipc_async_std/mod.rs | 3 ++- veilid-tools/src/ipc/ipc_async_std/windows.rs | 1 + 7 files changed, 31 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d6d1edbb..68599a2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -338,9 +338,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9d5715c2d329bf1b4da8d60455b99b187f27ba726df2883799af9af60997" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" dependencies = [ "async-lock 3.0.0", "cfg-if 1.0.0", @@ -352,8 +352,7 @@ dependencies = [ "rustix 0.38.28", "slab", "tracing", - "waker-fn", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -399,7 +398,7 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io 2.2.0", + "async-io 2.2.2", "async-lock 2.8.0", "atomic-waker", "cfg-if 1.0.0", @@ -2943,9 +2942,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" dependencies = [ "libc", "log", @@ -3856,7 +3855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" dependencies = [ "anyhow", - "itertools 0.10.5", + "itertools 0.11.0", "proc-macro2", "quote", "syn 2.0.41", @@ -5513,7 +5512,7 @@ dependencies = [ "log", "lru", "owning_ref", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "serde", "serde_derive", "serial_test", @@ -5709,7 +5708,7 @@ dependencies = [ "opentelemetry", "opentelemetry-otlp", "opentelemetry-semantic-conventions", - "parking_lot 0.11.2", + "parking_lot 0.12.1", "rpassword", "serde", "serde_derive", diff --git a/veilid-python/veilid/json_api.py b/veilid-python/veilid/json_api.py index 045fd60d..748da356 100644 --- a/veilid-python/veilid/json_api.py +++ b/veilid-python/veilid/json_api.py @@ -155,7 +155,6 @@ class _JsonVeilidAPI(VeilidAPI): async def connect_ipc( cls, ipc_path: str, update_callback: Callable[[VeilidUpdate], Awaitable] ) -> Self: - print("opening pipe") if os.name=='nt': async def open_windows_pipe(path=None, *, @@ -173,8 +172,6 @@ class _JsonVeilidAPI(VeilidAPI): else: reader, writer = await asyncio.open_unix_connection(ipc_path) - print(f"reader: {vars(reader)}\nwriter: {vars(writer)}\n") - veilid_api = cls(reader, writer, update_callback) veilid_api.handle_recv_messages_task = asyncio.create_task( veilid_api.handle_recv_messages(), name="JsonVeilidAPI.handle_recv_messages" diff --git a/veilid-server/Cargo.toml b/veilid-server/Cargo.toml index edb0292b..20e090dd 100644 --- a/veilid-server/Cargo.toml +++ b/veilid-server/Cargo.toml @@ -14,16 +14,19 @@ name = "veilid-server" path = "src/main.rs" [features] -default = ["rt-tokio", "veilid-core/default"] +default = ["rt-tokio", "veilid-core/default", "otlp-tonic"] default-async-std = ["rt-async-std", "veilid-core/default-async-std"] + crypto-test = ["rt-tokio", "veilid-core/crypto-test"] crypto-test-none = ["rt-tokio", "veilid-core/crypto-test-none"] +otlp-tonic = [ "opentelemetry-otlp/grpc-tonic", "opentelemetry-otlp/trace" ] +otlp-grpc = [ "opentelemetry-otlp/grpc-sys", "opentelemetry-otlp/trace" ] + rt-async-std = [ "veilid-core/rt-async-std", "async-std", "opentelemetry/rt-async-std", - "opentelemetry-otlp/grpc-sys", ] rt-tokio = [ "veilid-core/rt-tokio", @@ -46,7 +49,7 @@ tracing-appender = "^0" tracing-opentelemetry = "0.21" # Buggy: tracing-error = "^0" opentelemetry = { version = "0.20" } -opentelemetry-otlp = { version = "0.13" } +opentelemetry-otlp = { version = "0.13", default-features = false, optional=true } opentelemetry-semantic-conventions = "0.12" async-std = { version = "^1", features = ["unstable"], optional = true } tokio = { version = "1.35.0", features = ["full", "tracing"], optional = true } diff --git a/veilid-server/src/client_api.rs b/veilid-server/src/client_api.rs index 8933444a..a8520b84 100644 --- a/veilid-server/src/client_api.rs +++ b/veilid-server/src/client_api.rs @@ -19,9 +19,11 @@ use wg::AsyncWaitGroup; const MAX_NON_JSON_LOGGING: usize = 50; cfg_if! { + if #[cfg(feature="rt-async-std")] { use futures_util::{AsyncBufReadExt, AsyncWriteExt}; - } else if #[cfg(feature="rt-tokio")] { + } else + if #[cfg(feature="rt-tokio")] { use tokio::io::AsyncBufReadExt; use tokio::io::AsyncWriteExt; } else { diff --git a/veilid-server/src/veilid_logs.rs b/veilid-server/src/veilid_logs.rs index 7f390f4f..09b4d0a6 100644 --- a/veilid-server/src/veilid_logs.rs +++ b/veilid-server/src/veilid_logs.rs @@ -3,9 +3,15 @@ use crate::*; use cfg_if::*; #[cfg(feature = "rt-tokio")] use console_subscriber::ConsoleLayer; -use opentelemetry::sdk::*; -use opentelemetry::*; -use opentelemetry_otlp::WithExportConfig; + +cfg_if::cfg_if! { + if #[cfg(feature = "opentelemetry-otlp")] { + use opentelemetry::sdk::*; + use opentelemetry::*; + use opentelemetry_otlp::WithExportConfig; + } +} + use parking_lot::*; use std::collections::BTreeMap; use std::path::*; @@ -66,6 +72,7 @@ impl VeilidLogs { } // OpenTelemetry logger + #[cfg(feature="opentelemetry-otlp")] if settingsr.logging.otlp.enabled { let grpc_endpoint = settingsr.logging.otlp.grpc_endpoint.name.clone(); diff --git a/veilid-tools/src/ipc/ipc_async_std/mod.rs b/veilid-tools/src/ipc/ipc_async_std/mod.rs index a07114e9..4bef1caf 100644 --- a/veilid-tools/src/ipc/ipc_async_std/mod.rs +++ b/veilid-tools/src/ipc/ipc_async_std/mod.rs @@ -4,7 +4,8 @@ cfg_if! { if #[cfg(unix)] { mod unix; pub use unix::*; - } else if #[cfg(windows)] { + } + else if #[cfg(windows)] { mod windows; pub use windows::*; } diff --git a/veilid-tools/src/ipc/ipc_async_std/windows.rs b/veilid-tools/src/ipc/ipc_async_std/windows.rs index e69de29b..9ba0c76f 100644 --- a/veilid-tools/src/ipc/ipc_async_std/windows.rs +++ b/veilid-tools/src/ipc/ipc_async_std/windows.rs @@ -0,0 +1 @@ +compile_error!{"async-std compilation for windows is currently unsupported"} \ No newline at end of file From 5ad481451567049c0978b7288c92eca861e4d1d4 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 17 Dec 2023 10:05:08 -0500 Subject: [PATCH 55/67] push configuration check to veilid-server --- veilid-server/src/main.rs | 4 ++++ veilid-tools/src/ipc/ipc_async_std/windows.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/veilid-server/src/main.rs b/veilid-server/src/main.rs index 03c94e63..630a9d5d 100644 --- a/veilid-server/src/main.rs +++ b/veilid-server/src/main.rs @@ -4,6 +4,9 @@ #![deny(unused_must_use)] #![recursion_limit = "256"] +#[cfg(all(feature = "rt-async-std", windows))] +compile_error! {"async-std compilation for windows is currently unsupported"} + mod client_api; mod server; mod settings; @@ -77,6 +80,7 @@ pub struct CmdlineArgs { /// Turn on OpenTelemetry tracing /// /// This option uses the GRPC OpenTelemetry protocol, not HTTP. The format for the endpoint is host:port, like 'localhost:4317' + #[cfg(feature = "opentelemetry-otlp")] #[arg(long, value_name = "endpoint")] otlp: Option, diff --git a/veilid-tools/src/ipc/ipc_async_std/windows.rs b/veilid-tools/src/ipc/ipc_async_std/windows.rs index 9ba0c76f..2a7d26d2 100644 --- a/veilid-tools/src/ipc/ipc_async_std/windows.rs +++ b/veilid-tools/src/ipc/ipc_async_std/windows.rs @@ -1 +1 @@ -compile_error!{"async-std compilation for windows is currently unsupported"} \ No newline at end of file +compile_error! {"async-std compilation for windows is currently unsupported"} From 70ef9927145d9042cce035750143ad329c016b1d Mon Sep 17 00:00:00 2001 From: John Smith Date: Sun, 17 Dec 2023 10:39:03 -0500 Subject: [PATCH 56/67] windows fix --- veilid-server/src/main.rs | 2 +- veilid-tools/src/ipc/ipc_async_std/mod.rs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/veilid-server/src/main.rs b/veilid-server/src/main.rs index 630a9d5d..63c0e608 100644 --- a/veilid-server/src/main.rs +++ b/veilid-server/src/main.rs @@ -5,7 +5,7 @@ #![recursion_limit = "256"] #[cfg(all(feature = "rt-async-std", windows))] -compile_error! {"async-std compilation for windows is currently unsupported"} +compile_error! {"async-std compilation for windows is currently unsupportedg"} mod client_api; mod server; diff --git a/veilid-tools/src/ipc/ipc_async_std/mod.rs b/veilid-tools/src/ipc/ipc_async_std/mod.rs index 4bef1caf..ed421e1d 100644 --- a/veilid-tools/src/ipc/ipc_async_std/mod.rs +++ b/veilid-tools/src/ipc/ipc_async_std/mod.rs @@ -4,9 +4,9 @@ cfg_if! { if #[cfg(unix)] { mod unix; pub use unix::*; - } - else if #[cfg(windows)] { - mod windows; - pub use windows::*; } + // else if #[cfg(windows)] { + // mod windows; + // pub use windows::*; + // } } From 92cb5a07cf0c4b3e46e312c68660bf44b2eb7aa3 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 17 Dec 2023 14:03:56 -0500 Subject: [PATCH 57/67] add watch capability --- veilid-core/src/network_manager/native/mod.rs | 21 +++++++++---------- veilid-core/src/network_manager/wasm/mod.rs | 2 ++ .../src/routing_table/types/node_info.rs | 1 + .../src/rpc_processor/rpc_get_value.rs | 2 +- .../src/rpc_processor/rpc_watch_value.rs | 11 +++++++++- veilid-core/src/storage_manager/get_value.rs | 2 +- veilid-core/src/storage_manager/set_value.rs | 2 +- .../src/storage_manager/watch_value.rs | 2 +- veilid-python/veilid/types.py | 1 + 9 files changed, 28 insertions(+), 16 deletions(-) diff --git a/veilid-core/src/network_manager/native/mod.rs b/veilid-core/src/network_manager/native/mod.rs index 92551955..a6f171e6 100644 --- a/veilid-core/src/network_manager/native/mod.rs +++ b/veilid-core/src/network_manager/native/mod.rs @@ -31,11 +31,11 @@ pub const PEEK_DETECT_LEN: usize = 64; cfg_if! { if #[cfg(all(feature = "unstable-blockstore", feature="unstable-tunnels"))] { - const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 8; + const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 9; } else if #[cfg(any(feature = "unstable-blockstore", feature="unstable-tunnels"))] { - const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 7; + const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 8; } else { - const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 6; + const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 7; } } pub const PUBLIC_INTERNET_CAPABILITIES: [Capability; PUBLIC_INTERNET_CAPABILITIES_LEN] = [ @@ -46,19 +46,21 @@ pub const PUBLIC_INTERNET_CAPABILITIES: [Capability; PUBLIC_INTERNET_CAPABILITIE CAP_RELAY, CAP_VALIDATE_DIAL_INFO, CAP_DHT, + CAP_DHT_WATCH, CAP_APPMESSAGE, #[cfg(feature = "unstable-blockstore")] CAP_BLOCKSTORE, ]; #[cfg(feature = "unstable-blockstore")] -const LOCAL_NETWORK_CAPABILITIES_LEN: usize = 4; +const LOCAL_NETWORK_CAPABILITIES_LEN: usize = 5; #[cfg(not(feature = "unstable-blockstore"))] -const LOCAL_NETWORK_CAPABILITIES_LEN: usize = 3; +const LOCAL_NETWORK_CAPABILITIES_LEN: usize = 4; pub const LOCAL_NETWORK_CAPABILITIES: [Capability; LOCAL_NETWORK_CAPABILITIES_LEN] = [ CAP_RELAY, CAP_DHT, + CAP_DHT_WATCH, CAP_APPMESSAGE, #[cfg(feature = "unstable-blockstore")] CAP_BLOCKSTORE, @@ -551,12 +553,9 @@ impl Network { .wrap_err("connect failure")? } ProtocolType::WS | ProtocolType::WSS => { - WebsocketProtocolHandler::connect( - None, - &dial_info, - connect_timeout_ms) - .await - .wrap_err("connect failure")? + WebsocketProtocolHandler::connect(None, &dial_info, connect_timeout_ms) + .await + .wrap_err("connect failure")? } }); diff --git a/veilid-core/src/network_manager/wasm/mod.rs b/veilid-core/src/network_manager/wasm/mod.rs index 92b64ff6..88cc1fcb 100644 --- a/veilid-core/src/network_manager/wasm/mod.rs +++ b/veilid-core/src/network_manager/wasm/mod.rs @@ -27,6 +27,7 @@ pub const PUBLIC_INTERNET_CAPABILITIES: [Capability; PUBLIC_INTERNET_CAPABILITIE //CAP_RELAY, //CAP_VALIDATE_DIAL_INFO, CAP_DHT, + CAP_DHT_WATCH, CAP_APPMESSAGE, #[cfg(feature = "unstable-blockstore")] CAP_BLOCKSTORE, @@ -40,6 +41,7 @@ pub const PUBLIC_INTERNET_CAPABILITIES: [Capability; PUBLIC_INTERNET_CAPABILITIE // pub const LOCAL_NETWORK_CAPABILITIES: [Capability; LOCAL_NETWORK_CAPABILITIES_LEN] = [ // //CAP_RELAY, // CAP_DHT, +// CAP_DHT_WATCH, // CAP_APPMESSAGE, // #[cfg(feature = "unstable-blockstore")] // CAP_BLOCKSTORE, diff --git a/veilid-core/src/routing_table/types/node_info.rs b/veilid-core/src/routing_table/types/node_info.rs index 838022e3..93e178ea 100644 --- a/veilid-core/src/routing_table/types/node_info.rs +++ b/veilid-core/src/routing_table/types/node_info.rs @@ -8,6 +8,7 @@ pub const CAP_SIGNAL: Capability = FourCC(*b"SGNL"); pub const CAP_RELAY: Capability = FourCC(*b"RLAY"); pub const CAP_VALIDATE_DIAL_INFO: Capability = FourCC(*b"DIAL"); pub const CAP_DHT: Capability = FourCC(*b"DHTV"); +pub const CAP_DHT_WATCH: Capability = FourCC(*b"DHTW"); pub const CAP_APPMESSAGE: Capability = FourCC(*b"APPM"); #[cfg(feature = "unstable-blockstore")] pub const CAP_BLOCKSTORE: Capability = FourCC(*b"BLOC"); diff --git a/veilid-core/src/rpc_processor/rpc_get_value.rs b/veilid-core/src/rpc_processor/rpc_get_value.rs index 679f0423..0859c9b2 100644 --- a/veilid-core/src/rpc_processor/rpc_get_value.rs +++ b/veilid-core/src/rpc_processor/rpc_get_value.rs @@ -211,7 +211,7 @@ impl RPCProcessor { // Get the nodes that we know about that are closer to the the key than our own node let routing_table = self.routing_table(); - let closer_to_key_peers = network_result_try!(routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT])); + let closer_to_key_peers = network_result_try!(routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT, CAP_DHT_WATCH])); #[cfg(feature="debug-dht")] { diff --git a/veilid-core/src/rpc_processor/rpc_watch_value.rs b/veilid-core/src/rpc_processor/rpc_watch_value.rs index 77351cc8..8b08a642 100644 --- a/veilid-core/src/rpc_processor/rpc_watch_value.rs +++ b/veilid-core/src/rpc_processor/rpc_watch_value.rs @@ -164,6 +164,15 @@ impl RPCProcessor { if !opi.signed_node_info().node_info().has_capability(CAP_DHT) { return Ok(NetworkResult::service_unavailable("dht is not available")); } + if !opi + .signed_node_info() + .node_info() + .has_capability(CAP_DHT_WATCH) + { + return Ok(NetworkResult::service_unavailable( + "dht watch is not available", + )); + } // Get the question let kind = msg.operation.kind().clone(); @@ -199,7 +208,7 @@ impl RPCProcessor { // Get the nodes that we know about that are closer to the the key than our own node let closer_to_key_peers = network_result_try!( - routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT]) + routing_table.find_preferred_peers_closer_to_key(key, vec![CAP_DHT, CAP_DHT_WATCH]) ); // See if we would have accepted this as a set diff --git a/veilid-core/src/storage_manager/get_value.rs b/veilid-core/src/storage_manager/get_value.rs index 239fe20f..6e7b0ab1 100644 --- a/veilid-core/src/storage_manager/get_value.rs +++ b/veilid-core/src/storage_manager/get_value.rs @@ -169,7 +169,7 @@ impl StorageManager { key_count, fanout, timeout_us, - capability_fanout_node_info_filter(vec![CAP_DHT]), + capability_fanout_node_info_filter(vec![CAP_DHT, CAP_DHT_WATCH]), call_routine, check_done, ); diff --git a/veilid-core/src/storage_manager/set_value.rs b/veilid-core/src/storage_manager/set_value.rs index 50aa8dc7..e5279157 100644 --- a/veilid-core/src/storage_manager/set_value.rs +++ b/veilid-core/src/storage_manager/set_value.rs @@ -160,7 +160,7 @@ impl StorageManager { key_count, fanout, timeout_us, - capability_fanout_node_info_filter(vec![CAP_DHT]), + capability_fanout_node_info_filter(vec![CAP_DHT, CAP_DHT_WATCH]), call_routine, check_done, ); diff --git a/veilid-core/src/storage_manager/watch_value.rs b/veilid-core/src/storage_manager/watch_value.rs index f945c781..097bbd1d 100644 --- a/veilid-core/src/storage_manager/watch_value.rs +++ b/veilid-core/src/storage_manager/watch_value.rs @@ -127,7 +127,7 @@ impl StorageManager { key_count, 1, timeout_us, - capability_fanout_node_info_filter(vec![CAP_DHT]), + capability_fanout_node_info_filter(vec![CAP_DHT, CAP_DHT_WATCH]), call_routine, check_done, ); diff --git a/veilid-python/veilid/types.py b/veilid-python/veilid/types.py index a9a80587..c47d7590 100644 --- a/veilid-python/veilid/types.py +++ b/veilid-python/veilid/types.py @@ -59,6 +59,7 @@ class Capability(StrEnum): CAP_RELAY = "RLAY" CAP_VALIDATE_DIAL_INFO = "DIAL" CAP_DHT = "DHTV" + CAP_DHT_WATCH = "DHTW" CAP_APPMESSAGE = "APPM" CAP_BLOCKSTORE = "BLOC" From 37ed0239f3e634b0fa3842ce6fad598ba373f164 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Thu, 4 Jan 2024 22:29:31 -0500 Subject: [PATCH 58/67] checkpoint --- .../tasks/check_active_watches.rs | 11 +++++--- veilid-flutter/example/pubspec.lock | 26 +++++++++---------- veilid-flutter/lib/routing_context.dart | 6 ++--- veilid-flutter/lib/veilid_ffi.dart | 16 +++++++++--- veilid-flutter/lib/veilid_js.dart | 14 +++++++--- 5 files changed, 47 insertions(+), 26 deletions(-) diff --git a/veilid-core/src/storage_manager/tasks/check_active_watches.rs b/veilid-core/src/storage_manager/tasks/check_active_watches.rs index 5ce1917c..89c37903 100644 --- a/veilid-core/src/storage_manager/tasks/check_active_watches.rs +++ b/veilid-core/src/storage_manager/tasks/check_active_watches.rs @@ -1,7 +1,7 @@ use super::*; impl StorageManager { - // Flush records stores to disk and remove dead records and send watch notifications + // Check if watches either have dead nodes or if the watch has expired #[instrument(level = "trace", skip(self), err)] pub(super) async fn check_active_watches_task_routine( self, @@ -44,8 +44,15 @@ impl StorageManager { } } } + // See if the watch is expired + if !is_dead && active_watch.expiration_ts <= cur_ts { + // Watch has expired + is_dead = true; + } if is_dead { + v.clear_active_watch(); + if let Some(update_callback) = opt_update_callback.clone() { // Send valuechange with dead count and no subkeys update_callback(VeilidUpdate::ValueChange(Box::new(VeilidValueChange { @@ -55,8 +62,6 @@ impl StorageManager { value: ValueData::default(), }))); } - - v.clear_active_watch(); } } } diff --git a/veilid-flutter/example/pubspec.lock b/veilid-flutter/example/pubspec.lock index 73fc4fc6..28671d7b 100644 --- a/veilid-flutter/example/pubspec.lock +++ b/veilid-flutter/example/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: transitive description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" convert: dependency: transitive description: @@ -220,10 +220,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" path: dependency: "direct main" description: @@ -329,18 +329,18 @@ packages: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -377,10 +377,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" typed_data: dependency: transitive description: @@ -408,10 +408,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" win32: dependency: transitive description: @@ -437,5 +437,5 @@ packages: source: hosted version: "3.5.0" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" + dart: ">=3.2.0-194.0.dev <4.0.0" flutter: ">=3.10.6" diff --git a/veilid-flutter/lib/routing_context.dart b/veilid-flutter/lib/routing_context.dart index c94fd476..46e3ada6 100644 --- a/veilid-flutter/lib/routing_context.dart +++ b/veilid-flutter/lib/routing_context.dart @@ -256,7 +256,7 @@ abstract class VeilidRoutingContext { Future deleteDHTRecord(TypedKey key); Future getDHTValue(TypedKey key, int subkey, bool forceRefresh); Future setDHTValue(TypedKey key, int subkey, Uint8List data); - Future watchDHTValues(TypedKey key, List subkeys, - Timestamp expiration, int count); - Future cancelDHTWatch(TypedKey key, List subkeys); + Future watchDHTValues(TypedKey key, + {List? subkeys, Timestamp? expiration, int? count}); + Future cancelDHTWatch(TypedKey key, {List? subkeys}); } diff --git a/veilid-flutter/lib/veilid_ffi.dart b/veilid-flutter/lib/veilid_ffi.dart index c439d93a..66dcf8c0 100644 --- a/veilid-flutter/lib/veilid_ffi.dart +++ b/veilid-flutter/lib/veilid_ffi.dart @@ -671,8 +671,14 @@ class VeilidRoutingContextFFI extends VeilidRoutingContext { } @override - Future watchDHTValues(TypedKey key, List subkeys, - Timestamp expiration, int count) async { + Future watchDHTValues(TypedKey key, + {List? subkeys, + Timestamp? expiration, + int? count}) async { + subkeys ??= []; + expiration ??= Timestamp(value: BigInt.zero); + count ??= 0xFFFFFFFF; + _ctx.ensureValid(); final nativeKey = jsonEncode(key).toNativeUtf8(); final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8(); @@ -688,8 +694,10 @@ class VeilidRoutingContextFFI extends VeilidRoutingContext { } @override - Future cancelDHTWatch( - TypedKey key, List subkeys) async { + Future cancelDHTWatch(TypedKey key, + {List? subkeys}) async { + subkeys ??= []; + _ctx.ensureValid(); final nativeKey = jsonEncode(key).toNativeUtf8(); final nativeSubkeys = jsonEncode(subkeys).toNativeUtf8(); diff --git a/veilid-flutter/lib/veilid_js.dart b/veilid-flutter/lib/veilid_js.dart index 99649a5f..7cbd345b 100644 --- a/veilid-flutter/lib/veilid_js.dart +++ b/veilid-flutter/lib/veilid_js.dart @@ -185,8 +185,14 @@ class VeilidRoutingContextJS extends VeilidRoutingContext { } @override - Future watchDHTValues(TypedKey key, List subkeys, - Timestamp expiration, int count) async { + Future watchDHTValues(TypedKey key, + {List? subkeys, + Timestamp? expiration, + int? count}) async { + subkeys ??= []; + expiration ??= Timestamp(value: BigInt.zero); + count ??= 0xFFFFFFFF; + final id = _ctx.requireId(); final ts = await _wrapApiPromise(js_util.callMethod( wasm, 'routing_context_watch_dht_values', [ @@ -200,7 +206,9 @@ class VeilidRoutingContextJS extends VeilidRoutingContext { } @override - Future cancelDHTWatch(TypedKey key, List subkeys) { + Future cancelDHTWatch(TypedKey key, {List? subkeys}) { + subkeys ??= []; + final id = _ctx.requireId(); return _wrapApiPromise(js_util.callMethod( wasm, From b9aa268f71b7473de1cd0a50cbff18c21a2dc453 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 6 Jan 2024 20:46:52 -0500 Subject: [PATCH 59/67] schema work --- veilid-flutter/lib/routing_context.dart | 34 ++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/veilid-flutter/lib/routing_context.dart b/veilid-flutter/lib/routing_context.dart index 46e3ada6..99799bef 100644 --- a/veilid-flutter/lib/routing_context.dart +++ b/veilid-flutter/lib/routing_context.dart @@ -22,11 +22,13 @@ extension ValidateDFLT on DHTSchemaDFLT { } return true; } + + int subkeyCount() => oCnt; } extension ValidateSMPL on DHTSchemaSMPL { bool validate() { - final totalsv = members.fold(0, (acc, v) => acc + v.mCnt) + oCnt; + final totalsv = subkeyCount(); if (totalsv > 65535) { return false; } @@ -35,6 +37,28 @@ extension ValidateSMPL on DHTSchemaSMPL { } return true; } + + int subkeyCount() => members.fold(0, (acc, v) => acc + v.mCnt) + oCnt; +} + +extension Validate on DHTSchema { + bool validate() { + if (this is DHTSchemaDFLT) { + return (this as DHTSchemaDFLT).validate(); + } else if (this is DHTSchemaSMPL) { + return (this as DHTSchemaSMPL).validate(); + } + throw TypeError(); + } + + int subkeyCount() { + if (this is DHTSchemaDFLT) { + return (this as DHTSchemaDFLT).subkeyCount(); + } else if (this is DHTSchemaSMPL) { + return (this as DHTSchemaSMPL).subkeyCount(); + } + throw TypeError(); + } } ////////////////////////////////////// @@ -115,6 +139,14 @@ class ValueSubkeyRange with _$ValueSubkeyRange { _$ValueSubkeyRangeFromJson(json as Map); } +extension ValueSubkeyRangeExt on ValueSubkeyRange { + bool contains(int v) => low <= v && v <= high; +} + +extension ListValueSubkeyRangeExt on List { + bool containsSubkey(int v) => indexWhere((e) => e.contains(v)) != -1; +} + ////////////////////////////////////// /// ValueData From 7848c14c2bc29926f6b0a37267fc9ca48aab5973 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 19 Jan 2024 13:44:00 -0500 Subject: [PATCH 60/67] disable dht test due to inconsistencies --- veilid-core/src/tests/native/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/veilid-core/src/tests/native/mod.rs b/veilid-core/src/tests/native/mod.rs index 78dbae30..1faa2aa5 100644 --- a/veilid-core/src/tests/native/mod.rs +++ b/veilid-core/src/tests/native/mod.rs @@ -30,8 +30,8 @@ pub async fn run_all_tests() { veilid_api::tests::test_serialize_json::test_all().await; info!("TEST: routing_table::test_serialize_routing_table"); routing_table::tests::test_serialize_routing_table::test_all().await; - info!("TEST: test_dht"); - test_dht::test_all().await; + // info!("TEST: test_dht"); + // test_dht::test_all().await; info!("Finished unit tests"); } @@ -131,6 +131,6 @@ cfg_if! { run_test!(routing_table, test_serialize_routing_table); - run_test!(test_dht); + // run_test!(test_dht); } } From b9705285e9d7efae8d98ccb4c542f0c9130cb4d3 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 19 Jan 2024 14:34:09 -0500 Subject: [PATCH 61/67] xfer --- veilid-core/src/veilid_config.rs | 7 +++++-- veilid-tools/src/tools.rs | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index 0e1a9f4d..65e05091 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -1,6 +1,6 @@ -use std::path::PathBuf; -use directories::ProjectDirs; use crate::*; +use directories::ProjectDirs; +use std::path::PathBuf; //////////////////////////////////////////////////////////////////////////////////////////////// pub type ConfigCallbackReturn = VeilidAPIResult>; @@ -329,6 +329,9 @@ impl Default for VeilidConfigDHT { remote_max_records: 128, remote_max_subkey_cache_memory_mb: 256, remote_max_storage_space_mb: 256, + public_watch_limit: 32, + member_watch_limit: 8, + max_watch_expiration_ms: 600000, } } } diff --git a/veilid-tools/src/tools.rs b/veilid-tools/src/tools.rs index ffb552ba..e87679ca 100644 --- a/veilid-tools/src/tools.rs +++ b/veilid-tools/src/tools.rs @@ -381,7 +381,7 @@ cfg_if::cfg_if! { } } else { - pub fn ensure_file_private_owner>(_path: P) -> Result<(), String> + pub fn ensure_file_private_owner>(path: P) -> Result<(), String> { let path = path.as_ref(); if !path.is_file() { From ae339e657372a3e0fc43c34a36c1b45554ff6f5a Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 19 Jan 2024 21:30:48 -0500 Subject: [PATCH 62/67] wasm fixes --- Cargo.lock | 20 +++++++++---------- veilid-core/src/network_manager/wasm/mod.rs | 6 +++--- .../src/tests/common/test_veilid_core.rs | 4 ++-- veilid-core/src/veilid_config.rs | 9 +++++---- veilid-tools/src/ipc/mod.rs | 1 + 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 68599a2d..9353067a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5865,9 +5865,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" dependencies = [ "cfg-if 1.0.0", "serde", @@ -5877,9 +5877,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" dependencies = [ "bumpalo", "log", @@ -5904,9 +5904,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5914,9 +5914,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", @@ -5927,9 +5927,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.90" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-bindgen-test" diff --git a/veilid-core/src/network_manager/wasm/mod.rs b/veilid-core/src/network_manager/wasm/mod.rs index 88cc1fcb..d648be90 100644 --- a/veilid-core/src/network_manager/wasm/mod.rs +++ b/veilid-core/src/network_manager/wasm/mod.rs @@ -12,11 +12,11 @@ use std::io; cfg_if! { if #[cfg(all(feature = "unstable-blockstore", feature="unstable-tunnels"))] { - const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 6; + const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 7; } else if #[cfg(any(feature = "unstable-blockstore", feature="unstable-tunnels"))] { - const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 5; + const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 6; } else { - const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 4; + const PUBLIC_INTERNET_CAPABILITIES_LEN: usize = 5; } } pub const PUBLIC_INTERNET_CAPABILITIES: [Capability; PUBLIC_INTERNET_CAPABILITIES_LEN] = [ diff --git a/veilid-core/src/tests/common/test_veilid_core.rs b/veilid-core/src/tests/common/test_veilid_core.rs index 70b864cd..8013958b 100644 --- a/veilid-core/src/tests/common/test_veilid_core.rs +++ b/veilid-core/src/tests/common/test_veilid_core.rs @@ -19,12 +19,12 @@ pub async fn test_startup_shutdown_from_config() { table_store: VeilidConfigTableStore { directory: get_table_store_path(), delete: true, - ..Default::default() + // ..Default::default() }, block_store: VeilidConfigBlockStore { directory: get_block_store_path(), delete: true, - ..Default::default() + //..Default::default() }, protected_store: VeilidConfigProtectedStore { allow_insecure_fallback: true, diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index 65e05091..66477fbb 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -263,11 +263,12 @@ impl Default for VeilidConfigTLS { } pub fn get_default_ssl_directory(sub_path: &str) -> String { - let default_path = PathBuf::from("/etc/veilid-server/ssl").join(sub_path); - #[cfg(unix)] - if default_path.exists() { - return default_path.to_string_lossy().into(); + { + let default_path = PathBuf::from("/etc/veilid-server/ssl").join(sub_path); + if default_path.exists() { + return default_path.to_string_lossy().into(); + } } ProjectDirs::from("org", "Veilid", "Veilid") diff --git a/veilid-tools/src/ipc/mod.rs b/veilid-tools/src/ipc/mod.rs index 27f81639..665c52de 100644 --- a/veilid-tools/src/ipc/mod.rs +++ b/veilid-tools/src/ipc/mod.rs @@ -11,6 +11,7 @@ cfg_if! { } } +#[allow(unused_variables)] pub fn is_ipc_socket_path>(path: P) -> bool { cfg_if! { if #[cfg(windows)] { From 617d059eb5f06d967f1a6b22be2ce2325c425b89 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 19 Jan 2024 22:04:41 -0500 Subject: [PATCH 63/67] add missing function --- veilid-server/src/settings.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index f2f2c3bc..4acf7816 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -806,6 +806,28 @@ impl Settings { .unwrap_or_else(|| PathBuf::from("./veilid-server.conf")) } + #[allow(dead_code)] + fn get_or_create_default_directory(subpath: &str) -> PathBuf { + #[cfg(unix)] + if PathBuf::from("/var/db/veilid-server").is_dir() { + let globalpath = PathBuf::from("/var/db/veilid-server").join(subpath); + let _ = std::fs::create_dir_all(&globalpath); + if globalpath.is_dir() { + return globalpath; + } + } + + let mut ts_path = if let Some(my_proj_dirs) = ProjectDirs::from("org", "Veilid", "Veilid") { + PathBuf::from(my_proj_dirs.data_local_dir()) + } else { + PathBuf::from("./") + }; + ts_path.push(subpath); + let _ = std::fs::create_dir_all(&ts_path); + + ts_path + } + pub fn get_default_ipc_directory() -> PathBuf { cfg_if! { if #[cfg(windows)] { From 599677bb2dc52ac4cb457783cdfc4d56389163c9 Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Fri, 19 Jan 2024 22:10:10 -0500 Subject: [PATCH 64/67] better version --- veilid-server/src/settings.rs | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index 4acf7816..d6772f29 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -806,13 +806,23 @@ impl Settings { .unwrap_or_else(|| PathBuf::from("./veilid-server.conf")) } - #[allow(dead_code)] + fn get_or_create_private_directory>(path: P, group_read: bool) -> bool { + let path = path.as_ref(); + if !path.is_dir() + && (std::fs::create_dir_all(path).is_err() + || ensure_directory_private_owner(path, group_read).is_err()) + { + return false; + } + true + } + fn get_or_create_default_directory(subpath: &str) -> PathBuf { #[cfg(unix)] - if PathBuf::from("/var/db/veilid-server").is_dir() { + { let globalpath = PathBuf::from("/var/db/veilid-server").join(subpath); - let _ = std::fs::create_dir_all(&globalpath); - if globalpath.is_dir() { + + if Self::get_or_create_private_directory(&globalpath, true) { return globalpath; } } @@ -823,9 +833,12 @@ impl Settings { PathBuf::from("./") }; ts_path.push(subpath); - let _ = std::fs::create_dir_all(&ts_path); - ts_path + if Self::get_or_create_private_directory(&ts_path, true) { + return ts_path; + } + + panic!("Failed to create private directory for '{}'", subpath); } pub fn get_default_ipc_directory() -> PathBuf { From 2ef91116ee55b4b2f651ed6330c7df238f16e1bd Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sat, 20 Jan 2024 21:52:23 -0500 Subject: [PATCH 65/67] switch to build hash from modtime for capnp generation --- Cargo.lock | 712 ++++++++++++++++-------------- veilid-core/Cargo.toml | 2 + veilid-core/build.rs | 88 +++- veilid-core/proto/veilid_capnp.rs | 40 +- 4 files changed, 465 insertions(+), 377 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9353067a..1dcca8ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" dependencies = [ "cfg-if 1.0.0", "getrandom", @@ -74,9 +74,9 @@ dependencies = [ [[package]] name = "allo-isolate" -version = "0.1.20" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f56b7997817c178b853573e8bdfb6c3afe02810b43f17d766d6703560074b0c3" +checksum = "f2f5a5fd28223e6f3cafb7d9cd685f51eafdd71d33ca1229f8316925d5957240" dependencies = [ "atomic", ] @@ -112,7 +112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8619b80c242aa7bd638b5c7ddd952addeecb71f69c75e33f1d47b2804f8f883a" dependencies = [ "android_log-sys 0.2.0", - "env_logger 0.10.0", + "env_logger 0.10.2", "log", "once_cell", ] @@ -124,7 +124,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c494134f746c14dc653a35a4ea5aca24ac368529da5370ecf41fe0341c35772f" dependencies = [ "android_log-sys 0.3.1", - "env_logger 0.10.0", + "env_logger 0.10.2", "log", "once_cell", ] @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -179,37 +179,37 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" [[package]] name = "arboard" @@ -288,31 +288,44 @@ dependencies = [ ] [[package]] -name = "async-executor" -version = "1.6.0" +name = "async-channel" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0" +checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" dependencies = [ - "async-lock 2.8.0", + "concurrent-queue", + "event-listener 4.0.3", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", "async-task", "concurrent-queue", "fastrand 2.0.1", - "futures-lite 1.13.0", + "futures-lite 2.2.0", "slab", ] [[package]] name = "async-global-executor" -version = "2.3.1" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel", + "async-channel 2.1.1", "async-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io 2.3.0", + "async-lock 3.3.0", "blocking", - "futures-lite 1.13.0", + "futures-lite 2.2.0", "once_cell", ] @@ -338,18 +351,18 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "fb41eb19024a91746eba0773aa5e16036045bbf45733766661099e182ea6a744" dependencies = [ - "async-lock 3.0.0", + "async-lock 3.3.0", "cfg-if 1.0.0", "concurrent-queue", "futures-io", - "futures-lite 2.0.1", + "futures-lite 2.2.0", "parking", - "polling 3.3.0", - "rustix 0.38.28", + "polling 3.3.2", + "rustix 0.38.30", "slab", "tracing", "windows-sys 0.52.0", @@ -366,11 +379,11 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.0.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e900cdcd39bb94a14487d3f7ef92ca222162e6c7c3fe7cb3550ea75fb486ed" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" dependencies = [ - "event-listener 3.0.1", + "event-listener 4.0.3", "event-listener-strategy", "pin-project-lite", ] @@ -386,9 +399,9 @@ dependencies = [ "async-signal", "blocking", "cfg-if 1.0.0", - "event-listener 3.0.1", + "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.28", + "rustix 0.38.30", "windows-sys 0.48.0", ] @@ -398,13 +411,13 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io 2.2.2", + "async-io 2.3.0", "async-lock 2.8.0", "atomic-waker", "cfg-if 1.0.0", "futures-core", "futures-io", - "rustix 0.38.28", + "rustix 0.38.30", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -417,7 +430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" dependencies = [ "async-attributes", - "async-channel", + "async-channel 1.9.0", "async-global-executor", "async-io 1.13.0", "async-lock 2.8.0", @@ -472,24 +485,24 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "async-task" -version = "4.5.0" +version = "4.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4eb2cdb97421e01129ccb49169d8279ed21e829929144f4a22a6e54ac549ca1" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -642,9 +655,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -683,9 +696,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" [[package]] name = "blake2" @@ -717,7 +730,7 @@ checksum = "e0b121a9fe0df916e362fb3271088d071159cdf11db0e4182d02152850756eff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -762,16 +775,16 @@ checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" [[package]] name = "blocking" -version = "1.4.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel", - "async-lock 2.8.0", + "async-channel 2.1.1", + "async-lock 3.3.0", "async-task", "fastrand 2.0.1", "futures-io", - "futures-lite 1.13.0", + "futures-lite 2.2.0", "piper", "tracing", ] @@ -811,18 +824,18 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" [[package]] name = "capnp" -version = "0.18.10" +version = "0.18.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e78424967d6d4c8e295a3b5114ae6d849052e9dbbed3e62589a76acda54e3f0" +checksum = "384b671a5b39eadb909b0c2b81d22a400d446526e651e64be9eb6674b33644a4" dependencies = [ "embedded-io", ] [[package]] name = "capnpc" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5067f3c8ee94d993d03150153e9a57a6ff330127b1c1ad76475051e1cef79c2d" +checksum = "a642faaaa78187e70bdcc0014c593c213553cfeda3b15054426d0d596048b131" dependencies = [ "capnp", ] @@ -923,9 +936,9 @@ dependencies = [ [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "67523a3b4be3ce1989d607a828d036249522dd9c1c8de7f4dd2dae43a37369d1" dependencies = [ "glob", "libc", @@ -949,9 +962,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.7" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -959,9 +972,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.7" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -979,7 +992,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1045,9 +1058,9 @@ dependencies = [ [[package]] name = "concurrent-queue" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f057a694a54f12365049b0958a1685bb52d567f5593b355fbf685838e873d400" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" dependencies = [ "crossbeam-utils", ] @@ -1078,7 +1091,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd326812b3fd01da5bb1af7d340d0d555fd3d4b641e7f1dfcf5962a902952787" dependencies = [ "futures-core", - "prost 0.12.1", + "prost 0.12.3", "prost-types", "tonic 0.10.2", "tracing-core", @@ -1120,9 +1133,9 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "constant_time_eq" @@ -1132,9 +1145,9 @@ checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "core-foundation" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -1142,9 +1155,9 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "core-graphics" @@ -1161,9 +1174,9 @@ dependencies = [ [[package]] name = "core-graphics-types" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -1172,9 +1185,9 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" dependencies = [ "libc", ] @@ -1190,22 +1203,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" dependencies = [ - "cfg-if 1.0.0", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.17" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" [[package]] name = "crossterm" @@ -1260,17 +1269,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" dependencies = [ "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "ctrlc" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" +checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b" dependencies = [ "nix 0.27.1", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1278,7 +1287,7 @@ name = "cursive" version = "0.20.0" source = "git+https://gitlab.com/veilid/cursive.git#a76fc9050f69edf56bc37efc63194050b9f222e4" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "async-std", "cfg-if 1.0.0", "crossbeam-channel", @@ -1321,7 +1330,7 @@ name = "cursive_core" version = "0.3.7" source = "git+https://gitlab.com/veilid/cursive.git#a76fc9050f69edf56bc37efc63194050b9f222e4" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "ansi-parser", "async-std", "crossbeam-channel", @@ -1376,7 +1385,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1432,7 +1441,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1454,7 +1463,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core 0.20.3", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1464,7 +1473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if 1.0.0", - "hashbrown 0.14.2", + "hashbrown 0.14.3", "lock_api", "once_cell", "parking_lot_core 0.9.9", @@ -1488,9 +1497,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", ] @@ -1606,27 +1615,27 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "enum-map" -version = "2.7.0" +version = "2.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53337c2dbf26a3c31eccc73a37b10c1614e8d4ae99b6a50d553e8936423c1f16" +checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9" dependencies = [ "enum-map-derive", ] [[package]] name = "enum-map-derive" -version = "0.14.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25" +checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1669,7 +1678,7 @@ dependencies = [ "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -1687,9 +1696,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "log", "regex", @@ -1729,9 +1738,20 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cec0252c2afff729ee6f00e903d479fba81784c8e2bd77447673471fdfaea1" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" dependencies = [ "concurrent-queue", "parking", @@ -1740,11 +1760,11 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d96b852f1345da36d551b9473fa1e2b1eb5c5195585c6c018118bc92a8d91160" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" dependencies = [ - "event-listener 3.0.1", + "event-listener 4.0.3", "pin-project-lite", ] @@ -1787,9 +1807,9 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" -version = "0.3.1" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d6dafc854908ff5da46ff3f8f473c6984119a2876a383a860246dd7841a868" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] @@ -1806,9 +1826,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a481586acf778f1b1455424c343f71124b048ffa5f4fc3f8f6ae9dc432dcb3c7" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" [[package]] name = "filetime" @@ -1904,15 +1924,15 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" dependencies = [ - "rustix 0.38.28", + "rustix 0.38.30", "windows-sys 0.48.0", ] [[package]] name = "futures" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" dependencies = [ "futures-channel", "futures-core", @@ -1925,9 +1945,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" dependencies = [ "futures-core", "futures-sink", @@ -1935,15 +1955,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" dependencies = [ "futures-core", "futures-task", @@ -1952,9 +1972,9 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" [[package]] name = "futures-lite" @@ -1973,36 +1993,39 @@ dependencies = [ [[package]] name = "futures-lite" -version = "2.0.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" dependencies = [ + "fastrand 2.0.1", "futures-core", + "futures-io", + "parking", "pin-project-lite", ] [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" [[package]] name = "futures-task" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" [[package]] name = "futures-timer" @@ -2016,9 +2039,9 @@ dependencies = [ [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" dependencies = [ "futures-channel", "futures-core", @@ -2078,9 +2101,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -2091,9 +2114,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" [[package]] name = "glob" @@ -2172,9 +2195,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.21" +version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" dependencies = [ "bytes", "fnv", @@ -2182,7 +2205,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 1.9.3", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -2219,16 +2242,16 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", ] [[package]] name = "hashbrown" -version = "0.14.2" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7192158dbcda357bdec5fb5788eebf8bbac027f3f33e719d29135ae84156" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ - "ahash 0.8.6", + "ahash 0.8.7", "allocator-api2", ] @@ -2238,16 +2261,16 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" dependencies = [ - "hashbrown 0.14.2", + "hashbrown 0.14.3", ] [[package]] name = "hdrhistogram" -version = "7.5.2" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f19b9f54f7c7f55e31401bb647626ce0cf0f67b0004982ce815b3ee72a02aa8" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "base64 0.13.1", + "base64 0.21.7", "byteorder", "flate2", "nom 7.1.3", @@ -2283,9 +2306,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" [[package]] name = "hex" @@ -2315,11 +2338,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2335,9 +2358,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" dependencies = [ "bytes", "fnv", @@ -2346,9 +2369,9 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -2375,9 +2398,9 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" dependencies = [ "bytes", "futures-channel", @@ -2390,7 +2413,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2 0.5.5", "tokio", "tower-service", "tracing", @@ -2411,16 +2434,16 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -2470,14 +2493,13 @@ dependencies = [ [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", "color_quant", - "num-rational", "num-traits", "png", "tiff", @@ -2512,7 +2534,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.2", + "hashbrown 0.14.3", ] [[package]] @@ -2539,7 +2561,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.4", "libc", "windows-sys 0.48.0", ] @@ -2580,6 +2602,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.10" @@ -2610,15 +2641,15 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jpeg-decoder" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" dependencies = [ "wasm-bindgen", ] @@ -2740,9 +2771,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" [[package]] name = "libc-print" @@ -2755,12 +2786,12 @@ dependencies = [ [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" dependencies = [ "cfg-if 1.0.0", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -2769,7 +2800,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall 0.4.1", ] @@ -2787,9 +2818,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" dependencies = [ "cc", "libc", @@ -2811,9 +2842,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "lock_api" @@ -2854,9 +2885,9 @@ dependencies = [ [[package]] name = "lz4_flex" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea9b256699eda7b0387ffbc776dd625e28bde3918446381781245b7a50349d8" +checksum = "912b45c753ff5f7f5208307e8ace7d2a2e30d024e26d3509f3dce546c044ce15" [[package]] name = "malloc_buf" @@ -2890,9 +2921,9 @@ checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" [[package]] name = "memchr" -version = "2.6.4" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" [[package]] name = "memoffset" @@ -3136,7 +3167,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if 1.0.0", "libc", ] @@ -3262,7 +3293,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.4", "libc", ] @@ -3327,9 +3358,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.32.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" dependencies = [ "memchr", ] @@ -3603,9 +3634,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" dependencies = [ "memchr", "thiserror", @@ -3614,9 +3645,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81d78524685f5ef2a3b3bd1cafbc9fcabb036253d9b1463e726a91cd16e2dfc2" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" dependencies = [ "pest", "pest_generator", @@ -3624,22 +3655,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bd1206e71118b5356dae5ddc61c8b11e28b09ef6a31acbd15ea48a28e0c227" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "pest_meta" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c747191d4ad9e4a4ab9c8798f1e82a39affe7ef9648390b7e5548d18e099de6" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" dependencies = [ "once_cell", "pest", @@ -3673,7 +3704,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -3711,21 +3742,21 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "platforms" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" [[package]] name = "png" -version = "0.17.10" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -3752,16 +3783,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.0" +version = "3.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53b6af1f60f36f8c2ac2aad5459d75a5a9b4be1e8cdd40264f315d78193e531" +checksum = "545c980a3880efd47b2e262f6a4bb6daad6555cf3367aa9c4e52895f69537a41" dependencies = [ "cfg-if 1.0.0", "concurrent-queue", "pin-project-lite", - "rustix 0.38.28", + "rustix 0.38.30", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -3808,9 +3839,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.70" +version = "1.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" dependencies = [ "unicode-ident", ] @@ -3827,12 +3858,12 @@ dependencies = [ [[package]] name = "prost" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fdd22f3b9c31b53c060df4a0613a1c7f062d4115a2b984dd15b1858f7e340d" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", - "prost-derive 0.12.1", + "prost-derive 0.12.3", ] [[package]] @@ -3850,24 +3881,24 @@ dependencies = [ [[package]] name = "prost-derive" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "265baba7fabd416cf5078179f7d2cbeca4ce7a9041111900675ea7c4cb8a4c32" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" dependencies = [ "anyhow", "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "prost-types" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e081b29f63d83a4bc75cfc9f3fe424f9156cf92d8a4f0c9407cce9a1b67327cf" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ - "prost 0.12.1", + "prost 0.12.3", ] [[package]] @@ -3884,9 +3915,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -3923,12 +3954,12 @@ dependencies = [ [[package]] name = "range-set-blaze" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "113937773e2f2211b7b9816e54e3e3cf433549c10af0f9ab966a43aa8098188c" +checksum = "c7bf6195484b9c084e59358ac571e65e273b8278f7fed60fcee62159cd4f9e86" dependencies = [ "gen_ops", - "itertools 0.11.0", + "itertools 0.12.0", "num-integer", "num-traits", ] @@ -4049,13 +4080,13 @@ dependencies = [ [[package]] name = "rpassword" -version = "7.2.0" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6678cf63ab3491898c0d021b493c94c9b221d91295294a2a5746eacbe5928322" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", "rtoolbox", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -4079,12 +4110,12 @@ dependencies = [ [[package]] name = "rtoolbox" -version = "0.0.1" +version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "034e22c514f5c0cb8a10ff341b9b048b5ceb21591f31c8f44c43b960f9b3524a" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" dependencies = [ "libc", - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -4093,7 +4124,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "549b9d036d571d42e6e85d1c1425e2ac83491075078ca9a15be021c56b1641f2" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -4148,14 +4179,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -4177,7 +4208,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", ] [[package]] @@ -4302,9 +4333,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "send_wrapper" @@ -4323,9 +4354,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" dependencies = [ "serde_derive", ] @@ -4363,9 +4394,9 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab33ec92f677585af6d88c65593ae2375adde54efdbf16d597f2cbc7a6d368ff" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" dependencies = [ "serde", ] @@ -4382,13 +4413,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.195" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4410,14 +4441,14 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" dependencies = [ "itoa", "ryu", @@ -4426,29 +4457,29 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "serde_spanned" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12022b835073e5b11e90a14f86838ceb1c8fb0325b72416845c487ac0fa95e80" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] [[package]] name = "serde_yaml" -version = "0.9.27" +version = "0.9.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cc7a1570e38322cfe4154732e5110f887ea57e22b76f4bfd32b5bdd3368666c" +checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" dependencies = [ "indexmap 2.1.0", "itoa", @@ -4479,7 +4510,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4582,9 +4613,9 @@ dependencies = [ [[package]] name = "signature" -version = "2.0.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fe458c98333f9c8152221191a77e2a44e8325d0193484af2e9421a53019e57d" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", ] @@ -4617,9 +4648,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "snailquote" @@ -4662,9 +4693,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", "der", @@ -4688,7 +4719,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" dependencies = [ - "async-channel", + "async-channel 1.9.0", "cfg-if 1.0.0", "futures-core", "pin-project-lite", @@ -4731,9 +4762,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.41" +version = "2.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" dependencies = [ "proc-macro2", "quote", @@ -4775,7 +4806,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.38.28", + "rustix 0.38.30", "windows-sys 0.48.0", ] @@ -4790,22 +4821,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4820,9 +4851,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ "flate2", "jpeg-decoder", @@ -4831,9 +4862,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" dependencies = [ "deranged", "itoa", @@ -4853,9 +4884,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" dependencies = [ "time-core", ] @@ -4877,9 +4908,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.35.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" dependencies = [ "backtrace", "bytes", @@ -4913,7 +4944,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -4993,7 +5024,7 @@ checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" dependencies = [ "async-trait", "axum", - "base64 0.21.5", + "base64 0.21.7", "bytes", "futures-core", "futures-util", @@ -5022,7 +5053,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.5", + "base64 0.21.7", "bytes", "h2", "http", @@ -5031,7 +5062,7 @@ dependencies = [ "hyper-timeout", "percent-encoding", "pin-project", - "prost 0.12.1", + "prost 0.12.3", "tokio", "tokio-stream", "tower", @@ -5086,11 +5117,12 @@ dependencies = [ [[package]] name = "tracing-appender" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09d48f71a791638519505cefafe162606f706c25592e4bde4d97600c0195312e" +checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", + "thiserror", "time", "tracing-subscriber", ] @@ -5103,7 +5135,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -5222,9 +5254,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee8098afad3fb0c54a9007aab6804558410503ad676d4633f9c2559a00ac0f" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" dependencies = [ "serde", "stable_deref_trait", @@ -5278,9 +5310,9 @@ dependencies = [ [[package]] name = "try-lock" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tsify" @@ -5305,7 +5337,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -5341,9 +5373,9 @@ checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" @@ -5390,9 +5422,9 @@ dependencies = [ [[package]] name = "unsafe-libyaml" -version = "0.2.9" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" [[package]] name = "untrusted" @@ -5437,9 +5469,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.4.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" [[package]] name = "vcpkg" @@ -5495,7 +5527,7 @@ dependencies = [ "async-tungstenite", "cfg-if 1.0.0", "chrono", - "clap 4.4.7", + "clap 4.4.18", "config", "crossbeam-channel", "cursive", @@ -5589,6 +5621,7 @@ dependencies = [ "serde_bytes", "serde_json", "serial_test", + "sha2 0.10.8", "shell-words", "simplelog", "socket2 0.5.5", @@ -5667,7 +5700,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a3dabbda02cfe176635dcaa18a021416ff2eb4d0b47a913e3fdc7f62049d7b1" dependencies = [ - "hashbrown 0.14.2", + "hashbrown 0.14.3", "serde", ] @@ -5692,7 +5725,7 @@ dependencies = [ "async-std", "backtrace", "cfg-if 1.0.0", - "clap 4.4.7", + "clap 4.4.18", "color-eyre", "config", "console-subscriber", @@ -5886,15 +5919,15 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -5920,7 +5953,7 @@ checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5933,9 +5966,9 @@ checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" [[package]] name = "wasm-bindgen-test" -version = "0.3.39" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" +checksum = "139bd73305d50e1c1c4333210c0db43d989395b64a237bd35c10ef3832a7f70c" dependencies = [ "console_error_panic_hook", "js-sys", @@ -5947,13 +5980,13 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.39" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" +checksum = "70072aebfe5da66d2716002c729a14e4aec4da0e23cc2ea66323dac541c93928" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] @@ -5975,9 +6008,9 @@ checksum = "323f4da9523e9a669e1eaf9c6e763892769b1d38c623913647bfdc1532fe4549" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" dependencies = [ "js-sys", "wasm-bindgen", @@ -6046,7 +6079,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.28", + "rustix 0.38.30", ] [[package]] @@ -6101,7 +6134,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core", + "windows-core 0.51.1", "windows-targets 0.48.5", ] @@ -6114,6 +6147,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + [[package]] name = "windows-permissions" version = "0.2.4" @@ -6335,9 +6377,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.19" +version = "0.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" dependencies = [ "memchr", ] @@ -6472,29 +6514,29 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.25" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.25" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" dependencies = [ "zeroize_derive", ] @@ -6507,7 +6549,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.41", + "syn 2.0.48", ] [[package]] diff --git a/veilid-core/Cargo.toml b/veilid-core/Cargo.toml index 7bab4989..98b6091d 100644 --- a/veilid-core/Cargo.toml +++ b/veilid-core/Cargo.toml @@ -274,6 +274,8 @@ wasm-logger = "0.2.0" capnpc = "0.18.0" glob = "0.3.1" filetime = "0.2.23" +sha2 = "0.10.8" +hex = "0.4.3" [package.metadata.wasm-pack.profile.release] wasm-opt = ["-O", "--enable-mutable-globals"] diff --git a/veilid-core/build.rs b/veilid-core/build.rs index 590152b5..a4716f1b 100644 --- a/veilid-core/build.rs +++ b/veilid-core/build.rs @@ -1,7 +1,10 @@ -use filetime::{set_file_mtime, FileTime}; use glob::glob; +use sha2::{Digest, Sha256}; +use std::fs::OpenOptions; +use std::io::BufRead; +use std::io::Write; use std::{ - env, fs, io, + env, io, path::Path, process::{Command, Stdio}, }; @@ -29,24 +32,61 @@ fn get_capnp_version_string() -> String { s[20..].to_owned() } -fn is_input_file_outdated(input: P1, output: P2) -> io::Result +fn is_input_file_outdated(input: P, output: Q) -> io::Result where - P1: AsRef, - P2: AsRef, + P: AsRef, + Q: AsRef, { - let out_meta = fs::metadata(output); - if let Ok(meta) = out_meta { - let output_mtime = meta.modified()?; + let Some(out_bh) = get_build_hash(output) else { + // output file not found or no build hash, we are outdated + return Ok(true); + }; - // if input file is more recent than our output, we are outdated - let input_meta = fs::metadata(input)?; - let input_mtime = input_meta.modified()?; + let in_bh = make_build_hash(input); - Ok(input_mtime > output_mtime) - } else { - // output file not found, we are outdated - Ok(true) + Ok(out_bh != in_bh) +} + +fn calculate_hash(lines: std::io::Lines>) -> Vec { + let mut hasher = Sha256::new(); + // Build hash of lines, ignoring EOL conventions + for l in lines { + let l = l.unwrap(); + hasher.update(l.as_bytes()); + hasher.update(b"\n"); } + let out = hasher.finalize(); + out.to_vec() +} + +fn get_build_hash>(output_path: Q) -> Option> { + let lines = std::io::BufReader::new(std::fs::File::open(output_path).ok()?).lines(); + for l in lines { + let l = l.unwrap(); + if l.starts_with("//BUILDHASH:") { + return Some(hex::decode(&l[12..]).unwrap()); + } + } + None +} + +fn make_build_hash>(input_path: P) -> Vec { + let input_path = input_path.as_ref(); + let lines = std::io::BufReader::new(std::fs::File::open(input_path).unwrap()).lines(); + calculate_hash(lines) +} + +fn append_hash, Q: AsRef>(input_path: P, output_path: Q) { + let input_path = input_path.as_ref(); + let output_path = output_path.as_ref(); + let lines = std::io::BufReader::new(std::fs::File::open(input_path).unwrap()).lines(); + let h = calculate_hash(lines); + let mut out_file = OpenOptions::new() + .write(true) + .append(true) + .open(output_path) + .unwrap(); + writeln!(out_file, "\n//BUILDHASH:{}", hex::encode(h)).unwrap(); } fn do_capnp_build() { @@ -86,8 +126,8 @@ fn do_capnp_build() { .run() .expect("compiling schema"); - // If successful, update modification time - set_file_mtime("proto/veilid_capnp.rs", FileTime::now()).unwrap(); + // If successful, append a hash of the input to the output file + append_hash("proto/veilid.capnp", "proto/veilid_capnp.rs"); } // Fix for missing __extenddftf2 on Android x86_64 Emulator @@ -97,11 +137,13 @@ fn fix_android_emulator() { if target_arch == "x86_64" && target_os == "android" { let missing_library = "clang_rt.builtins-x86_64-android"; let android_home = env::var("ANDROID_HOME").expect("ANDROID_HOME not set"); - let lib_path = glob(&format!("{android_home}/ndk/25.1.8937393/**/lib{missing_library}.a")) - .expect("failed to glob") - .next() - .expect("Need libclang_rt.builtins-x86_64-android.a") - .unwrap(); + let lib_path = glob(&format!( + "{android_home}/ndk/25.1.8937393/**/lib{missing_library}.a" + )) + .expect("failed to glob") + .next() + .expect("Need libclang_rt.builtins-x86_64-android.a") + .unwrap(); let lib_dir = lib_path.parent().unwrap(); println!("cargo:rustc-link-search={}", lib_dir.display()); println!("cargo:rustc-link-lib=static={missing_library}"); @@ -117,7 +159,7 @@ fn main() { } if is_input_file_outdated("./proto/veilid.capnp", "./proto/veilid_capnp.rs").unwrap() { - println!("cargo:warning=rebuilding proto/veilid_capnp.rs because it is older than proto/veilid.capnp"); + println!("cargo:warning=rebuilding proto/veilid_capnp.rs because it has changed from the last generation of proto/veilid.capnp"); do_capnp_build(); } diff --git a/veilid-core/proto/veilid_capnp.rs b/veilid-core/proto/veilid_capnp.rs index 55eb4a1d..ec7837ac 100644 --- a/veilid-core/proto/veilid_capnp.rs +++ b/veilid-core/proto/veilid_capnp.rs @@ -7680,7 +7680,7 @@ pub mod node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) } #[inline] - pub fn set_envelope_support(&mut self, value: ::capnp::primitive_list::Reader<'a,u8>) -> ::capnp::Result<()> { + pub fn set_envelope_support(&mut self, value: ::capnp::primitive_list::Reader<'_,u8>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(2), value, false) } #[inline] @@ -7696,7 +7696,7 @@ pub mod node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(3), ::core::option::Option::None) } #[inline] - pub fn set_crypto_support(&mut self, value: ::capnp::primitive_list::Reader<'a,u32>) -> ::capnp::Result<()> { + pub fn set_crypto_support(&mut self, value: ::capnp::primitive_list::Reader<'_,u32>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(3), value, false) } #[inline] @@ -7712,7 +7712,7 @@ pub mod node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(4), ::core::option::Option::None) } #[inline] - pub fn set_capabilities(&mut self, value: ::capnp::primitive_list::Reader<'a,u32>) -> ::capnp::Result<()> { + pub fn set_capabilities(&mut self, value: ::capnp::primitive_list::Reader<'_,u32>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(4), value, false) } #[inline] @@ -7728,7 +7728,7 @@ pub mod node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(5), ::core::option::Option::None) } #[inline] - pub fn set_dial_info_detail_list(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::dial_info_detail::Owned>) -> ::capnp::Result<()> { + pub fn set_dial_info_detail_list(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::dial_info_detail::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(5), value, false) } #[inline] @@ -8096,7 +8096,7 @@ pub mod signed_direct_node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_signatures(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::typed_signature::Owned>) -> ::capnp::Result<()> { + pub fn set_signatures(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::typed_signature::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -8388,7 +8388,7 @@ pub mod signed_relayed_node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_relay_ids(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::typed_key::Owned>) -> ::capnp::Result<()> { + pub fn set_relay_ids(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::typed_key::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -8428,7 +8428,7 @@ pub mod signed_relayed_node_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(3), ::core::option::Option::None) } #[inline] - pub fn set_signatures(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::typed_signature::Owned>) -> ::capnp::Result<()> { + pub fn set_signatures(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::typed_signature::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(3), value, false) } #[inline] @@ -9004,7 +9004,7 @@ pub mod peer_info { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) } #[inline] - pub fn set_node_ids(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::typed_key::Owned>) -> ::capnp::Result<()> { + pub fn set_node_ids(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::typed_key::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) } #[inline] @@ -9277,7 +9277,7 @@ pub mod routed_operation { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) } #[inline] - pub fn set_signatures(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::signature512::Owned>) -> ::capnp::Result<()> { + pub fn set_signatures(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::signature512::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) } #[inline] @@ -10547,7 +10547,7 @@ pub mod operation_find_node_q { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_capabilities(&mut self, value: ::capnp::primitive_list::Reader<'a,u32>) -> ::capnp::Result<()> { + pub fn set_capabilities(&mut self, value: ::capnp::primitive_list::Reader<'_,u32>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -10777,7 +10777,7 @@ pub mod operation_find_node_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) } #[inline] - pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) } #[inline] @@ -12994,7 +12994,7 @@ pub mod operation_get_value_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -13619,7 +13619,7 @@ pub mod operation_set_value_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -13912,7 +13912,7 @@ pub mod operation_watch_value_q { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_subkeys(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::subkey_range::Owned>) -> ::capnp::Result<()> { + pub fn set_subkeys(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::subkey_range::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -14273,7 +14273,7 @@ pub mod operation_watch_value_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) } #[inline] - pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) } #[inline] @@ -14536,7 +14536,7 @@ pub mod operation_value_changed { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_subkeys(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::subkey_range::Owned>) -> ::capnp::Result<()> { + pub fn set_subkeys(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::subkey_range::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -15047,7 +15047,7 @@ pub mod operation_supply_block_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) } #[inline] - pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(0), value, false) } #[inline] @@ -15516,7 +15516,7 @@ pub mod operation_find_block_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) } #[inline] - pub fn set_suppliers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_suppliers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(1), value, false) } #[inline] @@ -15532,7 +15532,7 @@ pub mod operation_find_block_a { ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(2), ::core::option::Option::None) } #[inline] - pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'a,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { + pub fn set_peers(&mut self, value: ::capnp::struct_list::Reader<'_,crate::veilid_capnp::peer_info::Owned>) -> ::capnp::Result<()> { ::capnp::traits::SetPointerBuilder::set_pointer_builder(self.builder.reborrow().get_pointer_field(2), value, false) } #[inline] @@ -21292,3 +21292,5 @@ pub mod operation { pub type WhichBuilder<'a,> = Which<::capnp::Result>,::capnp::Result>,::capnp::Result>>; } } + +//BUILDHASH:ab4fd70d40c9e543f799ce326dd41c61c7ea78132fb53f164156073d9786a9f6 From a092463f7729f3cdec666844f0d9d6b34fcf5e69 Mon Sep 17 00:00:00 2001 From: John Smith Date: Sat, 20 Jan 2024 22:06:15 -0500 Subject: [PATCH 66/67] clean up warnings --- veilid-server/src/settings.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/veilid-server/src/settings.rs b/veilid-server/src/settings.rs index d6772f29..50893cbb 100644 --- a/veilid-server/src/settings.rs +++ b/veilid-server/src/settings.rs @@ -794,11 +794,12 @@ impl Settings { /// `/Users//Library/Application Support/org.Veilid.Veilid` /// pub fn get_default_config_path() -> PathBuf { - let default_path = PathBuf::from("/etc/veilid-server/veilid-server.conf"); - #[cfg(unix)] - if default_path.exists() { - return default_path; + { + let default_path = PathBuf::from("/etc/veilid-server/veilid-server.conf"); + if default_path.exists() { + return default_path; + } } ProjectDirs::from("org", "Veilid", "Veilid") @@ -806,6 +807,7 @@ impl Settings { .unwrap_or_else(|| PathBuf::from("./veilid-server.conf")) } + #[allow(dead_code)] fn get_or_create_private_directory>(path: P, group_read: bool) -> bool { let path = path.as_ref(); if !path.is_dir() @@ -817,6 +819,7 @@ impl Settings { true } + #[allow(dead_code)] fn get_or_create_default_directory(subpath: &str) -> PathBuf { #[cfg(unix)] { From fd4d42c6a2b525b028848d18403f09475b83d69c Mon Sep 17 00:00:00 2001 From: Christien Rioux Date: Sun, 21 Jan 2024 15:50:48 -0500 Subject: [PATCH 67/67] clippy lint --- veilid-core/build.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/veilid-core/build.rs b/veilid-core/build.rs index a4716f1b..acf2e05f 100644 --- a/veilid-core/build.rs +++ b/veilid-core/build.rs @@ -63,8 +63,8 @@ fn get_build_hash>(output_path: Q) -> Option> { let lines = std::io::BufReader::new(std::fs::File::open(output_path).ok()?).lines(); for l in lines { let l = l.unwrap(); - if l.starts_with("//BUILDHASH:") { - return Some(hex::decode(&l[12..]).unwrap()); + if let Some(rest) = l.strip_prefix("//BUILDHASH:") { + return Some(hex::decode(rest).unwrap()); } } None