Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Commit 7e5675c

Browse files
authored
fix some testcases in testool related to copy table (#653)
* should always expand * fix calldatacopy_d0(cdc_0_1_2)_g0_v0 * Revert "should always expand" This reverts commit 29f72ba. * fix outbounds * update test assertion * pass empty slice * fix * fix * fmt * add testcase of call_precompile_with_value * add testcase of test_oog_call_with_inner_sstore * fix busmapping assert * fix test_oog_call_with_inner_sstore * Revert "fix test_oog_call_with_inner_sstore" This reverts commit 63c26d1. * revert reversible_write_counter constraint * cleanup * cleanup
1 parent 2caf508 commit 7e5675c

File tree

4 files changed

+113
-6
lines changed

4 files changed

+113
-6
lines changed

bus-mapping/src/circuit_input_builder/input_state_ref.rs

+19-2
Original file line numberDiff line numberDiff line change
@@ -1844,12 +1844,21 @@ impl<'a> CircuitInputStateRef<'a> {
18441844
return Ok((vec![], vec![], vec![]));
18451845
}
18461846

1847+
let caller_memory = self.caller_ctx()?.memory.clone();
1848+
let call_data_length = self.call()?.call_data_length;
1849+
let call_data_offset = self.call()?.call_data_offset;
1850+
let call_data = if call_data_length != 0 {
1851+
let ends = call_data_offset + call_data_length;
1852+
&caller_memory.0[..ends as usize]
1853+
} else {
1854+
&caller_memory.0[..call_data_offset as usize]
1855+
};
18471856
let call_ctx = self.call_ctx_mut()?;
18481857
let (src_range, dst_range, write_slot_bytes) = combine_copy_slot_bytes(
18491858
src_addr.into().0,
18501859
dst_addr.into().0,
18511860
copy_length,
1852-
&call_ctx.call_data,
1861+
call_data,
18531862
&mut call_ctx.memory,
18541863
);
18551864

@@ -1897,12 +1906,20 @@ impl<'a> CircuitInputStateRef<'a> {
18971906
}
18981907

18991908
let last_callee_memory = self.call()?.last_callee_memory.clone();
1909+
let return_data_length = self.call()?.last_callee_return_data_length;
1910+
let return_data_offset = self.call()?.last_callee_return_data_offset;
1911+
let return_data: &[u8] = if return_data_length != 0 {
1912+
let ends = return_data_offset + return_data_length;
1913+
&last_callee_memory.0[..ends as usize]
1914+
} else {
1915+
&last_callee_memory.0[..return_data_offset as usize]
1916+
};
19001917
let call_ctx = self.call_ctx_mut()?;
19011918
let (src_range, dst_range, write_slot_bytes) = combine_copy_slot_bytes(
19021919
src_addr.into().0,
19031920
dst_addr.into().0,
19041921
copy_length,
1905-
&last_callee_memory.0,
1922+
return_data,
19061923
&mut call_ctx.memory,
19071924
);
19081925
let read_slot_bytes = self.call()?.last_callee_memory.read_chunk(src_range);

bus-mapping/src/evm/opcodes/callop.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
use eth_types::{
1414
evm_types::{
1515
gas_utils::{eip150_gas, memory_expansion_gas_cost},
16-
Gas, GasCost, OpcodeId,
16+
Gas, GasCost, OpcodeId, GAS_STIPEND_CALL_WITH_VALUE,
1717
},
1818
GethExecStep, ToWord, Word,
1919
};
@@ -461,7 +461,15 @@ impl<const N_ARGS: usize> Opcode for CallOpcode<N_ARGS> {
461461
state.handle_return(&mut precompile_step, geth_steps, true)?;
462462

463463
let real_cost = geth_steps[0].gas.0 - geth_steps[1].gas.0;
464-
debug_assert_eq!(real_cost, gas_cost + contract_gas_cost);
464+
debug_assert_eq!(
465+
real_cost
466+
+ if has_value && !callee_exists {
467+
GAS_STIPEND_CALL_WITH_VALUE
468+
} else {
469+
0
470+
},
471+
gas_cost + contract_gas_cost
472+
);
465473
exec_step.gas_cost = GasCost(gas_cost + contract_gas_cost);
466474
if real_cost != exec_step.gas_cost.0 {
467475
log::warn!(

zkevm-circuits/src/evm_circuit/execution/calldatacopy.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ impl<F: Field> ExecutionGadget<F> for CallDataCopyGadget<F> {
239239
mod test {
240240
use crate::{evm_circuit::test::rand_bytes, test_util::CircuitTestBuilder};
241241
use bus_mapping::circuit_input_builder::CircuitsParams;
242-
use eth_types::{bytecode, Word};
242+
use eth_types::{bytecode, word, Word};
243243
use mock::{
244244
generate_mock_call_bytecode,
245245
test_ctx::{helpers::*, TestContext},
@@ -363,4 +363,22 @@ mod test {
363363
test_root_ok(0x40, 0, 0x40.into(), Word::MAX);
364364
test_internal_ok(0x40, 0x40, 0, 0x10.into(), Word::MAX);
365365
}
366+
367+
#[test]
368+
fn calldatacopy_unaligned_data() {
369+
// calldatacopy_d0(cdc_0_1_2)_g0_v0
370+
test_internal_ok(0xf, 0x10, 2, 1.into(), 0x0.into());
371+
372+
// copy source out of bounds
373+
test_internal_ok(0xf, 0x10, 0x9, 0x20.into(), 0x0.into());
374+
375+
// calldatacopy_d4(cdc_0_neg6_ff)_g0_v0
376+
test_internal_ok(
377+
0xf,
378+
0x10,
379+
0x09,
380+
word!("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa"),
381+
0x0.into(),
382+
);
383+
}
366384
}

zkevm-circuits/src/evm_circuit/execution/callop.rs

+65-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
447447
// +15 call context lookups for precompile.
448448
let rw_counter_delta = 33.expr()
449449
+ is_call.expr() * 1.expr()
450-
+ transfer_rwc_delta
450+
+ transfer_rwc_delta.expr()
451451
+ is_callcode.expr()
452452
+ is_delegatecall.expr() * 2.expr()
453453
+ precompile_input_rws.expr()
@@ -1581,6 +1581,46 @@ mod test {
15811581
.run();
15821582
}
15831583

1584+
// minimal testool case: returndatasize_bug_d0_g0_v0
1585+
#[test]
1586+
fn test_oog_call_with_inner_sstore() {
1587+
let (addr_a, addr_b, addr_c) = (
1588+
mock::MOCK_ACCOUNTS[0],
1589+
mock::MOCK_ACCOUNTS[1],
1590+
mock::MOCK_ACCOUNTS[2],
1591+
);
1592+
let code_a = bytecode! {
1593+
.op_call(1, addr_b, 50000, 0, 0, 0, 0)
1594+
};
1595+
1596+
let code_b = bytecode! {
1597+
.op_call(10, 1, 50000, 0, 0, 0, 0)
1598+
.op_sstore(0, 0)
1599+
};
1600+
1601+
let ctx = TestContext::<3, 1>::new(
1602+
None,
1603+
|accs| {
1604+
accs[0]
1605+
.address(addr_a)
1606+
.balance(word!("0x0de0b6b3a7640000"))
1607+
.code(code_a);
1608+
accs[1].address(addr_b).code(code_b);
1609+
accs[2].address(addr_c).balance(word!("0x6400000000"));
1610+
},
1611+
|mut txs, accs| {
1612+
txs[0]
1613+
.from(accs[2].address)
1614+
.to(accs[0].address)
1615+
.gas(word!("0x0a00000000"));
1616+
},
1617+
|block, _tx| block.number(0xcafeu64),
1618+
)
1619+
.unwrap();
1620+
1621+
CircuitTestBuilder::new_from_test_ctx(ctx).run()
1622+
}
1623+
15841624
#[test]
15851625
fn callop_error_depth() {
15861626
let callee_code = bytecode! {
@@ -1632,6 +1672,30 @@ mod test_precompiles {
16321672
};
16331673
use paste::paste;
16341674

1675+
// FIXME: enable this test
1676+
#[ignore]
1677+
#[test]
1678+
fn call_precompile_with_value() {
1679+
let callee_code = bytecode! {
1680+
.op_call(0xc350, 0x4, 0x13, 0x0, 0x0, 0x0, 0x0)
1681+
};
1682+
1683+
let ctx = TestContext::<2, 1>::new(
1684+
None,
1685+
account_0_code_account_1_no_code(callee_code),
1686+
tx_from_1_to_0,
1687+
|block, _tx| block.number(0xcafeu64),
1688+
)
1689+
.unwrap();
1690+
1691+
CircuitTestBuilder::new_from_test_ctx(ctx)
1692+
.params(CircuitsParams {
1693+
max_rws: 500,
1694+
..Default::default()
1695+
})
1696+
.run();
1697+
}
1698+
16351699
fn test_precompile_inner(arg: PrecompileCallArgs, call_op: &OpcodeId) {
16361700
let code = arg.with_call_op(*call_op);
16371701
let ctx = TestContext::<2, 1>::new(

0 commit comments

Comments
 (0)