Use simple thresholds
This commit is contained in:
parent
dc7531689c
commit
ac1f09a8c1
|
@ -13,6 +13,7 @@ pub trait Analyzer {
|
|||
/// Evaluate open-entry bridge. Returns true if blocked, false otherwise.
|
||||
fn stage_one(
|
||||
&self,
|
||||
age: u32,
|
||||
confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
|
@ -24,6 +25,7 @@ pub trait Analyzer {
|
|||
/// blocked, false otherwise.
|
||||
fn stage_two(
|
||||
&self,
|
||||
age: u32,
|
||||
confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
|
@ -35,6 +37,7 @@ pub trait Analyzer {
|
|||
/// blocked, false otherwise.
|
||||
fn stage_three(
|
||||
&self,
|
||||
age: u32,
|
||||
confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
|
@ -118,6 +121,7 @@ pub fn blocked_in(
|
|||
// open-entry bridge and/or not enough days of
|
||||
// historical days for stages 2 and 3
|
||||
if analyzer.stage_one(
|
||||
age,
|
||||
confidence,
|
||||
&bridge_ips,
|
||||
bridge_ips_today,
|
||||
|
@ -132,6 +136,7 @@ pub fn blocked_in(
|
|||
// invite-only bridge without min_historical_days of
|
||||
// historical data on positive reports
|
||||
if analyzer.stage_two(
|
||||
age,
|
||||
confidence,
|
||||
&bridge_ips,
|
||||
bridge_ips_today,
|
||||
|
@ -144,6 +149,7 @@ pub fn blocked_in(
|
|||
// invite-only bridge that has min_historical_days or
|
||||
// more of historical data since the first positive report
|
||||
if analyzer.stage_three(
|
||||
age,
|
||||
confidence,
|
||||
&bridge_ips,
|
||||
bridge_ips_today,
|
||||
|
@ -168,6 +174,7 @@ pub struct ExampleAnalyzer {}
|
|||
impl Analyzer for ExampleAnalyzer {
|
||||
fn stage_one(
|
||||
&self,
|
||||
_age: u32,
|
||||
_confidence: f64,
|
||||
_bridge_ips: &[u32],
|
||||
_bridge_ips_today: u32,
|
||||
|
@ -179,6 +186,7 @@ impl Analyzer for ExampleAnalyzer {
|
|||
|
||||
fn stage_two(
|
||||
&self,
|
||||
_age: u32,
|
||||
_confidence: f64,
|
||||
_bridge_ips: &[u32],
|
||||
_bridge_ips_today: u32,
|
||||
|
@ -190,6 +198,7 @@ impl Analyzer for ExampleAnalyzer {
|
|||
|
||||
fn stage_three(
|
||||
&self,
|
||||
_age: u32,
|
||||
_confidence: f64,
|
||||
_bridge_ips: &[u32],
|
||||
_bridge_ips_today: u32,
|
||||
|
@ -221,6 +230,7 @@ impl Analyzer for NormalAnalyzer {
|
|||
/// Evaluate open-entry bridge based on only today's data
|
||||
fn stage_one(
|
||||
&self,
|
||||
_age: u32,
|
||||
_confidence: f64,
|
||||
_bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
|
@ -234,6 +244,7 @@ impl Analyzer for NormalAnalyzer {
|
|||
/// Evaluate invite-only bridge based on historical data
|
||||
fn stage_two(
|
||||
&self,
|
||||
_age: u32,
|
||||
confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
|
@ -305,6 +316,7 @@ impl Analyzer for NormalAnalyzer {
|
|||
/// Evaluate invite-only bridge with lv3+ users submitting positive reports
|
||||
fn stage_three(
|
||||
&self,
|
||||
age: u32,
|
||||
confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
|
@ -401,6 +413,7 @@ impl Analyzer for NormalAnalyzer {
|
|||
// evaluate each variable. Ignore positive reports and
|
||||
// compute as in stage 2
|
||||
if self.stage_two(
|
||||
age,
|
||||
confidence,
|
||||
bridge_ips,
|
||||
bridge_ips_today,
|
||||
|
|
|
@ -23,6 +23,7 @@ pub mod analysis;
|
|||
pub mod bridge_verification_info;
|
||||
pub mod crypto;
|
||||
pub mod extra_info;
|
||||
pub mod lox_analysis;
|
||||
pub mod negative_report;
|
||||
pub mod positive_report;
|
||||
pub mod request_handler;
|
||||
|
@ -34,6 +35,7 @@ pub mod simulation {
|
|||
|
||||
use analysis::Analyzer;
|
||||
use extra_info::*;
|
||||
use lox_analysis::LoxAnalyzer;
|
||||
use negative_report::*;
|
||||
use positive_report::*;
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
use crate::{analysis::Analyzer, BridgeCountryInfo, BridgeInfoType};
|
||||
use lox_library::{
|
||||
bridge_table::MAX_BRIDGES_PER_BUCKET,
|
||||
proto::{
|
||||
level_up::{LEVEL_INTERVAL, LEVEL_INVITATIONS, MAX_LEVEL},
|
||||
trust_promotion::UNTRUSTED_INTERVAL,
|
||||
},
|
||||
OPENINV_K,
|
||||
};
|
||||
|
||||
// Get max value from slice, or 0 if empty
|
||||
fn max(nums: &[u32]) -> u32 {
|
||||
let mut max_num = 0;
|
||||
for i in nums {
|
||||
if *i > max_num {
|
||||
max_num = *i;
|
||||
}
|
||||
}
|
||||
max_num
|
||||
}
|
||||
|
||||
// Max users expected on a Lox bridge based on how long it's been around
|
||||
fn max_users(days: u32) -> u32 {
|
||||
if days <= UNTRUSTED_INTERVAL {
|
||||
// k users for open-entry bucket
|
||||
OPENINV_K
|
||||
} else if days <= UNTRUSTED_INTERVAL + LEVEL_INTERVAL[1] {
|
||||
// k users per bridge x 3 bridges in invite-only bucket
|
||||
OPENINV_K * MAX_BRIDGES_PER_BUCKET as u32
|
||||
} else if days <= UNTRUSTED_INTERVAL + LEVEL_INTERVAL[2] {
|
||||
// suppose users have used all their invitations
|
||||
OPENINV_K * MAX_BRIDGES_PER_BUCKET as u32 * (1 + LEVEL_INVITATIONS[1])
|
||||
} else {
|
||||
// stop counting here, just say it's a lot
|
||||
100
|
||||
}
|
||||
}
|
||||
|
||||
// Maximum number of negative reports without considering the bridge blocked
|
||||
fn max_negative_reports(days: u32) -> u32 {
|
||||
// How many users do we expect to use this bridge?
|
||||
let max_users = max_users(days);
|
||||
|
||||
// Based on that, allow this many negative reports
|
||||
if max_users <= 10 {
|
||||
0
|
||||
} else if max_users <= 30 {
|
||||
5
|
||||
} else {
|
||||
10
|
||||
}
|
||||
}
|
||||
|
||||
fn too_few_bridge_ips(
|
||||
days: u32,
|
||||
max_bridge_ips: u32,
|
||||
bridge_ips_today: u32,
|
||||
positive_reports_today: u32,
|
||||
) -> bool {
|
||||
// How many users do we expect to use this bridge?
|
||||
let max_users = max_users(days);
|
||||
|
||||
// Based on that, expect this many bridge ips
|
||||
let min_bip = if max_users <= 16 {
|
||||
// expect 10
|
||||
8
|
||||
} else if max_users <= 40 {
|
||||
// expect 30
|
||||
24
|
||||
} else if max_users <= 96 {
|
||||
// expect 90
|
||||
32
|
||||
} else {
|
||||
// also 32, but it could be something else
|
||||
32
|
||||
};
|
||||
|
||||
// If we normally see low usage, halve the minimum
|
||||
let min_bip = if max_bridge_ips <= 8 {
|
||||
// If we have 1-8 users, allow the number to be 0
|
||||
0
|
||||
} else if max_bridge_ips <= max_users / 2 {
|
||||
min_bip / 2
|
||||
} else {
|
||||
min_bip
|
||||
};
|
||||
|
||||
// If we see positive reports from trusted users, double the minimum
|
||||
let min_bip = if positive_reports_today > 0 {
|
||||
min_bip * 2
|
||||
} else {
|
||||
min_bip
|
||||
};
|
||||
|
||||
bridge_ips_today < min_bip
|
||||
}
|
||||
|
||||
/// Analyzer for Lox bridges based on how long they've been active
|
||||
pub struct LoxAnalyzer {}
|
||||
|
||||
impl Analyzer for LoxAnalyzer {
|
||||
// At this stage, we expect 0-10 users, so 0, 8, or 16 bridge-ips
|
||||
fn stage_one(
|
||||
&self,
|
||||
age: u32,
|
||||
_confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
_negative_reports: &[u32],
|
||||
negative_reports_today: u32,
|
||||
) -> bool {
|
||||
// Get max bridge_ips we've seen
|
||||
let max_bridge_ips = max(bridge_ips);
|
||||
|
||||
if too_few_bridge_ips(age, max_bridge_ips, bridge_ips_today, 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have more negative reports than expected, consider the
|
||||
// bridge blocked
|
||||
negative_reports_today > max_negative_reports(age)
|
||||
}
|
||||
|
||||
fn stage_two(
|
||||
&self,
|
||||
age: u32,
|
||||
_confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
_negative_reports: &[u32],
|
||||
negative_reports_today: u32,
|
||||
) -> bool {
|
||||
// Get max bridge_ips we've seen
|
||||
let max_bridge_ips = max(bridge_ips);
|
||||
|
||||
if too_few_bridge_ips(age, max_bridge_ips, bridge_ips_today, 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have more negative reports than expected, consider the
|
||||
// bridge blocked
|
||||
negative_reports_today > max_negative_reports(age)
|
||||
}
|
||||
|
||||
fn stage_three(
|
||||
&self,
|
||||
age: u32,
|
||||
_confidence: f64,
|
||||
bridge_ips: &[u32],
|
||||
bridge_ips_today: u32,
|
||||
_negative_reports: &[u32],
|
||||
negative_reports_today: u32,
|
||||
_positive_reports: &[u32],
|
||||
positive_reports_today: u32,
|
||||
) -> bool {
|
||||
// Get max bridge_ips we've seen
|
||||
let max_bridge_ips = max(bridge_ips);
|
||||
|
||||
if too_few_bridge_ips(
|
||||
age,
|
||||
max_bridge_ips,
|
||||
bridge_ips_today,
|
||||
positive_reports_today,
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we have more negative reports than expected, consider the
|
||||
// bridge blocked
|
||||
negative_reports_today > max_negative_reports(age)
|
||||
}
|
||||
}
|
|
@ -103,7 +103,7 @@ async fn update_daily_info(
|
|||
update_positive_reports(db, distributors).await;
|
||||
let new_blockages = guess_blockages(
|
||||
db,
|
||||
&analysis::NormalAnalyzer::new(max_threshold, scaling_factor),
|
||||
&lox_analysis::LoxAnalyzer {},
|
||||
confidence,
|
||||
min_historical_days,
|
||||
max_historical_days,
|
||||
|
|
Loading…
Reference in New Issue