From 87cfb773e1047b42615894c7856b5db7d0e592a4 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Mon, 20 Jun 2022 22:03:55 -0400 Subject: [PATCH 1/6] cmd/geth: make dumpgenesis command load genesis from the datadir if it exists --- cmd/geth/chaincmd.go | 42 +++++++++++++++++++++++++++++++++++------- cmd/utils/flags.go | 7 +++++++ core/genesis.go | 35 +++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index a3016c4b091..d3ac8cfa016 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -63,7 +63,7 @@ It expects the genesis file as argument.`, ArgsUsage: "", Flags: utils.NetworkFlags, Description: ` -The dumpgenesis command dumps the genesis block configuration in JSON format to stdout.`, +The dumpgenesis command prints a genesis block as JSON. What it outputs is determined in order of preference: testnet preset if it is set, preexisting datadir, mainnet.`, } importCommand = &cli.Command{ Action: importChain, @@ -203,13 +203,41 @@ func initGenesis(ctx *cli.Context) error { } func dumpGenesis(ctx *cli.Context) error { - // TODO(rjl493456442) support loading from the custom datadir - genesis := utils.MakeGenesis(ctx) - if genesis == nil { - genesis = core.DefaultGenesisBlock() + // if there is a testnet preset enabled, dump that + if utils.IsTestnetPreset(ctx) { + genesis := utils.MakeGenesis(ctx) + if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil { + utils.Fatalf("could not encode genesis: %s", err) + } + return nil + } + // dump whatever already exists in the datadir + stack, _ := makeConfigNode(ctx) + for _, name := range []string{"chaindata", "lightchaindata"} { + db, err := stack.OpenDatabase(name, 0, 0, "", true) + if err != nil { + if !os.IsNotExist(err) { + return err + } + continue + } + genesis, err := core.ReadGenesis(db) + if err != nil { + utils.Fatalf("failed to read genesis: %s", err) + } + db.Close() + + if err := json.NewEncoder(os.Stdout).Encode(*genesis); err != nil { + utils.Fatalf("could not encode stored genesis: %s", err) + } + return nil + } + if ctx.GlobalIsSet(utils.DataDirFlag.Name) { + utils.Fatalf("no existing datadir at %s", stack.Config().DataDir) } - if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil { - utils.Fatalf("could not encode genesis") + // no datadir exists or is specified, dump mainnet + if err := json.NewEncoder(os.Stdout).Encode(core.DefaultGenesisBlock()); err != nil { + utils.Fatalf("could not encode genesis: %s", err) } return nil } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 595fe3360fe..f3a731eb8f4 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2140,6 +2140,13 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. return chainDb } +func IsTestnetPreset(ctx *cli.Context) bool { + if ctx.GlobalBool(RopstenFlag.Name) || ctx.GlobalBool(SepoliaFlag.Name) || ctx.GlobalBool(RinkebyFlag.Name) || ctx.GlobalBool(GoerliFlag.Name) || ctx.GlobalBool(KilnFlag.Name) || ctx.GlobalBool(DeveloperFlag.Name) { + return true + } + return false +} + func MakeGenesis(ctx *cli.Context) *core.Genesis { var genesis *core.Genesis switch { diff --git a/core/genesis.go b/core/genesis.go index 1c62bb1a137..798a3875597 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -65,6 +65,41 @@ type Genesis struct { BaseFee *big.Int `json:"baseFeePerGas"` } +func ReadGenesis(db ethdb.Database) (*Genesis, error) { + var genesis Genesis + stored := rawdb.ReadCanonicalHash(db, 0) + if (stored == common.Hash{}) { + return nil, fmt.Errorf("invalid genesis hash in database: %x", stored) + } + blob := rawdb.ReadGenesisState(db, stored) + if blob == nil { + return nil, fmt.Errorf("genesis state missing from db") + } + if len(blob) != 0 { + if err := genesis.Alloc.UnmarshalJSON(blob); err != nil { + return nil, fmt.Errorf("could not unmartial genesis state json: %s", err) + } + } + genesis.Config = rawdb.ReadChainConfig(db, stored) + if genesis.Config == nil { + return nil, fmt.Errorf("genesis config missing from db") + } + genesisBlock := rawdb.ReadBlock(db, stored, 0) + if genesisBlock == nil { + return nil, fmt.Errorf("genesis block missing from db") + } + genesisHeader := genesisBlock.Header() + genesis.Nonce = genesisHeader.Nonce.Uint64() + genesis.Timestamp = genesisHeader.Time + genesis.ExtraData = genesisHeader.Extra + genesis.GasLimit = genesisHeader.GasLimit + genesis.Difficulty = genesisHeader.Difficulty + genesis.Mixhash = genesisHeader.MixDigest + genesis.Coinbase = genesisHeader.Coinbase + + return &genesis, nil +} + // GenesisAlloc specifies the initial state that is part of the genesis block. type GenesisAlloc map[common.Address]GenesisAccount From f52ebe8d6a2ee1cc3cf81a1337b1882dfe2e0957 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Tue, 21 Jun 2022 20:41:34 -0400 Subject: [PATCH 2/6] make suggested change --- cmd/utils/flags.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f3a731eb8f4..f89739195c0 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2141,8 +2141,10 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. } func IsTestnetPreset(ctx *cli.Context) bool { - if ctx.GlobalBool(RopstenFlag.Name) || ctx.GlobalBool(SepoliaFlag.Name) || ctx.GlobalBool(RinkebyFlag.Name) || ctx.GlobalBool(GoerliFlag.Name) || ctx.GlobalBool(KilnFlag.Name) || ctx.GlobalBool(DeveloperFlag.Name) { - return true + for _, flag := range TestnetFlags { + if ctx.GlobalBool(flag.GetName()) { + return true + } } return false } From 97b051f725af8477842961649d06f3c3cc06b8f4 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Tue, 28 Jun 2022 19:40:34 +0000 Subject: [PATCH 3/6] make suggested changes --- cmd/geth/chaincmd.go | 15 +++++++-------- cmd/utils/flags.go | 7 +++++-- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index d3ac8cfa016..2177ff035fc 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -61,9 +61,11 @@ It expects the genesis file as argument.`, Name: "dumpgenesis", Usage: "Dumps genesis block JSON configuration to stdout", ArgsUsage: "", - Flags: utils.NetworkFlags, + Flags: append([]cli.Flag{utils.DataDirFlag}, utils.NetworkFlags...), + Category: "BLOCKCHAIN COMMANDS", Description: ` -The dumpgenesis command prints a genesis block as JSON. What it outputs is determined in order of preference: testnet preset if it is set, preexisting datadir, mainnet.`, +The dumpgenesis command prints the genesis configuration of the network preset +if one is set. Otherwise it prints the genesis from the datadir.`, } importCommand = &cli.Command{ Action: importChain, @@ -204,7 +206,7 @@ func initGenesis(ctx *cli.Context) error { func dumpGenesis(ctx *cli.Context) error { // if there is a testnet preset enabled, dump that - if utils.IsTestnetPreset(ctx) { + if utils.IsNetworkPreset(ctx) { genesis := utils.MakeGenesis(ctx) if err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil { utils.Fatalf("could not encode genesis: %s", err) @@ -232,13 +234,10 @@ func dumpGenesis(ctx *cli.Context) error { } return nil } - if ctx.GlobalIsSet(utils.DataDirFlag.Name) { + if ctx.IsSet(utils.DataDirFlag.Name) { utils.Fatalf("no existing datadir at %s", stack.Config().DataDir) } - // no datadir exists or is specified, dump mainnet - if err := json.NewEncoder(os.Stdout).Encode(core.DefaultGenesisBlock()); err != nil { - utils.Fatalf("could not encode genesis: %s", err) - } + utils.Fatalf("no network preset provided. no exisiting genesis in the default datadir") return nil } diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index f89739195c0..2c352a06a02 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -2140,12 +2140,15 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. return chainDb } -func IsTestnetPreset(ctx *cli.Context) bool { +func IsNetworkPreset(ctx *cli.Context) bool { for _, flag := range TestnetFlags { - if ctx.GlobalBool(flag.GetName()) { + if ctx.Bool(flag.String()) { return true } } + if ctx.Bool(MainnetFlag.Name) { + return true + } return false } From 16d031824a22365a223641cfd360e9590be86ad2 Mon Sep 17 00:00:00 2001 From: Jared Wasinger Date: Mon, 11 Jul 2022 22:34:45 +0000 Subject: [PATCH 4/6] fix --- cmd/geth/chaincmd.go | 1 - cmd/utils/flags.go | 12 ++++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 2177ff035fc..c89f736169e 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -62,7 +62,6 @@ It expects the genesis file as argument.`, Usage: "Dumps genesis block JSON configuration to stdout", ArgsUsage: "", Flags: append([]cli.Flag{utils.DataDirFlag}, utils.NetworkFlags...), - Category: "BLOCKCHAIN COMMANDS", Description: ` The dumpgenesis command prints the genesis configuration of the network preset if one is set. Otherwise it prints the genesis from the datadir.`, diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 2c352a06a02..745b9f088eb 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -988,9 +988,7 @@ var ( KilnFlag, } // NetworkFlags is the flag group of all built-in supported networks. - NetworkFlags = append([]cli.Flag{ - MainnetFlag, - }, TestnetFlags...) + NetworkFlags = append([]cli.Flag{MainnetFlag}, TestnetFlags...) // DatabasePathFlags is the flag group of all database path flags. DatabasePathFlags = []cli.Flag{ @@ -2141,14 +2139,12 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb. } func IsNetworkPreset(ctx *cli.Context) bool { - for _, flag := range TestnetFlags { - if ctx.Bool(flag.String()) { + for _, flag := range NetworkFlags { + bFlag, _ := flag.(*cli.BoolFlag) + if ctx.IsSet(bFlag.Name) { return true } } - if ctx.Bool(MainnetFlag.Name) { - return true - } return false } From 3e73445dd1544f79caeba1f849c1ab9ae48e94e7 Mon Sep 17 00:00:00 2001 From: jwasinger Date: Fri, 19 Aug 2022 14:53:20 -0400 Subject: [PATCH 5/6] apply suggested change Co-authored-by: Martin Holst Swende --- core/genesis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/genesis.go b/core/genesis.go index 798a3875597..db6f3c13364 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -77,7 +77,7 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) { } if len(blob) != 0 { if err := genesis.Alloc.UnmarshalJSON(blob); err != nil { - return nil, fmt.Errorf("could not unmartial genesis state json: %s", err) + return nil, fmt.Errorf("could not unmarshal genesis state json: %s", err) } } genesis.Config = rawdb.ReadChainConfig(db, stored) From 1e0b881ce16207b2181037e84e671158e922c9b0 Mon Sep 17 00:00:00 2001 From: Martin Holst Swende Date: Mon, 26 Sep 2022 13:03:04 +0200 Subject: [PATCH 6/6] core: squash fixup --- core/genesis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/genesis.go b/core/genesis.go index db6f3c13364..8b855147972 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -71,7 +71,7 @@ func ReadGenesis(db ethdb.Database) (*Genesis, error) { if (stored == common.Hash{}) { return nil, fmt.Errorf("invalid genesis hash in database: %x", stored) } - blob := rawdb.ReadGenesisState(db, stored) + blob := rawdb.ReadGenesisStateSpec(db, stored) if blob == nil { return nil, fmt.Errorf("genesis state missing from db") }