diff --git a/src/instruction/pumpswap.rs:67:17 b/src/instruction/pumpswap.rs:67:17 new file mode 100644 index 0000000..e69de29 diff --git a/src/lib.rs b/src/lib.rs index d082b73..10c4288 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub mod protos; pub mod swqos; pub mod trading; pub mod utils; +// use solana_program::example_mocks::solana_signature::Signature; use solana_sdk::signer::Signer; pub use solana_streamer_sdk; @@ -22,10 +23,10 @@ use crate::trading::MiddlewareManager; use crate::trading::SellParams; use crate::trading::TradeFactory; use common::{PriorityFee, SolanaRpcClient, TradeConfig}; +use parking_lot::Mutex; use rustls::crypto::{ring::default_provider, CryptoProvider}; use solana_sdk::hash::Hash; -use solana_sdk::{pubkey::Pubkey, signature::Keypair}; -use parking_lot::Mutex; +use solana_sdk::{pubkey::Pubkey, signature::Keypair, signature::Signature}; use std::sync::Arc; use swqos::SwqosClient; @@ -157,7 +158,7 @@ impl SolanaTrade { extension_params: Box, lookup_table_key: Option, wait_transaction_confirmed: bool, - ) -> Result<(), anyhow::Error> { + ) -> Result { if slippage_basis_points.is_none() { println!( "slippage_basis_points is none, use default slippage basis points: {}", @@ -205,9 +206,10 @@ impl SolanaTrade { return Err(anyhow::anyhow!("Invalid protocol params for Trade")); } - executor + let sig = executor .buy_with_tip(buy_params, self.swqos_clients.clone(), self.middleware_manager.clone()) - .await + .await; + sig } /// Execute a sell order for a specified token @@ -249,7 +251,7 @@ impl SolanaTrade { extension_params: Box, lookup_table_key: Option, wait_transaction_confirmed: bool, - ) -> Result<(), anyhow::Error> { + ) -> Result { if slippage_basis_points.is_none() { println!( "slippage_basis_points is none, use default slippage basis points: {}", @@ -301,7 +303,10 @@ impl SolanaTrade { if !with_tip { self.rpc_client.clone() } else { self.swqos_clients.clone() }; // Execute sell based on tip preference - executor.sell_with_tip(sell_params, _swqos_clients, self.middleware_manager.clone()).await + let sig = executor + .sell_with_tip(sell_params, _swqos_clients, self.middleware_manager.clone()) + .await; + sig } /// Execute a sell order for a percentage of the specified token amount @@ -349,23 +354,25 @@ impl SolanaTrade { extension_params: Box, lookup_table_key: Option, wait_transaction_confirmed: bool, - ) -> Result<(), anyhow::Error> { + ) -> Result { if percent == 0 || percent > 100 { return Err(anyhow::anyhow!("Percentage must be between 1 and 100")); } let amount = amount_token * percent / 100; - self.sell( - dex_type, - mint, - amount, - slippage_basis_points, - recent_blockhash, - custom_priority_fee, - with_tip, - extension_params, - lookup_table_key, - wait_transaction_confirmed, - ) - .await + let sig = self + .sell( + dex_type, + mint, + amount, + slippage_basis_points, + recent_blockhash, + custom_priority_fee, + with_tip, + extension_params, + lookup_table_key, + wait_transaction_confirmed, + ) + .await; + sig } } diff --git a/src/lib.rs:306:9 b/src/lib.rs:306:9 new file mode 100644 index 0000000..e69de29 diff --git a/src/trading/core/executor.rs b/src/trading/core/executor.rs index bf759e0..909e2b5 100755 --- a/src/trading/core/executor.rs +++ b/src/trading/core/executor.rs @@ -1,4 +1,5 @@ use anyhow::Result; +use solana_sdk::signature::Signature; use std::{sync::Arc, time::Instant}; use super::{ @@ -32,7 +33,7 @@ impl TradeExecutor for GenericTradeExecutor { params: BuyParams, swqos_clients: Vec>, middleware_manager: Option>, - ) -> Result<()> { + ) -> Result { let mut data_size_limit = params.data_size_limit; if data_size_limit == 0 { data_size_limit = MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT; @@ -55,7 +56,7 @@ impl TradeExecutor for GenericTradeExecutor { println!("Building buy transaction instructions time cost: {:?}", start.elapsed()); // Execute transactions in parallel - parallel_execute_with_tips( + let sig = parallel_execute_with_tips( swqos_clients, params.payer, final_instructions, @@ -71,7 +72,7 @@ impl TradeExecutor for GenericTradeExecutor { ) .await?; - Ok(()) + Ok(sig) } async fn sell_with_tip( @@ -79,7 +80,7 @@ impl TradeExecutor for GenericTradeExecutor { params: SellParams, swqos_clients: Vec>, middleware_manager: Option>, - ) -> Result<()> { + ) -> Result { let start = Instant::now(); // Build instructions directly from params to avoid unnecessary cloning @@ -97,7 +98,7 @@ impl TradeExecutor for GenericTradeExecutor { println!("Building sell transaction instructions time cost: {:?}", start.elapsed()); // Execute transactions in parallel - parallel_execute_with_tips( + let sig = parallel_execute_with_tips( swqos_clients, params.payer, final_instructions, @@ -113,7 +114,7 @@ impl TradeExecutor for GenericTradeExecutor { ) .await?; - Ok(()) + Ok(sig) } fn protocol_name(&self) -> &'static str { diff --git a/src/trading/core/parallel.rs b/src/trading/core/parallel.rs index fae7fd7..ab0ea94 100755 --- a/src/trading/core/parallel.rs +++ b/src/trading/core/parallel.rs @@ -1,6 +1,9 @@ use anyhow::{anyhow, Result}; use solana_hash::Hash; -use solana_sdk::{instruction::Instruction, pubkey::Pubkey, signature::Keypair}; +// use solana_program::example_mocks::solana_signature::Signature; +use solana_sdk::{ + instruction::Instruction, pubkey::Pubkey, signature::Keypair, signature::Signature, +}; use std::{str::FromStr, sync::Arc, time::Instant}; use tokio::sync::mpsc; use tokio::task::JoinHandle; @@ -25,9 +28,9 @@ pub async fn parallel_execute_with_tips( is_buy: bool, wait_transaction_confirmed: bool, with_tip: bool, -) -> Result<()> { +) -> Result { let cores = core_affinity::get_core_ids().unwrap(); - let mut handles: Vec>> = Vec::with_capacity(swqos_clients.len()); + let mut handles: Vec>> = Vec::with_capacity(swqos_clients.len()); if is_buy && (swqos_clients.len() > priority_fee.buy_tip_fees.len() || priority_fee.buy_tip_fees.is_empty()) @@ -103,7 +106,11 @@ pub async fn parallel_execute_with_tips( start.elapsed() ); - Ok::<(), anyhow::Error>(()) + transaction + .signatures + .first() + .ok_or_else(|| anyhow!("Transaction has no signatures")) + .cloned() }); handles.push(handle); @@ -125,13 +132,20 @@ pub async fn parallel_execute_with_tips( let mut errors = Vec::new(); if !wait_transaction_confirmed { - return Ok(()); + if let Some(result) = rx.recv().await { + match result { + Ok(Ok(sig)) => return Ok(sig), + Ok(Err(e)) => errors.push(format!("Task error: {}", e)), + Err(e) => errors.push(format!("Join error: {}", e)), + } + } + return Err(anyhow!("No transaction signature available")); } while let Some(result) = rx.recv().await { match result { - Ok(Ok(_)) => { - return Ok(()); + Ok(Ok(sig)) => { + return Ok(sig); } Ok(Err(e)) => errors.push(format!("Task error: {}", e)), Err(e) => errors.push(format!("Join error: {}", e)), diff --git a/src/trading/core/traits.rs b/src/trading/core/traits.rs index 9801901..c307612 100755 --- a/src/trading/core/traits.rs +++ b/src/trading/core/traits.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use crate::{swqos::SwqosClient, trading::MiddlewareManager}; use anyhow::Result; -use solana_sdk::instruction::Instruction; +use solana_sdk::{instruction::Instruction, signature::Signature}; use super::params::{BuyParams, SellParams}; @@ -15,14 +15,14 @@ pub trait TradeExecutor: Send + Sync { params: BuyParams, swqos_clients: Vec>, middleware_manager: Option>, - ) -> Result<()>; + ) -> Result; /// 使用MEV服务执行卖出交易 async fn sell_with_tip( &self, params: SellParams, swqos_clients: Vec>, middleware_manager: Option>, - ) -> Result<()>; + ) -> Result; /// 获取协议名称 fn protocol_name(&self) -> &'static str; }