From 3a0c88d167191e12b502f934e6c37ec067cd99f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 2 Jan 2018 12:28:07 +0200 Subject: [PATCH] build: fix version comparison for go1.10 and beyond (#15781) --- build/ci.go | 21 ++++++--- core/vm/eni/arg_parser/arg_parser_test.go | 54 +++++++++++++++++++++++ core/vm/instructions.go | 23 ++++++++++ 3 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 core/vm/eni/arg_parser/arg_parser_test.go diff --git a/build/ci.go b/build/ci.go index 6a52077d450c..fdf415c3aed8 100644 --- a/build/ci.go +++ b/build/ci.go @@ -175,11 +175,17 @@ func doInstall(cmdline []string) { // Check Go version. People regularly open issues about compilation // failure with outdated Go. This should save them the trouble. - if runtime.Version() < "go1.7" && !strings.Contains(runtime.Version(), "devel") { - log.Println("You have Go version", runtime.Version()) - log.Println("go-ethereum requires at least Go version 1.7 and cannot") - log.Println("be compiled with an earlier version. Please upgrade your Go installation.") - os.Exit(1) + if !strings.Contains(runtime.Version(), "devel") { + // Figure out the minor version number since we can't textually compare (1.10 < 1.7) + var minor int + fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor) + + if minor < 7 { + log.Println("You have Go version", runtime.Version()) + log.Println("go-ethereum requires at least Go version 1.7 and cannot") + log.Println("be compiled with an earlier version. Please upgrade your Go installation.") + os.Exit(1) + } } // Compile packages given as arguments, or everything if there are no arguments. packages := []string{"./..."} @@ -256,7 +262,10 @@ func goToolArch(arch string, subcmd string, args ...string) *exec.Cmd { if subcmd == "build" || subcmd == "install" || subcmd == "test" { // Go CGO has a Windows linker error prior to 1.8 (https://github.com/golang/go/issues/8756). // Work around issue by allowing multiple definitions for <1.8 builds. - if runtime.GOOS == "windows" && runtime.Version() < "go1.8" { + var minor int + fmt.Sscanf(strings.TrimPrefix(runtime.Version(), "go1."), "%d", &minor) + + if runtime.GOOS == "windows" && minor < 8 { cmd.Args = append(cmd.Args, []string{"-ldflags", "-extldflags -Wl,--allow-multiple-definition"}...) } } diff --git a/core/vm/eni/arg_parser/arg_parser_test.go b/core/vm/eni/arg_parser/arg_parser_test.go new file mode 100644 index 000000000000..f8b85d8cd2e0 --- /dev/null +++ b/core/vm/eni/arg_parser/arg_parser_test.go @@ -0,0 +1,54 @@ +package arg_parser +import "testing" +import "bytes" +import "fmt" + +// single positive integer (big endian) +func ExampleA(){ + var arg_parser arg_parser_t + var f, d []byte + var buf bytes.Buffer; + + f = make([]byte, 1, 1) + d = make([]byte, 70, 70) + f[0] = INT + for i:=0; i<70; i++ { d[i] = uint8(0) } + d[31] = uint8(72) // 32-byte big endian + arg_parser.parse_entry_point(f, d, &buf) + fmt.Println(buf.String()) + // Output: [72] +} + +// single positive integer (big endian) +func TestB(t *testing.T){ + var arg_parser arg_parser_t + var f, d []byte + var buf bytes.Buffer; + + f = make([]byte, 1, 1) + d = make([]byte, 70, 70) + f[0] = INT + for i:=0; i<70; i++ { d[i] = uint8(0) } + a:= -72 + d[31] = byte(a) // 32-byte big endian + arg_parser.parse_entry_point(f, d, &buf) +} + +// a int and a bool +func ExampleC(){ + var arg_parser arg_parser_t + var f, d []byte + var buf bytes.Buffer; + + f = make([]byte, 2, 2) + d = make([]byte, 70, 70) + f[0] = INT + f[1] = BOOL + for i:=0; i<70; i++ { d[i] = uint8(0) } + d[31] = uint8(72) // 32-byte big endian + arg_parser.parse_entry_point(f, d, &buf) + fmt.Println(buf.String()) + + // Output: [72,false] +} + diff --git a/core/vm/instructions.go b/core/vm/instructions.go index f5164fcdd43e..9ac2047c1170 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -19,10 +19,12 @@ package vm import ( "fmt" "math/big" + "strings" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm/eni/arg_parser" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" ) @@ -656,6 +658,27 @@ func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, st return ret, nil } +func opENI(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error) { + // get arguments + funcName := string(stack.pop().Bytes()).Trim(string(funcName), "\x00") + typeOffset, dataOffset := stack.pop().Int64(), stack.pop().Int64() + typeLength := new(big.Int).SetBytes(memory.Get(typeOffset, 32)).Int64() + dataLength := new(big.Int).SetBytes(memory.Get(dataOffset, 32)).Int64() + + typeSection := memory.Get(typeOffset+32, typeLength) + dataSection := memory.Get(dataOffset+32, dataLength) + + argsText := arg_parser.Parse(typeSection, dataSection) + + retText := evm.eni.ExecuteENI(funcName, argsText) + + // TODO: parse return value + retAddr := uint64(7112) + memory.Resize(retAddr + uint64(len(retText))) + memory.Set(retAddr, 32, []byte(retText)) + return nil, nil +} + func opReturn(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())