Skip to content

Commit

Permalink
[refactor] refactor and add more helper in Bytecode (privacy-scaling-…
Browse files Browse the repository at this point in the history
…explorations#1365)

### Description

Refactor and add more helper functions to Bytecode:
- Removed several functions such as `call`, `balance`, `mstore`,
`calldatacopy`, and `return_bytecode`
- Added `op_jumpdest` function
- Implemented `impl_push_n` macro to generate functions for `op_push1`
to `op_push32`
- Implemented `impl_other_opcodes` macro to generate functions for
various opcodes like `op_stop`, `op_add`, `op_mul`, `op_sub`, and so on
- Renamed opcode helper functions to `op_{opcode}` for consistency and
clarity

### Issue Link

N/A

### Type of change

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] This change requires a documentation update

### Contents

- Removal of several functions
- Addition of `op_jumpdest` function
- Implementation of `impl_push_n` macro to generate functions for
`op_push1` to `op_push32`
- Implementation of `impl_other_opcodes` macro to generate functions for
various opcodes
- Renaming of opcode helper functions

### Rationale

This refactor improves the code by removing unused functions, adding a
new function, and implementing macros to generate functions for opcodes.
The renaming of the opcode helper functions to `op_{opcode}` provides
consistency and clarity to the codebase.

### How Has This Been Tested?

https://github.com/scroll-tech/zkevm-circuits/actions/runs/4751119765
  • Loading branch information
lightsing authored Apr 21, 2023
1 parent e55ba06 commit 4e64bdb
Show file tree
Hide file tree
Showing 23 changed files with 268 additions and 175 deletions.
98 changes: 36 additions & 62 deletions bus-mapping/src/circuit_input_builder/tracer_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -357,8 +357,8 @@ fn tracer_err_address_collision() {
// that outputs the same, which will lead to the same new
// contract address.
let code_creator = bytecode! {
.mstore(0x00, 0x00)
.return_bytecode(0x00, 0x01)
.op_mstore(0x00, 0x00)
.op_return(0x00, 0x01)
};

// code_a calls code_b which executes code_creator in CREATE2
Expand All @@ -385,9 +385,7 @@ fn tracer_err_address_collision() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH3(0x123456) // salt
Expand Down Expand Up @@ -484,8 +482,8 @@ fn tracer_create_collision_free() {
// that outputs not the same, which will lead to the different new
// contract address.
let code_creator = bytecode! {
.mstore(0x00, 0x00)
.return_bytecode(0x00, 0x01)
.op_mstore(0x00, 0x00)
.op_return(0x00, 0x01)
};

// code_a calls code_b which executes code_creator in CREATE2
Expand All @@ -512,9 +510,7 @@ fn tracer_create_collision_free() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH1(len) // length
Expand Down Expand Up @@ -624,8 +620,8 @@ fn tracer_err_code_store_out_of_gas() {
// exhaust the gas to store the code.
let code_len = 0x100;
let code_creator = bytecode! {
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
.op_mstore(code_len, Word::zero())
.op_return(0x00, code_len)
};

// code_a calls code_b which executes code_creator in CREATE
Expand All @@ -652,9 +648,7 @@ fn tracer_err_code_store_out_of_gas() {
.chain(0..(32 - len % 32) as u8)
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH32(len) // length
Expand Down Expand Up @@ -717,8 +711,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! {
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
.op_mstore(code_len, Word::zero())
.op_return(0x00, code_len)
};

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

// code_a calls code_b which executes code_creator in CREATE
Expand All @@ -806,9 +800,7 @@ fn tracer_err_invalid_code() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH1(len) // length
Expand Down Expand Up @@ -880,8 +872,8 @@ fn tracer_err_max_code_size_exceeded() {
// trigger the max code size limit.
let code_len = 0x6000 + 1;
let code_creator = bytecode! {
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
.op_mstore(code_len, Word::zero())
.op_return(0x00, code_len)
};

// code_a calls code_b which executes code_creator in CREATE
Expand All @@ -908,9 +900,7 @@ fn tracer_err_max_code_size_exceeded() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH32(len) // length
Expand Down Expand Up @@ -973,8 +963,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! {
.mstore(code_len, Word::zero())
.return_bytecode(0x00, code_len)
.op_mstore(code_len, Word::zero())
.op_return(0x00, code_len)
};

// Get the execution steps from the external tracer
Expand Down Expand Up @@ -1022,7 +1012,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! {
.mstore(0x00, word!("0xef00000000000000000000000000000000000000000000000000000000000000"))
.op_mstore(0x00, word!("0xef00000000000000000000000000000000000000000000000000000000000000"))
PUSH1(0x01) // length
PUSH1(0x00) // offset
STOP
Expand Down Expand Up @@ -1052,9 +1042,7 @@ fn tracer_create_stop() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH1(len) // length
Expand Down Expand Up @@ -1421,8 +1409,8 @@ fn tracer_err_return_data_out_of_bounds() {
PUSH2(0xaa)
};
let code_b = bytecode! {
.mstore(0x00, 0x42)
.return_bytecode(0x00, 0x01)
.op_mstore(0x00, 0x42)
.op_return(0x00, 0x01)
};
// Get the execution steps from the external tracer
let block: GethData = TestContext::<3, 2>::new_with_logger_config(
Expand Down Expand Up @@ -1476,7 +1464,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! {
.mstore(0x100_0000_0000_0000_0000_u128, 0x42)
.op_mstore(0x100_0000_0000_0000_0000_u128, 0x42)
};
let block: GethData = TestContext::<2, 1>::new_with_logger_config(
None,
Expand Down Expand Up @@ -1515,7 +1503,7 @@ fn tracer_err_gas_uint_overflow() {
fn tracer_err_invalid_opcode() {
// The second opcode is invalid (0x0f)
let mut code = bytecode::Bytecode::default();
code.write_op(OpcodeId::PC);
code.op_pc();
code.write(0x0f, true);
let block: GethData = TestContext::<2, 1>::new_with_logger_config(
None,
Expand Down Expand Up @@ -1572,19 +1560,11 @@ fn tracer_err_write_protection(is_call: bool) {

PUSH2(0xaa)
};
let mut code_b = bytecode! {
PUSH1(0x01) // value
PUSH1(0x02) // key
};
let mut code_b = Bytecode::default();
if is_call {
code_b.push(1, Word::zero());
code_b.push(1, Word::from(0x20));
code_b.push(1, Word::from(0x10)); // value
code_b.push(32, *WORD_ADDR_B); // addr
code_b.push(32, Word::from(0x1000)); // gas
code_b.write_op(OpcodeId::CALL);
code_b.op_call(0x1000, *WORD_ADDR_B, 0x10, 0x20, 0, 0x02, 0x01);
} else {
code_b.write_op(OpcodeId::SSTORE);
code_b.op_sstore(0x02, 0x01);
}
code_b.push(2, Word::from(0xbb));

Expand Down Expand Up @@ -1753,8 +1733,8 @@ fn tracer_err_stack_underflow() {
fn create2_address() {
// code_creator outputs 0x6050.
let code_creator = bytecode! {
.mstore(0x00, word!("0x6050000000000000000000000000000000000000000000000000000000000000"))
.return_bytecode(0x00, 0x02)
.op_mstore(0x00, word!("0x6050000000000000000000000000000000000000000000000000000000000000"))
.op_return(0x00, 0x02)
};

// code_a calls code_b which executes code_creator in CREATE
Expand All @@ -1781,9 +1761,7 @@ fn create2_address() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH3(0x123456) // salt
Expand Down Expand Up @@ -1851,8 +1829,8 @@ fn create2_address() {
fn create_address() {
// code_creator outputs 0x6050.
let code_creator = bytecode! {
.mstore(0x00, word!("0x6050000000000000000000000000000000000000000000000000000000000000"))
.return_bytecode(0x00, 0x02)
.op_mstore(0x00, word!("0x6050000000000000000000000000000000000000000000000000000000000000"))
.op_return(0x00, 0x02)
};

// code_a calls code_b which executes code_creator in CREATE
Expand All @@ -1879,9 +1857,7 @@ fn create_address() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
// We do CREATE 2 times to use a nonce != 0 in the second one.
let code_b_end = bytecode! {
Expand Down Expand Up @@ -1977,7 +1953,7 @@ fn test_gen_access_trace() {
PUSH2(0xaa)
};
let code_b = bytecode! {
.mstore(0x01, word!("0x1234567890000000000000000000abcdef000000000000000000112233445566"))
.op_mstore(0x01, word!("0x1234567890000000000000000000abcdef000000000000000000112233445566"))
PUSH1(0x01) // value
PUSH1(0x02) // key
SSTORE
Expand Down Expand Up @@ -2202,9 +2178,7 @@ fn test_gen_access_trace_create_push_call_stack() {
.chain(0u8..((32 - len % 32) as u8))
.collect();
for (index, word) in code_creator.chunks(32).enumerate() {
code_b.push(32, Word::from_big_endian(word));
code_b.push(32, Word::from(index * 32));
code_b.write_op(OpcodeId::MSTORE);
code_b.op_mstore(index * 32, Word::from_big_endian(word));
}
let code_b_end = bytecode! {
PUSH1(len) // length
Expand Down
4 changes: 2 additions & 2 deletions bus-mapping/src/evm/opcodes/balance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,12 +125,12 @@ mod balance_tests {
let mut code = Bytecode::default();
if is_warm {
code.append(&bytecode! {
.balance(address)
.op_balance(address)
POP
});
}
code.append(&bytecode! {
.balance(address)
.op_balance(address)
STOP
});

Expand Down
6 changes: 3 additions & 3 deletions bus-mapping/src/evm/opcodes/calldatacopy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ mod calldatacopy_tests {
let offset = 0x00usize;
let copy_size = 0x10usize;
let code_b = bytecode! {
.calldatacopy(dst_offset, offset, copy_size)
.op_calldatacopy(dst_offset, offset, copy_size)
STOP
};

Expand Down Expand Up @@ -378,7 +378,7 @@ mod calldatacopy_tests {

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

Expand Down Expand Up @@ -428,7 +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! {
.calldatacopy(dst_offset, offset, size)
.op_calldatacopy(dst_offset, offset, size)
STOP
};

Expand Down
2 changes: 1 addition & 1 deletion bus-mapping/src/evm/opcodes/logs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ mod log_tests {
code.push(32, Word::from(msize));
code.push(32, Word::from(mstart));
code.write_op(cur_op_code);
code.write_op(OpcodeId::STOP);
code.op_stop();

// prepare memory data
let pushdata = hex::decode("1234567890abcdef1234567890abcdef").unwrap();
Expand Down
4 changes: 1 addition & 3 deletions bus-mapping/src/evm/opcodes/sha3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,7 @@ pub mod sha3_tests {
mem_chunk.to_vec()
};
memory.extend_from_slice(&mem_value);
code.push(32, Word::from_big_endian(&mem_value));
code.push(32, 32 * i);
code.write_op(OpcodeId::MSTORE);
code.op_mstore(32 * i, Word::from_big_endian(&mem_value));
}
// append SHA3 related opcodes at the tail end.
let code_tail = bytecode! {
Expand Down
Loading

0 comments on commit 4e64bdb

Please sign in to comment.