From 46de04d42cd3292bad26133a1d00905e342773dd Mon Sep 17 00:00:00 2001
From: Wei-Ning Huang
Date: Wed, 24 Oct 2018 18:59:48 +0800
Subject: Rename geth -> gdex and fix Dockerfile
---
cmd/faucet/faucet.go | 2 +-
cmd/gdex/accountcmd.go | 379 +++++++++++++++++++++++++++
cmd/gdex/accountcmd_test.go | 296 +++++++++++++++++++++
cmd/gdex/bugcmd.go | 113 ++++++++
cmd/gdex/chaincmd.go | 471 ++++++++++++++++++++++++++++++++++
cmd/gdex/config.go | 201 +++++++++++++++
cmd/gdex/consolecmd.go | 218 ++++++++++++++++
cmd/gdex/consolecmd_test.go | 163 ++++++++++++
cmd/gdex/dao_test.go | 152 +++++++++++
cmd/gdex/genesis_test.go | 110 ++++++++
cmd/gdex/main.go | 372 +++++++++++++++++++++++++++
cmd/gdex/misccmd.go | 139 ++++++++++
cmd/gdex/monitorcmd.go | 351 +++++++++++++++++++++++++
cmd/gdex/run_test.go | 98 +++++++
cmd/gdex/testdata/empty.js | 1 +
cmd/gdex/testdata/guswallet.json | 6 +
cmd/gdex/testdata/passwords.txt | 3 +
cmd/gdex/testdata/wrong-passwords.txt | 3 +
cmd/gdex/usage.go | 359 ++++++++++++++++++++++++++
cmd/geth/accountcmd.go | 379 ---------------------------
cmd/geth/accountcmd_test.go | 296 ---------------------
cmd/geth/bugcmd.go | 113 --------
cmd/geth/chaincmd.go | 471 ----------------------------------
cmd/geth/config.go | 201 ---------------
cmd/geth/consolecmd.go | 218 ----------------
cmd/geth/consolecmd_test.go | 163 ------------
cmd/geth/dao_test.go | 152 -----------
cmd/geth/genesis_test.go | 110 --------
cmd/geth/main.go | 372 ---------------------------
cmd/geth/misccmd.go | 139 ----------
cmd/geth/monitorcmd.go | 351 -------------------------
cmd/geth/run_test.go | 98 -------
cmd/geth/testdata/empty.js | 1 -
cmd/geth/testdata/guswallet.json | 6 -
cmd/geth/testdata/passwords.txt | 3 -
cmd/geth/testdata/wrong-passwords.txt | 3 -
cmd/geth/usage.go | 359 --------------------------
cmd/monkey/key | 1 +
cmd/puppeth/module_dashboard.go | 46 ++--
cmd/puppeth/module_node.go | 10 +-
cmd/puppeth/module_wallet.go | 4 +-
cmd/swarm/config.go | 2 +-
cmd/swarm/config_test.go | 12 +-
cmd/swarm/main.go | 6 +-
cmd/utils/flags.go | 10 +-
45 files changed, 3482 insertions(+), 3481 deletions(-)
create mode 100644 cmd/gdex/accountcmd.go
create mode 100644 cmd/gdex/accountcmd_test.go
create mode 100644 cmd/gdex/bugcmd.go
create mode 100644 cmd/gdex/chaincmd.go
create mode 100644 cmd/gdex/config.go
create mode 100644 cmd/gdex/consolecmd.go
create mode 100644 cmd/gdex/consolecmd_test.go
create mode 100644 cmd/gdex/dao_test.go
create mode 100644 cmd/gdex/genesis_test.go
create mode 100644 cmd/gdex/main.go
create mode 100644 cmd/gdex/misccmd.go
create mode 100644 cmd/gdex/monitorcmd.go
create mode 100644 cmd/gdex/run_test.go
create mode 100644 cmd/gdex/testdata/empty.js
create mode 100644 cmd/gdex/testdata/guswallet.json
create mode 100644 cmd/gdex/testdata/passwords.txt
create mode 100644 cmd/gdex/testdata/wrong-passwords.txt
create mode 100644 cmd/gdex/usage.go
delete mode 100644 cmd/geth/accountcmd.go
delete mode 100644 cmd/geth/accountcmd_test.go
delete mode 100644 cmd/geth/bugcmd.go
delete mode 100644 cmd/geth/chaincmd.go
delete mode 100644 cmd/geth/config.go
delete mode 100644 cmd/geth/consolecmd.go
delete mode 100644 cmd/geth/consolecmd_test.go
delete mode 100644 cmd/geth/dao_test.go
delete mode 100644 cmd/geth/genesis_test.go
delete mode 100644 cmd/geth/main.go
delete mode 100644 cmd/geth/misccmd.go
delete mode 100644 cmd/geth/monitorcmd.go
delete mode 100644 cmd/geth/run_test.go
delete mode 100644 cmd/geth/testdata/empty.js
delete mode 100644 cmd/geth/testdata/guswallet.json
delete mode 100644 cmd/geth/testdata/passwords.txt
delete mode 100644 cmd/geth/testdata/wrong-passwords.txt
delete mode 100644 cmd/geth/usage.go
create mode 100644 cmd/monkey/key
(limited to 'cmd')
diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go
index 79117f6d7..d900cadbe 100644
--- a/cmd/faucet/faucet.go
+++ b/cmd/faucet/faucet.go
@@ -215,7 +215,7 @@ type faucet struct {
func newFaucet(genesis *core.Genesis, port int, enodes []*discv5.Node, network uint64, stats string, ks *keystore.KeyStore, index []byte) (*faucet, error) {
// Assemble the raw devp2p protocol stack
stack, err := node.New(&node.Config{
- Name: "geth",
+ Name: "gdex",
Version: params.VersionWithMeta,
DataDir: filepath.Join(os.Getenv("HOME"), ".faucet"),
P2P: p2p.Config{
diff --git a/cmd/gdex/accountcmd.go b/cmd/gdex/accountcmd.go
new file mode 100644
index 000000000..d910831d7
--- /dev/null
+++ b/cmd/gdex/accountcmd.go
@@ -0,0 +1,379 @@
+// 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 .
+
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+
+ "github.com/dexon-foundation/dexon/accounts"
+ "github.com/dexon-foundation/dexon/accounts/keystore"
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/console"
+ "github.com/dexon-foundation/dexon/crypto"
+ "github.com/dexon-foundation/dexon/log"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ walletCommand = cli.Command{
+ Name: "wallet",
+ Usage: "Manage Ethereum presale wallets",
+ ArgsUsage: "",
+ Category: "ACCOUNT COMMANDS",
+ Description: `
+ gdex wallet import /path/to/my/presale.wallet
+
+will prompt for your password and imports your ether presale account.
+It can be used non-interactively with the --password option taking a
+passwordfile as argument containing the wallet password in plaintext.`,
+ Subcommands: []cli.Command{
+ {
+
+ Name: "import",
+ Usage: "Import Ethereum presale wallet",
+ ArgsUsage: "",
+ Action: utils.MigrateFlags(importWallet),
+ Category: "ACCOUNT COMMANDS",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.PasswordFileFlag,
+ utils.LightKDFFlag,
+ },
+ Description: `
+ gdex wallet [options] /path/to/my/presale.wallet
+
+will prompt for your password and imports your ether presale account.
+It can be used non-interactively with the --password option taking a
+passwordfile as argument containing the wallet password in plaintext.`,
+ },
+ },
+ }
+
+ accountCommand = cli.Command{
+ Name: "account",
+ Usage: "Manage accounts",
+ Category: "ACCOUNT COMMANDS",
+ Description: `
+
+Manage accounts, list all existing accounts, import a private key into a new
+account, create a new account or update an existing account.
+
+It supports interactive mode, when you are prompted for password as well as
+non-interactive mode where passwords are supplied via a given password file.
+Non-interactive mode is only meant for scripted use on test networks or known
+safe environments.
+
+Make sure you remember the password you gave when creating a new account (with
+either new or import). Without it you are not able to unlock your account.
+
+Note that exporting your key in unencrypted format is NOT supported.
+
+Keys are stored under /keystore.
+It is safe to transfer the entire directory or the individual keys therein
+between ethereum nodes by simply copying.
+
+Make sure you backup your keys regularly.`,
+ Subcommands: []cli.Command{
+ {
+ Name: "list",
+ Usage: "Print summary of existing accounts",
+ Action: utils.MigrateFlags(accountList),
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ },
+ Description: `
+Print a short summary of all accounts`,
+ },
+ {
+ Name: "new",
+ Usage: "Create a new account",
+ Action: utils.MigrateFlags(accountCreate),
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.PasswordFileFlag,
+ utils.LightKDFFlag,
+ },
+ Description: `
+ gdex account new
+
+Creates a new account and prints the address.
+
+The account is saved in encrypted format, you are prompted for a passphrase.
+
+You must remember this passphrase to unlock your account in the future.
+
+For non-interactive use the passphrase can be specified with the --password flag:
+
+Note, this is meant to be used for testing only, it is a bad idea to save your
+password to file or expose in any other way.
+`,
+ },
+ {
+ Name: "update",
+ Usage: "Update an existing account",
+ Action: utils.MigrateFlags(accountUpdate),
+ ArgsUsage: "",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.LightKDFFlag,
+ },
+ Description: `
+ gdex account update
+
+Update an existing account.
+
+The account is saved in the newest version in encrypted format, you are prompted
+for a passphrase to unlock the account and another to save the updated file.
+
+This same command can therefore be used to migrate an account of a deprecated
+format to the newest format or change the password for an account.
+
+For non-interactive use the passphrase can be specified with the --password flag:
+
+ gdex account update [options]
+
+Since only one password can be given, only format update can be performed,
+changing your password is only possible interactively.
+`,
+ },
+ {
+ Name: "import",
+ Usage: "Import a private key into a new account",
+ Action: utils.MigrateFlags(accountImport),
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.PasswordFileFlag,
+ utils.LightKDFFlag,
+ },
+ ArgsUsage: "",
+ Description: `
+ gdex account import
+
+Imports an unencrypted private key from and creates a new account.
+Prints the address.
+
+The keyfile is assumed to contain an unencrypted private key in hexadecimal format.
+
+The account is saved in encrypted format, you are prompted for a passphrase.
+
+You must remember this passphrase to unlock your account in the future.
+
+For non-interactive use the passphrase can be specified with the -password flag:
+
+ gdex account import [options]
+
+Note:
+As you can directly copy your encrypted accounts to another ethereum instance,
+this import mechanism is not needed when you transfer an account between
+nodes.
+`,
+ },
+ },
+ }
+)
+
+func accountList(ctx *cli.Context) error {
+ stack, _ := makeConfigNode(ctx)
+ var index int
+ for _, wallet := range stack.AccountManager().Wallets() {
+ for _, account := range wallet.Accounts() {
+ fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL)
+ index++
+ }
+ }
+ return nil
+}
+
+// tries unlocking the specified account a few times.
+func unlockAccount(ctx *cli.Context, ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) {
+ account, err := utils.MakeAddress(ks, address)
+ if err != nil {
+ utils.Fatalf("Could not list accounts: %v", err)
+ }
+ for trials := 0; trials < 3; trials++ {
+ prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3)
+ password := getPassPhrase(prompt, false, i, passwords)
+ err = ks.Unlock(account, password)
+ if err == nil {
+ log.Info("Unlocked account", "address", account.Address.Hex())
+ return account, password
+ }
+ if err, ok := err.(*keystore.AmbiguousAddrError); ok {
+ log.Info("Unlocked account", "address", account.Address.Hex())
+ return ambiguousAddrRecovery(ks, err, password), password
+ }
+ if err != keystore.ErrDecrypt {
+ // No need to prompt again if the error is not decryption-related.
+ break
+ }
+ }
+ // All trials expended to unlock account, bail out
+ utils.Fatalf("Failed to unlock account %s (%v)", address, err)
+
+ return accounts.Account{}, ""
+}
+
+// getPassPhrase retrieves the password associated with an account, either fetched
+// from a list of preloaded passphrases, or requested interactively from the user.
+func getPassPhrase(prompt string, confirmation bool, i int, passwords []string) string {
+ // If a list of passwords was supplied, retrieve from them
+ if len(passwords) > 0 {
+ if i < len(passwords) {
+ return passwords[i]
+ }
+ return passwords[len(passwords)-1]
+ }
+ // Otherwise prompt the user for the password
+ if prompt != "" {
+ fmt.Println(prompt)
+ }
+ password, 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 password != confirm {
+ utils.Fatalf("Passphrases do not match")
+ }
+ }
+ return password
+}
+
+func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account {
+ fmt.Printf("Multiple key files exist for address %x:\n", err.Addr)
+ for _, a := range err.Matches {
+ fmt.Println(" ", a.URL)
+ }
+ fmt.Println("Testing your passphrase against all of them...")
+ var match *accounts.Account
+ for _, a := range err.Matches {
+ if err := ks.Unlock(a, auth); err == nil {
+ match = &a
+ break
+ }
+ }
+ if match == nil {
+ utils.Fatalf("None of the listed files could be unlocked.")
+ }
+ fmt.Printf("Your passphrase unlocked %s\n", match.URL)
+ fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:")
+ for _, a := range err.Matches {
+ if a != *match {
+ fmt.Println(" ", a.URL)
+ }
+ }
+ return *match
+}
+
+// accountCreate creates a new account into the keystore defined by the CLI flags.
+func accountCreate(ctx *cli.Context) error {
+ cfg := gethConfig{Node: defaultNodeConfig()}
+ // Load config file.
+ if file := ctx.GlobalString(configFileFlag.Name); file != "" {
+ if err := loadConfig(file, &cfg); err != nil {
+ utils.Fatalf("%v", err)
+ }
+ }
+ utils.SetNodeConfig(ctx, &cfg.Node)
+ scryptN, scryptP, keydir, err := cfg.Node.AccountConfig()
+
+ if err != nil {
+ utils.Fatalf("Failed to read configuration: %v", err)
+ }
+
+ password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
+
+ address, err := keystore.StoreKey(keydir, password, scryptN, scryptP)
+
+ if err != nil {
+ utils.Fatalf("Failed to create account: %v", err)
+ }
+ fmt.Printf("Address: {%x}\n", address)
+ return nil
+}
+
+// accountUpdate transitions an account from a previous format to the current
+// one, also providing the possibility to change the pass-phrase.
+func accountUpdate(ctx *cli.Context) error {
+ if len(ctx.Args()) == 0 {
+ utils.Fatalf("No accounts specified to update")
+ }
+ stack, _ := makeConfigNode(ctx)
+ ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
+
+ for _, addr := range ctx.Args() {
+ account, oldPassword := unlockAccount(ctx, ks, addr, 0, nil)
+ newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil)
+ if err := ks.Update(account, oldPassword, newPassword); err != nil {
+ utils.Fatalf("Could not update the account: %v", err)
+ }
+ }
+ return nil
+}
+
+func importWallet(ctx *cli.Context) error {
+ keyfile := ctx.Args().First()
+ if len(keyfile) == 0 {
+ utils.Fatalf("keyfile must be given as argument")
+ }
+ keyJSON, err := ioutil.ReadFile(keyfile)
+ if err != nil {
+ utils.Fatalf("Could not read wallet file: %v", err)
+ }
+
+ stack, _ := makeConfigNode(ctx)
+ passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx))
+
+ ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
+ acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
+ if err != nil {
+ utils.Fatalf("%v", err)
+ }
+ fmt.Printf("Address: {%x}\n", acct.Address)
+ return nil
+}
+
+func accountImport(ctx *cli.Context) error {
+ keyfile := ctx.Args().First()
+ if len(keyfile) == 0 {
+ utils.Fatalf("keyfile must be given as argument")
+ }
+ key, err := crypto.LoadECDSA(keyfile)
+ if err != nil {
+ utils.Fatalf("Failed to load the private key: %v", err)
+ }
+ stack, _ := makeConfigNode(ctx)
+ passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
+
+ ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
+ acct, err := ks.ImportECDSA(key, passphrase)
+ if err != nil {
+ utils.Fatalf("Could not create the account: %v", err)
+ }
+ fmt.Printf("Address: {%x}\n", acct.Address)
+ return nil
+}
diff --git a/cmd/gdex/accountcmd_test.go b/cmd/gdex/accountcmd_test.go
new file mode 100644
index 000000000..38e21eaca
--- /dev/null
+++ b/cmd/gdex/accountcmd_test.go
@@ -0,0 +1,296 @@
+// 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 .
+
+package main
+
+import (
+ "io/ioutil"
+ "path/filepath"
+ "runtime"
+ "strings"
+ "testing"
+
+ "github.com/cespare/cp"
+)
+
+// These tests are 'smoke tests' for the account related
+// subcommands and flags.
+//
+// For most tests, the test files from package accounts
+// are copied into a temporary keystore directory.
+
+func tmpDatadirWithKeystore(t *testing.T) string {
+ datadir := tmpdir(t)
+ keystore := filepath.Join(datadir, "keystore")
+ source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore")
+ if err := cp.CopyAll(keystore, source); err != nil {
+ t.Fatal(err)
+ }
+ return datadir
+}
+
+func TestAccountListEmpty(t *testing.T) {
+ gdex := runGeth(t, "account", "list")
+ gdex.ExpectExit()
+}
+
+func TestAccountList(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t, "account", "list", "--datadir", datadir)
+ defer gdex.ExpectExit()
+ if runtime.GOOS == "windows" {
+ gdex.Expect(`
+Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
+Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa
+Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz
+`)
+ } else {
+ gdex.Expect(`
+Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
+Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
+Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz
+`)
+ }
+}
+
+func TestAccountNew(t *testing.T) {
+ gdex := runGeth(t, "account", "new", "--lightkdf")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+Your new account is locked with a password. Please give a password. Do not forget this password.
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+Repeat passphrase: {{.InputLine "foobar"}}
+`)
+ gdex.ExpectRegexp(`Address: \{[0-9a-f]{40}\}\n`)
+}
+
+func TestAccountNewBadRepeat(t *testing.T) {
+ gdex := runGeth(t, "account", "new", "--lightkdf")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+Your new account is locked with a password. Please give a password. Do not forget this password.
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "something"}}
+Repeat passphrase: {{.InputLine "something else"}}
+Fatal: Passphrases do not match
+`)
+}
+
+func TestAccountUpdate(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t, "account", "update",
+ "--datadir", datadir, "--lightkdf",
+ "f466859ead1932d743d622cb74fc058882e8648a")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+Please give a new password. Do not forget this password.
+Passphrase: {{.InputLine "foobar2"}}
+Repeat passphrase: {{.InputLine "foobar2"}}
+`)
+}
+
+func TestWalletImport(t *testing.T) {
+ gdex := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foo"}}
+Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
+`)
+
+ files, err := ioutil.ReadDir(filepath.Join(gdex.Datadir, "keystore"))
+ if len(files) != 1 {
+ t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err)
+ }
+}
+
+func TestWalletImportBadPassword(t *testing.T) {
+ gdex := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "wrong"}}
+Fatal: could not decrypt key with given passphrase
+`)
+}
+
+func TestUnlockFlag(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t,
+ "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
+ "js", "testdata/empty.js")
+ gdex.Expect(`
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+`)
+ gdex.ExpectExit()
+
+ wantMessages := []string{
+ "Unlocked account",
+ "=0xf466859eAD1932D743d622CB74FC058882E8648A",
+ }
+ for _, m := range wantMessages {
+ if !strings.Contains(gdex.StderrText(), m) {
+ t.Errorf("stderr text does not contain %q", m)
+ }
+ }
+}
+
+func TestUnlockFlagWrongPassword(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t,
+ "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "wrong1"}}
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
+Passphrase: {{.InputLine "wrong2"}}
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
+Passphrase: {{.InputLine "wrong3"}}
+Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given passphrase)
+`)
+}
+
+// https://github.com/dexon-foundation/dexon/issues/1785
+func TestUnlockFlagMultiIndex(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t,
+ "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--unlock", "0,2",
+ "js", "testdata/empty.js")
+ gdex.Expect(`
+Unlocking account 0 | Attempt 1/3
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+Unlocking account 2 | Attempt 1/3
+Passphrase: {{.InputLine "foobar"}}
+`)
+ gdex.ExpectExit()
+
+ wantMessages := []string{
+ "Unlocked account",
+ "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
+ "=0x289d485D9771714CCe91D3393D764E1311907ACc",
+ }
+ for _, m := range wantMessages {
+ if !strings.Contains(gdex.StderrText(), m) {
+ t.Errorf("stderr text does not contain %q", m)
+ }
+ }
+}
+
+func TestUnlockFlagPasswordFile(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t,
+ "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--password", "testdata/passwords.txt", "--unlock", "0,2",
+ "js", "testdata/empty.js")
+ gdex.ExpectExit()
+
+ wantMessages := []string{
+ "Unlocked account",
+ "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
+ "=0x289d485D9771714CCe91D3393D764E1311907ACc",
+ }
+ for _, m := range wantMessages {
+ if !strings.Contains(gdex.StderrText(), m) {
+ t.Errorf("stderr text does not contain %q", m)
+ }
+ }
+}
+
+func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
+ datadir := tmpDatadirWithKeystore(t)
+ gdex := runGeth(t,
+ "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
+ defer gdex.ExpectExit()
+ gdex.Expect(`
+Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase)
+`)
+}
+
+func TestUnlockFlagAmbiguous(t *testing.T) {
+ store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
+ gdex := runGeth(t,
+ "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
+ "js", "testdata/empty.js")
+ defer gdex.ExpectExit()
+
+ // Helper for the expect template, returns absolute keystore path.
+ gdex.SetTemplateFunc("keypath", func(file string) string {
+ abs, _ := filepath.Abs(filepath.Join(store, file))
+ return abs
+ })
+ gdex.Expect(`
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "foobar"}}
+Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
+ keystore://{{keypath "1"}}
+ keystore://{{keypath "2"}}
+Testing your passphrase against all of them...
+Your passphrase unlocked keystore://{{keypath "1"}}
+In order to avoid this warning, you need to remove the following duplicate key files:
+ keystore://{{keypath "2"}}
+`)
+ gdex.ExpectExit()
+
+ wantMessages := []string{
+ "Unlocked account",
+ "=0xf466859eAD1932D743d622CB74FC058882E8648A",
+ }
+ for _, m := range wantMessages {
+ if !strings.Contains(gdex.StderrText(), m) {
+ t.Errorf("stderr text does not contain %q", m)
+ }
+ }
+}
+
+func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
+ store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
+ gdex := runGeth(t,
+ "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
+ "--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
+ defer gdex.ExpectExit()
+
+ // Helper for the expect template, returns absolute keystore path.
+ gdex.SetTemplateFunc("keypath", func(file string) string {
+ abs, _ := filepath.Abs(filepath.Join(store, file))
+ return abs
+ })
+ gdex.Expect(`
+Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
+!! Unsupported terminal, password will be echoed.
+Passphrase: {{.InputLine "wrong"}}
+Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
+ keystore://{{keypath "1"}}
+ keystore://{{keypath "2"}}
+Testing your passphrase against all of them...
+Fatal: None of the listed files could be unlocked.
+`)
+ gdex.ExpectExit()
+}
diff --git a/cmd/gdex/bugcmd.go b/cmd/gdex/bugcmd.go
new file mode 100644
index 000000000..00c2f17e7
--- /dev/null
+++ b/cmd/gdex/bugcmd.go
@@ -0,0 +1,113 @@
+// 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 .
+
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "net/url"
+ "os/exec"
+ "runtime"
+ "strings"
+
+ "github.com/dexon-foundation/dexon/cmd/internal/browser"
+ "github.com/dexon-foundation/dexon/params"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ cli "gopkg.in/urfave/cli.v1"
+)
+
+var bugCommand = cli.Command{
+ Action: utils.MigrateFlags(reportBug),
+ Name: "bug",
+ Usage: "opens a window to report a bug on the gdex repo",
+ ArgsUsage: " ",
+ Category: "MISCELLANEOUS COMMANDS",
+}
+
+const issueURL = "https://github.com/dexon-foundation/dexon/issues/new"
+
+// reportBug reports a bug by opening a new URL to the go-ethereum GH issue
+// tracker and setting default values as the issue body.
+func reportBug(ctx *cli.Context) error {
+ // execute template and write contents to buff
+ var buff bytes.Buffer
+
+ fmt.Fprintln(&buff, "#### System information")
+ fmt.Fprintln(&buff)
+ fmt.Fprintln(&buff, "Version:", params.VersionWithMeta)
+ fmt.Fprintln(&buff, "Go Version:", runtime.Version())
+ fmt.Fprintln(&buff, "OS:", runtime.GOOS)
+ printOSDetails(&buff)
+ fmt.Fprintln(&buff, header)
+
+ // open a new GH issue
+ if !browser.Open(issueURL + "?body=" + url.QueryEscape(buff.String())) {
+ fmt.Printf("Please file a new issue at %s using this template:\n\n%s", issueURL, buff.String())
+ }
+ return nil
+}
+
+// copied from the Go source. Copyright 2017 The Go Authors
+func printOSDetails(w io.Writer) {
+ switch runtime.GOOS {
+ case "darwin":
+ printCmdOut(w, "uname -v: ", "uname", "-v")
+ printCmdOut(w, "", "sw_vers")
+ case "linux":
+ printCmdOut(w, "uname -sr: ", "uname", "-sr")
+ printCmdOut(w, "", "lsb_release", "-a")
+ case "openbsd", "netbsd", "freebsd", "dragonfly":
+ printCmdOut(w, "uname -v: ", "uname", "-v")
+ case "solaris":
+ out, err := ioutil.ReadFile("/etc/release")
+ if err == nil {
+ fmt.Fprintf(w, "/etc/release: %s\n", out)
+ } else {
+ fmt.Printf("failed to read /etc/release: %v\n", err)
+ }
+ }
+}
+
+// printCmdOut prints the output of running the given command.
+// It ignores failures; 'go bug' is best effort.
+//
+// copied from the Go source. Copyright 2017 The Go Authors
+func printCmdOut(w io.Writer, prefix, path string, args ...string) {
+ cmd := exec.Command(path, args...)
+ out, err := cmd.Output()
+ if err != nil {
+ fmt.Printf("%s %s: %v\n", path, strings.Join(args, " "), err)
+ return
+ }
+ fmt.Fprintf(w, "%s%s\n", prefix, bytes.TrimSpace(out))
+}
+
+const header = `
+#### Expected behaviour
+
+
+#### Actual behaviour
+
+
+#### Steps to reproduce the behaviour
+
+
+#### Backtrace
+`
diff --git a/cmd/gdex/chaincmd.go b/cmd/gdex/chaincmd.go
new file mode 100644
index 000000000..ce4216a94
--- /dev/null
+++ b/cmd/gdex/chaincmd.go
@@ -0,0 +1,471 @@
+// Copyright 2015 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 .
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "os"
+ "runtime"
+ "strconv"
+ "sync/atomic"
+ "time"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/console"
+ "github.com/dexon-foundation/dexon/core"
+ "github.com/dexon-foundation/dexon/core/state"
+ "github.com/dexon-foundation/dexon/core/types"
+ "github.com/dexon-foundation/dexon/eth/downloader"
+ "github.com/dexon-foundation/dexon/ethdb"
+ "github.com/dexon-foundation/dexon/event"
+ "github.com/dexon-foundation/dexon/log"
+ "github.com/dexon-foundation/dexon/trie"
+ "github.com/syndtr/goleveldb/leveldb/util"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ initCommand = cli.Command{
+ Action: utils.MigrateFlags(initGenesis),
+ Name: "init",
+ Usage: "Bootstrap and initialize a new genesis block",
+ ArgsUsage: "",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+The init command initializes a new genesis block and definition for the network.
+This is a destructive action and changes the network in which you will be
+participating.
+
+It expects the genesis file as argument.`,
+ }
+ importCommand = cli.Command{
+ Action: utils.MigrateFlags(importChain),
+ Name: "import",
+ Usage: "Import a blockchain file",
+ ArgsUsage: " ( ... ) ",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.CacheFlag,
+ utils.SyncModeFlag,
+ utils.GCModeFlag,
+ utils.CacheDatabaseFlag,
+ utils.CacheGCFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+The import command imports blocks from an RLP-encoded form. The form can be one file
+with several RLP-encoded blocks, or several files can be used.
+
+If only one file is used, import error will result in failure. If several files are used,
+processing will proceed even if an individual RLP-file import failure occurs.`,
+ }
+ exportCommand = cli.Command{
+ Action: utils.MigrateFlags(exportChain),
+ Name: "export",
+ Usage: "Export blockchain into file",
+ ArgsUsage: " [ ]",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.CacheFlag,
+ utils.SyncModeFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+Requires a first argument of the file to write to.
+Optional second and third arguments control the first and
+last block to write. In this mode, the file will be appended
+if already existing. If the file ends with .gz, the output will
+be gzipped.`,
+ }
+ importPreimagesCommand = cli.Command{
+ Action: utils.MigrateFlags(importPreimages),
+ Name: "import-preimages",
+ Usage: "Import the preimage database from an RLP stream",
+ ArgsUsage: "",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.CacheFlag,
+ utils.SyncModeFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+ The import-preimages command imports hash preimages from an RLP encoded stream.`,
+ }
+ exportPreimagesCommand = cli.Command{
+ Action: utils.MigrateFlags(exportPreimages),
+ Name: "export-preimages",
+ Usage: "Export the preimage database into an RLP stream",
+ ArgsUsage: "",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.CacheFlag,
+ utils.SyncModeFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+The export-preimages command export hash preimages to an RLP encoded stream`,
+ }
+ copydbCommand = cli.Command{
+ Action: utils.MigrateFlags(copyDb),
+ Name: "copydb",
+ Usage: "Create a local chain from a target chaindata folder",
+ ArgsUsage: "",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.CacheFlag,
+ utils.SyncModeFlag,
+ utils.FakePoWFlag,
+ utils.TestnetFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+The first argument must be the directory containing the blockchain to download from`,
+ }
+ removedbCommand = cli.Command{
+ Action: utils.MigrateFlags(removeDB),
+ Name: "removedb",
+ Usage: "Remove blockchain and state databases",
+ ArgsUsage: " ",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+Remove blockchain and state databases`,
+ }
+ dumpCommand = cli.Command{
+ Action: utils.MigrateFlags(dump),
+ Name: "dump",
+ Usage: "Dump a specific block from storage",
+ ArgsUsage: "[ | ]...",
+ Flags: []cli.Flag{
+ utils.DataDirFlag,
+ utils.CacheFlag,
+ utils.SyncModeFlag,
+ },
+ Category: "BLOCKCHAIN COMMANDS",
+ Description: `
+The arguments are interpreted as block numbers or hashes.
+Use "ethereum dump 0" to dump the genesis block.`,
+ }
+)
+
+// initGenesis will initialise the given JSON format genesis file and writes it as
+// the zero'd block (i.e. genesis) or will fail hard if it can't succeed.
+func initGenesis(ctx *cli.Context) error {
+ // Make sure we have a valid genesis JSON
+ genesisPath := ctx.Args().First()
+ if len(genesisPath) == 0 {
+ utils.Fatalf("Must supply path to genesis JSON file")
+ }
+ file, err := os.Open(genesisPath)
+ if err != nil {
+ utils.Fatalf("Failed to read genesis file: %v", err)
+ }
+ defer file.Close()
+
+ genesis := new(core.Genesis)
+ if err := json.NewDecoder(file).Decode(genesis); err != nil {
+ utils.Fatalf("invalid genesis file: %v", err)
+ }
+ // Open an initialise both full and light databases
+ stack := makeFullNode(ctx)
+ for _, name := range []string{"chaindata", "lightchaindata"} {
+ chaindb, err := stack.OpenDatabase(name, 0, 0)
+ if err != nil {
+ utils.Fatalf("Failed to open database: %v", err)
+ }
+ _, hash, err := core.SetupGenesisBlock(chaindb, genesis)
+ if err != nil {
+ utils.Fatalf("Failed to write genesis block: %v", err)
+ }
+ log.Info("Successfully wrote genesis state", "database", name, "hash", hash)
+ }
+ return nil
+}
+
+func importChain(ctx *cli.Context) error {
+ if len(ctx.Args()) < 1 {
+ utils.Fatalf("This command requires an argument.")
+ }
+ stack := makeFullNode(ctx)
+ chain, chainDb := utils.MakeChain(ctx, stack)
+ defer chainDb.Close()
+
+ // Start periodically gathering memory profiles
+ var peakMemAlloc, peakMemSys uint64
+ go func() {
+ stats := new(runtime.MemStats)
+ for {
+ runtime.ReadMemStats(stats)
+ if atomic.LoadUint64(&peakMemAlloc) < stats.Alloc {
+ atomic.StoreUint64(&peakMemAlloc, stats.Alloc)
+ }
+ if atomic.LoadUint64(&peakMemSys) < stats.Sys {
+ atomic.StoreUint64(&peakMemSys, stats.Sys)
+ }
+ time.Sleep(5 * time.Second)
+ }
+ }()
+ // Import the chain
+ start := time.Now()
+
+ if len(ctx.Args()) == 1 {
+ if err := utils.ImportChain(chain, ctx.Args().First()); err != nil {
+ log.Error("Import error", "err", err)
+ }
+ } else {
+ for _, arg := range ctx.Args() {
+ if err := utils.ImportChain(chain, arg); err != nil {
+ log.Error("Import error", "file", arg, "err", err)
+ }
+ }
+ }
+ chain.Stop()
+ fmt.Printf("Import done in %v.\n\n", time.Since(start))
+
+ // Output pre-compaction stats mostly to see the import trashing
+ db := chainDb.(*ethdb.LDBDatabase)
+
+ stats, err := db.LDB().GetProperty("leveldb.stats")
+ if err != nil {
+ utils.Fatalf("Failed to read database stats: %v", err)
+ }
+ fmt.Println(stats)
+
+ ioStats, err := db.LDB().GetProperty("leveldb.iostats")
+ if err != nil {
+ utils.Fatalf("Failed to read database iostats: %v", err)
+ }
+ fmt.Println(ioStats)
+
+ fmt.Printf("Trie cache misses: %d\n", trie.CacheMisses())
+ fmt.Printf("Trie cache unloads: %d\n\n", trie.CacheUnloads())
+
+ // Print the memory statistics used by the importing
+ mem := new(runtime.MemStats)
+ runtime.ReadMemStats(mem)
+
+ fmt.Printf("Object memory: %.3f MB current, %.3f MB peak\n", float64(mem.Alloc)/1024/1024, float64(atomic.LoadUint64(&peakMemAlloc))/1024/1024)
+ fmt.Printf("System memory: %.3f MB current, %.3f MB peak\n", float64(mem.Sys)/1024/1024, float64(atomic.LoadUint64(&peakMemSys))/1024/1024)
+ fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000)
+ fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs))
+
+ if ctx.GlobalIsSet(utils.NoCompactionFlag.Name) {
+ return nil
+ }
+
+ // Compact the entire database to more accurately measure disk io and print the stats
+ start = time.Now()
+ fmt.Println("Compacting entire database...")
+ if err = db.LDB().CompactRange(util.Range{}); err != nil {
+ utils.Fatalf("Compaction failed: %v", err)
+ }
+ fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
+
+ stats, err = db.LDB().GetProperty("leveldb.stats")
+ if err != nil {
+ utils.Fatalf("Failed to read database stats: %v", err)
+ }
+ fmt.Println(stats)
+
+ ioStats, err = db.LDB().GetProperty("leveldb.iostats")
+ if err != nil {
+ utils.Fatalf("Failed to read database iostats: %v", err)
+ }
+ fmt.Println(ioStats)
+
+ return nil
+}
+
+func exportChain(ctx *cli.Context) error {
+ if len(ctx.Args()) < 1 {
+ utils.Fatalf("This command requires an argument.")
+ }
+ stack := makeFullNode(ctx)
+ chain, _ := utils.MakeChain(ctx, stack)
+ start := time.Now()
+
+ var err error
+ fp := ctx.Args().First()
+ if len(ctx.Args()) < 3 {
+ err = utils.ExportChain(chain, fp)
+ } else {
+ // This can be improved to allow for numbers larger than 9223372036854775807
+ first, ferr := strconv.ParseInt(ctx.Args().Get(1), 10, 64)
+ last, lerr := strconv.ParseInt(ctx.Args().Get(2), 10, 64)
+ if ferr != nil || lerr != nil {
+ utils.Fatalf("Export error in parsing parameters: block number not an integer\n")
+ }
+ if first < 0 || last < 0 {
+ utils.Fatalf("Export error: block number must be greater than 0\n")
+ }
+ err = utils.ExportAppendChain(chain, fp, uint64(first), uint64(last))
+ }
+
+ if err != nil {
+ utils.Fatalf("Export error: %v\n", err)
+ }
+ fmt.Printf("Export done in %v\n", time.Since(start))
+ return nil
+}
+
+// importPreimages imports preimage data from the specified file.
+func importPreimages(ctx *cli.Context) error {
+ if len(ctx.Args()) < 1 {
+ utils.Fatalf("This command requires an argument.")
+ }
+ stack := makeFullNode(ctx)
+ diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase)
+
+ start := time.Now()
+ if err := utils.ImportPreimages(diskdb, ctx.Args().First()); err != nil {
+ utils.Fatalf("Import error: %v\n", err)
+ }
+ fmt.Printf("Import done in %v\n", time.Since(start))
+ return nil
+}
+
+// exportPreimages dumps the preimage data to specified json file in streaming way.
+func exportPreimages(ctx *cli.Context) error {
+ if len(ctx.Args()) < 1 {
+ utils.Fatalf("This command requires an argument.")
+ }
+ stack := makeFullNode(ctx)
+ diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase)
+
+ start := time.Now()
+ if err := utils.ExportPreimages(diskdb, ctx.Args().First()); err != nil {
+ utils.Fatalf("Export error: %v\n", err)
+ }
+ fmt.Printf("Export done in %v\n", time.Since(start))
+ return nil
+}
+
+func copyDb(ctx *cli.Context) error {
+ // Ensure we have a source chain directory to copy
+ if len(ctx.Args()) != 1 {
+ utils.Fatalf("Source chaindata directory path argument missing")
+ }
+ // Initialize a new chain for the running node to sync into
+ stack := makeFullNode(ctx)
+ chain, chainDb := utils.MakeChain(ctx, stack)
+
+ syncmode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode)
+ dl := downloader.New(syncmode, chainDb, new(event.TypeMux), chain, nil, nil)
+
+ // Create a source peer to satisfy downloader requests from
+ db, err := ethdb.NewLDBDatabase(ctx.Args().First(), ctx.GlobalInt(utils.CacheFlag.Name), 256)
+ if err != nil {
+ return err
+ }
+ hc, err := core.NewHeaderChain(db, chain.Config(), chain.Engine(), func() bool { return false })
+ if err != nil {
+ return err
+ }
+ peer := downloader.NewFakePeer("local", db, hc, dl)
+ if err = dl.RegisterPeer("local", 63, peer); err != nil {
+ return err
+ }
+ // Synchronise with the simulated peer
+ start := time.Now()
+
+ currentHeader := hc.CurrentHeader()
+ if err = dl.Synchronise("local", currentHeader.Hash(), hc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()), syncmode); err != nil {
+ return err
+ }
+ for dl.Synchronising() {
+ time.Sleep(10 * time.Millisecond)
+ }
+ fmt.Printf("Database copy done in %v\n", time.Since(start))
+
+ // Compact the entire database to remove any sync overhead
+ start = time.Now()
+ fmt.Println("Compacting entire database...")
+ if err = chainDb.(*ethdb.LDBDatabase).LDB().CompactRange(util.Range{}); err != nil {
+ utils.Fatalf("Compaction failed: %v", err)
+ }
+ fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
+
+ return nil
+}
+
+func removeDB(ctx *cli.Context) error {
+ stack, _ := makeConfigNode(ctx)
+
+ for _, name := range []string{"chaindata", "lightchaindata"} {
+ // Ensure the database exists in the first place
+ logger := log.New("database", name)
+
+ dbdir := stack.ResolvePath(name)
+ if !common.FileExist(dbdir) {
+ logger.Info("Database doesn't exist, skipping", "path", dbdir)
+ continue
+ }
+ // Confirm removal and execute
+ fmt.Println(dbdir)
+ confirm, err := console.Stdin.PromptConfirm("Remove this database?")
+ switch {
+ case err != nil:
+ utils.Fatalf("%v", err)
+ case !confirm:
+ logger.Warn("Database deletion aborted")
+ default:
+ start := time.Now()
+ os.RemoveAll(dbdir)
+ logger.Info("Database successfully deleted", "elapsed", common.PrettyDuration(time.Since(start)))
+ }
+ }
+ return nil
+}
+
+func dump(ctx *cli.Context) error {
+ stack := makeFullNode(ctx)
+ chain, chainDb := utils.MakeChain(ctx, stack)
+ for _, arg := range ctx.Args() {
+ var block *types.Block
+ if hashish(arg) {
+ block = chain.GetBlockByHash(common.HexToHash(arg))
+ } else {
+ num, _ := strconv.Atoi(arg)
+ block = chain.GetBlockByNumber(uint64(num))
+ }
+ if block == nil {
+ fmt.Println("{}")
+ utils.Fatalf("block not found")
+ } else {
+ state, err := state.New(block.Root(), state.NewDatabase(chainDb))
+ if err != nil {
+ utils.Fatalf("could not create new state: %v", err)
+ }
+ fmt.Printf("%s\n", state.Dump())
+ }
+ }
+ chainDb.Close()
+ return nil
+}
+
+// hashish returns true for strings that look like hashes.
+func hashish(x string) bool {
+ _, err := strconv.Atoi(x)
+ return err != nil
+}
diff --git a/cmd/gdex/config.go b/cmd/gdex/config.go
new file mode 100644
index 000000000..d9899409d
--- /dev/null
+++ b/cmd/gdex/config.go
@@ -0,0 +1,201 @@
+// 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 .
+
+package main
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "reflect"
+ "unicode"
+
+ cli "gopkg.in/urfave/cli.v1"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/dashboard"
+ "github.com/dexon-foundation/dexon/dex"
+ "github.com/dexon-foundation/dexon/node"
+ "github.com/dexon-foundation/dexon/params"
+ whisper "github.com/dexon-foundation/dexon/whisper/whisperv6"
+ "github.com/naoina/toml"
+)
+
+var (
+ dumpConfigCommand = cli.Command{
+ Action: utils.MigrateFlags(dumpConfig),
+ Name: "dumpconfig",
+ Usage: "Show configuration values",
+ ArgsUsage: "",
+ Flags: append(append(nodeFlags, rpcFlags...), whisperFlags...),
+ Category: "MISCELLANEOUS COMMANDS",
+ Description: `The dumpconfig command shows configuration values.`,
+ }
+
+ configFileFlag = cli.StringFlag{
+ Name: "config",
+ Usage: "TOML configuration file",
+ }
+)
+
+// These settings ensure that TOML keys use the same names as Go struct fields.
+var tomlSettings = toml.Config{
+ NormFieldName: func(rt reflect.Type, key string) string {
+ return key
+ },
+ FieldToKey: func(rt reflect.Type, field string) string {
+ return field
+ },
+ MissingField: func(rt reflect.Type, field string) error {
+ link := ""
+ if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
+ link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name())
+ }
+ return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link)
+ },
+}
+
+type ethstatsConfig struct {
+ URL string `toml:",omitempty"`
+}
+
+type gethConfig struct {
+ Dex dex.Config
+ Shh whisper.Config
+ Node node.Config
+ Ethstats ethstatsConfig
+ Dashboard dashboard.Config
+}
+
+func loadConfig(file string, cfg *gethConfig) error {
+ f, err := os.Open(file)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+
+ err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg)
+ // Add file name to errors that have a line number.
+ if _, ok := err.(*toml.LineError); ok {
+ err = errors.New(file + ", " + err.Error())
+ }
+ return err
+}
+
+func defaultNodeConfig() node.Config {
+ cfg := node.DefaultConfig
+ cfg.Name = clientIdentifier
+ cfg.Version = params.VersionWithCommit(gitCommit)
+ cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh")
+ cfg.WSModules = append(cfg.WSModules, "eth", "shh")
+ cfg.IPCPath = "gdex.ipc"
+ return cfg
+}
+
+func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
+ // Load defaults.
+ cfg := gethConfig{
+ Dex: dex.DefaultConfig,
+ Shh: whisper.DefaultConfig,
+ Node: defaultNodeConfig(),
+ Dashboard: dashboard.DefaultConfig,
+ }
+
+ // Load config file.
+ if file := ctx.GlobalString(configFileFlag.Name); file != "" {
+ if err := loadConfig(file, &cfg); err != nil {
+ utils.Fatalf("%v", err)
+ }
+ }
+
+ // Apply flags.
+ utils.SetNodeConfig(ctx, &cfg.Node)
+ stack, err := node.New(&cfg.Node)
+ if err != nil {
+ utils.Fatalf("Failed to create the protocol stack: %v", err)
+ }
+ utils.SetDexConfig(ctx, stack, &cfg.Dex)
+ if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) {
+ cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name)
+ }
+
+ utils.SetShhConfig(ctx, stack, &cfg.Shh)
+ utils.SetDashboardConfig(ctx, &cfg.Dashboard)
+
+ return stack, cfg
+}
+
+// enableWhisper returns true in case one of the whisper flags is set.
+func enableWhisper(ctx *cli.Context) bool {
+ for _, flag := range whisperFlags {
+ if ctx.GlobalIsSet(flag.GetName()) {
+ return true
+ }
+ }
+ return false
+}
+
+func makeFullNode(ctx *cli.Context) *node.Node {
+ stack, cfg := makeConfigNode(ctx)
+
+ utils.RegisterDexService(stack, &cfg.Dex)
+
+ if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
+ 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)
+ shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name)
+ if shhEnabled || shhAutoEnabled {
+ if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) {
+ cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name))
+ }
+ if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) {
+ cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name)
+ }
+ if ctx.GlobalIsSet(utils.WhisperRestrictConnectionBetweenLightClientsFlag.Name) {
+ cfg.Shh.RestrictConnectionBetweenLightClients = true
+ }
+ utils.RegisterShhService(stack, &cfg.Shh)
+ }
+
+ // Add the Ethereum Stats daemon if requested.
+ if cfg.Ethstats.URL != "" {
+ utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
+ }
+ return stack
+}
+
+// dumpConfig is the dumpconfig command.
+func dumpConfig(ctx *cli.Context) error {
+ _, cfg := makeConfigNode(ctx)
+ comment := ""
+
+ if cfg.Dex.Genesis != nil {
+ cfg.Dex.Genesis = nil
+ comment += "# Note: this config doesn't contain the genesis block.\n\n"
+ }
+
+ out, err := tomlSettings.Marshal(&cfg)
+ if err != nil {
+ return err
+ }
+ io.WriteString(os.Stdout, comment)
+ os.Stdout.Write(out)
+ return nil
+}
diff --git a/cmd/gdex/consolecmd.go b/cmd/gdex/consolecmd.go
new file mode 100644
index 000000000..9915e1ee0
--- /dev/null
+++ b/cmd/gdex/consolecmd.go
@@ -0,0 +1,218 @@
+// 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 .
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "os/signal"
+ "path/filepath"
+ "strings"
+ "syscall"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/console"
+ "github.com/dexon-foundation/dexon/node"
+ "github.com/dexon-foundation/dexon/rpc"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag}
+
+ consoleCommand = cli.Command{
+ Action: utils.MigrateFlags(localConsole),
+ Name: "console",
+ Usage: "Start an interactive JavaScript environment",
+ Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), whisperFlags...),
+ Category: "CONSOLE COMMANDS",
+ Description: `
+The Geth console is an interactive shell for the JavaScript runtime environment
+which exposes a node admin interface as well as the Ðapp JavaScript API.
+See https://github.com/dexon-foundation/dexon/wiki/JavaScript-Console.`,
+ }
+
+ attachCommand = cli.Command{
+ Action: utils.MigrateFlags(remoteConsole),
+ Name: "attach",
+ Usage: "Start an interactive JavaScript environment (connect to node)",
+ ArgsUsage: "[endpoint]",
+ Flags: append(consoleFlags, utils.DataDirFlag),
+ Category: "CONSOLE COMMANDS",
+ Description: `
+The Geth console is an interactive shell for the JavaScript runtime environment
+which exposes a node admin interface as well as the Ðapp JavaScript API.
+See https://github.com/dexon-foundation/dexon/wiki/JavaScript-Console.
+This command allows to open a console on a running gdex node.`,
+ }
+
+ javascriptCommand = cli.Command{
+ Action: utils.MigrateFlags(ephemeralConsole),
+ Name: "js",
+ Usage: "Execute the specified JavaScript files",
+ ArgsUsage: " [jsfile...]",
+ Flags: append(nodeFlags, consoleFlags...),
+ Category: "CONSOLE COMMANDS",
+ Description: `
+The JavaScript VM exposes a node admin interface as well as the Ðapp
+JavaScript API. See https://github.com/dexon-foundation/dexon/wiki/JavaScript-Console`,
+ }
+)
+
+// localConsole starts a new gdex node, attaching a JavaScript console to it at the
+// same time.
+func localConsole(ctx *cli.Context) error {
+ // Create and start the node based on the CLI flags
+ node := makeFullNode(ctx)
+ startNode(ctx, node)
+ defer node.Stop()
+
+ // Attach to the newly started node and start the JavaScript console
+ client, err := node.Attach()
+ if err != nil {
+ utils.Fatalf("Failed to attach to the inproc gdex: %v", err)
+ }
+ config := console.Config{
+ DataDir: utils.MakeDataDir(ctx),
+ DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
+ Client: client,
+ Preload: utils.MakeConsolePreloads(ctx),
+ }
+
+ console, err := console.New(config)
+ if err != nil {
+ utils.Fatalf("Failed to start the JavaScript console: %v", err)
+ }
+ defer console.Stop(false)
+
+ // If only a short execution was requested, evaluate and return
+ if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
+ console.Evaluate(script)
+ return nil
+ }
+ // Otherwise print the welcome screen and enter interactive mode
+ console.Welcome()
+ console.Interactive()
+
+ return nil
+}
+
+// remoteConsole will connect to a remote gdex instance, attaching a JavaScript
+// console to it.
+func remoteConsole(ctx *cli.Context) error {
+ // Attach to a remotely running gdex instance and start the JavaScript console
+ endpoint := ctx.Args().First()
+ if endpoint == "" {
+ path := node.DefaultDataDir()
+ if ctx.GlobalIsSet(utils.DataDirFlag.Name) {
+ path = ctx.GlobalString(utils.DataDirFlag.Name)
+ }
+ if path != "" {
+ if ctx.GlobalBool(utils.TestnetFlag.Name) {
+ path = filepath.Join(path, "testnet")
+ }
+ }
+ endpoint = fmt.Sprintf("%s/gdex.ipc", path)
+ }
+ client, err := dialRPC(endpoint)
+ if err != nil {
+ utils.Fatalf("Unable to attach to remote gdex: %v", err)
+ }
+ config := console.Config{
+ DataDir: utils.MakeDataDir(ctx),
+ DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
+ Client: client,
+ Preload: utils.MakeConsolePreloads(ctx),
+ }
+
+ console, err := console.New(config)
+ if err != nil {
+ utils.Fatalf("Failed to start the JavaScript console: %v", err)
+ }
+ defer console.Stop(false)
+
+ if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
+ console.Evaluate(script)
+ return nil
+ }
+
+ // Otherwise print the welcome screen and enter interactive mode
+ console.Welcome()
+ console.Interactive()
+
+ return nil
+}
+
+// dialRPC returns a RPC client which connects to the given endpoint.
+// The check for empty endpoint implements the defaulting logic
+// for "gdex attach" and "gdex monitor" with no argument.
+func dialRPC(endpoint string) (*rpc.Client, error) {
+ if endpoint == "" {
+ endpoint = node.DefaultIPCEndpoint(clientIdentifier)
+ } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
+ // Backwards compatibility with gdex < 1.5 which required
+ // these prefixes.
+ endpoint = endpoint[4:]
+ }
+ return rpc.Dial(endpoint)
+}
+
+// ephemeralConsole starts a new gdex node, attaches an ephemeral JavaScript
+// console to it, executes each of the files specified as arguments and tears
+// everything down.
+func ephemeralConsole(ctx *cli.Context) error {
+ // Create and start the node based on the CLI flags
+ node := makeFullNode(ctx)
+ startNode(ctx, node)
+ defer node.Stop()
+
+ // Attach to the newly started node and start the JavaScript console
+ client, err := node.Attach()
+ if err != nil {
+ utils.Fatalf("Failed to attach to the inproc gdex: %v", err)
+ }
+ config := console.Config{
+ DataDir: utils.MakeDataDir(ctx),
+ DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
+ Client: client,
+ Preload: utils.MakeConsolePreloads(ctx),
+ }
+
+ console, err := console.New(config)
+ if err != nil {
+ utils.Fatalf("Failed to start the JavaScript console: %v", err)
+ }
+ defer console.Stop(false)
+
+ // Evaluate each of the specified JavaScript files
+ for _, file := range ctx.Args() {
+ if err = console.Execute(file); err != nil {
+ utils.Fatalf("Failed to execute %s: %v", file, err)
+ }
+ }
+ // Wait for pending callbacks, but stop for Ctrl-C.
+ abort := make(chan os.Signal, 1)
+ signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM)
+
+ go func() {
+ <-abort
+ os.Exit(0)
+ }()
+ console.Stop(true)
+
+ return nil
+}
diff --git a/cmd/gdex/consolecmd_test.go b/cmd/gdex/consolecmd_test.go
new file mode 100644
index 000000000..9a79dcd90
--- /dev/null
+++ b/cmd/gdex/consolecmd_test.go
@@ -0,0 +1,163 @@
+// 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 .
+
+package main
+
+import (
+ "crypto/rand"
+ "math/big"
+ "os"
+ "path/filepath"
+ "runtime"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+
+ "github.com/dexon-foundation/dexon/params"
+)
+
+const (
+ ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0"
+ httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
+)
+
+// Tests that a node embedded within a console can be started up properly and
+// then terminated by closing the input stream.
+func TestConsoleWelcome(t *testing.T) {
+ coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
+
+ // Start a gdex console, make sure it's cleaned up and terminate the console
+ gdex := runGeth(t,
+ "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
+ "--etherbase", coinbase, "--shh",
+ "console")
+
+ // Gather all the infos the welcome message needs to contain
+ gdex.SetTemplateFunc("goos", func() string { return runtime.GOOS })
+ gdex.SetTemplateFunc("goarch", func() string { return runtime.GOARCH })
+ gdex.SetTemplateFunc("gover", runtime.Version)
+ gdex.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta })
+ gdex.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) })
+ gdex.SetTemplateFunc("apis", func() string { return ipcAPIs })
+
+ // Verify the actual welcome message to the required template
+ gdex.Expect(`
+Welcome to the Geth JavaScript console!
+
+instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
+coinbase: {{.Etherbase}}
+at block: 0 ({{niltime}})
+ datadir: {{.Datadir}}
+ modules: {{apis}}
+
+> {{.InputLine "exit"}}
+`)
+ gdex.ExpectExit()
+}
+
+// Tests that a console can be attached to a running node via various means.
+func TestIPCAttachWelcome(t *testing.T) {
+ // Configure the instance for IPC attachement
+ coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
+ var ipc string
+ if runtime.GOOS == "windows" {
+ ipc = `\\.\pipe\gdex` + strconv.Itoa(trulyRandInt(100000, 999999))
+ } else {
+ ws := tmpdir(t)
+ defer os.RemoveAll(ws)
+ ipc = filepath.Join(ws, "gdex.ipc")
+ }
+ // Note: we need --shh because testAttachWelcome checks for default
+ // list of ipc modules and shh is included there.
+ gdex := runGeth(t,
+ "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
+ "--etherbase", coinbase, "--shh", "--ipcpath", ipc)
+
+ time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
+ testAttachWelcome(t, gdex, "ipc:"+ipc, ipcAPIs)
+
+ gdex.Interrupt()
+ gdex.ExpectExit()
+}
+
+func TestHTTPAttachWelcome(t *testing.T) {
+ coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
+ port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P
+ gdex := runGeth(t,
+ "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
+ "--etherbase", coinbase, "--rpc", "--rpcport", port)
+
+ time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
+ testAttachWelcome(t, gdex, "http://localhost:"+port, httpAPIs)
+
+ gdex.Interrupt()
+ gdex.ExpectExit()
+}
+
+func TestWSAttachWelcome(t *testing.T) {
+ coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
+ port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P
+
+ gdex := runGeth(t,
+ "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
+ "--etherbase", coinbase, "--ws", "--wsport", port)
+
+ time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
+ testAttachWelcome(t, gdex, "ws://localhost:"+port, httpAPIs)
+
+ gdex.Interrupt()
+ gdex.ExpectExit()
+}
+
+func testAttachWelcome(t *testing.T, gdex *testgdex, endpoint, apis string) {
+ // Attach to a running gdex note and terminate immediately
+ attach := runGeth(t, "attach", endpoint)
+ defer attach.ExpectExit()
+ attach.CloseStdin()
+
+ // Gather all the infos the welcome message needs to contain
+ attach.SetTemplateFunc("goos", func() string { return runtime.GOOS })
+ attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH })
+ attach.SetTemplateFunc("gover", runtime.Version)
+ attach.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta })
+ attach.SetTemplateFunc("etherbase", func() string { return gdex.Etherbase })
+ attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) })
+ attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
+ attach.SetTemplateFunc("datadir", func() string { return gdex.Datadir })
+ attach.SetTemplateFunc("apis", func() string { return apis })
+
+ // Verify the actual welcome message to the required template
+ attach.Expect(`
+Welcome to the Geth JavaScript console!
+
+instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
+coinbase: {{etherbase}}
+at block: 0 ({{niltime}}){{if ipc}}
+ datadir: {{datadir}}{{end}}
+ modules: {{apis}}
+
+> {{.InputLine "exit" }}
+`)
+ attach.ExpectExit()
+}
+
+// trulyRandInt generates a crypto random integer used by the console tests to
+// not clash network ports with other tests running cocurrently.
+func trulyRandInt(lo, hi int) int {
+ num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo)))
+ return int(num.Int64()) + lo
+}
diff --git a/cmd/gdex/dao_test.go b/cmd/gdex/dao_test.go
new file mode 100644
index 000000000..19340fa1b
--- /dev/null
+++ b/cmd/gdex/dao_test.go
@@ -0,0 +1,152 @@
+// 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 .
+
+package main
+
+import (
+ "io/ioutil"
+ "math/big"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "github.com/dexon-foundation/dexon/common"
+ "github.com/dexon-foundation/dexon/core/rawdb"
+ "github.com/dexon-foundation/dexon/ethdb"
+ "github.com/dexon-foundation/dexon/params"
+)
+
+// Genesis block for nodes which don't care about the DAO fork (i.e. not configured)
+var daoOldGenesis = `{
+ "alloc" : {},
+ "coinbase" : "0x0000000000000000000000000000000000000000",
+ "difficulty" : "0x20000",
+ "extraData" : "",
+ "gasLimit" : "0x2fefd8",
+ "nonce" : "0x0000000000000042",
+ "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "timestamp" : "0x00",
+ "config" : {}
+}`
+
+// Genesis block for nodes which actively oppose the DAO fork
+var daoNoForkGenesis = `{
+ "alloc" : {},
+ "coinbase" : "0x0000000000000000000000000000000000000000",
+ "difficulty" : "0x20000",
+ "extraData" : "",
+ "gasLimit" : "0x2fefd8",
+ "nonce" : "0x0000000000000042",
+ "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "timestamp" : "0x00",
+ "config" : {
+ "daoForkBlock" : 314,
+ "daoForkSupport" : false
+ }
+}`
+
+// Genesis block for nodes which actively support the DAO fork
+var daoProForkGenesis = `{
+ "alloc" : {},
+ "coinbase" : "0x0000000000000000000000000000000000000000",
+ "difficulty" : "0x20000",
+ "extraData" : "",
+ "gasLimit" : "0x2fefd8",
+ "nonce" : "0x0000000000000042",
+ "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "timestamp" : "0x00",
+ "config" : {
+ "daoForkBlock" : 314,
+ "daoForkSupport" : true
+ }
+}`
+
+var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
+var daoGenesisForkBlock = big.NewInt(314)
+
+// TestDAOForkBlockNewChain tests that the DAO hard-fork number and the nodes support/opposition is correctly
+// set in the database after various initialization procedures and invocations.
+func TestDAOForkBlockNewChain(t *testing.T) {
+ for i, arg := range []struct {
+ genesis string
+ expectBlock *big.Int
+ expectVote bool
+ }{
+ // Test DAO Default Mainnet
+ {"", params.MainnetChainConfig.DAOForkBlock, true},
+ // test DAO Init Old Privnet
+ {daoOldGenesis, nil, false},
+ // test DAO Default No Fork Privnet
+ {daoNoForkGenesis, daoGenesisForkBlock, false},
+ // test DAO Default Pro Fork Privnet
+ {daoProForkGenesis, daoGenesisForkBlock, true},
+ } {
+ testDAOForkBlockNewChain(t, i, arg.genesis, arg.expectBlock, arg.expectVote)
+ }
+}
+
+func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) {
+ // Create a temporary data directory to use and inspect later
+ datadir := tmpdir(t)
+ defer os.RemoveAll(datadir)
+
+ // Start a Geth instance with the requested flags set and immediately terminate
+ if genesis != "" {
+ json := filepath.Join(datadir, "genesis.json")
+ if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
+ t.Fatalf("test %d: failed to write genesis file: %v", test, err)
+ }
+ runGeth(t, "--datadir", datadir, "init", json).WaitExit()
+ } else {
+ // Force chain initialization
+ args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
+ gdex := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
+ gdex.WaitExit()
+ }
+ // Retrieve the DAO config flag from the database
+ path := filepath.Join(datadir, "gdex", "chaindata")
+ db, err := ethdb.NewLDBDatabase(path, 0, 0)
+ if err != nil {
+ t.Fatalf("test %d: failed to open test database: %v", test, err)
+ }
+ defer db.Close()
+
+ genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
+ if genesis != "" {
+ genesisHash = daoGenesisHash
+ }
+ config := rawdb.ReadChainConfig(db, genesisHash)
+ if config == nil {
+ t.Errorf("test %d: failed to retrieve chain config: %v", test, err)
+ return // we want to return here, the other checks can't make it past this point (nil panic).
+ }
+ // Validate the DAO hard-fork block number against the expected value
+ if config.DAOForkBlock == nil {
+ if expectBlock != nil {
+ t.Errorf("test %d: dao hard-fork block mismatch: have nil, want %v", test, expectBlock)
+ }
+ } else if expectBlock == nil {
+ t.Errorf("test %d: dao hard-fork block mismatch: have %v, want nil", test, config.DAOForkBlock)
+ } else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
+ t.Errorf("test %d: dao hard-fork block mismatch: have %v, want %v", test, config.DAOForkBlock, expectBlock)
+ }
+ if config.DAOForkSupport != expectVote {
+ t.Errorf("test %d: dao hard-fork support mismatch: have %v, want %v", test, config.DAOForkSupport, expectVote)
+ }
+}
diff --git a/cmd/gdex/genesis_test.go b/cmd/gdex/genesis_test.go
new file mode 100644
index 000000000..05da35563
--- /dev/null
+++ b/cmd/gdex/genesis_test.go
@@ -0,0 +1,110 @@
+// 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 .
+
+package main
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "testing"
+)
+
+var customGenesisTests = []struct {
+ genesis string
+ query string
+ result string
+}{
+ // Plain genesis file without anything extra
+ {
+ genesis: `{
+ "alloc" : {},
+ "coinbase" : "0x0000000000000000000000000000000000000000",
+ "difficulty" : "0x20000",
+ "extraData" : "",
+ "gasLimit" : "0x2fefd8",
+ "nonce" : "0x0000000000000042",
+ "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "timestamp" : "0x00"
+ }`,
+ query: "eth.getBlock(0).nonce",
+ result: "0x0000000000000042",
+ },
+ // Genesis file with an empty chain configuration (ensure missing fields work)
+ {
+ genesis: `{
+ "alloc" : {},
+ "coinbase" : "0x0000000000000000000000000000000000000000",
+ "difficulty" : "0x20000",
+ "extraData" : "",
+ "gasLimit" : "0x2fefd8",
+ "nonce" : "0x0000000000000042",
+ "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "timestamp" : "0x00",
+ "config" : {}
+ }`,
+ query: "eth.getBlock(0).nonce",
+ result: "0x0000000000000042",
+ },
+ // Genesis file with specific chain configurations
+ {
+ genesis: `{
+ "alloc" : {},
+ "coinbase" : "0x0000000000000000000000000000000000000000",
+ "difficulty" : "0x20000",
+ "extraData" : "",
+ "gasLimit" : "0x2fefd8",
+ "nonce" : "0x0000000000000042",
+ "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
+ "timestamp" : "0x00",
+ "config" : {
+ "homesteadBlock" : 314,
+ "daoForkBlock" : 141,
+ "daoForkSupport" : true
+ }
+ }`,
+ query: "eth.getBlock(0).nonce",
+ result: "0x0000000000000042",
+ },
+}
+
+// Tests that initializing Geth with a custom genesis block and chain definitions
+// work properly.
+func TestCustomGenesis(t *testing.T) {
+ for i, tt := range customGenesisTests {
+ // Create a temporary data directory to use and inspect later
+ datadir := tmpdir(t)
+ defer os.RemoveAll(datadir)
+
+ // Initialize the data directory with the custom genesis block
+ json := filepath.Join(datadir, "genesis.json")
+ if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil {
+ t.Fatalf("test %d: failed to write genesis file: %v", i, err)
+ }
+ runGeth(t, "--datadir", datadir, "init", json).WaitExit()
+
+ // Query the custom genesis block
+ gdex := runGeth(t,
+ "--datadir", datadir, "--maxpeers", "0", "--port", "0",
+ "--nodiscover", "--nat", "none", "--ipcdisable",
+ "--exec", tt.query, "console")
+ gdex.ExpectRegexp(tt.result)
+ gdex.ExpectExit()
+ }
+}
diff --git a/cmd/gdex/main.go b/cmd/gdex/main.go
new file mode 100644
index 000000000..0253423ad
--- /dev/null
+++ b/cmd/gdex/main.go
@@ -0,0 +1,372 @@
+// Copyright 2014 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 .
+
+// gdex is the official command-line client for Ethereum.
+package main
+
+import (
+ "fmt"
+ "math"
+ "os"
+ godebug "runtime/debug"
+ "sort"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/dexon-foundation/dexon/accounts"
+ "github.com/dexon-foundation/dexon/accounts/keystore"
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/console"
+ "github.com/dexon-foundation/dexon/dex"
+ "github.com/dexon-foundation/dexon/eth"
+ "github.com/dexon-foundation/dexon/ethclient"
+ "github.com/dexon-foundation/dexon/internal/debug"
+ "github.com/dexon-foundation/dexon/log"
+ "github.com/dexon-foundation/dexon/metrics"
+ "github.com/dexon-foundation/dexon/node"
+ "github.com/elastic/gosigar"
+ "gopkg.in/urfave/cli.v1"
+)
+
+const (
+ clientIdentifier = "gdex" // Client identifier to advertise over the network
+)
+
+var (
+ // Git SHA1 commit hash of the release (set via linker flags)
+ gitCommit = ""
+ // The app that holds all commands and flags.
+ app = utils.NewApp(gitCommit, "the go-ethereum command line interface")
+ // flags that configure the node
+ nodeFlags = []cli.Flag{
+ utils.IdentityFlag,
+ utils.UnlockedAccountFlag,
+ utils.PasswordFileFlag,
+ utils.BootnodesFlag,
+ utils.BootnodesV4Flag,
+ utils.BootnodesV5Flag,
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.NoUSBFlag,
+ utils.DashboardEnabledFlag,
+ utils.DashboardAddrFlag,
+ utils.DashboardPortFlag,
+ utils.DashboardRefreshFlag,
+ utils.EthashCacheDirFlag,
+ utils.EthashCachesInMemoryFlag,
+ utils.EthashCachesOnDiskFlag,
+ utils.EthashDatasetDirFlag,
+ utils.EthashDatasetsInMemoryFlag,
+ utils.EthashDatasetsOnDiskFlag,
+ utils.TxPoolLocalsFlag,
+ utils.TxPoolNoLocalsFlag,
+ utils.TxPoolJournalFlag,
+ utils.TxPoolRejournalFlag,
+ utils.TxPoolPriceLimitFlag,
+ utils.TxPoolPriceBumpFlag,
+ utils.TxPoolAccountSlotsFlag,
+ utils.TxPoolGlobalSlotsFlag,
+ utils.TxPoolAccountQueueFlag,
+ utils.TxPoolGlobalQueueFlag,
+ utils.TxPoolLifetimeFlag,
+ utils.SyncModeFlag,
+ utils.GCModeFlag,
+ utils.LightServFlag,
+ utils.LightPeersFlag,
+ utils.LightKDFFlag,
+ utils.WhitelistFlag,
+ utils.CacheFlag,
+ utils.CacheDatabaseFlag,
+ utils.CacheTrieFlag,
+ utils.CacheGCFlag,
+ utils.TrieCacheGenFlag,
+ utils.ListenPortFlag,
+ utils.MaxPeersFlag,
+ utils.MaxPendingPeersFlag,
+ utils.ProposingEnabledFlag,
+ utils.MiningEnabledFlag,
+ utils.MinerThreadsFlag,
+ utils.MinerLegacyThreadsFlag,
+ utils.MinerNotifyFlag,
+ utils.MinerGasTargetFlag,
+ utils.MinerLegacyGasTargetFlag,
+ utils.MinerGasLimitFlag,
+ utils.MinerGasPriceFlag,
+ utils.MinerLegacyGasPriceFlag,
+ utils.MinerEtherbaseFlag,
+ utils.MinerLegacyEtherbaseFlag,
+ utils.MinerExtraDataFlag,
+ utils.MinerLegacyExtraDataFlag,
+ utils.MinerRecommitIntervalFlag,
+ utils.MinerNoVerfiyFlag,
+ utils.NATFlag,
+ utils.NoDiscoverFlag,
+ utils.DiscoveryV5Flag,
+ utils.NetrestrictFlag,
+ utils.NodeKeyFileFlag,
+ utils.NodeKeyHexFlag,
+ utils.DeveloperFlag,
+ utils.DeveloperPeriodFlag,
+ utils.TestnetFlag,
+ utils.VMEnableDebugFlag,
+ utils.NetworkIdFlag,
+ utils.ConstantinopleOverrideFlag,
+ utils.RPCCORSDomainFlag,
+ utils.RPCVirtualHostsFlag,
+ utils.EthStatsURLFlag,
+ utils.MetricsEnabledFlag,
+ utils.FakePoWFlag,
+ utils.NoCompactionFlag,
+ utils.GpoBlocksFlag,
+ utils.GpoPercentileFlag,
+ utils.EWASMInterpreterFlag,
+ utils.EVMInterpreterFlag,
+ configFileFlag,
+ }
+
+ rpcFlags = []cli.Flag{
+ utils.RPCEnabledFlag,
+ utils.RPCListenAddrFlag,
+ utils.RPCPortFlag,
+ utils.RPCApiFlag,
+ utils.WSEnabledFlag,
+ utils.WSListenAddrFlag,
+ utils.WSPortFlag,
+ utils.WSApiFlag,
+ utils.WSAllowedOriginsFlag,
+ utils.IPCDisabledFlag,
+ utils.IPCPathFlag,
+ }
+
+ whisperFlags = []cli.Flag{
+ utils.WhisperEnabledFlag,
+ utils.WhisperMaxMessageSizeFlag,
+ utils.WhisperMinPOWFlag,
+ utils.WhisperRestrictConnectionBetweenLightClientsFlag,
+ }
+
+ metricsFlags = []cli.Flag{
+ utils.MetricsEnableInfluxDBFlag,
+ utils.MetricsInfluxDBEndpointFlag,
+ utils.MetricsInfluxDBDatabaseFlag,
+ utils.MetricsInfluxDBUsernameFlag,
+ utils.MetricsInfluxDBPasswordFlag,
+ utils.MetricsInfluxDBHostTagFlag,
+ }
+)
+
+func init() {
+ // Initialize the CLI app and start Geth
+ app.Action = gdex
+ app.HideVersion = true // we have a command to print the version
+ app.Copyright = "Copyright 2013-2018 The go-ethereum Authors"
+ app.Commands = []cli.Command{
+ // See chaincmd.go:
+ initCommand,
+ importCommand,
+ exportCommand,
+ importPreimagesCommand,
+ exportPreimagesCommand,
+ copydbCommand,
+ removedbCommand,
+ dumpCommand,
+ // See monitorcmd.go:
+ monitorCommand,
+ // See accountcmd.go:
+ accountCommand,
+ walletCommand,
+ // See consolecmd.go:
+ consoleCommand,
+ attachCommand,
+ javascriptCommand,
+ // See misccmd.go:
+ makecacheCommand,
+ makedagCommand,
+ versionCommand,
+ bugCommand,
+ licenseCommand,
+ // See config.go
+ dumpConfigCommand,
+ }
+ sort.Sort(cli.CommandsByName(app.Commands))
+
+ app.Flags = append(app.Flags, nodeFlags...)
+ app.Flags = append(app.Flags, rpcFlags...)
+ app.Flags = append(app.Flags, consoleFlags...)
+ app.Flags = append(app.Flags, debug.Flags...)
+ app.Flags = append(app.Flags, whisperFlags...)
+ app.Flags = append(app.Flags, metricsFlags...)
+
+ app.Before = func(ctx *cli.Context) error {
+ logdir := ""
+ if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
+ logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs")
+ }
+ if err := debug.Setup(ctx, logdir); err != nil {
+ return err
+ }
+ // Cap the cache allowance and tune the garbage collector
+ var mem gosigar.Mem
+ if err := mem.Get(); err == nil {
+ allowance := int(mem.Total / 1024 / 1024 / 3)
+ if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance {
+ log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
+ ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance))
+ }
+ }
+ // Ensure Go's GC ignores the database cache for trigger percentage
+ cache := ctx.GlobalInt(utils.CacheFlag.Name)
+ gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024)))
+
+ log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
+ godebug.SetGCPercent(int(gogc))
+
+ // Start metrics export if enabled
+ utils.SetupMetrics(ctx)
+
+ // Start system runtime metrics collection
+ go metrics.CollectProcessMetrics(3 * time.Second)
+
+ return nil
+ }
+
+ app.After = func(ctx *cli.Context) error {
+ debug.Exit()
+ console.Stdin.Close() // Resets terminal mode.
+ return nil
+ }
+}
+
+func main() {
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
+
+// gdex is the main entry point into the system if no special subcommand is ran.
+// It creates a default node based on the command line arguments and runs it in
+// blocking mode, waiting for it to be shut down.
+func gdex(ctx *cli.Context) error {
+ if args := ctx.Args(); len(args) > 0 {
+ return fmt.Errorf("invalid command: %q", args[0])
+ }
+ node := makeFullNode(ctx)
+ startNode(ctx, node)
+ node.Wait()
+ return nil
+}
+
+// startNode boots up the system node and all registered protocols, after which
+// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
+// miner.
+func startNode(ctx *cli.Context, stack *node.Node) {
+ debug.Memsize.Add("node", stack)
+
+ // Start up the node itself
+ utils.StartNode(stack)
+
+ // Unlock any account specifically requested
+ ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
+
+ passwords := utils.MakePasswordList(ctx)
+ unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
+ for i, account := range unlocks {
+ if trimmed := strings.TrimSpace(account); trimmed != "" {
+ unlockAccount(ctx, ks, trimmed, i, passwords)
+ }
+ }
+ // Register wallet event handlers to open and auto-derive wallets
+ events := make(chan accounts.WalletEvent, 16)
+ stack.AccountManager().Subscribe(events)
+
+ go func() {
+ // Create a chain state reader for self-derivation
+ rpcClient, err := stack.Attach()
+ if err != nil {
+ utils.Fatalf("Failed to attach to self: %v", err)
+ }
+ stateReader := ethclient.NewClient(rpcClient)
+
+ // Open any wallets already attached
+ for _, wallet := range stack.AccountManager().Wallets() {
+ if err := wallet.Open(""); err != nil {
+ log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err)
+ }
+ }
+ // Listen for wallet event till termination
+ for event := range events {
+ switch event.Kind {
+ case accounts.WalletArrived:
+ if err := event.Wallet.Open(""); err != nil {
+ log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err)
+ }
+ case accounts.WalletOpened:
+ status, _ := event.Wallet.Status()
+ log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status)
+
+ derivationPath := accounts.DefaultBaseDerivationPath
+ if event.Wallet.URL().Scheme == "ledger" {
+ derivationPath = accounts.DefaultLedgerBaseDerivationPath
+ }
+ event.Wallet.SelfDerive(derivationPath, stateReader)
+
+ case accounts.WalletDropped:
+ log.Info("Old wallet dropped", "url", event.Wallet.URL())
+ event.Wallet.Close()
+ }
+ }
+ }()
+ // 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.GlobalString(utils.SyncModeFlag.Name) == "light" {
+ utils.Fatalf("Light clients do not support mining")
+ }
+ var ethereum *eth.Ethereum
+ if err := stack.Service(ðereum); err != nil {
+ utils.Fatalf("Ethereum service not running: %v", err)
+ }
+ // Set the gas price to the limits from the CLI and start mining
+ gasprice := utils.GlobalBig(ctx, utils.MinerLegacyGasPriceFlag.Name)
+ if ctx.IsSet(utils.MinerGasPriceFlag.Name) {
+ gasprice = utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
+ }
+ ethereum.TxPool().SetGasPrice(gasprice)
+
+ threads := ctx.GlobalInt(utils.MinerLegacyThreadsFlag.Name)
+ if ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) {
+ threads = ctx.GlobalInt(utils.MinerThreadsFlag.Name)
+ }
+ if err := ethereum.StartMining(threads); err != nil {
+ utils.Fatalf("Failed to start mining: %v", err)
+ }
+ }
+
+ if ctx.GlobalBool(utils.ProposingEnabledFlag.Name) {
+ if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
+ utils.Fatalf("Light clients do not support proposing")
+ }
+ var dexon *dex.Dexon
+ if err := stack.Service(&dexon); err != nil {
+ utils.Fatalf("Dexon service not running: %v", err)
+ }
+ if err := dexon.StartProposing(); err != nil {
+ utils.Fatalf("Failed to string proposing: %v", err)
+ }
+ }
+}
diff --git a/cmd/gdex/misccmd.go b/cmd/gdex/misccmd.go
new file mode 100644
index 000000000..8800c7376
--- /dev/null
+++ b/cmd/gdex/misccmd.go
@@ -0,0 +1,139 @@
+// 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 .
+
+package main
+
+import (
+ "fmt"
+ "os"
+ "runtime"
+ "strconv"
+ "strings"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/consensus/ethash"
+ "github.com/dexon-foundation/dexon/eth"
+ "github.com/dexon-foundation/dexon/params"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ makecacheCommand = cli.Command{
+ Action: utils.MigrateFlags(makecache),
+ Name: "makecache",
+ Usage: "Generate ethash verification cache (for testing)",
+ ArgsUsage: " ",
+ Category: "MISCELLANEOUS COMMANDS",
+ Description: `
+The makecache command generates an ethash cache in .
+
+This command exists to support the system testing project.
+Regular users do not need to execute it.
+`,
+ }
+ makedagCommand = cli.Command{
+ Action: utils.MigrateFlags(makedag),
+ Name: "makedag",
+ Usage: "Generate ethash mining DAG (for testing)",
+ ArgsUsage: " ",
+ Category: "MISCELLANEOUS COMMANDS",
+ Description: `
+The makedag command generates an ethash DAG in .
+
+This command exists to support the system testing project.
+Regular users do not need to execute it.
+`,
+ }
+ versionCommand = cli.Command{
+ Action: utils.MigrateFlags(version),
+ Name: "version",
+ Usage: "Print version numbers",
+ ArgsUsage: " ",
+ Category: "MISCELLANEOUS COMMANDS",
+ Description: `
+The output of this command is supposed to be machine-readable.
+`,
+ }
+ licenseCommand = cli.Command{
+ Action: utils.MigrateFlags(license),
+ Name: "license",
+ Usage: "Display license information",
+ ArgsUsage: " ",
+ Category: "MISCELLANEOUS COMMANDS",
+ }
+)
+
+// makecache generates an ethash verification cache into the provided folder.
+func makecache(ctx *cli.Context) error {
+ args := ctx.Args()
+ if len(args) != 2 {
+ utils.Fatalf(`Usage: gdex makecache `)
+ }
+ block, err := strconv.ParseUint(args[0], 0, 64)
+ if err != nil {
+ utils.Fatalf("Invalid block number: %v", err)
+ }
+ ethash.MakeCache(block, args[1])
+
+ return nil
+}
+
+// makedag generates an ethash mining DAG into the provided folder.
+func makedag(ctx *cli.Context) error {
+ args := ctx.Args()
+ if len(args) != 2 {
+ utils.Fatalf(`Usage: gdex makedag `)
+ }
+ block, err := strconv.ParseUint(args[0], 0, 64)
+ if err != nil {
+ utils.Fatalf("Invalid block number: %v", err)
+ }
+ ethash.MakeDataset(block, args[1])
+
+ return nil
+}
+
+func version(ctx *cli.Context) error {
+ fmt.Println(strings.Title(clientIdentifier))
+ fmt.Println("Version:", params.VersionWithMeta)
+ if gitCommit != "" {
+ fmt.Println("Git Commit:", gitCommit)
+ }
+ fmt.Println("Architecture:", runtime.GOARCH)
+ fmt.Println("Protocol Versions:", eth.ProtocolVersions)
+ fmt.Println("Network Id:", eth.DefaultConfig.NetworkId)
+ fmt.Println("Go Version:", runtime.Version())
+ fmt.Println("Operating System:", runtime.GOOS)
+ fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
+ fmt.Printf("GOROOT=%s\n", runtime.GOROOT())
+ return nil
+}
+
+func license(_ *cli.Context) error {
+ fmt.Println(`Geth 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.
+
+Geth 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 gdex. If not, see .`)
+ return nil
+}
diff --git a/cmd/gdex/monitorcmd.go b/cmd/gdex/monitorcmd.go
new file mode 100644
index 000000000..1038fe3a2
--- /dev/null
+++ b/cmd/gdex/monitorcmd.go
@@ -0,0 +1,351 @@
+// Copyright 2015 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 .
+
+package main
+
+import (
+ "fmt"
+ "math"
+ "reflect"
+ "runtime"
+ "sort"
+ "strings"
+ "time"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/node"
+ "github.com/dexon-foundation/dexon/rpc"
+ "github.com/gizak/termui"
+ "gopkg.in/urfave/cli.v1"
+)
+
+var (
+ monitorCommandAttachFlag = cli.StringFlag{
+ Name: "attach",
+ Value: node.DefaultIPCEndpoint(clientIdentifier),
+ Usage: "API endpoint to attach to",
+ }
+ monitorCommandRowsFlag = cli.IntFlag{
+ Name: "rows",
+ Value: 5,
+ Usage: "Maximum rows in the chart grid",
+ }
+ monitorCommandRefreshFlag = cli.IntFlag{
+ Name: "refresh",
+ Value: 3,
+ Usage: "Refresh interval in seconds",
+ }
+ monitorCommand = cli.Command{
+ Action: utils.MigrateFlags(monitor), // keep track of migration progress
+ Name: "monitor",
+ Usage: "Monitor and visualize node metrics",
+ ArgsUsage: " ",
+ Category: "MONITOR COMMANDS",
+ Description: `
+The Geth monitor is a tool to collect and visualize various internal metrics
+gathered by the node, supporting different chart types as well as the capacity
+to display multiple metrics simultaneously.
+`,
+ Flags: []cli.Flag{
+ monitorCommandAttachFlag,
+ monitorCommandRowsFlag,
+ monitorCommandRefreshFlag,
+ },
+ }
+)
+
+// monitor starts a terminal UI based monitoring tool for the requested metrics.
+func monitor(ctx *cli.Context) error {
+ var (
+ client *rpc.Client
+ err error
+ )
+ // Attach to an Ethereum node over IPC or RPC
+ endpoint := ctx.String(monitorCommandAttachFlag.Name)
+ if client, err = dialRPC(endpoint); err != nil {
+ utils.Fatalf("Unable to attach to gdex node: %v", err)
+ }
+ defer client.Close()
+
+ // Retrieve all the available metrics and resolve the user pattens
+ metrics, err := retrieveMetrics(client)
+ if err != nil {
+ utils.Fatalf("Failed to retrieve system metrics: %v", err)
+ }
+ monitored := resolveMetrics(metrics, ctx.Args())
+ if len(monitored) == 0 {
+ list := expandMetrics(metrics, "")
+ sort.Strings(list)
+
+ if len(list) > 0 {
+ utils.Fatalf("No metrics specified.\n\nAvailable:\n - %s", strings.Join(list, "\n - "))
+ } else {
+ utils.Fatalf("No metrics collected by gdex (--%s).\n", utils.MetricsEnabledFlag.Name)
+ }
+ }
+ sort.Strings(monitored)
+ if cols := len(monitored) / ctx.Int(monitorCommandRowsFlag.Name); cols > 6 {
+ utils.Fatalf("Requested metrics (%d) spans more that 6 columns:\n - %s", len(monitored), strings.Join(monitored, "\n - "))
+ }
+ // Create and configure the chart UI defaults
+ if err := termui.Init(); err != nil {
+ utils.Fatalf("Unable to initialize terminal UI: %v", err)
+ }
+ defer termui.Close()
+
+ rows := len(monitored)
+ if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max {
+ rows = max
+ }
+ cols := (len(monitored) + rows - 1) / rows
+ for i := 0; i < rows; i++ {
+ termui.Body.AddRows(termui.NewRow())
+ }
+ // Create each individual data chart
+ footer := termui.NewPar("")
+ footer.Block.Border = true
+ footer.Height = 3
+
+ charts := make([]*termui.LineChart, len(monitored))
+ units := make([]int, len(monitored))
+ data := make([][]float64, len(monitored))
+ for i := 0; i < len(monitored); i++ {
+ charts[i] = createChart((termui.TermHeight() - footer.Height) / rows)
+ row := termui.Body.Rows[i%rows]
+ row.Cols = append(row.Cols, termui.NewCol(12/cols, 0, charts[i]))
+ }
+ termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, footer)))
+
+ refreshCharts(client, monitored, data, units, charts, ctx, footer)
+ termui.Body.Align()
+ termui.Render(termui.Body)
+
+ // Watch for various system events, and periodically refresh the charts
+ termui.Handle("/sys/kbd/C-c", func(termui.Event) {
+ termui.StopLoop()
+ })
+ termui.Handle("/sys/wnd/resize", func(termui.Event) {
+ termui.Body.Width = termui.TermWidth()
+ for _, chart := range charts {
+ chart.Height = (termui.TermHeight() - footer.Height) / rows
+ }
+ termui.Body.Align()
+ termui.Render(termui.Body)
+ })
+ go func() {
+ tick := time.NewTicker(time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second)
+ for range tick.C {
+ if refreshCharts(client, monitored, data, units, charts, ctx, footer) {
+ termui.Body.Align()
+ }
+ termui.Render(termui.Body)
+ }
+ }()
+ termui.Loop()
+ return nil
+}
+
+// retrieveMetrics contacts the attached gdex node and retrieves the entire set
+// of collected system metrics.
+func retrieveMetrics(client *rpc.Client) (map[string]interface{}, error) {
+ var metrics map[string]interface{}
+ err := client.Call(&metrics, "debug_metrics", true)
+ return metrics, err
+}
+
+// resolveMetrics takes a list of input metric patterns, and resolves each to one
+// or more canonical metric names.
+func resolveMetrics(metrics map[string]interface{}, patterns []string) []string {
+ res := []string{}
+ for _, pattern := range patterns {
+ res = append(res, resolveMetric(metrics, pattern, "")...)
+ }
+ return res
+}
+
+// resolveMetrics takes a single of input metric pattern, and resolves it to one
+// or more canonical metric names.
+func resolveMetric(metrics map[string]interface{}, pattern string, path string) []string {
+ results := []string{}
+
+ // If a nested metric was requested, recurse optionally branching (via comma)
+ parts := strings.SplitN(pattern, "/", 2)
+ if len(parts) > 1 {
+ for _, variation := range strings.Split(parts[0], ",") {
+ submetrics, ok := metrics[variation].(map[string]interface{})
+ if !ok {
+ utils.Fatalf("Failed to retrieve system metrics: %s", path+variation)
+ return nil
+ }
+ results = append(results, resolveMetric(submetrics, parts[1], path+variation+"/")...)
+ }
+ return results
+ }
+ // Depending what the last link is, return or expand
+ for _, variation := range strings.Split(pattern, ",") {
+ switch metric := metrics[variation].(type) {
+ case float64:
+ // Final metric value found, return as singleton
+ results = append(results, path+variation)
+
+ case map[string]interface{}:
+ results = append(results, expandMetrics(metric, path+variation+"/")...)
+
+ default:
+ utils.Fatalf("Metric pattern resolved to unexpected type: %v", reflect.TypeOf(metric))
+ return nil
+ }
+ }
+ return results
+}
+
+// expandMetrics expands the entire tree of metrics into a flat list of paths.
+func expandMetrics(metrics map[string]interface{}, path string) []string {
+ // Iterate over all fields and expand individually
+ list := []string{}
+ for name, metric := range metrics {
+ switch metric := metric.(type) {
+ case float64:
+ // Final metric value found, append to list
+ list = append(list, path+name)
+
+ case map[string]interface{}:
+ // Tree of metrics found, expand recursively
+ list = append(list, expandMetrics(metric, path+name+"/")...)
+
+ default:
+ utils.Fatalf("Metric pattern %s resolved to unexpected type: %v", path+name, reflect.TypeOf(metric))
+ return nil
+ }
+ }
+ return list
+}
+
+// fetchMetric iterates over the metrics map and retrieves a specific one.
+func fetchMetric(metrics map[string]interface{}, metric string) float64 {
+ parts := strings.Split(metric, "/")
+ for _, part := range parts[:len(parts)-1] {
+ var found bool
+ metrics, found = metrics[part].(map[string]interface{})
+ if !found {
+ return 0
+ }
+ }
+ if v, ok := metrics[parts[len(parts)-1]].(float64); ok {
+ return v
+ }
+ return 0
+}
+
+// refreshCharts retrieves a next batch of metrics, and inserts all the new
+// values into the active datasets and charts
+func refreshCharts(client *rpc.Client, metrics []string, data [][]float64, units []int, charts []*termui.LineChart, ctx *cli.Context, footer *termui.Par) (realign bool) {
+ values, err := retrieveMetrics(client)
+ for i, metric := range metrics {
+ if len(data) < 512 {
+ data[i] = append([]float64{fetchMetric(values, metric)}, data[i]...)
+ } else {
+ data[i] = append([]float64{fetchMetric(values, metric)}, data[i][:len(data[i])-1]...)
+ }
+ if updateChart(metric, data[i], &units[i], charts[i], err) {
+ realign = true
+ }
+ }
+ updateFooter(ctx, err, footer)
+ return
+}
+
+// updateChart inserts a dataset into a line chart, scaling appropriately as to
+// not display weird labels, also updating the chart label accordingly.
+func updateChart(metric string, data []float64, base *int, chart *termui.LineChart, err error) (realign bool) {
+ dataUnits := []string{"", "K", "M", "G", "T", "E"}
+ timeUnits := []string{"ns", "µs", "ms", "s", "ks", "ms"}
+ colors := []termui.Attribute{termui.ColorBlue, termui.ColorCyan, termui.ColorGreen, termui.ColorYellow, termui.ColorRed, termui.ColorRed}
+
+ // Extract only part of the data that's actually visible
+ if chart.Width*2 < len(data) {
+ data = data[:chart.Width*2]
+ }
+ // Find the maximum value and scale under 1K
+ high := 0.0
+ if len(data) > 0 {
+ high = data[0]
+ for _, value := range data[1:] {
+ high = math.Max(high, value)
+ }
+ }
+ unit, scale := 0, 1.0
+ for high >= 1000 && unit+1 < len(dataUnits) {
+ high, unit, scale = high/1000, unit+1, scale*1000
+ }
+ // If the unit changes, re-create the chart (hack to set max height...)
+ if unit != *base {
+ realign, *base, *chart = true, unit, *createChart(chart.Height)
+ }
+ // Update the chart's data points with the scaled values
+ if cap(chart.Data) < len(data) {
+ chart.Data = make([]float64, len(data))
+ }
+ chart.Data = chart.Data[:len(data)]
+ for i, value := range data {
+ chart.Data[i] = value / scale
+ }
+ // Update the chart's label with the scale units
+ units := dataUnits
+ if strings.Contains(metric, "/Percentiles/") || strings.Contains(metric, "/pauses/") || strings.Contains(metric, "/time/") {
+ units = timeUnits
+ }
+ chart.BorderLabel = metric
+ if len(units[unit]) > 0 {
+ chart.BorderLabel += " [" + units[unit] + "]"
+ }
+ chart.LineColor = colors[unit] | termui.AttrBold
+ if err != nil {
+ chart.LineColor = termui.ColorRed | termui.AttrBold
+ }
+ return
+}
+
+// createChart creates an empty line chart with the default configs.
+func createChart(height int) *termui.LineChart {
+ chart := termui.NewLineChart()
+ if runtime.GOOS == "windows" {
+ chart.Mode = "dot"
+ }
+ chart.DataLabels = []string{""}
+ chart.Height = height
+ chart.AxesColor = termui.ColorWhite
+ chart.PaddingBottom = -2
+
+ chart.BorderLabelFg = chart.BorderFg | termui.AttrBold
+ chart.BorderFg = chart.BorderBg
+
+ return chart
+}
+
+// updateFooter updates the footer contents based on any encountered errors.
+func updateFooter(ctx *cli.Context, err error, footer *termui.Par) {
+ // Generate the basic footer
+ refresh := time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second
+ footer.Text = fmt.Sprintf("Press Ctrl+C to quit. Refresh interval: %v.", refresh)
+ footer.TextFgColor = termui.ThemeAttr("par.fg") | termui.AttrBold
+
+ // Append any encountered errors
+ if err != nil {
+ footer.Text = fmt.Sprintf("Error: %v.", err)
+ footer.TextFgColor = termui.ColorRed | termui.AttrBold
+ }
+}
diff --git a/cmd/gdex/run_test.go b/cmd/gdex/run_test.go
new file mode 100644
index 000000000..a53a914d2
--- /dev/null
+++ b/cmd/gdex/run_test.go
@@ -0,0 +1,98 @@
+// 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 .
+
+package main
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "testing"
+
+ "github.com/dexon-foundation/dexon/internal/cmdtest"
+ "github.com/docker/docker/pkg/reexec"
+)
+
+func tmpdir(t *testing.T) string {
+ dir, err := ioutil.TempDir("", "gdex-test")
+ if err != nil {
+ t.Fatal(err)
+ }
+ return dir
+}
+
+type testgdex struct {
+ *cmdtest.TestCmd
+
+ // template variables for expect
+ Datadir string
+ Etherbase string
+}
+
+func init() {
+ // Run the app if we've been exec'd as "gdex-test" in runGeth.
+ reexec.Register("gdex-test", func() {
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ os.Exit(0)
+ })
+}
+
+func TestMain(m *testing.M) {
+ // check if we have been reexec'd
+ if reexec.Init() {
+ return
+ }
+ os.Exit(m.Run())
+}
+
+// spawns gdex with the given command line args. If the args don't set --datadir, the
+// child g gets a temporary data directory.
+func runGeth(t *testing.T, args ...string) *testgdex {
+ tt := &testgdex{}
+ tt.TestCmd = cmdtest.NewTestCmd(t, tt)
+ for i, arg := range args {
+ switch {
+ case arg == "-datadir" || arg == "--datadir":
+ if i < len(args)-1 {
+ tt.Datadir = args[i+1]
+ }
+ case arg == "-etherbase" || arg == "--etherbase":
+ if i < len(args)-1 {
+ tt.Etherbase = args[i+1]
+ }
+ }
+ }
+ if tt.Datadir == "" {
+ tt.Datadir = tmpdir(t)
+ tt.Cleanup = func() { os.RemoveAll(tt.Datadir) }
+ args = append([]string{"-datadir", tt.Datadir}, args...)
+ // Remove the temporary datadir if something fails below.
+ defer func() {
+ if t.Failed() {
+ tt.Cleanup()
+ }
+ }()
+ }
+
+ // Boot "gdex". This actually runs the test binary but the TestMain
+ // function will prevent any tests from running.
+ tt.Run("gdex-test", args...)
+
+ return tt
+}
diff --git a/cmd/gdex/testdata/empty.js b/cmd/gdex/testdata/empty.js
new file mode 100644
index 000000000..8b1378917
--- /dev/null
+++ b/cmd/gdex/testdata/empty.js
@@ -0,0 +1 @@
+
diff --git a/cmd/gdex/testdata/guswallet.json b/cmd/gdex/testdata/guswallet.json
new file mode 100644
index 000000000..e8ea4f332
--- /dev/null
+++ b/cmd/gdex/testdata/guswallet.json
@@ -0,0 +1,6 @@
+{
+ "encseed": "26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba",
+ "ethaddr": "d4584b5f6229b7be90727b0fc8c6b91bb427821f",
+ "email": "gustav.simonsson@gmail.com",
+ "btcaddr": "1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx"
+}
diff --git a/cmd/gdex/testdata/passwords.txt b/cmd/gdex/testdata/passwords.txt
new file mode 100644
index 000000000..96f98c7f4
--- /dev/null
+++ b/cmd/gdex/testdata/passwords.txt
@@ -0,0 +1,3 @@
+foobar
+foobar
+foobar
diff --git a/cmd/gdex/testdata/wrong-passwords.txt b/cmd/gdex/testdata/wrong-passwords.txt
new file mode 100644
index 000000000..7d1e338bb
--- /dev/null
+++ b/cmd/gdex/testdata/wrong-passwords.txt
@@ -0,0 +1,3 @@
+wrong
+wrong
+wrong
diff --git a/cmd/gdex/usage.go b/cmd/gdex/usage.go
new file mode 100644
index 000000000..2dee6f417
--- /dev/null
+++ b/cmd/gdex/usage.go
@@ -0,0 +1,359 @@
+// Copyright 2015 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 .
+
+// Contains the gdex command usage template and generator.
+
+package main
+
+import (
+ "io"
+ "sort"
+
+ "strings"
+
+ "github.com/dexon-foundation/dexon/cmd/utils"
+ "github.com/dexon-foundation/dexon/internal/debug"
+ "gopkg.in/urfave/cli.v1"
+)
+
+// AppHelpTemplate is the test template for the default, global app help topic.
+var AppHelpTemplate = `NAME:
+ {{.App.Name}} - {{.App.Usage}}
+
+ Copyright 2013-2018 The go-ethereum Authors
+
+USAGE:
+ {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}}
+ {{if .App.Version}}
+VERSION:
+ {{.App.Version}}
+ {{end}}{{if len .App.Authors}}
+AUTHOR(S):
+ {{range .App.Authors}}{{ . }}{{end}}
+ {{end}}{{if .App.Commands}}
+COMMANDS:
+ {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
+ {{end}}{{end}}{{if .FlagGroups}}
+{{range .FlagGroups}}{{.Name}} OPTIONS:
+ {{range .Flags}}{{.}}
+ {{end}}
+{{end}}{{end}}{{if .App.Copyright }}
+COPYRIGHT:
+ {{.App.Copyright}}
+ {{end}}
+`
+
+// flagGroup is a collection of flags belonging to a single topic.
+type flagGroup struct {
+ Name string
+ Flags []cli.Flag
+}
+
+// AppHelpFlagGroups is the application flags, grouped by functionality.
+var AppHelpFlagGroups = []flagGroup{
+ {
+ Name: "ETHEREUM",
+ Flags: []cli.Flag{
+ configFileFlag,
+ utils.DataDirFlag,
+ utils.KeyStoreDirFlag,
+ utils.NoUSBFlag,
+ utils.NetworkIdFlag,
+ utils.TestnetFlag,
+ utils.SyncModeFlag,
+ utils.GCModeFlag,
+ utils.EthStatsURLFlag,
+ utils.IdentityFlag,
+ utils.LightServFlag,
+ utils.LightPeersFlag,
+ utils.LightKDFFlag,
+ utils.WhitelistFlag,
+ },
+ },
+ {
+ Name: "DEVELOPER CHAIN",
+ Flags: []cli.Flag{
+ utils.DeveloperFlag,
+ utils.DeveloperPeriodFlag,
+ },
+ },
+ {
+ Name: "ETHASH",
+ Flags: []cli.Flag{
+ utils.EthashCacheDirFlag,
+ utils.EthashCachesInMemoryFlag,
+ utils.EthashCachesOnDiskFlag,
+ utils.EthashDatasetDirFlag,
+ utils.EthashDatasetsInMemoryFlag,
+ utils.EthashDatasetsOnDiskFlag,
+ },
+ },
+ //{
+ // Name: "DASHBOARD",
+ // Flags: []cli.Flag{
+ // utils.DashboardEnabledFlag,
+ // utils.DashboardAddrFlag,
+ // utils.DashboardPortFlag,
+ // utils.DashboardRefreshFlag,
+ // utils.DashboardAssetsFlag,
+ // },
+ //},
+ {
+ Name: "TRANSACTION POOL",
+ Flags: []cli.Flag{
+ utils.TxPoolLocalsFlag,
+ utils.TxPoolNoLocalsFlag,
+ utils.TxPoolJournalFlag,
+ utils.TxPoolRejournalFlag,
+ utils.TxPoolPriceLimitFlag,
+ utils.TxPoolPriceBumpFlag,
+ utils.TxPoolAccountSlotsFlag,
+ utils.TxPoolGlobalSlotsFlag,
+ utils.TxPoolAccountQueueFlag,
+ utils.TxPoolGlobalQueueFlag,
+ utils.TxPoolLifetimeFlag,
+ },
+ },
+ {
+ Name: "PERFORMANCE TUNING",
+ Flags: []cli.Flag{
+ utils.CacheFlag,
+ utils.CacheDatabaseFlag,
+ utils.CacheTrieFlag,
+ utils.CacheGCFlag,
+ utils.TrieCacheGenFlag,
+ },
+ },
+ {
+ Name: "ACCOUNT",
+ Flags: []cli.Flag{
+ utils.UnlockedAccountFlag,
+ utils.PasswordFileFlag,
+ },
+ },
+ {
+ Name: "API AND CONSOLE",
+ Flags: []cli.Flag{
+ utils.RPCEnabledFlag,
+ utils.RPCListenAddrFlag,
+ utils.RPCPortFlag,
+ utils.RPCApiFlag,
+ utils.WSEnabledFlag,
+ utils.WSListenAddrFlag,
+ utils.WSPortFlag,
+ utils.WSApiFlag,
+ utils.WSAllowedOriginsFlag,
+ utils.IPCDisabledFlag,
+ utils.IPCPathFlag,
+ utils.RPCCORSDomainFlag,
+ utils.RPCVirtualHostsFlag,
+ utils.JSpathFlag,
+ utils.ExecFlag,
+ utils.PreloadJSFlag,
+ },
+ },
+ {
+ Name: "NETWORKING",
+ Flags: []cli.Flag{
+ utils.BootnodesFlag,
+ utils.BootnodesV4Flag,
+ utils.BootnodesV5Flag,
+ utils.ListenPortFlag,
+ utils.MaxPeersFlag,
+ utils.MaxPendingPeersFlag,
+ utils.NATFlag,
+ utils.NoDiscoverFlag,
+ utils.DiscoveryV5Flag,
+ utils.NetrestrictFlag,
+ utils.NodeKeyFileFlag,
+ utils.NodeKeyHexFlag,
+ },
+ },
+ {
+ Name: "PROPOSER",
+ Flags: []cli.Flag{
+ utils.ProposingEnabledFlag,
+ },
+ },
+ {
+ Name: "MINER",
+ Flags: []cli.Flag{
+ utils.MiningEnabledFlag,
+ utils.MinerThreadsFlag,
+ utils.MinerNotifyFlag,
+ utils.MinerGasPriceFlag,
+ utils.MinerGasTargetFlag,
+ utils.MinerGasLimitFlag,
+ utils.MinerEtherbaseFlag,
+ utils.MinerExtraDataFlag,
+ utils.MinerRecommitIntervalFlag,
+ utils.MinerNoVerfiyFlag,
+ },
+ },
+ {
+ Name: "GAS PRICE ORACLE",
+ Flags: []cli.Flag{
+ utils.GpoBlocksFlag,
+ utils.GpoPercentileFlag,
+ },
+ },
+ {
+ Name: "VIRTUAL MACHINE",
+ Flags: []cli.Flag{
+ utils.VMEnableDebugFlag,
+ utils.EVMInterpreterFlag,
+ utils.EWASMInterpreterFlag,
+ },
+ },
+ {
+ Name: "LOGGING AND DEBUGGING",
+ Flags: append([]cli.Flag{
+ utils.FakePoWFlag,
+ utils.NoCompactionFlag,
+ }, debug.Flags...),
+ },
+ {
+ Name: "METRICS AND STATS",
+ Flags: []cli.Flag{
+ utils.MetricsEnabledFlag,
+ utils.MetricsEnableInfluxDBFlag,
+ utils.MetricsInfluxDBEndpointFlag,
+ utils.MetricsInfluxDBDatabaseFlag,
+ utils.MetricsInfluxDBUsernameFlag,
+ utils.MetricsInfluxDBPasswordFlag,
+ utils.MetricsInfluxDBHostTagFlag,
+ },
+ },
+ {
+ Name: "WHISPER (EXPERIMENTAL)",
+ Flags: whisperFlags,
+ },
+ {
+ Name: "DEPRECATED",
+ Flags: []cli.Flag{
+ utils.MinerLegacyThreadsFlag,
+ utils.MinerLegacyGasTargetFlag,
+ utils.MinerLegacyGasPriceFlag,
+ utils.MinerLegacyEtherbaseFlag,
+ utils.MinerLegacyExtraDataFlag,
+ },
+ },
+ {
+ Name: "MISC",
+ },
+}
+
+// byCategory sorts an array of flagGroup by Name in the order
+// defined in AppHelpFlagGroups.
+type byCategory []flagGroup
+
+func (a byCategory) Len() int { return len(a) }
+func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a byCategory) Less(i, j int) bool {
+ iCat, jCat := a[i].Name, a[j].Name
+ iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last
+
+ for i, group := range AppHelpFlagGroups {
+ if iCat == group.Name {
+ iIdx = i
+ }
+ if jCat == group.Name {
+ jIdx = i
+ }
+ }
+
+ return iIdx < jIdx
+}
+
+func flagCategory(flag cli.Flag) string {
+ for _, category := range AppHelpFlagGroups {
+ for _, flg := range category.Flags {
+ if flg.GetName() == flag.GetName() {
+ return category.Name
+ }
+ }
+ }
+ return "MISC"
+}
+
+func init() {
+ // Override the default app help template
+ cli.AppHelpTemplate = AppHelpTemplate
+
+ // Define a one shot struct to pass to the usage template
+ type helpData struct {
+ App interface{}
+ FlagGroups []flagGroup
+ }
+
+ // Override the default app help printer, but only for the global app help
+ originalHelpPrinter := cli.HelpPrinter
+ cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) {
+ if tmpl == AppHelpTemplate {
+ // Iterate over all the flags and add any uncategorized ones
+ categorized := make(map[string]struct{})
+ for _, group := range AppHelpFlagGroups {
+ for _, flag := range group.Flags {
+ categorized[flag.String()] = struct{}{}
+ }
+ }
+ uncategorized := []cli.Flag{}
+ for _, flag := range data.(*cli.App).Flags {
+ if _, ok := categorized[flag.String()]; !ok {
+ if strings.HasPrefix(flag.GetName(), "dashboard") {
+ continue
+ }
+ uncategorized = append(uncategorized, flag)
+ }
+ }
+ if len(uncategorized) > 0 {
+ // Append all ungategorized options to the misc group
+ miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags)
+ AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...)
+
+ // Make sure they are removed afterwards
+ defer func() {
+ AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs]
+ }()
+ }
+ // Render out custom usage screen
+ originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups})
+ } else if tmpl == utils.CommandHelpTemplate {
+ // Iterate over all command specific flags and categorize them
+ categorized := make(map[string][]cli.Flag)
+ for _, flag := range data.(cli.Command).Flags {
+ if _, ok := categorized[flag.String()]; !ok {
+ categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag)
+ }
+ }
+
+ // sort to get a stable ordering
+ sorted := make([]flagGroup, 0, len(categorized))
+ for cat, flgs := range categorized {
+ sorted = append(sorted, flagGroup{cat, flgs})
+ }
+ sort.Sort(byCategory(sorted))
+
+ // add sorted array to data and render with default printer
+ originalHelpPrinter(w, tmpl, map[string]interface{}{
+ "cmd": data,
+ "categorizedFlags": sorted,
+ })
+ } else {
+ originalHelpPrinter(w, tmpl, data)
+ }
+ }
+}
diff --git a/cmd/geth/accountcmd.go b/cmd/geth/accountcmd.go
deleted file mode 100644
index bf6d9140d..000000000
--- a/cmd/geth/accountcmd.go
+++ /dev/null
@@ -1,379 +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 .
-
-package main
-
-import (
- "fmt"
- "io/ioutil"
-
- "github.com/dexon-foundation/dexon/accounts"
- "github.com/dexon-foundation/dexon/accounts/keystore"
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/console"
- "github.com/dexon-foundation/dexon/crypto"
- "github.com/dexon-foundation/dexon/log"
- "gopkg.in/urfave/cli.v1"
-)
-
-var (
- walletCommand = cli.Command{
- Name: "wallet",
- Usage: "Manage Ethereum presale wallets",
- ArgsUsage: "",
- Category: "ACCOUNT COMMANDS",
- Description: `
- geth wallet import /path/to/my/presale.wallet
-
-will prompt for your password and imports your ether presale account.
-It can be used non-interactively with the --password option taking a
-passwordfile as argument containing the wallet password in plaintext.`,
- Subcommands: []cli.Command{
- {
-
- Name: "import",
- Usage: "Import Ethereum presale wallet",
- ArgsUsage: "",
- Action: utils.MigrateFlags(importWallet),
- Category: "ACCOUNT COMMANDS",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.PasswordFileFlag,
- utils.LightKDFFlag,
- },
- Description: `
- geth wallet [options] /path/to/my/presale.wallet
-
-will prompt for your password and imports your ether presale account.
-It can be used non-interactively with the --password option taking a
-passwordfile as argument containing the wallet password in plaintext.`,
- },
- },
- }
-
- accountCommand = cli.Command{
- Name: "account",
- Usage: "Manage accounts",
- Category: "ACCOUNT COMMANDS",
- Description: `
-
-Manage accounts, list all existing accounts, import a private key into a new
-account, create a new account or update an existing account.
-
-It supports interactive mode, when you are prompted for password as well as
-non-interactive mode where passwords are supplied via a given password file.
-Non-interactive mode is only meant for scripted use on test networks or known
-safe environments.
-
-Make sure you remember the password you gave when creating a new account (with
-either new or import). Without it you are not able to unlock your account.
-
-Note that exporting your key in unencrypted format is NOT supported.
-
-Keys are stored under /keystore.
-It is safe to transfer the entire directory or the individual keys therein
-between ethereum nodes by simply copying.
-
-Make sure you backup your keys regularly.`,
- Subcommands: []cli.Command{
- {
- Name: "list",
- Usage: "Print summary of existing accounts",
- Action: utils.MigrateFlags(accountList),
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- },
- Description: `
-Print a short summary of all accounts`,
- },
- {
- Name: "new",
- Usage: "Create a new account",
- Action: utils.MigrateFlags(accountCreate),
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.PasswordFileFlag,
- utils.LightKDFFlag,
- },
- Description: `
- geth account new
-
-Creates a new account and prints the address.
-
-The account is saved in encrypted format, you are prompted for a passphrase.
-
-You must remember this passphrase to unlock your account in the future.
-
-For non-interactive use the passphrase can be specified with the --password flag:
-
-Note, this is meant to be used for testing only, it is a bad idea to save your
-password to file or expose in any other way.
-`,
- },
- {
- Name: "update",
- Usage: "Update an existing account",
- Action: utils.MigrateFlags(accountUpdate),
- ArgsUsage: "",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.LightKDFFlag,
- },
- Description: `
- geth account update
-
-Update an existing account.
-
-The account is saved in the newest version in encrypted format, you are prompted
-for a passphrase to unlock the account and another to save the updated file.
-
-This same command can therefore be used to migrate an account of a deprecated
-format to the newest format or change the password for an account.
-
-For non-interactive use the passphrase can be specified with the --password flag:
-
- geth account update [options]
-
-Since only one password can be given, only format update can be performed,
-changing your password is only possible interactively.
-`,
- },
- {
- Name: "import",
- Usage: "Import a private key into a new account",
- Action: utils.MigrateFlags(accountImport),
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.PasswordFileFlag,
- utils.LightKDFFlag,
- },
- ArgsUsage: "",
- Description: `
- geth account import
-
-Imports an unencrypted private key from and creates a new account.
-Prints the address.
-
-The keyfile is assumed to contain an unencrypted private key in hexadecimal format.
-
-The account is saved in encrypted format, you are prompted for a passphrase.
-
-You must remember this passphrase to unlock your account in the future.
-
-For non-interactive use the passphrase can be specified with the -password flag:
-
- geth account import [options]
-
-Note:
-As you can directly copy your encrypted accounts to another ethereum instance,
-this import mechanism is not needed when you transfer an account between
-nodes.
-`,
- },
- },
- }
-)
-
-func accountList(ctx *cli.Context) error {
- stack, _ := makeConfigNode(ctx)
- var index int
- for _, wallet := range stack.AccountManager().Wallets() {
- for _, account := range wallet.Accounts() {
- fmt.Printf("Account #%d: {%x} %s\n", index, account.Address, &account.URL)
- index++
- }
- }
- return nil
-}
-
-// tries unlocking the specified account a few times.
-func unlockAccount(ctx *cli.Context, ks *keystore.KeyStore, address string, i int, passwords []string) (accounts.Account, string) {
- account, err := utils.MakeAddress(ks, address)
- if err != nil {
- utils.Fatalf("Could not list accounts: %v", err)
- }
- for trials := 0; trials < 3; trials++ {
- prompt := fmt.Sprintf("Unlocking account %s | Attempt %d/%d", address, trials+1, 3)
- password := getPassPhrase(prompt, false, i, passwords)
- err = ks.Unlock(account, password)
- if err == nil {
- log.Info("Unlocked account", "address", account.Address.Hex())
- return account, password
- }
- if err, ok := err.(*keystore.AmbiguousAddrError); ok {
- log.Info("Unlocked account", "address", account.Address.Hex())
- return ambiguousAddrRecovery(ks, err, password), password
- }
- if err != keystore.ErrDecrypt {
- // No need to prompt again if the error is not decryption-related.
- break
- }
- }
- // All trials expended to unlock account, bail out
- utils.Fatalf("Failed to unlock account %s (%v)", address, err)
-
- return accounts.Account{}, ""
-}
-
-// getPassPhrase retrieves the password associated with an account, either fetched
-// from a list of preloaded passphrases, or requested interactively from the user.
-func getPassPhrase(prompt string, confirmation bool, i int, passwords []string) string {
- // If a list of passwords was supplied, retrieve from them
- if len(passwords) > 0 {
- if i < len(passwords) {
- return passwords[i]
- }
- return passwords[len(passwords)-1]
- }
- // Otherwise prompt the user for the password
- if prompt != "" {
- fmt.Println(prompt)
- }
- password, 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 password != confirm {
- utils.Fatalf("Passphrases do not match")
- }
- }
- return password
-}
-
-func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrError, auth string) accounts.Account {
- fmt.Printf("Multiple key files exist for address %x:\n", err.Addr)
- for _, a := range err.Matches {
- fmt.Println(" ", a.URL)
- }
- fmt.Println("Testing your passphrase against all of them...")
- var match *accounts.Account
- for _, a := range err.Matches {
- if err := ks.Unlock(a, auth); err == nil {
- match = &a
- break
- }
- }
- if match == nil {
- utils.Fatalf("None of the listed files could be unlocked.")
- }
- fmt.Printf("Your passphrase unlocked %s\n", match.URL)
- fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:")
- for _, a := range err.Matches {
- if a != *match {
- fmt.Println(" ", a.URL)
- }
- }
- return *match
-}
-
-// accountCreate creates a new account into the keystore defined by the CLI flags.
-func accountCreate(ctx *cli.Context) error {
- cfg := gethConfig{Node: defaultNodeConfig()}
- // Load config file.
- if file := ctx.GlobalString(configFileFlag.Name); file != "" {
- if err := loadConfig(file, &cfg); err != nil {
- utils.Fatalf("%v", err)
- }
- }
- utils.SetNodeConfig(ctx, &cfg.Node)
- scryptN, scryptP, keydir, err := cfg.Node.AccountConfig()
-
- if err != nil {
- utils.Fatalf("Failed to read configuration: %v", err)
- }
-
- password := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
-
- address, err := keystore.StoreKey(keydir, password, scryptN, scryptP)
-
- if err != nil {
- utils.Fatalf("Failed to create account: %v", err)
- }
- fmt.Printf("Address: {%x}\n", address)
- return nil
-}
-
-// accountUpdate transitions an account from a previous format to the current
-// one, also providing the possibility to change the pass-phrase.
-func accountUpdate(ctx *cli.Context) error {
- if len(ctx.Args()) == 0 {
- utils.Fatalf("No accounts specified to update")
- }
- stack, _ := makeConfigNode(ctx)
- ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
-
- for _, addr := range ctx.Args() {
- account, oldPassword := unlockAccount(ctx, ks, addr, 0, nil)
- newPassword := getPassPhrase("Please give a new password. Do not forget this password.", true, 0, nil)
- if err := ks.Update(account, oldPassword, newPassword); err != nil {
- utils.Fatalf("Could not update the account: %v", err)
- }
- }
- return nil
-}
-
-func importWallet(ctx *cli.Context) error {
- keyfile := ctx.Args().First()
- if len(keyfile) == 0 {
- utils.Fatalf("keyfile must be given as argument")
- }
- keyJSON, err := ioutil.ReadFile(keyfile)
- if err != nil {
- utils.Fatalf("Could not read wallet file: %v", err)
- }
-
- stack, _ := makeConfigNode(ctx)
- passphrase := getPassPhrase("", false, 0, utils.MakePasswordList(ctx))
-
- ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
- acct, err := ks.ImportPreSaleKey(keyJSON, passphrase)
- if err != nil {
- utils.Fatalf("%v", err)
- }
- fmt.Printf("Address: {%x}\n", acct.Address)
- return nil
-}
-
-func accountImport(ctx *cli.Context) error {
- keyfile := ctx.Args().First()
- if len(keyfile) == 0 {
- utils.Fatalf("keyfile must be given as argument")
- }
- key, err := crypto.LoadECDSA(keyfile)
- if err != nil {
- utils.Fatalf("Failed to load the private key: %v", err)
- }
- stack, _ := makeConfigNode(ctx)
- passphrase := getPassPhrase("Your new account is locked with a password. Please give a password. Do not forget this password.", true, 0, utils.MakePasswordList(ctx))
-
- ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
- acct, err := ks.ImportECDSA(key, passphrase)
- if err != nil {
- utils.Fatalf("Could not create the account: %v", err)
- }
- fmt.Printf("Address: {%x}\n", acct.Address)
- return nil
-}
diff --git a/cmd/geth/accountcmd_test.go b/cmd/geth/accountcmd_test.go
deleted file mode 100644
index c9983a219..000000000
--- a/cmd/geth/accountcmd_test.go
+++ /dev/null
@@ -1,296 +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 .
-
-package main
-
-import (
- "io/ioutil"
- "path/filepath"
- "runtime"
- "strings"
- "testing"
-
- "github.com/cespare/cp"
-)
-
-// These tests are 'smoke tests' for the account related
-// subcommands and flags.
-//
-// For most tests, the test files from package accounts
-// are copied into a temporary keystore directory.
-
-func tmpDatadirWithKeystore(t *testing.T) string {
- datadir := tmpdir(t)
- keystore := filepath.Join(datadir, "keystore")
- source := filepath.Join("..", "..", "accounts", "keystore", "testdata", "keystore")
- if err := cp.CopyAll(keystore, source); err != nil {
- t.Fatal(err)
- }
- return datadir
-}
-
-func TestAccountListEmpty(t *testing.T) {
- geth := runGeth(t, "account", "list")
- geth.ExpectExit()
-}
-
-func TestAccountList(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t, "account", "list", "--datadir", datadir)
- defer geth.ExpectExit()
- if runtime.GOOS == "windows" {
- geth.Expect(`
-Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}\keystore\UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
-Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}\keystore\aaa
-Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}\keystore\zzz
-`)
- } else {
- geth.Expect(`
-Account #0: {7ef5a6135f1fd6a02593eedc869c6d41d934aef8} keystore://{{.Datadir}}/keystore/UTC--2016-03-22T12-57-55.920751759Z--7ef5a6135f1fd6a02593eedc869c6d41d934aef8
-Account #1: {f466859ead1932d743d622cb74fc058882e8648a} keystore://{{.Datadir}}/keystore/aaa
-Account #2: {289d485d9771714cce91d3393d764e1311907acc} keystore://{{.Datadir}}/keystore/zzz
-`)
- }
-}
-
-func TestAccountNew(t *testing.T) {
- geth := runGeth(t, "account", "new", "--lightkdf")
- defer geth.ExpectExit()
- geth.Expect(`
-Your new account is locked with a password. Please give a password. Do not forget this password.
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "foobar"}}
-Repeat passphrase: {{.InputLine "foobar"}}
-`)
- geth.ExpectRegexp(`Address: \{[0-9a-f]{40}\}\n`)
-}
-
-func TestAccountNewBadRepeat(t *testing.T) {
- geth := runGeth(t, "account", "new", "--lightkdf")
- defer geth.ExpectExit()
- geth.Expect(`
-Your new account is locked with a password. Please give a password. Do not forget this password.
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "something"}}
-Repeat passphrase: {{.InputLine "something else"}}
-Fatal: Passphrases do not match
-`)
-}
-
-func TestAccountUpdate(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t, "account", "update",
- "--datadir", datadir, "--lightkdf",
- "f466859ead1932d743d622cb74fc058882e8648a")
- defer geth.ExpectExit()
- geth.Expect(`
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "foobar"}}
-Please give a new password. Do not forget this password.
-Passphrase: {{.InputLine "foobar2"}}
-Repeat passphrase: {{.InputLine "foobar2"}}
-`)
-}
-
-func TestWalletImport(t *testing.T) {
- geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
- defer geth.ExpectExit()
- geth.Expect(`
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "foo"}}
-Address: {d4584b5f6229b7be90727b0fc8c6b91bb427821f}
-`)
-
- files, err := ioutil.ReadDir(filepath.Join(geth.Datadir, "keystore"))
- if len(files) != 1 {
- t.Errorf("expected one key file in keystore directory, found %d files (error: %v)", len(files), err)
- }
-}
-
-func TestWalletImportBadPassword(t *testing.T) {
- geth := runGeth(t, "wallet", "import", "--lightkdf", "testdata/guswallet.json")
- defer geth.ExpectExit()
- geth.Expect(`
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "wrong"}}
-Fatal: could not decrypt key with given passphrase
-`)
-}
-
-func TestUnlockFlag(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t,
- "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
- "js", "testdata/empty.js")
- geth.Expect(`
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "foobar"}}
-`)
- geth.ExpectExit()
-
- wantMessages := []string{
- "Unlocked account",
- "=0xf466859eAD1932D743d622CB74FC058882E8648A",
- }
- for _, m := range wantMessages {
- if !strings.Contains(geth.StderrText(), m) {
- t.Errorf("stderr text does not contain %q", m)
- }
- }
-}
-
-func TestUnlockFlagWrongPassword(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t,
- "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
- defer geth.ExpectExit()
- geth.Expect(`
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "wrong1"}}
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 2/3
-Passphrase: {{.InputLine "wrong2"}}
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 3/3
-Passphrase: {{.InputLine "wrong3"}}
-Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could not decrypt key with given passphrase)
-`)
-}
-
-// https://github.com/dexon-foundation/dexon/issues/1785
-func TestUnlockFlagMultiIndex(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t,
- "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--unlock", "0,2",
- "js", "testdata/empty.js")
- geth.Expect(`
-Unlocking account 0 | Attempt 1/3
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "foobar"}}
-Unlocking account 2 | Attempt 1/3
-Passphrase: {{.InputLine "foobar"}}
-`)
- geth.ExpectExit()
-
- wantMessages := []string{
- "Unlocked account",
- "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
- "=0x289d485D9771714CCe91D3393D764E1311907ACc",
- }
- for _, m := range wantMessages {
- if !strings.Contains(geth.StderrText(), m) {
- t.Errorf("stderr text does not contain %q", m)
- }
- }
-}
-
-func TestUnlockFlagPasswordFile(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t,
- "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--password", "testdata/passwords.txt", "--unlock", "0,2",
- "js", "testdata/empty.js")
- geth.ExpectExit()
-
- wantMessages := []string{
- "Unlocked account",
- "=0x7EF5A6135f1FD6a02593eEdC869c6D41D934aef8",
- "=0x289d485D9771714CCe91D3393D764E1311907ACc",
- }
- for _, m := range wantMessages {
- if !strings.Contains(geth.StderrText(), m) {
- t.Errorf("stderr text does not contain %q", m)
- }
- }
-}
-
-func TestUnlockFlagPasswordFileWrongPassword(t *testing.T) {
- datadir := tmpDatadirWithKeystore(t)
- geth := runGeth(t,
- "--datadir", datadir, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--password", "testdata/wrong-passwords.txt", "--unlock", "0,2")
- defer geth.ExpectExit()
- geth.Expect(`
-Fatal: Failed to unlock account 0 (could not decrypt key with given passphrase)
-`)
-}
-
-func TestUnlockFlagAmbiguous(t *testing.T) {
- store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
- geth := runGeth(t,
- "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
- "js", "testdata/empty.js")
- defer geth.ExpectExit()
-
- // Helper for the expect template, returns absolute keystore path.
- geth.SetTemplateFunc("keypath", func(file string) string {
- abs, _ := filepath.Abs(filepath.Join(store, file))
- return abs
- })
- geth.Expect(`
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "foobar"}}
-Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
- keystore://{{keypath "1"}}
- keystore://{{keypath "2"}}
-Testing your passphrase against all of them...
-Your passphrase unlocked keystore://{{keypath "1"}}
-In order to avoid this warning, you need to remove the following duplicate key files:
- keystore://{{keypath "2"}}
-`)
- geth.ExpectExit()
-
- wantMessages := []string{
- "Unlocked account",
- "=0xf466859eAD1932D743d622CB74FC058882E8648A",
- }
- for _, m := range wantMessages {
- if !strings.Contains(geth.StderrText(), m) {
- t.Errorf("stderr text does not contain %q", m)
- }
- }
-}
-
-func TestUnlockFlagAmbiguousWrongPassword(t *testing.T) {
- store := filepath.Join("..", "..", "accounts", "keystore", "testdata", "dupes")
- geth := runGeth(t,
- "--keystore", store, "--nat", "none", "--nodiscover", "--maxpeers", "0", "--port", "0",
- "--unlock", "f466859ead1932d743d622cb74fc058882e8648a")
- defer geth.ExpectExit()
-
- // Helper for the expect template, returns absolute keystore path.
- geth.SetTemplateFunc("keypath", func(file string) string {
- abs, _ := filepath.Abs(filepath.Join(store, file))
- return abs
- })
- geth.Expect(`
-Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
-!! Unsupported terminal, password will be echoed.
-Passphrase: {{.InputLine "wrong"}}
-Multiple key files exist for address f466859ead1932d743d622cb74fc058882e8648a:
- keystore://{{keypath "1"}}
- keystore://{{keypath "2"}}
-Testing your passphrase against all of them...
-Fatal: None of the listed files could be unlocked.
-`)
- geth.ExpectExit()
-}
diff --git a/cmd/geth/bugcmd.go b/cmd/geth/bugcmd.go
deleted file mode 100644
index bb33a0af4..000000000
--- a/cmd/geth/bugcmd.go
+++ /dev/null
@@ -1,113 +0,0 @@
-// 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 .
-
-package main
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "net/url"
- "os/exec"
- "runtime"
- "strings"
-
- "github.com/dexon-foundation/dexon/cmd/internal/browser"
- "github.com/dexon-foundation/dexon/params"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- cli "gopkg.in/urfave/cli.v1"
-)
-
-var bugCommand = cli.Command{
- Action: utils.MigrateFlags(reportBug),
- Name: "bug",
- Usage: "opens a window to report a bug on the geth repo",
- ArgsUsage: " ",
- Category: "MISCELLANEOUS COMMANDS",
-}
-
-const issueURL = "https://github.com/dexon-foundation/dexon/issues/new"
-
-// reportBug reports a bug by opening a new URL to the go-ethereum GH issue
-// tracker and setting default values as the issue body.
-func reportBug(ctx *cli.Context) error {
- // execute template and write contents to buff
- var buff bytes.Buffer
-
- fmt.Fprintln(&buff, "#### System information")
- fmt.Fprintln(&buff)
- fmt.Fprintln(&buff, "Version:", params.VersionWithMeta)
- fmt.Fprintln(&buff, "Go Version:", runtime.Version())
- fmt.Fprintln(&buff, "OS:", runtime.GOOS)
- printOSDetails(&buff)
- fmt.Fprintln(&buff, header)
-
- // open a new GH issue
- if !browser.Open(issueURL + "?body=" + url.QueryEscape(buff.String())) {
- fmt.Printf("Please file a new issue at %s using this template:\n\n%s", issueURL, buff.String())
- }
- return nil
-}
-
-// copied from the Go source. Copyright 2017 The Go Authors
-func printOSDetails(w io.Writer) {
- switch runtime.GOOS {
- case "darwin":
- printCmdOut(w, "uname -v: ", "uname", "-v")
- printCmdOut(w, "", "sw_vers")
- case "linux":
- printCmdOut(w, "uname -sr: ", "uname", "-sr")
- printCmdOut(w, "", "lsb_release", "-a")
- case "openbsd", "netbsd", "freebsd", "dragonfly":
- printCmdOut(w, "uname -v: ", "uname", "-v")
- case "solaris":
- out, err := ioutil.ReadFile("/etc/release")
- if err == nil {
- fmt.Fprintf(w, "/etc/release: %s\n", out)
- } else {
- fmt.Printf("failed to read /etc/release: %v\n", err)
- }
- }
-}
-
-// printCmdOut prints the output of running the given command.
-// It ignores failures; 'go bug' is best effort.
-//
-// copied from the Go source. Copyright 2017 The Go Authors
-func printCmdOut(w io.Writer, prefix, path string, args ...string) {
- cmd := exec.Command(path, args...)
- out, err := cmd.Output()
- if err != nil {
- fmt.Printf("%s %s: %v\n", path, strings.Join(args, " "), err)
- return
- }
- fmt.Fprintf(w, "%s%s\n", prefix, bytes.TrimSpace(out))
-}
-
-const header = `
-#### Expected behaviour
-
-
-#### Actual behaviour
-
-
-#### Steps to reproduce the behaviour
-
-
-#### Backtrace
-`
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
deleted file mode 100644
index ce4216a94..000000000
--- a/cmd/geth/chaincmd.go
+++ /dev/null
@@ -1,471 +0,0 @@
-// Copyright 2015 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 .
-
-package main
-
-import (
- "encoding/json"
- "fmt"
- "os"
- "runtime"
- "strconv"
- "sync/atomic"
- "time"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/common"
- "github.com/dexon-foundation/dexon/console"
- "github.com/dexon-foundation/dexon/core"
- "github.com/dexon-foundation/dexon/core/state"
- "github.com/dexon-foundation/dexon/core/types"
- "github.com/dexon-foundation/dexon/eth/downloader"
- "github.com/dexon-foundation/dexon/ethdb"
- "github.com/dexon-foundation/dexon/event"
- "github.com/dexon-foundation/dexon/log"
- "github.com/dexon-foundation/dexon/trie"
- "github.com/syndtr/goleveldb/leveldb/util"
- "gopkg.in/urfave/cli.v1"
-)
-
-var (
- initCommand = cli.Command{
- Action: utils.MigrateFlags(initGenesis),
- Name: "init",
- Usage: "Bootstrap and initialize a new genesis block",
- ArgsUsage: "",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-The init command initializes a new genesis block and definition for the network.
-This is a destructive action and changes the network in which you will be
-participating.
-
-It expects the genesis file as argument.`,
- }
- importCommand = cli.Command{
- Action: utils.MigrateFlags(importChain),
- Name: "import",
- Usage: "Import a blockchain file",
- ArgsUsage: " ( ... ) ",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.CacheFlag,
- utils.SyncModeFlag,
- utils.GCModeFlag,
- utils.CacheDatabaseFlag,
- utils.CacheGCFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-The import command imports blocks from an RLP-encoded form. The form can be one file
-with several RLP-encoded blocks, or several files can be used.
-
-If only one file is used, import error will result in failure. If several files are used,
-processing will proceed even if an individual RLP-file import failure occurs.`,
- }
- exportCommand = cli.Command{
- Action: utils.MigrateFlags(exportChain),
- Name: "export",
- Usage: "Export blockchain into file",
- ArgsUsage: " [ ]",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.CacheFlag,
- utils.SyncModeFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-Requires a first argument of the file to write to.
-Optional second and third arguments control the first and
-last block to write. In this mode, the file will be appended
-if already existing. If the file ends with .gz, the output will
-be gzipped.`,
- }
- importPreimagesCommand = cli.Command{
- Action: utils.MigrateFlags(importPreimages),
- Name: "import-preimages",
- Usage: "Import the preimage database from an RLP stream",
- ArgsUsage: "",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.CacheFlag,
- utils.SyncModeFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
- The import-preimages command imports hash preimages from an RLP encoded stream.`,
- }
- exportPreimagesCommand = cli.Command{
- Action: utils.MigrateFlags(exportPreimages),
- Name: "export-preimages",
- Usage: "Export the preimage database into an RLP stream",
- ArgsUsage: "",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.CacheFlag,
- utils.SyncModeFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-The export-preimages command export hash preimages to an RLP encoded stream`,
- }
- copydbCommand = cli.Command{
- Action: utils.MigrateFlags(copyDb),
- Name: "copydb",
- Usage: "Create a local chain from a target chaindata folder",
- ArgsUsage: "",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.CacheFlag,
- utils.SyncModeFlag,
- utils.FakePoWFlag,
- utils.TestnetFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-The first argument must be the directory containing the blockchain to download from`,
- }
- removedbCommand = cli.Command{
- Action: utils.MigrateFlags(removeDB),
- Name: "removedb",
- Usage: "Remove blockchain and state databases",
- ArgsUsage: " ",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-Remove blockchain and state databases`,
- }
- dumpCommand = cli.Command{
- Action: utils.MigrateFlags(dump),
- Name: "dump",
- Usage: "Dump a specific block from storage",
- ArgsUsage: "[ | ]...",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.CacheFlag,
- utils.SyncModeFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- Description: `
-The arguments are interpreted as block numbers or hashes.
-Use "ethereum dump 0" to dump the genesis block.`,
- }
-)
-
-// initGenesis will initialise the given JSON format genesis file and writes it as
-// the zero'd block (i.e. genesis) or will fail hard if it can't succeed.
-func initGenesis(ctx *cli.Context) error {
- // Make sure we have a valid genesis JSON
- genesisPath := ctx.Args().First()
- if len(genesisPath) == 0 {
- utils.Fatalf("Must supply path to genesis JSON file")
- }
- file, err := os.Open(genesisPath)
- if err != nil {
- utils.Fatalf("Failed to read genesis file: %v", err)
- }
- defer file.Close()
-
- genesis := new(core.Genesis)
- if err := json.NewDecoder(file).Decode(genesis); err != nil {
- utils.Fatalf("invalid genesis file: %v", err)
- }
- // Open an initialise both full and light databases
- stack := makeFullNode(ctx)
- for _, name := range []string{"chaindata", "lightchaindata"} {
- chaindb, err := stack.OpenDatabase(name, 0, 0)
- if err != nil {
- utils.Fatalf("Failed to open database: %v", err)
- }
- _, hash, err := core.SetupGenesisBlock(chaindb, genesis)
- if err != nil {
- utils.Fatalf("Failed to write genesis block: %v", err)
- }
- log.Info("Successfully wrote genesis state", "database", name, "hash", hash)
- }
- return nil
-}
-
-func importChain(ctx *cli.Context) error {
- if len(ctx.Args()) < 1 {
- utils.Fatalf("This command requires an argument.")
- }
- stack := makeFullNode(ctx)
- chain, chainDb := utils.MakeChain(ctx, stack)
- defer chainDb.Close()
-
- // Start periodically gathering memory profiles
- var peakMemAlloc, peakMemSys uint64
- go func() {
- stats := new(runtime.MemStats)
- for {
- runtime.ReadMemStats(stats)
- if atomic.LoadUint64(&peakMemAlloc) < stats.Alloc {
- atomic.StoreUint64(&peakMemAlloc, stats.Alloc)
- }
- if atomic.LoadUint64(&peakMemSys) < stats.Sys {
- atomic.StoreUint64(&peakMemSys, stats.Sys)
- }
- time.Sleep(5 * time.Second)
- }
- }()
- // Import the chain
- start := time.Now()
-
- if len(ctx.Args()) == 1 {
- if err := utils.ImportChain(chain, ctx.Args().First()); err != nil {
- log.Error("Import error", "err", err)
- }
- } else {
- for _, arg := range ctx.Args() {
- if err := utils.ImportChain(chain, arg); err != nil {
- log.Error("Import error", "file", arg, "err", err)
- }
- }
- }
- chain.Stop()
- fmt.Printf("Import done in %v.\n\n", time.Since(start))
-
- // Output pre-compaction stats mostly to see the import trashing
- db := chainDb.(*ethdb.LDBDatabase)
-
- stats, err := db.LDB().GetProperty("leveldb.stats")
- if err != nil {
- utils.Fatalf("Failed to read database stats: %v", err)
- }
- fmt.Println(stats)
-
- ioStats, err := db.LDB().GetProperty("leveldb.iostats")
- if err != nil {
- utils.Fatalf("Failed to read database iostats: %v", err)
- }
- fmt.Println(ioStats)
-
- fmt.Printf("Trie cache misses: %d\n", trie.CacheMisses())
- fmt.Printf("Trie cache unloads: %d\n\n", trie.CacheUnloads())
-
- // Print the memory statistics used by the importing
- mem := new(runtime.MemStats)
- runtime.ReadMemStats(mem)
-
- fmt.Printf("Object memory: %.3f MB current, %.3f MB peak\n", float64(mem.Alloc)/1024/1024, float64(atomic.LoadUint64(&peakMemAlloc))/1024/1024)
- fmt.Printf("System memory: %.3f MB current, %.3f MB peak\n", float64(mem.Sys)/1024/1024, float64(atomic.LoadUint64(&peakMemSys))/1024/1024)
- fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000)
- fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs))
-
- if ctx.GlobalIsSet(utils.NoCompactionFlag.Name) {
- return nil
- }
-
- // Compact the entire database to more accurately measure disk io and print the stats
- start = time.Now()
- fmt.Println("Compacting entire database...")
- if err = db.LDB().CompactRange(util.Range{}); err != nil {
- utils.Fatalf("Compaction failed: %v", err)
- }
- fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
-
- stats, err = db.LDB().GetProperty("leveldb.stats")
- if err != nil {
- utils.Fatalf("Failed to read database stats: %v", err)
- }
- fmt.Println(stats)
-
- ioStats, err = db.LDB().GetProperty("leveldb.iostats")
- if err != nil {
- utils.Fatalf("Failed to read database iostats: %v", err)
- }
- fmt.Println(ioStats)
-
- return nil
-}
-
-func exportChain(ctx *cli.Context) error {
- if len(ctx.Args()) < 1 {
- utils.Fatalf("This command requires an argument.")
- }
- stack := makeFullNode(ctx)
- chain, _ := utils.MakeChain(ctx, stack)
- start := time.Now()
-
- var err error
- fp := ctx.Args().First()
- if len(ctx.Args()) < 3 {
- err = utils.ExportChain(chain, fp)
- } else {
- // This can be improved to allow for numbers larger than 9223372036854775807
- first, ferr := strconv.ParseInt(ctx.Args().Get(1), 10, 64)
- last, lerr := strconv.ParseInt(ctx.Args().Get(2), 10, 64)
- if ferr != nil || lerr != nil {
- utils.Fatalf("Export error in parsing parameters: block number not an integer\n")
- }
- if first < 0 || last < 0 {
- utils.Fatalf("Export error: block number must be greater than 0\n")
- }
- err = utils.ExportAppendChain(chain, fp, uint64(first), uint64(last))
- }
-
- if err != nil {
- utils.Fatalf("Export error: %v\n", err)
- }
- fmt.Printf("Export done in %v\n", time.Since(start))
- return nil
-}
-
-// importPreimages imports preimage data from the specified file.
-func importPreimages(ctx *cli.Context) error {
- if len(ctx.Args()) < 1 {
- utils.Fatalf("This command requires an argument.")
- }
- stack := makeFullNode(ctx)
- diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase)
-
- start := time.Now()
- if err := utils.ImportPreimages(diskdb, ctx.Args().First()); err != nil {
- utils.Fatalf("Import error: %v\n", err)
- }
- fmt.Printf("Import done in %v\n", time.Since(start))
- return nil
-}
-
-// exportPreimages dumps the preimage data to specified json file in streaming way.
-func exportPreimages(ctx *cli.Context) error {
- if len(ctx.Args()) < 1 {
- utils.Fatalf("This command requires an argument.")
- }
- stack := makeFullNode(ctx)
- diskdb := utils.MakeChainDatabase(ctx, stack).(*ethdb.LDBDatabase)
-
- start := time.Now()
- if err := utils.ExportPreimages(diskdb, ctx.Args().First()); err != nil {
- utils.Fatalf("Export error: %v\n", err)
- }
- fmt.Printf("Export done in %v\n", time.Since(start))
- return nil
-}
-
-func copyDb(ctx *cli.Context) error {
- // Ensure we have a source chain directory to copy
- if len(ctx.Args()) != 1 {
- utils.Fatalf("Source chaindata directory path argument missing")
- }
- // Initialize a new chain for the running node to sync into
- stack := makeFullNode(ctx)
- chain, chainDb := utils.MakeChain(ctx, stack)
-
- syncmode := *utils.GlobalTextMarshaler(ctx, utils.SyncModeFlag.Name).(*downloader.SyncMode)
- dl := downloader.New(syncmode, chainDb, new(event.TypeMux), chain, nil, nil)
-
- // Create a source peer to satisfy downloader requests from
- db, err := ethdb.NewLDBDatabase(ctx.Args().First(), ctx.GlobalInt(utils.CacheFlag.Name), 256)
- if err != nil {
- return err
- }
- hc, err := core.NewHeaderChain(db, chain.Config(), chain.Engine(), func() bool { return false })
- if err != nil {
- return err
- }
- peer := downloader.NewFakePeer("local", db, hc, dl)
- if err = dl.RegisterPeer("local", 63, peer); err != nil {
- return err
- }
- // Synchronise with the simulated peer
- start := time.Now()
-
- currentHeader := hc.CurrentHeader()
- if err = dl.Synchronise("local", currentHeader.Hash(), hc.GetTd(currentHeader.Hash(), currentHeader.Number.Uint64()), syncmode); err != nil {
- return err
- }
- for dl.Synchronising() {
- time.Sleep(10 * time.Millisecond)
- }
- fmt.Printf("Database copy done in %v\n", time.Since(start))
-
- // Compact the entire database to remove any sync overhead
- start = time.Now()
- fmt.Println("Compacting entire database...")
- if err = chainDb.(*ethdb.LDBDatabase).LDB().CompactRange(util.Range{}); err != nil {
- utils.Fatalf("Compaction failed: %v", err)
- }
- fmt.Printf("Compaction done in %v.\n\n", time.Since(start))
-
- return nil
-}
-
-func removeDB(ctx *cli.Context) error {
- stack, _ := makeConfigNode(ctx)
-
- for _, name := range []string{"chaindata", "lightchaindata"} {
- // Ensure the database exists in the first place
- logger := log.New("database", name)
-
- dbdir := stack.ResolvePath(name)
- if !common.FileExist(dbdir) {
- logger.Info("Database doesn't exist, skipping", "path", dbdir)
- continue
- }
- // Confirm removal and execute
- fmt.Println(dbdir)
- confirm, err := console.Stdin.PromptConfirm("Remove this database?")
- switch {
- case err != nil:
- utils.Fatalf("%v", err)
- case !confirm:
- logger.Warn("Database deletion aborted")
- default:
- start := time.Now()
- os.RemoveAll(dbdir)
- logger.Info("Database successfully deleted", "elapsed", common.PrettyDuration(time.Since(start)))
- }
- }
- return nil
-}
-
-func dump(ctx *cli.Context) error {
- stack := makeFullNode(ctx)
- chain, chainDb := utils.MakeChain(ctx, stack)
- for _, arg := range ctx.Args() {
- var block *types.Block
- if hashish(arg) {
- block = chain.GetBlockByHash(common.HexToHash(arg))
- } else {
- num, _ := strconv.Atoi(arg)
- block = chain.GetBlockByNumber(uint64(num))
- }
- if block == nil {
- fmt.Println("{}")
- utils.Fatalf("block not found")
- } else {
- state, err := state.New(block.Root(), state.NewDatabase(chainDb))
- if err != nil {
- utils.Fatalf("could not create new state: %v", err)
- }
- fmt.Printf("%s\n", state.Dump())
- }
- }
- chainDb.Close()
- return nil
-}
-
-// hashish returns true for strings that look like hashes.
-func hashish(x string) bool {
- _, err := strconv.Atoi(x)
- return err != nil
-}
diff --git a/cmd/geth/config.go b/cmd/geth/config.go
deleted file mode 100644
index 0c526f438..000000000
--- a/cmd/geth/config.go
+++ /dev/null
@@ -1,201 +0,0 @@
-// 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 .
-
-package main
-
-import (
- "bufio"
- "errors"
- "fmt"
- "io"
- "os"
- "reflect"
- "unicode"
-
- cli "gopkg.in/urfave/cli.v1"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/dashboard"
- "github.com/dexon-foundation/dexon/dex"
- "github.com/dexon-foundation/dexon/node"
- "github.com/dexon-foundation/dexon/params"
- whisper "github.com/dexon-foundation/dexon/whisper/whisperv6"
- "github.com/naoina/toml"
-)
-
-var (
- dumpConfigCommand = cli.Command{
- Action: utils.MigrateFlags(dumpConfig),
- Name: "dumpconfig",
- Usage: "Show configuration values",
- ArgsUsage: "",
- Flags: append(append(nodeFlags, rpcFlags...), whisperFlags...),
- Category: "MISCELLANEOUS COMMANDS",
- Description: `The dumpconfig command shows configuration values.`,
- }
-
- configFileFlag = cli.StringFlag{
- Name: "config",
- Usage: "TOML configuration file",
- }
-)
-
-// These settings ensure that TOML keys use the same names as Go struct fields.
-var tomlSettings = toml.Config{
- NormFieldName: func(rt reflect.Type, key string) string {
- return key
- },
- FieldToKey: func(rt reflect.Type, field string) string {
- return field
- },
- MissingField: func(rt reflect.Type, field string) error {
- link := ""
- if unicode.IsUpper(rune(rt.Name()[0])) && rt.PkgPath() != "main" {
- link = fmt.Sprintf(", see https://godoc.org/%s#%s for available fields", rt.PkgPath(), rt.Name())
- }
- return fmt.Errorf("field '%s' is not defined in %s%s", field, rt.String(), link)
- },
-}
-
-type ethstatsConfig struct {
- URL string `toml:",omitempty"`
-}
-
-type gethConfig struct {
- Dex dex.Config
- Shh whisper.Config
- Node node.Config
- Ethstats ethstatsConfig
- Dashboard dashboard.Config
-}
-
-func loadConfig(file string, cfg *gethConfig) error {
- f, err := os.Open(file)
- if err != nil {
- return err
- }
- defer f.Close()
-
- err = tomlSettings.NewDecoder(bufio.NewReader(f)).Decode(cfg)
- // Add file name to errors that have a line number.
- if _, ok := err.(*toml.LineError); ok {
- err = errors.New(file + ", " + err.Error())
- }
- return err
-}
-
-func defaultNodeConfig() node.Config {
- cfg := node.DefaultConfig
- cfg.Name = clientIdentifier
- cfg.Version = params.VersionWithCommit(gitCommit)
- cfg.HTTPModules = append(cfg.HTTPModules, "eth", "shh")
- cfg.WSModules = append(cfg.WSModules, "eth", "shh")
- cfg.IPCPath = "geth.ipc"
- return cfg
-}
-
-func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
- // Load defaults.
- cfg := gethConfig{
- Dex: dex.DefaultConfig,
- Shh: whisper.DefaultConfig,
- Node: defaultNodeConfig(),
- Dashboard: dashboard.DefaultConfig,
- }
-
- // Load config file.
- if file := ctx.GlobalString(configFileFlag.Name); file != "" {
- if err := loadConfig(file, &cfg); err != nil {
- utils.Fatalf("%v", err)
- }
- }
-
- // Apply flags.
- utils.SetNodeConfig(ctx, &cfg.Node)
- stack, err := node.New(&cfg.Node)
- if err != nil {
- utils.Fatalf("Failed to create the protocol stack: %v", err)
- }
- utils.SetDexConfig(ctx, stack, &cfg.Dex)
- if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) {
- cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name)
- }
-
- utils.SetShhConfig(ctx, stack, &cfg.Shh)
- utils.SetDashboardConfig(ctx, &cfg.Dashboard)
-
- return stack, cfg
-}
-
-// enableWhisper returns true in case one of the whisper flags is set.
-func enableWhisper(ctx *cli.Context) bool {
- for _, flag := range whisperFlags {
- if ctx.GlobalIsSet(flag.GetName()) {
- return true
- }
- }
- return false
-}
-
-func makeFullNode(ctx *cli.Context) *node.Node {
- stack, cfg := makeConfigNode(ctx)
-
- utils.RegisterDexService(stack, &cfg.Dex)
-
- if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
- 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)
- shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name)
- if shhEnabled || shhAutoEnabled {
- if ctx.GlobalIsSet(utils.WhisperMaxMessageSizeFlag.Name) {
- cfg.Shh.MaxMessageSize = uint32(ctx.Int(utils.WhisperMaxMessageSizeFlag.Name))
- }
- if ctx.GlobalIsSet(utils.WhisperMinPOWFlag.Name) {
- cfg.Shh.MinimumAcceptedPOW = ctx.Float64(utils.WhisperMinPOWFlag.Name)
- }
- if ctx.GlobalIsSet(utils.WhisperRestrictConnectionBetweenLightClientsFlag.Name) {
- cfg.Shh.RestrictConnectionBetweenLightClients = true
- }
- utils.RegisterShhService(stack, &cfg.Shh)
- }
-
- // Add the Ethereum Stats daemon if requested.
- if cfg.Ethstats.URL != "" {
- utils.RegisterEthStatsService(stack, cfg.Ethstats.URL)
- }
- return stack
-}
-
-// dumpConfig is the dumpconfig command.
-func dumpConfig(ctx *cli.Context) error {
- _, cfg := makeConfigNode(ctx)
- comment := ""
-
- if cfg.Dex.Genesis != nil {
- cfg.Dex.Genesis = nil
- comment += "# Note: this config doesn't contain the genesis block.\n\n"
- }
-
- out, err := tomlSettings.Marshal(&cfg)
- if err != nil {
- return err
- }
- io.WriteString(os.Stdout, comment)
- os.Stdout.Write(out)
- return nil
-}
diff --git a/cmd/geth/consolecmd.go b/cmd/geth/consolecmd.go
deleted file mode 100644
index 339919c8d..000000000
--- a/cmd/geth/consolecmd.go
+++ /dev/null
@@ -1,218 +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 .
-
-package main
-
-import (
- "fmt"
- "os"
- "os/signal"
- "path/filepath"
- "strings"
- "syscall"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/console"
- "github.com/dexon-foundation/dexon/node"
- "github.com/dexon-foundation/dexon/rpc"
- "gopkg.in/urfave/cli.v1"
-)
-
-var (
- consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag}
-
- consoleCommand = cli.Command{
- Action: utils.MigrateFlags(localConsole),
- Name: "console",
- Usage: "Start an interactive JavaScript environment",
- Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), whisperFlags...),
- Category: "CONSOLE COMMANDS",
- Description: `
-The Geth console is an interactive shell for the JavaScript runtime environment
-which exposes a node admin interface as well as the Ðapp JavaScript API.
-See https://github.com/dexon-foundation/dexon/wiki/JavaScript-Console.`,
- }
-
- attachCommand = cli.Command{
- Action: utils.MigrateFlags(remoteConsole),
- Name: "attach",
- Usage: "Start an interactive JavaScript environment (connect to node)",
- ArgsUsage: "[endpoint]",
- Flags: append(consoleFlags, utils.DataDirFlag),
- Category: "CONSOLE COMMANDS",
- Description: `
-The Geth console is an interactive shell for the JavaScript runtime environment
-which exposes a node admin interface as well as the Ðapp JavaScript API.
-See https://github.com/dexon-foundation/dexon/wiki/JavaScript-Console.
-This command allows to open a console on a running geth node.`,
- }
-
- javascriptCommand = cli.Command{
- Action: utils.MigrateFlags(ephemeralConsole),
- Name: "js",
- Usage: "Execute the specified JavaScript files",
- ArgsUsage: " [jsfile...]",
- Flags: append(nodeFlags, consoleFlags...),
- Category: "CONSOLE COMMANDS",
- Description: `
-The JavaScript VM exposes a node admin interface as well as the Ðapp
-JavaScript API. See https://github.com/dexon-foundation/dexon/wiki/JavaScript-Console`,
- }
-)
-
-// localConsole starts a new geth node, attaching a JavaScript console to it at the
-// same time.
-func localConsole(ctx *cli.Context) error {
- // Create and start the node based on the CLI flags
- node := makeFullNode(ctx)
- startNode(ctx, node)
- defer node.Stop()
-
- // Attach to the newly started node and start the JavaScript console
- client, err := node.Attach()
- if err != nil {
- utils.Fatalf("Failed to attach to the inproc geth: %v", err)
- }
- config := console.Config{
- DataDir: utils.MakeDataDir(ctx),
- DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
- Client: client,
- Preload: utils.MakeConsolePreloads(ctx),
- }
-
- console, err := console.New(config)
- if err != nil {
- utils.Fatalf("Failed to start the JavaScript console: %v", err)
- }
- defer console.Stop(false)
-
- // If only a short execution was requested, evaluate and return
- if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
- console.Evaluate(script)
- return nil
- }
- // Otherwise print the welcome screen and enter interactive mode
- console.Welcome()
- console.Interactive()
-
- return nil
-}
-
-// remoteConsole will connect to a remote geth instance, attaching a JavaScript
-// console to it.
-func remoteConsole(ctx *cli.Context) error {
- // Attach to a remotely running geth instance and start the JavaScript console
- endpoint := ctx.Args().First()
- if endpoint == "" {
- path := node.DefaultDataDir()
- if ctx.GlobalIsSet(utils.DataDirFlag.Name) {
- path = ctx.GlobalString(utils.DataDirFlag.Name)
- }
- if path != "" {
- if ctx.GlobalBool(utils.TestnetFlag.Name) {
- path = filepath.Join(path, "testnet")
- }
- }
- endpoint = fmt.Sprintf("%s/geth.ipc", path)
- }
- client, err := dialRPC(endpoint)
- if err != nil {
- utils.Fatalf("Unable to attach to remote geth: %v", err)
- }
- config := console.Config{
- DataDir: utils.MakeDataDir(ctx),
- DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
- Client: client,
- Preload: utils.MakeConsolePreloads(ctx),
- }
-
- console, err := console.New(config)
- if err != nil {
- utils.Fatalf("Failed to start the JavaScript console: %v", err)
- }
- defer console.Stop(false)
-
- if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
- console.Evaluate(script)
- return nil
- }
-
- // Otherwise print the welcome screen and enter interactive mode
- console.Welcome()
- console.Interactive()
-
- return nil
-}
-
-// dialRPC returns a RPC client which connects to the given endpoint.
-// The check for empty endpoint implements the defaulting logic
-// for "geth attach" and "geth monitor" with no argument.
-func dialRPC(endpoint string) (*rpc.Client, error) {
- if endpoint == "" {
- endpoint = node.DefaultIPCEndpoint(clientIdentifier)
- } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") {
- // Backwards compatibility with geth < 1.5 which required
- // these prefixes.
- endpoint = endpoint[4:]
- }
- return rpc.Dial(endpoint)
-}
-
-// ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript
-// console to it, executes each of the files specified as arguments and tears
-// everything down.
-func ephemeralConsole(ctx *cli.Context) error {
- // Create and start the node based on the CLI flags
- node := makeFullNode(ctx)
- startNode(ctx, node)
- defer node.Stop()
-
- // Attach to the newly started node and start the JavaScript console
- client, err := node.Attach()
- if err != nil {
- utils.Fatalf("Failed to attach to the inproc geth: %v", err)
- }
- config := console.Config{
- DataDir: utils.MakeDataDir(ctx),
- DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
- Client: client,
- Preload: utils.MakeConsolePreloads(ctx),
- }
-
- console, err := console.New(config)
- if err != nil {
- utils.Fatalf("Failed to start the JavaScript console: %v", err)
- }
- defer console.Stop(false)
-
- // Evaluate each of the specified JavaScript files
- for _, file := range ctx.Args() {
- if err = console.Execute(file); err != nil {
- utils.Fatalf("Failed to execute %s: %v", file, err)
- }
- }
- // Wait for pending callbacks, but stop for Ctrl-C.
- abort := make(chan os.Signal, 1)
- signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM)
-
- go func() {
- <-abort
- os.Exit(0)
- }()
- console.Stop(true)
-
- return nil
-}
diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go
deleted file mode 100644
index 1e3363c0d..000000000
--- a/cmd/geth/consolecmd_test.go
+++ /dev/null
@@ -1,163 +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 .
-
-package main
-
-import (
- "crypto/rand"
- "math/big"
- "os"
- "path/filepath"
- "runtime"
- "strconv"
- "strings"
- "testing"
- "time"
-
- "github.com/dexon-foundation/dexon/params"
-)
-
-const (
- ipcAPIs = "admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0"
- httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0"
-)
-
-// Tests that a node embedded within a console can be started up properly and
-// then terminated by closing the input stream.
-func TestConsoleWelcome(t *testing.T) {
- coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
-
- // Start a geth console, make sure it's cleaned up and terminate the console
- geth := runGeth(t,
- "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
- "--etherbase", coinbase, "--shh",
- "console")
-
- // Gather all the infos the welcome message needs to contain
- geth.SetTemplateFunc("goos", func() string { return runtime.GOOS })
- geth.SetTemplateFunc("goarch", func() string { return runtime.GOARCH })
- geth.SetTemplateFunc("gover", runtime.Version)
- geth.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta })
- geth.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) })
- geth.SetTemplateFunc("apis", func() string { return ipcAPIs })
-
- // Verify the actual welcome message to the required template
- geth.Expect(`
-Welcome to the Geth JavaScript console!
-
-instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
-coinbase: {{.Etherbase}}
-at block: 0 ({{niltime}})
- datadir: {{.Datadir}}
- modules: {{apis}}
-
-> {{.InputLine "exit"}}
-`)
- geth.ExpectExit()
-}
-
-// Tests that a console can be attached to a running node via various means.
-func TestIPCAttachWelcome(t *testing.T) {
- // Configure the instance for IPC attachement
- coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
- var ipc string
- if runtime.GOOS == "windows" {
- ipc = `\\.\pipe\geth` + strconv.Itoa(trulyRandInt(100000, 999999))
- } else {
- ws := tmpdir(t)
- defer os.RemoveAll(ws)
- ipc = filepath.Join(ws, "geth.ipc")
- }
- // Note: we need --shh because testAttachWelcome checks for default
- // list of ipc modules and shh is included there.
- geth := runGeth(t,
- "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
- "--etherbase", coinbase, "--shh", "--ipcpath", ipc)
-
- time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
- testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs)
-
- geth.Interrupt()
- geth.ExpectExit()
-}
-
-func TestHTTPAttachWelcome(t *testing.T) {
- coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
- port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P
- geth := runGeth(t,
- "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
- "--etherbase", coinbase, "--rpc", "--rpcport", port)
-
- time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
- testAttachWelcome(t, geth, "http://localhost:"+port, httpAPIs)
-
- geth.Interrupt()
- geth.ExpectExit()
-}
-
-func TestWSAttachWelcome(t *testing.T) {
- coinbase := "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182"
- port := strconv.Itoa(trulyRandInt(1024, 65536)) // Yeah, sometimes this will fail, sorry :P
-
- geth := runGeth(t,
- "--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none",
- "--etherbase", coinbase, "--ws", "--wsport", port)
-
- time.Sleep(2 * time.Second) // Simple way to wait for the RPC endpoint to open
- testAttachWelcome(t, geth, "ws://localhost:"+port, httpAPIs)
-
- geth.Interrupt()
- geth.ExpectExit()
-}
-
-func testAttachWelcome(t *testing.T, geth *testgeth, endpoint, apis string) {
- // Attach to a running geth note and terminate immediately
- attach := runGeth(t, "attach", endpoint)
- defer attach.ExpectExit()
- attach.CloseStdin()
-
- // Gather all the infos the welcome message needs to contain
- attach.SetTemplateFunc("goos", func() string { return runtime.GOOS })
- attach.SetTemplateFunc("goarch", func() string { return runtime.GOARCH })
- attach.SetTemplateFunc("gover", runtime.Version)
- attach.SetTemplateFunc("gethver", func() string { return params.VersionWithMeta })
- attach.SetTemplateFunc("etherbase", func() string { return geth.Etherbase })
- attach.SetTemplateFunc("niltime", func() string { return time.Unix(0, 0).Format(time.RFC1123) })
- attach.SetTemplateFunc("ipc", func() bool { return strings.HasPrefix(endpoint, "ipc") })
- attach.SetTemplateFunc("datadir", func() string { return geth.Datadir })
- attach.SetTemplateFunc("apis", func() string { return apis })
-
- // Verify the actual welcome message to the required template
- attach.Expect(`
-Welcome to the Geth JavaScript console!
-
-instance: Geth/v{{gethver}}/{{goos}}-{{goarch}}/{{gover}}
-coinbase: {{etherbase}}
-at block: 0 ({{niltime}}){{if ipc}}
- datadir: {{datadir}}{{end}}
- modules: {{apis}}
-
-> {{.InputLine "exit" }}
-`)
- attach.ExpectExit()
-}
-
-// trulyRandInt generates a crypto random integer used by the console tests to
-// not clash network ports with other tests running cocurrently.
-func trulyRandInt(lo, hi int) int {
- num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo)))
- return int(num.Int64()) + lo
-}
diff --git a/cmd/geth/dao_test.go b/cmd/geth/dao_test.go
deleted file mode 100644
index b4aefe9dd..000000000
--- a/cmd/geth/dao_test.go
+++ /dev/null
@@ -1,152 +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 .
-
-package main
-
-import (
- "io/ioutil"
- "math/big"
- "os"
- "path/filepath"
- "testing"
-
- "github.com/dexon-foundation/dexon/common"
- "github.com/dexon-foundation/dexon/core/rawdb"
- "github.com/dexon-foundation/dexon/ethdb"
- "github.com/dexon-foundation/dexon/params"
-)
-
-// Genesis block for nodes which don't care about the DAO fork (i.e. not configured)
-var daoOldGenesis = `{
- "alloc" : {},
- "coinbase" : "0x0000000000000000000000000000000000000000",
- "difficulty" : "0x20000",
- "extraData" : "",
- "gasLimit" : "0x2fefd8",
- "nonce" : "0x0000000000000042",
- "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp" : "0x00",
- "config" : {}
-}`
-
-// Genesis block for nodes which actively oppose the DAO fork
-var daoNoForkGenesis = `{
- "alloc" : {},
- "coinbase" : "0x0000000000000000000000000000000000000000",
- "difficulty" : "0x20000",
- "extraData" : "",
- "gasLimit" : "0x2fefd8",
- "nonce" : "0x0000000000000042",
- "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp" : "0x00",
- "config" : {
- "daoForkBlock" : 314,
- "daoForkSupport" : false
- }
-}`
-
-// Genesis block for nodes which actively support the DAO fork
-var daoProForkGenesis = `{
- "alloc" : {},
- "coinbase" : "0x0000000000000000000000000000000000000000",
- "difficulty" : "0x20000",
- "extraData" : "",
- "gasLimit" : "0x2fefd8",
- "nonce" : "0x0000000000000042",
- "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp" : "0x00",
- "config" : {
- "daoForkBlock" : 314,
- "daoForkSupport" : true
- }
-}`
-
-var daoGenesisHash = common.HexToHash("5e1fc79cb4ffa4739177b5408045cd5d51c6cf766133f23f7cd72ee1f8d790e0")
-var daoGenesisForkBlock = big.NewInt(314)
-
-// TestDAOForkBlockNewChain tests that the DAO hard-fork number and the nodes support/opposition is correctly
-// set in the database after various initialization procedures and invocations.
-func TestDAOForkBlockNewChain(t *testing.T) {
- for i, arg := range []struct {
- genesis string
- expectBlock *big.Int
- expectVote bool
- }{
- // Test DAO Default Mainnet
- {"", params.MainnetChainConfig.DAOForkBlock, true},
- // test DAO Init Old Privnet
- {daoOldGenesis, nil, false},
- // test DAO Default No Fork Privnet
- {daoNoForkGenesis, daoGenesisForkBlock, false},
- // test DAO Default Pro Fork Privnet
- {daoProForkGenesis, daoGenesisForkBlock, true},
- } {
- testDAOForkBlockNewChain(t, i, arg.genesis, arg.expectBlock, arg.expectVote)
- }
-}
-
-func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBlock *big.Int, expectVote bool) {
- // Create a temporary data directory to use and inspect later
- datadir := tmpdir(t)
- defer os.RemoveAll(datadir)
-
- // Start a Geth instance with the requested flags set and immediately terminate
- if genesis != "" {
- json := filepath.Join(datadir, "genesis.json")
- if err := ioutil.WriteFile(json, []byte(genesis), 0600); err != nil {
- t.Fatalf("test %d: failed to write genesis file: %v", test, err)
- }
- runGeth(t, "--datadir", datadir, "init", json).WaitExit()
- } else {
- // Force chain initialization
- args := []string{"--port", "0", "--maxpeers", "0", "--nodiscover", "--nat", "none", "--ipcdisable", "--datadir", datadir}
- geth := runGeth(t, append(args, []string{"--exec", "2+2", "console"}...)...)
- geth.WaitExit()
- }
- // Retrieve the DAO config flag from the database
- path := filepath.Join(datadir, "geth", "chaindata")
- db, err := ethdb.NewLDBDatabase(path, 0, 0)
- if err != nil {
- t.Fatalf("test %d: failed to open test database: %v", test, err)
- }
- defer db.Close()
-
- genesisHash := common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
- if genesis != "" {
- genesisHash = daoGenesisHash
- }
- config := rawdb.ReadChainConfig(db, genesisHash)
- if config == nil {
- t.Errorf("test %d: failed to retrieve chain config: %v", test, err)
- return // we want to return here, the other checks can't make it past this point (nil panic).
- }
- // Validate the DAO hard-fork block number against the expected value
- if config.DAOForkBlock == nil {
- if expectBlock != nil {
- t.Errorf("test %d: dao hard-fork block mismatch: have nil, want %v", test, expectBlock)
- }
- } else if expectBlock == nil {
- t.Errorf("test %d: dao hard-fork block mismatch: have %v, want nil", test, config.DAOForkBlock)
- } else if config.DAOForkBlock.Cmp(expectBlock) != 0 {
- t.Errorf("test %d: dao hard-fork block mismatch: have %v, want %v", test, config.DAOForkBlock, expectBlock)
- }
- if config.DAOForkSupport != expectVote {
- t.Errorf("test %d: dao hard-fork support mismatch: have %v, want %v", test, config.DAOForkSupport, expectVote)
- }
-}
diff --git a/cmd/geth/genesis_test.go b/cmd/geth/genesis_test.go
deleted file mode 100644
index e75b542cb..000000000
--- a/cmd/geth/genesis_test.go
+++ /dev/null
@@ -1,110 +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 .
-
-package main
-
-import (
- "io/ioutil"
- "os"
- "path/filepath"
- "testing"
-)
-
-var customGenesisTests = []struct {
- genesis string
- query string
- result string
-}{
- // Plain genesis file without anything extra
- {
- genesis: `{
- "alloc" : {},
- "coinbase" : "0x0000000000000000000000000000000000000000",
- "difficulty" : "0x20000",
- "extraData" : "",
- "gasLimit" : "0x2fefd8",
- "nonce" : "0x0000000000000042",
- "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp" : "0x00"
- }`,
- query: "eth.getBlock(0).nonce",
- result: "0x0000000000000042",
- },
- // Genesis file with an empty chain configuration (ensure missing fields work)
- {
- genesis: `{
- "alloc" : {},
- "coinbase" : "0x0000000000000000000000000000000000000000",
- "difficulty" : "0x20000",
- "extraData" : "",
- "gasLimit" : "0x2fefd8",
- "nonce" : "0x0000000000000042",
- "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp" : "0x00",
- "config" : {}
- }`,
- query: "eth.getBlock(0).nonce",
- result: "0x0000000000000042",
- },
- // Genesis file with specific chain configurations
- {
- genesis: `{
- "alloc" : {},
- "coinbase" : "0x0000000000000000000000000000000000000000",
- "difficulty" : "0x20000",
- "extraData" : "",
- "gasLimit" : "0x2fefd8",
- "nonce" : "0x0000000000000042",
- "mixhash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "parentHash" : "0x0000000000000000000000000000000000000000000000000000000000000000",
- "timestamp" : "0x00",
- "config" : {
- "homesteadBlock" : 314,
- "daoForkBlock" : 141,
- "daoForkSupport" : true
- }
- }`,
- query: "eth.getBlock(0).nonce",
- result: "0x0000000000000042",
- },
-}
-
-// Tests that initializing Geth with a custom genesis block and chain definitions
-// work properly.
-func TestCustomGenesis(t *testing.T) {
- for i, tt := range customGenesisTests {
- // Create a temporary data directory to use and inspect later
- datadir := tmpdir(t)
- defer os.RemoveAll(datadir)
-
- // Initialize the data directory with the custom genesis block
- json := filepath.Join(datadir, "genesis.json")
- if err := ioutil.WriteFile(json, []byte(tt.genesis), 0600); err != nil {
- t.Fatalf("test %d: failed to write genesis file: %v", i, err)
- }
- runGeth(t, "--datadir", datadir, "init", json).WaitExit()
-
- // Query the custom genesis block
- geth := runGeth(t,
- "--datadir", datadir, "--maxpeers", "0", "--port", "0",
- "--nodiscover", "--nat", "none", "--ipcdisable",
- "--exec", tt.query, "console")
- geth.ExpectRegexp(tt.result)
- geth.ExpectExit()
- }
-}
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
deleted file mode 100644
index 4ff0f42b3..000000000
--- a/cmd/geth/main.go
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright 2014 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 .
-
-// geth is the official command-line client for Ethereum.
-package main
-
-import (
- "fmt"
- "math"
- "os"
- godebug "runtime/debug"
- "sort"
- "strconv"
- "strings"
- "time"
-
- "github.com/dexon-foundation/dexon/accounts"
- "github.com/dexon-foundation/dexon/accounts/keystore"
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/console"
- "github.com/dexon-foundation/dexon/dex"
- "github.com/dexon-foundation/dexon/eth"
- "github.com/dexon-foundation/dexon/ethclient"
- "github.com/dexon-foundation/dexon/internal/debug"
- "github.com/dexon-foundation/dexon/log"
- "github.com/dexon-foundation/dexon/metrics"
- "github.com/dexon-foundation/dexon/node"
- "github.com/elastic/gosigar"
- "gopkg.in/urfave/cli.v1"
-)
-
-const (
- clientIdentifier = "geth" // Client identifier to advertise over the network
-)
-
-var (
- // Git SHA1 commit hash of the release (set via linker flags)
- gitCommit = ""
- // The app that holds all commands and flags.
- app = utils.NewApp(gitCommit, "the go-ethereum command line interface")
- // flags that configure the node
- nodeFlags = []cli.Flag{
- utils.IdentityFlag,
- utils.UnlockedAccountFlag,
- utils.PasswordFileFlag,
- utils.BootnodesFlag,
- utils.BootnodesV4Flag,
- utils.BootnodesV5Flag,
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.NoUSBFlag,
- utils.DashboardEnabledFlag,
- utils.DashboardAddrFlag,
- utils.DashboardPortFlag,
- utils.DashboardRefreshFlag,
- utils.EthashCacheDirFlag,
- utils.EthashCachesInMemoryFlag,
- utils.EthashCachesOnDiskFlag,
- utils.EthashDatasetDirFlag,
- utils.EthashDatasetsInMemoryFlag,
- utils.EthashDatasetsOnDiskFlag,
- utils.TxPoolLocalsFlag,
- utils.TxPoolNoLocalsFlag,
- utils.TxPoolJournalFlag,
- utils.TxPoolRejournalFlag,
- utils.TxPoolPriceLimitFlag,
- utils.TxPoolPriceBumpFlag,
- utils.TxPoolAccountSlotsFlag,
- utils.TxPoolGlobalSlotsFlag,
- utils.TxPoolAccountQueueFlag,
- utils.TxPoolGlobalQueueFlag,
- utils.TxPoolLifetimeFlag,
- utils.SyncModeFlag,
- utils.GCModeFlag,
- utils.LightServFlag,
- utils.LightPeersFlag,
- utils.LightKDFFlag,
- utils.WhitelistFlag,
- utils.CacheFlag,
- utils.CacheDatabaseFlag,
- utils.CacheTrieFlag,
- utils.CacheGCFlag,
- utils.TrieCacheGenFlag,
- utils.ListenPortFlag,
- utils.MaxPeersFlag,
- utils.MaxPendingPeersFlag,
- utils.ProposingEnabledFlag,
- utils.MiningEnabledFlag,
- utils.MinerThreadsFlag,
- utils.MinerLegacyThreadsFlag,
- utils.MinerNotifyFlag,
- utils.MinerGasTargetFlag,
- utils.MinerLegacyGasTargetFlag,
- utils.MinerGasLimitFlag,
- utils.MinerGasPriceFlag,
- utils.MinerLegacyGasPriceFlag,
- utils.MinerEtherbaseFlag,
- utils.MinerLegacyEtherbaseFlag,
- utils.MinerExtraDataFlag,
- utils.MinerLegacyExtraDataFlag,
- utils.MinerRecommitIntervalFlag,
- utils.MinerNoVerfiyFlag,
- utils.NATFlag,
- utils.NoDiscoverFlag,
- utils.DiscoveryV5Flag,
- utils.NetrestrictFlag,
- utils.NodeKeyFileFlag,
- utils.NodeKeyHexFlag,
- utils.DeveloperFlag,
- utils.DeveloperPeriodFlag,
- utils.TestnetFlag,
- utils.VMEnableDebugFlag,
- utils.NetworkIdFlag,
- utils.ConstantinopleOverrideFlag,
- utils.RPCCORSDomainFlag,
- utils.RPCVirtualHostsFlag,
- utils.EthStatsURLFlag,
- utils.MetricsEnabledFlag,
- utils.FakePoWFlag,
- utils.NoCompactionFlag,
- utils.GpoBlocksFlag,
- utils.GpoPercentileFlag,
- utils.EWASMInterpreterFlag,
- utils.EVMInterpreterFlag,
- configFileFlag,
- }
-
- rpcFlags = []cli.Flag{
- utils.RPCEnabledFlag,
- utils.RPCListenAddrFlag,
- utils.RPCPortFlag,
- utils.RPCApiFlag,
- utils.WSEnabledFlag,
- utils.WSListenAddrFlag,
- utils.WSPortFlag,
- utils.WSApiFlag,
- utils.WSAllowedOriginsFlag,
- utils.IPCDisabledFlag,
- utils.IPCPathFlag,
- }
-
- whisperFlags = []cli.Flag{
- utils.WhisperEnabledFlag,
- utils.WhisperMaxMessageSizeFlag,
- utils.WhisperMinPOWFlag,
- utils.WhisperRestrictConnectionBetweenLightClientsFlag,
- }
-
- metricsFlags = []cli.Flag{
- utils.MetricsEnableInfluxDBFlag,
- utils.MetricsInfluxDBEndpointFlag,
- utils.MetricsInfluxDBDatabaseFlag,
- utils.MetricsInfluxDBUsernameFlag,
- utils.MetricsInfluxDBPasswordFlag,
- utils.MetricsInfluxDBHostTagFlag,
- }
-)
-
-func init() {
- // Initialize the CLI app and start Geth
- app.Action = geth
- app.HideVersion = true // we have a command to print the version
- app.Copyright = "Copyright 2013-2018 The go-ethereum Authors"
- app.Commands = []cli.Command{
- // See chaincmd.go:
- initCommand,
- importCommand,
- exportCommand,
- importPreimagesCommand,
- exportPreimagesCommand,
- copydbCommand,
- removedbCommand,
- dumpCommand,
- // See monitorcmd.go:
- monitorCommand,
- // See accountcmd.go:
- accountCommand,
- walletCommand,
- // See consolecmd.go:
- consoleCommand,
- attachCommand,
- javascriptCommand,
- // See misccmd.go:
- makecacheCommand,
- makedagCommand,
- versionCommand,
- bugCommand,
- licenseCommand,
- // See config.go
- dumpConfigCommand,
- }
- sort.Sort(cli.CommandsByName(app.Commands))
-
- app.Flags = append(app.Flags, nodeFlags...)
- app.Flags = append(app.Flags, rpcFlags...)
- app.Flags = append(app.Flags, consoleFlags...)
- app.Flags = append(app.Flags, debug.Flags...)
- app.Flags = append(app.Flags, whisperFlags...)
- app.Flags = append(app.Flags, metricsFlags...)
-
- app.Before = func(ctx *cli.Context) error {
- logdir := ""
- if ctx.GlobalBool(utils.DashboardEnabledFlag.Name) {
- logdir = (&node.Config{DataDir: utils.MakeDataDir(ctx)}).ResolvePath("logs")
- }
- if err := debug.Setup(ctx, logdir); err != nil {
- return err
- }
- // Cap the cache allowance and tune the garbage collector
- var mem gosigar.Mem
- if err := mem.Get(); err == nil {
- allowance := int(mem.Total / 1024 / 1024 / 3)
- if cache := ctx.GlobalInt(utils.CacheFlag.Name); cache > allowance {
- log.Warn("Sanitizing cache to Go's GC limits", "provided", cache, "updated", allowance)
- ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(allowance))
- }
- }
- // Ensure Go's GC ignores the database cache for trigger percentage
- cache := ctx.GlobalInt(utils.CacheFlag.Name)
- gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024)))
-
- log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc))
- godebug.SetGCPercent(int(gogc))
-
- // Start metrics export if enabled
- utils.SetupMetrics(ctx)
-
- // Start system runtime metrics collection
- go metrics.CollectProcessMetrics(3 * time.Second)
-
- return nil
- }
-
- app.After = func(ctx *cli.Context) error {
- debug.Exit()
- console.Stdin.Close() // Resets terminal mode.
- return nil
- }
-}
-
-func main() {
- if err := app.Run(os.Args); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
-}
-
-// geth is the main entry point into the system if no special subcommand is ran.
-// It creates a default node based on the command line arguments and runs it in
-// blocking mode, waiting for it to be shut down.
-func geth(ctx *cli.Context) error {
- if args := ctx.Args(); len(args) > 0 {
- return fmt.Errorf("invalid command: %q", args[0])
- }
- node := makeFullNode(ctx)
- startNode(ctx, node)
- node.Wait()
- return nil
-}
-
-// startNode boots up the system node and all registered protocols, after which
-// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
-// miner.
-func startNode(ctx *cli.Context, stack *node.Node) {
- debug.Memsize.Add("node", stack)
-
- // Start up the node itself
- utils.StartNode(stack)
-
- // Unlock any account specifically requested
- ks := stack.AccountManager().Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore)
-
- passwords := utils.MakePasswordList(ctx)
- unlocks := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
- for i, account := range unlocks {
- if trimmed := strings.TrimSpace(account); trimmed != "" {
- unlockAccount(ctx, ks, trimmed, i, passwords)
- }
- }
- // Register wallet event handlers to open and auto-derive wallets
- events := make(chan accounts.WalletEvent, 16)
- stack.AccountManager().Subscribe(events)
-
- go func() {
- // Create a chain state reader for self-derivation
- rpcClient, err := stack.Attach()
- if err != nil {
- utils.Fatalf("Failed to attach to self: %v", err)
- }
- stateReader := ethclient.NewClient(rpcClient)
-
- // Open any wallets already attached
- for _, wallet := range stack.AccountManager().Wallets() {
- if err := wallet.Open(""); err != nil {
- log.Warn("Failed to open wallet", "url", wallet.URL(), "err", err)
- }
- }
- // Listen for wallet event till termination
- for event := range events {
- switch event.Kind {
- case accounts.WalletArrived:
- if err := event.Wallet.Open(""); err != nil {
- log.Warn("New wallet appeared, failed to open", "url", event.Wallet.URL(), "err", err)
- }
- case accounts.WalletOpened:
- status, _ := event.Wallet.Status()
- log.Info("New wallet appeared", "url", event.Wallet.URL(), "status", status)
-
- derivationPath := accounts.DefaultBaseDerivationPath
- if event.Wallet.URL().Scheme == "ledger" {
- derivationPath = accounts.DefaultLedgerBaseDerivationPath
- }
- event.Wallet.SelfDerive(derivationPath, stateReader)
-
- case accounts.WalletDropped:
- log.Info("Old wallet dropped", "url", event.Wallet.URL())
- event.Wallet.Close()
- }
- }
- }()
- // 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.GlobalString(utils.SyncModeFlag.Name) == "light" {
- utils.Fatalf("Light clients do not support mining")
- }
- var ethereum *eth.Ethereum
- if err := stack.Service(ðereum); err != nil {
- utils.Fatalf("Ethereum service not running: %v", err)
- }
- // Set the gas price to the limits from the CLI and start mining
- gasprice := utils.GlobalBig(ctx, utils.MinerLegacyGasPriceFlag.Name)
- if ctx.IsSet(utils.MinerGasPriceFlag.Name) {
- gasprice = utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
- }
- ethereum.TxPool().SetGasPrice(gasprice)
-
- threads := ctx.GlobalInt(utils.MinerLegacyThreadsFlag.Name)
- if ctx.GlobalIsSet(utils.MinerThreadsFlag.Name) {
- threads = ctx.GlobalInt(utils.MinerThreadsFlag.Name)
- }
- if err := ethereum.StartMining(threads); err != nil {
- utils.Fatalf("Failed to start mining: %v", err)
- }
- }
-
- if ctx.GlobalBool(utils.ProposingEnabledFlag.Name) {
- if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
- utils.Fatalf("Light clients do not support proposing")
- }
- var dexon *dex.Dexon
- if err := stack.Service(&dexon); err != nil {
- utils.Fatalf("Dexon service not running: %v", err)
- }
- if err := dexon.StartProposing(); err != nil {
- utils.Fatalf("Failed to string proposing: %v", err)
- }
- }
-}
diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go
deleted file mode 100644
index b90567154..000000000
--- a/cmd/geth/misccmd.go
+++ /dev/null
@@ -1,139 +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 .
-
-package main
-
-import (
- "fmt"
- "os"
- "runtime"
- "strconv"
- "strings"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/consensus/ethash"
- "github.com/dexon-foundation/dexon/eth"
- "github.com/dexon-foundation/dexon/params"
- "gopkg.in/urfave/cli.v1"
-)
-
-var (
- makecacheCommand = cli.Command{
- Action: utils.MigrateFlags(makecache),
- Name: "makecache",
- Usage: "Generate ethash verification cache (for testing)",
- ArgsUsage: " ",
- Category: "MISCELLANEOUS COMMANDS",
- Description: `
-The makecache command generates an ethash cache in .
-
-This command exists to support the system testing project.
-Regular users do not need to execute it.
-`,
- }
- makedagCommand = cli.Command{
- Action: utils.MigrateFlags(makedag),
- Name: "makedag",
- Usage: "Generate ethash mining DAG (for testing)",
- ArgsUsage: " ",
- Category: "MISCELLANEOUS COMMANDS",
- Description: `
-The makedag command generates an ethash DAG in .
-
-This command exists to support the system testing project.
-Regular users do not need to execute it.
-`,
- }
- versionCommand = cli.Command{
- Action: utils.MigrateFlags(version),
- Name: "version",
- Usage: "Print version numbers",
- ArgsUsage: " ",
- Category: "MISCELLANEOUS COMMANDS",
- Description: `
-The output of this command is supposed to be machine-readable.
-`,
- }
- licenseCommand = cli.Command{
- Action: utils.MigrateFlags(license),
- Name: "license",
- Usage: "Display license information",
- ArgsUsage: " ",
- Category: "MISCELLANEOUS COMMANDS",
- }
-)
-
-// makecache generates an ethash verification cache into the provided folder.
-func makecache(ctx *cli.Context) error {
- args := ctx.Args()
- if len(args) != 2 {
- utils.Fatalf(`Usage: geth makecache `)
- }
- block, err := strconv.ParseUint(args[0], 0, 64)
- if err != nil {
- utils.Fatalf("Invalid block number: %v", err)
- }
- ethash.MakeCache(block, args[1])
-
- return nil
-}
-
-// makedag generates an ethash mining DAG into the provided folder.
-func makedag(ctx *cli.Context) error {
- args := ctx.Args()
- if len(args) != 2 {
- utils.Fatalf(`Usage: geth makedag `)
- }
- block, err := strconv.ParseUint(args[0], 0, 64)
- if err != nil {
- utils.Fatalf("Invalid block number: %v", err)
- }
- ethash.MakeDataset(block, args[1])
-
- return nil
-}
-
-func version(ctx *cli.Context) error {
- fmt.Println(strings.Title(clientIdentifier))
- fmt.Println("Version:", params.VersionWithMeta)
- if gitCommit != "" {
- fmt.Println("Git Commit:", gitCommit)
- }
- fmt.Println("Architecture:", runtime.GOARCH)
- fmt.Println("Protocol Versions:", eth.ProtocolVersions)
- fmt.Println("Network Id:", eth.DefaultConfig.NetworkId)
- fmt.Println("Go Version:", runtime.Version())
- fmt.Println("Operating System:", runtime.GOOS)
- fmt.Printf("GOPATH=%s\n", os.Getenv("GOPATH"))
- fmt.Printf("GOROOT=%s\n", runtime.GOROOT())
- return nil
-}
-
-func license(_ *cli.Context) error {
- fmt.Println(`Geth 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.
-
-Geth 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 geth. If not, see .`)
- return nil
-}
diff --git a/cmd/geth/monitorcmd.go b/cmd/geth/monitorcmd.go
deleted file mode 100644
index 668401028..000000000
--- a/cmd/geth/monitorcmd.go
+++ /dev/null
@@ -1,351 +0,0 @@
-// Copyright 2015 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 .
-
-package main
-
-import (
- "fmt"
- "math"
- "reflect"
- "runtime"
- "sort"
- "strings"
- "time"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/node"
- "github.com/dexon-foundation/dexon/rpc"
- "github.com/gizak/termui"
- "gopkg.in/urfave/cli.v1"
-)
-
-var (
- monitorCommandAttachFlag = cli.StringFlag{
- Name: "attach",
- Value: node.DefaultIPCEndpoint(clientIdentifier),
- Usage: "API endpoint to attach to",
- }
- monitorCommandRowsFlag = cli.IntFlag{
- Name: "rows",
- Value: 5,
- Usage: "Maximum rows in the chart grid",
- }
- monitorCommandRefreshFlag = cli.IntFlag{
- Name: "refresh",
- Value: 3,
- Usage: "Refresh interval in seconds",
- }
- monitorCommand = cli.Command{
- Action: utils.MigrateFlags(monitor), // keep track of migration progress
- Name: "monitor",
- Usage: "Monitor and visualize node metrics",
- ArgsUsage: " ",
- Category: "MONITOR COMMANDS",
- Description: `
-The Geth monitor is a tool to collect and visualize various internal metrics
-gathered by the node, supporting different chart types as well as the capacity
-to display multiple metrics simultaneously.
-`,
- Flags: []cli.Flag{
- monitorCommandAttachFlag,
- monitorCommandRowsFlag,
- monitorCommandRefreshFlag,
- },
- }
-)
-
-// monitor starts a terminal UI based monitoring tool for the requested metrics.
-func monitor(ctx *cli.Context) error {
- var (
- client *rpc.Client
- err error
- )
- // Attach to an Ethereum node over IPC or RPC
- endpoint := ctx.String(monitorCommandAttachFlag.Name)
- if client, err = dialRPC(endpoint); err != nil {
- utils.Fatalf("Unable to attach to geth node: %v", err)
- }
- defer client.Close()
-
- // Retrieve all the available metrics and resolve the user pattens
- metrics, err := retrieveMetrics(client)
- if err != nil {
- utils.Fatalf("Failed to retrieve system metrics: %v", err)
- }
- monitored := resolveMetrics(metrics, ctx.Args())
- if len(monitored) == 0 {
- list := expandMetrics(metrics, "")
- sort.Strings(list)
-
- if len(list) > 0 {
- utils.Fatalf("No metrics specified.\n\nAvailable:\n - %s", strings.Join(list, "\n - "))
- } else {
- utils.Fatalf("No metrics collected by geth (--%s).\n", utils.MetricsEnabledFlag.Name)
- }
- }
- sort.Strings(monitored)
- if cols := len(monitored) / ctx.Int(monitorCommandRowsFlag.Name); cols > 6 {
- utils.Fatalf("Requested metrics (%d) spans more that 6 columns:\n - %s", len(monitored), strings.Join(monitored, "\n - "))
- }
- // Create and configure the chart UI defaults
- if err := termui.Init(); err != nil {
- utils.Fatalf("Unable to initialize terminal UI: %v", err)
- }
- defer termui.Close()
-
- rows := len(monitored)
- if max := ctx.Int(monitorCommandRowsFlag.Name); rows > max {
- rows = max
- }
- cols := (len(monitored) + rows - 1) / rows
- for i := 0; i < rows; i++ {
- termui.Body.AddRows(termui.NewRow())
- }
- // Create each individual data chart
- footer := termui.NewPar("")
- footer.Block.Border = true
- footer.Height = 3
-
- charts := make([]*termui.LineChart, len(monitored))
- units := make([]int, len(monitored))
- data := make([][]float64, len(monitored))
- for i := 0; i < len(monitored); i++ {
- charts[i] = createChart((termui.TermHeight() - footer.Height) / rows)
- row := termui.Body.Rows[i%rows]
- row.Cols = append(row.Cols, termui.NewCol(12/cols, 0, charts[i]))
- }
- termui.Body.AddRows(termui.NewRow(termui.NewCol(12, 0, footer)))
-
- refreshCharts(client, monitored, data, units, charts, ctx, footer)
- termui.Body.Align()
- termui.Render(termui.Body)
-
- // Watch for various system events, and periodically refresh the charts
- termui.Handle("/sys/kbd/C-c", func(termui.Event) {
- termui.StopLoop()
- })
- termui.Handle("/sys/wnd/resize", func(termui.Event) {
- termui.Body.Width = termui.TermWidth()
- for _, chart := range charts {
- chart.Height = (termui.TermHeight() - footer.Height) / rows
- }
- termui.Body.Align()
- termui.Render(termui.Body)
- })
- go func() {
- tick := time.NewTicker(time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second)
- for range tick.C {
- if refreshCharts(client, monitored, data, units, charts, ctx, footer) {
- termui.Body.Align()
- }
- termui.Render(termui.Body)
- }
- }()
- termui.Loop()
- return nil
-}
-
-// retrieveMetrics contacts the attached geth node and retrieves the entire set
-// of collected system metrics.
-func retrieveMetrics(client *rpc.Client) (map[string]interface{}, error) {
- var metrics map[string]interface{}
- err := client.Call(&metrics, "debug_metrics", true)
- return metrics, err
-}
-
-// resolveMetrics takes a list of input metric patterns, and resolves each to one
-// or more canonical metric names.
-func resolveMetrics(metrics map[string]interface{}, patterns []string) []string {
- res := []string{}
- for _, pattern := range patterns {
- res = append(res, resolveMetric(metrics, pattern, "")...)
- }
- return res
-}
-
-// resolveMetrics takes a single of input metric pattern, and resolves it to one
-// or more canonical metric names.
-func resolveMetric(metrics map[string]interface{}, pattern string, path string) []string {
- results := []string{}
-
- // If a nested metric was requested, recurse optionally branching (via comma)
- parts := strings.SplitN(pattern, "/", 2)
- if len(parts) > 1 {
- for _, variation := range strings.Split(parts[0], ",") {
- submetrics, ok := metrics[variation].(map[string]interface{})
- if !ok {
- utils.Fatalf("Failed to retrieve system metrics: %s", path+variation)
- return nil
- }
- results = append(results, resolveMetric(submetrics, parts[1], path+variation+"/")...)
- }
- return results
- }
- // Depending what the last link is, return or expand
- for _, variation := range strings.Split(pattern, ",") {
- switch metric := metrics[variation].(type) {
- case float64:
- // Final metric value found, return as singleton
- results = append(results, path+variation)
-
- case map[string]interface{}:
- results = append(results, expandMetrics(metric, path+variation+"/")...)
-
- default:
- utils.Fatalf("Metric pattern resolved to unexpected type: %v", reflect.TypeOf(metric))
- return nil
- }
- }
- return results
-}
-
-// expandMetrics expands the entire tree of metrics into a flat list of paths.
-func expandMetrics(metrics map[string]interface{}, path string) []string {
- // Iterate over all fields and expand individually
- list := []string{}
- for name, metric := range metrics {
- switch metric := metric.(type) {
- case float64:
- // Final metric value found, append to list
- list = append(list, path+name)
-
- case map[string]interface{}:
- // Tree of metrics found, expand recursively
- list = append(list, expandMetrics(metric, path+name+"/")...)
-
- default:
- utils.Fatalf("Metric pattern %s resolved to unexpected type: %v", path+name, reflect.TypeOf(metric))
- return nil
- }
- }
- return list
-}
-
-// fetchMetric iterates over the metrics map and retrieves a specific one.
-func fetchMetric(metrics map[string]interface{}, metric string) float64 {
- parts := strings.Split(metric, "/")
- for _, part := range parts[:len(parts)-1] {
- var found bool
- metrics, found = metrics[part].(map[string]interface{})
- if !found {
- return 0
- }
- }
- if v, ok := metrics[parts[len(parts)-1]].(float64); ok {
- return v
- }
- return 0
-}
-
-// refreshCharts retrieves a next batch of metrics, and inserts all the new
-// values into the active datasets and charts
-func refreshCharts(client *rpc.Client, metrics []string, data [][]float64, units []int, charts []*termui.LineChart, ctx *cli.Context, footer *termui.Par) (realign bool) {
- values, err := retrieveMetrics(client)
- for i, metric := range metrics {
- if len(data) < 512 {
- data[i] = append([]float64{fetchMetric(values, metric)}, data[i]...)
- } else {
- data[i] = append([]float64{fetchMetric(values, metric)}, data[i][:len(data[i])-1]...)
- }
- if updateChart(metric, data[i], &units[i], charts[i], err) {
- realign = true
- }
- }
- updateFooter(ctx, err, footer)
- return
-}
-
-// updateChart inserts a dataset into a line chart, scaling appropriately as to
-// not display weird labels, also updating the chart label accordingly.
-func updateChart(metric string, data []float64, base *int, chart *termui.LineChart, err error) (realign bool) {
- dataUnits := []string{"", "K", "M", "G", "T", "E"}
- timeUnits := []string{"ns", "µs", "ms", "s", "ks", "ms"}
- colors := []termui.Attribute{termui.ColorBlue, termui.ColorCyan, termui.ColorGreen, termui.ColorYellow, termui.ColorRed, termui.ColorRed}
-
- // Extract only part of the data that's actually visible
- if chart.Width*2 < len(data) {
- data = data[:chart.Width*2]
- }
- // Find the maximum value and scale under 1K
- high := 0.0
- if len(data) > 0 {
- high = data[0]
- for _, value := range data[1:] {
- high = math.Max(high, value)
- }
- }
- unit, scale := 0, 1.0
- for high >= 1000 && unit+1 < len(dataUnits) {
- high, unit, scale = high/1000, unit+1, scale*1000
- }
- // If the unit changes, re-create the chart (hack to set max height...)
- if unit != *base {
- realign, *base, *chart = true, unit, *createChart(chart.Height)
- }
- // Update the chart's data points with the scaled values
- if cap(chart.Data) < len(data) {
- chart.Data = make([]float64, len(data))
- }
- chart.Data = chart.Data[:len(data)]
- for i, value := range data {
- chart.Data[i] = value / scale
- }
- // Update the chart's label with the scale units
- units := dataUnits
- if strings.Contains(metric, "/Percentiles/") || strings.Contains(metric, "/pauses/") || strings.Contains(metric, "/time/") {
- units = timeUnits
- }
- chart.BorderLabel = metric
- if len(units[unit]) > 0 {
- chart.BorderLabel += " [" + units[unit] + "]"
- }
- chart.LineColor = colors[unit] | termui.AttrBold
- if err != nil {
- chart.LineColor = termui.ColorRed | termui.AttrBold
- }
- return
-}
-
-// createChart creates an empty line chart with the default configs.
-func createChart(height int) *termui.LineChart {
- chart := termui.NewLineChart()
- if runtime.GOOS == "windows" {
- chart.Mode = "dot"
- }
- chart.DataLabels = []string{""}
- chart.Height = height
- chart.AxesColor = termui.ColorWhite
- chart.PaddingBottom = -2
-
- chart.BorderLabelFg = chart.BorderFg | termui.AttrBold
- chart.BorderFg = chart.BorderBg
-
- return chart
-}
-
-// updateFooter updates the footer contents based on any encountered errors.
-func updateFooter(ctx *cli.Context, err error, footer *termui.Par) {
- // Generate the basic footer
- refresh := time.Duration(ctx.Int(monitorCommandRefreshFlag.Name)) * time.Second
- footer.Text = fmt.Sprintf("Press Ctrl+C to quit. Refresh interval: %v.", refresh)
- footer.TextFgColor = termui.ThemeAttr("par.fg") | termui.AttrBold
-
- // Append any encountered errors
- if err != nil {
- footer.Text = fmt.Sprintf("Error: %v.", err)
- footer.TextFgColor = termui.ColorRed | termui.AttrBold
- }
-}
diff --git a/cmd/geth/run_test.go b/cmd/geth/run_test.go
deleted file mode 100644
index c5bd7e6fc..000000000
--- a/cmd/geth/run_test.go
+++ /dev/null
@@ -1,98 +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 .
-
-package main
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "testing"
-
- "github.com/dexon-foundation/dexon/internal/cmdtest"
- "github.com/docker/docker/pkg/reexec"
-)
-
-func tmpdir(t *testing.T) string {
- dir, err := ioutil.TempDir("", "geth-test")
- if err != nil {
- t.Fatal(err)
- }
- return dir
-}
-
-type testgeth struct {
- *cmdtest.TestCmd
-
- // template variables for expect
- Datadir string
- Etherbase string
-}
-
-func init() {
- // Run the app if we've been exec'd as "geth-test" in runGeth.
- reexec.Register("geth-test", func() {
- if err := app.Run(os.Args); err != nil {
- fmt.Fprintln(os.Stderr, err)
- os.Exit(1)
- }
- os.Exit(0)
- })
-}
-
-func TestMain(m *testing.M) {
- // check if we have been reexec'd
- if reexec.Init() {
- return
- }
- os.Exit(m.Run())
-}
-
-// spawns geth with the given command line args. If the args don't set --datadir, the
-// child g gets a temporary data directory.
-func runGeth(t *testing.T, args ...string) *testgeth {
- tt := &testgeth{}
- tt.TestCmd = cmdtest.NewTestCmd(t, tt)
- for i, arg := range args {
- switch {
- case arg == "-datadir" || arg == "--datadir":
- if i < len(args)-1 {
- tt.Datadir = args[i+1]
- }
- case arg == "-etherbase" || arg == "--etherbase":
- if i < len(args)-1 {
- tt.Etherbase = args[i+1]
- }
- }
- }
- if tt.Datadir == "" {
- tt.Datadir = tmpdir(t)
- tt.Cleanup = func() { os.RemoveAll(tt.Datadir) }
- args = append([]string{"-datadir", tt.Datadir}, args...)
- // Remove the temporary datadir if something fails below.
- defer func() {
- if t.Failed() {
- tt.Cleanup()
- }
- }()
- }
-
- // Boot "geth". This actually runs the test binary but the TestMain
- // function will prevent any tests from running.
- tt.Run("geth-test", args...)
-
- return tt
-}
diff --git a/cmd/geth/testdata/empty.js b/cmd/geth/testdata/empty.js
deleted file mode 100644
index 8b1378917..000000000
--- a/cmd/geth/testdata/empty.js
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/cmd/geth/testdata/guswallet.json b/cmd/geth/testdata/guswallet.json
deleted file mode 100644
index e8ea4f332..000000000
--- a/cmd/geth/testdata/guswallet.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "encseed": "26d87f5f2bf9835f9a47eefae571bc09f9107bb13d54ff12a4ec095d01f83897494cf34f7bed2ed34126ecba9db7b62de56c9d7cd136520a0427bfb11b8954ba7ac39b90d4650d3448e31185affcd74226a68f1e94b1108e6e0a4a91cdd83eba",
- "ethaddr": "d4584b5f6229b7be90727b0fc8c6b91bb427821f",
- "email": "gustav.simonsson@gmail.com",
- "btcaddr": "1EVknXyFC68kKNLkh6YnKzW41svSRoaAcx"
-}
diff --git a/cmd/geth/testdata/passwords.txt b/cmd/geth/testdata/passwords.txt
deleted file mode 100644
index 96f98c7f4..000000000
--- a/cmd/geth/testdata/passwords.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-foobar
-foobar
-foobar
diff --git a/cmd/geth/testdata/wrong-passwords.txt b/cmd/geth/testdata/wrong-passwords.txt
deleted file mode 100644
index 7d1e338bb..000000000
--- a/cmd/geth/testdata/wrong-passwords.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-wrong
-wrong
-wrong
diff --git a/cmd/geth/usage.go b/cmd/geth/usage.go
deleted file mode 100644
index 911095c50..000000000
--- a/cmd/geth/usage.go
+++ /dev/null
@@ -1,359 +0,0 @@
-// Copyright 2015 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 .
-
-// Contains the geth command usage template and generator.
-
-package main
-
-import (
- "io"
- "sort"
-
- "strings"
-
- "github.com/dexon-foundation/dexon/cmd/utils"
- "github.com/dexon-foundation/dexon/internal/debug"
- "gopkg.in/urfave/cli.v1"
-)
-
-// AppHelpTemplate is the test template for the default, global app help topic.
-var AppHelpTemplate = `NAME:
- {{.App.Name}} - {{.App.Usage}}
-
- Copyright 2013-2018 The go-ethereum Authors
-
-USAGE:
- {{.App.HelpName}} [options]{{if .App.Commands}} command [command options]{{end}} {{if .App.ArgsUsage}}{{.App.ArgsUsage}}{{else}}[arguments...]{{end}}
- {{if .App.Version}}
-VERSION:
- {{.App.Version}}
- {{end}}{{if len .App.Authors}}
-AUTHOR(S):
- {{range .App.Authors}}{{ . }}{{end}}
- {{end}}{{if .App.Commands}}
-COMMANDS:
- {{range .App.Commands}}{{join .Names ", "}}{{ "\t" }}{{.Usage}}
- {{end}}{{end}}{{if .FlagGroups}}
-{{range .FlagGroups}}{{.Name}} OPTIONS:
- {{range .Flags}}{{.}}
- {{end}}
-{{end}}{{end}}{{if .App.Copyright }}
-COPYRIGHT:
- {{.App.Copyright}}
- {{end}}
-`
-
-// flagGroup is a collection of flags belonging to a single topic.
-type flagGroup struct {
- Name string
- Flags []cli.Flag
-}
-
-// AppHelpFlagGroups is the application flags, grouped by functionality.
-var AppHelpFlagGroups = []flagGroup{
- {
- Name: "ETHEREUM",
- Flags: []cli.Flag{
- configFileFlag,
- utils.DataDirFlag,
- utils.KeyStoreDirFlag,
- utils.NoUSBFlag,
- utils.NetworkIdFlag,
- utils.TestnetFlag,
- utils.SyncModeFlag,
- utils.GCModeFlag,
- utils.EthStatsURLFlag,
- utils.IdentityFlag,
- utils.LightServFlag,
- utils.LightPeersFlag,
- utils.LightKDFFlag,
- utils.WhitelistFlag,
- },
- },
- {
- Name: "DEVELOPER CHAIN",
- Flags: []cli.Flag{
- utils.DeveloperFlag,
- utils.DeveloperPeriodFlag,
- },
- },
- {
- Name: "ETHASH",
- Flags: []cli.Flag{
- utils.EthashCacheDirFlag,
- utils.EthashCachesInMemoryFlag,
- utils.EthashCachesOnDiskFlag,
- utils.EthashDatasetDirFlag,
- utils.EthashDatasetsInMemoryFlag,
- utils.EthashDatasetsOnDiskFlag,
- },
- },
- //{
- // Name: "DASHBOARD",
- // Flags: []cli.Flag{
- // utils.DashboardEnabledFlag,
- // utils.DashboardAddrFlag,
- // utils.DashboardPortFlag,
- // utils.DashboardRefreshFlag,
- // utils.DashboardAssetsFlag,
- // },
- //},
- {
- Name: "TRANSACTION POOL",
- Flags: []cli.Flag{
- utils.TxPoolLocalsFlag,
- utils.TxPoolNoLocalsFlag,
- utils.TxPoolJournalFlag,
- utils.TxPoolRejournalFlag,
- utils.TxPoolPriceLimitFlag,
- utils.TxPoolPriceBumpFlag,
- utils.TxPoolAccountSlotsFlag,
- utils.TxPoolGlobalSlotsFlag,
- utils.TxPoolAccountQueueFlag,
- utils.TxPoolGlobalQueueFlag,
- utils.TxPoolLifetimeFlag,
- },
- },
- {
- Name: "PERFORMANCE TUNING",
- Flags: []cli.Flag{
- utils.CacheFlag,
- utils.CacheDatabaseFlag,
- utils.CacheTrieFlag,
- utils.CacheGCFlag,
- utils.TrieCacheGenFlag,
- },
- },
- {
- Name: "ACCOUNT",
- Flags: []cli.Flag{
- utils.UnlockedAccountFlag,
- utils.PasswordFileFlag,
- },
- },
- {
- Name: "API AND CONSOLE",
- Flags: []cli.Flag{
- utils.RPCEnabledFlag,
- utils.RPCListenAddrFlag,
- utils.RPCPortFlag,
- utils.RPCApiFlag,
- utils.WSEnabledFlag,
- utils.WSListenAddrFlag,
- utils.WSPortFlag,
- utils.WSApiFlag,
- utils.WSAllowedOriginsFlag,
- utils.IPCDisabledFlag,
- utils.IPCPathFlag,
- utils.RPCCORSDomainFlag,
- utils.RPCVirtualHostsFlag,
- utils.JSpathFlag,
- utils.ExecFlag,
- utils.PreloadJSFlag,
- },
- },
- {
- Name: "NETWORKING",
- Flags: []cli.Flag{
- utils.BootnodesFlag,
- utils.BootnodesV4Flag,
- utils.BootnodesV5Flag,
- utils.ListenPortFlag,
- utils.MaxPeersFlag,
- utils.MaxPendingPeersFlag,
- utils.NATFlag,
- utils.NoDiscoverFlag,
- utils.DiscoveryV5Flag,
- utils.NetrestrictFlag,
- utils.NodeKeyFileFlag,
- utils.NodeKeyHexFlag,
- },
- },
- {
- Name: "PROPOSER",
- Flags: []cli.Flag{
- utils.ProposingEnabledFlag,
- },
- },
- {
- Name: "MINER",
- Flags: []cli.Flag{
- utils.MiningEnabledFlag,
- utils.MinerThreadsFlag,
- utils.MinerNotifyFlag,
- utils.MinerGasPriceFlag,
- utils.MinerGasTargetFlag,
- utils.MinerGasLimitFlag,
- utils.MinerEtherbaseFlag,
- utils.MinerExtraDataFlag,
- utils.MinerRecommitIntervalFlag,
- utils.MinerNoVerfiyFlag,
- },
- },
- {
- Name: "GAS PRICE ORACLE",
- Flags: []cli.Flag{
- utils.GpoBlocksFlag,
- utils.GpoPercentileFlag,
- },
- },
- {
- Name: "VIRTUAL MACHINE",
- Flags: []cli.Flag{
- utils.VMEnableDebugFlag,
- utils.EVMInterpreterFlag,
- utils.EWASMInterpreterFlag,
- },
- },
- {
- Name: "LOGGING AND DEBUGGING",
- Flags: append([]cli.Flag{
- utils.FakePoWFlag,
- utils.NoCompactionFlag,
- }, debug.Flags...),
- },
- {
- Name: "METRICS AND STATS",
- Flags: []cli.Flag{
- utils.MetricsEnabledFlag,
- utils.MetricsEnableInfluxDBFlag,
- utils.MetricsInfluxDBEndpointFlag,
- utils.MetricsInfluxDBDatabaseFlag,
- utils.MetricsInfluxDBUsernameFlag,
- utils.MetricsInfluxDBPasswordFlag,
- utils.MetricsInfluxDBHostTagFlag,
- },
- },
- {
- Name: "WHISPER (EXPERIMENTAL)",
- Flags: whisperFlags,
- },
- {
- Name: "DEPRECATED",
- Flags: []cli.Flag{
- utils.MinerLegacyThreadsFlag,
- utils.MinerLegacyGasTargetFlag,
- utils.MinerLegacyGasPriceFlag,
- utils.MinerLegacyEtherbaseFlag,
- utils.MinerLegacyExtraDataFlag,
- },
- },
- {
- Name: "MISC",
- },
-}
-
-// byCategory sorts an array of flagGroup by Name in the order
-// defined in AppHelpFlagGroups.
-type byCategory []flagGroup
-
-func (a byCategory) Len() int { return len(a) }
-func (a byCategory) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a byCategory) Less(i, j int) bool {
- iCat, jCat := a[i].Name, a[j].Name
- iIdx, jIdx := len(AppHelpFlagGroups), len(AppHelpFlagGroups) // ensure non categorized flags come last
-
- for i, group := range AppHelpFlagGroups {
- if iCat == group.Name {
- iIdx = i
- }
- if jCat == group.Name {
- jIdx = i
- }
- }
-
- return iIdx < jIdx
-}
-
-func flagCategory(flag cli.Flag) string {
- for _, category := range AppHelpFlagGroups {
- for _, flg := range category.Flags {
- if flg.GetName() == flag.GetName() {
- return category.Name
- }
- }
- }
- return "MISC"
-}
-
-func init() {
- // Override the default app help template
- cli.AppHelpTemplate = AppHelpTemplate
-
- // Define a one shot struct to pass to the usage template
- type helpData struct {
- App interface{}
- FlagGroups []flagGroup
- }
-
- // Override the default app help printer, but only for the global app help
- originalHelpPrinter := cli.HelpPrinter
- cli.HelpPrinter = func(w io.Writer, tmpl string, data interface{}) {
- if tmpl == AppHelpTemplate {
- // Iterate over all the flags and add any uncategorized ones
- categorized := make(map[string]struct{})
- for _, group := range AppHelpFlagGroups {
- for _, flag := range group.Flags {
- categorized[flag.String()] = struct{}{}
- }
- }
- uncategorized := []cli.Flag{}
- for _, flag := range data.(*cli.App).Flags {
- if _, ok := categorized[flag.String()]; !ok {
- if strings.HasPrefix(flag.GetName(), "dashboard") {
- continue
- }
- uncategorized = append(uncategorized, flag)
- }
- }
- if len(uncategorized) > 0 {
- // Append all ungategorized options to the misc group
- miscs := len(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags)
- AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = append(AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags, uncategorized...)
-
- // Make sure they are removed afterwards
- defer func() {
- AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags = AppHelpFlagGroups[len(AppHelpFlagGroups)-1].Flags[:miscs]
- }()
- }
- // Render out custom usage screen
- originalHelpPrinter(w, tmpl, helpData{data, AppHelpFlagGroups})
- } else if tmpl == utils.CommandHelpTemplate {
- // Iterate over all command specific flags and categorize them
- categorized := make(map[string][]cli.Flag)
- for _, flag := range data.(cli.Command).Flags {
- if _, ok := categorized[flag.String()]; !ok {
- categorized[flagCategory(flag)] = append(categorized[flagCategory(flag)], flag)
- }
- }
-
- // sort to get a stable ordering
- sorted := make([]flagGroup, 0, len(categorized))
- for cat, flgs := range categorized {
- sorted = append(sorted, flagGroup{cat, flgs})
- }
- sort.Sort(byCategory(sorted))
-
- // add sorted array to data and render with default printer
- originalHelpPrinter(w, tmpl, map[string]interface{}{
- "cmd": data,
- "categorizedFlags": sorted,
- })
- } else {
- originalHelpPrinter(w, tmpl, data)
- }
- }
-}
diff --git a/cmd/monkey/key b/cmd/monkey/key
new file mode 100644
index 000000000..a9fe18413
--- /dev/null
+++ b/cmd/monkey/key
@@ -0,0 +1 @@
+fa30b47a7a3d5ab6935d873ffaeb8ca5b9782d102c4094be6da6b7f2fc04b5bd
\ No newline at end of file
diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go
index 13e92f011..f0e4744ec 100644
--- a/cmd/puppeth/module_dashboard.go
+++ b/cmd/puppeth/module_dashboard.go
@@ -84,7 +84,7 @@ var dashboardContent = `
{{if .FaucetPage}}{{end}}
- You can download Geth from https://geth.ethereum.org/downloads/.
+ You can download Geth from https://gdex.ethereum.org/downloads/.
@@ -176,11 +176,11 @@ var dashboardContent = `
Initial processing required to synchronize is light, as it only verifies the validity of the headers; similarly required disk capacity is small, tallying around 500 bytes per header. Embedded machines with arbitrary storage, low power CPUs and 128MB+ RAM may work.
To run an embedded node, download {{.GethGenesis}}
and start Geth with:
-
geth --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}
- geth --networkid={{.NetworkID}} --datadir=$HOME/.{{.Network}} --cache=16 --ethash.cachesinmem=1 --syncmode=light{{if .Ethstats}} --ethstats='{{.Ethstats}}'{{end}} --bootnodes={{.BootnodesFlat}}
+ gdex --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}
+ gdex --networkid={{.NetworkID}} --datadir=$HOME/.{{.Network}} --cache=16 --ethash.cachesinmem=1 --syncmode=light{{if .Ethstats}} --ethstats='{{.Ethstats}}'{{end}} --bootnodes={{.BootnodesFlat}}
- You can download Geth from https://geth.ethereum.org/downloads/.
+ You can download Geth from https://gdex.ethereum.org/downloads/.
@@ -205,10 +205,10 @@ var dashboardContent = `
Under the hood the wallet is backed by a go-ethereum full node, meaning that a mid range machine is assumed. Similarly, synchronization is based on fast-sync, which will download all blockchain data from the network and make it available to the wallet. Light nodes cannot currently fully back the wallet, but it's a target actively pursued.
To connect with the Ethereum Wallet, you'll need to initialize your private network first via Geth as the wallet does not currently support calling Geth directly. To initialize your local chain, download {{.GethGenesis}}
and run:
-
geth --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}
+ gdex --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}
With your local chain initialized, you can start the Ethereum Wallet:
-
ethereumwallet --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}
+ ethereumwallet --rpc $HOME/.{{.Network}}/gdex.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}
You can download the Ethereum Wallet from https://github.com/ethereum/mist/releases.
@@ -226,10 +226,10 @@ var dashboardContent = `
Under the hood the browser is backed by a go-ethereum full node, meaning that a mid range machine is assumed. Similarly, synchronization is based on fast-sync, which will download all blockchain data from the network and make it available to the wallet. Light nodes cannot currently fully back the wallet, but it's a target actively pursued.
To connect with the Mist browser, you'll need to initialize your private network first via Geth as Mist does not currently support calling Geth directly. To initialize your local chain, download {{.GethGenesis}}
and run:
-
geth --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}
+ gdex --datadir=$HOME/.{{.Network}} init {{.GethGenesis}}
With your local chain initialized, you can start Mist:
-
mist --rpc $HOME/.{{.Network}}/geth.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}
+ mist --rpc $HOME/.{{.Network}}/gdex.ipc --node-networkid={{.NetworkID}} --node-datadir=$HOME/.{{.Network}}{{if .Ethstats}} --node-ethstats='{{.Ethstats}}'{{end}} --node-bootnodes={{.BootnodesFlat}}
You can download the Mist browser from https://github.com/ethereum/mist/releases.
@@ -258,8 +258,8 @@ var dashboardContent = `
The stable Android archives are distributed via Maven Central, and the develop snapshots via the Sonatype repositories. Before proceeding, please ensure you have a recent version configured in your Android project. You can find details in Mobile: Introduction – Android archive.
Before connecting to the Ethereum network, download the {{.GethGenesis}}
genesis json file and either store it in your Android project as a resource file you can access, or save it as a string in a variable. You're going to need to to initialize your client.
- Inside your Java code you can now import the geth archive and connect to Ethereum:
-
import org.ethereum.geth.*;
+ Inside your Java code you can now import the gdex archive and connect to Ethereum:
+
import org.ethereum.gdex.*;
Enodes bootnodes = new Enodes();{{range .Bootnodes}}
bootnodes.append(new Enode("{{.}}"));{{end}}
@@ -289,7 +289,7 @@ node.start();
Both stable and develop builds of the iOS framework are available via CocoaPods. Before proceeding, please ensure you have a recent version configured in your iOS project. You can find details in Mobile: Introduction – iOS framework.
Before connecting to the Ethereum network, download the {{.GethGenesis}}
genesis json file and either store it in your iOS project as a resource file you can access, or save it as a string in a variable. You're going to need to to initialize your client.
- Inside your Swift code you can now import the geth framework and connect to Ethereum (ObjC should be analogous):
+
Inside your Swift code you can now import the gdex framework and connect to Ethereum (ObjC should be analogous):
import Geth
var error: NSError?
@@ -419,7 +419,7 @@ try! node?.start();
Puppeth is a tool to aid you in creating a new Ethereum network down to the genesis block, bootnodes, signers, ethstats server, crypto faucet, wallet browsers, block explorer, dashboard and more; without the hassle that it would normally entail to manually configure all these services one by one.
Puppeth uses ssh to dial in to remote servers, and builds its network components out of docker containers using docker-compose. The user is guided through the process via a command line wizard that does the heavy lifting and topology configuration automatically behind the scenes.
- Puppeth is distributed as part of the Geth & Tools bundles, but can also be installed separately via:
go get github.com/dexon-foundation/dexon/cmd/puppeth
+ Puppeth is distributed as part of the Geth & Tools bundles, but can also be installed separately via:
go get github.com/dexon-foundation/dexon/cmd/puppeth
Copyright 2017. The go-ethereum Authors.
@@ -445,7 +445,7 @@ try! node?.start();
window.location.hash = hash;
// Fade out all possible pages (yes, ugly, no, don't care)
- $("#geth").fadeOut(300)
+ $("#gdex").fadeOut(300)
$("#mist").fadeOut(300)
$("#mobile").fadeOut(300)
$("#other").fadeOut(300)
diff --git a/cmd/puppeth/module_node.go b/cmd/puppeth/module_node.go
index 4013e7360..64f7e52e4 100644
--- a/cmd/puppeth/module_node.go
+++ b/cmd/puppeth/module_node.go
@@ -40,11 +40,11 @@ ADD genesis.json /genesis.json
ADD signer.pass /signer.pass
{{end}}
RUN \
- echo 'geth --cache 512 init /genesis.json' > geth.sh && \{{if .Unlock}}
- echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> geth.sh && \{{end}}
- echo $'exec geth --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --nat extip:{{.IP}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .Bootnodes}}--bootnodes {{.Bootnodes}}{{end}} {{if .Etherbase}}--miner.etherbase {{.Etherbase}} --mine --miner.threads 1{{end}} {{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --miner.gastarget {{.GasTarget}} --miner.gaslimit {{.GasLimit}} --miner.gasprice {{.GasPrice}}' >> geth.sh
+ echo 'gdex --cache 512 init /genesis.json' > gdex.sh && \{{if .Unlock}}
+ echo 'mkdir -p /root/.ethereum/keystore/ && cp /signer.json /root/.ethereum/keystore/' >> gdex.sh && \{{end}}
+ echo $'exec gdex --networkid {{.NetworkID}} --cache 512 --port {{.Port}} --nat extip:{{.IP}} --maxpeers {{.Peers}} {{.LightFlag}} --ethstats \'{{.Ethstats}}\' {{if .Bootnodes}}--bootnodes {{.Bootnodes}}{{end}} {{if .Etherbase}}--miner.etherbase {{.Etherbase}} --mine --miner.threads 1{{end}} {{if .Unlock}}--unlock 0 --password /signer.pass --mine{{end}} --miner.gastarget {{.GasTarget}} --miner.gaslimit {{.GasLimit}} --miner.gasprice {{.GasPrice}}' >> gdex.sh
-ENTRYPOINT ["/bin/sh", "geth.sh"]
+ENTRYPOINT ["/bin/sh", "gdex.sh"]
`
// nodeComposefile is the docker-compose.yml file required to deploy and maintain
@@ -229,7 +229,7 @@ func checkNode(client *sshClient, network string, boot bool) (*nodeInfos, error)
// Container available, retrieve its node ID and its genesis json
var out []byte
- if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 geth --exec admin.nodeInfo.enode --cache=16 attach", network, kind)); err != nil {
+ if out, err = client.Run(fmt.Sprintf("docker exec %s_%s_1 gdex --exec admin.nodeInfo.id --cache=16 attach", network, kind)); err != nil {
return nil, ErrServiceUnreachable
}
enode := bytes.Trim(bytes.TrimSpace(out), "\"")
diff --git a/cmd/puppeth/module_wallet.go b/cmd/puppeth/module_wallet.go
index 1d34779df..0539c19e4 100644
--- a/cmd/puppeth/module_wallet.go
+++ b/cmd/puppeth/module_wallet.go
@@ -36,8 +36,8 @@ ADD genesis.json /genesis.json
RUN \
echo 'node server.js &' > wallet.sh && \
- echo 'geth --cache 512 init /genesis.json' >> wallet.sh && \
- echo $'exec geth --networkid {{.NetworkID}} --port {{.NodePort}} --bootnodes {{.Bootnodes}} --ethstats \'{{.Ethstats}}\' --cache=512 --rpc --rpcaddr=0.0.0.0 --rpccorsdomain "*" --rpcvhosts "*"' >> wallet.sh
+ echo 'gdex --cache 512 init /genesis.json' >> wallet.sh && \
+ echo $'exec gdex --networkid {{.NetworkID}} --port {{.NodePort}} --bootnodes {{.Bootnodes}} --ethstats \'{{.Ethstats}}\' --cache=512 --rpc --rpcaddr=0.0.0.0 --rpccorsdomain "*" --rpcvhosts "*"' >> wallet.sh
RUN \
sed -i 's/PuppethNetworkID/{{.NetworkID}}/g' dist/js/etherwallet-master.js && \
diff --git a/cmd/swarm/config.go b/cmd/swarm/config.go
index 0729e33f8..4925e3724 100644
--- a/cmd/swarm/config.go
+++ b/cmd/swarm/config.go
@@ -125,7 +125,7 @@ func initSwarmNode(config *bzzapi.Config, stack *node.Node, ctx *cli.Context) {
//at this point, all vars should be set in the Config
//get the account for the provided swarm account
prvkey := getAccount(config.BzzAccount, ctx, stack)
- //set the resolved config path (geth --datadir)
+ //set the resolved config path (gdex --datadir)
config.Path = expandPath(stack.InstanceDir())
//finally, initialize the configuration
config.Init(prvkey)
diff --git a/cmd/swarm/config_test.go b/cmd/swarm/config_test.go
index 6bc613274..17abb7c78 100644
--- a/cmd/swarm/config_test.go
+++ b/cmd/swarm/config_test.go
@@ -473,7 +473,7 @@ func TestConfigValidate(t *testing.T) {
}{
{
cfg: &api.Config{EnsAPIs: []string{
- "/data/testnet/geth.ipc",
+ "/data/testnet/gdex.ipc",
}},
},
{
@@ -488,7 +488,7 @@ func TestConfigValidate(t *testing.T) {
},
{
cfg: &api.Config{EnsAPIs: []string{
- "test:/data/testnet/geth.ipc",
+ "test:/data/testnet/gdex.ipc",
}},
},
{
@@ -498,7 +498,7 @@ func TestConfigValidate(t *testing.T) {
},
{
cfg: &api.Config{EnsAPIs: []string{
- "314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/geth.ipc",
+ "314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/gdex.ipc",
}},
},
{
@@ -513,7 +513,7 @@ func TestConfigValidate(t *testing.T) {
},
{
cfg: &api.Config{EnsAPIs: []string{
- "test:314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/geth.ipc",
+ "test:314159265dD8dbb310642f98f50C066173C1259b@/data/testnet/gdex.ipc",
}},
},
{
@@ -546,9 +546,9 @@ func TestConfigValidate(t *testing.T) {
},
{
cfg: &api.Config{EnsAPIs: []string{
- "@/data/testnet/geth.ipc",
+ "@/data/testnet/gdex.ipc",
}},
- err: "invalid format [tld:][contract-addr@]url for ENS API endpoint configuration \"@/data/testnet/geth.ipc\": missing contract address",
+ err: "invalid format [tld:][contract-addr@]url for ENS API endpoint configuration \"@/data/testnet/gdex.ipc\": missing contract address",
},
} {
err := validateConfig(c.cfg)
diff --git a/cmd/swarm/main.go b/cmd/swarm/main.go
index 8b8af0c2b..fce5a5ce9 100644
--- a/cmd/swarm/main.go
+++ b/cmd/swarm/main.go
@@ -87,7 +87,7 @@ var defaultSubcommandHelp = cli.Command{
var defaultNodeConfig = node.DefaultConfig
-// This init function sets defaults so cmd/swarm can run alongside geth.
+// This init function sets defaults so cmd/swarm can run alongside gdex.
func init() {
defaultNodeConfig.Name = clientIdentifier
defaultNodeConfig.Version = sv.VersionWithCommit(gitCommit)
@@ -261,9 +261,9 @@ func bzzd(ctx *cli.Context) error {
//pss operates on ws
cfg.WSModules = append(cfg.WSModules, "pss")
- //geth only supports --datadir via command line
+ //gdex only supports --datadir via command line
//in order to be consistent within swarm, if we pass --datadir via environment variable
- //or via config file, we get the same directory for geth and swarm
+ //or via config file, we get the same directory for gdex and swarm
if _, err := os.Stat(bzzconfig.Path); err == nil {
cfg.DataDir = bzzconfig.Path
}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 5a6a6476f..c7a1b77de 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -603,7 +603,7 @@ var (
MetricsInfluxDBDatabaseFlag = cli.StringFlag{
Name: "metrics.influxdb.database",
Usage: "InfluxDB database name to push reported metrics to",
- Value: "geth",
+ Value: "gdex",
}
MetricsInfluxDBUsernameFlag = cli.StringFlag{
Name: "metrics.influxdb.username",
@@ -851,7 +851,7 @@ func MakeAddress(ks *keystore.KeyStore, account string) (accounts.Account, error
log.Warn("-------------------------------------------------------------------")
log.Warn("Referring to accounts by order in the keystore folder is dangerous!")
log.Warn("This functionality is deprecated and will be removed in the future!")
- log.Warn("Please use explicit addresses! (can search via `geth account list`)")
+ log.Warn("Please use explicit addresses! (can search via `gdex account list`)")
log.Warn("-------------------------------------------------------------------")
accs := ks.Accounts()
@@ -1317,7 +1317,7 @@ func SetupMetrics(ctx *cli.Context) {
if enableExport {
log.Info("Enabling metrics export to InfluxDB")
- go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "geth.", map[string]string{
+ go influxdb.InfluxDBWithTags(metrics.DefaultRegistry, 10*time.Second, endpoint, database, username, password, "gdex.", map[string]string{
"host": hosttag,
})
}
@@ -1420,11 +1420,11 @@ func MakeConsolePreloads(ctx *cli.Context) []string {
// This is a temporary function used for migrating old command/flags to the
// new format.
//
-// e.g. geth account new --keystore /tmp/mykeystore --lightkdf
+// e.g. gdex account new --keystore /tmp/mykeystore --lightkdf
//
// is equivalent after calling this method with:
//
-// geth --keystore /tmp/mykeystore --lightkdf account new
+// gdex --keystore /tmp/mykeystore --lightkdf account new
//
// This allows the use of the existing configuration functionality.
// When all flags are migrated this function can be removed and the existing
--
cgit v1.2.3