562 lines
15 KiB
Rust
562 lines
15 KiB
Rust
// UCA - Unified Cross-Chain Auditor
|
||
// 统一跨链审计器
|
||
//
|
||
// 功能:
|
||
// 1. 跨链行为追踪 - 记录节点在所有链上的转发、中继行为
|
||
// 2. 生成可验证的跨链行为证明
|
||
// 3. 违规跨链惩罚 - 发现恶意行为并触发宪法治理层处罚
|
||
// 4. 为GIDS提供信誉评分数据
|
||
|
||
use super::types::{ExtendedDID, NetworkBehaviorAudit, BehaviorType};
|
||
use nac_udm::primitives::{Hash, Timestamp};
|
||
use serde::{Deserialize, Serialize};
|
||
use std::collections::HashMap;
|
||
|
||
/// 统一跨链审计器
|
||
#[derive(Debug, Clone)]
|
||
pub struct UnifiedCrossChainAuditor {
|
||
/// 审计记录(按节点DID分组)
|
||
audit_records: HashMap<String, Vec<NetworkBehaviorAudit>>,
|
||
|
||
/// 违规记录
|
||
violations: Vec<ViolationRecord>,
|
||
|
||
/// 行为统计(按节点DID)
|
||
behavior_stats: HashMap<String, NodeBehaviorStats>,
|
||
|
||
/// 是否运行
|
||
is_running: bool,
|
||
}
|
||
|
||
/// 违规记录
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct ViolationRecord {
|
||
/// 违规ID
|
||
pub violation_id: Hash,
|
||
|
||
/// 节点DID
|
||
pub node_did: ExtendedDID,
|
||
|
||
/// 链ID
|
||
pub chain_id: u64,
|
||
|
||
/// 违规类型
|
||
pub violation_type: ViolationType,
|
||
|
||
/// 违规详情
|
||
pub details: String,
|
||
|
||
/// 证据哈希
|
||
pub evidence_hash: Hash,
|
||
|
||
/// 严重程度(1-10)
|
||
pub severity: u8,
|
||
|
||
/// 时间戳
|
||
pub timestamp: Timestamp,
|
||
|
||
/// 是否已处罚
|
||
pub is_penalized: bool,
|
||
}
|
||
|
||
/// 违规类型
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||
pub enum ViolationType {
|
||
/// 交易审查(恶意不转发交易)
|
||
TransactionCensorship,
|
||
|
||
/// 区块扣留(不传播区块)
|
||
BlockWithholding,
|
||
|
||
/// 双重中继(重复中继消息)
|
||
DoubleRelay,
|
||
|
||
/// 虚假状态证明
|
||
FalseStateProof,
|
||
|
||
/// 拒绝服务攻击
|
||
DenialOfService,
|
||
|
||
/// 恶意断开连接
|
||
MaliciousDisconnection,
|
||
}
|
||
|
||
/// 节点行为统计
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct NodeBehaviorStats {
|
||
/// 节点DID
|
||
pub node_did: String,
|
||
|
||
/// 总行为记录数
|
||
pub total_behaviors: usize,
|
||
|
||
/// 违规次数
|
||
pub violation_count: usize,
|
||
|
||
/// 成功转发次数
|
||
pub successful_forwards: usize,
|
||
|
||
/// 失败转发次数
|
||
pub failed_forwards: usize,
|
||
|
||
/// 跨链中继次数
|
||
pub cross_chain_relays: usize,
|
||
|
||
/// 最后活跃时间
|
||
pub last_active: Timestamp,
|
||
|
||
/// 信誉评分(0-100)
|
||
pub reputation_score: u8,
|
||
}
|
||
|
||
/// 行为证明
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct BehaviorProof {
|
||
/// 证明ID
|
||
pub proof_id: Hash,
|
||
|
||
/// 节点DID
|
||
pub node_did: ExtendedDID,
|
||
|
||
/// 行为类型
|
||
pub behavior_type: BehaviorType,
|
||
|
||
/// 证明数据
|
||
pub proof_data: Vec<u8>,
|
||
|
||
/// 见证节点列表
|
||
pub witnesses: Vec<ExtendedDID>,
|
||
|
||
/// 时间戳
|
||
pub timestamp: Timestamp,
|
||
}
|
||
|
||
impl UnifiedCrossChainAuditor {
|
||
/// 创建新的UCA实例
|
||
pub fn new() -> Self {
|
||
Self {
|
||
audit_records: HashMap::new(),
|
||
violations: Vec::new(),
|
||
behavior_stats: HashMap::new(),
|
||
is_running: false,
|
||
}
|
||
}
|
||
|
||
/// 启动审计器
|
||
pub fn start(&mut self) -> Result<(), String> {
|
||
if self.is_running {
|
||
return Err("UCA is already running".to_string());
|
||
}
|
||
|
||
self.is_running = true;
|
||
Ok(())
|
||
}
|
||
|
||
/// 停止审计器
|
||
pub fn stop(&mut self) -> Result<(), String> {
|
||
if !self.is_running {
|
||
return Err("UCA is not running".to_string());
|
||
}
|
||
|
||
self.is_running = false;
|
||
Ok(())
|
||
}
|
||
|
||
/// 记录网络行为
|
||
pub fn record_behavior(
|
||
&mut self,
|
||
node_did: ExtendedDID,
|
||
chain_id: u64,
|
||
behavior_type: BehaviorType,
|
||
details: String,
|
||
is_violation: bool,
|
||
) -> Result<Hash, String> {
|
||
if !self.is_running {
|
||
return Err("UCA is not running".to_string());
|
||
}
|
||
|
||
let audit_id = Hash::sha3_384(
|
||
format!("{}{}{}", node_did.to_string(), chain_id, Timestamp::now().as_secs())
|
||
.as_bytes()
|
||
);
|
||
|
||
let audit = NetworkBehaviorAudit {
|
||
audit_id: audit_id.clone(),
|
||
node_did: node_did.clone(),
|
||
chain_id,
|
||
behavior_type: behavior_type.clone(),
|
||
details: details.clone(),
|
||
is_violation,
|
||
timestamp: Timestamp::now(),
|
||
};
|
||
|
||
// 添加到审计记录
|
||
self.audit_records
|
||
.entry(node_did.to_string())
|
||
.or_insert_with(Vec::new)
|
||
.push(audit);
|
||
|
||
// 更新行为统计
|
||
self.update_behavior_stats(&node_did, &behavior_type, is_violation);
|
||
|
||
// 如果是违规行为,记录违规
|
||
if is_violation {
|
||
self.record_violation(
|
||
node_did,
|
||
chain_id,
|
||
self.infer_violation_type(&behavior_type),
|
||
details,
|
||
5, // 默认中等严重程度
|
||
)?;
|
||
}
|
||
|
||
Ok(audit_id)
|
||
}
|
||
|
||
/// 推断违规类型
|
||
fn infer_violation_type(&self, behavior_type: &BehaviorType) -> ViolationType {
|
||
match behavior_type {
|
||
BehaviorType::TransactionCensorship => ViolationType::TransactionCensorship,
|
||
BehaviorType::BlockPropagation => ViolationType::BlockWithholding,
|
||
BehaviorType::CrossChainRelay => ViolationType::DoubleRelay,
|
||
_ => ViolationType::DenialOfService,
|
||
}
|
||
}
|
||
|
||
/// 记录违规
|
||
pub fn record_violation(
|
||
&mut self,
|
||
node_did: ExtendedDID,
|
||
chain_id: u64,
|
||
violation_type: ViolationType,
|
||
details: String,
|
||
severity: u8,
|
||
) -> Result<Hash, String> {
|
||
let violation_id = Hash::sha3_384(
|
||
format!("{}{}{}", node_did.to_string(), chain_id, Timestamp::now().as_secs())
|
||
.as_bytes()
|
||
);
|
||
|
||
let evidence_hash = Hash::sha3_384(details.as_bytes());
|
||
|
||
let violation = ViolationRecord {
|
||
violation_id: violation_id.clone(),
|
||
node_did,
|
||
chain_id,
|
||
violation_type,
|
||
details,
|
||
evidence_hash,
|
||
severity,
|
||
timestamp: Timestamp::now(),
|
||
is_penalized: false,
|
||
};
|
||
|
||
self.violations.push(violation);
|
||
|
||
Ok(violation_id)
|
||
}
|
||
|
||
/// 更新行为统计
|
||
fn update_behavior_stats(
|
||
&mut self,
|
||
node_did: &ExtendedDID,
|
||
behavior_type: &BehaviorType,
|
||
is_violation: bool,
|
||
) {
|
||
let did_str = node_did.to_string();
|
||
|
||
let stats = self.behavior_stats
|
||
.entry(did_str.clone())
|
||
.or_insert_with(|| NodeBehaviorStats {
|
||
node_did: did_str,
|
||
total_behaviors: 0,
|
||
violation_count: 0,
|
||
successful_forwards: 0,
|
||
failed_forwards: 0,
|
||
cross_chain_relays: 0,
|
||
last_active: Timestamp::now(),
|
||
reputation_score: 100, // 初始满分
|
||
});
|
||
|
||
stats.total_behaviors += 1;
|
||
stats.last_active = Timestamp::now();
|
||
|
||
if is_violation {
|
||
stats.violation_count += 1;
|
||
// 每次违规扣10分,最低0分
|
||
stats.reputation_score = stats.reputation_score.saturating_sub(10);
|
||
} else {
|
||
// 正常行为加1分,最高100分
|
||
stats.reputation_score = stats.reputation_score.saturating_add(1).min(100);
|
||
}
|
||
|
||
match behavior_type {
|
||
BehaviorType::MessageForward => {
|
||
if is_violation {
|
||
stats.failed_forwards += 1;
|
||
} else {
|
||
stats.successful_forwards += 1;
|
||
}
|
||
}
|
||
BehaviorType::CrossChainRelay => {
|
||
stats.cross_chain_relays += 1;
|
||
}
|
||
_ => {}
|
||
}
|
||
}
|
||
|
||
/// 生成行为证明
|
||
pub fn generate_behavior_proof(
|
||
&self,
|
||
node_did: ExtendedDID,
|
||
behavior_type: BehaviorType,
|
||
proof_data: Vec<u8>,
|
||
witnesses: Vec<ExtendedDID>,
|
||
) -> Result<BehaviorProof, String> {
|
||
let proof_id = Hash::sha3_384(&proof_data);
|
||
|
||
Ok(BehaviorProof {
|
||
proof_id,
|
||
node_did,
|
||
behavior_type,
|
||
proof_data,
|
||
witnesses,
|
||
timestamp: Timestamp::now(),
|
||
})
|
||
}
|
||
|
||
/// 验证行为证明
|
||
pub fn verify_behavior_proof(&self, proof: &BehaviorProof) -> bool {
|
||
// 验证证明ID
|
||
let computed_id = Hash::sha3_384(&proof.proof_data);
|
||
if computed_id != proof.proof_id {
|
||
return false;
|
||
}
|
||
|
||
// 验证见证节点数量(至少需要3个见证)
|
||
if proof.witnesses.len() < 3 {
|
||
return false;
|
||
}
|
||
|
||
true
|
||
}
|
||
|
||
/// 获取节点审计记录
|
||
pub fn get_node_audits(&self, node_did: &str) -> Option<&Vec<NetworkBehaviorAudit>> {
|
||
self.audit_records.get(node_did)
|
||
}
|
||
|
||
/// 获取节点行为统计
|
||
pub fn get_node_stats(&self, node_did: &str) -> Option<&NodeBehaviorStats> {
|
||
self.behavior_stats.get(node_did)
|
||
}
|
||
|
||
/// 获取节点违规记录
|
||
pub fn get_node_violations(&self, node_did: &ExtendedDID) -> Vec<&ViolationRecord> {
|
||
self.violations
|
||
.iter()
|
||
.filter(|v| &v.node_did == node_did)
|
||
.collect()
|
||
}
|
||
|
||
/// 获取所有未处罚的违规
|
||
pub fn get_unpunished_violations(&self) -> Vec<&ViolationRecord> {
|
||
self.violations
|
||
.iter()
|
||
.filter(|v| !v.is_penalized)
|
||
.collect()
|
||
}
|
||
|
||
/// 标记违规已处罚
|
||
pub fn mark_violation_penalized(&mut self, violation_id: &Hash) -> Result<(), String> {
|
||
if let Some(violation) = self.violations.iter_mut().find(|v| &v.violation_id == violation_id) {
|
||
violation.is_penalized = true;
|
||
Ok(())
|
||
} else {
|
||
Err(format!("Violation not found: {:?}", violation_id))
|
||
}
|
||
}
|
||
|
||
/// 计算节点信誉评分
|
||
pub fn calculate_reputation(&self, node_did: &str) -> u8 {
|
||
if let Some(stats) = self.behavior_stats.get(node_did) {
|
||
stats.reputation_score
|
||
} else {
|
||
50 // 默认中等信誉
|
||
}
|
||
}
|
||
|
||
/// 获取审计统计
|
||
pub fn get_audit_stats(&self) -> AuditStats {
|
||
let total_audits: usize = self.audit_records.values().map(|v| v.len()).sum();
|
||
let total_violations = self.violations.len();
|
||
let unpunished_violations = self.violations.iter().filter(|v| !v.is_penalized).count();
|
||
|
||
let avg_reputation = if !self.behavior_stats.is_empty() {
|
||
let sum: u32 = self.behavior_stats.values().map(|s| s.reputation_score as u32).sum();
|
||
(sum / self.behavior_stats.len() as u32) as u8
|
||
} else {
|
||
0
|
||
};
|
||
|
||
AuditStats {
|
||
total_audits,
|
||
total_violations,
|
||
unpunished_violations,
|
||
monitored_nodes: self.behavior_stats.len(),
|
||
avg_reputation,
|
||
}
|
||
}
|
||
}
|
||
|
||
/// 审计统计
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct AuditStats {
|
||
/// 总审计记录数
|
||
pub total_audits: usize,
|
||
|
||
/// 总违规数
|
||
pub total_violations: usize,
|
||
|
||
/// 未处罚违规数
|
||
pub unpunished_violations: usize,
|
||
|
||
/// 监控节点数
|
||
pub monitored_nodes: usize,
|
||
|
||
/// 平均信誉评分
|
||
pub avg_reputation: u8,
|
||
}
|
||
|
||
impl Default for UnifiedCrossChainAuditor {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_uca_creation() {
|
||
let uca = UnifiedCrossChainAuditor::new();
|
||
assert!(!uca.is_running);
|
||
assert_eq!(uca.audit_records.len(), 0);
|
||
}
|
||
|
||
#[test]
|
||
fn test_record_behavior() {
|
||
let mut uca = UnifiedCrossChainAuditor::new();
|
||
uca.start().expect("mainnet: handle error");
|
||
|
||
let did = ExtendedDID::new(
|
||
"main".to_string(),
|
||
"cbp".to_string(),
|
||
"0x1234".to_string(),
|
||
);
|
||
|
||
let result = uca.record_behavior(
|
||
did.clone(),
|
||
1,
|
||
BehaviorType::MessageForward,
|
||
"Successfully forwarded message".to_string(),
|
||
false,
|
||
);
|
||
|
||
assert!(result.is_ok());
|
||
|
||
let audits = uca.get_node_audits(&did.to_string()).expect("mainnet: handle error");
|
||
assert_eq!(audits.len(), 1);
|
||
}
|
||
|
||
#[test]
|
||
fn test_record_violation() {
|
||
let mut uca = UnifiedCrossChainAuditor::new();
|
||
uca.start().expect("mainnet: handle error");
|
||
|
||
let did = ExtendedDID::new(
|
||
"main".to_string(),
|
||
"cbp".to_string(),
|
||
"0x1234".to_string(),
|
||
);
|
||
|
||
let result = uca.record_behavior(
|
||
did.clone(),
|
||
1,
|
||
BehaviorType::TransactionCensorship,
|
||
"Censored transaction".to_string(),
|
||
true, // 这是违规行为
|
||
);
|
||
|
||
assert!(result.is_ok());
|
||
|
||
let violations = uca.get_node_violations(&did);
|
||
assert_eq!(violations.len(), 1);
|
||
assert_eq!(violations[0].violation_type, ViolationType::TransactionCensorship);
|
||
}
|
||
|
||
#[test]
|
||
fn test_reputation_calculation() {
|
||
let mut uca = UnifiedCrossChainAuditor::new();
|
||
uca.start().expect("mainnet: handle error");
|
||
|
||
let did = ExtendedDID::new(
|
||
"main".to_string(),
|
||
"cbp".to_string(),
|
||
"0x1234".to_string(),
|
||
);
|
||
|
||
// 记录正常行为
|
||
for _ in 0..5 {
|
||
uca.record_behavior(
|
||
did.clone(),
|
||
1,
|
||
BehaviorType::MessageForward,
|
||
"Success".to_string(),
|
||
false,
|
||
).expect("mainnet: handle error");
|
||
}
|
||
|
||
// 记录违规行为
|
||
uca.record_behavior(
|
||
did.clone(),
|
||
1,
|
||
BehaviorType::TransactionCensorship,
|
||
"Violation".to_string(),
|
||
true,
|
||
).expect("mainnet: handle error");
|
||
|
||
let reputation = uca.calculate_reputation(&did.to_string());
|
||
|
||
// 初始100分,5次正常行为+5分=105(上限100),1次违规-10分=90
|
||
assert_eq!(reputation, 90);
|
||
}
|
||
|
||
#[test]
|
||
fn test_behavior_proof() {
|
||
let uca = UnifiedCrossChainAuditor::new();
|
||
|
||
let did = ExtendedDID::new(
|
||
"main".to_string(),
|
||
"cbp".to_string(),
|
||
"0x1234".to_string(),
|
||
);
|
||
|
||
let witnesses = vec![
|
||
ExtendedDID::new("main".to_string(), "cbp".to_string(), "0x2".to_string()),
|
||
ExtendedDID::new("main".to_string(), "cbp".to_string(), "0x3".to_string()),
|
||
ExtendedDID::new("main".to_string(), "cbp".to_string(), "0x4".to_string()),
|
||
];
|
||
|
||
let proof = uca.generate_behavior_proof(
|
||
did,
|
||
BehaviorType::MessageForward,
|
||
vec![1, 2, 3],
|
||
witnesses,
|
||
).expect("mainnet: handle error");
|
||
|
||
assert!(uca.verify_behavior_proof(&proof));
|
||
}
|
||
}
|