NAC_Blockchain/nac-udm/src/l1_protocol/acc/acc1410/events.rs

637 lines
18 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! 事件通知系统
//!
//! 实现完整的事件通知功能,包括事件定义、事件触发、事件监听和事件日志
use std::sync::Arc;
/// ACC-1410事件类型
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
/// Acc1410Event 协议事件
pub enum Acc1410Event {
/// 分区创建事件
PartitionCreated {
/// 分区标识符
partition_id: [u8; 32],
/// 名称
name: String,
/// partition_type 字段
partition_type: u8,
},
/// 分区关闭事件
PartitionClosed {
/// 分区标识符
partition_id: [u8; 32],
},
/// 转账事件
Transfer {
/// 发送方账户地址
from: String,
/// 接收方账户地址
to: String,
/// 代币数量(最小单位)
amount: u64,
/// 分区标识符
partition_id: [u8; 32],
},
/// 铸造事件
Mint {
/// 接收方账户地址
to: String,
/// 代币数量(最小单位)
amount: u64,
/// 分区标识符
partition_id: [u8; 32],
},
/// 销毁事件
Burn {
/// 发送方账户地址
from: String,
/// 代币数量(最小单位)
amount: u64,
/// 分区标识符
partition_id: [u8; 32],
},
/// 操作员授权事件
OperatorAuthorized {
/// account 字段
account: String,
/// 操作员账户地址
operator: String,
/// 分区标识符
partition_id: Option<[u8; 32]>,
},
/// 操作员撤销事件
OperatorRevoked {
/// account 字段
account: String,
/// 操作员账户地址
operator: String,
/// 分区标识符
partition_id: Option<[u8; 32]>,
},
/// 账户锁定事件
AccountLocked {
/// account 字段
account: String,
/// unlock_time 字段
unlock_time: u64,
},
/// 账户解锁事件
AccountUnlocked {
/// account 字段
account: String,
},
/// 批量转账事件
BatchTransfer {
/// 发送方账户地址
from: String,
/// recipient_count 字段
recipient_count: usize,
/// 操作总金额
total_amount: u64,
/// 分区标识符
partition_id: [u8; 32],
},
/// 批量铸造事件
BatchMint {
/// recipient_count 字段
recipient_count: usize,
/// 操作总金额
total_amount: u64,
/// 分区标识符
partition_id: [u8; 32],
},
/// 批量销毁事件
BatchBurn {
/// account_count 字段
account_count: usize,
/// 操作总金额
total_amount: u64,
/// 分区标识符
partition_id: [u8; 32],
},
}
/// 事件记录
#[derive(Debug, Clone)]
/// EventRecord 协议事件
pub struct EventRecord {
/// 事件ID
pub event_id: u64,
/// 事件类型
pub event: Acc1410Event,
/// 时间戳
pub timestamp: u64,
/// 区块高度(可选)
pub block_height: Option<u64>,
/// 交易哈希 (SHA3-384 Hash)(可选)
pub tx_hash: Option<[u8; 48]>,
}
/// 事件监听器trait
pub trait EventListener: Send + Sync + std::fmt::Debug {
/// 处理事件
fn on_event(&self, event: &EventRecord);
/// 获取监听器名称
fn name(&self) -> &str;
}
/// 事件过滤器
#[derive(Debug, Clone)]
/// EventFilter 协议事件
pub struct EventFilter {
/// 事件类型过滤None表示所有类型
pub event_types: Option<Vec<String>>,
/// 账户过滤
pub accounts: Option<Vec<String>>,
/// 分区过滤
pub partitions: Option<Vec<[u8; 32]>>,
/// 时间范围过滤
pub time_range: Option<(u64, u64)>,
}
/// 事件管理器
#[derive(Debug)]
/// EventManager 协议事件
pub struct EventManager {
/// 事件日志
event_log: Vec<EventRecord>,
/// 事件监听器
listeners: Vec<Arc<dyn EventListener>>,
/// 事件计数器
event_counter: u64,
/// 最大日志大小
max_log_size: usize,
}
impl EventManager {
/// 创建新的事件管理器
pub fn new() -> Self {
Self {
event_log: Vec::new(),
listeners: Vec::new(),
event_counter: 0,
max_log_size: 10000,
}
}
/// 设置最大日志大小
pub fn set_max_log_size(&mut self, size: usize) {
self.max_log_size = size;
}
/// 添加事件监听器
pub fn add_listener(&mut self, listener: Arc<dyn EventListener>) {
self.listeners.push(listener);
}
/// 移除事件监听器
pub fn remove_listener(&mut self, name: &str) {
self.listeners.retain(|l| l.name() != name);
}
/// 触发事件
pub fn emit_event(&mut self, event: Acc1410Event) {
self.emit_event_with_details(event, None, None);
}
/// 触发事件(带详细信息)
pub fn emit_event_with_details(
&mut self,
event: Acc1410Event,
block_height: Option<u64>,
tx_hash: Option<[u8; 48]>,
) {
self.event_counter += 1;
let record = EventRecord {
event_id: self.event_counter,
event,
timestamp: Self::current_timestamp(),
block_height,
tx_hash,
};
// 通知所有监听器
for listener in &self.listeners {
listener.on_event(&record);
}
// 添加到日志
self.event_log.push(record);
// 如果日志超过最大大小,移除最老的事件
if self.event_log.len() > self.max_log_size {
self.event_log.remove(0);
}
}
/// 查询事件
pub fn query_events(&self, filter: &EventFilter) -> Vec<EventRecord> {
self.event_log
.iter()
.filter(|record| self.matches_filter(record, filter))
.cloned()
.collect()
}
/// 获取最近的事件
pub fn get_recent_events(&self, count: usize) -> Vec<EventRecord> {
let start = if self.event_log.len() > count {
self.event_log.len() - count
} else {
0
};
self.event_log[start..].to_vec()
}
/// 获取账户相关的事件
pub fn get_account_events(&self, account: &str) -> Vec<EventRecord> {
self.event_log
.iter()
.filter(|record| self.event_involves_account(record, account))
.cloned()
.collect()
}
/// 获取分区相关的事件
pub fn get_partition_events(&self, partition_id: &[u8; 32]) -> Vec<EventRecord> {
self.event_log
.iter()
.filter(|record| self.event_involves_partition(record, partition_id))
.cloned()
.collect()
}
/// 清空事件日志
pub fn clear_log(&mut self) {
self.event_log.clear();
}
/// 获取事件统计
pub fn get_event_statistics(&self) -> EventStatistics {
let mut stats = EventStatistics::default();
for record in &self.event_log {
match &record.event {
Acc1410Event::PartitionCreated { .. } => stats.partition_created += 1,
Acc1410Event::PartitionClosed { .. } => stats.partition_closed += 1,
Acc1410Event::Transfer { .. } => stats.transfers += 1,
Acc1410Event::Mint { .. } => stats.mints += 1,
Acc1410Event::Burn { .. } => stats.burns += 1,
Acc1410Event::OperatorAuthorized { .. } => stats.operator_authorized += 1,
Acc1410Event::OperatorRevoked { .. } => stats.operator_revoked += 1,
Acc1410Event::AccountLocked { .. } => stats.account_locked += 1,
Acc1410Event::AccountUnlocked { .. } => stats.account_unlocked += 1,
Acc1410Event::BatchTransfer { .. } => stats.batch_transfers += 1,
Acc1410Event::BatchMint { .. } => stats.batch_mints += 1,
Acc1410Event::BatchBurn { .. } => stats.batch_burns += 1,
}
}
stats.total_events = self.event_log.len();
stats
}
/// 检查事件是否匹配过滤器
fn matches_filter(&self, record: &EventRecord, filter: &EventFilter) -> bool {
// 检查时间范围
if let Some((start, end)) = filter.time_range {
if record.timestamp < start || record.timestamp > end {
return false;
}
}
// 检查账户
if let Some(accounts) = &filter.accounts {
if !accounts.iter().any(|acc| self.event_involves_account(record, acc)) {
return false;
}
}
// 检查分区
if let Some(partitions) = &filter.partitions {
if !partitions.iter().any(|p| self.event_involves_partition(record, p)) {
return false;
}
}
true
}
/// 检查事件是否涉及账户
fn event_involves_account(&self, record: &EventRecord, account: &str) -> bool {
match &record.event {
Acc1410Event::Transfer { from, to, .. } => from == account || to == account,
Acc1410Event::Mint { to, .. } => to == account,
Acc1410Event::Burn { from, .. } => from == account,
Acc1410Event::OperatorAuthorized { account: acc, .. } => acc == account,
Acc1410Event::OperatorRevoked { account: acc, .. } => acc == account,
Acc1410Event::AccountLocked { account: acc, .. } => acc == account,
Acc1410Event::AccountUnlocked { account: acc } => acc == account,
Acc1410Event::BatchTransfer { from, .. } => from == account,
_ => false,
}
}
/// 检查事件是否涉及分区
fn event_involves_partition(&self, record: &EventRecord, partition_id: &[u8; 32]) -> bool {
match &record.event {
Acc1410Event::PartitionCreated { partition_id: p, .. } => p == partition_id,
Acc1410Event::PartitionClosed { partition_id: p } => p == partition_id,
Acc1410Event::Transfer { partition_id: p, .. } => p == partition_id,
Acc1410Event::Mint { partition_id: p, .. } => p == partition_id,
Acc1410Event::Burn { partition_id: p, .. } => p == partition_id,
Acc1410Event::OperatorAuthorized { partition_id: p, .. } => {
p.as_ref() == Some(partition_id)
}
Acc1410Event::OperatorRevoked { partition_id: p, .. } => {
p.as_ref() == Some(partition_id)
}
Acc1410Event::BatchTransfer { partition_id: p, .. } => p == partition_id,
Acc1410Event::BatchMint { partition_id: p, .. } => p == partition_id,
Acc1410Event::BatchBurn { partition_id: p, .. } => p == partition_id,
_ => false,
}
}
/// 获取当前时间戳
fn current_timestamp() -> u64 {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
}
/// 事件统计
#[derive(Debug, Default, Clone)]
/// EventStatistics 协议事件
pub struct EventStatistics {
/// 总事件数
pub total_events: usize,
/// 分区创建事件数
pub partition_created: usize,
/// 分区关闭事件数
pub partition_closed: usize,
/// 转账事件数
pub transfers: usize,
/// 铸造事件数
pub mints: usize,
/// 销毁事件数
pub burns: usize,
/// 操作员授权事件数
pub operator_authorized: usize,
/// 操作员撤销事件数
pub operator_revoked: usize,
/// 账户锁定事件数
pub account_locked: usize,
/// 账户解锁事件数
pub account_unlocked: usize,
/// 批量转账事件数
pub batch_transfers: usize,
/// 批量铸造事件数
pub batch_mints: usize,
/// 批量销毁事件数
pub batch_burns: usize,
}
impl Default for EventManager {
fn default() -> Self {
Self::new()
}
}
/// 控制台事件监听器(用于测试)
#[derive(Debug)]
/// ConsoleEventListener 协议事件
pub struct ConsoleEventListener {
name: String,
}
impl ConsoleEventListener {
/// new 方法
pub fn new(name: String) -> Self {
Self { name }
}
}
impl EventListener for ConsoleEventListener {
fn on_event(&self, event: &EventRecord) {
println!("[{}] Event #{}: {:?}", self.name, event.event_id, event.event);
}
fn name(&self) -> &str {
&self.name
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_emit_event() {
let mut manager = EventManager::new();
manager.emit_event(Acc1410Event::PartitionCreated {
partition_id: [1u8; 32],
name: "Test Partition".to_string(),
partition_type: 1,
});
assert_eq!(manager.event_log.len(), 1);
assert_eq!(manager.event_counter, 1);
}
#[test]
fn test_event_listener() {
let mut manager = EventManager::new();
let listener = Arc::new(ConsoleEventListener::new("test".to_string()));
manager.add_listener(listener);
manager.emit_event(Acc1410Event::Transfer {
from: "user1".to_string(),
to: "user2".to_string(),
amount: 100,
partition_id: [1u8; 32],
});
assert_eq!(manager.event_log.len(), 1);
}
#[test]
fn test_query_events() {
let mut manager = EventManager::new();
// 添加多个事件
manager.emit_event(Acc1410Event::Transfer {
from: "user1".to_string(),
to: "user2".to_string(),
amount: 100,
partition_id: [1u8; 32],
});
manager.emit_event(Acc1410Event::Mint {
to: "user3".to_string(),
amount: 200,
partition_id: [2u8; 32],
});
// 查询所有事件
let filter = EventFilter {
event_types: None,
accounts: None,
partitions: None,
time_range: None,
};
let events = manager.query_events(&filter);
assert_eq!(events.len(), 2);
}
#[test]
fn test_get_account_events() {
let mut manager = EventManager::new();
manager.emit_event(Acc1410Event::Transfer {
from: "user1".to_string(),
to: "user2".to_string(),
amount: 100,
partition_id: [1u8; 32],
});
manager.emit_event(Acc1410Event::Mint {
to: "user1".to_string(),
amount: 200,
partition_id: [2u8; 32],
});
manager.emit_event(Acc1410Event::Transfer {
from: "user3".to_string(),
to: "user4".to_string(),
amount: 300,
partition_id: [1u8; 32],
});
let events = manager.get_account_events("user1");
assert_eq!(events.len(), 2);
}
#[test]
fn test_get_partition_events() {
let mut manager = EventManager::new();
let partition1 = [1u8; 32];
let partition2 = [2u8; 32];
manager.emit_event(Acc1410Event::Transfer {
from: "user1".to_string(),
to: "user2".to_string(),
amount: 100,
partition_id: partition1,
});
manager.emit_event(Acc1410Event::Mint {
to: "user3".to_string(),
amount: 200,
partition_id: partition2,
});
manager.emit_event(Acc1410Event::Transfer {
from: "user4".to_string(),
to: "user5".to_string(),
amount: 300,
partition_id: partition1,
});
let events = manager.get_partition_events(&partition1);
assert_eq!(events.len(), 2);
}
#[test]
fn test_get_recent_events() {
let mut manager = EventManager::new();
// 添加10个事件
for i in 0..10 {
manager.emit_event(Acc1410Event::Transfer {
from: format!("user{}", i),
to: format!("user{}", i + 1),
amount: 100,
partition_id: [1u8; 32],
});
}
let recent = manager.get_recent_events(5);
assert_eq!(recent.len(), 5);
assert_eq!(recent[0].event_id, 6);
assert_eq!(recent[4].event_id, 10);
}
#[test]
fn test_max_log_size() {
let mut manager = EventManager::new();
manager.set_max_log_size(5);
// 添加10个事件
for i in 0..10 {
manager.emit_event(Acc1410Event::Transfer {
from: format!("user{}", i),
to: format!("user{}", i + 1),
amount: 100,
partition_id: [1u8; 32],
});
}
// 日志应该只保留最后5个事件
assert_eq!(manager.event_log.len(), 5);
assert_eq!(manager.event_log[0].event_id, 6);
assert_eq!(manager.event_log[4].event_id, 10);
}
#[test]
fn test_event_statistics() {
let mut manager = EventManager::new();
manager.emit_event(Acc1410Event::Transfer {
from: "user1".to_string(),
to: "user2".to_string(),
amount: 100,
partition_id: [1u8; 32],
});
manager.emit_event(Acc1410Event::Mint {
to: "user3".to_string(),
amount: 200,
partition_id: [2u8; 32],
});
manager.emit_event(Acc1410Event::Burn {
from: "user4".to_string(),
amount: 50,
partition_id: [1u8; 32],
});
let stats = manager.get_event_statistics();
assert_eq!(stats.total_events, 3);
assert_eq!(stats.transfers, 1);
assert_eq!(stats.mints, 1);
assert_eq!(stats.burns, 1);
}
#[test]
fn test_remove_listener() {
let mut manager = EventManager::new();
let listener = Arc::new(ConsoleEventListener::new("test".to_string()));
manager.add_listener(listener);
assert_eq!(manager.listeners.len(), 1);
manager.remove_listener("test");
assert_eq!(manager.listeners.len(), 0);
}
}