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 returnData []byte
terminationType terminationType terminationType terminationType
staticMode bool
} }
// NewEWASMInterpreter creates a new wagon-based eWASM interpreter. It // 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 // 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. // the return byte-slice and an error if one occurred.
func (in *InterpreterEWASM) Run(contract *Contract, input []byte, ro bool) ([]byte, error) { 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 = contract
in.contract.Input = input in.contract.Input = input
initialGas := contract.Gas 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 { if len(sig.ParamTypes) == 0 && len(sig.ReturnTypes) == 0 {
_, err = vm.ExecCode(int64(entry.Index)) _, err = vm.ExecCode(int64(entry.Index))
if err != nil {
in.terminationType = TerminateInvalid
}
if in.StateDB.HasSuicided(contract.Address()) { if in.StateDB.HasSuicided(contract.Address()) {
if initialGas-contract.Gas-params.TxGas < 2*params.SuicideRefundGas { if initialGas-contract.Gas-params.TxGas < 2*params.SuicideRefundGas {
in.StateDB.AddRefund((initialGas - contract.Gas - params.TxGas) / 2) 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 err = nil
} }
if err != nil {
in.terminationType = TerminateInvalid
}
return in.returnData, err return in.returnData, err
} }

View file

@ -358,10 +358,6 @@ func readSize(p *exec.Process, offset int32, size int) []byte {
return val return val
} }
func readU256(p *exec.Process, offset int32) []byte {
return readSize(p, offset, u256Len)
}
func useGas(p *exec.Process, in *InterpreterEWASM, amount int64) { func useGas(p *exec.Process, in *InterpreterEWASM, amount int64) {
in.gasAccounting(uint64(amount)) 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 { 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 savedVM := in.vm
in.Run(targetContract, input, ro) in.Run(targetContract, input, ro)
@ -612,12 +613,20 @@ func callStatic(p *exec.Process, in *InterpreterEWASM, gas int64, addressOffset
code := in.StateDB.GetCode(addr) code := in.StateDB.GetCode(addr)
targetContract.SetCallCode(&addr, in.StateDB.GetCodeHash(addr), code) 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) return callCommon(in, contract, targetContract, input, value, snapshot, gas, true)
} }
func storageStore(p *exec.Process, interpreter *InterpreterEWASM, pathOffset int32, valueOffset int32) { func storageStore(p *exec.Process, interpreter *InterpreterEWASM, pathOffset int32, valueOffset int32) {
loc := common.BytesToHash(readU256(p, pathOffset)) if interpreter.staticMode == true {
val := common.BytesToHash(readU256(p, valueOffset)) panic("Static mode violation in storageStore")
}
loc := common.BytesToHash(readSize(p, pathOffset, u256Len))
val := common.BytesToHash(readSize(p, valueOffset, u256Len))
fmt.Println(val, loc) fmt.Println(val, loc)
nonZeroBytes := 0 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) { func storageLoad(p *exec.Process, interpreter *InterpreterEWASM, pathOffset int32, resultOffset int32) {
interpreter.gasAccounting(interpreter.gasTable.SLoad) 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() valBytes := interpreter.StateDB.GetState(interpreter.contract.Address(), loc).Bytes()
p.WriteAt(valBytes, int64(resultOffset)) 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)) value := swapEndian(readSize(p, int32(valueOffset), u128Len))
in.terminationType = TerminateFinish
// EIP150 says that the calling contract should keep 1/64th of the // EIP150 says that the calling contract should keep 1/64th of the
// leftover gas. // leftover gas.
gas := in.contract.Gas - in.contract.Gas/64 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.vm = savedVM
in.contract = savedContract in.contract = savedContract
in.contract.Gas += gasLeft
p.WriteAt(addr.Bytes(), int64(resultOffset))
switch in.terminationType { switch in.terminationType {
case TerminateFinish: case TerminateFinish:
in.contract.Gas += gasLeft
p.WriteAt(addr.Bytes(), int64(resultOffset))
return EEICallSuccess return EEICallSuccess
case TerminateRevert: case TerminateRevert:
in.contract.Gas += gas
return ErrEEICallRevert return ErrEEICallRevert
default: default:
in.contract.Gas += gasLeft
return ErrEEICallFailure 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) { if uint64(len(in.vm.Memory())) <= uint64(topic1) {
panic("out of memory") 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 numberOfTopics > 1 {
if uint64(len(in.vm.Memory())) <= uint64(topic2) { if uint64(len(in.vm.Memory())) <= uint64(topic2) {
panic("out of memory") 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 numberOfTopics > 2 {
if uint64(len(in.vm.Memory())) <= uint64(topic3) { if uint64(len(in.vm.Memory())) <= uint64(topic3) {
panic("out of memory") 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 numberOfTopics > 3 {
if uint64(len(in.vm.Memory())) <= uint64(topic3) { if uint64(len(in.vm.Memory())) <= uint64(topic3) {
panic("out of memory") 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{ in.StateDB.AddLog(&types.Log{