//! 升级框架核心trait定义 use crate::{ error::Result, migration::UpgradeData, proposal::{ProposalId, UpgradeProposal}, snapshot::Snapshot, governance::{Vote, VoteResult}, version::Version, UpgradeRecord, }; /// 可升级trait - 所有NAC模块必须实现此trait pub trait Upgradeable { /// 获取模块名称 fn module_name(&self) -> &str; /// 获取当前版本 fn current_version(&self) -> Version; /// 检查是否可以升级到目标版本 fn can_upgrade_to(&self, target: &Version) -> Result; /// 执行升级 /// /// # 参数 /// - `target`: 目标版本 /// - `data`: 升级数据(包含迁移脚本、配置变更等) /// /// # 返回 /// - `Ok(())`: 升级成功 /// - `Err(UpgradeError)`: 升级失败 fn upgrade(&mut self, target: Version, data: UpgradeData) -> Result<()>; /// 创建状态快照 /// /// 在升级前创建快照,用于回滚 fn create_snapshot(&self) -> Result; /// 从快照回滚 /// /// # 参数 /// - `snapshot`: 要回滚到的快照 /// /// # 返回 /// - `Ok(())`: 回滚成功 /// - `Err(UpgradeError)`: 回滚失败 fn rollback(&mut self, snapshot: Snapshot) -> Result<()>; /// 获取升级历史 fn upgrade_history(&self) -> Vec; /// 验证升级后的状态 /// /// 升级后调用,验证状态是否正确 fn validate_state(&self) -> Result; } /// 升级治理trait - 管理升级提案和投票 pub trait UpgradeGovernance { /// 提交升级提案 /// /// # 参数 /// - `proposal`: 升级提案 /// /// # 返回 /// - `Ok(ProposalId)`: 提案ID /// - `Err(UpgradeError)`: 提交失败 fn propose_upgrade(&mut self, proposal: UpgradeProposal) -> Result; /// 对升级提案投票 /// /// # 参数 /// - `proposal_id`: 提案ID /// - `vote`: 投票(赞成/反对/弃权) /// /// # 返回 /// - `Ok(())`: 投票成功 /// - `Err(UpgradeError)`: 投票失败 fn vote(&mut self, proposal_id: ProposalId, vote: Vote) -> Result<()>; /// 执行已批准的升级 /// /// # 参数 /// - `proposal_id`: 提案ID /// /// # 返回 /// - `Ok(())`: 执行成功 /// - `Err(UpgradeError)`: 执行失败 fn execute_upgrade(&mut self, proposal_id: ProposalId) -> Result<()>; /// 获取提案 fn get_proposal(&self, proposal_id: ProposalId) -> Result; /// 获取投票结果 fn get_vote_result(&self, proposal_id: ProposalId) -> Result; /// 取消提案 /// /// 只有提案者可以在投票期前取消 fn cancel_proposal(&mut self, proposal_id: ProposalId) -> Result<()>; } #[cfg(test)] mod tests { use super::*; use crate::proposal::ProposalStatus; use std::collections::HashMap; // 测试用的简单实现 struct TestModule { name: String, version: Version, history: Vec, } impl Upgradeable for TestModule { fn module_name(&self) -> &str { &self.name } fn current_version(&self) -> Version { self.version.clone() } fn can_upgrade_to(&self, target: &Version) -> Result { Ok(self.version.can_upgrade_to(target)) } fn upgrade(&mut self, target: Version, _data: UpgradeData) -> Result<()> { self.version = target; Ok(()) } fn create_snapshot(&self) -> Result { Ok(Snapshot::new( self.name.clone(), self.version.clone(), vec![], )) } fn rollback(&mut self, snapshot: Snapshot) -> Result<()> { self.version = snapshot.version; Ok(()) } fn upgrade_history(&self) -> Vec { self.history.clone() } fn validate_state(&self) -> Result { Ok(true) } } #[test] fn test_upgradeable_trait() { let mut module = TestModule { name: "test-module".to_string(), version: Version::new(1, 0, 0), history: vec![], }; assert_eq!(module.module_name(), "test-module"); assert_eq!(module.current_version(), Version::new(1, 0, 0)); let target = Version::new(1, 1, 0); assert!(module.can_upgrade_to(&target).expect("mainnet: handle error")); let data = UpgradeData { migration_script: None, config_changes: HashMap::new(), state_migrations: vec![], breaking_changes: vec![], }; assert!(module.upgrade(target.clone(), data).is_ok()); assert_eq!(module.current_version(), target); } #[test] fn test_snapshot_and_rollback() { let mut module = TestModule { name: "test-module".to_string(), version: Version::new(1, 0, 0), history: vec![], }; let snapshot = module.create_snapshot().expect("mainnet: handle error"); assert_eq!(snapshot.version, Version::new(1, 0, 0)); // 升级 module.version = Version::new(1, 1, 0); // 回滚 assert!(module.rollback(snapshot).is_ok()); assert_eq!(module.current_version(), Version::new(1, 0, 0)); } }