From 3d123bcde67973b57c0a9e7edc219cc2ea589443 Mon Sep 17 00:00:00 2001 From: Jeffrey Wilcke Date: Tue, 15 Aug 2017 11:23:23 +0300 Subject: core/vm: implement metropolis static call opcode --- core/vm/interpreter.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'core/vm/interpreter.go') diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 3faa98704..32d764b9f 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,19 @@ 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 4th 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 || op == CALLCODE) && stack.Back(3).BitLen() > 0) { + return errWriteProtection + } + } + } return nil } @@ -95,6 +110,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-- }() -- cgit