173 lines
4.7 KiB
Rust
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);
|
|
}
|
|
}
|