From 20707974ab0d03ce2c5271407f5ee4fb24936308 Mon Sep 17 00:00:00 2001 From: Jerry Date: Wed, 6 Nov 2024 16:47:37 -0800 Subject: [PATCH] Remove redundant writes when a state object is reverted (#21) * Remove redundant writes when a state object is reverted * Change IsDirty to Transaction level We don't want a reverted transaction to show up in written trace because it was touched by a previous transaction. * Add storage read whenever there is a sstore This fixes an issue when a storage slot is * written but got reverted * never read by sLoad opcode When this happens, we still need to include the storage slot in the trace. --- core/state/intra_block_state.go | 5 +++++ core/vm/evmtypes/evmtypes.go | 1 + eth/tracers/native/zero.go | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/state/intra_block_state.go b/core/state/intra_block_state.go index e56462ed418..0760f9d7837 100644 --- a/core/state/intra_block_state.go +++ b/core/state/intra_block_state.go @@ -426,6 +426,11 @@ func (sdb *IntraBlockState) SeenAccount(addr libcommon.Address) bool { return ok } +func (sdb *IntraBlockState) IsDirtyJournal(addr libcommon.Address) bool { + _, ok := sdb.journal.dirties[addr] + return ok +} + func (sdb *IntraBlockState) HasLiveState(addr libcommon.Address, key *libcommon.Hash) bool { if stateObject := sdb.stateObjects[addr]; stateObject != nil { if _, ok := stateObject.originStorage[*key]; ok { diff --git a/core/vm/evmtypes/evmtypes.go b/core/vm/evmtypes/evmtypes.go index f4d10657fe3..0fa67f40653 100644 --- a/core/vm/evmtypes/evmtypes.go +++ b/core/vm/evmtypes/evmtypes.go @@ -82,6 +82,7 @@ type IntraBlockState interface { SetState(common.Address, *common.Hash, uint256.Int) HasLiveAccount(addr common.Address) bool SeenAccount(addr common.Address) bool + IsDirtyJournal(addr common.Address) bool HasLiveState(addr common.Address, key *common.Hash) bool GetTransientState(addr common.Address, key common.Hash) uint256.Int diff --git a/eth/tracers/native/zero.go b/eth/tracers/native/zero.go index 65c32c30069..3593a38eea1 100644 --- a/eth/tracers/native/zero.go +++ b/eth/tracers/native/zero.go @@ -220,7 +220,7 @@ func (t *zeroTracer) CaptureTxEnd(restGas uint64) { trace.StorageRead = nil } - if len(trace.StorageWritten) == 0 || !hasLiveAccount { + if len(trace.StorageWritten) == 0 || !hasLiveAccount || !t.env.IntraBlockState().IsDirtyJournal(addr) { trace.StorageWritten = nil } else { // A slot write could be reverted if the transaction is reverted. We will need to read the value from the statedb again to get the correct value. @@ -379,6 +379,7 @@ func (t *zeroTracer) addSLOADToAccount(addr libcommon.Address, key libcommon.Has func (t *zeroTracer) addSSTOREToAccount(addr libcommon.Address, key libcommon.Hash, value *uint256.Int) { t.tx.Traces[addr].StorageWritten[key] = value + t.tx.Traces[addr].StorageReadMap[key] = struct{}{} t.addOpCodeToAccount(addr, vm.SSTORE) }