sol_parser_sdk/instr/
utils.rs

1//! 指令解析通用工具函数
2
3use solana_sdk::{pubkey::Pubkey, signature::Signature};
4use crate::core::events::EventMetadata;
5
6/// 创建事件元数据的通用函数
7pub fn create_metadata(
8    signature: Signature,
9    slot: u64,
10    tx_index: u64,
11    block_time_us: i64,
12    grpc_recv_us: i64,
13) -> EventMetadata {
14    EventMetadata {
15        signature,
16        slot,
17        tx_index,
18        block_time_us,
19        grpc_recv_us,
20    }
21}
22
23/// 创建事件元数据的兼容性函数(用于指令解析)
24#[inline(always)]
25pub fn create_metadata_simple(
26    signature: Signature,
27    slot: u64,
28    tx_index: u64,
29    block_time: Option<i64>,
30    _program_id: Pubkey,
31) -> EventMetadata {
32    // 优化:macOS 使用 CLOCK_REALTIME(Linux 可用 CLOCK_REALTIME_COARSE)
33    let current_time = unsafe {
34        let mut ts = libc::timespec {
35            tv_sec: 0,
36            tv_nsec: 0,
37        };
38        #[cfg(target_os = "linux")]
39        libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, &mut ts);
40        #[cfg(not(target_os = "linux"))]
41        libc::clock_gettime(libc::CLOCK_REALTIME, &mut ts);
42        (ts.tv_sec as i64 * 1_000_000) + (ts.tv_nsec as i64 / 1_000)
43    };
44
45    EventMetadata {
46        signature,
47        slot,
48        tx_index,
49        block_time_us: block_time.map_or(0, |t| t * 1_000_000),
50        grpc_recv_us: current_time,
51    }
52}
53
54/// 从指令数据中读取 u64(小端序)- SIMD 优化
55#[inline(always)]
56pub fn read_u64_le(data: &[u8], offset: usize) -> Option<u64> {
57    data.get(offset..offset + 8)
58        .map(|slice| u64::from_le_bytes(slice.try_into().unwrap()))
59}
60
61/// 从指令数据中读取 u32(小端序)- SIMD 优化
62#[inline(always)]
63pub fn read_u32_le(data: &[u8], offset: usize) -> Option<u32> {
64    data.get(offset..offset + 4)
65        .map(|slice| u32::from_le_bytes(slice.try_into().unwrap()))
66}
67
68/// 从指令数据中读取 u16(小端序)- SIMD 优化
69#[inline(always)]
70pub fn read_u16_le(data: &[u8], offset: usize) -> Option<u16> {
71    data.get(offset..offset + 2)
72        .map(|slice| u16::from_le_bytes(slice.try_into().unwrap()))
73}
74
75/// 从指令数据中读取 u8
76#[inline(always)]
77pub fn read_u8(data: &[u8], offset: usize) -> Option<u8> {
78    data.get(offset).copied()
79}
80
81/// 从指令数据中读取 i32(小端序)- SIMD 优化
82#[inline(always)]
83pub fn read_i32_le(data: &[u8], offset: usize) -> Option<i32> {
84    data.get(offset..offset + 4)
85        .map(|slice| i32::from_le_bytes(slice.try_into().unwrap()))
86}
87
88/// 从指令数据中读取 u128(小端序)- SIMD 优化
89#[inline(always)]
90pub fn read_u128_le(data: &[u8], offset: usize) -> Option<u128> {
91    data.get(offset..offset + 16)
92        .map(|slice| u128::from_le_bytes(slice.try_into().unwrap()))
93}
94
95/// 从指令数据中读取布尔值
96#[inline(always)]
97pub fn read_bool(data: &[u8], offset: usize) -> Option<bool> {
98    data.get(offset).map(|&b| b != 0)
99}
100
101/// 从指令数据中读取公钥 - SIMD 优化
102#[inline(always)]
103pub fn read_pubkey(data: &[u8], offset: usize) -> Option<Pubkey> {
104    data.get(offset..offset + 32)
105        .and_then(|slice| Pubkey::try_from(slice).ok())
106}
107
108/// 从账户列表中获取账户
109#[inline(always)]
110pub fn get_account(accounts: &[Pubkey], index: usize) -> Option<Pubkey> {
111    accounts.get(index).copied()
112}
113
114/// 计算滑点基点
115pub fn calculate_slippage_bps(amount_in: u64, amount_out_min: u64) -> u16 {
116    if amount_in == 0 {
117        return 0;
118    }
119
120    // 简化的滑点计算
121    let slippage = ((amount_in.saturating_sub(amount_out_min)) * 10000) / amount_in;
122    slippage.min(10000) as u16
123}
124
125/// 计算价格影响基点
126pub fn calculate_price_impact_bps(amount_in: u64, amount_out: u64, expected_out: u64) -> u16 {
127    if expected_out == 0 {
128        return 0;
129    }
130
131    let impact = ((expected_out.saturating_sub(amount_out)) * 10000) / expected_out;
132    impact.min(10000) as u16
133}
134
135/// 从指令数据中读取字节数组
136pub fn read_bytes(data: &[u8], offset: usize, length: usize) -> Option<&[u8]> {
137    if data.len() < offset + length {
138        return None;
139    }
140    Some(&data[offset..offset + length])
141}
142
143/// 从指令数据中读取u64向量(简化版本)
144pub fn read_vec_u64(data: &[u8], _offset: usize) -> Option<Vec<u64>> {
145    // 简化版本:返回默认的两个元素向量
146    // 实际实现需要根据具体的数据格式来解析
147    Some(vec![0, 0])
148}