Compare commits
2 Commits
9495c8cbda
...
498d6b4cee
Author | SHA1 | Date |
---|---|---|
|
498d6b4cee | |
|
bc834c329d |
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aes-gcm = "0.10"
|
aes-gcm = "0.10"
|
||||||
|
anyhow = "1.0"
|
||||||
array-bytes = "6.2.0"
|
array-bytes = "6.2.0"
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
|
|
@ -44,7 +44,7 @@ pub struct Config {
|
||||||
pub la_test_port: u16,
|
pub la_test_port: u16,
|
||||||
pub tp_port: u16,
|
pub tp_port: u16,
|
||||||
pub tp_test_port: u16,
|
pub tp_test_port: u16,
|
||||||
pub censor_hides: censor::Hides,
|
pub censor_secrecy: censor::Secrecy,
|
||||||
pub censor_speed: censor::Speed,
|
pub censor_speed: censor::Speed,
|
||||||
pub censor_event_duration: u32,
|
pub censor_event_duration: u32,
|
||||||
pub censor_totality: censor::Totality,
|
pub censor_totality: censor::Totality,
|
||||||
|
@ -96,7 +96,7 @@ pub async fn main() {
|
||||||
la_pubkeys,
|
la_pubkeys,
|
||||||
la_net,
|
la_net,
|
||||||
tp_net,
|
tp_net,
|
||||||
censor_hides: config.censor_hides,
|
censor_secrecy: config.censor_secrecy,
|
||||||
censor_speed: config.censor_speed,
|
censor_speed: config.censor_speed,
|
||||||
censor_event_duration: config.censor_event_duration,
|
censor_event_duration: config.censor_event_duration,
|
||||||
censor_totality: config.censor_totality,
|
censor_totality: config.censor_totality,
|
||||||
|
@ -141,7 +141,8 @@ pub async fn main() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
// Advance simulated time
|
// Advance simulated time
|
||||||
set_simulated_date(get_date() + UNTRUSTED_INTERVAL);
|
set_simulated_date(get_date() + UNTRUSTED_INTERVAL);
|
||||||
|
|
||||||
|
@ -176,7 +177,8 @@ pub async fn main() {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into(),
|
.into(),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
// Advance simulated time
|
// Advance simulated time
|
||||||
set_simulated_date(get_date() + LEVEL_INTERVAL[i]);
|
set_simulated_date(get_date() + LEVEL_INTERVAL[i]);
|
||||||
|
|
||||||
|
@ -207,7 +209,8 @@ pub async fn main() {
|
||||||
"/advancedays".to_string(),
|
"/advancedays".to_string(),
|
||||||
serde_json::to_string(&(1 as u16)).unwrap().into(),
|
serde_json::to_string(&(1 as u16)).unwrap().into(),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Advance simulated time to tomorrow
|
// Advance simulated time to tomorrow
|
||||||
increment_simulated_date();
|
increment_simulated_date();
|
||||||
|
@ -366,10 +369,14 @@ pub async fn main() {
|
||||||
"/add".to_string(),
|
"/add".to_string(),
|
||||||
serde_json::to_string(&new_extra_infos).unwrap().into(),
|
serde_json::to_string(&new_extra_infos).unwrap().into(),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// TROLL PATROL TASKS
|
// TROLL PATROL TASKS
|
||||||
let new_blockages_resp = tp_net_test.request("/update".to_string(), vec![]).await;
|
let new_blockages_resp = tp_net_test
|
||||||
|
.request("/update".to_string(), vec![])
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
let new_blockages: HashMap<String, HashSet<String>> =
|
let new_blockages: HashMap<String, HashSet<String>> =
|
||||||
serde_json::from_slice(&new_blockages_resp).unwrap();
|
serde_json::from_slice(&new_blockages_resp).unwrap();
|
||||||
|
|
||||||
|
@ -415,7 +422,8 @@ pub async fn main() {
|
||||||
"/advancedays".to_string(),
|
"/advancedays".to_string(),
|
||||||
serde_json::to_string(&(1 as u16)).unwrap().into(),
|
serde_json::to_string(&(1 as u16)).unwrap().into(),
|
||||||
)
|
)
|
||||||
.await;
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// SIMULATION TASKS
|
// SIMULATION TASKS
|
||||||
|
|
||||||
|
|
|
@ -26,8 +26,8 @@ pub struct Bridge {
|
||||||
// bridge (for identifying stage three)
|
// bridge (for identifying stage three)
|
||||||
pub first_positive_report: u32,
|
pub first_positive_report: u32,
|
||||||
|
|
||||||
real_connections: u32,
|
pub real_connections: u32,
|
||||||
total_connections: u32,
|
pub total_connections: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Bridge {
|
impl Bridge {
|
||||||
|
|
|
@ -8,7 +8,10 @@ use lox_cli::{get_lox_pub, networking::Networking};
|
||||||
use lox_library::{cred::Lox, scalar_u32};
|
use lox_library::{cred::Lox, scalar_u32};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::{
|
||||||
|
cmp::min,
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
};
|
||||||
|
|
||||||
pub struct Censor {
|
pub struct Censor {
|
||||||
pub known_bridges: HashSet<[u8; 20]>,
|
pub known_bridges: HashSet<[u8; 20]>,
|
||||||
|
@ -112,17 +115,22 @@ impl Censor {
|
||||||
config.country.clone(),
|
config.country.clone(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
config
|
if config
|
||||||
.tp_net
|
.tp_net
|
||||||
.request("/positivereport".to_string(), pr.to_json().into_bytes())
|
.request("/positivereport".to_string(), pr.to_json().into_bytes())
|
||||||
.await;
|
.await
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
// failed to send positive report
|
||||||
|
return false;
|
||||||
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make a bunch of connections and submit positive reports if possible
|
// Make a bunch of connections and submit positive reports if possible
|
||||||
async fn flood(&self, config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>) {
|
async fn flood(&self, config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>) {
|
||||||
// Only do this if Flooding censor
|
// Only do this if Flooding censor
|
||||||
if config.censor_hides == Hides::Flooding {
|
if config.censor_secrecy == Secrecy::Flooding {
|
||||||
for fingerprint in &self.known_bridges {
|
for fingerprint in &self.known_bridges {
|
||||||
// Only do this if we're blocking the bridge
|
// Only do this if we're blocking the bridge
|
||||||
if config.censor_speed == Speed::Fast
|
if config.censor_speed == Speed::Fast
|
||||||
|
@ -156,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) {
|
fn recompute_delay(&mut self, config: &Config) {
|
||||||
// Only do this if Random censor
|
// Only do this if Random censor
|
||||||
if config.censor_speed == Speed::Random
|
if config.censor_speed == Speed::Random
|
||||||
|
@ -175,10 +215,14 @@ impl Censor {
|
||||||
config: &Config,
|
config: &Config,
|
||||||
bridges: &mut HashMap<[u8; 20], Bridge>,
|
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())
|
&& !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
|
||||||
{
|
{
|
||||||
self.flood(config, bridges).await;
|
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);
|
self.recompute_delay(config);
|
||||||
|
@ -193,7 +237,7 @@ pub enum Speed {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
|
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
|
||||||
pub enum Hides {
|
pub enum Secrecy {
|
||||||
Overt,
|
Overt,
|
||||||
Hiding,
|
Hiding,
|
||||||
Flooding,
|
Flooding,
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct Config {
|
||||||
pub la_net: HyperNet,
|
pub la_net: HyperNet,
|
||||||
pub tp_net: HyperNet,
|
pub tp_net: HyperNet,
|
||||||
// Define censor behavior
|
// Define censor behavior
|
||||||
pub censor_hides: censor::Hides,
|
pub censor_secrecy: censor::Secrecy,
|
||||||
pub censor_speed: censor::Speed,
|
pub censor_speed: censor::Speed,
|
||||||
pub censor_event_duration: u32,
|
pub censor_event_duration: u32,
|
||||||
pub censor_totality: censor::Totality,
|
pub censor_totality: censor::Totality,
|
||||||
|
|
|
@ -6,17 +6,17 @@ use crate::{
|
||||||
positive_report::PositiveReport,
|
positive_report::PositiveReport,
|
||||||
simulation::{
|
simulation::{
|
||||||
bridge::Bridge,
|
bridge::Bridge,
|
||||||
censor::{Censor, Hides::*, Totality::*},
|
censor::{Censor, Secrecy::*, Totality::*},
|
||||||
config::Config,
|
config::Config,
|
||||||
},
|
},
|
||||||
BridgeDistributor,
|
BridgeDistributor,
|
||||||
};
|
};
|
||||||
|
use anyhow::{anyhow, Result};
|
||||||
use lox_cli::{networking::*, *};
|
use lox_cli::{networking::*, *};
|
||||||
use lox_library::{
|
use lox_library::{
|
||||||
bridge_table::BridgeLine, cred::Lox, proto::check_blockage::MIN_TRUST_LEVEL, scalar_u32,
|
bridge_table::BridgeLine, cred::Lox, proto::check_blockage::MIN_TRUST_LEVEL, scalar_u32,
|
||||||
};
|
};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use serde_json::error::Error;
|
|
||||||
use std::{cmp::min, collections::HashMap};
|
use std::{cmp::min, collections::HashMap};
|
||||||
use x25519_dalek::PublicKey;
|
use x25519_dalek::PublicKey;
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ pub struct User {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
pub async fn new(config: &Config, is_censor: bool) -> Result<Self, Error> {
|
pub async fn new(config: &Config, is_censor: bool) -> Result<Self> {
|
||||||
let cred = get_lox_credential(
|
let cred = get_lox_credential(
|
||||||
&config.la_net,
|
&config.la_net,
|
||||||
&get_open_invitation(&config.la_net).await?,
|
&get_open_invitation(&config.la_net).await?,
|
||||||
|
@ -75,7 +75,7 @@ impl User {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn trusted_user(config: &Config) -> Result<Self, Error> {
|
pub async fn trusted_user(config: &Config) -> Result<Self> {
|
||||||
let cred = get_lox_credential(
|
let cred = get_lox_credential(
|
||||||
&config.la_net,
|
&config.la_net,
|
||||||
&get_open_invitation(&config.la_net).await?,
|
&get_open_invitation(&config.la_net).await?,
|
||||||
|
@ -98,7 +98,7 @@ impl User {
|
||||||
config: &Config,
|
config: &Config,
|
||||||
censor: &mut Censor,
|
censor: &mut Censor,
|
||||||
invited_user_is_censor: bool,
|
invited_user_is_censor: bool,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self> {
|
||||||
let etable = get_reachability_credential(&config.la_net).await?;
|
let etable = get_reachability_credential(&config.la_net).await?;
|
||||||
let (new_cred, invite) = issue_invite(
|
let (new_cred, invite) = issue_invite(
|
||||||
&config.la_net,
|
&config.la_net,
|
||||||
|
@ -157,7 +157,7 @@ impl User {
|
||||||
// Note that this does not involve making a real connection to a
|
// Note that this does not involve making a real connection to a
|
||||||
// real bridge. The function is async because the *censor* might
|
// real bridge. The function is async because the *censor* might
|
||||||
// submit a positive report during this function.
|
// 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 censor.blocks_bridge(config, &bridge.fingerprint) {
|
||||||
if config.censor_totality == Full
|
if config.censor_totality == Full
|
||||||
|| config.censor_totality == Partial
|
|| config.censor_totality == Partial
|
||||||
|
@ -165,7 +165,7 @@ impl User {
|
||||||
{
|
{
|
||||||
// If censor tries to hide its censorship, record a
|
// If censor tries to hide its censorship, record a
|
||||||
// false connection
|
// false connection
|
||||||
if config.censor_hides == Hiding {
|
if config.censor_secrecy == Hiding {
|
||||||
bridge.connect_total();
|
bridge.connect_total();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,15 +179,6 @@ impl User {
|
||||||
if event_happens(config.prob_user_treats_throttling_as_blocking) {
|
if event_happens(config.prob_user_treats_throttling_as_blocking) {
|
||||||
bridge.connect_total();
|
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
|
// Return false because there was interference
|
||||||
// detected in the connection
|
// detected in the connection
|
||||||
return false;
|
return false;
|
||||||
|
@ -205,7 +196,7 @@ impl User {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_new_credential(config: &Config) -> Result<(Lox, BridgeLine), Error> {
|
pub async fn get_new_credential(config: &Config) -> Result<(Lox, BridgeLine)> {
|
||||||
get_lox_credential(
|
get_lox_credential(
|
||||||
&config.la_net,
|
&config.la_net,
|
||||||
&get_open_invitation(&config.la_net).await?,
|
&get_open_invitation(&config.la_net).await?,
|
||||||
|
@ -214,7 +205,10 @@ impl User {
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_negative_reports(config: &Config, reports: Vec<NegativeReport>) {
|
pub async fn send_negative_reports(
|
||||||
|
config: &Config,
|
||||||
|
reports: Vec<NegativeReport>,
|
||||||
|
) -> Result<()> {
|
||||||
let date = get_date();
|
let date = get_date();
|
||||||
let pubkey = serde_json::from_slice::<Option<PublicKey>>(
|
let pubkey = serde_json::from_slice::<Option<PublicKey>>(
|
||||||
&config
|
&config
|
||||||
|
@ -223,9 +217,8 @@ impl User {
|
||||||
"/nrkey".to_string(),
|
"/nrkey".to_string(),
|
||||||
serde_json::to_string(&date).unwrap().into(),
|
serde_json::to_string(&date).unwrap().into(),
|
||||||
)
|
)
|
||||||
.await,
|
.await?,
|
||||||
)
|
)?
|
||||||
.unwrap()
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
for report in reports {
|
for report in reports {
|
||||||
config
|
config
|
||||||
|
@ -234,17 +227,22 @@ impl User {
|
||||||
"/negativereport".to_string(),
|
"/negativereport".to_string(),
|
||||||
bincode::serialize(&report.encrypt(&pubkey)).unwrap(),
|
bincode::serialize(&report.encrypt(&pubkey)).unwrap(),
|
||||||
)
|
)
|
||||||
.await;
|
.await?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn send_positive_reports(config: &Config, reports: Vec<PositiveReport>) {
|
pub async fn send_positive_reports(
|
||||||
|
config: &Config,
|
||||||
|
reports: Vec<PositiveReport>,
|
||||||
|
) -> Result<()> {
|
||||||
for report in reports {
|
for report in reports {
|
||||||
config
|
config
|
||||||
.tp_net
|
.tp_net
|
||||||
.request("/positivereport".to_string(), report.to_json().into_bytes())
|
.request("/positivereport".to_string(), report.to_json().into_bytes())
|
||||||
.await;
|
.await?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn daily_tasks(
|
pub async fn daily_tasks(
|
||||||
|
@ -254,7 +252,7 @@ impl User {
|
||||||
num_censor_invites: u32,
|
num_censor_invites: u32,
|
||||||
bridges: &mut HashMap<[u8; 20], Bridge>,
|
bridges: &mut HashMap<[u8; 20], Bridge>,
|
||||||
censor: &mut Censor,
|
censor: &mut Censor,
|
||||||
) -> Result<Vec<User>, Error> {
|
) -> Result<Vec<User>> {
|
||||||
if self.is_censor {
|
if self.is_censor {
|
||||||
self.daily_tasks_censor(config, bridges, censor).await
|
self.daily_tasks_censor(config, bridges, censor).await
|
||||||
} else {
|
} else {
|
||||||
|
@ -280,14 +278,17 @@ impl User {
|
||||||
num_censor_invites: u32,
|
num_censor_invites: u32,
|
||||||
bridges: &mut HashMap<[u8; 20], Bridge>,
|
bridges: &mut HashMap<[u8; 20], Bridge>,
|
||||||
censor: &mut Censor,
|
censor: &mut Censor,
|
||||||
) -> Result<Vec<User>, Error> {
|
) -> Result<Vec<User>> {
|
||||||
// Probabilistically decide if the user should use bridges today
|
// Probabilistically decide if the user should use bridges today
|
||||||
if event_happens(self.prob_use_bridges) {
|
if event_happens(self.prob_use_bridges) {
|
||||||
// Download bucket to see if bridge is still reachable. (We
|
// Download bucket to see if bridge is still reachable. (We
|
||||||
// assume that this step can be done even if the user can't
|
// assume that this step can be done even if the user can't
|
||||||
// actually talk to the LA.)
|
// actually talk to the LA.)
|
||||||
let (bucket, reachcred) = get_bucket(&config.la_net, &self.primary_cred).await?;
|
let (bucket, reachcred) = get_bucket(&config.la_net, &self.primary_cred).await?;
|
||||||
let level = scalar_u32(&self.primary_cred.trust_level).unwrap();
|
let level = match scalar_u32(&self.primary_cred.trust_level) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => return Err(anyhow!("Failed to get trust level from credential")),
|
||||||
|
};
|
||||||
|
|
||||||
// Make sure each bridge in bucket is in the global bridges set
|
// Make sure each bridge in bucket is in the global bridges set
|
||||||
for bridgeline in bucket {
|
for bridgeline in bucket {
|
||||||
|
@ -318,16 +319,13 @@ impl User {
|
||||||
for i in 0..bucket.len() {
|
for i in 0..bucket.len() {
|
||||||
// At level 0, we only have 1 bridge
|
// At level 0, we only have 1 bridge
|
||||||
if bucket[i] != BridgeLine::default() {
|
if bucket[i] != BridgeLine::default() {
|
||||||
if self
|
if self.connect(
|
||||||
.connect(
|
|
||||||
&config,
|
&config,
|
||||||
bridges
|
bridges
|
||||||
.get_mut(&bucket[i].get_hashed_fingerprint())
|
.get_mut(&bucket[i].get_hashed_fingerprint())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
&censor,
|
&censor,
|
||||||
)
|
) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
succeeded.push(bucket[i]);
|
succeeded.push(bucket[i]);
|
||||||
} else {
|
} else {
|
||||||
failed.push(bucket[i]);
|
failed.push(bucket[i]);
|
||||||
|
@ -368,16 +366,13 @@ impl User {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// Attempt to connect to second cred's bridge
|
// Attempt to connect to second cred's bridge
|
||||||
if self
|
if self.connect(
|
||||||
.connect(
|
|
||||||
&config,
|
&config,
|
||||||
bridges
|
bridges
|
||||||
.get_mut(&bridgeline.get_hashed_fingerprint())
|
.get_mut(&bridgeline.get_hashed_fingerprint())
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
censor,
|
censor,
|
||||||
)
|
) {
|
||||||
.await
|
|
||||||
{
|
|
||||||
succeeded.push(bridgeline);
|
succeeded.push(bridgeline);
|
||||||
if second_reachcred.is_some()
|
if second_reachcred.is_some()
|
||||||
&& eligible_for_trust_promotion(&config.la_net, &second_cred).await
|
&& eligible_for_trust_promotion(&config.la_net, &second_cred).await
|
||||||
|
@ -506,14 +501,17 @@ impl User {
|
||||||
}
|
}
|
||||||
|
|
||||||
if negative_reports.len() > 0 {
|
if negative_reports.len() > 0 {
|
||||||
Self::send_negative_reports(&config, negative_reports).await;
|
Self::send_negative_reports(&config, negative_reports).await?;
|
||||||
}
|
}
|
||||||
if positive_reports.len() > 0 {
|
if positive_reports.len() > 0 {
|
||||||
Self::send_positive_reports(&config, positive_reports).await;
|
Self::send_positive_reports(&config, positive_reports).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invite friends if applicable
|
// Invite friends if applicable
|
||||||
let invitations = scalar_u32(&self.primary_cred.invites_remaining).unwrap();
|
let invitations = match scalar_u32(&self.primary_cred.invites_remaining) {
|
||||||
|
Some(v) => v,
|
||||||
|
None => 0, // This is probably an error case that should not happen
|
||||||
|
};
|
||||||
let mut new_friends = Vec::<User>::new();
|
let mut new_friends = Vec::<User>::new();
|
||||||
for _i in 0..min(invitations, num_users_requesting_invites) {
|
for _i in 0..min(invitations, num_users_requesting_invites) {
|
||||||
if event_happens(config.prob_user_invites_friend) {
|
if event_happens(config.prob_user_invites_friend) {
|
||||||
|
@ -561,7 +559,7 @@ impl User {
|
||||||
config: &Config,
|
config: &Config,
|
||||||
bridges: &mut HashMap<[u8; 20], Bridge>,
|
bridges: &mut HashMap<[u8; 20], Bridge>,
|
||||||
censor: &mut Censor,
|
censor: &mut Censor,
|
||||||
) -> Result<Vec<User>, Error> {
|
) -> Result<Vec<User>> {
|
||||||
// Download bucket to see if bridge is still reachable and if we
|
// Download bucket to see if bridge is still reachable and if we
|
||||||
// have any new bridges
|
// have any new bridges
|
||||||
let (bucket, reachcred) = get_bucket(&config.la_net, &self.primary_cred).await?;
|
let (bucket, reachcred) = get_bucket(&config.la_net, &self.primary_cred).await?;
|
||||||
|
|
Loading…
Reference in New Issue