diff --git a/crates/lox-distributor/src/lox_context.rs b/crates/lox-distributor/src/lox_context.rs index 4a4732be19b27d5183bae1eef115f1879d1cd7c7..4c2b87ee3c9aeb8b233c3cb6815168042c360689 100644 --- a/crates/lox-distributor/src/lox_context.rs +++ b/crates/lox-distributor/src/lox_context.rs @@ -838,7 +838,7 @@ impl LoxServerContext { // Verify multiple negative reports, return count of verified reports // Note: This should be called on reports with the same (bridge, country, date) pub fn verify_negative_reports(self, request: Bytes) -> Response<Body> { - let mut reports: BTreeMap<String, u32> = match serde_json::from_slice(&request) { + let mut reports: Vec<SerializableNegativeReport> = match serde_json::from_slice(&request) { Ok(req) => req, Err(e) => { let response = json!({"error": e.to_string()}); @@ -847,29 +847,14 @@ impl LoxServerContext { } }; let mut count: u32 = 0; - while let Some((serializable_report, num_reports)) = reports.pop_first() { - let val = { - match NegativeReport::from_json(serializable_report) { - Ok(report) => { - let fingerprint = array_bytes::bytes2hex("", &report.fingerprint); - if self.verify_negative_report(report) { - println!( - "Report with fingerprint {} passed verification", - fingerprint - ); - 1 - } else { - println!( - "Report with fingerprint {} failed verification", - fingerprint - ); - 0 - } - } - Err(_) => 0, + while let Some(serializable_report) = reports.pop() { + let report = serializable_report.to_report(); + if report.is_ok() { + let report = report.unwrap(); + if self.verify_negative_report(report) { + count += 1; } - }; - count += val * num_reports; + } } prepare_header(count.to_string()) } diff --git a/crates/lox-distributor/src/troll_patrol_handler.rs b/crates/lox-distributor/src/troll_patrol_handler.rs index d082fe00d84bca6bb06da40487bf56a358823046..e4fb7624b66679aec03e28405935760d3e9a9f8c 100644 --- a/crates/lox-distributor/src/troll_patrol_handler.rs +++ b/crates/lox-distributor/src/troll_patrol_handler.rs @@ -62,7 +62,10 @@ mod tests { }; use troll_patrol::{ bridge_verification_info::BridgeVerificationInfo, - negative_report::{HashOfBridgeLine, HashOfBucket, NegativeReport, ProofOfBridgeKnowledge}, + negative_report::{ + HashOfBridgeLine, HashOfBucket, NegativeReport, ProofOfBridgeKnowledge, + SerializableNegativeReport, + }, positive_report::{PositiveReport, SerializablePositiveReport}, BridgeDistributor, }; @@ -72,7 +75,7 @@ mod tests { trait TpClient { fn reportblocked(&self, blocked_bridges: HashMap<String, HashSet<String>>) -> Request<Body>; - fn verifynegative(&self, reports: BTreeMap<String, u32>) -> Request<Body>; + fn verifynegative(&self, reports: Vec<SerializableNegativeReport>) -> Request<Body>; fn verifypositive(&self, reports: Vec<SerializablePositiveReport>) -> Request<Body>; } @@ -91,7 +94,7 @@ mod tests { .unwrap() } - fn verifynegative(&self, reports: BTreeMap<String, u32>) -> Request<Body> { + fn verifynegative(&self, reports: Vec<SerializableNegativeReport>) -> Request<Body> { let req = serde_json::to_string(&reports).unwrap(); Request::builder() .method("POST") @@ -364,55 +367,41 @@ mod tests { let bridges = get_bucket(&mut th, &cred).await; - // Create random number of negative reports for each bridge in bucket - let mut rng = rand::thread_rng(); - let num_report_1 = rng.next_u32() % 4 + 1; - let num_report_2 = rng.next_u32() % 4 + 1; - let num_report_3 = rng.next_u32() % 4 + 1; - let mut reports = BTreeMap::<String, u32>::new(); + // Create negative report for each bridge in bucket + let mut reports = Vec::<SerializableNegativeReport>::new(); let date = th.context.ba.lock().unwrap().today(); let report_1 = NegativeReport::from_bridgeline(bridges[0], "ru".to_string(), BridgeDistributor::Lox); - reports.insert(report_1.to_json(), num_report_1); + reports.push(report_1.to_serializable_report()); let report_2 = NegativeReport::from_lox_bucket(bridges[1].fingerprint, cred.bucket, "ru".to_string()); - reports.insert(report_2.to_json(), num_report_2); + reports.push(report_2.to_serializable_report()); let report_3 = - NegativeReport::from_lox_credential(bridges[2].fingerprint, cred, "ru".to_string()); - reports.insert(report_3.to_json(), num_report_3); + NegativeReport::from_lox_credential(bridges[2].fingerprint, &cred, "ru".to_string()); + reports.push(report_3.to_serializable_report()); // Check that reports with invalid fields are not counted - let num_invalid_report_1 = rng.next_u32() % 4 + 1; - let num_invalid_report_2 = rng.next_u32() % 4 + 1; + + let mut rng = rand::thread_rng(); // Date in the future let mut invalid_report_1 = NegativeReport::from_bridgeline(bridges[0], "ru".to_string(), BridgeDistributor::Lox) .to_serializable_report(); invalid_report_1.date = invalid_report_1.date + 2; - reports.insert( - serde_json::to_string(&invalid_report_1).unwrap(), - num_invalid_report_1, - ); + reports.push(invalid_report_1); // Invalid country code let invalid_report_2 = NegativeReport::from_bridgeline(bridges[1], "xx".to_string(), BridgeDistributor::Lox) .to_serializable_report(); - reports.insert( - serde_json::to_string(&invalid_report_2).unwrap(), - num_invalid_report_2, - ); + reports.push(invalid_report_2); // Check that well-formed reports with incorrect bridge data are not counted - let num_invalid_report_3 = rng.next_u32() % 4 + 1; - let num_invalid_report_4 = rng.next_u32() % 4 + 1; - let num_invalid_report_5 = rng.next_u32() % 4 + 1; - let mut hasher = Sha1::new(); hasher.update([0; 20]); let empty_bridgeline_fingerprint: [u8; 20] = hasher.finalize().into(); @@ -421,33 +410,40 @@ mod tests { let mut invalid_report_3 = NegativeReport::from_bridgeline(bridges[2], "ru".to_string(), BridgeDistributor::Lox); invalid_report_3.fingerprint = empty_bridgeline_fingerprint; - reports.insert(invalid_report_3.to_json(), num_invalid_report_3); + reports.push(invalid_report_3.to_serializable_report()); // Incorrect BridgeLine hash + let mut nonce = [0; 32]; + rng.fill_bytes(&mut nonce); let invalid_report_4 = NegativeReport::new( bridges[0].fingerprint, ProofOfBridgeKnowledge::HashOfBridgeLine(HashOfBridgeLine::new( &BridgeLine::default(), date, + nonce, )), "ru".to_string(), date, + nonce, BridgeDistributor::Lox, ); - reports.insert(invalid_report_4.to_json(), num_invalid_report_4); + reports.push(invalid_report_4.to_serializable_report()); // Incorrect bucket hash + let mut nonce = [0; 32]; + rng.fill_bytes(&mut nonce); let invalid_report_5 = NegativeReport::new( bridges[1].fingerprint, - ProofOfBridgeKnowledge::HashOfBucket(HashOfBucket::new(&Scalar::ZERO, date)), + ProofOfBridgeKnowledge::HashOfBucket(HashOfBucket::new(&Scalar::ZERO, date, nonce)), "ru".to_string(), date, + nonce, BridgeDistributor::Lox, ); - reports.insert(invalid_report_5.to_json(), num_invalid_report_5); + reports.push(invalid_report_5.to_serializable_report()); - // Ensure each negative report is distinct and added successfully - assert_eq!(reports.keys().len(), 8); + // Ensure each negative report is added successfully + assert_eq!(reports.len(), 8); let request = tpc.verifynegative(reports); let response = handle(th.context.clone(), &mut Htables, request) @@ -455,7 +451,7 @@ mod tests { .unwrap(); assert_eq!(response.status(), StatusCode::OK); let count: u32 = body_to_string(response).await.parse().unwrap(); - assert_eq!(num_report_1 + num_report_2 + num_report_3, count); + assert_eq!(3, count); } #[tokio::test]