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 solana_sdk::{pubkey::Pubkey, signature::Signature};
13use smallvec::{SmallVec, smallvec};
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]> {  // 零延迟优化:SmallVec 栈分配
40    let mut events = smallvec![];  // 栈分配,容量 4
41
42    // 2. 解析日志事件 - 大多数日志会成功解析
43    for log in logs {
44        if let Some(log_event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us) {
45            events.push(log_event);  // 热路径:成功解析
46        }
47        // 冷路径:解析失败,继续下一个
48    }
49
50    events
51}
52
53/// 简化版本 - 仅解析日志事件
54#[inline]  // 零延迟优化:内联
55pub fn parse_logs_only(
56    logs: &[String],
57    signature: Signature,
58    slot: u64,
59    block_time_us: Option<i64>,
60) -> SmallVec<[DexEvent; 4]> {  // 零延迟优化:SmallVec 栈分配
61    let mut events = SmallVec::with_capacity(logs.len().min(4));  // 预分配容量
62
63    for log in logs {
64        if let Some(event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us) {
65            events.push(event);
66        }
67    }
68
69    events
70}
71
72/// 事件监听器 trait - 用户可以实现此 trait 来处理解析出的事件
73pub trait EventListener {
74    fn on_dex_event(&self, event: &DexEvent);
75}
76
77/// 使用监听器解析交易的便捷函数
78pub fn parse_transaction_with_listener<T: EventListener>(
79    instruction_data: &[u8],
80    accounts: &[Pubkey],
81    logs: &[String],
82    signature: Signature,
83    slot: u64,
84    tx_index: u64,
85    block_time_us: Option<i64>,
86    program_id: &Pubkey,
87    listener: &T,
88) {
89    let events = parse_transaction_events(
90        instruction_data, accounts, logs, signature, slot, tx_index, block_time_us, program_id
91    );
92
93    for event in &events {
94        listener.on_dex_event(event);
95    }
96}
97
98/// 流式解析交易事件 - 每解析出一个事件就立即回调
99///
100/// 这个版本不做事件合并,确保每个事件都能立即被处理
101/// 适用于需要实时响应的场景
102pub fn parse_transaction_events_streaming<F>(
103    _instruction_data: &[u8],
104    _accounts: &[Pubkey],
105    logs: &[String],
106    signature: Signature,
107    slot: u64,
108    _tx_index: u64,
109    block_time_us: Option<i64>,
110    _program_id: &Pubkey,
111    mut callback: F,
112) where
113    F: FnMut(DexEvent)
114{
115    // 1. 先解析指令事件(如果有) - 立即回调
116    // if let Some(instr_event) = crate::instr::parse_instruction_unified(
117    //     instruction_data, accounts, signature, slot, tx_index, block_time_us, program_id
118    // ) {
119    //     callback(instr_event);  // 立即回调指令事件
120    // }
121
122    // 2. 逐个解析日志事件 - 每个事件立即回调
123    for log in logs {
124        if let Some(log_event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us) {
125            callback(log_event);  // 立即回调日志事件,不等待其他日志
126        }
127    }
128
129    // 注意:这里完全不做事件合并和缓存,确保每个事件都是立即回调
130    // 回调顺序:先指令事件,然后按日志顺序回调日志事件
131}
132
133/// 流式解析日志事件 - 每解析出一个事件就立即回调
134pub fn parse_logs_streaming<F>(
135    logs: &[String],
136    signature: Signature,
137    slot: u64,
138    block_time_us: Option<i64>,
139    mut callback: F,
140) where
141    F: FnMut(DexEvent)
142{
143    for log in logs {
144        if let Some(event) = crate::logs::parse_log_unified(log, signature, slot, block_time_us) {
145            callback(event);
146        }
147    }
148}
149
150/// 流式事件监听器 trait - 适用于流式处理
151pub trait StreamingEventListener {
152    fn on_dex_event_streaming(&mut self, event: DexEvent);
153}
154
155/// 使用流式监听器解析交易的便捷函数
156pub fn parse_transaction_with_streaming_listener<T: StreamingEventListener>(
157    instruction_data: &[u8],
158    accounts: &[Pubkey],
159    logs: &[String],
160    signature: Signature,
161    slot: u64,
162    tx_index: u64,
163    block_time_us: Option<i64>,
164    program_id: &Pubkey,
165    listener: &mut T,
166) {
167    parse_transaction_events_streaming(
168        instruction_data,
169        accounts,
170        logs,
171        signature,
172        slot,
173        tx_index,
174        block_time_us,
175        program_id,
176        |event| listener.on_dex_event_streaming(event)
177    );
178}