Fixing all tests. Changing memory to U256. Fixing tier_step_gas
This commit is contained in:
parent
263936145d
commit
23cae6607a
@ -42,7 +42,7 @@ impl<S : fmt::Display> Stack<S> for Vec<S> {
|
|||||||
|
|
||||||
fn pop_back(&mut self) -> S {
|
fn pop_back(&mut self) -> S {
|
||||||
let val = self.pop();
|
let val = self.pop();
|
||||||
println!("Popping from slide.");
|
println!("Popping from stack.");
|
||||||
match val {
|
match val {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => panic!("Tried to pop from empty stack.")
|
None => panic!("Tried to pop from empty stack.")
|
||||||
@ -51,7 +51,7 @@ impl<S : fmt::Display> Stack<S> for Vec<S> {
|
|||||||
|
|
||||||
fn pop_n(&mut self, no_of_elems: usize) -> Vec<S> {
|
fn pop_n(&mut self, no_of_elems: usize) -> Vec<S> {
|
||||||
let mut vec = Vec::new();
|
let mut vec = Vec::new();
|
||||||
for i in 1..no_of_elems {
|
for _i in 1..no_of_elems+1 {
|
||||||
vec.push(self.pop_back());
|
vec.push(self.pop_back());
|
||||||
}
|
}
|
||||||
vec
|
vec
|
||||||
@ -72,13 +72,15 @@ trait Memory {
|
|||||||
fn size(&self) -> usize;
|
fn size(&self) -> usize;
|
||||||
/// Resize (shrink or expand) the memory to specified size (fills 0)
|
/// Resize (shrink or expand) the memory to specified size (fills 0)
|
||||||
fn resize(&mut self, new_size: usize);
|
fn resize(&mut self, new_size: usize);
|
||||||
|
/// Resize the memory only if its smaller
|
||||||
|
fn expand(&mut self, new_size: U256);
|
||||||
/// Write single byte to memory
|
/// Write single byte to memory
|
||||||
fn write_byte(&mut self, offset: U256, value: U256);
|
fn write_byte(&mut self, offset: U256, value: U256);
|
||||||
/// Write a word from memory
|
/// Write a word to memory. Does not resize memory!
|
||||||
fn write(&mut self, offset: U256, value: U256);
|
fn write(&mut self, offset: U256, value: U256);
|
||||||
/// Read a word from memory
|
/// Read a word from memory
|
||||||
fn read(&self, offset: U256) -> u32;
|
fn read(&self, offset: U256) -> U256;
|
||||||
/// Write slice of bytes to memory
|
/// Write slice of bytes to memory. Does not resize memory!
|
||||||
fn write_slice(&mut self, offset: U256, &[u8]);
|
fn write_slice(&mut self, offset: U256, &[u8]);
|
||||||
/// Retrieve part of the memory between offset and offset + size
|
/// Retrieve part of the memory between offset and offset + size
|
||||||
fn read_slice(&self, offset: U256, size: U256) -> &[u8];
|
fn read_slice(&self, offset: U256, size: U256) -> &[u8];
|
||||||
@ -94,12 +96,12 @@ impl Memory for Vec<u8> {
|
|||||||
&self[init_off..init_off + init_size]
|
&self[init_off..init_off + init_size]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read(&self, offset: U256) -> u32 {
|
fn read(&self, offset: U256) -> U256 {
|
||||||
let off = offset.low_u64() as usize;
|
let off = offset.low_u64() as usize;
|
||||||
let mut val : u32 = 0;
|
let mut val = U256::zero();
|
||||||
for pos in off..off+4 {
|
for pos in off..off+32 {
|
||||||
val = val << 8;
|
val = val << 8;
|
||||||
val = val | (self[pos] as u32);
|
val = val | U256::from(self[pos] as u8);
|
||||||
}
|
}
|
||||||
val
|
val
|
||||||
}
|
}
|
||||||
@ -109,18 +111,20 @@ impl Memory for Vec<u8> {
|
|||||||
|
|
||||||
// TODO [todr] Optimize?
|
// TODO [todr] Optimize?
|
||||||
for pos in off..off+slice.len() {
|
for pos in off..off+slice.len() {
|
||||||
|
println!("Writing {:x}", slice[pos - off]);
|
||||||
self[pos] = slice[pos - off];
|
self[pos] = slice[pos - off];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&mut self, offset: U256, value: U256) {
|
fn write(&mut self, offset: U256, value: U256) {
|
||||||
let off = offset.low_u64() as usize;
|
let off = offset.low_u64() as usize;
|
||||||
let mut val = value.low_u64() as u32;
|
let mut val = value;
|
||||||
|
|
||||||
self[off] = (val >> 24) as u8;
|
let end = off + 32;
|
||||||
self[off+1] = (val >> 16) as u8;
|
for pos in off..end {
|
||||||
self[off+2] = (val >> 8) as u8;
|
self[end - pos - 1] = (val & U256::from(0xff)).low_u64() as u8;
|
||||||
self[off+3] = (val & 0xff) as u8;
|
val = val >> 8;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_byte(&mut self, offset: U256, value: U256) {
|
fn write_byte(&mut self, offset: U256, value: U256) {
|
||||||
@ -132,6 +136,13 @@ impl Memory for Vec<u8> {
|
|||||||
fn resize(&mut self, new_size: usize) {
|
fn resize(&mut self, new_size: usize) {
|
||||||
self.resize(new_size, 0);
|
self.resize(new_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn expand(&mut self, new_size: U256) {
|
||||||
|
let size = new_size.low_u64() as usize;
|
||||||
|
if size > self.len() {
|
||||||
|
Memory::resize(self, size)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Abstraction over raw vector of Bytes. Easier state management of PC.
|
/// Abstraction over raw vector of Bytes. Easier state management of PC.
|
||||||
@ -194,7 +205,7 @@ impl evm::Evm for Interpreter {
|
|||||||
reader.position += 1;
|
reader.position += 1;
|
||||||
|
|
||||||
// Calculate gas cost
|
// Calculate gas cost
|
||||||
let gas_cost = try!(self.get_gas_cost(ext, instruction, Memory::size(&mem), &stack));
|
let gas_cost = try!(self.get_gas_cost_and_expand_mem(ext, instruction, &mut mem, &stack));
|
||||||
try!(self.verify_gas(¤t_gas, &gas_cost));
|
try!(self.verify_gas(¤t_gas, &gas_cost));
|
||||||
current_gas = current_gas - gas_cost;
|
current_gas = current_gas - gas_cost;
|
||||||
println!("Gas cost: {} (left: {})", gas_cost, current_gas);
|
println!("Gas cost: {} (left: {})", gas_cost, current_gas);
|
||||||
@ -229,10 +240,10 @@ impl evm::Evm for Interpreter {
|
|||||||
|
|
||||||
impl Interpreter {
|
impl Interpreter {
|
||||||
|
|
||||||
fn get_gas_cost(&self,
|
fn get_gas_cost_and_expand_mem(&self,
|
||||||
ext: &evm::Ext,
|
ext: &evm::Ext,
|
||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
current_mem_size: usize,
|
mem: &mut Memory,
|
||||||
stack: &Stack<U256>
|
stack: &Stack<U256>
|
||||||
) -> evm::Result {
|
) -> evm::Result {
|
||||||
|
|
||||||
@ -335,12 +346,14 @@ impl Interpreter {
|
|||||||
InstructionCost::Gas(gas) => {
|
InstructionCost::Gas(gas) => {
|
||||||
Ok(gas)
|
Ok(gas)
|
||||||
},
|
},
|
||||||
InstructionCost::GasMem(gas, mem) => {
|
InstructionCost::GasMem(gas, mem_size) => {
|
||||||
let mem_gas = self.mem_gas_cost(schedule, current_mem_size, &mem);
|
mem.expand(mem_size);
|
||||||
|
let mem_gas = self.mem_gas_cost(schedule, mem.size(), &mem_size);
|
||||||
Ok(gas + mem_gas)
|
Ok(gas + mem_gas)
|
||||||
},
|
},
|
||||||
InstructionCost::GasMemCopy(gas, mem, copy) => {
|
InstructionCost::GasMemCopy(gas, mem_size, copy) => {
|
||||||
let mem_gas = self.mem_gas_cost(schedule, current_mem_size, &mem);
|
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));
|
let copy_gas = U256::from(schedule.copy_gas) * (add_u256_usize(©, 31) / U256::from(32));
|
||||||
Ok(gas + copy_gas + mem_gas)
|
Ok(gas + copy_gas + mem_gas)
|
||||||
}
|
}
|
||||||
@ -456,7 +469,6 @@ impl Interpreter {
|
|||||||
ext.log(topics, mem.read_slice(offset, size));
|
ext.log(topics, mem.read_slice(offset, size));
|
||||||
},
|
},
|
||||||
instructions::PUSH1...instructions::PUSH32 => {
|
instructions::PUSH1...instructions::PUSH32 => {
|
||||||
// Load to stack
|
|
||||||
let bytes = instructions::get_push_bytes(instruction);
|
let bytes = instructions::get_push_bytes(instruction);
|
||||||
let val = code.read(bytes);
|
let val = code.read(bytes);
|
||||||
stack.push(val);
|
stack.push(val);
|
||||||
@ -517,7 +529,12 @@ impl Interpreter {
|
|||||||
instructions::CALLVALUE => {
|
instructions::CALLVALUE => {
|
||||||
stack.push(params.value.clone());
|
stack.push(params.value.clone());
|
||||||
},
|
},
|
||||||
// instructions::CALLDATALOAD
|
instructions::CALLDATALOAD => {
|
||||||
|
let id = stack.pop_back().low_u64() as usize;
|
||||||
|
let mut v = params.data[id..id+32].to_vec();
|
||||||
|
v.resize(32, 0);
|
||||||
|
stack.push(U256::from(&v[..]))
|
||||||
|
},
|
||||||
instructions::CALLDATASIZE => {
|
instructions::CALLDATASIZE => {
|
||||||
stack.push(U256::from(params.data.len()));
|
stack.push(U256::from(params.data.len()));
|
||||||
},
|
},
|
||||||
@ -538,6 +555,9 @@ impl Interpreter {
|
|||||||
instructions::EXTCODECOPY => {
|
instructions::EXTCODECOPY => {
|
||||||
let address = u256_to_address(&stack.pop_back());
|
let address = u256_to_address(&stack.pop_back());
|
||||||
let code = ext.extcode(&address);
|
let code = ext.extcode(&address);
|
||||||
|
for b in &code {
|
||||||
|
println!("Code: {:x}", b);
|
||||||
|
}
|
||||||
self.copy_data_to_memory(mem, stack, &code);
|
self.copy_data_to_memory(mem, stack, &code);
|
||||||
},
|
},
|
||||||
instructions::GASPRICE => {
|
instructions::GASPRICE => {
|
||||||
@ -578,7 +598,7 @@ impl Interpreter {
|
|||||||
let index = stack.pop_back().low_u64() as usize;
|
let index = stack.pop_back().low_u64() as usize;
|
||||||
let size = stack.pop_back().low_u64() as usize;
|
let size = stack.pop_back().low_u64() as usize;
|
||||||
|
|
||||||
mem.write_slice(offset, &data[index..size]);
|
mem.write_slice(offset, &data[index..index+size]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify_instructions_requirements(&self,
|
fn verify_instructions_requirements(&self,
|
||||||
@ -776,27 +796,27 @@ mod tests {
|
|||||||
fn test_memory_read_and_write() {
|
fn test_memory_read_and_write() {
|
||||||
// given
|
// given
|
||||||
let mem : &mut super::Memory = &mut vec![];
|
let mem : &mut super::Memory = &mut vec![];
|
||||||
mem.resize(4);
|
mem.resize(32);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
mem.write(U256::from(0x00), U256::from(0xabcdef));
|
mem.write(U256::from(0x00), U256::from(0xabcdef));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(mem.read(U256::from(0x00)), 0xabcdef);
|
assert_eq!(mem.read(U256::from(0x00)), U256::from(0xabcdef));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_memory_read_and_write_byte() {
|
fn test_memory_read_and_write_byte() {
|
||||||
// given
|
// given
|
||||||
let mem : &mut super::Memory = &mut vec![];
|
let mem : &mut super::Memory = &mut vec![];
|
||||||
mem.resize(4);
|
mem.resize(32);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
mem.write_byte(U256::from(0x01), U256::from(0xab));
|
mem.write_byte(U256::from(0x1d), U256::from(0xab));
|
||||||
mem.write_byte(U256::from(0x02), U256::from(0xcd));
|
mem.write_byte(U256::from(0x1e), U256::from(0xcd));
|
||||||
mem.write_byte(U256::from(0x03), U256::from(0xef));
|
mem.write_byte(U256::from(0x1f), U256::from(0xef));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assert_eq!(mem.read(U256::from(0x00)), 0xabcdef);
|
assert_eq!(mem.read(U256::from(0x00)), U256::from(0xabcdef));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ impl Schedule {
|
|||||||
exceptional_failed_code_deposit: efcd,
|
exceptional_failed_code_deposit: efcd,
|
||||||
have_delegate_call: hdc,
|
have_delegate_call: hdc,
|
||||||
stack_limit: 1024,
|
stack_limit: 1024,
|
||||||
tier_step_gas: [0usize, 2, 3, 4, 5, 6, 10, 20],
|
tier_step_gas: [0usize, 2, 3, 5, 8, 10, 20, 0],
|
||||||
exp_gas: 10,
|
exp_gas: 10,
|
||||||
exp_byte_gas: 10,
|
exp_byte_gas: 10,
|
||||||
sha3_gas: 30,
|
sha3_gas: 30,
|
||||||
|
Loading…
Reference in New Issue
Block a user