NAC_Blockchain/nac-cross-chain-bridge/src/validator.rs

336 lines
11 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

use crate::types::*;
use async_trait::async_trait;
use sled::Db;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::RwLock;
/// 验证器池trait
#[async_trait]
pub trait ValidatorPool: Send + Sync {
/// 注册验证器
async fn register_validator(&self, validator: ValidatorInfo) -> Result<()>;
/// 注销验证器
async fn unregister_validator(&self, address: Address) -> Result<()>;
/// 获取活跃验证器列表
async fn get_active_validators(&self) -> Result<Vec<ValidatorInfo>>;
/// 加载验证器(从数据库)
async fn load_validators(&self) -> Result<()>;
/// 验证消息签名
async fn verify_message_signatures(
&self,
message: &CrossChainMessage,
) -> Result<bool>;
/// 获取验证器信息
async fn get_validator(&self, address: Address) -> Result<ValidatorInfo>;
/// 更新验证器声誉
async fn update_reputation(&self, address: Address, delta: i64) -> Result<()>;
}
/// 验证器池实现
pub struct ValidatorPoolImpl {
db: Arc<Db>,
validators: Arc<RwLock<HashMap<Address, ValidatorInfo>>>,
config: BridgeConfig,
}
impl ValidatorPoolImpl {
pub fn new(db: Arc<Db>, config: BridgeConfig) -> Self {
let validators = Arc::new(RwLock::new(HashMap::new()));
Self {
db,
validators,
config,
}
}
/// 从数据库加载验证器
pub async fn load_validators(&self) -> Result<()> {
let prefix = b"validator:";
let mut validators = self.validators.write().await;
for item in self.db.scan_prefix(prefix) {
let (_, value) = item.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
let validator: ValidatorInfo = bincode::deserialize(&value)
.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
validators.insert(validator.address, validator);
}
log::info!("Loaded {} validators from database", validators.len());
Ok(())
}
/// 保存验证器到数据库
fn save_validator(&self, validator: &ValidatorInfo) -> Result<()> {
let key = format!("validator:{}", hex::encode(validator.address));
let value = bincode::serialize(validator)
.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
self.db.insert(key.as_bytes(), value)
.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
Ok(())
}
/// 从数据库删除验证器
fn delete_validator(&self, address: Address) -> Result<()> {
let key = format!("validator:{}", hex::encode(address));
self.db.remove(key.as_bytes())
.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
Ok(())
}
/// 从数据库加载所有验证器
fn load_all_validators(&self) -> Result<Vec<ValidatorInfo>> {
let mut validators = Vec::new();
let prefix = b"validator:";
for item in self.db.scan_prefix(prefix) {
let (_key, value) = item.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
let validator: ValidatorInfo = bincode::deserialize(&value)
.map_err(|e| BridgeError::DatabaseError(e.to_string()))?;
validators.push(validator);
}
Ok(validators)
}
/// 验证单个签名使用NAC的签名验证
fn verify_signature(
&self,
message_hash: &Hash,
signature: &Signature,
validator_address: &Address,
) -> bool {
// TODO: 实现实际的签名验证逻辑
// 这里简化实现,假设签名有效
true
}
}
#[async_trait]
impl ValidatorPool for ValidatorPoolImpl {
async fn register_validator(&self, validator: ValidatorInfo) -> Result<()> {
// 验证质押金额
let min_stake = 10_000 * 10u128.pow(18); // 最小质押10,000 NAC
if validator.stake_amount < min_stake {
return Err(BridgeError::Other(
format!("Insufficient stake: {} < {}", validator.stake_amount, min_stake)
));
}
// 保存到数据库
self.save_validator(&validator)?;
// 更新内存缓存
let mut validators = self.validators.write().await;
validators.insert(validator.address, validator.clone());
log::info!(
"Validator registered: address={}, stake={}",
hex::encode(validator.address),
validator.stake_amount
);
Ok(())
}
async fn unregister_validator(&self, address: Address) -> Result<()> {
// 从数据库删除
self.delete_validator(address)?;
// 从内存缓存删除
let mut validators = self.validators.write().await;
validators.remove(&address);
log::info!("Validator unregistered: address={}", hex::encode(address));
Ok(())
}
async fn get_active_validators(&self) -> Result<Vec<ValidatorInfo>> {
let validators = self.validators.read().await;
let active: Vec<ValidatorInfo> = validators
.values()
.filter(|v| v.is_active)
.cloned()
.collect();
Ok(active)
}
async fn verify_message_signatures(
&self,
message: &CrossChainMessage,
) -> Result<bool> {
// 检查签名数量
if message.signatures.len() < self.config.min_validator_signatures {
return Ok(false);
}
// 获取活跃验证器
let active_validators = self.get_active_validators().await?;
if active_validators.is_empty() {
return Err(BridgeError::Other("No active validators".to_string()));
}
// 计算消息哈希NAC的48字节哈希
let message_hash = message.id;
// 验证每个签名
let mut valid_signatures = 0;
for signature in &message.signatures {
for validator in &active_validators {
if self.verify_signature(&message_hash, signature, &validator.address) {
valid_signatures += 1;
break;
}
}
}
// 检查是否达到最小签名数
Ok(valid_signatures >= self.config.min_validator_signatures)
}
async fn get_validator(&self, address: Address) -> Result<ValidatorInfo> {
let validators = self.validators.read().await;
validators
.get(&address)
.cloned()
.ok_or(BridgeError::Other(format!("Validator not found: {:?}", address)))
}
async fn update_reputation(&self, address: Address, delta: i64) -> Result<()> {
let mut validators = self.validators.write().await;
if let Some(validator) = validators.get_mut(&address) {
if delta < 0 {
validator.reputation = validator.reputation.saturating_sub((-delta) as u64);
} else {
validator.reputation = validator.reputation.saturating_add(delta as u64);
}
// 保存到数据库
self.save_validator(validator)?;
log::info!(
"Validator reputation updated: address={}, new_reputation={}",
hex::encode(address),
validator.reputation
);
}
Ok(())
}
async fn load_validators(&self) -> Result<()> {
// 加载所有验证器到内存
let validators = self.load_all_validators()?;
let mut validator_map = self.validators.write().await;
for validator in validators {
validator_map.insert(validator.address, validator);
}
log::info!("Loaded {} validators from database", validator_map.len());
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_register_validator() {
let db = Arc::new(sled::Config::new().temporary(true).open().unwrap());
let config = BridgeConfig::default();
let pool = ValidatorPoolImpl::new(db, config);
let validator = ValidatorInfo {
address: [1u8; 32],
stake_amount: 10_000 * 10u128.pow(18),
reputation: 100,
is_active: true,
};
pool.register_validator(validator.clone()).await.unwrap();
let loaded = pool.get_validator(validator.address).await.unwrap();
assert_eq!(loaded.address, validator.address);
assert_eq!(loaded.stake_amount, validator.stake_amount);
}
#[tokio::test]
async fn test_get_active_validators() {
let db = Arc::new(sled::Config::new().temporary(true).open().unwrap());
let config = BridgeConfig::default();
let pool = ValidatorPoolImpl::new(db, config);
// 注册2个活跃验证器
let validator1 = ValidatorInfo {
address: [1u8; 32],
stake_amount: 10_000 * 10u128.pow(18),
reputation: 100,
is_active: true,
};
let validator2 = ValidatorInfo {
address: [2u8; 32],
stake_amount: 20_000 * 10u128.pow(18),
reputation: 200,
is_active: true,
};
pool.register_validator(validator1).await.unwrap();
pool.register_validator(validator2).await.unwrap();
let active = pool.get_active_validators().await.unwrap();
assert_eq!(active.len(), 2);
}
#[tokio::test]
async fn test_unregister_validator() {
let db = Arc::new(sled::Config::new().temporary(true).open().unwrap());
let config = BridgeConfig::default();
let pool = ValidatorPoolImpl::new(db, config);
let validator = ValidatorInfo {
address: [1u8; 32],
stake_amount: 10_000 * 10u128.pow(18),
reputation: 100,
is_active: true,
};
pool.register_validator(validator.clone()).await.unwrap();
pool.unregister_validator(validator.address).await.unwrap();
let result = pool.get_validator(validator.address).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_update_reputation() {
let db = Arc::new(sled::Config::new().temporary(true).open().unwrap());
let config = BridgeConfig::default();
let pool = ValidatorPoolImpl::new(db, config);
let validator = ValidatorInfo {
address: [1u8; 32],
stake_amount: 10_000 * 10u128.pow(18),
reputation: 100,
is_active: true,
};
pool.register_validator(validator.clone()).await.unwrap();
pool.update_reputation(validator.address, 50).await.unwrap();
let updated = pool.get_validator(validator.address).await.unwrap();
assert_eq!(updated.reputation, 150);
}
}