Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,10 @@ 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...),
Description: `
The dumpgenesis command dumps the genesis block configuration in JSON format to stdout.`,
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,
Expand Down Expand Up @@ -203,14 +204,39 @@ 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.IsNetworkPreset(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 err := json.NewEncoder(os.Stdout).Encode(genesis); err != nil {
utils.Fatalf("could not encode genesis")
if ctx.IsSet(utils.DataDirFlag.Name) {
utils.Fatalf("no existing datadir at %s", stack.Config().DataDir)
}
utils.Fatalf("no network preset provided. no exisiting genesis in the default datadir")
return nil
}

Expand Down
14 changes: 11 additions & 3 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down Expand Up @@ -2140,6 +2138,16 @@ func MakeChainDatabase(ctx *cli.Context, stack *node.Node, readonly bool) ethdb.
return chainDb
}

func IsNetworkPreset(ctx *cli.Context) bool {
for _, flag := range NetworkFlags {
bFlag, _ := flag.(*cli.BoolFlag)
if ctx.IsSet(bFlag.Name) {
return true
}
}
return false
}

func MakeGenesis(ctx *cli.Context) *core.Genesis {
var genesis *core.Genesis
switch {
Expand Down
35 changes: 35 additions & 0 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.ReadGenesisStateSpec(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 unmarshal 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

Expand Down