diff --git a/circuit-benchmarks/src/evm_circuit.rs b/circuit-benchmarks/src/evm_circuit.rs index a950d506fc..6ac9c86f8a 100644 --- a/circuit-benchmarks/src/evm_circuit.rs +++ b/circuit-benchmarks/src/evm_circuit.rs @@ -22,7 +22,7 @@ impl Circuit for TestCircuit { fn configure(meta: &mut ConstraintSystem) -> Self::Config { let tx_table = [(); 4].map(|_| meta.advice_column()); - let rw_table = [(); 8].map(|_| meta.advice_column()); + let rw_table = [(); 10].map(|_| meta.advice_column()); let bytecode_table = [(); 4].map(|_| meta.advice_column()); let block_table = [(); 3].map(|_| meta.advice_column()); // Use constant expression to mock constant instance column for a more diff --git a/integration-tests/tests/circuits.rs b/integration-tests/tests/circuits.rs index 77d7ed7d6b..2eaf78c895 100644 --- a/integration-tests/tests/circuits.rs +++ b/integration-tests/tests/circuits.rs @@ -34,7 +34,7 @@ mod test_evm_circuit { #[derive(Clone)] struct TestCircuitConfig { tx_table: [Column; 4], - rw_table: [Column; 8], + rw_table: [Column; 10], bytecode_table: [Column; 4], evm_circuit: EvmCircuit, } @@ -185,7 +185,7 @@ mod test_evm_circuit { fn configure(meta: &mut ConstraintSystem) -> Self::Config { let tx_table = [(); 4].map(|_| meta.advice_column()); - let rw_table = [(); 8].map(|_| meta.advice_column()); + let rw_table = [(); 10].map(|_| meta.advice_column()); let bytecode_table = [(); 4].map(|_| meta.advice_column()); let block_table = [(); 3].map(|_| meta.advice_column()); diff --git a/zkevm-circuits/src/evm_circuit.rs b/zkevm-circuits/src/evm_circuit.rs index d451e860e2..2517d8b0a2 100644 --- a/zkevm-circuits/src/evm_circuit.rs +++ b/zkevm-circuits/src/evm_circuit.rs @@ -34,7 +34,7 @@ impl EvmCircuit { ) -> Self where TxTable: LookupTable, - RwTable: LookupTable, + RwTable: LookupTable, BytecodeTable: LookupTable, BlockTable: LookupTable, { @@ -160,7 +160,7 @@ pub(crate) mod test { #[derive(Clone)] pub(crate) struct TestCircuitConfig { tx_table: [Column; 4], - rw_table: [Column; 8], + rw_table: [Column; 10], bytecode_table: [Column; 4], block_table: [Column; 3], evm_circuit: EvmCircuit, @@ -353,7 +353,7 @@ pub(crate) mod test { fn configure(meta: &mut ConstraintSystem) -> Self::Config { let tx_table = [(); 4].map(|_| meta.advice_column()); - let rw_table = [(); 8].map(|_| meta.advice_column()); + let rw_table = [(); 10].map(|_| meta.advice_column()); let bytecode_table = [(); 4].map(|_| meta.advice_column()); let block_table = [(); 3].map(|_| meta.advice_column()); diff --git a/zkevm-circuits/src/evm_circuit/execution.rs b/zkevm-circuits/src/evm_circuit/execution.rs index 76c4e8a6a8..f0185041ab 100644 --- a/zkevm-circuits/src/evm_circuit/execution.rs +++ b/zkevm-circuits/src/evm_circuit/execution.rs @@ -119,7 +119,7 @@ impl ExecutionConfig { ) -> Self where TxTable: LookupTable, - RwTable: LookupTable, + RwTable: LookupTable, BytecodeTable: LookupTable, BlockTable: LookupTable, { @@ -314,7 +314,7 @@ impl ExecutionConfig { independent_lookups: Vec>>, ) where TxTable: LookupTable, - RwTable: LookupTable, + RwTable: LookupTable, BytecodeTable: LookupTable, BlockTable: LookupTable, { diff --git a/zkevm-circuits/src/evm_circuit/table.rs b/zkevm-circuits/src/evm_circuit/table.rs index 825155fd88..ef584aa3bd 100644 --- a/zkevm-circuits/src/evm_circuit/table.rs +++ b/zkevm-circuits/src/evm_circuit/table.rs @@ -153,6 +153,20 @@ pub enum RwTableTag { Memory, } +impl RwTableTag { + pub fn is_reversible(self) -> bool { + return matches!( + self, + RwTableTag::TxAccessListAccount + | RwTableTag::TxAccessListStorageSlot + | RwTableTag::TxRefund + | RwTableTag::Account + | RwTableTag::AccountStorage + | RwTableTag::AccountDestructed + ); + } +} + #[derive(Clone, Copy, Debug)] pub enum AccountFieldTag { Nonce = 1, @@ -237,7 +251,7 @@ pub(crate) enum Lookup { /// all tags. tag: Expression, /// Values corresponding to the tag. - values: [Expression; 5], + values: [Expression; 7], }, /// Lookup to bytecode table, which contains all used creation code and /// contract code. diff --git a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs index 62fbf9698b..95a4b23658 100644 --- a/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs +++ b/zkevm-circuits/src/evm_circuit/util/constraint_builder.rs @@ -480,7 +480,7 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { counter: Expression, is_write: Expression, tag: RwTableTag, - values: [Expression; 5], + values: [Expression; 7], ) { self.add_lookup( name, @@ -500,7 +500,7 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { name: &'static str, is_write: Expression, tag: RwTableTag, - values: [Expression; 5], + values: [Expression; 7], ) { self.rw_lookup_with_counter( name, @@ -516,7 +516,7 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { &mut self, name: &'static str, tag: RwTableTag, - mut values: [Expression; 5], + mut values: [Expression; 7], is_persistent: Expression, rw_counter_end_of_reversion: Expression, ) { @@ -527,15 +527,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { // Calculate state_write_counter so far let state_write_counter = cb.curr.state.state_write_counter.expr() + cb.state_write_counter_offset.expr(); + // Swap value and value_prev respect to tag - match tag { - RwTableTag::TxAccessListAccount => values.swap(2, 3), - RwTableTag::TxAccessListStorageSlot => values.swap(3, 4), - RwTableTag::Account => values.swap(2, 3), - RwTableTag::AccountStorage => values.swap(3, 4), - RwTableTag::AccountDestructed => values.swap(2, 3), - _ => {} - } + if tag.is_reversible() { + values.swap(3, 4) + }; cb.rw_lookup_with_counter( name, @@ -562,7 +558,15 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { "AccountAccessList write", true.expr(), RwTableTag::TxAccessListAccount, - [tx_id, account_address, value, value_prev, 0.expr()], + [ + tx_id, + account_address, + 0.expr(), + value, + value_prev, + 0.expr(), + 0.expr(), + ], ); } @@ -581,9 +585,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ account_address, field_tag.expr(), + 0.expr(), value.clone(), value, 0.expr(), + 0.expr(), ], ); } @@ -602,9 +608,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ account_address, field_tag.expr(), + 0.expr(), value, value_prev, 0.expr(), + 0.expr(), ], ); } @@ -624,9 +632,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ account_address, field_tag.expr(), + 0.expr(), value, value_prev, 0.expr(), + 0.expr(), ], is_persistent, rw_counter_end_of_reversion, @@ -658,9 +668,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ call_id.unwrap_or_else(|| self.curr.state.call_id.expr()), field_tag.expr(), + 0.expr(), value, 0.expr(), 0.expr(), + 0.expr(), ], ); } @@ -694,9 +706,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ self.curr.state.call_id.expr(), self.curr.state.stack_pointer.expr() + stack_pointer_offset, + 0.expr(), value, 0.expr(), 0.expr(), + 0.expr(), ], ); } @@ -716,9 +730,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ self.curr.state.call_id.expr(), memory_address, + 0.expr(), byte, 0.expr(), 0.expr(), + 0.expr(), ], ); } @@ -738,9 +754,11 @@ impl<'a, F: FieldExt> ConstraintBuilder<'a, F> { [ self.curr.state.call_id.expr(), memory_address, + 0.expr(), byte, 0.expr(), 0.expr(), + 0.expr(), ], ); } diff --git a/zkevm-circuits/src/evm_circuit/witness.rs b/zkevm-circuits/src/evm_circuit/witness.rs index 774f461c20..be1d07d01d 100644 --- a/zkevm-circuits/src/evm_circuit/witness.rs +++ b/zkevm-circuits/src/evm_circuit/witness.rs @@ -442,7 +442,7 @@ impl Rw { } } - pub fn table_assignment(&self, randomness: F) -> [F; 8] { + pub fn table_assignment(&self, randomness: F) -> [F; 10] { match self { Self::TxAccessListAccount { rw_counter, @@ -457,9 +457,11 @@ impl Rw { F::from(RwTableTag::TxAccessListAccount as u64), F::from(*tx_id as u64), account_address.to_scalar().unwrap(), + F::zero(), F::from(*value as u64), F::from(*value_prev as u64), F::zero(), + F::zero(), ], Self::Account { rw_counter, @@ -482,9 +484,11 @@ impl Rw { F::from(RwTableTag::Account as u64), account_address.to_scalar().unwrap(), F::from(*field_tag as u64), + F::zero(), to_scalar(value), to_scalar(value_prev), F::zero(), + F::zero(), ] } Self::CallContext { @@ -499,6 +503,7 @@ impl Rw { F::from(RwTableTag::CallContext as u64), F::from(*call_id as u64), F::from(*field_tag as u64), + F::zero(), match field_tag { CallContextFieldTag::OpcodeSource | CallContextFieldTag::Value => { @@ -514,6 +519,7 @@ impl Rw { }, F::zero(), F::zero(), + F::zero(), ], Self::Stack { rw_counter, @@ -527,12 +533,14 @@ impl Rw { F::from(RwTableTag::Stack as u64), F::from(*call_id as u64), F::from(*stack_pointer as u64), + F::zero(), RandomLinearCombination::random_linear_combine( value.to_le_bytes(), randomness, ), F::zero(), F::zero(), + F::zero(), ], Self::Memory { rw_counter, @@ -546,9 +554,11 @@ impl Rw { F::from(RwTableTag::Memory as u64), F::from(*call_id as u64), F::from(*memory_address), + F::zero(), F::from(*byte as u64), F::zero(), F::zero(), + F::zero(), ], _ => unimplemented!(), }