mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-24 21:56:43 +00:00
fix(api): fix debug_ API oom bug (#284)
* feat: fix oom bug * feat: format import * feat: remove unused code * Update version.go --------- Co-authored-by: colin <102356659+colinlyguo@users.noreply.github.com> Co-authored-by: HAOYUatHZ <37070449+HAOYUatHZ@users.noreply.github.com>
This commit is contained in:
parent
b22944a621
commit
f71fc6794a
4 changed files with 34 additions and 61 deletions
|
|
@ -3,26 +3,12 @@ package types
|
|||
import (
|
||||
"encoding/json"
|
||||
"math/big"
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/scroll-tech/go-ethereum/common"
|
||||
"github.com/scroll-tech/go-ethereum/common/hexutil"
|
||||
"github.com/scroll-tech/go-ethereum/params"
|
||||
)
|
||||
|
||||
var (
|
||||
loggerResPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
// init arrays here; other types are inited with default values
|
||||
return &StructLogRes{
|
||||
Stack: []string{},
|
||||
Memory: []string{},
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// BlockTrace contains block execution traces and results required for rollers.
|
||||
type BlockTrace struct {
|
||||
ChainID uint64 `json:"chainID"`
|
||||
|
|
@ -97,22 +83,21 @@ type StructLogRes struct {
|
|||
ExtraData *ExtraData `json:"extraData,omitempty"`
|
||||
}
|
||||
|
||||
// Basic StructLogRes skeleton, Stack&Memory&Storage&ExtraData are separated from it for GC optimization;
|
||||
// NewStructLogResBasic Basic StructLogRes skeleton, Stack&Memory&Storage&ExtraData are separated from it for GC optimization;
|
||||
// still need to fill in with Stack&Memory&Storage&ExtraData
|
||||
func NewStructLogResBasic(pc uint64, op string, gas, gasCost uint64, depth int, refundCounter uint64, err error) *StructLogRes {
|
||||
logRes := loggerResPool.Get().(*StructLogRes)
|
||||
logRes.Pc, logRes.Op, logRes.Gas, logRes.GasCost, logRes.Depth, logRes.RefundCounter = pc, op, gas, gasCost, depth, refundCounter
|
||||
logRes := &StructLogRes{
|
||||
Pc: pc,
|
||||
Op: op,
|
||||
Gas: gas,
|
||||
GasCost: gasCost,
|
||||
Depth: depth,
|
||||
RefundCounter: refundCounter,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
logRes.Error = err.Error()
|
||||
}
|
||||
runtime.SetFinalizer(logRes, func(logRes *StructLogRes) {
|
||||
logRes.Stack = logRes.Stack[:0]
|
||||
logRes.Memory = logRes.Memory[:0]
|
||||
logRes.Storage = nil
|
||||
logRes.ExtraData = nil
|
||||
logRes.Error = ""
|
||||
loggerResPool.Put(logRes)
|
||||
})
|
||||
return logRes
|
||||
}
|
||||
|
||||
|
|
@ -151,7 +136,7 @@ type AccountWrapper struct {
|
|||
Storage *StorageWrapper `json:"storage,omitempty"` // StorageWrapper can be empty if irrelated to storage operation
|
||||
}
|
||||
|
||||
// while key & value can also be retrieved from StructLogRes.Storage,
|
||||
// StorageWrapper while key & value can also be retrieved from StructLogRes.Storage,
|
||||
// we still stored in here for roller's processing convenience.
|
||||
type StorageWrapper struct {
|
||||
Key string `json:"key,omitempty"`
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import (
|
|||
var _ = (*structLogMarshaling)(nil)
|
||||
|
||||
// MarshalJSON marshals as JSON.
|
||||
func (s StructLog) MarshalJSON() ([]byte, error) {
|
||||
func (s *StructLog) MarshalJSON() ([]byte, error) {
|
||||
type StructLog struct {
|
||||
Pc uint64 `json:"pc"`
|
||||
Op OpCode `json:"op"`
|
||||
|
|
|
|||
|
|
@ -22,9 +22,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/holiman/uint256"
|
||||
|
|
@ -81,26 +79,15 @@ type StructLog struct {
|
|||
Err error `json:"-"`
|
||||
}
|
||||
|
||||
var (
|
||||
loggerPool = sync.Pool{
|
||||
New: func() interface{} {
|
||||
return &StructLog{
|
||||
// init arrays here; other types are inited with default values
|
||||
Stack: make([]uint256.Int, 0),
|
||||
}
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func NewStructlog(pc uint64, op OpCode, gas, cost uint64, depth int, err error) *StructLog {
|
||||
structlog := loggerPool.Get().(*StructLog)
|
||||
structlog.Pc, structlog.Op, structlog.Gas, structlog.GasCost, structlog.Depth, structlog.Err = pc, op, gas, cost, depth, err
|
||||
|
||||
runtime.SetFinalizer(structlog, func(logger *StructLog) {
|
||||
logger.clean()
|
||||
loggerPool.Put(logger)
|
||||
})
|
||||
return structlog
|
||||
return &StructLog{
|
||||
Pc: pc,
|
||||
Op: op,
|
||||
Gas: gas,
|
||||
GasCost: cost,
|
||||
Depth: depth,
|
||||
Err: err,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *StructLog) clean() {
|
||||
|
|
@ -185,6 +172,7 @@ func NewStructLogger(cfg *LogConfig) *StructLogger {
|
|||
if cfg != nil {
|
||||
logger.cfg = *cfg
|
||||
}
|
||||
|
||||
return logger
|
||||
}
|
||||
|
||||
|
|
@ -225,7 +213,7 @@ func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scop
|
|||
stack := scope.Stack
|
||||
contract := scope.Contract
|
||||
// create a struct log.
|
||||
structlog := NewStructlog(pc, op, gas, cost, depth, opErr)
|
||||
structLog := NewStructlog(pc, op, gas, cost, depth, opErr)
|
||||
|
||||
// check if already accumulated the specified number of logs
|
||||
if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) {
|
||||
|
|
@ -233,12 +221,12 @@ func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scop
|
|||
}
|
||||
// Copy a snapshot of the current memory state to a new buffer
|
||||
if l.cfg.EnableMemory {
|
||||
structlog.Memory.Write(memory.Data())
|
||||
structlog.MemorySize = memory.Len()
|
||||
structLog.Memory.Write(memory.Data())
|
||||
structLog.MemorySize = memory.Len()
|
||||
}
|
||||
// Copy a snapshot of the current stack state to a new buffer
|
||||
if !l.cfg.DisableStack {
|
||||
structlog.Stack = append(structlog.Stack, stack.Data()...)
|
||||
structLog.Stack = append(structLog.Stack, stack.Data()...)
|
||||
}
|
||||
var (
|
||||
recordStorageDetail bool
|
||||
|
|
@ -262,20 +250,20 @@ func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scop
|
|||
l.storage[contractAddress] = make(Storage)
|
||||
}
|
||||
l.storage[contractAddress][storageKey] = storageValue
|
||||
structlog.Storage = l.storage[contractAddress].Copy()
|
||||
structLog.Storage = l.storage[contractAddress].Copy()
|
||||
|
||||
if err := traceStorage(l, scope, structlog.getOrInitExtraData()); err != nil {
|
||||
if err := traceStorage(l, scope, structLog.getOrInitExtraData()); err != nil {
|
||||
log.Error("Failed to trace data", "opcode", op.String(), "err", err)
|
||||
}
|
||||
}
|
||||
if l.cfg.EnableReturnData {
|
||||
structlog.ReturnData.Write(rData)
|
||||
structLog.ReturnData.Write(rData)
|
||||
}
|
||||
execFuncList, ok := OpcodeExecs[op]
|
||||
if ok {
|
||||
// execute trace func list.
|
||||
for _, exec := range execFuncList {
|
||||
if err := exec(l, scope, structlog.getOrInitExtraData()); err != nil {
|
||||
if err := exec(l, scope, structLog.getOrInitExtraData()); err != nil {
|
||||
log.Error("Failed to trace data", "opcode", op.String(), "err", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -283,12 +271,12 @@ func (l *StructLogger) CaptureState(pc uint64, op OpCode, gas, cost uint64, scop
|
|||
// for each "calling" op, pick the caller's state
|
||||
switch op {
|
||||
case CALL, CALLCODE, STATICCALL, DELEGATECALL, CREATE, CREATE2:
|
||||
extraData := structlog.getOrInitExtraData()
|
||||
extraData := structLog.getOrInitExtraData()
|
||||
extraData.Caller = append(extraData.Caller, getWrappedAccountForAddr(l, scope.Contract.Address()))
|
||||
}
|
||||
|
||||
structlog.RefundCounter = l.env.StateDB.GetRefund()
|
||||
l.logs = append(l.logs, structlog)
|
||||
structLog.RefundCounter = l.env.StateDB.GetRefund()
|
||||
l.logs = append(l.logs, structLog)
|
||||
}
|
||||
|
||||
func (l *StructLogger) CaptureStateAfter(pc uint64, op OpCode, gas, cost uint64, scope *ScopeContext, rData []byte, depth int, err error) {
|
||||
|
|
@ -335,7 +323,7 @@ func (l *StructLogger) CaptureEnter(typ OpCode, from common.Address, to common.A
|
|||
}
|
||||
}
|
||||
|
||||
// in CaptureExit phase, a CREATE has its target address's code being set and queryable
|
||||
// CaptureExit phase, a CREATE has its target address's code being set and queryable
|
||||
func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) {
|
||||
stackH := len(l.callStackLogInd)
|
||||
if stackH == 0 {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import (
|
|||
const (
|
||||
VersionMajor = 3 // Major version component of the current release
|
||||
VersionMinor = 1 // Minor version component of the current release
|
||||
VersionPatch = 5 // Patch version component of the current release
|
||||
VersionPatch = 6 // Patch version component of the current release
|
||||
VersionMeta = "alpha" // Version metadata to append to the version string
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue