336 lines
11 KiB
Rust
336 lines
11 KiB
Rust
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);
|
||
}
|
||
}
|