feat(pumpswap): forward virtual quote reserve upgrade

This commit is contained in:
0xfnzero
2026-07-17 01:59:54 +08:00
parent 740838f414
commit aab0a3a143
8 changed files with 1237 additions and 13 deletions
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "solana-streamer-sdk"
version = "1.5.16"
version = "2.0.0"
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.5.15", default-features = false }
sol-parser-sdk = { version = "0.6.0", git = "https://github.com/0xfnzero/sol-parser-sdk", branch = "dev", default-features = false }
solana-sdk = "3.0.0"
solana-client = "3.1.12"
solana-transaction-status = "3.1.12"
+1122
View File
File diff suppressed because it is too large Load Diff
@@ -342,6 +342,11 @@ pub fn merge(instruction_event: &mut DexEvent, cpi_log_event: DexEvent) {
e.ix_name = cpie.ix_name.clone();
e.cashback_fee_basis_points = cpie.cashback_fee_basis_points;
e.cashback = cpie.cashback;
e.buyback_fee_basis_points = cpie.buyback_fee_basis_points;
e.buyback_fee = cpie.buyback_fee;
e.virtual_quote_reserves = cpie.virtual_quote_reserves;
e.can_boost = cpie.can_boost;
e.base_supply = cpie.base_supply;
e.is_pump_pool = cpie.is_pump_pool;
fill_pubkey(&mut e.base_mint, cpie.base_mint);
fill_pubkey(&mut e.quote_mint, cpie.quote_mint);
@@ -387,6 +392,11 @@ pub fn merge(instruction_event: &mut DexEvent, cpi_log_event: DexEvent) {
e.coin_creator_fee = cpie.coin_creator_fee;
e.cashback_fee_basis_points = cpie.cashback_fee_basis_points;
e.cashback = cpie.cashback;
e.buyback_fee_basis_points = cpie.buyback_fee_basis_points;
e.buyback_fee = cpie.buyback_fee;
e.virtual_quote_reserves = cpie.virtual_quote_reserves;
e.can_boost = cpie.can_boost;
e.base_supply = cpie.base_supply;
e.is_pump_pool = cpie.is_pump_pool;
fill_pubkey(&mut e.base_mint, cpie.base_mint);
fill_pubkey(&mut e.quote_mint, cpie.quote_mint);
@@ -858,6 +868,7 @@ mod tests {
use crate::streaming::event_parser::protocols::pumpfun::events::{
PumpFeesShareholder, PumpFunTradeEvent,
};
use crate::streaming::event_parser::protocols::pumpswap::events::PumpSwapSellEvent;
#[test]
fn pumpfun_merge_keeps_instruction_context_and_copies_latest_trade_tail() {
@@ -912,6 +923,30 @@ mod tests {
}
}
#[test]
fn pumpswap_merge_preserves_signed_virtual_quote_reserves() {
let mut instruction_event = DexEvent::PumpSwapSellEvent(PumpSwapSellEvent::default());
let log_event = DexEvent::PumpSwapSellEvent(PumpSwapSellEvent {
virtual_quote_reserves: -500,
buyback_fee_basis_points: 11,
buyback_fee: 22,
can_boost: true,
base_supply: 33,
..Default::default()
});
merge(&mut instruction_event, log_event);
let DexEvent::PumpSwapSellEvent(event) = instruction_event else {
panic!("expected PumpSwapSellEvent");
};
assert_eq!(event.virtual_quote_reserves, -500);
assert_eq!(event.buyback_fee_basis_points, 11);
assert_eq!(event.buyback_fee, 22);
assert!(event.can_boost);
assert_eq!(event.base_supply, 33);
}
#[test]
fn pumpfun_merge_replaces_sol_quote_sentinel_with_real_quote_mint() {
let quote_mint = Pubkey::new_unique();
@@ -44,6 +44,11 @@ pub struct PumpSwapBuyEvent {
pub ix_name: String,
pub cashback_fee_basis_points: u64,
pub cashback: u64,
pub buyback_fee_basis_points: u64,
pub buyback_fee: u64,
pub virtual_quote_reserves: i128,
pub can_boost: bool,
pub base_supply: u64,
#[borsh(skip)]
pub is_pump_pool: bool,
#[borsh(skip)]
@@ -105,6 +110,11 @@ pub struct PumpSwapSellEvent {
pub coin_creator_fee: u64,
pub cashback_fee_basis_points: u64,
pub cashback: u64,
pub buyback_fee_basis_points: u64,
pub buyback_fee: u64,
pub virtual_quote_reserves: i128,
pub can_boost: bool,
pub base_supply: u64,
#[borsh(skip)]
pub is_pump_pool: bool,
#[borsh(skip)]
@@ -33,13 +33,12 @@ pub struct Pool {
pub coin_creator: Pubkey,
pub is_mayhem_mode: bool,
pub is_cashback_coin: bool,
/// On-chain reserved tail (7 bytes); keep in sync with pump_amm pool account layout.
pub reserved: [u8; 7],
pub virtual_quote_reserves: i128,
}
/// Legacy pool account body (before `is_cashback_coin` + reserved).
pub const POOL_BODY_LEGACY: usize = 1 + 2 + 32 * 6 + 8 + 32 + 1;
/// Current pool account body including flags and reserved.
pub const POOL_BODY: usize = POOL_BODY_LEGACY + 1 + 7;
/// Legacy allocated pool account body.
pub const POOL_BODY_LEGACY: usize = 244;
/// Current serialized pool account body including signed virtual quote reserves.
pub const POOL_BODY: usize = 253;
pub const POOL_SIZE: usize = POOL_BODY;
@@ -185,7 +185,7 @@ pub(crate) fn pumpswap_pool_from_pb(p: sol_parser_sdk::core::events::PumpSwapPoo
coin_creator: p.coin_creator,
is_mayhem_mode: p.is_mayhem_mode,
is_cashback_coin: p.is_cashback_coin,
reserved: [0u8; 7],
virtual_quote_reserves: p.virtual_quote_reserves,
}
}
+52 -4
View File
@@ -43,10 +43,10 @@ mod tests {
use sol_parser_sdk::core::events::{
EventMetadata, MeteoraDlmmSwapEvent as PbDlmmSwap, OrcaWhirlpoolSwapEvent as PbOrcaSwap,
PumpFunCreateV2TokenEvent as PbPumpCreateV2, PumpFunTradeEvent as PbPumpTrade,
PumpSwapCreatePoolEvent as PbPumpSwapCreatePool, PumpSwapPool as PbPumpSwapPool,
PumpSwapPoolAccountEvent as PbPumpSwapPoolAccount,
RaydiumLaunchlabTradeEvent as PbBonkTrade, TokenInfoEvent as PbTokenInfo,
TradeDirection as PbBonkDir,
PumpSwapBuyEvent as PbPumpSwapBuy, PumpSwapCreatePoolEvent as PbPumpSwapCreatePool,
PumpSwapPool as PbPumpSwapPool, PumpSwapPoolAccountEvent as PbPumpSwapPoolAccount,
PumpSwapSellEvent as PbPumpSwapSell, RaydiumLaunchlabTradeEvent as PbBonkTrade,
TokenInfoEvent as PbTokenInfo, TradeDirection as PbBonkDir,
};
use sol_parser_sdk::DexEvent as PbDexEvent;
use solana_sdk::{pubkey::Pubkey, signature::Signature};
@@ -242,6 +242,52 @@ mod tests {
}
}
#[test]
fn converts_pumpswap_buy_boost_tail() {
let event = PbPumpSwapBuy {
virtual_quote_reserves: -123,
buyback_fee_basis_points: 11,
buyback_fee: 22,
can_boost: true,
base_supply: 33,
..Default::default()
};
let converted =
convert_parser_event(PbDexEvent::PumpSwapBuy(event), None, 999).expect("convert");
let DexEvent::PumpSwapBuyEvent(converted) = converted else {
panic!("expected PumpSwapBuyEvent");
};
assert_eq!(converted.virtual_quote_reserves, -123);
assert_eq!(converted.buyback_fee_basis_points, 11);
assert_eq!(converted.buyback_fee, 22);
assert!(converted.can_boost);
assert_eq!(converted.base_supply, 33);
}
#[test]
fn converts_pumpswap_sell_boost_tail() {
let event = PbPumpSwapSell {
virtual_quote_reserves: 123,
buyback_fee_basis_points: 44,
buyback_fee: 55,
can_boost: true,
base_supply: 66,
..Default::default()
};
let converted =
convert_parser_event(PbDexEvent::PumpSwapSell(event), None, 999).expect("convert");
let DexEvent::PumpSwapSellEvent(converted) = converted else {
panic!("expected PumpSwapSellEvent");
};
assert_eq!(converted.virtual_quote_reserves, 123);
assert_eq!(converted.buyback_fee_basis_points, 44);
assert_eq!(converted.buyback_fee, 55);
assert!(converted.can_boost);
assert_eq!(converted.base_supply, 66);
}
#[test]
fn converts_pumpswap_pool_account_cashback_flag() {
let pool_pubkey = Pubkey::new_unique();
@@ -272,6 +318,7 @@ mod tests {
coin_creator: Pubkey::new_unique(),
is_mayhem_mode: true,
is_cashback_coin: true,
virtual_quote_reserves: -777,
},
};
@@ -283,6 +330,7 @@ mod tests {
assert_eq!(st.pubkey, pool_pubkey);
assert!(st.pool.is_mayhem_mode);
assert!(st.pool.is_cashback_coin);
assert_eq!(st.pool.virtual_quote_reserves, -777);
}
_ => panic!("expected PumpSwapPoolAccountEvent"),
}
@@ -523,6 +523,11 @@ pub(crate) fn pumpswap_buy_full_from_parser(
ix_name: b.ix_name,
cashback_fee_basis_points: b.cashback_fee_basis_points,
cashback: b.cashback,
buyback_fee_basis_points: b.buyback_fee_basis_points,
buyback_fee: b.buyback_fee,
virtual_quote_reserves: b.virtual_quote_reserves,
can_boost: b.can_boost,
base_supply: b.base_supply,
is_pump_pool: b.is_pump_pool,
base_mint: b.base_mint,
quote_mint: b.quote_mint,
@@ -569,6 +574,11 @@ pub(crate) fn pumpswap_sell_full_from_parser(
coin_creator_fee: s.coin_creator_fee,
cashback_fee_basis_points: s.cashback_fee_basis_points,
cashback: s.cashback,
buyback_fee_basis_points: s.buyback_fee_basis_points,
buyback_fee: s.buyback_fee,
virtual_quote_reserves: s.virtual_quote_reserves,
can_boost: s.can_boost,
base_supply: s.base_supply,
is_pump_pool: s.is_pump_pool,
base_mint: s.base_mint,
quote_mint: s.quote_mint,