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 356434c8a7..f2582d916b 100644 --- a/bus-mapping/src/circuit_input_builder/input_state_ref.rs +++ b/bus-mapping/src/circuit_input_builder/input_state_ref.rs @@ -1179,6 +1179,14 @@ impl<'a> CircuitInputStateRef<'a> { None } } + OperationRef(Target::TransientStorage, idx) => { + let operation = &self.block.container.transient_storage[*idx]; + if operation.rw().is_write() && operation.reversible() { + Some(OpEnum::TransientStorage(operation.op().reverse())) + } else { + None + } + } OperationRef(Target::TxAccessListAccount, idx) => { let operation = &self.block.container.tx_access_list_account[*idx]; if operation.rw().is_write() && operation.reversible() { @@ -1698,6 +1706,7 @@ impl<'a> CircuitInputStateRef<'a> { OpcodeId::RETURNDATACOPY => Some(ExecError::ReturnDataOutOfBounds), // Break write protection (CALL with value will be handled below) OpcodeId::SSTORE + | OpcodeId::TSTORE | OpcodeId::CREATE | OpcodeId::CREATE2 | OpcodeId::SELFDESTRUCT diff --git a/bus-mapping/src/evm/opcodes/error_write_protection.rs b/bus-mapping/src/evm/opcodes/error_write_protection.rs index 963de9e080..85bc2611ba 100644 --- a/bus-mapping/src/evm/opcodes/error_write_protection.rs +++ b/bus-mapping/src/evm/opcodes/error_write_protection.rs @@ -31,6 +31,7 @@ impl Opcode for ErrorWriteProtection { // assert op code can only be following codes assert!([ OpcodeId::SSTORE, + OpcodeId::TSTORE, OpcodeId::CREATE, OpcodeId::CREATE2, OpcodeId::CALL, diff --git a/bus-mapping/src/operation/container.rs b/bus-mapping/src/operation/container.rs index beb1db69fe..b4eb3225af 100644 --- a/bus-mapping/src/operation/container.rs +++ b/bus-mapping/src/operation/container.rs @@ -115,8 +115,11 @@ impl OperationContainer { OperationRef::from((Target::Storage, self.storage.len() - 1)) } OpEnum::TransientStorage(op) => { - // removed rwc_inner_chunk here... does that matter? - self.transient_storage.push(Operation::new(rwc, rw, op)); + self.transient_storage.push(if reversible { + Operation::new_reversible(rwc, rw, op) + } else { + Operation::new(rwc, rw, op) + }); OperationRef::from((Target::TransientStorage, self.transient_storage.len() - 1)) } OpEnum::TxAccessListAccount(op) => { diff --git a/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs b/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs index 8ba1620693..3162baf4eb 100644 --- a/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs +++ b/zkevm-circuits/src/evm_circuit/execution/error_write_protection.rs @@ -44,11 +44,12 @@ impl ExecutionGadget for ErrorWriteProtectionGadget { // max_degree. otherwise need to do fixed lookup for these opcodes // checking. cb.require_in_set( - "ErrorWriteProtection only happens in [CALL, SSTORE, CREATE, CREATE2, SELFDESTRUCT, LOG0..4 ]", + "ErrorWriteProtection only happens in [CALL, SSTORE, TSTORE, CREATE, CREATE2, SELFDESTRUCT, LOG0..4 ]", opcode.expr(), vec![ OpcodeId::CALL.expr(), OpcodeId::SSTORE.expr(), + OpcodeId::TSTORE.expr(), OpcodeId::CREATE.expr(), OpcodeId::CREATE2.expr(), OpcodeId::SELFDESTRUCT.expr(),