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

Commit 52426de

Browse files
committed
Merge branch 'word_hi_lo' of https://github.com/scroll-tech/zkevm-circuits into word_hi_lo
2 parents d566e26 + 9a02431 commit 52426de

File tree

1 file changed

+62
-57
lines changed
  • zkevm-circuits/src/evm_circuit/execution

1 file changed

+62
-57
lines changed

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

+62-57
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@ use crate::{
1313
Transition::{Delta, To},
1414
},
1515
math_gadget::{
16-
ConstantDivisionGadget, ContractCreateGadget, IsZeroWordGadget, LtGadget,
17-
LtWordGadget,
16+
ConstantDivisionGadget, ContractCreateGadget, IsEqualWordGadget, IsZeroGadget,
17+
IsZeroWordGadget, LtGadget, LtWordGadget,
1818
},
1919
memory_gadget::{
2020
CommonMemoryAddressGadget, MemoryAddressGadget, MemoryExpansionGadget,
2121
},
22-
not, AccountAddress, CachedRegion, Cell, StepRws,
22+
not, or, AccountAddress, CachedRegion, Cell, StepRws,
2323
},
2424
witness::{Block, Call, ExecStep, Transaction},
2525
},
@@ -75,7 +75,9 @@ pub(crate) struct CreateGadget<F, const IS_CREATE2: bool, const S: ExecutionStat
7575
is_depth_in_range: LtGadget<F, N_BYTES_U64>,
7676
is_insufficient_balance: LtWordGadget<F>,
7777
is_nonce_in_range: LtGadget<F, N_BYTES_U64>,
78-
not_address_collision: IsZeroWordGadget<F, Word<Expression<F>>>,
78+
// both is_callee_once_zero and is_empty_callee_prev_hash are for checking address collision.
79+
is_callee_once_zero: IsZeroGadget<F>,
80+
is_empty_callee_prev_hash: IsEqualWordGadget<F, Word<Expression<F>>, Word<Expression<F>>>,
7981

8082
memory_expansion: MemoryExpansionGadget<F, 1, N_BYTES_MEMORY_WORD_SIZE>,
8183
gas_left: ConstantDivisionGadget<F, N_BYTES_GAS>,
@@ -261,61 +263,61 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
261263
let prev_keccak_code_hash = cb.query_word_unchecked();
262264
let callee_nonce = cb.query_cell();
263265

266+
let is_callee_once_zero = IsZeroGadget::construct(cb, callee_nonce.expr());
267+
let is_empty_callee_prev_hash =
268+
IsEqualWordGadget::construct(cb, &prev_code_hash.to_word(), &cb.empty_code_hash());
264269
// callee address's nonce
265-
let (prev_code_hash_is_zero, not_address_collision) =
266-
cb.condition(is_precheck_ok.expr(), |cb| {
267-
// increase caller's nonce
268-
cb.account_write(
269-
create.caller_address(),
270-
AccountFieldTag::Nonce,
271-
Word::from_lo_unchecked(caller_nonce.expr() + 1.expr()),
272-
Word::from_lo_unchecked(caller_nonce.expr()),
273-
Some(&mut reversion_info),
274-
);
270+
let prev_code_hash_is_zero = cb.condition(is_precheck_ok.expr(), |cb| {
271+
// increase caller's nonce
272+
cb.account_write(
273+
create.caller_address(),
274+
AccountFieldTag::Nonce,
275+
Word::from_lo_unchecked(caller_nonce.expr() + 1.expr()),
276+
Word::from_lo_unchecked(caller_nonce.expr()),
277+
Some(&mut reversion_info),
278+
);
275279

276-
// add callee to access list
277-
cb.account_access_list_write_unchecked(
278-
tx_id.expr(),
279-
contract_addr.to_word(),
280-
1.expr(),
281-
was_warm.expr(),
282-
Some(&mut reversion_info),
283-
);
280+
// add callee to access list
281+
cb.account_access_list_write_unchecked(
282+
tx_id.expr(),
283+
contract_addr.to_word(),
284+
1.expr(),
285+
was_warm.expr(),
286+
Some(&mut reversion_info),
287+
);
284288

285-
// read contract's previous hash
289+
// read contract's previous hash
290+
cb.account_read(
291+
contract_addr.to_word(),
292+
AccountFieldTag::CodeHash,
293+
prev_code_hash.to_word(),
294+
);
295+
296+
let prev_code_hash_is_zero = IsZeroWordGadget::construct(cb, &prev_code_hash);
297+
cb.condition(not::expr(prev_code_hash_is_zero.expr()), |cb| {
286298
cb.account_read(
287299
contract_addr.to_word(),
288-
AccountFieldTag::CodeHash,
289-
prev_code_hash.to_word(),
300+
AccountFieldTag::Nonce,
301+
Word::from_lo_unchecked(callee_nonce.expr()),
290302
);
291-
292-
let prev_code_hash_is_zero = IsZeroWordGadget::construct(cb, &prev_code_hash);
293-
cb.condition(not::expr(prev_code_hash_is_zero.expr()), |cb| {
294-
cb.account_read(
295-
contract_addr.to_word(),
296-
AccountFieldTag::Nonce,
297-
Word::from_lo_unchecked(callee_nonce.expr()),
298-
);
299-
});
300-
// ErrContractAddressCollision, if any one of following criteria meets.
301-
// Nonce is not zero or account code hash is not either 0 or EMPTY_CODE_HASH.
302-
// Here use `isZeroGadget(callee_nonce + prev_code_hash * (prev_code_hash -
303-
// empty_code_hash))` to represent `(callee_nonce == 0 && (prev_code_hash == 0
304-
// or prev_code_hash == empty_code_hash))`
305-
let prev_code_hash_word = prev_code_hash.to_word();
306-
(
307-
prev_code_hash_is_zero,
308-
IsZeroWordGadget::construct(
309-
cb,
310-
&Word::from_lo_unchecked(callee_nonce.expr()).add_unchecked(
311-
prev_code_hash_word.clone().mul_unchecked(
312-
prev_code_hash_word.sub_unchecked(cb.empty_code_hash()),
313-
),
314-
),
315-
),
316-
)
317303
});
318304

305+
prev_code_hash_is_zero
306+
});
307+
308+
// ErrContractAddressCollision, if any one of following criteria meets.
309+
// Nonce is not zero or account code hash is not either 0 or EMPTY_CODE_HASH.
310+
// Here use `isZeroGadget(callee_nonce + prev_code_hash * (prev_code_hash -
311+
// empty_code_hash))` to represent `(callee_nonce == 0 && (prev_code_hash == 0
312+
// or prev_code_hash == empty_code_hash))`
313+
let not_address_collision = and::expr([
314+
is_callee_once_zero.expr(),
315+
or::expr([
316+
is_empty_callee_prev_hash.expr(),
317+
prev_code_hash_is_zero.expr(),
318+
]),
319+
]);
320+
319321
for (field_tag, value) in [
320322
(
321323
CallContextFieldTag::ProgramCounter,
@@ -601,7 +603,9 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
601603
callee_nonce,
602604
keccak_code_hash,
603605
keccak_output,
604-
not_address_collision,
606+
//not_address_collision,
607+
is_callee_once_zero,
608+
is_empty_callee_prev_hash,
605609
is_success,
606610
prev_code_hash,
607611
prev_code_hash_is_zero,
@@ -694,14 +698,15 @@ impl<F: Field, const IS_CREATE2: bool, const S: ExecutionState> ExecutionGadget<
694698
.assign_u256(region, offset, callee_prev_code_hash)?;
695699
self.prev_code_hash_is_zero
696700
.assign_u256(region, offset, callee_prev_code_hash)?;
697-
self.not_address_collision.assign_u256(
701+
702+
self.is_callee_once_zero
703+
.assign(region, offset, F::from(callee_nonce))?;
704+
self.is_empty_callee_prev_hash.assign_u256(
698705
region,
699706
offset,
700-
U256::from(callee_nonce)
701-
+ callee_prev_code_hash
702-
* (CodeDB::empty_code_hash().to_word() - callee_prev_code_hash),
707+
callee_prev_code_hash,
708+
CodeDB::empty_code_hash().to_word(),
703709
)?;
704-
705710
let shift = init_code_start.low_u64() % 32;
706711
let copy_rw_increase: u64 = step.copy_rw_counter_delta;
707712
let values: Vec<u8> = if is_precheck_ok {

0 commit comments

Comments
 (0)