aot: enable post-Byzantium & no input => no copy

* Enable WASM precompiles after the Byzantium fork since the WASM code
  is modelled after that code.
* x86 glue would go into an infinite loop if the size of the data to
  copy was zero as it would cycle back to 0xffffffffffffffff
This commit is contained in:
Guillaume Ballet 2019-06-08 18:21:16 +02:00
parent 33a87d5fcc
commit 1243c05e8b
4 changed files with 24 additions and 25 deletions

View file

@ -24,7 +24,9 @@ import (
"bytes"
"encoding/binary"
"fmt"
"github.com/ethereum/go-ethereum/common"
"log"
"math/big"
"os"
"reflect"
"syscall"
@ -121,8 +123,8 @@ func (ac *AoTContract) ResolveGlobal(module, field string, t wa.Type) (init uint
return
}
func (ac *AoTContract) RequiredGas(code []byte) uint64 {
return 0
func (ac *AoTContract) RequiredGas(input []byte) uint64 {
return PrecompiledContractsByzantium[common.BigToAddress(big.NewInt(int64(ac.Num)))].RequiredGas(input)
}
func (ac *AoTContract) Run(input []byte, contract *Contract) ([]byte, error) {
@ -231,21 +233,13 @@ func (ac *AoTContract) Run(input []byte, contract *Contract) ([]byte, error) {
retaddr, retsize := aot.Exec(textAddr, stackLimit, memoryAddr, stackPtr)
gasLeft := binary.LittleEndian.Uint64(contractData[8:])
if gasLeft == 0xffffffffffffffff {
fmt.Println("Out of gas")
return nil, ErrOutOfGas
} else {
fmt.Println("gas left: ", gasLeft, "result: ", globalsMemory[retaddr+obj.MemoryOffset:retaddr+obj.MemoryOffset+retsize])
contract.Gas = gasLeft
if retsize == 0 {
return nil, nil
}
retData := make([]byte, retsize)
copy(retData, globalsMemory[retaddr+obj.MemoryOffset:retaddr+obj.MemoryOffset+retsize])
return retData, nil
if retsize == 0 {
return nil, nil
}
retData := make([]byte, retsize)
copy(retData, globalsMemory[retaddr+obj.MemoryOffset:retaddr+obj.MemoryOffset+retsize])
return retData, nil
// TODO cleanup all protected memory areas
}

View file

@ -36,13 +36,15 @@ TEXT ethereumUseGas<>(SB),NOSPLIT,$0
// Get pointer to the contract info area into r13
MOVQ -0x20(R15), R13
MOVQ 8(SP), AX // Gas required
MOVQ 0x8(R13), CX // Gas left
CMPQ AX, CX
JA oog
// Disable gas accounting as it is currently implemented
// before calling the precompile.
//MOVQ 8(SP), AX // Gas required
//MOVQ 0x8(R13), CX // Gas left
//CMPQ AX, CX
//JA oog
SUBQ AX, CX
MOVQ CX, 0x8(R13)
//SUBQ AX, CX
//MOVQ CX, 0x8(R13)
XORQ AX, AX
XORQ CX, CX
RET
@ -80,6 +82,10 @@ TEXT ethereumCallDataCopy<>(SB),NOSPLIT,$0
CMPQ AX, R12
JA eei_error
// Skip copy loop if there are no data to copy
CMPQ AX, $0
JZ calldatacopy_end
// Load address of the destination buffer
MOVQ 0x18(SP), DI
ADDQ R14, DI
@ -90,6 +96,7 @@ TEXT ethereumCallDataCopy<>(SB),NOSPLIT,$0
ADDQ $1, SI
ADDQ $1, DI
LOOP copy
calldatacopy_end:
RET
eei_error:

View file

@ -45,9 +45,6 @@ func run(evm *EVM, contract *Contract, input []byte, readOnly bool) ([]byte, err
if contract.CodeAddr != nil {
precompiles := PrecompiledContractsHomestead
if evm.ChainConfig().IsByzantium(evm.BlockNumber) {
precompiles = PrecompiledContractsByzantium
}
if evm.ChainConfig().IsEWASM(evm.BlockNumber) {
precompiles = PrecompiledContractsEWASM
}
if p := precompiles[*contract.CodeAddr]; p != nil {

View file

@ -104,6 +104,7 @@ var (
ByzantiumBlock: big.NewInt(1035301),
ConstantinopleBlock: big.NewInt(3660663),
PetersburgBlock: big.NewInt(4321234),
EWASMBlock: nil,
Clique: &CliqueConfig{
Period: 15,
Epoch: 30000,