mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-09 23:20:57 +00:00
fix(pumpswap): preserve complete trade event tails
This commit is contained in:
+2
-2
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "solana-streamer-sdk"
|
||||
version = "2.0.0"
|
||||
version = "2.0.1"
|
||||
edition = "2021"
|
||||
authors = ["William <byteblock6@gmail.com>", "sgxiang <sgxiang@gmail.com>", "wei <1415121722@qq.com>"]
|
||||
repository = "https://github.com/0xfnzero/solana-streamer"
|
||||
@@ -21,7 +21,7 @@ sdk-perf-stats = ["sol-parser-sdk/perf-stats"]
|
||||
sdk-ultra-perf = ["sol-parser-sdk/ultra-perf"]
|
||||
|
||||
[dependencies]
|
||||
sol-parser-sdk = { version = "0.6.0", git = "https://github.com/0xfnzero/sol-parser-sdk", rev = "995d88991b56234a23fc1d0911fdd33caa063c67", default-features = false }
|
||||
sol-parser-sdk = { version = "0.6.1", default-features = false }
|
||||
solana-sdk = "3.0.0"
|
||||
solana-client = "3.1.12"
|
||||
solana-transaction-status = "3.1.12"
|
||||
|
||||
@@ -40,12 +40,6 @@
|
||||
<a href="https://discord.gg/vuazbGkqQE">Discord</a>
|
||||
</p>
|
||||
|
||||
> ☕ **Support This Project**
|
||||
>
|
||||
> This SDK is completely free and open source. However, maintaining and continuously updating it requires significant AI computing resources and token consumption. If this SDK helps with your development, consider making a monthly SOL donation — any amount is appreciated and helps keep this project alive!
|
||||
>
|
||||
> **Donation Wallet:** `6oW7AXz1yRb57pYSxysuXnMs2aR1ha5rzGzReZ1MjPV8`
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
@@ -135,30 +129,34 @@ Add the dependency to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
# Add to your Cargo.toml
|
||||
solana-streamer-sdk = { path = "./solana-streamer", version = "1.5.16" }
|
||||
solana-streamer-sdk = { path = "./solana-streamer", version = "2.0.1" }
|
||||
```
|
||||
|
||||
### Use crates.io
|
||||
|
||||
```toml
|
||||
# Add to your Cargo.toml
|
||||
solana-streamer-sdk = "1.5.16"
|
||||
solana-streamer-sdk = "2.0.1"
|
||||
```
|
||||
|
||||
Parser backend features:
|
||||
|
||||
```toml
|
||||
# Default: sol-parser-sdk parse-borsh backend
|
||||
solana-streamer-sdk = "1.5.16"
|
||||
solana-streamer-sdk = "2.0.1"
|
||||
|
||||
# Zero-copy parser backend for latency-sensitive bots
|
||||
solana-streamer-sdk = { version = "1.5.16", default-features = false, features = ["sdk-parse-zero-copy"] }
|
||||
solana-streamer-sdk = { version = "2.0.1", default-features = false, features = ["sdk-parse-zero-copy"] }
|
||||
```
|
||||
|
||||
If both `sdk-parse-borsh` and `sdk-parse-zero-copy` are enabled, `sol-parser-sdk 0.5.15+` uses the zero-copy backend.
|
||||
If both `sdk-parse-borsh` and `sdk-parse-zero-copy` are enabled, `sol-parser-sdk 0.6.1+` uses the zero-copy backend.
|
||||
|
||||
## 🔄 Migration Guide
|
||||
|
||||
### Upgrading to v2.0.1
|
||||
|
||||
Version 2.0.1 uses `sol-parser-sdk 0.6.1` from crates.io. PumpSwap Buy/Sell events now preserve the complete current cashback, buyback, signed virtual quote reserve, boost, and base-supply tail through dispatcher and SDK bridge paths. Truncated current layouts are rejected consistently by the default and zero-copy parser backends while historical layouts remain supported.
|
||||
|
||||
### Upgrading to v1.5.16
|
||||
|
||||
Version 1.5.16 fixes `StreamingOrdered` delivery for transactions that parse into multiple events. Events from the same `(slot, tx_index)` are admitted as a group, the streaming watermark advances once per transaction, and stable sorting preserves parser order for equal transaction indexes. It also pins `yellowstone-grpc-proto` to the `12.4.x` API used by `sol-parser-sdk 0.5.15` so CI and clean installs do not resolve an incompatible newer proto crate.
|
||||
|
||||
+9
-11
@@ -39,12 +39,6 @@
|
||||
<a href="https://t.me/fnzero_group">Telegram</a>
|
||||
</p>
|
||||
|
||||
> ☕ **支持本项目**
|
||||
>
|
||||
> 本 SDK 完全免费且开源。但维护和持续更新需要消耗大量 AI 算力与 Token。如果这个 SDK 对您的开发有帮助,欢迎每月捐赠任意数量的 SOL,您的支持将帮助这个项目持续运行!
|
||||
>
|
||||
> **捐赠钱包:** `6oW7AXz1yRb57pYSxysuXnMs2aR1ha5rzGzReZ1MjPV8`
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
@@ -134,30 +128,34 @@ git clone https://github.com/0xfnzero/solana-streamer
|
||||
|
||||
```toml
|
||||
# 添加到您的 Cargo.toml
|
||||
solana-streamer-sdk = { path = "./solana-streamer", version = "1.5.16" }
|
||||
solana-streamer-sdk = { path = "./solana-streamer", version = "2.0.1" }
|
||||
```
|
||||
|
||||
### 使用 crates.io
|
||||
|
||||
```toml
|
||||
# 添加到您的 Cargo.toml
|
||||
solana-streamer-sdk = "1.5.16"
|
||||
solana-streamer-sdk = "2.0.1"
|
||||
```
|
||||
|
||||
解析后端 feature:
|
||||
|
||||
```toml
|
||||
# 默认:sol-parser-sdk parse-borsh 后端
|
||||
solana-streamer-sdk = "1.5.16"
|
||||
solana-streamer-sdk = "2.0.1"
|
||||
|
||||
# 面向低延迟 Bot 的 zero-copy 解析后端
|
||||
solana-streamer-sdk = { version = "1.5.16", default-features = false, features = ["sdk-parse-zero-copy"] }
|
||||
solana-streamer-sdk = { version = "2.0.1", default-features = false, features = ["sdk-parse-zero-copy"] }
|
||||
```
|
||||
|
||||
如果同时启用 `sdk-parse-borsh` 和 `sdk-parse-zero-copy`,`sol-parser-sdk 0.5.15+` 会优先使用 zero-copy 后端。
|
||||
如果同时启用 `sdk-parse-borsh` 和 `sdk-parse-zero-copy`,`sol-parser-sdk 0.6.1+` 会优先使用 zero-copy 后端。
|
||||
|
||||
## 🔄 迁移指南
|
||||
|
||||
### 升级到 v2.0.1
|
||||
|
||||
v2.0.1 使用 crates.io 上的 `sol-parser-sdk 0.6.1`。PumpSwap Buy/Sell 事件现在会在 dispatcher 和 SDK bridge 路径中完整保留 cashback、buyback、带符号 virtual quote reserve、boost 和 base supply 尾部字段。默认和 zero-copy 解析后端会一致拒绝截断的当前布局,同时继续兼容历史布局。
|
||||
|
||||
### 升级到 v1.5.16
|
||||
|
||||
v1.5.16 修复 `StreamingOrdered` 模式下同一交易解析出多个事件时的投递问题。同一 `(slot, tx_index)` 的事件会作为一组进入缓冲,streaming watermark 每笔交易只推进一次,并用 stable sort 保留相同交易索引下的解析器输出顺序。同时将 `yellowstone-grpc-proto` 固定到 `sol-parser-sdk 0.5.15` 使用的 `12.4.x` API,避免 CI 和干净安装解析到不兼容的新 proto crate。
|
||||
|
||||
@@ -198,3 +198,49 @@ fn pb_meta_from_streamer(sm: &EventMetadata) -> PbEventMetadata {
|
||||
recent_blockhash: sm.recent_blockhash.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::streaming::event_parser::common::EventType;
|
||||
|
||||
#[test]
|
||||
fn pumpswap_current_sell_tail_survives_dispatch_and_bridge() {
|
||||
let mut payload = vec![0u8; 409];
|
||||
payload[352..360].copy_from_slice(&11u64.to_le_bytes());
|
||||
payload[360..368].copy_from_slice(&22u64.to_le_bytes());
|
||||
payload[368..376].copy_from_slice(&33u64.to_le_bytes());
|
||||
payload[376..384].copy_from_slice(&44u64.to_le_bytes());
|
||||
payload[384..400].copy_from_slice(&i128::MIN.to_le_bytes());
|
||||
payload[400] = 1;
|
||||
payload[401..409].copy_from_slice(&55u64.to_le_bytes());
|
||||
|
||||
let event = EventDispatcher::dispatch_inner_instruction(
|
||||
Protocol::PumpSwap,
|
||||
&pump_amm_inner::discriminators::SELL,
|
||||
&payload,
|
||||
EventMetadata::default(),
|
||||
)
|
||||
.expect("current PumpSwap sell should dispatch");
|
||||
|
||||
let DexEvent::PumpSwapSellEvent(event) = event else {
|
||||
panic!("expected PumpSwapSellEvent");
|
||||
};
|
||||
assert_eq!(event.metadata.event_type, EventType::PumpSwapSell);
|
||||
assert_eq!(event.cashback_fee_basis_points, 11);
|
||||
assert_eq!(event.cashback, 22);
|
||||
assert_eq!(event.buyback_fee_basis_points, 33);
|
||||
assert_eq!(event.buyback_fee, 44);
|
||||
assert_eq!(event.virtual_quote_reserves, i128::MIN);
|
||||
assert!(event.can_boost);
|
||||
assert_eq!(event.base_supply, 55);
|
||||
|
||||
assert!(EventDispatcher::dispatch_inner_instruction(
|
||||
Protocol::PumpSwap,
|
||||
&pump_amm_inner::discriminators::SELL,
|
||||
&payload[..408],
|
||||
EventMetadata::default(),
|
||||
)
|
||||
.is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user