//! 升级治理模块(CBPP 宪法授权审批机制) //! //! 在 NAC 公链中,协议升级不通过节点投票决定,而是通过宪法授权审批。 //! 升级提案必须通过 CEE(宪法执行引擎)的合规验证,并由具有有效 DID+KYC 的 //! CBP(宪政区块生产者)进行宪法收据(CR)签署确认。 //! //! 与以太坊治理的根本区别: //! - 以太坊:节点投票(Yes/No/Abstain),多数决 //! - CBPP:宪法规则验证,CR 权重累计,合规优先 use serde::{Deserialize, Serialize}; /// 宪法授权类型(替代以太坊风格的 Yes/No/Abstain 投票) #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ConstitutionalApproval { /// 宪法授权通过(CBP 签署 CR,确认升级符合宪法规则) Authorized, /// 宪法拒绝(升级违反宪法规则,CEE 验证不通过) Rejected(String), /// 待审核(等待 CEE 完成合规验证) PendingReview, } /// 宪法审批记录(替代以太坊风格的 VoteRecord) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApprovalRecord { /// 审批 CBP 的 DID 地址(32 字节 NAC 地址,非以太坊 20 字节地址) pub cbp_did: String, /// 审批类型 pub approval: ConstitutionalApproval, /// CR 权重(宪法收据权重,非以太坊的 voting_power/stake) pub receipt_weight: u64, /// 审批时间(UTC) pub approved_at: chrono::DateTime, /// 宪法收据哈希(SHA3-384,48 字节,非以太坊 Keccak-256) pub receipt_hash: String, } impl ApprovalRecord { /// 创建新的宪法审批记录 pub fn new(cbp_did: String, approval: ConstitutionalApproval, receipt_weight: u64) -> Self { Self { cbp_did, approval, receipt_weight, approved_at: chrono::Utc::now(), receipt_hash: String::new(), } } /// 创建带 CR 哈希的审批记录 pub fn with_receipt( cbp_did: String, approval: ConstitutionalApproval, receipt_weight: u64, receipt_hash: String, ) -> Self { Self { cbp_did, approval, receipt_weight, approved_at: chrono::Utc::now(), receipt_hash, } } } /// 宪法审批结果(替代以太坊风格的 VoteResult) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ApprovalResult { /// 已授权的 CR 权重总量 pub authorized_weight: u64, /// 已拒绝的 CR 权重总量 pub rejected_weight: u64, /// 待审核的 CR 权重总量 pub pending_weight: u64, /// 总 CR 权重 pub total_weight: u64, /// 审批记录列表 pub records: Vec, } impl ApprovalResult { /// 创建新的审批结果 pub fn new() -> Self { Self { authorized_weight: 0, rejected_weight: 0, pending_weight: 0, total_weight: 0, records: Vec::new(), } } /// 添加审批记录 pub fn add_approval(&mut self, record: ApprovalRecord) { match &record.approval { ConstitutionalApproval::Authorized => { self.authorized_weight += record.receipt_weight; } ConstitutionalApproval::Rejected(_) => { self.rejected_weight += record.receipt_weight; } ConstitutionalApproval::PendingReview => { self.pending_weight += record.receipt_weight; } } self.total_weight += record.receipt_weight; self.records.push(record); } /// 判断升级是否通过宪法授权(基于 CR 权重比例,非投票数量) pub fn is_constitutionally_approved(&self, threshold_percent: u64) -> bool { if self.total_weight == 0 { return false; } let authorized_percent = self.authorized_weight * 100 / self.total_weight; authorized_percent >= threshold_percent } /// 判断升级是否被宪法拒绝 pub fn is_constitutionally_rejected(&self, threshold_percent: u64) -> bool { if self.total_weight == 0 { return false; } let rejected_percent = self.rejected_weight * 100 / self.total_weight; rejected_percent >= threshold_percent } /// 获取授权百分比 pub fn authorized_percentage(&self) -> f64 { if self.total_weight == 0 { return 0.0; } (self.authorized_weight as f64 / self.total_weight as f64) * 100.0 } /// 获取拒绝百分比 pub fn rejected_percentage(&self) -> f64 { if self.total_weight == 0 { return 0.0; } (self.rejected_weight as f64 / self.total_weight as f64) * 100.0 } /// 获取待审核百分比 pub fn pending_percentage(&self) -> f64 { if self.total_weight == 0 { return 0.0; } (self.pending_weight as f64 / self.total_weight as f64) * 100.0 } } impl Default for ApprovalResult { fn default() -> Self { Self::new() } } /// 宪法治理配置(替代以太坊风格的 GovernanceConfig) #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ConstitutionalGovernanceConfig { /// 授权通过阈值(CR 权重百分比,默认 66%) pub approval_threshold: u64, /// 最小参与 CBP 数量(开放生产网络 OPN 要求) pub min_cbp_count: usize, /// 最小总 CR 权重 pub min_total_weight: u64, /// 审批超时(秒) pub review_timeout_secs: u64, } impl ConstitutionalGovernanceConfig { /// 标准配置(66% CR 权重阈值) pub fn default_config() -> Self { Self { approval_threshold: 66, min_cbp_count: 3, min_total_weight: 1000, review_timeout_secs: 86400, // 24 小时 } } /// 严格配置(80% CR 权重阈值,用于重大协议升级) pub fn strict_config() -> Self { Self { approval_threshold: 80, min_cbp_count: 5, min_total_weight: 5000, review_timeout_secs: 604800, // 7 天 } } /// 宽松配置(50% CR 权重阈值,用于紧急修复) pub fn relaxed_config() -> Self { Self { approval_threshold: 50, min_cbp_count: 1, min_total_weight: 100, review_timeout_secs: 3600, // 1 小时 } } /// 验证审批结果是否满足宪法治理要求 pub fn validate_result(&self, result: &ApprovalResult) -> bool { // 检查最小 CBP 参与数量 let cbp_count = result.records.iter() .filter(|r| matches!(r.approval, ConstitutionalApproval::Authorized)) .count(); if cbp_count < self.min_cbp_count { return false; } // 检查最小总 CR 权重 if result.total_weight < self.min_total_weight { return false; } // 检查授权阈值 result.is_constitutionally_approved(self.approval_threshold) } } // ============================================================ // 向后兼容别名(保留旧 API 以避免破坏现有调用代码) // 注意:这些别名仅用于过渡期,新代码应使用 Constitutional* 类型 // ============================================================ /// @deprecated 使用 ConstitutionalApproval 替代 pub type Vote = ConstitutionalApproval; /// @deprecated 使用 ApprovalRecord 替代 pub type VoteRecord = ApprovalRecord; /// @deprecated 使用 ApprovalResult 替代 pub type VoteResult = ApprovalResult; /// @deprecated 使用 ConstitutionalGovernanceConfig 替代 pub type GovernanceConfig = ConstitutionalGovernanceConfig; #[cfg(test)] mod tests { use super::*; #[test] fn test_approval_record_creation() { let record = ApprovalRecord::new( "did:nac:cbp1".to_string(), ConstitutionalApproval::Authorized, 1000, ); assert_eq!(record.cbp_did, "did:nac:cbp1"); assert_eq!(record.approval, ConstitutionalApproval::Authorized); assert_eq!(record.receipt_weight, 1000); } #[test] fn test_approval_result_add_approval() { let mut result = ApprovalResult::new(); result.add_approval(ApprovalRecord::new( "did:nac:cbp1".to_string(), ConstitutionalApproval::Authorized, 1000, )); result.add_approval(ApprovalRecord::new( "did:nac:cbp2".to_string(), ConstitutionalApproval::Authorized, 1000, )); result.add_approval(ApprovalRecord::new( "did:nac:cbp3".to_string(), ConstitutionalApproval::Rejected("违反宪法第3条".to_string()), 500, )); assert_eq!(result.authorized_weight, 2000); assert_eq!(result.rejected_weight, 500); assert_eq!(result.total_weight, 2500); } #[test] fn test_constitutional_approval_threshold() { let mut result = ApprovalResult::new(); result.add_approval(ApprovalRecord::new( "did:nac:cbp1".to_string(), ConstitutionalApproval::Authorized, 700, )); result.add_approval(ApprovalRecord::new( "did:nac:cbp2".to_string(), ConstitutionalApproval::Rejected("".to_string()), 300, )); // 70% 授权权重 >= 66% 阈值 assert!(result.is_constitutionally_approved(66)); // 70% 授权权重 < 80% 阈值 assert!(!result.is_constitutionally_approved(80)); } #[test] fn test_governance_config_default() { let config = ConstitutionalGovernanceConfig::default_config(); assert_eq!(config.approval_threshold, 66); assert_eq!(config.min_cbp_count, 3); } #[test] fn test_governance_config_strict() { let config = ConstitutionalGovernanceConfig::strict_config(); assert_eq!(config.approval_threshold, 80); assert_eq!(config.min_cbp_count, 5); } #[test] fn test_governance_config_relaxed() { let config = ConstitutionalGovernanceConfig::relaxed_config(); assert_eq!(config.approval_threshold, 50); assert_eq!(config.min_cbp_count, 1); } #[test] fn test_governance_config_validate_result() { let config = ConstitutionalGovernanceConfig::default_config(); let mut result = ApprovalResult::new(); // 不满足最小 CBP 数量(需要 3 个) result.add_approval(ApprovalRecord::new( "did:nac:cbp1".to_string(), ConstitutionalApproval::Authorized, 500, )); assert!(!config.validate_result(&result)); // 满足 CBP 数量但不满足最小权重 result.add_approval(ApprovalRecord::new( "did:nac:cbp2".to_string(), ConstitutionalApproval::Authorized, 300, )); result.add_approval(ApprovalRecord::new( "did:nac:cbp3".to_string(), ConstitutionalApproval::Authorized, 100, )); // total_weight = 900 < min_total_weight = 1000 assert!(!config.validate_result(&result)); // 满足所有条件 result.add_approval(ApprovalRecord::new( "did:nac:cbp4".to_string(), ConstitutionalApproval::Authorized, 200, )); // total_weight = 1100 >= 1000, authorized = 1100/1100 = 100% >= 66% assert!(config.validate_result(&result)); } }