310 lines
8.4 KiB
Rust
310 lines
8.4 KiB
Rust
//! 资产锁定/解锁模块
|
||
|
||
use crate::error::{BridgeError, BridgeResult};
|
||
use serde::{Deserialize, Serialize};
|
||
use std::collections::HashMap;
|
||
|
||
/// 锁定记录
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct LockRecord {
|
||
/// 锁定ID
|
||
pub lock_id: String,
|
||
/// 以太坊交易哈希
|
||
pub eth_tx_hash: String,
|
||
/// 锁定金额
|
||
pub amount: u128,
|
||
/// Token地址(None表示ETH)
|
||
pub token_address: Option<String>,
|
||
/// NAC目标地址
|
||
pub nac_target_address: [u8; 32],
|
||
/// 锁定时间戳
|
||
pub locked_at: u64,
|
||
/// 状态
|
||
pub status: LockStatus,
|
||
/// 签名列表(多签)
|
||
pub signatures: Vec<Signature>,
|
||
}
|
||
|
||
/// 锁定状态
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||
pub enum LockStatus {
|
||
/// 待确认
|
||
Pending,
|
||
/// 已确认
|
||
Confirmed,
|
||
/// 已解锁
|
||
Unlocked,
|
||
/// 已取消
|
||
Cancelled,
|
||
}
|
||
|
||
/// 签名
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct Signature {
|
||
/// 签名者地址
|
||
pub signer: String,
|
||
/// 签名数据
|
||
pub signature: Vec<u8>,
|
||
/// 签名时间
|
||
pub signed_at: u64,
|
||
}
|
||
|
||
/// 解锁请求
|
||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||
pub struct UnlockRequest {
|
||
/// 解锁ID
|
||
pub unlock_id: String,
|
||
/// NAC交易哈希
|
||
pub nac_tx_hash: String,
|
||
/// 解锁金额
|
||
pub amount: u128,
|
||
/// Token地址(None表示ETH)
|
||
pub token_address: Option<String>,
|
||
/// 以太坊目标地址
|
||
pub eth_target_address: String,
|
||
/// 请求时间戳
|
||
pub requested_at: u64,
|
||
/// 状态
|
||
pub status: UnlockStatus,
|
||
/// 签名列表(多签)
|
||
pub signatures: Vec<Signature>,
|
||
}
|
||
|
||
/// 解锁状态
|
||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
|
||
pub enum UnlockStatus {
|
||
/// 待审批
|
||
PendingApproval,
|
||
/// 已批准
|
||
Approved,
|
||
/// 已执行
|
||
Executed,
|
||
/// 已拒绝
|
||
Rejected,
|
||
}
|
||
|
||
/// 锁定/解锁管理器
|
||
pub struct LockUnlockManager {
|
||
/// 锁定记录
|
||
locks: HashMap<String, LockRecord>,
|
||
/// 解锁请求
|
||
unlocks: HashMap<String, UnlockRequest>,
|
||
/// 多签阈值
|
||
multisig_threshold: usize,
|
||
/// 授权签名者列表
|
||
authorized_signers: Vec<String>,
|
||
}
|
||
|
||
impl LockUnlockManager {
|
||
/// 创建新的管理器
|
||
pub fn new(multisig_threshold: usize, authorized_signers: Vec<String>) -> Self {
|
||
Self {
|
||
locks: HashMap::new(),
|
||
unlocks: HashMap::new(),
|
||
multisig_threshold,
|
||
authorized_signers,
|
||
}
|
||
}
|
||
|
||
/// 记录锁定
|
||
pub fn record_lock(&mut self, lock: LockRecord) -> BridgeResult<()> {
|
||
if self.locks.contains_key(&lock.lock_id) {
|
||
return Err(BridgeError::ValidationError(
|
||
"Lock ID already exists".to_string()
|
||
));
|
||
}
|
||
|
||
self.locks.insert(lock.lock_id.clone(), lock);
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取锁定记录
|
||
pub fn get_lock(&self, lock_id: &str) -> Option<&LockRecord> {
|
||
self.locks.get(lock_id)
|
||
}
|
||
|
||
/// 添加锁定签名
|
||
pub fn add_lock_signature(
|
||
&mut self,
|
||
lock_id: &str,
|
||
signature: Signature,
|
||
) -> BridgeResult<()> {
|
||
// 验证签名者
|
||
if !self.authorized_signers.contains(&signature.signer) {
|
||
return Err(BridgeError::SecurityError(
|
||
"Unauthorized signer".to_string()
|
||
));
|
||
}
|
||
|
||
let lock = self.locks.get_mut(lock_id)
|
||
.ok_or_else(|| BridgeError::ValidationError("Lock not found".to_string()))?;
|
||
|
||
// 检查是否已签名
|
||
if lock.signatures.iter().any(|s| s.signer == signature.signer) {
|
||
return Err(BridgeError::ValidationError(
|
||
"Signer already signed".to_string()
|
||
));
|
||
}
|
||
|
||
lock.signatures.push(signature);
|
||
|
||
// 检查是否达到阈值
|
||
if lock.signatures.len() >= self.multisig_threshold {
|
||
lock.status = LockStatus::Confirmed;
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 记录解锁请求
|
||
pub fn record_unlock(&mut self, unlock: UnlockRequest) -> BridgeResult<()> {
|
||
if self.unlocks.contains_key(&unlock.unlock_id) {
|
||
return Err(BridgeError::ValidationError(
|
||
"Unlock ID already exists".to_string()
|
||
));
|
||
}
|
||
|
||
self.unlocks.insert(unlock.unlock_id.clone(), unlock);
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取解锁请求
|
||
pub fn get_unlock(&self, unlock_id: &str) -> Option<&UnlockRequest> {
|
||
self.unlocks.get(unlock_id)
|
||
}
|
||
|
||
/// 添加解锁签名
|
||
pub fn add_unlock_signature(
|
||
&mut self,
|
||
unlock_id: &str,
|
||
signature: Signature,
|
||
) -> BridgeResult<()> {
|
||
// 验证签名者
|
||
if !self.authorized_signers.contains(&signature.signer) {
|
||
return Err(BridgeError::SecurityError(
|
||
"Unauthorized signer".to_string()
|
||
));
|
||
}
|
||
|
||
let unlock = self.unlocks.get_mut(unlock_id)
|
||
.ok_or_else(|| BridgeError::ValidationError("Unlock not found".to_string()))?;
|
||
|
||
// 检查是否已签名
|
||
if unlock.signatures.iter().any(|s| s.signer == signature.signer) {
|
||
return Err(BridgeError::ValidationError(
|
||
"Signer already signed".to_string()
|
||
));
|
||
}
|
||
|
||
unlock.signatures.push(signature);
|
||
|
||
// 检查是否达到阈值
|
||
if unlock.signatures.len() >= self.multisig_threshold {
|
||
unlock.status = UnlockStatus::Approved;
|
||
}
|
||
|
||
Ok(())
|
||
}
|
||
|
||
/// 执行解锁
|
||
pub fn execute_unlock(&mut self, unlock_id: &str) -> BridgeResult<()> {
|
||
let unlock = self.unlocks.get_mut(unlock_id)
|
||
.ok_or_else(|| BridgeError::ValidationError("Unlock not found".to_string()))?;
|
||
|
||
if unlock.status != UnlockStatus::Approved {
|
||
return Err(BridgeError::ValidationError(
|
||
"Unlock not approved".to_string()
|
||
));
|
||
}
|
||
|
||
unlock.status = UnlockStatus::Executed;
|
||
Ok(())
|
||
}
|
||
|
||
/// 获取所有待确认的锁定
|
||
pub fn get_pending_locks(&self) -> Vec<&LockRecord> {
|
||
self.locks.values()
|
||
.filter(|lock| lock.status == LockStatus::Pending)
|
||
.collect()
|
||
}
|
||
|
||
/// 获取所有待审批的解锁
|
||
pub fn get_pending_unlocks(&self) -> Vec<&UnlockRequest> {
|
||
self.unlocks.values()
|
||
.filter(|unlock| unlock.status == UnlockStatus::PendingApproval)
|
||
.collect()
|
||
}
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use super::*;
|
||
|
||
#[test]
|
||
fn test_lock_unlock_manager() {
|
||
let signers = vec!["signer1".to_string(), "signer2".to_string()];
|
||
let mut manager = LockUnlockManager::new(2, signers);
|
||
|
||
// 测试锁定
|
||
let lock = LockRecord {
|
||
lock_id: "lock1".to_string(),
|
||
eth_tx_hash: "0x123".to_string(),
|
||
amount: 1000,
|
||
token_address: None,
|
||
nac_target_address: [0u8; 32],
|
||
locked_at: 1234567890,
|
||
status: LockStatus::Pending,
|
||
signatures: vec![],
|
||
};
|
||
|
||
assert!(manager.record_lock(lock).is_ok());
|
||
assert!(manager.get_lock("lock1").is_some());
|
||
|
||
// 测试签名
|
||
let sig1 = Signature {
|
||
signer: "signer1".to_string(),
|
||
signature: vec![1, 2, 3],
|
||
signed_at: 1234567891,
|
||
};
|
||
|
||
assert!(manager.add_lock_signature("lock1", sig1).is_ok());
|
||
assert_eq!(manager.get_lock("lock1").unwrap().signatures.len(), 1);
|
||
|
||
let sig2 = Signature {
|
||
signer: "signer2".to_string(),
|
||
signature: vec![4, 5, 6],
|
||
signed_at: 1234567892,
|
||
};
|
||
|
||
assert!(manager.add_lock_signature("lock1", sig2).is_ok());
|
||
assert_eq!(manager.get_lock("lock1").unwrap().status, LockStatus::Confirmed);
|
||
}
|
||
|
||
#[test]
|
||
fn test_unauthorized_signer() {
|
||
let signers = vec!["signer1".to_string()];
|
||
let mut manager = LockUnlockManager::new(1, signers);
|
||
|
||
let lock = LockRecord {
|
||
lock_id: "lock1".to_string(),
|
||
eth_tx_hash: "0x123".to_string(),
|
||
amount: 1000,
|
||
token_address: None,
|
||
nac_target_address: [0u8; 32],
|
||
locked_at: 1234567890,
|
||
status: LockStatus::Pending,
|
||
signatures: vec![],
|
||
};
|
||
|
||
manager.record_lock(lock).unwrap();
|
||
|
||
let sig = Signature {
|
||
signer: "unauthorized".to_string(),
|
||
signature: vec![1, 2, 3],
|
||
signed_at: 1234567891,
|
||
};
|
||
|
||
assert!(manager.add_lock_signature("lock1", sig).is_err());
|
||
}
|
||
}
|