//! 宪法历史追踪模块 use crate::{ConstitutionVersion, Result, Error}; use nac_udm::primitives::Address; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; use std::fs; /// 历史记录类型 #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum HistoryRecordType { /// 版本创建 VersionCreated, /// 升级提议 UpgradeProposed, /// 升级执行 UpgradeExecuted, /// 升级取消 UpgradeCancelled, /// 版本回滚 VersionRolledBack, } /// 历史记录 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct HistoryRecord { /// 记录类型 pub record_type: HistoryRecordType, /// 版本号 pub version: u64, /// 操作者地址 pub operator: Address, /// 时间戳 pub timestamp: u64, /// 区块高度 pub block_height: u64, /// 描述 pub description: String, } /// 审计日志 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AuditLog { /// 日志ID pub id: u64, /// 历史记录 pub record: HistoryRecord, /// 额外数据 pub extra_data: String, } /// 历史查询过滤器 #[derive(Debug, Clone)] pub struct HistoryFilter { /// 记录类型过滤 pub record_type: Option, /// 版本号过滤 pub version: Option, /// 操作者过滤 pub operator: Option
, /// 时间范围过滤(开始) pub time_from: Option, /// 时间范围过滤(结束) pub time_to: Option, /// 区块高度范围过滤(开始) pub block_from: Option, /// 区块高度范围过滤(结束) pub block_to: Option, } impl Default for HistoryFilter { fn default() -> Self { Self { record_type: None, version: None, operator: None, time_from: None, time_to: None, block_from: None, block_to: None, } } } /// 历史追踪器 pub struct HistoryTracker { /// 历史记录列表 records: Vec, /// 审计日志列表 audit_logs: Vec, /// 存储路径 storage_path: PathBuf, /// 下一个日志ID next_log_id: u64, } impl HistoryTracker { /// 创建新的历史追踪器 pub fn new() -> Self { let temp_path = std::env::temp_dir().join("nac_history_test.json"); Self { records: Vec::new(), audit_logs: Vec::new(), storage_path: temp_path, next_log_id: 1, } } /// 从存储加载历史追踪器 pub fn load(storage_path: &Path) -> Result { let history_path = storage_path.join("history.json"); if !history_path.exists() { return Ok(Self { records: Vec::new(), audit_logs: Vec::new(), storage_path: history_path, next_log_id: 1, }); } let json = fs::read_to_string(&history_path) .map_err(|e| Error::StorageError(format!("读取历史文件失败: {}", e)))?; let (records, audit_logs, next_log_id) = serde_json::from_str(&json) .map_err(|e| Error::StorageError(format!("反序列化历史失败: {}", e)))?; Ok(Self { records, audit_logs, storage_path: history_path, next_log_id, }) } /// 保存历史记录 fn save(&self) -> Result<()> { if let Some(parent) = self.storage_path.parent() { fs::create_dir_all(parent) .map_err(|e| Error::StorageError(format!("创建目录失败: {}", e)))?; } let data = (&self.records, &self.audit_logs, self.next_log_id); let json = serde_json::to_string_pretty(&data) .map_err(|e| Error::StorageError(format!("序列化历史失败: {}", e)))?; fs::write(&self.storage_path, json) .map_err(|e| Error::StorageError(format!("写入历史文件失败: {}", e)))?; Ok(()) } /// 记录版本创建 pub fn record_version(&mut self, version: &ConstitutionVersion) -> Result<()> { let record = HistoryRecord { record_type: HistoryRecordType::VersionCreated, version: version.version, operator: version.created_by, timestamp: version.created_at, block_height: version.effective_from, description: format!("创建版本: {}", version.description), }; self.add_record(record, String::new())?; Ok(()) } /// 记录升级提议 pub fn record_proposal(&mut self, version: &ConstitutionVersion, proposer: &Address) -> Result<()> { let record = HistoryRecord { record_type: HistoryRecordType::UpgradeProposed, version: version.version, operator: *proposer, timestamp: version.created_at, block_height: version.effective_from, description: format!("提议升级到版本{}: {}", version.version, version.description), }; self.add_record(record, String::new())?; Ok(()) } /// 记录升级执行 pub fn record_upgrade(&mut self, version: &ConstitutionVersion, block_height: u64) -> Result<()> { let record = HistoryRecord { record_type: HistoryRecordType::UpgradeExecuted, version: version.version, operator: version.created_by, timestamp: version.created_at, block_height, description: format!("执行升级到版本{}", version.version), }; self.add_record(record, String::new())?; Ok(()) } /// 记录升级取消 pub fn record_cancellation(&mut self, version: &ConstitutionVersion, canceller: &Address) -> Result<()> { let record = HistoryRecord { record_type: HistoryRecordType::UpgradeCancelled, version: version.version, operator: *canceller, timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(), block_height: 0, description: format!("取消升级到版本{}", version.version), }; self.add_record(record, String::new())?; Ok(()) } /// 记录版本回滚 pub fn record_rollback(&mut self, version: &ConstitutionVersion, operator: &Address) -> Result<()> { let record = HistoryRecord { record_type: HistoryRecordType::VersionRolledBack, version: version.version, operator: *operator, timestamp: std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) .unwrap() .as_secs(), block_height: 0, description: format!("回滚到版本{}", version.version), }; self.add_record(record, String::new())?; Ok(()) } /// 添加记录 fn add_record(&mut self, record: HistoryRecord, extra_data: String) -> Result<()> { let audit_log = AuditLog { id: self.next_log_id, record: record.clone(), extra_data, }; self.records.push(record); self.audit_logs.push(audit_log); self.next_log_id += 1; self.save()?; Ok(()) } /// 查询历史记录 pub fn query(&self, filter: HistoryFilter) -> Result> { let mut results = Vec::new(); for record in &self.records { // 应用过滤器 if let Some(ref record_type) = filter.record_type { if &record.record_type != record_type { continue; } } if let Some(version) = filter.version { if record.version != version { continue; } } if let Some(operator) = filter.operator { if record.operator != operator { continue; } } if let Some(time_from) = filter.time_from { if record.timestamp < time_from { continue; } } if let Some(time_to) = filter.time_to { if record.timestamp > time_to { continue; } } if let Some(block_from) = filter.block_from { if record.block_height < block_from { continue; } } if let Some(block_to) = filter.block_to { if record.block_height > block_to { continue; } } results.push(record.clone()); } Ok(results) } /// 获取审计日志 pub fn get_audit_log(&self, from: u64, to: u64) -> Result> { let logs = self.audit_logs .iter() .filter(|log| log.id >= from && log.id <= to) .cloned() .collect(); Ok(logs) } /// 获取所有记录 pub fn get_all_records(&self) -> &[HistoryRecord] { &self.records } /// 获取记录数量 pub fn record_count(&self) -> usize { self.records.len() } } impl Default for HistoryTracker { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; use nac_udm::primitives::Hash; fn create_test_version(version: u64) -> ConstitutionVersion { ConstitutionVersion::new( version, Hash::zero(), version * 1000, 10, version * 100, Address::zero(), format!("Version {}", version), ) } #[test] fn test_record_version() { let mut tracker = HistoryTracker::new(); let version = create_test_version(1); assert!(tracker.record_version(&version).is_ok()); assert_eq!(tracker.record_count(), 1); } #[test] fn test_query_by_type() { let mut tracker = HistoryTracker::new(); let version = create_test_version(1); tracker.record_version(&version).unwrap(); tracker.record_proposal(&version, &Address::zero()).unwrap(); let filter = HistoryFilter { record_type: Some(HistoryRecordType::VersionCreated), ..Default::default() }; let results = tracker.query(filter).unwrap(); assert_eq!(results.len(), 1); assert_eq!(results[0].record_type, HistoryRecordType::VersionCreated); } #[test] fn test_query_by_version() { let mut tracker = HistoryTracker::new(); tracker.record_version(&create_test_version(1)).unwrap(); tracker.record_version(&create_test_version(2)).unwrap(); let filter = HistoryFilter { version: Some(1), ..Default::default() }; let results = tracker.query(filter).unwrap(); assert_eq!(results.len(), 1); assert_eq!(results[0].version, 1); } #[test] fn test_audit_log() { let mut tracker = HistoryTracker::new(); let version = create_test_version(1); tracker.record_version(&version).unwrap(); let logs = tracker.get_audit_log(1, 1).unwrap(); assert_eq!(logs.len(), 1); assert_eq!(logs[0].id, 1); } }