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

Commit 2c8c749

Browse files
lightsinglispc
andauthored
add create2 deploy to non-zero balance address test (#727)
* add create2 deploy to non-zero balance address * replace TransferGadget * replace TransferGadget * reuse name construct --------- Co-authored-by: Zhang Zhuo <[email protected]>
1 parent 5740543 commit 2c8c749

File tree

3 files changed

+213
-165
lines changed

3 files changed

+213
-165
lines changed

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ pub(crate) struct CallOpGadget<F> {
5959
is_warm_prev: Cell<F>,
6060
callee_reversion_info: ReversionInfo<F>,
6161
transfer: TransferGadget<F>,
62+
code_hash_previous: Cell<F>,
63+
#[cfg(feature = "scroll")]
64+
keccak_code_hash_previous: Cell<F>,
6265
// current handling Call* opcode's caller balance
6366
caller_balance_word: Word<F>,
6467
// check if insufficient balance case
@@ -231,6 +234,8 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
231234
// skip the transfer (this is necessary for non-existing accounts, which
232235
// will not be crated when value is 0 and so the callee balance lookup
233236
// would be invalid).
237+
let code_hash_previous = cb.query_cell();
238+
let keccak_code_hash_previous = cb.query_cell_phase2();
234239
let transfer = cb.condition(and::expr(&[is_call.expr(), is_precheck_ok.expr()]), |cb| {
235240
TransferGadget::construct(
236241
cb,
@@ -241,6 +246,9 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
241246
is_precompile.expr(),
242247
]),
243248
0.expr(),
249+
code_hash_previous.expr(),
250+
#[cfg(feature = "scroll")]
251+
keccak_code_hash_previous.expr(),
244252
call_gadget.value.clone(),
245253
&mut callee_reversion_info,
246254
)
@@ -707,6 +715,9 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
707715
is_warm_prev,
708716
callee_reversion_info,
709717
transfer,
718+
code_hash_previous,
719+
#[cfg(feature = "scroll")]
720+
keccak_code_hash_previous,
710721
caller_balance_word,
711722
is_insufficient_balance,
712723
is_depth_ok,
@@ -817,9 +828,25 @@ impl<F: Field> ExecutionGadget<F> for CallOpGadget<F> {
817828
let (caller_balance_pair, callee_balance_pair) =
818829
if is_call && is_precheck_ok && !value.is_zero() {
819830
if !callee_exists {
831+
let code_hash_previous = block.rws[step.rw_indices[19 + rw_offset]]
832+
.account_codehash_pair()
833+
.1;
834+
self.code_hash_previous.assign(
835+
region,
836+
offset,
837+
region.word_rlc(code_hash_previous),
838+
)?;
820839
rw_offset += 2; // codehash read and write
821840
#[cfg(feature = "scroll")]
822841
{
842+
let keccak_code_hash_previous = block.rws[step.rw_indices[19 + rw_offset]]
843+
.account_keccak_codehash_pair()
844+
.1;
845+
self.keccak_code_hash_previous.assign(
846+
region,
847+
offset,
848+
region.word_rlc(keccak_code_hash_previous),
849+
)?;
823850
rw_offset += 2; // keccak codehash read and write
824851
}
825852
}

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

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ use eth_types::{
3434
use ethers_core::utils::keccak256;
3535
use gadgets::util::{and, expr_from_bytes};
3636
use halo2_proofs::{circuit::Value, plonk::Error};
37-
3837
use log::trace;
3938
use std::iter::once;
4039

@@ -68,6 +67,8 @@ pub(crate) struct CreateGadget<F, const IS_CREATE2: bool, const S: ExecutionStat
6867
keccak_output: Word<F>,
6968
// prevous code hash befor creating
7069
code_hash_previous: Cell<F>,
70+
#[cfg(feature = "scroll")]
71+
keccak_code_hash_previous: Cell<F>,
7172
code_hash_is_empty: IsEqualGadget<F>,
7273
code_hash_is_zero: IsZeroGadget<F>,
7374
copy_rwc_inc: Cell<F>,
@@ -84,6 +85,8 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
8485
// Use rw_counter of the step which triggers next call as its call_id.
8586
let callee_call_id = cb.curr.state.rw_counter.clone();
8687
let code_hash_previous = cb.query_cell();
88+
#[cfg(feature = "scroll")]
89+
let keccak_code_hash_previous = cb.query_cell_phase2();
8790
let opcode = cb.query_cell();
8891
let copy_rwc_inc = cb.query_cell();
8992

@@ -312,6 +315,9 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
312315
new_address.clone(),
313316
0.expr(),
314317
1.expr(),
318+
code_hash_previous.expr(),
319+
#[cfg(feature = "scroll")]
320+
keccak_code_hash_previous.expr(),
315321
value.clone(),
316322
&mut callee_reversion_info,
317323
);
@@ -509,6 +515,8 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
509515
keccak_code_hash,
510516
keccak_output,
511517
code_hash_previous,
518+
#[cfg(feature = "scroll")]
519+
keccak_code_hash_previous,
512520
code_hash_is_empty,
513521
code_hash_is_zero,
514522
copy_rwc_inc,
@@ -669,6 +677,14 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
669677
rw_offset += 2;
670678
#[cfg(feature = "scroll")]
671679
{
680+
let keccak_code_hash_previous = block.rws[step.rw_indices[16 + rw_offset]]
681+
.account_keccak_codehash_pair()
682+
.1;
683+
self.keccak_code_hash_previous.assign(
684+
region,
685+
offset,
686+
region.word_rlc(keccak_code_hash_previous),
687+
)?;
672688
rw_offset += 2; // Read Write empty Keccak code hash.
673689
}
674690
let [caller_balance_pair, callee_balance_pair] = if !value.is_zero() {
@@ -800,7 +816,7 @@ mod test {
800816
static ref CALLER_ADDRESS: Address = address!("0x00bbccddee000000000000000000000000002400");
801817
}
802818

803-
fn run_test_circuits(ctx: TestContext<2, 1>) {
819+
fn run_test_circuits<const NACC: usize, const NTX: usize>(ctx: TestContext<NACC, NTX>) {
804820
CircuitTestBuilder::new_from_test_ctx(ctx)
805821
.params(CircuitsParams {
806822
max_rws: 70_000,
@@ -1092,4 +1108,44 @@ mod test {
10921108
run_test_circuits(test_context(caller));
10931109
});
10941110
}
1111+
1112+
#[test]
1113+
fn test_create2_deploy_to_non_zero_balance_address() {
1114+
let initialization_code = initialization_bytecode(true);
1115+
let root_code = creater_bytecode(initialization_code, 0.into(), true, true);
1116+
let caller = Account {
1117+
address: *CALLER_ADDRESS,
1118+
code: root_code.into(),
1119+
nonce: Word::one(),
1120+
balance: eth(10),
1121+
..Default::default()
1122+
};
1123+
let ctx = TestContext::<3, 1>::new(
1124+
None,
1125+
|accs| {
1126+
accs[0]
1127+
.address(address!("0x000000000000000000000000000000000000cafe"))
1128+
.balance(eth(10));
1129+
accs[1].account(&caller);
1130+
accs[2]
1131+
.address(address!("0x4e74035cefd0998ea16ab5145f7713620a9eb0c5"))
1132+
.balance(eth(10));
1133+
},
1134+
|mut txs, accs| {
1135+
txs[0]
1136+
.from(accs[0].address)
1137+
.to(accs[1].address)
1138+
.gas(word!("0x2386F26FC10000"));
1139+
},
1140+
|block, _| block,
1141+
)
1142+
.unwrap();
1143+
CircuitTestBuilder::new_from_test_ctx(ctx)
1144+
.params(CircuitsParams {
1145+
max_rws: 200,
1146+
max_copy_rows: 200,
1147+
..Default::default()
1148+
})
1149+
.run();
1150+
}
10951151
}

0 commit comments

Comments
 (0)