@@ -22,7 +22,7 @@ use rust_decimal::prelude::*;
22
22
use rust_decimal_macros:: dec;
23
23
use solana_sdk:: pubkey:: Pubkey ;
24
24
use sqlx:: { PgPool , Postgres , Transaction } ;
25
- use std:: { num:: NonZeroU32 , str:: FromStr } ;
25
+ use std:: { collections :: HashMap , num:: NonZeroU32 , str:: FromStr } ;
26
26
use uuid:: Uuid ;
27
27
28
28
const HOTSPOT_1 : & str = "112E7TxoNHV46M6tiPA8N1MkeMeQxc9ztb4JQLXBVAAUfq1kJLoF" ;
@@ -1164,6 +1164,99 @@ async fn test_poc_boosted_hex_stack_multiplier(pool: PgPool) -> anyhow::Result<(
1164
1164
Ok ( ( ) )
1165
1165
}
1166
1166
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
+
1167
1260
async fn receive_expected_rewards (
1168
1261
mobile_rewards : & mut MockFileSinkReceiver ,
1169
1262
) -> anyhow:: Result < ( Vec < RadioReward > , UnallocatedReward ) > {
@@ -1813,6 +1906,14 @@ impl HexBoostableRadio {
1813
1906
Self :: new ( pubkey, BoostedHexDeviceType :: CbrsIndoor , location)
1814
1907
}
1815
1908
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
+
1816
1917
fn new ( pubkey : PublicKeyBinary , boost_type : BoostedHexDeviceType , location : Cell ) -> Self {
1817
1918
let ( hb_type, is_indoor, cbsd_id) = match boost_type {
1818
1919
BoostedHexDeviceType :: All => panic ! ( "a radio cannot be all types at once" ) ,
0 commit comments