release: update Pump program metadata for v4.0.8

This commit is contained in:
0xfnzero
2026-05-15 01:08:33 +08:00
parent 69b4f9bb9f
commit f6db55c874
57 changed files with 4772 additions and 3723 deletions
+4 -4
View File
@@ -1,9 +1,9 @@
use solana_hash::Hash;
use solana_sdk::{
instruction::Instruction, pubkey::Pubkey,
signature::Keypair, signer::Signer, transaction::VersionedTransaction,
};
use solana_message::AddressLookupTableAccount;
use solana_sdk::{
instruction::Instruction, pubkey::Pubkey, signature::Keypair, signer::Signer,
transaction::VersionedTransaction,
};
use solana_system_interface::instruction as system_instruction;
use std::sync::Arc;
+2 -1
View File
@@ -88,7 +88,8 @@ pub async fn transfer_sol(
return Err(anyhow!("Insufficient balance"));
}
let transfer_instruction = system_instruction::transfer(&payer.pubkey(), receive_wallet, amount);
let transfer_instruction =
system_instruction::transfer(&payer.pubkey(), receive_wallet, amount);
let recent_blockhash = rpc.get_latest_blockhash().await?;
+1 -1
View File
@@ -7,7 +7,7 @@ use crate::common::{
spl_token::close_account,
};
use smallvec::SmallVec;
use solana_sdk::{instruction::Instruction, instruction::AccountMeta, pubkey::Pubkey};
use solana_sdk::{instruction::AccountMeta, instruction::Instruction, pubkey::Pubkey};
use solana_system_interface::instruction as system_instruction;
#[inline]
+11 -25
View File
@@ -14,6 +14,7 @@
use anyhow::{anyhow, Result};
use crossbeam_queue::ArrayQueue;
use once_cell::sync::OnceCell;
use parking_lot::Mutex;
use solana_hash::Hash;
use solana_message::AddressLookupTableAccount;
use solana_sdk::{
@@ -21,7 +22,6 @@ use solana_sdk::{
};
use std::collections::HashMap;
use std::hash::BuildHasherDefault;
use parking_lot::Mutex;
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::{
str::FromStr,
@@ -187,11 +187,7 @@ fn ensure_dedicated_pool(
.map(|all_ids| {
sender_thread_cores
.map(|indices| {
indices
.iter()
.take(n)
.filter_map(|&i| all_ids.get(i).cloned())
.collect()
indices.iter().take(n).filter_map(|&i| all_ids.get(i).cloned()).collect()
})
.unwrap_or_else(|| all_ids.into_iter().take(n).collect())
})
@@ -416,8 +412,7 @@ impl ResultCollector {
}
// 「不等待链上确认」仍会等各 SWQOS 的 HTTP 回包;主循环在收齐或触达 `timeout_secs` 后结束。
// 若主窗口到时仍有未回包通道,晚到的 TaskResult 若立刻 drain 会丢签名——仅在该路径上拉长 grace。
let all_submitted =
self.completed_count.load(Ordering::Acquire) >= self.total_tasks;
let all_submitted = self.completed_count.load(Ordering::Acquire) >= self.total_tasks;
if all_submitted {
// 全数已登记:仅留极短 settle,避免极端情况下最后一笔与计数可见性竞态。
tokio::time::sleep(Duration::from_millis(35)).await;
@@ -472,11 +467,8 @@ pub async fn execute_parallel(
let instructions = Arc::new(instructions);
// One get_strategies call per batch (avoid N calls in loop).
let gas_fee_configs = gas_fee_strategy.get_strategies(if is_buy {
TradeType::Buy
} else {
TradeType::Sell
});
let gas_fee_configs =
gas_fee_strategy.get_strategies(if is_buy { TradeType::Buy } else { TradeType::Sell });
let mut task_configs = Vec::with_capacity(swqos_clients.len() * 3);
for (i, swqos_client) in swqos_clients.iter().enumerate() {
if !with_tip && !matches!(swqos_client.get_swqos_type(), SwqosType::Default) {
@@ -589,18 +581,12 @@ pub async fn execute_parallel(
if !wait_transaction_confirmed {
// submit_timeout_secs 为「等齐各 SWQOS HTTP 应答」的上限;收齐后会立刻进入短 settle,不会睡满整段秒数。
// `wait_for_all_submitted` 仅在未收齐时追加长 grace,避免过早 drain 丢晚到签名。
let ret = collector
.wait_for_all_submitted(submit_timeout_secs)
.await
.unwrap_or((
false,
vec![],
Some(anyhow!(
"No SWQOS result within grace window (primary {}s)",
submit_timeout_secs
)),
vec![],
));
let ret = collector.wait_for_all_submitted(submit_timeout_secs).await.unwrap_or((
false,
vec![],
Some(anyhow!("No SWQOS result within grace window (primary {}s)", submit_timeout_secs)),
vec![],
));
let (success, signatures, last_error, submit_timings) = ret;
return Ok((success, signatures, last_error, submit_timings));
}
+35 -13
View File
@@ -1,10 +1,9 @@
use anyhow::Result;
use solana_hash::Hash;
use solana_sdk::{
instruction::Instruction, pubkey::Pubkey,
signature::Keypair, signature::Signature,
};
use solana_message::AddressLookupTableAccount;
use solana_sdk::{
instruction::Instruction, pubkey::Pubkey, signature::Keypair, signature::Signature,
};
use std::{
sync::Arc,
time::{Duration, Instant},
@@ -13,6 +12,7 @@ use std::{
use tracing::{info, trace, warn};
use super::{params::SwapParams, traits::InstructionBuilder};
use crate::swqos::SwqosType;
use crate::swqos::TradeType;
use crate::{
common::{nonce_cache::DurableNonceInfo, GasFeeStrategy, SolanaRpcClient},
@@ -26,7 +26,6 @@ use crate::{
trading::MiddlewareManager,
};
use once_cell::sync::Lazy;
use crate::swqos::{ SwqosType};
/// Global syscall bypass manager (reserved for future time/IO optimizations).
/// 全局系统调用绕过管理器(预留,后续可接入时间/IO 等优化)。
@@ -234,10 +233,7 @@ impl TradeExecutor for GenericTradeExecutor {
);
}
Ok((ok, signatures, err, submit_timings))
};
result
@@ -368,8 +364,20 @@ mod tests {
let before_submit_ms = 15.67;
let w = 12usize; // same as crate::common::sdk_log::SWQOS_LABEL_WIDTH
println!("\n--- 1. 构建指令耗时 / 提交前耗时(各打印一次,统一 ms,保留 4 位小数)---\n");
println!(" [SDK][{:width$}] {} build_instructions: {:.4} ms", "-", dir, build_ms, width = w);
println!(" [SDK][{:width$}] {} before_submit: {:.4} ms", "-", dir, before_submit_ms, width = w);
println!(
" [SDK][{:width$}] {} build_instructions: {:.4} ms",
"-",
dir,
build_ms,
width = w
);
println!(
" [SDK][{:width$}] {} before_submit: {:.4} ms",
"-",
dir,
before_submit_ms,
width = w
);
println!("\n--- 2. 每个 SWQOS 独立耗时:submit_done=起点→该通道提交完成, confirmed=该通道提交→链上确认, total=起点→链上确认 ---\n");
for (swqos_type, submit_ms, confirmed_ms, total_ms) in [
@@ -388,7 +396,9 @@ mod tests {
);
}
println!("\n--- 3. 不等待链上确认时:每行 total = 该通道 submit_done(提交完成总耗时)---\n");
println!(
"\n--- 3. 不等待链上确认时:每行 total = 该通道 submit_done(提交完成总耗时)---\n"
);
for (swqos_type, submit_ms, total_ms) in
[(SwqosType::Jito, 44.20, 44.20), (SwqosType::Helius, 51.80, 51.80)]
{
@@ -403,8 +413,20 @@ mod tests {
}
println!("\n--- 4. Simulate 模式(build/before_submit 仍从 grpc_recv_us 起算)---\n");
println!(" [SDK][{:width$}] {} build_instructions: {:.4} ms", "-", dir, build_ms, width = w);
println!(" [SDK][{:width$}] {} before_submit: {:.4} ms", "-", dir, before_submit_ms, width = w);
println!(
" [SDK][{:width$}] {} build_instructions: {:.4} ms",
"-",
dir,
build_ms,
width = w
);
println!(
" [SDK][{:width$}] {} before_submit: {:.4} ms",
"-",
dir,
before_submit_ms,
width = w
);
println!(" [SDK][{:width$}] {} simulate (dry-run): {:.4} ms", "-", dir, 8.50, width = w);
println!(" [SDK][{:width$}] {} total: {:.4} ms", "-", dir, 36.51, width = w);
println!();
+2 -3
View File
@@ -97,9 +97,8 @@ pub struct SwapParams {
/// When Some(false), uses regular buy instruction where slippage is applied to SOL/quote input.
/// This option only applies to PumpFun and PumpSwap DEXes; it is ignored for other DEXes.
pub use_exact_sol_amount: Option<bool>,
/// Use PumpFun V2 instructions (buy_v2 / sell_v2 / buy_exact_quote_in_v2, 27-account metas, quote_mint support).
/// Default: `false` — uses V1 instructions (18-account metas, legacy SOL-paired).
/// Set to `true` when PumpFun officially deploys V2 on mainnet. Until then, keep `false` for smaller transaction size.
/// Use PumpFun V2 instructions (buy_v2 / sell_v2 / buy_exact_quote_in_v2, 27/26-account metas, quote_mint support).
/// Default: `false` keeps legacy SOL-paired instructions for smaller transactions; V2 is the official future-proof interface.
pub use_pumpfun_v2: bool,
}
+2 -3
View File
@@ -41,9 +41,8 @@ impl MeteoraDammV2Params {
) -> Result<Self, anyhow::Error> {
let pool_data =
crate::instruction::utils::meteora_damm_v2::fetch_pool(rpc, pool_address).await?;
let mint_accounts = rpc
.get_multiple_accounts(&[pool_data.token_a_mint, pool_data.token_b_mint])
.await?;
let mint_accounts =
rpc.get_multiple_accounts(&[pool_data.token_a_mint, pool_data.token_b_mint]).await?;
let token_a_program = mint_accounts
.get(0)
.and_then(|a| a.as_ref())
+43 -33
View File
@@ -5,7 +5,6 @@ use crate::instruction::utils::pumpfun::reconcile_mayhem_mode_for_trade;
use solana_sdk::pubkey::Pubkey;
use std::sync::Arc;
/// PumpFun protocol specific parameters
/// Configuration parameters specific to PumpFun trading protocol.
///
@@ -96,16 +95,19 @@ impl PumpFunParams {
is_mayhem_mode,
is_cashback_coin,
);
let creator_vault_resolved = crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve_account.creator,
creator_vault,
&mint,
None,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve_account.creator)
})
.unwrap_or_default();
let creator_vault_resolved =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve_account.creator,
creator_vault,
&mint,
None,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(
&bonding_curve_account.creator,
)
})
.unwrap_or_default();
Self {
bonding_curve: Arc::new(bonding_curve_account),
associated_bonding_curve: associated_bonding_curve,
@@ -154,16 +156,17 @@ impl PumpFunParams {
is_mayhem_mode,
is_cashback_coin,
);
let creator_vault_resolved = crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve.creator,
creator_vault,
&mint,
None,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator)
})
.unwrap_or_default();
let creator_vault_resolved =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve.creator,
creator_vault,
&mint,
None,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator)
})
.unwrap_or_default();
Self {
bonding_curve: Arc::new(bonding_curve),
associated_bonding_curve: associated_bonding_curve,
@@ -205,16 +208,21 @@ impl PumpFunParams {
&mint_account.owner,
);
let fee_sharing_creator_vault_if_active =
crate::instruction::utils::pumpfun::fetch_fee_sharing_creator_vault_if_active(rpc, mint)
.await?;
let creator_vault = crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve.creator,
Pubkey::default(),
mint,
fee_sharing_creator_vault_if_active,
)
.or_else(|| crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator))
.unwrap_or_default();
crate::instruction::utils::pumpfun::fetch_fee_sharing_creator_vault_if_active(
rpc, mint,
)
.await?;
let creator_vault =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
&bonding_curve.creator,
Pubkey::default(),
mint,
fee_sharing_creator_vault_if_active,
)
.or_else(|| {
crate::instruction::utils::pumpfun::get_creator_vault_pda(&bonding_curve.creator)
})
.unwrap_or_default();
Ok(Self {
bonding_curve: Arc::new(bonding_curve),
associated_bonding_curve: associated_bonding_curve,
@@ -246,8 +254,10 @@ impl PumpFunParams {
mint: &Pubkey,
) -> Result<Self, anyhow::Error> {
self.fee_sharing_creator_vault_if_active =
crate::instruction::utils::pumpfun::fetch_fee_sharing_creator_vault_if_active(rpc, mint)
.await?;
crate::instruction::utils::pumpfun::fetch_fee_sharing_creator_vault_if_active(
rpc, mint,
)
.await?;
let c = self.effective_creator_for_trade();
if let Some(v) =
crate::instruction::utils::pumpfun::resolve_creator_vault_for_ix_with_fee_sharing(
+5 -2
View File
@@ -1,7 +1,7 @@
use crate::swqos::SwqosType;
use crate::trading::SwapParams;
use anyhow::Result;
use solana_sdk::{instruction::Instruction, signature::Signature};
use crate::swqos::{SwqosType};
/// 交易执行器trait - 定义了所有交易协议都需要实现的核心方法
#[async_trait::async_trait]
pub trait TradeExecutor: Send + Sync {
@@ -9,7 +9,10 @@ pub trait TradeExecutor: Send + Sync {
/// - bool: 是否至少有一个交易成功
/// - Vec<Signature>: 所有提交的交易签名(按SWQOS顺序)
/// - Option<anyhow::Error>: 最后一个错误(如果全部失败)
async fn swap(&self, params: SwapParams) -> Result<(bool, Vec<Signature>, Option<anyhow::Error>, Vec<(SwqosType, i64)>)>;
async fn swap(
&self,
params: SwapParams,
) -> Result<(bool, Vec<Signature>, Option<anyhow::Error>, Vec<(SwqosType, i64)>)>;
/// 获取协议名称
fn protocol_name(&self) -> &'static str;
}
+1 -1
View File
@@ -19,13 +19,13 @@ const TX_BUILDER_POOL_PREFILL: usize = 64;
use crossbeam_queue::ArrayQueue;
use once_cell::sync::Lazy;
use solana_message::AddressLookupTableAccount;
use solana_sdk::{
hash::Hash,
instruction::Instruction,
message::{v0, Message, VersionedMessage},
pubkey::Pubkey,
};
use solana_message::AddressLookupTableAccount;
use std::sync::Arc;
/// 预分配的交易构建器
pub struct PreallocatedTxBuilder {