NAC_Blockchain/nvm_v2/nvm-l1/src/governance/proposal_execution.rs

173 lines
4.7 KiB
Rust

// 治理投票执行系统
// 自动执行通过的提案
use std::collections::HashMap;
/// 提案执行状态
#[derive(Debug, Clone, PartialEq)]
pub enum ExecutionStatus {
Pending, // 待执行
Executing, // 执行中
Completed, // 已完成
Failed, // 执行失败
}
/// 执行结果
#[derive(Debug, Clone)]
pub struct ExecutionResult {
pub success: bool,
pub message: String,
pub timestamp: u64,
}
/// 提案执行记录
#[derive(Debug, Clone)]
pub struct ExecutionRecord {
pub proposal_id: String,
pub status: ExecutionStatus,
pub result: Option<ExecutionResult>,
pub retry_count: u32,
}
/// 提案执行系统
pub struct ProposalExecutionSystem {
executions: HashMap<String, ExecutionRecord>,
stats: ExecutionStats,
}
#[derive(Debug, Clone, Default)]
pub struct ExecutionStats {
pub total_executions: u64,
pub successful_executions: u64,
pub failed_executions: u64,
pub pending_executions: u64,
}
impl ProposalExecutionSystem {
pub fn new() -> Self {
Self {
executions: HashMap::new(),
stats: ExecutionStats::default(),
}
}
/// 提交执行请求
pub fn submit_execution(&mut self, proposal_id: String) {
let record = ExecutionRecord {
proposal_id: proposal_id.clone(),
status: ExecutionStatus::Pending,
result: None,
retry_count: 0,
};
self.executions.insert(proposal_id, record);
self.stats.total_executions += 1;
self.stats.pending_executions += 1;
}
/// 执行提案
pub fn execute_proposal(&mut self, proposal_id: &str) -> Result<ExecutionResult, String> {
let record = self.executions.get_mut(proposal_id)
.ok_or("Proposal not found")?;
if record.status != ExecutionStatus::Pending {
return Err("Proposal is not in pending status".to_string());
}
// 更新状态为执行中
record.status = ExecutionStatus::Executing;
// 模拟执行(实际应调用相应的执行逻辑)
let success = true; // 简化实现
let result = ExecutionResult {
success,
message: if success {
"Proposal executed successfully".to_string()
} else {
"Proposal execution failed".to_string()
},
timestamp: 1000,
};
// 更新执行记录
record.status = if success {
ExecutionStatus::Completed
} else {
ExecutionStatus::Failed
};
record.result = Some(result.clone());
// 更新统计
if success {
self.stats.successful_executions += 1;
} else {
self.stats.failed_executions += 1;
}
self.stats.pending_executions = self.stats.pending_executions.saturating_sub(1);
Ok(result)
}
/// 重试失败的执行
pub fn retry_execution(&mut self, proposal_id: &str) -> Result<(), String> {
let record = self.executions.get_mut(proposal_id)
.ok_or("Proposal not found")?;
if record.status != ExecutionStatus::Failed {
return Err("Only failed executions can be retried".to_string());
}
if record.retry_count >= 3 {
return Err("Maximum retry count reached".to_string());
}
record.status = ExecutionStatus::Pending;
record.retry_count += 1;
self.stats.pending_executions += 1;
Ok(())
}
/// 获取执行记录
pub fn get_execution_record(&self, proposal_id: &str) -> Option<ExecutionRecord> {
self.executions.get(proposal_id).cloned()
}
/// 获取统计信息
pub fn get_stats(&self) -> ExecutionStats {
self.stats.clone()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_proposal_execution() {
let mut system = ProposalExecutionSystem::new();
// 提交执行请求
system.submit_execution("proposal_001".to_string());
// 检查待执行状态
let record = system.get_execution_record("proposal_001").expect("mainnet: handle error");
assert_eq!(record.status, ExecutionStatus::Pending);
// 执行提案
let result = system.execute_proposal("proposal_001").expect("mainnet: handle error");
assert!(result.success);
// 检查完成状态
let record = system.get_execution_record("proposal_001").expect("mainnet: handle error");
assert_eq!(record.status, ExecutionStatus::Completed);
// 检查统计
let stats = system.get_stats();
assert_eq!(stats.total_executions, 1);
assert_eq!(stats.successful_executions, 1);
assert_eq!(stats.pending_executions, 0);
}
}