Skip to content

Commit

Permalink
add proptests for service provider rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
michaeldjeffrey committed Sep 30, 2024
1 parent 3e43c5f commit f677951
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 28 deletions.
110 changes: 83 additions & 27 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mobile_verifier/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,4 @@ coverage-map = { path = "../coverage_map" }

[dev-dependencies]
backon = "0"
proptest = "1.5.0"
106 changes: 105 additions & 1 deletion mobile_verifier/src/service_provider/reward.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ mod tests {
use file_store::promotion_reward::Entity;
use helium_proto::services::poc_mobile::{MobileRewardShare, PromotionReward};

use crate::service_provider::promotions::rewards::PromotionRewardShare;
use crate::service_provider::{self, promotions::rewards::PromotionRewardShare};

use super::*;

Expand Down Expand Up @@ -617,4 +617,108 @@ mod tests {
.collect()
}
}

use proptest::prelude::*;

prop_compose! {
fn arb_share()(sp_id in 0..10_i32, ent_id in 0..200u8, shares in 1..=100u64) -> PromotionRewardShare {
PromotionRewardShare {
service_provider_id: sp_id,
rewardable_entity: Entity::SubscriberId(vec![ent_id]),
shares
}
}
}

prop_compose! {
fn arb_dc_session()(
sp_id in 0..10_i32,
// below 1 trillion
dc_session in (0..=1_000_000_000_000_u64).prop_map(Decimal::from)
) -> (i32, Decimal) {
(sp_id, dc_session)
}
}

prop_compose! {
fn arb_fund()(sp_id in 0..10_i32, bps in arb_bps()) -> (i32, u16) {
(sp_id, bps)
}
}

prop_compose! {
fn arb_bps()(bps in 0..=10_000u16) -> u16 { bps }
}

proptest! {
// #![proptest_config(ProptestConfig::with_cases(100_000))]

#[test]
fn single_provider_does_not_overallocate(
dc_session in any::<u64>().prop_map(Decimal::from),
fund_bps in arb_bps(),
shares in prop::collection::vec(arb_share(), 0..10),
total_allocation in any::<u64>().prop_map(Decimal::from)
) {

let sp_infos = ServiceProviderRewardInfos::new(
ServiceProviderDCSessions::from([(0, dc_session)]),
ServiceProviderFunds::from([(0, fund_bps)]),
ServiceProviderPromotions::from(shares),
total_allocation,
dec!(0.00001),
epoch()
);

let total_perc= sp_infos.total_percent();
assert!(total_perc <= dec!(1));

let mut allocated = dec!(0);
for (amount, _) in sp_infos.iter_rewards() {
allocated += Decimal::from(amount);
}
assert!(allocated <= total_allocation);
}

#[test]
fn multiple_provider_does_not_overallocate(
dc_sessions in prop::collection::vec(arb_dc_session(), 0..10),
funds in prop::collection::vec(arb_fund(), 0..10),
promotions in prop::collection::vec(arb_share(), 0..100),
) {
let epoch = epoch();
let total_allocation = service_provider::get_scheduled_tokens(&epoch);

let sp_infos = ServiceProviderRewardInfos::new(
ServiceProviderDCSessions::from(dc_sessions),
ServiceProviderFunds::from(funds),
ServiceProviderPromotions::from(promotions),
total_allocation,
dec!(0.00001),
epoch
);

let total_perc= sp_infos.total_percent();
prop_assert!(total_perc <= dec!(1));

let mut allocated = dec!(0);
for (amount, _) in sp_infos.iter_rewards() {
allocated += Decimal::from(amount);
}
prop_assert!(allocated <= total_allocation);
}

}

impl RewardInfo {
fn total_percent(&self) -> Decimal {
self.realized_dc_perc + self.realized_promo_perc + self.matched_promo_perc
}
}

impl ServiceProviderRewardInfos {
fn total_percent(&self) -> Decimal {
self.coll.iter().map(|x| x.total_percent()).sum()
}
}
}

0 comments on commit f677951

Please sign in to comment.