cmd/puppeth: store genesis locally to persist restarts

pull/15390/head
Péter Szilágyi 7 years ago
parent 7abf968d6f
commit 80be5e5463
No known key found for this signature in database
GPG Key ID: E9AE538CEDF8293D
  1. 24
      cmd/puppeth/module_dashboard.go
  2. 2
      cmd/puppeth/wizard.go
  3. 6
      cmd/puppeth/wizard_explorer.go
  4. 4
      cmd/puppeth/wizard_faucet.go
  5. 41
      cmd/puppeth/wizard_genesis.go
  6. 4
      cmd/puppeth/wizard_intro.go
  7. 6
      cmd/puppeth/wizard_netstats.go
  8. 12
      cmd/puppeth/wizard_node.go
  9. 6
      cmd/puppeth/wizard_wallet.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{}{ template.Must(template.New("").Parse(dashboardContent)).Execute(indexfile, map[string]interface{}{
"Network": network, "Network": network,
"NetworkID": conf.genesis.Config.ChainId, "NetworkID": conf.Genesis.Config.ChainId,
"NetworkTitle": strings.Title(network), "NetworkTitle": strings.Title(network),
"EthstatsPage": config.ethstats, "EthstatsPage": config.ethstats,
"ExplorerPage": config.explorer, "ExplorerPage": config.explorer,
@ -620,7 +620,7 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da
"BootnodesFullFlat": strings.Join(conf.bootFull, ","), "BootnodesFullFlat": strings.Join(conf.bootFull, ","),
"BootnodesLightFlat": strings.Join(conf.bootLight, ","), "BootnodesLightFlat": strings.Join(conf.bootLight, ","),
"Ethstats": statsLogin, "Ethstats": statsLogin,
"Ethash": conf.genesis.Config.Ethash != nil, "Ethash": conf.Genesis.Config.Ethash != nil,
"CppGenesis": network + "-cpp.json", "CppGenesis": network + "-cpp.json",
"CppBootnodes": strings.Join(bootCpp, " "), "CppBootnodes": strings.Join(bootCpp, " "),
"HarmonyGenesis": network + "-harmony.json", "HarmonyGenesis": network + "-harmony.json",
@ -628,36 +628,36 @@ func deployDashboard(client *sshClient, network string, conf *config, config *da
"ParityGenesis": network + "-parity.json", "ParityGenesis": network + "-parity.json",
"PythonGenesis": network + "-python.json", "PythonGenesis": network + "-python.json",
"PythonBootnodes": strings.Join(bootPython, ","), "PythonBootnodes": strings.Join(bootPython, ","),
"Homestead": conf.genesis.Config.HomesteadBlock, "Homestead": conf.Genesis.Config.HomesteadBlock,
"Tangerine": conf.genesis.Config.EIP150Block, "Tangerine": conf.Genesis.Config.EIP150Block,
"Spurious": conf.genesis.Config.EIP155Block, "Spurious": conf.Genesis.Config.EIP155Block,
"Byzantium": conf.genesis.Config.ByzantiumBlock, "Byzantium": conf.Genesis.Config.ByzantiumBlock,
}) })
files[filepath.Join(workdir, "index.html")] = indexfile.Bytes() files[filepath.Join(workdir, "index.html")] = indexfile.Bytes()
// Marshal the genesis spec files for go-ethereum and all the other clients // 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 files[filepath.Join(workdir, network+".json")] = genesis
if conf.genesis.Config.Ethash != nil { if conf.Genesis.Config.Ethash != nil {
cppSpec, err := newCppEthereumGenesisSpec(network, conf.genesis) cppSpec, err := newCppEthereumGenesisSpec(network, conf.Genesis)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cppSpecJSON, _ := json.Marshal(cppSpec) cppSpecJSON, _ := json.Marshal(cppSpec)
files[filepath.Join(workdir, network+"-cpp.json")] = cppSpecJSON files[filepath.Join(workdir, network+"-cpp.json")] = cppSpecJSON
harmonySpecJSON, _ := conf.genesis.MarshalJSON() harmonySpecJSON, _ := conf.Genesis.MarshalJSON()
files[filepath.Join(workdir, network+"-harmony.json")] = harmonySpecJSON 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 { if err != nil {
return nil, err return nil, err
} }
paritySpecJSON, _ := json.Marshal(paritySpec) paritySpecJSON, _ := json.Marshal(paritySpec)
files[filepath.Join(workdir, network+"-parity.json")] = paritySpecJSON files[filepath.Join(workdir, network+"-parity.json")] = paritySpecJSON
pyethSpec, err := newPyEthereumGenesisSpec(network, conf.genesis) pyethSpec, err := newPyEthereumGenesisSpec(network, conf.Genesis)
if err != nil { if err != nil {
return nil, err return nil, err
} }

@ -40,11 +40,11 @@ import (
// between sessions. // between sessions.
type config struct { type config struct {
path string // File containing the configuration values 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 bootFull []string // Bootnodes to always connect to by full nodes
bootLight []string // Bootnodes to always connect to by light nodes bootLight []string // Bootnodes to always connect to by light nodes
ethstats string // Ethstats settings to cache for node deploys 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"` Servers map[string][]byte `json:"servers,omitempty"`
} }

@ -27,7 +27,7 @@ import (
// deployExplorer creates a new block explorer based on some user input. // deployExplorer creates a new block explorer based on some user input.
func (w *wizard) deployExplorer() { func (w *wizard) deployExplorer() {
// Do some sanity check before the user wastes time on input // 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") log.Error("No genesis block configured")
return return
} }
@ -35,7 +35,7 @@ func (w *wizard) deployExplorer() {
log.Error("No ethstats server configured") log.Error("No ethstats server configured")
return return
} }
if w.conf.genesis.Config.Ethash == nil { if w.conf.Genesis.Config.Ethash == nil {
log.Error("Only ethash network supported") log.Error("Only ethash network supported")
return return
} }
@ -51,7 +51,7 @@ func (w *wizard) deployExplorer() {
if err != nil { if err != nil {
infos = &explorerInfos{nodePort: 30303, webPort: 80, webHost: client.server} 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 { if err != nil {
log.Error("Failed to create chain spec for explorer", "err", err) log.Error("Failed to create chain spec for explorer", "err", err)
return return

@ -47,8 +47,8 @@ func (w *wizard) deployFaucet() {
tiers: 3, tiers: 3,
} }
} }
infos.node.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") infos.node.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ")
infos.node.network = w.conf.genesis.Config.ChainId.Int64() infos.node.network = w.conf.Genesis.Config.ChainId.Int64()
// Figure out which port to listen on // Figure out which port to listen on
fmt.Println() fmt.Println()

@ -124,7 +124,10 @@ func (w *wizard) makeGenesis() {
genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536)))) genesis.Config.ChainId = new(big.Int).SetUint64(uint64(w.readDefaultInt(rand.Intn(65536))))
// All done, store the genesis and flush to disk // 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 // manageGenesis permits the modification of chain configuration parameters in
@ -134,44 +137,56 @@ func (w *wizard) manageGenesis() {
fmt.Println() fmt.Println()
fmt.Println(" 1. Modify existing fork rules") fmt.Println(" 1. Modify existing fork rules")
fmt.Println(" 2. Export genesis configuration") fmt.Println(" 2. Export genesis configuration")
fmt.Println(" 3. Remove genesis configuration")
choice := w.read() choice := w.read()
switch { switch {
case choice == "1": case choice == "1":
// Fork rule updating requested, iterate over each fork // Fork rule updating requested, iterate over each fork
fmt.Println() fmt.Println()
fmt.Printf("Which block should Homestead come into effect? (default = %v)\n", 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) w.conf.Genesis.Config.HomesteadBlock = w.readDefaultBigInt(w.conf.Genesis.Config.HomesteadBlock)
fmt.Println() fmt.Println()
fmt.Printf("Which block should EIP150 come into effect? (default = %v)\n", 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) w.conf.Genesis.Config.EIP150Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP150Block)
fmt.Println() fmt.Println()
fmt.Printf("Which block should EIP155 come into effect? (default = %v)\n", 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) w.conf.Genesis.Config.EIP155Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP155Block)
fmt.Println() fmt.Println()
fmt.Printf("Which block should EIP158 come into effect? (default = %v)\n", 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) w.conf.Genesis.Config.EIP158Block = w.readDefaultBigInt(w.conf.Genesis.Config.EIP158Block)
fmt.Println() fmt.Println()
fmt.Printf("Which block should Byzantium come into effect? (default = %v)\n", 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) 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) fmt.Printf("Chain configuration updated:\n\n%s\n", out)
case choice == "2": case choice == "2":
// Save whatever genesis configuration we currently have // Save whatever genesis configuration we currently have
fmt.Println() fmt.Println()
fmt.Printf("Which file to save the genesis into? (default = %s.json)\n", w.network) 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 { 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.Error("Failed to save genesis file", "err", err)
} }
log.Info("Exported existing genesis block") 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: default:
log.Error("That's not something I can do") log.Error("That's not something I can do")
} }

@ -107,7 +107,7 @@ func (w *wizard) run() {
fmt.Println() fmt.Println()
fmt.Println("What would you like to do? (default = stats)") fmt.Println("What would you like to do? (default = stats)")
fmt.Println(" 1. Show network stats") fmt.Println(" 1. Show network stats")
if w.conf.genesis == nil { if w.conf.Genesis == nil {
fmt.Println(" 2. Configure new genesis") fmt.Println(" 2. Configure new genesis")
} else { } else {
fmt.Println(" 2. Manage existing genesis") fmt.Println(" 2. Manage existing genesis")
@ -129,7 +129,7 @@ func (w *wizard) run() {
w.networkStats() w.networkStats()
case choice == "2": case choice == "2":
if w.conf.genesis == nil { if w.conf.Genesis == nil {
w.makeGenesis() w.makeGenesis()
} else { } else {
w.manageGenesis() w.manageGenesis()

@ -32,7 +32,7 @@ import (
// configuration set to give users hints on how to do various tasks. // configuration set to give users hints on how to do various tasks.
func (w *wizard) networkStats() { func (w *wizard) networkStats() {
if len(w.servers) == 0 { if len(w.servers) == 0 {
log.Error("No remote machines to gather stats from") log.Info("No remote machines to gather stats from")
return return
} }
// Clear out some previous configs to refill from current scan // 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() w.lock.Lock()
defer w.lock.Unlock() defer w.lock.Unlock()
if genesis != "" && w.conf.genesis == nil { if genesis != "" && w.conf.Genesis == nil {
g := new(core.Genesis) g := new(core.Genesis)
if err := json.Unmarshal([]byte(genesis), g); err != nil { if err := json.Unmarshal([]byte(genesis), g); err != nil {
log.Error("Failed to parse remote genesis", "err", err) log.Error("Failed to parse remote genesis", "err", err)
} else { } else {
w.conf.genesis = g w.conf.Genesis = g
} }
} }
if ethstats != "" { if ethstats != "" {

@ -29,7 +29,7 @@ import (
// deployNode creates a new node configuration based on some user input. // deployNode creates a new node configuration based on some user input.
func (w *wizard) deployNode(boot bool) { func (w *wizard) deployNode(boot bool) {
// Do some sanity check before the user wastes time on input // 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") log.Error("No genesis block configured")
return 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 = &nodeInfos{portFull: 30303, peersTotal: 50, peersLight: 0, gasTarget: 4.7, gasPrice: 18}
} }
} }
infos.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ")
infos.network = w.conf.genesis.Config.ChainId.Int64() infos.network = w.conf.Genesis.Config.ChainId.Int64()
// Figure out where the user wants to store the persistent data // Figure out where the user wants to store the persistent data
fmt.Println() 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) fmt.Printf("Where should data be stored on the remote machine? (default = %s)\n", infos.datadir)
infos.datadir = w.readDefaultString(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() fmt.Println()
if infos.ethashdir == "" { if infos.ethashdir == "" {
fmt.Printf("Where should the ethash mining DAGs be stored on the remote machine?\n") 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 the node is a miner/signer, load up needed credentials
if !boot { 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 // Ethash based miners only need an etherbase to mine against
fmt.Println() fmt.Println()
if infos.etherbase == "" { 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) fmt.Printf("What address should the miner user? (default = %s)\n", infos.etherbase)
infos.etherbase = w.readDefaultAddress(common.HexToAddress(infos.etherbase)).Hex() 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 a previous signer was already set, offer to reuse it
if infos.keyJSON != "" { if infos.keyJSON != "" {
if key, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil { if key, err := keystore.DecryptKey([]byte(infos.keyJSON), infos.keyPass); err != nil {

@ -27,7 +27,7 @@ import (
// deployWallet creates a new web wallet based on some user input. // deployWallet creates a new web wallet based on some user input.
func (w *wizard) deployWallet() { func (w *wizard) deployWallet() {
// Do some sanity check before the user wastes time on input // 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") log.Error("No genesis block configured")
return return
} }
@ -47,8 +47,8 @@ func (w *wizard) deployWallet() {
if err != nil { if err != nil {
infos = &walletInfos{nodePort: 30303, rpcPort: 8545, webPort: 80, webHost: client.server} infos = &walletInfos{nodePort: 30303, rpcPort: 8545, webPort: 80, webHost: client.server}
} }
infos.genesis, _ = json.MarshalIndent(w.conf.genesis, "", " ") infos.genesis, _ = json.MarshalIndent(w.conf.Genesis, "", " ")
infos.network = w.conf.genesis.Config.ChainId.Int64() infos.network = w.conf.Genesis.Config.ChainId.Int64()
// Figure out which port to listen on // Figure out which port to listen on
fmt.Println() fmt.Println()

Loading…
Cancel
Save