From 11be6eed1cca3bf4f9f470f364d41802214fe805 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 01:27:25 +0800 Subject: [PATCH 01/22] make balance update readable --- .../src/evm_circuit/execution/end_tx.rs | 5 ++-- .../src/evm_circuit/util/common_gadget.rs | 26 ++++--------------- .../evm_circuit/util/constraint_builder.rs | 21 +++++++++++++++ 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index 5f650f693a..0f04c6a71e 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -75,10 +75,9 @@ impl ExecutionGadget for EndTxGadget { tx_gas_price.clone(), effective_refund.min() + cb.curr.state.gas_left.expr(), ); - let gas_fee_refund = UpdateBalanceGadget::construct( - cb, + let gas_fee_refund = cb.increase_balance( tx_caller_address.to_word(), - vec![mul_gas_price_by_refund.product().clone()], + mul_gas_price_by_refund.product().clone(), None, ); diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 04ee168d49..8d00d8c201 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -309,7 +309,7 @@ impl pub(crate) fn construct( cb: &mut EVMConstraintBuilder, address: WordLoHi>, - updates: Vec>, + updates: &[Word32Cell], reversion_info: Option<&mut ReversionInfo>, ) -> Self { debug_assert!(updates.len() == N_ADDENDS - 1); @@ -397,12 +397,7 @@ impl TransferToGadget { ); } let receiver = cb.condition(not::expr(value_is_zero.expr()), |cb| { - UpdateBalanceGadget::construct( - cb, - receiver_address, - vec![value.clone()], - reversion_info, - ) + cb.increase_balance(receiver_address, value.clone(), reversion_info) }); Self { @@ -495,8 +490,7 @@ impl TransferWithGasFeeGadget { gas_fee: Word32Cell, reversion_info: &mut ReversionInfo, ) -> Self { - let sender_sub_fee = - UpdateBalanceGadget::construct(cb, sender_address.to_word(), vec![gas_fee], None); + let sender_sub_fee = cb.decrease_balance(sender_address.to_word(), gas_fee, None); let value_is_zero = cb.is_zero_word(&value); // If receiver doesn't exist, create it TransferToGadget::create_account( @@ -509,12 +503,7 @@ impl TransferWithGasFeeGadget { ); // Skip transfer if value == 0 let sender_sub_value = cb.condition(not::expr(value_is_zero.expr()), |cb| { - UpdateBalanceGadget::construct( - cb, - sender_address, - vec![value.clone()], - Some(reversion_info), - ) + cb.decrease_balance(sender_address, value.clone(), Some(reversion_info)) }); let receiver = TransferToGadget::construct( cb, @@ -630,12 +619,7 @@ impl TransferGadget { ); // Skip transfer if value == 0 let sender = cb.condition(not::expr(value_is_zero.expr()), |cb| { - UpdateBalanceGadget::construct( - cb, - sender_address, - vec![value.clone()], - Some(reversion_info), - ) + cb.decrease_balance(sender_address, value.clone(), Some(reversion_info)) }); let receiver = TransferToGadget::construct( cb, diff --git a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs index c7fce109ab..5e20bff23f 100644 --- a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs +++ b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs @@ -1,4 +1,5 @@ use super::{ + common_gadget::UpdateBalanceGadget, math_gadget::{ ConstantDivisionGadget, IsEqualGadget, IsEqualWordGadget, IsZeroGadget, IsZeroWordGadget, LtGadget, LtWordGadget, MinMaxGadget, @@ -639,6 +640,26 @@ impl<'a, F: Field> EVMConstraintBuilder<'a, F> { ConstantDivisionGadget::construct(self, numerator, denominator) } + // Common Gadget + + pub(crate) fn increase_balance( + &mut self, + address: WordLoHi>, + value: Word32Cell, + reversion_info: Option<&mut ReversionInfo>, + ) -> UpdateBalanceGadget { + UpdateBalanceGadget::construct(self, address, &[value], reversion_info) + } + + pub(crate) fn decrease_balance( + &mut self, + address: WordLoHi>, + value: Word32Cell, + reversion_info: Option<&mut ReversionInfo>, + ) -> UpdateBalanceGadget { + UpdateBalanceGadget::construct(self, address, &[value], reversion_info) + } + // Fixed pub(crate) fn range_lookup(&mut self, value: Expression, range: u64) { From 28112287b20a65d4e76a8b1b954b4c0208c42aa5 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 01:38:22 +0800 Subject: [PATCH 02/22] visibility control --- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 8d00d8c201..fa4519179d 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -371,7 +371,7 @@ pub(crate) struct TransferToGadget { receiver: UpdateBalanceGadget, receiver_exists: Expression, must_create: Expression, - pub(crate) value_is_zero: IsZeroWordGadget>, + value_is_zero: IsZeroWordGadget>, } impl TransferToGadget { @@ -475,7 +475,7 @@ pub(crate) struct TransferWithGasFeeGadget { sender_sub_fee: UpdateBalanceGadget, sender_sub_value: UpdateBalanceGadget, receiver: TransferToGadget, - pub(crate) value_is_zero: IsZeroWordGadget>, + value_is_zero: IsZeroWordGadget>, } impl TransferWithGasFeeGadget { From 7f73a7f9d751359274f2eb7d3ccd8ccc41288078 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 01:42:27 +0800 Subject: [PATCH 03/22] unused comment --- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index fa4519179d..f578adfc70 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -603,7 +603,6 @@ impl TransferGadget { receiver_address: WordLoHi>, receiver_exists: Expression, must_create: Expression, - // _prev_code_hash: WordLoHi>, value: Word32Cell, reversion_info: &mut ReversionInfo, ) -> Self { From 45e19c6cee76f4fc86523cc3848151b5e05d0a2f Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 01:47:01 +0800 Subject: [PATCH 04/22] must create is known --- zkevm-circuits/src/evm_circuit/execution/callop.rs | 2 +- zkevm-circuits/src/evm_circuit/execution/create.rs | 2 +- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index 761e54d50f..7883124dce 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -242,7 +242,7 @@ impl ExecutionGadget for CallOpGadget { caller_address.to_word(), callee_address.to_word(), not::expr(call_gadget.callee_not_exists.expr()), - 0.expr(), + false, call_gadget.value.clone(), &mut callee_reversion_info, ) diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index 9b560a16ce..b7df77aaa8 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -334,7 +334,7 @@ impl ExecutionGadget< create.caller_address(), contract_addr.to_word(), 0.expr(), - 1.expr(), + true, value.clone(), &mut callee_reversion_info, ); diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index f578adfc70..fac3f59ec0 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -602,7 +602,7 @@ impl TransferGadget { sender_address: WordLoHi>, receiver_address: WordLoHi>, receiver_exists: Expression, - must_create: Expression, + must_create: bool, value: Word32Cell, reversion_info: &mut ReversionInfo, ) -> Self { @@ -612,7 +612,7 @@ impl TransferGadget { cb, receiver_address.clone(), receiver_exists.clone(), - must_create.clone(), + must_create.expr(), value_is_zero.expr(), Some(reversion_info), ); @@ -624,7 +624,7 @@ impl TransferGadget { cb, receiver_address, receiver_exists, - must_create, + must_create.expr(), value, Some(reversion_info), false, From f62b1ccff3ed5931c62fd407b30ec320318f71c9 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 01:55:30 +0800 Subject: [PATCH 05/22] a sure place to dedup create account --- .../src/evm_circuit/util/common_gadget.rs | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index fac3f59ec0..0f4d693f7b 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -492,15 +492,6 @@ impl TransferWithGasFeeGadget { ) -> Self { let sender_sub_fee = cb.decrease_balance(sender_address.to_word(), gas_fee, None); let value_is_zero = cb.is_zero_word(&value); - // If receiver doesn't exist, create it - TransferToGadget::create_account( - cb, - receiver_address.clone(), - receiver_exists.clone(), - must_create.clone(), - value_is_zero.expr(), - Some(reversion_info), - ); // Skip transfer if value == 0 let sender_sub_value = cb.condition(not::expr(value_is_zero.expr()), |cb| { cb.decrease_balance(sender_address, value.clone(), Some(reversion_info)) @@ -512,7 +503,7 @@ impl TransferWithGasFeeGadget { must_create, value, Some(reversion_info), - false, + true, ); Self { @@ -607,15 +598,6 @@ impl TransferGadget { reversion_info: &mut ReversionInfo, ) -> Self { let value_is_zero = cb.is_zero_word(&value); - // If receiver doesn't exist, create it - TransferToGadget::create_account( - cb, - receiver_address.clone(), - receiver_exists.clone(), - must_create.expr(), - value_is_zero.expr(), - Some(reversion_info), - ); // Skip transfer if value == 0 let sender = cb.condition(not::expr(value_is_zero.expr()), |cb| { cb.decrease_balance(sender_address, value.clone(), Some(reversion_info)) @@ -627,7 +609,7 @@ impl TransferGadget { must_create.expr(), value, Some(reversion_info), - false, + true, ); Self { From b919f093bc99f11d22459a3fbc5d33247553f639 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 02:03:44 +0800 Subject: [PATCH 06/22] account_write is always true --- .../src/evm_circuit/execution/end_tx.rs | 1 - .../src/evm_circuit/util/common_gadget.rs | 23 ++++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index 0f04c6a71e..b3ce44b823 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -110,7 +110,6 @@ impl ExecutionGadget for EndTxGadget { false.expr(), mul_effective_tip_by_gas_used.product().clone(), None, - true, ); let end_tx = EndTxHelperGadget::construct( diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 0f4d693f7b..48084cddea 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -383,19 +383,18 @@ impl TransferToGadget { must_create: Expression, value: Word32Cell, mut reversion_info: Option<&mut ReversionInfo>, - account_write: bool, ) -> Self { let value_is_zero = cb.is_zero_word(&value); - if account_write { - Self::create_account( - cb, - receiver_address.clone(), - receiver_exists.clone(), - must_create.clone(), - value_is_zero.expr(), - reversion_info.as_deref_mut(), - ); - } + + Self::create_account( + cb, + receiver_address.clone(), + receiver_exists.clone(), + must_create.clone(), + value_is_zero.expr(), + reversion_info.as_deref_mut(), + ); + let receiver = cb.condition(not::expr(value_is_zero.expr()), |cb| { cb.increase_balance(receiver_address, value.clone(), reversion_info) }); @@ -503,7 +502,6 @@ impl TransferWithGasFeeGadget { must_create, value, Some(reversion_info), - true, ); Self { @@ -609,7 +607,6 @@ impl TransferGadget { must_create.expr(), value, Some(reversion_info), - true, ); Self { From 0241779f9d8d6207c2a0a49383b832f802aa94b8 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 02:09:02 +0800 Subject: [PATCH 07/22] the abstraction is no longer needed --- .../src/evm_circuit/util/common_gadget.rs | 46 ++++++------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 48084cddea..655e6dc318 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -385,40 +385,11 @@ impl TransferToGadget { mut reversion_info: Option<&mut ReversionInfo>, ) -> Self { let value_is_zero = cb.is_zero_word(&value); - - Self::create_account( - cb, - receiver_address.clone(), - receiver_exists.clone(), - must_create.clone(), - value_is_zero.expr(), - reversion_info.as_deref_mut(), - ); - - let receiver = cb.condition(not::expr(value_is_zero.expr()), |cb| { - cb.increase_balance(receiver_address, value.clone(), reversion_info) - }); - - Self { - receiver, - receiver_exists, - must_create, - value_is_zero, - } - } - - pub(crate) fn create_account( - cb: &mut EVMConstraintBuilder, - receiver_address: WordLoHi>, - receiver_exists: Expression, - must_create: Expression, - value_is_zero: Expression, - reversion_info: Option<&mut ReversionInfo>, - ) { + // Create account cb.condition( and::expr([ not::expr(receiver_exists.expr()), - or::expr([not::expr(value_is_zero.expr()), must_create]), + or::expr([not::expr(value_is_zero.expr()), must_create.clone()]), ]), |cb| { cb.account_write( @@ -426,10 +397,21 @@ impl TransferToGadget { AccountFieldTag::CodeHash, cb.empty_code_hash(), WordLoHi::zero(), - reversion_info, + reversion_info.as_deref_mut(), ); }, ); + + let receiver = cb.condition(not::expr(value_is_zero.expr()), |cb| { + cb.increase_balance(receiver_address, value.clone(), reversion_info) + }); + + Self { + receiver, + receiver_exists, + must_create, + value_is_zero, + } } pub(crate) fn assign( From 618f033e4d9be04d72b762d13221e1d1e6007f2f Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 03:09:30 +0800 Subject: [PATCH 08/22] merge transfer gadgets ugly --- .../src/evm_circuit/execution/begin_tx.rs | 24 +-- .../src/evm_circuit/execution/callop.rs | 6 +- .../src/evm_circuit/execution/create.rs | 6 +- .../src/evm_circuit/execution/end_tx.rs | 1 - .../src/evm_circuit/util/common_gadget.rs | 146 ++++-------------- 5 files changed, 51 insertions(+), 132 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index 80de4c1973..f0554c5b1f 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -5,7 +5,7 @@ use crate::{ step::ExecutionState, util::{ and, - common_gadget::TransferWithGasFeeGadget, + common_gadget::TransferGadget, constraint_builder::{ ConstrainBuilderCommon, EVMConstraintBuilder, ReversionInfo, StepStateTransition, Transition::{Delta, To}, @@ -14,7 +14,7 @@ use crate::{ math_gadget::{ ContractCreateGadget, IsEqualWordGadget, IsZeroWordGadget, RangeCheckGadget, }, - not, or, + not, tx::{BeginTxHelperGadget, TxDataGadget}, AccountAddress, CachedRegion, Cell, StepRws, }, @@ -41,7 +41,7 @@ pub(crate) struct BeginTxGadget { call_callee_address: AccountAddress, reversion_info: ReversionInfo, sufficient_gas_left: RangeCheckGadget, - transfer_with_gas_fee: TransferWithGasFeeGadget, + transfer_with_gas_fee: TransferGadget, code_hash: WordLoHiCell, is_empty_code_hash: IsEqualWordGadget>, WordLoHi>>, caller_nonce_hash_bytes: Word32Cell, @@ -170,17 +170,20 @@ impl ExecutionGadget for BeginTxGadget { AccountFieldTag::CodeHash, code_hash.to_word(), ); - + cb.require_equal( + "is create: callee_not_exists", + tx.is_create.expr(), + callee_not_exists.expr(), + ); // Transfer value from caller to callee, creating account if necessary. - let transfer_with_gas_fee = TransferWithGasFeeGadget::construct( + let transfer_with_gas_fee = TransferGadget::construct( cb, tx.caller_address.to_word(), tx.callee_address.to_word(), not::expr(callee_not_exists.expr()), - or::expr([tx.is_create.expr(), callee_not_exists.expr()]), tx.value.clone(), - tx.mul_gas_fee_by_gas.product().clone(), &mut reversion_info, + Some(tx.mul_gas_fee_by_gas.product().clone()), ); let caller_nonce_hash_bytes = cb.query_word32(); @@ -505,11 +508,14 @@ impl ExecutionGadget for BeginTxGadget { self.transfer_with_gas_fee.assign( region, offset, - caller_balance_sub_fee_pair, + ( + Some(caller_balance_sub_fee_pair.0), + Some(caller_balance_sub_fee_pair.1), + ), caller_balance_sub_value_pair, callee_balance_pair, tx.value, - gas_fee, + Some(gas_fee), )?; self.code_hash .assign_u256(region, offset, callee_code_hash)?; diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index 7883124dce..c688b43b7f 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -60,7 +60,7 @@ pub(crate) struct CallOpGadget { is_warm: Cell, is_warm_prev: Cell, callee_reversion_info: ReversionInfo, - transfer: TransferGadget, + transfer: TransferGadget, // current handling Call* opcode's caller balance caller_balance: WordLoHi>, // check if insufficient balance case @@ -242,9 +242,9 @@ impl ExecutionGadget for CallOpGadget { caller_address.to_word(), callee_address.to_word(), not::expr(call_gadget.callee_not_exists.expr()), - false, call_gadget.value.clone(), &mut callee_reversion_info, + None, ) }); // rwc_delta = 8 + is_delegatecall * 2 + call_gadget.rw_delta() + @@ -876,9 +876,11 @@ impl ExecutionGadget for CallOpGadget { self.transfer.assign( region, offset, + (None, None), caller_balance_pair, callee_balance_pair, value, + None, )?; } diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index b7df77aaa8..b351f4bfee 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -63,7 +63,7 @@ pub(crate) struct CreateGadget, prev_code_hash: WordLoHiCell, prev_code_hash_is_zero: IsZeroWordGadget>>, - transfer: TransferGadget, + transfer: TransferGadget, create: ContractCreateGadget, init_code: MemoryAddressGadget, @@ -334,9 +334,9 @@ impl ExecutionGadget< create.caller_address(), contract_addr.to_word(), 0.expr(), - true, value.clone(), &mut callee_reversion_info, + None, ); // EIP 161, the nonce of a newly created contract is 1 @@ -650,9 +650,11 @@ impl ExecutionGadget< self.transfer.assign( region, offset, + (None, None), caller_balance_pair, callee_balance_pair, value, + None, )?; } diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index b3ce44b823..d098e8a632 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -107,7 +107,6 @@ impl ExecutionGadget for EndTxGadget { cb, coinbase.to_word(), 1.expr() - coinbase_code_hash_is_zero.expr(), - false.expr(), mul_effective_tip_by_gas_used.product().clone(), None, ); diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 655e6dc318..6cf207f501 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -17,7 +17,7 @@ use crate::{ Transition::{Delta, Same, To}, }, math_gadget::{AddWordsGadget, RangeCheckGadget}, - not, or, Cell, + not, Cell, }, }, table::{AccountFieldTag, CallContextFieldTag}, @@ -370,7 +370,6 @@ impl pub(crate) struct TransferToGadget { receiver: UpdateBalanceGadget, receiver_exists: Expression, - must_create: Expression, value_is_zero: IsZeroWordGadget>, } @@ -380,16 +379,16 @@ impl TransferToGadget { cb: &mut EVMConstraintBuilder, receiver_address: WordLoHi>, receiver_exists: Expression, - must_create: Expression, value: Word32Cell, mut reversion_info: Option<&mut ReversionInfo>, ) -> Self { let value_is_zero = cb.is_zero_word(&value); + // Create account cb.condition( and::expr([ not::expr(receiver_exists.expr()), - or::expr([not::expr(value_is_zero.expr()), must_create.clone()]), + not::expr(value_is_zero.expr()), ]), |cb| { cb.account_write( @@ -409,7 +408,6 @@ impl TransferToGadget { Self { receiver, receiver_exists, - must_create, value_is_zero, } } @@ -436,8 +434,7 @@ impl TransferToGadget { pub(crate) fn rw_delta(&self) -> Expression { // +1 Write Account (receiver) CodeHash (account creation via code_hash update) and::expr([ - not::expr(self.receiver_exists.expr()), - or::expr([not::expr(self.value_is_zero.expr()), self.must_create.clone()]), + not::expr(self.receiver_exists.expr()),not::expr(self.value_is_zero.expr()) ]) + // +1 Write Account (receiver) Balance not::expr(self.value_is_zero.expr()) @@ -452,26 +449,29 @@ impl TransferToGadget { /// setting it's code_hash = EMPTY_HASH. The receiver account is also created /// unconditionally if must_create is true. This gadget is used in BeginTx. #[derive(Clone, Debug)] -pub(crate) struct TransferWithGasFeeGadget { - sender_sub_fee: UpdateBalanceGadget, +pub(crate) struct TransferGadget { + sender_sub_fee: Option>, sender_sub_value: UpdateBalanceGadget, receiver: TransferToGadget, - value_is_zero: IsZeroWordGadget>, + pub(crate) value_is_zero: IsZeroWordGadget>, } -impl TransferWithGasFeeGadget { +impl TransferGadget { #[allow(clippy::too_many_arguments)] pub(crate) fn construct( cb: &mut EVMConstraintBuilder, sender_address: WordLoHi>, receiver_address: WordLoHi>, receiver_exists: Expression, - must_create: Expression, value: Word32Cell, - gas_fee: Word32Cell, reversion_info: &mut ReversionInfo, + gas_fee: Option>, ) -> Self { - let sender_sub_fee = cb.decrease_balance(sender_address.to_word(), gas_fee, None); + let sender_sub_fee = if WITH_FEE { + Some(cb.decrease_balance(sender_address.to_word(), gas_fee.expect("fee exists"), None)) + } else { + None + }; let value_is_zero = cb.is_zero_word(&value); // Skip transfer if value == 0 let sender_sub_value = cb.condition(not::expr(value_is_zero.expr()), |cb| { @@ -481,7 +481,6 @@ impl TransferWithGasFeeGadget { cb, receiver_address, receiver_exists, - must_create, value, Some(reversion_info), ); @@ -496,12 +495,9 @@ impl TransferWithGasFeeGadget { pub(crate) fn rw_delta(&self) -> Expression { // +1 Write Account (sender) Balance (Not Reversible tx fee) - 1.expr() + + WITH_FEE.expr() + // +1 Write Account (receiver) CodeHash (account creation via code_hash update) - and::expr([not::expr(self.receiver.receiver_exists.expr()), or::expr([ - not::expr(self.value_is_zero.expr()), - self.receiver.must_create.clone()] - )]) * 1.expr() + + self.receiver.rw_delta()+ // +1 Write Account (sender) Balance // +1 Write Account (receiver) Balance not::expr(self.value_is_zero.expr()) * 2.expr() @@ -510,10 +506,7 @@ impl TransferWithGasFeeGadget { pub(crate) fn reversible_w_delta(&self) -> Expression { // NOTE: Write Account (sender) Balance (Not Reversible tx fee) // +1 Write Account (receiver) CodeHash (account creation via code_hash update) - and::expr([not::expr(self.receiver.receiver_exists.expr()), or::expr([ - not::expr(self.value_is_zero.expr()), - self.receiver.must_create.clone()] - )]) + + self.receiver.rw_delta()+ // +1 Write Account (sender) Balance // +1 Write Account (receiver) Balance not::expr(self.value_is_zero.expr()) * 2.expr() @@ -524,19 +517,21 @@ impl TransferWithGasFeeGadget { &self, region: &mut CachedRegion<'_, '_, F>, offset: usize, - (sender_balance_sub_fee, prev_sender_balance_sub_fee): (U256, U256), + (sender_balance_sub_fee, prev_sender_balance_sub_fee): (Option, Option), (sender_balance_sub_value, prev_sender_balance_sub_value): (U256, U256), (receiver_balance, prev_receiver_balance): (U256, U256), value: U256, - gas_fee: U256, + gas_fee: Option, ) -> Result<(), Error> { - self.sender_sub_fee.assign( - region, - offset, - prev_sender_balance_sub_fee, - vec![gas_fee], - sender_balance_sub_fee, - )?; + if WITH_FEE { + self.sender_sub_fee.as_ref().expect("Exists").assign( + region, + offset, + prev_sender_balance_sub_fee.expect("exists"), + vec![gas_fee.expect("exists")], + sender_balance_sub_fee.expect("exists"), + )?; + } self.sender_sub_value.assign( region, offset, @@ -556,91 +551,6 @@ impl TransferWithGasFeeGadget { } } -/// The TransferGadget handles a transfer of value from sender to receiver. The -/// transfer is only performed if the value is not zero. If the transfer is -/// performed and the receiver account doesn't exist, it will be created by -/// setting it's code_hash = EMPTY_HASH. This gadget is used in callop. -#[derive(Clone, Debug)] -pub(crate) struct TransferGadget { - sender: UpdateBalanceGadget, - receiver: TransferToGadget, - pub(crate) value_is_zero: IsZeroWordGadget>, -} - -impl TransferGadget { - pub(crate) fn construct( - cb: &mut EVMConstraintBuilder, - sender_address: WordLoHi>, - receiver_address: WordLoHi>, - receiver_exists: Expression, - must_create: bool, - value: Word32Cell, - reversion_info: &mut ReversionInfo, - ) -> Self { - let value_is_zero = cb.is_zero_word(&value); - // Skip transfer if value == 0 - let sender = cb.condition(not::expr(value_is_zero.expr()), |cb| { - cb.decrease_balance(sender_address, value.clone(), Some(reversion_info)) - }); - let receiver = TransferToGadget::construct( - cb, - receiver_address, - receiver_exists, - must_create.expr(), - value, - Some(reversion_info), - ); - - Self { - sender, - receiver, - value_is_zero, - } - } - - pub(crate) fn reversible_w_delta(&self) -> Expression { - // +1 Write Account (receiver) CodeHash (account creation via code_hash update) - or::expr([ - not::expr(self.value_is_zero.expr()) * not::expr(self.receiver.receiver_exists.clone()), - self.receiver.must_create.clone()] - ) * 1.expr() + - // +1 Write Account (sender) Balance - // +1 Write Account (receiver) Balance - not::expr(self.value_is_zero.expr()) * 2.expr() - } - - pub(crate) fn assign( - &self, - region: &mut CachedRegion<'_, '_, F>, - offset: usize, - (sender_balance, sender_balance_prev): (U256, U256), - (receiver_balance, receiver_balance_prev): (U256, U256), - value: U256, - ) -> Result<(), Error> { - self.sender.assign( - region, - offset, - sender_balance_prev, - vec![value], - sender_balance, - )?; - self.receiver.assign( - region, - offset, - (receiver_balance, receiver_balance_prev), - value, - )?; - self.value_is_zero - .assign_value(region, offset, Value::known(WordLoHi::from(value)))?; - Ok(()) - } - - pub(crate) fn rw_delta(&self) -> Expression { - // +1 Write Account (sender) Balance - not::expr(self.value_is_zero.expr()) + self.receiver.rw_delta() - } -} - #[derive(Clone, Debug)] pub(crate) struct CommonCallGadget { pub is_success: Cell, From 37c3fd104005b875c39037d8386c29758f8e9ea0 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 23:24:44 +0800 Subject: [PATCH 09/22] WIP --- .../src/evm_circuit/execution/begin_tx.rs | 6 +--- .../src/evm_circuit/execution/callop.rs | 1 + .../src/evm_circuit/execution/create.rs | 1 + .../src/evm_circuit/execution/end_tx.rs | 1 + .../src/evm_circuit/util/common_gadget.rs | 28 +++++++++++-------- 5 files changed, 20 insertions(+), 17 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index f0554c5b1f..29ebf8f95a 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -170,17 +170,13 @@ impl ExecutionGadget for BeginTxGadget { AccountFieldTag::CodeHash, code_hash.to_word(), ); - cb.require_equal( - "is create: callee_not_exists", - tx.is_create.expr(), - callee_not_exists.expr(), - ); // Transfer value from caller to callee, creating account if necessary. let transfer_with_gas_fee = TransferGadget::construct( cb, tx.caller_address.to_word(), tx.callee_address.to_word(), not::expr(callee_not_exists.expr()), + tx.is_create.expr(), tx.value.clone(), &mut reversion_info, Some(tx.mul_gas_fee_by_gas.product().clone()), diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index c688b43b7f..ee6f60a666 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -242,6 +242,7 @@ impl ExecutionGadget for CallOpGadget { caller_address.to_word(), callee_address.to_word(), not::expr(call_gadget.callee_not_exists.expr()), + false.expr(), call_gadget.value.clone(), &mut callee_reversion_info, None, diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index b351f4bfee..e3979f78a1 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -334,6 +334,7 @@ impl ExecutionGadget< create.caller_address(), contract_addr.to_word(), 0.expr(), + true.expr(), value.clone(), &mut callee_reversion_info, None, diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index d098e8a632..b3ce44b823 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -107,6 +107,7 @@ impl ExecutionGadget for EndTxGadget { cb, coinbase.to_word(), 1.expr() - coinbase_code_hash_is_zero.expr(), + false.expr(), mul_effective_tip_by_gas_used.product().clone(), None, ); diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 6cf207f501..9e86d8be08 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -31,7 +31,7 @@ use bus_mapping::state_db::CodeDB; use eth_types::{ evm_types::GasCost, Field, OpsIdentity, ToAddress, ToLittleEndian, ToScalar, ToWord, U256, }; -use gadgets::util::{select, sum}; +use gadgets::util::{or, select, sum}; use halo2_proofs::{ circuit::Value, plonk::{Error, Expression}, @@ -370,6 +370,7 @@ impl pub(crate) struct TransferToGadget { receiver: UpdateBalanceGadget, receiver_exists: Expression, + opcode_is_create: Expression, value_is_zero: IsZeroWordGadget>, } @@ -379,6 +380,7 @@ impl TransferToGadget { cb: &mut EVMConstraintBuilder, receiver_address: WordLoHi>, receiver_exists: Expression, + opcode_is_create: Expression, value: Word32Cell, mut reversion_info: Option<&mut ReversionInfo>, ) -> Self { @@ -388,7 +390,7 @@ impl TransferToGadget { cb.condition( and::expr([ not::expr(receiver_exists.expr()), - not::expr(value_is_zero.expr()), + or::expr([not::expr(value_is_zero.expr()), opcode_is_create.expr()]), ]), |cb| { cb.account_write( @@ -408,6 +410,7 @@ impl TransferToGadget { Self { receiver, receiver_exists, + opcode_is_create, value_is_zero, } } @@ -434,8 +437,9 @@ impl TransferToGadget { pub(crate) fn rw_delta(&self) -> Expression { // +1 Write Account (receiver) CodeHash (account creation via code_hash update) and::expr([ - not::expr(self.receiver_exists.expr()),not::expr(self.value_is_zero.expr()) - ]) + + not::expr(self.receiver_exists.expr()), + or::expr([not::expr(self.value_is_zero.expr()), self.opcode_is_create.expr()]) + ])+ // +1 Write Account (receiver) Balance not::expr(self.value_is_zero.expr()) } @@ -463,6 +467,7 @@ impl TransferGadget { sender_address: WordLoHi>, receiver_address: WordLoHi>, receiver_exists: Expression, + opcode_is_create: Expression, value: Word32Cell, reversion_info: &mut ReversionInfo, gas_fee: Option>, @@ -481,6 +486,7 @@ impl TransferGadget { cb, receiver_address, receiver_exists, + opcode_is_create, value, Some(reversion_info), ); @@ -496,20 +502,18 @@ impl TransferGadget { pub(crate) fn rw_delta(&self) -> Expression { // +1 Write Account (sender) Balance (Not Reversible tx fee) WITH_FEE.expr() + - // +1 Write Account (receiver) CodeHash (account creation via code_hash update) - self.receiver.rw_delta()+ // +1 Write Account (sender) Balance - // +1 Write Account (receiver) Balance - not::expr(self.value_is_zero.expr()) * 2.expr() + not::expr(self.value_is_zero.expr()) + + // +1 Write Account (receiver) CodeHash (account creation via code_hash update) + self.receiver.rw_delta() } pub(crate) fn reversible_w_delta(&self) -> Expression { // NOTE: Write Account (sender) Balance (Not Reversible tx fee) - // +1 Write Account (receiver) CodeHash (account creation via code_hash update) - self.receiver.rw_delta()+ // +1 Write Account (sender) Balance - // +1 Write Account (receiver) Balance - not::expr(self.value_is_zero.expr()) * 2.expr() + not::expr(self.value_is_zero.expr()) + + // +1 Write Account (receiver) CodeHash (account creation via code_hash update) + self.receiver.rw_delta() } #[allow(clippy::too_many_arguments)] From f82c3a7cf366f71e8f01e98ebb7c44dfbf5865b6 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Thu, 22 Feb 2024 23:35:22 +0800 Subject: [PATCH 10/22] deduplicate and fix busmapping constraint --- .../circuit_input_builder/input_state_ref.rs | 29 ++----------------- 1 file changed, 3 insertions(+), 26 deletions(-) diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index 57fd76d1db..1860a164a4 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -608,18 +608,7 @@ impl<'a> CircuitInputStateRef<'a> { sender_balance_prev, sender_balance ); - // If receiver doesn't exist, create it - if !receiver_exists && (!value.is_zero() || must_create) { - self.push_op_reversible( - step, - AccountOp { - address: receiver, - field: AccountField::CodeHash, - value: CodeDB::empty_code_hash().to_word(), - value_prev: Word::zero(), - }, - )?; - } + if value.is_zero() { // Skip transfer if value == 0 return Ok(()); @@ -634,19 +623,7 @@ impl<'a> CircuitInputStateRef<'a> { value_prev: sender_balance_prev, }, )?; - - let (_found, receiver_account) = self.sdb.get_account(&receiver); - let receiver_balance_prev = receiver_account.balance; - let receiver_balance = receiver_account.balance + value; - self.push_op_reversible( - step, - AccountOp { - address: receiver, - field: AccountField::Balance, - value: receiver_balance, - value_prev: receiver_balance_prev, - }, - )?; + self.transfer_to(step, receiver, receiver_exists, must_create, value, true)?; Ok(()) } @@ -683,7 +660,7 @@ impl<'a> CircuitInputStateRef<'a> { reversible: bool, ) -> Result<(), Error> { // If receiver doesn't exist, create it - if (!receiver_exists && !value.is_zero()) || must_create { + if !receiver_exists && (!value.is_zero() || must_create) { self.account_write( step, receiver, From 79d2c3f038484bb31da81c6c0002ba40cc0cc47a Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Fri, 23 Feb 2024 00:55:01 +0800 Subject: [PATCH 11/22] fix the read write order --- .../src/evm_circuit/execution/begin_tx.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index 29ebf8f95a..f7c99eb3f7 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -468,16 +468,20 @@ impl ExecutionGadget for BeginTxGadget { is_precompiled(&tx.to_or_contract_addr()) || !callee_code_hash.is_zero(); let caller_balance_sub_fee_pair = rws.next().account_balance_pair(); let must_create = tx.is_create(); + + let caller_balance_sub_value_pair = if !tx.value.is_zero() { + rws.next().account_balance_pair() + } else { + (zero, zero) + }; if !callee_exists && (!tx.value.is_zero() || must_create) { callee_code_hash = rws.next().account_codehash_pair().1; } - let mut caller_balance_sub_value_pair = (zero, zero); - let mut callee_balance_pair = (zero, zero); - if !tx.value.is_zero() { - caller_balance_sub_value_pair = rws.next().account_balance_pair(); - callee_balance_pair = rws.next().account_balance_pair(); + let callee_balance_pair = if !tx.value.is_zero() { + rws.next().account_balance_pair() + } else { + (zero, zero) }; - self.begin_tx.assign(region, offset, tx)?; self.tx.assign(region, offset, tx)?; From 52e80c45f6365a96aacdf20c44e948a6ae0acd7a Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Fri, 23 Feb 2024 01:33:39 +0800 Subject: [PATCH 12/22] doc fix --- .../src/evm_circuit/util/common_gadget.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 9e86d8be08..dc391def94 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -445,13 +445,13 @@ impl TransferToGadget { } } -// TODO: Merge with TransferGadget -/// The TransferWithGasFeeGadget handles an irreversible gas fee subtraction to -/// the sender and a transfer of value from sender to receiver. The value -/// transfer is only performed if the value is not zero. If the transfer is -/// performed and the receiver account doesn't exist, it will be created by -/// setting it's code_hash = EMPTY_HASH. The receiver account is also created -/// unconditionally if must_create is true. This gadget is used in BeginTx. +/// The [`TransferGadget`] handles +/// - (optional) an irreversible gas fee subtraction to the sender, and +/// - a transfer of value from sender to receiver. +/// +/// The value transfer is only performed if the value is not zero. +/// It also create the receiver account when the conditions in [`TransferToGadget`] is met. +/// This gadget is used in BeginTx, Call ops, and Create. #[derive(Clone, Debug)] pub(crate) struct TransferGadget { sender_sub_fee: Option>, From 0ee4aa4f7b56ff8c833227f0c961b9e4845a4167 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Fri, 23 Feb 2024 01:47:45 +0800 Subject: [PATCH 13/22] dedup busmapping transfer --- .../circuit_input_builder/input_state_ref.rs | 32 +++---------------- bus-mapping/src/evm/opcodes/begin_end_tx.rs | 2 +- bus-mapping/src/evm/opcodes/callop.rs | 1 + bus-mapping/src/evm/opcodes/create.rs | 3 +- 4 files changed, 9 insertions(+), 29 deletions(-) diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index 1860a164a4..2d1243342c 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -559,13 +559,13 @@ impl<'a> CircuitInputStateRef<'a> { /// balance by `value`. If `fee` is existing (not None), also need to push 1 /// non-reversible [`AccountOp`] to update `sender` balance by `fee`. #[allow(clippy::too_many_arguments)] - pub fn transfer_with_fee( + pub fn transfer( &mut self, step: &mut ExecStep, sender: Address, receiver: Address, receiver_exists: bool, - must_create: bool, + opcode_is_create: bool, value: Word, fee: Option, ) -> Result<(), Error> { @@ -623,44 +623,22 @@ impl<'a> CircuitInputStateRef<'a> { value_prev: sender_balance_prev, }, )?; - self.transfer_to(step, receiver, receiver_exists, must_create, value, true)?; + self.transfer_to(step, receiver, receiver_exists, opcode_is_create, value, true)?; Ok(()) } - /// Same functionality with `transfer_with_fee` but with `fee` set zero. - pub fn transfer( - &mut self, - step: &mut ExecStep, - sender: Address, - receiver: Address, - receiver_exists: bool, - must_create: bool, - value: Word, - ) -> Result<(), Error> { - self.transfer_with_fee( - step, - sender, - receiver, - receiver_exists, - must_create, - value, - None, - ) - } - /// Transfer to an address. Create an account if it is not existed before. pub fn transfer_to( &mut self, step: &mut ExecStep, receiver: Address, receiver_exists: bool, - must_create: bool, + opcode_is_create: bool, value: Word, reversible: bool, ) -> Result<(), Error> { - // If receiver doesn't exist, create it - if !receiver_exists && (!value.is_zero() || must_create) { + if !receiver_exists && (!value.is_zero() || opcode_is_create) { self.account_write( step, receiver, diff --git a/bus-mapping/src/evm/opcodes/begin_end_tx.rs b/bus-mapping/src/evm/opcodes/begin_end_tx.rs index 1b6c79a5c8..f9ee29d714 100644 --- a/bus-mapping/src/evm/opcodes/begin_end_tx.rs +++ b/bus-mapping/src/evm/opcodes/begin_end_tx.rs @@ -122,7 +122,7 @@ fn gen_begin_tx_steps(state: &mut CircuitInputStateRef) -> Result Opcode for CallOpcode { callee_exists, false, call.value, + None, )?; } diff --git a/bus-mapping/src/evm/opcodes/create.rs b/bus-mapping/src/evm/opcodes/create.rs index 51b399b099..c1a0bbf940 100644 --- a/bus-mapping/src/evm/opcodes/create.rs +++ b/bus-mapping/src/evm/opcodes/create.rs @@ -217,8 +217,9 @@ impl Opcode for Create { caller.address, callee.address, callee_exists, - !callee_exists, + true, callee.value, + None, )?; // EIP 161, increase callee's nonce From e3e1b1c56d9138e7e23ec07a09615de06a0a40e5 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Fri, 23 Feb 2024 01:52:01 +0800 Subject: [PATCH 14/22] rm must_create --- bus-mapping/src/circuit_input_builder/input_state_ref.rs | 9 ++++++++- zkevm-circuits/src/evm_circuit/execution/begin_tx.rs | 3 +-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index 2d1243342c..8a0a505c18 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -623,7 +623,14 @@ impl<'a> CircuitInputStateRef<'a> { value_prev: sender_balance_prev, }, )?; - self.transfer_to(step, receiver, receiver_exists, opcode_is_create, value, true)?; + self.transfer_to( + step, + receiver, + receiver_exists, + opcode_is_create, + value, + true, + )?; Ok(()) } diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index f7c99eb3f7..30a71ee41e 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -467,14 +467,13 @@ impl ExecutionGadget for BeginTxGadget { let callee_exists = is_precompiled(&tx.to_or_contract_addr()) || !callee_code_hash.is_zero(); let caller_balance_sub_fee_pair = rws.next().account_balance_pair(); - let must_create = tx.is_create(); let caller_balance_sub_value_pair = if !tx.value.is_zero() { rws.next().account_balance_pair() } else { (zero, zero) }; - if !callee_exists && (!tx.value.is_zero() || must_create) { + if !callee_exists && (!tx.value.is_zero() || tx.is_create()) { callee_code_hash = rws.next().account_codehash_pair().1; } let callee_balance_pair = if !tx.value.is_zero() { From 56ccc667c2274884504087c16e2d5b9d16d732dc Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Fri, 23 Feb 2024 18:33:02 +0800 Subject: [PATCH 15/22] move all the transfer rws handling to transfer gadget --- .../src/evm_circuit/execution/begin_tx.rs | 34 +++------------ .../src/evm_circuit/execution/callop.rs | 14 ++---- .../src/evm_circuit/execution/create.rs | 15 +------ .../src/evm_circuit/execution/end_tx.rs | 34 ++++++--------- .../src/evm_circuit/util/common_gadget.rs | 43 ++++++++++++------- 5 files changed, 52 insertions(+), 88 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index 30a71ee41e..5910fcb84c 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -466,21 +466,13 @@ impl ExecutionGadget for BeginTxGadget { } let callee_exists = is_precompiled(&tx.to_or_contract_addr()) || !callee_code_hash.is_zero(); - let caller_balance_sub_fee_pair = rws.next().account_balance_pair(); - - let caller_balance_sub_value_pair = if !tx.value.is_zero() { - rws.next().account_balance_pair() - } else { - (zero, zero) - }; - if !callee_exists && (!tx.value.is_zero() || tx.is_create()) { - callee_code_hash = rws.next().account_codehash_pair().1; - } - let callee_balance_pair = if !tx.value.is_zero() { - rws.next().account_balance_pair() - } else { - (zero, zero) - }; + self.transfer_with_gas_fee.assign( + region, + offset, + &mut rws, + (callee_exists, tx.value, tx.is_create()), + Some(gas_fee), + )?; self.begin_tx.assign(region, offset, tx)?; self.tx.assign(region, offset, tx)?; @@ -504,18 +496,6 @@ impl ExecutionGadget for BeginTxGadget { )?; self.sufficient_gas_left .assign(region, offset, F::from(tx.gas() - step.gas_cost))?; - self.transfer_with_gas_fee.assign( - region, - offset, - ( - Some(caller_balance_sub_fee_pair.0), - Some(caller_balance_sub_fee_pair.1), - ), - caller_balance_sub_value_pair, - callee_balance_pair, - tx.value, - Some(gas_fee), - )?; self.code_hash .assign_u256(region, offset, callee_code_hash)?; self.is_empty_code_hash.assign_u256( diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index ee6f60a666..ce9807083c 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -867,20 +867,12 @@ impl ExecutionGadget for CallOpGadget { depth.low_u64() < 1025 && (!(is_call || is_callcode) || caller_balance >= value); // conditionally assign - if is_call && is_precheck_ok && !value.is_zero() { - if !callee_exists { - rws.next().account_codehash_pair(); // callee hash - } - - let caller_balance_pair = rws.next().account_balance_pair(); - let callee_balance_pair = rws.next().account_balance_pair(); + if is_call && is_precheck_ok { self.transfer.assign( region, offset, - (None, None), - caller_balance_pair, - callee_balance_pair, - value, + &mut rws, + (callee_exists, value, false), None, )?; } diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index e3979f78a1..3e0403fdb6 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -639,22 +639,11 @@ impl ExecutionGadget< let code_hash = if is_precheck_ok { if !is_address_collision { - // transfer - if callee_prev_code_hash.is_zero() { - rws.next(); // codehash update - } - let [caller_balance_pair, callee_balance_pair] = if !value.is_zero() { - [(); 2].map(|_| rws.next().account_balance_pair()) - } else { - [(0.into(), 0.into()), (0.into(), 0.into())] - }; self.transfer.assign( region, offset, - (None, None), - caller_balance_pair, - callee_balance_pair, - value, + &mut rws, + (!callee_prev_code_hash.is_zero(), value, true), None, )?; } diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index b3ce44b823..c576811f5b 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -11,7 +11,7 @@ use crate::{ MulWordByU64Gadget, }, tx::EndTxHelperGadget, - CachedRegion, Cell, + CachedRegion, Cell, StepRws, }, witness::{Block, Call, ExecStep, Transaction}, }, @@ -150,9 +150,11 @@ impl ExecutionGadget for EndTxGadget { step: &ExecStep, ) -> Result<(), Error> { let gas_used = tx.gas() - step.gas_left; - let (refund, _) = block.get_rws(step, 2).tx_refund_value_pair(); - let (caller_balance, caller_balance_prev) = block.get_rws(step, 3).account_balance_pair(); - let (coinbase_code_hash_prev, _) = block.get_rws(step, 4).account_codehash_pair(); + let mut rws = StepRws::new(block, step); + rws.offset_add(2); + let (refund, _) = rws.next().tx_refund_value_pair(); + let (caller_balance, caller_balance_prev) = rws.next().account_balance_pair(); + let (coinbase_code_hash_prev, _) = rws.next().account_codehash_pair(); self.tx_id .assign(region, offset, Value::known(F::from(tx.id)))?; @@ -206,24 +208,12 @@ impl ExecutionGadget for EndTxGadget { .assign_u256(region, offset, coinbase_code_hash_prev)?; self.coinbase_code_hash_is_zero .assign_u256(region, offset, coinbase_code_hash_prev)?; - if !coinbase_reward.is_zero() { - let coinbase_balance_pair = block - .get_rws( - step, - if coinbase_code_hash_prev.is_zero() { - 6 - } else { - 5 - }, - ) - .account_balance_pair(); - self.coinbase_reward.assign( - region, - offset, - coinbase_balance_pair, - effective_tip * gas_used, - )?; - } + self.coinbase_reward.assign( + region, + offset, + &mut rws, + (!coinbase_code_hash_prev.is_zero(), coinbase_reward, false), + )?; self.is_persistent.assign( region, offset, diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index dc391def94..388bab7a11 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -3,7 +3,7 @@ use super::{ from_bytes, math_gadget::{IsEqualWordGadget, IsZeroGadget, IsZeroWordGadget, LtGadget}, memory_gadget::{CommonMemoryAddressGadget, MemoryExpansionGadget}, - AccountAddress, CachedRegion, + AccountAddress, CachedRegion, StepRws, }; use crate::{ evm_circuit::{ @@ -419,15 +419,24 @@ impl TransferToGadget { &self, region: &mut CachedRegion<'_, '_, F>, offset: usize, - (receiver_balance, prev_receiver_balance): (U256, U256), - value: U256, + rws: &mut StepRws, + (receiver_exists, value, opcode_is_create): (bool, U256, bool), ) -> Result<(), Error> { + if !receiver_exists && (!value.is_zero() || opcode_is_create) { + let _receiver_code_hash = rws.next().account_codehash_pair(); + } + + let receiver_balance_pair = if !value.is_zero() { + rws.next().account_balance_pair() + } else { + (0.into(), 0.into()) + }; self.receiver.assign( region, offset, - prev_receiver_balance, + receiver_balance_pair.1, vec![value], - receiver_balance, + receiver_balance_pair.0, )?; self.value_is_zero .assign_value(region, offset, Value::known(WordLoHi::from(value)))?; @@ -521,33 +530,37 @@ impl TransferGadget { &self, region: &mut CachedRegion<'_, '_, F>, offset: usize, - (sender_balance_sub_fee, prev_sender_balance_sub_fee): (Option, Option), - (sender_balance_sub_value, prev_sender_balance_sub_value): (U256, U256), - (receiver_balance, prev_receiver_balance): (U256, U256), - value: U256, + rws: &mut StepRws, + (receiver_exists, value, opcode_is_create): (bool, U256, bool), gas_fee: Option, ) -> Result<(), Error> { if WITH_FEE { + let sender_balance_sub_fee = rws.next().account_balance_pair(); self.sender_sub_fee.as_ref().expect("Exists").assign( region, offset, - prev_sender_balance_sub_fee.expect("exists"), + sender_balance_sub_fee.1, vec![gas_fee.expect("exists")], - sender_balance_sub_fee.expect("exists"), + sender_balance_sub_fee.0, )?; } + let sender_balance_sub_value = if !value.is_zero() { + rws.next().account_balance_pair() + } else { + (0.into(), 0.into()) + }; self.sender_sub_value.assign( region, offset, - prev_sender_balance_sub_value, + sender_balance_sub_value.1, vec![value], - sender_balance_sub_value, + sender_balance_sub_value.0, )?; self.receiver.assign( region, offset, - (receiver_balance, prev_receiver_balance), - value, + rws, + (receiver_exists, value, opcode_is_create), )?; self.value_is_zero .assign_value(region, offset, Value::known(WordLoHi::from(value)))?; From 7a13f054d38b2076727d96466688ce46ada59b12 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Fri, 23 Feb 2024 23:41:19 +0800 Subject: [PATCH 16/22] the early return skipped the receiver creation --- .../circuit_input_builder/input_state_ref.rs | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index 8a0a505c18..fb26840466 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -609,20 +609,18 @@ impl<'a> CircuitInputStateRef<'a> { sender_balance ); - if value.is_zero() { - // Skip transfer if value == 0 - return Ok(()); + if !value.is_zero() { + self.push_op_reversible( + step, + AccountOp { + address: sender, + field: AccountField::Balance, + value: sender_balance, + value_prev: sender_balance_prev, + }, + )?; } - self.push_op_reversible( - step, - AccountOp { - address: sender, - field: AccountField::Balance, - value: sender_balance, - value_prev: sender_balance_prev, - }, - )?; self.transfer_to( step, receiver, From 598ad1123be8be691433834c2ff9da0a72e598ce Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Tue, 27 Feb 2024 17:30:39 +0800 Subject: [PATCH 17/22] feedback --- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 388bab7a11..9b9b1be3bf 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -423,10 +423,11 @@ impl TransferToGadget { (receiver_exists, value, opcode_is_create): (bool, U256, bool), ) -> Result<(), Error> { if !receiver_exists && (!value.is_zero() || opcode_is_create) { - let _receiver_code_hash = rws.next().account_codehash_pair(); + // receiver's code_hash + rws.next().account_codehash_pair(); } - let receiver_balance_pair = if !value.is_zero() { + let (receiver_balance, receiver_balance_prev) = if !value.is_zero() { rws.next().account_balance_pair() } else { (0.into(), 0.into()) @@ -434,9 +435,9 @@ impl TransferToGadget { self.receiver.assign( region, offset, - receiver_balance_pair.1, + receiver_balance_prev, vec![value], - receiver_balance_pair.0, + receiver_balance, )?; self.value_is_zero .assign_value(region, offset, Value::known(WordLoHi::from(value)))?; From 0522b5c34bd0d72af02147fd12572258a6216679 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Tue, 27 Feb 2024 17:34:29 +0800 Subject: [PATCH 18/22] nitpick --- zkevm-circuits/src/evm_circuit/execution/create.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index 3e0403fdb6..adfb91fafb 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -333,7 +333,7 @@ impl ExecutionGadget< cb, create.caller_address(), contract_addr.to_word(), - 0.expr(), + false.expr(), true.expr(), value.clone(), &mut callee_reversion_info, From 77cfbcb9a3cdcf7c939996b339a2e7f48f9ffd30 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Tue, 5 Mar 2024 16:41:57 +0800 Subject: [PATCH 19/22] point to Geth\#28666 in the comment --- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index 9b9b1be3bf..f5f8ed31bf 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -387,6 +387,7 @@ impl TransferToGadget { let value_is_zero = cb.is_zero_word(&value); // Create account + // See https://github.com/ethereum/go-ethereum/pull/28666 for the context of this check. cb.condition( and::expr([ not::expr(receiver_exists.expr()), From 990afe19f694fa9d4fc037914758be31b7d224d1 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Tue, 5 Mar 2024 18:54:20 +0800 Subject: [PATCH 20/22] rename receiver -> receiver_balance --- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index f5f8ed31bf..aeab19215f 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -368,7 +368,7 @@ impl #[derive(Clone, Debug)] pub(crate) struct TransferToGadget { - receiver: UpdateBalanceGadget, + receiver_balance: UpdateBalanceGadget, receiver_exists: Expression, opcode_is_create: Expression, value_is_zero: IsZeroWordGadget>, @@ -404,12 +404,12 @@ impl TransferToGadget { }, ); - let receiver = cb.condition(not::expr(value_is_zero.expr()), |cb| { + let receiver_balance = cb.condition(not::expr(value_is_zero.expr()), |cb| { cb.increase_balance(receiver_address, value.clone(), reversion_info) }); Self { - receiver, + receiver_balance, receiver_exists, opcode_is_create, value_is_zero, @@ -433,7 +433,7 @@ impl TransferToGadget { } else { (0.into(), 0.into()) }; - self.receiver.assign( + self.receiver_balance.assign( region, offset, receiver_balance_prev, From 74492894b0198af74cee971eb425805b0b5b14f4 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Tue, 5 Mar 2024 18:57:56 +0800 Subject: [PATCH 21/22] rename opcode_is_create -> is_create --- .../circuit_input_builder/input_state_ref.rs | 15 +++------- .../src/evm_circuit/util/common_gadget.rs | 28 ++++++++----------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/bus-mapping/src/circuit_input_builder/input_state_ref.rs b/bus-mapping/src/circuit_input_builder/input_state_ref.rs index fb26840466..07c250ead4 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -565,7 +565,7 @@ impl<'a> CircuitInputStateRef<'a> { sender: Address, receiver: Address, receiver_exists: bool, - opcode_is_create: bool, + is_create: bool, value: Word, fee: Option, ) -> Result<(), Error> { @@ -621,14 +621,7 @@ impl<'a> CircuitInputStateRef<'a> { )?; } - self.transfer_to( - step, - receiver, - receiver_exists, - opcode_is_create, - value, - true, - )?; + self.transfer_to(step, receiver, receiver_exists, is_create, value, true)?; Ok(()) } @@ -639,11 +632,11 @@ impl<'a> CircuitInputStateRef<'a> { step: &mut ExecStep, receiver: Address, receiver_exists: bool, - opcode_is_create: bool, + is_create: bool, value: Word, reversible: bool, ) -> Result<(), Error> { - if !receiver_exists && (!value.is_zero() || opcode_is_create) { + if !receiver_exists && (!value.is_zero() || is_create) { self.account_write( step, receiver, diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index aeab19215f..e4c97f9b31 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -370,7 +370,7 @@ impl pub(crate) struct TransferToGadget { receiver_balance: UpdateBalanceGadget, receiver_exists: Expression, - opcode_is_create: Expression, + is_create: Expression, value_is_zero: IsZeroWordGadget>, } @@ -380,7 +380,7 @@ impl TransferToGadget { cb: &mut EVMConstraintBuilder, receiver_address: WordLoHi>, receiver_exists: Expression, - opcode_is_create: Expression, + is_create: Expression, value: Word32Cell, mut reversion_info: Option<&mut ReversionInfo>, ) -> Self { @@ -391,7 +391,7 @@ impl TransferToGadget { cb.condition( and::expr([ not::expr(receiver_exists.expr()), - or::expr([not::expr(value_is_zero.expr()), opcode_is_create.expr()]), + or::expr([not::expr(value_is_zero.expr()), is_create.expr()]), ]), |cb| { cb.account_write( @@ -411,7 +411,7 @@ impl TransferToGadget { Self { receiver_balance, receiver_exists, - opcode_is_create, + is_create, value_is_zero, } } @@ -421,9 +421,9 @@ impl TransferToGadget { region: &mut CachedRegion<'_, '_, F>, offset: usize, rws: &mut StepRws, - (receiver_exists, value, opcode_is_create): (bool, U256, bool), + (receiver_exists, value, is_create): (bool, U256, bool), ) -> Result<(), Error> { - if !receiver_exists && (!value.is_zero() || opcode_is_create) { + if !receiver_exists && (!value.is_zero() || is_create) { // receiver's code_hash rws.next().account_codehash_pair(); } @@ -449,7 +449,7 @@ impl TransferToGadget { // +1 Write Account (receiver) CodeHash (account creation via code_hash update) and::expr([ not::expr(self.receiver_exists.expr()), - or::expr([not::expr(self.value_is_zero.expr()), self.opcode_is_create.expr()]) + or::expr([not::expr(self.value_is_zero.expr()), self.is_create.expr()]) ])+ // +1 Write Account (receiver) Balance not::expr(self.value_is_zero.expr()) @@ -478,7 +478,7 @@ impl TransferGadget { sender_address: WordLoHi>, receiver_address: WordLoHi>, receiver_exists: Expression, - opcode_is_create: Expression, + is_create: Expression, value: Word32Cell, reversion_info: &mut ReversionInfo, gas_fee: Option>, @@ -497,7 +497,7 @@ impl TransferGadget { cb, receiver_address, receiver_exists, - opcode_is_create, + is_create, value, Some(reversion_info), ); @@ -533,7 +533,7 @@ impl TransferGadget { region: &mut CachedRegion<'_, '_, F>, offset: usize, rws: &mut StepRws, - (receiver_exists, value, opcode_is_create): (bool, U256, bool), + (receiver_exists, value, is_create): (bool, U256, bool), gas_fee: Option, ) -> Result<(), Error> { if WITH_FEE { @@ -558,12 +558,8 @@ impl TransferGadget { vec![value], sender_balance_sub_value.0, )?; - self.receiver.assign( - region, - offset, - rws, - (receiver_exists, value, opcode_is_create), - )?; + self.receiver + .assign(region, offset, rws, (receiver_exists, value, is_create))?; self.value_is_zero .assign_value(region, offset, Value::known(WordLoHi::from(value)))?; Ok(()) From f8773e27f95259a6fe4e589e485a5fb0563746d9 Mon Sep 17 00:00:00 2001 From: ChihChengLiang Date: Tue, 5 Mar 2024 19:02:54 +0800 Subject: [PATCH 22/22] expand receiver creation args --- zkevm-circuits/src/evm_circuit/execution/begin_tx.rs | 4 +++- zkevm-circuits/src/evm_circuit/execution/callop.rs | 9 ++------- zkevm-circuits/src/evm_circuit/execution/create.rs | 4 +++- zkevm-circuits/src/evm_circuit/execution/end_tx.rs | 4 +++- zkevm-circuits/src/evm_circuit/util/common_gadget.rs | 10 +++++++--- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs index 5910fcb84c..817b7dbff7 100644 --- a/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/begin_tx.rs @@ -470,7 +470,9 @@ impl ExecutionGadget for BeginTxGadget { region, offset, &mut rws, - (callee_exists, tx.value, tx.is_create()), + callee_exists, + tx.value, + tx.is_create(), Some(gas_fee), )?; self.begin_tx.assign(region, offset, tx)?; diff --git a/zkevm-circuits/src/evm_circuit/execution/callop.rs b/zkevm-circuits/src/evm_circuit/execution/callop.rs index ce9807083c..571a33dc5b 100644 --- a/zkevm-circuits/src/evm_circuit/execution/callop.rs +++ b/zkevm-circuits/src/evm_circuit/execution/callop.rs @@ -868,13 +868,8 @@ impl ExecutionGadget for CallOpGadget { // conditionally assign if is_call && is_precheck_ok { - self.transfer.assign( - region, - offset, - &mut rws, - (callee_exists, value, false), - None, - )?; + self.transfer + .assign(region, offset, &mut rws, callee_exists, value, false, None)?; } self.opcode diff --git a/zkevm-circuits/src/evm_circuit/execution/create.rs b/zkevm-circuits/src/evm_circuit/execution/create.rs index adfb91fafb..c999a73e40 100644 --- a/zkevm-circuits/src/evm_circuit/execution/create.rs +++ b/zkevm-circuits/src/evm_circuit/execution/create.rs @@ -643,7 +643,9 @@ impl ExecutionGadget< region, offset, &mut rws, - (!callee_prev_code_hash.is_zero(), value, true), + !callee_prev_code_hash.is_zero(), + value, + true, None, )?; } diff --git a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs index c576811f5b..27ca5f119e 100644 --- a/zkevm-circuits/src/evm_circuit/execution/end_tx.rs +++ b/zkevm-circuits/src/evm_circuit/execution/end_tx.rs @@ -212,7 +212,9 @@ impl ExecutionGadget for EndTxGadget { region, offset, &mut rws, - (!coinbase_code_hash_prev.is_zero(), coinbase_reward, false), + !coinbase_code_hash_prev.is_zero(), + coinbase_reward, + false, )?; self.is_persistent.assign( region, diff --git a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs index e4c97f9b31..ebf88f135f 100644 --- a/zkevm-circuits/src/evm_circuit/util/common_gadget.rs +++ b/zkevm-circuits/src/evm_circuit/util/common_gadget.rs @@ -421,7 +421,9 @@ impl TransferToGadget { region: &mut CachedRegion<'_, '_, F>, offset: usize, rws: &mut StepRws, - (receiver_exists, value, is_create): (bool, U256, bool), + receiver_exists: bool, + value: U256, + is_create: bool, ) -> Result<(), Error> { if !receiver_exists && (!value.is_zero() || is_create) { // receiver's code_hash @@ -533,7 +535,9 @@ impl TransferGadget { region: &mut CachedRegion<'_, '_, F>, offset: usize, rws: &mut StepRws, - (receiver_exists, value, is_create): (bool, U256, bool), + receiver_exists: bool, + value: U256, + is_create: bool, gas_fee: Option, ) -> Result<(), Error> { if WITH_FEE { @@ -559,7 +563,7 @@ impl TransferGadget { sender_balance_sub_value.0, )?; self.receiver - .assign(region, offset, rws, (receiver_exists, value, is_create))?; + .assign(region, offset, rws, receiver_exists, value, is_create)?; self.value_is_zero .assign_value(region, offset, Value::known(WordLoHi::from(value)))?; Ok(())