From 8ec1457858c60cb6e59be0715b095ac8fbeb595b Mon Sep 17 00:00:00 2001 From: ioxde <228087182+ioxde@users.noreply.github.com> Date: Mon, 8 Sep 2025 20:19:13 -0700 Subject: [PATCH] feat(event_parser): add requires_inner_instruction field to skip incomplete events - Add requires_inner_instruction field to GenericEventParseConfig - Skip events that require but lack inner instruction data during processing - Set PumpFun migrate events to require inner instructions (prevents parsing failed migrations) --- src/streaming/event_parser/core/traits.rs | 13 +++++++++++++ src/streaming/event_parser/protocols/bonk/parser.rs | 8 ++++++++ .../event_parser/protocols/pumpfun/parser.rs | 5 +++++ .../event_parser/protocols/pumpswap/parser.rs | 5 +++++ .../event_parser/protocols/raydium_amm_v4/parser.rs | 6 ++++++ .../event_parser/protocols/raydium_clmm/parser.rs | 8 ++++++++ .../event_parser/protocols/raydium_cpmm/parser.rs | 5 +++++ 7 files changed, 50 insertions(+) diff --git a/src/streaming/event_parser/core/traits.rs b/src/streaming/event_parser/core/traits.rs index 82ae0fc..ba3993b 100755 --- a/src/streaming/event_parser/core/traits.rs +++ b/src/streaming/event_parser/core/traits.rs @@ -891,6 +891,7 @@ pub struct GenericEventParseConfig { pub event_type: EventType, pub inner_instruction_parser: Option, pub instruction_parser: Option, + pub requires_inner_instruction: bool, } /// 内联指令事件解析器 @@ -1200,6 +1201,12 @@ impl EventParser for GenericEventParser { event.set_swap_data(swap_data); } } + + // Skip events that require inner instruction data but don't have it + if config.requires_inner_instruction && inner_instruction_event.is_none() { + continue; + } + // 合并事件 if let Some(inner_instruction_event) = inner_instruction_event { event.merge(&*inner_instruction_event); @@ -1335,6 +1342,12 @@ impl EventParser for GenericEventParser { event.set_swap_data(swap_data); } } + + // Skip events that require inner instruction data but don't have it + if config.requires_inner_instruction && inner_instruction_event.is_none() { + continue; + } + // 合并事件 if let Some(inner_instruction_event) = inner_instruction_event { event.merge(&*inner_instruction_event); diff --git a/src/streaming/event_parser/protocols/bonk/parser.rs b/src/streaming/event_parser/protocols/bonk/parser.rs index e16fc8f..0d57d5e 100755 --- a/src/streaming/event_parser/protocols/bonk/parser.rs +++ b/src/streaming/event_parser/protocols/bonk/parser.rs @@ -41,6 +41,7 @@ impl BonkEventParser { event_type: EventType::BonkBuyExactIn, inner_instruction_parser: Some(Self::parse_trade_inner_instruction), instruction_parser: Some(Self::parse_buy_exact_in_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -50,6 +51,7 @@ impl BonkEventParser { event_type: EventType::BonkBuyExactOut, inner_instruction_parser: Some(Self::parse_trade_inner_instruction), instruction_parser: Some(Self::parse_buy_exact_out_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -59,6 +61,7 @@ impl BonkEventParser { event_type: EventType::BonkSellExactIn, inner_instruction_parser: Some(Self::parse_trade_inner_instruction), instruction_parser: Some(Self::parse_sell_exact_in_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -68,6 +71,7 @@ impl BonkEventParser { event_type: EventType::BonkSellExactOut, inner_instruction_parser: Some(Self::parse_trade_inner_instruction), instruction_parser: Some(Self::parse_sell_exact_out_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -77,6 +81,7 @@ impl BonkEventParser { event_type: EventType::BonkInitialize, inner_instruction_parser: Some(Self::parse_pool_create_inner_instruction), instruction_parser: Some(Self::parse_initialize_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -86,6 +91,7 @@ impl BonkEventParser { event_type: EventType::BonkInitializeV2, inner_instruction_parser: Some(Self::parse_pool_create_inner_instruction), instruction_parser: Some(Self::parse_initialize_v2_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -95,6 +101,7 @@ impl BonkEventParser { event_type: EventType::BonkMigrateToAmm, inner_instruction_parser: None, instruction_parser: Some(Self::parse_migrate_to_amm_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: BONK_PROGRAM_ID, @@ -104,6 +111,7 @@ impl BonkEventParser { event_type: EventType::BonkMigrateToCpswap, inner_instruction_parser: None, instruction_parser: Some(Self::parse_migrate_to_cpswap_instruction), + requires_inner_instruction: false, }, ]; diff --git a/src/streaming/event_parser/protocols/pumpfun/parser.rs b/src/streaming/event_parser/protocols/pumpfun/parser.rs index 0de1634..6d79b74 100755 --- a/src/streaming/event_parser/protocols/pumpfun/parser.rs +++ b/src/streaming/event_parser/protocols/pumpfun/parser.rs @@ -40,6 +40,7 @@ impl PumpFunEventParser { event_type: EventType::PumpFunCreateToken, inner_instruction_parser: Some(Self::parse_create_token_inner_instruction), instruction_parser: Some(Self::parse_create_token_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPFUN_PROGRAM_ID, @@ -49,6 +50,7 @@ impl PumpFunEventParser { event_type: EventType::PumpFunBuy, inner_instruction_parser: Some(Self::parse_trade_inner_instruction), instruction_parser: Some(Self::parse_buy_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPFUN_PROGRAM_ID, @@ -58,6 +60,7 @@ impl PumpFunEventParser { event_type: EventType::PumpFunSell, inner_instruction_parser: Some(Self::parse_trade_inner_instruction), instruction_parser: Some(Self::parse_sell_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPFUN_PROGRAM_ID, @@ -67,6 +70,8 @@ impl PumpFunEventParser { event_type: EventType::PumpFunMigrate, inner_instruction_parser: Some(Self::parse_migrate_inner_instruction), instruction_parser: Some(Self::parse_migrate_instruction), + // Failed migrations lack inner instruction data (typically "Bonding curve already migrated") + requires_inner_instruction: true, }, ]; diff --git a/src/streaming/event_parser/protocols/pumpswap/parser.rs b/src/streaming/event_parser/protocols/pumpswap/parser.rs index d50372e..529badf 100755 --- a/src/streaming/event_parser/protocols/pumpswap/parser.rs +++ b/src/streaming/event_parser/protocols/pumpswap/parser.rs @@ -41,6 +41,7 @@ impl PumpSwapEventParser { event_type: EventType::PumpSwapBuy, inner_instruction_parser: Some(Self::parse_buy_inner_instruction), instruction_parser: Some(Self::parse_buy_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPSWAP_PROGRAM_ID, @@ -50,6 +51,7 @@ impl PumpSwapEventParser { event_type: EventType::PumpSwapSell, inner_instruction_parser: Some(Self::parse_sell_inner_instruction), instruction_parser: Some(Self::parse_sell_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPSWAP_PROGRAM_ID, @@ -59,6 +61,7 @@ impl PumpSwapEventParser { event_type: EventType::PumpSwapCreatePool, inner_instruction_parser: Some(Self::parse_create_pool_inner_instruction), instruction_parser: Some(Self::parse_create_pool_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPSWAP_PROGRAM_ID, @@ -68,6 +71,7 @@ impl PumpSwapEventParser { event_type: EventType::PumpSwapDeposit, inner_instruction_parser: Some(Self::parse_deposit_inner_instruction), instruction_parser: Some(Self::parse_deposit_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: PUMPSWAP_PROGRAM_ID, @@ -77,6 +81,7 @@ impl PumpSwapEventParser { event_type: EventType::PumpSwapWithdraw, inner_instruction_parser: Some(Self::parse_withdraw_inner_instruction), instruction_parser: Some(Self::parse_withdraw_instruction), + requires_inner_instruction: false, }, ]; diff --git a/src/streaming/event_parser/protocols/raydium_amm_v4/parser.rs b/src/streaming/event_parser/protocols/raydium_amm_v4/parser.rs index f9124e3..07ece61 100755 --- a/src/streaming/event_parser/protocols/raydium_amm_v4/parser.rs +++ b/src/streaming/event_parser/protocols/raydium_amm_v4/parser.rs @@ -39,6 +39,7 @@ impl RaydiumAmmV4EventParser { event_type: EventType::RaydiumAmmV4SwapBaseIn, inner_instruction_parser: None, instruction_parser: Some(Self::parse_swap_base_input_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_AMM_V4_PROGRAM_ID, @@ -48,6 +49,7 @@ impl RaydiumAmmV4EventParser { event_type: EventType::RaydiumAmmV4SwapBaseOut, inner_instruction_parser: None, instruction_parser: Some(Self::parse_swap_base_output_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_AMM_V4_PROGRAM_ID, @@ -57,6 +59,7 @@ impl RaydiumAmmV4EventParser { event_type: EventType::RaydiumAmmV4Deposit, inner_instruction_parser: None, instruction_parser: Some(Self::parse_deposit_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_AMM_V4_PROGRAM_ID, @@ -66,6 +69,7 @@ impl RaydiumAmmV4EventParser { event_type: EventType::RaydiumAmmV4Initialize2, inner_instruction_parser: None, instruction_parser: Some(Self::parse_initialize2_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_AMM_V4_PROGRAM_ID, @@ -75,6 +79,7 @@ impl RaydiumAmmV4EventParser { event_type: EventType::RaydiumAmmV4Withdraw, inner_instruction_parser: None, instruction_parser: Some(Self::parse_withdraw_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_AMM_V4_PROGRAM_ID, @@ -84,6 +89,7 @@ impl RaydiumAmmV4EventParser { event_type: EventType::RaydiumAmmV4WithdrawPnl, inner_instruction_parser: None, instruction_parser: Some(Self::parse_withdraw_pnl_instruction), + requires_inner_instruction: false, }, ]; diff --git a/src/streaming/event_parser/protocols/raydium_clmm/parser.rs b/src/streaming/event_parser/protocols/raydium_clmm/parser.rs index ced7677..6e1e6ba 100755 --- a/src/streaming/event_parser/protocols/raydium_clmm/parser.rs +++ b/src/streaming/event_parser/protocols/raydium_clmm/parser.rs @@ -44,6 +44,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmSwap, inner_instruction_parser: None, instruction_parser: Some(Self::parse_swap_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -53,6 +54,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmSwapV2, inner_instruction_parser: None, instruction_parser: Some(Self::parse_swap_v2_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -62,6 +64,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmClosePosition, inner_instruction_parser: None, instruction_parser: Some(Self::parse_close_position_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -71,6 +74,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmDecreaseLiquidityV2, inner_instruction_parser: None, instruction_parser: Some(Self::parse_decrease_liquidity_v2_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -80,6 +84,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmCreatePool, inner_instruction_parser: None, instruction_parser: Some(Self::parse_create_pool_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -89,6 +94,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmIncreaseLiquidityV2, inner_instruction_parser: None, instruction_parser: Some(Self::parse_increase_liquidity_v2_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -98,6 +104,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmOpenPositionWithToken22Nft, inner_instruction_parser: None, instruction_parser: Some(Self::parse_open_position_with_token_22_nft_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CLMM_PROGRAM_ID, @@ -107,6 +114,7 @@ impl RaydiumClmmEventParser { event_type: EventType::RaydiumClmmOpenPositionV2, inner_instruction_parser: None, instruction_parser: Some(Self::parse_open_position_v2_instruction), + requires_inner_instruction: false, }, ]; diff --git a/src/streaming/event_parser/protocols/raydium_cpmm/parser.rs b/src/streaming/event_parser/protocols/raydium_cpmm/parser.rs index d89f779..25020f1 100755 --- a/src/streaming/event_parser/protocols/raydium_cpmm/parser.rs +++ b/src/streaming/event_parser/protocols/raydium_cpmm/parser.rs @@ -39,6 +39,7 @@ impl RaydiumCpmmEventParser { event_type: EventType::RaydiumCpmmSwapBaseInput, inner_instruction_parser: None, instruction_parser: Some(Self::parse_swap_base_input_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CPMM_PROGRAM_ID, @@ -48,6 +49,7 @@ impl RaydiumCpmmEventParser { event_type: EventType::RaydiumCpmmSwapBaseOutput, inner_instruction_parser: None, instruction_parser: Some(Self::parse_swap_base_output_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CPMM_PROGRAM_ID, @@ -57,6 +59,7 @@ impl RaydiumCpmmEventParser { event_type: EventType::RaydiumCpmmDeposit, inner_instruction_parser: None, instruction_parser: Some(Self::parse_deposit_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CPMM_PROGRAM_ID, @@ -66,6 +69,7 @@ impl RaydiumCpmmEventParser { event_type: EventType::RaydiumCpmmInitialize, inner_instruction_parser: None, instruction_parser: Some(Self::parse_initialize_instruction), + requires_inner_instruction: false, }, GenericEventParseConfig { program_id: RAYDIUM_CPMM_PROGRAM_ID, @@ -75,6 +79,7 @@ impl RaydiumCpmmEventParser { event_type: EventType::RaydiumCpmmWithdraw, inner_instruction_parser: None, instruction_parser: Some(Self::parse_withdraw_instruction), + requires_inner_instruction: false, }, ];