@@ -82,6 +82,11 @@ pub const DEFAULT_MIN_HOPS: Hops = Hops::ThreeHops;
8282pub const UNREACHABLE_HOST_PENALTY : i64 = 100_000_000 ;
8383pub const RESPONSE_UNDESIRABILITY_FACTOR : usize = 1_000 ; // assumed response length is request * this
8484
85+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
86+ pub struct ExitLocationsRoutes < ' a > {
87+ routes : Vec < ( Vec < & ' a PublicKey > , i64 ) >
88+ }
89+
8590pub struct Neighborhood {
8691 cryptde : & ' static dyn CryptDE ,
8792 hopper_opt : Option < Recipient < IncipientCoresPackage > > ,
@@ -1262,12 +1267,14 @@ impl Neighborhood {
12621267 return_route_id
12631268 }
12641269
1270+
1271+
12651272 pub fn find_exit_location < ' a > (
12661273 & ' a self ,
12671274 source : & ' a PublicKey ,
12681275 minimum_hops : usize ,
12691276 payload_size : usize ,
1270- ) -> Vec < & PublicKey > { // HashMap<& PublicKey, Vec<>> { // Vec<(i64, Vec<&PublicKey>)
1277+ ) -> HashMap < PublicKey , ExitLocationsRoutes > {
12711278 let mut minimum_undesirability = i64:: MAX ;
12721279 let initial_undesirability =
12731280 self . compute_initial_undesirability ( source, payload_size as u64 , RouteDirection :: Over ) ;
@@ -1284,19 +1291,23 @@ impl Neighborhood {
12841291 true
12851292 ) ;
12861293
1287- let routes_exit = over_routes. into_iter ( ) . map ( |segment| {
1288- segment. nodes [ segment. nodes . len ( ) -1 ]
1289- } ) . collect ( ) ;
1290-
1291- // let mut result = HashMap::from(over_routes.into_iter().map(|segment| {
1292- // (segment.nodes[segment.nodes.len()-1], ) // vec![(segment.undesirability,segment.nodes)]
1293- // }).collect::<Vec<(&PublicKey, Vec<(i64, Vec<&PublicKey>)>)>>());
1294-
1295-
1296-
1297-
1298- routes_exit
1299- // result
1294+ let mut result_exit: HashMap < PublicKey , ExitLocationsRoutes > = HashMap :: new ( ) ;
1295+
1296+ over_routes. into_iter ( ) . for_each ( |segment| {
1297+ let exit_node = segment. nodes [ segment. nodes . len ( ) -1 ] ;
1298+ result_exit
1299+ . entry ( exit_node. clone ( ) )
1300+ . and_modify ( |e|
1301+ e. routes . push ( ( segment. nodes . clone ( ) , segment. undesirability ) ) )
1302+ . or_insert ( ExitLocationsRoutes {
1303+ routes : vec ! [ (
1304+ segment. nodes. clone( ) ,
1305+ segment. undesirability)
1306+ ]
1307+ }
1308+ ) ;
1309+ } ) ;
1310+ result_exit
13001311 }
13011312
13021313 // Interface to main routing engine. Supply source key, target key--if any--in target_opt,
@@ -1581,28 +1592,24 @@ impl Neighborhood {
15811592 let db = & self . neighborhood_database . clone ( ) ;
15821593 let db_keys = db. keys ( ) ;
15831594 let root_node = db. root ( ) . public_key ( ) ;
1584-
1585- let route = self . find_best_route_segment ( root_node, None , 3 , 10000 , RouteDirection :: Over , None ) ;
1586-
1587- eprintln ! ( "route: {:#?}" , route) ;
1588-
1589-
1590-
1591-
1595+ let exit_locations = self . find_exit_location (
1596+ root_node,
1597+ self . min_hops as usize ,
1598+ 10_000
1599+ ) ;
15921600
15931601 for db_key in db_keys {
15941602 let node_record = db. node_by_key ( db_key) . expect ( "Failed to get node record" ) ;
15951603 if root_node != & node_record. inner . public_key {
15961604 response. insert ( node_record. inner . public_key . to_string ( ) , NodeInfo {
15971605 version : node_record. inner . version ,
15981606 country_code_opt : node_record. inner . country_code_opt . clone ( ) ,
1599- exit_service : node_record. inner . accepts_connections ,
1607+ exit_service : exit_locations . contains_key ( & node_record. inner . public_key ) ,
16001608 unreachable_hosts : node_record. metadata . unreachable_hosts . clone ( ) . into_iter ( ) . collect ( ) ,
16011609 } ) ;
16021610 }
16031611 }
16041612
1605-
16061613 let response_inner = UiCollectNeighborhoodInfoResponse {
16071614 neighborhood_database : response
16081615 } ;
@@ -1723,6 +1730,7 @@ enum UndesirabilityType<'hostname> {
17231730 ExitAndRouteResponse ,
17241731}
17251732
1733+ #[ derive( Debug ) ]
17261734struct ComputedRouteSegment < ' a > {
17271735 pub nodes : Vec < & ' a PublicKey > ,
17281736 pub undesirability : i64 ,
@@ -1817,6 +1825,7 @@ mod tests {
18171825 use masq_lib:: test_utils:: logging:: { init_test_logging, TestLogHandler } ;
18181826 use masq_lib:: ui_gateway:: MessageTarget :: ClientId ;
18191827
1828+
18201829 impl Handler < AssertionsMessage < Neighborhood > > for Neighborhood {
18211830 type Result = ( ) ;
18221831
@@ -3324,7 +3333,7 @@ mod tests {
33243333
33253334 All these Nodes are standard-mode. L is the root Node.
33263335 */
3327-
3336+ // TODO: Add some non-standard nodes (consume only)
33283337 #[ test]
33293338 fn find_exit_location_test ( ) {
33303339 let mut subject = make_standard_subject ( ) ;
@@ -3373,24 +3382,45 @@ mod tests {
33733382 join_rows ( db, ( & k, & l, & m, & n, & o) , ( & p, & q, & r, & s, & t) ) ;
33743383 join_rows ( db, ( & p, & q, & r, & s, & t) , ( & u, & v, & w, & x, & y) ) ;
33753384 designate_root_node ( db, & l) ;
3376- let before = Instant :: now ( ) ;
3377-
3385+ // let before = Instant::now();
33783386 let db_clone = db. clone ( ) ;
33793387 let routes = subject. find_exit_location ( & l, 3 , 10_000 ) ;
33803388
3389+ let total_exit_nodes = routes. len ( ) ;
3390+ assert_eq ! ( total_exit_nodes, 14 ) ;
33813391
3382- // let node_key = key.clone();
3383- // let country_code = db_clone.node_by_key(&node_key).unwrap().inner.country_code_opt.clone();
3384- // eprintln!("Key: {}, country_code: {:?}", key, country_code);
3392+ // TODO: change pubkey to the let name instead of from...
33853393
3386- let result_vec: Vec < ( & PublicKey , String ) > = routes. into_iter ( ) . map ( |key| {
3387- let country_code = db_clone. node_by_key ( & key. clone ( ) ) . unwrap ( ) . inner . country_code_opt . clone ( ) . unwrap ( ) ;
3388- ( key, country_code)
3389- } ) . collect ( ) ;
3394+ let n_node_record = routes. get ( & n) . unwrap ( ) ;
3395+ let expected_route_1_public_key_1 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 1 ] ) ;
3396+ let expected_route_1_public_key_2 = PublicKey :: from ( vec ! [ 1 , 0 , 0 , 6 ] ) ;
3397+ let expected_route_1_public_key_3 = PublicKey :: from ( vec ! [ 1 , 0 , 0 , 7 ] ) ;
3398+ let expected_route_1_public_key_4 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 2 ] ) ;
3399+ let expected_route_1_public_key_5 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 3 ] ) ;
3400+ let expected_route_2_public_key_1 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 1 ] ) ;
3401+ let expected_route_2_public_key_2 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 6 ] ) ;
3402+ let expected_route_2_public_key_3 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 7 ] ) ;
3403+ let expected_route_2_public_key_4 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 2 ] ) ;
3404+ let expected_route_2_public_key_5 = PublicKey :: from ( vec ! [ 1 , 0 , 1 , 3 ] ) ;
33903405
3391- let hash_result: HashMap < & PublicKey , String > = result_vec. into_iter ( ) . collect ( ) ;
33923406
3393- eprintln ! ( "hash_result: {:#?}" , hash_result) ;
3407+ let expected_route_1 = ( vec ! [
3408+ & expected_route_1_public_key_1,
3409+ & expected_route_1_public_key_2,
3410+ & expected_route_1_public_key_3,
3411+ & expected_route_1_public_key_4,
3412+ & expected_route_1_public_key_5,
3413+ ] , 40_465_238i64 ) ;
3414+ let expected_route_2 = ( vec ! [
3415+ & expected_route_2_public_key_1,
3416+ & expected_route_2_public_key_2,
3417+ & expected_route_2_public_key_3,
3418+ & expected_route_2_public_key_4,
3419+ & expected_route_2_public_key_5,
3420+ ] , 40_665_258i64 ) ;
3421+
3422+ assert ! ( n_node_record. routes. contains( & expected_route_1) ) ;
3423+ assert ! ( n_node_record. routes. contains( & expected_route_2) ) ;
33943424
33953425 }
33963426
@@ -6008,7 +6038,6 @@ mod tests {
60086038 . set_past_neighbors_params ( & set_past_neighbors_params_arc)
60096039 . set_past_neighbors_result ( Ok ( ( ) ) ) ;
60106040 subject. persistent_config_opt = Some ( Box :: new ( persistent_config) ) ;
6011-
60126041 let p = & subject. neighborhood_database . root ( ) . clone ( ) ;
60136042 let q = & make_node_record ( 3456 , true ) ;
60146043 let r = & make_node_record ( 4567 , false ) ;
@@ -6018,8 +6047,6 @@ mod tests {
60186047 let b = & make_node_record ( 2222 , false ) ; // half
60196048 let c = & make_node_record ( 3333 , false ) ;
60206049 let d = & make_node_record ( 4444 , false ) ;
6021-
6022-
60236050 let db = & mut subject. neighborhood_database ;
60246051 db. add_node ( q. clone ( ) ) . unwrap ( ) ;
60256052 db. add_node ( t. clone ( ) ) . unwrap ( ) ;
@@ -6029,39 +6056,13 @@ mod tests {
60296056 db. add_node ( b. clone ( ) ) . unwrap ( ) ;
60306057 db. add_node ( c. clone ( ) ) . unwrap ( ) ;
60316058 db. add_node ( d. clone ( ) ) . unwrap ( ) ;
6032-
6033- println ! ( "p: {} q: {} r: {} s: {} t: {} a: {} b: {} c: {} d: {}" ,
6034- p. public_key( ) ,
6035- q. public_key( ) ,
6036- r. public_key( ) ,
6037- s. public_key( ) ,
6038- t. public_key( ) ,
6039- a. public_key( ) ,
6040- b. public_key( ) ,
6041- c. public_key( ) ,
6042- d. public_key( ) ,
6043- ) ;
6044- println ! ( "{:#?}" , db) ;
6045-
6046- // p: 5LD+wfgUUBbKEolBJiZXvxR3VpAVpjansF96JuYn1mw
6047- // q: AwQFBg
6048- // r: BAUGBw
6049- // s: BQYHCA
6050- // t: BwcHBw
6051- // a: AQEBAQ
6052- // b: AgICAg
6053- // c: AwMDAw
6054- // d: BAQEBA
6055- // digraph db { "5LD+wfgUUBbKEolBJiZXvxR3VpAVpjansF96JuYn1mw" [label="AR v0\n5LD+wfgU\n9.9.9.9:9999"] [style=filled]; "AwMDAw" [label="AR v0\nAwMDAw"]; "BQYHCA" [label="AR v0\nBQYHCA"]; "BwcHBw" [label="AR v0\nBwcHBw"]; "BAQEBA" [label="AR v0\nBAQEBA"]; "BAUGBw" [label="AR v0\nBAUGBw"]; "AQEBAQ" [label="AR v0\nAQEBAQ"]; "AwQFBg" [label="AR v0\nAwQFBg\n3.4.5.6:3456"]; "AgICAg" [label="AR v0\nAgICAg"]; }
6056-
60576059 let mut edge = |a : & NodeRecord , b : & NodeRecord , c : bool | {
60586060 if c {
60596061 db. add_arbitrary_full_neighbor ( a. public_key ( ) , b. public_key ( ) ) ;
60606062 } else {
60616063 db. add_arbitrary_half_neighbor ( a. public_key ( ) , b. public_key ( ) ) ;
60626064 }
60636065 } ;
6064-
60656066 edge ( p, q, true ) ;
60666067 edge ( q, t, true ) ;
60676068 edge ( q, r, true ) ;
@@ -6071,9 +6072,6 @@ mod tests {
60716072 edge ( p, r, true ) ;
60726073 edge ( p, a, false ) ;
60736074 edge ( r, b, false ) ;
6074-
6075- println ! ( "{:#?}" , db) ;
6076-
60776075 let ( ui_gateway, _, ui_gateway_recording_arc) = make_recorder ( ) ;
60786076 let subject_addr = subject. start ( ) ;
60796077 let peer_actors = peer_actors_builder ( ) . ui_gateway ( ui_gateway) . build ( ) ;
@@ -6096,18 +6094,16 @@ mod tests {
60966094 let message_opt = ui_gateway_recording
60976095 . get_record_opt :: < NodeToUiMessage > ( 0 )
60986096 . cloned ( ) ;
6099-
61006097 let mut expected_response: HashMap < String , NodeInfo > = HashMap :: new ( ) ;
6101- // expected_response.insert("B+TPRn12lX9mt7Zvs/8gfx+rd1ko4xyjy4DRSEdoKKA".to_string(), NodeInfo{ version:0,country_code_opt:Some("CH".to_string()),exit_service:true, unreachable_hosts:vec![]});
6102- expected_response. insert ( "BAUGBw" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "US" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6098+ // TODO: Add db record of version & unreachable_hosts
6099+ expected_response. insert ( "BAUGBw" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "US" . to_string ( ) ) , exit_service : false , unreachable_hosts : vec ! [ ] } ) ;
61036100 expected_response. insert ( "BAQEBA" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "AU" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
61046101 expected_response. insert ( "AwMDAw" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "AU" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6105- expected_response. insert ( "AwQFBg" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "FR" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6102+ expected_response. insert ( "AwQFBg" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "FR" . to_string ( ) ) , exit_service : false , unreachable_hosts : vec ! [ ] } ) ;
61066103 expected_response. insert ( "BQYHCA" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "FR" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6107- expected_response. insert ( "AQEBAQ" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "US" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6104+ expected_response. insert ( "AQEBAQ" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "US" . to_string ( ) ) , exit_service : false , unreachable_hosts : vec ! [ ] } ) ;
61086105 expected_response. insert ( "BwcHBw" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "US" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6109- expected_response. insert ( "AgICAg" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "FR" . to_string ( ) ) , exit_service : true , unreachable_hosts : vec ! [ ] } ) ;
6110-
6106+ expected_response. insert ( "AgICAg" . to_string ( ) , NodeInfo { version : 0 , country_code_opt : Some ( "FR" . to_string ( ) ) , exit_service : false , unreachable_hosts : vec ! [ ] } ) ;
61116107 let ( message_to, _) : ( UiCollectNeighborhoodInfoResponse , u64 ) = FromMessageBody :: fmb ( message_opt. unwrap ( ) . body ) . unwrap ( ) ;
61126108 let response_inner = UiCollectNeighborhoodInfoResponse {
61136109 neighborhood_database : expected_response
0 commit comments