Skip to content

Commit

Permalink
common/compiler: remove workaround for solc 0.3.5 stdin bug (ethereum…
Browse files Browse the repository at this point in the history
…#3522)

The crash when compiling stdin was fixed in solc 0.3.6 (released
2016-08-10). While here, simplify the test so it runs with any solc
version.

Fixes ethereum#3484. The byte code was different for each run because recent
solc embeds the swarm hash of contract metadata into the code. When
compiling from stdin the name in the metadata is constant.
  • Loading branch information
fjl authored Jan 6, 2017
1 parent 59b8245 commit e0fde02
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 36 deletions.
30 changes: 10 additions & 20 deletions common/compiler/solidity.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"os/exec"
"regexp"
"strings"
Expand Down Expand Up @@ -96,27 +94,16 @@ func CompileSolidityString(solc, source string) (map[string]*Contract, error) {
if solc == "" {
solc = "solc"
}
// Write source to a temporary file. Compiling stdin used to be supported
// but seems to produce an exception with solc 0.3.5.
infile, err := ioutil.TempFile("", "geth-compile-solidity")
if err != nil {
return nil, err
}
defer os.Remove(infile.Name())
if _, err := io.WriteString(infile, source); err != nil {
return nil, err
}
if err := infile.Close(); err != nil {
return nil, err
}

return CompileSolidity(solc, infile.Name())
args := append(solcParams, "--")
cmd := exec.Command(solc, append(args, "-")...)
cmd.Stdin = strings.NewReader(source)
return runsolc(cmd, source)
}

// CompileSolidity compiles all given Solidity source files.
func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract, error) {
if len(sourcefiles) == 0 {
return nil, errors.New("solc: no source ")
return nil, errors.New("solc: no source files")
}
source, err := slurpFiles(sourcefiles)
if err != nil {
Expand All @@ -125,10 +112,13 @@ func CompileSolidity(solc string, sourcefiles ...string) (map[string]*Contract,
if solc == "" {
solc = "solc"
}

var stderr, stdout bytes.Buffer
args := append(solcParams, "--")
cmd := exec.Command(solc, append(args, sourcefiles...)...)
return runsolc(cmd, source)
}

func runsolc(cmd *exec.Cmd, source string) (map[string]*Contract, error) {
var stderr, stdout bytes.Buffer
cmd.Stderr = &stderr
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
Expand Down
28 changes: 12 additions & 16 deletions common/compiler/solidity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,39 +20,34 @@ import (
"encoding/json"
"io/ioutil"
"os"
"os/exec"
"path"
"testing"

"github.com/ethereum/go-ethereum/common"
)

const (
supportedSolcVersion = "0.3.5"
testSource = `
testSource = `
contract test {
/// @notice Will multiply ` + "`a`" + ` by 7.
function multiply(uint a) returns(uint d) {
return a * 7;
}
}
`
testCode = "0x6060604052602a8060106000396000f3606060405260e060020a6000350463c6888fa18114601a575b005b6007600435026060908152602090f3"
testInfo = `{"source":"\ncontract test {\n /// @notice Will multiply ` + "`a`" + ` by 7.\n function multiply(uint a) returns(uint d) {\n return a * 7;\n }\n}\n","language":"Solidity","languageVersion":"0.1.1","compilerVersion":"0.1.1","compilerOptions":"--binary file --json-abi file --natspec-user file --natspec-dev file --add-std 1","abiDefinition":[{"constant":false,"inputs":[{"name":"a","type":"uint256"}],"name":"multiply","outputs":[{"name":"d","type":"uint256"}],"type":"function"}],"userDoc":{"methods":{"multiply(uint256)":{"notice":"Will multiply ` + "`a`" + ` by 7."}}},"developerDoc":{"methods":{}}}`
)

func skipUnsupported(t *testing.T) {
sol, err := SolidityVersion("")
if err != nil {
func skipWithoutSolc(t *testing.T) {
if _, err := exec.LookPath("solc"); err != nil {
t.Skip(err)
return
}
if sol.Version != supportedSolcVersion {
t.Skipf("unsupported version of solc found (%v, expect %v)", sol.Version, supportedSolcVersion)
}
}

func TestCompiler(t *testing.T) {
skipUnsupported(t)
skipWithoutSolc(t)

contracts, err := CompileSolidityString("", testSource)
if err != nil {
t.Fatalf("error compiling source. result %v: %v", contracts, err)
Expand All @@ -64,19 +59,20 @@ func TestCompiler(t *testing.T) {
if !ok {
t.Fatal("info for contract 'test' not present in result")
}
if c.Code != testCode {
t.Errorf("wrong code: expected\n%s, got\n%s", testCode, c.Code)
if c.Code == "" {
t.Error("empty code")
}
if c.Info.Source != testSource {
t.Error("wrong source")
}
if c.Info.CompilerVersion != supportedSolcVersion {
t.Errorf("wrong version: expected %q, got %q", supportedSolcVersion, c.Info.CompilerVersion)
if c.Info.CompilerVersion == "" {
t.Error("empty version")
}
}

func TestCompileError(t *testing.T) {
skipUnsupported(t)
skipWithoutSolc(t)

contracts, err := CompileSolidityString("", testSource[4:])
if err == nil {
t.Errorf("error expected compiling source. got none. result %v", contracts)
Expand Down

0 comments on commit e0fde02

Please sign in to comment.