aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeffrey Wilcke <jeffrey@ethereum.org>2017-08-16 20:32:59 +0800
committerPéter Szilágyi <peterke@gmail.com>2017-08-16 20:32:59 +0800
commitb70a73cd3e49e249a9ab2c41c2dd268786dcd1a3 (patch)
tree48364d1e6576be345fb97e44afb3d5c00eb7e9ac
parent0b978f91b6adcc4b595391096a72db73bc625bcf (diff)
downloadgo-tangerine-b70a73cd3e49e249a9ab2c41c2dd268786dcd1a3.tar.gz
go-tangerine-b70a73cd3e49e249a9ab2c41c2dd268786dcd1a3.tar.zst
go-tangerine-b70a73cd3e49e249a9ab2c41c2dd268786dcd1a3.zip
core/vm: implement REVERT metropolis opcode
-rw-r--r--core/vm/instructions.go8
-rw-r--r--core/vm/interpreter.go4
-rw-r--r--core/vm/jump_table.go7
-rw-r--r--core/vm/opcodes.go3
4 files changed, 21 insertions, 1 deletions
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index 4d6197912..b3b7310dd 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 954839f2e..23f930e91 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 2d238f7a1..2d7697e9c 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 be87cae18..0c6550735 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,
}