From 28510bd7466dd1cf76fc3ae6f0b3719ebc32556c Mon Sep 17 00:00:00 2001 From: Brian Balser Date: Wed, 28 Aug 2024 15:06:55 -0400 Subject: [PATCH] Change bool to OracleBoostingStatus enum --- coverage_point_calculator/src/hexes.rs | 23 +++--- coverage_point_calculator/src/lib.rs | 75 +++++++++++-------- .../tests/coverage_point_calculator.rs | 14 ++-- mobile_verifier/src/reward_shares.rs | 16 ++-- .../src/reward_shares/radio_reward_v2.rs | 10 +-- 5 files changed, 79 insertions(+), 59 deletions(-) diff --git a/coverage_point_calculator/src/hexes.rs b/coverage_point_calculator/src/hexes.rs index 6a4b985b8..912369a85 100644 --- a/coverage_point_calculator/src/hexes.rs +++ b/coverage_point_calculator/src/hexes.rs @@ -3,7 +3,7 @@ use hex_assignments::assignment::HexAssignments; use rust_decimal::Decimal; use rust_decimal_macros::dec; -use crate::{BoostedHexStatus, RadioType, Result}; +use crate::{OracleBoostingStatus, RadioType, Result, SpBoostedHexStatus}; /// Breakdown of points for a hex. /// @@ -58,9 +58,9 @@ pub struct CoveredHex { pub(crate) fn clean_covered_hexes( radio_type: RadioType, - boosted_hex_status: BoostedHexStatus, + boosted_hex_status: SpBoostedHexStatus, ranked_coverage: Vec, - hip131_ban: bool, + oracle_boosting_status: OracleBoostingStatus, ) -> Result> { // verify all hexes can obtain a base coverage point let covered_hexes = ranked_coverage @@ -75,9 +75,10 @@ pub(crate) fn clean_covered_hexes( None }; + // hip-131: if the radio is banned, it automatically gets an assignment_multiplier of 0.0 // hip-103: if a hex is boosted by a service provider >=1x, the oracle // multiplier will automatically be 1x, regardless of boosted_hex_status. - let assignment_multiplier = if hip131_ban { + let assignment_multiplier = if oracle_boosting_status == OracleBoostingStatus::Banned { dec!(0) } else if ranked.boosted.is_some() { dec!(1) @@ -135,11 +136,11 @@ mod tests { use super::*; #[rstest] - #[case(BoostedHexStatus::Eligible)] - #[case(BoostedHexStatus::WifiLocationScoreBelowThreshold(dec!(999)))] - #[case(BoostedHexStatus::RadioThresholdNotMet)] + #[case(SpBoostedHexStatus::Eligible)] + #[case(SpBoostedHexStatus::WifiLocationScoreBelowThreshold(dec!(999)))] + #[case(SpBoostedHexStatus::RadioThresholdNotMet)] fn hip_103_provider_boosted_hex_receives_maximum_oracle_boost( - #[case] boost_status: BoostedHexStatus, + #[case] boost_status: SpBoostedHexStatus, ) { // Regardless of the radio's eligibility to receive provider boosted // rewards, a boosted hex increases the oracle assignment. @@ -165,7 +166,7 @@ mod tests { RadioType::IndoorWifi, boost_status, vec![unboosted_coverage, boosted_coverage], - false, + OracleBoostingStatus::Eligible, ) .unwrap(); @@ -202,9 +203,9 @@ mod tests { let covered_hexes = clean_covered_hexes( RadioType::IndoorWifi, - BoostedHexStatus::Eligible, + SpBoostedHexStatus::Eligible, vec![unboosted_coverage, boosted_coverage], - true, + OracleBoostingStatus::Banned, ) .unwrap(); diff --git a/coverage_point_calculator/src/lib.rs b/coverage_point_calculator/src/lib.rs index aa831c9a8..35f708105 100644 --- a/coverage_point_calculator/src/lib.rs +++ b/coverage_point_calculator/src/lib.rs @@ -48,6 +48,10 @@ //! - Radio must pass at least 1mb of data from 3 unique phones [HIP-84][provider-boosting] //! - Service Provider can invalidate boosted rewards of a hotspot [HIP-125][provider-banning] //! +//! - [OracleBoostingStatus] +//! - Eligible: Radio is eligible for normal oracle boosting multipliers +//! - Banned: Radio is banned according to hip-131 rules and all assignment_multipliers are 0.0 +//! //! [modeled-coverage]: https://github.com/helium/HIP/blob/main/0074-mobile-poc-modeled-coverage-rewards.md#outdoor-radios //! [provider-boosting]: https://github.com/helium/HIP/blob/main/0084-service-provider-hex-boosting.md //! [wifi-aps]: https://github.com/helium/HIP/blob/main/0093-addition-of-wifi-aps-to-mobile-subdao.md @@ -135,7 +139,7 @@ pub struct CoveragePoints { /// Input ServiceProviderBoostedRewardEligibility pub service_provider_boosted_reward_eligibility: SPBoostedRewardEligibility, /// Derived Eligibility for Boosted Hex Rewards - pub boosted_hex_eligibility: BoostedHexStatus, + pub boosted_hex_eligibility: SpBoostedHexStatus, /// Speedtests used in calculation pub speedtests: Vec, /// Location Trust Scores used in calculation @@ -153,19 +157,24 @@ impl CoveragePoints { speedtests: Vec, location_trust_scores: Vec, ranked_coverage: Vec, - hip131_ban: bool, + oracle_boosting_status: OracleBoostingStatus, ) -> Result { let location_trust_multiplier = location::multiplier(radio_type, &location_trust_scores); - let boost_eligibility = BoostedHexStatus::new( + let boost_eligibility = SpBoostedHexStatus::new( radio_type, location_trust_multiplier, &location_trust_scores, service_provider_boosted_reward_eligibility, ); - let covered_hexes = - hexes::clean_covered_hexes(radio_type, boost_eligibility, ranked_coverage, hip131_ban)?; + let covered_hexes = hexes::clean_covered_hexes( + radio_type, + boost_eligibility, + ranked_coverage, + oracle_boosting_status, + )?; + let hex_coverage_points = hexes::calculated_coverage_points(&covered_hexes); let speedtests = speedtest::clean_speedtests(speedtests); @@ -222,17 +231,23 @@ impl CoveragePoints { fn boosted_points(&self) -> Decimal { match self.boosted_hex_eligibility { - BoostedHexStatus::Eligible => self.coverage_points.boosted, - BoostedHexStatus::WifiLocationScoreBelowThreshold(_) => dec!(0), - BoostedHexStatus::AverageAssertedDistanceOverLimit(_) => dec!(0), - BoostedHexStatus::RadioThresholdNotMet => dec!(0), - BoostedHexStatus::ServiceProviderBanned => dec!(0), + SpBoostedHexStatus::Eligible => self.coverage_points.boosted, + SpBoostedHexStatus::WifiLocationScoreBelowThreshold(_) => dec!(0), + SpBoostedHexStatus::AverageAssertedDistanceOverLimit(_) => dec!(0), + SpBoostedHexStatus::RadioThresholdNotMet => dec!(0), + SpBoostedHexStatus::ServiceProviderBanned => dec!(0), } } } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum BoostedHexStatus { +pub enum OracleBoostingStatus { + Eligible, + Banned, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum SpBoostedHexStatus { Eligible, WifiLocationScoreBelowThreshold(Decimal), AverageAssertedDistanceOverLimit(Decimal), @@ -240,7 +255,7 @@ pub enum BoostedHexStatus { ServiceProviderBanned, } -impl BoostedHexStatus { +impl SpBoostedHexStatus { fn new( radio_type: RadioType, location_trust_multiplier: Decimal, @@ -375,7 +390,7 @@ mod tests { assignments: assignments_from(Assignment::C), boosted: NonZeroU32::new(boost_multiplier), }], - false, + OracleBoostingStatus::Eligible, ) .unwrap(); @@ -401,7 +416,7 @@ mod tests { assignments: assignments_maximum(), boosted: NonZeroU32::new(5), }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi with location scores") }; @@ -438,7 +453,7 @@ mod tests { assignments: assignments_maximum(), boosted: NonZeroU32::new(5), }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi with location scores") }; @@ -477,7 +492,7 @@ mod tests { assignments: assignments_maximum(), boosted: NonZeroU32::new(5), }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi with location scores") }; @@ -514,7 +529,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor cbrs with speedtests") }; @@ -630,7 +645,7 @@ mod tests { ranked_coverage(C, B, C), // 0 ranked_coverage(C, C, C), // 0 ], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor cbrs"); @@ -661,7 +676,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("outdoor wifi"); @@ -711,7 +726,7 @@ mod tests { boosted: None, }, ], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi"); @@ -735,7 +750,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi"); @@ -772,7 +787,7 @@ mod tests { speedtest_maximum(), location_trust_maximum(), covered_hexes.clone(), - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi"); @@ -804,7 +819,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("outdoor cbrs"); @@ -832,7 +847,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor cbrs"); @@ -862,7 +877,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor cbrs"); @@ -890,7 +905,7 @@ mod tests { assignments: assignments_maximum(), boosted: None, }], - false, + OracleBoostingStatus::Eligible, ) .expect("indoor wifi"); @@ -905,7 +920,7 @@ mod tests { }]; let wifi_bad_trust_score = |sp_status: SPBoostedRewardEligibility| { - BoostedHexStatus::new( + SpBoostedHexStatus::new( RadioType::IndoorWifi, location::multiplier(RadioType::IndoorWifi, &bad_location), &bad_location, @@ -915,15 +930,15 @@ mod tests { assert_eq!( wifi_bad_trust_score(SPBoostedRewardEligibility::Eligible), - BoostedHexStatus::WifiLocationScoreBelowThreshold(dec!(0)), + SpBoostedHexStatus::WifiLocationScoreBelowThreshold(dec!(0)), ); assert_eq!( wifi_bad_trust_score(SPBoostedRewardEligibility::ServiceProviderBanned), - BoostedHexStatus::ServiceProviderBanned + SpBoostedHexStatus::ServiceProviderBanned ); assert_eq!( wifi_bad_trust_score(SPBoostedRewardEligibility::RadioThresholdNotMet), - BoostedHexStatus::RadioThresholdNotMet + SpBoostedHexStatus::RadioThresholdNotMet ); } diff --git a/coverage_point_calculator/tests/coverage_point_calculator.rs b/coverage_point_calculator/tests/coverage_point_calculator.rs index a960f269c..b7027ac92 100644 --- a/coverage_point_calculator/tests/coverage_point_calculator.rs +++ b/coverage_point_calculator/tests/coverage_point_calculator.rs @@ -3,8 +3,8 @@ use std::num::NonZeroU32; use chrono::Utc; use coverage_map::{BoostedHexMap, RankedCoverage, SignalLevel, UnrankedCoverage}; use coverage_point_calculator::{ - BytesPs, CoveragePoints, LocationTrust, RadioType, Result, SPBoostedRewardEligibility, - Speedtest, SpeedtestTier, + BytesPs, CoveragePoints, LocationTrust, OracleBoostingStatus, RadioType, Result, + SPBoostedRewardEligibility, Speedtest, SpeedtestTier, }; use hex_assignments::{assignment::HexAssignments, Assignment}; use rust_decimal_macros::dec; @@ -56,7 +56,7 @@ fn base_radio_coverage_points() { speedtests.clone(), location_trust_scores.clone(), hexes.clone(), - false, + OracleBoostingStatus::Eligible, ) .unwrap(); @@ -118,7 +118,7 @@ fn radios_with_coverage() { default_speedtests.clone(), default_location_trust_scores.clone(), base_hex_iter.clone().take(num_hexes).collect(), - false, + OracleBoostingStatus::Eligible, ) .unwrap(); @@ -257,7 +257,7 @@ fn cbrs_outdoor_with_mixed_signal_level_coverage() -> Result { top_ranked_coverage(0x8c2681a30648bff, SignalLevel::Low), top_ranked_coverage(0x8c2681a30646bff, SignalLevel::Low), ], - false, + OracleBoostingStatus::Eligible, ) .unwrap(); @@ -379,7 +379,7 @@ fn indoor_cbrs_radio( Speedtest::mock(speedtest_tier), vec![], coverage.to_owned(), - false, + OracleBoostingStatus::Eligible, ) } @@ -393,7 +393,7 @@ fn outdoor_cbrs_radio( Speedtest::mock(speedtest_tier), vec![], coverage.to_owned(), - false, + OracleBoostingStatus::Eligible, ) } diff --git a/mobile_verifier/src/reward_shares.rs b/mobile_verifier/src/reward_shares.rs index 4ede3846e..2231abedf 100644 --- a/mobile_verifier/src/reward_shares.rs +++ b/mobile_verifier/src/reward_shares.rs @@ -10,7 +10,7 @@ use crate::{ subscriber_verified_mapping_event::VerifiedSubscriberVerifiedMappingEventShares, }; use chrono::{DateTime, Duration, Utc}; -use coverage_point_calculator::SPBoostedRewardEligibility; +use coverage_point_calculator::{OracleBoostingStatus, SPBoostedRewardEligibility}; use file_store::traits::TimestampEncode; use futures::{Stream, StreamExt}; use helium_crypto::PublicKeyBinary; @@ -643,7 +643,7 @@ impl CoverageShares { fn coverage_points( &self, radio_id: &RadioId, - banned: bool, + oracle_boosting_status: OracleBoostingStatus, ) -> anyhow::Result { let radio_info = self.radio_infos.get(radio_id).unwrap(); @@ -662,7 +662,7 @@ impl CoverageShares { radio_info.speedtests.clone(), radio_info.trust_scores.clone(), hexes, - banned, + oracle_boosting_status, )?; Ok(coverage_points) @@ -687,9 +687,13 @@ impl CoverageShares { let mut processed_radios = vec![]; for (radio_id, radio_info) in self.radio_infos.iter() { let (pubkey, cbsd_id) = radio_id; - let banned = banned_radios.contains(pubkey, cbsd_id.as_deref()); + let oracle_boosting_status = if banned_radios.contains(pubkey, cbsd_id.as_deref()) { + OracleBoostingStatus::Banned + } else { + OracleBoostingStatus::Eligible + }; - let points = match self.coverage_points(radio_id, banned) { + let points = match self.coverage_points(radio_id, oracle_boosting_status) { Ok(points) => points, Err(err) => { tracing::error!( @@ -748,7 +752,7 @@ impl CoverageShares { /// Only used for testing pub fn test_hotspot_reward_shares(&self, hotspot: &RadioId) -> Decimal { - self.coverage_points(hotspot, false) + self.coverage_points(hotspot, OracleBoostingStatus::Eligible) .expect("reward shares for hotspot") .total_shares() } diff --git a/mobile_verifier/src/reward_shares/radio_reward_v2.rs b/mobile_verifier/src/reward_shares/radio_reward_v2.rs index bb7344f0a..629e3ce13 100644 --- a/mobile_verifier/src/reward_shares/radio_reward_v2.rs +++ b/mobile_verifier/src/reward_shares/radio_reward_v2.rs @@ -59,17 +59,17 @@ impl RadioRewardV2Ext for coverage_point_calculator::CoveragePoints { fn proto_boosted_hex_status(&self) -> BoostedHexStatus { match self.boosted_hex_eligibility { - coverage_point_calculator::BoostedHexStatus::Eligible => BoostedHexStatus::Eligible, - coverage_point_calculator::BoostedHexStatus::WifiLocationScoreBelowThreshold(_) => { + coverage_point_calculator::SpBoostedHexStatus::Eligible => BoostedHexStatus::Eligible, + coverage_point_calculator::SpBoostedHexStatus::WifiLocationScoreBelowThreshold(_) => { BoostedHexStatus::LocationScoreBelowThreshold } - coverage_point_calculator::BoostedHexStatus::RadioThresholdNotMet => { + coverage_point_calculator::SpBoostedHexStatus::RadioThresholdNotMet => { BoostedHexStatus::RadioThresholdNotMet } - coverage_point_calculator::BoostedHexStatus::ServiceProviderBanned => { + coverage_point_calculator::SpBoostedHexStatus::ServiceProviderBanned => { BoostedHexStatus::ServiceProviderBan } - coverage_point_calculator::BoostedHexStatus::AverageAssertedDistanceOverLimit(_) => { + coverage_point_calculator::SpBoostedHexStatus::AverageAssertedDistanceOverLimit(_) => { BoostedHexStatus::AverageAssertedDistanceOverLimit } }