mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-19 11:58:06 +00:00
refactor: restructure event handling from trait objects to enum pattern
- Convert UnifiedEvent from trait object (Box<dyn UnifiedEvent>) to concrete enum type - Remove match_event! macro in favor of native match expressions - Simplify event metadata access: event.event_type() -> event.metadata().event_type - Unify event callback signatures: Fn(Box<dyn UnifiedEvent>) -> Fn(UnifiedEvent) - Update all example code to use the new enum-based event system - Optimize type system to reduce runtime overhead and improve type safety Affected scope: - Core event parser and processor - All protocol event definitions (PumpFun, PumpSwap, Bonk, Raydium series, etc.) - gRPC and Shred streaming modules - All example code
This commit is contained in:
@@ -2,7 +2,6 @@ use borsh::BorshDeserialize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
|
||||
use crate::impl_unified_event;
|
||||
use crate::streaming::event_parser::common::EventMetadata;
|
||||
use crate::streaming::event_parser::protocols::pumpswap::types::{GlobalConfig, Pool};
|
||||
|
||||
@@ -67,32 +66,32 @@ pub fn pump_swap_buy_event_log_decode(data: &[u8]) -> Option<PumpSwapBuyEvent> {
|
||||
}
|
||||
|
||||
// 使用宏生成UnifiedEvent实现,指定需要合并的字段
|
||||
impl_unified_event!(
|
||||
PumpSwapBuyEvent,
|
||||
timestamp,
|
||||
base_amount_out,
|
||||
max_quote_amount_in,
|
||||
user_base_token_reserves,
|
||||
user_quote_token_reserves,
|
||||
pool_base_token_reserves,
|
||||
pool_quote_token_reserves,
|
||||
quote_amount_in,
|
||||
lp_fee_basis_points,
|
||||
lp_fee,
|
||||
protocol_fee_basis_points,
|
||||
protocol_fee,
|
||||
quote_amount_in_with_lp_fee,
|
||||
user_quote_amount_in,
|
||||
pool,
|
||||
user,
|
||||
user_base_token_account,
|
||||
user_quote_token_account,
|
||||
protocol_fee_recipient,
|
||||
protocol_fee_recipient_token_account,
|
||||
coin_creator,
|
||||
coin_creator_fee_basis_points,
|
||||
coin_creator_fee
|
||||
);
|
||||
// impl_unified_event!(
|
||||
// PumpSwapBuyEvent,
|
||||
// timestamp,
|
||||
// base_amount_out,
|
||||
// max_quote_amount_in,
|
||||
// user_base_token_reserves,
|
||||
// user_quote_token_reserves,
|
||||
// pool_base_token_reserves,
|
||||
// pool_quote_token_reserves,
|
||||
// quote_amount_in,
|
||||
// lp_fee_basis_points,
|
||||
// lp_fee,
|
||||
// protocol_fee_basis_points,
|
||||
// protocol_fee,
|
||||
// quote_amount_in_with_lp_fee,
|
||||
// user_quote_amount_in,
|
||||
// pool,
|
||||
// user,
|
||||
// user_base_token_account,
|
||||
// user_quote_token_account,
|
||||
// protocol_fee_recipient,
|
||||
// protocol_fee_recipient_token_account,
|
||||
// coin_creator,
|
||||
// coin_creator_fee_basis_points,
|
||||
// coin_creator_fee
|
||||
// );
|
||||
|
||||
/// 卖出事件
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
@@ -150,32 +149,32 @@ pub fn pump_swap_sell_event_log_decode(data: &[u8]) -> Option<PumpSwapSellEvent>
|
||||
}
|
||||
|
||||
// 使用宏生成UnifiedEvent实现,指定需要合并的字段
|
||||
impl_unified_event!(
|
||||
PumpSwapSellEvent,
|
||||
timestamp,
|
||||
base_amount_in,
|
||||
min_quote_amount_out,
|
||||
user_base_token_reserves,
|
||||
user_quote_token_reserves,
|
||||
pool_base_token_reserves,
|
||||
pool_quote_token_reserves,
|
||||
quote_amount_out,
|
||||
lp_fee_basis_points,
|
||||
lp_fee,
|
||||
protocol_fee_basis_points,
|
||||
protocol_fee,
|
||||
quote_amount_out_without_lp_fee,
|
||||
user_quote_amount_out,
|
||||
pool,
|
||||
user,
|
||||
user_base_token_account,
|
||||
user_quote_token_account,
|
||||
protocol_fee_recipient,
|
||||
protocol_fee_recipient_token_account,
|
||||
coin_creator,
|
||||
coin_creator_fee_basis_points,
|
||||
coin_creator_fee
|
||||
);
|
||||
// impl_unified_event!(
|
||||
// PumpSwapSellEvent,
|
||||
// timestamp,
|
||||
// base_amount_in,
|
||||
// min_quote_amount_out,
|
||||
// user_base_token_reserves,
|
||||
// user_quote_token_reserves,
|
||||
// pool_base_token_reserves,
|
||||
// pool_quote_token_reserves,
|
||||
// quote_amount_out,
|
||||
// lp_fee_basis_points,
|
||||
// lp_fee,
|
||||
// protocol_fee_basis_points,
|
||||
// protocol_fee,
|
||||
// quote_amount_out_without_lp_fee,
|
||||
// user_quote_amount_out,
|
||||
// pool,
|
||||
// user,
|
||||
// user_base_token_account,
|
||||
// user_quote_token_account,
|
||||
// protocol_fee_recipient,
|
||||
// protocol_fee_recipient_token_account,
|
||||
// coin_creator,
|
||||
// coin_creator_fee_basis_points,
|
||||
// coin_creator_fee
|
||||
// );
|
||||
|
||||
/// 创建池子事件
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
@@ -219,29 +218,29 @@ pub fn pump_swap_create_pool_event_log_decode(data: &[u8]) -> Option<PumpSwapCre
|
||||
borsh::from_slice::<PumpSwapCreatePoolEvent>(&data[..PUMP_SWAP_CREATE_POOL_EVENT_LOG_SIZE]).ok()
|
||||
}
|
||||
|
||||
impl_unified_event!(
|
||||
PumpSwapCreatePoolEvent,
|
||||
timestamp,
|
||||
index,
|
||||
creator,
|
||||
base_mint,
|
||||
quote_mint,
|
||||
base_mint_decimals,
|
||||
quote_mint_decimals,
|
||||
base_amount_in,
|
||||
quote_amount_in,
|
||||
pool_base_amount,
|
||||
pool_quote_amount,
|
||||
minimum_liquidity,
|
||||
initial_liquidity,
|
||||
lp_token_amount_out,
|
||||
pool_bump,
|
||||
pool,
|
||||
lp_mint,
|
||||
user_base_token_account,
|
||||
user_quote_token_account,
|
||||
coin_creator
|
||||
);
|
||||
// impl_unified_event!(
|
||||
// PumpSwapCreatePoolEvent,
|
||||
// timestamp,
|
||||
// index,
|
||||
// creator,
|
||||
// base_mint,
|
||||
// quote_mint,
|
||||
// base_mint_decimals,
|
||||
// quote_mint_decimals,
|
||||
// base_amount_in,
|
||||
// quote_amount_in,
|
||||
// pool_base_amount,
|
||||
// pool_quote_amount,
|
||||
// minimum_liquidity,
|
||||
// initial_liquidity,
|
||||
// lp_token_amount_out,
|
||||
// pool_bump,
|
||||
// pool,
|
||||
// lp_mint,
|
||||
// user_base_token_account,
|
||||
// user_quote_token_account,
|
||||
// coin_creator
|
||||
// );
|
||||
|
||||
/// 存款事件
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
@@ -283,25 +282,25 @@ pub fn pump_swap_deposit_event_log_decode(data: &[u8]) -> Option<PumpSwapDeposit
|
||||
borsh::from_slice::<PumpSwapDepositEvent>(&data[..PUMP_SWAP_DEPOSIT_EVENT_LOG_SIZE]).ok()
|
||||
}
|
||||
|
||||
impl_unified_event!(
|
||||
PumpSwapDepositEvent,
|
||||
timestamp,
|
||||
lp_token_amount_out,
|
||||
max_base_amount_in,
|
||||
max_quote_amount_in,
|
||||
user_base_token_reserves,
|
||||
user_quote_token_reserves,
|
||||
pool_base_token_reserves,
|
||||
pool_quote_token_reserves,
|
||||
base_amount_in,
|
||||
quote_amount_in,
|
||||
lp_mint_supply,
|
||||
pool,
|
||||
user,
|
||||
user_base_token_account,
|
||||
user_quote_token_account,
|
||||
user_pool_token_account
|
||||
);
|
||||
// impl_unified_event!(
|
||||
// PumpSwapDepositEvent,
|
||||
// timestamp,
|
||||
// lp_token_amount_out,
|
||||
// max_base_amount_in,
|
||||
// max_quote_amount_in,
|
||||
// user_base_token_reserves,
|
||||
// user_quote_token_reserves,
|
||||
// pool_base_token_reserves,
|
||||
// pool_quote_token_reserves,
|
||||
// base_amount_in,
|
||||
// quote_amount_in,
|
||||
// lp_mint_supply,
|
||||
// pool,
|
||||
// user,
|
||||
// user_base_token_account,
|
||||
// user_quote_token_account,
|
||||
// user_pool_token_account
|
||||
// );
|
||||
|
||||
/// 提款事件
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
@@ -343,25 +342,25 @@ pub fn pump_swap_withdraw_event_log_decode(data: &[u8]) -> Option<PumpSwapWithdr
|
||||
borsh::from_slice::<PumpSwapWithdrawEvent>(&data[..PUMP_SWAP_WITHDRAW_EVENT_LOG_SIZE]).ok()
|
||||
}
|
||||
|
||||
impl_unified_event!(
|
||||
PumpSwapWithdrawEvent,
|
||||
timestamp,
|
||||
lp_token_amount_in,
|
||||
min_base_amount_out,
|
||||
min_quote_amount_out,
|
||||
user_base_token_reserves,
|
||||
user_quote_token_reserves,
|
||||
pool_base_token_reserves,
|
||||
pool_quote_token_reserves,
|
||||
base_amount_out,
|
||||
quote_amount_out,
|
||||
lp_mint_supply,
|
||||
pool,
|
||||
user,
|
||||
user_base_token_account,
|
||||
user_quote_token_account,
|
||||
user_pool_token_account
|
||||
);
|
||||
// impl_unified_event!(
|
||||
// PumpSwapWithdrawEvent,
|
||||
// timestamp,
|
||||
// lp_token_amount_in,
|
||||
// min_base_amount_out,
|
||||
// min_quote_amount_out,
|
||||
// user_base_token_reserves,
|
||||
// user_quote_token_reserves,
|
||||
// pool_base_token_reserves,
|
||||
// pool_quote_token_reserves,
|
||||
// base_amount_out,
|
||||
// quote_amount_out,
|
||||
// lp_mint_supply,
|
||||
// pool,
|
||||
// user,
|
||||
// user_base_token_account,
|
||||
// user_quote_token_account,
|
||||
// user_pool_token_account
|
||||
// );
|
||||
|
||||
/// 全局配置
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
@@ -375,7 +374,6 @@ pub struct PumpSwapGlobalConfigAccountEvent {
|
||||
pub rent_epoch: u64,
|
||||
pub global_config: GlobalConfig,
|
||||
}
|
||||
impl_unified_event!(PumpSwapGlobalConfigAccountEvent,);
|
||||
|
||||
/// 池
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
@@ -389,7 +387,6 @@ pub struct PumpSwapPoolAccountEvent {
|
||||
pub rent_epoch: u64,
|
||||
pub pool: Pool,
|
||||
}
|
||||
impl_unified_event!(PumpSwapPoolAccountEvent,);
|
||||
|
||||
/// 事件鉴别器常量
|
||||
pub mod discriminators {
|
||||
|
||||
@@ -70,24 +70,18 @@ pub const CONFIGS: &[GenericEventParseConfig] = &[
|
||||
];
|
||||
|
||||
/// 解析买入日志事件
|
||||
fn parse_buy_inner_instruction(
|
||||
data: &[u8],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
fn parse_buy_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
|
||||
if let Some(event) = pump_swap_buy_event_log_decode(data) {
|
||||
Some(Box::new(PumpSwapBuyEvent { metadata, ..event }))
|
||||
Some(UnifiedEvent::PumpSwapBuyEvent(PumpSwapBuyEvent { metadata, ..event }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// 解析卖出日志事件
|
||||
fn parse_sell_inner_instruction(
|
||||
data: &[u8],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
fn parse_sell_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
|
||||
if let Some(event) = pump_swap_sell_event_log_decode(data) {
|
||||
Some(Box::new(PumpSwapSellEvent { metadata, ..event }))
|
||||
Some(UnifiedEvent::PumpSwapSellEvent(PumpSwapSellEvent { metadata, ..event }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -97,33 +91,27 @@ fn parse_sell_inner_instruction(
|
||||
fn parse_create_pool_inner_instruction(
|
||||
data: &[u8],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if let Some(event) = pump_swap_create_pool_event_log_decode(data) {
|
||||
Some(Box::new(PumpSwapCreatePoolEvent { metadata, ..event }))
|
||||
Some(UnifiedEvent::PumpSwapCreatePoolEvent(PumpSwapCreatePoolEvent { metadata, ..event }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// 解析存款日志事件
|
||||
fn parse_deposit_inner_instruction(
|
||||
data: &[u8],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
fn parse_deposit_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
|
||||
if let Some(event) = pump_swap_deposit_event_log_decode(data) {
|
||||
Some(Box::new(PumpSwapDepositEvent { metadata, ..event }))
|
||||
Some(UnifiedEvent::PumpSwapDepositEvent(PumpSwapDepositEvent { metadata, ..event }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// 解析提款日志事件
|
||||
fn parse_withdraw_inner_instruction(
|
||||
data: &[u8],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
fn parse_withdraw_inner_instruction(data: &[u8], metadata: EventMetadata) -> Option<UnifiedEvent> {
|
||||
if let Some(event) = pump_swap_withdraw_event_log_decode(data) {
|
||||
Some(Box::new(PumpSwapWithdrawEvent { metadata, ..event }))
|
||||
Some(UnifiedEvent::PumpSwapWithdrawEvent(PumpSwapWithdrawEvent { metadata, ..event }))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -134,7 +122,7 @@ fn parse_buy_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if data.len() < 16 || accounts.len() < 11 {
|
||||
return None;
|
||||
}
|
||||
@@ -142,7 +130,7 @@ fn parse_buy_instruction(
|
||||
let base_amount_out = read_u64_le(data, 0)?;
|
||||
let max_quote_amount_in = read_u64_le(data, 8)?;
|
||||
|
||||
Some(Box::new(PumpSwapBuyEvent {
|
||||
Some(UnifiedEvent::PumpSwapBuyEvent(PumpSwapBuyEvent {
|
||||
metadata,
|
||||
base_amount_out,
|
||||
max_quote_amount_in,
|
||||
@@ -169,7 +157,7 @@ fn parse_sell_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if data.len() < 16 || accounts.len() < 11 {
|
||||
return None;
|
||||
}
|
||||
@@ -177,7 +165,7 @@ fn parse_sell_instruction(
|
||||
let base_amount_in = read_u64_le(data, 0)?;
|
||||
let min_quote_amount_out = read_u64_le(data, 8)?;
|
||||
|
||||
Some(Box::new(PumpSwapSellEvent {
|
||||
Some(UnifiedEvent::PumpSwapSellEvent(PumpSwapSellEvent {
|
||||
metadata,
|
||||
base_amount_in,
|
||||
min_quote_amount_out,
|
||||
@@ -204,7 +192,7 @@ fn parse_create_pool_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if data.len() < 18 || accounts.len() < 11 {
|
||||
return None;
|
||||
}
|
||||
@@ -218,7 +206,7 @@ fn parse_create_pool_instruction(
|
||||
Pubkey::default()
|
||||
};
|
||||
|
||||
Some(Box::new(PumpSwapCreatePoolEvent {
|
||||
Some(UnifiedEvent::PumpSwapCreatePoolEvent(PumpSwapCreatePoolEvent {
|
||||
metadata,
|
||||
index,
|
||||
base_amount_in,
|
||||
@@ -243,7 +231,7 @@ fn parse_deposit_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if data.len() < 24 || accounts.len() < 11 {
|
||||
return None;
|
||||
}
|
||||
@@ -252,7 +240,7 @@ fn parse_deposit_instruction(
|
||||
let max_base_amount_in = u64::from_le_bytes(data[8..16].try_into().ok()?);
|
||||
let max_quote_amount_in = u64::from_le_bytes(data[16..24].try_into().ok()?);
|
||||
|
||||
Some(Box::new(PumpSwapDepositEvent {
|
||||
Some(UnifiedEvent::PumpSwapDepositEvent(PumpSwapDepositEvent {
|
||||
metadata,
|
||||
lp_token_amount_out,
|
||||
max_base_amount_in,
|
||||
@@ -275,7 +263,7 @@ fn parse_withdraw_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if data.len() < 24 || accounts.len() < 11 {
|
||||
return None;
|
||||
}
|
||||
@@ -284,7 +272,7 @@ fn parse_withdraw_instruction(
|
||||
let min_base_amount_out = u64::from_le_bytes(data[8..16].try_into().ok()?);
|
||||
let min_quote_amount_out = u64::from_le_bytes(data[16..24].try_into().ok()?);
|
||||
|
||||
Some(Box::new(PumpSwapWithdrawEvent {
|
||||
Some(UnifiedEvent::PumpSwapWithdrawEvent(PumpSwapWithdrawEvent {
|
||||
metadata,
|
||||
lp_token_amount_in,
|
||||
min_base_amount_out,
|
||||
|
||||
@@ -5,9 +5,7 @@ use solana_sdk::pubkey::Pubkey;
|
||||
use crate::streaming::{
|
||||
event_parser::{
|
||||
common::EventMetadata,
|
||||
protocols::pumpswap::{
|
||||
PumpSwapGlobalConfigAccountEvent, PumpSwapPoolAccountEvent,
|
||||
},
|
||||
protocols::pumpswap::{PumpSwapGlobalConfigAccountEvent, PumpSwapPoolAccountEvent},
|
||||
UnifiedEvent,
|
||||
},
|
||||
grpc::AccountPretty,
|
||||
@@ -36,12 +34,12 @@ pub fn global_config_decode(data: &[u8]) -> Option<GlobalConfig> {
|
||||
pub fn global_config_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
) -> Option<UnifiedEvent> {
|
||||
if account.data.len() < GLOBAL_CONFIG_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(config) = global_config_decode(&account.data[8..GLOBAL_CONFIG_SIZE + 8]) {
|
||||
Some(Box::new(PumpSwapGlobalConfigAccountEvent {
|
||||
Some(UnifiedEvent::PumpSwapGlobalConfigAccountEvent(PumpSwapGlobalConfigAccountEvent {
|
||||
metadata,
|
||||
pubkey: account.pubkey,
|
||||
executable: account.executable,
|
||||
@@ -78,15 +76,12 @@ pub fn pool_decode(data: &[u8]) -> Option<Pool> {
|
||||
borsh::from_slice::<Pool>(&data[..POOL_SIZE]).ok()
|
||||
}
|
||||
|
||||
pub fn pool_parser(
|
||||
account: &AccountPretty,
|
||||
metadata: EventMetadata,
|
||||
) -> Option<Box<dyn UnifiedEvent>> {
|
||||
pub fn pool_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
|
||||
if account.data.len() < POOL_SIZE + 8 {
|
||||
return None;
|
||||
}
|
||||
if let Some(pool) = pool_decode(&account.data[8..POOL_SIZE + 8]) {
|
||||
Some(Box::new(PumpSwapPoolAccountEvent {
|
||||
Some(UnifiedEvent::PumpSwapPoolAccountEvent(PumpSwapPoolAccountEvent {
|
||||
metadata,
|
||||
pubkey: account.pubkey,
|
||||
executable: account.executable,
|
||||
|
||||
Reference in New Issue
Block a user