From 80be5e546398203c1958a0f512e651a2c36b1fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Thu, 26 Oct 2017 12:39:03 +0300 Subject: [PATCH] cmd/puppeth: store genesis locally to persist restarts --- cmd/puppeth/module_dashboard.go | 24 +++++++++---------- cmd/puppeth/wizard.go | 10 ++++---- cmd/puppeth/wizard_explorer.go | 6 ++--- cmd/puppeth/wizard_faucet.go | 4 ++-- cmd/puppeth/wizard_genesis.go | 41 ++++++++++++++++++++++----------- cmd/puppeth/wizard_intro.go | 4 ++-- cmd/puppeth/wizard_netstats.go | 6 ++--- cmd/puppeth/wizard_node.go | 12 +++++----- cmd/puppeth/wizard_wallet.go | 6 ++--- 9 files changed, 64 insertions(+), 49 deletions(-) diff --git a/cmd/puppeth/module_dashboard.go b/cmd/puppeth/module_dashboard.go index 776f2c2191..4fdb03e784 100644 --- a/cmd/puppeth/module_dashboard.go +++ b/cmd/puppeth/module_dashboard.go @@ -608,7 +608,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da } template.Must(template.New("").Parse(dashboardContent)).Execute(indexfile, map[string]interface{}{ "Network": network, - "NetworkID": conf.genesis.Config.ChainId, + "NetworkID": conf.Genesis.Config.ChainId, "NetworkTitle": strings.Title(network), "EthstatsPage": config.ethstats, "ExplorerPage": config.explorer, @@ -620,7 +620,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da "BootnodesFullFlat": strings.Join(conf.bootFull, ","), "BootnodesLightFlat": strings.Join(conf.bootLight, ","), "Ethstats": statsLogin, - "Ethash": conf.genesis.Config.Ethash != nil, + "Ethash": conf.Genesis.Config.Ethash != nil, "CppGenesis": network + "-cpp.json", "CppBootnodes": strings.Join(bootCpp, " "), "HarmonyGenesis": network + "-harmony.json", @@ -628,36 +628,36 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da "ParityGenesis": network + "-parity.json", "PythonGenesis": network + "-python.json", "PythonBootnodes": strings.Join(bootPython, ","), - "Homestead": conf.genesis.Config.HomesteadBlock, - "Tangerine": conf.genesis.Config.EIP150Block, - "Spurious": conf.genesis.Config.EIP155Block, - "Byzantium": conf.genesis.Config.ByzantiumBlock, + "Homestead": conf.Genesis.Config.HomesteadBlock, + "Tangerine": conf.Genesis.Config.EIP150Block, + "Spurious": conf.Genesis.Config.EIP155Block, + "Byzantium": conf.Genesis.Config.ByzantiumBlock, }) files[filepath.Join(workdir, "index.html")] = indexfile.Bytes() // Marshal the genesis spec files for go-ethereum and all the other clients - genesis, _ := conf.genesis.MarshalJSON() + genesis, _ := conf.Genesis.MarshalJSON() files[filepath.Join(workdir, network+".json")] = genesis - if conf.genesis.Config.Ethash != nil { - cppSpec, err := newCppEthereumGenesisSpec(network, conf.genesis) + if conf.Genesis.Config.Ethash != nil { + cppSpec, err := newCppEthereumGenesisSpec(network, conf.Genesis) if err != nil { return nil, err } cppSpecJSON, _ := json.Marshal(cppSpec) files[filepath.Join(workdir, network+"-cpp.json")] = cppSpecJSON - harmonySpecJSON, _ := conf.genesis.MarshalJSON() + harmonySpecJSON, _ := conf.Genesis.MarshalJSON() files[filepath.Join(workdir, network+"-harmony.json")] = harmonySpecJSON - paritySpec, err := newParityChainSpec(network, conf.genesis, conf.bootFull) + paritySpec, err := newParityChainSpec(network, conf.Genesis, conf.bootFull) if err != nil { return nil, err } paritySpecJSON, _ := json.Marshal(paritySpec) files[filepath.Join(workdir, network+"-parity.json")] = paritySpecJSON - pyethSpec, err := newPyEthereumGenesisSpec(network, conf.genesis) + pyethSpec, err := newPyEthereumGenesisSpec(network, conf.Genesis) if err != nil { return nil, err } diff --git a/cmd/puppeth/wizard.go b/cmd/puppeth/wizard.go index e554dbd135..2e2b4644cf 100644 --- a/cmd/puppeth/wizard.go +++ b/cmd/puppeth/wizard.go @@ -39,12 +39,12 @@ import ( // config contains all the configurations needed by puppeth that should be saved // between sessions. type config struct { - path string // File containing the configuration values - genesis *core.Genesis // Genesis block to cache for node deploys - bootFull []string // Bootnodes to always connect to by full nodes - bootLight []string // Bootnodes to always connect to by light nodes - ethstats string // Ethstats settings to cache for node deploys + path string // File containing the configuration values + bootFull []string // Bootnodes to always connect to by full nodes + bootLight []string // Bootnodes to always connect to by light nodes + ethstats string // Ethstats settings to cache for node deploys + Genesis *core.Genesis `json:"genesis,omitempty"` // Genesis block to cache for node deploys Servers map[string][]byte `json:"servers,omitempty"` } diff --git a/cmd/puppeth/wizard_explorer.go b/cmd/puppeth/wizard_explorer.go index 2df77fa5cc..bbbe1e2759 100644 --- a/cmd/puppeth/wizard_explorer.go +++ b/cmd/puppeth/wizard_explorer.go @@ -27,7 +27,7 @@ import ( // deployExplorer creates a new block explorer based on some user input. func (w *wizard) deployExplorer() { // Do some sanity check before the user wastes time on input - if w.conf.genesis == nil { + if w.conf.Genesis == nil { log.Error("No genesis block configured") return } @@ -35,7 +35,7 @@ func (w *wizard) deployExplorer() { log.Error("No ethstats server configured") return } - if w.conf.genesis.Config.Ethash == nil { + if w.conf.Genesis.Config.Ethash == nil { log.Error("Only ethash network supported") return } @@ -51,7 +51,7 @@ func (w *wizard) deployExplorer() { if err != nil { infos = &explorerInfos{nodePort: 30303, webPort: 80, webHost: client.server} } - chainspec, err := newParityChainSpec(w.network, w.conf.genesis, w.conf.bootFull) + chainspec, err := newParityChainSpec(w.network, w.conf.Genesis, w.conf.bootFull) if err != nil { log.Error("Failed to create chain spec for explorer", "err", err) return diff --git a/cmd/puppeth/wizard_faucet.go b/cmd/puppeth/wizard_faucet.go index d5a084f15b..891a961977 100644 --- a/cmd/puppeth/wizard_faucet.go +++ b/cmd/puppeth/wizard_faucet.go @@ -47,8 +47,8 @@ func (w *wizard) deployFaucet() { tiers: 3, } } - infos.node.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") - infos.node.network = w.conf.genesis.Config.ChainId.Int64() + infos.node.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ") + infos.node.network = w.conf.Genesis.Config.ChainId.Int64() // Figure out which port to listen on fmt.Println() diff --git a/cmd/puppeth/wizard_genesis.go b/cmd/puppeth/wizard_genesis.go index e98b9a81dd..f255ef6e65 100644 --- a/cmd/puppeth/wizard_genesis.go +++ b/cmd/puppeth/wizard_genesis.go @@ -124,7 +124,10 @@ func (w *wizard) makeGenesis() { genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) // All done, store the genesis and flush to disk - w.conf.genesis = genesis + log.Info("Configured new genesis block") + + w.conf.Genesis = genesis + w.conf.flush() } // manageGenesis permits the modification of chain configuration parameters in @@ -134,44 +137,56 @@ func (w *wizard) manageGenesis() { fmt.Println() fmt.Println(" 1. Modify existing fork rules") fmt.Println(" 2. Export genesis configuration") + fmt.Println(" 3. Remove genesis configuration") choice := w.read() switch { case choice == "1": // Fork rule updating requested, iterate over each fork fmt.Println() - fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.genesis.Config.HomesteadBlock) - w.conf.genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.genesis.Config.HomesteadBlock) + fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", w.conf.Genesis.Config.HomesteadBlock) + w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock) fmt.Println() - fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", w.conf.genesis.Config.EIP150Block) - w.conf.genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.genesis.Config.EIP150Block) + fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP150Block) + w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block) fmt.Println() - fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", w.conf.genesis.Config.EIP155Block) - w.conf.genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.genesis.Config.EIP155Block) + fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP155Block) + w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block) fmt.Println() - fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", w.conf.genesis.Config.EIP158Block) - w.conf.genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.genesis.Config.EIP158Block) + fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", w.conf.Genesis.Config.EIP158Block) + w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block) fmt.Println() - fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.genesis.Config.ByzantiumBlock) - w.conf.genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.genesis.Config.ByzantiumBlock) + fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", w.conf.Genesis.Config.ByzantiumBlock) + w.conf.Genesis.Config.ByzantiumBlock = w.readDefaultBigInt(w.conf.Genesis.Config.ByzantiumBlock) - out, _ := json.MarshalIndent(w.conf.genesis.Config, "", " ") + out, _ := json.MarshalIndent(w.conf.Genesis.Config, "", " ") fmt.Printf("Chain configuration updated:\n\n%s\n", out) case choice == "2": // Save whatever genesis configuration we currently have fmt.Println() fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network) - out, _ := json.MarshalIndent(w.conf.genesis, "", " ") + out, _ := json.MarshalIndent(w.conf.Genesis, "", " ") if err := ioutil.WriteFile(w.readDefaultString(fmt.Sprintf("%s.json", w.network)), out, 0644); err != nil { log.Error("Failed to save genesis file", "err", err) } log.Info("Exported existing genesis block") + case choice == "3": + // Make sure we don't have any services running + if len(w.conf.servers()) > 0 { + log.Error("Genesis reset requires all services and servers torn down") + return + } + log.Info("Genesis block destroyed") + + w.conf.Genesis = nil + w.conf.flush() + default: log.Error("That's not something I can do") } diff --git a/cmd/puppeth/wizard_intro.go b/cmd/puppeth/wizard_intro.go index 10d8db75d1..84998afc93 100644 --- a/cmd/puppeth/wizard_intro.go +++ b/cmd/puppeth/wizard_intro.go @@ -107,7 +107,7 @@ func (w *wizard) run() { fmt.Println() fmt.Println("What would you like to do? (default = stats)") fmt.Println(" 1. Show network stats") - if w.conf.genesis == nil { + if w.conf.Genesis == nil { fmt.Println(" 2. Configure new genesis") } else { fmt.Println(" 2. Manage existing genesis") @@ -129,7 +129,7 @@ func (w *wizard) run() { w.networkStats() case choice == "2": - if w.conf.genesis == nil { + if w.conf.Genesis == nil { w.makeGenesis() } else { w.manageGenesis() diff --git a/cmd/puppeth/wizard_netstats.go b/cmd/puppeth/wizard_netstats.go index 469b7f2bfc..e19180bb16 100644 --- a/cmd/puppeth/wizard_netstats.go +++ b/cmd/puppeth/wizard_netstats.go @@ -32,7 +32,7 @@ import ( // configuration set to give users hints on how to do various tasks. func (w *wizard) networkStats() { if len(w.servers) == 0 { - log.Error("No remote machines to gather stats from") + log.Info("No remote machines to gather stats from") return } // Clear out some previous configs to refill from current scan @@ -173,12 +173,12 @@ func (w *wizard) gatherStats(server string, pubkey []byte, client *sshClient) *s w.lock.Lock() defer w.lock.Unlock() - if genesis != "" && w.conf.genesis == nil { + if genesis != "" && w.conf.Genesis == nil { g := new(core.Genesis) if err := json.Unmarshal([]byte(genesis), g); err != nil { log.Error("Failed to parse remote genesis", "err", err) } else { - w.conf.genesis = g + w.conf.Genesis = g } } if ethstats != "" { diff --git a/cmd/puppeth/wizard_node.go b/cmd/puppeth/wizard_node.go index f5b2d73580..a70178db20 100644 --- a/cmd/puppeth/wizard_node.go +++ b/cmd/puppeth/wizard_node.go @@ -29,7 +29,7 @@ import ( // deployNode creates a new node configuration based on some user input. func (w *wizard) deployNode(boot bool) { // Do some sanity check before the user wastes time on input - if w.conf.genesis == nil { + if w.conf.Genesis == nil { log.Error("No genesis block configured") return } @@ -53,8 +53,8 @@ func (w *wizard) deployNode(boot bool) { infos = &nodeInfos{portFull: 30303, peersTotal: 50, peersLight: 0, gasTarget: 4.7, gasPrice: 18} } } - infos.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") - infos.network = w.conf.genesis.Config.ChainId.Int64() + infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ") + infos.network = w.conf.Genesis.Config.ChainId.Int64() // Figure out where the user wants to store the persistent data fmt.Println() @@ -65,7 +65,7 @@ func (w *wizard) deployNode(boot bool) { fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir) infos.datadir = w.readDefaultString(infos.datadir) } - if w.conf.genesis.Config.Ethash != nil && !boot { + if w.conf.Genesis.Config.Ethash != nil && !boot { fmt.Println() if infos.ethashdir == "" { fmt.Printf("Where should the ethash mining DAGs be stored on the remote machine?\n") @@ -101,7 +101,7 @@ func (w *wizard) deployNode(boot bool) { } // If the node is a miner/signer, load up needed credentials if !boot { - if w.conf.genesis.Config.Ethash != nil { + if w.conf.Genesis.Config.Ethash != nil { // Ethash based miners only need an etherbase to mine against fmt.Println() if infos.etherbase == "" { @@ -116,7 +116,7 @@ func (w *wizard) deployNode(boot bool) { fmt.Printf("What address should the miner user? (default = %s)\n", infos.etherbase) infos.etherbase = w.readDefaultAddress(common.HexToAddress(infos.etherbase)).Hex() } - } else if w.conf.genesis.Config.Clique != nil { + } else if w.conf.Genesis.Config.Clique != nil { // If a previous signer was already set, offer to reuse it if infos.keyJSON != "" { if key, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil { diff --git a/cmd/puppeth/wizard_wallet.go b/cmd/puppeth/wizard_wallet.go index dfbf11804d..1165c5cdc8 100644 --- a/cmd/puppeth/wizard_wallet.go +++ b/cmd/puppeth/wizard_wallet.go @@ -27,7 +27,7 @@ import ( // deployWallet creates a new web wallet based on some user input. func (w *wizard) deployWallet() { // Do some sanity check before the user wastes time on input - if w.conf.genesis == nil { + if w.conf.Genesis == nil { log.Error("No genesis block configured") return } @@ -47,8 +47,8 @@ func (w *wizard) deployWallet() { if err != nil { infos = &walletInfos{nodePort: 30303, rpcPort: 8545, webPort: 80, webHost: client.server} } - infos.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") - infos.network = w.conf.genesis.Config.ChainId.Int64() + infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ") + infos.network = w.conf.Genesis.Config.ChainId.Int64() // Figure out which port to listen on fmt.Println()