diff --git a/core/vm/evm.go b/core/vm/evm.go index c0a14e746..0135ace7b 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -588,6 +588,8 @@ func (env *EVM) Push(statedb StateDB) { // Quorum : the read only depth to be set up only once for the entire // op code execution. This will be set first time transition from // private state to public state happens + // statedb will be the state of the contract being called. + // if a private contract is calling a public contract make it readonly. if !env.quorumReadOnly && env.privateState != statedb { env.quorumReadOnly = true env.readOnlyDepth = env.currentStateDepth diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 3440de3c4..24f5c41bf 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -207,10 +207,6 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( // Get the memory location of pc op = contract.GetOp(pc) - if in.evm.quorumReadOnly && op.isMutating() { - return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited") - } - if in.cfg.Debug { // Capture pre-execution values for tracing. logged, pcCopy, gasCopy = false, pc, contract.Gas @@ -222,6 +218,9 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) ( if !operation.valid { return nil, fmt.Errorf("invalid opcode 0x%x", int(op)) } + if in.evm.quorumReadOnly && operation.writes { + return nil, fmt.Errorf("VM in read-only mode. Mutating opcode prohibited") + } if err := operation.validateStack(stack); err != nil { return nil, err } diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 549458581..4349ffd29 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -538,13 +538,3 @@ var stringToOp = map[string]OpCode{ func StringToOp(str string) OpCode { return stringToOp[str] } - -func (op OpCode) isMutating() bool { - switch op { - // TODO(joel): REVERT? - case SELFDESTRUCT, CREATE, SSTORE, LOG0, LOG1, LOG2, LOG3, LOG4: - return true - default: - return false - } -}