Skip to main content

sol_parser_sdk/core/
unified_parser.rs

1//! 统一解析器 - 简化的单一入口解析器
2//!
3//! 提供完整的交易解析能力,支持指令和日志数据处理
4//!
5//! ## 零延迟优化
6//! - 使用 SmallVec 避免小数组堆分配
7//! - 内联热路径函数
8//! - 流式处理,立即回调
9//! - 分支预测提示
10
11use crate::core::events::*;
12use smallvec::{smallvec, SmallVec};
13use solana_sdk::{pubkey::Pubkey, signature::Signature};
14
15/// 主要解析函数 - 解析完整交易并返回所有 DEX 事件
16///
17/// 参数:
18/// - instruction_data: 交易指令数据
19/// - accounts: 账户列表
20/// - logs: 交易日志
21/// - signature: 交易签名
22/// - slot: 区块高度
23/// - block_time_us: 区块时间
24/// - program_id: 程序 ID
25///
26/// ## 零延迟优化
27/// - 使用 SmallVec<[DexEvent; 4]> 栈分配,大多数交易 ≤ 4 个事件
28/// - 预分配容量,避免动态扩容
29#[inline] // 零延迟优化:内联
30pub fn parse_transaction_events(
31    _instruction_data: &[u8],
32    _accounts: &[Pubkey],
33    logs: &[String],
34    signature: Signature,
35    slot: u64,
36    _tx_index: u64,
37    block_time_us: Option<i64>,
38    _program_id: &Pubkey,
39) -> SmallVec<[DexEvent; 4]> {
40    // 零延迟优化:SmallVec 栈分配
41    let mut events = smallvec![]; // 栈分配,容量 4
42
43    // 2. 解析日志事件 - 大多数日志会成功解析
44    for log in logs {
45        if let Some(log_event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us)
46        {
47            events.push(log_event); // 热路径:成功解析
48        }
49        // 冷路径:解析失败,继续下一个
50    }
51
52    events
53}
54
55/// 简化版本 - 仅解析日志事件
56#[inline] // 零延迟优化:内联
57pub fn parse_logs_only(
58    logs: &[String],
59    signature: Signature,
60    slot: u64,
61    block_time_us: Option<i64>,
62) -> SmallVec<[DexEvent; 4]> {
63    // 零延迟优化:SmallVec 栈分配
64    let mut events = SmallVec::with_capacity(logs.len().min(4)); // 预分配容量
65
66    for log in logs {
67        if let Some(event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us) {
68            events.push(event);
69        }
70    }
71
72    events
73}
74
75/// 事件监听器 trait - 用户可以实现此 trait 来处理解析出的事件
76pub trait EventListener {
77    fn on_dex_event(&self, event: &DexEvent);
78}
79
80/// 使用监听器解析交易的便捷函数
81pub fn parse_transaction_with_listener<T: EventListener>(
82    instruction_data: &[u8],
83    accounts: &[Pubkey],
84    logs: &[String],
85    signature: Signature,
86    slot: u64,
87    tx_index: u64,
88    block_time_us: Option<i64>,
89    program_id: &Pubkey,
90    listener: &T,
91) {
92    let events = parse_transaction_events(
93        instruction_data,
94        accounts,
95        logs,
96        signature,
97        slot,
98        tx_index,
99        block_time_us,
100        program_id,
101    );
102
103    for event in &events {
104        listener.on_dex_event(event);
105    }
106}
107
108/// 流式解析交易事件 - 每解析出一个事件就立即回调
109///
110/// 这个版本不做事件合并,确保每个事件都能立即被处理
111/// 适用于需要实时响应的场景
112pub fn parse_transaction_events_streaming<F>(
113    _instruction_data: &[u8],
114    _accounts: &[Pubkey],
115    logs: &[String],
116    signature: Signature,
117    slot: u64,
118    _tx_index: u64,
119    block_time_us: Option<i64>,
120    _program_id: &Pubkey,
121    mut callback: F,
122) where
123    F: FnMut(DexEvent),
124{
125    // 1. 先解析指令事件(如果有) - 立即回调
126    // if let Some(instr_event) = crate::instr::parse_instruction_unified(
127    //     instruction_data, accounts, signature, slot, tx_index, block_time_us, program_id
128    // ) {
129    //     callback(instr_event);  // 立即回调指令事件
130    // }
131
132    // 2. 逐个解析日志事件 - 每个事件立即回调
133    for log in logs {
134        if let Some(log_event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us)
135        {
136            callback(log_event); // 立即回调日志事件,不等待其他日志
137        }
138    }
139
140    // 注意:这里完全不做事件合并和缓存,确保每个事件都是立即回调
141    // 回调顺序:先指令事件,然后按日志顺序回调日志事件
142}
143
144/// 流式解析日志事件 - 每解析出一个事件就立即回调
145pub fn parse_logs_streaming<F>(
146    logs: &[String],
147    signature: Signature,
148    slot: u64,
149    block_time_us: Option<i64>,
150    mut callback: F,
151) where
152    F: FnMut(DexEvent),
153{
154    for log in logs {
155        if let Some(event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us) {
156            callback(event);
157        }
158    }
159}
160
161/// 流式事件监听器 trait - 适用于流式处理
162pub trait StreamingEventListener {
163    fn on_dex_event_streaming(&mut self, event: DexEvent);
164}
165
166/// 使用流式监听器解析交易的便捷函数
167pub fn parse_transaction_with_streaming_listener<T: StreamingEventListener>(
168    instruction_data: &[u8],
169    accounts: &[Pubkey],
170    logs: &[String],
171    signature: Signature,
172    slot: u64,
173    tx_index: u64,
174    block_time_us: Option<i64>,
175    program_id: &Pubkey,
176    listener: &mut T,
177) {
178    parse_transaction_events_streaming(
179        instruction_data,
180        accounts,
181        logs,
182        signature,
183        slot,
184        tx_index,
185        block_time_us,
186        program_id,
187        |event| listener.on_dex_event_streaming(event),
188    );
189}