diff options
Diffstat (limited to 'core/vm/interpreter.go')
-rw-r--r-- | core/vm/interpreter.go | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 3faa98704..661ada691 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -69,6 +69,8 @@ func NewInterpreter(evm *EVM, cfg Config) *Interpreter { // we'll set the default jump table. if !cfg.JumpTable[STOP].valid { switch { + case evm.ChainConfig().IsMetropolis(evm.BlockNumber): + cfg.JumpTable = metropolisInstructionSet case evm.ChainConfig().IsHomestead(evm.BlockNumber): cfg.JumpTable = homesteadInstructionSet default: @@ -85,6 +87,18 @@ func NewInterpreter(evm *EVM, cfg Config) *Interpreter { } func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack *Stack) error { + if in.evm.chainRules.IsMetropolis { + if in.readonly { + // If the interpreter is operating in readonly mode, make sure no + // state-modifying operation is performed. The 3rd stack item + // for a call operation is the value. Transfering value from one + // account to the others means the state is modified and should also + // return with an error. + if operation.writes || (op == CALL && stack.Back(2).BitLen() > 0) { + return errWriteProtection + } + } + } return nil } @@ -95,6 +109,7 @@ func (in *Interpreter) enforceRestrictions(op OpCode, operation operation, stack // considered a revert-and-consume-all-gas operation. No error specific checks // should be handled to reduce complexity and errors further down the in. func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret []byte, err error) { + // Increment the call depth which is restricted to 1024 in.evm.depth++ defer func() { in.evm.depth-- }() |