123 lines
2.5 KiB
Go
123 lines
2.5 KiB
Go
package types
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"regexp"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type ExecutionTrace struct {
|
|
Msg *Message
|
|
MsgRct *MessageReceipt
|
|
Error string
|
|
Duration time.Duration
|
|
GasCharges []*GasTrace
|
|
|
|
Subcalls []ExecutionTrace
|
|
}
|
|
|
|
type GasTrace struct {
|
|
Name string
|
|
|
|
Location []Loc `json:"loc"`
|
|
TotalGas int64 `json:"tg"`
|
|
ComputeGas int64 `json:"cg"`
|
|
StorageGas int64 `json:"sg"`
|
|
TotalVirtualGas int64 `json:"vtg"`
|
|
VirtualComputeGas int64 `json:"vcg"`
|
|
VirtualStorageGas int64 `json:"vsg"`
|
|
|
|
TimeTaken time.Duration `json:"tt"`
|
|
Extra interface{} `json:"ex,omitempty"`
|
|
|
|
Callers []uintptr `json:"-"`
|
|
}
|
|
|
|
type Loc struct {
|
|
File string
|
|
Line int
|
|
Function string
|
|
}
|
|
|
|
func (et ExecutionTrace) SumGas() GasTrace {
|
|
return SumGas(et.GasCharges)
|
|
}
|
|
|
|
func SumGas(charges []*GasTrace) GasTrace {
|
|
var out GasTrace
|
|
for _, gc := range charges {
|
|
out.TotalGas += gc.TotalGas
|
|
out.ComputeGas += gc.ComputeGas
|
|
out.StorageGas += gc.StorageGas
|
|
|
|
out.TotalVirtualGas += gc.TotalVirtualGas
|
|
out.VirtualComputeGas += gc.VirtualComputeGas
|
|
out.VirtualStorageGas += gc.VirtualStorageGas
|
|
}
|
|
|
|
return out
|
|
}
|
|
|
|
func (l Loc) Show() bool {
|
|
ignorePrefix := []string{
|
|
"reflect.",
|
|
"github.com/filecoin-project/lotus/chain/vm.(*Invoker).transform",
|
|
"github.com/filecoin-project/go-amt-ipld/",
|
|
}
|
|
for _, pre := range ignorePrefix {
|
|
if strings.HasPrefix(l.Function, pre) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
func (l Loc) String() string {
|
|
file := strings.Split(l.File, "/")
|
|
|
|
fn := strings.Split(l.Function, "/")
|
|
var fnpkg string
|
|
if len(fn) > 2 {
|
|
fnpkg = strings.Join(fn[len(fn)-2:], "/")
|
|
} else {
|
|
fnpkg = l.Function
|
|
}
|
|
|
|
return fmt.Sprintf("%s@%s:%d", fnpkg, file[len(file)-1], l.Line)
|
|
}
|
|
|
|
var importantRegex = regexp.MustCompile(`github.com/filecoin-project/specs-actors/(v\d+/)?actors/builtin`)
|
|
|
|
func (l Loc) Important() bool {
|
|
return importantRegex.MatchString(l.Function)
|
|
}
|
|
|
|
func (gt *GasTrace) MarshalJSON() ([]byte, error) {
|
|
type GasTraceCopy GasTrace
|
|
if len(gt.Location) == 0 {
|
|
if len(gt.Callers) != 0 {
|
|
frames := runtime.CallersFrames(gt.Callers)
|
|
for {
|
|
frame, more := frames.Next()
|
|
if frame.Function == "github.com/filecoin-project/lotus/chain/vm.(*VM).ApplyMessage" {
|
|
break
|
|
}
|
|
l := Loc{
|
|
File: frame.File,
|
|
Line: frame.Line,
|
|
Function: frame.Function,
|
|
}
|
|
gt.Location = append(gt.Location, l)
|
|
if !more {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
cpy := (*GasTraceCopy)(gt)
|
|
return json.Marshal(cpy)
|
|
}
|