core/state: fix tracer hook for EIP-7708 burn logs (#34688)

This PR fixes https://github.com/ethereum/go-ethereum/issues/34623 by
changing the `vm.StateDB` interface: 

Instead of `EmitLogsForBurnAccounts()` emitting burn logs, `LogsForBurnAccounts()
[]*types.Log` just returns these logs which are then emitted by the caller. 

This way when tracing is used, `hookedStateDB.AddLog` will be used 
automatically and there is no need to duplicate either the burn log
logic or the `OnLog` tracing hook.
This commit is contained in:
Felföldi Zsolt 2026-04-09 03:12:35 +02:00 committed by GitHub
parent a8ea6319f1
commit 21b19362c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 17 additions and 12 deletions

View file

@ -745,7 +745,7 @@ type removedAccountWithBalance struct {
balance *uint256.Int balance *uint256.Int
} }
// EmitLogsForBurnAccounts emits the eth burn logs for accounts scheduled for // LogsForBurnAccounts returns the eth burn logs for accounts scheduled for
// removal which still have positive balance. The purpose of this function is // removal which still have positive balance. The purpose of this function is
// to handle a corner case of EIP-7708 where a self-destructed account might // to handle a corner case of EIP-7708 where a self-destructed account might
// still receive funds between sending/burning its previous balance and actual // still receive funds between sending/burning its previous balance and actual
@ -755,7 +755,7 @@ type removedAccountWithBalance struct {
// //
// This function should only be invoked at the transaction boundary, specifically // This function should only be invoked at the transaction boundary, specifically
// before the Finalise. // before the Finalise.
func (s *StateDB) EmitLogsForBurnAccounts() { func (s *StateDB) LogsForBurnAccounts() []*types.Log {
var list []removedAccountWithBalance var list []removedAccountWithBalance
for addr := range s.journal.dirties { for addr := range s.journal.dirties {
if obj, exist := s.stateObjects[addr]; exist && obj.selfDestructed && !obj.Balance().IsZero() { if obj, exist := s.stateObjects[addr]; exist && obj.selfDestructed && !obj.Balance().IsZero() {
@ -765,14 +765,17 @@ func (s *StateDB) EmitLogsForBurnAccounts() {
}) })
} }
} }
if list != nil { if list == nil {
sort.Slice(list, func(i, j int) bool { return nil
return list[i].address.Cmp(list[j].address) < 0
})
} }
for _, acct := range list { sort.Slice(list, func(i, j int) bool {
s.AddLog(types.EthBurnLog(acct.address, acct.balance)) return list[i].address.Cmp(list[j].address) < 0
})
logs := make([]*types.Log, len(list))
for i, acct := range list {
logs[i] = types.EthBurnLog(acct.address, acct.balance)
} }
return logs
} }
// Finalise finalises the state by removing the destructed objects and clears // Finalise finalises the state by removing the destructed objects and clears

View file

@ -229,8 +229,8 @@ func (s *hookedStateDB) AddLog(log *types.Log) {
} }
} }
func (s *hookedStateDB) EmitLogsForBurnAccounts() { func (s *hookedStateDB) LogsForBurnAccounts() []*types.Log {
s.inner.EmitLogsForBurnAccounts() return s.inner.LogsForBurnAccounts()
} }
func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) { func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) {

View file

@ -584,7 +584,9 @@ func (st *stateTransition) execute() (*ExecutionResult, error) {
} }
} }
if rules.IsAmsterdam { if rules.IsAmsterdam {
st.evm.StateDB.EmitLogsForBurnAccounts() for _, log := range st.evm.StateDB.LogsForBurnAccounts() {
st.evm.StateDB.AddLog(log)
}
} }
return &ExecutionResult{ return &ExecutionResult{
UsedGas: st.gasUsed(), UsedGas: st.gasUsed(),

View file

@ -87,7 +87,7 @@ type StateDB interface {
Snapshot() int Snapshot() int
AddLog(*types.Log) AddLog(*types.Log)
EmitLogsForBurnAccounts() LogsForBurnAccounts() []*types.Log
AddPreimage(common.Hash, []byte) AddPreimage(common.Hash, []byte)
Witness() *stateless.Witness Witness() *stateless.Witness