diff --git a/src/common/gas_fee_strategy.rs b/src/common/gas_fee_strategy.rs index c6275b7..a852dfd 100644 --- a/src/common/gas_fee_strategy.rs +++ b/src/common/gas_fee_strategy.rs @@ -1,7 +1,7 @@ use crate::swqos::{SwqosType, TradeType}; use arc_swap::ArcSwap; use std::collections::HashMap; -use std::sync::{Arc, OnceLock}; +use std::sync::{Arc, LazyLock}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum GasFeeStrategyType { @@ -23,30 +23,15 @@ pub struct GasFeeStrategyValue { pub tip: f64, } -#[derive(Debug)] -pub struct GasFeeStrategy { - strategies: ArcSwap>, - enabled_types: ArcSwap>>, - swqos_disabled_types: ArcSwap>>, -} +// 静态存储策略数据 +static STRATEGIES: LazyLock< + ArcSwap>, +> = LazyLock::new(|| ArcSwap::from_pointee(HashMap::new())); -static INSTANCE: OnceLock> = OnceLock::new(); +pub struct GasFeeStrategy; impl GasFeeStrategy { - pub fn instance() -> Arc { - INSTANCE.get_or_init(|| Arc::new(GasFeeStrategy::new())).clone() - } - - fn new() -> Self { - Self { - strategies: ArcSwap::new(Arc::new(HashMap::new())), - enabled_types: ArcSwap::new(Arc::new(HashMap::new())), - swqos_disabled_types: ArcSwap::new(Arc::new(HashMap::new())), - } - } - pub fn add_high_low_fee_strategies( - &self, swqos_types: &[SwqosType], trade_type: TradeType, cu_limit: u32, @@ -54,8 +39,11 @@ impl GasFeeStrategy { high_cu_price: u64, low_tip: f64, high_tip: f64, - ) -> &Self { - self.strategies.rcu(|current_map| { + ) { + for swqos_type in swqos_types { + GasFeeStrategy::remove_strategy(*swqos_type, trade_type); + } + STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); for swqos_type in swqos_types { if swqos_type.eq(&SwqosType::Default) { @@ -72,11 +60,9 @@ impl GasFeeStrategy { } Arc::new(new_map) }); - self } pub fn add_high_low_fee_strategy( - &self, swqos_type: SwqosType, trade_type: TradeType, cu_limit: u32, @@ -84,11 +70,12 @@ impl GasFeeStrategy { high_cu_price: u64, low_tip: f64, high_tip: f64, - ) -> &Self { + ) { if swqos_type.eq(&SwqosType::Default) { - return self; + return; } - self.strategies.rcu(|current_map| { + GasFeeStrategy::remove_strategy(swqos_type, trade_type); + STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.insert( (swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice), @@ -100,18 +87,19 @@ impl GasFeeStrategy { ); Arc::new(new_map) }); - self } pub fn add_default_fee_strategies( - &self, swqos_types: &[SwqosType], trade_type: TradeType, cu_price: u64, tip: f64, cu_limit: u32, - ) -> &Self { - self.strategies.rcu(|current_map| { + ) { + for swqos_type in swqos_types { + GasFeeStrategy::remove_strategy(*swqos_type, trade_type); + } + STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); for swqos_type in swqos_types { new_map.insert( @@ -121,18 +109,17 @@ impl GasFeeStrategy { } Arc::new(new_map) }); - self } pub fn add_default_fee_strategy( - &self, swqos_type: SwqosType, trade_type: TradeType, cu_price: u64, tip: f64, cu_limit: u32, - ) -> &Self { - self.strategies.rcu(|current_map| { + ) { + GasFeeStrategy::remove_strategy(swqos_type, trade_type); + STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.insert( (swqos_type, trade_type, GasFeeStrategyType::Default), @@ -140,47 +127,22 @@ impl GasFeeStrategy { ); Arc::new(new_map) }); - self } - pub fn remove_default_fee_strategy( - &self, - swqos_type: SwqosType, - trade_type: TradeType, - ) -> &Self { - self.strategies.rcu(|current_map| { + pub fn remove_strategy(swqos_type: SwqosType, trade_type: TradeType) { + STRATEGIES.rcu(|current_map| { let mut new_map = (**current_map).clone(); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::Default)); - Arc::new(new_map) - }); - self - } - - pub fn remove_high_low_fee_strategy( - &self, - swqos_type: SwqosType, - trade_type: TradeType, - ) -> &Self { - self.strategies.rcu(|current_map| { - let mut new_map = (**current_map).clone(); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::LowTipHighCuPrice)); new_map.remove(&(swqos_type, trade_type, GasFeeStrategyType::HighTipLowCuPrice)); Arc::new(new_map) }); - self - } - - pub fn get_all_strategies( - &self, - ) -> HashMap<(SwqosType, TradeType, GasFeeStrategyType), GasFeeStrategyValue> { - (**self.strategies.load()).clone() } pub fn get_strategies( - &self, trade_type: TradeType, ) -> Vec<(SwqosType, GasFeeStrategyType, GasFeeStrategyValue)> { - let strategies = self.strategies.load(); + let strategies = STRATEGIES.load(); let mut result = Vec::new(); let mut swqos_types = std::collections::HashSet::new(); for (swqos_type, t_type, _) in strategies.keys() { @@ -200,81 +162,8 @@ impl GasFeeStrategy { result } - pub fn get_available_strategies( - &self, - trade_type: TradeType, - ) -> Vec<(SwqosType, GasFeeStrategyType, GasFeeStrategyValue)> { - let strategies = self.strategies.load(); - let enabled_types = self.get_enabled_strategy_types(trade_type); - let mut result = Vec::new(); - let mut swqos_types = std::collections::HashSet::new(); - for (swqos_type, t_type, _) in strategies.keys() { - if *t_type == trade_type { - swqos_types.insert(*swqos_type); - } - } - for swqos_type in swqos_types { - let disabled_types = self.get_swqos_disabled_strategy_types(swqos_type, trade_type); - for strategy_type in &enabled_types { - if disabled_types.contains(strategy_type) { - continue; - } - if let Some(strategy_value) = - strategies.get(&(swqos_type, trade_type, *strategy_type)) - { - result.push((swqos_type, *strategy_type, *strategy_value)); - } - } - } - result - } - - pub fn set_enabled_strategy_types( - &self, - trade_type: TradeType, - types: &[GasFeeStrategyType], - ) -> &Self { - self.enabled_types.rcu(|current_map| { - let mut new_map = (**current_map).clone(); - new_map.insert(trade_type, types.to_vec()); - Arc::new(new_map) - }); - self - } - - pub fn get_enabled_strategy_types(&self, trade_type: TradeType) -> Vec { - let strategies = self.enabled_types.load(); - (**strategies).get(&trade_type).cloned().unwrap_or_default() - } - - pub fn set_swqos_disabled_strategy_types( - &self, - swqos_type: SwqosType, - trade_type: TradeType, - types: &[GasFeeStrategyType], - ) -> &Self { - self.swqos_disabled_types.rcu(|current_map| { - let mut new_map = (**current_map).clone(); - new_map.insert((swqos_type, trade_type), types.to_vec()); - Arc::new(new_map) - }); - self - } - - pub fn get_swqos_disabled_strategy_types( - &self, - swqos_type: SwqosType, - trade_type: TradeType, - ) -> Vec { - let disabled_strategies = self.swqos_disabled_types.load(); - (**disabled_strategies).get(&(swqos_type, trade_type)).cloned().unwrap_or_default() - } - - pub fn clear(&self) -> &Self { - self.strategies.store(Arc::new(HashMap::new())); - self.enabled_types.store(Arc::new(HashMap::new())); - self.swqos_disabled_types.store(Arc::new(HashMap::new())); - self + pub fn clear() { + STRATEGIES.store(Arc::new(HashMap::new())); } } @@ -284,33 +173,42 @@ mod tests { #[test] fn demo() { - GasFeeStrategy::instance() - // 给SwqosType::Default在 Buy 时添加默认策略 - .add_default_fee_strategy(SwqosType::Default, TradeType::Buy, 100, 0.0001, 10) - // 给SwqosType::Jito在 Buy 时添加高低价策略 - .add_high_low_fee_strategy(SwqosType::Jito, TradeType::Buy, 10, 100, 10000, 0.001, 0.1) - // 给SwqosType::Jito在 Buy 时添加默认策略 - .add_default_fee_strategy(SwqosType::Jito, TradeType::Buy, 100, 0.0001, 10) - // 设置在 Buy 时启用策略 - 启用两个高低价策略、默认策略 - .set_enabled_strategy_types( - TradeType::Buy, - &[ - GasFeeStrategyType::HighTipLowCuPrice, - GasFeeStrategyType::LowTipHighCuPrice, - GasFeeStrategyType::Default, - ], - ) - // 设置SwqosType::Jito在 Buy 时禁用策略 - 禁用 (默认策略) - .set_swqos_disabled_strategy_types( - SwqosType::Jito, - TradeType::Buy, - &[GasFeeStrategyType::Default], - ); - // 获取在 Buy 时可用的策略 - let strategies = GasFeeStrategy::instance().get_available_strategies(TradeType::Buy); - println!("strategies: {:?}", strategies); - // 获取所有 Buy 策略(包括禁用的) - let all_strategies = GasFeeStrategy::instance().get_strategies(TradeType::Buy); - println!("all_strategies: {:?}", all_strategies); + // 给SwqosType::Default 在 Buy 时添加默认策略 + GasFeeStrategy::add_default_fee_strategy( + SwqosType::Default, + TradeType::Buy, + 100, + 0.0001, + 10, + ); + // 给SwqosType::Jito 在 Buy 时添加高低价策略 + GasFeeStrategy::add_high_low_fee_strategy( + SwqosType::Jito, + TradeType::Buy, + 10, + 100, + 10000, + 0.001, + 0.1, + ); + // 获取所有 Buy 策略 + let all_strategies = GasFeeStrategy::get_strategies(TradeType::Buy); + for strategy in all_strategies { + println!("strategy: {:?}", strategy); + } + println!("--------------------------------"); + // 给SwqosType::Jito 在 Buy 时添加默认策略(会删除 jito 的高低价策略) + GasFeeStrategy::add_default_fee_strategy(SwqosType::Jito, TradeType::Buy, 100, 0.0001, 10); + // 获取所有 Buy 策略 + let all_strategies = GasFeeStrategy::get_strategies(TradeType::Buy); + for strategy in all_strategies { + println!("strategy: {:?}", strategy); + } + // 删除SwqosType::Jito 在 Buy 时的策略 + GasFeeStrategy::remove_strategy(SwqosType::Jito, TradeType::Buy); + // 清空策略 + GasFeeStrategy::clear(); + println!("--------------------------------"); + println!("strategy {:?}", GasFeeStrategy::get_strategies(TradeType::Buy)); } } diff --git a/src/trading/core/parallel.rs b/src/trading/core/parallel.rs index 2edfa47..1d62fdf 100755 --- a/src/trading/core/parallel.rs +++ b/src/trading/core/parallel.rs @@ -10,9 +10,7 @@ use tokio::task::JoinHandle; use crate::{ common::GasFeeStrategy, swqos::{SwqosClient, SwqosType, TradeType}, - trading::{ - common::build_transaction, BuyParams, SellParams, MiddlewareManager, - }, + trading::{common::build_transaction, BuyParams, MiddlewareManager, SellParams}, }; pub async fn buy_parallel_execute( @@ -95,8 +93,11 @@ async fn parallel_execute( with_tip || matches!(swqos_client.get_swqos_type(), SwqosType::Default) }) .flat_map(|(i, swqos_client)| { - let gas_fee_strategy_configs = GasFeeStrategy::instance() - .get_available_strategies(if is_buy { TradeType::Buy } else { TradeType::Sell }); + let gas_fee_strategy_configs = GasFeeStrategy::get_strategies(if is_buy { + TradeType::Buy + } else { + TradeType::Sell + }); gas_fee_strategy_configs .into_iter() .filter(|config| config.0.eq(&swqos_client.get_swqos_type()))