Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

fix state circuit: value_prev column is initial_value for first access for (ext)codecopy #583

Merged
merged 3 commits into from
Jul 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 4 additions & 13 deletions bus-mapping/src/circuit_input_builder/input_state_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ impl<'a> CircuitInputStateRef<'a> {
step: &mut ExecStep,
address: MemoryAddress, //Caution: make sure this address = slot passing
value: Word,
) -> Result<(Vec<u8>), Error> {
) -> Result<Vec<u8>, Error> {
let mem = &mut self.call_ctx_mut()?.memory;
let value_prev = mem.read_word(address);
let value_prev_bytes = value_prev.to_be_bytes();
Expand Down Expand Up @@ -1657,6 +1657,7 @@ impl<'a> CircuitInputStateRef<'a> {
dst_addr: u64,
src_addr_end: u64,
bytes_left: u64,
memory_updated: Memory,
) -> Result<(CopyEventSteps, Vec<u8>), Error> {
let mut copy_steps = Vec::with_capacity(bytes_left as usize);
let mut prev_bytes: Vec<u8> = vec![];
Expand All @@ -1666,13 +1667,9 @@ impl<'a> CircuitInputStateRef<'a> {

let (dst_begin_slot, full_length, _) = Memory::align_range(dst_addr, bytes_left);

let code_slot_bytes = self
.call_ctx()?
.memory
.read_chunk(dst_begin_slot.into(), full_length.into());
let code_slot_bytes = memory_updated.read_chunk(dst_begin_slot.into(), full_length.into());

let mut copy_start = 0u64;
let mut first_set = true;
let copy_start = dst_addr - dst_begin_slot;
for (idx, value) in code_slot_bytes.iter().enumerate() {
if (idx as u64 + dst_begin_slot < dst_addr)
|| (idx as u64 + dst_begin_slot >= dst_addr + bytes_left)
Expand All @@ -1681,11 +1678,6 @@ impl<'a> CircuitInputStateRef<'a> {
copy_steps.push((*value, false, true));
} else {
// real copy byte
if first_set {
copy_start = idx as u64;
first_set = false;
}

let addr = src_addr
.checked_add(idx as u64 - copy_start)
.unwrap_or(src_addr_end);
Expand Down Expand Up @@ -2191,7 +2183,6 @@ impl<'a> CircuitInputStateRef<'a> {

Ok((read_steps, write_steps))
}

// TODO: add new gen_copy_steps for common use
pub(crate) fn gen_memory_copy_steps(
steps: &mut CopyEventSteps,
Expand Down
24 changes: 10 additions & 14 deletions bus-mapping/src/evm/opcodes/codecopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,6 @@ impl Opcode for Codecopy {
let geth_step = &geth_steps[0];
let mut exec_steps = vec![gen_codecopy_step(state, geth_step)?];

// reconstruction
let dst_offset = geth_step.stack.nth_last(0)?;
let code_offset = geth_step.stack.nth_last(1)?;
let length = geth_step.stack.nth_last(2)?;

let code_hash = state.call()?.code_hash;
let code = state.code(code_hash)?;

let call_ctx = state.call_ctx_mut()?;
let memory = &mut call_ctx.memory;

// TODO: move to the "memory_updated" approach.
memory.copy_from(dst_offset, code_offset, length, &code);

let copy_event = gen_copy_event(state, geth_step, &mut exec_steps[0])?;
state.push_copy(&mut exec_steps[0], copy_event);
Ok(exec_steps)
Expand Down Expand Up @@ -90,6 +76,15 @@ fn gen_copy_event(
.unwrap_or(u64::MAX)
.min(src_addr_end);

let call_ctx = state.call_ctx_mut()?;
let memory = &mut call_ctx.memory;
memory.extend_for_range(dst_offset, length.into());
let memory_updated = {
let mut memory_updated = memory.clone();
memory_updated.copy_from(dst_offset, code_offset, length.into(), &bytecode.to_vec());
memory_updated
};

let mut exec_step = state.new_step(geth_step)?;
let (copy_steps, prev_bytes) = state.gen_copy_steps_for_bytecode(
&mut exec_step,
Expand All @@ -98,6 +93,7 @@ fn gen_copy_event(
dst_addr,
src_addr_end,
length,
memory_updated,
)?;

Ok(CopyEvent {
Expand Down
40 changes: 19 additions & 21 deletions bus-mapping/src/evm/opcodes/extcodecopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,6 @@ impl Opcode for Extcodecopy {
let geth_step = &geth_steps[0];
let mut exec_steps = vec![gen_extcodecopy_step(state, geth_step)?];

// reconstruction
let address = geth_steps[0].stack.nth_last(0)?.to_address();
let dst_offset = geth_steps[0].stack.nth_last(1)?;
let code_offset = geth_step.stack.nth_last(2)?;
let length = geth_steps[0].stack.nth_last(3)?;

let (_, account) = state.sdb.get_account(&address);
let code_hash = account.code_hash;
let code = state.code(code_hash)?;

let call_ctx = state.call_ctx_mut()?;
let memory = &mut call_ctx.memory;

// TODO: move to the "memory_updated" approach.
memory.copy_from(dst_offset, code_offset, length, &code);

let copy_event = gen_copy_event(state, geth_step, &mut exec_steps[0])?;
state.push_copy(&mut exec_steps[0], copy_event);
Ok(exec_steps)
Expand Down Expand Up @@ -149,14 +133,23 @@ fn gen_copy_event(
.unwrap_or(u64::MAX)
.min(src_addr_end);

let mut exec_step = state.new_step(geth_step)?;
let call_ctx = state.call_ctx_mut()?;
let memory = &mut call_ctx.memory;
memory.extend_for_range(dst_offset, length.into());
let memory_updated = {
let mut memory_updated = memory.clone();
memory_updated.copy_from(dst_offset, code_offset, length.into(), &bytecode.to_vec());
memory_updated
};

let (copy_steps, prev_bytes) = state.gen_copy_steps_for_bytecode(
&mut exec_step,
exec_step,
&bytecode,
src_addr,
dst_addr,
src_addr_end,
length,
memory_updated,
)?;

Ok(CopyEvent {
Expand Down Expand Up @@ -416,8 +409,13 @@ mod extcodecopy_tests {
.iter()
.map(|(b, _, _)| *b)
.collect::<Vec<_>>();
assert_eq!(builder.block.container.memory_word.len(), word_ops);
let prev_bytes = builder.block.copy_events[0]
.copy_bytes
.bytes_write_prev
.clone()
.unwrap();

assert_eq!(builder.block.container.memory_word.len(), word_ops);
assert_eq!(
(0..word_ops)
.map(|idx| &builder.block.container.memory_word[idx])
Expand All @@ -431,7 +429,8 @@ mod extcodecopy_tests {
call_id,
MemoryAddress(copy_start + idx * 32),
Word::from(&copied_bytes[idx * 32..(idx + 1) * 32]),
Word::from(&copied_bytes[idx * 32..(idx + 1) * 32]), // TODO: get previous value
// get previous value
Word::from(&prev_bytes[idx * 32..(idx + 1) * 32]),
),
)
})
Expand All @@ -440,7 +439,6 @@ mod extcodecopy_tests {

let copy_events = builder.block.copy_events.clone();
assert_eq!(copy_events.len(), 1);
//assert_eq!(copy_events[0].bytes.len(), copy_size);
assert_eq!(copy_events[0].src_id, NumberOrHash::Hash(code_hash));
assert_eq!(copy_events[0].src_addr as usize, data_offset);
assert_eq!(copy_events[0].src_addr_end as usize, code_ext.len());
Expand Down
4 changes: 2 additions & 2 deletions bus-mapping/src/operation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ impl fmt::Debug for MemoryWordOp {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("MemoryWordOp { ")?;
f.write_fmt(format_args!(
"call_id: {:?}, addr: {:?}, value: 0x{:?}",
self.call_id, self.address, self.value
"call_id: {:?}, addr: {:?}, value: 0x{:?} value_prev {:?}",
self.call_id, self.address, self.value, self.value_prev
))?;
f.write_str(" }")
}
Expand Down