NAC_Blockchain/nac-constitution-clauses/src/validator/mod.rs

348 lines
10 KiB
Rust

//! 宪法条款验证模块
//!
//! 提供条款内容验证、层级验证、依赖验证和冲突检测功能
use crate::{ConstitutionalClause, ClauseTier};
use nac_udm::primitives::Hash;
use std::collections::{HashMap, HashSet};
/// 验证错误类型
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ValidationError {
/// 条款内容为空
EmptyContent,
/// 条款标题为空
EmptyTitle,
/// 无效的条款索引
InvalidIndex,
/// 层级冲突
TierConflict(String),
/// 依赖缺失
MissingDependency(u64),
/// 循环依赖
CircularDependency(Vec<u64>),
/// 条款冲突
ClauseConflict(u64, String),
/// 生效时间无效
InvalidEffectiveTime,
/// 哈希不匹配
HashMismatch,
}
/// 条款验证器
pub struct ClauseValidator {
/// 已知的条款索引
known_clauses: HashSet<u64>,
/// 条款依赖关系 (clause_index -> dependencies)
dependencies: HashMap<u64, Vec<u64>>,
}
impl ClauseValidator {
/// 创建新的验证器
pub fn new() -> Self {
Self {
known_clauses: HashSet::new(),
dependencies: HashMap::new(),
}
}
/// 注册已知条款
pub fn register_clause(&mut self, index: u64, dependencies: Vec<u64>) {
self.known_clauses.insert(index);
if !dependencies.is_empty() {
self.dependencies.insert(index, dependencies);
}
}
/// 验证条款基本内容
pub fn validate_content(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> {
// 验证标题
if clause.title.trim().is_empty() {
return Err(ValidationError::EmptyTitle);
}
// 验证内容
if clause.content.trim().is_empty() {
return Err(ValidationError::EmptyContent);
}
// 验证索引
if clause.clause_index == 0 {
return Err(ValidationError::InvalidIndex);
}
// 验证生效时间
if clause.effective_from == 0 {
return Err(ValidationError::InvalidEffectiveTime);
}
Ok(())
}
/// 验证条款层级
pub fn validate_tier(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> {
// 永恒级条款的特殊规则
if clause.tier == ClauseTier::Eternal {
// 永恒级条款索引应该在1-100范围内
if clause.clause_index > 100 {
return Err(ValidationError::TierConflict(
"永恒级条款索引应在1-100范围内".to_string()
));
}
}
// 战略级条款的特殊规则
if clause.tier == ClauseTier::Strategic {
// 战略级条款索引应该在101-1000范围内
if clause.clause_index <= 100 || clause.clause_index > 1000 {
return Err(ValidationError::TierConflict(
"战略级条款索引应在101-1000范围内".to_string()
));
}
}
// 战术级条款的特殊规则
if clause.tier == ClauseTier::Tactical {
// 战术级条款索引应该大于1000
if clause.clause_index <= 1000 {
return Err(ValidationError::TierConflict(
"战术级条款索引应大于1000".to_string()
));
}
}
Ok(())
}
/// 验证条款依赖
pub fn validate_dependencies(&self, clause_index: u64) -> Result<(), ValidationError> {
if let Some(deps) = self.dependencies.get(&clause_index) {
// 检查所有依赖是否存在
for &dep in deps {
if !self.known_clauses.contains(&dep) {
return Err(ValidationError::MissingDependency(dep));
}
}
// 检查循环依赖
if let Some(cycle) = self.detect_circular_dependency(clause_index) {
return Err(ValidationError::CircularDependency(cycle));
}
}
Ok(())
}
/// 检测循环依赖
fn detect_circular_dependency(&self, start: u64) -> Option<Vec<u64>> {
let mut visited = HashSet::new();
let mut path = Vec::new();
if self.dfs_cycle_detection(start, &mut visited, &mut path) {
Some(path)
} else {
None
}
}
/// 深度优先搜索检测循环
fn dfs_cycle_detection(&self, current: u64, visited: &mut HashSet<u64>, path: &mut Vec<u64>) -> bool {
if path.contains(&current) {
path.push(current);
return true;
}
if visited.contains(&current) {
return false;
}
visited.insert(current);
path.push(current);
if let Some(deps) = self.dependencies.get(&current) {
for &dep in deps {
if self.dfs_cycle_detection(dep, visited, path) {
return true;
}
}
}
path.pop();
false
}
/// 验证条款哈希
pub fn validate_hash(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> {
let computed_hash = Self::compute_clause_hash(clause);
if computed_hash != clause.clause_hash {
return Err(ValidationError::HashMismatch);
}
Ok(())
}
/// 计算条款哈希
pub fn compute_clause_hash(clause: &ConstitutionalClause) -> Hash {
use sha3::{Sha3_384, Digest};
let mut hasher = Sha3_384::new();
hasher.update(clause.clause_index.to_le_bytes());
hasher.update(clause.title.as_bytes());
hasher.update(clause.content.as_bytes());
hasher.update(&[clause.tier as u8]);
hasher.update(clause.effective_from.to_le_bytes());
let result = hasher.finalize();
let mut bytes = [0u8; 48];
bytes.copy_from_slice(&result);
Hash::new(bytes)
}
/// 完整验证条款
pub fn validate_clause(&self, clause: &ConstitutionalClause) -> Result<(), ValidationError> {
self.validate_content(clause)?;
self.validate_tier(clause)?;
self.validate_dependencies(clause.clause_index)?;
self.validate_hash(clause)?;
Ok(())
}
}
impl Default for ClauseValidator {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
fn create_test_clause(index: u64, tier: ClauseTier) -> ConstitutionalClause {
let clause = ConstitutionalClause {
clause_index: index,
title: "测试条款".to_string(),
content: "这是一个测试条款内容".to_string(),
clause_hash: Hash::zero(),
effective_from: 1000,
tier,
};
let hash = ClauseValidator::compute_clause_hash(&clause);
ConstitutionalClause {
clause_hash: hash,
..clause
}
}
#[test]
fn test_validate_content() {
let validator = ClauseValidator::new();
let clause = create_test_clause(1, ClauseTier::Eternal);
assert!(validator.validate_content(&clause).is_ok());
}
#[test]
fn test_validate_empty_title() {
let validator = ClauseValidator::new();
let mut clause = create_test_clause(1, ClauseTier::Eternal);
clause.title = "".to_string();
assert_eq!(
validator.validate_content(&clause),
Err(ValidationError::EmptyTitle)
);
}
#[test]
fn test_validate_empty_content() {
let validator = ClauseValidator::new();
let mut clause = create_test_clause(1, ClauseTier::Eternal);
clause.content = "".to_string();
assert_eq!(
validator.validate_content(&clause),
Err(ValidationError::EmptyContent)
);
}
#[test]
fn test_validate_tier_eternal() {
let validator = ClauseValidator::new();
let clause = create_test_clause(50, ClauseTier::Eternal);
assert!(validator.validate_tier(&clause).is_ok());
}
#[test]
fn test_validate_tier_strategic() {
let validator = ClauseValidator::new();
let clause = create_test_clause(500, ClauseTier::Strategic);
assert!(validator.validate_tier(&clause).is_ok());
}
#[test]
fn test_validate_tier_tactical() {
let validator = ClauseValidator::new();
let clause = create_test_clause(2000, ClauseTier::Tactical);
assert!(validator.validate_tier(&clause).is_ok());
}
#[test]
fn test_validate_dependencies() {
let mut validator = ClauseValidator::new();
validator.register_clause(1, vec![]);
validator.register_clause(2, vec![1]);
assert!(validator.validate_dependencies(2).is_ok());
}
#[test]
fn test_missing_dependency() {
let mut validator = ClauseValidator::new();
validator.register_clause(2, vec![1]);
assert_eq!(
validator.validate_dependencies(2),
Err(ValidationError::MissingDependency(1))
);
}
#[test]
fn test_circular_dependency() {
let mut validator = ClauseValidator::new();
validator.register_clause(1, vec![2]);
validator.register_clause(2, vec![1]);
assert!(matches!(
validator.validate_dependencies(1),
Err(ValidationError::CircularDependency(_))
));
}
#[test]
fn test_validate_hash() {
let validator = ClauseValidator::new();
let clause = create_test_clause(1, ClauseTier::Eternal);
assert!(validator.validate_hash(&clause).is_ok());
}
#[test]
fn test_validate_hash_mismatch() {
let validator = ClauseValidator::new();
let mut clause = create_test_clause(1, ClauseTier::Eternal);
clause.clause_hash = Hash::zero();
assert_eq!(
validator.validate_hash(&clause),
Err(ValidationError::HashMismatch)
);
}
}