Fixing memory cost calculation
This commit is contained in:
parent
f1ef2792e8
commit
eebcd0f35b
@ -262,8 +262,10 @@ impl Interpreter {
|
|||||||
let cost = match instruction {
|
let cost = match instruction {
|
||||||
instructions::SSTORE => {
|
instructions::SSTORE => {
|
||||||
let address = H256::from(stack.peek(0));
|
let address = H256::from(stack.peek(0));
|
||||||
|
let newval = stack.peek(1);
|
||||||
let val = U256::from(ext.sload(&address).as_slice());
|
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
|
schedule.sstore_set_gas
|
||||||
} else {
|
} else {
|
||||||
schedule.sstore_reset_gas
|
schedule.sstore_reset_gas
|
||||||
@ -310,7 +312,7 @@ impl Interpreter {
|
|||||||
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
InstructionCost::GasMem(gas, self.mem_needed(stack.peek(0), stack.peek(1)))
|
||||||
},
|
},
|
||||||
instructions::CALL | instructions::CALLCODE => {
|
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(
|
let mem = cmp::max(
|
||||||
self.mem_needed(stack.peek(5), stack.peek(6)),
|
self.mem_needed(stack.peek(5), stack.peek(6)),
|
||||||
self.mem_needed(stack.peek(3), stack.peek(4))
|
self.mem_needed(stack.peek(3), stack.peek(4))
|
||||||
@ -344,14 +346,16 @@ impl Interpreter {
|
|||||||
Ok(gas)
|
Ok(gas)
|
||||||
},
|
},
|
||||||
InstructionCost::GasMem(gas, mem_size) => {
|
InstructionCost::GasMem(gas, mem_size) => {
|
||||||
mem.expand(mem_size);
|
|
||||||
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &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)
|
Ok(gas + mem_gas)
|
||||||
},
|
},
|
||||||
InstructionCost::GasMemCopy(gas, mem_size, copy) => {
|
InstructionCost::GasMemCopy(gas, mem_size, copy) => {
|
||||||
mem.expand(mem_size);
|
|
||||||
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &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));
|
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)
|
Ok(gas + copy_gas + mem_gas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,13 +486,11 @@ impl Interpreter {
|
|||||||
},
|
},
|
||||||
instructions::LOG0...instructions::LOG4 => {
|
instructions::LOG0...instructions::LOG4 => {
|
||||||
let no_of_topics = instructions::get_log_topics(instruction);
|
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 offset = stack.pop_back();
|
||||||
let size = topics_data[1];
|
let size = stack.pop_back();
|
||||||
let topics = topics_data
|
let topics = stack.pop_n(no_of_topics)
|
||||||
.iter()
|
.iter()
|
||||||
.skip(2)
|
|
||||||
.map(H256::from)
|
.map(H256::from)
|
||||||
.collect();
|
.collect();
|
||||||
ext.log(topics, mem.read_slice(offset, size));
|
ext.log(topics, mem.read_slice(offset, size));
|
||||||
|
@ -684,7 +684,7 @@ mod tests {
|
|||||||
// 60 00 - push 0
|
// 60 00 - push 0
|
||||||
// f3 - return
|
// f3 - return
|
||||||
|
|
||||||
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
|
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0".from_hex().unwrap();
|
||||||
|
|
||||||
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
let address = contract_address(&sender, &U256::zero());
|
let address = contract_address(&sender, &U256::zero());
|
||||||
|
@ -9,14 +9,14 @@ use ethereum;
|
|||||||
|
|
||||||
struct TestEngine {
|
struct TestEngine {
|
||||||
spec: Spec,
|
spec: Spec,
|
||||||
stack_limit: usize
|
max_depth: usize
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestEngine {
|
impl TestEngine {
|
||||||
fn new(stack_limit: usize) -> TestEngine {
|
fn new(max_depth: usize) -> TestEngine {
|
||||||
TestEngine {
|
TestEngine {
|
||||||
spec: ethereum::new_frontier_test(),
|
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 spec(&self) -> &Spec { &self.spec }
|
||||||
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
|
fn schedule(&self, _env_info: &EnvInfo) -> Schedule {
|
||||||
let mut schedule = Schedule::new_frontier();
|
let mut schedule = Schedule::new_frontier();
|
||||||
schedule.stack_limit = self.stack_limit;
|
schedule.max_depth = self.max_depth;
|
||||||
schedule
|
schedule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ impl<'a> Ext for TestExt<'a> {
|
|||||||
});
|
});
|
||||||
Ok((gas_left, Some(address)))
|
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 => {
|
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));
|
let address = contract_address(&ext.params.address, &ext.state.nonce(&ext.params.address));
|
||||||
self.callcreates.push(CallCreate {
|
self.callcreates.push(CallCreate {
|
||||||
|
Loading…
Reference in New Issue
Block a user