core/vm: implement REVERT metropolis opcode

This commit is contained in:
Jeffrey Wilcke 2017-08-16 15:32:59 +03:00 committed by Péter Szilágyi
parent 0b978f91b6
commit b70a73cd3e
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
4 changed files with 21 additions and 1 deletions

View File

@ -718,7 +718,14 @@ func opReturn(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *S
ret := memory.GetPtr(offset.Int64(), size.Int64()) ret := memory.GetPtr(offset.Int64(), size.Int64())
evm.interpreter.intPool.put(offset, size) 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 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.AddBalance(common.BigToAddress(stack.pop()), balance)
evm.StateDB.Suicide(contract.Address()) evm.StateDB.Suicide(contract.Address())
return nil, nil return nil, nil
} }

View File

@ -209,6 +209,10 @@ func (in *Interpreter) Run(snapshot int, contract *Contract, input []byte) (ret
if verifyPool { if verifyPool {
verifyIntegerPool(in.intPool) verifyIntegerPool(in.intPool)
} }
// checks whether the operation should revert state.
if operation.reverts {
in.evm.StateDB.RevertToSnapshot(snapshot)
}
switch { switch {
case err != nil: case err != nil:

View File

@ -89,6 +89,13 @@ func NewMetropolisInstructionSet() [256]operation {
memorySize: memoryReturnDataCopy, memorySize: memoryReturnDataCopy,
valid: true, valid: true,
} }
instructionSet[REVERT] = operation{
execute: opRevert,
gasCost: constGasFunc(GasFastestStep),
validateStack: makeStackFunc(2, 0),
valid: true,
reverts: true,
}
return instructionSet return instructionSet
} }

View File

@ -204,6 +204,7 @@ const (
DELEGATECALL DELEGATECALL
STATICCALL = 0xfa STATICCALL = 0xfa
REVERT = 0xfd
SELFDESTRUCT = 0xff SELFDESTRUCT = 0xff
) )
@ -360,6 +361,7 @@ var opCodeToString = map[OpCode]string{
CALLCODE: "CALLCODE", CALLCODE: "CALLCODE",
DELEGATECALL: "DELEGATECALL", DELEGATECALL: "DELEGATECALL",
STATICCALL: "STATICCALL", STATICCALL: "STATICCALL",
REVERT: "REVERT",
SELFDESTRUCT: "SELFDESTRUCT", SELFDESTRUCT: "SELFDESTRUCT",
PUSH: "PUSH", PUSH: "PUSH",
@ -509,6 +511,7 @@ var stringToOp = map[string]OpCode{
"CALL": CALL, "CALL": CALL,
"RETURN": RETURN, "RETURN": RETURN,
"CALLCODE": CALLCODE, "CALLCODE": CALLCODE,
"REVERT": REVERT,
"SELFDESTRUCT": SELFDESTRUCT, "SELFDESTRUCT": SELFDESTRUCT,
} }