Skip to content

Commit

Permalink
reconstruct memory when set EnableMemory to false in tracing (privacy…
Browse files Browse the repository at this point in the history
…-scaling-explorations#614)

* impl memory reconstruction

* fix reconstruction order

* fix return copy length

* revert change of OpCode trait

* fix reconstruction order

* Merge upstream/main into issues/502

* fix tracer_tests

* remove println

* cleanup

* cleanup x2

* tiny return data fix

* fix execution tests

* fix some mem

* cargo fmt

* clean codedb

Co-authored-by: Zhang Zhuo <[email protected]>
  • Loading branch information
lightsing and lispc authored Jul 29, 2022
1 parent 14a7495 commit a86aa1d
Show file tree
Hide file tree
Showing 32 changed files with 1,351 additions and 223 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
*.png
.DS_Store
.vscode
8 changes: 6 additions & 2 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,14 @@ impl<'a> CircuitInputBuilder {
}

/// Retrieve the init_code from memory for {CREATE, CREATE2}
pub fn get_create_init_code(step: &GethExecStep) -> Result<&[u8], Error> {
pub fn get_create_init_code<'a, 'b>(
call_ctx: &'a CallContext,
step: &'b GethExecStep,
) -> Result<&'a [u8], Error> {
let offset = step.stack.nth_last(1)?;
let length = step.stack.nth_last(2)?;
Ok(&step.memory.0[offset.low_u64() as usize..(offset.low_u64() + length.low_u64()) as usize])
Ok(&call_ctx.memory.0
[offset.low_u64() as usize..(offset.low_u64() + length.low_u64()) as usize])
}

/// Retrieve the memory offset and length of call.
Expand Down
5 changes: 5 additions & 0 deletions bus-mapping/src/circuit_input_builder/call.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::CodeSource;
use crate::{exec_trace::OperationRef, Error};
use eth_types::evm_types::Memory;
use eth_types::{evm_types::OpcodeId, Address, Hash, Word};

/// Type of a *CALL*/CREATE* Function.
Expand Down Expand Up @@ -108,6 +109,10 @@ pub struct CallContext {
/// Call data (copy of tx input or caller's
/// memory[call_data_offset..call_data_offset + call_data_length])
pub call_data: Vec<u8>,
/// memory context of current call
pub memory: Memory,
/// return data buffer
pub return_data: Vec<u8>,
}

/// A reversion group is the collection of calls and the operations which are
Expand Down
11 changes: 7 additions & 4 deletions bus-mapping/src/circuit_input_builder/execution.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
//! Execution step related module.
use crate::{error::ExecError, exec_trace::OperationRef, operation::RWCounter, operation::RW};
use crate::{
circuit_input_builder::CallContext, error::ExecError, exec_trace::OperationRef,
operation::RWCounter, operation::RW,
};
use eth_types::{
evm_types::{Gas, GasCost, OpcodeId, ProgramCounter},
GethExecStep, H256,
Expand Down Expand Up @@ -47,7 +50,7 @@ impl ExecStep {
/// Create a new Self from a `GethExecStep`.
pub fn new(
step: &GethExecStep,
call_index: usize,
call_ctx: &CallContext,
rwc: RWCounter,
reversible_write_counter: usize,
log_id: usize,
Expand All @@ -56,11 +59,11 @@ impl ExecStep {
exec_state: ExecState::Op(step.op),
pc: step.pc,
stack_size: step.stack.0.len(),
memory_size: step.memory.0.len(),
memory_size: call_ctx.memory.len(),
gas_left: step.gas,
gas_cost: step.gas_cost,
gas_refund: Gas(0),
call_index,
call_index: call_ctx.index,
rwc,
reversible_write_counter,
log_id,
Expand Down
36 changes: 26 additions & 10 deletions bus-mapping/src/circuit_input_builder/input_state_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ impl<'a> CircuitInputStateRef<'a> {

Ok(ExecStep::new(
geth_step,
call_ctx.index,
call_ctx,
self.block_ctx.rwc,
call_ctx.reversible_write_counter,
self.tx_ctx.log_id,
Expand Down Expand Up @@ -500,12 +500,24 @@ impl<'a> CircuitInputStateRef<'a> {
self.tx_ctx.call_ctx_mut()
}

/// Mutable reference to the caller CallContext
pub fn caller_ctx_mut(&mut self) -> Result<&mut CallContext, Error> {
self.tx_ctx
.calls
.iter_mut()
.rev()
.nth(1)
.ok_or(Error::InternalError("caller id not found in call map"))
}

/// Push a new [`Call`] into the [`Transaction`], and add its index and
/// [`CallContext`] in the `call_stack` of the [`TransactionContext`]
pub fn push_call(&mut self, call: Call, step: &GethExecStep) {
pub fn push_call(&mut self, call: Call) {
let current_call = self.call_ctx().expect("current call not found");
let call_data = match call.kind {
CallKind::Call | CallKind::CallCode | CallKind::DelegateCall | CallKind::StaticCall => {
step.memory
current_call
.memory
.read_chunk(call.call_data_offset.into(), call.call_data_length.into())
}
CallKind::Create | CallKind::Create2 => Vec::new(),
Expand Down Expand Up @@ -537,11 +549,12 @@ impl<'a> CircuitInputStateRef<'a> {
/// deterministically from the arguments in the stack.
pub(crate) fn create2_address(&self, step: &GethExecStep) -> Result<Address, Error> {
let salt = step.stack.nth_last(3)?;
let init_code = get_create_init_code(step)?;
let call_ctx = self.call_ctx()?;
let init_code = get_create_init_code(call_ctx, step)?.to_vec();
Ok(get_create2_address(
self.call()?.address,
salt.to_be_bytes().to_vec(),
init_code.to_vec(),
init_code,
))
}

Expand All @@ -560,6 +573,7 @@ impl<'a> CircuitInputStateRef<'a> {
.unwrap();
let kind = CallKind::try_from(step.op)?;
let caller = self.call()?;
let caller_ctx = self.call_ctx()?;

let (caller_address, address, value) = match kind {
CallKind::Call => (
Expand All @@ -584,8 +598,8 @@ impl<'a> CircuitInputStateRef<'a> {

let (code_source, code_hash) = match kind {
CallKind::Create | CallKind::Create2 => {
let init_code = get_create_init_code(step)?;
let code_hash = self.code_db.insert(init_code.to_vec());
let init_code = get_create_init_code(caller_ctx, step)?.to_vec();
let code_hash = self.code_db.insert(init_code);
(CodeSource::Memory, code_hash)
}
_ => {
Expand Down Expand Up @@ -777,12 +791,13 @@ impl<'a> CircuitInputStateRef<'a> {
/// previous call context.
pub fn handle_return(&mut self, step: &GethExecStep) -> Result<(), Error> {
let call = self.call()?.clone();
let call_ctx = self.call_ctx()?;

// Store deployed code if it's a successful create
if call.is_create() && call.is_success {
let offset = step.stack.nth_last(0)?;
let length = step.stack.nth_last(1)?;
let code = step
let code = call_ctx
.memory
.read_chunk(offset.low_u64().into(), length.low_u64().into());
let code_hash = self.code_db.insert(code);
Expand Down Expand Up @@ -837,6 +852,7 @@ impl<'a> CircuitInputStateRef<'a> {
.unwrap_or_else(Word::zero);

let call = self.call()?;
let call_ctx = self.call_ctx()?;

// Return from a call with a failure
if step.depth == next_depth + 1 && next_result.is_zero() {
Expand Down Expand Up @@ -875,8 +891,8 @@ impl<'a> CircuitInputStateRef<'a> {
if length > Word::from(0x6000u64) {
return Ok(Some(ExecError::MaxCodeSizeExceeded));
} else if length > Word::zero()
&& !step.memory.0.is_empty()
&& step.memory.0.get(offset.low_u64() as usize) == Some(&0xef)
&& !call_ctx.memory.is_empty()
&& call_ctx.memory.0.get(offset.low_u64() as usize) == Some(&0xef)
{
return Ok(Some(ExecError::InvalidCreationCode));
} else if Word::from(200u64) * length > Word::from(step.gas.0) {
Expand Down
Loading

0 comments on commit a86aa1d

Please sign in to comment.