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:
ysq
2025-10-10 18:19:44 +08:00
parent 77caa39f0c
commit 312a675a40
43 changed files with 1013 additions and 1839 deletions
@@ -1,6 +1,6 @@
use crate::streaming::event_parser::common::EventMetadata;
use crate::{
impl_unified_event, streaming::event_parser::protocols::raydium_amm_v4::types::AmmInfo,
streaming::event_parser::protocols::raydium_amm_v4::types::AmmInfo,
};
use borsh::BorshDeserialize;
use serde::{Deserialize, Serialize};
@@ -38,8 +38,6 @@ pub struct RaydiumAmmV4SwapEvent {
pub user_source_owner: Pubkey,
}
impl_unified_event!(RaydiumAmmV4SwapEvent,);
/// 添加流动性
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
pub struct RaydiumAmmV4DepositEvent {
@@ -64,7 +62,6 @@ pub struct RaydiumAmmV4DepositEvent {
pub user_owner: Pubkey,
pub serum_event_queue: Pubkey,
}
impl_unified_event!(RaydiumAmmV4DepositEvent,);
/// 初始化
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -98,7 +95,6 @@ pub struct RaydiumAmmV4Initialize2Event {
pub user_token_pc: Pubkey,
pub user_lp_token_account: Pubkey,
}
impl_unified_event!(RaydiumAmmV4Initialize2Event,);
/// 移除流动性
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -130,7 +126,6 @@ pub struct RaydiumAmmV4WithdrawEvent {
pub serum_bids: Pubkey,
pub serum_asks: Pubkey,
}
impl_unified_event!(RaydiumAmmV4WithdrawEvent,);
/// 提现
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -156,7 +151,6 @@ pub struct RaydiumAmmV4WithdrawPnlEvent {
pub serum_pc_vault_account: Pubkey,
pub serum_vault_signer: Pubkey,
}
impl_unified_event!(RaydiumAmmV4WithdrawPnlEvent,);
/// 池信息
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
@@ -170,7 +164,6 @@ pub struct RaydiumAmmV4AmmInfoAccountEvent {
pub rent_epoch: u64,
pub amm_info: AmmInfo,
}
impl_unified_event!(RaydiumAmmV4AmmInfoAccountEvent,);
/// 事件鉴别器常量
pub mod discriminators {
@@ -82,12 +82,12 @@ fn parse_withdraw_pnl_instruction(
_data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if accounts.len() < 17 {
return None;
}
Some(Box::new(RaydiumAmmV4WithdrawPnlEvent {
Some(UnifiedEvent::RaydiumAmmV4WithdrawPnlEvent(RaydiumAmmV4WithdrawPnlEvent {
metadata,
token_program: accounts[0],
amm: accounts[1],
@@ -114,13 +114,13 @@ fn parse_withdraw_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 8 || accounts.len() < 22 {
return None;
}
let amount = read_u64_le(data, 0)?;
Some(Box::new(RaydiumAmmV4WithdrawEvent {
Some(UnifiedEvent::RaydiumAmmV4WithdrawEvent(RaydiumAmmV4WithdrawEvent {
metadata,
amount,
@@ -154,7 +154,7 @@ fn parse_initialize2_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 25 || accounts.len() < 21 {
return None;
}
@@ -163,7 +163,7 @@ fn parse_initialize2_instruction(
let init_pc_amount = read_u64_le(data, 9)?;
let init_coin_amount = read_u64_le(data, 17)?;
Some(Box::new(RaydiumAmmV4Initialize2Event {
Some(UnifiedEvent::RaydiumAmmV4Initialize2Event(RaydiumAmmV4Initialize2Event {
metadata,
nonce,
open_time,
@@ -199,7 +199,7 @@ fn parse_deposit_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 24 || accounts.len() < 14 {
return None;
}
@@ -207,7 +207,7 @@ fn parse_deposit_instruction(
let max_pc_amount = read_u64_le(data, 8)?;
let base_side = read_u64_le(data, 16)?;
Some(Box::new(RaydiumAmmV4DepositEvent {
Some(UnifiedEvent::RaydiumAmmV4DepositEvent(RaydiumAmmV4DepositEvent {
metadata,
max_coin_amount,
max_pc_amount,
@@ -235,7 +235,7 @@ fn parse_swap_base_output_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 17 {
return None;
}
@@ -249,7 +249,7 @@ fn parse_swap_base_output_instruction(
accounts.insert(4, Pubkey::default());
}
Some(Box::new(RaydiumAmmV4SwapEvent {
Some(UnifiedEvent::RaydiumAmmV4SwapEvent(RaydiumAmmV4SwapEvent {
metadata,
max_amount_in,
amount_out,
@@ -282,7 +282,7 @@ fn parse_swap_base_input_instruction(
data: &[u8],
accounts: &[Pubkey],
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
) -> Option<UnifiedEvent> {
if data.len() < 16 || accounts.len() < 17 {
return None;
}
@@ -296,7 +296,7 @@ fn parse_swap_base_input_instruction(
accounts.insert(4, Pubkey::default());
}
Some(Box::new(RaydiumAmmV4SwapEvent {
Some(UnifiedEvent::RaydiumAmmV4SwapEvent(RaydiumAmmV4SwapEvent {
metadata,
amount_in,
minimum_amount_out,
@@ -86,15 +86,12 @@ pub fn amm_info_decode(data: &[u8]) -> Option<AmmInfo> {
borsh::from_slice::<AmmInfo>(&data[..AMM_INFO_SIZE]).ok()
}
pub fn amm_info_parser(
account: &AccountPretty,
metadata: EventMetadata,
) -> Option<Box<dyn UnifiedEvent>> {
pub fn amm_info_parser(account: &AccountPretty, metadata: EventMetadata) -> Option<UnifiedEvent> {
if account.data.len() < AMM_INFO_SIZE {
return None;
}
if let Some(amm_info) = amm_info_decode(&account.data[..AMM_INFO_SIZE]) {
Some(Box::new(RaydiumAmmV4AmmInfoAccountEvent {
Some(UnifiedEvent::RaydiumAmmV4AmmInfoAccountEvent(RaydiumAmmV4AmmInfoAccountEvent {
metadata,
pubkey: account.pubkey,
executable: account.executable,