Skip to content

Commit

Permalink
bus-mapping: Add call_id in StackOp and MemoryOp (privacy-scaling-exp…
Browse files Browse the repository at this point in the history
…lorations#252)

Rename TxAccessListStorageSlot to TxAccessListAccountStorage

Rename GlobalCounter to RWCounter and gc to rwc
  • Loading branch information
ed255 authored Dec 22, 2021
1 parent 2621779 commit 1d6537a
Show file tree
Hide file tree
Showing 18 changed files with 398 additions and 377 deletions.
81 changes: 67 additions & 14 deletions bus-mapping/src/circuit_input_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use crate::eth_types::{
self, Address, ChainConstants, GethExecStep, GethExecTrace, Hash,
ToAddress, ToBigEndian, Word,
};
use crate::evm::{Gas, GasCost, GlobalCounter, OpcodeId, ProgramCounter};
use crate::evm::{
Gas, GasCost, MemoryAddress, OpcodeId, ProgramCounter, RWCounter,
StackAddress,
};
use crate::exec_trace::OperationRef;
use crate::geth_errors::*;
use crate::operation::container::OperationContainer;
use crate::operation::RW;
use crate::operation::{Op, Operation};
use crate::operation::{MemoryOp, Op, Operation, StackOp, RW};
use crate::state_db::{CodeDB, StateDB};
use crate::Error;
use core::fmt::Debug;
Expand Down Expand Up @@ -107,7 +109,7 @@ pub struct ExecStep {
/// Call index within the [`Transaction`]
pub call_index: usize,
/// The global counter when this step was executed.
pub gc: GlobalCounter,
pub rwc: RWCounter,
/// State Write Counter. Counter of state write operations in the call
/// that haven't been reverted yet up to this step.
pub swc: usize,
Expand All @@ -124,7 +126,7 @@ impl ExecStep {
pub fn new(
step: &GethExecStep,
call_index: usize,
gc: GlobalCounter,
rwc: RWCounter,
swc: usize, // State Write Counter
) -> Self {
ExecStep {
Expand All @@ -135,7 +137,7 @@ impl ExecStep {
gas_left: step.gas,
gas_cost: step.gas_cost,
call_index,
gc,
rwc,
swc,
bus_mapping_instance: Vec::new(),
error: None,
Expand All @@ -148,7 +150,8 @@ impl ExecStep {
#[derive(Debug)]
pub struct BlockContext {
/// Used to track the global counter in every operation in the block.
pub gc: GlobalCounter,
/// Contains the next available value.
pub rwc: RWCounter,
}

impl Default for BlockContext {
Expand All @@ -161,7 +164,7 @@ impl BlockContext {
/// Create a new Self
pub fn new() -> Self {
Self {
gc: GlobalCounter::new(),
rwc: RWCounter::new(),
}
}
}
Expand Down Expand Up @@ -244,6 +247,8 @@ impl TryFrom<OpcodeId> for CallKind {
/// Circuit Input related to an Ethereum Call
#[derive(Debug)]
pub struct Call {
/// Unique call identifier within the Block.
call_id: usize,
/// Type of call
kind: CallKind,
/// This call is being executed without write access (STATIC)
Expand Down Expand Up @@ -344,6 +349,7 @@ pub struct Transaction {
impl Transaction {
/// Create a new Self.
pub fn new(
call_id: usize,
sdb: &StateDB,
code_db: &mut CodeDB,
eth_tx: &eth_types::Transaction,
Expand All @@ -357,6 +363,7 @@ impl Transaction {
}
let code_hash = account.code_hash;
calls.push(Call {
call_id,
kind: CallKind::Call,
is_static: false,
is_root: true,
Expand All @@ -368,6 +375,7 @@ impl Transaction {
// Contract creation
let code_hash = code_db.insert(eth_tx.input.to_vec());
calls.push(Call {
call_id,
kind: CallKind::Create,
is_static: false,
is_root: true,
Expand Down Expand Up @@ -412,6 +420,7 @@ impl Transaction {
fn push_call(
&mut self,
parent_index: usize,
call_id: usize,
kind: CallKind,
address: Address,
code_source: CodeSource,
Expand All @@ -420,6 +429,7 @@ impl Transaction {
let is_static =
kind == CallKind::StaticCall || self.calls[parent_index].is_static;
self.calls.push(Call {
call_id,
kind,
is_static,
is_root: false,
Expand Down Expand Up @@ -452,17 +462,57 @@ pub struct CircuitInputStateRef<'a> {

impl<'a> CircuitInputStateRef<'a> {
/// Push an [`Operation`] into the [`OperationContainer`] with the next
/// [`GlobalCounter`] and then adds a reference to the stored operation
/// [`RWCounter`] and then adds a reference to the stored operation
/// ([`OperationRef`]) inside the bus-mapping instance of the current
/// [`ExecStep`]. Then increase the block_ctx [`GlobalCounter`] by one.
/// [`ExecStep`]. Then increase the block_ctx [`RWCounter`] by one.
pub fn push_op<T: Op>(&mut self, op: T) {
let op_ref = self
.block
.container
.insert(Operation::new(self.block_ctx.gc.inc_pre(), op));
.insert(Operation::new(self.block_ctx.rwc.inc_pre(), op));
self.step.bus_mapping_instance.push(op_ref);
}

/// Push a [`MemoryOp`] into the [`OperationContainer`] with the next
/// [`RWCounter`] and `call_id`, and then adds a reference to
/// the stored operation ([`OperationRef`]) inside the bus-mapping
/// instance of the current [`ExecStep`]. Then increase the `block_ctx`
/// [`RWCounter`] by one.
pub fn push_memory_op(
&mut self,
rw: RW,
address: MemoryAddress,
value: u8,
) {
let call_id = self.call().call_id;
self.push_op(MemoryOp {
rw,
call_id,
address,
value,
});
}

/// Push a [`StackOp`] into the [`OperationContainer`] with the next
/// [`RWCounter`] and `call_id`, and then adds a reference to
/// the stored operation ([`OperationRef`]) inside the bus-mapping
/// instance of the current [`ExecStep`]. Then increase the `block_ctx`
/// [`RWCounter`] by one.
pub fn push_stack_op(
&mut self,
rw: RW,
address: StackAddress,
value: Word,
) {
let call_id = self.call().call_id;
self.push_op(StackOp {
rw,
call_id,
address,
value,
});
}

/// Reference to the current Call
pub fn call(&self) -> &Call {
&self.tx.calls[self.tx_ctx.call_index()]
Expand All @@ -488,8 +538,10 @@ impl<'a> CircuitInputStateRef<'a> {
code_hash: Hash,
) {
let parent_index = self.tx_ctx.call_index();
let call_id = self.block_ctx.rwc.0;
let index = self.tx.push_call(
parent_index,
call_id,
kind,
address,
code_source,
Expand Down Expand Up @@ -801,7 +853,8 @@ impl<'a> CircuitInputBuilder {
&mut self,
eth_tx: &eth_types::Transaction,
) -> Result<Transaction, Error> {
Transaction::new(&self.sdb, &mut self.code_db, eth_tx)
let call_id = self.block_ctx.rwc.0;
Transaction::new(call_id, &self.sdb, &mut self.code_db, eth_tx)
}

/// Handle a transaction with its corresponding execution trace to generate
Expand All @@ -819,7 +872,7 @@ impl<'a> CircuitInputBuilder {
let mut step = ExecStep::new(
geth_step,
tx_ctx.call_index(),
self.block_ctx.gc,
self.block_ctx.rwc,
tx_ctx.call_ctx().swc,
);
let mut state_ref = self.state_ref(&mut tx, &mut tx_ctx, &mut step);
Expand Down Expand Up @@ -1175,7 +1228,7 @@ mod tracer_tests {
builder,
tx,
tx_ctx: TransactionContext::new(&block.eth_tx),
step: ExecStep::new(geth_step, 0, GlobalCounter(0), 0),
step: ExecStep::new(geth_step, 0, RWCounter::new(), 0),
}
}

Expand Down
24 changes: 12 additions & 12 deletions bus-mapping/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,39 +55,39 @@ impl ProgramCounter {
/// Wrapper type over `usize` which represents the global counter associated to
/// an [`ExecStep`](crate::circuit_input_builder::ExecStep) or
/// [`Operation`](crate::operation::Operation). The purpose of the
/// `GlobalCounter` is to enforce that each Opcode/Instruction and Operation is
/// `RWCounter` is to enforce that each Opcode/Instruction and Operation is
/// unique and just executed once.
#[derive(Clone, Copy, Eq, PartialEq, PartialOrd, Ord)]
pub struct GlobalCounter(pub(crate) usize);
pub struct RWCounter(pub(crate) usize);

impl fmt::Debug for GlobalCounter {
impl fmt::Debug for RWCounter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("{}", self.0))
}
}

impl From<GlobalCounter> for usize {
fn from(addr: GlobalCounter) -> usize {
impl From<RWCounter> for usize {
fn from(addr: RWCounter) -> usize {
addr.0
}
}

impl From<usize> for GlobalCounter {
fn from(gc: usize) -> Self {
GlobalCounter(gc)
impl From<usize> for RWCounter {
fn from(rwc: usize) -> Self {
RWCounter(rwc)
}
}

impl Default for GlobalCounter {
impl Default for RWCounter {
fn default() -> Self {
Self::new()
}
}

impl GlobalCounter {
/// Create a new GlobalCounter with the initial default value
impl RWCounter {
/// Create a new RWCounter with the initial default value
pub fn new() -> Self {
Self(0)
Self(1)
}

/// Increase Self by one
Expand Down
21 changes: 9 additions & 12 deletions bus-mapping/src/evm/opcodes/dup.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use super::Opcode;
use crate::circuit_input_builder::CircuitInputStateRef;
use crate::eth_types::GethExecStep;
use crate::{
operation::{StackOp, RW},
Error,
};
use crate::{operation::RW, Error};

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the `OpcodeId::DUP*` `OpcodeId`.
Expand All @@ -20,13 +17,13 @@ impl<const N: usize> Opcode for Dup<N> {

let stack_value_read = step.stack.nth_last(N - 1)?;
let stack_position = step.stack.nth_last_filled(N - 1);
state.push_op(StackOp::new(RW::READ, stack_position, stack_value_read));
state.push_stack_op(RW::READ, stack_position, stack_value_read);

state.push_op(StackOp::new(
state.push_stack_op(
RW::WRITE,
step.stack.last_filled().map(|a| a - 1),
stack_value_read,
));
);

Ok(())
}
Expand Down Expand Up @@ -75,23 +72,23 @@ mod dup_tests {
let mut step = ExecStep::new(
&block.geth_trace.struct_logs[i],
0,
test_builder.block_ctx.gc,
test_builder.block_ctx.rwc,
0,
);
let mut state_ref =
test_builder.state_ref(&mut tx, &mut tx_ctx, &mut step);

state_ref.push_op(StackOp::new(
state_ref.push_stack_op(
RW::READ,
StackAddress(1024 - 3 + i),
*word,
));
);

state_ref.push_op(StackOp::new(
state_ref.push_stack_op(
RW::WRITE,
StackAddress(1024 - 4 - i),
*word,
));
);

tx.steps_mut().push(step);
}
Expand Down
14 changes: 5 additions & 9 deletions bus-mapping/src/evm/opcodes/jump.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
use super::Opcode;
use crate::circuit_input_builder::CircuitInputStateRef;
use crate::eth_types::GethExecStep;
use crate::{
operation::{StackOp, RW},
Error,
};
use crate::{operation::RW, Error};

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the [`OpcodeId::JUMP`](crate::evm::OpcodeId::JUMP)
Expand All @@ -20,12 +17,11 @@ impl Opcode for Jump {
let step = &steps[0];

// `JUMP` needs only one read operation
let op = StackOp::new(
state.push_stack_op(
RW::READ,
step.stack.nth_last_filled(0),
step.stack.nth_last(0)?,
);
state.push_op(op);

Ok(())
}
Expand Down Expand Up @@ -75,18 +71,18 @@ mod jump_tests {
let mut step = ExecStep::new(
&block.geth_trace.struct_logs[0],
0,
test_builder.block_ctx.gc,
test_builder.block_ctx.rwc,
0,
);
let mut state_ref =
test_builder.state_ref(&mut tx, &mut tx_ctx, &mut step);

// Add the last Stack read
state_ref.push_op(StackOp::new(
state_ref.push_stack_op(
RW::READ,
StackAddress::from(1023),
Word::from(destination),
));
);

tx.steps_mut().push(step);
test_builder.block.txs_mut().push(tx);
Expand Down
Loading

0 comments on commit 1d6537a

Please sign in to comment.