Browse Source

allow 4000 unstaked connections in TPU (#8144)

Alex Pyattaev 1 week ago
parent
commit
5d4b65dc17
2 changed files with 26 additions and 33 deletions
  1. 25 32
      streamer/src/nonblocking/stream_throttle.rs
  2. 1 1
      streamer/src/quic.rs

+ 25 - 32
streamer/src/nonblocking/stream_throttle.rs

@@ -1,6 +1,5 @@
 use {
 use {
     crate::{nonblocking::quic::ConnectionPeerType, quic::StreamerStats},
     crate::{nonblocking::quic::ConnectionPeerType, quic::StreamerStats},
-    percentage::Percentage,
     std::{
     std::{
         cmp,
         cmp,
         sync::{
         sync::{
@@ -12,7 +11,6 @@ use {
     tokio::time::sleep,
     tokio::time::sleep,
 };
 };
 
 
-const MAX_UNSTAKED_STREAMS_PERCENT: u64 = 20;
 pub const STREAM_THROTTLING_INTERVAL_MS: u64 = 100;
 pub const STREAM_THROTTLING_INTERVAL_MS: u64 = 100;
 pub const STREAM_THROTTLING_INTERVAL: Duration =
 pub const STREAM_THROTTLING_INTERVAL: Duration =
     Duration::from_millis(STREAM_THROTTLING_INTERVAL_MS);
     Duration::from_millis(STREAM_THROTTLING_INTERVAL_MS);
@@ -20,6 +18,9 @@ const STREAM_LOAD_EMA_INTERVAL_MS: u64 = 5;
 const STREAM_LOAD_EMA_INTERVAL_COUNT: u64 = 10;
 const STREAM_LOAD_EMA_INTERVAL_COUNT: u64 = 10;
 const EMA_WINDOW_MS: u64 = STREAM_LOAD_EMA_INTERVAL_MS * STREAM_LOAD_EMA_INTERVAL_COUNT;
 const EMA_WINDOW_MS: u64 = STREAM_LOAD_EMA_INTERVAL_MS * STREAM_LOAD_EMA_INTERVAL_COUNT;
 
 
+/// Maximum TPS for unstaked connections
+const UNSTAKED_MAX_TPS: u64 = 200;
+
 pub(crate) struct StakedStreamLoadEMA {
 pub(crate) struct StakedStreamLoadEMA {
     current_load_ema: AtomicU64,
     current_load_ema: AtomicU64,
     load_in_recent_interval: AtomicU64,
     load_in_recent_interval: AtomicU64,
@@ -42,18 +43,10 @@ impl StakedStreamLoadEMA {
         max_streams_per_ms: u64,
         max_streams_per_ms: u64,
     ) -> Self {
     ) -> Self {
         let allow_unstaked_streams = max_unstaked_connections > 0;
         let allow_unstaked_streams = max_unstaked_connections > 0;
-        let max_staked_load_in_ema_window = if allow_unstaked_streams {
-            (max_streams_per_ms
-                - Percentage::from(MAX_UNSTAKED_STREAMS_PERCENT).apply_to(max_streams_per_ms))
-                * EMA_WINDOW_MS
-        } else {
-            max_streams_per_ms * EMA_WINDOW_MS
-        };
+        let max_staked_load_in_ema_window = max_streams_per_ms * EMA_WINDOW_MS;
 
 
         let max_unstaked_load_in_throttling_window = if allow_unstaked_streams {
         let max_unstaked_load_in_throttling_window = if allow_unstaked_streams {
-            Percentage::from(MAX_UNSTAKED_STREAMS_PERCENT)
-                .apply_to(max_streams_per_ms * STREAM_THROTTLING_INTERVAL_MS)
-                .saturating_div(max_unstaked_connections as u64)
+            UNSTAKED_MAX_TPS * STREAM_THROTTLING_INTERVAL_MS / 1000
         } else {
         } else {
             0
             0
         };
         };
@@ -287,7 +280,7 @@ pub mod test {
             DEFAULT_MAX_UNSTAKED_CONNECTIONS,
             DEFAULT_MAX_UNSTAKED_CONNECTIONS,
             DEFAULT_MAX_STREAMS_PER_MS,
             DEFAULT_MAX_STREAMS_PER_MS,
         ));
         ));
-        // 50K packets per ms * 20% / 500 max unstaked connections
+        // should be 20 for 200 TPS (as throttling interval is 100ms)
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
                 ConnectionPeerType::Unstaked,
                 ConnectionPeerType::Unstaked,
@@ -307,73 +300,73 @@ pub mod test {
 
 
         // EMA load is used for staked connections to calculate max number of allowed streams.
         // EMA load is used for staked connections to calculate max number of allowed streams.
         // EMA window = 5ms interval * 10 intervals = 50ms
         // EMA window = 5ms interval * 10 intervals = 50ms
-        // max streams per window = 500K streams/sec * 80% = 400K/sec = 20K per 50ms
-        // max_streams in 50ms = ((20K * 20K) / ema_load) * stake / total_stake
+        // max streams per window = 500K = 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.
         // Stream throttling window is 100ms. So it'll double the amount of max streams.
-        // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 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(20000, Ordering::Relaxed);
-        // ema_load = 20K, stake = 15, total_stake = 10K
-        // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 20K) * 15 / 10K  = 60
+        load_ema.current_load_ema.store(10000, Ordering::Relaxed);
+        // ema_load = 20K, stake = 40, total_stake = 10K
+        // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 10K) * 40 / 10K  = 50
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
-                ConnectionPeerType::Staked(15),
+                ConnectionPeerType::Staked(40),
                 10000,
                 10000,
             ),
             ),
-            60
+            500
         );
         );
 
 
         // ema_load = 20K, stake = 1K, total_stake = 10K
         // ema_load = 20K, stake = 1K, total_stake = 10K
-        // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 20K) * 1K / 10K  = 4K
+        // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 10K) * 1000 / 10K  = 50
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
                 ConnectionPeerType::Staked(1000),
                 ConnectionPeerType::Staked(1000),
                 10000,
                 10000,
             ),
             ),
-            4000
+            12500
         );
         );
 
 
         load_ema.current_load_ema.store(5000, Ordering::Relaxed);
         load_ema.current_load_ema.store(5000, Ordering::Relaxed);
         // ema_load = 5K, stake = 15, total_stake = 10K
         // ema_load = 5K, stake = 15, total_stake = 10K
-        // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 5K) * 15 / 10K  = 240
+        // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 10K) * 15 / 10K  = 300
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
                 ConnectionPeerType::Staked(15),
                 ConnectionPeerType::Staked(15),
                 10000,
                 10000,
             ),
             ),
-            240
+            300
         );
         );
 
 
         // ema_load = 5K, stake = 1K, total_stake = 10K
         // ema_load = 5K, stake = 1K, total_stake = 10K
-        // max_streams in 100ms (throttling window) = 2 * ((20K * 20K) / 5K) * 1K / 10K  = 16000
+        // max_streams in 100ms (throttling window) = 2 * ((25K * 25K) / 5K) * 1K / 10K  = 16000
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
                 ConnectionPeerType::Staked(1000),
                 ConnectionPeerType::Staked(1000),
                 10000,
                 10000,
             ),
             ),
-            16000
+            20000
         );
         );
 
 
-        // At 4000, the load is less than 25% of max_load (20K).
+        // 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 5000.
         // 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);
         load_ema.current_load_ema.store(4000, Ordering::Relaxed);
-        // function = ((20K * 20K) / 25% of 20K) * stake / total_stake
+        // function = ((25K * 25K) / 25% of 20K) * stake / total_stake
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
                 ConnectionPeerType::Staked(15),
                 ConnectionPeerType::Staked(15),
                 10000,
                 10000,
             ),
             ),
-            240
+            300
         );
         );
 
 
-        // function = ((20K * 20K) / 25% of 20K) * stake / total_stake
+        // function = ((25K * 25K) / 25% of 20K) * stake / total_stake
         assert_eq!(
         assert_eq!(
             load_ema.available_load_capacity_in_throttling_duration(
             load_ema.available_load_capacity_in_throttling_duration(
                 ConnectionPeerType::Staked(1000),
                 ConnectionPeerType::Staked(1000),
                 10000,
                 10000,
             ),
             ),
-            16000
+            20000
         );
         );
 
 
         // At 1/40000 stake weight, and minimum load, it should still allow
         // At 1/40000 stake weight, and minimum load, it should still allow

+ 1 - 1
streamer/src/quic.rs

@@ -44,7 +44,7 @@ pub const DEFAULT_MAX_QUIC_CONNECTIONS_PER_STAKED_PEER: usize = 8;
 
 
 pub const DEFAULT_MAX_STAKED_CONNECTIONS: usize = 2000;
 pub const DEFAULT_MAX_STAKED_CONNECTIONS: usize = 2000;
 
 
-pub const DEFAULT_MAX_UNSTAKED_CONNECTIONS: usize = 500;
+pub const DEFAULT_MAX_UNSTAKED_CONNECTIONS: usize = 4000;
 
 
 /// Limit to 500K PPS
 /// Limit to 500K PPS
 pub const DEFAULT_MAX_STREAMS_PER_MS: u64 = 500;
 pub const DEFAULT_MAX_STREAMS_PER_MS: u64 = 500;