diff options
-rw-r--r-- | core/vm/errors.go | 1 | ||||
-rw-r--r-- | core/vm/logger.go | 11 | ||||
-rw-r--r-- | core/vm/vm.go | 5 | ||||
-rw-r--r-- | internal/debug/flags.go | 2 | ||||
-rw-r--r-- | internal/ethapi/tracer.go | 47 | ||||
-rw-r--r-- | rpc/http.go | 2 | ||||
-rw-r--r-- | swarm/storage/chunker_test.go | 1 |
7 files changed, 40 insertions, 29 deletions
diff --git a/core/vm/errors.go b/core/vm/errors.go index 116fbe456..1766bf9fb 100644 --- a/core/vm/errors.go +++ b/core/vm/errors.go @@ -26,3 +26,4 @@ import ( var OutOfGasError = errors.New("Out of gas") var CodeStoreOutOfGasError = errors.New("Contract creation code storage out of gas") var DepthError = fmt.Errorf("Max call depth exceeded (%d)", params.CallCreateDepth) +var TraceLimitReachedError = errors.New("The number of logs reached the specified limit") diff --git a/core/vm/logger.go b/core/vm/logger.go index ae62b6b57..9e13d703b 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -42,6 +42,7 @@ type LogConfig struct { DisableStack bool // disable stack capture DisableStorage bool // disable storage capture FullStorage bool // show full storage (slow) + Limit int // maximum length of output, but zero means unlimited } // StructLog is emitted to the Environment each cycle and lists information about the current internal state @@ -64,7 +65,7 @@ type StructLog struct { // Note that reference types are actual VM data structures; make copies // if you need to retain them beyond the current call. type Tracer interface { - CaptureState(env Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) + CaptureState(env Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error } // StructLogger is an EVM state logger and implements Tracer. @@ -93,7 +94,12 @@ func NewStructLogger(cfg *LogConfig) *StructLogger { // captureState logs a new structured log message and pushes it out to the environment // // captureState also tracks SSTORE ops to track dirty values. -func (l *StructLogger) CaptureState(env Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) { +func (l *StructLogger) CaptureState(env Environment, pc uint64, op OpCode, gas, cost *big.Int, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { + // check if already accumulated the specified number of logs + if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { + return TraceLimitReachedError + } + // initialise new changed values storage container for this contract // if not present. if l.changedValues[contract.Address()] == nil { @@ -152,6 +158,7 @@ func (l *StructLogger) CaptureState(env Environment, pc uint64, op OpCode, gas, log := StructLog{pc, op, new(big.Int).Set(gas), cost, mem, stck, storage, env.Depth(), err} l.logs = append(l.logs, log) + return nil } // StructLogs returns a list of captured log entries diff --git a/core/vm/vm.go b/core/vm/vm.go index 205934822..09cddc2f8 100644 --- a/core/vm/vm.go +++ b/core/vm/vm.go @@ -188,7 +188,10 @@ func (evm *EVM) Run(contract *Contract, input []byte) (ret []byte, err error) { mem.Resize(newMemSize.Uint64()) // Add a log message if evm.cfg.Debug { - evm.cfg.Tracer.CaptureState(evm.env, pc, op, contract.Gas, cost, mem, stack, contract, evm.env.Depth(), nil) + err = evm.cfg.Tracer.CaptureState(evm.env, pc, op, contract.Gas, cost, mem, stack, contract, evm.env.Depth(), nil) + if err != nil { + return nil, err + } } if opPtr := evm.jumpTable[op]; opPtr.valid { diff --git a/internal/debug/flags.go b/internal/debug/flags.go index ed17f87c4..d7bbfae1e 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -53,7 +53,7 @@ var ( Value: 6060, } pprofAddrFlag = cli.StringFlag{ - Name: "pprofaddr", + Name: "pprofaddr", Usage: "pprof HTTP server listening interface", Value: "127.0.0.1", } diff --git a/internal/ethapi/tracer.go b/internal/ethapi/tracer.go index 16ec6ebf0..5f69826a3 100644 --- a/internal/ethapi/tracer.go +++ b/internal/ethapi/tracer.go @@ -167,17 +167,17 @@ func (dw *dbWrapper) toValue(vm *otto.Otto) otto.Value { // JavascriptTracer provides an implementation of Tracer that evaluates a // Javascript function for each VM execution step. type JavascriptTracer struct { - vm *otto.Otto // Javascript VM instance - traceobj *otto.Object // User-supplied object to call - log map[string]interface{} // (Reusable) map for the `log` arg to `step` - logvalue otto.Value // JS view of `log` - memory *memoryWrapper // Wrapper around the VM memory - memvalue otto.Value // JS view of `memory` - stack *stackWrapper // Wrapper around the VM stack - stackvalue otto.Value // JS view of `stack` - db *dbWrapper // Wrapper around the VM environment - dbvalue otto.Value // JS view of `db` - err error // Error, if one has occurred + vm *otto.Otto // Javascript VM instance + traceobj *otto.Object // User-supplied object to call + log map[string]interface{} // (Reusable) map for the `log` arg to `step` + logvalue otto.Value // JS view of `log` + memory *memoryWrapper // Wrapper around the VM memory + memvalue otto.Value // JS view of `memory` + stack *stackWrapper // Wrapper around the VM stack + stackvalue otto.Value // JS view of `stack` + db *dbWrapper // Wrapper around the VM environment + dbvalue otto.Value // JS view of `db` + err error // Error, if one has occurred } // NewJavascriptTracer instantiates a new JavascriptTracer instance. @@ -222,17 +222,17 @@ func NewJavascriptTracer(code string) (*JavascriptTracer, error) { db := &dbWrapper{} return &JavascriptTracer{ - vm: vm, - traceobj: jstracer, - log: log, - logvalue: logvalue, - memory: mem, - memvalue: mem.toValue(vm), - stack: stack, - stackvalue: stack.toValue(vm), - db: db, - dbvalue: db.toValue(vm), - err: nil, + vm: vm, + traceobj: jstracer, + log: log, + logvalue: logvalue, + memory: mem, + memvalue: mem.toValue(vm), + stack: stack, + stackvalue: stack.toValue(vm), + db: db, + dbvalue: db.toValue(vm), + err: nil, }, nil } @@ -278,7 +278,7 @@ func wrapError(context string, err error) error { } // CaptureState implements the Tracer interface to trace a single step of VM execution -func (jst *JavascriptTracer) CaptureState(env vm.Environment, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) { +func (jst *JavascriptTracer) CaptureState(env vm.Environment, pc uint64, op vm.OpCode, gas, cost *big.Int, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error { if jst.err == nil { jst.memory.memory = memory jst.stack.stack = stack @@ -301,6 +301,7 @@ func (jst *JavascriptTracer) CaptureState(env vm.Environment, pc uint64, op vm.O jst.err = wrapError("step", err) } } + return nil } // GetResult calls the Javascript 'result' function and returns its value, or any accumulated error diff --git a/rpc/http.go b/rpc/http.go index c923580bf..7d4fe5d47 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -170,7 +170,7 @@ func newCorsHandler(srv *Server, corsString string) http.Handler { c := cors.New(cors.Options{ AllowedOrigins: allowedOrigins, AllowedMethods: []string{"POST", "GET"}, - MaxAge: 600, + MaxAge: 600, }) return c.Handler(srv) } diff --git a/swarm/storage/chunker_test.go b/swarm/storage/chunker_test.go index 4f05cd1cc..40f870246 100644 --- a/swarm/storage/chunker_test.go +++ b/swarm/storage/chunker_test.go @@ -28,7 +28,6 @@ import ( "time" ) - /* Tests TreeChunker by splitting and joining a random byte slice */ |