// NVM-L1 合约执行器 use crate::contract::Contract; use crate::gas::{GasError, GasMeter}; use crate::state::StateManager; use crate::types::{Address, Hash}; use serde::{Deserialize, Serialize}; /// 执行上下文 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionContext { /// 调用者地址 pub caller: Address, /// 合约地址 pub contract_address: Address, /// 交易发起者 pub origin: Address, /// Gas价格 pub gas_price: u64, /// 区块号 pub block_number: u64, /// 区块时间戳 pub block_timestamp: u64, /// 调用数据 pub call_data: Vec, /// 调用值 pub call_value: u128, } impl ExecutionContext { /// 创建新的执行上下文 pub fn new( caller: Address, contract_address: Address, origin: Address, call_data: Vec, call_value: u128, ) -> Self { Self { caller, contract_address, origin, gas_price: 1, block_number: 0, block_timestamp: 0, call_data, call_value, } } } /// 执行结果 #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExecutionResult { /// 是否成功 pub success: bool, /// 返回数据 pub return_data: Vec, /// 使用的Gas pub gas_used: u64, /// 错误信息 pub error: Option, /// 状态变更 pub state_changes: Vec, } /// 状态变更 #[derive(Debug, Clone, Serialize, Deserialize)] pub enum StateChange { /// 余额变更 BalanceChange { address: Address, old_balance: u128, new_balance: u128, }, /// 存储变更 StorageChange { address: Address, key: Hash, old_value: Option>, new_value: Vec, }, /// 合约创建 ContractCreation { address: Address, code_hash: Hash, }, /// 合约销毁 ContractDestruction { address: Address, }, } /// 执行错误 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum ExecutionError { /// Gas相关错误 Gas(GasError), /// 合约不存在 ContractNotFound, /// 合约已暂停 ContractPaused, /// 合约已销毁 ContractDestroyed, /// 余额不足 InsufficientBalance, /// 调用深度超限 CallDepthExceeded, /// 无效操作码 InvalidOpcode(u8), /// 栈溢出 StackOverflow, /// 栈下溢 StackUnderflow, /// 内存访问越界 MemoryAccessOutOfBounds, /// 除零错误 DivisionByZero, /// 其他错误 Other(String), } impl From for ExecutionError { fn from(error: GasError) -> Self { ExecutionError::Gas(error) } } /// 简化的操作码 #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Opcode { /// 停止执行 STOP = 0x00, /// 加法 ADD = 0x01, /// 乘法 MUL = 0x02, /// 减法 SUB = 0x03, /// 除法 DIV = 0x04, /// 模运算 MOD = 0x05, /// 压栈 PUSH1 = 0x60, /// 弹栈 POP = 0x50, /// 存储写入 SSTORE = 0x55, /// 存储读取 SLOAD = 0x54, /// 返回 RETURN = 0xf3, } impl Opcode { /// 从字节转换为操作码 pub fn from_byte(byte: u8) -> Option { match byte { 0x00 => Some(Opcode::STOP), 0x01 => Some(Opcode::ADD), 0x02 => Some(Opcode::MUL), 0x03 => Some(Opcode::SUB), 0x04 => Some(Opcode::DIV), 0x05 => Some(Opcode::MOD), 0x50 => Some(Opcode::POP), 0x54 => Some(Opcode::SLOAD), 0x55 => Some(Opcode::SSTORE), 0x60 => Some(Opcode::PUSH1), 0xf3 => Some(Opcode::RETURN), _ => None, } } } /// 合约执行器 #[derive(Debug)] pub struct ContractExecutor { /// 状态管理器 state_manager: StateManager, /// 调用栈深度限制 #[allow(dead_code)] max_call_depth: usize, /// 栈大小限制 max_stack_size: usize, } impl ContractExecutor { /// 创建新的合约执行器 pub fn new() -> Self { Self { state_manager: StateManager::new(), max_call_depth: 1024, max_stack_size: 1024, } } /// 获取状态管理器 pub fn state_manager(&self) -> &StateManager { &self.state_manager } /// 获取可变状态管理器 pub fn state_manager_mut(&mut self) -> &mut StateManager { &mut self.state_manager } /// 执行合约调用 pub fn call( &mut self, context: ExecutionContext, gas_limit: u64, ) -> ExecutionResult { let mut gas_meter = GasMeter::new(gas_limit); let state_changes = Vec::new(); // 创建状态快照 self.state_manager.snapshot(); // 消耗基础调用Gas if let Err(e) = gas_meter.consume_contract_call_gas() { return ExecutionResult { success: false, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: Some(format!("Gas error: {:?}", e)), state_changes, }; } // 获取合约 let contract = match self.state_manager.current_state().get_contract(&context.contract_address) { Some(contract) => contract.clone(), None => { return ExecutionResult { success: false, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: Some("Contract not found".to_string()), state_changes, }; } }; // 检查合约状态 if !contract.is_active() { return ExecutionResult { success: false, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: Some("Contract is not active".to_string()), state_changes, }; } // 执行字节码 match self.execute_bytecode(&contract, &context, &mut gas_meter) { Ok(return_data) => { self.state_manager.commit(); ExecutionResult { success: true, return_data, gas_used: gas_meter.gas_used(), error: None, state_changes, } } Err(e) => { self.state_manager.revert().ok(); ExecutionResult { success: false, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: Some(format!("{:?}", e)), state_changes, } } } } /// 部署合约 pub fn deploy( &mut self, contract: Contract, gas_limit: u64, ) -> ExecutionResult { let mut gas_meter = GasMeter::new(gas_limit); let mut state_changes = Vec::new(); // 消耗合约创建Gas if let Err(e) = gas_meter.consume_contract_creation_gas() { return ExecutionResult { success: false, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: Some(format!("Gas error: {:?}", e)), state_changes, }; } // 部署合约 match self.state_manager.current_state_mut().deploy_contract(contract.clone()) { Ok(()) => { state_changes.push(StateChange::ContractCreation { address: contract.address, code_hash: *contract.code.code_hash(), }); ExecutionResult { success: true, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: None, state_changes, } } Err(e) => ExecutionResult { success: false, return_data: Vec::new(), gas_used: gas_meter.gas_used(), error: Some(e), state_changes, }, } } /// 执行字节码(简化版本) fn execute_bytecode( &mut self, contract: &Contract, context: &ExecutionContext, gas_meter: &mut GasMeter, ) -> Result, ExecutionError> { let bytecode = contract.code.bytecode(); let mut pc = 0; // 程序计数器 let mut stack: Vec = Vec::new(); let mut memory = Vec::new(); while pc < bytecode.len() { let opcode_byte = bytecode[pc]; let opcode = Opcode::from_byte(opcode_byte) .ok_or(ExecutionError::InvalidOpcode(opcode_byte))?; // 消耗计算Gas gas_meter.consume_compute_gas(1)?; match opcode { Opcode::STOP => break, Opcode::ADD => { if stack.len() < 2 { return Err(ExecutionError::StackUnderflow); } let b = stack.pop().unwrap(); let a = stack.pop().unwrap(); stack.push(a.wrapping_add(b)); } Opcode::SUB => { if stack.len() < 2 { return Err(ExecutionError::StackUnderflow); } let b = stack.pop().unwrap(); let a = stack.pop().unwrap(); stack.push(a.wrapping_sub(b)); } Opcode::MUL => { if stack.len() < 2 { return Err(ExecutionError::StackUnderflow); } let b = stack.pop().unwrap(); let a = stack.pop().unwrap(); stack.push(a.wrapping_mul(b)); } Opcode::DIV => { if stack.len() < 2 { return Err(ExecutionError::StackUnderflow); } let b = stack.pop().unwrap(); let a = stack.pop().unwrap(); if b == 0 { return Err(ExecutionError::DivisionByZero); } stack.push(a / b); } Opcode::PUSH1 => { if pc + 1 >= bytecode.len() { return Err(ExecutionError::Other("Invalid PUSH1".to_string())); } pc += 1; let value = bytecode[pc] as u64; stack.push(value); } Opcode::POP => { if stack.is_empty() { return Err(ExecutionError::StackUnderflow); } stack.pop(); } Opcode::SLOAD => { if stack.is_empty() { return Err(ExecutionError::StackUnderflow); } let key_bytes = stack.pop().unwrap().to_le_bytes(); let mut key_array = [0u8; 48]; key_array[..8].copy_from_slice(&key_bytes); let key = Hash::new(key_array); gas_meter.consume_storage_read_gas(32)?; let value = self.state_manager .current_state() .get_storage(&context.contract_address, &key) .unwrap_or_default(); let value_u64 = if value.len() >= 8 { u64::from_le_bytes([ value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], ]) } else { 0 }; stack.push(value_u64); } Opcode::SSTORE => { if stack.len() < 2 { return Err(ExecutionError::StackUnderflow); } let value = stack.pop().unwrap(); let key_bytes = stack.pop().unwrap().to_le_bytes(); let mut key_array = [0u8; 48]; key_array[..8].copy_from_slice(&key_bytes); let key = Hash::new(key_array); gas_meter.consume_storage_write_gas(32)?; let value_bytes = value.to_le_bytes().to_vec(); self.state_manager .current_state_mut() .set_storage(&context.contract_address, key, value_bytes); } Opcode::RETURN => { if stack.len() < 2 { return Err(ExecutionError::StackUnderflow); } let size = stack.pop().unwrap() as usize; let offset = stack.pop().unwrap() as usize; if offset + size > memory.len() { memory.resize(offset + size, 0); gas_meter.consume_memory_expansion_gas(offset + size - memory.len())?; } return Ok(memory[offset..offset + size].to_vec()); } _ => { return Err(ExecutionError::InvalidOpcode(opcode_byte)); } } if stack.len() > self.max_stack_size { return Err(ExecutionError::StackOverflow); } pc += 1; } Ok(Vec::new()) } } impl Default for ContractExecutor { fn default() -> Self { Self::new() } } #[cfg(test)] mod tests { use super::*; use crate::contract::{ContractCode, ContractMetadata}; fn create_test_executor() -> ContractExecutor { ContractExecutor::new() } fn create_test_contract() -> Contract { let address = Address::new([1u8; 20]); let owner = Address::new([2u8; 20]); // 简单的字节码: PUSH1 42, PUSH1 0, SSTORE, STOP let bytecode = vec![0x60, 42, 0x60, 0, 0x55, 0x00]; let code = ContractCode::new(bytecode); let metadata = ContractMetadata::default(); Contract::new(address, code, owner, metadata) } #[test] fn test_contract_deployment() { let mut executor = create_test_executor(); let contract = create_test_contract(); let result = executor.deploy(contract, 100000); assert!(result.success); } #[test] fn test_contract_call() { let mut executor = create_test_executor(); let contract = create_test_contract(); let address = contract.address; // 先部署合约 executor.deploy(contract, 100000); // 调用合约 let context = ExecutionContext::new( Address::new([3u8; 20]), address, Address::new([3u8; 20]), Vec::new(), 0, ); let result = executor.call(context, 100000); assert!(result.success); } #[test] fn test_opcode_execution() { let opcode = Opcode::from_byte(0x01); assert_eq!(opcode, Some(Opcode::ADD)); let invalid_opcode = Opcode::from_byte(0xff); assert_eq!(invalid_opcode, None); } }