diff --git a/src/common/gas_fee_strategy.rs b/src/common/gas_fee_strategy.rs index f4d17e6..5ace5c9 100644 --- a/src/common/gas_fee_strategy.rs +++ b/src/common/gas_fee_strategy.rs @@ -300,7 +300,7 @@ impl GasFeeStrategy { pub fn update_buy_tip(&self, buy_tip: f64) { self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); - for ((swqos_type, trade_type, strategy_type), value) in new_map.iter_mut() { + for ((_swqos_type, trade_type, _strategy_type), value) in new_map.iter_mut() { if *trade_type == TradeType::Buy { value.tip = buy_tip; } @@ -314,7 +314,7 @@ impl GasFeeStrategy { pub fn update_sell_tip(&self, sell_tip: f64) { self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); - for ((swqos_type, trade_type, strategy_type), value) in new_map.iter_mut() { + for ((_swqos_type, trade_type, _strategy_type), value) in new_map.iter_mut() { if *trade_type == TradeType::Sell { value.tip = sell_tip; } @@ -328,7 +328,7 @@ impl GasFeeStrategy { pub fn update_buy_cu_price(&self, buy_cu_price: u64) { self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); - for ((swqos_type, trade_type, strategy_type), value) in new_map.iter_mut() { + for ((_swqos_type, trade_type, _strategy_type), value) in new_map.iter_mut() { if *trade_type == TradeType::Buy { value.cu_price = buy_cu_price; } @@ -342,7 +342,7 @@ impl GasFeeStrategy { pub fn update_sell_cu_price(&self, sell_cu_price: u64) { self.strategies.rcu(|current_map| { let mut new_map = (**current_map).clone(); - for ((swqos_type, trade_type, strategy_type), value) in new_map.iter_mut() { + for ((_swqos_type, trade_type, _strategy_type), value) in new_map.iter_mut() { if *trade_type == TradeType::Sell { value.cu_price = sell_cu_price; } diff --git a/src/instruction/utils/pumpswap.rs b/src/instruction/utils/pumpswap.rs index bbaf4e9..c7bb2cc 100644 --- a/src/instruction/utils/pumpswap.rs +++ b/src/instruction/utils/pumpswap.rs @@ -227,6 +227,7 @@ pub async fn find_by_base_mint( sort_results: None, }; let program_id = accounts::AMM_PROGRAM; + #[allow(deprecated)] let accounts = rpc.get_program_accounts_with_config(&program_id, config).await?; if accounts.is_empty() { return Err(anyhow!("No pool found for mint {}", base_mint)); @@ -277,6 +278,7 @@ pub async fn find_by_quote_mint( sort_results: None, }; let program_id = accounts::AMM_PROGRAM; + #[allow(deprecated)] let accounts = rpc.get_program_accounts_with_config(&program_id, config).await?; if accounts.is_empty() { return Err(anyhow!("No pool found for mint {}", quote_mint)); diff --git a/src/lib.rs b/src/lib.rs index d3d65dd..4061708 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ pub mod utils; use crate::common::nonce_cache::DurableNonceInfo; use crate::common::GasFeeStrategy; use crate::common::{TradeConfig, InfrastructureConfig}; +#[cfg(feature = "perf-trace")] use crate::constants::trade::trade::DEFAULT_SLIPPAGE; use crate::constants::SOL_TOKEN_ACCOUNT; use crate::constants::USD1_TOKEN_ACCOUNT; @@ -286,7 +287,13 @@ impl TradingClient { crate::common::fast_fn::fast_init(&payer.pubkey()); if create_wsol_ata { - Self::ensure_wsol_ata(&payer, &infrastructure.rpc).await; + // 在后台异步创建 WSOL ATA,不阻塞启动 + let payer_clone = payer.clone(); + let rpc_clone = infrastructure.rpc.clone(); + tokio::spawn(async move { + Self::ensure_wsol_ata(&payer_clone, &rpc_clone).await; + }); + println!("ℹ️ WSOL ATA 创建已在后台启动,不阻塞机器人启动"); } Self { @@ -309,6 +316,7 @@ impl TradingClient { match rpc.get_account(&wsol_ata).await { Ok(_) => { println!("✅ WSOL ATA已存在: {}", wsol_ata); + return; } Err(_) => { println!("🔨 创建WSOL ATA: {}", wsol_ata); @@ -317,35 +325,87 @@ impl TradingClient { if !create_ata_ixs.is_empty() { use solana_sdk::transaction::Transaction; - let recent_blockhash = rpc.get_latest_blockhash().await.unwrap(); - let tx = Transaction::new_signed_with_payer( - &create_ata_ixs, - Some(&payer.pubkey()), - &[payer.as_ref()], - recent_blockhash, - ); - match rpc.send_and_confirm_transaction(&tx).await { - Ok(signature) => { - println!("✅ WSOL ATA创建成功: {}", signature); + // 重试逻辑:最多尝试3次,每次超时10秒 + const MAX_RETRIES: usize = 3; + const TIMEOUT_SECS: u64 = 10; + let mut last_error = None; + + for attempt in 1..=MAX_RETRIES { + if attempt > 1 { + println!("🔄 重试创建WSOL ATA (第{}/{}次)...", attempt, MAX_RETRIES); + tokio::time::sleep(tokio::time::Duration::from_secs(2)).await; } - Err(e) => { - match rpc.get_account(&wsol_ata).await { - Ok(_) => { + + let recent_blockhash = match rpc.get_latest_blockhash().await { + Ok(hash) => hash, + Err(e) => { + eprintln!("⚠️ 获取最新blockhash失败: {}", e); + last_error = Some(format!("获取blockhash失败: {}", e)); + continue; + } + }; + + let tx = Transaction::new_signed_with_payer( + &create_ata_ixs, + Some(&payer.pubkey()), + &[payer.as_ref()], + recent_blockhash, + ); + + // 使用超时包装 send_and_confirm_transaction + let send_result = tokio::time::timeout( + tokio::time::Duration::from_secs(TIMEOUT_SECS), + rpc.send_and_confirm_transaction(&tx) + ).await; + + match send_result { + Ok(Ok(signature)) => { + println!("✅ WSOL ATA创建成功: {}", signature); + return; + } + Ok(Err(e)) => { + last_error = Some(format!("{}", e)); + + // 检查账户是否实际已存在 + if let Ok(_) = rpc.get_account(&wsol_ata).await { println!( "✅ WSOL ATA已存在(交易失败但账户存在): {}", wsol_ata ); + return; } - Err(_) => { - panic!( - "❌ WSOL ATA创建失败且账户不存在: {}. 错误: {}", - wsol_ata, e - ); + + if attempt < MAX_RETRIES { + eprintln!("⚠️ 第{}次尝试失败: {}", attempt, e); } } + Err(_) => { + last_error = Some(format!("交易确认超时({}秒)", TIMEOUT_SECS)); + eprintln!("⚠️ 第{}次尝试超时", attempt); + } } } + + // 所有重试都失败了 + if let Some(err) = last_error { + eprintln!("❌ WSOL ATA创建失败(已重试{}次): {}", MAX_RETRIES, wsol_ata); + eprintln!(" 错误详情: {}", err); + eprintln!(" 💡 可能原因:"); + eprintln!(" 1. 钱包SOL余额不足(需要约0.002 SOL用于租金豁免)"); + eprintln!(" 2. RPC节点响应超时或网络拥堵"); + eprintln!(" 3. 交易费用不足"); + eprintln!(" 🔧 解决方案:"); + eprintln!(" 1. 给钱包充值至少0.1 SOL"); + eprintln!(" 2. 等待几秒后重试"); + eprintln!(" 3. 检查RPC节点连接"); + eprintln!(" ⚠️ 程序将在5秒后退出,请解决上述问题后重启"); + std::thread::sleep(std::time::Duration::from_secs(5)); + panic!( + "❌ WSOL ATA创建失败且账户不存在: {}. 错误: {}", + wsol_ata, err + ); + } } else { println!("ℹ️ WSOL ATA已存在(无需创建)"); } diff --git a/src/swqos/bloxroute.rs b/src/swqos/bloxroute.rs index 1091045..87f7032 100755 --- a/src/swqos/bloxroute.rs +++ b/src/swqos/bloxroute.rs @@ -111,7 +111,7 @@ impl BloxrouteClient { Ok(()) } - pub async fn send_transactions(&self, trade_type: TradeType, transactions: &Vec, wait_confirmation: bool) -> Result<()> { + pub async fn send_transactions(&self, trade_type: TradeType, transactions: &Vec, _wait_confirmation: bool) -> Result<()> { let start_time = Instant::now(); let body = serde_json::json!({ diff --git a/src/trading/common/transaction_builder.rs b/src/trading/common/transaction_builder.rs index 08eafc8..e03f408 100755 --- a/src/trading/common/transaction_builder.rs +++ b/src/trading/common/transaction_builder.rs @@ -11,14 +11,13 @@ use super::{ }; use crate::{ common::{nonce_cache::DurableNonceInfo, SolanaRpcClient}, - constants::swqos::NODE1_TIP_ACCOUNTS, trading::{MiddlewareManager, core::transaction_pool::{acquire_builder, release_builder}}, }; /// Build standard RPC transaction pub async fn build_transaction( payer: Arc, - rpc: Option>, + _rpc: Option>, unit_limit: u32, unit_price: u64, business_instructions: Vec, diff --git a/src/trading/core/async_executor.rs b/src/trading/core/async_executor.rs index 08679f4..098a126 100644 --- a/src/trading/core/async_executor.rs +++ b/src/trading/core/async_executor.rs @@ -38,6 +38,7 @@ struct TaskResult { success: bool, signature: Signature, error: Option, + #[allow(dead_code)] swqos_type: SwqosType, // 🔧 增加:记录SWQOS类型 landed_on_chain: bool, // 🔧 Whether tx landed on-chain (even if failed) } @@ -349,6 +350,7 @@ pub async fn execute_parallel( let _send_start = Instant::now(); let mut err: Option = None; + #[allow(unused_assignments)] let mut landed_on_chain = false; let success = match swqos_client .send_transaction( diff --git a/src/trading/core/executor.rs b/src/trading/core/executor.rs index fc1a2db..4b901e0 100755 --- a/src/trading/core/executor.rs +++ b/src/trading/core/executor.rs @@ -11,7 +11,7 @@ use crate::{ perf::syscall_bypass::SystemCallBypassManager, trading::core::{ async_executor::execute_parallel, - execution::{ExecutionPath, InstructionProcessor, Prefetch}, + execution::{InstructionProcessor, Prefetch}, traits::TradeExecutor, }, trading::MiddlewareManager,