NAC_Blockchain/nac-upgrade-framework/src/governance.rs

356 lines
11 KiB
Rust
Raw Permalink 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.

//! 升级治理模块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<chrono::Utc>,
/// 宪法收据哈希SHA3-38448 字节,非以太坊 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<ApprovalRecord>,
}
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));
}
}