aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorJanos Guljas <janos@resenje.org>2018-02-09 19:23:30 +0800
committerJanos Guljas <janos@resenje.org>2018-02-22 21:23:17 +0800
commita3a07350dcef0ba39829a20d8ddba4bd3463d293 (patch)
tree100f2515cadd92105537a12e6981fab2193435ee /cmd
parent820cf09c98706f71d4b02b6c25e62db15830f3fb (diff)
parent1a4e68721a901e86322631fed1191025a6d14c52 (diff)
downloaddexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.tar
dexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.tar.gz
dexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.tar.bz2
dexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.tar.lz
dexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.tar.xz
dexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.tar.zst
dexon-a3a07350dcef0ba39829a20d8ddba4bd3463d293.zip
swarm, cmd/swarm: Merge branch 'master' into multiple-ens-endpoints
Diffstat (limited to 'cmd')
-rw-r--r--cmd/bootnode/main.go25
-rw-r--r--cmd/ethkey/README.md41
-rw-r--r--cmd/ethkey/generate.go118
-rw-r--r--cmd/ethkey/inspect.go75
-rw-r--r--cmd/ethkey/main.go67
-rw-r--r--cmd/ethkey/message.go159
-rw-r--r--cmd/ethkey/message_test.go70
-rw-r--r--cmd/ethkey/run_test.go54
-rw-r--r--cmd/ethkey/utils.go83
-rw-r--r--cmd/evm/json_logger.go10
-rw-r--r--cmd/evm/runner.go4
-rw-r--r--cmd/faucet/faucet.go11
-rw-r--r--cmd/faucet/website.go25
-rw-r--r--cmd/geth/chaincmd.go4
-rw-r--r--cmd/geth/config.go19
-rw-r--r--cmd/geth/consolecmd.go8
-rw-r--r--cmd/geth/main.go8
-rw-r--r--cmd/geth/misccmd.go3
-rw-r--r--cmd/geth/usage.go6
-rw-r--r--cmd/puppeth/genesis.go38
-rw-r--r--cmd/puppeth/module_faucet.go2
-rw-r--r--cmd/swarm/config.go2
-rw-r--r--cmd/utils/cmd.go26
-rw-r--r--cmd/utils/fdlimit_freebsd.go54
-rw-r--r--cmd/utils/fdlimit_test.go35
-rw-r--r--cmd/utils/fdlimit_unix.go50
-rw-r--r--cmd/utils/fdlimit_windows.go41
-rw-r--r--cmd/utils/flags.go106
-rw-r--r--cmd/wnode/main.go4
29 files changed, 855 insertions, 293 deletions
diff --git a/cmd/bootnode/main.go b/cmd/bootnode/main.go
index e1734d89a..ecfc6fc24 100644
--- a/cmd/bootnode/main.go
+++ b/cmd/bootnode/main.go
@@ -21,6 +21,7 @@ import (
"crypto/ecdsa"
"flag"
"fmt"
+ "net"
"os"
"github.com/ethereum/go-ethereum/cmd/utils"
@@ -96,12 +97,32 @@ func main() {
}
}
+ addr, err := net.ResolveUDPAddr("udp", *listenAddr)
+ if err != nil {
+ utils.Fatalf("-ResolveUDPAddr: %v", err)
+ }
+ conn, err := net.ListenUDP("udp", addr)
+ if err != nil {
+ utils.Fatalf("-ListenUDP: %v", err)
+ }
+
+ realaddr := conn.LocalAddr().(*net.UDPAddr)
+ if natm != nil {
+ if !realaddr.IP.IsLoopback() {
+ go nat.Map(natm, nil, "udp", realaddr.Port, realaddr.Port, "ethereum discovery")
+ }
+ // TODO: react to external IP changes over time.
+ if ext, err := natm.ExternalIP(); err == nil {
+ realaddr = &net.UDPAddr{IP: ext, Port: realaddr.Port}
+ }
+ }
+
if *runv5 {
- if _, err := discv5.ListenUDP(nodeKey, *listenAddr, natm, "", restrictList); err != nil {
+ if _, err := discv5.ListenUDP(nodeKey, conn, realaddr, "", restrictList); err != nil {
utils.Fatalf("%v", err)
}
} else {
- if _, err := discover.ListenUDP(nodeKey, *listenAddr, natm, "", restrictList); err != nil {
+ if _, err := discover.ListenUDP(nodeKey, conn, realaddr, nil, "", restrictList); err != nil {
utils.Fatalf("%v", err)
}
}
diff --git a/cmd/ethkey/README.md b/cmd/ethkey/README.md
new file mode 100644
index 000000000..cf72ba43d
--- /dev/null
+++ b/cmd/ethkey/README.md
@@ -0,0 +1,41 @@
+ethkey
+======
+
+ethkey is a simple command-line tool for working with Ethereum keyfiles.
+
+
+# Usage
+
+### `ethkey generate`
+
+Generate a new keyfile.
+If you want to use an existing private key to use in the keyfile, it can be
+specified by setting `--privatekey` with the location of the file containing the
+private key.
+
+
+### `ethkey inspect <keyfile>`
+
+Print various information about the keyfile.
+Private key information can be printed by using the `--private` flag;
+make sure to use this feature with great caution!
+
+
+### `ethkey sign <keyfile> <message/file>`
+
+Sign the message with a keyfile.
+It is possible to refer to a file containing the message.
+
+
+### `ethkey verify <address> <signature> <message/file>`
+
+Verify the signature of the message.
+It is possible to refer to a file containing the message.
+
+
+## Passphrases
+
+For every command that uses a keyfile, you will be prompted to provide the
+passphrase for decrypting the keyfile. To avoid this message, it is possible
+to pass the passphrase by using the `--passphrase` flag pointing to a file that
+contains the passphrase.
diff --git a/cmd/ethkey/generate.go b/cmd/ethkey/generate.go
new file mode 100644
index 000000000..6d57d17fb
--- /dev/null
+++ b/cmd/ethkey/generate.go
@@ -0,0 +1,118 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "crypto/ecdsa"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/pborman/uuid"
+ "gopkg.in/urfave/cli.v1"
+)
+
+type outputGenerate struct {
+ Address string
+ AddressEIP55 string
+}
+
+var commandGenerate = cli.Command{
+ Name: "generate",
+ Usage: "generate new keyfile",
+ ArgsUsage: "[ <keyfile> ]",
+ Description: `
+Generate a new keyfile.
+
+If you want to encrypt an existing private key, it can be specified by setting
+--privatekey with the location of the file containing the private key.
+`,
+ Flags: []cli.Flag{
+ passphraseFlag,
+ jsonFlag,
+ cli.StringFlag{
+ Name: "privatekey",
+ Usage: "file containing a raw private key to encrypt",
+ },
+ },
+ Action: func(ctx *cli.Context) error {
+ // Check if keyfile path given and make sure it doesn't already exist.
+ keyfilepath := ctx.Args().First()
+ if keyfilepath == "" {
+ keyfilepath = defaultKeyfileName
+ }
+ if _, err := os.Stat(keyfilepath); err == nil {
+ utils.Fatalf("Keyfile already exists at %s.", keyfilepath)
+ } else if !os.IsNotExist(err) {
+ utils.Fatalf("Error checking if keyfile exists: %v", err)
+ }
+
+ var privateKey *ecdsa.PrivateKey
+ var err error
+ if file := ctx.String("privatekey"); file != "" {
+ // Load private key from file.
+ privateKey, err = crypto.LoadECDSA(file)
+ if err != nil {
+ utils.Fatalf("Can't load private key: %v", err)
+ }
+ } else {
+ // If not loaded, generate random.
+ privateKey, err = crypto.GenerateKey()
+ if err != nil {
+ utils.Fatalf("Failed to generate random private key: %v", err)
+ }
+ }
+
+ // Create the keyfile object with a random UUID.
+ id := uuid.NewRandom()
+ key := &keystore.Key{
+ Id: id,
+ Address: crypto.PubkeyToAddress(privateKey.PublicKey),
+ PrivateKey: privateKey,
+ }
+
+ // Encrypt key with passphrase.
+ passphrase := getPassPhrase(ctx, true)
+ keyjson, err := keystore.EncryptKey(key, passphrase, keystore.StandardScryptN, keystore.StandardScryptP)
+ if err != nil {
+ utils.Fatalf("Error encrypting key: %v", err)
+ }
+
+ // Store the file to disk.
+ if err := os.MkdirAll(filepath.Dir(keyfilepath), 0700); err != nil {
+ utils.Fatalf("Could not create directory %s", filepath.Dir(keyfilepath))
+ }
+ if err := ioutil.WriteFile(keyfilepath, keyjson, 0600); err != nil {
+ utils.Fatalf("Failed to write keyfile to %s: %v", keyfilepath, err)
+ }
+
+ // Output some information.
+ out := outputGenerate{
+ Address: key.Address.Hex(),
+ }
+ if ctx.Bool(jsonFlag.Name) {
+ mustPrintJSON(out)
+ } else {
+ fmt.Println("Address:", out.Address)
+ }
+ return nil
+ },
+}
diff --git a/cmd/ethkey/inspect.go b/cmd/ethkey/inspect.go
new file mode 100644
index 000000000..219a5460b
--- /dev/null
+++ b/cmd/ethkey/inspect.go
@@ -0,0 +1,75 @@
+package main
+
+import (
+ "encoding/hex"
+ "fmt"
+ "io/ioutil"
+
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/crypto"
+ "gopkg.in/urfave/cli.v1"
+)
+
+type outputInspect struct {
+ Address string
+ PublicKey string
+ PrivateKey string
+}
+
+var commandInspect = cli.Command{
+ Name: "inspect",
+ Usage: "inspect a keyfile",
+ ArgsUsage: "<keyfile>",
+ Description: `
+Print various information about the keyfile.
+
+Private key information can be printed by using the --private flag;
+make sure to use this feature with great caution!`,
+ Flags: []cli.Flag{
+ passphraseFlag,
+ jsonFlag,
+ cli.BoolFlag{
+ Name: "private",
+ Usage: "include the private key in the output",
+ },
+ },
+ Action: func(ctx *cli.Context) error {
+ keyfilepath := ctx.Args().First()
+
+ // Read key from file.
+ keyjson, err := ioutil.ReadFile(keyfilepath)
+ if err != nil {
+ utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err)
+ }
+
+ // Decrypt key with passphrase.
+ passphrase := getPassPhrase(ctx, false)
+ key, err := keystore.DecryptKey(keyjson, passphrase)
+ if err != nil {
+ utils.Fatalf("Error decrypting key: %v", err)
+ }
+
+ // Output all relevant information we can retrieve.
+ showPrivate := ctx.Bool("private")
+ out := outputInspect{
+ Address: key.Address.Hex(),
+ PublicKey: hex.EncodeToString(
+ crypto.FromECDSAPub(&key.PrivateKey.PublicKey)),
+ }
+ if showPrivate {
+ out.PrivateKey = hex.EncodeToString(crypto.FromECDSA(key.PrivateKey))
+ }
+
+ if ctx.Bool(jsonFlag.Name) {
+ mustPrintJSON(out)
+ } else {
+ fmt.Println("Address: ", out.Address)
+ fmt.Println("Public key: ", out.PublicKey)
+ if showPrivate {
+ fmt.Println("Private key: ", out.PrivateKey)
+ }
+ }
+ return nil
+ },
+}
diff --git a/cmd/ethkey/main.go b/cmd/ethkey/main.go
new file mode 100644
index 000000000..2a9e5ee48
--- /dev/null
+++ b/cmd/ethkey/main.go
@@ -0,0 +1,67 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "fmt"
+ "os"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "gopkg.in/urfave/cli.v1"
+)
+
+const (
+ defaultKeyfileName = "keyfile.json"
+)
+
+// Git SHA1 commit hash of the release (set via linker flags)
+var gitCommit = ""
+
+var app *cli.App
+
+func init() {
+ app = utils.NewApp(gitCommit, "an Ethereum key manager")
+ app.Commands = []cli.Command{
+ commandGenerate,
+ commandInspect,
+ commandSignMessage,
+ commandVerifyMessage,
+ }
+}
+
+// Commonly used command line flags.
+var (
+ passphraseFlag = cli.StringFlag{
+ Name: "passwordfile",
+ Usage: "the file that contains the passphrase for the keyfile",
+ }
+ jsonFlag = cli.BoolFlag{
+ Name: "json",
+ Usage: "output JSON instead of human-readable format",
+ }
+ messageFlag = cli.StringFlag{
+ Name: "message",
+ Usage: "the file that contains the message to sign/verify",
+ }
+)
+
+func main() {
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
diff --git a/cmd/ethkey/message.go b/cmd/ethkey/message.go
new file mode 100644
index 000000000..531a931c8
--- /dev/null
+++ b/cmd/ethkey/message.go
@@ -0,0 +1,159 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "encoding/hex"
+ "fmt"
+ "io/ioutil"
+
+ "github.com/ethereum/go-ethereum/accounts/keystore"
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/crypto"
+ "gopkg.in/urfave/cli.v1"
+)
+
+type outputSign struct {
+ Signature string
+}
+
+var msgfileFlag = cli.StringFlag{
+ Name: "msgfile",
+ Usage: "file containing the message to sign/verify",
+}
+
+var commandSignMessage = cli.Command{
+ Name: "signmessage",
+ Usage: "sign a message",
+ ArgsUsage: "<keyfile> <message>",
+ Description: `
+Sign the message with a keyfile.
+
+To sign a message contained in a file, use the --msgfile flag.
+`,
+ Flags: []cli.Flag{
+ passphraseFlag,
+ jsonFlag,
+ msgfileFlag,
+ },
+ Action: func(ctx *cli.Context) error {
+ message := getMessage(ctx, 1)
+
+ // Load the keyfile.
+ keyfilepath := ctx.Args().First()
+ keyjson, err := ioutil.ReadFile(keyfilepath)
+ if err != nil {
+ utils.Fatalf("Failed to read the keyfile at '%s': %v", keyfilepath, err)
+ }
+
+ // Decrypt key with passphrase.
+ passphrase := getPassPhrase(ctx, false)
+ key, err := keystore.DecryptKey(keyjson, passphrase)
+ if err != nil {
+ utils.Fatalf("Error decrypting key: %v", err)
+ }
+
+ signature, err := crypto.Sign(signHash(message), key.PrivateKey)
+ if err != nil {
+ utils.Fatalf("Failed to sign message: %v", err)
+ }
+ out := outputSign{Signature: hex.EncodeToString(signature)}
+ if ctx.Bool(jsonFlag.Name) {
+ mustPrintJSON(out)
+ } else {
+ fmt.Println("Signature:", out.Signature)
+ }
+ return nil
+ },
+}
+
+type outputVerify struct {
+ Success bool
+ RecoveredAddress string
+ RecoveredPublicKey string
+}
+
+var commandVerifyMessage = cli.Command{
+ Name: "verifymessage",
+ Usage: "verify the signature of a signed message",
+ ArgsUsage: "<address> <signature> <message>",
+ Description: `
+Verify the signature of the message.
+It is possible to refer to a file containing the message.`,
+ Flags: []cli.Flag{
+ jsonFlag,
+ msgfileFlag,
+ },
+ Action: func(ctx *cli.Context) error {
+ addressStr := ctx.Args().First()
+ signatureHex := ctx.Args().Get(1)
+ message := getMessage(ctx, 2)
+
+ if !common.IsHexAddress(addressStr) {
+ utils.Fatalf("Invalid address: %s", addressStr)
+ }
+ address := common.HexToAddress(addressStr)
+ signature, err := hex.DecodeString(signatureHex)
+ if err != nil {
+ utils.Fatalf("Signature encoding is not hexadecimal: %v", err)
+ }
+
+ recoveredPubkey, err := crypto.SigToPub(signHash(message), signature)
+ if err != nil || recoveredPubkey == nil {
+ utils.Fatalf("Signature verification failed: %v", err)
+ }
+ recoveredPubkeyBytes := crypto.FromECDSAPub(recoveredPubkey)
+ recoveredAddress := crypto.PubkeyToAddress(*recoveredPubkey)
+ success := address == recoveredAddress
+
+ out := outputVerify{
+ Success: success,
+ RecoveredPublicKey: hex.EncodeToString(recoveredPubkeyBytes),
+ RecoveredAddress: recoveredAddress.Hex(),
+ }
+ if ctx.Bool(jsonFlag.Name) {
+ mustPrintJSON(out)
+ } else {
+ if out.Success {
+ fmt.Println("Signature verification successful!")
+ } else {
+ fmt.Println("Signature verification failed!")
+ }
+ fmt.Println("Recovered public key:", out.RecoveredPublicKey)
+ fmt.Println("Recovered address:", out.RecoveredAddress)
+ }
+ return nil
+ },
+}
+
+func getMessage(ctx *cli.Context, msgarg int) []byte {
+ if file := ctx.String("msgfile"); file != "" {
+ if len(ctx.Args()) > msgarg {
+ utils.Fatalf("Can't use --msgfile and message argument at the same time.")
+ }
+ msg, err := ioutil.ReadFile(file)
+ if err != nil {
+ utils.Fatalf("Can't read message file: %v", err)
+ }
+ return msg
+ } else if len(ctx.Args()) == msgarg+1 {
+ return []byte(ctx.Args().Get(msgarg))
+ }
+ utils.Fatalf("Invalid number of arguments: want %d, got %d", msgarg+1, len(ctx.Args()))
+ return nil
+}
diff --git a/cmd/ethkey/message_test.go b/cmd/ethkey/message_test.go
new file mode 100644
index 000000000..fb16f03d0
--- /dev/null
+++ b/cmd/ethkey/message_test.go
@@ -0,0 +1,70 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+func TestMessageSignVerify(t *testing.T) {
+ tmpdir, err := ioutil.TempDir("", "ethkey-test")
+ if err != nil {
+ t.Fatal("Can't create temporary directory:", err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ keyfile := filepath.Join(tmpdir, "the-keyfile")
+ message := "test message"
+
+ // Create the key.
+ generate := runEthkey(t, "generate", keyfile)
+ generate.Expect(`
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+Repeat passphrase: {{.InputLine "foobar"}}
+`)
+ _, matches := generate.ExpectRegexp(`Address: (0x[0-9a-fA-F]{40})\n`)
+ address := matches[1]
+ generate.ExpectExit()
+
+ // Sign a message.
+ sign := runEthkey(t, "signmessage", keyfile, message)
+ sign.Expect(`
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+`)
+ _, matches = sign.ExpectRegexp(`Signature: ([0-9a-f]+)\n`)
+ signature := matches[1]
+ sign.ExpectExit()
+
+ // Verify the message.
+ verify := runEthkey(t, "verifymessage", address, signature, message)
+ _, matches = verify.ExpectRegexp(`
+Signature verification successful!
+Recovered public key: [0-9a-f]+
+Recovered address: (0x[0-9a-fA-F]{40})
+`)
+ recovered := matches[1]
+ verify.ExpectExit()
+
+ if recovered != address {
+ t.Error("recovered address doesn't match generated key")
+ }
+}
diff --git a/cmd/ethkey/run_test.go b/cmd/ethkey/run_test.go
new file mode 100644
index 000000000..8ce4fe5cd
--- /dev/null
+++ b/cmd/ethkey/run_test.go
@@ -0,0 +1,54 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "testing"
+
+ "github.com/docker/docker/pkg/reexec"
+ "github.com/ethereum/go-ethereum/internal/cmdtest"
+)
+
+type testEthkey struct {
+ *cmdtest.TestCmd
+}
+
+// spawns ethkey with the given command line args.
+func runEthkey(t *testing.T, args ...string) *testEthkey {
+ tt := new(testEthkey)
+ tt.TestCmd = cmdtest.NewTestCmd(t, tt)
+ tt.Run("ethkey-test", args...)
+ return tt
+}
+
+func TestMain(m *testing.M) {
+ // Run the app if we've been exec'd as "ethkey-test" in runEthkey.
+ reexec.Register("ethkey-test", func() {
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ os.Exit(0)
+ })
+ // check if we have been reexec'd
+ if reexec.Init() {
+ return
+ }
+ os.Exit(m.Run())
+}
diff --git a/cmd/ethkey/utils.go b/cmd/ethkey/utils.go
new file mode 100644
index 000000000..0e563bf92
--- /dev/null
+++ b/cmd/ethkey/utils.go
@@ -0,0 +1,83 @@
+// Copyright 2017 The go-ethereum Authors
+// This file is part of go-ethereum.
+//
+// go-ethereum is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// go-ethereum is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "strings"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ "github.com/ethereum/go-ethereum/console"
+ "github.com/ethereum/go-ethereum/crypto"
+ "gopkg.in/urfave/cli.v1"
+)
+
+// getPassPhrase obtains a passphrase given by the user. It first checks the
+// --passphrase command line flag and ultimately prompts the user for a
+// passphrase.
+func getPassPhrase(ctx *cli.Context, confirmation bool) string {
+ // Look for the --passphrase flag.
+ passphraseFile := ctx.String(passphraseFlag.Name)
+ if passphraseFile != "" {
+ content, err := ioutil.ReadFile(passphraseFile)
+ if err != nil {
+ utils.Fatalf("Failed to read passphrase file '%s': %v",
+ passphraseFile, err)
+ }
+ return strings.TrimRight(string(content), "\r\n")
+ }
+
+ // Otherwise prompt the user for the passphrase.
+ passphrase, err := console.Stdin.PromptPassword("Passphrase: ")
+ if err != nil {
+ utils.Fatalf("Failed to read passphrase: %v", err)
+ }
+ if confirmation {
+ confirm, err := console.Stdin.PromptPassword("Repeat passphrase: ")
+ if err != nil {
+ utils.Fatalf("Failed to read passphrase confirmation: %v", err)
+ }
+ if passphrase != confirm {
+ utils.Fatalf("Passphrases do not match")
+ }
+ }
+ return passphrase
+}
+
+// signHash is a helper function that calculates a hash for the given message
+// that can be safely used to calculate a signature from.
+//
+// The hash is calulcated as
+// keccak256("\x19Ethereum Signed Message:\n"${message length}${message}).
+//
+// This gives context to the signed message and prevents signing of transactions.
+func signHash(data []byte) []byte {
+ msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data)
+ return crypto.Keccak256([]byte(msg))
+}
+
+// mustPrintJSON prints the JSON encoding of the given object and
+// exits the program with an error message when the marshaling fails.
+func mustPrintJSON(jsonObject interface{}) {
+ str, err := json.MarshalIndent(jsonObject, "", " ")
+ if err != nil {
+ utils.Fatalf("Failed to marshal JSON object: %v", err)
+ }
+ fmt.Println(string(str))
+}
diff --git a/cmd/evm/json_logger.go b/cmd/evm/json_logger.go
index eb7b0c466..47daf7dbb 100644
--- a/cmd/evm/json_logger.go
+++ b/cmd/evm/json_logger.go
@@ -19,6 +19,7 @@ package main
import (
"encoding/json"
"io"
+ "math/big"
"time"
"github.com/ethereum/go-ethereum/common"
@@ -35,6 +36,10 @@ func NewJSONLogger(cfg *vm.LogConfig, writer io.Writer) *JSONLogger {
return &JSONLogger{json.NewEncoder(writer), cfg}
}
+func (l *JSONLogger) CaptureStart(from common.Address, to common.Address, create bool, input []byte, gas uint64, value *big.Int) error {
+ return nil
+}
+
// CaptureState outputs state information on the logger.
func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error {
log := vm.StructLog{
@@ -56,6 +61,11 @@ func (l *JSONLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, gas, cos
return l.encoder.Encode(log)
}
+// CaptureFault outputs state information on the logger.
+func (l *JSONLogger) CaptureFault(env *vm.EVM, pc uint64, op vm.OpCode, gas, cost uint64, memory *vm.Memory, stack *vm.Stack, contract *vm.Contract, depth int, err error) error {
+ return nil
+}
+
// CaptureEnd is triggered at end of execution.
func (l *JSONLogger) CaptureEnd(output []byte, gasUsed uint64, t time.Duration, err error) error {
type endLog struct {
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index 96de0c76a..a9a2e5420 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -96,7 +96,9 @@ func runCmd(ctx *cli.Context) error {
}
if ctx.GlobalString(GenesisFlag.Name) != "" {
gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
- _, statedb = gen.ToBlock()
+ db, _ := ethdb.NewMemDatabase()
+ genesis := gen.ToBlock(db)
+ statedb, _ = state.New(genesis.Root(), state.NewDatabase(db))
chainConfig = gen.Config
} else {
db, _ := ethdb.NewMemDatabase()
diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go
index 5f16f2978..99527f9d1 100644
--- a/cmd/faucet/faucet.go
+++ b/cmd/faucet/faucet.go
@@ -18,10 +18,10 @@
package main
//go:generate go-bindata -nometadata -o website.go faucet.html
+//go:generate gofmt -w -s website.go
import (
"bytes"
- "compress/zlib"
"context"
"encoding/json"
"errors"
@@ -223,7 +223,6 @@ func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network u
NoDiscovery: true,
DiscoveryV5: true,
ListenAddr: fmt.Sprintf(":%d", port),
- DiscoveryV5Addr: fmt.Sprintf(":%d", port+1),
MaxPeers: 25,
BootstrapNodesV5: enodes,
},
@@ -474,7 +473,7 @@ func (f *faucet) apiHandler(conn *websocket.Conn) {
amount = new(big.Int).Mul(amount, new(big.Int).Exp(big.NewInt(5), big.NewInt(int64(msg.Tier)), nil))
amount = new(big.Int).Div(amount, new(big.Int).Exp(big.NewInt(2), big.NewInt(int64(msg.Tier)), nil))
- tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, big.NewInt(21000), f.price, nil)
+ tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, 21000, f.price, nil)
signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainId)
if err != nil {
f.lock.Unlock()
@@ -698,11 +697,7 @@ func authTwitter(url string) (string, string, common.Address, error) {
}
defer res.Body.Close()
- reader, err := zlib.NewReader(res.Body)
- if err != nil {
- return "", "", common.Address{}, err
- }
- body, err := ioutil.ReadAll(reader)
+ body, err := ioutil.ReadAll(res.Body)
if err != nil {
return "", "", common.Address{}, err
}
diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go
index 7936b158e..fab1d4346 100644
--- a/cmd/faucet/website.go
+++ b/cmd/faucet/website.go
@@ -1,7 +1,6 @@
-// Code generated by go-bindata.
+// Code generated by go-bindata. DO NOT EDIT.
// sources:
// faucet.html
-// DO NOT EDIT!
package main
@@ -92,8 +91,8 @@ func faucetHtml() (*asset, error) {
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[cannonicalName]; ok {
+ canonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[canonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
@@ -118,8 +117,8 @@ func MustAsset(name string) []byte {
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- if f, ok := _bindata[cannonicalName]; ok {
+ canonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[canonicalName]; ok {
a, err := f()
if err != nil {
return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
@@ -159,8 +158,8 @@ var _bindata = map[string]func() (*asset, error){
func AssetDir(name string) ([]string, error) {
node := _bintree
if len(name) != 0 {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- pathList := strings.Split(cannonicalName, "/")
+ canonicalName := strings.Replace(name, "\\", "/", -1)
+ pathList := strings.Split(canonicalName, "/")
for _, p := range pathList {
node = node.Children[p]
if node == nil {
@@ -205,11 +204,7 @@ func RestoreAsset(dir, name string) error {
if err != nil {
return err
}
- err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
- if err != nil {
- return err
- }
- return nil
+ return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
}
// RestoreAssets restores an asset under the given directory recursively
@@ -230,6 +225,6 @@ func RestoreAssets(dir, name string) error {
}
func _filePath(dir, name string) string {
- cannonicalName := strings.Replace(name, "\\", "/", -1)
- return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+ canonicalName := strings.Replace(name, "\\", "/", -1)
+ return filepath.Join(append([]string{dir}, strings.Split(canonicalName, "/")...)...)
}
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index 4a9a7b11b..35bf576e1 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -202,7 +202,7 @@ func importChain(ctx *cli.Context) error {
if len(ctx.Args()) == 1 {
if err := utils.ImportChain(chain, ctx.Args().First()); err != nil {
- utils.Fatalf("Import error: %v", err)
+ log.Error("Import error", "err", err)
}
} else {
for _, arg := range ctx.Args() {
@@ -211,7 +211,7 @@ func importChain(ctx *cli.Context) error {
}
}
}
-
+ chain.Stop()
fmt.Printf("Import done in %v.\n\n", time.Since(start))
// Output pre-compaction stats mostly to see the import trashing
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
index 27490c404..50e4de2e7 100644
--- a/cmd/geth/config.go
+++ b/cmd/geth/config.go
@@ -18,7 +18,6 @@ package main
import (
"bufio"
- "encoding/hex"
"errors"
"fmt"
"io"
@@ -29,7 +28,6 @@ import (
cli "gopkg.in/urfave/cli.v1"
"github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/contracts/release"
"github.com/ethereum/go-ethereum/dashboard"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/node"
@@ -158,7 +156,7 @@ func makeFullNode(ctx *cli.Context) *node.Node {
utils.RegisterEthService(stack, &cfg.Eth)
if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
- utils.RegisterDashboardService(stack, &cfg.Dashboard)
+ utils.RegisterDashboardService(stack, &cfg.Dashboard, gitCommit)
}
// Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
shhEnabled := enableWhisper(ctx)
@@ -177,21 +175,6 @@ func makeFullNode(ctx *cli.Context) *node.Node {
if cfg.Ethstats.URL != "" {
utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
}
-
- // Add the release oracle service so it boots along with node.
- if err := stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- config := release.Config{
- Oracle: relOracle,
- Major: uint32(params.VersionMajor),
- Minor: uint32(params.VersionMinor),
- Patch: uint32(params.VersionPatch),
- }
- commit, _ := hex.DecodeString(gitCommit)
- copy(config.Commit[:], commit)
- return release.NewReleaseService(ctx, config)
- }); err != nil {
- utils.Fatalf("Failed to register the Geth release oracle service: %v", err)
- }
return stack
}
diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go
index 2c6b16687..9d5cc38a1 100644
--- a/cmd/geth/consolecmd.go
+++ b/cmd/geth/consolecmd.go
@@ -120,8 +120,12 @@ func remoteConsole(ctx *cli.Context) error {
if ctx.GlobalIsSet(utils.DataDirFlag.Name) {
path = ctx.GlobalString(utils.DataDirFlag.Name)
}
- if path != "" && ctx.GlobalBool(utils.TestnetFlag.Name) {
- path = filepath.Join(path, "testnet")
+ if path != "" {
+ if ctx.GlobalBool(utils.TestnetFlag.Name) {
+ path = filepath.Join(path, "testnet")
+ } else if ctx.GlobalBool(utils.RinkebyFlag.Name) {
+ path = filepath.Join(path, "rinkeby")
+ }
}
endpoint = fmt.Sprintf("%s/geth.ipc", path)
}
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index bdb7fad62..cb8d63bf7 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -85,10 +85,13 @@ var (
utils.FastSyncFlag,
utils.LightModeFlag,
utils.SyncModeFlag,
+ utils.GCModeFlag,
utils.LightServFlag,
utils.LightPeersFlag,
utils.LightKDFFlag,
utils.CacheFlag,
+ utils.CacheDatabaseFlag,
+ utils.CacheGCFlag,
utils.TrieCacheGenFlag,
utils.ListenPortFlag,
utils.MaxPeersFlag,
@@ -278,9 +281,12 @@ func startNode(ctx *cli.Context, stack *node.Node) {
// Start auxiliary services if enabled
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
// Mining only makes sense if a full Ethereum node is running
+ if ctx.GlobalBool(utils.LightModeFlag.Name) || ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
+ utils.Fatalf("Light clients do not support mining")
+ }
var ethereum *eth.Ethereum
if err := stack.Service(&ethereum); err != nil {
- utils.Fatalf("ethereum service not running: %v", err)
+ utils.Fatalf("Ethereum service not running: %v", err)
}
// Use a reduced number of threads if requested
if threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name); threads > 0 {
diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go
index 2e68dcda3..aa9b1ee56 100644
--- a/cmd/geth/misccmd.go
+++ b/cmd/geth/misccmd.go
@@ -134,7 +134,6 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with geth. If not, see <http://www.gnu.org/licenses/>.
-`)
+along with geth. If not, see <http://www.gnu.org/licenses/>.`)
return nil
}
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
index a834d5b7a..a2bcaff02 100644
--- a/cmd/geth/usage.go
+++ b/cmd/geth/usage.go
@@ -22,10 +22,11 @@ import (
"io"
"sort"
+ "strings"
+
"github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/internal/debug"
"gopkg.in/urfave/cli.v1"
- "strings"
)
// AppHelpTemplate is the test template for the default, global app help topic.
@@ -74,6 +75,7 @@ var AppHelpFlagGroups = []flagGroup{
utils.TestnetFlag,
utils.RinkebyFlag,
utils.SyncModeFlag,
+ utils.GCModeFlag,
utils.EthStatsURLFlag,
utils.IdentityFlag,
utils.LightServFlag,
@@ -127,6 +129,8 @@ var AppHelpFlagGroups = []flagGroup{
Name: "PERFORMANCE TUNING",
Flags: []cli.Flag{
utils.CacheFlag,
+ utils.CacheDatabaseFlag,
+ utils.CacheGCFlag,
utils.TrieCacheGenFlag,
},
},
diff --git a/cmd/puppeth/genesis.go b/cmd/puppeth/genesis.go
index 5e36f7fce..f747f4739 100644
--- a/cmd/puppeth/genesis.go
+++ b/cmd/puppeth/genesis.go
@@ -44,7 +44,7 @@ type cppEthereumGenesisSpec struct {
MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
MinGasLimit hexutil.Uint64 `json:"minGasLimit"`
MaxGasLimit hexutil.Uint64 `json:"maxGasLimit"`
- GasLimitBoundDivisor *hexutil.Big `json:"gasLimitBoundDivisor"`
+ GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"`
MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"`
DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
DurationLimit *hexutil.Big `json:"durationLimit"`
@@ -107,11 +107,11 @@ func newCppEthereumGenesisSpec(network string, genesis *core.Genesis) (*cppEther
spec.Params.ChainID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64())
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
- spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit.Uint64())
+ spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.MaxGasLimit = (hexutil.Uint64)(math.MaxUint64)
spec.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
spec.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
- spec.Params.GasLimitBoundDivisor = (*hexutil.Big)(params.GasLimitBoundDivisor)
+ spec.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
spec.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
spec.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
@@ -168,26 +168,26 @@ type parityChainSpec struct {
Engine struct {
Ethash struct {
Params struct {
- MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"`
- DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
- GasLimitBoundDivisor *hexutil.Big `json:"gasLimitBoundDivisor"`
- DurationLimit *hexutil.Big `json:"durationLimit"`
- BlockReward *hexutil.Big `json:"blockReward"`
- HomesteadTransition uint64 `json:"homesteadTransition"`
- EIP150Transition uint64 `json:"eip150Transition"`
- EIP160Transition uint64 `json:"eip160Transition"`
- EIP161abcTransition uint64 `json:"eip161abcTransition"`
- EIP161dTransition uint64 `json:"eip161dTransition"`
- EIP649Reward *hexutil.Big `json:"eip649Reward"`
- EIP100bTransition uint64 `json:"eip100bTransition"`
- EIP649Transition uint64 `json:"eip649Transition"`
+ MinimumDifficulty *hexutil.Big `json:"minimumDifficulty"`
+ DifficultyBoundDivisor *hexutil.Big `json:"difficultyBoundDivisor"`
+ GasLimitBoundDivisor hexutil.Uint64 `json:"gasLimitBoundDivisor"`
+ DurationLimit *hexutil.Big `json:"durationLimit"`
+ BlockReward *hexutil.Big `json:"blockReward"`
+ HomesteadTransition uint64 `json:"homesteadTransition"`
+ EIP150Transition uint64 `json:"eip150Transition"`
+ EIP160Transition uint64 `json:"eip160Transition"`
+ EIP161abcTransition uint64 `json:"eip161abcTransition"`
+ EIP161dTransition uint64 `json:"eip161dTransition"`
+ EIP649Reward *hexutil.Big `json:"eip649Reward"`
+ EIP100bTransition uint64 `json:"eip100bTransition"`
+ EIP649Transition uint64 `json:"eip649Transition"`
} `json:"params"`
} `json:"Ethash"`
} `json:"engine"`
Params struct {
MaximumExtraDataSize hexutil.Uint64 `json:"maximumExtraDataSize"`
- MinGasLimit *hexutil.Big `json:"minGasLimit"`
+ MinGasLimit hexutil.Uint64 `json:"minGasLimit"`
NetworkID hexutil.Uint64 `json:"networkID"`
MaxCodeSize uint64 `json:"maxCodeSize"`
EIP155Transition uint64 `json:"eip155Transition"`
@@ -270,7 +270,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
}
spec.Engine.Ethash.Params.MinimumDifficulty = (*hexutil.Big)(params.MinimumDifficulty)
spec.Engine.Ethash.Params.DifficultyBoundDivisor = (*hexutil.Big)(params.DifficultyBoundDivisor)
- spec.Engine.Ethash.Params.GasLimitBoundDivisor = (*hexutil.Big)(params.GasLimitBoundDivisor)
+ spec.Engine.Ethash.Params.GasLimitBoundDivisor = (hexutil.Uint64)(params.GasLimitBoundDivisor)
spec.Engine.Ethash.Params.DurationLimit = (*hexutil.Big)(params.DurationLimit)
spec.Engine.Ethash.Params.BlockReward = (*hexutil.Big)(ethash.FrontierBlockReward)
spec.Engine.Ethash.Params.HomesteadTransition = genesis.Config.HomesteadBlock.Uint64()
@@ -283,7 +283,7 @@ func newParityChainSpec(network string, genesis *core.Genesis, bootnodes []strin
spec.Engine.Ethash.Params.EIP649Transition = genesis.Config.ByzantiumBlock.Uint64()
spec.Params.MaximumExtraDataSize = (hexutil.Uint64)(params.MaximumExtraDataSize)
- spec.Params.MinGasLimit = (*hexutil.Big)(params.MinGasLimit)
+ spec.Params.MinGasLimit = (hexutil.Uint64)(params.MinGasLimit)
spec.Params.NetworkID = (hexutil.Uint64)(genesis.Config.ChainId.Uint64())
spec.Params.MaxCodeSize = params.MaxCodeSize
spec.Params.EIP155Transition = genesis.Config.EIP155Block.Uint64()
diff --git a/cmd/puppeth/module_faucet.go b/cmd/puppeth/module_faucet.go
index 57b7a2dc0..92b4cb286 100644
--- a/cmd/puppeth/module_faucet.go
+++ b/cmd/puppeth/module_faucet.go
@@ -39,6 +39,8 @@ ADD genesis.json /genesis.json
ADD account.json /account.json
ADD account.pass /account.pass
+EXPOSE 8080 30303 30303/udp
+
ENTRYPOINT [ \
"faucet", "--genesis", "/genesis.json", "--network", "{{.NetworkID}}", "--bootnodes", "{{.Bootnodes}}", "--ethstats", "{{.Ethstats}}", "--ethport", "{{.EthPort}}", \
"--faucet.name", "{{.FaucetName}}", "--faucet.amount", "{{.FaucetAmount}}", "--faucet.minutes", "{{.FaucetMinutes}}", "--faucet.tiers", "{{.FaucetTiers}}", \
diff --git a/cmd/swarm/config.go b/cmd/swarm/config.go
index a3c03c00d..adac772ba 100644
--- a/cmd/swarm/config.go
+++ b/cmd/swarm/config.go
@@ -361,7 +361,7 @@ func validateEnsAPIs(s string) (err error) {
func printConfig(config *bzzapi.Config) string {
out, err := tomlSettings.Marshal(&config)
if err != nil {
- return (fmt.Sprintf("Something is not right with the configuration: %v", err))
+ return fmt.Sprintf("Something is not right with the configuration: %v", err)
}
return string(out)
}
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 23b10c2d7..53cdf7861 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -116,7 +116,6 @@ func ImportChain(chain *core.BlockChain, fn string) error {
return err
}
}
-
stream := rlp.NewStream(reader, 0)
// Run actual the import.
@@ -150,25 +149,34 @@ func ImportChain(chain *core.BlockChain, fn string) error {
if checkInterrupt() {
return fmt.Errorf("interrupted")
}
- if hasAllBlocks(chain, blocks[:i]) {
+ missing := missingBlocks(chain, blocks[:i])
+ if len(missing) == 0 {
log.Info("Skipping batch as all blocks present", "batch", batch, "first", blocks[0].Hash(), "last", blocks[i-1].Hash())
continue
}
-
- if _, err := chain.InsertChain(blocks[:i]); err != nil {
+ if _, err := chain.InsertChain(missing); err != nil {
return fmt.Errorf("invalid block %d: %v", n, err)
}
}
return nil
}
-func hasAllBlocks(chain *core.BlockChain, bs []*types.Block) bool {
- for _, b := range bs {
- if !chain.HasBlock(b.Hash(), b.NumberU64()) {
- return false
+func missingBlocks(chain *core.BlockChain, blocks []*types.Block) []*types.Block {
+ head := chain.CurrentBlock()
+ for i, block := range blocks {
+ // If we're behind the chain head, only check block, state is available at head
+ if head.NumberU64() > block.NumberU64() {
+ if !chain.HasBlock(block.Hash(), block.NumberU64()) {
+ return blocks[i:]
+ }
+ continue
+ }
+ // If we're above the chain head, state availability is a must
+ if !chain.HasBlockAndState(block.Hash(), block.NumberU64()) {
+ return blocks[i:]
}
}
- return true
+ return nil
}
func ExportChain(blockchain *core.BlockChain, fn string) error {
diff --git a/cmd/utils/fdlimit_freebsd.go b/cmd/utils/fdlimit_freebsd.go
deleted file mode 100644
index 4cb5013c8..000000000
--- a/cmd/utils/fdlimit_freebsd.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-// +build freebsd
-
-package utils
-
-import "syscall"
-
-// This file is largely identical to fdlimit_unix.go,
-// but Rlimit fields have type int64 on FreeBSD so it needs
-// an extra conversion.
-
-// raiseFdLimit tries to maximize the file descriptor allowance of this process
-// to the maximum hard-limit allowed by the OS.
-func raiseFdLimit(max uint64) error {
- // Get the current limit
- var limit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return err
- }
- // Try to update the limit to the max allowance
- limit.Cur = limit.Max
- if limit.Cur > int64(max) {
- limit.Cur = int64(max)
- }
- if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return err
- }
- return nil
-}
-
-// getFdLimit retrieves the number of file descriptors allowed to be opened by this
-// process.
-func getFdLimit() (int, error) {
- var limit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return 0, err
- }
- return int(limit.Cur), nil
-}
diff --git a/cmd/utils/fdlimit_test.go b/cmd/utils/fdlimit_test.go
deleted file mode 100644
index 0a950a6c9..000000000
--- a/cmd/utils/fdlimit_test.go
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-package utils
-
-import "testing"
-
-// TestFileDescriptorLimits simply tests whether the file descriptor allowance
-// per this process can be retrieved.
-func TestFileDescriptorLimits(t *testing.T) {
- target := 4096
-
- if limit, err := getFdLimit(); err != nil || limit <= 0 {
- t.Fatalf("failed to retrieve file descriptor limit (%d): %v", limit, err)
- }
- if err := raiseFdLimit(uint64(target)); err != nil {
- t.Fatalf("failed to raise file allowance")
- }
- if limit, err := getFdLimit(); err != nil || limit < target {
- t.Fatalf("failed to retrieve raised descriptor limit (have %v, want %v): %v", limit, target, err)
- }
-}
diff --git a/cmd/utils/fdlimit_unix.go b/cmd/utils/fdlimit_unix.go
deleted file mode 100644
index 08e153bbd..000000000
--- a/cmd/utils/fdlimit_unix.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-// +build linux darwin netbsd openbsd solaris
-
-package utils
-
-import "syscall"
-
-// raiseFdLimit tries to maximize the file descriptor allowance of this process
-// to the maximum hard-limit allowed by the OS.
-func raiseFdLimit(max uint64) error {
- // Get the current limit
- var limit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return err
- }
- // Try to update the limit to the max allowance
- limit.Cur = limit.Max
- if limit.Cur > max {
- limit.Cur = max
- }
- if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return err
- }
- return nil
-}
-
-// getFdLimit retrieves the number of file descriptors allowed to be opened by this
-// process.
-func getFdLimit() (int, error) {
- var limit syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &limit); err != nil {
- return 0, err
- }
- return int(limit.Cur), nil
-}
diff --git a/cmd/utils/fdlimit_windows.go b/cmd/utils/fdlimit_windows.go
deleted file mode 100644
index 53aad3d7a..000000000
--- a/cmd/utils/fdlimit_windows.go
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2016 The go-ethereum Authors
-// This file is part of go-ethereum.
-//
-// go-ethereum is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// go-ethereum is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-
-package utils
-
-import "errors"
-
-// raiseFdLimit tries to maximize the file descriptor allowance of this process
-// to the maximum hard-limit allowed by the OS.
-func raiseFdLimit(max uint64) error {
- // This method is NOP by design:
- // * Linux/Darwin counterparts need to manually increase per process limits
- // * On Windows Go uses the CreateFile API, which is limited to 16K files, non
- // changeable from within a running process
- // This way we can always "request" raising the limits, which will either have
- // or not have effect based on the platform we're running on.
- if max > 16384 {
- return errors.New("file descriptor limit (16384) reached")
- }
- return nil
-}
-
-// getFdLimit retrieves the number of file descriptors allowed to be opened by this
-// process.
-func getFdLimit() (int, error) {
- // Please see raiseFdLimit for the reason why we use hard coded 16K as the limit
- return 16384, nil
-}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 30edf199c..2a2909ff2 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -31,6 +31,7 @@ import (
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/ethereum/go-ethereum/common"
+ "github.com/ethereum/go-ethereum/common/fdlimit"
"github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/consensus/ethash"
@@ -96,7 +97,7 @@ func NewApp(gitCommit, usage string) *cli.App {
//app.Authors = nil
app.Email = ""
app.Version = params.Version
- if gitCommit != "" {
+ if len(gitCommit) >= 8 {
app.Version += "-" + gitCommit[:8]
}
app.Usage = usage
@@ -169,7 +170,11 @@ var (
Usage: `Blockchain sync mode ("fast", "full", or "light")`,
Value: &defaultSyncMode,
}
-
+ GCModeFlag = cli.StringFlag{
+ Name: "gcmode",
+ Usage: `Blockchain garbage collection mode ("full", "archive")`,
+ Value: "full",
+ }
LightServFlag = cli.IntFlag{
Name: "lightserv",
Usage: "Maximum percentage of time allowed for serving LES requests (0-90)",
@@ -178,7 +183,7 @@ var (
LightPeersFlag = cli.IntFlag{
Name: "lightpeers",
Usage: "Maximum number of LES client peers",
- Value: 20,
+ Value: eth.DefaultConfig.LightPeers,
}
LightKDFFlag = cli.BoolFlag{
Name: "lightkdf",
@@ -292,8 +297,18 @@ var (
// Performance tuning settings
CacheFlag = cli.IntFlag{
Name: "cache",
- Usage: "Megabytes of memory allocated to internal caching (min 16MB / database forced)",
- Value: 128,
+ Usage: "Megabytes of memory allocated to internal caching",
+ Value: 1024,
+ }
+ CacheDatabaseFlag = cli.IntFlag{
+ Name: "cache.database",
+ Usage: "Percentage of cache memory allowance to use for database io",
+ Value: 75,
+ }
+ CacheGCFlag = cli.IntFlag{
+ Name: "cache.gc",
+ Usage: "Percentage of cache memory allowance to use for trie pruning",
+ Value: 25,
}
TrieCacheGenFlag = cli.IntFlag{
Name: "trie-cache-gens",
@@ -313,7 +328,7 @@ var (
TargetGasLimitFlag = cli.Uint64Flag{
Name: "targetgaslimit",
Usage: "Target gas limit sets the artificial target gas floor for the blocks to mine",
- Value: params.GenesisGasLimit.Uint64(),
+ Value: params.GenesisGasLimit,
}
EtherbaseFlag = cli.StringFlag{
Name: "etherbase",
@@ -611,7 +626,7 @@ func setBootstrapNodesV5(ctx *cli.Context, cfg *p2p.Config) {
urls = strings.Split(ctx.GlobalString(BootnodesFlag.Name), ",")
}
case ctx.GlobalBool(RinkebyFlag.Name):
- urls = params.RinkebyV5Bootnodes
+ urls = params.RinkebyBootnodes
case cfg.BootstrapNodesV5 != nil:
return // already set, don't apply defaults.
}
@@ -635,14 +650,6 @@ func setListenAddress(ctx *cli.Context, cfg *p2p.Config) {
}
}
-// setDiscoveryV5Address creates a UDP listening address string from set command
-// line flags for the V5 discovery protocol.
-func setDiscoveryV5Address(ctx *cli.Context, cfg *p2p.Config) {
- if ctx.GlobalIsSet(ListenPortFlag.Name) {
- cfg.DiscoveryV5Addr = fmt.Sprintf(":%d", ctx.GlobalInt(ListenPortFlag.Name)+1)
- }
-}
-
// setNAT creates a port mapper from command line flags.
func setNAT(ctx *cli.Context, cfg *p2p.Config) {
if ctx.GlobalIsSet(NATFlag.Name) {
@@ -721,13 +728,15 @@ func setIPC(ctx *cli.Context, cfg *node.Config) {
// makeDatabaseHandles raises out the number of allowed file handles per process
// for Geth and returns half of the allowance to assign to the database.
func makeDatabaseHandles() int {
- if err := raiseFdLimit(2048); err != nil {
- Fatalf("Failed to raise file descriptor allowance: %v", err)
- }
- limit, err := getFdLimit()
+ limit, err := fdlimit.Current()
if err != nil {
Fatalf("Failed to retrieve file descriptor allowance: %v", err)
}
+ if limit < 2048 {
+ if err := fdlimit.Raise(2048); err != nil {
+ Fatalf("Failed to raise file descriptor allowance: %v", err)
+ }
+ }
if limit > 2048 { // cap database file descriptors even if more is available
limit = 2048
}
@@ -793,24 +802,43 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
setNodeKey(ctx, cfg)
setNAT(ctx, cfg)
setListenAddress(ctx, cfg)
- setDiscoveryV5Address(ctx, cfg)
setBootstrapNodes(ctx, cfg)
setBootstrapNodesV5(ctx, cfg)
+ lightClient := ctx.GlobalBool(LightModeFlag.Name) || ctx.GlobalString(SyncModeFlag.Name) == "light"
+ lightServer := ctx.GlobalInt(LightServFlag.Name) != 0
+ lightPeers := ctx.GlobalInt(LightPeersFlag.Name)
+
if ctx.GlobalIsSet(MaxPeersFlag.Name) {
cfg.MaxPeers = ctx.GlobalInt(MaxPeersFlag.Name)
+ } else {
+ if lightServer {
+ cfg.MaxPeers += lightPeers
+ }
+ if lightClient && ctx.GlobalIsSet(LightPeersFlag.Name) && cfg.MaxPeers < lightPeers {
+ cfg.MaxPeers = lightPeers
+ }
}
+ if !(lightClient || lightServer) {
+ lightPeers = 0
+ }
+ ethPeers := cfg.MaxPeers - lightPeers
+ if lightClient {
+ ethPeers = 0
+ }
+ log.Info("Maximum peer count", "ETH", ethPeers, "LES", lightPeers, "total", cfg.MaxPeers)
+
if ctx.GlobalIsSet(MaxPendingPeersFlag.Name) {
cfg.MaxPendingPeers = ctx.GlobalInt(MaxPendingPeersFlag.Name)
}
- if ctx.GlobalIsSet(NoDiscoverFlag.Name) || ctx.GlobalBool(LightModeFlag.Name) {
+ if ctx.GlobalIsSet(NoDiscoverFlag.Name) || lightClient {
cfg.NoDiscovery = true
}
// if we're running a light client or server, force enable the v5 peer discovery
// unless it is explicitly disabled with --nodiscover note that explicitly specifying
// --v5disc overrides --nodiscover, in which case the later only disables v4 discovery
- forceV5Discovery := (ctx.GlobalBool(LightModeFlag.Name) || ctx.GlobalInt(LightServFlag.Name) > 0) && !ctx.GlobalBool(NoDiscoverFlag.Name)
+ forceV5Discovery := (lightClient || lightServer) && !ctx.GlobalBool(NoDiscoverFlag.Name)
if ctx.GlobalIsSet(DiscoveryV5Flag.Name) {
cfg.DiscoveryV5 = ctx.GlobalBool(DiscoveryV5Flag.Name)
} else if forceV5Discovery {
@@ -829,7 +857,6 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) {
// --dev mode can't use p2p networking.
cfg.MaxPeers = 0
cfg.ListenAddr = ":0"
- cfg.DiscoveryV5Addr = ":0"
cfg.NoDiscovery = true
cfg.DiscoveryV5 = false
}
@@ -1008,11 +1035,19 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *eth.Config) {
cfg.NetworkId = ctx.GlobalUint64(NetworkIdFlag.Name)
}
- if ctx.GlobalIsSet(CacheFlag.Name) {
- cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name)
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheDatabaseFlag.Name) {
+ cfg.DatabaseCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
}
cfg.DatabaseHandles = makeDatabaseHandles()
+ if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
+ Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
+ }
+ cfg.NoPruning = ctx.GlobalString(GCModeFlag.Name) == "archive"
+
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
+ cfg.TrieCache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
+ }
if ctx.GlobalIsSet(MinerThreadsFlag.Name) {
cfg.MinerThreads = ctx.GlobalInt(MinerThreadsFlag.Name)
}
@@ -1103,9 +1138,9 @@ func RegisterEthService(stack *node.Node, cfg *eth.Config) {
}
// RegisterDashboardService adds a dashboard to the stack.
-func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config) {
+func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
- return dashboard.New(cfg)
+ return dashboard.New(cfg, commit)
})
}
@@ -1138,13 +1173,13 @@ func RegisterEthStatsService(stack *node.Node, url string) {
// SetupNetwork configures the system for either the main net or some test network.
func SetupNetwork(ctx *cli.Context) {
// TODO(fjl): move target gas limit into config
- params.TargetGasLimit = new(big.Int).SetUint64(ctx.GlobalUint64(TargetGasLimitFlag.Name))
+ params.TargetGasLimit = ctx.GlobalUint64(TargetGasLimitFlag.Name)
}
// MakeChainDatabase open an LevelDB using the flags passed to the client and will hard crash if it fails.
func MakeChainDatabase(ctx *cli.Context, stack *node.Node) ethdb.Database {
var (
- cache = ctx.GlobalInt(CacheFlag.Name)
+ cache = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheDatabaseFlag.Name) / 100
handles = makeDatabaseHandles()
)
name := "chaindata"
@@ -1196,8 +1231,19 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
})
}
}
+ if gcmode := ctx.GlobalString(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
+ Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
+ }
+ cache := &core.CacheConfig{
+ Disabled: ctx.GlobalString(GCModeFlag.Name) == "archive",
+ TrieNodeLimit: eth.DefaultConfig.TrieCache,
+ TrieTimeLimit: eth.DefaultConfig.TrieTimeout,
+ }
+ if ctx.GlobalIsSet(CacheFlag.Name) || ctx.GlobalIsSet(CacheGCFlag.Name) {
+ cache.TrieNodeLimit = ctx.GlobalInt(CacheFlag.Name) * ctx.GlobalInt(CacheGCFlag.Name) / 100
+ }
vmcfg := vm.Config{EnablePreimageRecording: ctx.GlobalBool(VMEnableDebugFlag.Name)}
- chain, err = core.NewBlockChain(chainDb, config, engine, vmcfg)
+ chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg)
if err != nil {
Fatalf("Can't create BlockChain: %v", err)
}
diff --git a/cmd/wnode/main.go b/cmd/wnode/main.go
index 05e6b2908..e69b57d69 100644
--- a/cmd/wnode/main.go
+++ b/cmd/wnode/main.go
@@ -601,7 +601,7 @@ func requestExpiredMessagesLoop() {
if err != nil {
utils.Fatalf("Failed to save symmetric key for mail request: %s", err)
}
- peerID = extractIdFromEnode(*argEnode)
+ peerID = extractIDFromEnode(*argEnode)
shh.AllowP2PMessagesFromPeer(peerID)
for {
@@ -652,7 +652,7 @@ func requestExpiredMessagesLoop() {
}
}
-func extractIdFromEnode(s string) []byte {
+func extractIDFromEnode(s string) []byte {
n, err := discover.ParseNode(s)
if err != nil {
utils.Fatalf("Failed to parse enode: %s", err)