forked from cerc-io/plugeth
Merge Geth v1.10.21 as well as update to Plugeth-Utils v0.0.18
This commit is contained in:
+25
-27
@@ -25,29 +25,27 @@ import (
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
walletCommand = cli.Command{
|
||||
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{
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
|
||||
Name: "import",
|
||||
Usage: "Import Ethereum presale wallet",
|
||||
ArgsUsage: "<keyFile>",
|
||||
Action: utils.MigrateFlags(importWallet),
|
||||
Category: "ACCOUNT COMMANDS",
|
||||
Action: importWallet,
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
@@ -64,10 +62,9 @@ passwordfile as argument containing the wallet password in plaintext.`,
|
||||
},
|
||||
}
|
||||
|
||||
accountCommand = cli.Command{
|
||||
Name: "account",
|
||||
Usage: "Manage accounts",
|
||||
Category: "ACCOUNT COMMANDS",
|
||||
accountCommand = &cli.Command{
|
||||
Name: "account",
|
||||
Usage: "Manage accounts",
|
||||
Description: `
|
||||
|
||||
Manage accounts, list all existing accounts, import a private key into a new
|
||||
@@ -88,11 +85,11 @@ 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{
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "list",
|
||||
Usage: "Print summary of existing accounts",
|
||||
Action: utils.MigrateFlags(accountList),
|
||||
Action: accountList,
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
@@ -103,7 +100,7 @@ Print a short summary of all accounts`,
|
||||
{
|
||||
Name: "new",
|
||||
Usage: "Create a new account",
|
||||
Action: utils.MigrateFlags(accountCreate),
|
||||
Action: accountCreate,
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
@@ -128,7 +125,7 @@ password to file or expose in any other way.
|
||||
{
|
||||
Name: "update",
|
||||
Usage: "Update an existing account",
|
||||
Action: utils.MigrateFlags(accountUpdate),
|
||||
Action: accountUpdate,
|
||||
ArgsUsage: "<address>",
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
@@ -157,7 +154,7 @@ changing your password is only possible interactively.
|
||||
{
|
||||
Name: "import",
|
||||
Usage: "Import a private key into a new account",
|
||||
Action: utils.MigrateFlags(accountImport),
|
||||
Action: accountImport,
|
||||
Flags: []cli.Flag{
|
||||
utils.DataDirFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
@@ -239,14 +236,15 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
|
||||
}
|
||||
fmt.Println("Testing your password against all of them...")
|
||||
var match *accounts.Account
|
||||
for _, a := range err.Matches {
|
||||
if err := ks.Unlock(a, auth); err == nil {
|
||||
match = &a
|
||||
for i, a := range err.Matches {
|
||||
if e := ks.Unlock(a, auth); e == nil {
|
||||
match = &err.Matches[i]
|
||||
break
|
||||
}
|
||||
}
|
||||
if match == nil {
|
||||
utils.Fatalf("None of the listed files could be unlocked.")
|
||||
return accounts.Account{}
|
||||
}
|
||||
fmt.Printf("Your password unlocked %s\n", match.URL)
|
||||
fmt.Println("In order to avoid this warning, you need to remove the following duplicate key files:")
|
||||
@@ -262,7 +260,7 @@ func ambiguousAddrRecovery(ks *keystore.KeyStore, err *keystore.AmbiguousAddrErr
|
||||
func accountCreate(ctx *cli.Context) error {
|
||||
cfg := gethConfig{Node: defaultNodeConfig()}
|
||||
// Load config file.
|
||||
if file := ctx.GlobalString(configFileFlag.Name); file != "" {
|
||||
if file := ctx.String(configFileFlag.Name); file != "" {
|
||||
if err := loadConfig(file, &cfg); err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
}
|
||||
@@ -299,13 +297,13 @@ func accountCreate(ctx *cli.Context) error {
|
||||
// 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 {
|
||||
if ctx.Args().Len() == 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() {
|
||||
for _, addr := range ctx.Args().Slice() {
|
||||
account, oldPassword := unlockAccount(ks, addr, 0, nil)
|
||||
newPassword := utils.GetPassPhraseWithList("Please give a new password. Do not forget this password.", true, 0, nil)
|
||||
if err := ks.Update(account, oldPassword, newPassword); err != nil {
|
||||
@@ -316,10 +314,10 @@ func accountUpdate(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func importWallet(ctx *cli.Context) error {
|
||||
keyfile := ctx.Args().First()
|
||||
if len(keyfile) == 0 {
|
||||
utils.Fatalf("keyfile must be given as argument")
|
||||
if ctx.Args().Len() != 1 {
|
||||
utils.Fatalf("keyfile must be given as the only argument")
|
||||
}
|
||||
keyfile := ctx.Args().First()
|
||||
keyJSON, err := os.ReadFile(keyfile)
|
||||
if err != nil {
|
||||
utils.Fatalf("Could not read wallet file: %v", err)
|
||||
@@ -338,10 +336,10 @@ func importWallet(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func accountImport(ctx *cli.Context) error {
|
||||
keyfile := ctx.Args().First()
|
||||
if len(keyfile) == 0 {
|
||||
utils.Fatalf("keyfile must be given as argument")
|
||||
if ctx.Args().Len() != 1 {
|
||||
utils.Fatalf("keyfile must be given as the only argument")
|
||||
}
|
||||
keyfile := ctx.Args().First()
|
||||
key, err := crypto.LoadECDSA(keyfile)
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to load the private key: %v", err)
|
||||
|
||||
+44
-17
@@ -49,20 +49,27 @@ func TestAccountListEmpty(t *testing.T) {
|
||||
|
||||
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(`
|
||||
var want = `
|
||||
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
|
||||
`)
|
||||
`
|
||||
if runtime.GOOS == "windows" {
|
||||
want = `
|
||||
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
|
||||
`
|
||||
}
|
||||
{
|
||||
geth := runGeth(t, "account", "list", "--datadir", datadir)
|
||||
geth.Expect(want)
|
||||
geth.ExpectExit()
|
||||
}
|
||||
{
|
||||
geth := runGeth(t, "--datadir", datadir, "account", "list")
|
||||
geth.Expect(want)
|
||||
geth.ExpectExit()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +117,20 @@ func TestAccountImport(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountHelp(t *testing.T) {
|
||||
geth := runGeth(t, "account", "-h")
|
||||
geth.WaitExit()
|
||||
if have, want := geth.ExitStatus(), 0; have != want {
|
||||
t.Errorf("exit error, have %d want %d", have, want)
|
||||
}
|
||||
|
||||
geth = runGeth(t, "account", "import", "-h")
|
||||
geth.WaitExit()
|
||||
if have, want := geth.ExitStatus(), 0; have != want {
|
||||
t.Errorf("exit error, have %d want %d", have, want)
|
||||
}
|
||||
}
|
||||
|
||||
func importAccountWithExpect(t *testing.T, key string, expected string) {
|
||||
dir := t.TempDir()
|
||||
keyfile := filepath.Join(dir, "key.prv")
|
||||
@@ -120,7 +141,7 @@ func importAccountWithExpect(t *testing.T, key string, expected string) {
|
||||
if err := os.WriteFile(passwordFile, []byte("foobar"), 0600); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
geth := runGeth(t, "--lightkdf", "account", "import", keyfile, "-password", passwordFile)
|
||||
geth := runGeth(t, "--lightkdf", "account", "import", "-password", passwordFile, keyfile)
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(expected)
|
||||
}
|
||||
@@ -180,11 +201,12 @@ Fatal: could not decrypt key with given password
|
||||
|
||||
func TestUnlockFlag(t *testing.T) {
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js")
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
geth.Expect(`
|
||||
Unlocking account f466859ead1932d743d622cb74fc058882e8648a | Attempt 1/3
|
||||
!! Unsupported terminal, password will be echoed.
|
||||
Password: {{.InputLine "foobar"}}
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
@@ -201,7 +223,7 @@ Password: {{.InputLine "foobar"}}
|
||||
|
||||
func TestUnlockFlagWrongPassword(t *testing.T) {
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "js", "testdata/empty.js")
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
defer geth.ExpectExit()
|
||||
geth.Expect(`
|
||||
@@ -219,7 +241,7 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could
|
||||
// https://github.com/ethereum/go-ethereum/issues/1785
|
||||
func TestUnlockFlagMultiIndex(t *testing.T) {
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "js", "testdata/empty.js")
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
geth.Expect(`
|
||||
Unlocking account 0 | Attempt 1/3
|
||||
@@ -227,6 +249,7 @@ Unlocking account 0 | Attempt 1/3
|
||||
Password: {{.InputLine "foobar"}}
|
||||
Unlocking account 2 | Attempt 1/3
|
||||
Password: {{.InputLine "foobar"}}
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
@@ -244,8 +267,11 @@ Password: {{.InputLine "foobar"}}
|
||||
|
||||
func TestUnlockFlagPasswordFile(t *testing.T) {
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "js", "testdata/empty.js")
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--password", "testdata/passwords.txt", "--unlock", "0,2", "console", "--exec", "loadScript('testdata/empty.js')")
|
||||
|
||||
geth.Expect(`
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
wantMessages := []string{
|
||||
@@ -275,7 +301,7 @@ func TestUnlockFlagAmbiguous(t *testing.T) {
|
||||
geth := runMinimalGeth(t, "--port", "0", "--ipcdisable", "--datadir", tmpDatadirWithKeystore(t),
|
||||
"--unlock", "f466859ead1932d743d622cb74fc058882e8648a", "--keystore",
|
||||
store, "--unlock", "f466859ead1932d743d622cb74fc058882e8648a",
|
||||
"js", "testdata/empty.js")
|
||||
"console", "--exec", "loadScript('testdata/empty.js')")
|
||||
defer geth.ExpectExit()
|
||||
|
||||
// Helper for the expect template, returns absolute keystore path.
|
||||
@@ -294,6 +320,7 @@ Testing your password against all of them...
|
||||
Your password unlocked keystore://{{keypath "1"}}
|
||||
In order to avoid this warning, you need to remove the following duplicate key files:
|
||||
keystore://{{keypath "2"}}
|
||||
undefined
|
||||
`)
|
||||
geth.ExpectExit()
|
||||
|
||||
|
||||
+39
-43
@@ -35,20 +35,20 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
initCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(initGenesis),
|
||||
initCommand = &cli.Command{
|
||||
Action: initGenesis,
|
||||
Name: "init",
|
||||
Usage: "Bootstrap and initialize a new genesis block",
|
||||
ArgsUsage: "<genesisPath>",
|
||||
Flags: utils.DatabasePathFlags,
|
||||
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
|
||||
@@ -56,22 +56,21 @@ participating.
|
||||
|
||||
It expects the genesis file as argument.`,
|
||||
}
|
||||
dumpGenesisCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(dumpGenesis),
|
||||
dumpGenesisCommand = &cli.Command{
|
||||
Action: dumpGenesis,
|
||||
Name: "dumpgenesis",
|
||||
Usage: "Dumps genesis block JSON configuration to stdout",
|
||||
ArgsUsage: "",
|
||||
Flags: utils.NetworkFlags,
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
Description: `
|
||||
The dumpgenesis command dumps the genesis block configuration in JSON format to stdout.`,
|
||||
}
|
||||
importCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(importChain),
|
||||
importCommand = &cli.Command{
|
||||
Action: importChain,
|
||||
Name: "import",
|
||||
Usage: "Import a blockchain file",
|
||||
ArgsUsage: "<filename> (<filename 2> ... <filename N>) ",
|
||||
Flags: append([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.CacheFlag,
|
||||
utils.SyncModeFlag,
|
||||
utils.GCModeFlag,
|
||||
@@ -93,8 +92,7 @@ The dumpgenesis command dumps the genesis block configuration in JSON format to
|
||||
utils.MetricsInfluxDBBucketFlag,
|
||||
utils.MetricsInfluxDBOrganizationFlag,
|
||||
utils.TxLookupLimitFlag,
|
||||
}, utils.DatabasePathFlags...),
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
}, utils.DatabasePathFlags),
|
||||
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.
|
||||
@@ -102,16 +100,15 @@ 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),
|
||||
exportCommand = &cli.Command{
|
||||
Action: exportChain,
|
||||
Name: "export",
|
||||
Usage: "Export blockchain into file",
|
||||
ArgsUsage: "<filename> [<blockNumFirst> <blockNumLast>]",
|
||||
Flags: append([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.CacheFlag,
|
||||
utils.SyncModeFlag,
|
||||
}, utils.DatabasePathFlags...),
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
}, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
Requires a first argument of the file to write to.
|
||||
Optional second and third arguments control the first and
|
||||
@@ -119,42 +116,40 @@ 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),
|
||||
importPreimagesCommand = &cli.Command{
|
||||
Action: importPreimages,
|
||||
Name: "import-preimages",
|
||||
Usage: "Import the preimage database from an RLP stream",
|
||||
ArgsUsage: "<datafile>",
|
||||
Flags: append([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.CacheFlag,
|
||||
utils.SyncModeFlag,
|
||||
}, utils.DatabasePathFlags...),
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
}, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
The import-preimages command imports hash preimages from an RLP encoded stream.
|
||||
It's deprecated, please use "geth db import" instead.
|
||||
`,
|
||||
}
|
||||
exportPreimagesCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(exportPreimages),
|
||||
exportPreimagesCommand = &cli.Command{
|
||||
Action: exportPreimages,
|
||||
Name: "export-preimages",
|
||||
Usage: "Export the preimage database into an RLP stream",
|
||||
ArgsUsage: "<dumpfile>",
|
||||
Flags: append([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.CacheFlag,
|
||||
utils.SyncModeFlag,
|
||||
}, utils.DatabasePathFlags...),
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
}, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
The export-preimages command exports hash preimages to an RLP encoded stream.
|
||||
It's deprecated, please use "geth db export" instead.
|
||||
`,
|
||||
}
|
||||
dumpCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(dump),
|
||||
dumpCommand = &cli.Command{
|
||||
Action: dump,
|
||||
Name: "dump",
|
||||
Usage: "Dump a specific block from storage",
|
||||
ArgsUsage: "[? <blockHash> | <blockNum>]",
|
||||
Flags: append([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.CacheFlag,
|
||||
utils.IterativeOutputFlag,
|
||||
utils.ExcludeCodeFlag,
|
||||
@@ -162,8 +157,7 @@ It's deprecated, please use "geth db export" instead.
|
||||
utils.IncludeIncompletesFlag,
|
||||
utils.StartKeyFlag,
|
||||
utils.DumpLimitFlag,
|
||||
}, utils.DatabasePathFlags...),
|
||||
Category: "BLOCKCHAIN COMMANDS",
|
||||
}, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
This command dumps out the state for a given block (or latest, if none provided).
|
||||
`,
|
||||
@@ -173,10 +167,12 @@ This command dumps out the state for a given block (or latest, if none provided)
|
||||
// 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
|
||||
if ctx.Args().Len() != 1 {
|
||||
utils.Fatalf("need genesis.json file as the only argument")
|
||||
}
|
||||
genesisPath := ctx.Args().First()
|
||||
if len(genesisPath) == 0 {
|
||||
utils.Fatalf("Must supply path to genesis JSON file")
|
||||
utils.Fatalf("invalid path to genesis file")
|
||||
}
|
||||
file, err := os.Open(genesisPath)
|
||||
if err != nil {
|
||||
@@ -192,7 +188,7 @@ func initGenesis(ctx *cli.Context) error {
|
||||
stack, _ := makeConfigNode(ctx)
|
||||
defer stack.Close()
|
||||
for _, name := range []string{"chaindata", "lightchaindata"} {
|
||||
chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.GlobalString(utils.AncientFlag.Name), "", false)
|
||||
chaindb, err := stack.OpenDatabaseWithFreezer(name, 0, 0, ctx.String(utils.AncientFlag.Name), "", false)
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to open database: %v", err)
|
||||
}
|
||||
@@ -219,7 +215,7 @@ func dumpGenesis(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func importChain(ctx *cli.Context) error {
|
||||
if len(ctx.Args()) < 1 {
|
||||
if ctx.Args().Len() < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
// Start metrics export if enabled
|
||||
@@ -253,13 +249,13 @@ func importChain(ctx *cli.Context) error {
|
||||
|
||||
var importErr error
|
||||
|
||||
if len(ctx.Args()) == 1 {
|
||||
if ctx.Args().Len() == 1 {
|
||||
if err := utils.ImportChain(chain, ctx.Args().First()); err != nil {
|
||||
importErr = err
|
||||
log.Error("Import error", "err", err)
|
||||
}
|
||||
} else {
|
||||
for _, arg := range ctx.Args() {
|
||||
for _, arg := range ctx.Args().Slice() {
|
||||
if err := utils.ImportChain(chain, arg); err != nil {
|
||||
importErr = err
|
||||
log.Error("Import error", "file", arg, "err", err)
|
||||
@@ -281,7 +277,7 @@ func importChain(ctx *cli.Context) error {
|
||||
fmt.Printf("Allocations: %.3f million\n", float64(mem.Mallocs)/1000000)
|
||||
fmt.Printf("GC pause: %v\n\n", time.Duration(mem.PauseTotalNs))
|
||||
|
||||
if ctx.GlobalBool(utils.NoCompactionFlag.Name) {
|
||||
if ctx.Bool(utils.NoCompactionFlag.Name) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -298,7 +294,7 @@ func importChain(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func exportChain(ctx *cli.Context) error {
|
||||
if len(ctx.Args()) < 1 {
|
||||
if ctx.Args().Len() < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
|
||||
@@ -310,7 +306,7 @@ func exportChain(ctx *cli.Context) error {
|
||||
|
||||
var err error
|
||||
fp := ctx.Args().First()
|
||||
if len(ctx.Args()) < 3 {
|
||||
if ctx.Args().Len() < 3 {
|
||||
err = utils.ExportChain(chain, fp)
|
||||
} else {
|
||||
// This can be improved to allow for numbers larger than 9223372036854775807
|
||||
@@ -337,7 +333,7 @@ func exportChain(ctx *cli.Context) error {
|
||||
|
||||
// importPreimages imports preimage data from the specified file.
|
||||
func importPreimages(ctx *cli.Context) error {
|
||||
if len(ctx.Args()) < 1 {
|
||||
if ctx.Args().Len() < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
|
||||
@@ -356,7 +352,7 @@ func importPreimages(ctx *cli.Context) error {
|
||||
|
||||
// exportPreimages dumps the preimage data to specified json file in streaming way.
|
||||
func exportPreimages(ctx *cli.Context) error {
|
||||
if len(ctx.Args()) < 1 {
|
||||
if ctx.Args().Len() < 1 {
|
||||
utils.Fatalf("This command requires an argument.")
|
||||
}
|
||||
stack, _ := makeConfigNode(ctx)
|
||||
|
||||
+48
-46
@@ -25,7 +25,7 @@ import (
|
||||
"reflect"
|
||||
"unicode"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/ethereum/go-ethereum/accounts/external"
|
||||
"github.com/ethereum/go-ethereum/accounts/keystore"
|
||||
@@ -35,6 +35,7 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/eth/ethconfig"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/metrics"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
@@ -43,19 +44,19 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
dumpConfigCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(dumpConfig),
|
||||
dumpConfigCommand = &cli.Command{
|
||||
Action: dumpConfig,
|
||||
Name: "dumpconfig",
|
||||
Usage: "Show configuration values",
|
||||
ArgsUsage: "",
|
||||
Flags: utils.GroupFlags(nodeFlags, rpcFlags),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: flags.Merge(nodeFlags, rpcFlags),
|
||||
Description: `The dumpconfig command shows configuration values.`,
|
||||
}
|
||||
|
||||
configFileFlag = cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "TOML configuration file",
|
||||
configFileFlag = &cli.StringFlag{
|
||||
Name: "config",
|
||||
Usage: "TOML configuration file",
|
||||
Category: flags.EthCategory,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -127,7 +128,7 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
||||
}
|
||||
|
||||
// Load config file.
|
||||
if file := ctx.GlobalString(configFileFlag.Name); file != "" {
|
||||
if file := ctx.String(configFileFlag.Name); file != "" {
|
||||
if err := loadConfig(file, &cfg); err != nil {
|
||||
utils.Fatalf("%v", err)
|
||||
}
|
||||
@@ -145,8 +146,8 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
||||
}
|
||||
|
||||
utils.SetEthConfig(ctx, stack, &cfg.Eth)
|
||||
if ctx.GlobalIsSet(utils.EthStatsURLFlag.Name) {
|
||||
cfg.Ethstats.URL = ctx.GlobalString(utils.EthStatsURLFlag.Name)
|
||||
if ctx.IsSet(utils.EthStatsURLFlag.Name) {
|
||||
cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name)
|
||||
}
|
||||
applyMetricConfig(ctx, &cfg)
|
||||
|
||||
@@ -156,15 +157,15 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) {
|
||||
// makeFullNode loads geth configuration and creates the Ethereum backend.
|
||||
func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
||||
stack, cfg := makeConfigNode(ctx)
|
||||
if ctx.GlobalIsSet(utils.OverrideArrowGlacierFlag.Name) {
|
||||
cfg.Eth.OverrideArrowGlacier = new(big.Int).SetUint64(ctx.GlobalUint64(utils.OverrideArrowGlacierFlag.Name))
|
||||
if ctx.IsSet(utils.OverrideGrayGlacierFlag.Name) {
|
||||
cfg.Eth.OverrideGrayGlacier = new(big.Int).SetUint64(ctx.Uint64(utils.OverrideGrayGlacierFlag.Name))
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.OverrideTerminalTotalDifficulty.Name) {
|
||||
cfg.Eth.OverrideTerminalTotalDifficulty = utils.GlobalBig(ctx, utils.OverrideTerminalTotalDifficulty.Name)
|
||||
if ctx.IsSet(utils.OverrideTerminalTotalDifficulty.Name) {
|
||||
cfg.Eth.OverrideTerminalTotalDifficulty = flags.GlobalBig(ctx, utils.OverrideTerminalTotalDifficulty.Name)
|
||||
}
|
||||
backend, eth := utils.RegisterEthService(stack, &cfg.Eth)
|
||||
// Warn users to migrate if they have a legacy freezer format.
|
||||
if eth != nil {
|
||||
if eth != nil && !ctx.IsSet(utils.IgnoreLegacyReceiptsFlag.Name) {
|
||||
firstIdx := uint64(0)
|
||||
// Hack to speed up check for mainnet because we know
|
||||
// the first non-empty block.
|
||||
@@ -176,12 +177,13 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) {
|
||||
if err != nil {
|
||||
log.Error("Failed to check db for legacy receipts", "err", err)
|
||||
} else if isLegacy {
|
||||
log.Warn("Database has receipts with a legacy format. Please run `geth db freezer-migrate`.")
|
||||
stack.Close()
|
||||
utils.Fatalf("Database has receipts with a legacy format. Please run `geth db freezer-migrate`.")
|
||||
}
|
||||
}
|
||||
|
||||
// Configure GraphQL if requested
|
||||
if ctx.GlobalIsSet(utils.GraphQLEnabledFlag.Name) {
|
||||
if ctx.IsSet(utils.GraphQLEnabledFlag.Name) {
|
||||
utils.RegisterGraphQLService(stack, backend, cfg.Node)
|
||||
}
|
||||
// Add the Ethereum Stats daemon if requested.
|
||||
@@ -221,47 +223,47 @@ func dumpConfig(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
func applyMetricConfig(ctx *cli.Context, cfg *gethConfig) {
|
||||
if ctx.GlobalIsSet(utils.MetricsEnabledFlag.Name) {
|
||||
cfg.Metrics.Enabled = ctx.GlobalBool(utils.MetricsEnabledFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsEnabledFlag.Name) {
|
||||
cfg.Metrics.Enabled = ctx.Bool(utils.MetricsEnabledFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsEnabledExpensiveFlag.Name) {
|
||||
cfg.Metrics.EnabledExpensive = ctx.GlobalBool(utils.MetricsEnabledExpensiveFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsEnabledExpensiveFlag.Name) {
|
||||
cfg.Metrics.EnabledExpensive = ctx.Bool(utils.MetricsEnabledExpensiveFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsHTTPFlag.Name) {
|
||||
cfg.Metrics.HTTP = ctx.GlobalString(utils.MetricsHTTPFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsHTTPFlag.Name) {
|
||||
cfg.Metrics.HTTP = ctx.String(utils.MetricsHTTPFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsPortFlag.Name) {
|
||||
cfg.Metrics.Port = ctx.GlobalInt(utils.MetricsPortFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsPortFlag.Name) {
|
||||
cfg.Metrics.Port = ctx.Int(utils.MetricsPortFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsEnableInfluxDBFlag.Name) {
|
||||
cfg.Metrics.EnableInfluxDB = ctx.GlobalBool(utils.MetricsEnableInfluxDBFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsEnableInfluxDBFlag.Name) {
|
||||
cfg.Metrics.EnableInfluxDB = ctx.Bool(utils.MetricsEnableInfluxDBFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBEndpointFlag.Name) {
|
||||
cfg.Metrics.InfluxDBEndpoint = ctx.GlobalString(utils.MetricsInfluxDBEndpointFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBEndpointFlag.Name) {
|
||||
cfg.Metrics.InfluxDBEndpoint = ctx.String(utils.MetricsInfluxDBEndpointFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBDatabaseFlag.Name) {
|
||||
cfg.Metrics.InfluxDBDatabase = ctx.GlobalString(utils.MetricsInfluxDBDatabaseFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBDatabaseFlag.Name) {
|
||||
cfg.Metrics.InfluxDBDatabase = ctx.String(utils.MetricsInfluxDBDatabaseFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBUsernameFlag.Name) {
|
||||
cfg.Metrics.InfluxDBUsername = ctx.GlobalString(utils.MetricsInfluxDBUsernameFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBUsernameFlag.Name) {
|
||||
cfg.Metrics.InfluxDBUsername = ctx.String(utils.MetricsInfluxDBUsernameFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBPasswordFlag.Name) {
|
||||
cfg.Metrics.InfluxDBPassword = ctx.GlobalString(utils.MetricsInfluxDBPasswordFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBPasswordFlag.Name) {
|
||||
cfg.Metrics.InfluxDBPassword = ctx.String(utils.MetricsInfluxDBPasswordFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBTagsFlag.Name) {
|
||||
cfg.Metrics.InfluxDBTags = ctx.GlobalString(utils.MetricsInfluxDBTagsFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBTagsFlag.Name) {
|
||||
cfg.Metrics.InfluxDBTags = ctx.String(utils.MetricsInfluxDBTagsFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
|
||||
cfg.Metrics.EnableInfluxDBV2 = ctx.GlobalBool(utils.MetricsEnableInfluxDBV2Flag.Name)
|
||||
if ctx.IsSet(utils.MetricsEnableInfluxDBV2Flag.Name) {
|
||||
cfg.Metrics.EnableInfluxDBV2 = ctx.Bool(utils.MetricsEnableInfluxDBV2Flag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBTokenFlag.Name) {
|
||||
cfg.Metrics.InfluxDBToken = ctx.GlobalString(utils.MetricsInfluxDBTokenFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBTokenFlag.Name) {
|
||||
cfg.Metrics.InfluxDBToken = ctx.String(utils.MetricsInfluxDBTokenFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBBucketFlag.Name) {
|
||||
cfg.Metrics.InfluxDBBucket = ctx.GlobalString(utils.MetricsInfluxDBBucketFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBBucketFlag.Name) {
|
||||
cfg.Metrics.InfluxDBBucket = ctx.String(utils.MetricsInfluxDBBucketFlag.Name)
|
||||
}
|
||||
if ctx.GlobalIsSet(utils.MetricsInfluxDBOrganizationFlag.Name) {
|
||||
cfg.Metrics.InfluxDBOrganization = ctx.GlobalString(utils.MetricsInfluxDBOrganizationFlag.Name)
|
||||
if ctx.IsSet(utils.MetricsInfluxDBOrganizationFlag.Name) {
|
||||
cfg.Metrics.InfluxDBOrganization = ctx.String(utils.MetricsInfluxDBOrganizationFlag.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+38
-92
@@ -18,39 +18,36 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/console"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/node"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
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: utils.GroupFlags(nodeFlags, rpcFlags, consoleFlags),
|
||||
Category: "CONSOLE COMMANDS",
|
||||
consoleCommand = &cli.Command{
|
||||
Action: localConsole,
|
||||
Name: "console",
|
||||
Usage: "Start an interactive JavaScript environment",
|
||||
Flags: flags.Merge(nodeFlags, rpcFlags, consoleFlags),
|
||||
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://geth.ethereum.org/docs/interface/javascript-console.`,
|
||||
}
|
||||
|
||||
attachCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(remoteConsole),
|
||||
attachCommand = &cli.Command{
|
||||
Action: remoteConsole,
|
||||
Name: "attach",
|
||||
Usage: "Start an interactive JavaScript environment (connect to node)",
|
||||
ArgsUsage: "[endpoint]",
|
||||
Flags: utils.GroupFlags([]cli.Flag{utils.DataDirFlag}, consoleFlags),
|
||||
Category: "CONSOLE COMMANDS",
|
||||
Flags: flags.Merge([]cli.Flag{utils.DataDirFlag}, consoleFlags),
|
||||
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.
|
||||
@@ -58,13 +55,12 @@ See https://geth.ethereum.org/docs/interface/javascript-console.
|
||||
This command allows to open a console on a running geth node.`,
|
||||
}
|
||||
|
||||
javascriptCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(ephemeralConsole),
|
||||
javascriptCommand = &cli.Command{
|
||||
Action: ephemeralConsole,
|
||||
Name: "js",
|
||||
Usage: "Execute the specified JavaScript files",
|
||||
Usage: "(DEPRECATED) Execute the specified JavaScript files",
|
||||
ArgsUsage: "<jsfile> [jsfile...]",
|
||||
Flags: utils.GroupFlags(nodeFlags, consoleFlags),
|
||||
Category: "CONSOLE COMMANDS",
|
||||
Flags: flags.Merge(nodeFlags, consoleFlags),
|
||||
Description: `
|
||||
The JavaScript VM exposes a node admin interface as well as the Ðapp
|
||||
JavaScript API. See https://geth.ethereum.org/docs/interface/javascript-console`,
|
||||
@@ -87,7 +83,7 @@ func localConsole(ctx *cli.Context) error {
|
||||
}
|
||||
config := console.Config{
|
||||
DataDir: utils.MakeDataDir(ctx),
|
||||
DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
|
||||
DocRoot: ctx.String(utils.JSpathFlag.Name),
|
||||
Client: client,
|
||||
Preload: utils.MakeConsolePreloads(ctx),
|
||||
}
|
||||
@@ -98,7 +94,7 @@ func localConsole(ctx *cli.Context) error {
|
||||
defer console.Stop(false)
|
||||
|
||||
// If only a short execution was requested, evaluate and return.
|
||||
if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
|
||||
if script := ctx.String(utils.ExecFlag.Name); script != "" {
|
||||
console.Evaluate(script)
|
||||
return nil
|
||||
}
|
||||
@@ -119,33 +115,15 @@ func localConsole(ctx *cli.Context) error {
|
||||
// remoteConsole will connect to a remote geth instance, attaching a JavaScript
|
||||
// console to it.
|
||||
func remoteConsole(ctx *cli.Context) error {
|
||||
if ctx.Args().Len() > 1 {
|
||||
utils.Fatalf("invalid command-line: too many arguments")
|
||||
}
|
||||
|
||||
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.RopstenFlag.Name) {
|
||||
// Maintain compatibility with older Geth configurations storing the
|
||||
// Ropsten database in `testnet` instead of `ropsten`.
|
||||
legacyPath := filepath.Join(path, "testnet")
|
||||
if common.FileExist(legacyPath) {
|
||||
path = legacyPath
|
||||
} else {
|
||||
path = filepath.Join(path, "ropsten")
|
||||
}
|
||||
} else if ctx.GlobalBool(utils.RinkebyFlag.Name) {
|
||||
path = filepath.Join(path, "rinkeby")
|
||||
} else if ctx.GlobalBool(utils.GoerliFlag.Name) {
|
||||
path = filepath.Join(path, "goerli")
|
||||
} else if ctx.GlobalBool(utils.SepoliaFlag.Name) {
|
||||
path = filepath.Join(path, "sepolia")
|
||||
} else if ctx.GlobalBool(utils.KilnFlag.Name) {
|
||||
path = filepath.Join(path, "kiln")
|
||||
}
|
||||
}
|
||||
endpoint = fmt.Sprintf("%s/geth.ipc", path)
|
||||
cfg := defaultNodeConfig()
|
||||
utils.SetDataDir(ctx, &cfg)
|
||||
endpoint = cfg.IPCEndpoint()
|
||||
}
|
||||
client, err := dialRPC(endpoint)
|
||||
if err != nil {
|
||||
@@ -153,7 +131,7 @@ func remoteConsole(ctx *cli.Context) error {
|
||||
}
|
||||
config := console.Config{
|
||||
DataDir: utils.MakeDataDir(ctx),
|
||||
DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
|
||||
DocRoot: ctx.String(utils.JSpathFlag.Name),
|
||||
Client: client,
|
||||
Preload: utils.MakeConsolePreloads(ctx),
|
||||
}
|
||||
@@ -163,7 +141,7 @@ func remoteConsole(ctx *cli.Context) error {
|
||||
}
|
||||
defer console.Stop(false)
|
||||
|
||||
if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
|
||||
if script := ctx.String(utils.ExecFlag.Name); script != "" {
|
||||
console.Evaluate(script)
|
||||
return nil
|
||||
}
|
||||
@@ -174,6 +152,19 @@ func remoteConsole(ctx *cli.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
var b strings.Builder
|
||||
for _, file := range ctx.Args().Slice() {
|
||||
b.Write([]byte(fmt.Sprintf("loadScript('%s');", file)))
|
||||
}
|
||||
utils.Fatalf(`The "js" command is deprecated. Please use the following instead:
|
||||
geth --exec "%s" console`, b.String())
|
||||
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" with no argument.
|
||||
@@ -187,48 +178,3 @@ func dialRPC(endpoint string) (*rpc.Client, error) {
|
||||
}
|
||||
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
|
||||
stack, backend := makeFullNode(ctx)
|
||||
startNode(ctx, stack, backend, false)
|
||||
defer stack.Close()
|
||||
|
||||
// Attach to the newly started node and start the JavaScript console
|
||||
client, err := stack.Attach()
|
||||
if err != nil {
|
||||
return fmt.Errorf("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 {
|
||||
return fmt.Errorf("Failed to start the JavaScript console: %v", err)
|
||||
}
|
||||
defer console.Stop(false)
|
||||
|
||||
// Interrupt the JS interpreter when node is stopped.
|
||||
go func() {
|
||||
stack.Wait()
|
||||
console.Stop(false)
|
||||
}()
|
||||
|
||||
// Evaluate each of the specified JavaScript files.
|
||||
for _, file := range ctx.Args() {
|
||||
if err = console.Execute(file); err != nil {
|
||||
return fmt.Errorf("Failed to execute %s: %v", file, err)
|
||||
}
|
||||
}
|
||||
|
||||
// The main script is now done, but keep running timers/callbacks.
|
||||
console.Stop(true)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ func runMinimalGeth(t *testing.T, args ...string) *testgeth {
|
||||
// --ropsten to make the 'writing genesis to disk' faster (no accounts)
|
||||
// --networkid=1337 to avoid cache bump
|
||||
// --syncmode=full to avoid allocating fast sync bloom
|
||||
allArgs := []string{"--ropsten", "--networkid", "1337", "--syncmode=full", "--port", "0",
|
||||
allArgs := []string{"--ropsten", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0",
|
||||
"--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64",
|
||||
"--datadir.minfreedisk", "0"}
|
||||
return runGeth(t, append(allArgs, args...)...)
|
||||
|
||||
+56
-57
@@ -37,29 +37,28 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/ethdb"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
"github.com/olekukonko/tablewriter"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
removedbCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(removeDB),
|
||||
removedbCommand = &cli.Command{
|
||||
Action: removeDB,
|
||||
Name: "removedb",
|
||||
Usage: "Remove blockchain and state databases",
|
||||
ArgsUsage: "",
|
||||
Flags: utils.DatabasePathFlags,
|
||||
Category: "DATABASE COMMANDS",
|
||||
Description: `
|
||||
Remove blockchain and state databases`,
|
||||
}
|
||||
dbCommand = cli.Command{
|
||||
dbCommand = &cli.Command{
|
||||
Name: "db",
|
||||
Usage: "Low level database operations",
|
||||
ArgsUsage: "",
|
||||
Category: "DATABASE COMMANDS",
|
||||
Subcommands: []cli.Command{
|
||||
Subcommands: []*cli.Command{
|
||||
dbInspectCmd,
|
||||
dbStatCmd,
|
||||
dbCompactCmd,
|
||||
@@ -75,39 +74,39 @@ Remove blockchain and state databases`,
|
||||
dbCheckStateContentCmd,
|
||||
},
|
||||
}
|
||||
dbInspectCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(inspect),
|
||||
dbInspectCmd = &cli.Command{
|
||||
Action: inspect,
|
||||
Name: "inspect",
|
||||
ArgsUsage: "<prefix> <start>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Usage: "Inspect the storage size for each type of data in the database",
|
||||
Description: `This commands iterates the entire database. If the optional 'prefix' and 'start' arguments are provided, then the iteration is limited to the given subset of data.`,
|
||||
}
|
||||
dbCheckStateContentCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(checkStateContent),
|
||||
dbCheckStateContentCmd = &cli.Command{
|
||||
Action: checkStateContent,
|
||||
Name: "check-state-content",
|
||||
ArgsUsage: "<start (optional)>",
|
||||
Flags: utils.GroupFlags(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Usage: "Verify that state data is cryptographically correct",
|
||||
Description: `This command iterates the entire database for 32-byte keys, looking for rlp-encoded trie nodes.
|
||||
For each trie node encountered, it checks that the key corresponds to the keccak256(value). If this is not true, this indicates
|
||||
a data corruption.`,
|
||||
}
|
||||
dbStatCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(dbStats),
|
||||
dbStatCmd = &cli.Command{
|
||||
Action: dbStats,
|
||||
Name: "stats",
|
||||
Usage: "Print leveldb statistics",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
}
|
||||
dbCompactCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(dbCompact),
|
||||
dbCompactCmd = &cli.Command{
|
||||
Action: dbCompact,
|
||||
Name: "compact",
|
||||
Usage: "Compact leveldb database. WARNING: May take a very long time",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
utils.CacheFlag,
|
||||
utils.CacheDatabaseFlag,
|
||||
@@ -116,93 +115,93 @@ a data corruption.`,
|
||||
WARNING: This operation may take a very long time to finish, and may cause database
|
||||
corruption if it is aborted during execution'!`,
|
||||
}
|
||||
dbGetCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(dbGet),
|
||||
dbGetCmd = &cli.Command{
|
||||
Action: dbGet,
|
||||
Name: "get",
|
||||
Usage: "Show the value of a database key",
|
||||
ArgsUsage: "<hex-encoded key>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: "This command looks up the specified database key from the database.",
|
||||
}
|
||||
dbDeleteCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(dbDelete),
|
||||
dbDeleteCmd = &cli.Command{
|
||||
Action: dbDelete,
|
||||
Name: "delete",
|
||||
Usage: "Delete a database key (WARNING: may corrupt your database)",
|
||||
ArgsUsage: "<hex-encoded key>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `This command deletes the specified database key from the database.
|
||||
WARNING: This is a low-level operation which may cause database corruption!`,
|
||||
}
|
||||
dbPutCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(dbPut),
|
||||
dbPutCmd = &cli.Command{
|
||||
Action: dbPut,
|
||||
Name: "put",
|
||||
Usage: "Set the value of a database key (WARNING: may corrupt your database)",
|
||||
ArgsUsage: "<hex-encoded key> <hex-encoded value>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `This command sets a given database key to the given value.
|
||||
WARNING: This is a low-level operation which may cause database corruption!`,
|
||||
}
|
||||
dbGetSlotsCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(dbDumpTrie),
|
||||
dbGetSlotsCmd = &cli.Command{
|
||||
Action: dbDumpTrie,
|
||||
Name: "dumptrie",
|
||||
Usage: "Show the storage key/values of a given storage trie",
|
||||
ArgsUsage: "<hex-encoded storage trie root> <hex-encoded start (optional)> <int max elements (optional)>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: "This command looks up the specified database key from the database.",
|
||||
}
|
||||
dbDumpFreezerIndex = cli.Command{
|
||||
Action: utils.MigrateFlags(freezerInspect),
|
||||
dbDumpFreezerIndex = &cli.Command{
|
||||
Action: freezerInspect,
|
||||
Name: "freezer-index",
|
||||
Usage: "Dump out the index of a given freezer type",
|
||||
ArgsUsage: "<type> <start (int)> <end (int)>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: "This command displays information about the freezer index.",
|
||||
}
|
||||
dbImportCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(importLDBdata),
|
||||
dbImportCmd = &cli.Command{
|
||||
Action: importLDBdata,
|
||||
Name: "import",
|
||||
Usage: "Imports leveldb-data from an exported RLP dump.",
|
||||
ArgsUsage: "<dumpfile> <start (optional)",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: "The import command imports the specific chain data from an RLP encoded stream.",
|
||||
}
|
||||
dbExportCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(exportChaindata),
|
||||
dbExportCmd = &cli.Command{
|
||||
Action: exportChaindata,
|
||||
Name: "export",
|
||||
Usage: "Exports the chain data into an RLP dump. If the <dumpfile> has .gz suffix, gzip compression will be used.",
|
||||
ArgsUsage: "<type> <dumpfile>",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: "Exports the specified chain data to an RLP encoded stream, optionally gzip-compressed.",
|
||||
}
|
||||
dbMetadataCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(showMetaData),
|
||||
dbMetadataCmd = &cli.Command{
|
||||
Action: showMetaData,
|
||||
Name: "metadata",
|
||||
Usage: "Shows metadata about the chain status.",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: "Shows metadata about the chain status.",
|
||||
}
|
||||
dbMigrateFreezerCmd = cli.Command{
|
||||
Action: utils.MigrateFlags(freezerMigrate),
|
||||
dbMigrateFreezerCmd = &cli.Command{
|
||||
Action: freezerMigrate,
|
||||
Name: "freezer-migrate",
|
||||
Usage: "Migrate legacy parts of the freezer. (WARNING: may take a long time)",
|
||||
ArgsUsage: "",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.SyncModeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `The freezer-migrate command checks your database for receipts in a legacy format and updates those.
|
||||
@@ -307,7 +306,7 @@ func checkStateContent(ctx *cli.Context) error {
|
||||
start []byte
|
||||
)
|
||||
if ctx.NArg() > 1 {
|
||||
return fmt.Errorf("Max 1 argument: %v", ctx.Command.ArgsUsage)
|
||||
return fmt.Errorf("max 1 argument: %v", ctx.Command.ArgsUsage)
|
||||
}
|
||||
if ctx.NArg() > 0 {
|
||||
if d, err := hexutil.Decode(ctx.Args().First()); err != nil {
|
||||
@@ -332,16 +331,16 @@ func checkStateContent(ctx *cli.Context) error {
|
||||
)
|
||||
for it.Next() {
|
||||
count++
|
||||
v := it.Value()
|
||||
k := it.Key()
|
||||
v := it.Value()
|
||||
hasher.Reset()
|
||||
hasher.Write(v)
|
||||
hasher.Read(got)
|
||||
if !bytes.Equal(k, got) {
|
||||
errs++
|
||||
fmt.Printf("Error at 0x%x\n", k)
|
||||
fmt.Printf(" Hash: 0x%x\n", got)
|
||||
fmt.Printf(" Data: 0x%x\n", v)
|
||||
fmt.Printf("Error at %#x\n", k)
|
||||
fmt.Printf(" Hash: %#x\n", got)
|
||||
fmt.Printf(" Data: %#x\n", v)
|
||||
}
|
||||
if time.Since(lastLog) > 8*time.Second {
|
||||
log.Info("Iterating the database", "at", fmt.Sprintf("%#x", k), "elapsed", common.PrettyDuration(time.Since(startTime)))
|
||||
@@ -418,7 +417,7 @@ func dbGet(ctx *cli.Context) error {
|
||||
|
||||
data, err := db.Get(key)
|
||||
if err != nil {
|
||||
log.Info("Get operation failed", "key", fmt.Sprintf("0x%#x", key), "error", err)
|
||||
log.Info("Get operation failed", "key", fmt.Sprintf("%#x", key), "error", err)
|
||||
return err
|
||||
}
|
||||
fmt.Printf("key %#x: %#x\n", key, data)
|
||||
@@ -446,7 +445,7 @@ func dbDelete(ctx *cli.Context) error {
|
||||
fmt.Printf("Previous value: %#x\n", data)
|
||||
}
|
||||
if err = db.Delete(key); err != nil {
|
||||
log.Info("Delete operation returned an error", "key", fmt.Sprintf("0x%#x", key), "error", err)
|
||||
log.Info("Delete operation returned an error", "key", fmt.Sprintf("%#x", key), "error", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -519,7 +518,7 @@ func dbDumpTrie(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
theTrie, err := trie.New(stRoot, trie.NewDatabase(db))
|
||||
theTrie, err := trie.New(common.Hash{}, stRoot, trie.NewDatabase(db))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -718,7 +717,7 @@ func showMetaData(ctx *cli.Context) error {
|
||||
if val == nil {
|
||||
return "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("%d (0x%x)", *val, *val)
|
||||
return fmt.Sprintf("%d (%#x)", *val, *val)
|
||||
}
|
||||
data := [][]string{
|
||||
{"databaseVersion", pp(rawdb.ReadDatabaseVersion(db))},
|
||||
@@ -728,7 +727,7 @@ func showMetaData(ctx *cli.Context) error {
|
||||
if b := rawdb.ReadHeadBlock(db); b != nil {
|
||||
data = append(data, []string{"headBlock.Hash", fmt.Sprintf("%v", b.Hash())})
|
||||
data = append(data, []string{"headBlock.Root", fmt.Sprintf("%v", b.Root())})
|
||||
data = append(data, []string{"headBlock.Number", fmt.Sprintf("%d (0x%x)", b.Number(), b.Number())})
|
||||
data = append(data, []string{"headBlock.Number", fmt.Sprintf("%d (%#x)", b.Number(), b.Number())})
|
||||
}
|
||||
if b := rawdb.ReadSkeletonSyncStatus(db); b != nil {
|
||||
data = append(data, []string{"SkeletonSyncStatus", string(b)})
|
||||
@@ -736,7 +735,7 @@ func showMetaData(ctx *cli.Context) error {
|
||||
if h := rawdb.ReadHeadHeader(db); h != nil {
|
||||
data = append(data, []string{"headHeader.Hash", fmt.Sprintf("%v", h.Hash())})
|
||||
data = append(data, []string{"headHeader.Root", fmt.Sprintf("%v", h.Root)})
|
||||
data = append(data, []string{"headHeader.Number", fmt.Sprintf("%d (0x%x)", h.Number, h.Number)})
|
||||
data = append(data, []string{"headHeader.Number", fmt.Sprintf("%d (%#x)", h.Number, h.Number)})
|
||||
}
|
||||
data = append(data, [][]string{{"frozen", fmt.Sprintf("%d items", ancients)},
|
||||
{"lastPivotNumber", pp(rawdb.ReadLastPivotNumber(db))},
|
||||
|
||||
@@ -83,7 +83,7 @@ func TestCustomGenesis(t *testing.T) {
|
||||
|
||||
// Query the custom genesis block
|
||||
geth := runGeth(t, "--networkid", "1337", "--syncmode=full", "--cache", "16",
|
||||
"--datadir", datadir, "--maxpeers", "0", "--port", "0",
|
||||
"--datadir", datadir, "--maxpeers", "0", "--port", "0", "--authrpc.port", "0",
|
||||
"--nodiscover", "--nat", "none", "--ipcdisable",
|
||||
"--exec", tt.query, "console")
|
||||
geth.ExpectRegexp(tt.result)
|
||||
|
||||
+2
-37
@@ -81,41 +81,6 @@ func (g *gethrpc) getNodeInfo() *p2p.NodeInfo {
|
||||
return g.nodeInfo
|
||||
}
|
||||
|
||||
func (g *gethrpc) waitSynced() {
|
||||
// Check if it's synced now
|
||||
var result interface{}
|
||||
g.callRPC(&result, "eth_syncing")
|
||||
syncing, ok := result.(bool)
|
||||
if ok && !syncing {
|
||||
g.geth.Logf("%v already synced", g.name)
|
||||
return
|
||||
}
|
||||
|
||||
// Actually wait, subscribe to the event
|
||||
ch := make(chan interface{})
|
||||
sub, err := g.rpc.Subscribe(context.Background(), "eth", ch, "syncing")
|
||||
if err != nil {
|
||||
g.geth.Fatalf("%v syncing: %v", g.name, err)
|
||||
}
|
||||
defer sub.Unsubscribe()
|
||||
timeout := time.After(4 * time.Second)
|
||||
select {
|
||||
case ev := <-ch:
|
||||
g.geth.Log("'syncing' event", ev)
|
||||
syncing, ok := ev.(bool)
|
||||
if ok && !syncing {
|
||||
break
|
||||
}
|
||||
g.geth.Log("Other 'syncing' event", ev)
|
||||
case err := <-sub.Err():
|
||||
g.geth.Fatalf("%v notification: %v", g.name, err)
|
||||
break
|
||||
case <-timeout:
|
||||
g.geth.Fatalf("%v timeout syncing", g.name)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// ipcEndpoint resolves an IPC endpoint based on a configured value, taking into
|
||||
// account the set data folders as well as the designated platform we're currently
|
||||
// running on.
|
||||
@@ -146,7 +111,7 @@ var nextIPC = uint32(0)
|
||||
|
||||
func startGethWithIpc(t *testing.T, name string, args ...string) *gethrpc {
|
||||
ipcName := fmt.Sprintf("geth-%d.ipc", atomic.AddUint32(&nextIPC, 1))
|
||||
args = append([]string{"--networkid=42", "--port=0", "--ipcpath", ipcName}, args...)
|
||||
args = append([]string{"--networkid=42", "--port=0", "--authrpc.port", "0", "--ipcpath", ipcName}, args...)
|
||||
t.Logf("Starting %v with rpc: %v", name, args)
|
||||
|
||||
g := &gethrpc{
|
||||
@@ -179,7 +144,7 @@ func initGeth(t *testing.T) string {
|
||||
func startLightServer(t *testing.T) *gethrpc {
|
||||
datadir := initGeth(t)
|
||||
t.Logf("Importing keys to geth")
|
||||
runGeth(t, "--datadir", datadir, "--password", "./testdata/password.txt", "account", "import", "./testdata/key.prv", "--lightkdf").WaitExit()
|
||||
runGeth(t, "account", "import", "--datadir", datadir, "--password", "./testdata/password.txt", "--lightkdf", "./testdata/key.prv").WaitExit()
|
||||
account := "0x02f0d131f1f97aef08aec6e3291b957d9efe7105"
|
||||
server := startGethWithIpc(t, "lightserver", "--allow-insecure-unlock", "--datadir", datadir, "--password", "./testdata/password.txt", "--unlock", account, "--mine", "--light.serve=100", "--light.maxpeers=1", "--nodiscover", "--nat=extip:127.0.0.1", "--verbosity=4")
|
||||
return server
|
||||
|
||||
+39
-34
@@ -47,7 +47,7 @@ import (
|
||||
_ "github.com/ethereum/go-ethereum/eth/tracers/js"
|
||||
_ "github.com/ethereum/go-ethereum/eth/tracers/native"
|
||||
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -61,7 +61,7 @@ var (
|
||||
// The app that holds all commands and flags.
|
||||
app = flags.NewApp(gitCommit, gitDate, "the go-ethereum command line interface")
|
||||
// flags that configure the node
|
||||
nodeFlags = utils.GroupFlags([]cli.Flag{
|
||||
nodeFlags = flags.Merge([]cli.Flag{
|
||||
utils.IdentityFlag,
|
||||
utils.UnlockedAccountFlag,
|
||||
utils.PasswordFileFlag,
|
||||
@@ -72,7 +72,7 @@ var (
|
||||
utils.NoUSBFlag,
|
||||
utils.USBFlag,
|
||||
utils.SmartCardDaemonPathFlag,
|
||||
utils.OverrideArrowGlacierFlag,
|
||||
utils.OverrideGrayGlacierFlag,
|
||||
utils.OverrideTerminalTotalDifficulty,
|
||||
utils.EthashCacheDirFlag,
|
||||
utils.EthashCachesInMemoryFlag,
|
||||
@@ -122,6 +122,7 @@ var (
|
||||
utils.CachePreimagesFlag,
|
||||
utils.FDLimitFlag,
|
||||
utils.ListenPortFlag,
|
||||
utils.DiscoveryPortFlag,
|
||||
utils.MaxPeersFlag,
|
||||
utils.MaxPendingPeersFlag,
|
||||
utils.MiningEnabledFlag,
|
||||
@@ -154,6 +155,7 @@ var (
|
||||
utils.GpoMaxGasPriceFlag,
|
||||
utils.GpoIgnoreGasPriceFlag,
|
||||
utils.MinerNotifyFullFlag,
|
||||
utils.IgnoreLegacyReceiptsFlag,
|
||||
configFileFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags)
|
||||
|
||||
@@ -210,7 +212,7 @@ func init() {
|
||||
app.Action = geth
|
||||
app.HideVersion = true // we have a command to print the version
|
||||
app.Copyright = "Copyright 2013-2022 The go-ethereum Authors"
|
||||
app.Commands = []cli.Command{
|
||||
app.Commands = []*cli.Command{
|
||||
// See chaincmd.go:
|
||||
initCommand,
|
||||
importCommand,
|
||||
@@ -244,13 +246,16 @@ func init() {
|
||||
}
|
||||
sort.Sort(cli.CommandsByName(app.Commands))
|
||||
|
||||
app.Flags = utils.GroupFlags(nodeFlags,
|
||||
app.Flags = flags.Merge(
|
||||
nodeFlags,
|
||||
rpcFlags,
|
||||
consoleFlags,
|
||||
debug.Flags,
|
||||
metricsFlags)
|
||||
metricsFlags,
|
||||
)
|
||||
|
||||
app.Before = func(ctx *cli.Context) error {
|
||||
flags.MigrateGlobalFlags(ctx)
|
||||
return debug.Setup(ctx)
|
||||
}
|
||||
app.After = func(ctx *cli.Context) error {
|
||||
@@ -272,22 +277,22 @@ func main() {
|
||||
func prepare(ctx *cli.Context) {
|
||||
// If we're running a known preset, log it for convenience.
|
||||
switch {
|
||||
case ctx.GlobalIsSet(utils.RopstenFlag.Name):
|
||||
case ctx.IsSet(utils.RopstenFlag.Name):
|
||||
log.Info("Starting Geth on Ropsten testnet...")
|
||||
|
||||
case ctx.GlobalIsSet(utils.RinkebyFlag.Name):
|
||||
case ctx.IsSet(utils.RinkebyFlag.Name):
|
||||
log.Info("Starting Geth on Rinkeby testnet...")
|
||||
|
||||
case ctx.GlobalIsSet(utils.GoerliFlag.Name):
|
||||
case ctx.IsSet(utils.GoerliFlag.Name):
|
||||
log.Info("Starting Geth on Görli testnet...")
|
||||
|
||||
case ctx.GlobalIsSet(utils.SepoliaFlag.Name):
|
||||
case ctx.IsSet(utils.SepoliaFlag.Name):
|
||||
log.Info("Starting Geth on Sepolia testnet...")
|
||||
|
||||
case ctx.GlobalIsSet(utils.KilnFlag.Name):
|
||||
case ctx.IsSet(utils.KilnFlag.Name):
|
||||
log.Info("Starting Geth on Kiln testnet...")
|
||||
|
||||
case ctx.GlobalIsSet(utils.DeveloperFlag.Name):
|
||||
case ctx.IsSet(utils.DeveloperFlag.Name):
|
||||
log.Info("Starting Geth in ephemeral dev mode...")
|
||||
log.Warn(`You are running Geth in --dev mode. Please note the following:
|
||||
|
||||
@@ -305,27 +310,27 @@ func prepare(ctx *cli.Context) {
|
||||
to 0, and discovery is disabled.
|
||||
`)
|
||||
|
||||
case !ctx.GlobalIsSet(utils.NetworkIdFlag.Name):
|
||||
case !ctx.IsSet(utils.NetworkIdFlag.Name):
|
||||
log.Info("Starting Geth on Ethereum mainnet...")
|
||||
}
|
||||
// If we're a full node on mainnet without --cache specified, bump default cache allowance
|
||||
if ctx.GlobalString(utils.SyncModeFlag.Name) != "light" && !ctx.GlobalIsSet(utils.CacheFlag.Name) && !ctx.GlobalIsSet(utils.NetworkIdFlag.Name) {
|
||||
if ctx.String(utils.SyncModeFlag.Name) != "light" && !ctx.IsSet(utils.CacheFlag.Name) && !ctx.IsSet(utils.NetworkIdFlag.Name) {
|
||||
// Make sure we're not on any supported preconfigured testnet either
|
||||
if !ctx.GlobalIsSet(utils.RopstenFlag.Name) &&
|
||||
!ctx.GlobalIsSet(utils.SepoliaFlag.Name) &&
|
||||
!ctx.GlobalIsSet(utils.RinkebyFlag.Name) &&
|
||||
!ctx.GlobalIsSet(utils.GoerliFlag.Name) &&
|
||||
!ctx.GlobalIsSet(utils.KilnFlag.Name) &&
|
||||
!ctx.GlobalIsSet(utils.DeveloperFlag.Name) {
|
||||
if !ctx.IsSet(utils.RopstenFlag.Name) &&
|
||||
!ctx.IsSet(utils.SepoliaFlag.Name) &&
|
||||
!ctx.IsSet(utils.RinkebyFlag.Name) &&
|
||||
!ctx.IsSet(utils.GoerliFlag.Name) &&
|
||||
!ctx.IsSet(utils.KilnFlag.Name) &&
|
||||
!ctx.IsSet(utils.DeveloperFlag.Name) {
|
||||
// Nope, we're really on mainnet. Bump that cache up!
|
||||
log.Info("Bumping default cache on mainnet", "provided", ctx.GlobalInt(utils.CacheFlag.Name), "updated", 4096)
|
||||
ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(4096))
|
||||
log.Info("Bumping default cache on mainnet", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 4096)
|
||||
ctx.Set(utils.CacheFlag.Name, strconv.Itoa(4096))
|
||||
}
|
||||
}
|
||||
// If we're running a light client on any network, drop the cache to some meaningfully low amount
|
||||
if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" && !ctx.GlobalIsSet(utils.CacheFlag.Name) {
|
||||
log.Info("Dropping default light client cache", "provided", ctx.GlobalInt(utils.CacheFlag.Name), "updated", 128)
|
||||
ctx.GlobalSet(utils.CacheFlag.Name, strconv.Itoa(128))
|
||||
if ctx.String(utils.SyncModeFlag.Name) == "light" && !ctx.IsSet(utils.CacheFlag.Name) {
|
||||
log.Info("Dropping default light client cache", "provided", ctx.Int(utils.CacheFlag.Name), "updated", 128)
|
||||
ctx.Set(utils.CacheFlag.Name, strconv.Itoa(128))
|
||||
}
|
||||
|
||||
// Start metrics export if enabled
|
||||
@@ -340,12 +345,12 @@ func prepare(ctx *cli.Context) {
|
||||
// blocking mode, waiting for it to be shut down.
|
||||
func geth(ctx *cli.Context) error {
|
||||
//begin PluGeth code injection
|
||||
if err := plugins.Initialize(path.Join(ctx.GlobalString(utils.DataDirFlag.Name), "plugins"), ctx); err != nil {
|
||||
if err := plugins.Initialize(path.Join(ctx.String(utils.DataDirFlag.Name), "plugins"), ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
prepare(ctx)
|
||||
if !plugins.ParseFlags(ctx.Args()) {
|
||||
if args := ctx.Args(); len(args) > 0 {
|
||||
if !plugins.ParseFlags(ctx.Args().Slice()) {
|
||||
if args := ctx.Args().Slice(); len(args) > 0 {
|
||||
return fmt.Errorf("invalid command: %q", args[0])
|
||||
}
|
||||
}
|
||||
@@ -422,7 +427,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
|
||||
|
||||
// Spawn a standalone goroutine for status synchronization monitoring,
|
||||
// close the node when synchronization is complete if user required.
|
||||
if ctx.GlobalBool(utils.ExitWhenSyncedFlag.Name) {
|
||||
if ctx.Bool(utils.ExitWhenSyncedFlag.Name) {
|
||||
go func() {
|
||||
sub := stack.EventMux().Subscribe(downloader.DoneEvent{})
|
||||
defer sub.Unsubscribe()
|
||||
@@ -445,9 +450,9 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
|
||||
}
|
||||
|
||||
// Start auxiliary services if enabled
|
||||
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
|
||||
if ctx.Bool(utils.MiningEnabledFlag.Name) || ctx.Bool(utils.DeveloperFlag.Name) {
|
||||
// Mining only makes sense if a full Ethereum node is running
|
||||
if ctx.GlobalString(utils.SyncModeFlag.Name) == "light" {
|
||||
if ctx.String(utils.SyncModeFlag.Name) == "light" {
|
||||
utils.Fatalf("Light clients do not support mining")
|
||||
}
|
||||
ethBackend, ok := backend.(*eth.EthAPIBackend)
|
||||
@@ -455,10 +460,10 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
|
||||
utils.Fatalf("Ethereum service not running")
|
||||
}
|
||||
// Set the gas price to the limits from the CLI and start mining
|
||||
gasprice := utils.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
|
||||
gasprice := flags.GlobalBig(ctx, utils.MinerGasPriceFlag.Name)
|
||||
ethBackend.TxPool().SetGasPrice(gasprice)
|
||||
// start mining
|
||||
threads := ctx.GlobalInt(utils.MinerThreadsFlag.Name)
|
||||
threads := ctx.Int(utils.MinerThreadsFlag.Name)
|
||||
if err := ethBackend.StartMining(threads); err != nil {
|
||||
utils.Fatalf("Failed to start mining: %v", err)
|
||||
}
|
||||
@@ -468,7 +473,7 @@ func startNode(ctx *cli.Context, stack *node.Node, backend ethapi.Backend, isCon
|
||||
// unlockAccounts unlocks any account specifically requested.
|
||||
func unlockAccounts(ctx *cli.Context, stack *node.Node) {
|
||||
var unlocks []string
|
||||
inputs := strings.Split(ctx.GlobalString(utils.UnlockedAccountFlag.Name), ",")
|
||||
inputs := strings.Split(ctx.String(utils.UnlockedAccountFlag.Name), ",")
|
||||
for _, input := range inputs {
|
||||
if trimmed := strings.TrimSpace(input); trimmed != "" {
|
||||
unlocks = append(unlocks, trimmed)
|
||||
|
||||
+16
-21
@@ -26,28 +26,27 @@ import (
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/consensus/ethash"
|
||||
"github.com/ethereum/go-ethereum/params"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
VersionCheckUrlFlag = cli.StringFlag{
|
||||
VersionCheckUrlFlag = &cli.StringFlag{
|
||||
Name: "check.url",
|
||||
Usage: "URL to use when checking vulnerabilities",
|
||||
Value: "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json",
|
||||
}
|
||||
VersionCheckVersionFlag = cli.StringFlag{
|
||||
VersionCheckVersionFlag = &cli.StringFlag{
|
||||
Name: "check.version",
|
||||
Usage: "Version to check",
|
||||
Value: fmt.Sprintf("Geth/v%v/%v-%v/%v",
|
||||
params.VersionWithCommit(gitCommit, gitDate),
|
||||
runtime.GOOS, runtime.GOARCH, runtime.Version()),
|
||||
}
|
||||
makecacheCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(makecache),
|
||||
makecacheCommand = &cli.Command{
|
||||
Action: makecache,
|
||||
Name: "makecache",
|
||||
Usage: "Generate ethash verification cache (for testing)",
|
||||
ArgsUsage: "<blockNum> <outputDir>",
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Description: `
|
||||
The makecache command generates an ethash cache in <outputDir>.
|
||||
|
||||
@@ -55,12 +54,11 @@ This command exists to support the system testing project.
|
||||
Regular users do not need to execute it.
|
||||
`,
|
||||
}
|
||||
makedagCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(makedag),
|
||||
makedagCommand = &cli.Command{
|
||||
Action: makedag,
|
||||
Name: "makedag",
|
||||
Usage: "Generate ethash mining DAG (for testing)",
|
||||
ArgsUsage: "<blockNum> <outputDir>",
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Description: `
|
||||
The makedag command generates an ethash DAG in <outputDir>.
|
||||
|
||||
@@ -68,43 +66,40 @@ This command exists to support the system testing project.
|
||||
Regular users do not need to execute it.
|
||||
`,
|
||||
}
|
||||
versionCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(version),
|
||||
versionCommand = &cli.Command{
|
||||
Action: version,
|
||||
Name: "version",
|
||||
Usage: "Print version numbers",
|
||||
ArgsUsage: " ",
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Description: `
|
||||
The output of this command is supposed to be machine-readable.
|
||||
`,
|
||||
}
|
||||
versionCheckCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(versionCheck),
|
||||
versionCheckCommand = &cli.Command{
|
||||
Action: versionCheck,
|
||||
Flags: []cli.Flag{
|
||||
VersionCheckUrlFlag,
|
||||
VersionCheckVersionFlag,
|
||||
},
|
||||
Name: "version-check",
|
||||
Usage: "Checks (online) whether the current version suffers from any known security vulnerabilities",
|
||||
Usage: "Checks (online) for known Geth security vulnerabilities",
|
||||
ArgsUsage: "<versionstring (optional)>",
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Description: `
|
||||
The version-check command fetches vulnerability-information from https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json,
|
||||
and displays information about any security vulnerabilities that affect the currently executing version.
|
||||
`,
|
||||
}
|
||||
licenseCommand = cli.Command{
|
||||
Action: utils.MigrateFlags(license),
|
||||
licenseCommand = &cli.Command{
|
||||
Action: 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()
|
||||
args := ctx.Args().Slice()
|
||||
if len(args) != 2 {
|
||||
utils.Fatalf(`Usage: geth makecache <block number> <outputdir>`)
|
||||
}
|
||||
@@ -119,7 +114,7 @@ func makecache(ctx *cli.Context) error {
|
||||
|
||||
// makedag generates an ethash mining DAG into the provided folder.
|
||||
func makedag(ctx *cli.Context) error {
|
||||
args := ctx.Args()
|
||||
args := ctx.Args().Slice()
|
||||
if len(args) != 2 {
|
||||
utils.Fatalf(`Usage: geth makedag <block number> <outputdir>`)
|
||||
}
|
||||
|
||||
+90
-35
@@ -31,10 +31,11 @@ import (
|
||||
"github.com/ethereum/go-ethereum/core/state/snapshot"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"github.com/ethereum/go-ethereum/trie"
|
||||
cli "gopkg.in/urfave/cli.v1"
|
||||
cli "github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -46,19 +47,17 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
snapshotCommand = cli.Command{
|
||||
snapshotCommand = &cli.Command{
|
||||
Name: "snapshot",
|
||||
Usage: "A set of commands based on the snapshot",
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Description: "",
|
||||
Subcommands: []cli.Command{
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "prune-state",
|
||||
Usage: "Prune stale ethereum state data based on the snapshot",
|
||||
ArgsUsage: "<root>",
|
||||
Action: utils.MigrateFlags(pruneState),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Action: pruneState,
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.CacheTrieJournalFlag,
|
||||
utils.BloomFilterSizeFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
@@ -81,9 +80,8 @@ the trie clean cache with default directory will be deleted.
|
||||
Name: "verify-state",
|
||||
Usage: "Recalculate state hash based on the snapshot for verification",
|
||||
ArgsUsage: "<root>",
|
||||
Action: utils.MigrateFlags(verifyState),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: utils.GroupFlags(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Action: verifyState,
|
||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
geth snapshot verify-state <state-root>
|
||||
will traverse the whole accounts and storages set based on the specified
|
||||
@@ -95,21 +93,30 @@ In other words, this command does the snapshot to trie conversion.
|
||||
Name: "check-dangling-storage",
|
||||
Usage: "Check that there is no 'dangling' snap storage",
|
||||
ArgsUsage: "<root>",
|
||||
Action: utils.MigrateFlags(checkDanglingStorage),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: utils.GroupFlags(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Action: checkDanglingStorage,
|
||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
geth snapshot check-dangling-storage <state-root> traverses the snap storage
|
||||
data, and verifies that all snapshot storage data has a corresponding account.
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "inspect-account",
|
||||
Usage: "Check all snapshot layers for the a specific account",
|
||||
ArgsUsage: "<address | hash>",
|
||||
Action: checkAccount,
|
||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
geth snapshot inspect-account <address | hash> checks all snapshot layers and prints out
|
||||
information about the specified address.
|
||||
`,
|
||||
},
|
||||
{
|
||||
Name: "traverse-state",
|
||||
Usage: "Traverse the state with given root hash for verification",
|
||||
Usage: "Traverse the state with given root hash and perform quick verification",
|
||||
ArgsUsage: "<root>",
|
||||
Action: utils.MigrateFlags(traverseState),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: utils.GroupFlags(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Action: traverseState,
|
||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
geth snapshot traverse-state <state-root>
|
||||
will traverse the whole state from the given state root and will abort if any
|
||||
@@ -121,11 +128,10 @@ It's also usable without snapshot enabled.
|
||||
},
|
||||
{
|
||||
Name: "traverse-rawstate",
|
||||
Usage: "Traverse the state with given root hash for verification",
|
||||
Usage: "Traverse the state with given root hash and perform detailed verification",
|
||||
ArgsUsage: "<root>",
|
||||
Action: utils.MigrateFlags(traverseRawState),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: utils.GroupFlags(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Action: traverseRawState,
|
||||
Flags: flags.Merge(utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
Description: `
|
||||
geth snapshot traverse-rawstate <state-root>
|
||||
will traverse the whole state from the given root and will abort if any referenced
|
||||
@@ -140,9 +146,8 @@ It's also usable without snapshot enabled.
|
||||
Name: "dump",
|
||||
Usage: "Dump a specific block from storage (same as 'geth dump' but using snapshots)",
|
||||
ArgsUsage: "[? <blockHash> | <blockNum>]",
|
||||
Action: utils.MigrateFlags(dumpState),
|
||||
Category: "MISCELLANEOUS COMMANDS",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
Action: dumpState,
|
||||
Flags: flags.Merge([]cli.Flag{
|
||||
utils.ExcludeCodeFlag,
|
||||
utils.ExcludeStorageFlag,
|
||||
utils.StartKeyFlag,
|
||||
@@ -165,7 +170,7 @@ func pruneState(ctx *cli.Context) error {
|
||||
defer stack.Close()
|
||||
|
||||
chaindb := utils.MakeChainDatabase(ctx, stack, false)
|
||||
pruner, err := pruner.NewPruner(chaindb, stack.ResolvePath(""), stack.ResolvePath(config.Eth.TrieCleanCacheJournal), ctx.GlobalUint64(utils.BloomFilterSizeFlag.Name))
|
||||
pruner, err := pruner.NewPruner(chaindb, stack.ResolvePath(""), stack.ResolvePath(config.Eth.TrieCleanCacheJournal), ctx.Uint64(utils.BloomFilterSizeFlag.Name))
|
||||
if err != nil {
|
||||
log.Error("Failed to open snapshot tree", "err", err)
|
||||
return err
|
||||
@@ -176,7 +181,7 @@ func pruneState(ctx *cli.Context) error {
|
||||
}
|
||||
var targetRoot common.Hash
|
||||
if ctx.NArg() == 1 {
|
||||
targetRoot, err = parseRoot(ctx.Args()[0])
|
||||
targetRoot, err = parseRoot(ctx.Args().First())
|
||||
if err != nil {
|
||||
log.Error("Failed to resolve state root", "err", err)
|
||||
return err
|
||||
@@ -210,7 +215,7 @@ func verifyState(ctx *cli.Context) error {
|
||||
}
|
||||
var root = headBlock.Root()
|
||||
if ctx.NArg() == 1 {
|
||||
root, err = parseRoot(ctx.Args()[0])
|
||||
root, err = parseRoot(ctx.Args().First())
|
||||
if err != nil {
|
||||
log.Error("Failed to resolve state root", "err", err)
|
||||
return err
|
||||
@@ -255,7 +260,7 @@ func traverseState(ctx *cli.Context) error {
|
||||
err error
|
||||
)
|
||||
if ctx.NArg() == 1 {
|
||||
root, err = parseRoot(ctx.Args()[0])
|
||||
root, err = parseRoot(ctx.Args().First())
|
||||
if err != nil {
|
||||
log.Error("Failed to resolve state root", "err", err)
|
||||
return err
|
||||
@@ -266,7 +271,7 @@ func traverseState(ctx *cli.Context) error {
|
||||
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
|
||||
}
|
||||
triedb := trie.NewDatabase(chaindb)
|
||||
t, err := trie.NewSecure(root, triedb)
|
||||
t, err := trie.NewSecure(common.Hash{}, root, triedb)
|
||||
if err != nil {
|
||||
log.Error("Failed to open trie", "root", root, "err", err)
|
||||
return err
|
||||
@@ -287,7 +292,7 @@ func traverseState(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
if acc.Root != emptyRoot {
|
||||
storageTrie, err := trie.NewSecure(acc.Root, triedb)
|
||||
storageTrie, err := trie.NewSecure(common.BytesToHash(accIter.Key), acc.Root, triedb)
|
||||
if err != nil {
|
||||
log.Error("Failed to open storage trie", "root", acc.Root, "err", err)
|
||||
return err
|
||||
@@ -344,7 +349,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||
err error
|
||||
)
|
||||
if ctx.NArg() == 1 {
|
||||
root, err = parseRoot(ctx.Args()[0])
|
||||
root, err = parseRoot(ctx.Args().First())
|
||||
if err != nil {
|
||||
log.Error("Failed to resolve state root", "err", err)
|
||||
return err
|
||||
@@ -355,7 +360,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||
log.Info("Start traversing the state", "root", root, "number", headBlock.NumberU64())
|
||||
}
|
||||
triedb := trie.NewDatabase(chaindb)
|
||||
t, err := trie.NewSecure(root, triedb)
|
||||
t, err := trie.NewSecure(common.Hash{}, root, triedb)
|
||||
if err != nil {
|
||||
log.Error("Failed to open trie", "root", root, "err", err)
|
||||
return err
|
||||
@@ -367,6 +372,8 @@ func traverseRawState(ctx *cli.Context) error {
|
||||
codes int
|
||||
lastReport time.Time
|
||||
start = time.Now()
|
||||
hasher = crypto.NewKeccakState()
|
||||
got = make([]byte, 32)
|
||||
)
|
||||
accIter := t.NodeIterator(nil)
|
||||
for accIter.Next(true) {
|
||||
@@ -376,10 +383,18 @@ func traverseRawState(ctx *cli.Context) error {
|
||||
// Check the present for non-empty hash node(embedded node doesn't
|
||||
// have their own hash).
|
||||
if node != (common.Hash{}) {
|
||||
if !rawdb.HasTrieNode(chaindb, node) {
|
||||
blob := rawdb.ReadTrieNode(chaindb, node)
|
||||
if len(blob) == 0 {
|
||||
log.Error("Missing trie node(account)", "hash", node)
|
||||
return errors.New("missing account")
|
||||
}
|
||||
hasher.Reset()
|
||||
hasher.Write(blob)
|
||||
hasher.Read(got)
|
||||
if !bytes.Equal(got, node.Bytes()) {
|
||||
log.Error("Invalid trie node(account)", "hash", node.Hex(), "value", blob)
|
||||
return errors.New("invalid account node")
|
||||
}
|
||||
}
|
||||
// If it's a leaf node, yes we are touching an account,
|
||||
// dig into the storage trie further.
|
||||
@@ -391,7 +406,7 @@ func traverseRawState(ctx *cli.Context) error {
|
||||
return errors.New("invalid account")
|
||||
}
|
||||
if acc.Root != emptyRoot {
|
||||
storageTrie, err := trie.NewSecure(acc.Root, triedb)
|
||||
storageTrie, err := trie.NewSecure(common.BytesToHash(accIter.LeafKey()), acc.Root, triedb)
|
||||
if err != nil {
|
||||
log.Error("Failed to open storage trie", "root", acc.Root, "err", err)
|
||||
return errors.New("missing storage trie")
|
||||
@@ -404,10 +419,18 @@ func traverseRawState(ctx *cli.Context) error {
|
||||
// Check the present for non-empty hash node(embedded node doesn't
|
||||
// have their own hash).
|
||||
if node != (common.Hash{}) {
|
||||
if !rawdb.HasTrieNode(chaindb, node) {
|
||||
blob := rawdb.ReadTrieNode(chaindb, node)
|
||||
if len(blob) == 0 {
|
||||
log.Error("Missing trie node(storage)", "hash", node)
|
||||
return errors.New("missing storage")
|
||||
}
|
||||
hasher.Reset()
|
||||
hasher.Write(blob)
|
||||
hasher.Read(got)
|
||||
if !bytes.Equal(got, node.Bytes()) {
|
||||
log.Error("Invalid trie node(storage)", "hash", node.Hex(), "value", blob)
|
||||
return errors.New("invalid storage node")
|
||||
}
|
||||
}
|
||||
// Bump the counter if it's leaf node.
|
||||
if storageIter.Leaf() {
|
||||
@@ -517,3 +540,35 @@ func dumpState(ctx *cli.Context) error {
|
||||
"elapsed", common.PrettyDuration(time.Since(start)))
|
||||
return nil
|
||||
}
|
||||
|
||||
// checkAccount iterates the snap data layers, and looks up the given account
|
||||
// across all layers.
|
||||
func checkAccount(ctx *cli.Context) error {
|
||||
if ctx.NArg() != 1 {
|
||||
return errors.New("need <address|hash> arg")
|
||||
}
|
||||
var (
|
||||
hash common.Hash
|
||||
addr common.Address
|
||||
)
|
||||
switch arg := ctx.Args().First(); len(arg) {
|
||||
case 40, 42:
|
||||
addr = common.HexToAddress(arg)
|
||||
hash = crypto.Keccak256Hash(addr.Bytes())
|
||||
case 64, 66:
|
||||
hash = common.HexToHash(arg)
|
||||
default:
|
||||
return errors.New("malformed address or hash")
|
||||
}
|
||||
stack, _ := makeConfigNode(ctx)
|
||||
defer stack.Close()
|
||||
chaindb := utils.MakeChainDatabase(ctx, stack, true)
|
||||
defer chaindb.Close()
|
||||
start := time.Now()
|
||||
log.Info("Checking difflayer journal", "address", addr, "hash", hash)
|
||||
if err := snapshot.CheckJournalAccount(chaindb, hash); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Info("Checked the snapshot journalled storage", "time", common.PrettyDuration(time.Since(start)))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,300 +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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Contains the geth command usage template and generator.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sort"
|
||||
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/internal/debug"
|
||||
"github.com/ethereum/go-ethereum/internal/flags"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
)
|
||||
|
||||
// AppHelpFlagGroups is the application flags, grouped by functionality.
|
||||
var AppHelpFlagGroups = []flags.FlagGroup{
|
||||
{
|
||||
Name: "ETHEREUM",
|
||||
Flags: utils.GroupFlags([]cli.Flag{
|
||||
configFileFlag,
|
||||
utils.MinFreeDiskSpaceFlag,
|
||||
utils.KeyStoreDirFlag,
|
||||
utils.USBFlag,
|
||||
utils.SmartCardDaemonPathFlag,
|
||||
utils.NetworkIdFlag,
|
||||
utils.SyncModeFlag,
|
||||
utils.ExitWhenSyncedFlag,
|
||||
utils.GCModeFlag,
|
||||
utils.TxLookupLimitFlag,
|
||||
utils.EthStatsURLFlag,
|
||||
utils.IdentityFlag,
|
||||
utils.LightKDFFlag,
|
||||
utils.EthRequiredBlocksFlag,
|
||||
}, utils.NetworkFlags, utils.DatabasePathFlags),
|
||||
},
|
||||
{
|
||||
Name: "LIGHT CLIENT",
|
||||
Flags: []cli.Flag{
|
||||
utils.LightServeFlag,
|
||||
utils.LightIngressFlag,
|
||||
utils.LightEgressFlag,
|
||||
utils.LightMaxPeersFlag,
|
||||
utils.UltraLightServersFlag,
|
||||
utils.UltraLightFractionFlag,
|
||||
utils.UltraLightOnlyAnnounceFlag,
|
||||
utils.LightNoPruneFlag,
|
||||
utils.LightNoSyncServeFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "DEVELOPER CHAIN",
|
||||
Flags: []cli.Flag{
|
||||
utils.DeveloperFlag,
|
||||
utils.DeveloperPeriodFlag,
|
||||
utils.DeveloperGasLimitFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ETHASH",
|
||||
Flags: []cli.Flag{
|
||||
utils.EthashCacheDirFlag,
|
||||
utils.EthashCachesInMemoryFlag,
|
||||
utils.EthashCachesOnDiskFlag,
|
||||
utils.EthashCachesLockMmapFlag,
|
||||
utils.EthashDatasetDirFlag,
|
||||
utils.EthashDatasetsInMemoryFlag,
|
||||
utils.EthashDatasetsOnDiskFlag,
|
||||
utils.EthashDatasetsLockMmapFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
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.CacheTrieJournalFlag,
|
||||
utils.CacheTrieRejournalFlag,
|
||||
utils.CacheGCFlag,
|
||||
utils.CacheSnapshotFlag,
|
||||
utils.CacheNoPrefetchFlag,
|
||||
utils.CachePreimagesFlag,
|
||||
utils.FDLimitFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ACCOUNT",
|
||||
Flags: []cli.Flag{
|
||||
utils.UnlockedAccountFlag,
|
||||
utils.PasswordFileFlag,
|
||||
utils.ExternalSignerFlag,
|
||||
utils.InsecureUnlockAllowedFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "API AND CONSOLE",
|
||||
Flags: []cli.Flag{
|
||||
utils.IPCDisabledFlag,
|
||||
utils.IPCPathFlag,
|
||||
utils.HTTPEnabledFlag,
|
||||
utils.HTTPListenAddrFlag,
|
||||
utils.HTTPPortFlag,
|
||||
utils.HTTPApiFlag,
|
||||
utils.HTTPPathPrefixFlag,
|
||||
utils.HTTPCORSDomainFlag,
|
||||
utils.HTTPVirtualHostsFlag,
|
||||
utils.WSEnabledFlag,
|
||||
utils.WSListenAddrFlag,
|
||||
utils.WSPortFlag,
|
||||
utils.WSApiFlag,
|
||||
utils.WSPathPrefixFlag,
|
||||
utils.WSAllowedOriginsFlag,
|
||||
utils.JWTSecretFlag,
|
||||
utils.AuthListenFlag,
|
||||
utils.AuthPortFlag,
|
||||
utils.AuthVirtualHostsFlag,
|
||||
utils.GraphQLEnabledFlag,
|
||||
utils.GraphQLCORSDomainFlag,
|
||||
utils.GraphQLVirtualHostsFlag,
|
||||
utils.RPCGlobalGasCapFlag,
|
||||
utils.RPCGlobalEVMTimeoutFlag,
|
||||
utils.RPCGlobalTxFeeCapFlag,
|
||||
utils.AllowUnprotectedTxs,
|
||||
utils.JSpathFlag,
|
||||
utils.ExecFlag,
|
||||
utils.PreloadJSFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "NETWORKING",
|
||||
Flags: []cli.Flag{
|
||||
utils.BootnodesFlag,
|
||||
utils.DNSDiscoveryFlag,
|
||||
utils.ListenPortFlag,
|
||||
utils.MaxPeersFlag,
|
||||
utils.MaxPendingPeersFlag,
|
||||
utils.NATFlag,
|
||||
utils.NoDiscoverFlag,
|
||||
utils.DiscoveryV5Flag,
|
||||
utils.NetrestrictFlag,
|
||||
utils.NodeKeyFileFlag,
|
||||
utils.NodeKeyHexFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "MINER",
|
||||
Flags: []cli.Flag{
|
||||
utils.MiningEnabledFlag,
|
||||
utils.MinerThreadsFlag,
|
||||
utils.MinerNotifyFlag,
|
||||
utils.MinerNotifyFullFlag,
|
||||
utils.MinerGasPriceFlag,
|
||||
utils.MinerGasLimitFlag,
|
||||
utils.MinerEtherbaseFlag,
|
||||
utils.MinerExtraDataFlag,
|
||||
utils.MinerRecommitIntervalFlag,
|
||||
utils.MinerNoVerifyFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GAS PRICE ORACLE",
|
||||
Flags: []cli.Flag{
|
||||
utils.GpoBlocksFlag,
|
||||
utils.GpoPercentileFlag,
|
||||
utils.GpoMaxGasPriceFlag,
|
||||
utils.GpoIgnoreGasPriceFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "VIRTUAL MACHINE",
|
||||
Flags: []cli.Flag{
|
||||
utils.VMEnableDebugFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "LOGGING AND DEBUGGING",
|
||||
Flags: append([]cli.Flag{
|
||||
utils.FakePoWFlag,
|
||||
utils.NoCompactionFlag,
|
||||
}, debug.Flags...),
|
||||
},
|
||||
{
|
||||
Name: "METRICS AND STATS",
|
||||
Flags: metricsFlags,
|
||||
},
|
||||
{
|
||||
Name: "ALIASED (deprecated)",
|
||||
Flags: []cli.Flag{
|
||||
utils.NoUSBFlag,
|
||||
utils.LegacyWhitelistFlag,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "MISC",
|
||||
Flags: []cli.Flag{
|
||||
utils.SnapshotFlag,
|
||||
utils.BloomFilterSizeFlag,
|
||||
cli.HelpFlag,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Override the default app help template
|
||||
cli.AppHelpTemplate = flags.AppHelpTemplate
|
||||
|
||||
// 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 == flags.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{}{}
|
||||
}
|
||||
}
|
||||
deprecated := make(map[string]struct{})
|
||||
for _, flag := range utils.DeprecatedFlags {
|
||||
deprecated[flag.String()] = struct{}{}
|
||||
}
|
||||
// Only add uncategorized flags if they are not deprecated
|
||||
var uncategorized []cli.Flag
|
||||
for _, flag := range data.(*cli.App).Flags {
|
||||
if _, ok := categorized[flag.String()]; !ok {
|
||||
if _, ok := deprecated[flag.String()]; !ok {
|
||||
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, flags.HelpData{App: data, FlagGroups: AppHelpFlagGroups})
|
||||
} else if tmpl == flags.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[flags.FlagCategory(flag, AppHelpFlagGroups)] = append(categorized[flags.FlagCategory(flag, AppHelpFlagGroups)], flag)
|
||||
}
|
||||
}
|
||||
|
||||
// sort to get a stable ordering
|
||||
sorted := make([]flags.FlagGroup, 0, len(categorized))
|
||||
for cat, flgs := range categorized {
|
||||
sorted = append(sorted, flags.FlagGroup{Name: cat, Flags: flgs})
|
||||
}
|
||||
sort.Sort(flags.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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/jedisct1/go-minisign"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
var gethPubKeys []string = []string{
|
||||
|
||||
@@ -118,7 +118,6 @@ func TestMatching(t *testing.T) {
|
||||
version, vuln.Introduced, vuln.Fixed, vuln.Name, vulnIntro, current, vulnFixed)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
for major := 1; major < 2; major++ {
|
||||
|
||||
Reference in New Issue
Block a user