core/vm: enable optional EVM error collection in interpreter

This commit is contained in:
Valentin Wüstholz 2017-05-23 10:43:22 +02:00 committed by Felix Lange
parent 2909f6d7a2
commit 5e80e00d2e
2 changed files with 22 additions and 0 deletions

View file

@ -104,6 +104,11 @@ type EVM struct {
// global (to this context) ethereum virtual machine
// used throughout the execution of the tx.
interpreter *Interpreter
// InterpreterErrors contain the errors returned by the EVM. The errors
// aren't consensus errors but rather errors that were returned by
// invalid opcodes, stack over and underflow, etc. This slice will only
// be populated if the CollectEVMErrors option is enabled.
InterpreterErrors []EVMError
// abort is used to abort the EVM calling operations
// NOTE: must be set atomically
abort int32

View file

@ -28,6 +28,8 @@ import (
type Config struct {
// Debug enabled debugging Interpreter options
Debug bool
// CollectEVMErrors enables EVM error collecting
CollectEVMErrors bool
// Tracer is the op code logger
Tracer Tracer
// NoRecursion disabled Interpreter call, callcode,
@ -41,6 +43,15 @@ type Config struct {
JumpTable [256]operation
}
type EVMError struct {
Err error
Depth int
}
func (e EVMError) Error() string {
return fmt.Sprintf("%d: %v", e.Depth, e.Err)
}
// Interpreter is used to run Ethereum based contracts and will utilise the
// passed environment to query external sources for state information.
// The Interpreter will run the byte code VM based on the passed
@ -154,6 +165,12 @@ func (in *Interpreter) Run(contract *Contract, input []byte) (ret []byte, err er
}
}()
}
if in.cfg.CollectEVMErrors {
defer func() {
in.evm.InterpreterErrors = append(in.evm.InterpreterErrors, EVMError{Err: err, Depth: in.evm.depth})
}()
}
// The Interpreter main run loop (contextual). This loop runs until either an
// explicit STOP, RETURN or SELFDESTRUCT is executed, an error occurred during
// the execution of one of the operations or until the done flag is set by the