Merge Geth v1.10.21 as well as update to Plugeth-Utils v0.0.18

This commit is contained in:
philip-morlier
2022-07-27 10:38:42 -07:00
380 changed files with 6936 additions and 6262 deletions
+25 -27
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
+1 -1
View File
@@ -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
View File
@@ -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))},
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
-300
View File
@@ -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)
}
}
}
+1 -1
View File
@@ -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{
-1
View File
@@ -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++ {