Skip to content

Commit 807b015

Browse files
0xfnzerocursoragent
andcommitted
Release v3.5.0: performance, constants, bilingual docs
- Bump version to 3.5.0 - Performance: hot-path timing only when log_enabled/simulate; execute_parallel takes &[Arc<SwqosClient>]; shared HTTP client constants for SWQoS - Code quality: validate_protocol_params extracted for buy/sell; BYTES_PER_ACCOUNT, MAX_INSTRUCTIONS_WARN, HTTP timeout constants; prefetch/syscall bypass comments - Documentation: bilingual (EN + 中文) doc comments in execution, executor, perf, swqos; README/README_CN version and What's new in 3.5.0 - Add release_notes_v3.5.0.md Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 8f6cc6f commit 807b015

31 files changed

Lines changed: 807 additions & 509 deletions

.github/workflows/release.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# 推送 tag(如 v3.4.1)时自动创建 GitHub Release
2+
name: Release
3+
4+
on:
5+
push:
6+
tags:
7+
- 'v*'
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
release:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
20+
- name: Get version from tag
21+
id: tag
22+
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
23+
24+
- name: Create Release
25+
uses: softprops/action-gh-release@v2
26+
with:
27+
name: v${{ steps.tag.outputs.VERSION }}
28+
body: |
29+
## sol-trade-sdk ${{ steps.tag.outputs.VERSION }}
30+
Rust SDK to interact with the dex trade Solana program (Pump.fun, Raydium, etc.).
31+
- **Cargo**: `sol-trade-sdk = { git = "https://github.com/${{ github.repository }}", tag = "v${{ steps.tag.outputs.VERSION }}" }`
32+
draft: false
33+
generate_release_notes: true
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

CHANGELOG_CN.md

Lines changed: 0 additions & 21 deletions
This file was deleted.

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "sol-trade-sdk"
3-
version = "3.4.1"
3+
version = "3.5.0"
44
edition = "2021"
55
authors = [
66
"William <byteblock6@gmail.com>",
@@ -81,7 +81,6 @@ rustls = { version = "0.23.23", features = ["ring"] }
8181
rustls-native-certs = "0.8.1"
8282
tokio-rustls = "0.26.1"
8383
core_affinity = "0.8"
84-
log = "0.4.22"
8584
chrono = "0.4.39"
8685
regex = "1"
8786
tracing = "0.1.41"

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@
6060

6161
---
6262

63+
## 🆕 What's new in 3.5.0
64+
65+
- **Performance**: Hot-path timing only when logging; reduced clones (`execute_parallel` takes `&[Arc<SwqosClient>]`); shared HTTP client constants for SWQoS.
66+
- **Code quality**: Extracted `validate_protocol_params` for buy/sell; constants for instruction/account sizes and HTTP timeouts; prefetch and branch-hint comments.
67+
- **Documentation**: Bilingual (English + 中文) doc comments across execution, executor, perf, and swqos modules.
68+
69+
---
70+
6371
## ✨ Features
6472

6573
1. **PumpFun Trading**: Support for `buy` and `sell` operations
@@ -89,14 +97,14 @@ Add the dependency to your `Cargo.toml`:
8997

9098
```toml
9199
# Add to your Cargo.toml
92-
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.4.1" }
100+
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.5.0" }
93101
```
94102

95103
### Use crates.io
96104

97105
```toml
98106
# Add to your Cargo.toml
99-
sol-trade-sdk = "3.4.1"
107+
sol-trade-sdk = "3.5.0"
100108
```
101109

102110
## 🛠️ Usage Examples

README_CN.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,14 @@
6060

6161
---
6262

63+
## 🆕 3.5.0 更新说明
64+
65+
- **性能**:仅在打日志时做热路径计时;减少 clone(`execute_parallel` 改为接收 `&[Arc<SwqosClient>]`);SWQoS 共用 HTTP 客户端常量。
66+
- **代码质量**:抽取 buy/sell 共用的 `validate_protocol_params`;指令/账户大小与 HTTP 超时常量化;预取与分支提示注释完善。
67+
- **文档**:execution、executor、perf、swqos 等模块增加中英双语文档注释。
68+
69+
---
70+
6371
## ✨ 项目特性
6472

6573
1. **PumpFun 交易**: 支持`购买``卖出`功能
@@ -89,14 +97,14 @@ git clone https://github.com/0xfnzero/sol-trade-sdk
8997

9098
```toml
9199
# 添加到您的 Cargo.toml
92-
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.4.1" }
100+
sol-trade-sdk = { path = "./sol-trade-sdk", version = "3.5.0" }
93101
```
94102

95103
### 使用 crates.io
96104

97105
```toml
98106
# 添加到您的 Cargo.toml
99-
sol-trade-sdk = "3.4.1"
107+
sol-trade-sdk = "3.5.0"
100108
```
101109

102110
## 🛠️ 使用示例

release_notes_v3.4.1.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# sol-trade-sdk v3.4.1
2+
3+
Rust SDK for Solana DEX trading (Pump.fun, PumpSwap, Raydium, Bonk, Meteora, etc.).
4+
5+
## What's Changed
6+
7+
### New Features
8+
9+
- **PumpFun & PumpSwap Cashback** (#77): Support for cashback in PumpFun and PumpSwap trading flows. See [Cashback documentation](docs/PUMP_CASHBACK_README.md).
10+
- **Events**: `is_cashback_coin` is now passed from events; PumpFun examples use `sol-parser-sdk` only for event parsing.
11+
12+
### Performance
13+
14+
- **SWQoS**: Reduced submit latency; fixed high latency after ~5 minutes idle.
15+
16+
### Bug Fixes
17+
18+
- **WSOL ATA**: WSOL Associated Token Account creation now runs in background with retry and timeout for more reliable setup.
19+
- Silenced unused and deprecated compiler warnings.
20+
21+
### Documentation
22+
23+
- README (EN/中文): Added Cashback section, outline, examples and tables.
24+
- Updated crates.io / docs references in README.
25+
26+
---
27+
28+
## Cargo
29+
30+
**From Git (this release):**
31+
```toml
32+
sol-trade-sdk = { git = "https://github.com/0xfnzero/sol-trade-sdk", tag = "v3.4.1" }
33+
```
34+
35+
**From crates.io** (when published):
36+
```toml
37+
sol-trade-sdk = "3.4.1"
38+
```
39+
40+
**Full Changelog**: https://github.com/0xfnzero/sol-trade-sdk/compare/v3.4.0...v3.4.1

release_notes_v3.5.0.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# sol-trade-sdk v3.5.0
2+
3+
Rust SDK for Solana DEX trading (Pump.fun, PumpSwap, Raydium, Bonk, Meteora, etc.).
4+
5+
## What's Changed
6+
7+
### Performance
8+
9+
- **Hot-path timing**: `Instant::now()` for build/submit/total/confirm only when `log_enabled` or (for total) simulate, reducing cold-path syscalls.
10+
- **Fewer clones**: `execute_parallel` now takes `&[Arc<SwqosClient>]` instead of `Vec<Arc<SwqosClient>>`; caller no longer clones the client list.
11+
- **SWQoS HTTP**: Named constants for pool idle timeout, connect/request timeouts, and HTTP/2 keepalive in `swqos/common.rs`.
12+
13+
### Code quality
14+
15+
- **Protocol params**: Single `validate_protocol_params(dex_type, params)` used by both buy and sell; removed duplicated match blocks.
16+
- **Constants**: `BYTES_PER_ACCOUNT`, `MAX_INSTRUCTIONS_WARN` in execution; HTTP timeout constants in swqos common.
17+
- **Comments**: Prefetch and branch-hint safety/usage documented; `SYSCALL_BYPASS` marked as reserved for future use.
18+
19+
### Documentation
20+
21+
- **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`.
22+
- **README**: Version references and "What's new in 3.5.0" (EN) / "3.5.0 更新说明" (CN) updated.
23+
24+
---
25+
26+
## Cargo
27+
28+
**From Git (this release):**
29+
```toml
30+
sol-trade-sdk = { git = "https://github.com/0xfnzero/sol-trade-sdk", tag = "v3.5.0" }
31+
```
32+
33+
**From crates.io** (when published):
34+
```toml
35+
sol-trade-sdk = "3.5.0"
36+
```
37+
38+
**Full Changelog**: https://github.com/0xfnzero/sol-trade-sdk/compare/v3.4.1...v3.5.0

src/common/clock.rs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
//! High-performance clock (same design as sol-parser-sdk for consistent grpc_recv_us vs "now").
2+
//!
3+
//! Uses monotonic clock + base UTC timestamp to avoid frequent syscalls; aligned with sol-parser-sdk
4+
//! so event-side grpc_recv_us and SDK-side now_micros() share the same time scale.
5+
6+
use std::time::Instant;
7+
8+
/// High-performance clock: monotonic + base UTC microsecond timestamp.
9+
#[derive(Debug)]
10+
pub struct HighPerformanceClock {
11+
base_instant: Instant,
12+
base_timestamp_us: i64,
13+
last_calibration: Instant,
14+
calibration_interval_secs: u64,
15+
}
16+
17+
impl HighPerformanceClock {
18+
/// Calibrate every 5 minutes by default.
19+
pub fn new() -> Self {
20+
Self::new_with_calibration_interval(300)
21+
}
22+
23+
/// Sample multiple times and use the lowest-latency baseline to reduce init error.
24+
pub fn new_with_calibration_interval(calibration_interval_secs: u64) -> Self {
25+
let mut best_offset = i64::MAX;
26+
let mut best_instant = Instant::now();
27+
let mut best_timestamp = chrono::Utc::now().timestamp_micros();
28+
29+
for _ in 0..3 {
30+
let instant_before = Instant::now();
31+
let timestamp = chrono::Utc::now().timestamp_micros();
32+
let instant_after = Instant::now();
33+
let sample_latency = instant_after.duration_since(instant_before).as_nanos() as i64;
34+
if sample_latency < best_offset {
35+
best_offset = sample_latency;
36+
best_instant = instant_before;
37+
best_timestamp = timestamp;
38+
}
39+
}
40+
41+
Self {
42+
base_instant: best_instant,
43+
base_timestamp_us: best_timestamp,
44+
last_calibration: best_instant,
45+
calibration_interval_secs,
46+
}
47+
}
48+
49+
#[inline(always)]
50+
pub fn now_micros(&self) -> i64 {
51+
let elapsed = self.base_instant.elapsed();
52+
self.base_timestamp_us + elapsed.as_micros() as i64
53+
}
54+
55+
/// Recalibrate when needed to prevent drift.
56+
pub fn now_micros_with_calibration(&mut self) -> i64 {
57+
if self.last_calibration.elapsed().as_secs() >= self.calibration_interval_secs {
58+
self.recalibrate();
59+
}
60+
self.now_micros()
61+
}
62+
63+
fn recalibrate(&mut self) {
64+
let current_monotonic = Instant::now();
65+
let current_utc = chrono::Utc::now().timestamp_micros();
66+
let expected_utc = self.base_timestamp_us
67+
+ current_monotonic.duration_since(self.base_instant).as_micros() as i64;
68+
let drift_us = current_utc - expected_utc;
69+
if drift_us.abs() > 1000 {
70+
self.base_instant = current_monotonic;
71+
self.base_timestamp_us = current_utc;
72+
}
73+
self.last_calibration = current_monotonic;
74+
}
75+
}
76+
77+
impl Default for HighPerformanceClock {
78+
fn default() -> Self {
79+
Self::new()
80+
}
81+
}
82+
83+
static HIGH_PERF_CLOCK: once_cell::sync::OnceCell<HighPerformanceClock> =
84+
once_cell::sync::OnceCell::new();
85+
86+
/// Current time in microseconds (UTC scale); same as sol-parser-sdk clock::now_micros for comparable grpc_recv_us.
87+
#[inline(always)]
88+
pub fn now_micros() -> i64 {
89+
let clock = HIGH_PERF_CLOCK.get_or_init(HighPerformanceClock::new);
90+
clock.now_micros()
91+
}
92+
93+
/// Elapsed microseconds from start_timestamp_us to now.
94+
#[inline(always)]
95+
pub fn elapsed_micros_since(start_timestamp_us: i64) -> i64 {
96+
now_micros() - start_timestamp_us
97+
}

src/common/fast_timing.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ mod tests {
174174
let total_elapsed = start.elapsed();
175175
let avg_per_call = total_elapsed.as_nanos() / iterations;
176176

177-
println!("Average fast_now_nanos() call: {}ns", avg_per_call);
177+
if crate::common::sdk_log::sdk_log_enabled() {
178+
println!("Average fast_now_nanos() call: {}ns", avg_per_call);
179+
}
178180

179181
// 快速时间戳应该非常快(< 100ns per call)
180182
assert!(avg_per_call < 100);
@@ -193,6 +195,8 @@ mod tests {
193195
let total_elapsed = start.elapsed();
194196
let avg_per_call = total_elapsed.as_nanos() / iterations;
195197

196-
println!("Average Instant::now() call: {}ns", avg_per_call);
198+
if crate::common::sdk_log::sdk_log_enabled() {
199+
println!("Average Instant::now() call: {}ns", avg_per_call);
200+
}
197201
}
198202
}

src/common/gas_fee_strategy.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,9 @@ impl GasFeeStrategy {
354354
/// 打印所有策略。
355355
/// Print all strategies
356356
pub fn print_all_strategies(&self) {
357+
if !crate::common::sdk_log::sdk_log_enabled() {
358+
return;
359+
}
357360
for strategy in self.get_strategies(TradeType::Buy) {
358361
println!("[buy] - {:?}", strategy);
359362
}

0 commit comments

Comments
 (0)