Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(trace): add more opcode handlings #128

Merged
merged 15 commits into from
Jul 24, 2022
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)
}