//! acc_governance - NAC 原生协议实现 use crate::primitives::{Address, Hash, Timestamp}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] /// ACCGovernanceError 错误类型 pub enum ACCGovernanceError { /// ProposalNotFound 变体 ProposalNotFound(Hash), /// ProposalAlreadyExecuted 变体 ProposalAlreadyExecuted(Hash), /// VotingPeriodEnded 变体 VotingPeriodEnded(Hash), /// AlreadyVoted 变体 AlreadyVoted(Address), /// InsufficientVotingPower 变体 InsufficientVotingPower { /// 所需数量 required: u128, /// actual 字段 actual: u128, }, /// QuorumNotReached 变体 QuorumNotReached { /// 所需数量 required: u128, /// actual 字段 actual: u128, }, /// 宪法收据无效错误 InvalidConstitutionalReceipt, /// 未授权操作错误 Unauthorized(Address), } impl std::fmt::Display for ACCGovernanceError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::ProposalNotFound(h) => write!(f, "提案不存在: {}", h.to_hex()), Self::ProposalAlreadyExecuted(h) => write!(f, "提案已执行: {}", h.to_hex()), Self::VotingPeriodEnded(h) => write!(f, "投票期已结束: {}", h.to_hex()), Self::AlreadyVoted(a) => write!(f, "已投票: {}", a.to_hex()), Self::InsufficientVotingPower { required, actual } => write!(f, "投票权不足: 需要 {},实际 {}", required, actual), Self::QuorumNotReached { required, actual } => write!(f, "未达法定人数: 需要 {},实际 {}", required, actual), Self::InvalidConstitutionalReceipt => write!(f, "宪法收据无效"), Self::Unauthorized(a) => write!(f, "未授权: {}", a.to_hex()), } } } #[derive(Debug, Clone, Serialize, Deserialize)] /// ProposalType 类型 pub enum ProposalType { /// ParameterChange 变体 ParameterChange { /// parameter 字段 parameter: String, /// new_value 字段 new_value: Vec, }, /// ProtocolUpgrade 变体 ProtocolUpgrade { /// new_version 字段 new_version: String, /// upgrade_hash 哈希值(48字节 SHA3-384) upgrade_hash: Hash, }, /// AssetPolicyChange 变体 AssetPolicyChange { /// 资产标识符 asset_id: Hash, /// policy_hash 哈希值(48字节 SHA3-384) policy_hash: Hash, }, /// EmergencyPause 变体 EmergencyPause { /// 操作原因说明 reason: String, }, /// GovernanceMemberChange 变体 GovernanceMemberChange { /// member 字段 member: Address, /// action 字段 action: MemberAction, }, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] /// MemberAction 枚举类型 pub enum MemberAction { /// Add 变体 Add, /// Remove 变体 Remove, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] /// ProposalStatus 状态枚举 pub enum ProposalStatus { /// 活跃状态 Active, /// 已通过状态 Passed, /// 已拒绝状态 Rejected, /// 已执行状态 Executed, /// 已取消状态 Cancelled, /// 已过期状态 Expired, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] /// VoteChoice 枚举类型 pub enum VoteChoice { /// For 变体 For, /// Against 变体 Against, /// Abstain 变体 Abstain, } #[derive(Debug, Clone, Serialize, Deserialize)] /// GovernanceProposal 结构体 pub struct GovernanceProposal { /// 治理提案标识符 pub proposal_id: Hash, /// proposer 字段 pub proposer: Address, /// proposal_type 字段 pub proposal_type: ProposalType, /// 详细描述 pub description: String, /// 状态 pub status: ProposalStatus, /// votes_for 字段 pub votes_for: u128, /// votes_against 字段 pub votes_against: u128, /// votes_abstain 字段 pub votes_abstain: u128, /// vote_records 字段 pub vote_records: HashMap, /// voting_start 字段 pub voting_start: Timestamp, /// voting_end 字段 pub voting_end: Timestamp, /// quorum_bps 字段 pub quorum_bps: u32, /// pass_threshold_bps 字段 pub pass_threshold_bps: u32, /// 宪法收据哈希(CBPP 共识凭证) pub constitutional_receipt: Hash, /// 创建时间戳 pub created_at: Timestamp, /// 执行时间戳 pub executed_at: Option, } #[derive(Debug, Clone, Serialize, Deserialize)] /// GovernanceProtocolEvent 协议事件 pub enum GovernanceProtocolEvent { /// ProposalCreated 变体 ProposalCreated { /// 治理提案标识符 proposal_id: Hash, /// proposer 字段 proposer: Address, /// 操作时间戳(UTC Unix 毫秒) timestamp: Timestamp, }, /// VoteCast 变体 VoteCast { /// 治理提案标识符 proposal_id: Hash, /// 投票者账户地址 voter: Address, /// choice 字段 choice: VoteChoice, /// voting_power 字段 voting_power: u128, /// 操作时间戳(UTC Unix 毫秒) timestamp: Timestamp, }, /// ProposalPassed 变体 ProposalPassed { /// 治理提案标识符 proposal_id: Hash, /// votes_for 字段 votes_for: u128, /// votes_against 字段 votes_against: u128, /// 操作时间戳(UTC Unix 毫秒) timestamp: Timestamp, }, /// ProposalRejected 变体 ProposalRejected { /// 治理提案标识符 proposal_id: Hash, /// 操作原因说明 reason: String, /// 操作时间戳(UTC Unix 毫秒) timestamp: Timestamp, }, /// ProposalExecuted 变体 ProposalExecuted { /// 治理提案标识符 proposal_id: Hash, /// 操作时间戳(UTC Unix 毫秒) timestamp: Timestamp, /// 宪法收据哈希(CBPP 共识凭证) constitutional_receipt: Hash, }, } #[derive(Debug, Clone, Serialize, Deserialize)] /// ACCGovernanceProtocol 协议实现 pub struct ACCGovernanceProtocol { /// 协议唯一标识符 pub protocol_uid: String, /// NAC-Lens 协议向量 pub lens_protocol_vector: String, /// proposals 字段 pub proposals: HashMap, /// voting_power_registry 字段 pub voting_power_registry: HashMap, /// total_voting_power 字段 pub total_voting_power: u128, /// default_quorum_bps 字段 pub default_quorum_bps: u32, /// default_pass_threshold_bps 字段 pub default_pass_threshold_bps: u32, /// 待广播的 CSNP 协议事件队列 pub pending_events: Vec, /// 创建时间戳 pub created_at: Timestamp, /// 最后更新时间戳 pub updated_at: Timestamp, } impl ACCGovernanceProtocol { /// new 方法 pub fn new(default_quorum_bps: u32, default_pass_threshold_bps: u32) -> Self { Self { protocol_uid: "nac.acc.ACCGovernanceProtocol.v1".to_string(), lens_protocol_vector: "ACC-Governance".to_string(), proposals: HashMap::new(), voting_power_registry: HashMap::new(), total_voting_power: 0, default_quorum_bps, default_pass_threshold_bps, pending_events: Vec::new(), created_at: Timestamp::now(), updated_at: Timestamp::now(), } } /// register_voting_power 方法 pub fn register_voting_power(&mut self, address: Address, power: u128) { let old = self.voting_power_registry.insert(address, power).unwrap_or(0); self.total_voting_power = self.total_voting_power.saturating_sub(old).saturating_add(power); } /// 创建治理提案 pub fn create_proposal( &mut self, proposer: Address, proposal_type: ProposalType, description: String, voting_duration_secs: u64, constitutional_receipt: Hash, timestamp: Timestamp, ) -> Result { if constitutional_receipt.is_zero() { return Err(ACCGovernanceError::InvalidConstitutionalReceipt); } let proposer_power = self.voting_power_registry.get(&proposer).copied().unwrap_or(0); if proposer_power == 0 { return Err(ACCGovernanceError::InsufficientVotingPower { required: 1, actual: 0 }); } let mut data = Vec::new(); data.extend_from_slice(proposer.as_bytes()); data.extend_from_slice(×tamp.as_secs().to_be_bytes()); let proposal_id = Hash::sha3_384(&data); let proposal = GovernanceProposal { proposal_id, proposer: proposer.clone(), proposal_type, description, status: ProposalStatus::Active, votes_for: 0, votes_against: 0, votes_abstain: 0, vote_records: HashMap::new(), voting_start: timestamp.clone(), voting_end: timestamp.add_secs(voting_duration_secs), quorum_bps: self.default_quorum_bps, pass_threshold_bps: self.default_pass_threshold_bps, constitutional_receipt, created_at: timestamp.clone(), executed_at: None, }; self.proposals.insert(proposal_id, proposal); self.pending_events.push(GovernanceProtocolEvent::ProposalCreated { proposal_id, proposer, timestamp }); self.updated_at = Timestamp::now(); Ok(proposal_id) } /// 投票 pub fn cast_vote( &mut self, proposal_id: Hash, voter: Address, choice: VoteChoice, timestamp: Timestamp, ) -> Result<(), ACCGovernanceError> { let voting_power = self.voting_power_registry.get(&voter).copied().unwrap_or(0); if voting_power == 0 { return Err(ACCGovernanceError::InsufficientVotingPower { required: 1, actual: 0 }); } let proposal = self.proposals.get_mut(&proposal_id) .ok_or(ACCGovernanceError::ProposalNotFound(proposal_id))?; if proposal.status != ProposalStatus::Active { return Err(ACCGovernanceError::VotingPeriodEnded(proposal_id)); } if proposal.vote_records.contains_key(&voter) { return Err(ACCGovernanceError::AlreadyVoted(voter)); } match choice { VoteChoice::For => proposal.votes_for = proposal.votes_for.saturating_add(voting_power), VoteChoice::Against => proposal.votes_against = proposal.votes_against.saturating_add(voting_power), VoteChoice::Abstain => proposal.votes_abstain = proposal.votes_abstain.saturating_add(voting_power), } proposal.vote_records.insert(voter.clone(), choice); self.pending_events.push(GovernanceProtocolEvent::VoteCast { proposal_id, voter, choice, voting_power, timestamp }); Ok(()) } /// finalize_proposal 方法 pub fn finalize_proposal( &mut self, proposal_id: Hash, constitutional_receipt: Hash, timestamp: Timestamp, ) -> Result { if constitutional_receipt.is_zero() { return Err(ACCGovernanceError::InvalidConstitutionalReceipt); } let proposal = self.proposals.get_mut(&proposal_id) .ok_or(ACCGovernanceError::ProposalNotFound(proposal_id))?; let total_votes = proposal.votes_for + proposal.votes_against + proposal.votes_abstain; let quorum_required = (self.total_voting_power as u64 * proposal.quorum_bps as u64 / 10000) as u128; if total_votes < quorum_required { proposal.status = ProposalStatus::Rejected; self.pending_events.push(GovernanceProtocolEvent::ProposalRejected { proposal_id, reason: format!("未达法定人数: {} < {}", total_votes, quorum_required), timestamp, }); return Ok(false); } let effective_votes = proposal.votes_for + proposal.votes_against; let pass_required = (effective_votes as u64 * proposal.pass_threshold_bps as u64 / 10000) as u128; let passed = proposal.votes_for >= pass_required; if passed { proposal.status = ProposalStatus::Executed; proposal.executed_at = Some(timestamp.clone()); self.pending_events.push(GovernanceProtocolEvent::ProposalExecuted { proposal_id, timestamp, constitutional_receipt }); } else { proposal.status = ProposalStatus::Rejected; self.pending_events.push(GovernanceProtocolEvent::ProposalRejected { proposal_id, reason: "赞成票未达阈值".to_string(), timestamp, }); } Ok(passed) } /// 获取提案详情 pub fn get_proposal(&self, id: &Hash) -> Option<&GovernanceProposal> { self.proposals.get(id) } /// 排空待广播事件队列 pub fn drain_pending_events(&mut self) -> Vec { std::mem::take(&mut self.pending_events) } }