opt: improve trace handling logic to decrease GC pressure. (#92)

* Upgrade trace code to decrease GC pressure.

* Fix golangci bug

* Add goproxy

* update docker file

* trigger ci

* trigger ci

* Upgrade code

* Upgrade code

* trigger ci

Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
This commit is contained in:
maskpp 2022-05-18 22:38:15 +08:00 committed by GitHub
parent 571dcad4be
commit 9199413d21
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 47 additions and 26 deletions

View file

@ -32,17 +32,17 @@ type ExecutionResult struct {
// StructLogRes stores a structured log emitted by the EVM while replaying a
// transaction in debug mode
type StructLogRes struct {
Pc uint64 `json:"pc"`
Op string `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
Depth int `json:"depth"`
Error string `json:"error,omitempty"`
Stack *[]string `json:"stack,omitempty"`
Memory *[]string `json:"memory,omitempty"`
Storage *map[string]string `json:"storage,omitempty"`
RefundCounter uint64 `json:"refund,omitempty"`
ExtraData *ExtraData `json:"extraData,omitempty"`
Pc uint64 `json:"pc"`
Op string `json:"op"`
Gas uint64 `json:"gas"`
GasCost uint64 `json:"gasCost"`
Depth int `json:"depth"`
Error string `json:"error,omitempty"`
Stack []string `json:"stack,omitempty"`
Memory []string `json:"memory,omitempty"`
Storage map[string]string `json:"storage,omitempty"`
RefundCounter uint64 `json:"refund,omitempty"`
ExtraData *ExtraData `json:"extraData,omitempty"`
}
type ExtraData struct {

View file

@ -441,11 +441,29 @@ func (t *mdLogger) CaptureEnter(typ OpCode, from common.Address, to common.Addre
func (t *mdLogger) CaptureExit(output []byte, gasUsed uint64, err error) {}
var (
formatPool = sync.Pool{
New: func() interface{} {
return make([]types.StructLogRes, 0, 128)
},
}
)
// FormatLogs formats EVM returned structured logs for json output
func FormatLogs(logs []StructLog) []types.StructLogRes {
formatted := make([]types.StructLogRes, len(logs))
formatted := formatPool.Get().([]types.StructLogRes)
runtime.SetFinalizer(&formatted, func(format *[]types.StructLogRes) {
for _, res := range *format {
res.ExtraData = nil
res.Storage = nil
res.Stack = res.Stack[:0]
res.Memory = res.Memory[:0]
}
formatPool.Put(*format)
})
for index, trace := range logs {
formatted[index] = types.StructLogRes{
formatted = append(formatted, types.StructLogRes{
Pc: trace.Pc,
Op: trace.Op.String(),
Gas: trace.Gas,
@ -453,27 +471,29 @@ func FormatLogs(logs []StructLog) []types.StructLogRes {
Depth: trace.Depth,
RefundCounter: trace.RefundCounter,
Error: trace.ErrorString(),
}
})
if len(trace.Stack) != 0 {
stack := make([]string, len(trace.Stack))
for i, stackValue := range trace.Stack {
stack[i] = stackValue.Hex()
if formatted[index].Stack == nil {
formatted[index].Stack = make([]string, 0, len(trace.Stack))
}
for _, stackValue := range trace.Stack {
formatted[index].Stack = append(formatted[index].Stack, stackValue.Hex())
}
formatted[index].Stack = &stack
}
if trace.Memory.Len() != 0 {
memory := make([]string, 0, (trace.Memory.Len()+31)/32)
for i := 0; i+32 <= trace.Memory.Len(); i += 32 {
memory = append(memory, fmt.Sprintf("%x", trace.Memory.Bytes()[i:i+32]))
if formatted[index].Memory == nil {
formatted[index].Memory = make([]string, 0, (trace.Memory.Len()+31)/32)
}
for i := 0; i+32 <= trace.Memory.Len(); i += 32 {
formatted[index].Memory = append(formatted[index].Memory, common.Bytes2Hex(trace.Memory.Bytes()[i:i+32]))
}
formatted[index].Memory = &memory
}
if len(trace.Storage) != 0 {
storage := make(map[string]string)
for i, storageValue := range trace.Storage {
storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue)
storage[i.Hex()] = storageValue.Hex()
}
formatted[index].Storage = &storage
formatted[index].Storage = storage
}
if trace.ExtraData != nil {
formatted[index].ExtraData = trace.ExtraData.SealExtraData()

View file

@ -161,12 +161,13 @@ func getWrappedProofForStorage(l *StructLogger, address common.Address, key comm
}, nil
}
func encodeProof(proof [][]byte) (res []string) {
func encodeProof(proof [][]byte) []string {
if len(proof) == 0 {
return nil
}
res := make([]string, 0, len(proof))
for _, node := range proof {
res = append(res, hexutil.Encode(node))
}
return
return res
}