diff --git a/doc/config/sample.config b/doc/config/sample.config index 1b169390..f4693374 100644 --- a/doc/config/sample.config +++ b/doc/config/sample.config @@ -63,7 +63,7 @@ core: max_timestamp_behind_ms: 10000 max_timestamp_ahead_ms: 10000 timeout_ms: 10000 - max_route_hop_count: 7 + max_route_hop_count: 5 default_route_hop_count: 2 dht: diff --git a/doc/config/veilid-server-config.md b/doc/config/veilid-server-config.md index 210b52b4..b7968693 100644 --- a/doc/config/veilid-server-config.md +++ b/doc/config/veilid-server-config.md @@ -228,7 +228,7 @@ rpc: max_timestamp_behind_ms: 10000 max_timestamp_ahead_ms: 10000 timeout_ms: 10000 - max_route_hop_count: 7 + max_route_hop_count: 4 default_route_hop_count: 2 ``` diff --git a/veilid-core/src/routing_table/find_nodes.rs b/veilid-core/src/routing_table/find_nodes.rs index 0e304d91..952c4b14 100644 --- a/veilid-core/src/routing_table/find_nodes.rs +++ b/veilid-core/src/routing_table/find_nodes.rs @@ -218,17 +218,36 @@ impl RoutingTable { ) -> core::cmp::Ordering, T: FnMut(&'a RoutingTableInner, DHTKey, Option>) -> O, { - let inner = self.inner.read(); - let inner = &*inner; - let self_node_id = self.unlocked_inner.node_id; + let inner = &*self.inner.read(); + Self::find_peers_with_sort_and_filter_inner( + inner, node_count, cur_ts, filter, compare, transform, + ) + } + pub fn find_peers_with_sort_and_filter_inner<'a, 'b, F, C, T, O>( + inner: &RoutingTableInner, + node_count: usize, + cur_ts: u64, + mut filter: F, + compare: C, + mut transform: T, + ) -> Vec + where + F: FnMut(&'a RoutingTableInner, DHTKey, Option>) -> bool, + C: FnMut( + &'a RoutingTableInner, + &'b (DHTKey, Option>), + &'b (DHTKey, Option>), + ) -> core::cmp::Ordering, + T: FnMut(&'a RoutingTableInner, DHTKey, Option>) -> O, + { // collect all the nodes for sorting let mut nodes = Vec::<(DHTKey, Option>)>::with_capacity(inner.bucket_entry_count + 1); // add our own node (only one of there with the None entry) - if filter(inner, self_node_id, None) { - nodes.push((self_node_id, None)); + if filter(inner, inner.node_id, None) { + nodes.push((inner.node_id, None)); } // add all nodes from buckets diff --git a/veilid-core/src/routing_table/mod.rs b/veilid-core/src/routing_table/mod.rs index ab6fcc09..2bccb4fb 100644 --- a/veilid-core/src/routing_table/mod.rs +++ b/veilid-core/src/routing_table/mod.rs @@ -219,18 +219,18 @@ impl RoutingTable { pub fn with_route_spec_store_mut(&self, f: F) -> R where - F: FnOnce(&mut RouteSpecStore) -> R, + F: FnOnce(&mut RouteSpecStore, &mut RoutingTableInner) -> R, { - let inner = self.inner.write(); - f(&mut inner.route_spec_store) + let inner = &mut *self.inner.write(); + f(&mut inner.route_spec_store, inner) } pub fn with_route_spec_store(&self, f: F) -> R where - F: FnOnce(&RouteSpecStore) -> R, + F: FnOnce(&RouteSpecStore, &RoutingTableInner) -> R, { - let inner = self.inner.read(); - f(&inner.route_spec_store) + let inner = &*self.inner.read(); + f(&inner.route_spec_store, inner) } pub fn relay_node(&self, domain: RoutingDomain) -> Option { @@ -339,6 +339,30 @@ impl RoutingTable { true } + #[instrument(level = "trace", skip(inner), ret)] + fn get_contact_method_inner( + inner: &RoutingTableInner, + routing_domain: RoutingDomain, + node_a_id: &DHTKey, + node_a: &NodeInfo, + node_b_id: &DHTKey, + node_b: &NodeInfo, + dial_info_filter: DialInfoFilter, + reliable: bool, + ) -> ContactMethod { + Self::with_routing_domain(inner, routing_domain, |rdd| { + rdd.get_contact_method( + inner, + node_a_id, + node_a, + node_b_id, + node_b, + dial_info_filter, + reliable, + ) + }) + } + /// Look up the best way for two nodes to reach each other over a specific routing domain #[instrument(level = "trace", skip(self), ret)] pub fn get_contact_method( @@ -352,17 +376,16 @@ impl RoutingTable { reliable: bool, ) -> ContactMethod { let inner = &*self.inner.read(); - Self::with_routing_domain(inner, routing_domain, |rdd| { - rdd.get_contact_method( - inner, - node_a_id, - node_a, - node_b_id, - node_b, - dial_info_filter, - reliable, - ) - }) + Self::get_contact_method_inner( + inner, + routing_domain, + node_a_id, + node_a, + node_b_id, + node_b, + dial_info_filter, + reliable, + ) } // Figure out how to reach a node from our own node over the best routing domain and reference the nodes we want to access @@ -384,11 +407,11 @@ impl RoutingTable { }; // Node A is our own node - let node_a = self.get_own_node_info(routing_domain); + let node_a = get_own_node_info_inner(inner, routing_domain); let node_a_id = self.node_id(); // Node B is the target node - let node_b = target_node_ref.operate(|_rti, e| e.node_info(routing_domain).unwrap()); + let node_b = target_node_ref.xxx operate(|_rti, e| e.node_info(routing_domain).unwrap()); let node_b_id = target_node_ref.node_id(); // Dial info filter comes from the target node ref @@ -411,8 +434,7 @@ impl RoutingTable { ContactMethod::Existing => NodeContactMethod::Existing, ContactMethod::Direct(di) => NodeContactMethod::Direct(di), ContactMethod::SignalReverse(relay_key, target_key) => { - let relay_nr = self - .lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter) + let relay_nr = Self::lookup_and_filter_noderef_inner(inner, self.clone(), relay_key, routing_domain.into(), dial_info_filter) .ok_or_else(|| eyre!("couldn't look up relay"))?; if target_node_ref.node_id() != target_key { bail!("target noderef didn't match target key"); @@ -420,8 +442,7 @@ impl RoutingTable { NodeContactMethod::SignalReverse(relay_nr, target_node_ref) } ContactMethod::SignalHolePunch(relay_key, target_key) => { - let relay_nr = self - .lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter) + let relay_nr = Self::lookup_and_filter_noderef_inner(inner, self.clone(), relay_key, routing_domain.into(), dial_info_filter) .ok_or_else(|| eyre!("couldn't look up relay"))?; if target_node_ref.node_id() != target_key { bail!("target noderef didn't match target key"); @@ -429,14 +450,12 @@ impl RoutingTable { NodeContactMethod::SignalHolePunch(relay_nr, target_node_ref) } ContactMethod::InboundRelay(relay_key) => { - let relay_nr = self - .lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter) + let relay_nr = Self::lookup_and_filter_noderef_nner(inner, self.clone(), relay_key, routing_domain.into(), dial_info_filter) .ok_or_else(|| eyre!("couldn't look up relay"))?; NodeContactMethod::InboundRelay(relay_nr) } ContactMethod::OutboundRelay(relay_key) => { - let relay_nr = self - .lookup_and_filter_noderef(relay_key, routing_domain.into(), dial_info_filter) + let relay_nr = Self::lookup_and_filter_noderef(inner, self.clone(), relay_key, routing_domain.into(), dial_info_filter) .ok_or_else(|| eyre!("couldn't look up relay"))?; NodeContactMethod::OutboundRelay(relay_nr) } @@ -486,13 +505,19 @@ impl RoutingTable { } /// Return a copy of our node's nodeinfo - pub fn get_own_node_info(&self, routing_domain: RoutingDomain) -> NodeInfo { - let inner = &*self.inner.read(); + fn get_own_node_info_inner( + inner: &RoutingTableInner, + routing_domain: RoutingDomain, + ) -> NodeInfo { Self::with_routing_domain(inner, routing_domain, |rdd| { rdd.common() .with_peer_info(|pi| pi.signed_node_info.node_info.clone()) }) } + pub fn get_own_node_info(&self, routing_domain: RoutingDomain) -> NodeInfo { + let inner = &*self.inner.read(); + Self::get_own_node_info_inner(inner, routing_domain) + } /// Return our currently registered network class pub fn has_valid_own_node_info(&self, routing_domain: RoutingDomain) -> bool { @@ -880,6 +905,15 @@ impl RoutingTable { } /// Resolve an existing routing table entry and return a reference to it + fn lookup_node_ref_inner(inner: &RoutingTableInner, routing_table: RoutingTable, node_id: DHTKey) -> Option { + { + let idx = routing_table.find_bucket_index(node_id); + let bucket = &inner.buckets[idx]; + bucket + .entry(&node_id) + .map(|e| NodeRef::new(routing_table, node_id, e, None)) + } + pub fn lookup_node_ref(&self, node_id: DHTKey) -> Option { if node_id == self.unlocked_inner.node_id { log_rtab!(debug "can't look up own node id in routing table"); diff --git a/veilid-core/src/routing_table/route_spec_store.rs b/veilid-core/src/routing_table/route_spec_store.rs index a7b0d80e..8228acb9 100644 --- a/veilid-core/src/routing_table/route_spec_store.rs +++ b/veilid-core/src/routing_table/route_spec_store.rs @@ -5,6 +5,8 @@ use serde::*; /// Options for safety routes (sender privacy) #[derive(Copy, Clone, Debug, Serialize, Deserialize)] pub struct SafetySpec { + /// preferred safety route if it still exists + pub preferred_route: Option, /// 0 = no safety route, just use node's node id, more hops is safer but slower pub hop_count: usize, /// prefer more reliable protocols and relays over faster ones @@ -76,6 +78,10 @@ pub struct RouteSpecStoreCache { #[derive(Debug)] pub struct RouteSpecStore { + /// Our node id + node_id: DHTKey, + /// Our node id secret + node_id_secret: DHTKeySecret, /// Maximum number of hops in a route max_route_hop_count: usize, /// Default number of hops in a route @@ -83,7 +89,7 @@ pub struct RouteSpecStore { /// Serialize RouteSpecStore content content: RouteSpecStoreContent, /// RouteSpecStore cache - cache: Mutex, + cache: RouteSpecStoreCache, } fn route_hops_to_hop_cache(hops: &[DHTKey]) -> Vec { @@ -170,16 +176,13 @@ where impl RouteSpecStore { pub fn new(config: VeilidConfig) -> Self { - let (max_route_hop_count, default_route_hop_count) = { - let c = config.get(); - let max_route_hop_count = c.network.rpc.max_route_hop_count; - let default_route_hop_count = c.network.rpc.max_route_hop_count; - (max_route_hop_count.into(), default_route_hop_count.into()) - }; + let c = config.get(); Self { - max_route_hop_count, - default_route_hop_count, + node_id: c.network.node_id, + node_id_secret: c.network.node_id_secret, + max_route_hop_count: c.network.rpc.max_route_hop_count.into(), + default_route_hop_count: c.network.rpc.default_route_hop_count.into(), content: RouteSpecStoreContent { details: HashMap::new(), }, @@ -188,20 +191,17 @@ impl RouteSpecStore { } pub async fn load(routing_table: RoutingTable) -> EyreResult { - let (max_route_hop_count, default_route_hop_count) = { - let c = routing_table.unlocked_inner.config.get(); - let max_route_hop_count = c.network.rpc.max_route_hop_count; - let default_route_hop_count = c.network.rpc.max_route_hop_count; - (max_route_hop_count.into(), default_route_hop_count.into()) - }; - + let config = routing_table.network_manager().config(); + let c = config.get(); // Get cbor blob from table store let table_store = routing_table.network_manager().table_store(); let rsstdb = table_store.open("RouteSpecStore", 1).await?; let content = rsstdb.load_cbor(0, b"content").await?.unwrap_or_default(); let mut rss = RouteSpecStore { - max_route_hop_count, - default_route_hop_count, + node_id: c.network.node_id, + node_id_secret: c.network.node_id_secret, + max_route_hop_count: c.network.rpc.max_route_hop_count.into(), + default_route_hop_count: c.network.rpc.default_route_hop_count.into(), content, cache: Default::default(), }; @@ -284,17 +284,17 @@ impl RouteSpecStore { } } - fn detail_mut(&mut self, public_key: &DHTKey) -> &mut RouteSpecDetail { - self.content.details.get_mut(&public_key).unwrap() + fn detail_mut(&mut self, public_key: &DHTKey) -> Option<&mut RouteSpecDetail> { + self.content.details.get_mut(&public_key) } /// Create a new route /// Prefers nodes that are not currently in use by another route /// The route is not yet tested for its reachability /// Returns None if no route could be allocated at this time - pub async fn allocate_route( + pub fn allocate_route( &mut self, - routing_table: RoutingTable, + rti: &RoutingTableInner, reliable: bool, hop_count: usize, directions: DirectionSet, @@ -309,10 +309,6 @@ impl RouteSpecStore { bail!("Not allocating route longer than max route hop count"); } - // Lock routing table for reading, make sure things don't change - // because we want to iterate the table without changes being made to it - let rti = routing_table.inner.read(); - // Get list of all nodes, and sort them for selection let cur_ts = intf::get_timestamp(); let dial_info_sort = if reliable { @@ -417,12 +413,20 @@ impl RouteSpecStore { }; // Pull the whole routing table in sorted order - let node_count = routing_table.get_entry_count( + let node_count = RoutingTable::get_entry_count_inner( + rti, RoutingDomain::PublicInternet.into(), BucketEntryState::Unreliable, ); - let nodes = routing_table - .find_peers_with_sort_and_filter(node_count, cur_ts, filter, compare, transform); + let nodes = RoutingTable::find_peers_with_sort_and_filter_inner( + rti, + self.node_id, + node_count, + cur_ts, + filter, + compare, + transform, + ); // If we couldn't find enough nodes, wait until we have more nodes in the routing table if nodes.len() < hop_count { @@ -447,13 +451,14 @@ impl RouteSpecStore { // Ensure this route is viable by checking that each node can contact the next one if directions.contains(Direction::Outbound) { let our_node_info = - routing_table.get_own_node_info(RoutingDomain::PublicInternet); - let our_node_id = routing_table.node_id(); + RoutingTable::get_own_node_info_inner(rti, RoutingDomain::PublicInternet); + let our_node_id = self.node_id; let mut previous_node = &(our_node_id, our_node_info); let mut reachable = true; for n in permutation { let current_node = nodes.get(*n).unwrap(); - let cm = routing_table.get_contact_method( + let cm = RoutingTable::get_contact_method_inner( + rti, RoutingDomain::PublicInternet, &previous_node.0, &previous_node.1, @@ -474,13 +479,14 @@ impl RouteSpecStore { } if directions.contains(Direction::Inbound) { let our_node_info = - routing_table.get_own_node_info(RoutingDomain::PublicInternet); - let our_node_id = routing_table.node_id(); + RoutingTable::get_own_node_info_inner(rti, RoutingDomain::PublicInternet); + let our_node_id = self.node_id; let mut next_node = &(our_node_id, our_node_info); let mut reachable = true; for n in permutation.iter().rev() { let current_node = nodes.get(*n).unwrap(); - let cm = routing_table.get_contact_method( + let cm = RoutingTable::get_contact_method_inner( + rti, RoutingDomain::PublicInternet, &next_node.0, &next_node.1, @@ -608,20 +614,53 @@ impl RouteSpecStore { /// Compiles a safety route to the private route, with caching pub fn compile_safety_route( - &self, + &mut self, + rti: &RoutingTableInner, safety_spec: SafetySpec, private_route: PrivateRoute, ) -> Result { + let pr_hopcount = private_route.hop_count as usize; + if pr_hopcount > self.max_route_hop_count { + return Err(RPCError::internal("private route hop count too long")); + } + + // See if the preferred route is here + let opt_safety_rsd: Option<&mut RouteSpecDetail> = + if let Some(preferred_route) = safety_spec.preferred_route { + self.detail_mut(&preferred_route) + } else { + // Preferred safety route was not requested + None + }; + let safety_rsd: &mut RouteSpecDetail = if let Some(safety_rsd) = opt_safety_rsd { + // Safety route exists + safety_rsd + } else { + // Select a safety route from the pool or make one if we don't have one that matches + if let Some(sr_pubkey) = self.first_unpublished_route( + safety_spec.reliable, + safety_spec.hop_count, + safety_spec.hop_count, + Direction::Outbound.into(), + ) { + // Found a route to use + self.detail_mut(&sr_pubkey).unwrap() + } else { + // No route found, gotta allocate one + self.allocate_route(rti) + } + }; + // xxx implement caching first! + // xxx implement, ensure we handle hops == 0 for our safetyspec // Ensure the total hop count isn't too long for our config - let pr_hopcount = private_route.hop_count as usize; - let sr_hopcount = safety_route_spec.hops.len(); - let hopcount = 1 + sr_hopcount + pr_hopcount; - if hopcount > self.max_route_hop_count { - return Err(RPCError::internal("hop count too long for route")); + let sr_hopcount = safety_spec.hop_count; + if sr_hopcount > self.max_route_hop_count { + return Err(RPCError::internal("private route hop count too long")); } + let total_hopcount = sr_hopcount + pr_hopcount; // Create hops let hops = if sr_hopcount == 0 { @@ -719,41 +758,66 @@ impl RouteSpecStore { /// Mark route as published /// When first deserialized, routes must be re-published in order to ensure they remain /// in the RouteSpecStore. - pub fn mark_route_published(&mut self, key: &DHTKey) { - self.detail_mut(&key).published = true; + pub fn mark_route_published(&mut self, key: &DHTKey) -> EyreResult<()> { + self.detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .published = true; + Ok(()) } /// Mark route as checked - pub fn touch_route_checked(&mut self, key: &DHTKey, cur_ts: u64) { - self.detail_mut(&key).last_checked_ts = Some(cur_ts); + pub fn touch_route_checked(&mut self, key: &DHTKey, cur_ts: u64) -> EyreResult<()> { + self.detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .last_checked_ts = Some(cur_ts); + Ok(()) } /// Mark route as used - pub fn touch_route_used(&mut self, key: &DHTKey, cur_ts: u64) { - self.detail_mut(&key).last_used_ts = Some(cur_ts); + pub fn touch_route_used(&mut self, key: &DHTKey, cur_ts: u64) -> EyreResult<()> { + self.detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .last_used_ts = Some(cur_ts); + Ok(()) } /// Record latency on the route - pub fn record_latency(&mut self, key: &DHTKey, latency: u64) { - let lsa = &mut self.detail_mut(&key).latency_stats_accounting; + pub fn record_latency(&mut self, key: &DHTKey, latency: u64) -> EyreResult<()> { + let lsa = &mut self + .detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .latency_stats_accounting; self.detail_mut(&key).latency_stats = lsa.record_latency(latency); + Ok(()) } /// Get the calculated latency stats - pub fn latency_stats(&self, key: &DHTKey) -> LatencyStats { - self.detail_mut(&key).latency_stats.clone() + pub fn latency_stats(&mut self, key: &DHTKey) -> EyreResult { + Ok(self + .detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .latency_stats + .clone()) } /// Add download transfers to route - pub fn add_down(&mut self, key: &DHTKey, bytes: u64) { - let tsa = &mut self.detail_mut(&key).transfer_stats_accounting; + pub fn add_down(&mut self, key: &DHTKey, bytes: u64) -> EyreResult<()> { + let tsa = &mut self + .detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .transfer_stats_accounting; tsa.add_down(bytes); + Ok(()) } /// Add upload transfers to route - pub fn add_up(&mut self, key: &DHTKey, bytes: u64) { - let tsa = &mut self.detail_mut(&key).transfer_stats_accounting; + pub fn add_up(&mut self, key: &DHTKey, bytes: u64) -> EyreResult<()> { + let tsa = &mut self + .detail_mut(&key) + .ok_or_else(|| eyre!("route does not exist"))? + .transfer_stats_accounting; tsa.add_up(bytes); + Ok(()) } /// Process transfer statistics to get averages diff --git a/veilid-core/src/rpc_processor/destination.rs b/veilid-core/src/rpc_processor/destination.rs index 872bebd2..76d86990 100644 --- a/veilid-core/src/rpc_processor/destination.rs +++ b/veilid-core/src/rpc_processor/destination.rs @@ -8,8 +8,7 @@ pub enum Destination { /// The node to send to target: NodeRef, /// Require safety route or not - xxx convert back to safety spec, bubble up to api - safety: bool, + safety: Option, }, /// Send to node for relay purposes Relay { @@ -18,14 +17,14 @@ pub enum Destination { /// The final destination the relay should send to target: DHTKey, /// Require safety route or not - safety: bool, + safety: Option, }, /// Send to private route (privateroute) PrivateRoute { /// A private route to send to private_route: PrivateRoute, /// Require safety route or not - safety: bool, + safety: Option, /// Prefer reliability or not reliable: bool, }, @@ -35,29 +34,29 @@ impl Destination { pub fn direct(target: NodeRef) -> Self { Self::Direct { target, - safety: false, + safety: None, } } pub fn relay(relay: NodeRef, target: DHTKey) -> Self { Self::Relay { relay, target, - safety: false, + safety: None, } } pub fn private_route(private_route: PrivateRoute, reliable: bool) -> Self { Self::PrivateRoute { private_route, - safety: false, + safety: None, reliable, } } - pub fn with_safety(self) -> Self { + pub fn with_safety(self, spec: SafetySpec) -> Self { match self { Destination::Direct { target, safety: _ } => Self::Direct { target, - safety: true, + safety: Some(spec), }, Destination::Relay { relay, @@ -66,7 +65,7 @@ impl Destination { } => Self::Relay { relay, target, - safety: true, + safety: Some(spec), }, Destination::PrivateRoute { private_route, @@ -74,7 +73,7 @@ impl Destination { reliable, } => Self::PrivateRoute { private_route, - safety: true, + safety: Some(spec), reliable, }, } @@ -85,7 +84,7 @@ impl fmt::Display for Destination { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Destination::Direct { target, safety } => { - let sr = if *safety { "+SR" } else { "" }; + let sr = if safety.is_some() { "+SR" } else { "" }; write!(f, "{}{}", target, sr) } @@ -94,7 +93,7 @@ impl fmt::Display for Destination { target, safety, } => { - let sr = if *safety { "+SR" } else { "" }; + let sr = if safety.is_some() { "+SR" } else { "" }; write!(f, "{}@{}{}", target.encode(), relay, sr) } @@ -103,7 +102,7 @@ impl fmt::Display for Destination { safety, reliable, } => { - let sr = if *safety { "+SR" } else { "" }; + let sr = if safety.is_some() { "+SR" } else { "" }; let rl = if *reliable { "+RL" } else { "" }; write!(f, "{}{}{}", private_route, sr, rl) diff --git a/veilid-core/src/rpc_processor/mod.rs b/veilid-core/src/rpc_processor/mod.rs index e8f8a221..dab096a6 100644 --- a/veilid-core/src/rpc_processor/mod.rs +++ b/veilid-core/src/rpc_processor/mod.rs @@ -409,13 +409,6 @@ impl RPCProcessor { rss.compile_safety_route(safety_spec, private_route) })?; - // Verify hop count isn't larger than out maximum routed hop count - if compiled_route.safety_route.hop_count as usize > self.unlocked_inner.max_route_hop_count - { - return Err(RPCError::internal("hop count too long for route")) - .map_err(logthru_rpc!(warn)); - } - // Encrypt routed operation // Xmsg + ENC(Xmsg, DH(PKapr, SKbsr)) let nonce = Crypto::get_random_nonce(); @@ -613,17 +606,6 @@ impl RPCProcessor { hop_count, } = self.render_operation(dest, &operation)?; - // If we need to resolve the first hop, do it - let node_ref = match node_ref { - None => match self.resolve_node(node_id).await? { - None => { - return Ok(NetworkResult::no_connection_other(node_id)); - } - Some(nr) => nr, - }, - Some(nr) => nr, - }; - // Calculate answer timeout // Timeout is number of hops times the timeout per hop let timeout = self.unlocked_inner.timeout * (hop_count as u64); @@ -687,17 +669,6 @@ impl RPCProcessor { hop_count: _, } = self.render_operation(dest, &operation)?; - // If we need to resolve the first hop, do it - let node_ref = match node_ref { - None => match self.resolve_node(node_id).await? { - None => { - return Ok(NetworkResult::no_connection_other(node_id)); - } - Some(nr) => nr, - }, - Some(nr) => nr, - }; - // Send statement let bytes = message.len() as u64; let send_ts = intf::get_timestamp(); @@ -782,17 +753,6 @@ impl RPCProcessor { hop_count: _, } = self.render_operation(dest, &operation)?; - // If we need to resolve the first hop, do it - let node_ref = match node_ref { - None => match self.resolve_node(node_id).await? { - None => { - return Ok(NetworkResult::no_connection_other(node_id)); - } - Some(nr) => nr, - }, - Some(nr) => nr, - }; - // Send the reply let bytes = message.len() as u64; let send_ts = intf::get_timestamp(); diff --git a/veilid-core/src/veilid_config.rs b/veilid-core/src/veilid_config.rs index ca576b5f..9fdb88a8 100644 --- a/veilid-core/src/veilid_config.rs +++ b/veilid-core/src/veilid_config.rs @@ -641,9 +641,9 @@ impl VeilidConfig { "max route hop count must be >= 1 in 'network.rpc.max_route_hop_count'" ); } - if inner.network.rpc.max_route_hop_count > 7 { + if inner.network.rpc.max_route_hop_count > 5 { apibail_generic!( - "max route hop count must be <= 7 in 'network.rpc.max_route_hop_count'" + "max route hop count must be <= 5 in 'network.rpc.max_route_hop_count'" ); } if inner.network.rpc.default_route_hop_count == 0 { diff --git a/veilid-flutter/example/lib/config.dart b/veilid-flutter/example/lib/config.dart index 3f224264..9eb209c3 100644 --- a/veilid-flutter/example/lib/config.dart +++ b/veilid-flutter/example/lib/config.dart @@ -65,7 +65,7 @@ Future getDefaultVeilidConfig() async { maxTimestampBehindMs: 10000, maxTimestampAheadMs: 10000, timeoutMs: 10000, - maxRouteHopCount: 7, + maxRouteHopCount: 4, defaultRouteHopCount: 2, ), dht: VeilidConfigDHT( diff --git a/veilid-wasm/tests/web.rs b/veilid-wasm/tests/web.rs index 299f9acf..230f0609 100644 --- a/veilid-wasm/tests/web.rs +++ b/veilid-wasm/tests/web.rs @@ -45,7 +45,7 @@ fn init_callbacks() { case "network.rpc.max_timestamp_behind": return 10000000; case "network.rpc.max_timestamp_ahead": return 10000000; case "network.rpc.timeout": return 10000000; - case "network.rpc.max_route_hop_count": return 7; + case "network.rpc.max_route_hop_count": return 4; case "network.rpc.default_route_hop_count": return 2; case "network.dht.resolve_node_timeout": return null; case "network.dht.resolve_node_count": return 20;