Skip to content

Commit dc181f8

Browse files
add test to ensure boosts only apply to single device types
There is another test for same device types across hexes. This test is for different types in the same hex. The 2nd unboosted hex serves the purpose of giving us a relative baseline so we don't need to hardcode values into the test.
1 parent c9e98cb commit dc181f8

File tree

1 file changed

+102
-1
lines changed

1 file changed

+102
-1
lines changed

mobile_verifier/tests/integrations/hex_boosting.rs

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rust_decimal::prelude::*;
2222
use rust_decimal_macros::dec;
2323
use solana_sdk::pubkey::Pubkey;
2424
use sqlx::{PgPool, Postgres, Transaction};
25-
use std::{num::NonZeroU32, str::FromStr};
25+
use std::{collections::HashMap, num::NonZeroU32, str::FromStr};
2626
use uuid::Uuid;
2727

2828
const HOTSPOT_1: &str = "112E7TxoNHV46M6tiPA8N1MkeMeQxc9ztb4JQLXBVAAUfq1kJLoF";
@@ -1164,6 +1164,99 @@ async fn test_poc_boosted_hex_stack_multiplier(pool: PgPool) -> anyhow::Result<(
11641164
Ok(())
11651165
}
11661166

1167+
#[sqlx::test]
1168+
async fn test_poc_boosted_hex_only_applies_to_device_type(pool: PgPool) -> anyhow::Result<()> {
1169+
// This tests ensures that device specific device types don't affect other device types.
1170+
// There are 2 hexes:
1171+
// - #1 BoostType::CbrsOutdoor at 5x
1172+
// - #2 No Boosts
1173+
//
1174+
// There are 4 radios that all qualify for hex boosting:
1175+
// - CbrsOutdoor in boosted hex
1176+
// - Cbrsoutdoor in unboosted hex
1177+
// - WifiOutdoor in boosted hex
1178+
// - WifiOutdoor in unboosted hex
1179+
//
1180+
// The boosted cbrs radio should have 5x the rewards of the unboosted cbrs radio.
1181+
// The wifi radios should have the same rewards.
1182+
//
1183+
1184+
let (mobile_rewards_client, mut mobile_rewards) = common::create_file_sink();
1185+
let (speedtest_avg_client, _speedtest_avg_server) = common::create_file_sink();
1186+
1187+
let now = Utc::now();
1188+
let epoch = (now - ChronoDuration::hours(24))..now;
1189+
1190+
let boosted_cbrs_pubkey = PublicKeyBinary::from_str(HOTSPOT_1)?;
1191+
let unboosted_cbrs_pubkey = PublicKeyBinary::from_str(HOTSPOT_2)?;
1192+
let wifi_pubkey1 = PublicKeyBinary::from_str(HOTSPOT_3)?;
1193+
let wifi_pubkey2 = PublicKeyBinary::from_str(HOTSPOT_4)?;
1194+
1195+
let boosted_location = Cell::from_raw(0x8a1fb466d2dffff)?;
1196+
let unboosted_location = Cell::from_raw(0x8a1fb46622d7fff)?;
1197+
1198+
let boostable_radios = vec![
1199+
HexBoostableRadio::cbrs_outdoor(boosted_cbrs_pubkey.clone(), boosted_location),
1200+
HexBoostableRadio::cbrs_outdoor(unboosted_cbrs_pubkey.clone(), unboosted_location),
1201+
HexBoostableRadio::wifi_outdoor(wifi_pubkey1.clone(), boosted_location),
1202+
HexBoostableRadio::wifi_outdoor(wifi_pubkey2.clone(), unboosted_location),
1203+
];
1204+
1205+
let mut txn = pool.begin().await?;
1206+
for radio in boostable_radios {
1207+
radio.seed(epoch.start, &mut txn).await?;
1208+
}
1209+
txn.commit().await?;
1210+
update_assignments(&pool).await?;
1211+
1212+
let boosted_hex = BoostedHexInfo {
1213+
location: boosted_location,
1214+
start_ts: None,
1215+
end_ts: None,
1216+
period_length: Duration::days(30),
1217+
multipliers: vec![NonZeroU32::new(5).unwrap()],
1218+
boosted_hex_pubkey: Pubkey::from_str(BOOST_HEX_PUBKEY)?,
1219+
boost_config_pubkey: Pubkey::from_str(BOOST_CONFIG_PUBKEY)?,
1220+
version: 0,
1221+
device_type: BoostedHexDeviceType::CbrsOutdoor,
1222+
};
1223+
1224+
let hex_boosting_client = MockHexBoostingClient::new(vec![boosted_hex]);
1225+
let (_, poc_rewards_map) = tokio::join!(
1226+
rewarder::reward_poc_and_dc(
1227+
&pool,
1228+
&hex_boosting_client,
1229+
&mobile_rewards_client,
1230+
&speedtest_avg_client,
1231+
&epoch,
1232+
dec!(0.0001)
1233+
),
1234+
async move {
1235+
let one = mobile_rewards.receive_radio_reward().await;
1236+
let two = mobile_rewards.receive_radio_reward().await;
1237+
let three = mobile_rewards.receive_radio_reward().await;
1238+
let four = mobile_rewards.receive_radio_reward().await;
1239+
1240+
mobile_rewards.assert_no_messages();
1241+
1242+
vec![one, two, three, four]
1243+
.into_iter()
1244+
.map(|r| (r.hotspot_key.clone(), r))
1245+
.collect::<HashMap<_, _>>()
1246+
}
1247+
);
1248+
1249+
let boosted_cbrs = poc_rewards_map.get(boosted_cbrs_pubkey.as_ref()).unwrap();
1250+
let unboosted_cbrs = poc_rewards_map.get(unboosted_cbrs_pubkey.as_ref()).unwrap();
1251+
let wifi1 = poc_rewards_map.get(wifi_pubkey1.as_ref()).unwrap();
1252+
let wifi2 = poc_rewards_map.get(wifi_pubkey2.as_ref()).unwrap();
1253+
1254+
assert_eq!(5, boosted_cbrs.poc_reward / unboosted_cbrs.poc_reward,);
1255+
assert_eq!(wifi1.poc_reward, wifi2.poc_reward);
1256+
1257+
Ok(())
1258+
}
1259+
11671260
async fn receive_expected_rewards(
11681261
mobile_rewards: &mut MockFileSinkReceiver,
11691262
) -> anyhow::Result<(Vec<RadioReward>, UnallocatedReward)> {
@@ -1813,6 +1906,14 @@ impl HexBoostableRadio {
18131906
Self::new(pubkey, BoostedHexDeviceType::CbrsIndoor, location)
18141907
}
18151908

1909+
fn cbrs_outdoor(pubkey: PublicKeyBinary, location: Cell) -> Self {
1910+
Self::new(pubkey, BoostedHexDeviceType::CbrsOutdoor, location)
1911+
}
1912+
1913+
fn wifi_outdoor(pubkey: PublicKeyBinary, location: Cell) -> Self {
1914+
Self::new(pubkey, BoostedHexDeviceType::WifiOutdoor, location)
1915+
}
1916+
18161917
fn new(pubkey: PublicKeyBinary, boost_type: BoostedHexDeviceType, location: Cell) -> Self {
18171918
let (hb_type, is_indoor, cbsd_id) = match boost_type {
18181919
BoostedHexDeviceType::All => panic!("a radio cannot be all types at once"),

0 commit comments

Comments
 (0)