core/vm: fix some tests

This commit is contained in:
Guillaume Ballet 2018-09-21 15:26:04 +02:00
parent ea221535f5
commit 8054399e1b
2 changed files with 36 additions and 17 deletions

View file

@ -56,6 +56,8 @@ type InterpreterEWASM struct {
returnData []byte
terminationType terminationType
staticMode bool
}
// NewEWASMInterpreter creates a new wagon-based eWASM interpreter. It
@ -68,6 +70,10 @@ func NewEWASMInterpreter(evm *EVM, cfg Config) Interpreter {
// Run loops and evaluates the contract's code with the given input data and returns
// the return byte-slice and an error if one occurred.
func (in *InterpreterEWASM) Run(contract *Contract, input []byte, ro bool) ([]byte, error) {
// Increment the call depth which is restricted to 1024
in.evm.depth++
defer func() { in.evm.depth-- }()
in.contract = contract
in.contract.Input = input
initialGas := contract.Gas
@ -99,6 +105,10 @@ func (in *InterpreterEWASM) Run(contract *Contract, input []byte, ro bool) ([]by
if len(sig.ParamTypes) == 0 && len(sig.ReturnTypes) == 0 {
_, err = vm.ExecCode(int64(entry.Index))
if err != nil {
in.terminationType = TerminateInvalid
}
if in.StateDB.HasSuicided(contract.Address()) {
if initialGas-contract.Gas-params.TxGas < 2*params.SuicideRefundGas {
in.StateDB.AddRefund((initialGas - contract.Gas - params.TxGas) / 2)
@ -108,10 +118,6 @@ func (in *InterpreterEWASM) Run(contract *Contract, input []byte, ro bool) ([]by
err = nil
}
if err != nil {
in.terminationType = TerminateInvalid
}
return in.returnData, err
}

View file

@ -358,10 +358,6 @@ func readSize(p *exec.Process, offset int32, size int) []byte {
return val
}
func readU256(p *exec.Process, offset int32) []byte {
return readSize(p, offset, u256Len)
}
func useGas(p *exec.Process, in *InterpreterEWASM, amount int64) {
in.gasAccounting(uint64(amount))
}
@ -394,6 +390,11 @@ func getBlockHash(p *exec.Process, in *InterpreterEWASM, number int64, resultOff
}
func callCommon(in *InterpreterEWASM, contract, targetContract *Contract, input []byte, value *big.Int, snapshot int, gas int64, ro bool) int32 {
if in.evm.depth > maxCallDepth {
contract.UseGas(contract.Gas)
return ErrEEICallFailure
}
savedVM := in.vm
in.Run(targetContract, input, ro)
@ -612,12 +613,20 @@ func callStatic(p *exec.Process, in *InterpreterEWASM, gas int64, addressOffset
code := in.StateDB.GetCode(addr)
targetContract.SetCallCode(&addr, in.StateDB.GetCodeHash(addr), code)
saveStatic := in.staticMode
in.staticMode = true
defer func() { in.staticMode = saveStatic }()
return callCommon(in, contract, targetContract, input, value, snapshot, gas, true)
}
func storageStore(p *exec.Process, interpreter *InterpreterEWASM, pathOffset int32, valueOffset int32) {
loc := common.BytesToHash(readU256(p, pathOffset))
val := common.BytesToHash(readU256(p, valueOffset))
if interpreter.staticMode == true {
panic("Static mode violation in storageStore")
}
loc := common.BytesToHash(readSize(p, pathOffset, u256Len))
val := common.BytesToHash(readSize(p, valueOffset, u256Len))
fmt.Println(val, loc)
nonZeroBytes := 0
@ -648,7 +657,7 @@ func storageStore(p *exec.Process, interpreter *InterpreterEWASM, pathOffset int
func storageLoad(p *exec.Process, interpreter *InterpreterEWASM, pathOffset int32, resultOffset int32) {
interpreter.gasAccounting(interpreter.gasTable.SLoad)
loc := common.BytesToHash(readU256(p, pathOffset))
loc := common.BytesToHash(readSize(p, pathOffset, u256Len))
valBytes := interpreter.StateDB.GetState(interpreter.contract.Address(), loc).Bytes()
p.WriteAt(valBytes, int64(resultOffset))
}
@ -697,6 +706,8 @@ func create(p *exec.Process, in *InterpreterEWASM, valueOffset uint32, codeOffse
}
value := swapEndian(readSize(p, int32(valueOffset), u128Len))
in.terminationType = TerminateFinish
// EIP150 says that the calling contract should keep 1/64th of the
// leftover gas.
gas := in.contract.Gas - in.contract.Gas/64
@ -706,15 +717,17 @@ func create(p *exec.Process, in *InterpreterEWASM, valueOffset uint32, codeOffse
in.vm = savedVM
in.contract = savedContract
in.contract.Gas += gasLeft
p.WriteAt(addr.Bytes(), int64(resultOffset))
switch in.terminationType {
case TerminateFinish:
in.contract.Gas += gasLeft
p.WriteAt(addr.Bytes(), int64(resultOffset))
return EEICallSuccess
case TerminateRevert:
in.contract.Gas += gas
return ErrEEICallRevert
default:
in.contract.Gas += gasLeft
return ErrEEICallFailure
}
}
@ -776,25 +789,25 @@ func log(p *exec.Process, in *InterpreterEWASM, dataOffset int32, length int32,
if uint64(len(in.vm.Memory())) <= uint64(topic1) {
panic("out of memory")
}
topics[0] = common.BigToHash(big.NewInt(0).SetBytes(readU256(p, topic1)))
topics[0] = common.BigToHash(big.NewInt(0).SetBytes(readSize(p, topic1, u256Len)))
}
if numberOfTopics > 1 {
if uint64(len(in.vm.Memory())) <= uint64(topic2) {
panic("out of memory")
}
topics[1] = common.BigToHash(big.NewInt(0).SetBytes(readU256(p, topic2)))
topics[1] = common.BigToHash(big.NewInt(0).SetBytes(readSize(p, topic2, u256Len)))
}
if numberOfTopics > 2 {
if uint64(len(in.vm.Memory())) <= uint64(topic3) {
panic("out of memory")
}
topics[2] = common.BigToHash(big.NewInt(0).SetBytes(readU256(p, topic3)))
topics[2] = common.BigToHash(big.NewInt(0).SetBytes(readSize(p, topic3, u256Len)))
}
if numberOfTopics > 3 {
if uint64(len(in.vm.Memory())) <= uint64(topic3) {
panic("out of memory")
}
topics[3] = common.BigToHash(big.NewInt(0).SetBytes(readU256(p, topic4)))
topics[3] = common.BigToHash(big.NewInt(0).SetBytes(readSize(p, topic4, u256Len)))
}
in.StateDB.AddLog(&types.Log{