Эх сурвалжийг харах

core/vm: implement REVERT metropolis opcode

Jeffrey Wilcke 8 жил өмнө
parent
commit
b70a73cd3e

+ 7 - 1
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
 }
 

+ 4 - 0
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:

+ 7 - 0
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
 }
 

+ 3 - 0
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,
 }