This commit is contained in:
John Smith 2023-03-11 15:23:50 +00:00
parent 0d614c61a2
commit e52b5f60cd
5 changed files with 39 additions and 26 deletions

View File

@ -556,6 +556,10 @@ impl<'a> NodeRefLockedMut<'a> {
nr, nr,
} }
} }
pub fn unlocked(&self) -> NodeRef {
self.nr.clone()
}
} }
impl<'a> NodeRefBase for NodeRefLockedMut<'a> { impl<'a> NodeRefBase for NodeRefLockedMut<'a> {

View File

@ -124,11 +124,11 @@ impl RouteSetSpecDetail {
} }
/// Generate a key for the cache that can be used to uniquely identify this route's contents /// Generate a key for the cache that can be used to uniquely identify this route's contents
pub fn make_cache_key(&self) -> Vec<u8> { pub fn make_cache_key(&self, rti: &RoutingTableInner) -> Vec<u8> {
let hops = &self.hop_node_refs; let hops = &self.hop_node_refs;
let mut cache: Vec<u8> = Vec::with_capacity(hops.len() * PUBLIC_KEY_LENGTH); let mut cache: Vec<u8> = Vec::with_capacity(hops.len() * PUBLIC_KEY_LENGTH);
for hop in hops { for hop in hops {
cache.extend_from_slice(&hop.best_node_id().value.bytes); cache.extend_from_slice(&hop.locked(rti).best_node_id().value.bytes);
} }
cache cache
} }

View File

@ -72,8 +72,9 @@ impl RouteSpecStore {
}; };
// Rebuild the routespecstore cache // Rebuild the routespecstore cache
let rti = &*routing_table.inner.read();
for (_, rssd) in inner.content.iter_details() { for (_, rssd) in inner.content.iter_details() {
inner.cache.add_to_cache(&rssd); inner.cache.add_to_cache(rti, &rssd);
} }
// Return the loaded RouteSpecStore // Return the loaded RouteSpecStore
@ -81,7 +82,7 @@ impl RouteSpecStore {
unlocked_inner: Arc::new(RouteSpecStoreUnlockedInner { unlocked_inner: Arc::new(RouteSpecStoreUnlockedInner {
max_route_hop_count, max_route_hop_count,
default_route_hop_count, default_route_hop_count,
routing_table, routing_table: routing_table.clone(),
}), }),
inner: Arc::new(Mutex::new(inner)), inner: Arc::new(Mutex::new(inner)),
}; };
@ -338,8 +339,8 @@ impl RouteSpecStore {
}; };
// Pull the whole routing table in sorted order // Pull the whole routing table in sorted order
let nodes:Vec<NodeRefLocked> = let nodes:Vec<NodeRef> =
rti.find_peers_with_sort_and_filter(usize::MAX, cur_ts, filters, compare, transform).iter().map(|n| n.locked(rti)).collect(); rti.find_peers_with_sort_and_filter(usize::MAX, cur_ts, filters, compare, transform);
// If we couldn't find enough nodes, wait until we have more nodes in the routing table // If we couldn't find enough nodes, wait until we have more nodes in the routing table
if nodes.len() < hop_count { if nodes.len() < hop_count {
@ -348,20 +349,20 @@ impl RouteSpecStore {
} }
// Get peer info for everything // Get peer info for everything
let nodes_pi: Vec<PeerInfo> = nodes.iter().map(|nr| nr.make_peer_info(RoutingDomain::PublicInternet).unwrap()).collect(); let nodes_pi: Vec<PeerInfo> = nodes.iter().map(|nr| nr.locked(rti).make_peer_info(RoutingDomain::PublicInternet).unwrap()).collect();
// Now go through nodes and try to build a route we haven't seen yet // Now go through nodes and try to build a route we haven't seen yet
let mut perm_func = Box::new(|permutation: &[usize]| { let mut perm_func = Box::new(|permutation: &[usize]| {
/// Get the hop cache key for a particular route permutation // Get the hop cache key for a particular route permutation
/// uses the same algorithm as RouteSetSpecDetail::make_cache_key // uses the same algorithm as RouteSetSpecDetail::make_cache_key
fn route_permutation_to_hop_cache(_rti: &RoutingTableInner, nodes: &[NodeRefLocked], perm: &[usize]) -> Vec<u8> { let route_permutation_to_hop_cache = |_rti: &RoutingTableInner, nodes: &[NodeRef], perm: &[usize]| -> Vec<u8> {
let mut cache: Vec<u8> = Vec::with_capacity(perm.len() * PUBLIC_KEY_LENGTH); let mut cache: Vec<u8> = Vec::with_capacity(perm.len() * PUBLIC_KEY_LENGTH);
for n in perm { for n in perm {
cache.extend_from_slice(&nodes[*n].best_node_id().value.bytes) cache.extend_from_slice(&nodes[*n].locked(rti).best_node_id().value.bytes)
} }
cache cache
} };
let cache_key = route_permutation_to_hop_cache(rti, &nodes, permutation); let cache_key = route_permutation_to_hop_cache(rti, &nodes, permutation);
// Skip routes we have already seen // Skip routes we have already seen
@ -373,12 +374,12 @@ impl RouteSpecStore {
let mut seen_nodes: HashSet<TypedKey> = HashSet::new(); let mut seen_nodes: HashSet<TypedKey> = HashSet::new();
for n in permutation { for n in permutation {
let node = nodes.get(*n).unwrap(); let node = nodes.get(*n).unwrap();
if !seen_nodes.insert(node.best_node_id()) { if !seen_nodes.insert(node.locked(rti).best_node_id()) {
// Already seen this node, should not be in the route twice // Already seen this node, should not be in the route twice
return None; return None;
} }
if let Some(relay) = node.relay(RoutingDomain::PublicInternet).map(|n| n.locked(rti)) { if let Some(relay) = node.locked_mut(rti).relay(RoutingDomain::PublicInternet) {
let relay_id = relay.best_node_id(); let relay_id = relay.locked(rti).best_node_id();
if !seen_nodes.insert(relay_id) { if !seen_nodes.insert(relay_id) {
// Already seen this node, should not be in the route twice // Already seen this node, should not be in the route twice
return None; return None;
@ -482,16 +483,18 @@ impl RouteSpecStore {
return Ok(None); return Ok(None);
} }
drop(perm_func);
// Got a unique route, lets build the details, register it, and return it // Got a unique route, lets build the details, register it, and return it
let hop_node_refs:Vec<NodeRef> = route_nodes let hop_node_refs:Vec<NodeRef> = route_nodes
.iter() .iter()
.map(|k| nodes[*k].unlocked()) .map(|k| nodes[*k].clone())
.collect(); .collect();
let mut route_set = BTreeMap::<PublicKey, RouteSpecDetail>::new(); let mut route_set = BTreeMap::<PublicKey, RouteSpecDetail>::new();
for crypto_kind in crypto_kinds.iter().copied() { for crypto_kind in crypto_kinds.iter().copied() {
let vcrypto = self.unlocked_inner.routing_table.crypto().get(crypto_kind).unwrap(); let vcrypto = self.unlocked_inner.routing_table.crypto().get(crypto_kind).unwrap();
let keypair = vcrypto.generate_keypair(); let keypair = vcrypto.generate_keypair();
let hops: Vec<PublicKey> = route_nodes.iter().map(|v| nodes[*v].node_ids().get(crypto_kind).unwrap().value).collect(); let hops: Vec<PublicKey> = route_nodes.iter().map(|v| nodes[*v].locked(rti).node_ids().get(crypto_kind).unwrap().value).collect();
route_set.insert(keypair.key, RouteSpecDetail { route_set.insert(keypair.key, RouteSpecDetail {
crypto_kind, crypto_kind,
@ -509,13 +512,12 @@ impl RouteSpecStore {
can_do_sequenced, can_do_sequenced,
); );
drop(perm_func);
// make id // make id
let id = self.generate_allocated_route_id(&rssd)?; let id = self.generate_allocated_route_id(&rssd)?;
// Add to cache // Add to cache
inner.cache.add_to_cache(&rssd); inner.cache.add_to_cache(rti, &rssd);
// Keep route in spec store // Keep route in spec store
inner.content.add_detail(id.clone(), rssd); inner.content.add_detail(id.clone(), rssd);
@ -686,7 +688,8 @@ impl RouteSpecStore {
}; };
// Remove from hop cache // Remove from hop cache
if !inner.cache.remove_from_cache(id, &rssd) { let rti = &*self.unlocked_inner.routing_table.inner.read();
if !inner.cache.remove_from_cache(rti, id, &rssd) {
panic!("hop cache should have contained cache key"); panic!("hop cache should have contained cache key");
} }

View File

@ -41,8 +41,8 @@ pub struct RouteSpecStoreCache {
impl RouteSpecStoreCache { impl RouteSpecStoreCache {
/// add an allocated route set to our cache via its cache key /// add an allocated route set to our cache via its cache key
pub fn add_to_cache(&mut self, rssd: &RouteSetSpecDetail) { pub fn add_to_cache(&mut self, rti: &RoutingTableInner, rssd: &RouteSetSpecDetail) {
let cache_key = rssd.make_cache_key(); let cache_key = rssd.make_cache_key(rti);
if !self.hop_cache.insert(cache_key) { if !self.hop_cache.insert(cache_key) {
panic!("route should never be inserted twice"); panic!("route should never be inserted twice");
} }
@ -66,8 +66,13 @@ impl RouteSpecStoreCache {
} }
/// removes an allocated route set from our cache /// removes an allocated route set from our cache
pub fn remove_from_cache(&mut self, id: RouteId, rssd: &RouteSetSpecDetail) -> bool { pub fn remove_from_cache(
let cache_key = rssd.make_cache_key(); &mut self,
rti: &RoutingTableInner,
id: RouteId,
rssd: &RouteSetSpecDetail,
) -> bool {
let cache_key = rssd.make_cache_key(rti);
// Remove from hop cache // Remove from hop cache
if !self.hop_cache.remove(&cache_key) { if !self.hop_cache.remove(&cache_key) {

View File

@ -156,6 +156,7 @@ impl RPCProcessor {
// Look up the private route and ensure it's one in our spec store // Look up the private route and ensure it's one in our spec store
// Ensure the route is validated, and construct a return safetyspec that matches the inbound preferences // Ensure the route is validated, and construct a return safetyspec that matches the inbound preferences
let rss = self.routing_table.route_spec_store(); let rss = self.routing_table.route_spec_store();
let preferred_route = rss.get_route_id_for_key(&pr_pubkey.value);
let Some((secret_key, safety_spec)) = rss let Some((secret_key, safety_spec)) = rss
.with_signature_validated_route( .with_signature_validated_route(
&pr_pubkey, &pr_pubkey,
@ -166,7 +167,7 @@ impl RPCProcessor {
( (
rsd.secret_key, rsd.secret_key,
SafetySpec { SafetySpec {
preferred_route: rss.get_route_id_for_key(&pr_pubkey.value), preferred_route,
hop_count: rssd.hop_count(), hop_count: rssd.hop_count(),
stability: rssd.get_stability(), stability: rssd.get_stability(),
sequencing: routed_operation.sequencing, sequencing: routed_operation.sequencing,