// NVM-L0 交易定义和交易池 use crate::types::{Address, Hash, Signature}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; /// 交易类型 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum TransactionType { /// 转账 Transfer, /// 合约部署 ContractDeploy, /// 合约调用 ContractCall, } /// 交易 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Transaction { /// 交易哈希 pub hash: Hash, /// 发送方 pub from: Address, /// 接收方 pub to: Address, /// 金额 pub value: u128, /// Nonce pub nonce: u64, /// Gas限制 pub gas_limit: u64, /// Gas价格 pub gas_price: u64, /// 数据 pub data: Vec, /// 交易类型 pub tx_type: TransactionType, /// 签名 pub signature: Signature, /// 时间戳 pub timestamp: u64, } impl Transaction { /// 创建新交易 pub fn new( from: Address, to: Address, value: u128, nonce: u64, gas_limit: u64, gas_price: u64, data: Vec, tx_type: TransactionType, ) -> Self { let mut tx = Self { hash: Hash::zero(), from, to, value, nonce, gas_limit, gas_price, data, tx_type, signature: Signature::empty(), timestamp: 0, }; tx.hash = tx.calculate_hash(); tx } /// 计算交易哈希 pub fn calculate_hash(&self) -> Hash { let mut data = Vec::new(); data.extend_from_slice(self.from.as_bytes()); data.extend_from_slice(self.to.as_bytes()); data.extend_from_slice(&self.value.to_le_bytes()); data.extend_from_slice(&self.nonce.to_le_bytes()); data.extend_from_slice(&self.gas_limit.to_le_bytes()); data.extend_from_slice(&self.gas_price.to_le_bytes()); data.extend_from_slice(&self.data); Hash::sha3_384(&data) } /// 签名交易 pub fn sign(&mut self, signature: Signature) { self.signature = signature; } /// 验证签名 pub fn verify_signature(&self) -> bool { self.signature.verify(self.hash.as_bytes(), &[]) } /// 计算交易费用 pub fn calculate_fee(&self) -> u64 { self.gas_limit * self.gas_price } } /// 交易池 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct TransactionPool { /// 待处理交易 (hash -> transaction) pending: HashMap, /// 已确认交易 confirmed: HashMap, /// 最大交易数 max_size: usize, } impl TransactionPool { /// 创建新交易池 pub fn new(max_size: usize) -> Self { Self { pending: HashMap::new(), confirmed: HashMap::new(), max_size, } } /// 添加交易 pub fn add_transaction(&mut self, tx: Transaction) -> Result<(), String> { if self.pending.len() >= self.max_size { return Err("Transaction pool is full".to_string()); } if self.pending.contains_key(&tx.hash) || self.confirmed.contains_key(&tx.hash) { return Err("Transaction already exists".to_string()); } if !tx.verify_signature() { return Err("Invalid signature".to_string()); } self.pending.insert(tx.hash, tx); Ok(()) } /// 获取待处理交易 pub fn get_pending_transactions(&self) -> Vec { self.pending.values().cloned().collect() } /// 确认交易 pub fn confirm_transaction(&mut self, hash: &Hash) -> Result<(), String> { let tx = self .pending .remove(hash) .ok_or("Transaction not found in pending pool")?; self.confirmed.insert(*hash, tx); Ok(()) } /// 移除交易 pub fn remove_transaction(&mut self, hash: &Hash) { self.pending.remove(hash); } /// 获取交易 pub fn get_transaction(&self, hash: &Hash) -> Option<&Transaction> { self.pending.get(hash).or_else(|| self.confirmed.get(hash)) } /// 获取待处理交易数量 pub fn pending_count(&self) -> usize { self.pending.len() } /// 获取已确认交易数量 pub fn confirmed_count(&self) -> usize { self.confirmed.len() } /// 清理已确认交易 pub fn clear_confirmed(&mut self) { self.confirmed.clear(); } } impl Default for TransactionPool { fn default() -> Self { Self::new(10000) } } #[cfg(test)] mod tests { use super::*; fn create_test_transaction() -> Transaction { Transaction::new( Address::new([1u8; 32]), Address::new([2u8; 32]), 1000, 1, 21000, 1, Vec::new(), TransactionType::Transfer, ) } #[test] fn test_transaction_creation() { let tx = create_test_transaction(); assert_eq!(tx.value, 1000); assert_eq!(tx.nonce, 1); } #[test] fn test_transaction_hash() { let tx = create_test_transaction(); let hash1 = tx.calculate_hash(); let hash2 = tx.calculate_hash(); assert_eq!(hash1, hash2); } #[test] fn test_transaction_pool_add() { let mut pool = TransactionPool::new(100); let mut tx = create_test_transaction(); tx.sign(Signature::new(vec![1, 2, 3])); assert!(pool.add_transaction(tx).is_ok()); assert_eq!(pool.pending_count(), 1); } #[test] fn test_transaction_pool_confirm() { let mut pool = TransactionPool::new(100); let mut tx = create_test_transaction(); tx.sign(Signature::new(vec![1, 2, 3])); let hash = tx.hash; pool.add_transaction(tx).unwrap(); assert!(pool.confirm_transaction(&hash).is_ok()); assert_eq!(pool.pending_count(), 0); assert_eq!(pool.confirmed_count(), 1); } #[test] fn test_transaction_pool_full() { let mut pool = TransactionPool::new(1); let mut tx1 = create_test_transaction(); tx1.sign(Signature::new(vec![1, 2, 3])); let mut tx2 = create_test_transaction(); tx2.nonce = 2; tx2.hash = tx2.calculate_hash(); tx2.sign(Signature::new(vec![4, 5, 6])); assert!(pool.add_transaction(tx1).is_ok()); assert!(pool.add_transaction(tx2).is_err()); } }