mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +00:00
core/vm: fix some tests
This commit is contained in:
parent
ea221535f5
commit
8054399e1b
2 changed files with 36 additions and 17 deletions
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue