622 lines
18 KiB
Rust
622 lines
18 KiB
Rust
//! 区块验证系统
|
||
//!
|
||
//! 实现完整的区块验证功能,包括宪法验证、交易验证、合规检查和状态转换
|
||
|
||
use crate::block::{Block, BlockHeader};
|
||
use serde::{Deserialize, Serialize};
|
||
use std::collections::{HashMap, HashSet};
|
||
use chrono::Utc;
|
||
|
||
/// 验证错误类型
|
||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||
pub enum ValidationError {
|
||
/// 宪法验证失败
|
||
ConstitutionalViolation(String),
|
||
/// 交易验证失败
|
||
InvalidTransaction(String),
|
||
/// 合规检查失败
|
||
ComplianceFailure(String),
|
||
/// 状态转换失败
|
||
StateTransitionError(String),
|
||
/// 签名验证失败
|
||
InvalidSignature(String),
|
||
/// 时间戳无效
|
||
InvalidTimestamp(String),
|
||
/// 区块高度无效
|
||
InvalidHeight(String),
|
||
/// Merkle根不匹配
|
||
MerkleRootMismatch,
|
||
/// 区块大小超限
|
||
BlockSizeExceeded,
|
||
/// Gas限制超限
|
||
GasLimitExceeded,
|
||
}
|
||
|
||
/// 宪法规则
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct ConstitutionalRule {
|
||
/// 规则ID
|
||
pub id: String,
|
||
/// 规则名称
|
||
pub name: String,
|
||
/// 规则描述
|
||
pub description: String,
|
||
/// 规则类型
|
||
pub rule_type: RuleType,
|
||
/// 是否启用
|
||
pub enabled: bool,
|
||
/// 优先级
|
||
pub priority: u32,
|
||
}
|
||
|
||
/// 规则类型
|
||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||
pub enum RuleType {
|
||
/// 区块结构规则
|
||
BlockStructure,
|
||
/// 交易规则
|
||
Transaction,
|
||
/// 验证者规则
|
||
Validator,
|
||
/// 共识规则
|
||
Consensus,
|
||
/// 资产规则
|
||
Asset,
|
||
/// 合规规则
|
||
Compliance,
|
||
}
|
||
|
||
/// 交易验证规则
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct TransactionRule {
|
||
/// 最小交易费
|
||
pub min_fee: u64,
|
||
/// 最大交易大小
|
||
pub max_size: usize,
|
||
/// 最大Gas限制
|
||
pub max_gas: u64,
|
||
/// 需要签名数量
|
||
pub required_signatures: usize,
|
||
}
|
||
|
||
/// 合规检查器
|
||
#[derive(Debug, Clone)]
|
||
pub struct ComplianceChecker {
|
||
/// KYC要求
|
||
kyc_required: bool,
|
||
/// AML检查
|
||
aml_enabled: bool,
|
||
/// 黑名单
|
||
blacklist: HashSet<String>,
|
||
/// 白名单
|
||
whitelist: HashSet<String>,
|
||
/// 地域限制
|
||
pub geo_restrictions: HashMap<String, bool>,
|
||
}
|
||
|
||
impl ComplianceChecker {
|
||
pub fn new() -> Self {
|
||
ComplianceChecker {
|
||
kyc_required: true,
|
||
aml_enabled: true,
|
||
blacklist: HashSet::new(),
|
||
whitelist: HashSet::new(),
|
||
geo_restrictions: HashMap::new(),
|
||
}
|
||
}
|
||
|
||
/// 检查地址是否合规
|
||
pub fn check_address(&self, address: &str) -> Result<(), ValidationError> {
|
||
// 检查黑名单
|
||
if self.blacklist.contains(address) {
|
||
return Err(ValidationError::ComplianceFailure(
|
||
format!("Address {} is blacklisted", address)
|
||
));
|
||
}
|
||
|
||
// 检查白名单(如果启用)
|
||
if !self.whitelist.is_empty() && !self.whitelist.contains(address) {
|
||
return Err(ValidationError::ComplianceFailure(
|
||
format!("Address {} is not whitelisted", address)
|
||
));
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 检查KYC状态
|
||
pub fn check_kyc(&self, address: &str) -> Result<(), ValidationError> {
|
||
if !self.kyc_required {
|
||
return Ok(());
|
||
}
|
||
|
||
// 简化实现:假设所有地址都需要KYC验证
|
||
// 实际应该查询KYC数据库
|
||
if address.len() < 42 {
|
||
return Err(ValidationError::ComplianceFailure(
|
||
format!("Address {} has not completed KYC", address)
|
||
));
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 执行AML检查
|
||
pub fn check_aml(&self, address: &str, amount: u64) -> Result<(), ValidationError> {
|
||
if !self.aml_enabled {
|
||
return Ok(());
|
||
}
|
||
|
||
// 简化实现:检查大额交易
|
||
if amount > 1_000_000_000 {
|
||
// 需要额外的AML审查
|
||
return Err(ValidationError::ComplianceFailure(
|
||
format!("Large transaction from {} requires AML review", address)
|
||
));
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 添加到黑名单
|
||
pub fn add_to_blacklist(&mut self, address: String) {
|
||
self.blacklist.insert(address);
|
||
}
|
||
|
||
/// 添加到白名单
|
||
pub fn add_to_whitelist(&mut self, address: String) {
|
||
self.whitelist.insert(address);
|
||
}
|
||
}
|
||
|
||
impl Default for ComplianceChecker {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
/// 状态转换器
|
||
#[derive(Debug, Clone)]
|
||
pub struct StateTransition {
|
||
/// 前状态根
|
||
pub prev_state_root: String,
|
||
/// 后状态根
|
||
pub next_state_root: String,
|
||
/// 状态变更
|
||
pub changes: Vec<StateChange>,
|
||
}
|
||
|
||
/// 状态变更
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct StateChange {
|
||
/// 账户地址
|
||
pub address: String,
|
||
/// 变更类型
|
||
pub change_type: ChangeType,
|
||
/// 旧值
|
||
pub old_value: Option<String>,
|
||
/// 新值
|
||
pub new_value: String,
|
||
}
|
||
|
||
/// 变更类型
|
||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||
pub enum ChangeType {
|
||
/// 余额变更
|
||
Balance,
|
||
/// Nonce变更
|
||
Nonce,
|
||
/// 存储变更
|
||
Storage,
|
||
/// 代码变更
|
||
Code,
|
||
}
|
||
|
||
/// 区块验证器
|
||
#[derive(Debug)]
|
||
pub struct BlockValidator {
|
||
/// 宪法规则
|
||
constitutional_rules: Vec<ConstitutionalRule>,
|
||
/// 交易规则
|
||
transaction_rules: TransactionRule,
|
||
/// 合规检查器
|
||
compliance_checker: ComplianceChecker,
|
||
/// 最大区块大小
|
||
max_block_size: usize,
|
||
/// 最大区块Gas
|
||
max_block_gas: u64,
|
||
}
|
||
|
||
impl BlockValidator {
|
||
pub fn new() -> Self {
|
||
BlockValidator {
|
||
constitutional_rules: Self::default_constitutional_rules(),
|
||
transaction_rules: TransactionRule {
|
||
min_fee: 1000,
|
||
max_size: 1024 * 1024, // 1MB
|
||
max_gas: 10_000_000,
|
||
required_signatures: 1,
|
||
},
|
||
compliance_checker: ComplianceChecker::new(),
|
||
max_block_size: 10 * 1024 * 1024, // 10MB
|
||
max_block_gas: 100_000_000,
|
||
}
|
||
}
|
||
|
||
/// 默认宪法规则
|
||
fn default_constitutional_rules() -> Vec<ConstitutionalRule> {
|
||
vec![
|
||
ConstitutionalRule {
|
||
id: "rule_001".to_string(),
|
||
name: "Block Size Limit".to_string(),
|
||
description: "Maximum block size is 10MB".to_string(),
|
||
rule_type: RuleType::BlockStructure,
|
||
enabled: true,
|
||
priority: 1,
|
||
},
|
||
ConstitutionalRule {
|
||
id: "rule_002".to_string(),
|
||
name: "Transaction Fee".to_string(),
|
||
description: "Minimum transaction fee is 1000 units".to_string(),
|
||
rule_type: RuleType::Transaction,
|
||
enabled: true,
|
||
priority: 2,
|
||
},
|
||
ConstitutionalRule {
|
||
id: "rule_003".to_string(),
|
||
name: "Validator Signature".to_string(),
|
||
description: "Block must be signed by a valid validator".to_string(),
|
||
rule_type: RuleType::Validator,
|
||
enabled: true,
|
||
priority: 3,
|
||
},
|
||
ConstitutionalRule {
|
||
id: "rule_004".to_string(),
|
||
name: "KYC Requirement".to_string(),
|
||
description: "All participants must complete KYC".to_string(),
|
||
rule_type: RuleType::Compliance,
|
||
enabled: true,
|
||
priority: 4,
|
||
},
|
||
]
|
||
}
|
||
|
||
/// 完整的区块验证
|
||
pub fn validate_block(&self, block: &Block, prev_block: Option<&Block>) -> Result<(), ValidationError> {
|
||
// 1. 验证区块头
|
||
self.validate_header(&block.header, prev_block)?;
|
||
|
||
// 2. 宪法验证
|
||
self.validate_constitutional(block)?;
|
||
|
||
// 3. 交易验证
|
||
self.validate_transactions(block)?;
|
||
|
||
// 4. 合规检查
|
||
self.validate_compliance(block)?;
|
||
|
||
// 5. 状态转换验证
|
||
self.validate_state_transition(block)?;
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 验证区块头
|
||
fn validate_header(&self, header: &BlockHeader, prev_block: Option<&Block>) -> Result<(), ValidationError> {
|
||
// 验证时间戳
|
||
let now = Utc::now();
|
||
let future_limit = now + chrono::Duration::seconds(300);
|
||
|
||
if header.timestamp > future_limit {
|
||
return Err(ValidationError::InvalidTimestamp(
|
||
"Block timestamp is too far in the future".to_string()
|
||
));
|
||
}
|
||
|
||
// 验证高度
|
||
if let Some(prev) = prev_block {
|
||
if header.height != prev.header.height + 1 {
|
||
return Err(ValidationError::InvalidHeight(
|
||
format!("Expected height {}, got {}", prev.header.height + 1, header.height)
|
||
));
|
||
}
|
||
|
||
// 验证父哈希
|
||
if header.prev_hash != prev.hash() {
|
||
return Err(ValidationError::StateTransitionError(
|
||
"Previous hash does not match".to_string()
|
||
));
|
||
}
|
||
|
||
// 验证时间戳递增
|
||
if header.timestamp <= prev.header.timestamp {
|
||
return Err(ValidationError::InvalidTimestamp(
|
||
"Block timestamp must be greater than previous block".to_string()
|
||
));
|
||
}
|
||
} else if header.height != 0 {
|
||
return Err(ValidationError::InvalidHeight(
|
||
"Genesis block must have height 0".to_string()
|
||
));
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 宪法验证
|
||
fn validate_constitutional(&self, block: &Block) -> Result<(), ValidationError> {
|
||
for rule in &self.constitutional_rules {
|
||
if !rule.enabled {
|
||
continue;
|
||
}
|
||
|
||
match rule.rule_type {
|
||
RuleType::BlockStructure => {
|
||
// 验证区块大小
|
||
let block_size = self.estimate_block_size(block);
|
||
if block_size > self.max_block_size {
|
||
return Err(ValidationError::ConstitutionalViolation(
|
||
format!("Block size {} exceeds limit {}", block_size, self.max_block_size)
|
||
));
|
||
}
|
||
}
|
||
RuleType::Transaction => {
|
||
// 交易规则在validate_transactions中验证
|
||
}
|
||
RuleType::Validator => {
|
||
// 验证签名
|
||
if block.header.validator.is_empty() {
|
||
return Err(ValidationError::ConstitutionalViolation(
|
||
"Block must have a proposer".to_string()
|
||
));
|
||
}
|
||
}
|
||
RuleType::Consensus => {
|
||
// 共识规则验证
|
||
}
|
||
RuleType::Asset => {
|
||
// 资产规则验证
|
||
}
|
||
RuleType::Compliance => {
|
||
// 合规规则在validate_compliance中验证
|
||
}
|
||
}
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 交易验证
|
||
fn validate_transactions(&self, block: &Block) -> Result<(), ValidationError> {
|
||
let mut total_gas = 0u64;
|
||
|
||
for tx in &block.body.transactions {
|
||
// 验证交易大小
|
||
let tx_size = serde_json::to_string(tx).expect("FIX-006: unexpected None/Err").len();
|
||
if tx_size > self.transaction_rules.max_size {
|
||
return Err(ValidationError::InvalidTransaction(
|
||
format!("Transaction size {} exceeds limit {}", tx_size, self.transaction_rules.max_size)
|
||
));
|
||
}
|
||
|
||
// 验证Gas限制
|
||
// 简化实现:假设每个交易消耗固定Gas
|
||
let tx_gas = 21000u64;
|
||
if tx_gas > self.transaction_rules.max_gas {
|
||
return Err(ValidationError::InvalidTransaction(
|
||
format!("Transaction gas {} exceeds limit {}", tx_gas, self.transaction_rules.max_gas)
|
||
));
|
||
}
|
||
|
||
total_gas += tx_gas;
|
||
}
|
||
|
||
// 验证区块总Gas
|
||
if total_gas > self.max_block_gas {
|
||
return Err(ValidationError::GasLimitExceeded);
|
||
}
|
||
|
||
// 验证Merkle根
|
||
let tx_hashes: Vec<String> = block.body.transactions.iter().map(|tx| tx.hash()).collect();
|
||
let calculated_root = self.calculate_merkle_root_from_hashes(&tx_hashes);
|
||
if calculated_root != block.header.merkle_root {
|
||
return Err(ValidationError::MerkleRootMismatch);
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 合规检查
|
||
fn validate_compliance(&self, block: &Block) -> Result<(), ValidationError> {
|
||
// 检查提议者合规性
|
||
self.compliance_checker.check_address(&block.header.validator)?;
|
||
self.compliance_checker.check_kyc(&block.header.validator)?;
|
||
|
||
// 检查交易合规性
|
||
for tx in &block.body.transactions {
|
||
// 简化实现:从交易中提取地址
|
||
// 实际应该解析交易数据
|
||
// 检查交易发送者
|
||
self.compliance_checker.check_address(&tx.from)?;
|
||
|
||
// 检查AML
|
||
self.compliance_checker.check_aml(&tx.from, tx.amount)?;
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 状态转换验证
|
||
fn validate_state_transition(&self, block: &Block) -> Result<(), ValidationError> {
|
||
// 验证状态根
|
||
if block.header.state_root.is_empty() {
|
||
return Err(ValidationError::StateTransitionError(
|
||
"State root is empty".to_string()
|
||
));
|
||
}
|
||
|
||
// 简化实现:实际应该执行所有交易并验证状态根
|
||
// 这里只做基本检查
|
||
if block.header.state_root.len() != 64 {
|
||
return Err(ValidationError::StateTransitionError(
|
||
"Invalid state root format".to_string()
|
||
));
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 估算区块大小
|
||
fn estimate_block_size(&self, block: &Block) -> usize {
|
||
let mut size = 0;
|
||
|
||
// 区块头大小
|
||
size += 200; // 简化估算
|
||
|
||
// 交易大小
|
||
for tx in &block.body.transactions {
|
||
size += serde_json::to_string(tx).expect("FIX-006: unexpected None/Err").len();
|
||
}
|
||
|
||
size
|
||
}
|
||
|
||
/// 计算Merkle根
|
||
fn calculate_merkle_root_from_hashes(&self, hashes: &[String]) -> String {
|
||
if hashes.is_empty() {
|
||
return "0".repeat(64);
|
||
}
|
||
|
||
// 简化实现:使用SHA256
|
||
use sha2::{Sha256, Digest};
|
||
let mut hasher = Sha256::new();
|
||
for hash in hashes {
|
||
hasher.update(hash.as_bytes());
|
||
}
|
||
hex::encode(hasher.finalize())
|
||
}
|
||
|
||
/// 获取合规检查器的可变引用
|
||
pub fn compliance_checker_mut(&mut self) -> &mut ComplianceChecker {
|
||
&mut self.compliance_checker
|
||
}
|
||
|
||
/// 添加宪法规则
|
||
pub fn add_constitutional_rule(&mut self, rule: ConstitutionalRule) {
|
||
self.constitutional_rules.push(rule);
|
||
}
|
||
|
||
/// 更新交易规则
|
||
pub fn update_transaction_rules(&mut self, rules: TransactionRule) {
|
||
self.transaction_rules = rules;
|
||
}
|
||
}
|
||
|
||
impl Default for BlockValidator {
|
||
fn default() -> Self {
|
||
Self::new()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
use crate::block::{Block, BlockBody};
|
||
|
||
#[test]
|
||
fn test_compliance_checker() {
|
||
let mut checker = ComplianceChecker::new();
|
||
|
||
// 测试黑名单
|
||
checker.add_to_blacklist("0x123".to_string());
|
||
assert!(checker.check_address("0x123").is_err());
|
||
|
||
// 测试白名单
|
||
checker.add_to_whitelist("0x456".to_string());
|
||
assert!(checker.check_address("0x456").is_ok());
|
||
}
|
||
|
||
#[test]
|
||
fn test_kyc_check() {
|
||
let checker = ComplianceChecker::new();
|
||
|
||
// 短地址应该失败
|
||
assert!(checker.check_kyc("0x123").is_err());
|
||
|
||
// 长地址应该通过
|
||
let long_address = "0x1234567890123456789012345678901234567890";
|
||
assert!(checker.check_kyc(long_address).is_ok());
|
||
}
|
||
|
||
#[test]
|
||
fn test_aml_check() {
|
||
let checker = ComplianceChecker::new();
|
||
|
||
// 小额交易应该通过
|
||
assert!(checker.check_aml("0x123", 1000).is_ok());
|
||
|
||
// 大额交易应该需要审查
|
||
assert!(checker.check_aml("0x123", 2_000_000_000).is_err());
|
||
}
|
||
|
||
#[test]
|
||
fn test_block_validator_creation() {
|
||
let validator = BlockValidator::new();
|
||
assert_eq!(validator.constitutional_rules.len(), 4);
|
||
assert_eq!(validator.max_block_size, 10 * 1024 * 1024);
|
||
}
|
||
|
||
#[test]
|
||
fn test_validate_header() {
|
||
let validator = BlockValidator::new();
|
||
let mut block = Block::new(0, "0".repeat(96), "validator1".to_string());
|
||
|
||
// 设置有效的时间戳(当前时间)
|
||
block.header.timestamp = chrono::Utc::now();
|
||
|
||
// 创世区块应该通过
|
||
assert!(validator.validate_header(&block.header, None).is_ok());
|
||
}
|
||
|
||
#[test]
|
||
fn test_validate_block_size() {
|
||
let validator = BlockValidator::new();
|
||
let mut block = Block::new(1, "genesis".to_string(), "validator1".to_string());
|
||
|
||
// 添加一些交易
|
||
use crate::block::Transaction;
|
||
block.body.transactions.push(Transaction::new(
|
||
"0x123".to_string(),
|
||
"0x456".to_string(),
|
||
1000,
|
||
1,
|
||
));
|
||
|
||
// 应该通过
|
||
assert!(validator.validate_constitutional(&block).is_ok());
|
||
}
|
||
|
||
#[test]
|
||
fn test_merkle_root_calculation() {
|
||
let validator = BlockValidator::new();
|
||
let hashes = vec![
|
||
"hash1".to_string(),
|
||
"hash2".to_string(),
|
||
];
|
||
|
||
let root = validator.calculate_merkle_root_from_hashes(&hashes);
|
||
assert_eq!(root.len(), 64);
|
||
}
|
||
|
||
#[test]
|
||
fn test_state_transition_validation() {
|
||
let validator = BlockValidator::new();
|
||
let mut block = Block::new(1, "genesis".to_string(), "validator1".to_string());
|
||
|
||
// 设置有效的状态根
|
||
block.header.state_root = "0".repeat(64);
|
||
|
||
assert!(validator.validate_state_transition(&block).is_ok());
|
||
}
|
||
}
|