Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f37950adf | |||
| dd4f42324e | |||
| d0897b53d3 | |||
| e67a21df58 | |||
| 147c6068d1 | |||
| 6ce8ee582e | |||
| bcc6860bc3 | |||
| 1b7e3781c7 |
+1
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "sol-trade-sdk"
|
||||
version = "3.5.0"
|
||||
version = "3.5.3"
|
||||
edition = "2021"
|
||||
authors = [
|
||||
"William <byteblock6@gmail.com>",
|
||||
@@ -19,8 +19,6 @@ members = [
|
||||
"examples/trading_client",
|
||||
"examples/shared_infrastructure",
|
||||
"examples/middleware_system",
|
||||
"examples/pumpfun_copy_trading",
|
||||
"examples/pumpfun_sniper_trading",
|
||||
"examples/pumpswap_trading",
|
||||
"examples/bonk_sniper_trading",
|
||||
"examples/bonk_copy_trading",
|
||||
|
||||
@@ -60,6 +60,23 @@
|
||||
|
||||
---
|
||||
|
||||
## 🆕 What's new in 3.5.3
|
||||
|
||||
- **Full release**: Includes all updates (3.5.2 SWQoS perf + IDL/instruction changes). Use this version.
|
||||
- **SWQoS submit latency**: Sync serialize + buffer-pool hot path; `format!` body for single/batch submit (Bloxroute); avoid status clone in confirmation polling.
|
||||
- **First-submit & 5-min idle**: Immediate first ping + 30s keepalive; `pool_max_idle_per_host=4` and `pool_idle_timeout=300s` (BlockRazor, Temporal, Node1, Astralane, Stellium); ping consumes response body for connection reuse.
|
||||
- **PumpFun / PumpSwap**: IDL updates (pump.json, pump_amm.json); instruction and utils updates for pumpfun and pumpswap; fast_fn and release notes.
|
||||
|
||||
## 🆕 What's new in 3.5.2
|
||||
|
||||
- **SWQoS submit latency**: Sync serialize + buffer-pool hot path; `format!` body for single/batch submit (Bloxroute); avoid status clone in confirmation polling.
|
||||
- **First-submit & 5-min idle**: Immediate first ping + 30s keepalive; `pool_max_idle_per_host=4` and `pool_idle_timeout=300s` (BlockRazor, Temporal, Node1, Astralane, Stellium) so submit reuses the same connection; ping consumes response body for connection reuse.
|
||||
- **Docs**: All SWQoS comments translated to English.
|
||||
|
||||
## 🆕 What's new in 3.5.1
|
||||
|
||||
- **SWQoS / executor**: Updates to common SWQoS logic and trading executor.
|
||||
|
||||
## 🆕 What's new in 3.5.0
|
||||
|
||||
- **Performance**: Hot-path timing only when logging; reduced clones (`execute_parallel` takes `&[Arc<SwqosClient>]`); shared HTTP client constants for SWQoS.
|
||||
@@ -97,14 +114,14 @@ Add the dependency to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
# Add to your Cargo.toml
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.5.0" }
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.5.3" }
|
||||
```
|
||||
|
||||
### Use crates.io
|
||||
|
||||
```toml
|
||||
# Add to your Cargo.toml
|
||||
sol-trade-sdk = "3.5.0"
|
||||
sol-trade-sdk = "3.5.3"
|
||||
```
|
||||
|
||||
## 🛠️ Usage Examples
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ git clone https://github.com/0xfnzero/sol-trade-sdk
|
||||
|
||||
```toml
|
||||
# 添加到您的 Cargo.toml
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.5.0" }
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.5.3" }
|
||||
```
|
||||
|
||||
### 使用 crates.io
|
||||
|
||||
@@ -768,6 +768,21 @@
|
||||
{
|
||||
"name": "fee_program",
|
||||
"address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
||||
},
|
||||
{
|
||||
"name": "bonding_curve_v2",
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101, 45, 118, 50]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
@@ -1164,6 +1179,21 @@
|
||||
{
|
||||
"name": "fee_program",
|
||||
"address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
||||
},
|
||||
{
|
||||
"name": "bonding_curve_v2",
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101, 45, 118, 50]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
@@ -3957,6 +3987,21 @@
|
||||
{
|
||||
"name": "fee_program",
|
||||
"address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
||||
},
|
||||
{
|
||||
"name": "bonding_curve_v2",
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [98, 111, 110, 100, 105, 110, 103, 45, 99, 117, 114, 118, 101, 45, 118, 50]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
|
||||
+46
-1
@@ -688,6 +688,21 @@
|
||||
{
|
||||
"name": "fee_program",
|
||||
"address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
||||
},
|
||||
{
|
||||
"name": "pool_v2",
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [112, 111, 111, 108, 45, 118, 50]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "base_mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
@@ -1119,6 +1134,21 @@
|
||||
{
|
||||
"name": "fee_program",
|
||||
"address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
||||
},
|
||||
{
|
||||
"name": "pool_v2",
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [112, 111, 111, 108, 45, 118, 50]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "base_mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
@@ -3162,6 +3192,21 @@
|
||||
{
|
||||
"name": "fee_program",
|
||||
"address": "pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ"
|
||||
},
|
||||
{
|
||||
"name": "pool_v2",
|
||||
"pda": {
|
||||
"seeds": [
|
||||
{
|
||||
"kind": "const",
|
||||
"value": [112, 111, 111, 108, 45, 118, 50]
|
||||
},
|
||||
{
|
||||
"kind": "account",
|
||||
"path": "base_mint"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"args": [
|
||||
@@ -4835,7 +4880,7 @@
|
||||
},
|
||||
{
|
||||
"code": 6052,
|
||||
"name": "CashbackEarnedDoesNotMatchTokenInVault"
|
||||
"name": "TokensInVaultLessThanCashbackEarned"
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
|
||||
+9
-10
@@ -6,20 +6,19 @@ Rust SDK for Solana DEX trading (Pump.fun, PumpSwap, Raydium, Bonk, Meteora, etc
|
||||
|
||||
### Performance
|
||||
|
||||
- **Hot-path timing**: `Instant::now()` for build/submit/total/confirm only when `log_enabled` or (for total) simulate, reducing cold-path syscalls.
|
||||
- **Fewer clones**: `execute_parallel` now takes `&[Arc<SwqosClient>]` instead of `Vec<Arc<SwqosClient>>`; caller no longer clones the client list.
|
||||
- **SWQoS HTTP**: Named constants for pool idle timeout, connect/request timeouts, and HTTP/2 keepalive in `swqos/common.rs`.
|
||||
- **Executor hot path**: Sample `Instant::now()` only when `log_enabled` or `simulate` (total, build, submit, confirm) to reduce cold-path syscalls.
|
||||
- **SWQOS**: `execute_parallel` now takes `&[Arc<SwqosClient>]` to avoid cloning the client list on each swap.
|
||||
- **Constants**: Named constants for instruction/account sizes and HTTP client timeouts; no magic numbers in hot paths.
|
||||
|
||||
### Code quality
|
||||
### Code Quality
|
||||
|
||||
- **Protocol params**: Single `validate_protocol_params(dex_type, params)` used by both buy and sell; removed duplicated match blocks.
|
||||
- **Constants**: `BYTES_PER_ACCOUNT`, `MAX_INSTRUCTIONS_WARN` in execution; HTTP timeout constants in swqos common.
|
||||
- **Comments**: Prefetch and branch-hint safety/usage documented; `SYSCALL_BYPASS` marked as reserved for future use.
|
||||
- **Protocol params**: Single `validate_protocol_params()` used for both buy and sell; removed duplicate match blocks in `lib.rs`.
|
||||
- **Comments**: Bilingual (English + 中文) doc and inline comments across execution, executor, perf (hardware_optimizations, syscall_bypass), and swqos/common.
|
||||
- **Prefetch/safety**: Clearer docs for cache prefetch and `unsafe` usage (valid read-only ref, no concurrent write).
|
||||
|
||||
### Documentation
|
||||
|
||||
- **Bilingual docs**: English + 中文 doc comments in `trading/core/execution.rs`, `trading/core/executor.rs`, `perf/hardware_optimizations.rs`, `perf/mod.rs`, `perf/syscall_bypass.rs`, `swqos/common.rs`.
|
||||
- **README**: Version references and "What's new in 3.5.0" (EN) / "3.5.0 更新说明" (CN) updated.
|
||||
- README (EN/CN): Version references updated to 3.5.0 for path and crates.io usage.
|
||||
|
||||
---
|
||||
|
||||
@@ -30,7 +29,7 @@ Rust SDK for Solana DEX trading (Pump.fun, PumpSwap, Raydium, Bonk, Meteora, etc
|
||||
sol-trade-sdk = { git = "https://github.com/0xfnzero/sol-trade-sdk", tag = "v3.5.0" }
|
||||
```
|
||||
|
||||
**From crates.io** (when published):
|
||||
**From crates.io:**
|
||||
```toml
|
||||
sol-trade-sdk = "3.5.0"
|
||||
```
|
||||
|
||||
@@ -153,10 +153,12 @@ pub fn _create_associated_token_account_idempotent_fast(
|
||||
pub enum PdaCacheKey {
|
||||
PumpFunUserVolume(Pubkey),
|
||||
PumpFunBondingCurve(Pubkey),
|
||||
PumpFunBondingCurveV2(Pubkey),
|
||||
PumpFunCreatorVault(Pubkey),
|
||||
BonkPool(Pubkey, Pubkey),
|
||||
BonkVault(Pubkey, Pubkey),
|
||||
PumpSwapUserVolume(Pubkey),
|
||||
PumpSwapPoolV2(Pubkey),
|
||||
}
|
||||
|
||||
/// Global lock-free PDA cache for storing computation results
|
||||
|
||||
@@ -8,8 +8,9 @@ use crate::{
|
||||
};
|
||||
use crate::{
|
||||
instruction::utils::pumpfun::{
|
||||
accounts, get_bonding_curve_pda, get_creator, get_user_volume_accumulator_pda,
|
||||
global_constants::{self}, BUY_DISCRIMINATOR, BUY_EXACT_SOL_IN_DISCRIMINATOR,
|
||||
accounts, get_bonding_curve_pda, get_bonding_curve_v2_pda, get_creator,
|
||||
get_user_volume_accumulator_pda, global_constants::{self}, BUY_DISCRIMINATOR,
|
||||
BUY_EXACT_SOL_IN_DISCRIMINATOR,
|
||||
},
|
||||
utils::calc::{
|
||||
common::{calculate_with_slippage_buy, calculate_with_slippage_sell},
|
||||
@@ -143,7 +144,8 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
|
||||
global_constants::FEE_RECIPIENT_META
|
||||
};
|
||||
|
||||
let accounts: [AccountMeta; 16] = [
|
||||
let bonding_curve_v2 = get_bonding_curve_v2_pda(¶ms.output_mint).unwrap();
|
||||
let mut accounts: Vec<AccountMeta> = vec![
|
||||
global_constants::GLOBAL_ACCOUNT_META,
|
||||
fee_recipient_meta,
|
||||
AccountMeta::new_readonly(params.output_mint, false),
|
||||
@@ -161,11 +163,12 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
|
||||
accounts::FEE_CONFIG_META,
|
||||
accounts::FEE_PROGRAM_META,
|
||||
];
|
||||
accounts.push(AccountMeta::new_readonly(bonding_curve_v2, false)); // bonding_curve_v2 (readonly) at end
|
||||
|
||||
instructions.push(Instruction::new_with_bytes(
|
||||
accounts::PUMPFUN,
|
||||
&buy_data,
|
||||
accounts.to_vec(),
|
||||
accounts,
|
||||
));
|
||||
|
||||
Ok(instructions)
|
||||
@@ -286,6 +289,9 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
|
||||
get_user_volume_accumulator_pda(¶ms.payer.pubkey()).unwrap();
|
||||
accounts.push(AccountMeta::new(user_volume_accumulator, false));
|
||||
}
|
||||
// Program upgrade: bonding_curve_v2 (readonly) at end of account list
|
||||
let bonding_curve_v2 = get_bonding_curve_v2_pda(¶ms.input_mint).unwrap();
|
||||
accounts.push(AccountMeta::new_readonly(bonding_curve_v2, false));
|
||||
|
||||
instructions.push(Instruction::new_with_bytes(
|
||||
accounts::PUMPFUN,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
constants::trade::trade::DEFAULT_SLIPPAGE,
|
||||
instruction::utils::pumpswap::{
|
||||
accounts, fee_recipient_ata, get_user_volume_accumulator_pda,
|
||||
accounts, fee_recipient_ata, get_pool_v2_pda, get_user_volume_accumulator_pda,
|
||||
get_user_volume_accumulator_wsol_ata, BUY_DISCRIMINATOR,
|
||||
BUY_EXACT_QUOTE_IN_DISCRIMINATOR, SELL_DISCRIMINATOR,
|
||||
},
|
||||
@@ -190,6 +190,11 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
|
||||
accounts.push(AccountMeta::new(wsol_ata, false));
|
||||
}
|
||||
}
|
||||
// Program upgrade: pool_v2 (readonly) at end of account list
|
||||
accounts.push(AccountMeta::new_readonly(
|
||||
get_pool_v2_pda(&base_mint).unwrap(),
|
||||
false,
|
||||
));
|
||||
|
||||
// Create instruction data
|
||||
let mut data = [0u8; 24];
|
||||
@@ -392,6 +397,11 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
|
||||
accounts.push(AccountMeta::new(accumulator, false));
|
||||
}
|
||||
}
|
||||
// Program upgrade: pool_v2 (readonly) at end of account list
|
||||
accounts.push(AccountMeta::new_readonly(
|
||||
get_pool_v2_pda(&base_mint).unwrap(),
|
||||
false,
|
||||
));
|
||||
|
||||
// Create instruction data
|
||||
let mut data = [0u8; 24];
|
||||
|
||||
@@ -7,6 +7,8 @@ use std::sync::Arc;
|
||||
pub mod seeds {
|
||||
/// Seed for bonding curve PDAs
|
||||
pub const BONDING_CURVE_SEED: &[u8] = b"bonding-curve";
|
||||
/// Seed for bonding curve v2 PDA (required by program upgrade, readonly at end of account list)
|
||||
pub const BONDING_CURVE_V2_SEED: &[u8] = b"bonding-curve-v2";
|
||||
|
||||
/// Seed for creator vault PDAs
|
||||
pub const CREATOR_VAULT_SEED: &[u8] = b"creator-vault";
|
||||
@@ -178,6 +180,20 @@ pub fn get_bonding_curve_pda(mint: &Pubkey) -> Option<Pubkey> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Bonding curve v2 PDA (seeds: ["bonding-curve-v2", mint]). Required at end of buy/sell/buy_exact_sol_in accounts.
|
||||
#[inline]
|
||||
pub fn get_bonding_curve_v2_pda(mint: &Pubkey) -> Option<Pubkey> {
|
||||
crate::common::fast_fn::get_cached_pda(
|
||||
crate::common::fast_fn::PdaCacheKey::PumpFunBondingCurveV2(*mint),
|
||||
|| {
|
||||
let seeds: &[&[u8]; 2] = &[seeds::BONDING_CURVE_V2_SEED, mint.as_ref()];
|
||||
let program_id: &Pubkey = &accounts::PUMPFUN;
|
||||
let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id);
|
||||
pda.map(|pubkey| pubkey.0)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_creator(creator_vault_pda: &Pubkey) -> Pubkey {
|
||||
if creator_vault_pda.eq(&Pubkey::default()) {
|
||||
|
||||
@@ -26,6 +26,9 @@ pub mod seeds {
|
||||
pub const USER_VOLUME_ACCUMULATOR_SEED: &[u8] = b"user_volume_accumulator";
|
||||
pub const GLOBAL_VOLUME_ACCUMULATOR_SEED: &[u8] = b"global_volume_accumulator";
|
||||
pub const FEE_CONFIG_SEED: &[u8] = b"fee_config";
|
||||
|
||||
/// Seed for pool v2 PDA (required by program upgrade, readonly at end of account list)
|
||||
pub const POOL_V2_SEED: &[u8] = b"pool-v2";
|
||||
}
|
||||
|
||||
/// Constants related to program accounts and authorities
|
||||
@@ -139,6 +142,16 @@ pub const BUY_DISCRIMINATOR: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
|
||||
pub const BUY_EXACT_QUOTE_IN_DISCRIMINATOR: [u8; 8] = [198, 46, 21, 82, 180, 217, 232, 112];
|
||||
pub const SELL_DISCRIMINATOR: [u8; 8] = [51, 230, 133, 164, 1, 127, 131, 173];
|
||||
|
||||
/// Pool v2 PDA (seeds: ["pool-v2", base_mint]). Required at end of buy/sell/buy_exact_quote_in accounts.
|
||||
#[inline]
|
||||
pub fn get_pool_v2_pda(base_mint: &Pubkey) -> Option<Pubkey> {
|
||||
let (pda, _) = Pubkey::find_program_address(
|
||||
&[seeds::POOL_V2_SEED, base_mint.as_ref()],
|
||||
&accounts::AMM_PROGRAM,
|
||||
);
|
||||
Some(pda)
|
||||
}
|
||||
|
||||
// Find a pool for a specific mint
|
||||
pub async fn find_pool(rpc: &SolanaRpcClient, mint: &Pubkey) -> Result<Pubkey, anyhow::Error> {
|
||||
let (pool_address, _) = find_by_mint(rpc, mint).await?;
|
||||
|
||||
+39
-16
@@ -89,41 +89,64 @@ pub async fn poll_transaction_confirmation(
|
||||
txt_sig: Signature,
|
||||
wait_confirmation: bool,
|
||||
) -> Result<Signature> {
|
||||
// If no confirmation needed, return signature immediately
|
||||
poll_any_transaction_confirmation(rpc, &[txt_sig], wait_confirmation).await
|
||||
}
|
||||
|
||||
/// Poll multiple signatures in parallel (one RPC call per poll) and return the first one that confirms.
|
||||
/// When transactions are submitted to multiple SWQOS channels, each channel produces a different
|
||||
/// signature. Only one will land on-chain, so we must check all of them.
|
||||
pub async fn poll_any_transaction_confirmation(
|
||||
rpc: &SolanaRpcClient,
|
||||
signatures: &[Signature],
|
||||
wait_confirmation: bool,
|
||||
) -> Result<Signature> {
|
||||
if signatures.is_empty() {
|
||||
return Err(anyhow::anyhow!("No signatures to confirm"));
|
||||
}
|
||||
// If no confirmation needed, return first signature immediately
|
||||
if !wait_confirmation {
|
||||
return Ok(txt_sig);
|
||||
return Ok(signatures[0]);
|
||||
}
|
||||
|
||||
let timeout: Duration = Duration::from_secs(15); // 15s to avoid timeout under network congestion
|
||||
let timeout: Duration = Duration::from_secs(15);
|
||||
let interval: Duration = Duration::from_millis(1000);
|
||||
let start: Instant = Instant::now();
|
||||
let mut poll_count = 0u32;
|
||||
// Track which signature landed (confirmed or failed on-chain)
|
||||
let mut landed_sig: Option<Signature> = None;
|
||||
|
||||
loop {
|
||||
if start.elapsed() >= timeout {
|
||||
return Err(anyhow::anyhow!("Transaction {}'s confirmation timed out", txt_sig));
|
||||
return Err(anyhow::anyhow!("Transaction confirmation timed out after {}s ({} signatures polled)", timeout.as_secs(), signatures.len()));
|
||||
}
|
||||
|
||||
poll_count += 1;
|
||||
|
||||
let status = rpc.get_signature_statuses(&[txt_sig]).await?;
|
||||
let first = status.value.get(0).and_then(|o| o.as_ref());
|
||||
match first {
|
||||
Some(s) => {
|
||||
let status = rpc.get_signature_statuses(signatures).await?;
|
||||
// Check all signatures for any that confirmed successfully
|
||||
for (i, maybe_status) in status.value.iter().enumerate() {
|
||||
if let Some(s) = maybe_status {
|
||||
if s.err.is_none()
|
||||
&& (s.confirmation_status == Some(TransactionConfirmationStatus::Confirmed)
|
||||
|| s.confirmation_status == Some(TransactionConfirmationStatus::Finalized))
|
||||
{
|
||||
return Ok(txt_sig);
|
||||
return Ok(signatures[i]);
|
||||
}
|
||||
// Track the first signature that landed on-chain (even if errored)
|
||||
if landed_sig.is_none() {
|
||||
landed_sig = Some(signatures[i]);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
sleep(interval).await;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let should_get_transaction = first.map(|s| s.err.is_some()).unwrap_or(false) || poll_count >= 10;
|
||||
// If no signature has any status yet, keep waiting
|
||||
if landed_sig.is_none() {
|
||||
sleep(interval).await;
|
||||
continue;
|
||||
}
|
||||
|
||||
let landed = landed_sig.unwrap();
|
||||
let should_get_transaction = poll_count >= 10;
|
||||
|
||||
if !should_get_transaction {
|
||||
sleep(interval).await;
|
||||
@@ -132,7 +155,7 @@ pub async fn poll_transaction_confirmation(
|
||||
|
||||
let tx_details = match rpc
|
||||
.get_transaction_with_config(
|
||||
&txt_sig,
|
||||
&landed,
|
||||
RpcTransactionConfig {
|
||||
encoding: Some(UiTransactionEncoding::JsonParsed),
|
||||
max_supported_transaction_version: Some(0),
|
||||
@@ -155,7 +178,7 @@ pub async fn poll_transaction_confirmation(
|
||||
} else {
|
||||
let meta = meta.unwrap();
|
||||
if meta.err.is_none() {
|
||||
return Ok(txt_sig);
|
||||
return Ok(landed);
|
||||
} else {
|
||||
// Extract error message from log_messages
|
||||
let mut error_msg = String::new();
|
||||
|
||||
@@ -11,7 +11,7 @@ use tracing::{info, trace, warn};
|
||||
use crate::{
|
||||
common::{nonce_cache::DurableNonceInfo, GasFeeStrategy, SolanaRpcClient},
|
||||
perf::syscall_bypass::SystemCallBypassManager,
|
||||
swqos::common::poll_transaction_confirmation,
|
||||
swqos::common::poll_any_transaction_confirmation,
|
||||
trading::core::{
|
||||
async_executor::execute_parallel,
|
||||
execution::{InstructionProcessor, Prefetch},
|
||||
@@ -156,10 +156,12 @@ impl TradeExecutor for GenericTradeExecutor {
|
||||
),
|
||||
Err(e) => (false, vec![], Some(anyhow::anyhow!("{}", e))),
|
||||
};
|
||||
let first_sig = sigs.first().copied();
|
||||
let confirm_result = if let (Some(rpc), Some(sig)) = (params.rpc.as_ref(), first_sig) {
|
||||
let confirm_result = if let Some(rpc) = params.rpc.as_ref() {
|
||||
if sigs.is_empty() {
|
||||
(ok, sigs, err)
|
||||
} else {
|
||||
let confirm_start = (params.log_enabled && crate::common::sdk_log::sdk_log_enabled()).then(Instant::now);
|
||||
let poll_res = poll_transaction_confirmation(rpc, sig, true).await;
|
||||
let poll_res = poll_any_transaction_confirmation(rpc, &sigs, true).await;
|
||||
let confirm_elapsed = confirm_start.map(|s| s.elapsed()).unwrap_or(Duration::ZERO);
|
||||
if params.log_enabled && crate::common::sdk_log::sdk_log_enabled() {
|
||||
let dir = if is_buy { "Buy" } else { "Sell" };
|
||||
@@ -171,6 +173,7 @@ impl TradeExecutor for GenericTradeExecutor {
|
||||
Ok(_) => (true, sigs, None),
|
||||
Err(e) => (false, sigs, Some(e)),
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(ok, sigs, err)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user