perf: P0/P1/P2 low-latency and maintainability improvements

P0:
- blockhash/nonce: get_transaction_blockhash returns Result; buy/sell entry validation
- Bonk sell: remove RPC get_token_balance from build path; require caller to pass input_amount
- Hot path: drop redundant dex_type/protocol_params clone; tip via sol_f64_to_lamports (no String)
- compute_budget cache uses Arc; extend_compute_budget_instructions avoids SmallVec clone

P1:
- middleware protocol_name takes &str; executor destructures result once to avoid signatures/submit_timings clone
- Error messages include dex context; params use Copy for Pubkey; pumpswap utils clone only Pool for pools[0]

P2:
- transaction_pool capacity constants; TIP_ACCOUNT_CACHE marked allow(dead_code)
- Fix error copy in raydium_amm_v4 / meteora_damm_v2 to correct protocol names

Made-with: Cursor
This commit is contained in:
Wood
2026-03-08 01:05:27 +08:00
parent e32e7ee6ab
commit 9f79e865ab
17 changed files with 397 additions and 294 deletions
+14 -4
View File
@@ -49,7 +49,11 @@ impl SwqosClientTrait for BlockRazorClient {
impl BlockRazorClient {
pub fn new(rpc_url: String, endpoint: String, auth_token: String) -> Self {
let rpc_client = SolanaRpcClient::new(rpc_url);
let http_client = default_http_client_builder().build().unwrap();
// 官方文档:請求中唯一允許的 header 是 Content-Type: text/plain;避免默认 User-Agent 等导致 500
let http_client = default_http_client_builder()
.user_agent("")
.build()
.unwrap();
let client = Self {
rpc_client: Arc::new(rpc_client),
@@ -127,6 +131,7 @@ impl BlockRazorClient {
}
/// Send transaction via v2 API: plain Base64 body, Content-Type: text/plain. Only required URI param: auth.
/// 文档要求:auth 以 URI 参数传入;body 为纯 Base64 编码交易;唯一允许的 header 为 Content-Type: text/plain。
pub async fn send_transaction(&self, trade_type: TradeType, transaction: &VersionedTransaction, wait_confirmation: bool) -> Result<()> {
let start_time = Instant::now();
let (content, signature) = serialize_transaction_and_encode(transaction, UiTransactionEncoding::Base64)?;
@@ -140,16 +145,21 @@ impl BlockRazorClient {
.await?;
let status = response.status();
let _ = response.bytes().await;
if status.is_success() {
let _ = response.bytes().await;
if crate::common::sdk_log::sdk_log_enabled() {
println!(" [blockrazor] {} submitted: {:?}", trade_type, start_time.elapsed());
}
} else {
let body = response.text().await.unwrap_or_default();
if crate::common::sdk_log::sdk_log_enabled() {
eprintln!(" [blockrazor] {} submission failed: status {}", trade_type, status);
eprintln!(" [blockrazor] {} submission failed: status {} body: {}", trade_type, status, body);
}
return Err(anyhow::anyhow!("BlockRazor sendTransaction failed: {}", status));
return Err(anyhow::anyhow!(
"BlockRazor sendTransaction failed: status {} body: {}",
status,
body
));
}
let start_time = Instant::now();
+2
View File
@@ -77,6 +77,8 @@ use crate::{
};
lazy_static::lazy_static! {
/// Reserved for future per-SWQOS tip account caching (currently unused).
#[allow(dead_code)]
static ref TIP_ACCOUNT_CACHE: RwLock<Vec<String>> = RwLock::new(Vec::new());
}