From eebcd0f35badb06ad7329563a8265d9aaeee92b1 Mon Sep 17 00:00:00 2001 From: Tomusdrw Date: Thu, 14 Jan 2016 12:33:49 +0100 Subject: [PATCH] Fixing memory cost calculation --- src/evm/interpreter.rs | 30 ++++++++++++++++-------------- src/executive.rs | 2 +- src/tests/executive.rs | 10 +++++----- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/evm/interpreter.rs b/src/evm/interpreter.rs index e9ac7ebca..1bbf73d0a 100644 --- a/src/evm/interpreter.rs +++ b/src/evm/interpreter.rs @@ -235,11 +235,11 @@ impl evm::Evm for Interpreter { impl Interpreter { fn get_gas_cost_and_expand_mem(&self, - ext: &evm::Ext, - instruction: Instruction, - mem: &mut Memory, - stack: &Stack - ) -> evm::Result { + ext: &evm::Ext, + instruction: Instruction, + mem: &mut Memory, + stack: &Stack + ) -> evm::Result { let schedule = ext.schedule(); let info = instructions::get_info(instruction); @@ -262,8 +262,10 @@ impl Interpreter { let cost = match instruction { instructions::SSTORE => { let address = H256::from(stack.peek(0)); + let newval = stack.peek(1); let val = U256::from(ext.sload(&address).as_slice()); - let gas = if self.is_zero(&val) && !self.is_zero(stack.peek(1)) { + + let gas = if self.is_zero(&val) && !self.is_zero(newval) { schedule.sstore_set_gas } else { schedule.sstore_reset_gas @@ -310,7 +312,7 @@ impl Interpreter { InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1))) }, instructions::CALL | instructions::CALLCODE => { - let gas = add_u256_usize(stack.peek(0), schedule.call_gas + schedule.call_value_transfer_gas); + let gas = add_u256_usize(stack.peek(0), schedule.call_gas); let mem = cmp::max( self.mem_needed(stack.peek(5), stack.peek(6)), self.mem_needed(stack.peek(3), stack.peek(4)) @@ -344,14 +346,16 @@ impl Interpreter { Ok(gas) }, InstructionCost::GasMem(gas, mem_size) => { - mem.expand(mem_size); let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size); + // Expand after calculating the cost + mem.expand(mem_size); Ok(gas + mem_gas) }, InstructionCost::GasMemCopy(gas, mem_size, copy) => { - mem.expand(mem_size); let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size); let copy_gas = U256::from(schedule.copy_gas) * (add_u256_usize(©, 31) / U256::from(32)); + // Expand after calculating the cost + mem.expand(mem_size); Ok(gas + copy_gas + mem_gas) } } @@ -482,13 +486,11 @@ impl Interpreter { }, instructions::LOG0...instructions::LOG4 => { let no_of_topics = instructions::get_log_topics(instruction); - let topics_data = stack.pop_n(no_of_topics + 2); - let offset = topics_data[0]; - let size = topics_data[1]; - let topics = topics_data + let offset = stack.pop_back(); + let size = stack.pop_back(); + let topics = stack.pop_n(no_of_topics) .iter() - .skip(2) .map(H256::from) .collect(); ext.log(topics, mem.read_slice(offset, size)); diff --git a/src/executive.rs b/src/executive.rs index 5d0e3789a..370eb7c0b 100644 --- a/src/executive.rs +++ b/src/executive.rs @@ -684,7 +684,7 @@ mod tests { // 60 00 - push 0 // f3 - return - let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap(); + let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap(); let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap(); let address = contract_address(&sender, &U256::zero()); diff --git a/src/tests/executive.rs b/src/tests/executive.rs index 0a71aa3e4..d49ac5f8b 100644 --- a/src/tests/executive.rs +++ b/src/tests/executive.rs @@ -9,14 +9,14 @@ use ethereum; struct TestEngine { spec: Spec, - stack_limit: usize + max_depth: usize } impl TestEngine { - fn new(stack_limit: usize) -> TestEngine { + fn new(max_depth: usize) -> TestEngine { TestEngine { spec: ethereum::new_frontier_test(), - stack_limit: stack_limit + max_depth: max_depth } } } @@ -26,7 +26,7 @@ impl Engine for TestEngine { fn spec(&self) -> &Spec { &self.spec } fn schedule(&self, _env_info: &EnvInfo) -> Schedule { let mut schedule = Schedule::new_frontier(); - schedule.stack_limit = self.stack_limit; + schedule.max_depth = self.max_depth; schedule } } @@ -87,7 +87,7 @@ impl<'a> Ext for TestExt<'a> { }); Ok((gas_left, Some(address))) }, - // creation failed only due to reaching stack_limit + // creation failed only due to reaching max_depth Ok((gas_left, None)) if ext.state.balance(&ext.params.address) >= *value => { let address = contract_address(&ext.params.address, &ext.state.nonce(&ext.params.address)); self.callcreates.push(CallCreate {