Skip to content

Commit

Permalink
35 buffer tests now passing
Browse files Browse the repository at this point in the history
  • Loading branch information
max-wickham committed Mar 27, 2024
1 parent bdd80d2 commit c777a7d
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 26 deletions.
28 changes: 22 additions & 6 deletions src/configs/gas_costs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,6 @@ pub enum DynamicCosts {
len: U256,
},
/// Gas cost for `EXTCODECOPY`.
ExtCodeCopy {
/// True if target has not been previously accessed in this transaction
target_is_cold: bool,
/// Length.
len: U256,
},
Exp {
/// Power of `EXP`.
power: U256,
Expand All @@ -126,6 +120,13 @@ pub enum DynamicCosts {
/// True if target has not been previously accessed in this transaction
target_is_cold: bool,
},
Copy {
size_bytes: usize,
},
ExtCodeCopy {
target_is_cold: bool,
size_bytes: usize,
}
}

impl DynamicCosts {
Expand Down Expand Up @@ -213,6 +214,21 @@ impl DynamicCosts {
let bytes = (power.bits() + 7) / 8;
static_costs::G_EXP + static_costs::G_EXP_BYTE * bytes as u64
}

DynamicCosts::Copy { size_bytes } => {
static_costs::G_VERY_LOW + static_costs::G_COPY * (size_bytes.div_ceil(32) as u64)
}

DynamicCosts::ExtCodeCopy { target_is_cold, size_bytes } => {
println!("size_bytes: {}", size_bytes);
println!("size_bytes.div_ceil(32): {}", size_bytes.div_ceil(32) as u64);
static_costs::G_COPY * (size_bytes.div_ceil(32) as u64) +
if *target_is_cold {
static_costs::G_COLD_ACCOUNT_ACCESS
} else {
static_costs::G_WARM_ACCESS
}
}
_ => 0,
}
}
Expand Down
27 changes: 16 additions & 11 deletions src/evm_logic/evm/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,14 @@ pub fn decode_instruction(evm: &mut EVMContext, runtime: &mut impl Runtime, debu

opcodes::CALLDATACOPY => {
// TODO fix
let (dest_offset, offset, length) = (
let (dest_offset, offset, size) = (
pop!(evm).as_usize(),
pop!(evm).as_usize(),
pop!(evm).as_usize(),
);
evm.gas_recorder.record_gas(DynamicCosts::Copy { size_bytes: size}.cost());
evm.memory
.copy_from_bytes(&mut evm.message.data, offset, dest_offset, size, &mut evm.gas_recorder);
},

opcodes::CODESIZE => {
Expand All @@ -356,14 +359,14 @@ pub fn decode_instruction(evm: &mut EVMContext, runtime: &mut impl Runtime, debu
},

opcodes::CODECOPY => {
let (dest_offset, offset, length) = (
let (dest_offset, offset, size) = (
pop!(evm).as_usize(),
pop!(evm).as_usize(),
pop!(evm).as_usize(),
);

evm.gas_recorder.record_gas(DynamicCosts::Copy { size_bytes: size}.cost());
evm.memory
.copy_from(&mut evm.program, offset, dest_offset, length, &mut evm.gas_recorder);
.copy_from(&mut evm.program, offset, dest_offset, size, &mut evm.gas_recorder);
},

opcodes::GASPRICE => {
Expand All @@ -379,18 +382,19 @@ pub fn decode_instruction(evm: &mut EVMContext, runtime: &mut impl Runtime, debu
},

opcodes::EXTCODECOPY => {
let (addr, dest_offset, offset, length) = (
let (addr, dest_offset, offset, size) = (
pop!(evm),
pop!(evm).as_usize(),
pop!(evm).as_usize(),
pop!(evm).as_usize(),
);

evm.memory.copy_from(
&mut Memory::from(runtime.code(addr), &mut evm.gas_recorder),
evm.gas_recorder.record_gas(DynamicCosts::ExtCodeCopy { target_is_cold: runtime.is_cold(addr), size_bytes: size}.cost());
evm.memory.copy_from_bytes(
&runtime.code(addr),
offset,
dest_offset,
length,
size,
&mut evm.gas_recorder
);
runtime.mark_hot(addr);
Expand All @@ -403,13 +407,14 @@ pub fn decode_instruction(evm: &mut EVMContext, runtime: &mut impl Runtime, debu
},

opcodes::RETURNDATACOPY => {
let (dest_offset, offset, length) = (
let (dest_offset, offset, size) = (
pop!(evm).as_usize(),
pop!(evm).as_usize(),
pop!(evm).as_usize(),
);
evm.gas_recorder.record_gas(DynamicCosts::Copy { size_bytes: size}.cost());
evm.memory
.copy_from(&mut evm.last_return_data, offset, dest_offset, length, &mut evm.gas_recorder);
.copy_from(&mut evm.last_return_data, offset, dest_offset, size, &mut evm.gas_recorder);
},

opcodes::EXTCODEHASH => {
Expand Down Expand Up @@ -609,7 +614,7 @@ pub fn decode_instruction(evm: &mut EVMContext, runtime: &mut impl Runtime, debu
opcodes::RETURN => {
let (offset, size) = (pop!(evm).as_usize(), pop!(evm).as_usize());
evm.result.set_length(size);
evm.result.copy_from(&mut evm.memory, offset, 0, size, &mut evm.gas_recorder);
evm.result.copy_from_with_local_cost(&mut evm.memory, offset, 0, size, &mut evm.gas_recorder);
evm.stopped = true;
},

Expand Down
6 changes: 3 additions & 3 deletions src/evm_logic/gas_calculator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,13 @@ impl GasRecorder {
if new_memory_size == 0 {
return;
}
let max_index = new_memory_size - 1;
let memory_size_word = (max_index / 4) as u64;
let old_cost = GasRecorder::memory_cost(current_memory_size);
let new_cost = GasRecorder::memory_cost(new_memory_size);
// println!("Old cost: {}, New cost: {}", old_cost, new_cost);
let len = new_memory_size - current_memory_size;
// let memory_expansion_cost = 3 + 3 * (len as u64 + 31 / 32) as usize + (new_cost - old_cost);
let memory_expansion_cost = new_cost - old_cost;
println!("Memory expansion cost: {}", memory_expansion_cost);
self.gas_usage += memory_expansion_cost;
}

Expand All @@ -48,7 +47,8 @@ impl GasRecorder {
if current_memory_size_bytes == 0 {
return 0;
}
let memory_size_word = (current_memory_size_bytes + 31) / 32;
println!("current_memory_size_bytes: {}", current_memory_size_bytes);
let memory_size_word = current_memory_size_bytes.div_ceil(32);
let memory_cost = (memory_size_word.pow(2)) / 512 + (3 * memory_size_word);
memory_cost
// let memory_size_word = (current_memory_size_bytes - 1) / 4;
Expand Down
71 changes: 66 additions & 5 deletions src/state/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,14 @@ impl Memory {
length: usize,
gas_recorder: &mut GasRecorder,
) {
if write_address > self.max_index {
self.expand(write_address, gas_recorder)
println!("Write addresses: {}", write_address);
if write_address + length > self.max_index {
println!("Expanding memory");
println!("memory bytes length: {}", memory.bytes.len());
println!("read address: {}", read_address);
println!("length: {}", length);
println!("max index: {}", self.max_index);
self.expand(write_address + length, gas_recorder)
}
if memory.bytes.len() < read_address + length {
memory.expand(read_address + length, gas_recorder)
Expand All @@ -53,6 +59,54 @@ impl Memory {
.copy_from_slice(&memory.bytes[read_address..(read_address + length)]);
}

#[inline]
pub fn copy_from_with_local_cost(
&mut self,
memory: &mut Memory,
read_address: usize,
write_address: usize,
length: usize,
gas_recorder: &mut GasRecorder,
) {
println!("Write addresses: {}", write_address);
if write_address + length > self.max_index {
println!("Expanding memory");
println!("memory bytes length: {}", memory.bytes.len());
println!("read address: {}", read_address);
println!("length: {}", length);
println!("max index: {}", self.max_index);
self.expand(write_address + length, &mut GasRecorder{gas_usage: 0, gas_refunds: 0});
}
if memory.bytes.len() < read_address + length {
memory.expand(read_address + length, gas_recorder)
}
self.bytes[write_address..write_address + length]
.copy_from_slice(&memory.bytes[read_address..(read_address + length)]);
}

#[inline]
pub fn copy_from_bytes(
&mut self,
bytes: &Vec<u8>,
read_address: usize,
write_address: usize,
length: usize,
gas_recorder: &mut GasRecorder,
) {
if write_address + length > self.max_index {
self.expand(write_address + length, gas_recorder)
}
let (mut start_address, mut end_address) = (read_address, read_address + length);
if start_address > bytes.len() {
start_address = bytes.len();
}
if end_address > bytes.len() {
end_address = bytes.len();
}
self.bytes[write_address..write_address + (end_address - start_address)]
.copy_from_slice(&bytes[start_address..end_address]);
}

#[inline]
pub fn set_length(&mut self, length: usize) {
// TODO add gas recorder here?
Expand All @@ -74,7 +128,7 @@ impl Memory {
#[inline]
pub fn write(&mut self, address: usize, value: U256, gas_recorder: &mut GasRecorder) {
if address > {if self.max_index > 32 {self.max_index - 32} else {self.max_index}} {
self.expand(address,gas_recorder);
self.expand(address + 32,gas_recorder);
}
let index = address;
let end_index = index + 32;
Expand Down Expand Up @@ -103,12 +157,19 @@ impl Memory {
panic!("Memory expansion error");
}
if new_max_address == 0 {
println!("New max address is 0");
return;
}
let new_max_address= new_max_address + 32;
println!("Self.butes.len() : {}", self.bytes.len());
let mut new_max_address = new_max_address;
println!("New max address : {}", new_max_address);
// if new_max_address % 32 != 0 {
// new_max_address= new_max_address + 32;
// }
// println!("New max address : {}", new_max_address);
self.max_index = new_max_address;
gas_recorder.record_memory_usage(self.bytes.len(), new_max_address);
println!("Max Address : {}", new_max_address);
// println!("Max Address : {}", new_max_address);
self.bytes.resize(new_max_address, 0);
}
}
Expand Down
2 changes: 1 addition & 1 deletion test_gen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ pub fn generate_official_tests_from_file(input: TokenStream) -> TokenStream {
}
}
for i in 0..num_tests {
// for i in 0..10 {
// for i in 10..20 {
let test_name = Ident::new(
format!("run_test_{}", i).as_str(),
proc_macro2::Span::call_site(),
Expand Down

0 comments on commit c777a7d

Please sign in to comment.