Skip to content

Commit

Permalink
Remove code duplication between returndatacopy and others (privacy-sc…
Browse files Browse the repository at this point in the history
…aling-explorations#1340)

### Description

Remove code duplication between returndatacopy and others as they use
similar test codes to construct bytecode for testing.

### Issue Link


privacy-scaling-explorations#1324

### Type of change

- [x] Refactor code

### Contents

Remove code duplication in unit tests between returndatacopy, balance,
calldataload and others. The unit tests should behave the same.

### Rationale

It's easier to manage the mock bytecode when we move similar code into
one place.

### How Has This Been Tested?

Use the command `make test` to run unit tests 

<hr>

---------

Co-authored-by: Brecht Devos <[email protected]>
  • Loading branch information
xiaodino and Brechtpd authored Apr 12, 2023
1 parent 4e5e78a commit fa320ea
Show file tree
Hide file tree
Showing 23 changed files with 380 additions and 471 deletions.
92 changes: 23 additions & 69 deletions bus-mapping/src/circuit_input_builder/tracer_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,12 +357,8 @@ fn tracer_err_address_collision() {
// that outputs the same, which will lead to the same new
// contract address.
let code_creator = bytecode! {
PUSH1(0x00) // value
PUSH1(0x00) // offset
MSTORE
PUSH1(0x01) // length
PUSH1(0x00) // offset
RETURN
.mstore(0x00, 0x00)
.return_bytecode(0x00, 0x01)
};

// code_a calls code_b which executes code_creator in CREATE2
Expand Down Expand Up @@ -488,12 +484,8 @@ fn tracer_create_collision_free() {
// that outputs not the same, which will lead to the different new
// contract address.
let code_creator = bytecode! {
PUSH1(0x00) // value
PUSH1(0x00) // offset
MSTORE
PUSH1(0x01) // length
PUSH1(0x00) // offset
RETURN
.mstore(0x00, 0x00)
.return_bytecode(0x00, 0x01)
};

// code_a calls code_b which executes code_creator in CREATE2
Expand Down Expand Up @@ -632,12 +624,8 @@ fn tracer_err_code_store_out_of_gas() {
// exhaust the gas to store the code.
let code_len = 0x100;
let code_creator = bytecode! {
PUSH1(Word::zero()) // value
PUSH32(code_len) // offset
MSTORE
PUSH32(code_len) // length
PUSH1(0x00) // offset
RETURN
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
};

// code_a calls code_b which executes code_creator in CREATE
Expand Down Expand Up @@ -729,12 +717,8 @@ fn tracer_err_code_store_out_of_gas_tx_deploy() {
// exhaust the gas to store the code.
let code_len = 0x100;
let code_creator = bytecode! {
PUSH1(Word::zero()) // value
PUSH32(code_len) // offset
MSTORE
PUSH32(code_len) // length
PUSH1(0x00) // offset
RETURN
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
};

// Get the execution steps from the external tracer
Expand Down Expand Up @@ -794,12 +778,8 @@ fn tracer_err_invalid_code() {
// code_creator outputs byte array that starts with 0xef, which is
// invalid code.
let code_creator = bytecode! {
PUSH32(word!("0xef00000000000000000000000000000000000000000000000000000000000000")) // value
PUSH1(0x00) // offset
MSTORE
PUSH1(0x01) // length
PUSH1(0x00) // offset
RETURN
.mstore(0x00, word!("0xef00000000000000000000000000000000000000000000000000000000000000"))
.return_bytecode(0x00, 0x01)
};

// code_a calls code_b which executes code_creator in CREATE
Expand Down Expand Up @@ -900,12 +880,8 @@ fn tracer_err_max_code_size_exceeded() {
// trigger the max code size limit.
let code_len = 0x6000 + 1;
let code_creator = bytecode! {
PUSH1(Word::zero()) // value
PUSH32(code_len) // offset
MSTORE
PUSH32(code_len) // length
PUSH1(0x00) // offset
RETURN
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
};

// code_a calls code_b which executes code_creator in CREATE
Expand Down Expand Up @@ -997,12 +973,8 @@ fn tracer_err_max_code_size_exceeded_tx_deploy() {
// trigger the max code size limit.
let code_len = 0x6000 + 1;
let code_creator = bytecode! {
PUSH1(Word::zero()) // value
PUSH32(code_len) // offset
MSTORE
PUSH32(code_len) // length
PUSH1(0x00) // offset
RETURN
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
};

// Get the execution steps from the external tracer
Expand Down Expand Up @@ -1050,9 +1022,7 @@ fn tracer_err_max_code_size_exceeded_tx_deploy() {
fn tracer_create_stop() {
// code_creator doesn't output anything because it stops.
let code_creator = bytecode! {
PUSH32(word!("0xef00000000000000000000000000000000000000000000000000000000000000")) // value
PUSH1(0x00) // offset
MSTORE
.mstore(0x00, word!("0xef00000000000000000000000000000000000000000000000000000000000000"))
PUSH1(0x01) // length
PUSH1(0x00) // offset
STOP
Expand Down Expand Up @@ -1451,12 +1421,8 @@ fn tracer_err_return_data_out_of_bounds() {
PUSH2(0xaa)
};
let code_b = bytecode! {
PUSH2(0x42) // value
PUSH2(0x00) // offset
MSTORE
PUSH1(0x01) // length
PUSH1(0x00) // offset
RETURN
.mstore(0x00, 0x42)
.return_bytecode(0x00, 0x01)
};
// Get the execution steps from the external tracer
let block: GethData = TestContext::<3, 2>::new_with_logger_config(
Expand Down Expand Up @@ -1510,9 +1476,7 @@ fn tracer_err_gas_uint_overflow() {
// MSTORE a value at an offset so high that the gast cost is big enough
// to overflow an uint64
let code = bytecode! {
PUSH32(0x42) // value
PUSH32(0x100_0000_0000_0000_0000_u128) // offset
MSTORE
.mstore(0x100_0000_0000_0000_0000_u128, 0x42)
};
let block: GethData = TestContext::<2, 1>::new_with_logger_config(
None,
Expand Down Expand Up @@ -1789,12 +1753,8 @@ fn tracer_err_stack_underflow() {
fn create2_address() {
// code_creator outputs 0x6050.
let code_creator = bytecode! {
PUSH32(word!("0x6050000000000000000000000000000000000000000000000000000000000000")) // value
PUSH1(0x00) // offset
MSTORE
PUSH1(0x02) // length
PUSH1(0x00) // offset
RETURN
.mstore(0x00, word!("0x6050000000000000000000000000000000000000000000000000000000000000"))
.return_bytecode(0x00, 0x02)
};

// code_a calls code_b which executes code_creator in CREATE
Expand Down Expand Up @@ -1891,12 +1851,8 @@ fn create2_address() {
fn create_address() {
// code_creator outputs 0x6050.
let code_creator = bytecode! {
PUSH32(word!("0x6050000000000000000000000000000000000000000000000000000000000000")) // value
PUSH1(0x00) // offset
MSTORE
PUSH1(0x02) // length
PUSH1(0x00) // offset
RETURN
.mstore(0x00, word!("0x6050000000000000000000000000000000000000000000000000000000000000"))
.return_bytecode(0x00, 0x02)
};

// code_a calls code_b which executes code_creator in CREATE
Expand Down Expand Up @@ -2021,9 +1977,7 @@ fn test_gen_access_trace() {
PUSH2(0xaa)
};
let code_b = bytecode! {
PUSH32(word!("0x1234567890000000000000000000abcdef000000000000000000112233445566")) // value
PUSH1(0x01) // offset
MSTORE
.mstore(0x01, word!("0x1234567890000000000000000000abcdef000000000000000000112233445566"))
PUSH1(0x01) // value
PUSH1(0x02) // key
SSTORE
Expand Down
6 changes: 2 additions & 4 deletions bus-mapping/src/evm/opcodes/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,12 @@ mod balance_tests {
let mut code = Bytecode::default();
if is_warm {
code.append(&bytecode! {
PUSH20(address.to_word())
BALANCE
.balance(address)
POP
});
}
code.append(&bytecode! {
PUSH20(address.to_word())
BALANCE
.balance(address)
STOP
});

Expand Down
75 changes: 24 additions & 51 deletions bus-mapping/src/evm/opcodes/calldatacopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,14 @@ mod calldatacopy_tests {
bytecode,
evm_types::{OpcodeId, StackAddress},
geth_types::GethData,
ToWord, Word,
Word,
};

use mock::test_ctx::{helpers::*, TestContext};
use mock::{
generate_mock_call_bytecode,
test_ctx::{helpers::*, TestContext},
MockCallBytecodeParams,
};
use pretty_assertions::assert_eq;

#[test]
Expand All @@ -198,10 +202,7 @@ mod calldatacopy_tests {
let offset = 0x00usize;
let copy_size = 0x10usize;
let code_b = bytecode! {
PUSH32(copy_size) // size
PUSH32(offset) // offset
PUSH32(dst_offset) // dst_offset
CALLDATACOPY
.calldatacopy(dst_offset, offset, copy_size)
STOP
};

Expand All @@ -211,24 +212,16 @@ mod calldatacopy_tests {
.take(24)
.chain(pushdata.clone())
.collect::<Vec<u8>>();

let call_data_length = 0x20usize;
let call_data_offset = 0x10usize;
let code_a = bytecode! {
// populate memory in A's context.
PUSH8(Word::from_big_endian(&pushdata))
PUSH1(0x00) // offset
MSTORE
// call addr_b.
PUSH1(0x00) // retLength
PUSH1(0x00) // retOffset
PUSH1(call_data_length) // argsLength
PUSH1(call_data_offset) // argsOffset
PUSH1(0x00) // value
PUSH32(addr_b.to_word()) // addr
PUSH32(0x1_0000) // gas
CALL
STOP
};
let code_a = generate_mock_call_bytecode(MockCallBytecodeParams {
address: addr_b,
pushdata,
call_data_length,
call_data_offset,
..MockCallBytecodeParams::default()
});

// Get the execution steps from the external tracer
let block: GethData = TestContext::<3, 1>::new(
Expand Down Expand Up @@ -384,14 +377,8 @@ mod calldatacopy_tests {
let (addr_a, addr_b) = (mock::MOCK_ACCOUNTS[0], mock::MOCK_ACCOUNTS[1]);

// code B gets called by code A, so the call is an internal call.
let dst_offset = 0x00usize;
let offset = 0x00usize;
let copy_size = 0x50usize;
let code_b = bytecode! {
PUSH32(copy_size) // size
PUSH32(offset) // offset
PUSH32(dst_offset) // dst_offset
CALLDATACOPY
.calldatacopy(0x00usize, 0x00usize, 0x50usize)
STOP
};

Expand All @@ -401,24 +388,13 @@ mod calldatacopy_tests {
.take(24)
.chain(pushdata.clone())
.collect::<Vec<u8>>();
let call_data_length = 0x20usize;
let call_data_offset = 0x10usize;
let code_a = bytecode! {
// populate memory in A's context.
PUSH8(Word::from_big_endian(&pushdata))
PUSH1(0x00) // offset
MSTORE
// call addr_b.
PUSH1(0x00) // retLength
PUSH1(0x00) // retOffset
PUSH1(call_data_length) // argsLength
PUSH1(call_data_offset) // argsOffset
PUSH1(0x00) // value
PUSH32(addr_b.to_word()) // addr
PUSH32(0x1_0000) // gas
CALL
STOP
};
let code_a = generate_mock_call_bytecode(MockCallBytecodeParams {
address: addr_b,
pushdata,
call_data_length: 0x20usize,
call_data_offset: 0x10usize,
..MockCallBytecodeParams::default()
});

// Get the execution steps from the external tracer
let block: GethData = TestContext::<3, 1>::new(
Expand Down Expand Up @@ -452,10 +428,7 @@ mod calldatacopy_tests {
let calldata = vec![1, 3, 5, 7, 9, 2, 4, 6, 8];
let calldata_len = calldata.len();
let code = bytecode! {
PUSH32(size)
PUSH32(offset)
PUSH32(dst_offset)
CALLDATACOPY
.calldatacopy(dst_offset, offset, size)
STOP
};

Expand Down
30 changes: 12 additions & 18 deletions bus-mapping/src/evm/opcodes/calldataload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,12 @@ mod calldataload_tests {
bytecode,
evm_types::{OpcodeId, StackAddress},
geth_types::GethData,
ToWord, Word,
Word,
};
use mock::{
generate_mock_call_bytecode, test_ctx::helpers::account_0_code_account_1_no_code,
MockCallBytecodeParams, TestContext,
};
use mock::{test_ctx::helpers::account_0_code_account_1_no_code, TestContext};
use rand::random;

use crate::{circuit_input_builder::ExecState, mock::BlockData, operation::StackOp};
Expand Down Expand Up @@ -138,22 +141,13 @@ mod calldataload_tests {
if memory_a.len() < call_data_length {
memory_a.resize(call_data_length, 0);
}
let code_a = bytecode! {
// populate memory in A's context.
PUSH32(Word::from_big_endian(&pushdata))
PUSH1(0x00) // offset
MSTORE
// call addr_b
PUSH1(0x00) // retLength
PUSH1(0x00) // retOffset
PUSH1(call_data_length) // argsLength
PUSH1(call_data_offset) // argsOffset
PUSH1(0x00) // value
PUSH32(addr_b.to_word()) // addr
PUSH32(0x1_0000) // gas
CALL
STOP
};
let code_a = generate_mock_call_bytecode(MockCallBytecodeParams {
address: addr_b,
pushdata,
call_data_length,
call_data_offset,
..MockCallBytecodeParams::default()
});

// Get the execution steps from the external tracer
let block: GethData = TestContext::<3, 1>::new(
Expand Down
6 changes: 3 additions & 3 deletions bus-mapping/src/evm/opcodes/error_return_data_outofbound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,16 @@ impl Opcode for ErrorReturnDataOutOfBound {
mod tests {
use super::*;
use crate::{circuit_input_builder::ExecState, mock::BlockData, operation::RW};
use eth_types::{bytecode, evm_types::OpcodeId, geth_types::GethData, word};
use eth_types::{bytecode, evm_types::OpcodeId, geth_types::GethData};
use mock::{
test_ctx::helpers::{account_0_code_account_1_no_code, tx_from_1_to_0},
TestContext,
TestContext, MOCK_DEPLOYED_CONTRACT_BYTECODE,
};

#[test]
fn test_returndata_error() {
let code = bytecode! {
PUSH21(word!("6B6020600060003760206000F3600052600C6014F3"))
PUSH21(*MOCK_DEPLOYED_CONTRACT_BYTECODE)
PUSH1(0)
MSTORE

Expand Down
Loading

0 comments on commit fa320ea

Please sign in to comment.