Skip to content

Commit

Permalink
Refactor: move Sha3CodeGen struct and rand_bytes function to mock…
Browse files Browse the repository at this point in the history
… crate (privacy-scaling-explorations#1481)

### Description

1. Move `Sha3CodeGen` and `rand_bytes` from bus-mapping to mock crate.
Since they are only used for test.

2. Delete `rand` dependency for bus-mapping.

### Issue Link

`cargo build` fails in `bus-mapping` folder.

### Type of change

- [x] Bug fix (non-breaking change which fixes an issue)
  • Loading branch information
silathdiir authored Jun 20, 2023
1 parent 0ecd781 commit 1e1d104
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 132 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 1 addition & 3 deletions bus-mapping/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ halo2_proofs = { git = "https://github.com/privacy-scaling-explorations/halo2.gi
itertools = "0.10"
lazy_static = "1.4"
log = "0.4.14"
rand = { version = "0.8", optional = true }
serde = {version = "1.0.130", features = ["derive"] }
serde_json = "1.0.66"
strum = "0.24"
Expand All @@ -30,7 +29,6 @@ pretty_assertions = "1.0.0"
tokio = { version = "1.13", features = ["macros"] }
url = "2.2.2"
mock = { path = "../mock" }
rand = "0.8"

[features]
test = ["mock", "rand"]
test = ["mock"]
2 changes: 0 additions & 2 deletions bus-mapping/src/evm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,3 @@ pub(crate) mod opcodes;

pub use eth_types::evm_types::opcode_ids::OpcodeId;
pub use opcodes::Opcode;

pub use opcodes::Sha3CodeGen;
2 changes: 0 additions & 2 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use crate::{
use core::fmt::Debug;
use eth_types::{evm_unimplemented, GethExecStep, ToAddress};

pub use self::sha3::Sha3CodeGen;

mod address;
mod balance;
mod begin_end_tx;
Expand Down
20 changes: 8 additions & 12 deletions bus-mapping/src/evm/opcodes/calldataload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,26 +103,22 @@ impl Opcode for Calldataload {

#[cfg(test)]
mod calldataload_tests {
use crate::operation::CallContextOp;
use super::*;
use crate::{
circuit_input_builder::ExecState,
mock::BlockData,
operation::{CallContextOp, StackOp},
};
use eth_types::{
bytecode,
evm_types::{OpcodeId, StackAddress},
geth_types::GethData,
Word,
};
use mock::{
generate_mock_call_bytecode, test_ctx::helpers::account_0_code_account_1_no_code,
MockCallBytecodeParams, TestContext,
generate_mock_call_bytecode, rand_bytes,
test_ctx::helpers::account_0_code_account_1_no_code, MockCallBytecodeParams, TestContext,
};
use rand::random;

use crate::{circuit_input_builder::ExecState, mock::BlockData, operation::StackOp};

use super::*;

fn rand_bytes(size: usize) -> Vec<u8> {
(0..size).map(|_| random()).collect::<Vec<u8>>()
}

fn test_internal_ok(
call_data_length: usize,
Expand Down
113 changes: 6 additions & 107 deletions bus-mapping/src/evm/opcodes/sha3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ use crate::{
},
Error,
};
use eth_types::{bytecode, Bytecode, GethExecStep, Word, U256};
use eth_types::{GethExecStep, U256};
use ethers_core::utils::keccak256;
use rand::{rngs::ThreadRng, Rng};

#[derive(Clone, Copy, Debug)]
pub(crate) struct Sha3;
Expand Down Expand Up @@ -46,7 +45,7 @@ impl Opcode for Sha3 {

// keccak-256 hash of the given data in memory.
let sha3 = keccak256(&memory);
debug_assert_eq!(Word::from_big_endian(&sha3), expected_sha3);
debug_assert_eq!(U256::from_big_endian(&sha3), expected_sha3);
state.stack_write(
&mut exec_step,
geth_steps[1].stack.last_filled(),
Expand Down Expand Up @@ -87,113 +86,13 @@ impl Opcode for Sha3 {
}
}

/// Generate Sha3 opcode
pub struct Sha3CodeGen {
/// The offset
pub offset: usize,
/// The size
pub size: usize,
data_len: usize,
rng: ThreadRng,
}
impl Sha3CodeGen {
/// Construct with memory less than size
pub fn mem_lt_size(offset: usize, size: usize) -> Self {
let mut rng = rand::thread_rng();
let data_len = offset
+ if size.gt(&0) {
rng.gen_range(0..size)
} else {
0
};
Self {
offset,
size,
data_len,
rng,
}
}
/// Construct with memory equal to size
pub fn mem_eq_size(offset: usize, size: usize) -> Self {
let data_len = offset + size;
Self {
offset,
size,
data_len,
rng: rand::thread_rng(),
}
}
/// Construct with memory greater than size
pub fn mem_gt_size(offset: usize, size: usize) -> Self {
let mut rng = rand::thread_rng();
let data_len = offset
+ size
+ if size.gt(&0) {
rng.gen_range(0..size)
} else {
0
};
Self {
offset,
size,
data_len,
rng,
}
}
/// Construct with empty memory
pub fn mem_empty(offset: usize, size: usize) -> Self {
Self {
offset,
size,
data_len: 0,
rng: rand::thread_rng(),
}
}
fn rand_bytes(&mut self) -> Vec<u8> {
(0..self.data_len)
.map(|_| self.rng.gen())
.collect::<Vec<u8>>()
}
/// Generate bytecode for SHA3 opcode after having populated sufficient
/// memory given the offset and size arguments for SHA3.
pub fn gen_sha3_code(&mut self) -> (Bytecode, Vec<u8>) {
let data = self.rand_bytes();
let mut memory = Vec::with_capacity(self.data_len);

// add opcodes to populate memory in the current context.
let mut code = Bytecode::default();
for (i, mem_chunk) in data.chunks(32).enumerate() {
let mem_value = if mem_chunk.len() < 32 {
std::iter::repeat(0u8)
.take(32 - mem_chunk.len())
.chain(mem_chunk.to_vec())
.collect::<Vec<u8>>()
} else {
mem_chunk.to_vec()
};
memory.extend_from_slice(&mem_value);
code.op_mstore(32 * i, Word::from_big_endian(&mem_value));
}
// append SHA3 related opcodes at the tail end.
let code_tail = bytecode! {
PUSH32(self.size)
PUSH32(self.offset)
SHA3
STOP
};
code.append(&code_tail);
(code, memory)
}
}

#[cfg(test)]
pub(crate) mod sha3_tests {
use super::Sha3CodeGen;
use eth_types::{evm_types::OpcodeId, geth_types::GethData, Word};
use eth_types::{evm_types::OpcodeId, geth_types::GethData, U256};
use ethers_core::utils::keccak256;
use mock::{
test_ctx::helpers::{account_0_code_account_1_no_code, tx_from_1_to_0},
TestContext,
Sha3CodeGen, TestContext,
};

use crate::{
Expand Down Expand Up @@ -253,11 +152,11 @@ pub(crate) mod sha3_tests {
[
(
RW::READ,
&StackOp::new(call_id, 1022.into(), Word::from(offset)),
&StackOp::new(call_id, 1022.into(), U256::from(offset)),
),
(
RW::READ,
&StackOp::new(call_id, 1023.into(), Word::from(size)),
&StackOp::new(call_id, 1023.into(), U256::from(size)),
),
(
RW::WRITE,
Expand Down
9 changes: 8 additions & 1 deletion mock/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
use eth_types::{address, bytecode, bytecode::Bytecode, word, Address, Bytes, Word};
use ethers_signers::LocalWallet;
use lazy_static::lazy_static;
use rand::SeedableRng;
use rand::{random, SeedableRng};
use rand_chacha::ChaCha20Rng;
mod account;
mod block;
mod sha3;
pub mod test_ctx;
mod transaction;

pub(crate) use account::MockAccount;
pub(crate) use block::MockBlock;
pub use sha3::Sha3CodeGen;
pub use test_ctx::TestContext;
pub use transaction::{AddrOrWallet, MockTransaction, CORRECT_MOCK_TXS};

Expand Down Expand Up @@ -126,6 +128,11 @@ impl Default for MockCallBytecodeParams {
}
}

/// Generate random bytes for the specified size.
pub fn rand_bytes(size: usize) -> Vec<u8> {
(0..size).map(|_| random()).collect::<Vec<u8>>()
}

/// Generate mock EVM bytecode that performs a contract call
pub fn generate_mock_call_bytecode(params: MockCallBytecodeParams) -> Bytecode {
bytecode! {
Expand Down
101 changes: 101 additions & 0 deletions mock/src/sha3.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
use eth_types::{bytecode, Bytecode, U256};
use rand::{rngs::ThreadRng, Rng};

/// Generate Sha3 opcode
pub struct Sha3CodeGen {
/// The offset
pub offset: usize,
/// The size
pub size: usize,
data_len: usize,
rng: ThreadRng,
}
impl Sha3CodeGen {
/// Construct with memory less than size
pub fn mem_lt_size(offset: usize, size: usize) -> Self {
let mut rng = rand::thread_rng();
let data_len = offset
+ if size.gt(&0) {
rng.gen_range(0..size)
} else {
0
};
Self {
offset,
size,
data_len,
rng,
}
}
/// Construct with memory equal to size
pub fn mem_eq_size(offset: usize, size: usize) -> Self {
let data_len = offset + size;
Self {
offset,
size,
data_len,
rng: rand::thread_rng(),
}
}
/// Construct with memory greater than size
pub fn mem_gt_size(offset: usize, size: usize) -> Self {
let mut rng = rand::thread_rng();
let data_len = offset
+ size
+ if size.gt(&0) {
rng.gen_range(0..size)
} else {
0
};
Self {
offset,
size,
data_len,
rng,
}
}
/// Construct with empty memory
pub fn mem_empty(offset: usize, size: usize) -> Self {
Self {
offset,
size,
data_len: 0,
rng: rand::thread_rng(),
}
}
fn rand_bytes(&mut self) -> Vec<u8> {
(0..self.data_len)
.map(|_| self.rng.gen())
.collect::<Vec<u8>>()
}
/// Generate bytecode for SHA3 opcode after having populated sufficient
/// memory given the offset and size arguments for SHA3.
pub fn gen_sha3_code(&mut self) -> (Bytecode, Vec<u8>) {
let data = self.rand_bytes();
let mut memory = Vec::with_capacity(self.data_len);

// add opcodes to populate memory in the current context.
let mut code = Bytecode::default();
for (i, mem_chunk) in data.chunks(32).enumerate() {
let mem_value = if mem_chunk.len() < 32 {
std::iter::repeat(0u8)
.take(32 - mem_chunk.len())
.chain(mem_chunk.to_vec())
.collect::<Vec<u8>>()
} else {
mem_chunk.to_vec()
};
memory.extend_from_slice(&mem_value);
code.op_mstore(32 * i, U256::from_big_endian(&mem_value));
}
// append SHA3 related opcodes at the tail end.
let code_tail = bytecode! {
PUSH32(self.size)
PUSH32(self.offset)
SHA3
STOP
};
code.append(&code_tail);
(code, memory)
}
}
5 changes: 3 additions & 2 deletions zkevm-circuits/src/copy_circuit/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ use crate::{
};
use bus_mapping::{
circuit_input_builder::{CircuitInputBuilder, CircuitsParams},
evm::Sha3CodeGen,
mock::BlockData,
};
use eth_types::{bytecode, geth_types::GethData, ToWord, Word};
use halo2_proofs::{
dev::{MockProver, VerifyFailure},
halo2curves::bn256::Fr,
};
use mock::{test_ctx::helpers::account_0_code_account_1_no_code, TestContext, MOCK_ACCOUNTS};
use mock::{
test_ctx::helpers::account_0_code_account_1_no_code, Sha3CodeGen, TestContext, MOCK_ACCOUNTS,
};

#[test]
fn copy_circuit_unusable_rows() {
Expand Down
4 changes: 2 additions & 2 deletions zkevm-circuits/src/evm_circuit/execution/sha3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ impl<F: Field> ExecutionGadget<F> for Sha3Gadget<F> {
#[cfg(test)]
mod tests {
use crate::test_util::CircuitTestBuilder;
use bus_mapping::{circuit_input_builder::CircuitsParams, evm::Sha3CodeGen};
use bus_mapping::circuit_input_builder::CircuitsParams;
use eth_types::{bytecode, U256};
use mock::TestContext;
use mock::{Sha3CodeGen, TestContext};

fn test_ok(mut gen: Sha3CodeGen) {
let (code, _) = gen.gen_sha3_code();
Expand Down

0 comments on commit 1e1d104

Please sign in to comment.