go-ethereum/eth/tracers/logger/logger_trace.go
HAOYUatHZ 74578fa06e
refactor: remove unused storage traces (#902)
refactor: remove unused storage traces  (#819)

Co-authored-by: Ömer Faruk Irmak <omerfirmak@gmail.com>
2024-07-15 16:31:11 +08:00

110 lines
4.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package logger
import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/core/vm"
)
type traceFunc func(l *StructLogger, scope *vm.ScopeContext, extraData *types.ExtraData) error
var (
// OpcodeExecs the map to load opcodes' trace funcs.
OpcodeExecs = map[vm.OpCode][]traceFunc{
vm.CALL: {traceToAddressCode, traceLastNAddressCode(1), traceContractAccount, traceLastNAddressAccount(1)}, // contract account is the caller, stack.nth_last(1) is the callee's address
vm.CALLCODE: {traceToAddressCode, traceLastNAddressCode(1), traceContractAccount, traceLastNAddressAccount(1)}, // contract account is the caller, stack.nth_last(1) is the callee's address
vm.DELEGATECALL: {traceToAddressCode, traceLastNAddressCode(1)},
vm.STATICCALL: {traceToAddressCode, traceLastNAddressCode(1), traceLastNAddressAccount(1)},
vm.CREATE: {}, // caller is already recorded in ExtraData.Caller, callee is recorded in CaptureEnter&CaptureExit
vm.CREATE2: {}, // caller is already recorded in ExtraData.Caller, callee is recorded in CaptureEnter&CaptureExit
vm.SLOAD: {}, // trace storage in `captureState` instead of here, to handle `l.cfg.DisableStorage` flag
vm.SSTORE: {}, // trace storage in `captureState` instead of here, to handle `l.cfg.DisableStorage` flag
vm.SELFDESTRUCT: {traceContractAccount, traceLastNAddressAccount(0)},
vm.SELFBALANCE: {traceContractAccount},
vm.BALANCE: {traceLastNAddressAccount(0)},
vm.EXTCODEHASH: {traceLastNAddressAccount(0)},
vm.CODESIZE: {traceContractCode},
vm.CODECOPY: {traceContractCode},
vm.EXTCODESIZE: {traceLastNAddressCode(0)},
vm.EXTCODECOPY: {traceLastNAddressCode(0)},
}
)
// traceToAddressCode gets tx.to addresss code
func traceToAddressCode(l *StructLogger, scope *vm.ScopeContext, extraData *types.ExtraData) error {
if l.env.To == nil {
return nil
}
code := l.env.StateDB.GetCode(*l.env.To)
extraData.CodeList = append(extraData.CodeList, hexutil.Encode(code))
return nil
}
// traceLastNAddressCode
func traceLastNAddressCode(n int) traceFunc {
return func(l *StructLogger, scope *vm.ScopeContext, extraData *types.ExtraData) error {
stack := scope.Stack
stackData := stack.Data()
stackLen := len(stackData)
if stackLen <= n {
return nil
}
address := common.Address(stackData[stackLen-1-n].Bytes20())
code := l.env.StateDB.GetCode(address)
extraData.CodeList = append(extraData.CodeList, hexutil.Encode(code))
l.statesAffected[address] = struct{}{}
return nil
}
}
// traceContractCode gets the contract's code
func traceContractCode(l *StructLogger, scope *vm.ScopeContext, extraData *types.ExtraData) error {
code := l.env.StateDB.GetCode(scope.Contract.Address())
extraData.CodeList = append(extraData.CodeList, hexutil.Encode(code))
return nil
}
// traceContractAccount gets the contract's account
func traceContractAccount(l *StructLogger, scope *vm.ScopeContext, extraData *types.ExtraData) error {
// Get account state.
state := getWrappedAccountForAddr(l, scope.Contract.Address())
extraData.StateList = append(extraData.StateList, state)
l.statesAffected[scope.Contract.Address()] = struct{}{}
return nil
}
// traceLastNAddressAccount returns func about the last N's address account.
func traceLastNAddressAccount(n int) traceFunc {
return func(l *StructLogger, scope *vm.ScopeContext, extraData *types.ExtraData) error {
stack := scope.Stack
stackData := stack.Data()
stackLen := len(stackData)
if stackLen <= n {
return nil
}
address := common.Address(stackData[stackLen-1-n].Bytes20())
state := getWrappedAccountForAddr(l, address)
extraData.StateList = append(extraData.StateList, state)
l.statesAffected[address] = struct{}{}
return nil
}
}
// StorageWrapper will be empty
func getWrappedAccountForAddr(l *StructLogger, address common.Address) *types.AccountWrapper {
return &types.AccountWrapper{
Address: address,
Nonce: l.env.StateDB.GetNonce(address),
Balance: (*hexutil.Big)(l.env.StateDB.GetBalance(address)),
KeccakCodeHash: l.env.StateDB.GetKeccakCodeHash(address),
PoseidonCodeHash: l.env.StateDB.GetPoseidonCodeHash(address),
CodeSize: l.env.StateDB.GetCodeSize(address),
}
}
func getCodeForAddr(l *StructLogger, address common.Address) []byte {
return l.env.StateDB.GetCode(address)
}