NAC_Blockchain/nvm_v2/nvm-l1/src/oracle/bridge_enhanced.rs

620 lines
17 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.

// Enhanced Cross-Chain Bridge
// 跨链资产桥接增强 - 基于ACC-CrossChain扩展
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use super::crosschain_message::{ChainId, CrossChainMessage, MessageType};
/// 桥接资产类型
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum BridgeAssetType {
/// 原生代币
NativeToken,
/// 资产TOKEN
AssetToken,
/// 权益代币
EquityToken,
/// NFT
NFT,
}
/// 桥接操作类型
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum BridgeOperation {
/// 锁定(源链)
Lock,
/// 铸造(目标链)
Mint,
/// 销毁(目标链)
Burn,
/// 解锁(源链)
Unlock,
}
/// 桥接状态
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum BridgeStatus {
/// 初始化
Initialized,
/// 已锁定
Locked,
/// 已铸造
Minted,
/// 已销毁
Burned,
/// 已解锁
Unlocked,
/// 失败
Failed,
}
/// 桥接交易
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BridgeTransaction {
/// 交易ID
pub tx_id: String,
/// 源链
pub source_chain: ChainId,
/// 目标链
pub target_chain: ChainId,
/// 资产类型
pub asset_type: BridgeAssetType,
/// 资产ID对于TOKEN/NFT
pub asset_id: String,
/// 数量18位小数
pub amount: u128,
/// 发送者
pub sender: String,
/// 接收者
pub receiver: String,
/// 桥接状态
pub status: BridgeStatus,
/// 锁定交易哈希
pub lock_tx_hash: Option<String>,
/// 铸造交易哈希
pub mint_tx_hash: Option<String>,
/// 销毁交易哈希
pub burn_tx_hash: Option<String>,
/// 解锁交易哈希
pub unlock_tx_hash: Option<String>,
/// 创建时间
pub created_at: u64,
/// 完成时间
pub completed_at: Option<u64>,
/// 手续费
pub fee: u128,
}
impl BridgeTransaction {
pub fn new(
tx_id: String,
source_chain: ChainId,
target_chain: ChainId,
asset_type: BridgeAssetType,
asset_id: String,
amount: u128,
sender: String,
receiver: String,
fee: u128,
) -> Self {
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
Self {
tx_id,
source_chain,
target_chain,
asset_type,
asset_id,
amount,
sender,
receiver,
status: BridgeStatus::Initialized,
lock_tx_hash: None,
mint_tx_hash: None,
burn_tx_hash: None,
unlock_tx_hash: None,
created_at: now,
completed_at: None,
fee,
}
}
/// 标记为已锁定
pub fn mark_locked(&mut self, tx_hash: String) {
self.status = BridgeStatus::Locked;
self.lock_tx_hash = Some(tx_hash);
}
/// 标记为已铸造
pub fn mark_minted(&mut self, tx_hash: String) {
self.status = BridgeStatus::Minted;
self.mint_tx_hash = Some(tx_hash);
self.completed_at = Some(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
);
}
/// 标记为已销毁
pub fn mark_burned(&mut self, tx_hash: String) {
self.status = BridgeStatus::Burned;
self.burn_tx_hash = Some(tx_hash);
}
/// 标记为已解锁
pub fn mark_unlocked(&mut self, tx_hash: String) {
self.status = BridgeStatus::Unlocked;
self.unlock_tx_hash = Some(tx_hash);
self.completed_at = Some(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
);
}
/// 标记为失败
pub fn mark_failed(&mut self) {
self.status = BridgeStatus::Failed;
self.completed_at = Some(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
);
}
}
/// 流动性池
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LiquidityPool {
/// 池ID
pub pool_id: String,
/// 链ID
pub chain_id: ChainId,
/// 资产ID
pub asset_id: String,
/// 总流动性
pub total_liquidity: u128,
/// 已锁定金额
pub locked_amount: u128,
/// 可用金额
pub available_amount: u128,
}
impl LiquidityPool {
pub fn new(pool_id: String, chain_id: ChainId, asset_id: String, initial_liquidity: u128) -> Self {
Self {
pool_id,
chain_id,
asset_id,
total_liquidity: initial_liquidity,
locked_amount: 0,
available_amount: initial_liquidity,
}
}
/// 锁定流动性
pub fn lock(&mut self, amount: u128) -> Result<(), String> {
if amount > self.available_amount {
return Err("Insufficient liquidity".to_string());
}
self.locked_amount += amount;
self.available_amount -= amount;
Ok(())
}
/// 解锁流动性
pub fn unlock(&mut self, amount: u128) -> Result<(), String> {
if amount > self.locked_amount {
return Err("Insufficient locked amount".to_string());
}
self.locked_amount -= amount;
self.available_amount += amount;
Ok(())
}
/// 添加流动性
pub fn add_liquidity(&mut self, amount: u128) {
self.total_liquidity += amount;
self.available_amount += amount;
}
/// 移除流动性
pub fn remove_liquidity(&mut self, amount: u128) -> Result<(), String> {
if amount > self.available_amount {
return Err("Insufficient available liquidity".to_string());
}
self.total_liquidity -= amount;
self.available_amount -= amount;
Ok(())
}
}
/// 增强型跨链桥接系统
pub struct EnhancedCrossChainBridge {
/// 桥接交易 (tx_id -> BridgeTransaction)
transactions: HashMap<String, BridgeTransaction>,
/// 流动性池 (chain_id, asset_id) -> LiquidityPool
liquidity_pools: HashMap<(ChainId, String), LiquidityPool>,
/// 支持的资产 (chain_id -> Vec<asset_id>)
supported_assets: HashMap<ChainId, Vec<String>>,
/// 手续费率基点1基点=0.01%
fee_rate: u16,
/// 最小桥接金额
min_bridge_amount: u128,
/// 最大桥接金额
max_bridge_amount: u128,
/// 统计信息
stats: BridgeStats,
}
/// 桥接统计
#[derive(Debug, Clone, Default)]
pub struct BridgeStats {
/// 总交易数
pub total_transactions: u64,
/// 成功交易数
pub successful_transactions: u64,
/// 失败交易数
pub failed_transactions: u64,
/// 总桥接金额
pub total_volume: u128,
/// 总手续费
pub total_fees: u128,
}
impl EnhancedCrossChainBridge {
/// 创建新的桥接系统
pub fn new(fee_rate: u16, min_amount: u128, max_amount: u128) -> Self {
Self {
transactions: HashMap::new(),
liquidity_pools: HashMap::new(),
supported_assets: HashMap::new(),
fee_rate,
min_bridge_amount: min_amount,
max_bridge_amount: max_amount,
stats: BridgeStats::default(),
}
}
/// 添加支持的资产
pub fn add_supported_asset(&mut self, chain_id: ChainId, asset_id: String) {
self.supported_assets
.entry(chain_id)
.or_insert_with(Vec::new)
.push(asset_id);
}
/// 创建流动性池
pub fn create_liquidity_pool(
&mut self,
chain_id: ChainId,
asset_id: String,
initial_liquidity: u128,
) -> Result<String, String> {
let pool_id = format!("pool_{}_{}", chain_id.0, asset_id);
if self.liquidity_pools.contains_key(&(chain_id.clone(), asset_id.clone())) {
return Err("Pool already exists".to_string());
}
let pool = LiquidityPool::new(pool_id.clone(), chain_id.clone(), asset_id.clone(), initial_liquidity);
self.liquidity_pools.insert((chain_id, asset_id), pool);
Ok(pool_id)
}
/// 初始化桥接交易
pub fn initiate_bridge(
&mut self,
source_chain: ChainId,
target_chain: ChainId,
asset_type: BridgeAssetType,
asset_id: String,
amount: u128,
sender: String,
receiver: String,
) -> Result<String, String> {
// 验证金额范围
if amount < self.min_bridge_amount {
return Err(format!("Amount below minimum: {}", self.min_bridge_amount));
}
if amount > self.max_bridge_amount {
return Err(format!("Amount exceeds maximum: {}", self.max_bridge_amount));
}
// 验证资产支持
if let Some(assets) = self.supported_assets.get(&source_chain) {
if !assets.contains(&asset_id) {
return Err("Asset not supported on source chain".to_string());
}
} else {
return Err("Source chain not supported".to_string());
}
// 计算手续费
let fee = (amount * self.fee_rate as u128) / 10000;
let now = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
let tx_id = format!("bridge_{}_{}", source_chain.0, now);
let transaction = BridgeTransaction::new(
tx_id.clone(),
source_chain,
target_chain,
asset_type,
asset_id,
amount,
sender,
receiver,
fee,
);
self.transactions.insert(tx_id.clone(), transaction);
self.stats.total_transactions += 1;
Ok(tx_id)
}
/// 执行锁定操作
pub fn execute_lock(&mut self, tx_id: &str, lock_tx_hash: String) -> Result<(), String> {
let tx = self.transactions.get_mut(tx_id)
.ok_or("Transaction not found")?;
if tx.status != BridgeStatus::Initialized {
return Err(format!("Invalid status: {:?}", tx.status));
}
// 锁定流动性池
if let Some(pool) = self.liquidity_pools.get_mut(&(tx.source_chain.clone(), tx.asset_id.clone())) {
pool.lock(tx.amount)?;
}
tx.mark_locked(lock_tx_hash);
Ok(())
}
/// 执行铸造操作
pub fn execute_mint(&mut self, tx_id: &str, mint_tx_hash: String) -> Result<(), String> {
let tx = self.transactions.get_mut(tx_id)
.ok_or("Transaction not found")?;
if tx.status != BridgeStatus::Locked {
return Err(format!("Invalid status: {:?}", tx.status));
}
tx.mark_minted(mint_tx_hash);
self.stats.successful_transactions += 1;
self.stats.total_volume += tx.amount;
self.stats.total_fees += tx.fee;
Ok(())
}
/// 执行销毁操作(反向桥接)
pub fn execute_burn(&mut self, tx_id: &str, burn_tx_hash: String) -> Result<(), String> {
let tx = self.transactions.get_mut(tx_id)
.ok_or("Transaction not found")?;
if tx.status != BridgeStatus::Initialized {
return Err(format!("Invalid status: {:?}", tx.status));
}
tx.mark_burned(burn_tx_hash);
Ok(())
}
/// 执行解锁操作(反向桥接)
pub fn execute_unlock(&mut self, tx_id: &str, unlock_tx_hash: String) -> Result<(), String> {
let tx = self.transactions.get_mut(tx_id)
.ok_or("Transaction not found")?;
if tx.status != BridgeStatus::Burned {
return Err(format!("Invalid status: {:?}", tx.status));
}
// 解锁流动性池
if let Some(pool) = self.liquidity_pools.get_mut(&(tx.target_chain.clone(), tx.asset_id.clone())) {
pool.unlock(tx.amount)?;
}
tx.mark_unlocked(unlock_tx_hash);
self.stats.successful_transactions += 1;
self.stats.total_volume += tx.amount;
self.stats.total_fees += tx.fee;
Ok(())
}
/// 标记交易失败
pub fn mark_transaction_failed(&mut self, tx_id: &str) -> Result<(), String> {
let tx = self.transactions.get_mut(tx_id)
.ok_or("Transaction not found")?;
// 如果已锁定,需要解锁
if tx.status == BridgeStatus::Locked {
if let Some(pool) = self.liquidity_pools.get_mut(&(tx.source_chain.clone(), tx.asset_id.clone())) {
pool.unlock(tx.amount)?;
}
}
tx.mark_failed();
self.stats.failed_transactions += 1;
Ok(())
}
/// 获取交易
pub fn get_transaction(&self, tx_id: &str) -> Option<&BridgeTransaction> {
self.transactions.get(tx_id)
}
/// 获取流动性池
pub fn get_liquidity_pool(&self, chain_id: &ChainId, asset_id: &str) -> Option<&LiquidityPool> {
self.liquidity_pools.get(&(chain_id.clone(), asset_id.to_string()))
}
/// 添加流动性
pub fn add_liquidity(
&mut self,
chain_id: &ChainId,
asset_id: &str,
amount: u128,
) -> Result<(), String> {
let pool = self.liquidity_pools.get_mut(&(chain_id.clone(), asset_id.to_string()))
.ok_or("Pool not found")?;
pool.add_liquidity(amount);
Ok(())
}
/// 获取统计信息
pub fn get_stats(&self) -> &BridgeStats {
&self.stats
}
}
impl Default for EnhancedCrossChainBridge {
fn default() -> Self {
Self::new(
30, // 0.3% 手续费
1_000_000_000_000_000_000, // 最小1个TOKEN
1_000_000_000_000_000_000_000, // 最大1000个TOKEN
)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bridge_creation() {
let bridge = EnhancedCrossChainBridge::default();
assert_eq!(bridge.fee_rate, 30);
}
#[test]
fn test_add_supported_asset() {
let mut bridge = EnhancedCrossChainBridge::default();
bridge.add_supported_asset(ChainId::nac(), "XTZH".to_string());
assert!(bridge.supported_assets.contains_key(&ChainId::nac()));
}
#[test]
fn test_create_liquidity_pool() {
let mut bridge = EnhancedCrossChainBridge::default();
let pool_id = bridge.create_liquidity_pool(
ChainId::nac(),
"XTZH".to_string(),
1000_000_000_000_000_000_000,
).unwrap();
assert!(pool_id.starts_with("pool_"));
assert!(bridge.get_liquidity_pool(&ChainId::nac(), "XTZH").is_some());
}
#[test]
fn test_initiate_bridge() {
let mut bridge = EnhancedCrossChainBridge::default();
let eth_chain = ChainId::new("ETH".to_string());
bridge.add_supported_asset(ChainId::nac(), "XTZH".to_string());
let tx_id = bridge.initiate_bridge(
ChainId::nac(),
eth_chain,
BridgeAssetType::NativeToken,
"XTZH".to_string(),
100_000_000_000_000_000_000,
"sender".to_string(),
"receiver".to_string(),
).unwrap();
assert!(bridge.get_transaction(&tx_id).is_some());
assert_eq!(bridge.stats.total_transactions, 1);
}
#[test]
fn test_bridge_lifecycle() {
let mut bridge = EnhancedCrossChainBridge::default();
let eth_chain = ChainId::new("ETH".to_string());
bridge.add_supported_asset(ChainId::nac(), "XTZH".to_string());
bridge.create_liquidity_pool(ChainId::nac(), "XTZH".to_string(), 1000_000_000_000_000_000_000).unwrap();
let tx_id = bridge.initiate_bridge(
ChainId::nac(),
eth_chain,
BridgeAssetType::NativeToken,
"XTZH".to_string(),
100_000_000_000_000_000_000,
"sender".to_string(),
"receiver".to_string(),
).unwrap();
// 锁定
bridge.execute_lock(&tx_id, "lock_hash".to_string()).unwrap();
assert_eq!(bridge.get_transaction(&tx_id).unwrap().status, BridgeStatus::Locked);
// 铸造
bridge.execute_mint(&tx_id, "mint_hash".to_string()).unwrap();
assert_eq!(bridge.get_transaction(&tx_id).unwrap().status, BridgeStatus::Minted);
assert_eq!(bridge.stats.successful_transactions, 1);
}
#[test]
fn test_liquidity_pool_operations() {
let mut pool = LiquidityPool::new(
"pool1".to_string(),
ChainId::nac(),
"XTZH".to_string(),
1000,
);
// 锁定
pool.lock(300).unwrap();
assert_eq!(pool.locked_amount, 300);
assert_eq!(pool.available_amount, 700);
// 解锁
pool.unlock(100).unwrap();
assert_eq!(pool.locked_amount, 200);
assert_eq!(pool.available_amount, 800);
// 添加流动性
pool.add_liquidity(500);
assert_eq!(pool.total_liquidity, 1500);
assert_eq!(pool.available_amount, 1300);
}
#[test]
fn test_insufficient_liquidity() {
let mut pool = LiquidityPool::new(
"pool1".to_string(),
ChainId::nac(),
"XTZH".to_string(),
100,
);
let result = pool.lock(200);
assert!(result.is_err());
}
}