//! 安全机制模块 use crate::error::{BridgeError, BridgeResult}; use chrono::Datelike; use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// 安全配置 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SecurityConfig { /// 单笔交易上限 pub max_transaction_amount: u128, /// 每日交易上限 pub daily_limit: u128, /// 是否暂停 pub paused: bool, /// 紧急提款启用 pub emergency_withdrawal_enabled: bool, /// 审计日志启用 pub audit_log_enabled: bool, } impl Default for SecurityConfig { fn default() -> Self { Self { max_transaction_amount: 1_000_000_000_000_000_000, // 1 ETH daily_limit: 10_000_000_000_000_000_000, // 10 ETH paused: false, emergency_withdrawal_enabled: true, audit_log_enabled: true, } } } /// 审计日志条目 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AuditLogEntry { /// 日志ID pub log_id: String, /// 操作类型 pub operation: String, /// 操作者 pub operator: String, /// 时间戳 pub timestamp: u64, /// 详细信息 pub details: HashMap, /// 结果 pub result: OperationResult, } /// 操作结果 #[derive(Debug, Clone, Serialize, Deserialize)] pub enum OperationResult { /// 成功 Success, /// 失败 Failure(String), } /// 每日交易统计 #[derive(Debug, Clone)] struct DailyStats { /// 日期(YYYYMMDD) date: u32, /// 总金额 total_amount: u128, } /// 安全管理器 pub struct SecurityManager { /// 安全配置 config: SecurityConfig, /// 审计日志 audit_logs: Vec, /// 每日统计 daily_stats: HashMap, } impl SecurityManager { /// 创建新的安全管理器 pub fn new(config: SecurityConfig) -> Self { Self { config, audit_logs: Vec::new(), daily_stats: HashMap::new(), } } /// 检查是否暂停 pub fn is_paused(&self) -> bool { self.config.paused } /// 暂停桥接 pub fn pause(&mut self, operator: &str) -> BridgeResult<()> { if self.config.paused { return Err(BridgeError::SecurityError( "Bridge already paused".to_string() )); } self.config.paused = true; self.log_operation(AuditLogEntry { log_id: format!("pause_{}", chrono::Utc::now().timestamp()), operation: "pause".to_string(), operator: operator.to_string(), timestamp: chrono::Utc::now().timestamp() as u64, details: HashMap::new(), result: OperationResult::Success, }); Ok(()) } /// 恢复桥接 pub fn unpause(&mut self, operator: &str) -> BridgeResult<()> { if !self.config.paused { return Err(BridgeError::SecurityError( "Bridge not paused".to_string() )); } self.config.paused = false; self.log_operation(AuditLogEntry { log_id: format!("unpause_{}", chrono::Utc::now().timestamp()), operation: "unpause".to_string(), operator: operator.to_string(), timestamp: chrono::Utc::now().timestamp() as u64, details: HashMap::new(), result: OperationResult::Success, }); Ok(()) } /// 验证交易金额 pub fn validate_amount(&mut self, amount: u128, token: &str) -> BridgeResult<()> { // 检查单笔上限 if amount > self.config.max_transaction_amount { return Err(BridgeError::SecurityError( format!("Amount exceeds max transaction limit: {} > {}", amount, self.config.max_transaction_amount) )); } // 检查每日限额 let today = self.get_today(); let stats = self.daily_stats.entry(token.to_string()) .or_insert(DailyStats { date: today, total_amount: 0, }); // 如果是新的一天,重置统计 if stats.date != today { stats.date = today; stats.total_amount = 0; } if stats.total_amount + amount > self.config.daily_limit { return Err(BridgeError::SecurityError( format!("Amount exceeds daily limit: {} + {} > {}", stats.total_amount, amount, self.config.daily_limit) )); } // 更新统计 stats.total_amount += amount; Ok(()) } /// 紧急提款 pub fn emergency_withdraw( &mut self, operator: &str, amount: u128, destination: &str, ) -> BridgeResult<()> { if !self.config.emergency_withdrawal_enabled { return Err(BridgeError::SecurityError( "Emergency withdrawal not enabled".to_string() )); } let mut details = HashMap::new(); details.insert("amount".to_string(), amount.to_string()); details.insert("destination".to_string(), destination.to_string()); self.log_operation(AuditLogEntry { log_id: format!("emergency_withdraw_{}", chrono::Utc::now().timestamp()), operation: "emergency_withdraw".to_string(), operator: operator.to_string(), timestamp: chrono::Utc::now().timestamp() as u64, details, result: OperationResult::Success, }); Ok(()) } /// 记录审计日志 pub fn log_operation(&mut self, entry: AuditLogEntry) { if self.config.audit_log_enabled { self.audit_logs.push(entry); } } /// 查询审计日志 pub fn query_audit_logs(&self, operation: Option<&str>, operator: Option<&str>) -> Vec<&AuditLogEntry> { self.audit_logs.iter() .filter(|entry| { if let Some(op) = operation { if entry.operation != op { return false; } } if let Some(opr) = operator { if entry.operator != opr { return false; } } true }) .collect() } /// 获取今天的日期(YYYYMMDD) fn get_today(&self) -> u32 { let now = chrono::Utc::now(); (now.year() as u32) * 10000 + (now.month() * 100) + now.day() } /// 获取配置 pub fn config(&self) -> &SecurityConfig { &self.config } /// 更新配置 pub fn update_config(&mut self, config: SecurityConfig) { self.config = config; } } #[cfg(test)] mod tests { use super::*; #[test] fn test_pause_unpause() { let mut manager = SecurityManager::new(SecurityConfig::default()); assert!(!manager.is_paused()); assert!(manager.pause("admin").is_ok()); assert!(manager.is_paused()); assert!(manager.unpause("admin").is_ok()); assert!(!manager.is_paused()); } #[test] fn test_validate_amount() { let mut manager = SecurityManager::new(SecurityConfig::default()); // 测试单笔上限 let result = manager.validate_amount(2_000_000_000_000_000_000, "ETH"); assert!(result.is_err()); // 测试正常金额 let result = manager.validate_amount(500_000_000_000_000_000, "ETH"); assert!(result.is_ok()); } #[test] fn test_audit_log() { let mut manager = SecurityManager::new(SecurityConfig::default()); manager.pause("admin").unwrap(); let logs = manager.query_audit_logs(Some("pause"), None); assert_eq!(logs.len(), 1); assert_eq!(logs[0].operator, "admin"); } }