NAC_Blockchain/nvm_v2/nvm-l0/src/vm_integration.rs

342 lines
9.5 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.

// 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<Hash, String> {
// 验证交易
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<Block, String> {
// 获取待处理交易
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);
}
}