fix(trace): add more opcode handlings (#128)

This commit is contained in:
HAOYUatHZ 2022-07-24 21:39:33 +08:00 committed by GitHub
parent 37dbb86aa6
commit eb11a84c56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 13 deletions

View file

@ -107,6 +107,9 @@ type ExtraData struct {
// Indicate the call succeeds or not for CALL/CREATE op // Indicate the call succeeds or not for CALL/CREATE op
CallFailed bool `json:"callFailed,omitempty"` CallFailed bool `json:"callFailed,omitempty"`
// CALL | CALLCODE | DELEGATECALL | STATICCALL: [tx.to addresss code, stack.nth_last(1) addresss code] // CALL | CALLCODE | DELEGATECALL | STATICCALL: [tx.to addresss code, stack.nth_last(1) addresss code]
// CREATE | CREATE2: [created contracts code]
// CODESIZE | CODECOPY: [contracts code]
// EXTCODESIZE | EXTCODECOPY: [stack.nth_last(0) addresss code]
CodeList []string `json:"codeList,omitempty"` CodeList []string `json:"codeList,omitempty"`
// SSTORE | SLOAD: [storageProof] // SSTORE | SLOAD: [storageProof]
// SELFDESTRUCT: [contract addresss account, stack.nth_last(0) addresss account] // SELFDESTRUCT: [contract addresss account, stack.nth_last(0) addresss account]

View file

@ -349,6 +349,8 @@ func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) {
lastAccData := theLog.ExtraData.StateList[dataLen-1] lastAccData := theLog.ExtraData.StateList[dataLen-1]
wrappedStatus := getWrappedAccountForAddr(l, lastAccData.Address) wrappedStatus := getWrappedAccountForAddr(l, lastAccData.Address)
theLog.ExtraData.StateList = append(theLog.ExtraData.StateList, wrappedStatus) theLog.ExtraData.StateList = append(theLog.ExtraData.StateList, wrappedStatus)
code := getCodeForAddr(l, lastAccData.Address)
theLog.ExtraData.CodeList = append(theLog.ExtraData.CodeList, hexutil.Encode(code))
default: default:
//do nothing for other op code //do nothing for other op code
return return

View file

@ -11,8 +11,8 @@ type traceFunc func(l *StructLogger, scope *ScopeContext, extraData *types.Extra
var ( var (
// OpcodeExecs the map to load opcodes' trace funcs. // OpcodeExecs the map to load opcodes' trace funcs.
OpcodeExecs = map[OpCode][]traceFunc{ OpcodeExecs = map[OpCode][]traceFunc{
CALL: {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), traceCaller, traceLastNAddressAccount(1)}, 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)}, DELEGATECALL: {traceToAddressCode, traceLastNAddressCode(1)},
STATICCALL: {traceToAddressCode, traceLastNAddressCode(1), traceLastNAddressAccount(1)}, STATICCALL: {traceToAddressCode, traceLastNAddressCode(1), traceLastNAddressAccount(1)},
CREATE: {}, // sender is already recorded in ExecutionResult, callee is recorded in CaptureEnter&CaptureExit CREATE: {}, // sender is already recorded in ExecutionResult, callee is recorded in CaptureEnter&CaptureExit
@ -23,6 +23,10 @@ var (
SELFBALANCE: {traceContractAccount}, SELFBALANCE: {traceContractAccount},
BALANCE: {traceLastNAddressAccount(0)}, BALANCE: {traceLastNAddressAccount(0)},
EXTCODEHASH: {traceLastNAddressAccount(0)}, EXTCODEHASH: {traceLastNAddressAccount(0)},
CODESIZE: {traceContractCode},
CODECOPY: {traceContractCode},
EXTCODESIZE: {traceLastNAddressCode(0)},
EXTCODECOPY: {traceLastNAddressCode(0)},
} }
) )
@ -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 // traceStorage get contract's storage at storage_address
func traceStorage(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error { func traceStorage(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error {
if scope.Stack.len() == 0 { if scope.Stack.len() == 0 {
@ -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 // StorageWrapper will be empty
func getWrappedAccountForAddr(l *StructLogger, address common.Address) *types.AccountWrapper { func getWrappedAccountForAddr(l *StructLogger, address common.Address) *types.AccountWrapper {
return &types.AccountWrapper{ return &types.AccountWrapper{
@ -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)
}