Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gh 468 #545 - assign country undesirability for newly introduced Nodes from Gossip #549

Open
wants to merge 7 commits into
base: GH-468-545-base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion multinode_integration_tests/tests/data_routing_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ fn multiple_stream_zero_hop_test() {
let mut another_client = zero_hop_node.make_client(8080, STANDARD_CLIENT_TIMEOUT_MILLIS);

one_client.send_chunk(b"GET / HTTP/1.1\r\nHost: www.example.com\r\n\r\n");
another_client.send_chunk(b"GET /online/ HTTP/1.1\r\nHost: whatever.neverssl.com\r\n\r\n");
another_client.send_chunk(b"GET /online/ HTTP/1.1\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\r\nAccept-Language: cs-CZ,cs;q=0.9,en;q=0.8,sk;q=0.7\r\nCache-Control: max-age=0\r\nConnection: keep-alive\r\nHost: whatever.neverssl.com\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36\r\n\r\n");

let one_response = one_client.wait_for_chunk();
let another_response = another_client.wait_for_chunk();
Expand Down
116 changes: 106 additions & 10 deletions node/src/neighborhood/gossip_acceptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::neighborhood::gossip::{GossipBuilder, GossipNodeRecord, Gossip_0v1};
use crate::neighborhood::neighborhood_database::{NeighborhoodDatabase, NeighborhoodDatabaseError};
use crate::neighborhood::node_record::NodeRecord;
use crate::neighborhood::AccessibleGossipRecord;
use crate::neighborhood::{AccessibleGossipRecord, UserExitPreferences};
use crate::sub_lib::cryptde::{CryptDE, PublicKey};
use crate::sub_lib::neighborhood::{
ConnectionProgressEvent, ConnectionProgressMessage, GossipFailure_0v1, NeighborhoodMetadata,
Expand Down Expand Up @@ -130,7 +130,7 @@ impl GossipHandler for DebutHandler {
database: &mut NeighborhoodDatabase,
mut agrs: Vec<AccessibleGossipRecord>,
gossip_source: SocketAddr,
_neighborhood_metadata: NeighborhoodMetadata,
neighborhood_metadata: NeighborhoodMetadata,
) -> GossipAcceptanceResult {
let source_agr = {
let mut agr = agrs.remove(0); // empty Gossip shouldn't get here
Expand Down Expand Up @@ -165,7 +165,13 @@ impl GossipHandler for DebutHandler {
source_node_addr,
);
}
if let Ok(result) = self.try_accept_debut(cryptde, database, &source_agr, gossip_source) {
if let Ok(result) = self.try_accept_debut(
cryptde,
database,
&source_agr,
gossip_source,
neighborhood_metadata.user_exit_preferences_opt,
) {
return result;
}
debug!(self.logger, "Seeking neighbor for Pass");
Expand Down Expand Up @@ -266,13 +272,22 @@ impl DebutHandler {
database: &mut NeighborhoodDatabase,
debuting_agr: &AccessibleGossipRecord,
gossip_source: SocketAddr,
user_exit_preferences_opt: Option<UserExitPreferences>,
) -> Result<GossipAcceptanceResult, ()> {
if database.gossip_target_degree(database.root().public_key()) >= MAX_DEGREE {
debug!(self.logger, "Neighbor count already at maximum");
return Err(());
}
let debut_node_addr_opt = debuting_agr.node_addr_opt.clone();
let debuting_node = NodeRecord::from(debuting_agr);
let mut debuting_node = NodeRecord::from(debuting_agr);
match user_exit_preferences_opt {
Some(user_exit_preferences) => {
user_exit_preferences.assign_nodes_country_undesirability(&mut debuting_node)
}
None => (),
}

// TODO 468 make debuting_node mut and add country_undesirability to its metadata
let debut_node_key = database
.add_node(debuting_node)
.expect("Debuting Node suddenly appeared in database");
Expand Down Expand Up @@ -685,7 +700,13 @@ impl GossipHandler for IntroductionHandler {
.as_ref()
.expect("IP Address not found for the Node Addr.")
.ip_addr();
match self.update_database(database, cryptde, introducer) {
// TODO 468 pass the NeighborhoodMetadata into update_database
match self.update_database(
database,
cryptde,
introducer,
neighborhood_metadata.user_exit_preferences_opt,
) {
Ok(_) => (),
Err(e) => {
return GossipAcceptanceResult::Ban(format!(
Expand Down Expand Up @@ -845,6 +866,7 @@ impl IntroductionHandler {
database: &mut NeighborhoodDatabase,
cryptde: &dyn CryptDE,
introducer: AccessibleGossipRecord,
user_exit_preferences_opt: Option<UserExitPreferences>,
) -> Result<bool, String> {
let introducer_key = introducer.inner.public_key.clone();
match database.node_by_key_mut(&introducer_key) {
Expand All @@ -869,7 +891,14 @@ impl IntroductionHandler {
}
}
None => {
let new_introducer = NodeRecord::from(introducer);
let mut new_introducer = NodeRecord::from(introducer);
//TODO 468 add country undesirability
match user_exit_preferences_opt {
Some(user_exit_preferences) => user_exit_preferences
.assign_nodes_country_undesirability(&mut new_introducer),
None => (),
}
//TODO probably make one function to use on all places
debug!(
self.logger,
"Adding introducer {} to database", introducer_key
Expand Down Expand Up @@ -980,10 +1009,12 @@ impl GossipHandler for StandardGossipHandler {
let patch = self.compute_patch(&agrs, database.root(), neighborhood_metadata.db_patch_size);
let filtered_agrs = self.filter_agrs_by_patch(agrs, patch);

// TODO 468 get structs from neighborhood metadata
let mut db_changed = self.identify_and_add_non_introductory_new_nodes(
database,
&filtered_agrs,
gossip_source,
neighborhood_metadata.user_exit_preferences_opt.as_ref(),
);
db_changed = self.identify_and_update_obsolete_nodes(database, filtered_agrs) || db_changed;
db_changed =
Expand Down Expand Up @@ -1095,6 +1126,7 @@ impl StandardGossipHandler {
database: &mut NeighborhoodDatabase,
agrs: &[AccessibleGossipRecord],
gossip_source: SocketAddr,
user_exit_preferences_opt: Option<&UserExitPreferences>,
) -> bool {
let all_keys = database
.keys()
Expand All @@ -1112,7 +1144,14 @@ impl StandardGossipHandler {
}
})
.for_each(|agr| {
let node_record = NodeRecord::from(agr);
let mut node_record = NodeRecord::from(agr);
// TODO modify for country undesirability in node_record (make it mut)
match user_exit_preferences_opt {
Some(user_exit_preferences) => {
user_exit_preferences.assign_nodes_country_undesirability(&mut node_record)
}
None => (),
}
trace!(
self.logger,
"Discovered new Node {:?}: {:?}",
Expand Down Expand Up @@ -1369,8 +1408,14 @@ mod tests {
use crate::neighborhood::gossip_producer::GossipProducer;
use crate::neighborhood::gossip_producer::GossipProducerReal;
use crate::neighborhood::node_record::NodeRecord;
use crate::neighborhood::{
ExitPreference, UserExitPreferences, COUNTRY_UNDESIRABILITY_FACTOR,
UNREACHABLE_COUNTRY_PENALTY,
};
use crate::sub_lib::cryptde_null::CryptDENull;
use crate::sub_lib::neighborhood::{ConnectionProgressEvent, ConnectionProgressMessage};
use crate::sub_lib::neighborhood::{
ConnectionProgressEvent, ConnectionProgressMessage, ExitLocation,
};
use crate::sub_lib::utils::time_t_timestamp;
use crate::test_utils::neighborhood_test_utils::{
db_from_node, gossip_about_nodes_from_database, linearly_connect_nodes,
Expand Down Expand Up @@ -1407,6 +1452,7 @@ mod tests {
connection_progress_peers: vec![],
cpm_recipient: make_cpm_recipient().0,
db_patch_size: DB_PATCH_SIZE_FOR_TEST,
user_exit_preferences_opt: None,
}
}

Expand Down Expand Up @@ -1677,13 +1723,15 @@ mod tests {
dest_db.add_arbitrary_half_neighbor(root_node.public_key(), half_debuted_node.public_key());
let logger = Logger::new("Debut test");
let subject = DebutHandler::new(logger);
let neighborhood_metadata = make_default_neighborhood_metadata();

let counter_debut = subject
.try_accept_debut(
&root_node_cryptde,
&mut dest_db,
&AccessibleGossipRecord::from(&new_debutant),
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(4, 5, 6, 7)), 4567),
neighborhood_metadata.user_exit_preferences_opt,
)
.unwrap();

Expand Down Expand Up @@ -2020,14 +2068,23 @@ mod tests {
let cryptde = CryptDENull::from(dest_db.root().public_key(), TEST_DEFAULT_CHAIN);
let subject = IntroductionHandler::new(Logger::new("test"));
let agrs: Vec<AccessibleGossipRecord> = gossip.try_into().unwrap();
let mut neighborhood_metadata = make_default_neighborhood_metadata();
neighborhood_metadata.user_exit_preferences_opt = Some(UserExitPreferences {
exit_countries: vec!["FR".to_string()],
exit_location_preference: ExitPreference::ExitCountryNoFallback,
exit_locations_opt: Some(vec![ExitLocation {
country_codes: vec!["FR".to_string()],
priority: 2,
}]),
});

let qualifies_result = subject.qualifies(&dest_db, &agrs, gossip_source);
let handle_result = subject.handle(
&cryptde,
&mut dest_db,
agrs.clone(),
gossip_source,
make_default_neighborhood_metadata(),
neighborhood_metadata,
);

assert_eq!(Qualification::Matched, qualifies_result);
Expand All @@ -2047,6 +2104,7 @@ mod tests {
dest_db.node_by_key_mut(&agrs[0].inner.public_key).unwrap();
let mut expected_introducer = NodeRecord::from(&agrs[0]);
expected_introducer.metadata.last_update = result_introducer.metadata.last_update;
expected_introducer.metadata.country_undesirability = COUNTRY_UNDESIRABILITY_FACTOR;
expected_introducer.resign();
assert_eq!(result_introducer, &expected_introducer);
assert_eq!(
Expand Down Expand Up @@ -2407,6 +2465,14 @@ mod tests {
let gossip_source: SocketAddr = src_root.node_addr_opt().unwrap().into();
let (cpm_recipient, recording_arc) = make_cpm_recipient();
let mut neighborhood_metadata = make_default_neighborhood_metadata();
neighborhood_metadata.user_exit_preferences_opt = Some(UserExitPreferences {
exit_countries: vec!["FR".to_string()],
exit_location_preference: ExitPreference::ExitCountryWithFallback,
exit_locations_opt: Some(vec![ExitLocation {
country_codes: vec!["FR".to_string()],
priority: 1,
}]),
});
neighborhood_metadata.cpm_recipient = cpm_recipient;
let system = System::new("test");

Expand All @@ -2419,6 +2485,22 @@ mod tests {
neighborhood_metadata,
);

assert_eq!(
dest_db
.node_by_key(node_a.public_key())
.unwrap()
.metadata
.country_undesirability,
0u32
);
assert_eq!(
dest_db
.node_by_key(node_b.public_key())
.unwrap()
.metadata
.country_undesirability,
UNREACHABLE_COUNTRY_PENALTY
);
assert_eq!(Qualification::Matched, qualifies_result);
assert_eq!(GossipAcceptanceResult::Accepted, handle_result);
assert_eq!(
Expand Down Expand Up @@ -2979,12 +3061,21 @@ mod tests {
let (gossip, mut debut_node, gossip_source) = make_debut(2345, Mode::Standard);
let subject = make_subject(&root_node_cryptde);
let before = time_t_timestamp();
let mut neighborhood_metadata = make_default_neighborhood_metadata();
neighborhood_metadata.user_exit_preferences_opt = Some(UserExitPreferences {
exit_countries: vec!["CZ".to_string()],
exit_location_preference: ExitPreference::ExitCountryWithFallback,
exit_locations_opt: Some(vec![ExitLocation {
country_codes: vec!["CZ".to_string()],
priority: 1,
}]),
});

let result = subject.handle(
&mut dest_db,
gossip.try_into().unwrap(),
gossip_source,
make_default_neighborhood_metadata(),
neighborhood_metadata,
);

let after = time_t_timestamp();
Expand Down Expand Up @@ -3034,6 +3125,11 @@ Length: 24 (0x18) bytes
let reference_node = dest_db.node_by_key_mut(debut_node.public_key()).unwrap();
debut_node.metadata.last_update = reference_node.metadata.last_update;
debut_node.resign();
assert_eq!(
reference_node.metadata.country_undesirability,
UNREACHABLE_COUNTRY_PENALTY
);
reference_node.metadata.country_undesirability = 0u32;
assert_node_records_eq(reference_node, &debut_node, before, after);
}

Expand Down
Loading
Loading