393 lines
13 KiB
Rust
393 lines
13 KiB
Rust
//! CBPP L1层集成测试
|
||
|
||
use nac_cbpp_l1::*;
|
||
use nac_udm::primitives::Address;
|
||
|
||
fn create_test_registry() -> CbpRegistry {
|
||
CbpRegistry::new()
|
||
}
|
||
|
||
fn register_test_cbp(registry: &mut CbpRegistry, id: u8) -> Address {
|
||
let address = Address::new([id; 32]);
|
||
registry.register_cbp(
|
||
address,
|
||
format!("did:nac:test{}", id),
|
||
100_000_000_000,
|
||
2,
|
||
8000,
|
||
80,
|
||
1000,
|
||
).expect("mainnet: handle error");
|
||
registry.activate_cbp(&address).expect("mainnet: handle error");
|
||
address
|
||
}
|
||
|
||
#[test]
|
||
fn test_full_lifecycle() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 1);
|
||
|
||
// 1. 注册和激活
|
||
assert_eq!(registry.get_cbp(&address).expect("mainnet: handle error").status, CbpStatus::Active);
|
||
|
||
// 2. 记录声誉事件
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.reputation_manager_mut().record_event(
|
||
&mut node,
|
||
ReputationEvent::BlockProduced,
|
||
2000,
|
||
None,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
// 提交退出请求
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.exit_manager_mut().submit_exit_request(
|
||
&node,
|
||
ExitReason::Voluntary,
|
||
3000,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 4. 审核退出
|
||
registry.exit_manager_mut().review_exit_request(
|
||
&address,
|
||
true,
|
||
Address::new([99u8; 32]),
|
||
Some("Approved".to_string()),
|
||
3000 + 8 * 24 * 3600,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 5. 确认退出
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.exit_manager_mut().confirm_exit(
|
||
&address,
|
||
&node,
|
||
100_000_000_000,
|
||
0,
|
||
3000 + 22 * 24 * 3600,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 更新节点状态
|
||
node.status = CbpStatus::Exited;
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
assert_eq!(registry.get_cbp(&address).expect("mainnet: handle error").status, CbpStatus::Exited);
|
||
}
|
||
|
||
#[test]
|
||
fn test_redemption_workflow() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 2);
|
||
|
||
// 等待锁定期
|
||
let timestamp = 1000 + 31 * 24 * 3600;
|
||
|
||
// 提交赎回请求
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.redemption_manager_mut().submit_redemption_request(
|
||
&node,
|
||
RedemptionType::Partial,
|
||
50_000_000_000,
|
||
timestamp,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 处理赎回
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let (actual, _penalty) = registry.redemption_manager_mut().process_redemption(
|
||
&address,
|
||
&node,
|
||
timestamp + 100,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 更新质押金额
|
||
node.stake_amount -= actual;
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
// 验证质押减少
|
||
assert!(registry.get_cbp(&address).expect("mainnet: handle error").stake_amount < 100_000_000_000);
|
||
}
|
||
|
||
#[test]
|
||
fn test_penalty_and_appeal() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 3);
|
||
|
||
// 检测违规
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let detection = registry.penalty_manager().detect_violation(
|
||
&node,
|
||
ViolationType::ConsecutiveMissedBlocks,
|
||
"Missed 10 blocks".to_string(),
|
||
5,
|
||
2000,
|
||
);
|
||
|
||
// 执行处罚
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let penalty_id = registry.penalty_manager_mut().execute_penalty(
|
||
&mut node,
|
||
detection,
|
||
2000,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
// 提交申诉
|
||
let appeal_id = registry.penalty_manager_mut().submit_appeal(
|
||
penalty_id,
|
||
address,
|
||
"False positive".to_string(),
|
||
"Counter evidence".to_string(),
|
||
2000 + 3600,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 审核申诉
|
||
registry.penalty_manager_mut().review_appeal(
|
||
appeal_id,
|
||
true,
|
||
Address::new([99u8; 32]),
|
||
Some("Approved".to_string()),
|
||
2000 + 7200,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 撤销处罚
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.penalty_manager_mut().revoke_penalty(
|
||
penalty_id,
|
||
&mut node,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
}
|
||
|
||
#[test]
|
||
fn test_reputation_decay() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 4);
|
||
|
||
let initial_reputation = registry.get_cbp(&address).expect("mainnet: handle error").reputation;
|
||
|
||
// 应用衰减(1天后)
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.reputation_manager_mut().apply_decay(
|
||
&mut node,
|
||
1000 + 24 * 3600,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
assert!(registry.get_cbp(&address).expect("mainnet: handle error").reputation < initial_reputation);
|
||
}
|
||
|
||
#[test]
|
||
fn test_emergency_redemption_penalty() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 5);
|
||
|
||
let timestamp = 1000 + 31 * 24 * 3600;
|
||
|
||
// 紧急赎回
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.redemption_manager_mut().submit_redemption_request(
|
||
&node,
|
||
RedemptionType::Emergency,
|
||
100_000_000_000,
|
||
timestamp,
|
||
).expect("mainnet: handle error");
|
||
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let (actual, penalty) = registry.redemption_manager_mut().process_redemption(
|
||
&address,
|
||
&node,
|
||
timestamp + 100,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 更新质押金额
|
||
node.stake_amount -= actual;
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
// 紧急赎回有20%处罚
|
||
assert_eq!(penalty, 100_000_000_000 * 20 / 100);
|
||
assert_eq!(actual, 100_000_000_000 - penalty);
|
||
}
|
||
|
||
#[test]
|
||
fn test_multiple_violations() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 6);
|
||
|
||
// 第一次违规
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let detection1 = registry.penalty_manager().detect_violation(
|
||
&node,
|
||
ViolationType::HardwareFailure,
|
||
"Hardware issue".to_string(),
|
||
3,
|
||
2000,
|
||
);
|
||
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.penalty_manager_mut().execute_penalty(
|
||
&mut node,
|
||
detection1,
|
||
2000,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
// 第二次违规
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let detection2 = registry.penalty_manager().detect_violation(
|
||
&node,
|
||
ViolationType::ConsecutiveMissedBlocks,
|
||
"Missed blocks".to_string(),
|
||
5,
|
||
3000,
|
||
);
|
||
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.penalty_manager_mut().execute_penalty(
|
||
&mut node,
|
||
detection2,
|
||
3000,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
let records = registry.penalty_manager().get_penalty_records(Some(&address));
|
||
assert_eq!(records.len(), 2);
|
||
}
|
||
|
||
#[test]
|
||
fn test_exit_cancellation() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 7);
|
||
|
||
// 提交退出请求
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.exit_manager_mut().submit_exit_request(
|
||
&node,
|
||
ExitReason::Voluntary,
|
||
2000,
|
||
).expect("mainnet: handle error");
|
||
|
||
// 取消退出
|
||
registry.exit_manager_mut().cancel_exit_request(&address).expect("mainnet: handle error");
|
||
|
||
let request = registry.exit_manager().get_exit_request(&address).expect("mainnet: handle error");
|
||
assert_eq!(request.status, ExitStatus::Cancelled);
|
||
}
|
||
|
||
#[test]
|
||
fn test_reputation_recovery() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 8);
|
||
|
||
// 降低声誉
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.reputation_manager_mut().record_event(
|
||
&mut node,
|
||
ReputationEvent::BlockMissed,
|
||
2000,
|
||
None,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
let low_reputation = registry.get_cbp(&address).expect("mainnet: handle error").reputation;
|
||
|
||
// 恢复声誉
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.reputation_manager_mut().recover_reputation(
|
||
&mut node,
|
||
0.1,
|
||
3000,
|
||
"Community contribution".to_string(),
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
assert!(registry.get_cbp(&address).expect("mainnet: handle error").reputation > low_reputation);
|
||
}
|
||
|
||
#[test]
|
||
fn test_slashing_penalty() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 9);
|
||
|
||
let original_stake = registry.get_cbp(&address).expect("mainnet: handle error").stake_amount;
|
||
|
||
// 双签违规
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let detection = registry.penalty_manager().detect_violation(
|
||
&node,
|
||
ViolationType::DoubleSign,
|
||
"Double signing detected".to_string(),
|
||
10,
|
||
2000,
|
||
);
|
||
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.penalty_manager_mut().execute_penalty(
|
||
&mut node,
|
||
detection,
|
||
2000,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
assert!(registry.get_cbp(&address).expect("mainnet: handle error").stake_amount < original_stake);
|
||
}
|
||
|
||
#[test]
|
||
fn test_batch_reputation_update() {
|
||
let mut registry = create_test_registry();
|
||
let addr1 = register_test_cbp(&mut registry, 10);
|
||
let addr2 = register_test_cbp(&mut registry, 11);
|
||
|
||
// 设置出块数
|
||
registry.get_cbp_mut(&addr1).expect("mainnet: handle error").blocks_produced = 10;
|
||
registry.get_cbp_mut(&addr2).expect("mainnet: handle error").blocks_produced = 5;
|
||
|
||
// 批量更新
|
||
let mut nodes: Vec<CbpNode> = registry.get_all_nodes().into_iter().cloned().collect();
|
||
let updated = registry.reputation_manager_mut().batch_update_for_blocks(
|
||
&mut nodes,
|
||
3000,
|
||
).expect("mainnet: handle error");
|
||
|
||
assert!(updated >= 2);
|
||
}
|
||
|
||
#[test]
|
||
fn test_statistics() {
|
||
let mut registry = create_test_registry();
|
||
let address = register_test_cbp(&mut registry, 12);
|
||
|
||
// 生成一些活动
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.reputation_manager_mut().record_event(
|
||
&mut node,
|
||
ReputationEvent::BlockProduced,
|
||
2000,
|
||
None,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
let node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
let detection = registry.penalty_manager().detect_violation(
|
||
&node,
|
||
ViolationType::HardwareFailure,
|
||
"Test".to_string(),
|
||
3,
|
||
3000,
|
||
);
|
||
|
||
let mut node = registry.get_cbp(&address).expect("mainnet: handle error").clone();
|
||
registry.penalty_manager_mut().execute_penalty(
|
||
&mut node,
|
||
detection,
|
||
3000,
|
||
).expect("mainnet: handle error");
|
||
*registry.get_cbp_mut(&address).expect("mainnet: handle error") = node;
|
||
|
||
// 获取统计
|
||
let rep_stats = registry.reputation_manager().get_reputation_statistics(&address);
|
||
assert!(rep_stats.total_changes > 0);
|
||
|
||
let penalty_stats = registry.penalty_manager().get_penalty_statistics();
|
||
assert!(penalty_stats.total_penalties > 0);
|
||
}
|