diff --git a/quic-client/src/nonblocking/quic_client.rs b/quic-client/src/nonblocking/quic_client.rs index 6a60a8b2a4247a..606db52e520ee1 100644 --- a/quic-client/src/nonblocking/quic_client.rs +++ b/quic-client/src/nonblocking/quic_client.rs @@ -19,7 +19,7 @@ use { solana_measure::measure::Measure, solana_net_utils::{SocketConfig, VALIDATOR_PORT_RANGE}, solana_quic_definitions::{ - QUIC_CONNECTION_HANDSHAKE_TIMEOUT, QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT, + QUIC_CONNECTION_HANDSHAKE_TIMEOUT, QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT, QUIC_SEND_FAIRNESS, }, solana_rpc_client_api::client_error::ErrorKind as ClientErrorKind, solana_streamer::nonblocking::quic::ALPN_TPU_PROTOCOL_ID, @@ -105,6 +105,7 @@ impl QuicLazyInitializedEndpoint { let timeout = IdleTimeout::try_from(QUIC_MAX_TIMEOUT).unwrap(); transport_config.max_idle_timeout(Some(timeout)); transport_config.keep_alive_interval(Some(QUIC_KEEP_ALIVE)); + transport_config.send_fairness(QUIC_SEND_FAIRNESS); config.transport_config(Arc::new(transport_config)); endpoint.set_default_client_config(config); diff --git a/sdk/quic-definitions/src/lib.rs b/sdk/quic-definitions/src/lib.rs index cb3385991e3242..244073216b49ec 100644 --- a/sdk/quic-definitions/src/lib.rs +++ b/sdk/quic-definitions/src/lib.rs @@ -19,6 +19,14 @@ pub const QUIC_MAX_STAKED_CONCURRENT_STREAMS: usize = 512; pub const QUIC_MAX_TIMEOUT: Duration = Duration::from_secs(2); pub const QUIC_KEEP_ALIVE: Duration = Duration::from_secs(1); +// Disable Quic send fairness. +// When set to false, streams are still scheduled based on priority, +// but once a chunk of a stream has been written out, quinn tries to complete +// the stream instead of trying to round-robin balance it among the streams +// with the same priority. +// See https://github.com/quinn-rs/quinn/pull/2002. +pub const QUIC_SEND_FAIRNESS: bool = false; + // Based on commonly-used handshake timeouts for various TCP // applications. Different applications vary, but most seem to // be in the 30-60 second range diff --git a/streamer/src/nonblocking/testing_utilities.rs b/streamer/src/nonblocking/testing_utilities.rs index 0e74f28b190551..b3c9b73fec9024 100644 --- a/streamer/src/nonblocking/testing_utilities.rs +++ b/streamer/src/nonblocking/testing_utilities.rs @@ -20,7 +20,7 @@ use { solana_keypair::Keypair, solana_net_utils::bind_to_localhost, solana_perf::packet::PacketBatch, - solana_quic_definitions::{QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT}, + solana_quic_definitions::{QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT, QUIC_SEND_FAIRNESS}, solana_tls_utils::{new_dummy_x509_certificate, tls_client_config_builder}, std::{ net::{SocketAddr, UdpSocket}, @@ -46,6 +46,7 @@ pub fn get_client_config(keypair: &Keypair) -> ClientConfig { let timeout = IdleTimeout::try_from(QUIC_MAX_TIMEOUT).unwrap(); transport_config.max_idle_timeout(Some(timeout)); transport_config.keep_alive_interval(Some(QUIC_KEEP_ALIVE)); + transport_config.send_fairness(QUIC_SEND_FAIRNESS); config.transport_config(Arc::new(transport_config)); config diff --git a/tpu-client-next/src/quic_networking.rs b/tpu-client-next/src/quic_networking.rs index 7aa65d969d8b11..d17e65af54e0f4 100644 --- a/tpu-client-next/src/quic_networking.rs +++ b/tpu-client-next/src/quic_networking.rs @@ -5,7 +5,7 @@ use { crypto::rustls::QuicClientConfig, ClientConfig, Connection, Endpoint, IdleTimeout, TransportConfig, }, - solana_quic_definitions::{QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT}, + solana_quic_definitions::{QUIC_KEEP_ALIVE, QUIC_MAX_TIMEOUT, QUIC_SEND_FAIRNESS}, solana_streamer::nonblocking::quic::ALPN_TPU_PROTOCOL_ID, solana_tls_utils::tls_client_config_builder, std::{net::SocketAddr, sync::Arc}, @@ -35,6 +35,7 @@ pub(crate) fn create_client_config(client_certificate: QuicClientCertificate) -> let timeout = IdleTimeout::try_from(QUIC_MAX_TIMEOUT).unwrap(); res.max_idle_timeout(Some(timeout)); res.keep_alive_interval(Some(QUIC_KEEP_ALIVE)); + res.send_fairness(QUIC_SEND_FAIRNESS); res };