From c42cd8a8437271c109597bce383c4c672e827e68 Mon Sep 17 00:00:00 2001 From: Macpie Date: Wed, 11 Dec 2024 12:48:52 -0800 Subject: [PATCH 1/5] eligible_for_coverage_map --- mobile_verifier/src/reward_shares.rs | 112 +++++++++++++++++++-------- 1 file changed, 80 insertions(+), 32 deletions(-) diff --git a/mobile_verifier/src/reward_shares.rs b/mobile_verifier/src/reward_shares.rs index 5d3901981..a36a41bcf 100644 --- a/mobile_verifier/src/reward_shares.rs +++ b/mobile_verifier/src/reward_shares.rs @@ -11,7 +11,10 @@ use crate::{ unique_connections::{self, UniqueConnectionCounts}, }; use chrono::{DateTime, Duration, Utc}; -use coverage_point_calculator::{OracleBoostingStatus, SPBoostedRewardEligibility}; +use coverage_point_calculator::{ + BytesPs, LocationTrust, OracleBoostingStatus, SPBoostedRewardEligibility, Speedtest, + SpeedtestTier, +}; use file_store::traits::TimestampEncode; use futures::{Stream, StreamExt}; use helium_crypto::PublicKeyBinary; @@ -430,6 +433,28 @@ impl CoverageShares { .fetch_seniority(heartbeat_key, reward_period.end) .await?; + let trust_scores: Vec = heartbeat + .iter_distances_and_scores() + .map(|(distance, trust_score)| LocationTrust { + meters_to_asserted: distance as u32, + trust_score, + }) + .collect(); + + let speedtests = match speedtest_averages.get_average(&pubkey) { + Some(avg) => avg.speedtests, + None => vec![], + }; + let speedtests: Vec = speedtests + .iter() + .map(|test| Speedtest { + upload_speed: BytesPs::new(test.report.upload_speed), + download_speed: BytesPs::new(test.report.download_speed), + latency_millis: test.report.latency, + timestamp: test.report.timestamp, + }) + .collect(); + let is_indoor = { let mut is_indoor = false; @@ -449,13 +474,21 @@ impl CoverageShares { }); } - coverage_map_builder.insert_coverage_object(coverage_map::CoverageObject { - indoor: is_indoor, - hotspot_key: pubkey.clone().into(), - cbsd_id: cbsd_id.clone(), - seniority_timestamp: seniority.seniority_ts, - coverage: covered_hexes, - }); + if eligible_for_coverage_map( + &pubkey, + cbsd_id.clone(), + banned_radios, + &speedtests, + &trust_scores, + ) { + coverage_map_builder.insert_coverage_object(coverage_map::CoverageObject { + indoor: is_indoor, + hotspot_key: pubkey.clone().into(), + cbsd_id: cbsd_id.clone(), + seniority_timestamp: seniority.seniority_ts, + coverage: covered_hexes, + }); + } is_indoor }; @@ -468,21 +501,6 @@ impl CoverageShares { (false, Some(_)) => RadioType::OutdoorCbrs, }; - use coverage_point_calculator::{BytesPs, Speedtest}; - let speedtests = match speedtest_averages.get_average(&pubkey) { - Some(avg) => avg.speedtests, - None => vec![], - }; - let speedtests = speedtests - .iter() - .map(|test| Speedtest { - upload_speed: BytesPs::new(test.report.upload_speed), - download_speed: BytesPs::new(test.report.download_speed), - latency_millis: test.report.latency, - timestamp: test.report.timestamp, - }) - .collect(); - let oracle_boosting_status = if unique_connections::is_qualified(unique_connections, &pubkey, &radio_type) { OracleBoostingStatus::Qualified @@ -495,15 +513,6 @@ impl CoverageShares { let sp_boosted_reward_eligibility = boosted_hex_eligibility.eligibility(pubkey, cbsd_id); - use coverage_point_calculator::LocationTrust; - let trust_scores = heartbeat - .iter_distances_and_scores() - .map(|(distance, trust_score)| LocationTrust { - meters_to_asserted: distance as u32, - trust_score, - }) - .collect(); - radio_infos.insert( key, RadioInfo { @@ -770,6 +779,45 @@ pub fn get_scheduled_tokens_for_oracles(duration: Duration) -> Decimal { get_total_scheduled_tokens(duration) * ORACLES_PERCENT } +fn eligible_for_coverage_map( + pubkey: &PublicKeyBinary, + cbsd_id: Option, + banned_radios: &BannedRadios, + speedtests: &[Speedtest], + trust_scores: &[LocationTrust], +) -> bool { + if banned_radios.contains(pubkey, cbsd_id.as_deref()) { + return false; + } + + let avg_speedtest = Speedtest::avg(speedtests); + if !is_tier_eligible(avg_speedtest.tier()) { + return false; + } + + let avg_trust_score = average_trust_score(trust_scores); + if avg_trust_score <= dec!(0.0) { + return false; + } + + true +} + +fn is_tier_eligible(tier: SpeedtestTier) -> bool { + matches!( + tier, + SpeedtestTier::Good | SpeedtestTier::Acceptable | SpeedtestTier::Degraded + ) +} + +fn average_trust_score(trust_scores: &[LocationTrust]) -> Decimal { + if trust_scores.is_empty() { + return dec!(0); + } + let total_score: Decimal = trust_scores.iter().map(|lt| lt.trust_score).sum(); + total_score / Decimal::from(trust_scores.len() as u64) +} + #[cfg(test)] mod test { From ba1328d50960e340bf666bd795138b610bac9b01 Mon Sep 17 00:00:00 2001 From: Macpie Date: Wed, 11 Dec 2024 13:24:48 -0800 Subject: [PATCH 2/5] Fix check_speedtest_avg_in_radio_reward_v2 --- mobile_verifier/src/reward_shares.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mobile_verifier/src/reward_shares.rs b/mobile_verifier/src/reward_shares.rs index a36a41bcf..4ecb56c32 100644 --- a/mobile_verifier/src/reward_shares.rs +++ b/mobile_verifier/src/reward_shares.rs @@ -1237,7 +1237,7 @@ mod test { timestamp, upload_speed: bytes_per_s(10), download_speed: bytes_per_s(100), - latency: 50, + latency: 10, serial: "".to_string(), }, }; @@ -1247,7 +1247,7 @@ mod test { timestamp, upload_speed: bytes_per_s(20), download_speed: bytes_per_s(200), - latency: 100, + latency: 20, serial: "".to_string(), }, }; @@ -1290,7 +1290,7 @@ mod test { let speedtest_avg = radio_reward.speedtest_average.unwrap(); assert_eq!(speedtest_avg.upload_speed_bps, bytes_per_s(15)); assert_eq!(speedtest_avg.download_speed_bps, bytes_per_s(150)); - assert_eq!(speedtest_avg.latency_ms, 75); + assert_eq!(speedtest_avg.latency_ms, 15); } /// Test to ensure that different speedtest averages correctly afferct reward shares. From 6a4ddaf5b1b87f12affbec61d7156160f1884cfb Mon Sep 17 00:00:00 2001 From: Macpie Date: Thu, 12 Dec 2024 12:15:52 -0800 Subject: [PATCH 3/5] Allow SpeedtestTier::Poor to work --- mobile_verifier/src/reward_shares.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/mobile_verifier/src/reward_shares.rs b/mobile_verifier/src/reward_shares.rs index 4ecb56c32..b49e32cac 100644 --- a/mobile_verifier/src/reward_shares.rs +++ b/mobile_verifier/src/reward_shares.rs @@ -791,7 +791,7 @@ fn eligible_for_coverage_map( } let avg_speedtest = Speedtest::avg(speedtests); - if !is_tier_eligible(avg_speedtest.tier()) { + if avg_speedtest.tier() == SpeedtestTier::Fail { return false; } @@ -803,13 +803,6 @@ fn eligible_for_coverage_map( true } -fn is_tier_eligible(tier: SpeedtestTier) -> bool { - matches!( - tier, - SpeedtestTier::Good | SpeedtestTier::Acceptable | SpeedtestTier::Degraded - ) -} - fn average_trust_score(trust_scores: &[LocationTrust]) -> Decimal { if trust_scores.is_empty() { return dec!(0); @@ -1237,7 +1230,7 @@ mod test { timestamp, upload_speed: bytes_per_s(10), download_speed: bytes_per_s(100), - latency: 10, + latency: 50, serial: "".to_string(), }, }; @@ -1247,7 +1240,7 @@ mod test { timestamp, upload_speed: bytes_per_s(20), download_speed: bytes_per_s(200), - latency: 20, + latency: 100, serial: "".to_string(), }, }; @@ -1290,7 +1283,7 @@ mod test { let speedtest_avg = radio_reward.speedtest_average.unwrap(); assert_eq!(speedtest_avg.upload_speed_bps, bytes_per_s(15)); assert_eq!(speedtest_avg.download_speed_bps, bytes_per_s(150)); - assert_eq!(speedtest_avg.latency_ms, 15); + assert_eq!(speedtest_avg.latency_ms, 75); } /// Test to ensure that different speedtest averages correctly afferct reward shares. From 9b7fa88bc3acb308aeabbec37f0f959b005a01ab Mon Sep 17 00:00:00 2001 From: Macpie Date: Fri, 13 Dec 2024 10:30:23 -0800 Subject: [PATCH 4/5] Move eligible_for_coverage_map and use oracle_boosting_status instead of just is banned --- mobile_verifier/src/reward_shares.rs | 37 +++++++++++----------------- 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/mobile_verifier/src/reward_shares.rs b/mobile_verifier/src/reward_shares.rs index b49e32cac..ec6ee12f8 100644 --- a/mobile_verifier/src/reward_shares.rs +++ b/mobile_verifier/src/reward_shares.rs @@ -455,7 +455,7 @@ impl CoverageShares { }) .collect(); - let is_indoor = { + let (is_indoor, covered_hexes) = { let mut is_indoor = false; let covered_hexes_stream = hex_streams @@ -473,24 +473,7 @@ impl CoverageShares { assignments: hex_coverage.assignments, }); } - - if eligible_for_coverage_map( - &pubkey, - cbsd_id.clone(), - banned_radios, - &speedtests, - &trust_scores, - ) { - coverage_map_builder.insert_coverage_object(coverage_map::CoverageObject { - indoor: is_indoor, - hotspot_key: pubkey.clone().into(), - cbsd_id: cbsd_id.clone(), - seniority_timestamp: seniority.seniority_ts, - coverage: covered_hexes, - }); - } - - is_indoor + (is_indoor, covered_hexes) }; use coverage_point_calculator::RadioType; @@ -510,6 +493,16 @@ impl CoverageShares { OracleBoostingStatus::Eligible }; + if eligible_for_coverage_map(oracle_boosting_status, &speedtests, &trust_scores) { + coverage_map_builder.insert_coverage_object(coverage_map::CoverageObject { + indoor: is_indoor, + hotspot_key: pubkey.clone().into(), + cbsd_id: cbsd_id.clone(), + seniority_timestamp: seniority.seniority_ts, + coverage: covered_hexes, + }); + } + let sp_boosted_reward_eligibility = boosted_hex_eligibility.eligibility(pubkey, cbsd_id); @@ -780,13 +773,11 @@ pub fn get_scheduled_tokens_for_oracles(duration: Duration) -> Decimal { } fn eligible_for_coverage_map( - pubkey: &PublicKeyBinary, - cbsd_id: Option, - banned_radios: &BannedRadios, + oracle_boosting_status: OracleBoostingStatus, speedtests: &[Speedtest], trust_scores: &[LocationTrust], ) -> bool { - if banned_radios.contains(pubkey, cbsd_id.as_deref()) { + if oracle_boosting_status == OracleBoostingStatus::Banned { return false; } From 1a5240a6b593c59581f925d66c6040251e3cfd08 Mon Sep 17 00:00:00 2001 From: Macpie Date: Mon, 16 Dec 2024 11:03:15 -0800 Subject: [PATCH 5/5] Use coverage_point_calculator::location::multiplier --- coverage_point_calculator/src/lib.rs | 2 +- coverage_point_calculator/src/location.rs | 2 +- mobile_verifier/src/reward_shares.rs | 22 ++++++++++------------ 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/coverage_point_calculator/src/lib.rs b/coverage_point_calculator/src/lib.rs index 9dcdcbcf9..9a2ea0951 100644 --- a/coverage_point_calculator/src/lib.rs +++ b/coverage_point_calculator/src/lib.rs @@ -82,7 +82,7 @@ use rust_decimal_macros::dec; use service_provider_boosting::{MAX_AVERAGE_DISTANCE, MIN_WIFI_TRUST_MULTIPLIER}; mod hexes; -mod location; +pub mod location; mod service_provider_boosting; pub mod speedtest; diff --git a/coverage_point_calculator/src/location.rs b/coverage_point_calculator/src/location.rs index ad4ac179d..d630c2299 100644 --- a/coverage_point_calculator/src/location.rs +++ b/coverage_point_calculator/src/location.rs @@ -51,7 +51,7 @@ pub(crate) fn average_distance(radio_type: RadioType, trust_scores: &[LocationTr sum / count } -pub(crate) fn multiplier(radio_type: RadioType, trust_scores: &[LocationTrust]) -> Decimal { +pub fn multiplier(radio_type: RadioType, trust_scores: &[LocationTrust]) -> Decimal { // CBRS radios are always trusted because they have internal GPS if radio_type.is_cbrs() { return dec!(1); diff --git a/mobile_verifier/src/reward_shares.rs b/mobile_verifier/src/reward_shares.rs index ec6ee12f8..076978636 100644 --- a/mobile_verifier/src/reward_shares.rs +++ b/mobile_verifier/src/reward_shares.rs @@ -12,7 +12,7 @@ use crate::{ }; use chrono::{DateTime, Duration, Utc}; use coverage_point_calculator::{ - BytesPs, LocationTrust, OracleBoostingStatus, SPBoostedRewardEligibility, Speedtest, + BytesPs, LocationTrust, OracleBoostingStatus, RadioType, SPBoostedRewardEligibility, Speedtest, SpeedtestTier, }; use file_store::traits::TimestampEncode; @@ -493,7 +493,12 @@ impl CoverageShares { OracleBoostingStatus::Eligible }; - if eligible_for_coverage_map(oracle_boosting_status, &speedtests, &trust_scores) { + if eligible_for_coverage_map( + oracle_boosting_status, + &speedtests, + radio_type, + &trust_scores, + ) { coverage_map_builder.insert_coverage_object(coverage_map::CoverageObject { indoor: is_indoor, hotspot_key: pubkey.clone().into(), @@ -775,6 +780,7 @@ pub fn get_scheduled_tokens_for_oracles(duration: Duration) -> Decimal { fn eligible_for_coverage_map( oracle_boosting_status: OracleBoostingStatus, speedtests: &[Speedtest], + radio_type: RadioType, trust_scores: &[LocationTrust], ) -> bool { if oracle_boosting_status == OracleBoostingStatus::Banned { @@ -786,22 +792,14 @@ fn eligible_for_coverage_map( return false; } - let avg_trust_score = average_trust_score(trust_scores); - if avg_trust_score <= dec!(0.0) { + let multiplier = coverage_point_calculator::location::multiplier(radio_type, trust_scores); + if multiplier <= dec!(0.0) { return false; } true } -fn average_trust_score(trust_scores: &[LocationTrust]) -> Decimal { - if trust_scores.is_empty() { - return dec!(0); - } - let total_score: Decimal = trust_scores.iter().map(|lt| lt.trust_score).sum(); - total_score / Decimal::from(trust_scores.len() as u64) -} - #[cfg(test)] mod test {