feat: add global MEV protection and refactor TradeConfig to builder pattern
- Add `mev_protection: bool` to `TradeConfig` and `InfrastructureConfig` (default: false) - Astralane QUIC: switches to port 9000 (MEV-protected endpoint) when enabled - BlockRazor HTTP: uses `mode=sandwichMitigation` query param when enabled - BlockRazor gRPC: uses `mode=sandwichMitigation` when enabled - Add `SWQOS_ENDPOINTS_ASTRALANE_QUIC_MEV` constants (port 9000) to `constants/swqos.rs` - Fix `astralane_quic.rs` IP candidates to use the actual port from the address (supports both 7000 and 9000) - Refactor `TradeConfig` to builder pattern via `TradeConfig::builder()` - Introduce `TradeConfigBuilder` with all optional fields and clear defaults - `TradeConfig::new()` kept as a shortcut (calls `builder().build()`) for backward compatibility - Remove old `with_wsol_ata_config` / `with_check_min_tip` / `with_swqos_cores_from_end` / `with_mev_protection` chain methods - Update all 16 examples to use `TradeConfig::builder()` with commented-out options so users can discover all available settings at a glance - Update README.md and README_CN.md code snippets to use builder pattern 🤖 Generated with [Qoder][https://qoder.com]
This commit is contained in:
+115
-22
@@ -11,6 +11,10 @@ pub struct InfrastructureConfig {
|
||||
pub commitment: CommitmentConfig,
|
||||
/// When true, SWQOS sender threads use the *last* N cores instead of the first N. Reduces contention with main thread / default tokio workers that often use low-numbered cores. Default false.
|
||||
pub swqos_cores_from_end: bool,
|
||||
/// Global MEV protection flag. When true, SWQOS providers that support MEV protection
|
||||
/// (Astralane QUIC port 9000, BlockRazor revert_protection) will use their MEV-protected
|
||||
/// endpoints/modes. Default false.
|
||||
pub mev_protection: bool,
|
||||
}
|
||||
|
||||
impl InfrastructureConfig {
|
||||
@@ -24,6 +28,7 @@ impl InfrastructureConfig {
|
||||
swqos_configs,
|
||||
commitment,
|
||||
swqos_cores_from_end: false,
|
||||
mev_protection: false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +39,7 @@ impl InfrastructureConfig {
|
||||
swqos_configs: config.swqos_configs.clone(),
|
||||
commitment: config.commitment.clone(),
|
||||
swqos_cores_from_end: config.swqos_cores_from_end,
|
||||
mev_protection: config.mev_protection,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +59,7 @@ impl Hash for InfrastructureConfig {
|
||||
self.swqos_configs.hash(state);
|
||||
format!("{:?}", self.commitment).hash(state);
|
||||
self.swqos_cores_from_end.hash(state);
|
||||
self.mev_protection.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +69,7 @@ impl PartialEq for InfrastructureConfig {
|
||||
&& self.swqos_configs == other.swqos_configs
|
||||
&& self.commitment == other.commitment
|
||||
&& self.swqos_cores_from_end == other.swqos_cores_from_end
|
||||
&& self.mev_protection == other.mev_protection
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,52 +91,137 @@ pub struct TradeConfig {
|
||||
pub check_min_tip: bool,
|
||||
/// When true, SWQOS uses the *last* N cores (instead of the first N). Use when main thread / tokio use low-numbered cores to reduce CPU contention. Default false.
|
||||
pub swqos_cores_from_end: bool,
|
||||
/// Global MEV protection flag. When true, SWQOS providers that support MEV protection
|
||||
/// (Astralane QUIC port 9000, BlockRazor sandwichMitigation mode) will use their
|
||||
/// MEV-protected endpoints/modes. Default false (no MEV protection, lower latency).
|
||||
pub mev_protection: bool,
|
||||
}
|
||||
|
||||
impl TradeConfig {
|
||||
/// Create a new TradeConfig using the builder pattern.
|
||||
///
|
||||
/// # Available builder methods
|
||||
/// - `.create_wsol_ata_on_startup(bool)` — check & create WSOL ATA on init (default: true)
|
||||
/// - `.use_seed_optimize(bool)` — seed optimization for ATA ops (default: true)
|
||||
/// - `.log_enabled(bool)` — SDK timing/SWQOS logs (default: true)
|
||||
/// - `.check_min_tip(bool)` — filter SWQOS below min tip (default: false)
|
||||
/// - `.swqos_cores_from_end(bool)` — bind SWQOS to last N cores (default: false)
|
||||
/// - `.mev_protection(bool)` — MEV protection for Astralane/BlockRazor (default: false)
|
||||
///
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// let config = TradeConfig::builder(rpc_url, swqos_configs, commitment)
|
||||
/// .mev_protection(true)
|
||||
/// .check_min_tip(true)
|
||||
/// .log_enabled(false)
|
||||
/// .build();
|
||||
/// ```
|
||||
pub fn builder(
|
||||
rpc_url: String,
|
||||
swqos_configs: Vec<SwqosConfig>,
|
||||
commitment: CommitmentConfig,
|
||||
) -> TradeConfigBuilder {
|
||||
TradeConfigBuilder::new(rpc_url, swqos_configs, commitment)
|
||||
}
|
||||
|
||||
/// Shortcut: create a TradeConfig with all defaults. Equivalent to `builder(...).build()`.
|
||||
pub fn new(
|
||||
rpc_url: String,
|
||||
swqos_configs: Vec<SwqosConfig>,
|
||||
commitment: CommitmentConfig,
|
||||
) -> Self {
|
||||
if crate::common::sdk_log::sdk_log_enabled() {
|
||||
println!("🔧 TradeConfig create_wsol_ata_on_startup default: true");
|
||||
println!("🔧 TradeConfig use_seed_optimize default: true");
|
||||
}
|
||||
Self::builder(rpc_url, swqos_configs, commitment).build()
|
||||
}
|
||||
}
|
||||
|
||||
/// Builder for [`TradeConfig`]. Created via [`TradeConfig::builder`].
|
||||
///
|
||||
/// All fields are optional and pre-filled with sensible defaults.
|
||||
/// Call `.build()` to produce the final [`TradeConfig`].
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TradeConfigBuilder {
|
||||
rpc_url: String,
|
||||
swqos_configs: Vec<SwqosConfig>,
|
||||
commitment: CommitmentConfig,
|
||||
create_wsol_ata_on_startup: bool,
|
||||
use_seed_optimize: bool,
|
||||
log_enabled: bool,
|
||||
check_min_tip: bool,
|
||||
swqos_cores_from_end: bool,
|
||||
mev_protection: bool,
|
||||
}
|
||||
|
||||
impl TradeConfigBuilder {
|
||||
fn new(rpc_url: String, swqos_configs: Vec<SwqosConfig>, commitment: CommitmentConfig) -> Self {
|
||||
Self {
|
||||
rpc_url,
|
||||
swqos_configs,
|
||||
commitment,
|
||||
create_wsol_ata_on_startup: true, // default: check and create on startup
|
||||
use_seed_optimize: true, // default: use seed optimization
|
||||
log_enabled: true, // default: enable all SDK logs
|
||||
check_min_tip: false, // default: skip min tip check to reduce latency
|
||||
create_wsol_ata_on_startup: true,
|
||||
use_seed_optimize: true,
|
||||
log_enabled: true,
|
||||
check_min_tip: false,
|
||||
swqos_cores_from_end: false,
|
||||
mev_protection: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a TradeConfig with custom WSOL ATA settings
|
||||
pub fn with_wsol_ata_config(
|
||||
mut self,
|
||||
create_wsol_ata_on_startup: bool,
|
||||
use_seed_optimize: bool,
|
||||
) -> Self {
|
||||
self.create_wsol_ata_on_startup = create_wsol_ata_on_startup;
|
||||
self.use_seed_optimize = use_seed_optimize;
|
||||
/// Check and create WSOL ATA on SDK initialization. Default: `true`.
|
||||
pub fn create_wsol_ata_on_startup(mut self, v: bool) -> Self {
|
||||
self.create_wsol_ata_on_startup = v;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set whether to check minimum tip per SWQOS (filter out configs below min). Default false for lower latency.
|
||||
pub fn with_check_min_tip(mut self, check_min_tip: bool) -> Self {
|
||||
self.check_min_tip = check_min_tip;
|
||||
/// Enable seed optimization for all ATA operations. Default: `true`.
|
||||
pub fn use_seed_optimize(mut self, v: bool) -> Self {
|
||||
self.use_seed_optimize = v;
|
||||
self
|
||||
}
|
||||
|
||||
/// Use the *last* N cores for SWQOS (instead of the first N). Call this when the main thread or tokio workers use low-numbered cores to avoid binding SWQOS to busy cores. Default false.
|
||||
pub fn with_swqos_cores_from_end(mut self, from_end: bool) -> Self {
|
||||
self.swqos_cores_from_end = from_end;
|
||||
/// Enable SDK logs (timing, SWQOS submit/confirm, WSOL, blacklist, etc.). Default: `true`.
|
||||
pub fn log_enabled(mut self, v: bool) -> Self {
|
||||
self.log_enabled = v;
|
||||
self
|
||||
}
|
||||
|
||||
/// Filter out SWQOS providers whose tip is below their minimum requirement.
|
||||
/// Adds a small check on the hot path; disable for lowest latency. Default: `false`.
|
||||
pub fn check_min_tip(mut self, v: bool) -> Self {
|
||||
self.check_min_tip = v;
|
||||
self
|
||||
}
|
||||
|
||||
/// Bind SWQOS sender threads to the *last* N CPU cores instead of the first N.
|
||||
/// Useful when main thread / tokio workers occupy low-numbered cores. Default: `false`.
|
||||
pub fn swqos_cores_from_end(mut self, v: bool) -> Self {
|
||||
self.swqos_cores_from_end = v;
|
||||
self
|
||||
}
|
||||
|
||||
/// Enable global MEV protection. When `true`:
|
||||
/// - **Astralane QUIC** uses port `9000` (MEV-protected endpoint)
|
||||
/// - **BlockRazor** uses `mode=sandwichMitigation` (skips blacklisted Leader slots)
|
||||
///
|
||||
/// May reduce landing speed. Default: `false`.
|
||||
pub fn mev_protection(mut self, v: bool) -> Self {
|
||||
self.mev_protection = v;
|
||||
self
|
||||
}
|
||||
|
||||
/// Consume the builder and produce a [`TradeConfig`].
|
||||
pub fn build(self) -> TradeConfig {
|
||||
TradeConfig {
|
||||
rpc_url: self.rpc_url,
|
||||
swqos_configs: self.swqos_configs,
|
||||
commitment: self.commitment,
|
||||
create_wsol_ata_on_startup: self.create_wsol_ata_on_startup,
|
||||
use_seed_optimize: self.use_seed_optimize,
|
||||
log_enabled: self.log_enabled,
|
||||
check_min_tip: self.check_min_tip,
|
||||
swqos_cores_from_end: self.swqos_cores_from_end,
|
||||
mev_protection: self.mev_protection,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type SolanaRpcClient = solana_client::nonblocking::rpc_client::RpcClient;
|
||||
|
||||
Reference in New Issue
Block a user