Skip to content

Commit

Permalink
fix(trace): add more opcode handlings (ethereum#128)
Browse files Browse the repository at this point in the history
  • Loading branch information
0xmountaintop authored Jul 24, 2022
1 parent 37dbb86 commit eb11a84
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 13 deletions.
3 changes: 3 additions & 0 deletions core/types/l2trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ type ExtraData struct {
// Indicate the call succeeds or not for CALL/CREATE op
CallFailed bool `json:"callFailed,omitempty"`
// CALL | CALLCODE | DELEGATECALL | STATICCALL: [tx.to address’s code, stack.nth_last(1) address’s code]
// CREATE | CREATE2: [created contract’s code]
// CODESIZE | CODECOPY: [contract’s code]
// EXTCODESIZE | EXTCODECOPY: [stack.nth_last(0) address’s code]
CodeList []string `json:"codeList,omitempty"`
// SSTORE | SLOAD: [storageProof]
// SELFDESTRUCT: [contract address’s account, stack.nth_last(0) address’s account]
Expand Down
2 changes: 2 additions & 0 deletions core/vm/logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) {
lastAccData := theLog.ExtraData.StateList[dataLen-1]
wrappedStatus := getWrappedAccountForAddr(l, lastAccData.Address)
theLog.ExtraData.StateList = append(theLog.ExtraData.StateList, wrappedStatus)
code := getCodeForAddr(l, lastAccData.Address)
theLog.ExtraData.CodeList = append(theLog.ExtraData.CodeList, hexutil.Encode(code))
default:
//do nothing for other op code
return
Expand Down
30 changes: 17 additions & 13 deletions core/vm/logger_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ type traceFunc func(l *StructLogger, scope *ScopeContext, extraData *types.Extra
var (
// OpcodeExecs the map to load opcodes' trace funcs.
OpcodeExecs = map[OpCode][]traceFunc{
CALL: {traceToAddressCode, traceLastNAddressCode(1), traceCaller, traceLastNAddressAccount(1)},
CALLCODE: {traceToAddressCode, traceLastNAddressCode(1), traceCaller, traceLastNAddressAccount(1)},
CALL: {traceToAddressCode, traceLastNAddressCode(1), traceContractAccount, traceLastNAddressAccount(1)}, // contract account is the caller, stack.nth_last(1) is the callee's address
CALLCODE: {traceToAddressCode, traceLastNAddressCode(1), traceContractAccount, traceLastNAddressAccount(1)}, // contract account is the caller, stack.nth_last(1) is the callee's address
DELEGATECALL: {traceToAddressCode, traceLastNAddressCode(1)},
STATICCALL: {traceToAddressCode, traceLastNAddressCode(1), traceLastNAddressAccount(1)},
CREATE: {}, // sender is already recorded in ExecutionResult, callee is recorded in CaptureEnter&CaptureExit
Expand All @@ -23,6 +23,10 @@ var (
SELFBALANCE: {traceContractAccount},
BALANCE: {traceLastNAddressAccount(0)},
EXTCODEHASH: {traceLastNAddressAccount(0)},
CODESIZE: {traceContractCode},
CODECOPY: {traceContractCode},
EXTCODESIZE: {traceLastNAddressCode(0)},
EXTCODECOPY: {traceLastNAddressCode(0)},
}
)

Expand Down Expand Up @@ -50,6 +54,13 @@ func traceLastNAddressCode(n int) traceFunc {
}
}

// traceContractCode gets the contract's code
func traceContractCode(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error {
code := l.env.StateDB.GetCode(scope.Contract.Address())
extraData.CodeList = append(extraData.CodeList, hexutil.Encode(code))
return nil
}

// traceStorage get contract's storage at storage_address
func traceStorage(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error {
if scope.Stack.len() == 0 {
Expand Down Expand Up @@ -89,17 +100,6 @@ func traceLastNAddressAccount(n int) traceFunc {
}
}

// traceCaller gets caller address's account.
func traceCaller(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error {
address := scope.Contract.CallerAddress
state := getWrappedAccountForAddr(l, address)

extraData.StateList = append(extraData.StateList, state)
l.statesAffected[scope.Contract.Address()] = struct{}{}

return nil
}

// StorageWrapper will be empty
func getWrappedAccountForAddr(l *StructLogger, address common.Address) *types.AccountWrapper {
return &types.AccountWrapper{
Expand All @@ -122,3 +122,7 @@ func getWrappedAccountForStorage(l *StructLogger, address common.Address, key co
},
}
}

func getCodeForAddr(l *StructLogger, address common.Address) []byte {
return l.env.StateDB.GetCode(address)
}

0 comments on commit eb11a84

Please sign in to comment.