fix: post-merge robustness - global_state cleanup count, swap bounds, blockhash & i32 index

- global_state: only decrement signature_count when remove() actually removed entry
- types: bounds-check program_id_index and account indices in swap extraction
- types: require data.len() >= 9/12 before slicing token instruction data
- types: use i32 for current_index and safe skip count to avoid i8 truncation/UB
- event_parser: encode recent_blockhash only when len() == 32; pass i32 to swap parsers

Made-with: Cursor
This commit is contained in:
Wood
2026-03-09 10:23:33 +08:00
parent adb4cfc52d
commit 6e5e378247
3 changed files with 36 additions and 18 deletions
@@ -82,7 +82,7 @@ impl EventParser {
.collect();
// 解析指令事件
let instructions = &message.instructions;
let recent_blockhash = if message.recent_blockhash.is_empty() {
let recent_blockhash = if message.recent_blockhash.len() != 32 {
None
} else {
Some(solana_sdk::bs58::encode(&message.recent_blockhash).into_string())
@@ -434,7 +434,7 @@ impl EventParser {
if let Some(swap_data) = parse_swap_data_from_next_grpc_instructions(
&event,
inner_instructions_ref,
current_inner_idx as i8,
current_inner_idx,
accounts,
) {
event.metadata_mut().set_swap_data(swap_data);
@@ -602,7 +602,7 @@ impl EventParser {
parse_swap_data_from_next_instructions(
&event,
inner_instructions_ref,
current_inner_idx as i8,
current_inner_idx,
accounts,
)
} else {
@@ -55,10 +55,11 @@ impl GlobalState {
.map(|entry| *entry.key())
.collect();
// Remove old signatures atomically
// Remove old signatures atomically; only decrement count when entry was present
for signature in signatures_to_remove {
self.signature_data.remove(&signature);
self.signature_count.fetch_sub(1, Ordering::Relaxed);
if self.signature_data.remove(&signature).is_some() {
self.signature_count.fetch_sub(1, Ordering::Relaxed);
}
}
}