Browse Source

Change Hides to Secrecy, have censor submit all false reports at end

If the censor submits a report each time it blocks a connection, this number may exceed the number of Lox credentials the censor can actually use to submit these reports. This is an issue if we restrict these reports to one per credential.
Vecna 5 months ago
parent
commit
498d6b4cee
5 changed files with 65 additions and 41 deletions
  1. 2 2
      src/bin/simulation.rs
  2. 2 2
      src/simulation/bridge.rs
  3. 43 4
      src/simulation/censor.rs
  4. 1 1
      src/simulation/config.rs
  5. 17 32
      src/simulation/user.rs

+ 2 - 2
src/bin/simulation.rs

@@ -44,7 +44,7 @@ pub struct Config {
     pub la_test_port: u16,
     pub tp_port: u16,
     pub tp_test_port: u16,
-    pub censor_hides: censor::Hides,
+    pub censor_secrecy: censor::Secrecy,
     pub censor_speed: censor::Speed,
     pub censor_event_duration: u32,
     pub censor_totality: censor::Totality,
@@ -96,7 +96,7 @@ pub async fn main() {
         la_pubkeys,
         la_net,
         tp_net,
-        censor_hides: config.censor_hides,
+        censor_secrecy: config.censor_secrecy,
         censor_speed: config.censor_speed,
         censor_event_duration: config.censor_event_duration,
         censor_totality: config.censor_totality,

+ 2 - 2
src/simulation/bridge.rs

@@ -26,8 +26,8 @@ pub struct Bridge {
     // bridge (for identifying stage three)
     pub first_positive_report: u32,
 
-    real_connections: u32,
-    total_connections: u32,
+    pub real_connections: u32,
+    pub total_connections: u32,
 }
 
 impl Bridge {

+ 43 - 4
src/simulation/censor.rs

@@ -8,7 +8,10 @@ use lox_cli::{get_lox_pub, networking::Networking};
 use lox_library::{cred::Lox, scalar_u32};
 use rand::Rng;
 use serde::Deserialize;
-use std::collections::{HashMap, HashSet};
+use std::{
+    cmp::min,
+    collections::{HashMap, HashSet},
+};
 
 pub struct Censor {
     pub known_bridges: HashSet<[u8; 20]>,
@@ -127,7 +130,7 @@ impl Censor {
     // Make a bunch of connections and submit positive reports if possible
     async fn flood(&self, config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>) {
         // Only do this if Flooding censor
-        if config.censor_hides == Hides::Flooding {
+        if config.censor_secrecy == Secrecy::Flooding {
             for fingerprint in &self.known_bridges {
                 // Only do this if we're blocking the bridge
                 if config.censor_speed == Speed::Fast
@@ -161,6 +164,38 @@ impl Censor {
         }
     }
 
+    // Send one positive report per connection we blocked
+    async fn send_positive_reports(
+        &self,
+        config: &Config,
+        bridges: &mut HashMap<[u8; 20], Bridge>,
+    ) {
+        // Only do this if Hiding censor. Flooding censors should use
+        // flood() instead.
+        if config.censor_secrecy == Secrecy::Hiding {
+            for fingerprint in &self.known_bridges {
+                // Only do this if we're blocking the bridge
+                if self.blocks_bridge(config, fingerprint) && self.has_lox_cred(fingerprint) {
+                    let bridge = bridges.get_mut(fingerprint).unwrap();
+
+                    // We may be restricted to one positive report per
+                    // credential
+                    let num_reports_to_send = if config.one_positive_report_per_cred {
+                        min(
+                            bridge.total_connections - bridge.real_connections,
+                            self.lox_credentials.get(fingerprint).unwrap().1,
+                        )
+                    } else {
+                        bridge.total_connections - bridge.real_connections
+                    };
+                    for _ in 0..num_reports_to_send {
+                        self.send_positive_report(config, fingerprint).await;
+                    }
+                }
+            }
+        }
+    }
+
     fn recompute_delay(&mut self, config: &Config) {
         // Only do this if Random censor
         if config.censor_speed == Speed::Random
@@ -180,10 +215,14 @@ impl Censor {
         config: &Config,
         bridges: &mut HashMap<[u8; 20], Bridge>,
     ) {
-        if config.censor_hides == Hides::Flooding
+        if config.censor_secrecy == Secrecy::Flooding
             && !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
         {
             self.flood(config, bridges).await;
+        } else if config.censor_secrecy == Secrecy::Hiding
+            && !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
+        {
+            self.send_positive_reports(config, bridges).await;
         }
 
         self.recompute_delay(config);
@@ -198,7 +237,7 @@ pub enum Speed {
 }
 
 #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
-pub enum Hides {
+pub enum Secrecy {
     Overt,
     Hiding,
     Flooding,

+ 1 - 1
src/simulation/config.rs

@@ -8,7 +8,7 @@ pub struct Config {
     pub la_net: HyperNet,
     pub tp_net: HyperNet,
     // Define censor behavior
-    pub censor_hides: censor::Hides,
+    pub censor_secrecy: censor::Secrecy,
     pub censor_speed: censor::Speed,
     pub censor_event_duration: u32,
     pub censor_totality: censor::Totality,

+ 17 - 32
src/simulation/user.rs

@@ -6,7 +6,7 @@ use crate::{
     positive_report::PositiveReport,
     simulation::{
         bridge::Bridge,
-        censor::{Censor, Hides::*, Totality::*},
+        censor::{Censor, Secrecy::*, Totality::*},
         config::Config,
     },
     BridgeDistributor,
@@ -157,7 +157,7 @@ impl User {
     // Note that this does not involve making a real connection to a
     // real bridge. The function is async because the *censor* might
     // submit a positive report during this function.
-    pub async fn connect(&self, config: &Config, bridge: &mut Bridge, censor: &Censor) -> bool {
+    pub fn connect(&self, config: &Config, bridge: &mut Bridge, censor: &Censor) -> bool {
         if censor.blocks_bridge(config, &bridge.fingerprint) {
             if config.censor_totality == Full
                 || config.censor_totality == Partial
@@ -165,7 +165,7 @@ impl User {
             {
                 // If censor tries to hide its censorship, record a
                 // false connection
-                if config.censor_hides == Hiding {
+                if config.censor_secrecy == Hiding {
                     bridge.connect_total();
                 }
 
@@ -179,15 +179,6 @@ impl User {
                 if event_happens(config.prob_user_treats_throttling_as_blocking) {
                     bridge.connect_total();
 
-                    // A Hiding censor does not make an additional
-                    // connection here, but it will make a false
-                    // positive report if possible.
-                    if config.censor_hides == Hiding && censor.has_lox_cred(&bridge.fingerprint) {
-                        censor
-                            .send_positive_report(config, &bridge.fingerprint)
-                            .await;
-                    }
-
                     // Return false because there was interference
                     // detected in the connection
                     return false;
@@ -328,16 +319,13 @@ impl User {
             for i in 0..bucket.len() {
                 // At level 0, we only have 1 bridge
                 if bucket[i] != BridgeLine::default() {
-                    if self
-                        .connect(
-                            &config,
-                            bridges
-                                .get_mut(&bucket[i].get_hashed_fingerprint())
-                                .unwrap(),
-                            &censor,
-                        )
-                        .await
-                    {
+                    if self.connect(
+                        &config,
+                        bridges
+                            .get_mut(&bucket[i].get_hashed_fingerprint())
+                            .unwrap(),
+                        &censor,
+                    ) {
                         succeeded.push(bucket[i]);
                     } else {
                         failed.push(bucket[i]);
@@ -378,16 +366,13 @@ impl User {
                             );
                         }
                         // Attempt to connect to second cred's bridge
-                        if self
-                            .connect(
-                                &config,
-                                bridges
-                                    .get_mut(&bridgeline.get_hashed_fingerprint())
-                                    .unwrap(),
-                                censor,
-                            )
-                            .await
-                        {
+                        if self.connect(
+                            &config,
+                            bridges
+                                .get_mut(&bridgeline.get_hashed_fingerprint())
+                                .unwrap(),
+                            censor,
+                        ) {
                             succeeded.push(bridgeline);
                             if second_reachcred.is_some()
                                 && eligible_for_trust_promotion(&config.la_net, &second_cred).await