// NVM-L0 虚拟机集成层 // 将L0和L1层整合,提供统一的虚拟机接口 use crate::block::{Block, BlockHeader}; use crate::consensus::{ConsensusEngine, DagConsensus}; use crate::state_tree::StateTree; use crate::transaction::{Transaction, TransactionPool}; use crate::types::{Address, Hash}; use serde::{Deserialize, Serialize}; /// 虚拟机配置 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct VMConfig { /// 区块Gas限制 pub block_gas_limit: u64, /// 交易池大小 pub tx_pool_size: usize, /// 共识难度 pub consensus_difficulty: u64, /// 区块时间(秒) pub block_time: u64, } impl Default for VMConfig { fn default() -> Self { Self { block_gas_limit: 10_000_000, tx_pool_size: 10_000, consensus_difficulty: 1000, block_time: 6, } } } /// NVM虚拟机 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct NVM { /// 配置 config: VMConfig, /// 状态树 state: StateTree, /// 交易池 tx_pool: TransactionPool, /// 共识引擎 consensus: DagConsensus, /// 当前区块号 current_block: u64, /// 最新区块哈希 latest_block_hash: Hash, } impl NVM { /// 创建新的虚拟机实例 pub fn new(config: VMConfig) -> Self { Self { tx_pool: TransactionPool::new(config.tx_pool_size), consensus: DagConsensus::new(config.consensus_difficulty), config, state: StateTree::new(), current_block: 0, latest_block_hash: Hash::zero(), } } /// 使用默认配置创建 pub fn with_defaults() -> Self { Self::new(VMConfig::default()) } /// 提交交易到交易池 pub fn submit_transaction(&mut self, tx: Transaction) -> Result { // 验证交易 if !tx.verify_signature() { return Err("Invalid transaction signature".to_string()); } // 检查余额 let balance = self.state.get_balance(&tx.from); let total_cost = tx.value + (tx.gas_limit * tx.gas_price) as u128; if balance < total_cost { return Err("Insufficient balance".to_string()); } // 检查nonce let expected_nonce = self.state.get_nonce(&tx.from); if tx.nonce != expected_nonce { return Err(format!( "Invalid nonce: expected {}, got {}", expected_nonce, tx.nonce )); } let hash = tx.hash; self.tx_pool.add_transaction(tx)?; Ok(hash) } /// 生成新区块 pub fn produce_block(&mut self, miner: Address) -> Result { // 获取待处理交易 let transactions = self.tx_pool.get_pending_transactions(); if transactions.is_empty() { return Err("No pending transactions".to_string()); } // 创建区块头 let header = BlockHeader { number: self.current_block + 1, timestamp: self.get_current_timestamp(), parent_hash: self.latest_block_hash, state_root: self.state.root_hash(), tx_root: self.calculate_tx_root(&transactions), miner, }; // 创建区块 let block = Block::new(header, transactions.clone()); // 验证区块 if !self.consensus.validate_block(&block) { return Err("Block validation failed".to_string()); } // 执行交易 self.execute_transactions(&transactions)?; // 确认交易 for tx in &transactions { self.tx_pool.confirm_transaction(&tx.hash)?; } // 更新区块信息 self.current_block = block.header.number; self.latest_block_hash = block.hash; Ok(block) } /// 执行交易列表 fn execute_transactions(&mut self, transactions: &[Transaction]) -> Result<(), String> { for tx in transactions { self.execute_transaction(tx)?; } Ok(()) } /// 执行单个交易 fn execute_transaction(&mut self, tx: &Transaction) -> Result<(), String> { // 扣除Gas费用 let gas_cost = (tx.gas_limit * tx.gas_price) as u128; self.state.sub_balance(tx.from, gas_cost)?; // 执行转账 if tx.value > 0 { self.state.transfer(tx.from, tx.to, tx.value)?; } // 增加nonce self.state.increment_nonce(tx.from); Ok(()) } /// 计算交易根哈希 fn calculate_tx_root(&self, transactions: &[Transaction]) -> Hash { if transactions.is_empty() { return Hash::zero(); } let mut data = Vec::new(); for tx in transactions { data.extend_from_slice(tx.hash.as_bytes()); } Hash::sha3_384(&data) } /// 获取当前时间戳 fn get_current_timestamp(&self) -> u64 { use std::time::{SystemTime, UNIX_EPOCH}; SystemTime::now() .duration_since(UNIX_EPOCH) .expect("mainnet: handle error") .as_secs() } /// 获取账户余额 pub fn get_balance(&self, address: &Address) -> u128 { self.state.get_balance(address) } /// 获取账户nonce pub fn get_nonce(&self, address: &Address) -> u64 { self.state.get_nonce(address) } /// 获取当前区块号 pub fn get_block_number(&self) -> u64 { self.current_block } /// 获取状态根哈希 pub fn get_state_root(&self) -> Hash { self.state.root_hash() } /// 获取待处理交易数量 pub fn pending_transaction_count(&self) -> usize { self.tx_pool.pending_count() } /// 设置账户余额(仅用于测试) #[cfg(test)] pub fn set_balance(&mut self, address: Address, balance: u128) { self.state.set_balance(address, balance); } } #[cfg(test)] mod tests { use super::*; use crate::transaction::TransactionType; use crate::types::Signature; fn create_test_vm() -> NVM { NVM::with_defaults() } fn create_test_transaction(from: Address, to: Address, value: u128, nonce: u64) -> Transaction { let mut tx = Transaction::new( from, to, value, nonce, 21000, 1, Vec::new(), TransactionType::Transfer, ); tx.sign(Signature::new(vec![1, 2, 3])); tx } #[test] fn test_vm_creation() { let vm = create_test_vm(); assert_eq!(vm.get_block_number(), 0); } #[test] fn test_submit_transaction() { let mut vm = create_test_vm(); let from = Address::new([1u8; 32]); let to = Address::new([2u8; 32]); // 设置初始余额 vm.set_balance(from, 100000); let tx = create_test_transaction(from, to, 1000, 0); assert!(vm.submit_transaction(tx).is_ok()); assert_eq!(vm.pending_transaction_count(), 1); } #[test] fn test_insufficient_balance() { let mut vm = create_test_vm(); let from = Address::new([1u8; 32]); let to = Address::new([2u8; 32]); // 不设置余额 let tx = create_test_transaction(from, to, 1000, 0); assert!(vm.submit_transaction(tx).is_err()); } #[test] fn test_produce_block() { let mut vm = create_test_vm(); let from = Address::new([1u8; 32]); let to = Address::new([2u8; 32]); let miner = Address::new([3u8; 32]); // 设置初始余额 vm.set_balance(from, 100000); // 提交交易 let tx = create_test_transaction(from, to, 1000, 0); vm.submit_transaction(tx).expect("mainnet: handle error"); // 生成区块 let block = vm.produce_block(miner).expect("mainnet: handle error"); assert_eq!(block.header.number, 1); assert_eq!(block.transactions.len(), 1); // 验证余额变化 assert_eq!(vm.get_balance(&to), 1000); assert_eq!(vm.get_nonce(&from), 1); } #[test] fn test_invalid_nonce() { let mut vm = create_test_vm(); let from = Address::new([1u8; 32]); let to = Address::new([2u8; 32]); vm.set_balance(from, 100000); // 使用错误的nonce let tx = create_test_transaction(from, to, 1000, 5); assert!(vm.submit_transaction(tx).is_err()); } #[test] fn test_multiple_transactions() { let mut vm = create_test_vm(); let from = Address::new([1u8; 32]); let to1 = Address::new([2u8; 32]); let to2 = Address::new([3u8; 32]); let miner = Address::new([4u8; 32]); vm.set_balance(from, 100000); // 提交第一个交易 let tx1 = create_test_transaction(from, to1, 1000, 0); vm.submit_transaction(tx1).expect("mainnet: handle error"); // 生成第一个区块 let block1 = vm.produce_block(miner).expect("mainnet: handle error"); assert_eq!(block1.transactions.len(), 1); assert_eq!(vm.get_balance(&to1), 1000); assert_eq!(vm.get_nonce(&from), 1); // 现在nonce是1,可以提交第二个交易 let tx2 = create_test_transaction(from, to2, 2000, 1); vm.submit_transaction(tx2).expect("mainnet: handle error"); // 生成第二个区块 let block2 = vm.produce_block(miner).expect("mainnet: handle error"); assert_eq!(block2.transactions.len(), 1); assert_eq!(vm.get_balance(&to2), 2000); assert_eq!(vm.get_nonce(&from), 2); } }