diff --git a/streamer/src/nonblocking/stream_throttle.rs b/streamer/src/nonblocking/stream_throttle.rs index 7baeab7d5b1646..8cdce0d58d8e06 100644 --- a/streamer/src/nonblocking/stream_throttle.rs +++ b/streamer/src/nonblocking/stream_throttle.rs @@ -252,13 +252,13 @@ pub mod test { DEFAULT_MAX_UNSTAKED_CONNECTIONS, DEFAULT_MAX_STREAMS_PER_MS, )); - // 25K packets per ms * 20% / 500 max unstaked connections + // 50K packets per ms * 20% / 500 max unstaked connections assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Unstaked, 10000, ), - 10 + 20 ); } @@ -272,73 +272,73 @@ pub mod test { // EMA load is used for staked connections to calculate max number of allowed streams. // EMA window = 5ms interval * 10 intervals = 50ms - // max streams per window = 250K streams/sec * 80% = 200K/sec = 10K per 50ms - // max_streams in 50ms = ((10K * 10K) / ema_load) * stake / total_stake + // max streams per window = 500K streams/sec * 80% = 400K/sec = 20K per 50ms + // max_streams in 50ms = ((20K * 20K) / ema_load) * stake / total_stake // // Stream throttling window is 100ms. So it'll double the amount of max streams. - // max_streams in 100ms (throttling window) = 2 * ((10K * 10K) / ema_load) * stake / total_stake + // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / ema_load) * stake / total_stake - load_ema.current_load_ema.store(10000, Ordering::Relaxed); - // ema_load = 10K, stake = 15, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((10K * 10K) / 10K) * 15 / 10K = 30 + load_ema.current_load_ema.store(20000, Ordering::Relaxed); + // ema_load = 20K, stake = 15, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 20K) * 15 / 10K = 60 assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(15), 10000, ), - 30 + 60 ); - // ema_load = 10K, stake = 1K, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((10K * 10K) / 10K) * 1K / 10K = 2K + // ema_load = 20K, stake = 1K, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 20K) * 1K / 10K = 4K assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(1000), 10000, ), - 2000 + 4000 ); - load_ema.current_load_ema.store(2500, Ordering::Relaxed); - // ema_load = 2.5K, stake = 15, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((10K * 10K) / 2.5K) * 15 / 10K = 120 + load_ema.current_load_ema.store(5000, Ordering::Relaxed); + // ema_load = 5K, stake = 15, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 5K) * 15 / 10K = 240 assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(15), 10000, ), - 120 + 240 ); - // ema_load = 2.5K, stake = 1K, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((10K * 10K) / 2.5K) * 1K / 10K = 8000 + // ema_load = 5K, stake = 1K, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 5K) * 1K / 10K = 16000 assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(1000), 10000, ), - 8000 + 16000 ); - // At 2000, the load is less than 25% of max_load (10K). - // Test that we cap it to 25%, yielding the same result as if load was 2500. - load_ema.current_load_ema.store(2000, Ordering::Relaxed); - // function = ((10K * 10K) / 25% of 10K) * stake / total_stake + // At 4000, the load is less than 25% of max_load (20K). + // Test that we cap it to 25%, yielding the same result as if load was 5000. + load_ema.current_load_ema.store(4000, Ordering::Relaxed); + // function = ((20K * 20K) / 25% of 20K) * stake / total_stake assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(15), 10000, ), - 120 + 240 ); - // function = ((10K * 10K) / 25% of 10K) * stake / total_stake + // function = ((20K * 20K) / 25% of 20K) * stake / total_stake assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(1000), 10000, ), - 8000 + 16000 ); // At 1/40000 stake weight, and minimum load, it should still allow @@ -364,69 +364,71 @@ pub mod test { // EMA load is used for staked connections to calculate max number of allowed streams. // EMA window = 5ms interval * 10 intervals = 50ms - // max streams per window = 250K streams/sec = 12.5K per 50ms - // max_streams in 50ms = ((12.5K * 12.5K) / ema_load) * stake / total_stake + // max streams per window = 500K streams/sec = 25K per 50ms + // max_streams in 50ms = ((25K * 25K) / ema_load) * stake / total_stake // // Stream throttling window is 100ms. So it'll double the amount of max streams. - // max_streams in 100ms (throttling window) = 2 * ((12.5K * 12.5K) / ema_load) * stake / total_stake + // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / ema_load) * stake / total_stake - load_ema.current_load_ema.store(10000, Ordering::Relaxed); - // ema_load = 10K, stake = 15, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((12.5K * 12.5K) / 10K) * 15 / 10K = 46.875 + load_ema.current_load_ema.store(20000, Ordering::Relaxed); + // ema_load = 20K, stake = 15, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 20K) * 15 / 10K = 93.75 + // Loss of precision occurs here because max streams is computed for 50ms window and then doubled. assert!( - (46u64..=47).contains(&load_ema.available_load_capacity_in_throttling_duration( + (92u64..=94).contains(&load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(15), 10000 )) ); - // ema_load = 10K, stake = 1K, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((12.5K * 12.5K) / 10K) * 1K / 10K = 3125 - assert!((3124u64..=3125).contains( + // ema_load = 20K, stake = 1K, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 20K) * 1K / 10K = 6250 + assert!((6249u64..=6250).contains( &load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(1000), 10000 ) )); - load_ema.current_load_ema.store(5000, Ordering::Relaxed); - // ema_load = 5K, stake = 15, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((12.5K * 12.5K) / 5K) * 15 / 10K = 93.75 + load_ema.current_load_ema.store(10000, Ordering::Relaxed); + // ema_load = 10K, stake = 15, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 10K) * 15 / 10K = 187.5 + // Loss of precision occurs here because max streams is computed for 50ms window and then doubled. assert!( - (92u64..=94).contains(&load_ema.available_load_capacity_in_throttling_duration( + (186u64..=188).contains(&load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(15), 10000 )) ); - // ema_load = 5K, stake = 1K, total_stake = 10K - // max_streams in 100ms (throttling window) = 2 * ((12.5K * 12.5K) / 5K) * 1K / 10K = 6250 - assert!((6248u64..=6250).contains( + // ema_load = 10K, stake = 1K, total_stake = 10K + // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 10K) * 1K / 10K = 12500 + assert!((12499u64..=12500).contains( &load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(1000), 10000 ) )); - // At 2000, the load is less than 25% of max_load (12.5K). - // Test that we cap it to 25%, yielding the same result as if load was 12.5K/4. - load_ema.current_load_ema.store(2000, Ordering::Relaxed); - // function = ((10K * 10K) / 25% of 12.5K) * stake / total_stake + // At 4000, the load is less than 25% of max_load (25K). + // Test that we cap it to 25%, yielding the same result as if load was 25K/4. + load_ema.current_load_ema.store(4000, Ordering::Relaxed); + // function = ((20K * 20K) / 25% of 25K) * stake / total_stake assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(15), 10000 ), - 150 + 300 ); - // function = ((12.5K * 12.5K) / 25% of 12.5K) * stake / total_stake + // function = ((25K * 25K) / 25% of 25K) * stake / total_stake assert_eq!( load_ema.available_load_capacity_in_throttling_duration( ConnectionPeerType::Staked(1000), 10000 ), - 10000 + 20000 ); // At 1/400000 stake weight, and minimum load, it should still allow diff --git a/streamer/src/quic.rs b/streamer/src/quic.rs index 22ccdc00ba2519..9681b3209477b1 100644 --- a/streamer/src/quic.rs +++ b/streamer/src/quic.rs @@ -48,8 +48,8 @@ pub const MAX_UNSTAKED_CONNECTIONS: usize = 500; pub const DEFAULT_MAX_UNSTAKED_CONNECTIONS: usize = 500; -/// Limit to 250K PPS -pub const DEFAULT_MAX_STREAMS_PER_MS: u64 = 250; +/// Limit to 500K PPS +pub const DEFAULT_MAX_STREAMS_PER_MS: u64 = 500; /// The new connections per minute from a particular IP address. /// Heuristically set to the default maximum concurrent connections