diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 4d6197912fcb3bdbc67aef57719a31b3a7134360..b3b7310dd45d2ef3f288fdd9ca53b17d4629b5c2 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -718,7 +718,14 @@ func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S ret := memory.GetPtr(offset.Int64(), size.Int64()) evm.interpreter.intPool.put(offset, size) + return ret, nil +} +func opRevert(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + offset, size := stack.pop(), stack.pop() + ret := memory.GetPtr(offset.Int64(), size.Int64()) + + evm.interpreter.intPool.put(offset, size) return ret, nil } @@ -731,7 +738,6 @@ func opSuicide(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack * evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) evm.StateDB.Suicide(contract.Address()) - return nil, nil } diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 954839f2e395555b57543533b005d6a30d6049d9..23f930e9133a44f4428f85ae4db2e01e47698f8e 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -209,6 +209,10 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret if verifyPool { verifyIntegerPool(in.intPool) } + // checks whether the operation should revert state. + if operation.reverts { + in.evm.StateDB.RevertToSnapshot(snapshot) + } switch { case err != nil: diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 2d238f7a169758b8d5ba1b1c54f9bbdbfcffe680..2d7697e9c1efcbe7bd6db873bbf1f1f5bfe489a7 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -89,6 +89,13 @@ func NewMetropolisInstructionSet() [256]operation { memorySize: memoryReturnDataCopy, valid: true, } + instructionSet[REVERT] = operation{ + execute: opRevert, + gasCost: constGasFunc(GasFastestStep), + validateStack: makeStackFunc(2, 0), + valid: true, + reverts: true, + } return instructionSet } diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index be87cae18b9ce29266c942a13f7b0f344e41e0b9..0c655073557cd57e1944141b508899d860d7d7ac 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -204,6 +204,7 @@ const ( DELEGATECALL STATICCALL = 0xfa + REVERT = 0xfd SELFDESTRUCT = 0xff ) @@ -360,6 +361,7 @@ var opCodeToString = map[OpCode]string{ CALLCODE: "CALLCODE", DELEGATECALL: "DELEGATECALL", STATICCALL: "STATICCALL", + REVERT: "REVERT", SELFDESTRUCT: "SELFDESTRUCT", PUSH: "PUSH", @@ -509,6 +511,7 @@ var stringToOp = map[string]OpCode{ "CALL": CALL, "RETURN": RETURN, "CALLCODE": CALLCODE, + "REVERT": REVERT, "SELFDESTRUCT": SELFDESTRUCT, }